diff --git a/.github/workflows/build_documentation.yml b/.github/workflows/build_documentation.yml index 5dfbb3d0d84..a0e60ecf30a 100644 --- a/.github/workflows/build_documentation.yml +++ b/.github/workflows/build_documentation.yml @@ -30,7 +30,7 @@ jobs: vale-version: "2.29.6" docs_build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -74,26 +74,38 @@ jobs: - name: Install doc build requirements run: | - sudo apt install graphviz + sudo apt update + sudo apt install graphviz texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra -y # run doc build, without creating the examples directory # note that we have to add the examples file here since it won't # be created as gallery is disabled on linux. - - name: Documentation Build + - name: Documentation Build (HTML) run: | make -C doc clean mkdir doc/source/examples -p echo $'Examples\n========' > doc/source/examples/index.rst - make -C doc html SPHINXOPTS="-j auto -w build_errors.txt -N" + make -C doc phtml-no-examples SPHINXOPTS="-j auto -w build_errors.txt -N" # Verify that sphinx generates no warnings - name: Check for warnings run: | python doc/print_errors.py -# - name: Upload Documentation -# uses: actions/upload-artifact@v4 -# with: -# name: Documentation -# path: doc/_build/html -# retention-days: 7 + - name: Upload Documentation + uses: actions/upload-artifact@v3 + with: + name: Documentation + path: doc/_build/html + retention-days: 7 + + - name: Documentation Build (PDF) + run: | + make -C doc pdf-no-examples + + - name: Upload documentation PDF artifact + uses: actions/upload-artifact@v3 + with: + name: Documentation-pdf + path: doc/_build/latex/*.pdf + retention-days: 7 diff --git a/.github/workflows/nightly-docs.yml b/.github/workflows/nightly-docs.yml index 648055fd444..59f4dceeb5d 100644 --- a/.github/workflows/nightly-docs.yml +++ b/.github/workflows/nightly-docs.yml @@ -35,9 +35,32 @@ jobs: run: | pip install .[doc] - - name: Full Documentation Build + - name: Install doc build requirements + run: | + sudo apt update + sudo apt install graphviz texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra -y + + - name: Documentation Build (HTML) + run: | + make -C doc clean + mkdir doc/source/examples -p + echo $'Examples\n========' > doc/source/examples/index.rst + make -C doc phtml-no-examples SPHINXOPTS="-j auto -w build_errors.txt -N" + + # Verify that sphinx generates no warnings + - name: Check for warnings + run: | + python doc/print_errors.py + + - name: Documentation Build (PDF) run: | - make -C doc phtml + make -C doc pdf-no-examples + + - name: Add assets to HTML docs + run: | + zip -r documentation-html.zip ./doc/_build/html + mv documentation-html.zip ./doc/_build/html/_static/assets/download/ + cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf - name: Upload documentation HTML artifact uses: actions/upload-artifact@v3 @@ -46,13 +69,18 @@ jobs: path: doc/_build/html retention-days: 7 + - name: Upload documentation PDF artifact + uses: actions/upload-artifact@v3 + with: + name: Documentation-pdf + path: doc/_build/latex/*.pdf + retention-days: 7 docs_upload: needs: docs_build runs-on: ubuntu-latest steps: - - - name: Deploy development documentation + - name: Upload development documentation uses: ansys/actions/doc-deploy-dev@v4 with: cname: ${{ env.DOCUMENTATION_CNAME }} diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index dd16afa66bf..473ec840b8c 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -69,7 +69,7 @@ jobs: - name: 'Unit testing' uses: nick-fields/retry@v3 with: - max_attempts: 3 + max_attempts: 1 retry_on: error timeout_minutes: 40 command: | @@ -132,13 +132,13 @@ jobs: - name: 'Unit testing' uses: nick-fields/retry@v3 with: - max_attempts: 3 + max_attempts: 2 retry_on: error timeout_minutes: 50 command: | testenv\Scripts\Activate.ps1 Set-Item -Path env:PYTHONMALLOC -Value "malloc" - pytest -n 6 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest + pytest -n 4 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest - uses: codecov/codecov-action@v4 env: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 40b1fcafcc6..66133ced6e0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ exclude: | repos: - repo: https://github.com/psf/black - rev: 24.3.0 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!! + rev: 24.4.0 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!! hooks: - id: black args: @@ -41,14 +41,14 @@ repos: - tomli - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: debug-statements - id: trailing-whitespace # validate GitHub workflow files - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.28.1 + rev: 0.28.2 hooks: - id: check-github-workflows @@ -56,7 +56,13 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==24.3.0] + additional_dependencies: [black==24.4.0] + +# This validates our pre-commit.ci configuration +- repo: https://github.com/pre-commit-ci/pre-commit-ci-config + rev: v1.6.1 + hooks: + - id: check-pre-commit-ci-config # - repo: https://github.com/numpy/numpydoc diff --git a/_unittest/conftest.py b/_unittest/conftest.py index c118de30461..afbf23fabd4 100644 --- a/_unittest/conftest.py +++ b/_unittest/conftest.py @@ -38,7 +38,7 @@ settings.enable_error_handler = False settings.enable_desktop_logs = False settings.desktop_launch_timeout = 180 - +settings.release_on_exception = False from pyaedt import Edb from pyaedt import Hfss diff --git a/_unittest/example_models/T03/iron_pyaedt.amat b/_unittest/example_models/T03/iron_pyaedt.amat index 4e88aefde9e..d27fbdf1c75 100644 --- a/_unittest/example_models/T03/iron_pyaedt.amat +++ b/_unittest/example_models/T03/iron_pyaedt.amat @@ -95,4 +95,4 @@ GUID: 04b3107f-45c5-4e7c-bdd6-3bf3cffc2ef2' Y('0.996931', '1.09554', '1.17332', '1.23238', '1.27806', '1.31149', '1.33712', '1.3594', '1.37946', '1.40174', '1.43406', '1.53657') $end '$Thermal_expansion_coefficient_with_temperature_1' $end 'RefDatasets' -$end 'iron_pyaedt' +$end 'iron_pyaedt' \ No newline at end of file diff --git a/_unittest/example_models/T03/material_sample.amat b/_unittest/example_models/T03/material_sample.amat index c9461d59858..2d48102644c 100644 --- a/_unittest/example_models/T03/material_sample.amat +++ b/_unittest/example_models/T03/material_sample.amat @@ -78,4 +78,4 @@ $begin '$index$' $base_index$(pos=0, lin=1, lvl=0) $index$(pos=2021, lin=72, lvl=0) $end '$index$' -$end '$index$' +$end '$index$' \ No newline at end of file diff --git a/_unittest/example_models/T12/EMI_RCV_241.aedtz b/_unittest/example_models/T12/EMI_RCV_241.aedtz new file mode 100644 index 00000000000..22c5a966bb9 Binary files /dev/null and b/_unittest/example_models/T12/EMI_RCV_241.aedtz differ diff --git a/_unittest/example_models/T13/material_sample.amat b/_unittest/example_models/T13/material_sample.amat index c9461d59858..2d48102644c 100644 --- a/_unittest/example_models/T13/material_sample.amat +++ b/_unittest/example_models/T13/material_sample.amat @@ -78,4 +78,4 @@ $begin '$index$' $base_index$(pos=0, lin=1, lvl=0) $index$(pos=2021, lin=72, lvl=0) $end '$index$' -$end '$index$' +$end '$index$' \ No newline at end of file diff --git a/_unittest/example_models/T21/SSN_custom.s6p b/_unittest/example_models/T21/SSN_custom.s6p new file mode 100644 index 00000000000..f0bf9ba6b95 --- /dev/null +++ b/_unittest/example_models/T21/SSN_custom.s6p @@ -0,0 +1,5084 @@ +! Touchstone file exported from HFSS 3D Layout Design 2021.2.0 +! File: D:/Simulation/SSN.aedt +! Generated: 12:36:15 PM Feb 18, 2021 +! Design: ssn +! Project: SSN +! Setup: SYZ Sweep 1 +! Solution: SYZ Sweep 1 +! +# GHz S MA R 50.000000 +! Terminal data exported +! Port[1] = A-MII-RXD1_30.SQFP28X28_208.P +! Port[2] = A-MII-RXD1_65.SQFP20X20_144.N +! Port[3] = A-MII-RXD2_32.SQFP28X28_208.P +! Port[4] = A-MII-RXD2_66.SQFP20X20_144.N +! Port[5] = A-MII-RXD3_33.SQFP28X28_208.P +! Port[6] = A-MII-RXD3_67.SQFP20X20_144.N +0 0.00298166409530576 0 0.997018335804667 0 9.71569326119175E-06 0 9.71569326119176E-06 180 + 9.71553401690422E-06 0 9.71553398912824E-06 180 + 0.997018335804667 0 0.00298166409530576 0 9.71569326119175E-06 180 9.71569326119175E-06 0 + 9.71553398921538E-06 180 9.71553401684487E-06 0 + 9.71569326119175E-06 0 9.71569326119175E-06 180 0.00299134546858548 0 0.997008654431399 0 + 9.71543966877399E-06 0 9.71543965339285E-06 180 + 9.71569326119176E-06 180 9.71569326119175E-06 0 0.997008654431399 0 0.0029913454685857 0 + 9.71543965340107E-06 180 9.71543966877518E-06 0 + 9.71553401690422E-06 0 9.71553398921538E-06 180 9.71543966877399E-06 0 9.71543965340107E-06 180 + 0.00300768812298791 0 0.996992311774038 0 + 9.71553398912824E-06 180 9.71553401684487E-06 0 9.71543965339285E-06 180 9.71543966877518E-06 0 + 0.996992311774038 0 0.00300768812300545 0 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1E-09 0.00298166368434043 -2.50463494557164E-05 0.997018335393844 -2.26230518148201E-07 9.71583079266345E-06 -8.63804976255341E-05 9.71555581087442E-06 179.998276195267 + 9.71552424906832E-06 -0.00148026903575998 9.71554381058921E-06 179.998490647022 + 0.997018335393844 -2.26230518148201E-07 0.0029816636843446 -2.50463494555352E-05 9.71555581086154E-06 179.998276195267 9.71583079275975E-06 -8.63804976191674E-05 + 9.71554381059778E-06 179.998490647022 9.71552424894711E-06 -0.00148026903576143 + 9.71583079266345E-06 -8.63804976255341E-05 9.71555581086154E-06 179.998276195267 0.00299134510789917 0.000108728185556684 0.997008654070648 -5.32487000288021E-07 + 9.71549119858817E-06 0.0011570803002674 9.715388219442E-06 -179.99964576313 + 9.71555581087442E-06 179.998276195267 9.71583079275975E-06 -8.63804976191674E-05 0.997008654070648 -5.32487000288021E-07 0.00299134510788463 0.000108728185558091 + 9.71538821943929E-06 -179.99964576313 9.7154911985589E-06 0.00115708030027184 + 9.71552424906832E-06 -0.00148026903575998 9.71554381059778E-06 179.998490647022 9.71549119858817E-06 0.0011570803002674 9.71538821943929E-06 -179.99964576313 + 0.00300768806597006 0.00104882229072098 0.996992311716399 -3.43984852719754E-06 + 9.71554381058921E-06 179.998490647022 9.71552424894711E-06 -0.00148026903576143 9.715388219442E-06 -179.99964576313 9.7154911985589E-06 0.00115708030027184 + 0.996992311716399 -3.43984852719754E-06 0.00300768806597006 0.00104882229070033 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.12201845430196E-09 0.00298166372929937 -2.51820950132448E-05 0.997018335438569 -2.59508355866464E-07 9.71582869716878E-06 0.000904455524638895 9.71555794448528E-06 179.998972539976 + 9.7155233766824E-06 -0.00162321985992371 9.71554471218261E-06 179.998328916887 + 0.997018335438569 -2.59508355866464E-07 0.00298166372930877 -2.51820950131107E-05 9.71555794436615E-06 179.998972539976 9.71582869702549E-06 0.000904455524652325 + 9.71554471216592E-06 179.998328916887 9.71552337659425E-06 -0.00162321985991986 + 9.71582869716878E-06 0.000904455524638895 9.71555794436615E-06 179.998972539976 0.00299134504893657 0.000115468451818421 0.99700865401149 -5.84682868026181E-07 + 9.71550162340926E-06 0.00169819782439261 9.71537779479712E-06 -179.999344823827 + 9.71555794448528E-06 179.998972539976 9.71582869702549E-06 0.000904455524652325 0.99700865401149 -5.84682868026181E-07 0.00299134504891846 0.000115468451818199 + 9.71537779487713E-06 -179.999344823827 9.71550162351117E-06 0.00169819782437531 + 9.7155233766824E-06 -0.00162321985992371 9.71554471216592E-06 179.998328916887 9.71550162340926E-06 0.00169819782439261 9.71537779487713E-06 -179.999344823827 + 0.00300768806410785 0.00103330249744647 0.996992311714594 -3.41957306993116E-06 + 9.71554471218261E-06 179.998328916887 9.71552337659425E-06 -0.00162321985991986 9.71537779479712E-06 -179.999344823827 9.71550162351117E-06 0.00169819782437531 + 0.996992311714594 -3.41957306993116E-06 0.00300768806410785 0.0010333024974382 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.25892541179417E-09 0.00298166377913648 -2.45145087200816E-05 0.997018335488564 -2.98483356284924E-07 9.71582595725865E-06 0.00198522926820376 9.71556066617563E-06 179.999745096866 + 9.71552236735945E-06 -0.00177793605829864 9.71554575010256E-06 179.998151375069 + 0.997018335488564 -2.98483356284924E-07 0.00298166377916807 -2.45145087198817E-05 9.71556066618077E-06 179.999745096866 9.71582595723E-06 0.00198522926820897 + 9.71554575003024E-06 179.998151375069 9.71552236736216E-06 -0.00177793605828242 + 9.71582595725865E-06 0.00198522926820376 9.71556066618077E-06 179.999745096866 0.0029913449905094 0.000121972016771414 0.997008653953048 -6.4100189209108E-07 + 9.71551285191221E-06 0.00237274772866408 9.71536660779507E-06 -179.998960216601 + 9.71556066617563E-06 179.999745096866 9.71582595723E-06 0.00198522926820897 0.997008653953048 -6.4100189209108E-07 0.00299134499052478 0.000121972016770019 + 9.71536660763342E-06 -179.998960216601 9.71551285170957E-06 0.00237274772870896 + 9.71552236735945E-06 -0.00177793605829864 9.71554575003024E-06 179.998151375069 9.71551285191221E-06 0.00237274772866408 9.71536660763342E-06 -179.998960216601 + 0.00300768806216454 0.00100672374741004 0.996992311712278 -3.37004403425713E-06 + 9.71554575010256E-06 179.998151375069 9.71552236736216E-06 -0.00177793605828242 9.71536660779507E-06 -179.998960216601 9.71551285170957E-06 0.00237274772870896 + 0.996992311712278 -3.37004403425713E-06 0.00300768806216454 0.00100672374740178 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.41253754462275E-09 0.00298166383363459 -2.28142613217374E-05 0.997018335542906 -3.4412947052537E-07 9.71582291770519E-06 0.00315609849361151 9.71556377000634E-06 -179.999410108533 + 9.71552111380374E-06 -0.00194676049634697 9.71554704361231E-06 179.99795553925 + 0.997018335542906 -3.4412947052537E-07 0.00298166383363705 -2.28142613209708E-05 9.71556376998053E-06 -179.999410108533 9.71582291769363E-06 0.00315609849361745 + 9.71554704363931E-06 179.99795553925 9.71552111376124E-06 -0.00194676049636727 + 9.71582291770519E-06 0.00315609849361151 9.71556376998053E-06 -179.999410108533 0.00299134493473842 0.000128241290680446 0.997008653897606 -7.01910447793314E-07 + 9.71552441488999E-06 0.00319546202058417 9.71535511459779E-06 -179.998480684543 + 9.71556377000634E-06 -179.999410108533 9.71582291769363E-06 0.00315609849361745 0.997008653897606 -7.01910447793314E-07 0.00299134493471708 0.00012824129068445 + 9.7153551146057E-06 -179.998480684543 9.71552441483144E-06 0.00319546202061659 + 9.71552111380374E-06 -0.00194676049634697 9.71554704363931E-06 179.99795553925 9.71552441488999E-06 0.00319546202058417 9.7153551146057E-06 -179.998480684543 + 0.00300768805980164 0.000971042873668454 0.996992311709947 -3.29783811032227E-06 + 9.71554704361231E-06 179.99795553925 9.71552111376124E-06 -0.00194676049636727 9.71535511459779E-06 -179.998480684543 9.71552441483144E-06 0.00319546202061659 + 0.996992311709947 -3.29783811032227E-06 0.00300768805981585 0.000971042873663866 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.58489319246111E-09 0.00298166389135839 -1.98232652397444E-05 0.997018335600333 -3.97581370598148E-07 9.71581972995913E-06 0.00442025832687641 9.71556702438095E-06 -179.998495068654 + 9.7155193986776E-06 -0.00213235271231629 9.7155487522158E-06 179.997738720824 + 0.997018335600333 -3.97581370598148E-07 0.00298166389132509 -1.98232652407864E-05 9.71556702441998E-06 -179.998495068654 9.71581972998617E-06 0.00442025832688423 + 9.71554875215183E-06 179.997738720824 9.71551939858653E-06 -0.00213235271234179 + 9.71581972995913E-06 0.00442025832687641 9.71556702441998E-06 -179.998495068654 0.00299134488445324 0.000134332295517096 0.997008653846738 -7.68013450036262E-07 + 9.71553569414283E-06 0.00417820627258091 9.71534380187987E-06 -179.997896618034 + 9.71556702438095E-06 -179.998495068654 9.71581972998617E-06 0.00442025832688423 0.997008653846738 -7.68013450036262E-07 0.00299134488445376 0.000134332295516384 + 9.7153438018133E-06 -179.997896618034 9.71553569403256E-06 0.00417820627261241 + 9.7155193986776E-06 -0.00213235271231629 9.71554875215183E-06 179.997738720824 9.71553569414283E-06 0.00417820627258091 9.7153438018133E-06 -179.997896618034 + 0.00300768805722093 0.000928569789148646 0.996992311707688 -3.21057309724182E-06 + 9.7155487522158E-06 179.997738720824 9.71551939858653E-06 -0.00213235271234179 9.71534380187987E-06 -179.997896618034 9.71553569403256E-06 0.00417820627261241 + 0.996992311707688 -3.21057309724182E-06 0.00300768805724935 0.000928569789135741 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.77827941003892E-09 0.00298166395022459 -1.52908666444291E-05 0.997018335659389 -4.60050804232623E-07 9.7158164909789E-06 0.00578313850606297 9.71557035694512E-06 -179.997510332459 + 9.71551692914736E-06 -0.0023370859169489 9.71555124661228E-06 179.997498598359 + 0.997018335659389 -4.60050804232623E-07 0.00298166395021448 -1.52908666448281E-05 9.71557035695171E-06 -179.997510332459 9.71581649098378E-06 0.00578313850608786 + 9.71555124675181E-06 179.997498598359 9.71551692921588E-06 -0.00233708591694565 + 9.7158164909789E-06 0.00578313850606297 9.71557035695171E-06 -179.997510332459 0.00299134484059529 0.0001403733024081 0.997008653803087 -8.40119844765442E-07 + 9.71554623798129E-06 0.00533327922310712 9.71533336597466E-06 -179.997196916383 + 9.71557035694512E-06 -179.997510332459 9.71581649098378E-06 0.00578313850608786 0.997008653803087 -8.40119844765442E-07 0.00299134484056553 0.000140373302411201 + 9.71533336591677E-06 -179.997196916383 9.71554623797056E-06 0.00533327922314283 + 9.71551692914736E-06 -0.0023370859169489 9.71555124675181E-06 179.997498598359 9.71554623798129E-06 0.00533327922310712 9.71533336591677E-06 -179.997196916383 + 0.00300768805486571 0.00088172336638848 0.996992311705513 -3.11618123538204E-06 + 9.71555124661228E-06 179.997498598359 9.71551692921588E-06 -0.00233708591694565 9.71533336597466E-06 -179.997196916383 9.71554623797056E-06 0.00533327922314283 + 0.996992311705513 -3.11618123538204E-06 0.0030076880548515 0.000881723366392645 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.99526231496888E-09 0.00298166400818376 -8.98450201470995E-06 0.997018335717148 -5.32812621640177E-07 9.71581309787337E-06 0.00725405178839934 9.71557379118368E-06 -179.99645320373 + 9.71551308458165E-06 -0.00256397934639565 9.7155551876545E-06 179.997232235785 + 0.997018335717148 -5.32812621640177E-07 0.0029816640081734 -8.98450201337025E-06 9.71557379104258E-06 -179.99645320373 9.71581309783478E-06 0.00725405178839986 + 9.7155551876351E-06 179.997232235785 9.71551308455282E-06 -0.00256397934636783 + 9.71581309787337E-06 0.00725405178839934 9.71557379104258E-06 -179.99645320373 0.00299134480492676 0.000146527947071099 0.99700865376729 -9.19163913106022E-07 + 9.71555542890276E-06 0.0066704532130217 9.71532423673654E-06 -179.996372314279 + 9.71557379118368E-06 -179.99645320373 9.71581309783478E-06 0.00725405178839986 0.99700865376729 -9.19163913106022E-07 0.00299134480488754 0.00014652794707249 + 9.7153242367824E-06 -179.996372314279 9.7155554289265E-06 0.00667045321305723 + 9.71551308458165E-06 -0.00256397934639565 9.7155551876351E-06 179.997232235785 9.71555542890276E-06 0.0066704532130217 9.7153242367824E-06 -179.996372314279 + 0.00300768805309358 0.000832815986464385 0.996992311703438 -3.02226963801615E-06 + 9.7155551876545E-06 179.997232235785 9.71551308455282E-06 -0.00256397934636783 9.71532423673654E-06 -179.996372314279 9.7155554289265E-06 0.00667045321305723 + 0.996992311703438 -3.02226963801615E-06 0.00300768805305094 0.00083281598648032 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.23872113856834E-09 0.00298166402644255 -7.02077788921655E-07 0.997018335735284 -6.17221457747E-07 9.71580432611496E-06 0.00884533634839875 9.71558256493335E-06 -179.995318344617 + 9.71551280322133E-06 -0.00281786893704759 9.71555558189041E-06 179.99693486704 + 0.997018335735284 -6.17221457747E-07 0.00298166402646239 -7.02077789968389E-07 9.71558256496109E-06 -179.995318344617 9.71580432614096E-06 0.00884533634834984 + 9.7155555818632E-06 179.99693486704 9.71551280325277E-06 -0.00281786893704413 + 9.71580432611496E-06 0.00884533634839875 9.71558256496109E-06 -179.995318344617 0.00299134477680374 0.000152997892481166 0.997008653739522 -1.00625365167948E-06 + 9.7155638263215E-06 0.00819998884074468 9.71531604869544E-06 -179.995412914545 + 9.71558256493335E-06 -179.995318344617 9.71580432614096E-06 0.00884533634834984 0.997008653739522 -1.00625365167948E-06 0.00299134477683923 0.000152997892478863 + 9.71531604854983E-06 -179.995412914545 9.71556382621958E-06 0.00819998884072595 + 9.71551280322133E-06 -0.00281786893704759 9.7155555818632E-06 179.99693486704 9.7155638263215E-06 0.00819998884074468 9.71531604854983E-06 -179.995412914545 + 0.00300768805095414 0.000783904506124983 0.996992311701591 -2.93572097513238E-06 + 9.71555558189041E-06 179.99693486704 9.71551280325277E-06 -0.00281786893704413 9.71531604869544E-06 -179.995412914545 9.71556382621958E-06 0.00819998884072595 + 0.996992311701591 -2.93572097513238E-06 0.00300768805095414 0.00078390450610846 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.51188643150958E-09 0.00298166402970408 9.73200481869685E-06 0.997018335738545 -7.14725807509597E-07 9.71579599303253E-06 0.0105713986794012 9.71559095900123E-06 -179.994098776392 + 9.71551402834838E-06 -0.00310180845744596 9.71555450725348E-06 179.996603444117 + 0.997018335738545 -7.14725807509597E-07 0.00298166402972463 9.73200481844861E-06 9.71559095897352E-06 -179.994098776392 9.71579599295652E-06 0.0105713986794337 + 9.71555450725207E-06 179.996603444117 9.71551402831119E-06 -0.00310180845743567 + 9.71579599303253E-06 0.0105713986794012 9.71559095897352E-06 -179.994098776392 0.00299134475796451 0.000160006563395709 0.997008653720277 -1.10264414282085E-06 + 9.71557060606567E-06 0.00993326069221422 9.71530942994452E-06 -179.994308309152 + 9.71559095900123E-06 -179.994098776392 9.71579599295652E-06 0.0105713986794337 0.997008653720277 -1.10264414282085E-06 0.00299134475795197 0.000160006563395036 + 9.71530942991438E-06 -179.994308309152 9.71557060607977E-06 0.00993326069216078 + 9.71551402834838E-06 -0.00310180845744596 9.71555450725207E-06 179.996603444117 9.71557060606567E-06 0.00993326069221422 9.71530942991438E-06 -179.994308309152 + 0.00300768804920175 0.000736699690101306 0.99699231169953 -2.86243046922369E-06 + 9.71555450725348E-06 179.996603444117 9.71551402831119E-06 -0.00310180845743567 9.71530942994452E-06 -179.994308309152 9.71557060607977E-06 0.00993326069216078 + 0.99699231169953 -2.86243046922369E-06 0.00300768804923017 0.000736699690094344 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.81838293126445E-09 0.00298166403195582 2.2440070318581E-05 0.997018335740557 -8.2679249924881E-07 9.71578989748405E-06 0.0124512568110959 9.71559751232794E-06 -179.992783395045 + 9.71551480908391E-06 -0.0034204972711321 9.71555355807495E-06 179.996233159638 + 0.997018335740557 -8.2679249924881E-07 0.00298166403195984 2.24400703194104E-05 9.71559751223849E-06 -179.992783395045 9.71578989743328E-06 0.0124512568111602 + 9.71555355801131E-06 179.996233159638 9.71551480909671E-06 -0.00342049727109954 + 9.71578989748405E-06 0.0124512568110959 9.71559751223849E-06 -179.992783395045 0.00299134474734158 0.000167805083402874 0.997008653709358 -1.20980954715068E-06 + 9.7155754614316E-06 0.0118841879880258 9.71530456491558E-06 -179.993046713906 + 9.71559751232794E-06 -179.992783395045 9.71578989743328E-06 0.0124512568111602 0.997008653709358 -1.20980954715068E-06 0.00299134474730932 0.000167805083408806 + 9.71530456496036E-06 -179.993046713906 9.71557546145914E-06 0.01188418798796 + 9.71551480908391E-06 -0.0034204972711321 9.71555355801131E-06 179.996233159638 9.7155754614316E-06 0.0118841879880258 9.71530456496036E-06 -179.993046713906 + 0.0030076880477944 0.000692566917397121 0.996992311697953 -2.80735149687713E-06 + 9.71555355807495E-06 179.996233159638 9.71551480909671E-06 -0.00342049727109954 9.71530456491558E-06 -179.993046713906 9.71557546145914E-06 0.01188418798796 + 0.996992311697953 -2.80735149687713E-06 0.00300768804778019 0.000692566917396262 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.16227766016838E-09 0.00298166403351575 3.75290652568022E-05 0.997018335741783 -9.55028944381628E-07 9.71578528314548E-06 0.0145063652859238 9.71560233038025E-06 -179.991359174145 + 9.71551560274655E-06 -0.00378001560268008 9.71555308921893E-06 179.995817683028 + 0.997018335741783 -9.55028944381628E-07 0.00298166403352014 3.75290652576688E-05 9.71560233041873E-06 -179.991359174145 9.71578528324928E-06 0.0145063652857201 + 9.71555308930415E-06 179.995817683028 9.71551560278308E-06 -0.00378001560264916 + 9.71578528314548E-06 0.0145063652859238 9.71560233041873E-06 -179.991359174145 0.00299134474345963 0.00017664869892419 0.99700865370551 -1.32939208756624E-06 + 9.71557881900526E-06 0.0140692156366145 9.71530153145275E-06 -179.991615580472 + 9.71560233038025E-06 -179.991359174145 9.71578528324928E-06 0.0145063652857201 0.99700865370551 -1.32939208756624E-06 0.00299134474344325 0.000176648698925505 + 9.71530153148918E-06 -179.991615580472 9.71557881898173E-06 0.0140692156366168 + 9.71551560274655E-06 -0.00378001560268008 9.71555308930415E-06 179.995817683028 9.71557881900526E-06 0.0140692156366145 9.71530153148918E-06 -179.991615580472 + 0.00300768804673234 0.00065252862027927 0.996992311696645 -2.77452129839522E-06 + 9.71555308921893E-06 179.995817683028 9.71551560278308E-06 -0.00378001560264916 9.71530153145275E-06 -179.991615580472 9.71557881898173E-06 0.0140692156366168 + 0.996992311696645 -2.77452129839522E-06 0.00300768804674655 0.000652528620272056 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.54813389233576E-09 0.0029816640346036 5.50856824443223E-05 0.997018335742443 -1.10113422396348E-06 9.71578202914697E-06 0.0167611223780647 9.7156058991959E-06 -179.989810866497 + 9.71551611108544E-06 -0.00418403810440766 9.71555273185882E-06 179.99535291592 + 0.997018335742443 -1.10113422396348E-06 0.00298166403460617 5.50856824426513E-05 9.71560589911345E-06 -179.989810866497 9.71578202912394E-06 0.0167611223779675 + 9.71555273194816E-06 179.99535291592 9.71551611111894E-06 -0.00418403810435311 + 9.71578202914697E-06 0.0167611223780647 9.71560589911345E-06 -179.989810866497 0.00299134474532155 0.00018680988832402 0.997008653706905 -1.46327035545514E-06 + 9.71558077491143E-06 0.0165069529703363 9.71529991850776E-06 -179.990002302067 + 9.7156058991959E-06 -179.989810866497 9.71578202912394E-06 0.0167611223779675 0.997008653706905 -1.46327035545514E-06 0.00299134474534942 0.00018680988831557 + 9.71529991841224E-06 -179.990002302067 9.71558077484594E-06 0.0165069529703316 + 9.71551611108544E-06 -0.00418403810440766 9.71555273194816E-06 179.99535291592 9.71558077491143E-06 0.0165069529703363 9.71529991841224E-06 -179.990002302067 + 0.00300768804605816 0.000617333076008926 0.996992311695722 -2.7672837251072E-06 + 9.71555273185882E-06 179.99535291592 9.71551611111894E-06 -0.00418403810435311 9.71529991850776E-06 -179.990002302067 9.71558077484594E-06 0.0165069529703316 + 0.996992311695722 -2.7672837251072E-06 0.00300768804604395 0.000617333076020104 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.98107170553497E-09 0.00298166403510818 7.51930203605324E-05 0.997018335742992 -1.26694697572493E-06 9.71577990158395E-06 0.0192436089409667 9.71560843025344E-06 -179.988120342595 + 9.71551645422389E-06 -0.00463942728939779 9.7155525497958E-06 179.994831397619 + 0.997018335742992 -1.26694697572493E-06 0.00298166403511311 7.5193020356693E-05 9.71560843025438E-06 -179.988120342595 9.71577990153676E-06 0.0192436089410323 + 9.71555254979548E-06 179.994831397619 9.71551645428049E-06 -0.00463942728934165 + 9.71577990158395E-06 0.0192436089409667 9.71560843025438E-06 -179.988120342595 0.00299134475099057 0.00019857686981068 0.997008653712493 -1.61356972830344E-06 + 9.71558171679457E-06 0.0192203587132869 9.71529952695374E-06 -179.988192219734 + 9.71560843025344E-06 -179.988120342595 9.71577990153676E-06 0.0192436089410323 0.997008653712493 -1.61356972830344E-06 0.00299134475099132 0.000198576869809613 + 9.71529952689486E-06 -179.988192219734 9.71558171674632E-06 0.019220358713333 + 9.71551645422389E-06 -0.00463942728939779 9.71555254979548E-06 179.994831397619 9.71558171679457E-06 0.0192203587132869 9.71529952689486E-06 -179.988192219734 + 0.00300768804561537 0.000587501262549986 0.996992311695096 -2.78846117100341E-06 + 9.7155525497958E-06 179.994831397619 9.71551645428049E-06 -0.00463942728934165 9.71529952695374E-06 -179.988192219734 9.71558171674632E-06 0.019220358713333 + 0.996992311695096 -2.78846117100341E-06 0.00300768804557274 0.000587501262566575 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.46683592150963E-09 0.0029816640356266 9.79455578365771E-05 0.997018335743001 -1.45446064306201E-06 9.71577872366164E-06 0.0219852777606646 9.71561010521351E-06 -179.986267129762 + 9.71551668884815E-06 -0.00515299678455381 9.71555255201711E-06 179.994245534406 + 0.997018335743001 -1.45446064306201E-06 0.00298166403560822 9.79455578365225E-05 9.71561010527902E-06 -179.986267129762 9.71577872367337E-06 0.0219852777608822 + 9.71555255199683E-06 179.994245534406 9.71551668888588E-06 -0.0051529967845423 + 9.71577872366164E-06 0.0219852777606646 9.71561010527902E-06 -179.986267129762 0.00299134475945494 0.00021223522761243 0.997008653720402 -1.78262612807786E-06 + 9.71558174690744E-06 0.0222376165603052 9.71529985916465E-06 -179.986167734212 + 9.71561010521351E-06 -179.986267129762 9.71577872367337E-06 0.0219852777608822 0.997008653720402 -1.78262612807786E-06 0.00299134475944515 0.000212235227609728 + 9.71529985914134E-06 -179.986167734212 9.71558174694745E-06 0.0222376165601432 + 9.71551668884815E-06 -0.00515299678455381 9.71555255199683E-06 179.994245534406 9.71558174690744E-06 0.0222376165603052 9.71529985914134E-06 -179.986167734212 + 0.00300768804541792 0.00056338502239091 0.996992311694698 -2.84053513785956E-06 + 9.71555255201711E-06 179.994245534406 9.71551668888588E-06 -0.0051529967845423 9.71529985916465E-06 -179.986167734212 9.71558174694745E-06 0.0222376165601432 + 0.996992311694698 -2.84053513785956E-06 0.00300768804541792 0.000563385022386779 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.01187233627272E-09 0.00298166403588653 0.000123461169856662 0.997018335742772 -1.66587552515989E-06 9.71577838207716E-06 0.025021337280298 9.71561110950566E-06 -179.984228119219 + 9.71551684495951E-06 -0.00573187907872924 9.71555272349143E-06 179.993587251825 + 0.997018335742772 -1.66587552515989E-06 0.00298166403590401 0.000123461169851249 9.71561110941993E-06 -179.984228119219 9.71577838202177E-06 0.0250213372801626 + 9.71555272345554E-06 179.993587251825 9.7155168449298E-06 -0.00573187907871671 + 9.71577838207716E-06 0.025021337280298 9.71561110941993E-06 -179.984228119219 0.00299134476930745 0.000228103816732402 0.997008653729709 -1.97308717844199E-06 + 9.71558145475937E-06 0.0255897129028388 9.71530096294049E-06 -179.983910717467 + 9.71561110950566E-06 -179.984228119219 9.71577838202177E-06 0.0250213372801626 0.997008653729709 -1.97308717844199E-06 0.00299134476928994 0.000228103816733414 + 9.71530096298364E-06 -179.983910717467 9.71558145482995E-06 0.0255897129026398 + 9.71551684495951E-06 -0.00573187907872924 9.71555272345554E-06 179.993587251825 9.71558145475937E-06 0.0255897129028388 9.71530096298364E-06 -179.983910717467 + 0.00300768804560765 0.000545228153559701 0.996992311694358 -2.92585325269663E-06 + 9.71555272349143E-06 179.993587251825 9.7155168449298E-06 -0.00573187907871671 9.71530096294049E-06 -179.983910717467 9.71558145482995E-06 0.0255897129026398 + 0.996992311694358 -2.92585325269663E-06 0.00300768804559344 0.000545228153558146 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.62341325190349E-09 0.00298166403610491 0.000151894895833929 0.997018335742287 -1.90362870555536E-06 9.71577872774718E-06 0.0283914493313519 9.71561157028954E-06 -179.981977140968 + 9.71551698386448E-06 -0.00638443781894965 9.71555308112239E-06 179.992847081344 + 0.997018335742287 -1.90362870555536E-06 0.00298166403609401 0.000151894895832449 9.71561157035581E-06 -179.981977140968 9.71577872777248E-06 0.0283914493311709 + 9.71555308095553E-06 179.992847081344 9.71551698375357E-06 -0.00638443781897828 + 9.71577872774718E-06 0.0283914493313519 9.71561157035581E-06 -179.981977140968 0.00299134477959489 0.000246503764302102 0.997008653739392 -2.18783907189379E-06 + 9.71558085263752E-06 0.0293143108554738 9.71530239130396E-06 -179.981398471684 + 9.71561157028954E-06 -179.981977140968 9.71577872777248E-06 0.0283914493311709 0.997008653739392 -2.18783907189379E-06 0.00299134477960702 0.000246503764307767 + 9.71530239140978E-06 -179.981398471684 9.71558085276936E-06 0.0293143108551209 + 9.71551698386448E-06 -0.00638443781894965 9.71555308095553E-06 179.992847081344 9.71558085263752E-06 0.0293143108554738 9.71530239140978E-06 -179.981398471684 + 0.00300768804599961 0.000533205434265391 0.996992311693931 -3.04677047472072E-06 + 9.71555308112239E-06 179.992847081344 9.71551698375357E-06 -0.00638443781897828 9.71530239130396E-06 -179.981398471684 9.71558085276936E-06 0.0293143108551209 + 0.996992311693931 -3.04677047472072E-06 0.00300768804599961 0.000533205434261261 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.30957344480193E-09 0.00298166403620127 0.0001834364850685 0.997018335741699 -2.17042548454152E-06 9.71577966468123E-06 0.0321397170156516 9.71561164689349E-06 -179.979485114142 + 9.71551707455718E-06 -0.00711962189847479 9.71555354774126E-06 179.992014824308 + 0.997018335741699 -2.17042548454152E-06 0.00298166403627835 0.000183436485054802 9.71561164676459E-06 -179.979485114142 9.71577966460225E-06 0.0321397170154594 + 9.71555354755206E-06 179.992014824308 9.71551707441309E-06 -0.00711962189846322 + 9.71577966468123E-06 0.0321397170156516 9.71561164676459E-06 -179.979485114142 0.00299134478976964 0.000267783905553358 0.997008653748805 -2.43009316094649E-06 + 9.71558031403659E-06 0.0334537384308959 9.71530415846684E-06 -179.978605659869 + 9.71561164689349E-06 -179.979485114142 9.71577966460225E-06 0.0321397170154594 0.997008653748805 -2.43009316094649E-06 0.0029913447897559 0.000267783905556048 + 9.71530415844331E-06 -179.978605659868 9.715580314002E-06 0.0334537384312635 + 9.71551707455718E-06 -0.00711962189847479 9.71555354755206E-06 179.992014824308 9.71558031403659E-06 0.0334537384308959 9.71530415844331E-06 -179.978605659868 + 0.00300768804645157 0.000527465459987755 0.996992311693633 -3.20579516022451E-06 + 9.71555354774126E-06 179.992014824308 9.71551707441309E-06 -0.00711962189846322 9.71530415846684E-06 -179.978605659869 9.715580314002E-06 0.0334537384312635 + 0.996992311693633 -3.20579516022451E-06 0.00300768804640894 0.000527465460003493 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.07945784384138E-09 0.00298166403643309 0.000218331256451189 0.997018335740735 -2.46932622658203E-06 9.71578111882658E-06 0.0363154340234493 9.71561150649298E-06 -179.976719562888 + 9.71551715326146E-06 -0.00794755910913818 9.71555411391763E-06 179.991078955092 + 0.997018335740735 -2.46932622658203E-06 0.00298166403645694 0.000218331256446681 9.715611506503E-06 -179.976719562888 9.71578111880205E-06 0.0363154340234466 + 9.71555411386808E-06 179.991078955092 9.71551715323707E-06 -0.00794755910909616 + 9.71578111882658E-06 0.0363154340234493 9.715611506503E-06 -179.976719562888 0.00299134479939591 0.000292307474059163 0.997008653757446 -2.70336172919592E-06 + 9.71557990801573E-06 0.0380576258825632 9.71530607003312E-06 -179.975501657593 + 9.71561150649298E-06 -179.976719562888 9.71578111880205E-06 0.0363154340234466 0.997008653757446 -2.70336172919592E-06 0.00299134479939386 0.000292307474062475 + 9.71530607004386E-06 -179.975501657593 9.71557990803915E-06 0.0380576258824768 + 9.71551715326146E-06 -0.00794755910913818 9.71555411386808E-06 179.991078955092 9.71557990801573E-06 0.0380576258825632 9.71530607004386E-06 -179.975501657593 + 0.00300768804702034 0.000528154560776956 0.99699231169342 -3.40568896799496E-06 + 9.71555411391763E-06 179.991078955092 9.71551715323707E-06 -0.00794755910909616 9.71530607003312E-06 -179.975501657593 9.71557990803915E-06 0.0380576258824768 + 0.99699231169342 -3.40568896799496E-06 0.00300768804703455 0.000528154560778592 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.94328234724282E-09 0.0029816640367602 0.000256878030457029 0.997018335739634 -2.80380133345084E-06 9.71578297506768E-06 0.0409738954049502 9.71561124722974E-06 -179.973643978837 + 9.71551731249908E-06 -0.00887976644673818 9.71555482986123E-06 179.990026417535 + 0.997018335739634 -2.80380133345084E-06 0.00298166403674965 0.000256878030456361 9.71561124714121E-06 -179.973643978837 9.71578297503405E-06 0.0409738954049645 + 9.71555482989625E-06 179.990026417535 9.71551731248954E-06 -0.00887976644678265 + 9.71578297506768E-06 0.0409738954049502 9.71561124714121E-06 -179.973643978837 0.00299134480815071 0.000320474824733297 0.997008653765099 -3.01154993617261E-06 + 9.71557970884694E-06 0.0431827658232072 9.71530801850037E-06 -179.972050762792 + 9.71561124722974E-06 -179.973643978837 9.71578297503405E-06 0.0409738954049645 0.997008653765099 -3.01154993617261E-06 0.00299134480816802 0.000320474824733 + 9.71530801846871E-06 -179.972050762792 9.71557970876953E-06 0.0431827658238741 + 9.71551731249908E-06 -0.00887976644673818 9.71555482989625E-06 179.990026417535 9.71557970884694E-06 0.0431827658232072 9.71530801846871E-06 -179.972050762792 + 0.00300768804777706 0.000535442730601026 0.996992311692852 -3.64957548839603E-06 + 9.71555482986123E-06 179.990026417535 9.71551731248954E-06 -0.00887976644678265 9.71530801850037E-06 -179.972050762792 9.71557970876953E-06 0.0431827658238741 + 0.996992311692852 -3.64957548839603E-06 0.00300768804776285 0.000535442730611817 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.91250938133745E-09 0.00298166403705027 0.000299445374826856 0.997018335738531 -3.17781474415448E-06 9.71578523490167E-06 0.0461764000888698 9.71561105604828E-06 -179.970218142717 + 9.71551754968666E-06 -0.00992877814386481 9.71555565374055E-06 179.988842976583 + 0.997018335738531 -3.17781474415448E-06 0.00298166403710368 0.000299445374817288 9.71561105590613E-06 -179.970218142717 9.71578523481766E-06 0.0461764000891751 + 9.71555565365794E-06 179.988842976583 9.71551754966802E-06 -0.00992877814373386 + 9.71578523490167E-06 0.0461764000888698 9.71561105590613E-06 -179.970218142717 0.00299134481618745 0.000352712006802869 0.99700865377151 -3.35895512879553E-06 + 9.71557991563353E-06 0.0488929628960554 9.71531008427972E-06 -179.968212495028 + 9.71561105604828E-06 -179.970218142717 9.71578523481766E-06 0.0461764000891751 0.99700865377151 -3.35895512879553E-06 0.00299134481618281 0.000352712006798518 + 9.71531008421824E-06 -179.968212495028 9.71557991557205E-06 0.0488929628961618 + 9.71551754968666E-06 -0.00992877814386481 9.71555565365794E-06 179.988842976583 9.71557991563353E-06 0.0488929628960554 9.71531008421824E-06 -179.968212495028 + 0.00300768804872199 0.00054954404393306 0.996992311692312 -3.94103610281319E-06 + 9.71555565374055E-06 179.988842976583 9.71551754966802E-06 -0.00992877814373386 9.71531008427972E-06 -179.968212495028 9.71557991557205E-06 0.0488929628961618 + 0.996992311692312 -3.94103610281319E-06 0.00300768804870778 0.000549544043931526 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1E-08 0.00298166403773645 0.000346468653257116 0.997018335736964 -3.59587537221629E-06 9.71578782856957E-06 0.0519921822938506 9.71561100860751E-06 -179.966396453167 + 9.71551792347337E-06 -0.0111087538078274 9.71555661434426E-06 179.987512597324 + 0.997018335736964 -3.59587537221629E-06 0.00298166403773959 0.000346468653265357 9.71561100863683E-06 -179.966396453167 9.71578782856035E-06 0.0519921822941546 + 9.71555661440465E-06 179.987512597324 9.71551792355674E-06 -0.0111087538076073 + 9.71578782856957E-06 0.0519921822938506 9.71561100863683E-06 -179.966396453167 0.00299134482341425 0.000389495180946886 0.997008653776802 -3.75037645345778E-06 + 9.71558059438712E-06 0.0552611436603984 9.71531225909971E-06 -179.963939738713 + 9.71561100860751E-06 -179.966396453167 9.71578782856035E-06 0.0519921822941546 0.997008653776802 -3.75037645345778E-06 0.00299134482341094 0.000389495180948358 + 9.71531225913592E-06 -179.963939738712 9.71558059443396E-06 0.0552611436603355 + 9.71551792347337E-06 -0.0111087538078274 9.71555661440465E-06 179.987512597324 9.71558059438712E-06 0.0552611436603984 9.71531225913592E-06 -179.963939738712 + 0.00300768804979868 0.000570729393530321 0.996992311691474 -4.28418244394554E-06 + 9.71555661434426E-06 179.987512597324 9.71551792355674E-06 -0.0111087538076073 9.71531225909971E-06 -179.963939738713 9.71558059443396E-06 0.0552611436603355 + 0.996992311691474 -4.28418244394554E-06 0.00300768804978447 0.000570729393520625 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.12201845430196E-08 0.0029816640386077 0.000398466620595794 0.99701833573523 -4.06314497945777E-06 9.71579080992816E-06 0.0584980655709882 9.71561125988973E-06 -179.962128579966 + 9.71551847208172E-06 -0.0124355224849686 9.71555772521838E-06 179.986017379799 + 0.99701833573523 -4.06314497945777E-06 0.00298166403859669 0.000398466620614603 9.71561125994646E-06 -179.962128579966 9.71579080984865E-06 0.0584980655713929 + 9.7155577252638E-06 179.986017379799 9.7155184720583E-06 -0.0124355224847744 + 9.71579080992816E-06 0.0584980655709882 9.71561125994646E-06 -179.962128579966 0.00299134482980952 0.000431345643976673 0.997008653780811 -4.19114314158553E-06 + 9.71558186581491E-06 0.0623693990617077 9.71531461815594E-06 -179.959179022081 + 9.71561125988973E-06 -179.962128579966 9.71579080984865E-06 0.0584980655713929 0.997008653780811 -4.19114314158553E-06 0.00299134482982741 0.000431345643977245 + 9.71531461820571E-06 -179.959179022081 9.7155818658625E-06 0.0623693990613353 + 9.71551847208172E-06 -0.0124355224849686 9.7155577252638E-06 179.986017379799 9.71558186581491E-06 0.0623693990617077 9.71531461820571E-06 -179.959179022081 + 0.0030076880511072 0.000599339159071791 0.996992311690466 -4.68374323598688E-06 + 9.71555772521838E-06 179.986017379799 9.7155184720583E-06 -0.0124355224847744 9.71531461815594E-06 -179.959179022081 9.7155818658625E-06 0.0623693990613353 + 0.996992311690466 -4.68374323598688E-06 0.00300768805113562 0.000599339159061996 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.25892541179417E-08 0.00298166403987807 0.000456041897372058 0.997018335733187 -4.58549441559618E-06 9.71579423384353E-06 0.0657803374355738 9.7156119201013E-06 -179.957357952427 + 9.71551930483281E-06 -0.0139271566833449 9.71555908022901E-06 179.984336956246 + 0.997018335733187 -4.58549441559618E-06 0.00298166403986141 0.000456041897374773 9.71561192013559E-06 -179.957357952427 9.71579423383421E-06 0.0657803374356452 + 9.71555908029537E-06 179.984336956246 9.7155193049601E-06 -0.0139271566832556 + 9.71579423384353E-06 0.0657803374355738 9.71561192013559E-06 -179.957357952427 0.00299134483580587 0.000478846787718923 0.997008653783674 -4.68721682337271E-06 + 9.71558384067641E-06 0.0703101674233999 9.71531724138387E-06 -179.953869711883 + 9.7156119201013E-06 -179.957357952427 9.71579423383421E-06 0.0657803374356452 0.997008653783674 -4.68721682337271E-06 0.00299134483581097 0.000478846787713899 + 9.71531724147191E-06 -179.953869711883 9.71558384086864E-06 0.0703101674222548 + 9.71551930483281E-06 -0.0139271566833449 9.71555908029537E-06 179.984336956246 9.71558384067641E-06 0.0703101674233999 9.71531724147191E-06 -179.953869711883 + 0.00300768805277629 0.000635796468730237 0.996992311689088 -5.14514533776406E-06 + 9.71555908022901E-06 179.984336956246 9.7155193049601E-06 -0.0139271566832556 9.71531724138387E-06 -179.953869711883 9.71558384086864E-06 0.0703101674222548 + 0.996992311689088 -5.14514533776406E-06 0.0030076880527905 0.000635796468718971 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.41253754462275E-08 0.00298166404163632 0.000519887524149165 0.997018335730804 -5.16958028291688E-06 9.71579819825205E-06 0.0739355679775767 9.71561310058211E-06 -179.95202134493 + 9.71552039789045E-06 -0.0156030446408662 9.7155606471831E-06 179.982449385649 + 0.997018335730804 -5.16958028291688E-06 0.00298166404158521 0.000519887524161769 9.71561310073655E-06 -179.95202134493 9.71579819839298E-06 0.0739355679772777 + 9.7155606473247E-06 179.982449385649 9.71552039808181E-06 -0.0156030446407757 + 9.71579819825205E-06 0.0739355679775767 9.71561310073655E-06 -179.95202134493 0.00299134484135406 0.000532647908587387 0.997008653785428 -5.24526075424438E-06 + 9.71558660149174E-06 0.0791878382777171 9.71532018145525E-06 -179.947942843669 + 9.71561310058211E-06 -179.95202134493 9.71579819839298E-06 0.0739355679772777 0.997008653785428 -5.24526075424438E-06 0.00299134484133817 0.000532647908590572 + 9.7153201815667E-06 -179.94794284367 9.71558660157013E-06 0.079187838277155 + 9.71552039789045E-06 -0.0156030446408662 9.7155606473247E-06 179.982449385649 9.71558660149174E-06 0.0791878382777171 9.7153201815667E-06 -179.94794284367 + 0.00300768805479283 0.000680615218227865 0.996992311687327 -5.67460073688231E-06 + 9.7155606471831E-06 179.982449385649 9.71552039808181E-06 -0.0156030446407757 9.71532018145525E-06 -179.947942843669 9.71558660157013E-06 0.079187838277155 + 0.996992311687327 -5.67460073688231E-06 0.00300768805480704 0.00068061521822878 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.58489319246111E-08 0.00298166404395001 0.00059079436231775 0.997018335727859 -5.82292990421576E-06 9.7158028319017E-06 0.0830720839633622 9.71561490511988E-06 -179.946047849375 + 9.71552188354921E-06 -0.0174858741674461 9.71556255556806E-06 179.980329133727 + 0.997018335727859 -5.82292990421576E-06 0.00298166404395857 0.000590794362324234 9.71561490523318E-06 -179.946047849375 9.71580283199647E-06 0.083072083962951 + 9.71556255560373E-06 179.980329133728 9.71552188361198E-06 -0.0174858741672788 + 9.7158028319017E-06 0.0830720839633622 9.71561490523318E-06 -179.946047849375 0.00299134484678949 0.000593477753761348 0.997008653785993 -5.87274020597755E-06 + 9.7155904027766E-06 0.0891187280725551 9.71532366040857E-06 -179.941321653794 + 9.71561490511988E-06 -179.946047849375 9.71580283199647E-06 0.083072083962951 0.997008653785993 -5.87274020597755E-06 0.00299134484682174 0.000593477753755257 + 9.71532366041519E-06 -179.941321653795 9.71559040268661E-06 0.0891187280730334 + 9.71552188354921E-06 -0.0174858741674461 9.71556255560373E-06 179.980329133728 9.7155904027766E-06 0.0891187280725551 9.71532366041519E-06 -179.941321653795 + 0.00300768805731461 0.000734411882825002 0.996992311685026 -6.27919785038949E-06 + 9.71556255556806E-06 179.980329133727 9.71552188361198E-06 -0.0174858741672788 9.71532366040857E-06 -179.941321653794 9.71559040268661E-06 0.0891187280730334 + 0.996992311685026 -6.27919785038949E-06 0.00300768805730039 0.000734411882820211 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.77827941003892E-08 0.00298166404697208 0.000669663543269128 0.997018335724272 -6.5540508403358E-06 9.71580836815571E-06 0.0933108821428846 9.71561750855113E-06 -179.939358445705 + 9.71552380553773E-06 -0.0196004243523496 9.71556485112758E-06 179.977948243532 + 0.997018335724272 -6.5540508403358E-06 0.00298166404698783 0.00066966354326072 9.71561750859933E-06 -179.939358445705 9.71580836818755E-06 0.0933108821425611 + 9.71556485119892E-06 179.977948243532 9.71552380552483E-06 -0.0196004243522651 + 9.71580836815571E-06 0.0933108821428846 9.71561750859933E-06 -179.939358445705 0.00299134485224507 0.000662153906262362 0.997008653785395 -6.57802522849903E-06 + 9.71559539111866E-06 0.100234210689553 9.71532777810534E-06 -179.933918981981 + 9.71561750855113E-06 -179.939358445705 9.71580836818755E-06 0.0933108821425611 0.997008653785395 -6.57802522849903E-06 0.0029913448522543 0.000662153906251911 + 9.71532777811932E-06 -179.933918981981 9.71559539113363E-06 0.100234210690195 + 9.71552380553773E-06 -0.0196004243523496 9.71556485119892E-06 179.977948243532 9.71559539111866E-06 0.100234210689553 9.71532777811932E-06 -179.933918981981 + 0.00300768806044294 0.000797915071478248 0.996992311682114 -6.96700403968595E-06 + 9.71556485112758E-06 179.977948243532 9.71552380552483E-06 -0.0196004243522651 9.71532777810534E-06 -179.933918981981 9.71559539113363E-06 0.100234210690195 + 0.996992311682114 -6.96700403968595E-06 0.00300768806041452 0.000797915071485788 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.99526231496888E-08 0.0029816640509492 0.000757506034402198 0.997018335719942 -7.37250460414058E-06 9.71581504413356E-06 0.104787939966519 9.71562105670082E-06 -179.931864255149 + 9.71552633756219E-06 -0.0219751528481994 9.71556771313444E-06 179.975274703203 + 0.997018335719942 -7.37250460414058E-06 0.00298166405094299 0.00075750603440891 9.71562105674797E-06 -179.931864255149 9.71581504414746E-06 0.104787939966674 + 9.71556771318279E-06 179.975274703202 9.71552633770693E-06 -0.0219751528479851 + 9.71581504413356E-06 0.104787939966519 9.71562105674797E-06 -179.931864255149 0.00299134485815371 0.000739595513537036 0.997008653783503 -7.37050944509372E-06 + 9.7156018615694E-06 0.112681161384515 9.71533276270941E-06 -179.925637430278 + 9.71562105670082E-06 -179.931864255149 9.71581504414746E-06 0.104787939966674 0.997008653783503 -7.37050944509372E-06 0.00299134485812268 0.000739595513614271 + 9.71533276291031E-06 -179.925637430278 9.71560186168454E-06 0.112681161384731 + 9.71552633756219E-06 -0.0219751528481994 9.71556771318279E-06 179.975274703202 9.7156018615694E-06 0.112681161384515 9.71533276291031E-06 -179.925637430278 + 0.0030076880643081 0.000871980504717112 0.996992311678392 -7.74718232516697E-06 + 9.71556771313444E-06 179.975274703203 9.71552633770693E-06 -0.0219751528479851 9.71533276270941E-06 -179.925637430278 9.71560186168454E-06 0.112681161384731 + 0.996992311678392 -7.74718232516697E-06 0.00300768806429389 0.000871980504721232 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.23872113856834E-08 0.00298166405597881 0.00085546664044784 0.997018335714574 -8.28906191338639E-06 9.71582322166472E-06 0.117655383019425 9.71562579150241E-06 -179.923466005513 + 9.71552953824358E-06 -0.0246411554245732 9.7155712073166E-06 179.972273436292 + 0.997018335714574 -8.28906191338639E-06 0.00298166405596936 0.00085546664045011 9.71562579150733E-06 -179.923466005513 9.71582322162596E-06 0.117655383019207 + 9.71557120726868E-06 179.972273436292 9.71552953823013E-06 -0.0246411554245977 + 9.71582322166472E-06 0.117655383019425 9.71562579150733E-06 -179.923466005513 0.00299134486453583 0.000826836829472924 0.997008653780283 -8.26073433527909E-06 + 9.71561018985846E-06 0.126624191145435 9.71533889750747E-06 -179.916367823195 + 9.71562579150241E-06 -179.923466005513 9.71582322162596E-06 0.117655383019207 0.997008653780283 -8.26073433527909E-06 0.00299134486456662 0.0008268368294556 + 9.71533889741021E-06 -179.916367823194 9.71561018980805E-06 0.126624191145185 + 9.71552953824358E-06 -0.0246411554245732 9.71557120726868E-06 179.972273436292 9.71561018985846E-06 0.126624191145435 9.71533889741021E-06 -179.916367823194 + 0.00300768806919734 0.000957596735623412 0.996992311673733 -8.6301029869655E-06 + 9.7155712073166E-06 179.972273436292 9.71552953823013E-06 -0.0246411554245977 9.71533889750747E-06 -179.916367823195 9.71561018980805E-06 0.126624191145185 + 0.996992311673733 -8.6301029869655E-06 0.00300768806916892 0.000957596735615938 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.51188643150958E-08 0.00298166406239688 0.000964826013003955 0.997018335707894 -9.31580671007987E-06 9.71583327808302E-06 0.132084142050872 9.71563193963818E-06 -179.914052068976 + 9.71553363959013E-06 -0.0276341421504466 9.71557557366368E-06 179.968904272744 + 0.997018335707894 -9.31580671007987E-06 0.00298166406241663 0.000964826012959906 9.71563193958338E-06 -179.914052068977 9.71583327807886E-06 0.13208414204942 + 9.71557557357098E-06 179.968904272744 9.71553363951586E-06 -0.0276341421504462 + 9.71583327808302E-06 0.132084142050872 9.71563193958338E-06 -179.914052068977 0.00299134487191563 0.000925039420380583 0.997008653775471 -9.26053051649366E-06 + 9.71562078111141E-06 0.142248250949319 9.71534646199534E-06 -179.905987331377 + 9.71563193963818E-06 -179.914052068976 9.71583327807886E-06 0.13208414204942 0.997008653775471 -9.26053051649366E-06 0.00299134487196631 0.000925039420359537 + 9.71534646192498E-06 -179.905987331378 9.71562078095821E-06 0.142248250949883 + 9.71553363959013E-06 -0.0276341421504466 9.71557557357098E-06 179.968904272744 9.71562078111141E-06 0.142248250949319 9.71534646192498E-06 -179.905987331378 + 0.00300768807522816 0.00105590662429884 0.996992311667824 -9.62750230651492E-06 + 9.71557557366368E-06 179.968904272744 9.71553363951586E-06 -0.0276341421504462 9.71534646199534E-06 -179.905987331377 9.71562078095821E-06 0.142248250949883 + 0.996992311667824 -9.62750230651492E-06 0.00300768807519974 0.00105590662430056 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.81838293126445E-08 0.00298166407061988 0.00108702098074328 0.997018335699433 -1.04663061417636E-05 9.71584578593411E-06 0.148265408412279 9.71563988566355E-06 -179.903497788317 + 9.71553886182064E-06 -0.0309938611307467 9.71558104199528E-06 179.965122465454 + 0.997018335699433 -1.04663061417636E-05 0.00298166407060768 0.00108702098074669 9.71563988562587E-06 -179.903497788317 9.71584578584659E-06 0.148265408414351 + 9.71558104196167E-06 179.965122465454 9.7155388617944E-06 -0.0309938611306185 + 9.71584578593411E-06 0.148265408412279 9.71563988562587E-06 -179.903497788317 0.00299134488070876 0.00103550895542888 0.997008653768812 -1.0383175610155E-05 + 9.71563425361042E-06 0.159760145374634 9.71535590770786E-06 -179.894358807508 + 9.71563988566355E-06 -179.903497788317 9.71584578584659E-06 0.148265408414351 0.997008653768812 -1.0383175610155E-05 0.00299134488067003 0.00103550895544785 + 9.7153559077367E-06 -179.894358807509 9.71563425360522E-06 0.159760145375599 + 9.71553886182064E-06 -0.0309938611307467 9.71558104196167E-06 179.965122465454 9.71563425361042E-06 0.159760145374634 9.7153559077367E-06 -179.894358807509 + 0.00300768808277486 0.00116821825384554 0.99699231166041 -1.07526244803553E-05 + 9.71558104199528E-06 179.965122465454 9.7155388617944E-06 -0.0309938611306185 9.71535590770786E-06 -179.894358807508 9.71563425360522E-06 0.159760145375599 + 0.99699231166041 -1.07526244803553E-05 0.00300768808286013 0.00116821825378764 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.16227766016838E-08 0.00298166408103127 0.00122366510298627 0.997018335689013 -1.17557916080568E-05 9.71586134405253E-06 0.16641420209601 9.71565000118967E-06 -179.891662800988 + 9.7155454501064E-06 -0.03476467999077 9.71558786743775E-06 179.960878040291 + 0.997018335689013 -1.17557916080568E-05 0.00298166408100555 0.00122366510302179 9.71565000121107E-06 -179.891662800988 9.71586134408658E-06 0.166414202094566 + 9.71558786750323E-06 179.960878040291 9.71554545014251E-06 -0.0347646799909193 + 9.71586134405253E-06 0.16641420209601 9.71565000121107E-06 -179.891662800988 0.0029913448911795 0.00115971436142605 0.997008653760033 -1.16435783581113E-05 + 9.71565126291636E-06 0.179392448069115 9.71536767197471E-06 -179.88132779497 + 9.71565000118967E-06 -179.891662800988 9.71586134408658E-06 0.166414202094566 0.997008653760033 -1.16435783581113E-05 0.00299134489120353 0.00115971436144441 + 9.71536767188114E-06 -179.88132779497 9.71565126285662E-06 0.17939244806835 + 9.7155454501064E-06 -0.03476467999077 9.71558786750323E-06 179.960878040291 9.71565126291636E-06 0.179392448069115 9.71536767188114E-06 -179.88132779497 + 0.00300768809251147 0.00129602429385283 0.996992311651021 -1.20204066610292E-05 + 9.71558786743775E-06 179.960878040291 9.71554545014251E-06 -0.0347646799909193 9.71536767197471E-06 -179.88132779497 9.71565126285662E-06 0.17939244806835 + 0.996992311651021 -1.20204066610292E-05 0.00300768809251147 0.00129602429384457 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.54813389233575E-08 0.00298166409414963 0.00137656388091204 0.997018335675939 -1.32013420291728E-05 9.71588085061325E-06 0.186770885609171 9.71566290319273E-06 -179.878390511069 + 9.7155537923916E-06 -0.0389968735457141 9.71559644826344E-06 179.95611443391 + 0.997018335675939 -1.32013420291728E-05 0.00298166409415271 0.00137656388091854 9.71566290322889E-06 -179.878390511068 9.7158808506028E-06 0.186770885609221 + 9.71559644816966E-06 179.956114433909 9.71555379227244E-06 -0.0389968735462922 + 9.71588085061325E-06 0.186770885609171 9.71566290322889E-06 -179.878390511068 0.00299134490402676 0.00129930458778686 0.997008653748499 -1.30584671453893E-05 + 9.71567279211522E-06 0.201405088027432 9.71538245639172E-06 -179.866721987561 + 9.71566290319273E-06 -179.878390511069 9.7158808506028E-06 0.186770885609221 0.997008653748499 -1.30584671453893E-05 0.00299134490400126 0.00129930458783059 + 9.71538245651229E-06 -179.866721987561 9.71567279216553E-06 0.201405088026464 + 9.7155537923916E-06 -0.0389968735457141 9.71559644816966E-06 179.956114433909 9.71567279211522E-06 0.201405088027432 9.71538245651229E-06 -179.866721987561 + 0.00300768810457355 0.00144102312115637 0.996992311639075 -1.34476786622208E-05 + 9.71559644826344E-06 179.95611443391 9.71555379227244E-06 -0.0389968735462922 9.71538245639172E-06 -179.866721987561 9.71567279216553E-06 0.201405088026464 + 0.996992311639075 -1.34476786622208E-05 0.00300768810458776 0.00144102312121565 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.98107170553497E-08 0.00298166411067377 0.00154774177552186 0.997018335659435 -1.48221206355618E-05 9.71590528707047E-06 0.20960583663192 9.71567922848464E-06 -179.863504520387 + 9.71556432332869E-06 -0.0437465264429422 9.71560723083109E-06 179.950768508341 + 0.997018335659435 -1.48221206355618E-05 0.00298166411065417 0.00154774177552868 9.71567922849895E-06 -179.863504520387 9.71590528720654E-06 0.209605836629293 + 9.71560723097615E-06 179.950768508341 9.71556432339537E-06 -0.0437465264431259 + 9.71590528707047E-06 0.20960583663192 9.71567922849895E-06 -179.863504520387 0.00299134491986303 0.00145613260983973 0.997008653733761 -1.46466211122917E-05 + 9.71569993607549E-06 0.226090309270304 9.71540099534064E-06 -179.850347425338 + 9.71567922848464E-06 -179.863504520387 9.71590528720654E-06 0.209605836629293 0.997008653733761 -1.46466211122917E-05 0.00299134491986061 0.00145613260982805 + 9.71540099534715E-06 -179.85034742534 9.71569993604015E-06 0.226090309270467 + 9.71556432332869E-06 -0.0437465264429422 9.71560723097615E-06 179.950768508341 9.71569993607549E-06 0.226090309270304 9.71540099534715E-06 -179.85034742534 + 0.00300768811975238 0.00160514025692873 0.996992311624104 -1.50533844703601E-05 + 9.71560723083109E-06 179.950768508341 9.71556432339537E-06 -0.0437465264431259 9.71540099534064E-06 -179.850347425338 9.71569993604015E-06 0.226090309270467 + 0.996992311624104 -1.50533844703601E-05 0.00300768811972396 0.0016051402569439 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.46683592150963E-08 0.00298166413159309 0.00173946587663978 0.997018335638726 -1.66396163065711E-05 9.71593596543245E-06 0.235221923126389 9.71569986035954E-06 -179.846807407966 + 9.71557757876001E-06 -0.0490765178488398 9.71562076315762E-06 179.944769470653 + 0.997018335638726 -1.66396163065711E-05 0.00298166413156892 0.00173946587663034 9.71569986048585E-06 -179.846807407966 9.71593596551032E-06 0.235221923125394 + 9.71562076324804E-06 179.944769470653 9.7155775788913E-06 -0.049076517849288 + 9.71593596543245E-06 0.235221923126389 9.71569986048585E-06 -179.846807407966 0.002991344939571 0.00163228095746656 0.997008653714878 -1.64291191162291E-05 + 9.71573415157699E-06 0.253775496409189 9.71542428579786E-06 -179.831986986137 + 9.71569986035954E-06 -179.846807407966 9.71593596551032E-06 0.235221923125394 0.997008653714878 -1.64291191162291E-05 0.00299134493955522 0.00163228095752335 + 9.71542428577802E-06 -179.831986986136 9.71573415157569E-06 0.253775496409802 + 9.71557757876001E-06 -0.0490765178488398 9.71562076324804E-06 179.944769470653 9.71573415157699E-06 0.253775496409189 9.71542428577802E-06 -179.831986986136 + 0.00300768813887018 0.00179055387493365 0.996992311605312 -1.6858830492606E-05 + 9.71562076315762E-06 179.944769470653 9.7155775788913E-06 -0.049076517849288 9.71542428579786E-06 -179.831986986137 9.71573415157569E-06 0.253775496409802 + 0.996992311605312 -1.6858830492606E-05 0.00300768813885597 0.00179055387489254 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.01187233627272E-08 0.00298166415786687 0.00195427803123582 0.997018335612667 -1.86779367039924E-05 9.71597452372039E-06 0.263958930887772 9.71572590524973E-06 -179.82807768861 + 9.71559428809946E-06 -0.0550577035271408 9.71563778871617E-06 179.938037587335 + 0.997018335612667 -1.86779367039924E-05 0.00298166415788374 0.00195427803124085 9.71572590523937E-06 -179.82807768861 9.71597452373032E-06 0.263958930886547 + 9.71563778865145E-06 179.938037587334 9.71559428807854E-06 -0.055057703527019 + 9.71597452372039E-06 0.263958930887772 9.71572590523937E-06 -179.82807768861 0.00299134496416236 0.00183008721255906 0.997008653690979 -1.84296158510326E-05 + 9.71577724789134E-06 0.284827918119199 9.71545355443967E-06 -179.811397091826 + 9.71572590524973E-06 -179.82807768861 9.71597452373032E-06 0.263958930886547 0.997008653690979 -1.84296158510326E-05 0.00299134496418438 0.00183008721256191 + 9.71545355450212E-06 -179.811397091829 9.71577724785881E-06 0.284827918119957 + 9.71559428809946E-06 -0.0550577035271408 9.71563778865145E-06 179.938037587334 9.71577724789134E-06 0.284827918119199 9.71545355450212E-06 -179.811397091829 + 0.00300768816297971 0.00199972585206509 0.996992311581605 -1.88879802540045E-05 + 9.71563778871617E-06 179.938037587335 9.71559428807854E-06 -0.055057703527019 9.71545355443967E-06 -179.811397091826 9.71577724785881E-06 0.284827918119957 + 0.996992311581605 -1.88879802540045E-05 0.00300768816295129 0.00199972585203442 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.62341325190349E-08 0.00298166419102197 0.0021950264798892 0.997018335579923 -2.09641198466366E-05 9.71602300154252E-06 0.296198129819772 9.71575873759336E-06 -179.80706681808 + 9.71561536263901E-06 -0.0617695581238643 9.71565923512985E-06 179.930483423007 + 0.997018335579923 -2.09641198466366E-05 0.00298166419104782 0.00219502647986991 9.715758737454E-06 -179.807066818079 9.71602300139846E-06 0.29619812982102 + 9.71565923511348E-06 179.930483423009 9.71561536258849E-06 -0.0617695581223104 + 9.71602300154252E-06 0.296198129819772 9.715758737454E-06 -179.807066818079 0.00299134499500868 0.00205217693403287 0.997008653660695 -2.06746590367483E-05 + 9.71583155896588E-06 0.319659231063778 9.71549039869264E-06 -179.788304850461 + 9.71575873759336E-06 -179.80706681808 9.71602300139846E-06 0.29619812982102 0.997008653660695 -2.06746590367483E-05 0.00299134499502587 0.00205217693402067 + 9.71549039871953E-06 -179.788304850464 9.71583155894506E-06 0.319659231061971 + 9.71561536263901E-06 -0.0617695581238643 9.71565923511348E-06 179.930483423009 9.71583155896588E-06 0.319659231063778 9.71549039871953E-06 -179.788304850464 + 0.00300768819325138 0.00223543159520642 0.996992311551761 -2.11677576427492E-05 + 9.71565923512985E-06 179.930483423007 9.71561536258849E-06 -0.0617695581223104 9.71549039869264E-06 -179.788304850461 9.71583155894506E-06 0.319659231061971 + 0.996992311551761 -2.11677576427492E-05 0.00300768819326559 0.00223543159514629 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.30957344480193E-08 0.0029816642327678 0.0024649050254661 0.99701833553868 -2.35284988059806E-05 9.71608399814949E-06 0.332367014000603 9.71580012502312E-06 -179.783496197595 + 9.71564187114572E-06 -0.0693008189013351 9.71568619194397E-06 179.922007065846 + 0.99701833553868 -2.35284988059806E-05 0.00298166423280521 0.00246490502538947 9.71580012500977E-06 -179.783496197598 9.71608399807428E-06 0.332367014000487 + 9.71568619182514E-06 179.922007065846 9.71564187100705E-06 -0.0693008189016074 + 9.71608399814949E-06 0.332367014000603 9.71580012500977E-06 -179.783496197598 0.00299134503374525 0.00230149604714574 0.997008653622455 -2.31940368171166E-05 + 9.71589992909497E-06 0.35873166485444 9.71553673270344E-06 -179.762403695567 + 9.71580012502312E-06 -179.783496197595 9.71608399807428E-06 0.332367014000487 0.997008653622455 -2.31940368171166E-05 0.00299134503375683 0.00230149604713951 + 9.71553673275364E-06 -179.762403695566 9.71589992907133E-06 0.358731664856603 + 9.71564187114572E-06 -0.0693008189013351 9.71568619182514E-06 179.922007065846 9.71589992909497E-06 0.35873166485444 9.71553673275364E-06 -179.762403695566 + 0.00300768823144327 0.00250079899678824 0.996992311514177 -2.3728414544137E-05 + 9.71568619194397E-06 179.922007065846 9.71564187100705E-06 -0.0693008189016074 9.71553673270344E-06 -179.762403695567 9.71589992907133E-06 0.358731664856603 + 0.996992311514177 -2.3728414544137E-05 0.00300768823144327 0.00250079899680476 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.07945784384138E-08 0.0029816642852905 0.00276749420752903 0.99701833548677 -2.64050978034301E-05 9.71616074649282E-06 0.372945353161905 9.71585225679207E-06 -179.75705309689 + 9.71567526669685E-06 -0.0777516289556739 9.71572013393538E-06 179.912495834891 + 0.99701833548677 -2.64050978034301E-05 0.00298166428530952 0.0027674942075403 9.71585225680467E-06 -179.757053096891 9.71616074647409E-06 0.372945353161128 + 9.71572013388138E-06 179.912495834891 9.71567526663386E-06 -0.0777516289547943 + 9.71616074649282E-06 0.372945353161905 9.71585225680467E-06 -179.757053096891 0.00299134508237106 0.00258135511363135 0.997008653574232 -2.60211858371632E-05 + 9.71598604060189E-06 0.402563111479742 9.71559506560418E-06 -179.733350359194 + 9.71585225679207E-06 -179.75705309689 9.71616074647409E-06 0.372945353161128 0.997008653574232 -2.60211858371632E-05 0.00299134508235589 0.00258135511368615 + 9.71559506571434E-06 -179.733350359194 9.71598604071736E-06 0.40256311147788 + 9.71567526669685E-06 -0.0777516289556739 9.71572013388138E-06 179.912495834891 9.71598604060189E-06 0.402563111479742 9.71559506571434E-06 -179.733350359194 + 0.00300768827947608 0.00279935000307439 0.996992311466905 -2.66039319703454E-05 + 9.71572013393538E-06 179.912495834891 9.71567526663386E-06 -0.0777516289547943 9.71559506560418E-06 -179.733350359194 9.71598604071736E-06 0.40256311147788 + 0.996992311466905 -2.66039319703454E-05 0.00300768827949029 0.00279935000312725 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.94328234724281E-08 0.00298166435153343 0.00310680725002365 0.997018335421417 -2.96320810909341E-05 9.71625734291288E-06 0.418471188616087 9.71591791863906E-06 -179.727386850422 + 9.71571731068581E-06 -0.0872339899396792 9.71576285319129E-06 179.901823662504 + 0.997018335421417 -2.96320810909341E-05 0.00298166435155882 0.00310680724996418 9.71591791856568E-06 -179.727386850422 9.71625734282131E-06 0.418471188616575 + 9.71576285312884E-06 179.901823662504 9.71571731056763E-06 -0.0872339899396726 + 9.71625734291288E-06 0.418471188616087 9.71591791856568E-06 -179.727386850422 0.00299134514347696 0.00289546682895145 0.997008653513453 -2.91936185792579E-05 + 9.71609444864019E-06 0.45173492502763 9.71566847341482E-06 -179.700759361185 + 9.71591791863906E-06 -179.727386850422 9.71625734282131E-06 0.418471188616575 0.997008653513453 -2.91936185792579E-05 0.00299134514348583 0.00289546682894037 + 9.7156684733939E-06 -179.700759361187 9.71609444870361E-06 0.451734925023568 + 9.71571731068581E-06 -0.0872339899396792 9.71576285312884E-06 179.901823662504 9.71609444864019E-06 0.45173492502763 9.7156684733939E-06 -179.700759361187 + 0.00300768833993216 0.00313504639866254 0.996992311407333 -2.98324671550453E-05 + 9.71576285319129E-06 179.901823662504 9.71571731056763E-06 -0.0872339899396726 9.71566847341482E-06 -179.700759361185 9.71609444870361E-06 0.451734925023568 + 0.996992311407333 -2.98324671550453E-05 0.00300768833996058 0.00313504639869901 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.91250938133746E-08 0.00298166443485857 0.00348734708920449 0.997018335339139 -3.32522698470813E-05 9.71637892407497E-06 0.469548119460755 9.71600060113523E-06 -179.694104037414 + 9.71577024379184E-06 -0.0978736781791627 9.71581662504783E-06 179.889848991936 + 0.997018335339139 -3.32522698470813E-05 0.00298166443487011 0.00348734708922142 9.71600060111808E-06 -179.694104037414 9.71637892401355E-06 0.469548119464628 + 9.7158166250578E-06 179.889848991935 9.71577024376723E-06 -0.0978736781794231 + 9.71637892407497E-06 0.469548119460755 9.71600060111808E-06 -179.694104037414 0.00299134522037415 0.00324799910145827 0.997008653436766 -3.27534310514587E-05 + 9.71623095101704E-06 0.506898799179532 9.71576088965341E-06 -179.664198707676 + 9.71600060113523E-06 -179.694104037414 9.71637892401355E-06 0.469548119464628 0.997008653436766 -3.27534310514587E-05 0.00299134522036024 0.00324799910148215 + 9.71576088975185E-06 -179.664198707679 9.71623095109716E-06 0.506898799175546 + 9.71577024379184E-06 -0.0978736781791627 9.7158166250578E-06 179.889848991935 9.71623095101704E-06 0.506898799179532 9.71576088975185E-06 -179.664198707679 + 0.00300768841605756 0.00351234241370063 0.996992311332377 -3.34568590632876E-05 + 9.71581662504783E-06 179.889848991936 9.71577024376723E-06 -0.0978736781794231 9.71576088965341E-06 -179.664198707676 9.71623095109716E-06 0.506898799175546 + 0.996992311332377 -3.34568590632876E-05 0.00300768841605756 0.0035123424136015 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1E-07 0.00298166453979786 0.00391416243314134 0.997018335235635 -3.73136985797873E-05 9.71653197112396E-06 0.526853142250247 9.71610471459086E-06 -179.656763400974 + 9.7158368984291E-06 -0.109811877175776 9.71588432779967E-06 179.876412935883 + 0.997018335235635 -3.73136985797873E-05 0.00298166453980712 0.00391416243315824 9.71610471458812E-06 -179.656763400976 9.7165319710866E-06 0.526853142248321 + 9.71588432777712E-06 179.876412935884 9.7158368983428E-06 -0.10981187717644 + 9.71653197112396E-06 0.526853142250247 9.71610471458812E-06 -179.656763400976 0.00299134531713813 0.00364363012008153 0.997008653340278 -3.67478611124882E-05 + 9.71640280468625E-06 0.568785911583313 9.71587722471004E-06 -179.623183624359 + 9.71610471459086E-06 -179.656763400974 9.7165319710866E-06 0.526853142248321 0.997008653340278 -3.67478611124882E-05 0.00299134531713076 0.00364363012003314 + 9.71587722464E-06 -179.623183624363 9.71640280459484E-06 0.568785911581166 + 9.7158368984291E-06 -0.109811877175776 9.71588432777712E-06 179.876412935884 9.71640280468625E-06 0.568785911583313 9.71587722464E-06 -179.623183624363 + 0.00300768851189248 0.00393624510840334 0.996992311237933 -3.75252030907804E-05 + 9.71588432779967E-06 179.876412935883 9.7158368983428E-06 -0.10981187717644 9.71587722471004E-06 -179.623183624359 9.71640280459484E-06 0.568785911581166 + 0.996992311237933 -3.75252030907804E-05 0.00300768851184985 0.00393624510869046 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.12201845430196E-07 0.00298166467188407 0.00439291705133695 0.997018335105282 -4.18702604109493E-05 9.71672462527265E-06 0.591145684332554 9.71623579465475E-06 -179.614869894329 + 9.71592081165067E-06 -0.123206810074585 9.71596955319641E-06 179.861337410894 + 0.997018335105282 -4.18702604109493E-05 0.00298166467191332 0.00439291705124495 9.71623579460101E-06 -179.614869894334 9.71672462517671E-06 0.591145684335647 + 9.71596955316584E-06 179.861337410894 9.71592081162867E-06 -0.123206810075364 + 9.71672462527265E-06 0.591145684332554 9.71623579460101E-06 -179.614869894334 0.00299134543889058 0.00408760981496611 0.997008653218793 -4.12299128129662E-05 + 9.71661914487183E-06 0.638216313902055 9.71602365842791E-06 -179.577170384341 + 9.71623579465475E-06 -179.614869894329 9.71672462517671E-06 0.591145684335647 0.997008653218793 -4.12299128129662E-05 0.0029913454389098 0.00408760981494128 + 9.71602365850792E-06 -179.577170384348 9.71661914490934E-06 0.63821631389607 + 9.71592081165067E-06 -0.123206810074585 9.71596955316584E-06 179.861337410894 9.71661914487183E-06 0.638216313902055 9.71602365850792E-06 -179.577170384348 + 0.00300768863245935 0.00441237907927198 0.996992311119057 -4.2091483341422E-05 + 9.71596955319641E-06 179.861337410894 9.71592081162867E-06 -0.123206810075364 9.71602365842791E-06 -179.577170384341 9.71661914490934E-06 0.63821631389607 + 0.996992311119057 -4.2091483341422E-05 0.00300768863247356 0.00441237907911895 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.25892541179417E-07 0.00298166483818877 0.00492996375130369 0.997018334941178 -4.69824181713855E-05 9.71696714650254E-06 0.663277381686505 9.71640082494867E-06 -179.567868347404 + 9.71602645532512E-06 -0.138236084526097 9.71607684399338E-06 179.844422530748 + 0.997018334941178 -4.69824181713855E-05 0.00298166483818427 0.00492996375128337 9.71640082493055E-06 -179.567868347405 9.71696714652726E-06 0.663277381683432 + 9.71607684392226E-06 179.844422530747 9.71602645521898E-06 -0.138236084526421 + 9.71696714650254E-06 0.663277381686505 9.71640082493055E-06 -179.567868347405 0.00299134559213391 0.00458582952056055 0.997008653065724 -4.62590598910546E-05 + 9.71689151831387E-06 0.716109380716413 9.71620801652992E-06 -179.525549446333 + 9.71640082494867E-06 -179.567868347404 9.71696714652726E-06 0.663277381683432 0.997008653065724 -4.62590598910546E-05 0.00299134559213533 0.00458582952066731 + 9.71620801652157E-06 -179.525549446331 9.71689151828059E-06 0.716109380719904 + 9.71602645532512E-06 -0.138236084526097 9.71607684392226E-06 179.844422530747 9.71689151831387E-06 0.716109380716413 9.71620801652157E-06 -179.525549446331 + 0.00300768878437792 0.00494706286850819 0.996992310969472 -4.72162926967953E-05 + 9.71607684399338E-06 179.844422530748 9.71602645521898E-06 -0.138236084526421 9.71620801652992E-06 -179.525549446333 9.71689151828059E-06 0.716109380719904 + 0.996992310969472 -4.72162926967953E-05 0.00300768878437792 0.0049470628684421 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.41253754462275E-07 0.00298166504755928 0.0055324277111285 0.997018334734671 -5.2718003704263E-05 9.71727244608259E-06 0.74420333827349 9.71660859096406E-06 -179.515136051695 + 9.71615945199223E-06 -0.155098881904288 9.71621190960374E-06 179.825444124025 + 0.997018334734671 -5.2718003704263E-05 0.00298166504756177 0.00553242771103271 9.71660859093956E-06 -179.515136051698 9.71727244597813E-06 0.744203338274048 + 9.71621190955896E-06 179.825444124026 9.7161594519558E-06 -0.155098881902592 + 9.71727244608259E-06 0.74420333827349 9.71660859093956E-06 -179.515136051698 0.00299134578507819 0.00514490005029728 0.997008652873068 -5.19020360041788E-05 + 9.71723440118011E-06 0.803496373307773 9.71644009099884E-06 -179.467636892528 + 9.71660859096406E-06 -179.515136051695 9.71727244597813E-06 0.744203338274048 0.997008652873068 -5.19020360041788E-05 0.00299134578507426 0.00514490005033626 + 9.7164400909237E-06 -179.467636892527 9.71723440108308E-06 0.803496373312261 + 9.71615945199223E-06 -0.155098881904288 9.71621190955896E-06 179.825444124026 9.71723440118011E-06 0.803496373307773 9.7164400909237E-06 -179.467636892527 + 0.00300768897555781 0.00554739082278487 0.996992310781081 -5.29676328290509E-05 + 9.71621190960374E-06 179.825444124025 9.7161594519558E-06 -0.155098881902592 9.71644009099884E-06 -179.467636892528 9.71723440108308E-06 0.803496373312261 + 0.996992310781081 -5.29676328290509E-05 0.00300768897552938 0.00554739082270511 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.58489319246111E-07 0.00298166531113994 0.00620830371524765 0.997018334474548 -5.91531263177203E-05 9.71765678387421E-06 0.834994434795605 9.71687016243012E-06 -179.455974732223 + 9.71632688729682E-06 -0.174018666456542 9.71638194639327E-06 179.804150697366 + 0.997018334474548 -5.91531263177203E-05 0.00298166531112722 0.00620830371540848 9.71687016244413E-06 -179.455974732223 9.71765678393356E-06 0.834994434791778 + 9.71638194646786E-06 179.804150697366 9.71632688728305E-06 -0.174018666456836 + 9.71765678387421E-06 0.834994434795605 9.71687016244413E-06 -179.455974732223 0.00299134602794059 0.00577223999562707 0.997008652630462 -5.82337202192323E-05 + 9.71766606021724E-06 0.901533286725879 9.71673225177919E-06 -179.402666041152 + 9.71687016243012E-06 -179.455974732223 9.71765678393356E-06 0.834994434791778 0.997008652630462 -5.82337202192323E-05 0.00299134602792952 0.00577223999567925 + 9.71673225185671E-06 -179.402666041156 9.71766606030407E-06 0.901533286717832 + 9.71632688729682E-06 -0.174018666456542 9.71638194646786E-06 179.804150697366 9.71766606021724E-06 0.901533286725879 9.71673225185671E-06 -179.402666041156 + 0.00300768921622821 0.00622132896951371 0.996992310543884 -5.94218203938527E-05 + 9.71638194639327E-06 179.804150697366 9.71632688728305E-06 -0.174018666456836 9.71673225177919E-06 -179.402666041152 9.71766606030407E-06 0.901533286717832 + 0.996992310543884 -5.94218203938527E-05 0.00300768921619979 0.0062213289696386 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.77827941003892E-07 0.00298166564294427 0.00696656047194279 0.997018334147234 -6.63731766523644E-05 9.71814060478321E-06 0.936851410049508 9.71719945188322E-06 -179.389601233126 + 9.71653766504765E-06 -0.195245965230908 9.71659599649367E-06 179.780260288208 + 0.997018334147234 -6.63731766523644E-05 0.00298166564298853 0.00696656047172016 9.71719945191597E-06 -179.389601233129 9.71814060480236E-06 0.936851410041507 + 9.71659599640986E-06 179.780260288206 9.71653766495983E-06 -0.195245965232438 + 9.71814060478321E-06 0.936851410049508 9.71719945191597E-06 -179.389601233129 0.00299134633370008 0.00647617387696981 0.997008652325042 -6.53381304349093E-05 + 9.71820945966158E-06 1.01151615719805 9.71710004215935E-06 -179.329777089882 + 9.71719945188322E-06 -179.389601233126 9.71814060480236E-06 0.936851410041507 0.997008652325042 -6.53381304349093E-05 0.00299134633367007 0.00647617387705204 + 9.71710004222962E-06 -179.329777089878 9.71820945969501E-06 1.01151615720807 + 9.71653766504765E-06 -0.195245965230908 9.71659599640986E-06 179.780260288206 9.71820945966158E-06 1.01151615719805 9.71710004222962E-06 -179.329777089878 + 0.00300768951923029 0.00697782067993687 0.996992310245367 -6.66645007568649E-05 + 9.71659599649367E-06 179.780260288208 9.71653766495983E-06 -0.195245965232438 9.71710004215935E-06 -179.329777089882 9.71820945969501E-06 1.01151615720807 + 0.996992310245367 -6.66645007568649E-05 0.00300768951921607 0.00697782067990374 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.99526231496888E-07 0.00298166606078508 0.00781725849385102 0.997018333735051 -7.44739574976337E-05 9.71874967381843E-06 1.05111996153151 9.717614004303E-06 -179.315137696404 + 9.71680303173678E-06 -0.219061950544653 9.71686548104292E-06 179.753456473644 + 0.997018333735051 -7.44739574976337E-05 0.00298166606073815 0.00781725849423426 9.71761400443562E-06 -179.315137696396 9.71874967390442E-06 1.05111996153606 + 9.71686548120653E-06 179.753456473642 9.71680303191785E-06 -0.219061950545675 + 9.71874967381843E-06 1.05111996153151 9.71761400443562E-06 -179.315137696396 0.00299134671850171 0.00726604251772738 0.997008651940565 -7.3309538405944E-05 + 9.71889352743694E-06 1.13489738109386 9.71756304923513E-06 -179.248006276332 + 9.717614004303E-06 -179.315137696404 9.71874967390442E-06 1.05111996153606 0.997008651940565 -7.3309538405944E-05 0.00299134671850393 0.00726604251760867 + 9.71756304923966E-06 -179.248006276345 9.71889352734477E-06 1.13489738109543 + 9.71680303173678E-06 -0.219061950544653 9.71686548120653E-06 179.753456473642 9.71889352743694E-06 1.13489738109386 9.71756304923966E-06 -179.248006276345 + 0.00300768990068114 0.00782690341662896 0.996992309869494 -7.47917781688822E-05 + 9.71686548104292E-06 179.753456473644 9.71680303191785E-06 -0.219061950545675 9.71756304923513E-06 -179.248006276332 9.71889352734477E-06 1.13489738109543 + 0.996992309869494 -7.47917781688822E-05 0.00300768990066693 0.00782690341659985 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.23872113856834E-07 0.00298166658662799 0.00877168693946894 0.99701833321619 -8.35629642268369E-05 9.71951639854098E-06 1.17930823195778 9.71813588132476E-06 -179.231599928137 + 9.71713710655794E-06 -0.245781672302209 9.71720473719927E-06 179.723384679882 + 0.99701833321619 -8.35629642268369E-05 0.00298166658660642 0.00877168693985811 9.71813588136565E-06 -179.231599928134 9.71951639860311E-06 1.17930823195792 + 9.71720473718822E-06 179.723384679881 9.71713710671114E-06 -0.245781672300194 + 9.71951639854098E-06 1.17930823195778 9.71813588136565E-06 -179.231599928134 0.00299134720300176 0.00815232648441176 0.997008651456477 -8.22537188110161E-05 + 9.71975467124753E-06 1.27330427953155 9.71814592726711E-06 -179.156273371212 + 9.71813588132476E-06 -179.231599928137 9.71951639860311E-06 1.17930823195792 0.997008651456477 -8.22537188110161E-05 0.00299134720302394 0.00815232648445337 + 9.71814592726634E-06 -179.156273371216 9.71975467121708E-06 1.27330427953593 + 9.71713710655794E-06 -0.245781672302209 9.71720473718822E-06 179.723384679881 9.71975467124753E-06 1.27330427953155 9.71814592726634E-06 -179.156273371216 + 0.00300769038085369 0.0087798446052217 0.99699230939628 -8.39114979577456E-05 + 9.71720473719927E-06 179.723384679882 9.71713710671114E-06 -0.245781672300194 9.71814592726711E-06 -179.156273371212 9.71975467121708E-06 1.27330427953593 + 0.99699230939628 -8.39114979577456E-05 0.00300769038085369 0.00877984460541998 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.51188643150958E-07 0.00298166724878105 0.00984250916784644 0.997018332563024 -9.37607994822187E-05 9.72048157523886E-06 1.32310565697883 9.71879286232965E-06 -179.137884989027 + 9.71755767278132E-06 -0.275758390674549 9.71763182640919E-06 179.689647340726 + 0.997018332563024 -9.37607994822187E-05 0.00298166724875612 0.00984250916812918 9.7187928622615E-06 -179.137884989018 9.72048157519749E-06 1.323105656982 + 9.71763182631823E-06 179.689647340724 9.71755767281883E-06 -0.275758390671911 + 9.72048157523886E-06 1.32310565697883 9.7187928622615E-06 -179.137884989018 0.0029913478129243 0.00914678630770214 0.997008650847085 -9.22893561629187E-05 + 9.72083868834641E-06 1.42855965040057 9.71887968369228E-06 -179.053367780327 + 9.71879286232965E-06 -179.137884989027 9.72048157519749E-06 1.323105656982 0.997008650847085 -9.22893561629187E-05 0.00299134781294374 0.00914678630740548 + 9.71887968363655E-06 -179.053367780325 9.72083868830706E-06 1.42855965040512 + 9.71755767278132E-06 -0.275758390674549 9.71763182631823E-06 179.689647340724 9.72083868834641E-06 1.42855965040057 9.71887968363655E-06 -179.053367780325 + 0.00300769098542931 0.0098492889249019 0.996992308800653 -9.41446735751807E-05 + 9.71763182640919E-06 179.689647340726 9.71755767281883E-06 -0.275758390671911 9.71887968369228E-06 -179.053367780327 9.72083868830706E-06 1.42855965040512 + 0.996992308800653 -9.41446735751807E-05 0.00300769098542931 0.009849288924968 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.81838293126445E-07 0.0029816680822362 0.0110439352679766 0.997018331740728 -0.00010520278538859 9.72169655182438E-06 1.48440402852391 9.71961991655601E-06 -179.032757202278 + 9.71808713452972E-06 -0.309388137234533 9.71816949906516E-06 179.65179876845 + 0.997018331740728 -0.00010520278538859 0.00298166808224694 0.0110439352681091 9.71961991650243E-06 -179.032757202279 9.72169655176196E-06 1.48440402852604 + 9.7181694990154E-06 179.651798768449 9.71808713456615E-06 -0.309388137230576 + 9.72169655182438E-06 1.48440402852391 9.71961991650243E-06 -179.032757202279 0.0029913485808029 0.0102626174259667 0.997008650079831 -0.000103549616629785 + 9.72220325238711E-06 1.60270394877028 9.7198033849442E-06 -178.937933630459 + 9.71961991655601E-06 -179.032757202278 9.72169655176196E-06 1.48440402852604 0.997008650079831 -0.000103549616629785 0.00299134858077846 0.0102626174261884 + 9.71980338504711E-06 -178.937933630461 9.72220325242348E-06 1.60270394877623 + 9.71808713452972E-06 -0.309388137234533 9.7181694990154E-06 179.651798768449 9.72220325238711E-06 1.60270394877028 9.71980338504711E-06 -178.937933630461 + 0.0030076917465274 0.0110494269897816 0.996992308050696 -0.000105627092246834 + 9.71816949906516E-06 179.65179876845 9.71808713456615E-06 -0.309388137230576 9.7198033849442E-06 -178.937933630459 9.72220325242348E-06 1.60270394877623 + 0.996992308050696 -0.000105627092246834 0.00300769174651319 0.0110494269898338 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.16227766016838E-07 0.00298166913158074 0.0123919059819895 0.997018330705484 -0.000118040747038973 9.72322594415554E-06 1.66532067193576 9.72066105689731E-06 -178.914832664774 + 9.71875368735204E-06 -0.347114650755007 9.71884638867343E-06 179.609339589483 + 0.997018330705484 -0.000118040747038973 0.00298166913159567 0.0123919059820985 9.7206610568514E-06 -178.914832664775 9.72322594412743E-06 1.66532067193044 + 9.71884638861976E-06 179.609339589481 9.71875368739563E-06 -0.347114650754594 + 9.72322594415554E-06 1.66532067193576 9.7206610568514E-06 -178.914832664775 0.00299134954750328 0.0115146260965556 0.997008649113996 -0.000116183917698302 + 9.72392091419304E-06 1.79802033970399 9.72096617723379E-06 -178.808452597674 + 9.72066105689731E-06 -178.914832664774 9.72322594412743E-06 1.66532067193044 0.997008649113996 -0.000116183917698302 0.00299134954749504 0.011514626096571 + 9.72096617732161E-06 -178.808452597682 9.72392091422003E-06 1.79802033969974 + 9.71875368735204E-06 -0.347114650755007 9.71884638861976E-06 179.609339589481 9.72392091419304E-06 1.79802033970399 9.72096617732161E-06 -178.808452597682 + 0.00300769270472076 0.0123961841455656 0.996992307106596 -0.000118511119869929 + 9.71884638867343E-06 179.609339589483 9.71875368739563E-06 -0.347114650754594 9.72096617723379E-06 -178.808452597674 9.72392091422003E-06 1.79802033969974 + 0.996992307106596 -0.000118511119869929 0.00300769270469234 0.0123961841458149 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.54813389233575E-07 0.00298167045261756 0.0139043080886985 0.997018329402176 -0.000132445038099166 9.72515106119818E-06 1.86822377845152 9.72197167613476E-06 -178.782562223235 + 9.71959280484098E-06 -0.389434866273705 9.7196985196515E-06 179.561710558203 + 0.997018329402176 -0.000132445038099166 0.00298167045260309 0.0139043080886944 9.7219716760351E-06 -178.782562223214 9.72515106111403E-06 1.86822377847042 + 9.71969851968338E-06 179.561710558204 9.71959280485692E-06 -0.389434866273746 + 9.72515106119818E-06 1.86822377845152 9.7219716760351E-06 -178.782562223214 0.00299135076448871 0.0129194247802744 0.997008647898018 -0.000130359907634279 + 9.72608296961661E-06 2.01706151641692 9.72242992244316E-06 -178.663225540704 + 9.72197167613476E-06 -178.782562223235 9.72515106111403E-06 1.86822377847042 0.997008647898018 -0.000130359907634279 0.00299135076448403 0.012919424780112 + 9.72242992242594E-06 -178.663225540697 9.72608296958837E-06 2.01706151642973 + 9.71959280484098E-06 -0.389434866273705 9.71969851968338E-06 179.561710558204 9.72608296961661E-06 2.01706151641692 9.72242992242594E-06 -178.663225540697 + 0.00300769391090137 0.0139074310119784 0.996992305917998 -0.000132967721057596 + 9.7196985196515E-06 179.561710558203 9.71959280485692E-06 -0.389434866273746 9.72242992244316E-06 -178.663225540704 9.72608296958837E-06 2.01706151642973 + 0.996992305917998 -0.000132967721057596 0.00300769391088716 0.0139074310123085 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.98107170553497E-07 0.0029816721157133 0.0156012092163705 0.997018327761458 -0.000148606793724738 9.72757421343313E-06 2.09575989890361 9.7236214970217E-06 -178.634212839875 + 9.72064918451261E-06 -0.436905422801415 9.72077128383395E-06 179.50828528149 + 0.997018327761458 -0.000148606793724738 0.00298167211569204 0.0156012092165996 9.72362149705273E-06 -178.634212839884 9.72757421351527E-06 2.09575989888385 + 9.72077128393641E-06 179.50828528149 9.72064918461312E-06 -0.436905422803673 + 9.72757421343313E-06 2.09575989890361 9.72362149705273E-06 -178.634212839884 0.00299135229653324 0.0144956539189761 0.997008646367232 -0.00014626569384111 + 9.7288042797199E-06 2.26267893447088 9.72427247625313E-06 -178.500352206164 + 9.7236214970217E-06 -178.634212839875 9.72757421351527E-06 2.09575989888385 0.997008646367232 -0.00014626569384111 0.00299135229653493 0.0144956539184499 + 9.72427247619354E-06 -178.500352206176 9.7288042796059E-06 2.26267893447685 + 9.72064918451261E-06 -0.436905422801415 9.72077128393641E-06 179.50828528149 9.7288042797199E-06 2.26267893447088 9.72427247619354E-06 -178.500352206176 + 0.00300769542944781 0.015603220357537 0.996992304421665 -0.000149188725111824 + 9.72077128383395E-06 179.50828528149 9.72064918461312E-06 -0.436905422803673 9.72427247625313E-06 -178.500352206164 9.7288042796059E-06 2.26267893447685 + 0.996992304421665 -0.000149188725111824 0.00300769542944781 0.015603220357537 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.46683592150963E-07 0.00298167420404226 0.0175051256552444 0.997018325690573 -0.000166740472180952 9.7306239061874E-06 2.35088372951404 9.7256984442285E-06 -178.467847179522 + 9.72198222827108E-06 -0.490148854445221 9.72211860603886E-06 179.448362844489 + 0.997018325690573 -0.000166740472180952 0.00298167420404271 0.0175051256555076 9.72569844424995E-06 -178.467847179508 9.73062390628619E-06 2.35088372949582 + 9.72211860597694E-06 179.44836284449 9.72198222816981E-06 -0.490148854446967 + 9.7306239061874E-06 2.35088372951404 9.72569844424995E-06 -178.467847179508 0.00299135422534788 0.0162642277816374 0.997008644440087 -0.00016411233572122 + 9.73222941772146E-06 2.53805419569436 9.72659167413855E-06 -178.317709056043 + 9.7256984442285E-06 -178.467847179522 9.73062390628619E-06 2.35088372949582 0.997008644440087 -0.00016411233572122 0.00299135422532673 0.0162642277822728 + 9.72659167426814E-06 -178.317709056048 9.73222941788446E-06 2.538054195664 + 9.72198222827108E-06 -0.490148854445221 9.72211860597694E-06 179.44836284449 9.73222941772146E-06 2.53805419569436 9.72659167426814E-06 -178.317709056048 + 0.00300769733930013 0.0175060547871372 0.996992302536049 -0.00016738937878482 + 9.72211860603886E-06 179.448362844489 9.72198222816981E-06 -0.490148854446967 9.72659167413855E-06 -178.317709056043 9.73222941788446E-06 2.538054195664 + 0.996992302536049 -0.00016738937878482 0.00300769733930013 0.0175060547871372 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.01187233627273E-07 0.00298167682784715 0.0196413191801434 0.997018323078264 -0.000187086694476185 9.73446190296751E-06 2.63688952624184 9.7283130287598E-06 -178.281301648109 + 9.723663206676E-06 -0.549861578690292 9.7238119279642E-06 179.381159404179 + 0.997018323078264 -0.000187086694476185 0.00298167682784843 0.0196413191798154 9.72831302881804E-06 -178.281301648121 9.73446190305997E-06 2.63688952621008 + 9.72381192806807E-06 179.381159404181 9.72366320672121E-06 -0.549861578689282 + 9.73446190296751E-06 2.63688952624184 9.72831302881804E-06 -178.281301648121 0.00299135665343407 0.0182486131833441 0.997008642013982 -0.00018413664801961 + 9.73654015394235E-06 2.84673171475283 9.72951074443331E-06 -178.112925977768 + 9.7283130287598E-06 -178.281301648109 9.73446190305997E-06 2.63688952621008 0.997008642013982 -0.00018413664801961 0.00299135665344183 0.0182486131826065 + 9.72951074437612E-06 -178.112925977774 9.73654015387646E-06 2.84673171475332 + 9.723663206676E-06 -0.549861578690292 9.72381192806807E-06 179.381159404181 9.73654015394235E-06 2.84673171475283 9.72951074437612E-06 -178.112925977774 + 0.00300769974213916 0.0196411831757485 0.996992300160712 -0.000187811193932341 + 9.7238119279642E-06 179.381159404179 9.72366320672121E-06 -0.549861578689282 9.72951074443331E-06 -178.112925977768 9.73654015387646E-06 2.84673171475332 + 0.996992300160712 -0.000187811193932341 0.00300769974215337 0.0196411831757878 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.62341325190349E-07 0.00298168013063606 0.0220381339456287 0.997018319789224 -0.000209915443275275 9.73929181000682E-06 2.95744386547288 9.73160413223047E-06 -178.07216301163 + 9.72577912630826E-06 -0.616821838695925 9.72594387772129E-06 179.30579938491 + 0.997018319789224 -0.000209915443275275 0.00298168013064416 0.0220381339446598 9.73160413228086E-06 -178.072163011657 9.73929181002421E-06 2.95744386543577 + 9.72594387765765E-06 179.305799384906 9.72577912622131E-06 -0.616821838700122 + 9.73929181000682E-06 2.95744386547288 9.73160413228086E-06 -178.072163011657 0.00299135971030735 0.0204751391220466 0.9970086389597 -0.000206604339346065 + 9.74196488383444E-06 3.19265316359732 9.73318479449576E-06 -177.883360835495 + 9.73160413223047E-06 -178.07216301163 9.73929181002421E-06 2.95744386543577 0.9970086389597 -0.000206604339346065 0.00299135971030175 0.0204751391226678 + 9.73318479440121E-06 -177.883360835469 9.74196488368071E-06 3.19265316364662 + 9.72577912630826E-06 -0.616821838695925 9.72594387765765E-06 179.305799384906 9.74196488383444E-06 3.19265316359732 9.73318479440121E-06 -177.883360835469 + 0.00300770276749912 0.0220369371535461 0.996992297170728 -0.000210725158863528 + 9.72594387772129E-06 179.30579938491 9.72577912622131E-06 -0.616821838700122 9.73318479449576E-06 -177.883360835495 9.74196488368071E-06 3.19265316364662 + 0.996992297170728 -0.000210725158863528 0.00300770276752755 0.0220369371533379 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.30957344480193E-07 0.00298168428705025 0.0247273712843389 0.997018315647081 -0.000235529642022889 9.74536884182302E-06 3.3166195867365 9.73574717071652E-06 -177.837743719844 + 9.72844071218974E-06 -0.691898181149417 9.72862983353701E-06 179.221305646468 + 0.997018315647081 -0.000235529642022889 0.00298168428704083 0.0247273712842555 9.73574717067484E-06 -177.837743719823 9.74536884186083E-06 3.31661958672463 + 9.72862983347782E-06 179.221305646462 9.72844071215353E-06 -0.691898181152381 + 9.74536884182302E-06 3.3166195867365 9.73574717067484E-06 -177.837743719823 0.00299136355828882 0.022973347538606 0.997008635114296 -0.000231813542332281 + 9.74878974486707E-06 3.5801916914385 9.73780986910935E-06 -177.62607377317 + 9.73574717071652E-06 -177.837743719844 9.74536884186083E-06 3.31661958672463 0.997008635114296 -0.000231813542332281 0.00299136355828889 0.0229733475392772 + 9.73780986918375E-06 -177.626073773176 9.74878974492754E-06 3.58019169143426 + 9.72844071218974E-06 -0.691898181149417 9.72862983347782E-06 179.221305646462 9.74878974486707E-06 3.5801916914385 9.73780986918375E-06 -177.626073773176 + 0.00300770657348168 0.0247251065966078 0.996992293403868 -0.000236435331571261 + 9.72862983353701E-06 179.221305646468 9.72844071215353E-06 -0.691898181152381 9.73780986910935E-06 -177.62607377317 9.74878974492754E-06 3.58019169143426 + 0.996992293403868 -0.000236435331571261 0.00300770657345326 0.0247251065963128 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.07945784384138E-07 0.00298168951448709 0.0277447116080407 0.997018310427367 -0.000264269175514366 9.75301212802931E-06 3.71892888515523 9.74096438708934E-06 -177.575057167367 + 9.73178217411347E-06 -0.77605908578721 9.7320201809557E-06 179.126589762813 + 0.997018310427367 -0.000264269175514366 0.00298168951446979 0.0277447116078883 9.74096438707268E-06 -177.575057167371 9.75301212801434E-06 3.71892888514236 + 9.73202018092175E-06 179.126589762819 9.73178217414523E-06 -0.776059085783401 + 9.75301212802931E-06 3.71892888515523 9.74096438707268E-06 -177.575057167371 0.00299136840082223 0.0257763840239946 0.997008630271622 -0.00026009876711683 + 9.75737082627971E-06 4.01418588002418 9.74363587626379E-06 -177.337801520449 + 9.74096438708934E-06 -177.575057167367 9.75301212801434E-06 3.71892888514236 0.997008630271622 -0.00026009876711683 0.00299136840084509 0.0257763840237376 + 9.74363587619344E-06 -177.337801520478 9.75737082627356E-06 4.01418587998256 + 9.73178217411347E-06 -0.77605908578721 9.73202018092175E-06 179.126589762819 9.75737082627971E-06 4.01418588002418 9.74363587619344E-06 -177.337801520478 + 0.00300771134810781 0.0277413615269067 0.996992288645046 -0.000265282876310639 + 9.7320201809557E-06 179.126589762813 9.73178217414523E-06 -0.776059085783401 9.74363587626379E-06 -177.337801520449 9.75737082627356E-06 4.01418587998256 + 0.996992288645046 -0.000265282876310639 0.00300771134810781 0.0277413615269067 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.94328234724281E-07 0.00298169609554825 0.0311301871563835 0.9970183038565 -0.00029651539925252 9.7626275889765E-06 4.16935126060776 9.74753014656788E-06 -177.280791044236 + 9.73598859705891E-06 -0.870381107261996 9.73628809845033E-06 179.020439556357 + 0.9970183038565 -0.00029651539925252 0.002981696095581 0.0311301871554309 9.74753014641675E-06 -177.280791044218 9.76262758883354E-06 4.16935126062182 + 9.73628809836998E-06 179.020439556356 9.735988597055E-06 -0.870381107258776 + 9.7626275889765E-06 4.16935126060776 9.74753014641675E-06 -177.280791044218 0.00299137449709757 0.0289214367892232 0.99700862417512 -0.000291835338864906 + 9.76816493786466E-06 4.49996347750905 9.75096732538309E-06 -177.014928755399 + 9.74753014656788E-06 -177.280791044236 9.76262758883354E-06 4.16935126062182 0.99700862417512 -0.000291835338864906 0.00299137449713232 0.0289214367886571 + 9.75096732523222E-06 -177.014928755394 9.76816493774202E-06 4.49996347756048 + 9.73598859705891E-06 -0.870381107261996 9.73628809836998E-06 179.020439556356 9.76816493786466E-06 4.49996347750905 9.75096732523222E-06 -177.014928755394 + 0.00300771735902021 0.0311257249446153 0.996992282654158 -0.000297650589931381 + 9.73628809845033E-06 179.020439556357 9.735988597055E-06 -0.870381107258776 9.75096732538309E-06 -177.014928755399 9.76816493774202E-06 4.49996347756048 + 0.996992282654158 -0.000297650589931381 0.00300771735897758 0.0311257249453208 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.91250938133746E-07 0.00298170438039875 0.0349287129159688 0.997018295584266 -0.000332696201069853 9.77472189523951E-06 4.67336012911045 9.75579227400407E-06 -176.951285404392 + 9.74128378749124E-06 -0.976059614254558 9.74166063006322E-06 178.901510330858 + 0.997018295584266 -0.000332696201069853 0.00298170438038954 0.0349287129156548 9.75579227402334E-06 -176.951285404416 9.77472189523784E-06 4.67336012905853 + 9.74166063006452E-06 178.901510330859 9.74128378750618E-06 -0.976059614245587 + 9.77472189523951E-06 4.67336012911045 9.75579227402334E-06 -176.951285404416 0.00299138217180878 0.0324502308307036 0.997008616500248 -0.000327444381838268 + 9.78173996777445E-06 5.04336709981231 9.76019223268785E-06 -176.653467700089 + 9.75579227400407E-06 -176.951285404392 9.77472189523784E-06 4.67336012905853 0.997008616500248 -0.000327444381838268 0.00299138217185518 0.0324502308303893 + 9.7601922327495E-06 -176.653467700103 9.78173996783039E-06 5.04336709976885 + 9.74128378749124E-06 -0.976059614254558 9.74166063006452E-06 178.901510330859 9.78173996777445E-06 5.04336709981231 9.7601922327495E-06 -176.653467700103 + 0.00300772492613402 0.0349231039048559 0.996992275112231 -0.000333967982239939 + 9.74166063006322E-06 178.901510330858 9.74128378750618E-06 -0.976059614245587 9.76019223268785E-06 -176.653467700089 9.78173996783039E-06 5.04336709976885 + 0.996992275112231 -0.000333967982239939 0.0030077249261056 0.0349231039057146 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1E-06 0.0029817148101507 0.0391906811991496 0.997018285170433 -0.000373291677198969 9.78993059871556E-06 5.2369370160129 9.76618786186002E-06 -176.582512108787 + 9.74794944886822E-06 -1.09441784436867 9.74842353720055E-06 178.768313758866 + 0.997018285170433 -0.000373291677198969 0.00298171481016061 0.0391906811988716 9.76618786176745E-06 -176.582512108742 9.78993059867247E-06 5.23693701601561 + 9.74842353720412E-06 178.768313758869 9.74794944890788E-06 -1.0944178443589 + 9.78993059871556E-06 5.2369370160129 9.76618786176745E-06 -176.582512108742 0.00299139183334356 0.0364095788128024 0.997008606838268 -0.000367398402148557 + 9.79880790004229E-06 5.65076135993056 9.77179805350589E-06 -176.249038862003 + 9.76618786186002E-06 -176.582512108787 9.78993059867247E-06 5.23693701601561 0.997008606838268 -0.000367398402148557 0.00299139183339467 0.0364095788116028 + 9.77179805343633E-06 -176.249038862005 9.79880790002328E-06 5.65076135994646 + 9.74794944886822E-06 -1.09441784436867 9.74842353720412E-06 178.768313758869 9.79880790004229E-06 5.65076135993056 9.77179805343633E-06 -176.249038862005 + 0.003007734452307 0.0391838862023586 0.996992265617697 -0.00037471697944852 + 9.74842353720055E-06 178.768313758866 9.74794944890788E-06 -1.0944178443589 9.77179805350589E-06 -176.249038862003 9.79880790002328E-06 5.65076135994646 + 0.996992265617697 -0.00037471697944852 0.00300773445229279 0.0391838862030724 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.12201845430196E-06 0.00298172794003049 0.0439726292737664 0.997018272060526 -0.000418840504784822 9.8090502134427E-06 5.86657055998819 9.77926595236509E-06 -176.170061410203 + 9.75634007105341E-06 -1.22691488070143 9.756936393196E-06 178.619208973898 + 0.997018272060526 -0.000418840504784822 0.00298172794004101 0.043972629275601 9.77926595238068E-06 -176.170061410231 9.80905021343144E-06 5.86657055997723 + 9.75693639318134E-06 178.619208973905 9.75634007104905E-06 -1.22691488069403 + 9.8090502134427E-06 5.86657055998819 9.77926595238068E-06 -176.170061410231 0.00299140399628621 0.040852002214435 0.997008594674968 -0.000412227562072381 + 9.82026044597185E-06 6.32902193486208 9.78639684002545E-06 -175.796861034364 + 9.77926595236509E-06 -176.170061410203 9.80905021343144E-06 5.86657055997723 0.997008594674968 -0.000412227562072381 0.00299140399625635 0.0408520022147296 + 9.78639684008736E-06 -175.79686103436 9.82026044609812E-06 6.32902193484253 + 9.75634007105341E-06 -1.22691488070143 9.75693639318134E-06 178.619208973905 9.82026044597185E-06 6.32902193486208 9.78639684008736E-06 -175.79686103436 + 0.00300774644465484 0.0439646073189449 0.996992253665068 -0.000420438316438469 + 9.756936393196E-06 178.619208973898 9.75634007104905E-06 -1.22691488069403 9.78639684002545E-06 -175.796861034364 9.82026044609812E-06 6.32902193484253 + 0.996992253665068 -0.000420438316438469 0.00300774644465484 0.0439646073178874 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.25892541179417E-06 0.00298174446897012 0.0493379869227792 0.997018255556785 -0.000469947086954705 9.8330778262894E-06 6.5692320696933 9.79571579909804E-06 -175.709138810605 + 9.76690175433926E-06 -1.37515223811657 9.76765165840029E-06 178.452395333305 + 0.997018255556785 -0.000469947086954705 0.00298174446897699 0.0493379869243363 9.79571579899968E-06 -175.709138810521 9.83307782623697E-06 6.56923206975751 + 9.76765165851851E-06 178.452395333328 9.76690175437269E-06 -1.3751522381233 + 9.8330778262894E-06 6.5692320696933 9.79571579899968E-06 -175.709138810521 0.00299141930788483 0.0458364254258073 0.997008579362945 -0.000462526710785566 + 9.84721295392312E-06 7.08549573556167 9.80475656606969E-06 -175.291754528311 + 9.79571579909804E-06 -175.709138810605 9.83307782623697E-06 6.56923206975751 0.997008579362945 -0.000462526710785566 0.00299141930790219 0.0458364254241511 + 9.8047565659626E-06 -175.291754528322 9.84721295371283E-06 7.08549573570104 + 9.76690175433926E-06 -1.37515223811657 9.76765165851851E-06 178.452395333328 9.84721295392312E-06 7.08549573556167 9.8047565659626E-06 -175.291754528322 + 0.00300776154153583 0.0493287014388607 0.996992238618147 -0.000471738717861427 + 9.76765165840029E-06 178.452395333305 9.76690175437269E-06 -1.3751522381233 9.80475656606969E-06 -175.291754528311 9.84721295371283E-06 7.08549573570104 + 0.996992238618147 -0.000471738717861427 0.00300776154153583 0.0493287014388607 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.41253754462275E-06 0.00298176527669877 0.0553579161878613 0.997018234780771 -0.000527289575958072 9.86325985167187E-06 7.35231622988449 9.81640207389008E-06 -175.194578375034 + 9.78019577308149E-06 -1.5408767074046 9.78113854819687E-06 178.265909384473 + 0.997018234780771 -0.000527289575958072 0.00298176527668767 0.0553579161875494 9.81640207402856E-06 -175.19457837508 9.86325985174569E-06 7.35231622985704 + 9.78113854813673E-06 178.265909384462 9.78019577301094E-06 -1.54087670741627 + 9.86325985167187E-06 7.35231622988449 9.81640207402856E-06 -175.19457837508 0.00299143858319123 0.051428955362524 0.997008560087099 -0.000518963279926907 + 9.8810582608753E-06 7.92791918837829 9.82784005907892E-06 -174.72816475664 + 9.81640207389008E-06 -175.194578375034 9.86325985174569E-06 7.35231622985704 0.997008560087099 -0.000518963279926907 0.0029914385831851 0.0514289553631899 + 9.82784005902257E-06 -174.728164756636 9.88105826083218E-06 7.92791918841088 + 9.78019577308149E-06 -1.5408767074046 9.78113854813673E-06 178.265909384462 9.8810582608753E-06 7.92791918837829 9.82784005902257E-06 -174.728164756636 + 0.00300778054656251 0.0553473421525297 0.996992219676068 -0.000529298951324616 + 9.78113854819687E-06 178.265909384473 9.78019577301094E-06 -1.54087670741627 9.82784005907892E-06 -174.72816475664 9.88105826083218E-06 7.92791918841088 + 0.996992219676068 -0.000529298951324616 0.00300778054656251 0.0553473421530584 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.58489319246111E-06 0.00298179147056219 0.0621122510662723 0.99701820862686 -0.000591628869444183 9.90115164948256E-06 8.22353285884835 9.84240855553462E-06 -174.62088008063 + 9.79692822914173E-06 -1.7259782849553 9.79811306257217E-06 178.057627467612 + 0.99701820862686 -0.000591628869444183 0.00298179147057451 0.0621122510653591 9.84240855545897E-06 -174.620880080548 9.90115164942187E-06 8.22353285892882 + 9.79811306255146E-06 178.057627467627 9.79692822913946E-06 -1.72597828493651 + 9.90115164948256E-06 8.22353285884835 9.84240855545897E-06 -174.620880080548 0.00299146284784376 0.0577037540137245 0.997008535821639 -0.000582286136324837 + 9.9235322608434E-06 8.86427845739723 9.8568531889686E-06 -174.100215201843 + 9.84240855553462E-06 -174.62088008063 9.90115164942187E-06 8.22353285892882 0.997008535821639 -0.000582286136324837 0.00299146284783049 0.0577037540141591 + 9.85685318906221E-06 -174.100215201801 9.92353226089371E-06 8.86427845742748 + 9.79692822914173E-06 -1.7259782849553 9.79811306255146E-06 178.057627467627 9.9235322608434E-06 8.86427845739723 9.85685318906221E-06 -174.100215201801 + 0.00300780447096098 0.0621003864018349 0.99699219583071 -0.000593882864873394 + 9.79811306257217E-06 178.057627467612 9.79692822913946E-06 -1.72597828493651 9.8568531889686E-06 -174.100215201843 9.92353226089371E-06 8.86427845742748 + 0.99699219583071 -0.000593882864873394 0.00300780447094677 0.0621003864031857 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.77827941003892E-06 0.00298182444427586 0.0696905512343147 0.997018175703542 -0.000663818707397497 9.94868991990067E-06 9.19073119898509 9.87509217884518E-06 -173.982281882803 + 9.81798727318537E-06 -1.93248016235444 9.81947565345908E-06 177.825277335725 + 0.997018175703542 -0.000663818707397497 0.00298182444430223 0.069690551234837 9.87509217892084E-06 -173.982281882821 9.94868991997786E-06 9.19073119894706 + 9.81947565342719E-06 177.82527733574 9.81798727323326E-06 -1.93248016232463 + 9.94868991990067E-06 9.19073119898509 9.87509217892084E-06 -173.982281882821 0.0029914933930097 0.0647440171961892 0.997008505275552 -0.000653335519219174 + 9.97679311162188E-06 9.90259074002984 9.89330430563547E-06 -173.401802325911 + 9.87509217884518E-06 -173.982281882803 9.94868991997786E-06 9.19073119894706 0.997008505275552 -0.000653335519219174 0.00299149339299087 0.0647440171969544 + 9.89330430568776E-06 -173.401802325943 9.97679311166881E-06 9.90259073996226 + 9.81798727318537E-06 -1.93248016235444 9.81947565342719E-06 177.82527733574 9.97679311162188E-06 9.90259074002984 9.89330430568776E-06 -173.401802325943 + 0.00300783458768064 0.0696774333736119 0.996992165813361 -0.000666347531927554 + 9.81947565345908E-06 177.825277335725 9.81798727323326E-06 -1.93248016232463 9.89330430563547E-06 -173.401802325911 9.97679311166881E-06 9.90259073996226 + 0.996992165813361 -0.000666347531927554 0.00300783458766643 0.0696774333718262 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.99526231496888E-06 0.00298186595194868 0.0781932826080484 0.997018134259344 -0.000744816999956078 1.00082798281519E-05 10.2616343374743 9.91614960662073E-06 -173.272880190486 + 9.84448978348354E-06 -2.1625170965171 9.84635844135793E-06 177.566462954923 + 0.997018134259344 -0.000744816999956078 0.00298186595191294 0.0781932826114754 9.91614960681426E-06 -173.272880190545 1.00082798283676E-05 10.2616343373878 + 9.84635844163008E-06 177.56646295494 9.84448978364405E-06 -2.16251709652374 + 1.00082798281519E-05 10.2616343374743 9.91614960681426E-06 -173.272880190545 0.00299153184347993 0.0726430703954083 0.997008466823873 -0.000733054187303562 + 1.00435159282753E-05 11.0505821997732 9.93907716598037E-06 -172.626748168931 + 9.91614960662073E-06 -173.272880190486 1.00082798283676E-05 10.2616343373878 0.997008466823873 -0.000733054187303562 0.00299153184349763 0.0726430703947626 + 9.93907716583569E-06 -172.626748168914 1.00435159282482E-05 11.0505821997365 + 9.84448978348354E-06 -2.1625170965171 9.84635844163008E-06 177.56646295494 1.00435159282753E-05 11.0505821997732 9.93907716583569E-06 -172.626748168914 + 0.00300787249874749 0.0781790113866537 0.996992128027047 -0.000747654630569776 + 9.84635844135793E-06 177.566462954923 9.84448978364405E-06 -2.16251709652374 9.93907716598037E-06 -172.626748168931 1.00435159282482E-05 11.0505821997365 + 0.996992128027047 -0.000747654630569776 0.0030078724987617 0.0781790113857557 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.23872113856834E-06 0.00298191820084186 0.0877331391202791 0.997018082090425 -0.000835698538461356 1.00828987168836E-05 11.4434576897689 9.96769881798992E-06 -172.486816231753 + 9.87783988513265E-06 -2.41829727156247 9.88018435347584E-06 177.278708011697 + 0.997018082090425 -0.000835698538461356 0.0029819182008206 0.0877331391221062 9.96769881813805E-06 -172.486816231858 1.00828987170435E-05 11.4434576895922 + 9.88018435350339E-06 177.278708011712 9.87783988515739E-06 -2.41829727154807 + 1.00828987168836E-05 11.4434576897689 9.96769881813805E-06 -172.486816231858 0.00299158024408867 0.0815055958544311 0.997008418421902 -0.000822499925948121 + 1.01270045762586E-05 12.3152352762367 9.99651987530694E-06 -171.769030299375 + 9.96769881798992E-06 -172.486816231753 1.00828987170435E-05 11.4434576895922 0.997008418421902 -0.000822499925948121 0.002991580244109 0.0815055958539441 + 9.99651987512254E-06 -171.769030299211 1.01270045761901E-05 12.315235276258 + 9.87783988513265E-06 -2.41829727156247 9.88018435350339E-06 177.278708011712 1.01270045762586E-05 12.3152352762367 9.99651987512254E-06 -171.769030299211 + 0.0030079202201793 0.0877179101091414 0.996992080462202 -0.000838883219901488 + 9.88018435347584E-06 177.278708011697 9.87783988515739E-06 -2.41829727154807 9.99651987530694E-06 -171.769030299375 1.01270045761901E-05 12.315235276258 + 0.996992080462202 -0.000838883219901488 0.00300792022016509 0.0877179101095558 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.51188643150958E-06 0.002981983968678 0.0984365218310586 0.997018016423289 -0.000937669254660304 1.01762179314526E-05 12.742384164658 1.0032378472798E-05 -171.618549308676 + 9.91980223866487E-06 -2.70204126371422 9.92274112358511E-06 176.959525339461 + 0.997018016423289 -0.000937669254660304 0.0029819839686419 0.0984365218317118 1.00323784728523E-05 -171.618549308649 1.01762179315005E-05 12.7423841646979 + 9.92274112359981E-06 176.959525339444 9.9198022386647E-06 -2.70204126377394 + 1.01762179314526E-05 12.742384164658 1.00323784728523E-05 -171.618549308649 0.00299164116787743 0.0914490052480022 0.997008357496389 -0.000922859578489004 + 1.02313216866065E-05 13.7021783543692 1.00685525975136E-05 -170.823112368598 + 1.0032378472798E-05 -171.618549308676 1.01762179315005E-05 12.7423841646979 0.997008357496389 -0.000922859578489004 0.00299164116790078 0.0914490052461772 + 1.00685525973052E-05 -170.823112368508 1.02313216864398E-05 13.702178354488 + 9.91980223866487E-06 -2.70204126371422 9.92274112359981E-06 176.959525339444 1.02313216866065E-05 13.7021783543692 1.00685525973052E-05 -170.823112368508 + 0.00300798028879524 0.0984206731457458 0.996992020590152 -0.000941244074590159 + 9.92274112358511E-06 176.959525339461 9.9198022386647E-06 -2.70204126377394 1.00685525975136E-05 -170.823112368598 1.02313216864398E-05 13.702178354488 + 0.996992020590152 -0.000941244074590159 0.00300798028879524 0.0984206731436311 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.81838293126445E-06 0.00298206675020916 0.110445194220093 0.997017933768793 -0.00105208222346051 1.02927436600542E-05 14.1628712610956 1.011346805988E-05 -170.663240942419 + 9.97259371559048E-06 -3.01588988537169 9.97627374797188E-06 176.606521508716 + 0.997017933768793 -0.00105208222346051 0.00298206675022331 0.110445194219912 1.01134680598705E-05 -170.663240942533 1.02927436600415E-05 14.1628712610178 + 9.9762737478982E-06 176.606521508698 9.97259371554356E-06 -3.01588988534675 + 1.02927436600542E-05 14.1628712610956 1.01134680598705E-05 -170.663240942533 0.00299171785209471 0.102604975513939 0.997008280810103 -0.00103546479042329 + 1.03614371232539E-05 15.2148971070201 1.01587968921907E-05 -169.784400437282 + 1.011346805988E-05 -170.663240942419 1.02927436600415E-05 14.1628712610178 0.997008280810103 -0.00103546479042329 0.00299171785206587 0.102604975510741 + 1.0158796892314E-05 -169.784400437348 1.03614371233654E-05 15.2148971069971 + 9.97259371559048E-06 -3.01588988537169 9.9762737478982E-06 176.606521508698 1.03614371232539E-05 15.2148971070201 1.0158796892314E-05 -169.784400437348 + 0.00300805589622263 0.110429272064739 0.996991945228956 -0.00105609577609735 + 9.97627374797188E-06 176.606521508716 9.97259371554356E-06 -3.01588988534675 1.01587968921907E-05 -169.784400437282 1.03614371233654E-05 15.2148971069971 + 0.996991945228956 -0.00105609577609735 0.00300805589615158 0.110429272068405 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.16227766016838E-06 0.00298217094189322 0.123918130518286 0.997017829737395 -0.00118045561252587 1.04379767251315E-05 15.7067757999715 1.02150319426944E-05 -169.617274284366 + 1.00389978777085E-05 -3.36177084344408 1.00435997803553E-05 176.217547838673 + 0.997017829737395 -0.00118045561252587 0.00298217094186231 0.123918130521608 1.02150319427493E-05 -169.617274284409 1.04379767251994E-05 15.7067757999299 + 1.00435997803349E-05 176.217547838654 1.00389978776459E-05 -3.3617708434869 + 1.04379767251315E-05 15.7067757999715 1.02150319427493E-05 -169.617274284409 0.00299181436921628 0.115121163587752 0.997008184290663 -0.00116180967030479 + 1.05233939603956E-05 16.8537625257817 1.0271729492989E-05 -168.649848689949 + 1.02150319426944E-05 -169.617274284366 1.04379767251994E-05 15.7067757999299 0.997008184290663 -0.00116180967030479 0.00299181436925732 0.115121163584317 + 1.02717294929068E-05 -168.649848689914 1.05233939603134E-05 16.8537625258422 + 1.00389978777085E-05 -3.36177084344408 1.00435997803349E-05 176.217547838654 1.05233939603956E-05 16.8537625257817 1.02717294929068E-05 -168.649848689914 + 0.00300815105728789 0.123902981296654 0.996991850376104 -0.0011849627723112 + 1.00435997803553E-05 176.217547838673 1.00389978776459E-05 -3.3617708434869 1.0271729492989E-05 -168.649848689949 1.05233939603134E-05 16.8537625258422 + 0.996991850376104 -0.0011849627723112 0.0030081510573021 0.123902981292897 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.54813389233575E-06 0.00298230207303403 0.139033580330677 0.997017698808457 -0.00132449282505955 1.0618590099307E-05 17.3723031375733 1.03420904741237E-05 -168.478929434146 + 1.01225077504527E-05 -3.74121306918967 1.01282528838333E-05 175.790910273638 + 0.997017698808457 -0.00132449282505955 0.00298230207305284 0.139033580325504 1.03420904741053E-05 -168.478929434188 1.06185900992962E-05 17.3723031374907 + 1.01282528838363E-05 175.790910273642 1.01225077504319E-05 -3.74121306921489 + 1.0618590099307E-05 17.3723031375733 1.03420904741053E-05 -168.478929434188 0.00299193584122616 0.129163120944311 0.99700806281584 -0.00130357060436305 + 1.07244897343577E-05 18.6148987905904 1.0412863262891E-05 -167.418731201989 + 1.03420904741237E-05 -168.478929434146 1.06185900992962E-05 17.3723031374907 0.99700806281584 -0.00130357060436305 0.0029919358412522 0.129163120942298 + 1.04128632629196E-05 -167.418731202209 1.07244897343752E-05 18.6148987904946 + 1.01225077504527E-05 -3.74121306918967 1.01282528838363E-05 175.790910273642 1.07244897343577E-05 18.6148987905904 1.04128632629196E-05 -167.418731202209 + 0.00300827082165561 0.13902047748227 0.996991730996996 -0.00132955564843884 + 1.01282528838333E-05 175.790910273638 1.01225077504319E-05 -3.74121306921489 1.0412863262891E-05 -167.418731201989 1.07244897343752E-05 18.6148987904946 + 0.996991730996996 -0.00132955564843884 0.00300827082162719 0.139020477481468 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.98107170553497E-06 0.00298246709666718 0.155991369205539 0.997017534040106 -0.00148610509602124 1.08426217325446E-05 19.1528239834461 1.05008212539072E-05 -167.249223195581 + 1.02275035315153E-05 -4.15509706587256 1.02346611726679E-05 175.325650982158 + 0.997017534040106 -0.00148610509602124 0.00298246709666769 0.155991369206662 1.05008212538939E-05 -167.249223195604 1.08426217325574E-05 19.152823983345 + 1.02346611726374E-05 175.325650982091 1.0227503531562E-05 -4.15509706591758 + 1.08426217325446E-05 19.1528239834461 1.05008212538939E-05 -167.249223195604 0.00299208870879771 0.144916426786751 0.997007909945321 -0.0014626284855312 + 1.09734696385121E-05 20.488958596996 1.05889578003859E-05 -166.093578659688 + 1.05008212539072E-05 -167.249223195581 1.08426217325574E-05 19.152823983345 0.997007909945321 -0.0014626284855312 0.00299208870880426 0.144916426785864 + 1.05889578003799E-05 -166.09357865976 1.09734696384673E-05 20.4889585970172 + 1.02275035315153E-05 -4.15509706587256 1.02346611726374E-05 175.325650982091 1.09734696385121E-05 20.488958596996 1.05889578003799E-05 -166.09357865976 + 0.00300842153862464 0.155982187885018 0.996991580761063 -0.0014917938800054 + 1.02346611726679E-05 175.325650982158 1.0227503531562E-05 -4.15509706591758 1.05889578003859E-05 -166.093578659688 1.09734696384673E-05 20.4889585970172 + 0.996991580761063 -0.0014917938800054 0.00300842153862464 0.155982187880789 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.46683592150963E-06 0.00298267475294612 0.17501545958659 0.997017326706465 -0.00166743684490276 1.11196797874813E-05 21.0356528577734 1.06987936727396E-05 -165.932898703346 + 1.0359473309882E-05 -4.60333156354295 1.03683682356769E-05 174.821912162482 + 0.997017326706465 -0.00166743684490276 0.00298267475298419 0.175015459581191 1.06987936727705E-05 -165.932898703367 1.11196797875269E-05 21.0356528575733 + 1.03683682355728E-05 174.82191216243 1.03594733098602E-05 -4.60333156352162 + 1.11196797874813E-05 21.0356528577734 1.06987936727705E-05 -165.932898703367 0.00299228106770858 0.162589060454444 0.997007717583276 -0.00164109364684106 + 1.12807283234584E-05 22.4599308313346 1.08082621921733E-05 -164.681248501485 + 1.06987936727396E-05 -165.932898703346 1.11196797875269E-05 21.0356528575733 0.997007717583276 -0.00164109364684106 0.00299228106771556 0.162589060452675 + 1.08082621920979E-05 -164.681248501501 1.12807283234042E-05 22.459930831274 + 1.0359473309882E-05 -4.60333156354295 1.03683682355728E-05 174.82191216243 1.12807283234584E-05 22.4599308313346 1.08082621920979E-05 -164.681248501501 + 0.00300861118898589 0.175012913453742 0.996991391709838 -0.00167383137199661 + 1.03683682356769E-05 174.821912162482 1.03594733098602E-05 -4.60333156352162 1.08082621921733E-05 -164.681248501485 1.12807283234042E-05 22.459930831274 + 0.996991391709838 -0.00167383137199661 0.00300861118898589 0.175012913451628 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.01187233627273E-06 0.00298293602433931 0.196356792583253 0.997017065843082 -0.00187089411349499 1.14611584004042E-05 23.0009439133237 1.09452403183395E-05 -164.53951194087 + 1.05252866517427E-05 -5.08445310016377 1.05363064490371E-05 174.281385211137 + 0.997017065843082 -0.00187089411349499 0.0029829360243117 0.196356792588322 1.09452403184233E-05 -164.539511941009 1.14611584004628E-05 23.0009439132736 + 1.0536306449217E-05 174.281385211194 1.05252866518409E-05 -5.08445310015419 + 1.14611584004042E-05 23.0009439133237 1.09452403184233E-05 -164.539511941009 0.00299252309081729 0.182414034718263 0.997007475557363 -0.00184133383114613 + 1.16585191017524E-05 24.5041673588688 1.10807930726112E-05 -163.194050387499 + 1.09452403183395E-05 -164.53951194087 1.14611584004628E-05 23.0009439132736 0.997007475557363 -0.00184133383114613 0.00299252309081279 0.182414034720884 + 1.10807930726617E-05 -163.194050387519 1.1658519101819E-05 24.5041673587263 + 1.05252866517427E-05 -5.08445310016377 1.0536306449217E-05 174.281385211194 1.16585191017524E-05 24.5041673588688 1.10807930726617E-05 -163.194050387519 + 0.00300884980064547 0.196364752406624 0.9969911538427 -0.00187808512262033 + 1.05363064490371E-05 174.281385211137 1.05252866518409E-05 -5.08445310015419 1.10807930726112E-05 -163.194050387499 1.1658519101819E-05 24.5041673587263 + 0.9969911538427 -0.00187808512262033 0.0030088498006881 0.196364752393271 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.62341325190349E-06 0.00298326470402171 0.220296434702771 0.997016737679991 -0.00209917646978223 1.18804659347301E-05 25.0209179528283 1.12513703158637E-05 -163.084508482333 + 1.07335329631421E-05 -5.59515735256695 1.07471341652952E-05 173.707834410567 + 0.997016737679991 -0.00209917646978223 0.00298326470403467 0.220296434700463 1.12513703158055E-05 -163.084508482137 1.18804659347654E-05 25.0209179528343 + 1.07471341652198E-05 173.707834410522 1.07335329631427E-05 -5.59515735256186 + 1.18804659347301E-05 25.0209179528283 1.12513703158055E-05 -163.084508482137 0.00299282755419842 0.204652309818629 0.997007171092 -0.00206600556176956 + 1.21211749367558E-05 26.5898625956161 1.14186533381408E-05 -161.650789170977 + 1.12513703158637E-05 -163.084508482333 1.18804659347654E-05 25.0209179528343 0.997007171092 -0.00206600556176956 0.00299282755420519 0.204652309821952 + 1.14186533381198E-05 -161.650789171031 1.21211749367414E-05 26.5898625956363 + 1.07335329631421E-05 -5.59515735256695 1.07471341652198E-05 173.707834410522 1.21211749367558E-05 26.5898625956161 1.14186533381198E-05 -161.650789171031 + 0.00300914996710403 0.220320348833365 0.99699085459879 -0.00210726738682074 + 1.07471341652952E-05 173.707834410567 1.07335329631427E-05 -5.59515735256186 1.14186533381408E-05 -161.650789170977 1.21211749367414E-05 26.5898625956363 + 0.99699085459879 -0.00210726738682074 0.00300914996708982 0.220320348840748 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.30957344480193E-06 0.00298367810490156 0.247149045447436 0.997016324934191 -0.00235531278725981 1.23932755587116E-05 27.0596658634202 1.16307331901148E-05 -161.59012034382 + 1.09949390908104E-05 -6.12979199837806 1.10116508535075E-05 173.107660566159 + 0.997016324934191 -0.00235531278725981 0.00298367810487882 0.247149045452105 1.16307331902025E-05 -161.590120343894 1.23932755587893E-05 27.059665863224 + 1.10116508536093E-05 173.107660566149 1.0994939090881E-05 -6.12979199842384 + 1.23932755587116E-05 27.0596658634202 1.16307331902025E-05 -161.590120343894 0.00299321049359534 0.229596005092421 0.997006788152945 -0.00231808932291399 + 1.26853555688082E-05 28.67722616022 1.18364015696204E-05 -160.07752353314 + 1.16307331901148E-05 -161.59012034382 1.23932755587893E-05 27.059665863224 0.997006788152945 -0.00231808932291399 0.0029932104935904 0.22959600509516 + 1.18364015696066E-05 -160.077523533167 1.26853555687929E-05 28.6772261602958 + 1.09949390908104E-05 -6.12979199837806 1.10116508536093E-05 173.107660566149 1.26853555688082E-05 28.67722616022 1.18364015696066E-05 -160.077523533167 + 0.003009527494252 0.24719648701185 0.996990478211448 -0.00236442175875361 + 1.10116508535075E-05 173.107660566159 1.0994939090881E-05 -6.12979199842384 1.18364015696204E-05 -160.07752353314 1.26853555687929E-05 28.6772261602958 + 0.996990478211448 -0.00236442175875361 0.003009527494252 0.247196487009737 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.07945784384138E-06 0.0029841979400532 0.277266681006694 0.997015805931042 -0.00264270137021658 1.30178204345103E-05 29.0737520682239 1.20996483712161E-05 -160.085853587371 + 1.13228838367619E-05 -6.67987184107576 1.13433074936393E-05 172.490435424254 + 0.997015805931042 -0.00264270137021658 0.00298419794005696 0.277266680998358 1.20996483711659E-05 -160.0858535876 1.3017820434382E-05 29.0737520684102 + 1.13433074936008E-05 172.490435424275 1.13228838367172E-05 -6.67987184102507 + 1.30178204345103E-05 29.0737520682239 1.20996483711659E-05 -160.0858535876 0.00299369201988522 0.257571922368635 0.997006306631366 -0.00260092900824021 + 1.33703496454847E-05 30.719530097686 1.23514906623855E-05 -158.507790909396 + 1.20996483712161E-05 -160.085853587371 1.3017820434382E-05 29.0737520684102 0.997006306631366 -0.00260092900824021 0.00299369201988834 0.257571922364904 + 1.23514906623828E-05 -158.507790909416 1.33703496454242E-05 30.7195300978656 + 1.13228838367619E-05 -6.67987184107576 1.13433074936008E-05 172.490435424275 1.33703496454847E-05 30.719530097686 1.23514906623828E-05 -158.507790909416 + 0.00301000220374831 0.277348042176334 0.996990004905114 -0.00265296362647054 + 1.13433074936393E-05 172.490435424254 1.13228838367172E-05 -6.67987184102507 1.23514906623855E-05 -158.507790909396 1.33703496454242E-05 30.7195300978656 + 0.996990004905114 -0.00265296362647054 0.00301000220377673 0.277348042169488 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.94328234724281E-06 0.00298485141488646 0.31104293541665 0.997015153515367 -0.00296515493609443 1.37752722336778E-05 31.0137479902014 1.26777259886128E-05 -158.608307521927 + 1.17340308316242E-05 -7.23371483593861 1.17588334109849E-05 171.869295802557 + 0.997015153515367 -0.00296515493609443 0.00298485141490684 0.31104293540434 1.26777259885108E-05 -158.608307522182 1.37752722335916E-05 31.0137479900141 + 1.17588334108877E-05 171.869295802669 1.1734030831578E-05 -7.23371483587436 + 1.37752722336778E-05 31.0137479902014 1.26777259885108E-05 -158.608307522182 0.00299429732962287 0.288945387551125 0.997005701334376 -0.00291827614826667 + 1.41984782429713E-05 32.6650816336825 1.29848069752421E-05 -156.982045692331 + 1.26777259886128E-05 -158.608307521927 1.37752722335916E-05 31.0137479900141 0.997005701334376 -0.00291827614826667 0.00299429732962931 0.288945387544768 + 1.29848069751186E-05 -156.982045692098 1.41984782428925E-05 32.6650816338743 + 1.17340308316242E-05 -7.23371483593861 1.17588334108877E-05 171.869295802669 1.41984782429713E-05 32.6650816336825 1.29848069751186E-05 -156.982045692098 + 0.00301059892918442 0.31117228577526 0.99698940990095 -0.00297672549717142 + 1.17588334109849E-05 171.869295802557 1.1734030831578E-05 -7.23371483587436 1.29848069752421E-05 -156.982045692331 1.41984782428925E-05 32.6650816338743 + 0.99698940990095 -0.00297672549717142 0.00301059892922705 0.311172285775079 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.91250938133746E-06 0.00298567257305955 0.348917407206405 0.997014333708945 -0.00332695102594061 1.46902597007462E-05 32.8266677308775 1.33885190254945E-05 -157.200093814421 + 1.22491059516164E-05 -7.776336123276 1.22790058010507E-05 171.261044907026 + 0.997014333708945 -0.00332695102594061 0.0029856725730133 0.348917407220946 1.33885190256649E-05 -157.200093814441 1.46902597009589E-05 32.8266677307963 + 1.2279005801223E-05 171.261044906984 1.22491059517239E-05 -7.77633612338956 + 1.46902597007462E-05 32.8266677308775 1.33885190256649E-05 -157.200093814441 0.0029950579513048 0.324124403355889 0.997004940739665 -0.00327433947863696 + 1.51956637117043E-05 34.459995523285 1.37613577418861E-05 -155.546122553364 + 1.33885190254945E-05 -157.200093814421 1.46902597009589E-05 32.8266677307963 0.997004940739665 -0.00327433947863696 0.0029950579512722 0.324124403359231 + 1.37613577419791E-05 -155.546122553483 1.51956637117302E-05 34.4599955231354 + 1.22491059516164E-05 -7.776336123276 1.2279005801223E-05 171.261044906984 1.51956637117043E-05 34.459995523285 1.37613577419791E-05 -155.546122553483 + 0.00301134874403756 0.349113518456237 0.996988662190385 -0.00334000772338304 + 1.22790058010507E-05 171.261044907026 1.22491059517239E-05 -7.77633612338956 1.37613577418861E-05 -155.546122553364 1.51956637117302E-05 34.4599955231354 + 0.996988662190385 -0.00334000772338304 0.00301134874400914 0.349113518459532 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1E-05 0.00298670394795243 0.391380453729768 0.997013304065087 -0.00373288846311065 1.57915999439574E-05 34.4590948261498 1.42603636014946E-05 -155.907730044598 + 1.28938504131511E-05 -8.28975809195744 1.29295936208501E-05 170.685787229694 + 0.997013304065087 -0.00373288846311065 0.00298670394794551 0.391380453738765 1.4260363601549E-05 -155.907730044749 1.57915999439795E-05 34.4590948261093 + 1.29295936208435E-05 170.685787229635 1.28938504131668E-05 -8.28975809204185 + 1.57915999439574E-05 34.4590948261498 1.4260363601549E-05 -155.907730044749 0.00299601327331435 0.363564092067433 0.99700398546913 -0.0036738404809941 + 1.63922416639594E-05 36.0514694413272 1.47111722560693E-05 -154.248681084096 + 1.42603636014946E-05 -155.907730044598 1.57915999439795E-05 34.4590948261093 0.99700398546913 -0.0036738404809941 0.00299601327335671 0.363564092067951 + 1.47111722560124E-05 -154.24868108446 1.63922416638589E-05 36.0514694412334 + 1.28938504131511E-05 -8.28975809195744 1.29295936208435E-05 170.685787229635 1.63922416639594E-05 36.0514694413272 1.47111722560124E-05 -154.24868108446 + 0.00301229046830854 0.391667972257571 0.996987723031157 -0.00374763519737809 + 1.29295936208501E-05 170.685787229694 1.28938504131668E-05 -8.28975809204185 1.47111722560693E-05 -154.248681084096 1.63922416638589E-05 36.0514694412334 + 0.996987723031157 -0.00374763519737809 0.00301229046830854 0.391667972253347 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.12201845430196E-05 0.00298799857241954 0.438978158572232 0.997012011665523 -0.00418835053544646 1.71133249321244E-05 35.8606432803835 1.53274791758321E-05 -154.778561845609 + 1.37001860859426E-05 -8.75387632310857 1.37425119303878E-05 170.16594531327 + 0.997012011665523 -0.00418835053544646 0.00298799857244444 0.438978158562743 1.53274791757196E-05 -154.778561845455 1.71133249320567E-05 35.8606432806448 + 1.37425119303337E-05 170.165945313279 1.37001860859252E-05 -8.75387632308657 + 1.71133249321244E-05 35.8606432803835 1.53274791757196E-05 -154.778561845455 0.00299721240332919 0.407771379606715 0.997002786431738 -0.00412207558384471 + 1.78241006761546E-05 37.391167024733 1.58704965334762E-05 -153.137786812489 + 1.53274791758321E-05 -154.778561845609 1.71133249320567E-05 35.8606432806448 0.997002786431738 -0.00412207558384471 0.00299721240336154 0.407771379594567 + 1.58704965334958E-05 -153.137786812519 1.78241006761324E-05 37.3911670246248 + 1.37001860859426E-05 -8.75387632310857 1.37425119303337E-05 170.165945313279 1.78241006761546E-05 37.391167024733 1.58704965334958E-05 -153.137786812519 + 0.00301347250366015 0.439388878596082 0.996986544118509 -0.00420502060981131 + 1.37425119303878E-05 170.16594531327 1.37001860859252E-05 -8.75387632308657 1.58704965334762E-05 -153.137786812489 1.78241006761324E-05 37.3911670246248 + 0.996986544118509 -0.00420502060981131 0.0030134725035749 0.439388878629623 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.25892541179417E-05 0.00298962240086903 0.492317385237079 0.997010390710016 -0.00469937562043469 1.86960861214039E-05 36.9873418911698 1.66314079873203E-05 -153.856983446104 + 1.47076297376175E-05 -9.14794359550663 1.47572269539602E-05 169.724597629995 + 0.997010390710016 -0.00469937562043469 0.00298962240086187 0.492317385237384 1.66314079873275E-05 -153.856983446134 1.86960861213487E-05 36.9873418911549 + 1.4757226953812E-05 169.724597629732 1.47076297375207E-05 -9.1479435957202 + 1.86960861214039E-05 36.9873418911698 1.66314079873275E-05 -153.856983446134 0.00299871640791654 0.457309838859643 0.997001282588245 -0.00462498578581735 + 1.95342319969582E-05 38.4383210190382 1.72833659695307E-05 -152.256986554715 + 1.66314079873203E-05 -153.856983446104 1.86960861213487E-05 36.9873418911549 0.997001282588245 -0.00462498578581735 0.00299871640792092 0.457309838863511 + 1.7283365969593E-05 -152.256986554969 1.95342319969411E-05 38.4383210190723 + 1.47076297376175E-05 -9.14794359550663 1.4757226953812E-05 169.724597629732 1.95342319969582E-05 38.4383210190382 1.7283365969593E-05 -152.256986554969 + 0.00301495504459448 0.492891543296324 0.996985065382644 -0.00471823489987458 + 1.47572269539602E-05 169.724597629995 1.47076297375207E-05 -9.1479435957202 1.72833659695307E-05 -152.256986554715 1.95342319969411E-05 38.4383210190723 + 0.996985065382644 -0.00471823489987458 0.00301495504460869 0.49289154329822 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.41253754462276E-05 0.0029916571879968 0.552070716995361 0.99700835965198 -0.00527273600823502 2.05890087887382E-05 37.8045841356447 1.8222866180111E-05 -153.180415169646 + 1.59649815534333E-05 -9.45259282276205 1.60224544659866E-05 169.383242207885 + 0.99700835965198 -0.00527273600823502 0.00299165718800312 0.552070716981556 1.82228661799541E-05 -153.180415170009 2.05890087885817E-05 37.804584135468 + 1.6022454465852E-05 169.383242207918 1.59649815534003E-05 -9.45259282267046 + 2.05890087887382E-05 37.8045841356447 1.82228661799541E-05 -153.180415170009 0.00300060097376803 0.512804564466381 0.996999398296511 -0.00518923452783374 + 2.15747585390217E-05 39.1622746321423 1.90036293819695E-05 -151.64137711565 + 1.8222866180111E-05 -153.180415169646 2.05890087885817E-05 37.804584135468 0.996999398296511 -0.00518923452783374 0.00300060097380808 0.512804564446001 + 1.90036293817467E-05 -151.641377115745 2.15747585388613E-05 39.1622746322903 + 1.59649815534333E-05 -9.45259282276205 1.6022454465852E-05 169.383242207918 2.15747585390217E-05 39.1622746321423 1.90036293817467E-05 -151.641377115745 + 0.00301681271057704 0.552858206832141 0.996983212374082 -0.00529408556767604 + 1.60224544659866E-05 169.383242207885 1.59649815534003E-05 -9.45259282267046 1.90036293819695E-05 -151.64137711565 2.15747585388613E-05 39.1622746322903 + 0.996983212374082 -0.00529408556767604 0.00301681271059125 0.55285820682532 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.58489319246111E-05 0.00299420384782907 0.618980986390621 0.99700581786146 -0.00591602569562185 2.28520418327697E-05 38.2894125309178 2.01640512068427E-05 -152.775597563801 + 1.75323259479195E-05 -9.65211777888115 1.75981485062063E-05 169.159268738996 + 0.99700581786146 -0.00591602569562185 0.00299420384780061 0.618980986418012 2.01640512069304E-05 -152.775597563701 2.28520418327964E-05 38.2894125308681 + 1.75981485063848E-05 169.159268738984 1.7532325948112E-05 -9.65211777884546 + 2.28520418327697E-05 38.2894125309178 2.01640512069304E-05 -152.775597563701 0.00300295951031415 0.574946891748315 0.996997040218873 -0.00582229471270066 + 2.4009486067926E-05 39.5443263842613 2.10974652872583E-05 -151.314203951691 + 2.01640512068427E-05 -152.775597563801 2.28520418327964E-05 38.2894125308681 0.996997040218873 -0.00582229471270066 0.00300295951030331 0.574946891755406 + 2.10974652875799E-05 -151.314203951792 2.40094860681447E-05 39.5443263841596 + 1.75323259479195E-05 -9.65211777888115 1.75981485063848E-05 169.159268738984 2.4009486067926E-05 39.5443263842613 2.10974652875799E-05 -151.314203951792 + 0.00301913761813344 0.620042398898143 0.996980893217507 -0.00594020356630185 + 1.75981485062063E-05 169.159268738996 1.7532325948112E-05 -9.65211777884546 2.10974652872583E-05 -151.314203951691 2.40094860681447E-05 39.5443263841596 + 0.996980893217507 -0.00594020356630185 0.00301913761816186 0.620042398892306 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.77827941003892E-05 0.00299738626752167 0.693864984796077 0.997002641841646 -0.00663775792675125 2.55588030277587E-05 38.4320434032192 2.25313953696204E-05 -152.655745231216 + 1.94833012837558E-05 -9.73660248316364 1.95577861882333E-05 169.063622857326 + 0.997002641841646 -0.00663775792675125 0.00299738626747727 0.693864984817783 2.25313953698909E-05 -152.655745231483 2.5558803028044E-05 38.4320434028527 + 1.95577861883271E-05 169.063622857261 1.94833012838434E-05 -9.73660248330881 + 2.55588030277587E-05 38.4320434032192 2.25313953698909E-05 -152.655745231483 0.00300590667003758 0.644498704244462 0.996994093819112 -0.00653254584060744 + 2.69169730283683E-05 39.5788673682108 2.36463721413897E-05 -151.28445627478 + 2.25313953696204E-05 -152.655745231216 2.5558803028044E-05 38.4320434028527 0.996994093819112 -0.00653254584060744 0.0030059066700378 0.644498704240763 + 2.36463721411957E-05 -151.284456274875 2.69169730281504E-05 39.5788673682626 + 1.94833012837558E-05 -9.73660248316364 1.95577861883271E-05 169.063622857261 2.69169730283683E-05 39.5788673682108 2.36463721411957E-05 -151.284456274875 + 0.00302204287458591 0.695272427541279 0.996977995159545 -0.00666513956634615 + 1.95577861882333E-05 169.063622857326 1.94833012838434E-05 -9.73660248330881 2.36463721413897E-05 -151.28445627478 2.69169730281504E-05 39.5788673682626 + 0.996977995159545 -0.00666513956634615 0.0030220428745859 0.695272427524441 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.99526231496888E-05 0.00300135546642892 0.777615818722083 0.996998681112395 -0.00744747324669283 2.87998438566935E-05 38.2366289957295 2.54186679240157E-05 -152.818979891596 + 2.19075677390452E-05 -9.70341527973034 2.19908522032658E-05 169.099170184712 + 0.996998681112395 -0.00744747324669283 0.00300135546646976 0.777615818722801 2.54186679238812E-05 -152.818979891788 2.87998438566244E-05 38.2366289956241 + 2.19908522030043E-05 169.099170184898 2.19075677389441E-05 -9.70341527954023 + 2.87998438566935E-05 38.2366289957295 2.54186679238812E-05 -152.818979891788 0.00300958218199362 0.722296002247882 0.996990419554355 -0.00732938230337044 + 3.03940370830336E-05 39.2738564809653 2.67505224715102E-05 -151.545777690261 + 2.54186679240157E-05 -152.818979891596 2.87998438566244E-05 38.2366289956241 0.996990419554355 -0.00732938230337044 0.00300958218197705 0.722296002250375 + 2.67505224712959E-05 -151.545777690042 3.03940370827697E-05 39.2738564812596 + 2.19075677390452E-05 -9.70341527973034 2.19908522030043E-05 169.099170184898 3.03940370830336E-05 39.2738564809653 2.67505224712959E-05 -151.545777690042 + 0.00302566639186062 0.779453582797453 0.996974380811563 -0.00747847046971822 + 2.19908522032658E-05 169.099170184712 2.19075677389441E-05 -9.70341527954023 2.67505224715102E-05 -151.545777690261 3.03940370827697E-05 39.2738564812596 + 0.996974380811563 -0.00747847046971822 0.00302566639187483 0.779453582785384 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.23872113856834E-05 0.00300629384134 0.871203288655434 0.996993754024036 -0.00835585883308834 3.26861365054643E-05 37.7212794883276 2.89401996418127E-05 -153.248266993324 + 2.49132830978048E-05 -9.55770066669522 2.50053355656738E-05 169.260159607738 + 0.996993754024036 -0.00835585883308834 0.00300629384134958 0.871203288669247 2.89401996420765E-05 -153.248266993943 3.26861365055759E-05 37.7212794880719 + 2.50053355655486E-05 169.260159607756 2.49132830975557E-05 -9.55770066686121 + 3.26861365054643E-05 37.7212794883276 2.89401996420765E-05 -153.248266993943 0.00301415475720587 0.809251350297913 0.996985849010799 -0.00822333396897581 + 3.45594888791618E-05 38.6506676625806 3.05322369933504E-05 -152.076826031757 + 2.89401996418127E-05 -153.248266993324 3.26861365055759E-05 37.7212794880719 0.996985849010799 -0.00822333396897581 0.00301415475720585 0.809251350311141 + 3.05322369934073E-05 -152.07682603168 3.45594888791408E-05 38.6506676625209 + 2.49132830978048E-05 -9.55770066669522 2.50053355655486E-05 169.260159607756 3.45594888791618E-05 38.6506676625806 3.05322369934073E-05 -152.07682603168 + 0.00303017478704216 0.873568599289409 0.996969884326176 -0.00839091715311169 + 2.50053355656738E-05 169.260159607738 2.49132830975557E-05 -9.55770066686121 3.05322369933504E-05 -152.076826031757 3.45594888791408E-05 38.6506676625209 + 0.996969884326176 -0.00839091715311169 0.00303017478708479 0.873568599277118 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.51188643150958E-05 0.00301241899556387 0.97567166759007 0.996987644009191 -0.00937487991802973 3.73523975574282E-05 36.9173506260818 3.32338202132884E-05 -153.912852732123 + 2.8629236260548E-05 -9.31174716830672 2.87298849645359E-05 169.532915980589 + 0.996987644009191 -0.00937487991802973 0.00301241899557774 0.975671667603477 3.32338202132707E-05 -153.912852732313 3.73523975572892E-05 36.9173506260459 + 2.87298849645874E-05 169.532915980586 2.86292362605287E-05 -9.31174716841474 + 3.73523975574282E-05 36.9173506260818 3.32338202132707E-05 -153.912852732313 0.00301982559726858 0.906354825833322 0.996980181458416 -0.00922620030954348 + 3.95576848311115E-05 37.7433007417161 3.51391428312255E-05 -152.84301826544 + 3.32338202132884E-05 -153.912852732123 3.73523975572892E-05 36.9173506260459 0.996980181458416 -0.00922620030954348 0.00301982559732386 0.906354825811579 + 3.5139142830828E-05 -152.843018265566 3.95576848305317E-05 37.7433007417569 + 2.8629236260548E-05 -9.31174716830672 2.87298849645874E-05 169.532915980586 3.95576848311115E-05 37.7433007417161 3.5139142830828E-05 -152.843018265566 + 0.00303576691086918 0.978675964517378 0.996964307964837 -0.00941447456496813 + 2.87298849645359E-05 169.532915980589 2.86292362605287E-05 -9.31174716841474 3.51391428312255E-05 -152.84301826544 3.95576848305317E-05 37.7433007417569 + 0.996964307964837 -0.00941447456496813 0.00303576691081236 0.978675964552463 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.81838293126445E-05 0.00301998626699278 1.0921344681744 0.996980097160871 -0.0105179242851085 4.29595830295809E-05 35.8679922174422 3.84628379072089E-05 -154.770970307156 + 3.32060418650416E-05 -8.98340642571102 3.33150227361214E-05 169.897572542609 + 0.996980097160871 -0.0105179242851085 0.00301998626693918 1.09213446821373 3.84628379077489E-05 -154.770970306941 4.2959583030071E-05 35.8679922174873 + 3.33150227364623E-05 169.897572542609 3.32060418653613E-05 -8.98340642572609 + 4.29595830295809E-05 35.8679922174422 3.84628379077489E-05 -154.770970306941 0.00302683068109196 1.01467322491051 0.996973181657751 -0.0103511995084321 + 4.55611950766768E-05 36.5969268778664 4.07463043744536E-05 -153.799402154267 + 3.84628379072089E-05 -154.770970307156 4.2959583030071E-05 35.8679922174873 0.996973181657751 -0.0103511995084321 0.00302683068104799 1.01467322493353 + 4.07463043752673E-05 -153.799402154273 4.55611950771388E-05 36.596926877691 + 3.32060418650416E-05 -8.98340642571102 3.33150227364623E-05 169.897572542609 4.55611950766768E-05 36.5969268778664 4.07463043752673E-05 -153.799402154273 + 0.00304267619936909 1.09590586429808 0.996957419861783 -0.0105625555237136 + 3.33150227361214E-05 169.897572542609 3.32060418653613E-05 -8.98340642572609 4.07463043744536E-05 -153.799402154267 4.55611950771388E-05 36.596926877691 + 0.996957419861783 -0.0105625555237136 0.00304267619939747 1.0959058642544 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.16227766016838E-05 0.00302928849156494 1.22176638657227 0.996970822609847 -0.0117999611948266 4.96954886402461E-05 34.6259984380719 4.48160223153285E-05 -155.773382200587 + 3.8815433274719E-05 -8.59396721878076 3.89324525163958E-05 170.330405760776 + 0.996970822609847 -0.0117999611948266 0.00302928849159235 1.22176638651296 4.48160223151003E-05 -155.773382200635 4.96954886397562E-05 34.6259984382626 + 3.8932452516464E-05 170.330405760844 3.88154332749576E-05 -8.59396721887515 + 4.96954886402461E-05 34.6259984380719 4.48160223151003E-05 -155.773382200635 0.00303544046783535 1.13534768242306 0.996964580296499 -0.0116131342899268 + 5.27714605595583E-05 35.2657841805258 4.75562188864269E-05 -154.894225478572 + 4.48160223153285E-05 -155.773382200587 4.96954886397562E-05 34.6259984382626 0.996964580296499 -0.0116131342899268 0.0030354404678289 1.13534768242785 + 4.75562188864195E-05 -154.894225478503 5.27714605597129E-05 35.2657841805552 + 3.8815433274719E-05 -8.59396721878076 3.8932452516464E-05 170.330405760844 5.27714605595583E-05 35.2657841805258 4.75562188864195E-05 -154.894225478503 + 0.00305117051943596 1.22645408430342 0.996948954318818 -0.0118501499637585 + 3.89324525163958E-05 170.330405760776 3.88154332749576E-05 -8.59396721887515 4.75562188864269E-05 -154.894225478572 5.27714605597129E-05 35.2657841805552 + 0.996948954318818 -0.0118501499637585 0.003051170519436 1.22645408433677 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.54813389233575E-05 0.00304065070486049 1.36579383797587 0.996959498003616 -0.0132377167719635 5.7771844601025E-05 33.2511353545779 5.25040529311799E-05 -156.867155791593 + 4.56461648416266E-05 -8.16596868549576 4.57709713039017E-05 170.806245225664 + 0.996959498003616 -0.0132377167719635 0.0030406507048694 1.36579383799148 5.25040529314567E-05 -156.867155791586 5.77718446017008E-05 33.2511353542997 + 4.57709713038816E-05 170.806245225521 4.56461648418612E-05 -8.16596868565093 + 5.7771844601025E-05 33.2511353545779 5.25040529314567E-05 -156.867155791586 0.0030459548763651 1.26959072424422 0.996954079207765 -0.0130285766864159 + 6.14157333860817E-05 33.8105579549102 5.57950065006197E-05 -156.072660553131 + 5.25040529311799E-05 -156.867155791593 5.77718446017008E-05 33.2511353542997 0.996954079207765 -0.0130285766864159 0.00304595487635162 1.26959072426186 + 5.57950065007472E-05 -156.072660553014 6.14157333863479E-05 33.8105579549844 + 4.56461648416266E-05 -8.16596868549576 4.57709713038816E-05 170.806245225521 6.14157333860817E-05 33.8105579549102 5.57950065007472E-05 -156.072660553014 + 0.0030615474197818 1.37157525036141 0.996938616724811 -0.013294002014831 + 4.57709713039017E-05 170.806245225664 4.56461648418612E-05 -8.16596868565093 5.57950065006197E-05 -156.072660553131 6.14157333863479E-05 33.8105579549844 + 0.996938616724811 -0.013294002014831 0.00306154741979598 1.37157525033843 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.98107170553497E-05 0.0030544163550062 1.52548766628761 0.996945783529473 -0.0148498689722928 6.74156459748362E-05 31.8073657389117 6.17502932513845E-05 -157.998853529593 + 5.3894319346683E-05 -7.72136523389072 5.40267836851604E-05 171.300504724811 + 0.996945783529473 -0.0148498689722928 0.00305441635504533 1.52548766625957 6.17502932508282E-05 -157.998853529686 6.74156459741147E-05 31.807365738998 + 5.40267836851699E-05 171.300504724812 5.38943193465554E-05 -7.72136523389911 + 6.74156459748362E-05 31.8073657389117 6.17502932508282E-05 -157.998853529686 0.00305869034811279 1.4186853939517 0.996941364582374 -0.0146160747036613 + 7.1737836636326E-05 32.295539933604 6.57023598903834E-05 -157.280122968118 + 6.17502932513845E-05 -157.998853529593 6.74156459741147E-05 31.807365738998 0.996941364582374 -0.0146160747036613 0.00305869034811061 1.41868539393366 + 6.57023598905144E-05 -157.280122968216 7.17378366364344E-05 32.2955399334829 + 5.3894319346683E-05 -7.72136523389072 5.40267836851699E-05 171.300504724812 7.1737836636326E-05 32.295539933604 6.57023598905144E-05 -157.280122968216 + 0.00307412168047201 1.53257865272439 0.996926096229011 -0.0149128082493464 + 5.40267836851604E-05 171.300504724811 5.38943193465554E-05 -7.72136523389911 6.57023598903834E-05 -157.280122968118 7.17378366364344E-05 32.2955399334829 + 0.996926096229011 -0.0149128082493464 0.00307412168045773 1.53257865268183 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.46683592150963E-05 0.00307092021492326 1.70216503427622 0.996929349315671 -0.016657266762524 7.88518893902668E-05 30.3605843578267 7.2772933928914E-05 -159.116153903421 + 6.37449344040943E-05 -7.28029186524109 6.38851354382176E-05 171.790555276585 + 0.996929349315671 -0.016657266762524 0.00307092021489385 1.70216503427792 7.2772933929448E-05 -159.116153903368 7.88518893905444E-05 30.3605843580181 + 6.38851354385417E-05 171.790555276678 6.37449344044844E-05 -7.28029186522351 + 7.88518893902668E-05 30.3605843578267 7.2772933929448E-05 -159.116153903368 0.00307395450287404 1.583991839791 0.996926132678668 -0.0163963849072571 + 8.39793714472489E-05 30.785999750913 7.75118710376366E-05 -158.464710273627 + 7.2772933928914E-05 -159.116153903421 7.88518893905444E-05 30.3605843580181 0.996926132678668 -0.0163963849072571 0.00307395450288704 1.58399183981447 + 7.75118710372782E-05 -158.46471027365 8.39793714466868E-05 30.7859997509538 + 6.37449344040943E-05 -7.28029186524109 6.38851354385417E-05 171.790555276678 8.39793714472489E-05 30.785999750913 7.75118710372782E-05 -158.46471027365 + 0.00308920079093512 1.71083289092515 0.996911090568712 -0.0167274417394318 + 6.38851354382176E-05 171.790555276585 6.37449344044844E-05 -7.28029186522351 7.75118710376366E-05 -158.464710273627 8.39793714466868E-05 30.7859997509538 + 0.996911090568712 -0.0167274417394318 0.00308920079093507 1.71083289089222 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.01187233627273E-05 0.00309044176927003 1.89721240979983 0.996909922475902 -0.0186831801764214 9.22738531644982E-05 28.9765794975072 8.57534891514328E-05 -160.168820647736 + 7.53409630298156E-05 -6.86050386001322 7.54892858852948E-05 172.256350258495 + 0.996909922475902 -0.0186831801764214 0.00309044176928708 1.89721240980725 8.57534891511958E-05 -160.168820647549 9.22738531642022E-05 28.9765794977092 + 7.54892858852019E-05 172.256350258437 7.53409630297948E-05 -6.86050386003622 + 9.22738531644982E-05 28.9765794975072 8.57534891511958E-05 -160.168820647549 0.00309200257939571 1.76697093365992 0.99690813385773 -0.0183927363920768 + 9.83471060811276E-05 29.3462614884156 9.14173867156145E-05 -159.578449131549 + 8.57534891514328E-05 -160.168820647736 9.22738531642022E-05 28.9765794977092 0.99690813385773 -0.0183927363920768 0.00309200257938939 1.76697093361442 + 9.14173867168922E-05 -159.578449131567 9.83471060821433E-05 29.3462614883937 + 7.53409630298156E-05 -6.86050386001322 7.54892858852019E-05 172.256350258437 9.83471060811276E-05 29.3462614884156 9.14173867168922E-05 -159.578449131567 + 0.00310704270694931 1.90778993322404 0.996893348749869 -0.0187612082635102 + 7.54892858852948E-05 172.256350258495 7.53409630297948E-05 -6.86050386003622 9.14173867156145E-05 -159.578449131549 9.83471060821433E-05 29.3462614883937 + 0.996893348749869 -0.0187612082635102 0.00310704270696354 1.90778993323169 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.62341325190349E-05 0.00311313208587883 2.11214778072956 0.996887360852926 -0.0209535904081949 0.000107794587003543 27.7185031401898 0.000100785689363195 -161.111960609685 + 8.87350970444915E-05 -6.47743864575097 8.88923516437257E-05 172.680351374898 + 0.996887360852926 -0.0209535904081949 0.00311313208585398 2.11214778077019 0.00010078568936448 -161.111960609764 0.0001077945870047 27.7185031399775 + 8.88923516450239E-05 172.680351374917 8.87350970451668E-05 -6.47743864575896 + 0.000107794587003543 27.7185031401898 0.00010078568936448 -161.111960609764 0.0031129691260201 1.96924013201778 0.996887241491452 -0.0206311333536116 + 0.000114961883062462 28.0389373613838 0.000107520545639268 -160.577217112827 + 0.000100785689363195 -161.111960609685 0.0001077945870047 27.7185031399775 0.996887241491452 -0.0206311333536116 0.00311296912601723 1.96924013199475 + 0.000107520545639232 -160.577217112889 0.00011496188306256 28.0389373612303 + 8.87350970444915E-05 -6.47743864575097 8.88923516450239E-05 172.680351374917 0.000114961883062462 28.0389373613838 0.000107520545639232 -160.577217112889 + 0.00312778953281075 2.12504487060933 0.996872737997827 -0.0210401431139265 + 8.88923516437257E-05 172.680351374898 8.87350970451668E-05 -6.47743864575896 0.000107520545639268 -160.577217112827 0.00011496188306256 28.0389373612303 + 0.996872737997827 -0.0210401431139265 0.00312778953279668 2.12504487068402 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.30957344480193E-05 0.00313890855158706 2.34874656114708 0.996861759175964 -0.0234975320537809 0.000125376990505249 26.6475018201007 0.00011780522368051 -161.905628933136 + 0.00010382087013461 -6.14479155169348 0.000103988441549795 173.046866764704 + 0.996861759175964 -0.0234975320537809 0.00313890855158677 2.34874656113863 0.000117805223680627 -161.905628933064 0.000125376990505703 26.6475018201331 + 0.000103988441550488 173.046866764754 0.000103820870135583 -6.14479155153783 + 0.000125376990505249 26.6475018201007 0.000117805223680627 -161.905628933064 0.00313676968935519 2.19268292186163 0.996863551020418 -0.0231407053103952 + 0.000133785566326824 26.9256530473809 0.000125755713389143 -161.419336932557 + 0.00011780522368051 -161.905628933136 0.000125376990505703 26.6475018201331 0.996863551020418 -0.0231407053103952 0.00313676968933627 2.19268292194494 + 0.000125755713388717 -161.419336932572 0.000133785566326788 26.9256530473913 + 0.00010382087013461 -6.14479155169348 0.000103988441550488 173.046866764754 0.000133785566326824 26.9256530473809 0.000125755713388717 -161.419336932572 + 0.00315137201718134 2.36445360853626 0.996849340171547 -0.0235933592569001 + 0.000103988441549795 173.046866764704 0.000103820870135583 -6.14479155153783 0.000125755713389143 -161.419336932557 0.000133785566326788 26.9256530473913 + 0.996849340171547 -0.0235933592569001 0.00315137201716725 2.36445360859532 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.07945784384137E-05 0.00316731829026717 2.60925856438489 0.996833586944387 -0.0263475022994818 0.000144747000793774 25.8266906179382 0.000136501224027055 -162.509108100558 + 0.000120243593129207 -5.87550135479874 0.000120423635560049 173.340907899644 + 0.996833586944387 -0.0263475022994818 0.0031673182902817 2.60925856439171 0.000136501224025823 -162.50910810051 0.000144747000792929 25.8266906179808 + 0.00012042363555934 173.340907899629 0.000120243593128526 -5.87550135466408 + 0.000144747000793774 25.8266906179382 0.000136501224025823 -162.50910810051 0.00316297325649614 2.43963668005922 0.996837508448779 -0.0259541149676041 + 0.000154527443593565 26.0694404796666 0.000145793281288537 -162.062902180299 + 0.000136501224027055 -162.509108100558 0.000144747000792929 25.8266906179808 0.996837508448779 -0.0259541149676041 0.00316297325649646 2.43963668003162 + 0.000145793281287243 -162.06290218023 0.00015452744359204 26.0694404797914 + 0.000120243593129207 -5.87550135479874 0.00012042363555934 173.340907899629 0.000154527443593565 26.0694404796666 0.000145793281287243 -162.06290218023 + 0.00317738559295389 2.62833381175243 0.996823577013107 -0.0264534594401947 + 0.000120423635560049 173.340907899644 0.000120243593128526 -5.87550135466408 0.000145793281288537 -162.062902180299 0.00015452744359204 26.0694404797914 + 0.996823577013107 -0.0264534594401947 0.00317738559296788 2.62833381166068 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.94328234724282E-05 0.00319738751744474 2.89673539902111 0.996803840931345 -0.0295399534231717 0.000165300382871498 25.3252902402652 0.000156217820775307 -162.876534236666 + 0.000137302223255882 -5.68306915899716 0.00013749790468348 173.54663925304 + 0.996803840931345 -0.0295399534231717 0.00319738751742664 2.89673539908108 0.00015621782077711 -162.876534236796 0.000165300382872691 25.3252902400811 + 0.000137497904684903 173.546639252686 0.000137302223257976 -5.68306915927011 + 0.000165300382871498 25.3252902402652 0.00015621782077711 -162.876534236796 0.00319066157126914 2.71317773444194 0.996810052237542 -0.0291080329172547 + 0.000176543650785975 25.5387488607318 0.000166934304882066 -162.46192912724 + 0.000156217820775307 -162.876534236666 0.000165300382872691 25.3252902400811 0.996810052237542 -0.0291080329172547 0.00319066157125686 2.71317773442772 + 0.000166934304883459 -162.46192912726 0.000176543650786846 25.5387488606638 + 0.000137302223255882 -5.68306915899716 0.000137497904684903 173.546639252686 0.000176543650785975 25.5387488607318 0.000166934304883459 -162.46192912726 + 0.003204953632403 2.91976741063237 0.996796348680822 -0.0296570249598351 + 0.00013749790468348 173.54663925304 0.000137302223257976 -5.68306915927011 0.000166934304882066 -162.46192912724 0.000176543650786846 25.5387488606638 + 0.996796348680822 -0.0296570249598351 0.00320495363241729 2.91976741065114 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.91250938133746E-05 0.00322750731322668 3.21545430956971 0.996774161961561 -0.033115883681434 0.000186037610138788 25.2234089685549 0.000175881659391224 -162.952824761645 + 0.000153874565063369 -5.58312039343942 0.000154090356187704 173.64550642864 + 0.996774161961561 -0.033115883681434 0.00322750731322577 3.21545430961846 0.000175881659393849 -162.952824761852 0.000186037610140135 25.2234089684202 + 0.000154090356189878 173.645506428702 0.000153874565064225 -5.58312039349752 + 0.000186037610138788 25.2234089685549 0.000175881659393849 -162.952824761852 0.00321832247917137 3.01749360826847 0.996782721558196 -0.0326436847810007 + 0.000198767276594794 25.4125036378311 0.000188033541597799 -162.561626490778 + 0.000175881659391224 -162.952824761645 0.000186037610140135 25.2234089684202 0.996782721558196 -0.0326436847810007 0.0032183224791691 3.01749360829756 + 0.000188033541598167 -162.56162649083 0.000198767276595017 25.4125036377064 + 0.000153874565063369 -5.58312039343942 0.000154090356189878 173.645506428702 0.000198767276594794 25.4125036378311 0.000188033541598167 -162.56162649083 + 0.00323262379308803 3.24299222556225 0.9967691398089 -0.0332451905538768 + 0.000154090356187704 173.64550642864 0.000153874565064225 -5.58312039349752 0.000188033541597799 -162.561626490778 0.000198767276595017 25.4125036377064 + 0.9967691398089 -0.0332451905538768 0.00323262379305966 3.24299222559075 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0001 0.00325546141355835 3.57134216343247 0.996746810367405 -0.0371215351161876 0.000205599169444334 25.6160079970374 0.000194027726949757 -162.669484279951 + 0.0001684335089428 -5.59491216866813 0.000168675478283257 173.614359417296 + 0.996746810367405 -0.0371215351161876 0.00325546141356886 3.5713421633695 0.000194027726949724 -162.669484279926 0.00020559916944424 25.616007997043 + 0.000168675478283292 173.614359417301 0.000168433508941491 -5.59491216858946 + 0.000205599169444334 25.6160079970374 0.000194027726949724 -162.669484279926 0.00324387593122073 3.35825894648324 0.996757632363976 -0.0366074694745543 + 0.000219745654560306 25.784105737538 0.000207527445262542 -162.293961675495 + 0.000194027726949757 -162.669484279951 0.00020559916944424 25.616007997043 0.996757632363976 -0.0366074694745543 0.00324387593126178 3.35825894637203 + 0.000207527445260097 -162.293961675414 0.000219745654558349 25.7841057376143 + 0.0001684335089428 -5.59491216866813 0.000168675478283292 173.614359417301 0.000219745654560306 25.784105737538 0.000207527445260097 -162.293961675414 + 0.00325839343881055 3.60379345192946 0.996743997128431 -0.0372643071268504 + 0.000168675478283257 173.614359417296 0.000168433508941491 -5.59491216858946 0.000207527445262542 -162.293961675495 0.000219745654558349 25.7841057376143 + 0.996743997128431 -0.0372643071268504 0.00325839343878185 3.60379345186735 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000112201845430196 0.00327873838074741 3.96672674296334 0.996724317519578 -0.0415886464060162 0.000222515246342942 26.6112984379148 0.000209041614815165 -161.943822575932 + 0.00017926350004302 -5.74380427929854 0.0001795451375767 173.421034208921 + 0.996724317519578 -0.0415886464060162 0.0032787383807554 3.96672674291202 0.000209041614813997 -161.943822575992 0.000222515246343339 26.6112984377851 + 0.000179545137575993 173.421034209163 0.000179263500042739 -5.74380427910141 + 0.000222515246342942 26.6112984379148 0.000209041614813997 -161.943822575992 0.00326503456543622 3.73800889890509 0.996737217474099 -0.0410401471054426 + 0.000237926358023918 26.7697234265672 0.000223707759493572 -161.56692299056 + 0.000209041614815165 -161.943822575932 0.000222515246343339 26.6112984377851 0.996737217474099 -0.0410401471054426 0.00326503456545655 3.73800889889462 + 0.000223707759492706 -161.566922990509 0.000237926358021951 26.7697234267354 + 0.00017926350004302 -5.74380427929854 0.000179545137575993 173.421034209163 0.000237926358023918 26.7697234265672 0.000223707759492706 -161.566922990509 + 0.00327999221000329 4.00490198263106 0.996723210862443 -0.0417486944970084 + 0.0001795451375767 173.421034208921 0.000179263500042739 -5.74380427910141 0.000223707759493572 -161.56692299056 0.000237926358021951 26.7697234267354 + 0.996723210862443 -0.0417486944970084 0.00327999220998874 4.00490198255553 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000125892541179417 0.00329546106058324 4.41350411032135 0.99670866077849 -0.0465856342842265 0.000235771377824712 28.295272427288 0.00021972456245546 -160.698135302083 + 0.000185006079301611 -6.03975854406399 0.000185339879094394 173.050681579813 + 0.99670866077849 -0.0465856342842265 0.00329546106061315 4.41350411017412 0.000219724562456025 -160.698135302069 0.000235771377826166 28.2952724271214 + 0.000185339879094372 173.050681579932 0.000185006079301569 -6.03975854401082 + 0.000235771377824712 28.295272427288 0.000219724562456025 -160.698135302069 0.00327997391349814 4.16819246601642 0.996723261704166 -0.0460044054781135 + 0.000252212087603612 28.4451355113511 0.000235289042076561 -160.312883578 + 0.00021972456245546 -160.698135302083 0.000235771377826166 28.2952724271214 0.996723261704166 -0.0460044054781135 0.00327997391347187 4.16819246606487 + 0.000235289042078603 -160.312883578022 0.000252212087606207 28.4451355111439 + 0.000185006079301611 -6.03975854406399 0.000185339879094372 173.050681579932 0.000252212087603612 28.4451355113511 0.000235289042078603 -160.312883578022 + 0.00329573091112309 4.45727778776549 0.996708570945185 -0.0467645377236341 + 0.000185339879094394 173.050681579813 0.000185006079301569 -6.03975854401082 0.000235289042076561 -160.312883578 0.000252212087606207 28.4451355111439 + 0.996708570945185 -0.0467645377236341 0.00329573091112253 4.45727778764234 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000141253754462276 0.00330569324984107 4.91982960024724 0.996699877971683 -0.0521750296988862 0.00024567285952179 30.6728776752752 0.000226201079030451 -158.907191007066 + 0.000185526818785582 -6.47686587552791 0.000185937941769968 172.499325802006 + 0.996699877971683 -0.0521750296988862 0.00330568195438173 4.91812849919866 0.000226200764391561 -158.907117297525 0.000245661164661063 30.6613855325764 + 0.000185938525138596 172.499789644773 0.000185526533359229 -6.48648431933086 + 0.00024567285952179 30.6728776752752 0.000226200764391561 -158.907117297525 0.00328886478483318 4.65681746024679 0.996715799891704 -0.0515635431302372 + 0.000262927008409583 30.8101548645631 0.000242409760734087 -158.509104650654 + 0.000226201079030451 -158.907191007066 0.000245661164661063 30.6613855325764 0.996715799891704 -0.0515635431302372 0.00328861777398889 4.6555641765653 + 0.000242409060289699 -158.509182820775 0.000262918240713934 30.8038435077515 + 0.000185526818785582 -6.47686587552791 0.000185938525138596 172.499789644773 0.000262927008409583 30.8101548645631 0.000242409060289699 -158.509182820775 + 0.0033056851922787 4.9687936973388 0.996700102602665 -0.0523743425315148 + 0.000185937941769968 172.499325802006 0.000185526533359229 -6.48648431933086 0.000242409760734087 -158.509104650654 0.000262918240713934 30.8038435077515 + 0.996700102602665 -0.0523743425315148 0.00330567744841589 4.96720098405442 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000158489319246111 0.00331256110176818 5.48715425457147 0.996694937302036 -0.0584260257060056 0.000254386478278825 33.5240978959839 0.000230582450785077 -156.694783299543 + 0.000182645790473326 -7.00883616078954 0.000183144463865491 171.822964769713 + 0.996694937302036 -0.0584260257060056 0.00331254579889819 5.48527554465864 0.000230582055421913 -156.694695205175 0.000254372018573152 33.5117111164273 + 0.000183145149576426 171.823445386918 0.000182643563092303 -7.02036841994439 + 0.000254386478278825 33.5240978959839 0.000230582055421913 -156.694695205175 0.00329443726417498 5.20631406089063 0.996711999790875 -0.0577876678229208 + 0.000272386271959903 33.6462298366584 0.000247327319511663 -156.285079607502 + 0.000230582450785077 -156.694783299543 0.000254372018573152 33.5117111164273 0.996711999790875 -0.0577876678229208 0.00329408372207976 5.20521552984918 + 0.00024732645610877 -156.285157416327 0.000272376426638301 33.6399301027409 + 0.000182645790473326 -7.00883616078954 0.000183145149576426 171.823445386918 0.000272386271959903 33.6462298366584 0.00024732645610877 -156.285157416327 + 0.00331272052046152 5.54111808507602 0.996695039805149 -0.0586472748815917 + 0.000183144463865491 171.822964769713 0.000182643563092303 -7.02036841994439 0.000247327319511663 -156.285079607502 0.000272376426638301 33.6399301027409 + 0.996695039805149 -0.0586472748815917 0.00331271031883569 5.53934763599257 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000177827941003892 0.00332087830868207 6.11529303833058 0.996689144011487 -0.0654165422127943 0.000264904985225612 36.4713443748309 0.000235950987625536 -154.333178710595 + 0.000179211142754242 -7.51760205699562 0.000179807887772979 171.145518344951 + 0.996689144011487 -0.0654165422127943 0.00332085852050499 6.11322312608472 0.00023595049179348 -154.333072723191 0.000264887498867027 36.4580392835871 + 0.000179808654380307 171.14601396345 0.000179205569563668 -7.53119995522242 + 0.000264904985225612 36.4713443748309 0.00023595049179348 -154.333072723191 0.00330125364971453 5.81769780270153 0.996707481621367 -0.0647559106456512 + 0.000283779757013428 36.5712902657741 0.000253330540802659 -153.919610262936 + 0.000235950987625536 -154.333178710595 0.000264887498867027 36.4580392835871 0.996707481621367 -0.0647559106456512 0.00330078348450307 5.81691712154632 + 0.000253329467344612 -153.919682181853 0.000283769868667269 36.5650392750138 + 0.000179211142754242 -7.51760205699562 0.000179808654380307 171.14601396345 0.000283779757013428 36.5712902657741 0.000253329467344612 -153.919682181853 + 0.00332123691304136 6.17448020120704 0.996689104522933 -0.0656612632427548 + 0.000179807887772979 171.145518344951 0.000179205569563668 -7.53119995522242 0.000253330540802659 -153.919610262936 0.000283769868667269 36.5650392750138 + 0.996689104522933 -0.0656612632427548 0.00332122391068581 6.17251469128645 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000199526231496888 0.00333094781396134 6.809579910569 0.996682348717703 -0.0732331760977695 0.000277516001157769 39.4781369862742 0.000242493165085337 -151.837174934519 + 0.000175157551705083 -7.97473428226928 0.000175861566868594 170.490326993695 + 0.996682348717703 -0.0732331760977695 0.00333092318017823 6.80730423835881 0.000242492544389117 -151.837046654738 0.000277495291250835 39.4638771167576 + 0.000175862381759331 170.490839895752 0.000175147023169983 -7.99039753727984 + 0.000277516001157769 39.4781369862742 0.000242492544389117 -151.837046654738 0.00330958853738788 6.49720274956787 0.996702116021907 -0.0725567180679174 + 0.000297406321380688 39.5487254341814 0.000260615251512436 -151.429211006203 + 0.000242493165085337 -151.837174934519 0.000277495291250835 39.4638771167576 0.996702116021907 -0.0725567180679174 0.00330899670042897 6.49697332106364 + 0.000260613911144942 -151.429268473761 0.000297398032847153 39.5424818467028 + 0.000175157551705083 -7.97473428226928 0.000175862381759331 170.490839895752 0.000297406321380688 39.5487254341814 0.000260613911144942 -151.429268473761 + 0.00333153988069626 6.87417273003421 0.99668214855911 -0.0735029784405318 + 0.000175861566868594 170.490326993695 0.000175147023169983 -7.99039753727984 0.000260615251512436 -151.429211006203 0.000297398032847153 39.5424818467028 + 0.99668214855911 -0.0735029784405318 0.00333152376731136 6.87199303033182 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000223872113856834 0.00334313394786293 7.57533126231533 0.996674370007721 -0.0819719379928014 0.000292526549294216 42.5034300902746 0.000250415935474521 -149.228502123865 + 0.000170425850010116 -8.3429403225021 0.000171243906460096 169.888244968507 + 0.996674370007721 -0.0819719379928014 0.00334310432920313 7.57283305939427 0.000250415159819312 -149.228346081273 0.000292502510736211 42.4881538289182 + 0.000171244730565496 169.88878508173 0.000170408820686379 -8.36043690278943 + 0.000292526549294216 42.5034300902746 0.000250415159819312 -149.228346081273 0.00331978191611028 7.25138167810599 0.996695742629151 -0.0812888308432522 + 0.000313582199399106 42.5380595018079 0.000269395641378442 -148.836822963749 + 0.000250415935474521 -149.228502123865 0.000292502510736211 42.4881538289182 0.996695742629151 -0.0812888308432522 0.00331907230412455 7.25201342552368 + 0.000269393968821885 -148.836853547799 0.000313577892932862 42.5316503338065 + 0.000170425850010116 -8.3429403225021 0.000171244730565496 169.88878508173 0.000313582199399106 42.5380595018079 0.000269393968821885 -148.836853547799 + 0.00334399650860557 7.64547024415427 0.996673991846349 -0.0822685941036505 + 0.000171243906460096 169.888244968507 0.000170408820686379 -8.36043690278943 0.000269395641378442 -148.836822963749 0.000313577892932862 42.5316503338065 + 0.996673991846349 -0.0822685941036505 0.00334397704794629 7.64305456062825 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000251188643150958 0.0033578681234081 8.41763183898652 0.996664993084369 -0.0917388640880637 0.000310258954366098 45.5041585533375 0.00025994385399628 -146.535656735224 + 0.000164966630256092 -8.5743409575586 0.000165901680564901 169.378805588282 + 0.996664993084369 -0.0917388640880637 0.00335783372543202 8.41488973236785 0.000259942886312514 -146.535466198306 0.000310231591120075 45.4877650092187 + 0.00016590248039478 169.379394795574 0.000164942074785501 -8.59315300344474 + 0.000310258954366098 45.5041585533375 0.000259942886312514 -146.535466198306 0.00333225451125877 8.08692844494498 0.996688161929257 -0.0910621225853787 + 0.000332636587353146 45.4976215074897 0.000279900731586408 -146.171257003236 + 0.00025994385399628 -146.535656735224 0.000310231591120075 45.4877650092187 0.996688161929257 -0.0910621225853787 0.00333144504308751 8.08878967234227 + 0.000279898657158282 -146.171243779637 0.000332639447879986 45.4906763656779 + 0.000164966630256092 -8.5743409575586 0.00016590248039478 169.379394795574 0.000332636587353146 45.4976215074897 0.000279898657158282 -146.171243779637 + 0.00335904151362422 8.49341246871523 0.996664420323388 -0.0920644016819003 + 0.000165901680564901 169.378805588282 0.000164942074785501 -8.59315300344474 0.000279900731586408 -146.171257003236 0.000332639447879986 45.4906763656779 + 0.996664420323388 -0.0920644016819003 0.00335901858862721 8.49073485378732 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000281838293126446 0.00337565121365397 9.34109326781467 0.99665397246046 -0.102650709932295 0.000331046919886457 48.4382051965352 0.000271314729453852 -143.792902105268 + 0.000158742768728856 -8.60806937292711 0.000159791997977448 169.011692339656 + 0.99665397246046 -0.102650709932295 0.00337561270482819 9.3380772909821 0.000271313524139429 -143.792668893127 0.000331016340364168 48.4205404654669 + 0.000159792767225065 169.012368265585 0.000158710777148024 -8.62742441335105 + 0.000331046919886457 48.4382051965352 0.000271313524139429 -143.792668893127 0.0033475244745583 9.01039271202952 0.996679127472016 -0.101998348054783 + 0.000354907900541388 48.3875307782038 0.000292369863091412 -143.465836821357 + 0.000271314729453852 -143.792902105268 0.000331016340364168 48.4205404654669 0.996679127472016 -0.101998348054783 0.00334665270364285 9.01384143149447 + 0.000292367320324206 -143.465758308963 0.000354921810662822 48.3794039490916 + 0.000158742768728856 -8.60806937292711 0.000159792767225065 169.012368265585 0.000354907900541388 48.3875307782038 0.000292367320324206 -143.465758308963 + 0.00337717989187639 9.42255682180361 0.996653187879897 -0.103007484737245 + 0.000159791997977448 169.011692339656 0.000158710777148024 -8.62742441335105 0.000292369863091412 -143.465836821357 0.000354921810662822 48.3794039490916 + 0.996653187879897 -0.103007484737245 0.00337715353674173 9.41958483992999 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000316227766016838 0.00339705177871354 10.3496176294561 0.996641039411451 -0.114835849199176 0.000355232567004127 51.2673568073892 0.000284774177467691 -141.038379628582 + 0.000151730385655428 -8.36627950497183 0.00015288195415934 168.849179959176 + 0.996641039411451 -0.114835849199176 0.00339701034644554 10.3462833536952 0.000284772678437041 -141.038093939261 0.000355198941664126 51.2482037382865 + 0.000152882744657272 168.84999653643 0.000151692707936097 -8.38535376346069 + 0.000355232567004127 51.2673568073892 0.000284772678437041 -141.038093939261 0.00336622380274989 10.0277562552439 0.996668339948116 -0.11423177893726 + 0.000380741616779639 51.1725406274433 0.00030704786324704 -140.756307553357 + 0.000284774177467691 -141.038379628582 0.000355198941664126 51.2482037382865 0.996668339948116 -0.11423177893726 0.00336535096378192 10.0329889542485 + 0.000307044800297616 -140.756138585583 0.000380770680703185 51.1622190979097 + 0.000151730385655428 -8.36627950497183 0.000152882744657272 168.84999653643 0.000380741616779639 51.1725406274433 0.000307044800297616 -140.756138585583 + 0.00339898521609468 10.4367345081109 0.996640023278688 -0.115226578620868 + 0.00015288195415934 168.849179959176 0.000151692707936097 -8.38535376346069 0.00030704786324704 -140.756307553357 0.000380770680703185 51.1622190979097 + 0.996640023278688 -0.115226578620868 0.00339895560268711 10.4334259680701 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000354813389233575 0.00342270004589447 11.4462102501447 0.996625914123724 -0.128435529685133 0.000383165214060699 53.9598098730308 0.000300569832039182 -138.311465111675 + 0.000143918879304301 -7.74678973825378 0.00014514565956433 168.97095977843 + 0.996625914123724 -0.128435529685133 0.00342265729604487 11.4424914036153 0.000300567970133604 -138.311115374863 0.00038312867787255 53.9388853056543 + 0.000145146615863522 168.971979845593 0.000143879026467556 -7.76517447279369 + 0.000383165214060699 53.9598098730308 0.000300567970133604 -138.311115374863 0.00338911079340629 11.143838917626 0.996655445598946 -0.127909715793228 + 0.000410490422606851 53.8243160154787 0.000324180693574448 -138.0782629873 + 0.000300569832039182 -138.311465111675 0.00038312867787255 53.9388853056543 0.996655445598946 -0.127909715793228 0.00338831963509477 11.1506428625385 + 0.000324177087101913 -138.077976781245 0.000410537644666616 53.8103066564471 + 0.000143918879304301 -7.74678973825378 0.000145146615863522 168.971979845593 0.000410490422606851 53.8243160154787 0.000324177087101913 -138.077976781245 + 0.00342509345511547 11.5388571402601 0.996624642138323 -0.128863276078953 + 0.00014514565956433 168.97095977843 0.000143879026467556 -7.76517447279369 0.000324180693574448 -138.0782629873 0.000410537644666616 53.8103066564471 + 0.996624642138323 -0.128863276078953 0.00342506078276265 11.5351561874841 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000398107170553497 0.00345327879073143 12.6328926106761 0.996608321378252 -0.143605655009942 0.000415202597079351 56.491890181353 0.000318946305680583 -135.649707044464 + 0.00013531306457103 -6.60915170317091 0.000136559943919599 169.484120813478 + 0.996608321378252 -0.143605655009942 0.00345323636820455 12.6286938857446 0.00031894399496234 -135.64927976854 0.000415163082545095 56.4688546123254 + 0.000136561326158219 169.485393631852 0.000135275377789938 -6.62760575249317 + 0.000415202597079351 56.491890181353 0.00031894399496234 -135.64927976854 0.00341707064730622 12.361529587273 0.996640043322954 -0.143192924719242 + 0.000444516937604191 56.3229016165577 0.000344012084523841 -135.464461187599 + 0.000318946305680583 -135.649707044464 0.000415163082545095 56.4688546123254 0.996640043322954 -0.143192924719242 0.00341644983345971 12.3690023935239 + 0.0003440079524914 -135.464032529592 0.000444580733830346 56.3030979463133 + 0.00013531306457103 -6.60915170317091 0.000136561326158219 169.485393631852 0.000444516937604191 56.3229016165577 0.0003440079524914 -135.464032529592 + 0.00345619353692343 12.7308273753851 0.996606762882443 -0.144073758363131 + 0.000136559943919599 169.484120813478 0.000135275377789938 -6.62760575249317 0.000344012084523841 -135.464461187599 0.000444580733830346 56.3030979463133 + 0.996606762882443 -0.144073758363131 0.00345615776478587 12.726660972933 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000446683592150963 0.00348951410229516 13.9107608678943 0.996588007156715 -0.160519250401485 0.000451715083369834 58.8488199728431 0.000340142164108563 -133.085826353572 + 0.000125945069103519 -4.74855806956494 0.000127103303346707 170.543653232183 + 0.996588007156715 -0.160519250401485 0.00348947293561353 13.9059546339863 0.000340139296403152 -133.085305849355 0.00045167207545533 58.8233067498801 + 0.000127105468891379 170.545168502565 0.0001259121668306 -4.7698342375279 + 0.000451715083369834 58.8488199728431 0.000340139296403152 -133.085305849355 0.00345109045164461 13.6809570663501 0.996621707092476 -0.16025626557006 + 0.000483198966901186 58.6575006030576 0.000366780575507149 -132.94225745445 + 0.000340142164108563 -133.085826353572 0.00045167207545533 58.8233067498801 0.996621707092476 -0.16025626557006 0.00345070049382862 13.687413259686 + 0.00036677598308747 -132.94166638525 0.00048326338698542 58.6291753089144 + 0.000125945069103519 -4.74855806956494 0.000127105468891379 170.545168502565 0.000483198966901186 58.6575006030576 0.00036677598308747 -132.94166638525 + 0.00349301780035408 14.0135999563665 0.996586124022492 -0.161031221819744 + 0.000127103303346707 170.543653232183 0.0001259121668306 -4.7698342375279 0.000366780575507149 -132.94225745445 0.00048326338698542 58.6291753089144 + 0.996586124022492 -0.161031221819744 0.00349297818272368 14.008876823328 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000501187233627273 0.00353217126184341 15.2802084348271 0.996564751902586 -0.179369713506589 0.000493093113168686 61.0245489780322 0.000364390040497176 -130.645278438402 + 0.000115913084391345 -1.84854666973238 0.000116769845531332 172.394023239956 + 0.996564751902586 -0.179369713506589 0.00353213047964965 15.2746409638915 0.000364386478036138 -130.644646189941 0.000493045287779514 60.9962278602369 + 0.000116773144523092 172.395637979421 0.000115881729478985 -1.87752475288057 + 0.000493093113168686 61.0245489780322 0.000364386478036138 -130.644646189941 0.00349219417358158 15.0990063710849 0.996600029069412 -0.179290264135319 + 0.000526940842514687 60.8274016657255 0.00039271579697371 -130.530376338484 + 0.000364390040497176 -130.645278438402 0.000493045287779514 60.9962278602369 0.996600029069412 -0.179290264135319 0.00349202514571128 15.1024098991277 + 0.000392710848681211 -130.529611131041 0.000526948677772185 60.7886464856638 + 0.000115913084391345 -1.84854666973238 0.000116773144523092 172.395637979421 0.000526940842514687 60.8274016657255 0.000392710848681211 -130.529611131041 + 0.00353633772978166 15.3874094704912 0.996562498402915 -0.179929110451551 + 0.000116769845531332 172.394023239956 0.000115881729478985 -1.87752475288057 0.00039271579697371 -130.530376338484 0.000526948677772185 60.7886464856638 + 0.996562498402915 -0.179929110451551 0.00353629220008833 15.3820244405144 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000562341325190349 0.00358206293382038 16.7412748427913 0.996538374813779 -0.200374826632072 0.000539757114384034 63.0208412654941 0.000391920106093187 -128.344743840223 + 0.000105484567917378 2.59757266895003 0.000105628095527967 175.451599257962 + 0.996538374813779 -0.200374826632072 0.0035820188135447 16.7347872025637 0.000391915674825447 -128.343977262672 0.00053970141839209 62.9895623595552 + 0.00010563263997901 175.452960349497 0.000105442060249505 2.55612257977455 + 0.000539757114384034 63.0208412654941 0.000391915674825447 -128.343977262672 0.00354134695736928 16.6099385810822 0.996574676130861 -0.200504916008102 + 0.000576231850866646 62.8441850432 0.000422063836960908 -128.231220056675 + 0.000391920106093187 -128.344743840223 0.00053970141839209 62.9895623595552 0.996574676130861 -0.200504916008102 0.00354130444421997 16.6089361194743 + 0.000422058650246941 -128.230277920181 0.000576066022543387 62.8034024584312 + 0.000105484567917378 2.59757266895003 0.00010563263997901 175.452960349497 0.000576231850866646 62.8441850432 0.000422058650246941 -128.230277920181 + 0.00358697216865337 16.8521217919041 0.99653569861893 -0.200985134980961 + 0.000105628095527967 175.451599257962 0.000105442060249505 2.55612257977455 0.000422063836960908 -128.231220056675 0.000576066022543387 62.8034024584312 + 0.99653569861893 -0.200985134980961 0.00358691680160428 16.8459680510982 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000630957344480193 0.00364007722711261 18.2940001965967 0.996508723361616 -0.223781313798578 0.000592163688989866 64.8460604813519 0.000422962054900098 -126.191653739426 + 9.53389534602261E-05 9.37931300800081 9.39983828306158E-05 -179.547579203395 + 0.996508723361616 -0.223781313798578 0.00364002292670402 18.2864628258751 0.00042295654796144 -126.190725418686 0.00059208875571636 64.8121662766248 + 9.40037735841338E-05 -179.547013016517 9.52658694218323E-05 9.32712886882584 + 0.000592163688989866 64.8460604813519 0.00042295654796144 -126.190725418686 0.00359939814623858 18.2076113380396 0.996545426290248 -0.224136599910416 + 0.000631884681035089 64.7181811241333 0.000455337914915856 -126.038979374486 + 0.000422962054900098 -126.191653739426 0.00059208875571636 64.8121662766248 0.996545426290248 -0.224136599910416 0.00359935363457699 18.2024429424476 + 0.000455332573489456 -126.037863736451 0.000631672507242515 64.6939756471321 + 9.53389534602261E-05 9.37931300800081 9.40037735841338E-05 -179.547013016517 0.000631884681035089 64.7181811241333 0.000455332573489456 -126.037863736451 + 0.0036458150988059 18.4075827251049 0.996505567723611 -0.224445853154843 + 9.39983828306158E-05 -179.547579203395 9.52658694218323E-05 9.32712886882584 0.000455337914915856 -126.038979374486 0.000631672507242515 64.6939756471321 + 0.996505567723611 -0.224445853154843 0.00364574404827566 18.4005691217786 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000707945784384137 0.00370723005834706 19.9385774899558 0.996475644319241 -0.249869500664878 0.000650734178011492 66.5126554382033 0.000457700139872968 -124.18975362472 + 8.70261887788997E-05 19.4934793835864 8.28841346281351E-05 -171.388127345785 + 0.996475644319241 -0.249869500664878 0.00370715693759008 19.9299239738328 0.000457693307165015 -124.188632756215 0.000650576881255141 66.4705008563995 + 8.28895589810805E-05 -171.388899589188 8.69110476959932E-05 19.4458757912996 + 0.000650734178011492 66.5126554382033 0.000457693307165015 -124.188632756215 0.00366716794500008 19.8881602604494 0.996512138623895 -0.250456636833242 + 0.000694700318012462 66.4104082651457 0.000493051739034951 -124.010502315737 + 0.000457700139872968 -124.18975362472 0.000650576881255141 66.4705008563995 0.996512138623895 -0.250456636833242 0.00366704446293952 19.880369315031 + 0.000493046243608538 -124.009214588321 0.000694565105730276 66.3825236088606 + 8.70261887788997E-05 19.4934793835864 8.28895589810805E-05 -171.388899589188 0.000694700318012462 66.4104082651457 0.000493046243608538 -124.009214588321 + 0.00371388630918874 20.0537653542635 0.996471951941556 -0.250591385365201 + 8.28841346281351E-05 -171.388127345785 8.69110476959932E-05 19.4458757912996 0.000493051739034951 -124.010502315737 0.000694565105730276 66.3825236088606 + 0.996471951941556 -0.250591385365201 0.00371379231589703 20.045833736888 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000794328234724282 0.0037847378851336 21.6750449699828 0.996438937553341 -0.278957440354315 0.00071642845035045 67.9846727684696 0.000496734520334524 -122.360023578244 + 8.33507861977839E-05 33.3040630543551 7.46375686852407E-05 -158.704408190302 + 0.996438937553341 -0.278957440354315 0.00378463860561048 21.665276292971 0.000496726055249399 -122.358675256806 0.000716279521109691 67.9511955690236 + 7.46422116031238E-05 -158.706990229288 8.32031211016519E-05 33.2819856592055 + 0.00071642845035045 67.9846727684696 0.000496726055249399 -122.358675256806 0.00374567432794959 21.6504160580061 0.99647465208063 -0.279777476114101 + 0.000764781698766542 67.9256929807836 0.000535142934840968 -122.151534974486 + 0.000496734520334524 -122.360023578244 0.000716279521109691 67.9511955690236 0.99647465208063 -0.279777476114101 0.00374547995034609 21.6415044068072 + 0.000535137214418866 -122.150063879661 0.000764601228098352 67.8944325279155 + 8.33507861977839E-05 33.3040630543551 7.46422116031238E-05 -158.706990229288 0.000764781698766542 67.9256929807836 0.000535137214418866 -122.150063879661 + 0.00379240159950848 21.7904919708681 0.996434655668612 -0.279739699362545 + 7.46375686852407E-05 -158.704408190302 8.32031211016519E-05 33.2819856592055 0.000535142934840968 -122.151534974486 0.000764601228098352 67.8944325279155 + 0.996434655668612 -0.279739699362545 0.00379227759983222 21.7816223216044 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.000891250938133746 0.00387409512116808 23.5023735985384 0.996398301680109 -0.311404019572363 0.000789852335671037 69.3804957842411 0.000540193118422454 -120.625025626991 + 8.74180692216323E-05 48.9211578084577 7.28422445561687E-05 -141.876036873954 + 0.996398301680109 -0.311404019572363 0.0038739657880265 23.4915096239929 0.000540182665827166 -120.62340922837 0.000789612087019972 69.3322467380635 + 7.28448452478614E-05 -141.880546081425 8.72488418546859E-05 48.9319686564467 + 0.000789852335671037 69.3804957842411 0.000540182665827166 -120.62340922837 0.0038363170629574 23.4931008452043 0.996432683234137 -0.312454109475494 + 0.000842792231939268 69.3097263216965 0.000581931571833435 -120.426664091675 + 0.000540193118422454 -120.625025626991 0.000789612087019972 69.3322467380635 0.996432683234137 -0.312454109475494 0.00383609610271756 23.4835938692233 + 0.000581925592934765 -120.424978938055 0.000842577521537354 69.2770080878014 + 8.74180692216323E-05 48.9211578084577 7.28448452478614E-05 -141.880546081425 0.000842792231939268 69.3097263216965 0.000581925592934765 -120.424978938055 + 0.00388284621546166 23.6165693967883 0.996393388142933 -0.312249839371761 + 7.28422445561687E-05 -141.876036873954 8.72488418546859E-05 48.9319686564467 0.000581931571833435 -120.426664091675 0.000842577521537354 69.2770080878014 + 0.996393388142933 -0.312249839371761 0.00388268647739502 23.6067535869808 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.001 0.00397712203116927 25.4170092336222 0.996353291807121 -0.347610739344195 0.00087154653837716 70.6459459627034 0.000588441891699507 -119.018902594928 + 0.00010029139459554 62.9379788548094 8.00055958839189E-05 -124.635738516158 + 0.996353291807121 -0.347610739344195 0.00397696064297881 25.4050084624075 0.000588429022926142 -119.016972271977 0.00087127112951475 70.5911893572716 + 8.00045885874891E-05 -124.640832837124 0.000100104061449764 62.9821926630461 + 0.00087154653837716 70.6459459627034 0.000588429022926142 -119.016972271977 0.0039408648921596 25.4114323668569 0.996385795973537 -0.34888317611131 + 0.000929745268785624 70.5808383511455 0.000633932163848482 -118.819040012996 + 0.000588441891699507 -119.018902594928 0.00087127112951475 70.5911893572716 0.996385795973537 -0.34888317611131 0.00394063584231957 25.4011131142957 + 0.000633926110467809 -118.817104282282 0.000929494783596753 70.5457252366165 + 0.00010029139459554 62.9379788548094 8.00045885874891E-05 -124.640832837124 0.000929745268785624 70.5808383511455 0.000633926110467809 -118.817104282282 + 0.00398702483580272 25.5284708530299 0.996347719041324 -0.348524079883929 + 8.00055958839189E-05 -124.635738516158 0.000100104061449764 62.9821926630461 0.000633932163848482 -118.819040012996 0.000929494783596753 70.5457252366165 + 0.996347719041324 -0.348524079883929 0.00398682367973387 25.517673369253 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00112201845430196 0.00409595823400695 27.4115307349551 0.996303310767702 -0.388023456057867 0.000962594663479048 71.8017278845963 0.000642031308875918 -117.524099251911 + 0.000120919278627531 73.6327459217469 9.58550045089264E-05 -110.700210261247 + 0.996303310767702 -0.388023456057867 0.00409575586123359 27.3982590897741 0.000642015532067366 -117.521801422033 0.000962266154922514 71.7416552100315 + 9.58499120910156E-05 -110.70422760951 0.000120731757300295 73.7022797193482 + 0.000962594663479048 71.8017278845963 0.000642015532067366 -117.521801422033 0.00406131792875175 27.3960488319773 0.996333438101503 -0.389504409255625 + 0.00102672293483685 71.749277045331 0.000691732604179235 -117.314811636205 + 0.000642031308875918 -117.524099251911 0.000962266154922514 71.7416552100315 0.996333438101503 -0.389504409255625 0.00406105589817684 27.3846849850365 + 0.000691726809016852 -117.312615325472 0.00102642094050347 71.7113433570591 + 0.000120919278627531 73.6327459217469 9.58499120910156E-05 -110.70422760951 0.00102672293483685 71.749277045331 0.000691726809016852 -117.312615325472 + 0.00410706354344203 27.5191041886953 0.996297064308612 -0.38900998698463 + 9.58550045089264E-05 -110.700210261247 0.000120731757300295 73.7022797193482 0.000691732604179235 -117.314811636205 0.00102642094050347 71.7113433570591 + 0.996297064308612 -0.38900998698463 0.00410681046705139 27.5072486007917 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00125892541179417 0.00423299560406242 29.4749787623844 0.996247674068106 -0.433138507277293 0.00106407751907734 72.8616726355841 0.000701541061459922 -116.126768912202 + 0.00014809471849547 81.2076049776735 0.000118926211771376 -100.859770351501 + 0.996247674068106 -0.433138507277293 0.00423272593947797 29.4602965777585 0.000701521861339971 -116.124038672692 0.00106368159357148 72.7964209348839 + 0.000118917182838943 -100.862204008836 0.000147912867726756 81.2866016647073 + 0.00106407751907734 72.8616726355841 0.000701521861339971 -116.124038672692 0.00419979120416176 29.4348654981608 0.996275023068895 -0.434807804852826 + 0.00113496173569422 72.8249928883719 0.00075608315462718 -115.900168953709 + 0.000701541061459922 -116.126768912202 0.00106368159357148 72.7964209348839 0.996275023068895 -0.434807804852826 0.00419944756172586 29.4226061679266 + 0.00075607718711241 -115.897726985955 0.00113459101398186 72.784270428396 + 0.00014809471849547 81.2076049776735 0.000118917182838943 -100.862204008836 0.00113496173569422 72.8249928883719 0.00075607718711241 -115.897726985955 + 0.0042453589139536 29.5780906180158 0.996240742547502 -0.434206613644174 + 0.000118926211771376 -100.859770351501 0.000147912867726756 81.2866016647073 0.00075608315462718 -115.900168953709 0.00113459101398186 72.784270428396 + 0.996240742547502 -0.434206613644174 0.00424503245099148 29.5651112077856 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00141253754462276 0.00439046898619231 31.6036014450174 0.996186315703031 -0.483534090471103 0.00117722891579054 73.8451427460591 0.000767647969305183 -114.809102546544 + 0.000180538545901958 86.1339247511313 0.000147446961767333 -94.6259692313703 + 0.996186315703031 -0.483534090471103 0.00439012313759705 31.5874677706777 0.00076762470151647 -114.805872485722 0.00117675613978402 73.7738803020321 + 0.00014743413496529 -94.6269120535705 0.000180363237031271 86.2196536474676 + 0.00117722891579054 73.8451427460591 0.00076762470151647 -114.805872485722 0.00435822411737477 31.5236236001861 0.99621044713986 -0.485358387740737 + 0.00125567801959428 73.8217615224734 0.000827601993303011 -114.568367771573 + 0.000767647969305183 -114.809102546544 0.00117675613978402 73.7738803020321 0.99621044713986 -0.485358387740737 0.00435780353605044 31.5103366994151 + 0.000827596206903061 -114.565644466392 0.00125522996653513 73.777959307447 + 0.000180538545901958 86.1339247511313 0.00014743413496529 -94.6269120535705 0.00125567801959428 73.8217615224734 0.000827596206903061 -114.565644466392 + 0.00440415631045354 31.7013760826561 0.996178690054782 -0.484691957829196 + 0.000147446961767333 -94.6259692313703 0.000180363237031271 86.2196536474676 0.000827601993303011 -114.568367771573 0.00125522996653513 73.777959307447 + 0.996178690054782 -0.484691957829196 0.00440374386142437 31.6872619906242 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00158489319246111 0.00456868842235151 33.7094440846006 0.996117387870389 -0.539472588802662 0.00130210226213896 74.705283874106 0.000839961336864408 -113.657917768695 + 0.000222172572628249 89.8456541565819 0.000184969832538999 -90.0792867478454 + 0.996117387870389 -0.539472588802662 0.0045682439171736 33.6918085861233 0.000839933032544481 -113.654097205368 0.00130153597239055 74.6276281538536 + 0.000184952821761585 -90.0786409728161 0.000222008895949747 89.9344297582166 + 0.00130210226213896 74.705283874106 0.000839933032544481 -113.654097205368 0.00453711790238329 33.5827662459037 0.996137896296454 -0.541458525349668 + 0.00138894698960312 74.6941089604845 0.00090590436682097 -113.402370206831 + 0.000839961336864408 -113.657917768695 0.00130153597239055 74.6276281538536 0.996137896296454 -0.541458525349668 0.00453660337895844 33.5684338703751 + 0.000905899095049769 -113.399357836776 0.00138840380989928 74.6472423468646 + 0.000222172572628249 89.8456541565819 0.000184952821761585 -90.0786409728161 0.00138894698960312 74.6941089604845 0.000905899095049769 -113.399357836776 + 0.00458374289302535 33.799475583839 0.996108979937687 -0.540721529894251 + 0.000184969832538999 -90.0792867478454 0.000222008895949747 89.9344297582166 0.00090590436682097 -113.402370206831 0.00138840380989928 74.6472423468646 + 0.996108979937687 -0.540721529894251 0.00458322078390708 33.7842332441217 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00177827941003892 0.00476852379545043 35.7585392953161 0.996039942854296 -0.601478612382992 0.00143947048947502 75.4492907287303 0.000918591991911893 -112.670300804362 + 0.000274871744527219 92.5323644740603 0.000233208711444822 -86.9119235849837 + 0.996039942854296 -0.601478612382992 0.0047679506949369 35.7394033191255 0.000918557420205104 -112.665774166901 0.00143879046812627 75.3649955353863 + 0.000233187084421288 -86.9096361961538 0.000274726293486197 92.6221161050072 + 0.00143947048947502 75.4492907287303 0.000918557420205104 -112.665774166901 0.00473723836349899 35.5781752002652 0.996056370671255 -0.603630887373604 + 0.00153561215703284 75.4492920320224 0.00099113876393339 -112.398978761997 + 0.000918591991911893 -112.670300804362 0.00143879046812627 75.3649955353863 0.996056370671255 -0.603630887373604 0.00473660832732047 35.5628167103881 + 0.000991134468486771 -112.395678287066 0.00153495213247752 75.3995742862432 + 0.000274871744527219 92.5323644740603 0.000233187084421288 -86.9096361961538 0.00153561215703284 75.4492920320224 0.000991134468486771 -112.395678287066 + 0.00478495942898975 35.8383300241896 0.996030646712486 -0.602818424339248 + 0.000233208711444822 -86.9119235849837 0.000274726293486197 92.6221161050072 0.00099113876393339 -112.398978761997 0.00153495213247752 75.3995742862432 + 0.996030646712486 -0.602818424339248 0.00478429628723243 35.8220317165165 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00199526231496888 0.00500183721747394 37.9937053861863 0.995958958267986 -0.671612724012457 0.00159675986699738 76.2672034812499 0.00100948216530932 -111.504441498052 + 0.000324057552139667 93.3990420312594 0.000277375473387928 -85.919900017239 + 0.995958958267986 -0.671612724012457 0.00500111162044288 37.9731948974649 0.00100944113497128 -111.499107031987 0.00159596256394973 76.1756367188536 + 0.000277349700496462 -85.9165647516866 0.000323930490011739 93.4962115334066 + 0.00159675986699738 76.2672034812499 0.00100944113497128 -111.499107031987 0.00496912931966895 37.7548602443948 0.995971659047581 -0.673893403189842 + 0.00170363914081925 76.2736530767527 0.00108974676628598 -111.227204090225 + 0.00100948216530932 -111.504441498052 0.00159596256394973 76.1756367188536 0.995971659047581 -0.673893403189842 0.00496835352779497 37.7386467906048 + 0.0010897428760416 -111.223573186953 0.00170286090559507 76.2209021442424 + 0.000324057552139667 93.3990420312594 0.000277349700496462 -85.9165647516866 0.00170363914081925 76.2736530767527 0.0010897428760416 -111.223573186953 + 0.0050198936639746 38.0677537622889 0.995948914393064 -0.673081543986031 + 0.000277375473387928 -85.919900017239 0.000323930490011739 93.4962115334066 0.00108974676628598 -111.227204090225 0.00170286090559507 76.2209021442424 + 0.995948914393064 -0.673081543986031 0.00501906281563084 38.0506308663835 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00223872113856834 0.00526454594992569 40.1419148065875 0.995867045164274 -0.7494929661981 0.00177064001109692 76.9422327790944 0.00110929290515341 -110.546273376668 + 0.000382945055236393 93.8593959032622 0.000330656413046734 -85.4169665130839 + 0.995867045164274 -0.7494929661981 0.00526367636644505 40.1205484756832 0.00110924683128042 -110.53999143188 0.00176977071415102 76.8430504304957 + 0.000330627534317523 -85.4126618559776 0.000382916252345703 93.9610391624992 + 0.00177064001109692 76.9422327790944 0.00110924683128042 -110.53999143188 0.0052295304808465 39.8356071373219 0.995875353979453 -0.751879672418504 + 0.00188944165726767 76.9501290934918 0.00119812878326933 -110.268297360425 + 0.00110929290515341 -110.546273376668 0.00176977071415102 76.8430504304957 0.995875353979453 -0.751879672418504 0.00522863107756003 39.819118204067 + 0.00119812447495193 -110.264353014325 0.00188859994248216 76.8945259583973 + 0.000382945055236393 93.8593959032622 0.000330627534317523 -85.4126618559776 0.00188944165726767 76.9501290934918 0.00119812447495193 -110.264353014325 + 0.00528450930492459 40.2046014237948 0.995855753142899 -0.751090303609504 + 0.000330656413046734 -85.4169665130839 0.000382916252345703 93.9610391624992 0.00119812878326933 -110.268297360425 0.00188859994248216 76.8945259583973 + 0.995855753142899 -0.751090303609504 0.00528353738733126 40.1873975599857 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00251188643150958 0.00555604838044734 42.1661922348304 0.995763529833477 -0.835797148483546 0.00196095105417916 77.5066046754435 0.00121685173021414 -109.762614102605 + 0.000452572646620747 94.156235867111 0.000394003705485485 -85.1167922038354 + 0.995763529833477 -0.835797148483546 0.00555509645561531 42.1436032059482 0.00121679850236167 -109.755409687547 0.00196004680280601 77.396377049701 + 0.000393964653082863 -85.1112781118175 0.000452685598051961 94.2475252705998 + 0.00196095105417916 77.5066046754435 0.00121679850236167 -109.755409687547 0.00551720032138501 41.7849710179865 0.995767085116866 -0.838248656346075 + 0.00209275812664374 77.521624135081 0.00131491393209684 -109.473069639458 + 0.00121685173021414 -109.762614102605 0.00196004680280601 77.396377049701 0.995767085116866 -0.838248656346075 0.00551625258487932 41.7677283750639 + 0.0013149044685514 -109.468722797155 0.00209188622497487 77.4601648672936 + 0.000452572646620747 94.156235867111 0.000393964653082863 -85.1112781118175 0.00209275812664374 77.521624135081 0.0013149044685514 -109.468722797155 + 0.00557736123544225 42.2162537536628 0.995751285342824 -0.837505949374879 + 0.000394003705485485 -85.1167922038354 0.000452685598051961 94.2475252705998 0.00131491393209684 -109.473069639458 0.00209188622497487 77.4601648672936 + 0.995751285342824 -0.837505949374879 0.0055763254821862 42.19838791758 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00281838293126445 0.00589285605392988 44.4101179861471 0.995662340257006 -0.933540835902792 0.00217900786260643 78.251730188434 0.00134087771367009 -108.635391146509 + 0.000519534090729046 94.1764462096862 0.000453715843313973 -85.1081529348961 + 0.995662340257006 -0.933540835902792 0.00589161313766585 44.3837632623033 0.00134081086573336 -108.627208294241 0.00217775904669124 78.1263087142686 + 0.000453672340016337 -85.1012554670275 0.000519454476719899 94.2637678721013 + 0.00217900786260643 78.251730188434 0.00134081086573336 -108.627208294241 0.00584836203054485 43.9750544410127 0.995662256469954 -0.936116132724624 + 0.00232581748118724 78.2692258375552 0.00144966845016604 -108.346673676663 + 0.00134087771367009 -108.635391146509 0.00217775904669124 78.1263087142686 0.995662256469954 -0.936116132724624 0.00584713819006785 43.9544946003023 + 0.00144966431110824 -108.34155806129 0.00232458250218332 78.1984498213243 + 0.000519534090729046 94.1764462096862 0.000453672340016337 -85.1012554670275 0.00232581748118724 78.2692258375552 0.00144966431110824 -108.34155806129 + 0.00591565449897691 44.4577018215634 0.995649844147746 -0.935420634125502 + 0.000453715843313973 -85.1081529348961 0.000519454476719899 94.2637678721013 0.00144966845016604 -108.346673676663 0.00232458250218332 78.1984498213243 + 0.995649844147746 -0.935420634125502 0.00591429918983058 44.4363123845838 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00316227766016838 0.00627288582181645 46.5284864988988 0.99554644475993 -1.0423581810477 0.00242419119596764 78.8497129215091 0.00148112782742592 -107.707581185972 + 0.000600921548545233 93.8625780149639 0.00052703767407725 -85.4722935157387 + 0.99554644475993 -1.0423581810477 0.00627123880460206 46.500999155172 0.00148104727580365 -107.697974059168 0.00242266538743931 78.7148183982036 + 0.000526987348678956 -85.4640343809009 0.000600828572474314 93.9695283028709 + 0.00242419119596764 78.8497129215091 0.00148104727580365 -107.697974059168 0.00622149964720241 46.0364757712783 0.995541977993901 -1.04504749138887 + 0.00258810038434934 78.8672893192677 0.00160225212786297 -107.420290345263 + 0.00148112782742592 -107.707581185972 0.00242266538743931 78.7148183982036 0.995541977993901 -1.04504749138887 0.00621989172013149 46.0153842450698 + 0.00160225066521047 -107.414748502281 0.00258657916377505 78.7938395707622 + 0.000600921548545233 93.8625780149639 0.000526987348678956 -85.4640343809009 0.00258810038434934 78.8672893192677 0.00160225066521047 -107.414748502281 + 0.00629811086536641 46.5735294430622 0.995533159241522 -1.0444614459498 + 0.00052703767407725 -85.4722935157387 0.000600828572474314 93.9695283028709 0.00160225212786297 -107.420290345263 0.00258657916377505 78.7938395707622 + 0.995533159241522 -1.0444614459498 0.00629631113391665 46.5519205896474 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00354813389233575 0.00669570644707427 48.4900159879207 0.995414953808065 -1.16326738134698 0.00269741860410397 79.3303736321743 0.00163708130366944 -106.950647253905 + 0.000698227712835553 93.3958467692365 0.000615320971524758 -86.0064632517389 + 0.995414953808065 -1.16326738134698 0.00669357890275346 48.4624788393207 0.00163698598709282 -106.939267748928 0.0026956306594331 79.1869330248333 + 0.000615263757082143 -85.996310763931 0.000698210792535216 93.5271204135428 + 0.00269741860410397 79.3303736321743 0.00163698598709282 -106.939267748928 0.00663584515098439 47.9375295102059 0.995405315993759 -1.1660490772682 + 0.00288076034020285 79.3459132510091 0.00177230900180442 -106.664729049978 + 0.00163708130366944 -106.950647253905 0.0026956306594331 79.1869330248333 0.995405315993759 -1.1660490772682 0.00663378637262747 47.9170671537393 + 0.00177230885433964 -106.658774791776 0.00287897195672814 79.2716772767362 + 0.000698227712835553 93.3958467692365 0.000615263757082143 -85.996310763931 0.00288076034020285 79.3459132510091 0.00177230885433964 -106.658774791776 + 0.00672437756521303 48.5326899780705 0.995400358047157 -1.1656547139692 + 0.000615320971524758 -86.0064632517389 0.000698210792535216 93.5271204135428 0.00177230900180442 -106.664729049978 0.00287897195672814 79.2716772767362 + 0.995400358047157 -1.1656547139692 0.00672205264301422 48.5123450288252 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00398107170553497 0.00717474533706409 50.2529196559757 0.995256198971678 -1.29797582947306 0.00301280811451824 79.5277335057972 0.00182244352486136 -106.594375673537 + 0.000824873443970993 91.9371327392574 0.000732088992475793 -87.6390559512044 + 0.995256198971678 -1.29797582947306 0.00717212170932029 50.2324362567335 0.0018223488923506 -106.579989272174 0.00301124261972538 79.3891654527946 + 0.000732042794335074 -87.6254784425805 0.000825634359439803 92.1346897119093 + 0.00301280811451824 79.5277335057972 0.0018223488923506 -106.579989272174 0.00710713232581359 49.6333683228258 0.995238545319104 -1.3009181942604 + 0.0032203941234279 79.5191778215715 0.00197612561047447 -106.335024548392 + 0.00182244352486136 -106.594375673537 0.00301124261972538 79.3891654527946 0.995238545319104 -1.3009181942604 0.007104620211307 49.6212851415663 + 0.00197611760704728 -106.329072925359 0.0032188866548858 79.4592727326943 + 0.000824873443970993 91.9371327392574 0.000732042794335074 -87.6254784425805 0.0032203941234279 79.5191778215715 0.00197611760704728 -106.329072925359 + 0.00721362461926865 50.2857771939314 0.995235599468598 -1.30094180206889 + 0.000732088992475793 -87.6390559512044 0.000825634359439803 92.1346897119093 0.00197612561047447 -106.335024548392 0.0032188866548858 79.4592727326943 + 0.995235599468598 -1.30094180206889 0.0072107837684503 50.2761161333229 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00446683592150963 0.00767346258602892 52.0826275918165 0.995118224324393 -1.44740140859332 0.00330248392311661 79.996407871999 0.0019648199813755 -106.022472141499 + 0.000876089591510975 92.093087595896 0.000771705542995952 -87.5359591375903 + 0.995118224324393 -1.44740140859332 0.00767176454312998 52.0424020661501 0.00196472440245953 -106.009846833811 0.00330075534192535 79.7865144731235 + 0.000771632877254724 -87.5271749517491 0.000876384042997889 92.1033456389186 + 0.00330248392311661 79.996407871999 0.00196472440245953 -106.009846833811 0.00758462886058568 51.3826796569005 0.995096997127328 -1.44991963200486 + 0.00352361954154135 79.9810645576698 0.00212542865892784 -105.789825109876 + 0.0019648199813755 -106.022472141499 0.00330075534192535 79.7865144731235 0.995096997127328 -1.44991963200486 0.00758323715880452 51.3498186054015 + 0.00212541265757624 -105.781522744044 0.00352196723756119 79.8563180973837 + 0.000876089591510975 92.093087595896 0.000771632877254724 -87.5271749517491 0.00352361954154135 79.9810645576698 0.00212541265757624 -105.781522744044 + 0.00769728971962187 52.03507338284 0.995098878434736 -1.44947821534072 + 0.000771705542995952 -87.5359591375903 0.000876384042997889 92.1033456389186 0.00212542865892784 -105.789825109876 0.00352196723756119 79.8563180973837 + 0.995098878434736 -1.44947821534072 0.00769584052025432 52.0008077162856 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00501187233627272 0.00828128341198588 54.0255992870801 0.994964001274753 -1.61758506952127 0.00369940582155424 80.5468774023048 0.00219475167739922 -105.021935309109 + 0.00101880073509581 91.8635833458238 0.000901451877813572 -87.7574920356958 + 0.994964001274753 -1.61758506952127 0.00827813980582539 53.9869711155942 0.0021946076555073 -105.006236814364 0.00369660761700824 80.3339250659696 + 0.000901352915852111 -87.7447206532995 0.00101866901120253 91.9539101555779 + 0.00369940582155424 80.5468774023048 0.0021946076555073 -105.006236814364 0.00817788561084677 53.3123714195583 0.994938897553664 -1.62035869144355 + 0.00394986091445211 80.5489624427121 0.00237693618151165 -104.759889093431 + 0.00219475167739922 -105.021935309109 0.00369660761700824 80.3339250659696 0.994938897553664 -1.62035869144355 0.00817499413745252 53.2819097922936 + 0.00237693241834676 -104.751236057976 0.00394707679818472 80.4321929170805 + 0.00101880073509581 91.8635833458238 0.000901352915852111 -87.7447206532995 0.00394986091445211 80.5489624427121 0.00237693241834676 -104.751236057976 + 0.00831114797843359 54.0210909345959 0.994946751424125 -1.62032798461292 + 0.000901451877813572 -87.7574920356958 0.00101866901120253 91.9539101555779 0.00237693618151165 -104.759889093431 0.00394707679818472 80.4321929170805 + 0.994946751424125 -1.62032798461292 0.00830796661947228 53.9904266589268 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00562341325190349 0.00894740420265886 55.6920051720008 0.994782472812917 -1.80620431900668 0.00413143620105686 80.8542248901823 0.00244141554742776 -104.454338784953 + 0.00117124691105852 91.1428364012844 0.00103953870241881 -88.5475422083429 + 0.994782472812917 -1.80620431900668 0.00894317613546402 55.6547646293042 0.00244124168505728 -104.435799250817 0.00412812456368131 80.6279562742743 + 0.00103942191325386 -88.5318777289923 0.00117112976175679 91.2737677047986 + 0.00413143620105686 80.8542248901823 0.00244124168505728 -104.435799250817 0.00882625147396247 54.9438747753916 0.994751063596597 -1.80908829513281 + 0.00441283899652177 80.8501912192098 0.00264607024865235 -104.196101292261 + 0.00244141554742776 -104.454338784953 0.00412812456368131 80.6279562742743 0.994751063596597 -1.80908829513281 0.00882233221404271 54.9156897823922 + 0.00264606608832337 -104.18681096901 0.00440949771310619 80.7324101647691 + 0.00117124691105852 91.1428364012844 0.00103942191325386 -88.5318777289923 0.00441283899652177 80.8501912192098 0.00264606608832337 -104.18681096901 + 0.00898283088754694 55.6947881065403 0.994764131317442 -1.80943658780572 + 0.00103953870241881 -88.5475422083429 0.00117112976175679 91.2737677047986 0.00264607024865235 -104.196101292261 0.00440949771310619 80.7324101647691 + 0.994764131317442 -1.80943658780572 0.0089784614123732 55.6674849617943 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00630957344480193 0.0096844082230959 57.1444994347057 0.994572160993273 -2.01611568305468 0.00462168208890481 81.0136693572451 0.00272454501743372 -104.099026831174 + 0.00135778257609838 90.1486714752838 0.00121010235184749 -89.6315518968275 + 0.994572160993273 -2.01611568305468 0.00967894152305092 57.1119711057869 0.00272434376688341 -104.076894283952 0.00461793750171131 80.7786513902184 + 0.00120996949487972 -89.6122928749245 0.00135795756591405 90.3366461383294 + 0.00462168208890481 81.0136693572451 0.00272434376688341 -104.076894283952 0.00954359495508931 56.3581519770664 0.994532689125399 -2.01912057906917 + 0.00493905786341417 81.0006727488365 0.00295572334261804 -103.845935469152 + 0.00272454501743372 -104.099026831174 0.00461793750171131 80.7786513902184 0.994532689125399 -2.01912057906917 0.00953848345217746 56.3356272465548 + 0.00295571207753942 -103.83619170467 0.00493527234382191 80.8874313762411 + 0.00135778257609838 90.1486714752838 0.00120996949487972 -89.6122928749245 0.00493905786341417 81.0006727488365 0.00295571207753942 -103.83619170467 + 0.00972936419276726 57.1522762377522 0.994550813718394 -2.02006209826503 + 0.00121010235184749 -89.6315518968275 0.00135795756591405 90.3366461383294 0.00295572334261804 -103.845935469152 0.00493527234382191 80.8874313762411 + 0.994550813718394 -2.02006209826503 0.00972366669345479 57.132335547092 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00707945784384137 0.0106418474875112 57.8892024563239 0.994177883137459 -2.25462152289105 0.00521094890075497 79.0037825180665 0.00310440364909795 -107.282354017877 + 0.00156784150160121 81.324936965779 0.00140808028851425 -99.4229819573216 + 0.994177883137459 -2.25462152289105 0.0106423690971361 57.8875465129148 0.0031045166858644 -107.254794069619 0.0052163102800013 78.7776938725264 + 0.00140812589486863 -99.3991312074729 0.0015768975126997 81.6323983438898 + 0.00521094890075497 79.0037825180665 0.0031045166858644 -107.254794069619 0.0104961085514494 56.9557450877525 0.994103300221044 -2.25794992663073 + 0.0055743749946782 78.8428943410882 0.00337343180384761 -107.207517966798 + 0.00310440364909795 -107.282354017877 0.0052163102800013 78.7776938725264 0.994103300221044 -2.25794992663073 0.0104971526803086 56.9672555888451 + 0.0033731700765151 -107.198068169623 0.00558016121537918 78.7534806948481 + 0.00156784150160121 81.324936965779 0.00140812589486863 -99.3991312074729 0.0055743749946782 78.8428943410882 0.0033731700765151 -107.198068169623 + 0.0107275006184774 57.6586056645305 0.99409880559423 -2.25960778435756 + 0.00140808028851425 -99.4229819573216 0.0015768975126997 81.6323983438898 0.00337343180384761 -107.207517966798 0.00558016121537918 78.7534806948481 + 0.99409880559423 -2.25960778435756 0.0107292004244415 57.6780793238437 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00794328234724282 0.0113717329203503 59.7870475918719 0.994117517966782 -2.51076855310419 0.00565012165872164 81.000979087106 0.00326422724673561 -104.169497591935 + 0.0016119084585389 87.774126017455 0.00142699293933976 -92.3553618342317 + 0.994117517966782 -2.51076855310419 0.0113678976346174 59.7358044098844 0.0032640737871663 -104.144200107258 0.00564785149274055 80.6582823668774 + 0.00142686815907123 -92.3348823081675 0.00161414826780212 87.8310894361876 + 0.00565012165872164 81.000979087106 0.0032640737871663 -104.144200107258 0.0111682009748399 58.8914230738901 0.994058609617711 -2.51311602722144 + 0.00603335347179634 80.9287225506554 0.00353938982912266 -103.992114683378 + 0.00326422724673561 -104.169497591935 0.00564785149274055 80.6582823668774 0.994058609617711 -2.51311602722144 0.0111650501420472 58.8519029591919 + 0.00353929977573489 -103.977719526237 0.00603127383798196 80.7410070307306 + 0.0016119084585389 87.774126017455 0.00142686815907123 -92.3348823081675 0.00603335347179634 80.9287225506554 0.00353929977573489 -103.977719526237 + 0.0114063514328508 59.6751785691929 0.994082223842491 -2.51407857647956 + 0.00142699293933976 -92.3553618342317 0.00161414826780212 87.8310894361876 0.00353938982912266 -103.992114683378 0.00603127383798196 80.7410070307306 + 0.994082223842491 -2.51407857647956 0.011403214655668 59.6373676783848 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.00891250938133746 0.0123702288262876 61.1301115437126 0.993889057342035 -2.80395665311003 0.00631442584189433 81.3853124194542 0.00363281358071992 -103.395390563659 + 0.00183940069758539 88.1484161386896 0.00163077953876956 -91.9078458200808 + 0.993889057342035 -2.80395665311003 0.0123633957572533 61.0724075751633 0.00363254239448342 -103.366885365608 0.00630930302436868 81.0058246887706 + 0.0016305632668725 -91.8853706595645 0.00183956673269799 88.2184710824671 + 0.00631442584189433 81.3853124194542 0.00363254239448342 -103.366885365608 0.01212982980458 60.2338914286483 0.993825311194184 -2.80623281147719 + 0.00674220816616299 81.3285609626111 0.00393873437737318 -103.191079486601 + 0.00363281358071992 -103.395390563659 0.00630930302436868 81.0058246887706 0.993825311194184 -2.80623281147719 0.0121237292370948 60.187879038582 + 0.00393868085693605 -103.175351703025 0.00673710720722286 81.1212715444283 + 0.00183940069758539 88.1484161386896 0.0016305632668725 -91.8853706595645 0.00674220816616299 81.3285609626111 0.00393868085693605 -103.175351703025 + 0.0124028119417585 61.0574279668178 0.993861167575192 -2.80763342281113 + 0.00163077953876956 -91.9078458200808 0.00183956673269799 88.2184710824671 0.00393873437737318 -103.191079486601 0.00673710720722286 81.1212715444283 + 0.993861167575192 -2.80763342281113 0.012396415520198 61.0123100334056 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.01 0.0135566383948024 62.455397880063 0.993631628020784 -3.13623831993242 0.0070732640881459 81.3816399402078 0.00406464119975555 -103.243116461802 + 0.00208427475454753 87.0831533320632 0.00185055069102458 -93.0615218253211 + 0.993631628020784 -3.13623831993242 0.0135481954017211 62.4005260918701 0.0040643418856736 -103.209908234388 0.00706765491588225 80.9726523595835 + 0.00185030717697875 -93.034606082019 0.00208488286103406 87.2076662175039 + 0.0070732640881459 81.3816399402078 0.0040643418856736 -103.209908234388 0.0132799257407697 61.5509528276383 0.993556305969965 -3.13862562581239 + 0.00755350784390282 81.3039620751756 0.0044081855080817 -103.060354647951 + 0.00406464119975555 -103.243116461802 0.00706765491588225 80.9726523595835 0.993556305969965 -3.13862562581239 0.0132722775312442 61.5093037367567 + 0.00440809977645826 -103.043140030238 0.00754796668827354 81.0880802232298 + 0.00208427475454753 87.0831533320632 0.00185030717697875 -93.034606082019 0.00755350784390282 81.3039620751756 0.00440809977645826 -103.043140030238 + 0.0135960320972683 62.3722106255119 0.993598310115272 -3.14052322421106 + 0.00185055069102458 -93.0615218253211 0.00208488286103406 87.2076662175039 0.0044081855080817 -103.060354647951 0.00754796668827354 81.0880802232298 + 0.993598310115272 -3.14052322421106 0.0135881322957086 62.3328747088074 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0112201845430196 0.0148040187661864 63.6264283625416 0.993344486879934 -3.50375252447337 0.00790329539455951 81.3142611998341 0.00452628237508153 -103.17926594353 + 0.00233821295395378 86.3211925749743 0.00207736396702779 -93.8926880555149 + 0.993344486879934 -3.50375252447337 0.0147927933015816 63.5765506222883 0.00452582874784251 -103.141721245511 0.00790147435000498 80.9089902147982 + 0.00207593057637594 -93.8712373144493 0.0023388105531643 86.4670298241752 + 0.00790329539455951 81.3142611998341 0.00452582874784251 -103.141721245511 0.0145866375027376 62.6302416756578 0.993236438289119 -3.50875944960616 + 0.00843901043190073 81.2229239227436 0.00490693935832083 -103.027495119028 + 0.00452628237508153 -103.17926594353 0.00790147435000498 80.9089902147982 0.993236438289119 -3.50875944960616 0.0145035041277476 62.7640234780577 + 0.00490697910545627 -103.008299557942 0.00843261540907781 80.9846284602248 + 0.00233821295395378 86.3211925749743 0.00207593057637594 -93.8712373144493 0.00843901043190073 81.2229239227436 0.00490697910545627 -103.008299557942 + 0.0148444128093046 63.5670716484598 0.993313694732022 -3.50830619944492 + 0.00207736396702779 -93.8926880555149 0.0023388105531643 86.4670298241752 0.00490693935832083 -103.027495119028 0.00843261540907781 80.9846284602248 + 0.993313694732022 -3.50830619944492 0.0148325230855323 63.5209835390038 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0125892541179417 0.0161986528135762 64.6526813093145 0.993032976878045 -3.9145140712694 0.00882988568305035 81.1753237975132 0.00504124130463971 -103.21472575511 + 0.00262276136821123 85.5190735994445 0.00233134743358282 -94.7626068592694 + 0.993032976878045 -3.9145140712694 0.0161842334750619 64.6056641714289 0.00504061013410112 -103.17237724931 0.00883297391087036 80.755808544063 + 0.00232888353342387 -94.7464624671314 0.00262330296176819 85.6881695231279 + 0.00882988568305035 81.1753237975132 0.00504061013410112 -103.17237724931 0.0160473524385256 63.5017736317475 0.992879760143567 -3.92195885362819 + 0.00942760407821294 81.070946334044 0.00546319319771447 -103.083308286394 + 0.00504124130463971 -103.21472575511 0.00883297391087036 80.755808544063 0.992879760143567 -3.92195885362819 0.0158707545279352 63.8310882737436 + 0.00546335254780805 -103.061865880563 0.00942023522258511 80.8078461490607 + 0.00262276136821123 85.5190735994445 0.00232888353342387 -94.7464624671314 0.00942760407821294 81.070946334044 0.00546335254780805 -103.061865880563 + 0.016239900874155 64.6136191903542 0.993005751325056 -3.91941929331478 + 0.00233134743358282 -94.7626068592694 0.00262330296176819 85.6881695231279 0.00546319319771447 -103.083308286394 0.00942023522258511 80.8078461490607 + 0.993005751325056 -3.91941929331478 0.016224110565496 64.5631501684224 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0141253754462276 0.0177578791164449 65.542730027949 0.992697721497206 -4.37392052243246 0.00986429316322925 80.964284487784 0.0056158213644594 -103.352642254728 + 0.00294152407718861 84.6660445140696 0.00261570369724631 -95.6843728142246 + 0.992697721497206 -4.37392052243246 0.0177398485333343 65.496802624501 0.00561496962749594 -103.305007499545 0.00987327490055073 80.5116177304016 + 0.00261236571990985 -95.6717721272605 0.0029419391414877 84.8606651224872 + 0.00986429316322925 80.964284487784 0.00561496962749594 -103.305007499545 0.0176823534254253 64.1375424929657 0.992480873023849 -4.3834675542595 + 0.0105313859862365 80.8470226907139 0.00608389665937539 -103.231337080839 + 0.0056158213644594 -103.352642254728 0.00987327490055073 80.5116177304016 0.992480873023849 -4.3834675542595 0.0173897481723098 64.7176135693455 + 0.00608418223594644 -103.207252354838 0.0105229616659637 80.5564621508196 + 0.00294152407718861 84.6660445140696 0.00261236571990985 -95.6717721272605 0.0105313859862365 80.8470226907139 0.00608418223594644 -103.207252354838 + 0.0178005733235868 65.519784301177 0.992674517100877 -4.37930259842509 + 0.00261570369724631 -95.6843728142246 0.0029419391414877 84.8606651224872 0.00608389665937539 -103.231337080839 0.0105229616659637 80.5564621508196 + 0.992674517100877 -4.37930259842509 0.0177808341481276 65.4669673421887 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0158489319246111 0.0195019449732516 66.2997690591586 0.992337760066383 -4.88806393391376 0.0110190865248328 80.6792422631339 0.00625701908848658 -103.597808420831 + 0.00329849406716888 83.7508236588403 0.00293398630122487 -96.6712290827537 + 0.992337760066383 -4.88806393391376 0.0194798531625967 66.2534857616288 0.00625585927167974 -103.544244916324 0.0110347103007451 80.1739482491904 + 0.0029299152875974 -96.6594757880061 0.00329867589086705 83.973596743654 + 0.0110190865248328 80.6792422631339 0.00625585927167974 -103.544244916324 0.0195094261979859 64.4568631616108 0.992027328707565 -4.89898361574988 + 0.0117638753853973 80.548703564179 0.00677680223669597 -103.476998791973 + 0.00625701908848658 -103.597808420831 0.0110347103007451 80.1739482491904 0.992027328707565 -4.89898361574988 0.0190783266143482 65.4228183810542 + 0.00677725823745836 -103.449891908529 0.0117544422172903 80.2274941890746 + 0.00329849406716888 83.7508236588403 0.0029299152875974 -96.6594757880061 0.0117638753853973 80.548703564179 0.00677725823745836 -103.449891908529 + 0.0195472678051023 66.2879656729529 0.992318274917238 -4.8940796402633 + 0.00293398630122487 -96.6712290827537 0.00329867589086705 83.973596743654 0.00677680223669597 -103.476998791973 0.0117544422172903 80.2274941890746 + 0.992318274917238 -4.8940796402633 0.019523393472383 66.2344675087493 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0177827941003892 0.0214538867075269 66.9215942993168 0.991949987759764 -5.46377721981161 0.0123082203760694 80.3177617697151 0.00697257112896871 -103.955914524853 + 0.00369807904205284 82.7614905307678 0.00329012275877097 -97.7367844697139 + 0.991949987759764 -5.46377721981161 0.0214272213613278 66.8737831102382 0.00697092732402507 -103.895083246315 0.0123309753764086 79.7395045132953 + 0.00328543357372608 -97.7227649102541 0.00369786873666176 83.0154316924305 + 0.0123082203760694 80.3177617697151 0.00697092732402507 -103.895083246315 0.0215008400656003 64.2784113328371 0.991496592703687 -5.47373218373221 + 0.0131400886856953 80.1729085056706 0.0075504948408281 -103.826556070239 + 0.00697257112896871 -103.955914524853 0.0123309753764086 79.7395045132953 0.991496592703687 -5.47373218373221 0.020950825076998 65.9342841386413 + 0.00755124862573535 -103.796602879908 0.0131299894528301 79.8162519337225 + 0.00369807904205284 82.7614905307678 0.00328543357372608 -97.7227649102541 0.0131400886856953 80.1729085056706 0.00755124862573535 -103.796602879908 + 0.0215033907813829 66.9152591281134 0.991933070184317 -5.47059978575852 + 0.00329012275877097 -97.7367844697139 0.00369786873666176 83.0154316924305 0.0075504948408281 -103.826556070239 0.0131299894528301 79.8162519337225 + 0.991933070184317 -5.47059978575852 0.0214750556970054 66.8623931431062 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0199526231496888 0.0236392363595381 67.4014656403922 0.991528824716208 -6.10867956374064 0.013747801972292 79.8794581158934 0.0077712510809297 -104.431939534689 + 0.00414512420118279 81.6853385156993 0.00368843541204551 -98.895232421461 + 0.991528824716208 -6.10867956374064 0.0236073871996335 67.351179893754 0.00776895306543979 -104.360134519969 0.0137774520106423 79.2044305739912 + 0.00368320774902308 -98.8757826001653 0.00414428660532882 81.9739058210333 + 0.013747801972292 79.8794581158934 0.00776895306543979 -104.360134519969 0.0233925282215025 63.5563103569571 0.990907034311656 -6.10980822236178 + 0.0146773450278716 79.7185212954535 0.00841484330202298 -104.284379142194 + 0.0077712510809297 -104.431939534689 0.0137774520106423 79.2044305739912 0.990907034311656 -6.10980822236178 0.0229985624878637 66.2678629159991 + 0.00841599867663157 -104.254012524328 0.0146668692748544 79.3166297421962 + 0.00414512420118279 81.6853385156993 0.00368320774902308 -98.8757826001653 0.0146773450278716 79.7185212954535 0.00841599867663157 -104.254012524328 + 0.0236945913497572 67.3945359804871 0.991512471895248 -6.11648256966593 + 0.00368843541204551 -98.895232421461 0.00414428660532882 81.9739058210333 0.00841484330202298 -104.284379142194 0.0146668692748544 79.3166297421962 + 0.991512471895248 -6.11648256966593 0.0236613212517138 67.3433056049886 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0223872113856834 0.0260856243463297 67.7294974542474 0.991066151307404 -6.83122764856409 0.015359194659742 79.3554345793442 0.00866392936937546 -105.036634945184 + 0.00464490902061815 80.5086171290514 0.00413364661322192 -100.161609674748 + 0.991066151307404 -6.83122764856409 0.0260478481541062 67.6760001930539 0.00866161025563837 -104.950203684985 0.0153918863187031 78.5617854193078 + 0.00412791727872761 -100.133747922376 0.00464310958887975 80.8358827146227 + 0.015359194659742 79.3554345793442 0.00866161025563837 -104.950203684985 0.0249457154126463 63.9157573561394 0.990491288875662 -6.81675135855337 + 0.0163985598405917 79.1758625697796 0.00938287247239646 -104.863391667691 + 0.00866392936937546 -105.036634945184 0.0153918863187031 78.5617854193078 0.990491288875662 -6.81675135855337 0.0252399437371784 66.615903634284 + 0.00938361945395225 -104.834860936083 0.0163849186386451 78.7187610834969 + 0.00464490902061815 80.5086171290514 0.00412791727872761 -100.133747922376 0.0163985598405917 79.1758625697796 0.00938361945395225 -104.834860936083 + 0.0261483687531355 67.7159478105899 0.991047592662162 -6.84017033162287 + 0.00413364661322192 -100.161609674748 0.00464310958887975 80.8358827146227 0.00938287247239646 -104.863391667691 0.0163849186386451 78.7187610834969 + 0.991047592662162 -6.84017033162287 0.0261095287991533 67.66713335638 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0251188643150958 0.0288223643934275 67.8943295083831 0.990551536144103 -7.64078051929554 0.0171615838928882 78.7163601970897 0.00966106219690606 -105.793240061714 + 0.00520311915407605 79.2169882060349 0.00463087117156538 -101.551577114523 + 0.990551536144103 -7.64078051929554 0.0287777657892848 67.837033602258 0.00965929134959323 -105.696359999913 0.0171930078807504 77.8000417110952 + 0.00462462640313914 -101.512633138492 0.00519990993435534 79.5874379449605 + 0.0171615838928882 78.7163601970897 0.00965929134959323 -105.696359999913 0.0272419021327623 65.5025261180862 0.990148245131078 -7.6235924943514 + 0.0183242845780814 78.5148192338236 0.010466191199771 -105.596899867973 + 0.00966106219690606 -105.793240061714 0.0171930078807504 77.8000417110952 0.990148245131078 -7.6235924943514 0.0278263549451513 66.9082105987844 + 0.0104657422638973 -105.564265715318 0.0183048963227127 78.007889255774 + 0.00520311915407605 79.2169882060349 0.00462462640313914 -101.512633138492 0.0183242845780814 78.5148192338236 0.0104657422638973 -105.564265715318 + 0.0288936906984889 67.8686155487778 0.990527385997684 -7.65099628251438 + 0.00463087117156538 -101.551577114523 0.00519990993435534 79.5874379449605 0.010466191199771 -105.596899867973 0.0183048963227127 78.007889255774 + 0.990527385997684 -7.65099628251438 0.0288484875630643 67.8228061609806 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0281838293126446 0.0318802186115964 67.8845240954067 0.989972656740879 -8.54768716639657 0.0191725412064829 77.9581207342651 0.0107730311176708 -106.710566637398 + 0.00582588199319673 77.7952021897616 0.00518564312334493 -103.081720973761 + 0.989972656740879 -8.54768716639657 0.0318276798966201 67.8229380883342 0.0107714781820612 -106.604508079865 0.019201133286881 76.9110136073028 + 0.00517880787768211 -103.029386354973 0.00582063520043877 78.213638017048 + 0.0191725412064829 77.9581207342651 0.0107714781820612 -106.604508079865 0.0302799820494431 66.3016579074383 0.989620806531353 -8.53342891961328 + 0.0204732836385132 77.7305492818158 0.0116753418533172 -106.492869262247 + 0.0107730311176708 -106.710566637398 0.019201133286881 76.9110136073028 0.989620806531353 -8.53342891961328 0.0307615562951802 66.9312705797126 + 0.0116738537683403 -106.452898326433 0.0204489817600168 77.172911681741 + 0.00582588199319673 77.7952021897616 0.00517880787768211 -103.029386354973 0.0204732836385132 77.7305492818158 0.0116738537683403 -106.452898326433 + 0.031960823911468 67.841942658509 0.989939106594368 -8.55927669952766 + 0.00518564312334493 -103.081720973761 0.00582063520043877 78.213638017048 0.0116753418533172 -106.492869262247 0.0204489817600168 77.172911681741 + 0.989939106594368 -8.55927669952766 0.0319082483734329 67.7995640416264 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0316227766016838 0.0352912381873229 67.6894413300013 0.989315868369903 -9.56339713792369 0.0214157152961767 77.0742395804286 0.0120126833398973 -107.800009661696 + 0.00651967956872597 76.2265098969828 0.00580387102983936 -104.769956714405 + 0.989315868369903 -9.56339713792369 0.0352293462969706 67.6231977314318 0.0120110997573862 -107.683190855662 0.0214394592475379 75.8836454510347 + 0.0057962926481968 -104.70227761697 0.00651152881270679 76.6982913442204 + 0.0214157152961767 77.0742395804286 0.0120110997573862 -107.683190855662 0.0337052680756472 66.4231853362485 0.98894343719849 -9.55129382113862 + 0.0228707260021903 76.8159423623526 0.0130244829422531 -107.561459933886 + 0.0120126833398973 -107.800009661696 0.0214394592475379 75.8836454510347 0.98894343719849 -9.55129382113862 0.0340360020028127 66.7128786346105 + 0.0130219540939626 -107.513595203149 0.0228420460367646 76.2004802272784 + 0.00651967956872597 76.2265098969828 0.0057962926481968 -104.70227761697 0.0228707260021903 76.8159423623526 0.0130219540939626 -107.513595203149 + 0.035381237769772 67.6263451206941 0.989268891482697 -9.57642619034853 + 0.00580387102983936 -104.769956714405 0.00651152881270679 76.6982913442204 0.0130244829422531 -107.561459933886 0.0228420460367646 76.2004802272784 + 0.989268891482697 -9.57642619034853 0.0353200048391463 67.5877643229792 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0354813389233575 0.0390888160859497 67.2997119440537 0.988566883553107 -10.7006035319578 0.023916478906171 76.0508196194545 0.0133938319273104 -109.078377925246 + 0.00729124581367162 74.4927721045317 0.00649178655429395 -106.635488810485 + 0.988566883553107 -10.7006035319578 0.039015779423463 67.2285808607123 0.0133920960435916 -108.948818396364 0.0239331154913384 74.7035029237036 + 0.00648320845486049 -106.550826718173 0.00727902005538458 75.0238965972155 + 0.023916478906171 76.0508196194545 0.0133920960435916 -108.948818396364 0.0374763226113631 66.1456618187525 0.988140174949704 -10.6895228514093 + 0.0255435240574767 75.7565757826444 0.0145287347801738 -108.820078863443 + 0.0133938319273104 -109.078377925246 0.0239331154913384 74.7035029237036 0.988140174949704 -10.6895228514093 0.0376771785391765 66.2770527843691 + 0.0145249245053154 -108.763902957071 0.0255105438979822 75.0747778673096 + 0.00729124581367162 74.4927721045317 0.00648320845486049 -106.550826718173 0.0255435240574767 75.7565757826444 0.0145249245053154 -108.763902957071 + 0.0391877233383277 67.2135841781693 0.988502429836049 -10.7151057201109 + 0.00649178655429395 -106.635488810485 0.00727902005538458 75.0238965972155 0.0145287347801738 -108.820078863443 0.0255105438979822 75.0747778673096 + 0.988502429836049 -10.7151057201109 0.0391162048405548 67.179180254846 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0398107170553497 0.0433079905417253 66.7070956021222 0.987711399602461 -11.9734228253979 0.0267011474924026 74.8720316538796 0.0149309692383597 -110.564640423091 + 0.00814743349388253 72.5742373943026 0.00725587521386862 -108.698982359002 + 0.987711399602461 -11.9734228253979 0.0432215240573444 66.6310106922347 0.0149290033702962 -110.420273238138 0.0267088725550616 73.3538154090979 + 0.00724589477669471 -108.595950789834 0.00812956508200236 73.1714707961023 + 0.0267011474924026 74.8720316538796 0.0149290033702962 -110.420273238138 0.0416249491533975 65.574599472043 0.987206407287461 -11.9625552185256 + 0.0285194910317916 74.5361884072915 0.0162037388007434 -110.287928181526 + 0.0149309692383597 -110.564640423091 0.0267088725550616 73.3538154090979 0.987206407287461 -11.9625552185256 0.0417189313635534 65.6261763770156 + 0.0161982200471633 -110.222797122821 0.0284821683899601 73.7786939294129 + 0.00814743349388253 72.5742373943026 0.00724589477669471 -108.595950789834 0.0285194910317916 74.5361884072915 0.0161982200471633 -110.222797122821 + 0.0434147615376679 66.5964872154423 0.987625546127975 -11.9894074594479 + 0.00725587521386862 -108.698982359002 0.00812956508200236 73.1714707961023 0.0162037388007434 -110.287928181526 0.0284821683899601 73.7786939294129 + 0.987625546127975 -11.9894074594479 0.0433308905003261 66.5667171262327 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0446683592150963 0.0479859492093729 65.903782283274 0.986735511794736 -13.3976136049299 0.0297967909355618 73.5210288774811 0.0166391463581179 -112.279398794242 + 0.00909501427622015 70.449249210387 0.00810276869442312 -110.98277648615 + 0.986735511794736 -13.3976136049299 0.0478831242065199 65.8228857491783 0.0166368827616137 -112.11802037117 0.0297947821963673 71.8156625548122 + 0.00809077216425176 -110.860153176184 0.00906941458152612 71.1203510863355 + 0.0297967909355618 73.5210288774811 0.0166368827616137 -112.11802037117 0.04619108476917 64.7445785206452 0.986127431573353 -13.3862717495275 + 0.0318271348568703 73.1375562692344 0.0180656107192132 -111.985165990004 + 0.0166391463581179 -112.279398794242 0.0297947821963673 71.8156625548122 0.986127431573353 -13.3862717495275 0.0461952827887227 64.7552413452445 + 0.0180577547360104 -111.910205142805 0.0317854718478419 72.2939647102397 + 0.00909501427622015 70.449249210387 0.00809077216425176 -110.860153176184 0.0318271348568703 73.1375562692344 0.0180577547360104 -111.910205142805 + 0.0480990762640366 65.7681309163039 0.986624527705795 -13.4150776522675 + 0.00810276869442312 -110.98277648615 0.00906941458152612 71.1203510863355 0.0180656107192132 -111.985165990004 0.0317854718478419 72.2939647102397 + 0.986624527705795 -13.4150776522675 0.0480002224025377 65.7435984123191 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0501187233627272 0.0531626159895489 64.8812197441301 0.9856256960536 -14.9908318826749 0.0332307108565901 71.9799527689871 0.0185337140954464 -114.244880798542 + 0.0101403971321093 68.0939410659367 0.00903908903801329 -113.511111177847 + 0.9856256960536 -14.9908318826749 0.053039670804101 64.7959226684282 0.0185310827465315 -114.064082372233 0.0332195726089442 70.0680288699693 + 0.00902415470483395 -113.367717164751 0.0101042847148023 68.8479802275245 + 0.0332307108565901 71.9799527689871 0.0185310827465315 -114.064082372233 0.0512140354213089 63.6646116604115 0.984885357314167 -14.9782052184973 + 0.0354950949370877 71.5424430627275 0.0201307327047248 -113.933003126523 + 0.0185337140954464 -114.244880798542 0.0332195726089442 70.0680288699693 0.984885357314167 -14.9782052184973 0.0511401043622203 63.6565186878172 + 0.0201196501850227 -113.847109735685 0.0354492402231502 70.601072612437 + 0.0101403971321093 68.0939410659367 0.00902415470483395 -113.367717164751 0.0354950949370877 71.5424430627275 0.0201196501850227 -113.847109735685 + 0.0532802372950974 64.7205795681067 0.985485978576584 -15.0097737894903 + 0.00903908903801329 -113.511111177847 0.0101042847148023 68.8479802275245 0.0201307327047248 -113.933003126523 0.0354492402231502 70.601072612437 + 0.985485978576584 -15.0097737894903 0.0531630513940437 64.702105339755 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0562341325190349 0.0588810449912191 63.6286035721641 0.98436815014262 -16.772911996226 0.0370295712699872 70.2298116121378 0.0206299180098752 -116.485014241905 + 0.0112892381312851 65.4819295137642 0.0100712260923484 -116.310362598543 + 0.98436815014262 -16.772911996226 0.058733154835267 63.5396540470541 0.0206268435394837 -116.282123460927 0.0370117531433013 68.0878118463945 + 0.0100519859289899 -116.144894022904 0.0112388969843137 66.3296714010944 + 0.0370295712699872 70.2298116121378 0.0206268435394837 -116.282123460927 0.0567323559872208 62.3328813862094 0.983461191924603 -16.7578538551479 + 0.0395512056746043 69.731413099135 0.0224153906079974 -116.153938430725 + 0.0206299180098752 -116.485014241905 0.0370117531433013 68.0878118463945 0.983461191924603 -16.7578538551479 0.0565875119195832 62.3201699876864 + 0.0223998366939563 -116.055757279547 0.0395015543713563 68.6790550102332 + 0.0112892381312851 65.4819295137642 0.0100519859289899 -116.144894022904 0.0395512056746043 69.731413099135 0.0223998366939563 -116.055757279547 + 0.0590010147674363 63.4433253012765 0.984196002121142 -16.7933432206779 + 0.0100712260923484 -116.310362598543 0.0112388969843137 66.3296714010944 0.0224153906079974 -116.153938430725 0.0395015543713563 68.6790550102332 + 0.984196002121142 -16.7933432206779 0.0588612403608088 63.4320153705794 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0630957344480193 0.065187148681184 62.1312592606222 0.9829473980792 -18.766151924013 0.0412181163057418 68.2503319691531 0.0229423120009277 -119.025521298467 + 0.012545901082009 62.5840193984832 0.0112050191420191 -119.409263856185 + 0.9829473980792 -18.766151924013 0.0650081565439393 62.0398058010941 0.0229387166128606 -118.79754976375 0.0411983389593764 65.8497690966461 + 0.0111794690360054 -119.220061827104 0.0124763407323728 63.5383526391371 + 0.0412181163057418 68.2503319691531 0.0229387166128606 -118.79754976375 0.0627844915406676 60.7409491836173 0.981834881200555 -18.7470105528487 + 0.0440211130296139 67.6836083483181 0.0249352322046016 -118.672012461107 + 0.0229423120009277 -119.025521298467 0.0411983389593764 65.8497690966461 0.981834881200555 -18.7470105528487 0.0625720113626472 60.7333564248794 + 0.024913470531356 -118.559883514719 0.043968433929626 66.5052554158238 + 0.012545901082009 62.5840193984832 0.0111794690360054 -119.220061827104 0.0440211130296139 67.6836083483181 0.024913470531356 -118.559883514719 + 0.0653069929001469 61.9216710730537 0.98273865415658 -18.7881004183391 + 0.0112050191420191 -119.409263856185 0.0124763407323728 63.5383526391371 0.0249352322046016 -118.672012461107 0.043968433929626 66.5052554158238 + 0.98273865415658 -18.7881004183391 0.0651392455158038 61.9189785471545 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0707945784384137 0.0721281113137147 60.3692427211377 0.981344318392192 -20.9955746094684 0.0458173549616788 66.0198120570418 0.0254839295117014 -121.89398584979 + 0.0139127131991757 59.3679340170197 0.0124453013291405 -122.839065439439 + 0.981344318392192 -20.9955746094684 0.0719102241881745 60.276875789676 0.0254797419553593 -121.637578270451 0.0458030652080317 63.3264044147254 + 0.0124105512751682 -122.623815757415 0.0138171996848676 60.4442959810132 + 0.0458173549616788 66.0198120570418 0.0254797419553593 -121.637578270451 0.0694085524912616 58.8742488016621 0.979984050251614 -20.9700817464963 + 0.0489263103053137 65.3765135304052 0.0277044929928693 -121.513027012139 + 0.0254839295117014 -121.89398584979 0.0458030652080317 63.3264044147254 0.979984050251614 -20.9700817464963 0.0691277313820448 58.8787824418212 + 0.0276741083548487 -121.384901929227 0.0488719248131517 64.055035538389 + 0.0139127131991757 59.3679340170197 0.0124105512751682 -122.623815757415 0.0489263103053137 65.3765135304052 0.0276741083548487 -121.384901929227 + 0.0722447905712644 60.1353881906703 0.981093882947932 -21.0190741106096 + 0.0124453013291405 -122.839065439439 0.0138171996848676 60.4442959810132 0.0277044929928693 -121.513027012139 0.0488719248131517 64.055035538389 + 0.981093882947932 -21.0190741106096 0.0720423059555492 60.1431617078523 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0794328234724282 0.0797487805442619 58.3165309195863 0.979534126595947 -23.489138702628 0.05084206048565 63.5149989458895 0.0282651386451472 -125.119824995112 + 0.0153889452738889 55.798075966672 0.0137952530201948 -126.633561744001 + 0.979534126595947 -23.489138702628 0.0794822320467687 58.2252843224736 0.0282603103734344 -124.831207201566 0.0508439295575341 60.4878078320313 + 0.0137472103481842 -126.388929075132 0.0152583734166925 57.0148381601301 + 0.05084206048565 63.5149989458895 0.0282603103734344 -124.831207201566 0.0766402842019998 56.7113857715565 0.977881902892889 -23.4543607353079 + 0.0542814155007879 62.7857216145579 0.0307349193734532 -124.704677824755 + 0.0282651386451472 -125.119824995112 0.0508439295575341 60.4878078320313 0.977881902892889 -23.4543607353079 0.0762858606097799 56.7332553452151 + 0.0306925655154297 -124.557997171291 0.0542274579380845 61.3014558106998 + 0.0153889452738889 55.798075966672 0.0137472103481842 -126.388929075132 0.0542814155007879 62.7857216145579 0.0306925655154297 -124.557997171291 + 0.0798582026078193 58.0580115554229 0.979235545837369 -23.5141992446143 + 0.0137952530201948 -126.633561744001 0.0152583734166925 57.0148381601301 0.0307349193734532 -124.704677824755 0.0542274579380845 61.3014558106998 + 0.979235545837369 -23.5141992446143 0.0796125528465623 58.0785237412208 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.0891250938133746 0.0880854860632431 55.9411046394166 0.977485221942095 -26.2778882371445 0.056297409374556 60.7110029501055 0.0312921083408176 -128.734083714894 + 0.0169694361201995 51.8353155679126 0.01525550144121 -130.828877271734 + 0.977485221942095 -26.2778882371445 0.0877581521207389 55.8534056157212 0.0312866382482758 -128.409006845654 0.056329884047806 57.3014625291377 + 0.0151884798498771 -130.550091921175 0.0167915186358733 53.2140927263048 + 0.056297409374556 60.7110029501055 0.0312866382482758 -128.409006845654 0.0845082562044163 54.2234919879108 0.975495114120911 -26.2302162823075 + 0.0600904678581238 59.8847036609155 0.0340343069196816 -128.276542175442 + 0.0312921083408176 -128.734083714894 0.056329884047806 57.3014625291377 0.975495114120911 -26.2302162823075 0.0840692724120402 54.2668235350571 + 0.0339753746974646 -128.108059779856 0.0600402670523099 58.2149159884469 + 0.0169694361201995 51.8353155679126 0.0151884798498771 -130.550091921175 0.0600904678581238 59.8847036609155 0.0339753746974646 -128.108059779856 + 0.088181752893208 55.6570516754923 0.97713045495193 -26.3044466717086 + 0.01525550144121 -130.828877271734 0.0167915186358733 53.2140927263048 0.0340343069196816 -128.276542175442 0.0600402670523099 58.2149159884469 + 0.97713045495193 -26.3044466717086 0.0878825191485712 55.6930048867252 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.1 0.0971571429769542 53.2060075371856 0.975160031419034 -29.3960624039433 0.0621745662045286 57.5812503828366 0.0345648301946941 -132.768968312247 + 0.0186427821348224 47.4367939652631 0.016822904267142 -135.462866733113 + 0.975160031419034 -29.3960624039433 0.0967540683852383 53.1245835011288 0.0345587995815713 -132.402644941455 0.0622564935211429 53.7320102795013 + 0.0167291450529433 -135.143284032045 0.0184010362618956 49.0026325135041 + 0.0621745662045286 57.5812503828366 0.0345587995815713 -132.402644941455 0.0930254496914378 51.3744232786488 0.972783162828828 -29.3311767894969 + 0.0663419661456153 56.6445820769199 0.037604560684559 -132.259845993459 + 0.0345648301946941 -132.768968312247 0.0622564935211429 53.7320102795013 0.972783162828828 -29.3311767894969 0.092483527030571 51.443017388715 + 0.0375227534846448 -132.065380627224 0.0663005986168034 54.7627319394163 + 0.0186427821348224 47.4367939652631 0.0167291450529433 -135.143284032045 0.0663419661456153 56.6445820769199 0.0375227534846448 -132.065380627224 + 0.097231566945591 52.895180747298 0.974739599468929 -29.423916095975 + 0.016822904267142 -135.462866733113 0.0184010362618956 49.0026325135041 0.037604560684559 -132.259845993459 0.0663005986168034 54.7627319394163 + 0.974739599468929 -29.423916095975 0.0968659365255693 52.9496974069016 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.112201845430197 0.106954081091915 50.0711283132256 0.972518866562118 -32.8812286235464 0.0684450023473413 54.0974701676438 0.0380746799256386 -137.257024657366 + 0.0203890318869972 42.555716522276 0.0184889723748332 -140.573927630788 + 0.972518866562118 -32.8812286235464 0.106456837608145 49.9989092886186 0.0380683008223068 -136.844049842333 0.0686003853627699 49.740932383071 + 0.0183580479793923 -140.204551962441 0.0200615384860267 44.3370860900689 + 0.0684450023473413 54.0974701676438 0.0380683008223068 -136.844049842333 0.10217703505294 48.1222201966577 0.969701039885485 -32.7939417338497 + 0.0730023060672703 53.0339150960632 0.0414391810738213 -136.686886517058 + 0.0380746799256386 -137.257024657366 0.0686003853627699 49.740932383071 0.969701039885485 -32.7939417338497 0.101504153611557 48.220488073361 + 0.04132599140559 -136.460973162602 0.0729773701255386 50.9086191877808 + 0.0203890318869972 42.555716522276 0.0183580479793923 -140.204551962441 0.0730023060672703 53.0339150960632 0.04132599140559 -136.460973162602 + 0.106994052493022 49.732123973035 0.972022550585452 -32.9099602348348 + 0.0184889723748332 -140.573927630788 0.0200615384860267 44.3370860900689 0.0414391810738213 -136.686886517058 0.0729773701255386 50.9086191877808 + 0.972022550585452 -32.9099602348348 0.106546278918297 49.8087454906265 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.125892541179417 0.117425560301628 46.4950926318032 0.9695272202416 -36.7745418207094 0.0750533267805734 50.2297248911493 0.0418015803424654 -142.229829704977 + 0.0221768744038803 37.141095993983 0.0202379366068534 -146.198922769664 + 0.9695272202416 -36.7745418207094 0.116811335281971 46.4351835114726 0.0417952655163795 -141.764077042773 0.0753123297527714 45.2860626988387 + 0.0200559806558027 -145.767810252606 0.0217347409660518 39.1695615600566 + 0.0750533267805734 50.2297248911493 0.0417952655163795 -141.764077042773 0.111905218499707 44.4217489320677 0.966207192153991 -36.6584332249111 + 0.0800072266336871 49.0185292891813 0.0455201166387815 -141.589887674043 + 0.0418015803424654 -142.229829704977 0.0753123297527714 45.2860626988387 0.966207192153991 -36.6584332249111 0.11106131332553 44.5558641836969 + 0.0453642139992613 -141.325290033106 0.0800098468630777 46.6120634508869 + 0.0221768744038803 37.141095993983 0.0200559806558027 -145.767810252606 0.0800072266336871 49.0185292891813 0.0453642139992613 -141.325290033106 + 0.117413402522126 46.126643511515 0.968945448824722 -36.8034486402195 + 0.0202379366068534 -146.198922769664 0.0217347409660518 39.1695615600566 0.0455201166387815 -141.589887674043 0.0800098468630777 46.6120634508869 + 0.968945448824722 -36.8034486402195 0.116864045796983 46.2293824169253 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.141253754462276 0.128466988840435 42.4364105252076 0.966165898805274 -41.1212503286885 0.0819084377067443 45.9465435307717 0.0457109881591201 -147.715983907473 + 0.023960413898573 31.1373694156899 0.0220445875678306 -152.369708685178 + 0.966165898805274 -41.1212503286885 0.127707339218587 42.3922298112038 0.0457054644665232 -147.190466448115 0.082308813151317 40.3208057103369 + 0.0217932692923834 -151.861014135324 0.023365739886897 33.4468596765384 + 0.0819084377067443 45.9465435307717 0.0457054644665232 -147.190466448115 0.122093284792658 40.2278044912835 0.962277480270276 -40.9680909165444 + 0.0872509246015614 44.5614752972648 0.0498140945963228 -146.998925375938 + 0.0457109881591201 -147.715983907473 0.082308813151317 40.3208057103369 0.962277480270276 -40.9680909165444 0.121024253742784 40.4069965885634 + 0.0496006641950492 -146.685955597023 0.0872968617342476 41.8275657150616 + 0.023960413898573 31.1373694156899 0.0217932692923834 -151.861014135324 0.0872509246015614 44.5614752972648 0.0496006641950492 -146.685955597023 + 0.128379023289852 42.0377634215033 0.965491906020126 -41.1492990942417 + 0.0220445875678306 -152.369708685178 0.023365739886897 33.4468596765384 0.0498140945963228 -146.998925375938 0.0872968617342476 41.8275657150616 + 0.965491906020126 -41.1492990942417 0.127703906855761 42.1712704863254 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.158489319246111 0.139907008349828 37.8530496596087 0.962442238976933 -45.9715429955722 0.0888729196972309 41.2152898688104 0.0497512555542724 -153.73807602759 + 0.0256758391386107 24.4836762582257 0.0238723488000686 -159.107440598432 + 0.962442238976933 -45.9715429955722 0.138966348152323 37.8287203359636 0.0497477713983808 -153.14477167133 0.0894620126056464 34.7928701796943 + 0.0235275083063971 -158.499629769781 0.0248787329162743 27.1097399515137 + 0.0888729196972309 41.2152898688104 0.0497477713983808 -153.14477167133 0.132551619917008 35.4973562799873 0.957923653485138 -45.7706671798076 + 0.0945727711398509 39.6231933135354 0.0542689997547035 -152.93845196296 + 0.0497512555542724 -153.73807602759 0.0894620126056464 34.7928701796943 0.957923653485138 -45.7706671798076 0.131188519351058 35.7351474625174 + 0.0539791163580789 -152.564015236055 0.0946831865355869 36.5036771480006 + 0.0256758391386107 24.4836762582257 0.0235275083063971 -158.499629769781 0.0945727711398509 39.6231933135354 0.0539791163580789 -152.564015236055 + 0.139713165269835 37.4243840922058 0.961674925148636 -45.9973801866972 + 0.0238723488000686 -159.107440598432 0.0248787329162743 27.1097399515137 0.0542689997547035 -152.93845196296 0.0946831865355869 36.5036771480006 + 0.961674925148636 -45.9973801866972 0.138882088490658 37.5942946151674 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.177827941003892 0.151492653298904 32.6999917083792 0.958400107961538 -51.3817568909474 0.0957507728562375 36.0029800566318 0.0538525186827876 -160.308180354347 + 0.0272386781886292 17.1120414125222 0.0256729018982888 -166.413733466427 + 0.958400107961538 -51.3817568909474 0.150326756489156 32.7010090388063 0.0538532501795151 -159.637864442496 0.0965881342101974 28.6422071236745 + 0.0252028403374879 -165.67610743993 0.0261728698405444 20.0931043162529 + 0.0957507728562375 36.0029800566318 0.0538532501795151 -159.637864442496 0.143007449568804 30.1893211091362 0.953211952381445 -51.1197319287776 + 0.101742143713207 34.1619305174727 0.0588117777565914 -159.422064811715 + 0.0538525186827876 -160.308180354347 0.0965881342101974 28.6422071236745 0.953211952381445 -51.1197319287776 0.141267425099547 30.5044243826952 + 0.0584219584287265 -158.968283363216 0.101942982420704 30.5813447789308 + 0.0272386781886292 17.1120414125222 0.0252028403374879 -165.67610743993 0.101742143713207 34.1619305174727 0.0584219584287265 -158.968283363216 + 0.151157011930531 32.2427846861777 0.957547278577008 -51.4038103093582 + 0.0256729018982888 -166.413733466427 0.0261728698405444 20.0931043162529 0.0588117777565914 -159.422064811715 0.101942982420704 30.5813447789308 + 0.957547278577008 -51.4038103093582 0.150132446443868 32.4562892196555 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.199526231496888 0.16286826505561 26.9250601569069 0.954127294160553 -57.41587690307 0.102273487965827 30.2777323997925 0.0579291800558089 -167.421404233615 + 0.0285426219288766 8.94218869808316 0.0273902116926374 -174.259601297558 + 0.954127294160553 -57.41587690307 0.161423188551297 26.9591567695821 0.0579380043509873 -166.663662329081 0.103433988583882 21.7976319942231 + 0.0267539155189435 -173.345769673354 0.027121093866476 12.326795407703 + 0.102273487965827 30.2777323997925 0.0579380043509873 -166.663662329081 0.153096362655495 24.2605783648261 0.948275750904216 -57.0769060506476 + 0.108442356882075 28.1344351838949 0.0633506932783353 -166.446148087562 + 0.0579291800558089 -167.421404233615 0.103433988583882 21.7976319942231 0.948275750904216 -57.0769060506476 0.15088473521957 24.6772529430316 + 0.062832875159514 -165.888288598734 0.10876215501161 23.989544503325 + 0.0285426219288766 8.94218869808316 0.0267539155189435 -173.345769673354 0.108442356882075 28.1344351838949 0.062832875159514 -165.888288598734 + 0.162350691864684 26.4422382418181 0.95320871230497 -57.4325769528309 + 0.0273902116926374 -174.259601297558 0.027121093866476 12.326795407703 0.0633506932783353 -166.446148087562 0.10876215501161 23.989544503325 + 0.95320871230497 -57.4325769528309 0.161086712930977 26.7089163211189 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.223872113856834 0.173542370410641 20.4641652722913 0.949761508292496 -64.1472592216854 0.108084030973637 24.0106048496366 0.0618892406400937 -175.047313381897 + 0.029459997350257 -0.1310262213917 0.028971357918755 177.420852844693 + 0.949761508292496 -64.1472592216854 0.171753930287594 20.5422261851747 0.0619130724441047 -174.191002884146 0.109661076380808 14.1713781479312 + 0.0281177239854915 178.584997118208 0.0275764664938816 3.72450988910984 + 0.108084030973637 24.0106048496366 0.0619130724441047 -174.191002884146 0.162347717071783 17.6581663090891 0.943318155688285 -63.7145472673397 + 0.11425292087635 21.4964610140276 0.0677911232335051 -173.986866694786 + 0.0618892406400937 -175.047313381897 0.109661076380808 14.1713781479312 0.943318155688285 -63.7145472673397 0.159557397128181 18.2058922497696 + 0.0671136176772143 -173.290289135547 0.114742974217376 16.6377340910469 + 0.029459997350257 -0.1310262213917 0.0281177239854915 178.584997118208 0.11425292087635 21.4964610140276 0.0671136176772143 -173.290289135547 + 0.172800666982337 19.9599355143404 0.948811277679776 -64.157350112477 + 0.028971357918755 177.420852844693 0.0275764664938816 3.72450988910984 0.0677911232335051 -173.986866694786 0.114742974217376 16.6377340910469 + 0.948811277679776 -64.157350112477 0.171240760429979 20.2927101714037 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.251188643150958 0.182838454117438 13.2375711117401 0.945498633821158 -71.6607339982294 0.112718680606568 17.17665079261 0.0656567648077118 176.878804013969 + 0.0298427559706626 -10.2620922086299 0.0303816805744645 168.72441550592 + 0.945498633821158 -71.6607339982294 0.180631849371165 13.3745530670088 0.065706721359577 177.845160954683 0.114826772534934 5.65016198273101 + 0.0292502909482954 170.262132688663 0.0273827557998562 -5.87536163167521 + 0.112718680606568 17.17665079261 0.065706721359577 177.845160954683 0.170150351089766 10.3091051768389 0.938603342717123 -71.118551151248 + 0.118633194655204 14.2009236838845 0.0720898526764615 178.022124238468 + 0.0656567648077118 176.878804013969 0.114826772534934 5.65016198273101 0.938603342717123 -71.118551151248 0.166657758896283 11.0200291800605 + 0.0712212581911044 178.90594214076 0.119390795784586 8.45693729509599 + 0.0298427559706626 -10.2620922086299 0.0292502909482954 170.262132688663 0.118633194655204 14.2009236838845 0.0712212581911044 178.90594214076 + 0.181828769769694 12.7166606484382 0.944563432682101 -71.6636122664739 + 0.0303816805744645 168.72441550592 0.0273827557998562 -5.87536163167521 0.0720898526764615 178.022124238468 0.119390795784586 8.45693729509599 + 0.944563432682101 -71.6636122664739 0.179905405236419 13.1309621779893 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.281838293126445 0.18983095787447 5.14820313387902 0.941603843278391 -80.0556630413001 0.115589393426029 9.75498802356865 0.0692181046431333 168.462681329628 + 0.0295274913297193 -21.7020740573387 0.0316217266598031 159.794478241172 + 0.941603843278391 -80.0556630413001 0.187119715331603 5.36408620466209 0.0693097145811466 169.548931076306 0.118363580200698 -3.9187988034538 + 0.0301503500391205 161.903282347855 0.0263658860164379 -16.7952810341569 + 0.115589393426029 9.75498802356865 0.0693097145811466 169.548931076306 0.175691582961008 2.11171961449647 0.934451328123402 -79.3918909553745 + 0.120888662339936 6.2012233988248 0.0762518028637238 169.702935377645 + 0.0692181046431333 168.462681329628 0.118363580200698 -3.9187988034538 0.934451328123402 -79.3918909553745 0.171350576009872 3.02372440582905 + 0.0751698229888772 170.841368223776 0.121919440508051 -0.677660405713323 + 0.0295274913297193 -21.7020740573387 0.0301503500391205 161.903282347855 0.120888662339936 6.2012233988248 0.0751698229888772 170.841368223776 + 0.188508049382877 4.61484423160055 0.940740645937476 -80.0522064668953 + 0.0316217266598031 159.794478241172 0.0263658860164379 -16.7952810341569 0.0762518028637238 169.702935377645 0.121919440508051 -0.677660405713323 + 0.940740645937476 -80.0522064668953 0.186150256792142 5.13188114226705 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.316227766016838 0.193275632914982 -3.91814541669157 0.938415092741345 -89.450820912821 0.115962470753005 1.73416134902365 0.0726987201345983 159.843772085473 + 0.0283344611985184 -34.9084141443049 0.0327623193505226 150.850022607045 + 0.938415092741345 -89.450820912821 0.189956060736457 -3.59697208352952 0.0728542716580427 161.055208768052 0.119548770604218 -14.7540808340176 + 0.0309128909315397 153.838427910742 0.0243062140163838 -29.657210016556 + 0.115962470753005 1.73416134902365 0.0728542716580427 161.055208768052 0.177864875585177 -7.06618449822582 0.93123850175312 -88.6589253216471 + 0.120116588400979 -2.56436421598584 0.0804428531527706 161.163815135872 + 0.0726987201345983 159.843772085473 0.119548770604218 -14.7540808340176 0.93123850175312 -88.6589253216471 0.172474771252654 -5.90315573546652 + 0.0791509292909507 162.643327623643 0.121469991228893 -10.9894266177132 + 0.0283344611985184 -34.9084141443049 0.0309128909315397 153.838427910742 0.120116588400979 -2.56436421598584 0.0791509292909507 162.643327623643 + 0.191587489424113 -4.45930363585873 0.937691371132005 -89.4441792438909 + 0.0327623193505226 150.850022607045 0.0243062140163838 -29.657210016556 0.0804428531527706 161.163815135872 0.121469991228893 -10.9894266177132 + 0.937691371132005 -89.4441792438909 0.188711097598595 -3.80958617600111 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.354813389233576 0.191549457336787 -14.0916175107876 0.936310487072272 -99.9915941741072 0.112918436567134 -6.86120340212875 0.0764906079987619 151.152994255076 + 0.0260543552892051 -50.7755528046446 0.0340517971029146 142.155679872536 + 0.936310487072272 -99.9915941741072 0.187481502880527 -13.627709434098 0.0767381119387532 152.485618799724 0.117462735994297 -27.1870552033685 + 0.0318607775549643 146.450449215971 0.0209752061977208 -45.7890130005805 + 0.112918436567134 -6.86120340212875 0.0767381119387532 152.485618799724 0.175174604034472 -17.3842452353053 0.929361869316205 -99.073250064998 + 0.115172437629394 -12.1584116581387 0.0851179295353319 152.484044555007 + 0.0764906079987619 151.152994255076 0.117462735994297 -27.1870552033685 0.929361869316205 -99.073250064998 0.168455756094543 -15.8936827911862 + 0.0836832578248072 154.401924362242 0.116961398102155 -22.7880012481223 + 0.0260543552892051 -50.7755528046446 0.0318607775549643 146.450449215971 0.115172437629394 -12.1584116581387 0.0836832578248072 154.401924362242 + 0.189422939323646 -14.633518562048 0.935793423196069 -99.9885921727562 + 0.0340517971029146 142.155679872536 0.0209752061977208 -45.7890130005805 0.0851179295353319 152.484044555007 0.116961398102155 -22.7880012481223 + 0.935793423196069 -99.9885921727562 0.185927916312599 -13.8074129494069 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.398107170553497 0.18261992121049 -25.5146161646696 0.935590796399222 -111.858514518406 0.105302204481979 -15.8651041408112 0.0814369832398217 142.385312146224 + 0.0224924764655306 -71.1776695823633 0.0360741572331273 133.758403659714 + 0.935590796399222 -111.858514518406 0.177588948453823 -24.8422211936684 0.0818027977780583 143.82189561751 0.110942859224918 -41.7462269368367 + 0.0337282996612282 139.770805289239 0.0162953927561438 -68.8173348362406 + 0.105302204481979 -15.8651041408112 0.0818027977780583 143.82189561751 0.165680291825198 -29.0188555457262 0.929103675154067 -110.828320996845 + 0.104585341484952 -22.5563413653631 0.0911750033683001 143.59140714377 + 0.0814369832398217 142.385312146224 0.110942859224918 -41.7462269368367 0.929103675154067 -110.828320996845 0.157263505436141 -27.0617394630566 + 0.0897818817710688 146.030403539503 0.106986365651532 -36.5988423363908 + 0.0224924764655306 -71.1776695823633 0.0337282996612282 139.770805289239 0.104585341484952 -22.5563413653631 0.0897818817710688 146.030403539503 + 0.179933976026388 -26.0411417156993 0.935318117427384 -111.871723803179 + 0.0360741572331273 133.758403659714 0.0162953927561438 -68.8173348362406 0.0911750033683001 143.59140714377 0.106986365651532 -36.5988423363908 + 0.935318117427384 -111.871723803179 0.175705994170927 -24.9636159905657 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.446683592150963 0.164080140984611 -38.3208528282524 0.936217453370793 -125.273030097426 0.0918308438847092 -24.5923915226374 0.0889993365361669 133.10937791407 + 0.0177949108751801 -100.792491742464 0.0397980445956522 124.923085472967 + 0.936217453370793 -125.273030097426 0.157757528698508 -37.2876616651121 0.0894917563933115 134.622141214964 0.0986095430264192 -59.3413573883405 + 0.037673794277362 132.694031038824 0.0113152909270369 -111.242715510219 + 0.0918308438847092 -24.5923915226374 0.0894917563933115 134.622141214964 0.146995629878117 -42.1217973996706 0.930300439245387 -124.162982834675 + 0.0865885163449396 -33.3028814388691 0.100158868045474 134.024407543332 + 0.0889993365361669 133.10937791407 0.0986095430264192 -59.3413573883405 0.930300439245387 -124.162982834675 0.136487009666514 -39.4094998316432 + 0.0991216982025458 136.983221119893 0.0898373887196774 -53.4157486645296 + 0.0177949108751801 -100.792491742464 0.037673794277362 132.694031038824 0.0865885163449396 -33.3028814388691 0.0991216982025458 136.983221119893 + 0.160621594541902 -38.778367982881 0.936131771499364 -125.322427323894 + 0.0397980445956522 124.923085472967 0.0113152909270369 -111.242715510219 0.100158868045474 134.024407543332 0.0898373887196774 -53.4157486645296 + 0.936131771499364 -125.322427323894 0.155551178302089 -37.2973485594002 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.501187233627271 0.133344207286152 -52.519354173143 0.93735115987188 -140.493155859436 0.0720255224395789 -30.499356725639 0.101029498991271 122.138866985148 + 0.0139763078638825 -151.32226940008 0.0463069567365372 113.842930099283 + 0.93735115987188 -140.493155859436 0.125335334933231 -50.6794397493715 0.101618064556139 123.7115762986 0.0792714433692562 -81.8242156095046 + 0.0448574992312897 122.792962064234 0.0124956172820405 175.130443984113 + 0.0720255224395789 -30.499356725639 0.101618064556139 123.7115762986 0.11672067040281 -56.8727526629947 0.931431450494841 -139.317087073908 + 0.0598656713152403 -41.7876991651494 0.114026641161931 122.651696933668 + 0.101029498991271 122.138866985148 0.0792714433692562 -81.8242156095046 0.931431450494841 -139.317087073908 0.103774982909863 -52.2568412461502 + 0.11369715042331 125.968019322651 0.0640873411985971 -75.759613852323 + 0.0139763078638825 -151.32226940008 0.0448574992312897 122.792962064234 0.0598656713152403 -41.7876991651494 0.11369715042331 125.968019322651 + 0.128820852804764 -52.6882102148011 0.937187998479955 -140.603202396194 + 0.0463069567365372 113.842930099283 0.0124956172820405 175.130443984113 0.114026641161931 122.651696933668 0.0640873411985971 -75.759613852323 + 0.937187998479955 -140.603202396194 0.122867639053205 -50.4247249901066 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.562341325190349 0.0883419986245842 -67.3583978048032 0.93695362793501 -157.799261934274 0.0500463671535398 -24.3277351342871 0.118606358180807 107.770374009253 + 0.0173570174586989 140.670761464713 0.056174095739068 98.2393173378266 + 0.93695362793501 -157.799261934274 0.0784285721242486 -63.0235591880074 0.119133996524741 109.438779215638 0.0534803122691083 -114.530817133312 + 0.0556248911576868 107.519539672398 0.0236872436481829 123.202467682295 + 0.0500463671535398 -24.3277351342871 0.119133996524741 109.438779215638 0.0728532592842006 -71.9436180757441 0.929485737208428 -156.683614797381 + 0.0283090005534056 -28.0671886160993 0.133766723489624 107.881163316051 + 0.118606358180807 107.770374009253 0.0534803122691083 -114.530817133312 0.929485737208428 -156.683614797381 0.0563207799581135 -61.7833467435705 + 0.13440980338803 111.305209826133 0.0315012274220904 -116.881607673937 + 0.0173570174586989 140.670761464713 0.0556248911576868 107.519539672398 0.0283090005534056 -28.0671886160993 0.13440980338803 111.305209826133 + 0.0827240647955333 -66.1213936219266 0.935904644516158 -157.980644532838 + 0.056174095739068 98.2393173378266 0.0236872436481829 123.202467682295 0.133766723489624 107.881163316051 0.0315012274220904 -116.881607673937 + 0.935904644516158 -157.980644532838 0.076083809873997 -61.7197523862776 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.630957344480194 0.0308137153748346 -73.268900120334 0.93222001325084 -177.3708763307 0.0467404711687316 4.9960793586515 0.140404327717864 88.7374256392361 + 0.0285725916009231 89.3241033554652 0.0683066433225294 76.7585730739663 + 0.93222001325084 -177.3708763307 0.0234785777698477 -44.3092718020261 0.140709515354877 90.5726064715766 0.0310908927425968 -179.378396690617 + 0.0683792333290767 85.8981332120222 0.0387658938173954 87.2062687973903 + 0.0467404711687316 4.9960793586515 0.140709515354877 90.5726064715766 0.01858644579506 -68.7244929457764 0.920723021024004 -176.262248712149 + 0.0388525978159405 39.5318346856907 0.157914434755452 88.5545297985903 + 0.140404327717864 88.7374256392361 0.0310908927425968 -179.378396690617 0.920723021024004 -176.262248712149 0.0205286783727088 12.6022910207355 + 0.159313543410982 91.9219944920498 0.0287522213379386 125.652174542803 + 0.0285725916009231 89.3241033554652 0.0683792333290767 85.8981332120222 0.0388525978159405 39.5318346856907 0.159313543410982 91.9219944920498 + 0.0267911286027086 -59.1505973985187 0.929337999118823 -177.612669725253 + 0.0683066433225294 76.7585730739663 0.0387658938173954 87.2062687973903 0.157914434755452 88.5545297985903 0.0287522213379386 125.652174542803 + 0.929337999118823 -177.612669725253 0.0243332469137009 -36.4637157986085 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.707945784384137 0.039190925542603 49.6130322713435 0.921200726474262 160.792216455637 0.0723405664768641 14.7761218614598 0.16202363357557 65.2011470470918 + 0.0413442447883195 47.6318581171437 0.0796512368228134 49.8928492627212 + 0.921200726474262 160.792216455637 0.0581492057686352 43.3867359204866 0.161904725487012 67.3189816923991 0.0420169757892811 94.0817934106218 + 0.0795610667206902 58.9505509965632 0.0521331920194859 53.3683670303112 + 0.0723405664768641 14.7761218614598 0.161904725487012 67.3189816923991 0.046425530424054 45.9796959857372 0.903040733262392 162.046050488277 + 0.0831247581819105 36.0971124277467 0.181668059487831 64.8365323040243 + 0.16202363357557 65.2011470470918 0.0420169757892811 94.0817934106218 0.903040733262392 162.046050488277 0.0774051598594565 41.185784401375 + 0.183099138132847 68.1755681853532 0.0682956669280762 73.1963360226893 + 0.0413442447883195 47.6318581171437 0.0795610667206902 58.9505509965632 0.0831247581819105 36.0971124277467 0.183099138132847 68.1755681853532 + 0.0477634230828738 39.9881041531388 0.915736776927132 160.582980878777 + 0.0796512368228134 49.8928492627212 0.0521331920194859 53.3683670303112 0.181668059487831 64.8365323040243 0.0682956669280762 73.1963360226893 + 0.915736776927132 160.582980878777 0.0600193754922104 39.7850982049881 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.794328234724282 0.103781436213569 36.5139885400508 0.90502509580476 136.642964824952 0.0983613531776571 2.04264586402847 0.179598678869773 38.6324449033264 + 0.0494169232889389 8.2026588034792 0.0871766761213426 20.2991744513546 + 0.90502509580476 136.642964824952 0.122593751225546 29.5371956302258 0.179048461266094 41.2044296227618 0.0666227472027708 45.2737913346971 + 0.0859650319252224 29.6953398916091 0.0575222735871698 18.8668960063279 + 0.0983613531776571 2.04264586402847 0.179048461266094 41.2044296227618 0.100642454167278 29.3416070424327 0.880812521655193 138.293454868646 + 0.119758560774629 15.452716722717 0.200837481216629 38.1346434907288 + 0.179598678869773 38.6324449033264 0.0666227472027708 45.2737913346971 0.880812521655193 138.293454868646 0.134220925075906 22.7844986511693 + 0.201284382541642 41.6440011696697 0.101262402347251 40.7112653387772 + 0.0494169232889389 8.2026588034792 0.0859650319252224 29.6953398916091 0.119758560774629 15.452716722717 0.201284382541642 41.6440011696697 + 0.108934799138394 28.9365119849685 0.897453114257497 136.526062720056 + 0.0871766761213426 20.2991744513546 0.0575222735871698 18.8668960063279 0.200837481216629 38.1346434907288 0.101262402347251 40.7112653387772 + 0.897453114257497 136.526062720056 0.120863291162463 27.1192647046962 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +0.891250938133744 0.153948227659807 14.1647267464913 0.888782134291173 109.989006521524 0.106165076318315 -19.5898298795426 0.192604197406861 10.4104964646789 + 0.0499784054395195 -34.4785787036255 0.0910745075607269 -10.1405853185258 + 0.888782134291173 109.989006521524 0.169979392004882 6.84995169148913 0.192035564893328 13.598441158352 0.0785332518587958 5.81285868237334 + 0.0880202802754112 0.51529306029017 0.0510850759465168 -19.3950491704605 + 0.106165076318315 -19.5898298795426 0.192035564893328 13.598441158352 0.136409503952877 7.02827977294024 0.86166228732955 112.206160203268 + 0.134325235214333 -10.9849324984174 0.214749220101907 9.74624198092196 + 0.192604197406861 10.4104964646789 0.0785332518587958 5.81285868237334 0.86166228732955 112.206160203268 0.168525727051741 -0.887826344681608 + 0.21376487889865 13.8859998215087 0.11267919646785 10.3480878939314 + 0.0499784054395195 -34.4785787036255 0.0880202802754112 0.51529306029017 0.134325235214333 -10.9849324984174 0.21376487889865 13.8859998215087 + 0.152699418438379 7.24970766315131 0.88077984648084 110.034395329501 + 0.0910745075607269 -10.1405853185258 0.0510850759465168 -19.3950491704605 0.214749220101907 9.74624198092196 0.11267919646785 10.3480878939314 + 0.88077984648084 110.034395329501 0.164255763903909 5.37220169547267 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1 0.174367420974623 -10.9453580895679 0.877807227123618 80.165771263654 0.0842920279969044 -46.1377515794864 0.20720639397607 -18.5514918435605 + 0.0420052822108501 -87.2485554268819 0.0962902026692905 -39.1717184872237 + 0.877807227123618 80.165771263654 0.182856710756712 -19.3267172217218 0.207740306993072 -14.7374926774268 0.0683622317768401 -38.1112001413473 + 0.0919863422155101 -25.9252417645329 0.0319641288010845 -70.6304367626142 + 0.0842920279969044 -46.1377515794864 0.207740306993072 -14.7374926774268 0.142243008333662 -16.3630821227432 0.85112687636061 82.7547752550909 + 0.115498042124598 -43.0763348381669 0.229945407779206 -19.4297429280178 + 0.20720639397607 -18.5514918435605 0.0683622317768401 -38.1112001413473 0.85112687636061 82.7547752550909 0.166786852960484 -26.9120788258921 + 0.228571363527002 -14.1436647037691 0.0921767009533662 -21.0709019955194 + 0.0420052822108501 -87.2485554268819 0.0919863422155101 -25.9252417645329 0.115498042124598 -43.0763348381669 0.228571363527002 -14.1436647037691 + 0.164275109868118 -17.6842133150461 0.870969795820705 80.2868382568511 + 0.0962902026692905 -39.1717184872237 0.0319641288010845 -70.6304367626142 0.229945407779206 -19.4297429280178 0.0921767009533662 -21.0709019955194 + 0.870969795820705 80.2868382568511 0.174992539206605 -19.6047509532626 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.05 0.16995626094341 -21.6410597005515 0.874857396313523 66.3915237763807 0.0633728912322541 -57.8995364926354 0.215982976927996 -31.305529522349 + 0.0363552946773987 -117.932867182819 0.100474646952171 -51.452453268839 + 0.874857396313523 66.3915237763807 0.172669836851078 -31.1626663913309 0.217336843319183 -27.3106344465553 0.056225288401389 -63.4861202041557 + 0.096492509450571 -37.0256452599838 0.0224525647727234 -112.125546476163 + 0.0633728912322541 -57.8995364926354 0.217336843319183 -27.3106344465553 0.13268799647085 -25.2500496517178 0.848461600502365 69.0011474103875 + 0.0940797711395723 -59.3087235621052 0.23879817415994 -32.1674966471096 + 0.215982976927996 -31.305529522349 0.056225288401389 -63.4861202041557 0.848461600502365 69.0011474103875 0.150574951600012 -38.4012678678585 + 0.238212795213403 -26.4093373862299 0.0702524218529428 -35.3195764685865 + 0.0363552946773987 -117.932867182819 0.096492509450571 -37.0256452599838 0.0940797711395723 -59.3087235621052 0.238212795213403 -26.4093373862299 + 0.15420907376011 -28.2040804003641 0.8690111134754 66.5167295668859 + 0.100474646952171 -51.452453268839 0.0224525647727234 -112.125546476163 0.23879817415994 -32.1674966471096 0.0702524218529428 -35.3195764685865 + 0.8690111134754 66.5167295668859 0.164378083710712 -30.6475629664317 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.1 0.158150127283435 -31.9511278510485 0.871232975676953 52.4432221320569 0.0382350568962812 -68.8753108048292 0.228265665084871 -44.4204624809266 + 0.0333046070305314 -153.062791271633 0.108714842139985 -64.2994999437787 + 0.871232975676953 52.4432221320569 0.153872193463177 -42.277987565846 0.230535925614364 -40.3293024375365 0.0437899591999703 -97.0465833595101 + 0.105385264170495 -48.8367836602314 0.0208702798288208 -171.806947812326 + 0.0382350568962812 -68.8753108048292 0.230535925614364 -40.3293024375365 0.117558975039323 -32.6789351692672 0.843675480287391 54.9807039678259 + 0.0680633318951218 -78.7368754519606 0.251708585040889 -45.2732644752363 + 0.228265665084871 -44.4204624809266 0.0437899591999703 -97.0465833595101 0.843675480287391 54.9807039678259 0.126540153141625 -48.7328131001442 + 0.252470115739036 -39.0472218306355 0.0431819091016726 -49.265046353166 + 0.0333046070305314 -153.062791271633 0.105385264170495 -48.8367836602314 0.0680633318951218 -78.7368754519606 0.252470115739036 -39.0472218306355 + 0.137239858589395 -37.9019611460696 0.86581992141281 52.4850848603613 + 0.108714842139985 -64.2994999437787 0.0208702798288208 -171.806947812326 0.251708585040889 -45.2732644752363 0.0431819091016726 -49.265046353166 + 0.86581992141281 52.4850848603613 0.146891592527274 -40.9009917350511 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.15 0.13963206082024 -40.8514841800386 0.866098448575975 38.4142049722549 0.00945371984849898 -59.5003111957116 0.242217496572717 -58.1388297489114 + 0.033325773166921 167.085480898121 0.118918372283203 -78.4296819844083 + 0.866098448575975 38.4142049722549 0.126558788341957 -52.0207638947318 0.245365880273596 -54.0124157475251 0.0374178473631437 -145.724237384754 + 0.116630982333505 -62.2593432091355 0.031334265132685 138.734453198002 + 0.00945371984849898 -59.5003111957116 0.245365880273596 -54.0124157475251 0.0988829940877613 -36.0178085932443 0.835733205390065 40.8337399967002 + 0.0379878764783204 -107.655398405861 0.266393662578722 -58.924762214548 + 0.242217496572717 -58.1388297489114 0.0374178473631437 -145.724237384754 0.835733205390065 40.8337399967002 0.0948227651913827 -56.1307591218161 + 0.26910866675763 -52.3856718105903 0.0104020882326794 -60.2585490358623 + 0.033325773166921 167.085480898121 0.116630982333505 -62.2593432091355 0.0379878764783204 -107.655398405861 0.26910866675763 -52.3856718105903 + 0.113364194417634 -44.9128865550695 0.860413149870603 38.348686342076 + 0.118918372283203 -78.4296819844083 0.031334265132685 138.734453198002 0.266393662578722 -58.924762214548 0.0104020882326794 -60.2585490358623 + 0.860413149870603 38.348686342076 0.121448700317315 -49.4703835730485 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.2 0.113968027182867 -47.3706156381698 0.859750539229299 24.516167353938 0.0257025960724953 68.9286431439172 0.254077547067725 -72.3117229730991 + 0.0399042286045801 129.413219200075 0.126889910847218 -93.8187903409036 + 0.859750539229299 24.516167353938 0.0922016637695539 -56.4980476051525 0.25794689719758 -68.3291913485439 0.0438531139140045 160.057609888168 + 0.126307453079412 -77.6362105030229 0.0487343533320884 103.488661910186 + 0.0257025960724953 68.9286431439172 0.25794689719758 -68.3291913485439 0.0800548147895688 -32.3549321982411 0.82506218209413 26.8152160436185 + 0.0216237575389155 166.634289008321 0.278863304833697 -73.0149550856691 + 0.254077547067725 -72.3117229730991 0.0438531139140045 160.057609888168 0.82506218209413 26.8152160436185 0.0606351402194509 -50.5935186490197 + 0.283904649483556 -66.4599947516215 0.0275948307246331 90.4502166742484 + 0.0399042286045801 129.413219200075 0.126307453079412 -77.6362105030229 0.0216237575389155 166.634289008321 0.283904649483556 -66.4599947516215 + 0.0849814894308389 -47.2179572157496 0.852759917158544 24.3664606000743 + 0.126889910847218 -93.8187903409036 0.0487343533320884 103.488661910186 0.278863304833697 -73.0149550856691 0.0275948307246331 90.4502166742484 + 0.852759917158544 24.3664606000743 0.0919304373406621 -51.159807480615 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.25 0.091341068731877 -48.0913223642819 0.852600094260662 10.4299397856904 0.0597755658635856 55.2011282086107 0.268635431030241 -86.8609971871197 + 0.0470212860411302 93.0258480398945 0.138079212149516 -109.281349849228 + 0.852600094260662 10.4299397856904 0.0630444628826687 -51.1293857511607 0.272268619441582 -82.8676140472741 0.0588038822582823 125.343606610365 + 0.137338692960112 -92.9940889457445 0.0622355373656468 78.3843184595155 + 0.0597755658635856 55.2011282086107 0.272268619441582 -82.8676140472741 0.0759464519560823 -20.7721273486845 0.811350142050956 12.6712720215659 + 0.046101485959434 96.1255820582646 0.294520702463955 -87.4309500535413 + 0.268635431030241 -86.8609971871197 0.0588038822582823 125.343606610365 0.811350142050956 12.6712720215659 0.0451864628445637 -21.6536113916696 + 0.300857658594995 -80.8648581788027 0.0605620971303818 78.9156128986554 + 0.0470212860411302 93.0258480398945 0.137338692960112 -92.9940889457445 0.046101485959434 96.1255820582646 0.300857658594995 -80.8648581788027 + 0.064328354703721 -34.7983100169845 0.844120093689518 10.1784405259507 + 0.138079212149516 -109.281349849228 0.0622355373656468 78.3843184595155 0.294520702463955 -87.4309500535413 0.0605620971303818 78.9156128986554 + 0.844120093689518 10.1784405259507 0.0686423192226272 -46.0816789414736 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.3 0.0719832134445066 -42.7911375019868 0.843752035681066 -3.5588011579994 0.0899993389302809 41.408150083506 0.280600905206202 -101.889385079503 + 0.0551091192995826 62.7790256911914 0.14775431502411 -125.9476993822 + 0.843752035681066 -3.5588011579994 0.0474710445379474 -24.2985535473617 0.283988886758712 -97.882516141226 0.0758882227958037 99.1416078236273 + 0.146809167306355 -109.530247086527 0.0755516613784082 56.3506329311829 + 0.0899993389302809 41.408150083506 0.283988886758712 -97.882516141226 0.0843979986535189 -12.2839501746795 0.794546343007566 -1.23756019495952 + 0.0787489640728208 69.9821313355317 0.307618157871294 -102.34528138245 + 0.280600905206202 -101.889385079503 0.0758882227958037 99.1416078236273 0.794546343007566 -1.23756019495952 0.0625084675597756 6.77534885880661 + 0.314883340149959 -95.8159958206561 0.0921491079161728 65.2889707013539 + 0.0551091192995826 62.7790256911914 0.146809167306355 -109.530247086527 0.0787489640728208 69.9821313355317 0.314883340149959 -95.8159958206561 + 0.0628409370077339 -13.7498147152012 0.832711409514299 -3.8596416597201 + 0.14775431502411 -125.9476993822 0.0755516613784082 56.3506329311829 0.307618157871294 -102.34528138245 0.0921491079161728 65.2889707013539 + 0.832711409514299 -3.8596416597201 0.0569088151146829 -27.0520564017026 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.35 0.0617532866806546 -29.4547720889065 0.833987837609112 -17.4412030192185 0.115412791668806 26.8371983008541 0.289922045231621 -117.040846891122 + 0.0619604329696226 35.6461871887317 0.155279081541348 -142.996352245202 + 0.833987837609112 -17.4412030192185 0.0610564584628179 2.78248542019616 0.292707426607777 -112.969527345438 0.0895749300326898 77.7952936279271 + 0.153635886007974 -126.358411495072 0.0852107860413892 35.3831913171508 + 0.115412791668806 26.8371983008541 0.292707426607777 -112.969527345438 0.0987270859062718 -11.1947162052788 0.777004305263069 -14.8646376470961 + 0.107763919780827 50.6183450904275 0.318083341014391 -117.428705123448 + 0.289922045231621 -117.040846891122 0.0895749300326898 77.7952936279271 0.777004305263069 -14.8646376470961 0.0933385904789673 10.02156221543 + 0.325603035406804 -110.925987659201 0.118305505994035 51.1935319182815 + 0.0619604329696226 35.6461871887317 0.153635886007974 -126.358411495072 0.107763919780827 50.6183450904275 0.325603035406804 -110.925987659201 + 0.0788742971922487 -1.63999288914778 0.820111234657208 -17.7354914713197 + 0.155279081541348 -142.996352245202 0.0852107860413892 35.3831913171508 0.318083341014391 -117.428705123448 0.118305505994035 51.1935319182815 + 0.820111234657208 -17.7354914713197 0.0652554281811962 -7.83614845989276 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.4 0.0634439125467282 -14.1339603761818 0.824383749561212 -31.2416028971686 0.134157367883056 12.2923146771701 0.296994198443923 -132.029643298638 + 0.0664836936835252 10.3423195091249 0.160759317624783 -159.931096564594 + 0.824383749561212 -31.2416028971686 0.0875967210002125 8.82994952741715 0.298974506152623 -127.824403464492 0.0980147648572925 59.3300439842134 + 0.158040174977754 -142.907448132861 0.0902228733600411 15.1689584792553 + 0.134157367883056 12.2923146771701 0.298974506152623 -127.824403464492 0.111365861866775 -15.4313793147923 0.760638139886211 -28.2521942423602 + 0.130528082307692 33.7900018926257 0.326259103455708 -132.408653502234 + 0.296994198443923 -132.029643298638 0.0980147648572925 59.3300439842134 0.760638139886211 -28.2521942423602 0.121861195549735 3.85161353653219 + 0.333358168072281 -125.860582624974 0.137127640889559 37.5584768123741 + 0.0664836936835252 10.3423195091249 0.158040174977754 -142.907448132861 0.130528082307692 33.7900018926257 0.333358168072281 -125.860582624974 + 0.0993758209930337 -0.722934695144082 0.807769142544092 -31.4660945109184 + 0.160759317624783 -159.931096564594 0.0902228733600411 15.1689584792553 0.326259103455708 -132.408653502234 0.137127640889559 37.5584768123741 + 0.807769142544092 -31.4660945109184 0.0837145173702387 -1.28242665172789 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.45 0.0731727205529138 -3.9996612301996 0.814120433539715 -44.9762988686056 0.144696689270865 -1.7881270458121 0.302402541386633 -146.949863755042 + 0.0671679641522495 -13.7092213404429 0.165001263921041 -176.945532963389 + 0.814120433539715 -44.9762988686056 0.114006857723408 5.88055241680271 0.30359370827527 -142.558619508139 0.101265246529225 43.195755207636 + 0.161220469124948 -159.317992719345 0.0903813689721159 -3.81455490885149 + 0.144696689270865 -1.7881270458121 0.30359370827527 -142.558619508139 0.117440810877624 -22.0661254681035 0.745282121312955 -41.4483292900911 + 0.145201162975827 18.6422163971544 0.332522915508913 -147.435209302269 + 0.302402541386633 -146.949863755042 0.101265246529225 43.195755207636 0.745282121312955 -41.4483292900911 0.143821046039827 -4.87835902610091 + 0.339040023507404 -140.69790504544 0.148762170549703 24.9953642768104 + 0.0671679641522495 -13.7092213404429 0.161220469124948 -159.317992719345 0.145201162975827 18.6422163971544 0.339040023507404 -140.69790504544 + 0.115748920310337 -5.02061324031681 0.794721156681856 -45.0759935631523 + 0.165001263921041 -176.945532963389 0.0903813689721159 -3.81455490885149 0.332522915508913 -147.435209302269 0.148762170549703 24.9953642768104 + 0.794721156681856 -45.0759935631523 0.103084620383783 -1.81053004518643 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.5 0.090576469084507 0.0140313036970921 0.807883977350118 -58.4505816975962 0.151513650424633 -15.116149174282 0.303395067885474 -160.940961672144 + 0.0676766094263429 -34.8015457115297 0.162452037004892 167.062777069216 + 0.807883977350118 -58.4505816975962 0.141391481905007 -2.33660941958133 0.303237485396792 -156.275906999005 0.100453445156098 25.1495599150788 + 0.157681208495871 -174.758510541967 0.0924229306180248 -24.6928540823416 + 0.151513650424633 -15.116149174282 0.303237485396792 -156.275906999005 0.120581998866825 -28.2048298042293 0.737003818603949 -54.3432362594137 + 0.157082355446694 4.71963235223072 0.332989631229163 -161.428305038486 + 0.303395067885474 -160.940961672144 0.100453445156098 25.1495599150788 0.737003818603949 -54.3432362594137 0.162982580642462 -15.970608720464 + 0.338790011781243 -154.609103291786 0.155324770534115 10.6465536070608 + 0.0676766094263429 -34.8015457115297 0.157681208495871 -174.758510541967 0.157082355446694 4.71963235223072 0.338790011781243 -154.609103291786 + 0.130711664207408 -9.87563828201797 0.787719731481444 -58.2589527705096 + 0.162452037004892 167.062777069216 0.0924229306180248 -24.6928540823416 0.332989631229163 -161.428305038486 0.155324770534115 10.6465536070608 + 0.787719731481444 -58.2589527705096 0.12519309608302 -9.4546555960532 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.55 0.106641253949556 -3.0977179025415 0.802278486152509 -72.3571360693865 0.151299667959735 -30.0420695184467 0.310463152770796 -174.541384334171 + 0.0678641191443553 -58.8148971170791 0.165356929822616 153.0305651068 + 0.802278486152509 -72.3571360693865 0.155774309674698 -12.6778730599632 0.309834761880008 -169.393586015802 0.0878121699439303 8.97513894422521 + 0.159206584724271 172.229445442164 0.0843041096816235 -48.2127217753234 + 0.151299667959735 -30.0420695184467 0.309834761880008 -169.393586015802 0.118824430713213 -36.9788918335074 0.729957034609517 -67.81199732954 + 0.161209042103988 -10.6038894972537 0.341280110160461 -175.082757899607 + 0.310463152770796 -174.541384334171 0.0878121699439303 8.97513894422521 0.729957034609517 -67.81199732954 0.167489351577929 -27.9011834384406 + 0.345413989528415 -167.884449713367 0.146520131061651 -2.09806954572875 + 0.0678641191443553 -58.8148971170791 0.159206584724271 172.229445442164 0.161209042103988 -10.6038894972537 0.345413989528415 -167.884449713367 + 0.141587367435069 -18.2235878384133 0.782492712826457 -72.0578433592704 + 0.165356929822616 153.0305651068 0.0843041096816235 -48.2127217753234 0.341280110160461 -175.082757899607 0.146520131061651 -2.09806954572875 + 0.782492712826457 -72.0578433592704 0.132012309835804 -18.2828473799511 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.6 0.118417334287234 -7.61961498698039 0.794228760331576 -86.2636650413767 0.142290837349221 -44.9062908028528 0.318078856606758 171.587036075373 + 0.0646079445500287 -83.9735813656637 0.169756133138361 138.593854108149 + 0.794228760331576 -86.2636650413767 0.162694559024915 -23.2600783214566 0.31773443554279 177.194267476469 0.0701469148060102 -6.90911963136501 + 0.16320324491038 158.983045430835 0.0745733765351601 -73.2334865219871 + 0.142290837349221 -44.9062908028528 0.31773443554279 177.194267476469 0.108089693833275 -45.3399875309751 0.721659526863604 -81.3297361923453 + 0.155956065761286 -25.4325424731445 0.349530078576842 170.890258116226 + 0.318078856606758 171.587036075373 0.0701469148060102 -6.90911963136501 0.721659526863604 -81.3297361923453 0.163854251274312 -39.6797209982794 + 0.35313073658533 178.636156704026 0.13093088822759 -13.7602456116703 + 0.0646079445500287 -83.9735813656637 0.16320324491038 158.983045430835 0.155956065761286 -25.4325424731445 0.35313073658533 178.636156704026 + 0.143022331091228 -26.9184056346696 0.774717848733427 -85.863702019124 + 0.169756133138361 138.593854108149 0.0745733765351601 -73.2334865219871 0.349530078576842 170.890258116226 0.13093088822759 -13.7602456116703 + 0.774717848733427 -85.863702019124 0.133511223024641 -27.0756727512977 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.65 0.125765569689288 -13.1668848789823 0.784190143395266 -100.161479369482 0.126545013218691 -60.4318607962822 0.326436903996487 157.470423673553 + 0.0608245622235505 -110.899438548984 0.175869603427074 123.879363452215 + 0.784190143395266 -100.161479369482 0.160375097922502 -34.1704432024257 0.327122652485598 163.513450528952 0.0462274164534948 -23.6941533808308 + 0.169788614802447 145.497596416685 0.0646955985915576 -102.91762617267 + 0.126545013218691 -60.4318607962822 0.327122652485598 163.513450528952 0.0906747592258703 -52.6451622948832 0.711880163987235 -94.938621563605 + 0.143408015339843 -40.4303422852317 0.358094625540206 156.600173961612 + 0.326436903996487 157.470423673553 0.0462274164534948 -23.6941533808308 0.711880163987235 -94.938621563605 0.150817514752518 -51.6157062469485 + 0.362372293519519 164.973201756606 0.107135024239975 -23.9535654899477 + 0.0608245622235505 -110.899438548984 0.169788614802447 145.497596416685 0.143408015339843 -40.4303422852317 0.362372293519519 164.973201756606 + 0.137034718033449 -35.4428972008569 0.765009796676809 -99.7044133207341 + 0.175869603427074 123.879363452215 0.0646955985915576 -102.91762617267 0.358094625540206 156.600173961612 0.107135024239975 -23.9535654899477 + 0.765009796676809 -99.7044133207341 0.127341862158995 -36.0008980705685 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.7 0.133695863304198 -18.1009878913188 0.773575938722578 -113.925560499619 0.106858221857655 -73.9643270898154 0.334092242342525 143.240332489676 + 0.0524746282182275 -136.891381238066 0.181813849136032 108.890539887938 + 0.773575938722578 -113.925560499619 0.145609066814576 -45.7267160118333 0.336337301152158 149.730121308642 0.0137849785900226 -53.5319904397422 + 0.177155593503789 131.637848040565 0.0600031513944977 -142.570806044715 + 0.106858221857655 -73.9643270898154 0.336337301152158 149.730121308642 0.0724137807270103 -52.4086863993677 0.701586132587426 -108.577072093801 + 0.127278750129059 -53.1974700430623 0.36561201639091 142.295132064505 + 0.334092242342525 143.240332489676 0.0137849785900226 -53.5319904397422 0.701586132587426 -108.577072093801 0.12532617171867 -64.250628799681 + 0.371914470885741 151.188913093861 0.0723655623706649 -29.8408021366842 + 0.0524746282182275 -136.891381238066 0.177155593503789 131.637848040565 0.127278750129059 -53.1974700430623 0.371914470885741 151.188913093861 + 0.126628471282937 -40.4854701721764 0.754650648985956 -113.484767219875 + 0.181813849136032 108.890539887938 0.0600031513944977 -142.570806044715 0.36561201639091 142.295132064505 0.0723655623706649 -29.8408021366842 + 0.754650648985956 -113.484767219875 0.108891885768 -44.3454766025907 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.75 0.133311119638889 -26.8489032752059 0.759149107053381 -127.502604399013 0.0882135175312036 -93.2765759012694 0.339863721352547 128.257295504445 + 0.0522258840103778 -160.63375506907 0.189144540742092 92.3062061157529 + 0.759149107053381 -127.502604399013 0.118909156285014 -53.4388636154359 0.345204299778145 135.02001706195 0.0256737527642384 126.408608551014 + 0.187365045079678 116.027952325286 0.0615040343268282 170.39819596634 + 0.0882135175312036 -93.2765759012694 0.345204299778145 135.02001706195 0.0541034779924082 -53.2496524766018 0.685994599677725 -122.004455421465 + 0.110877513123968 -70.2987158950825 0.370936548736542 127.109737207272 + 0.339863721352547 128.257295504445 0.0256737527642384 126.408608551014 0.685994599677725 -122.004455421465 0.0874728100717623 -71.8954180344316 + 0.380723769484587 136.481471680907 0.0420777703720326 -5.66621978421204 + 0.0522258840103778 -160.63375506907 0.187365045079678 116.027952325286 0.110877513123968 -70.2987158950825 0.380723769484587 136.481471680907 + 0.116690959431706 -47.69499166633 0.73806307722336 -127.069671702997 + 0.189144540742092 92.3062061157529 0.0615040343268282 170.39819596634 0.370936548736542 127.109737207272 0.0420777703720326 -5.66621978421204 + 0.73806307722336 -127.069671702997 0.0846408366002271 -43.4728679477528 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.8 0.117334047272239 -34.2730773810547 0.751657025124455 -140.53181851516 0.0655244281221002 -125.268076480888 0.337709036595091 114.362791762417 + 0.0609861149920199 172.598644124962 0.185437135297223 75.9739371929182 + 0.751657025124455 -140.53181851516 0.0929896787278237 -51.1480588753936 0.346474863159734 121.038781708494 0.0627169042699258 98.8922393354474 + 0.188518647426192 99.9837975867081 0.069359485111684 123.287946954842 + 0.0655244281221002 -125.268076480888 0.346474863159734 121.038781708494 0.0267192156257469 -39.8138789019508 0.677978010934085 -134.943799722827 + 0.0878280031008969 -95.4359919971131 0.36627823428346 113.037933651508 + 0.337709036595091 114.362791762417 0.0627169042699258 98.8922393354474 0.677978010934085 -134.943799722827 0.0548889604624605 -56.8452359750148 + 0.379805702411336 122.412057832551 0.0630759789819374 31.7767868533036 + 0.0609861149920199 172.598644124962 0.188518647426192 99.9837975867081 0.0878280031008969 -95.4359919971131 0.379805702411336 122.412057832551 + 0.0961594340237164 -58.2661342328649 0.7285391551417 -139.797458634997 + 0.185437135297223 75.9739371929182 0.069359485111684 123.287946954842 0.36627823428346 113.037933651508 0.0630759789819374 31.7767868533036 + 0.7285391551417 -139.797458634997 0.0798674049853028 -28.2528206753685 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.85 0.101328238570803 -29.594125990875 0.751036653046584 -154.213158717521 0.0401191554994268 174.390000765986 0.344915438462228 101.837099079613 + 0.0723716355807284 135.287675509303 0.184367075146063 63.8873874826313 + 0.751036653046584 -154.213158717521 0.0823415835193601 -45.2543231322153 0.35504095708573 108.20064467205 0.0861210569665333 81.4524678269607 + 0.19013981567873 87.025279647709 0.0762750907868976 88.8849795920719 + 0.0401191554994268 174.390000765986 0.35504095708573 108.20064467205 0.0442232097269056 36.6540536901745 0.674140585949186 -148.832787541976 + 0.0506347851457291 -132.770373244253 0.371203802220578 100.657349560274 + 0.344915438462228 101.837099079613 0.0861210569665333 81.4524678269607 0.674140585949186 -148.832787541976 0.0544133973158744 -31.7296224089494 + 0.385764905620914 109.896082492994 0.091363025884698 31.0180489789859 + 0.0723716355807284 135.287675509303 0.19013981567873 87.025279647709 0.0506347851457291 -132.770373244253 0.385764905620914 109.896082492994 + 0.0557332451211763 -57.5153099713865 0.730964877872738 -153.241800959858 + 0.184367075146063 63.8873874826313 0.0762750907868976 88.8849795920719 0.371203802220578 100.657349560274 0.091363025884698 31.0180489789859 + 0.730964877872738 -153.241800959858 0.0913601083390341 -26.5911938405955 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.9 0.100395343429803 -26.1686555273341 0.741910439281126 -167.906157139786 0.045186698521858 108.548169503624 0.353807587471509 87.5870345148459 + 0.0757588143038787 103.333302695385 0.191942968766659 49.4805865058752 + 0.741910439281126 -167.906157139786 0.0770126344300586 -36.1167895799047 0.364338751821589 93.7063354773514 0.107164729835367 66.882526055195 + 0.19824629420001 72.0710565688164 0.0875378960715251 60.8857473397449 + 0.045186698521858 108.548169503624 0.364338751821589 93.7063354773514 0.0862692497913178 32.020519222143 0.658865590875768 -162.519597628802 + 0.0292529781768899 168.76302312481 0.378616437115051 86.576955846326 + 0.353807587471509 87.5870345148459 0.107164729835367 66.882526055195 0.658865590875768 -162.519597628802 0.06969507779318 -16.2991055485526 + 0.395308284208725 95.9111341201695 0.117577243147935 25.9966625659845 + 0.0757588143038787 103.333302695385 0.19824629420001 72.0710565688164 0.0292529781768899 168.76302312481 0.395308284208725 95.9111341201695 + 0.0414417851629666 -21.5918386169944 0.723312473510453 -166.967464473227 + 0.191942968766659 49.4805865058752 0.0875378960715251 60.8857473397449 0.378616437115051 86.576955846326 0.117577243147935 25.9966625659845 + 0.723312473510453 -166.967464473227 0.0977397892697531 -28.2253763684372 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +1.95 0.109808362360894 -24.2633347922942 0.734470766603644 178.155470089372 0.0682125824263226 64.0458030391694 0.365425496498388 73.3951966247043 + 0.0809962798868298 69.5950173774073 0.202850806965503 35.6831082907686 + 0.734470766603644 178.155470089372 0.0712228562899246 -30.1612669930184 0.375883883670264 79.5610474490845 0.119263722136642 57.2976345054522 + 0.206998059227245 58.1356755457978 0.0913503549625198 41.84117937207 + 0.0682125824263226 64.0458030391694 0.375883883670264 79.5610474490845 0.128743021645302 19.0993664657849 0.643006507188034 -176.441194182968 + 0.0375655484479952 91.5881289226963 0.390636450834023 72.6763762908911 + 0.365425496498388 73.3951966247043 0.119263722136642 57.2976345054522 0.643006507188034 -176.441194182968 0.0809761610071058 -12.9681647751223 + 0.40800121536421 82.127339946525 0.132191045443119 21.7257810250584 + 0.0809962798868298 69.5950173774073 0.206998059227245 58.1356755457978 0.0375655484479952 91.5881289226963 0.40800121536421 82.127339946525 + 0.0664795118498353 7.60787005613199 0.716416295001503 178.87482667333 + 0.202850806965503 35.6831082907686 0.0913503549625198 41.84117937207 0.390636450834023 72.6763762908911 0.132191045443119 21.7257810250584 + 0.716416295001503 178.87482667333 0.0877126402923642 -31.7607566407312 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2 0.111174117245766 -25.8097794386547 0.730281542800369 164.632524117342 0.0902989921512574 41.7682566974002 0.370032555340583 59.6510416693978 + 0.083213194605852 42.31386109861 0.205930814759612 21.4368638832701 + 0.730281542800369 164.632524117342 0.0822774856419212 -22.6683719179155 0.379326435093873 65.5984552221468 0.129042979306245 42.0029930533977 + 0.20881722824786 43.0784389384601 0.09826459958591 16.271720742822 + 0.0902989921512574 41.7682566974002 0.379326435093873 65.5984552221468 0.156236307979173 6.92548148913055 0.63173149435693 170.312381643189 + 0.0581456533401922 61.7573713961653 0.394931782494596 59.2710845179515 + 0.370032555340583 59.6510416693978 0.129042979306245 42.0029930533977 0.63173149435693 170.312381643189 0.103933413009524 -17.7986999639789 + 0.412200931551582 68.4050140971618 0.151379668132665 11.2729941002692 + 0.083213194605852 42.31386109861 0.20881722824786 43.0784389384601 0.0581456533401922 61.7573713961653 0.412200931551582 68.4050140971618 + 0.0967218906440744 8.68365082897377 0.711914237227749 165.318034548598 + 0.205930814759612 21.4368638832701 0.09826459958591 16.271720742822 0.394931782494596 59.2710845179515 0.151379668132665 11.2729941002692 + 0.711914237227749 165.318034548598 0.0898535500170814 -35.3362366535685 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.05 0.110669970331221 -25.4529235181693 0.716770005542453 150.76951240137 0.110849447757565 24.9307447672016 0.378983006269696 44.3757225106133 + 0.0842933941073184 18.386303955854 0.219587094388318 5.05511323353832 + 0.716770005542453 150.76951240137 0.087072871082389 -16.1186974048673 0.387813400309735 50.4291917072565 0.135002193091084 32.4271781649747 + 0.218852068102967 27.481451431963 0.0995838175268364 0.131785710090473 + 0.110849447757565 24.9307447672016 0.387813400309735 50.4291917072565 0.177295798070994 -4.13900166753798 0.609498957540367 157.046935598419 + 0.077065552003077 44.6907025746825 0.404129487956671 44.0216902511611 + 0.378983006269696 44.3757225106133 0.135002193091084 32.4271781649747 0.609498957540367 157.046935598419 0.116129836395342 -20.7375331884388 + 0.422039624058686 53.5799174572665 0.166171216661152 5.57226378202131 + 0.0842933941073184 18.386303955854 0.218852068102967 27.481451431963 0.077065552003077 44.6907025746825 0.422039624058686 53.5799174572665 + 0.121727169784193 3.91824547285337 0.695200646401976 151.373090299922 + 0.219587094388318 5.05511323353832 0.0995838175268364 0.131785710090473 0.404129487956671 44.0216902511611 0.166171216661152 5.57226378202131 + 0.695200646401976 151.373090299922 0.081570938983403 -27.7802715668613 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.1 0.120594945660971 -28.178556960769 0.712633037867423 137.057552088182 0.130059610663346 4.49698702821124 0.383439487707705 30.5542699425688 + 0.0927021116443073 -8.81896440113313 0.223813522845283 -9.42728725023631 + 0.712633037867423 137.057552088182 0.105087009729126 -19.086726053513 0.390454971349063 36.7697913647339 0.132294765809712 16.497290010917 + 0.218486071827777 13.1859692514556 0.102835057082339 -25.8659661319092 + 0.130059610663346 4.49698702821124 0.390454971349063 36.7697913647339 0.199524256298932 -17.9277309939428 0.599232510716745 143.98194730311 + 0.0962714206057972 24.1487994210728 0.409621958095127 30.4774280713771 + 0.383439487707705 30.5542699425688 0.132294765809712 16.497290010917 0.599232510716745 143.98194730311 0.131657407260311 -32.2653386153774 + 0.425244002247917 40.0400450466963 0.175136068152578 -7.33083410143531 + 0.0927021116443073 -8.81896440113313 0.218486071827777 13.1859692514556 0.0962714206057972 24.1487994210728 0.425244002247917 40.0400450466963 + 0.153349143535299 -3.74573876171777 0.689715586143068 137.715263059785 + 0.223813522845283 -9.42728725023631 0.102835057082339 -25.8659661319092 0.409621958095127 30.4774280713771 0.175136068152578 -7.33083410143531 + 0.689715586143068 137.715263059785 0.0847665516181755 -32.7760125681569 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.15 0.11848540646039 -33.6620504685716 0.700413074881456 123.200789049453 0.132298508805676 -14.2703007966635 0.389178393117236 15.7671397751192 + 0.0927698389972592 -37.9701239437085 0.233547130756161 -25.4689165549186 + 0.700413074881456 123.200789049453 0.107170273715477 -26.5573454218019 0.395929816072842 22.2681327281822 0.110800252208886 3.21759336007753 + 0.224939645321951 -1.3552623235075 0.091147509751113 -54.5776853534596 + 0.132298508805676 -14.2703007966635 0.395929816072842 22.2681327281822 0.201029030954284 -32.9930857496743 0.583645502710776 131.015552409415 + 0.0986376330731353 5.93278034144647 0.416654161409455 15.7961737834617 + 0.389178393117236 15.7671397751192 0.110800252208886 3.21759336007753 0.583645502710776 131.015552409415 0.126195552818508 -45.9294547203947 + 0.432154031641529 25.8727591407117 0.162673491757738 -18.3125432782753 + 0.0927698389972592 -37.9701239437085 0.224939645321951 -1.3552623235075 0.0986376330731353 5.93278034144647 0.432154031641529 25.8727591407117 + 0.1717538804688 -15.6978364026341 0.675972367901504 123.835867100891 + 0.233547130756161 -25.4689165549186 0.091147509751113 -54.5776853534596 0.416654161409455 15.7961737834617 0.162673491757738 -18.3125432782753 + 0.675972367901504 123.835867100891 0.0685626075725209 -34.9920648520061 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.2 0.102392645070596 -38.2315174093957 0.69111749276767 109.915504401475 0.11615360472917 -31.2456144999383 0.387708138035813 1.57591783808335 + 0.0855621058122976 -71.2198693119841 0.235035630667452 -42.016191192622 + 0.69111749276767 109.915504401475 0.0928405954414483 -25.9862911221443 0.395108685745278 8.25185964937789 0.0826381868343826 3.44927967357327 + 0.226984651375037 -16.4933662972519 0.0635806133155963 -84.1198178196822 + 0.11615360472917 -31.2456144999383 0.395108685745278 8.25185964937789 0.178007027854769 -47.6036724228433 0.575075221849331 118.382610526506 + 0.0829537285630762 -7.55052930720222 0.417520202608437 1.52185101012828 + 0.387708138035813 1.57591783808335 0.0826381868343826 3.44927967357327 0.575075221849331 118.382610526506 0.0992158872009507 -52.6409506495012 + 0.433762689126233 11.9090840135873 0.141475009235224 -20.432112839184 + 0.0855621058122976 -71.2198693119841 0.226984651375037 -16.4933662972519 0.0829537285630762 -7.55052930720222 0.433762689126233 11.9090840135873 + 0.169924819066485 -28.4180014203547 0.662444827157978 110.507970450054 + 0.235035630667452 -42.016191192622 0.0635806133155963 -84.1198178196822 0.417520202608437 1.52185101012828 0.141475009235224 -20.432112839184 + 0.662444827157978 110.507970450054 0.0552090490893729 -7.0555303287734 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.25 0.0969855516649355 -28.2781962301824 0.690077910721627 96.094023647386 0.107743160176392 -37.471658728803 0.392232852502097 -11.3344315284262 + 0.0705355104703394 -94.058183395745 0.232238341093572 -55.9788986974928 + 0.690077910721627 96.094023647386 0.106763586071421 -19.9583434632808 0.398881887047489 -4.49424690010164 0.0815350009918644 3.19470320337003 + 0.224942214086517 -29.7276810499469 0.0494397625445889 -97.5831054811367 + 0.107743160176392 -37.471658728803 0.398881887047489 -4.49424690010164 0.158381967114034 -52.6053126166191 0.57048329171978 104.940998399566 + 0.0823832297063271 -6.61543175525809 0.421181917082905 -11.6624195901938 + 0.392232852502097 -11.3344315284262 0.0815350009918644 3.19470320337003 0.57048329171978 104.940998399566 0.0961579918156821 -49.1952723587519 + 0.43673780915173 -1.13418366691093 0.149832088498131 -23.5434271607282 + 0.0705355104703394 -94.058183395745 0.224942214086517 -29.7276810499469 0.0823832297063271 -6.61543175525809 0.43673780915173 -1.13418366691093 + 0.164372436077325 -32.6814443567148 0.657285922416686 97.2618755139255 + 0.232238341093572 -55.9788986974928 0.0494397625445889 -97.5831054811367 0.421181917082905 -11.6624195901938 0.149832088498131 -23.5434271607282 + 0.657285922416686 97.2618755139255 0.0881120073839595 -1.05190880038933 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.3 0.0948732446711447 -20.1445602786187 0.674850086770888 80.7554410230545 0.0868114614396109 -47.8682776912098 0.416618722582181 -25.6408845261908 + 0.0654560261546747 -130.068931925455 0.252917934795547 -68.3586153463379 + 0.674850086770888 80.7554410230545 0.103384307872895 -28.3245766208993 0.424608792399938 -18.5281346750185 0.0517140294397544 -1.16121826340501 + 0.243544698132872 -40.5518067588739 0.0538803976326548 -143.29621159457 + 0.0868114614396109 -47.8682776912098 0.424608792399938 -18.5281346750185 0.126947287154854 -61.7325669474965 0.549438698437865 89.9077339473764 + 0.0668093291596864 -10.5766239261446 0.447526877256862 -26.3320375686802 + 0.416618722582181 -25.6408845261908 0.0517140294397544 -1.16121826340501 0.549438698437865 89.9077339473764 0.0797705018845787 -62.9157552476646 + 0.460809387599078 -14.5234443919887 0.127195344855034 -33.6930192187285 + 0.0654560261546747 -130.068931925455 0.243544698132872 -40.5518067588739 0.0668093291596864 -10.5766239261446 0.460809387599078 -14.5234443919887 + 0.151242572253028 -42.4677778237503 0.644329466843818 82.079106873619 + 0.252917934795547 -68.3586153463379 0.0538803976326548 -143.29621159457 0.447526877256862 -26.3320375686802 0.127195344855034 -33.6930192187285 + 0.644329466843818 82.079106873619 0.0860880453430154 -2.45965641443907 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.35 0.128563672403987 -12.4638404996194 0.631666894495238 67.2606619856709 0.0842523457227639 -39.730452565089 0.426288890859964 -44.186720017697 + 0.0397853976724781 -169.648260362501 0.279279091487319 -88.4405433791167 + 0.631666894495238 67.2606619856709 0.0872531417657529 -15.4755967311333 0.436158815706668 -37.0327063919941 0.0530158402739555 50.9139407374973 + 0.274881789885131 -58.8199195292163 0.0603541664340214 149.3794613063 + 0.0842523457227639 -39.730452565089 0.436158815706668 -37.0327063919941 0.107336497593481 -50.9095436910873 0.503661788538027 77.9497568876881 + 0.0802070181905112 4.14898398372629 0.453497043392905 -45.2516179959214 + 0.426288890859964 -44.186720017697 0.0530158402739555 50.9139407374973 0.503661788538027 77.9497568876881 0.0359859571453473 -40.750033401501 + 0.477646107233776 -32.0841462495659 0.101684423788264 -20.7457987460945 + 0.0397853976724781 -169.648260362501 0.274881789885131 -58.8199195292163 0.0802070181905112 4.14898398372629 0.477646107233776 -32.0841462495659 + 0.13255346044226 -38.4142960844749 0.599776323281335 68.6130096616131 + 0.279279091487319 -88.4405433791167 0.0603541664340214 149.3794613063 0.453497043392905 -45.2516179959214 0.101684423788264 -20.7457987460945 + 0.599776323281335 68.6130096616131 0.112899243985872 12.1604467188949 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.4 0.171016473087779 -27.9636264936091 0.607401493813828 57.715016981357 0.115825679521494 -53.3590203862872 0.393088208866977 -62.1625971260115 + 0.0140383678087775 -128.397927216647 0.270285036481987 -112.468422354767 + 0.607401493813828 57.715016981357 0.129471477182357 -7.01928345786288 0.400990535396594 -55.2100052474931 0.0988126668679678 41.4009960349551 + 0.274826252543664 -82.2826229126292 0.0612736529725182 88.559763364585 + 0.115825679521494 -53.3590203862872 0.400990535396594 -55.2100052474931 0.14043983909028 -52.9542288641157 0.491350430307428 71.0096785253767 + 0.119146456679812 -13.4608719092599 0.410815543137007 -63.0688352436015 + 0.393088208866977 -62.1625971260115 0.0988126668679678 41.4009960349551 0.491350430307428 71.0096785253767 0.0768325268922348 -1.7079018602007 + 0.449982264379896 -50.1278157000298 0.138401770172365 -14.425717383225 + 0.0140383678087775 -128.397927216647 0.274826252543664 -82.2826229126292 0.119146456679812 -13.4608719092599 0.449982264379896 -50.1278157000298 + 0.163103382253151 -35.9966935099143 0.57206368769693 59.816746902568 + 0.270285036481987 -112.468422354767 0.0612736529725182 88.559763364585 0.410815543137007 -63.0688352436015 0.138401770172365 -14.425717383225 + 0.57206368769693 59.816746902568 0.170405649752081 -0.301858237821054 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.45 0.138018425872326 -52.1179800482075 0.638190360872208 46.2025162691404 0.103254324034239 -99.9907667223451 0.359719563067159 -71.2089449017911 + 0.0597228730857963 -154.071395326384 0.224100365217897 -127.099132230953 + 0.638190360872208 46.2025162691404 0.133331242008108 -20.4885956908672 0.367439700985233 -63.7208417166729 0.0937267099461983 35.8299061480345 + 0.235642603516439 -97.2343752410784 0.0593602713244793 78.8493750209876 + 0.103254324034239 -99.9907667223451 0.367439700985233 -63.7208417166729 0.119263869275621 -87.8502799250839 0.537009099188687 58.6880320462491 + 0.0951417539697207 -53.0022732138953 0.378449553812121 -70.6733734183306 + 0.359719563067159 -71.2089449017911 0.0937267099461983 35.8299061480345 0.537009099188687 58.6880320462491 0.0876877621745312 -11.4674939779945 + 0.414314030681899 -60.1110804054569 0.133790796604174 -24.7091041511626 + 0.0597228730857963 -154.071395326384 0.235642603516439 -97.2343752410784 0.0951417539697207 -53.0022732138953 0.414314030681899 -60.1110804054569 + 0.170405859421936 -59.3745324887882 0.609429295264047 48.7584067650953 + 0.224100365217897 -127.099132230953 0.0593602713244793 78.8493750209876 0.378449553812121 -70.6733734183306 0.133790796604174 -24.7091041511626 + 0.609429295264047 48.7584067650953 0.166908002060993 -15.2896178040998 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.5 0.106285519465153 -37.2889019255879 0.647156421375857 30.7317144217508 0.0364040849883833 -131.998281768836 0.384858741988401 -81.1986214945403 + 0.0650559738633696 143.040528338665 0.226160748685974 -132.501215828063 + 0.647156421375857 30.7317144217508 0.14715805163549 -22.8871952201941 0.391709641239572 -74.0742545265415 0.111600788400098 29.7922667692545 + 0.236811920084825 -105.365221662015 0.0756234204972608 52.9233146829382 + 0.0364040849883833 -131.998281768836 0.391709641239572 -74.0742545265415 0.0422476423059685 -77.6491242884734 0.532692508739581 41.944456592614 + 0.0467867316958285 -39.4740196434963 0.409852512264676 -81.72367605067 + 0.384858741988401 -81.1986214945403 0.111600788400098 29.7922667692545 0.532692508739581 41.944456592614 0.108656548933323 -14.9231308588324 + 0.434982457333969 -70.6247227765956 0.139065579145322 -27.73821251239 + 0.0650559738633696 143.040528338665 0.236811920084825 -105.365221662015 0.0467867316958285 -39.4740196434963 0.434982457333969 -70.6247227765956 + 0.114892096065841 -65.7597172063806 0.616899034316692 33.086199390862 + 0.226160748685974 -132.501215828063 0.0756234204972608 52.9233146829382 0.409852512264676 -81.72367605067 0.139065579145322 -27.73821251239 + 0.616899034316692 33.086199390862 0.174633638357148 -24.8313780292451 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.55 0.11447337893234 -42.285694634508 0.639659131167004 16.7129943682449 0.0240856090193534 -146.610496223384 0.39535666338666 -95.3123939663335 + 0.0510467364648147 118.086854855828 0.237402127151978 -146.104916596137 + 0.639659131167004 16.7129943682449 0.1431668915217 -35.0660217539294 0.40070467738754 -87.3880323590418 0.103506841081986 24.572923846595 + 0.241785695693201 -118.375403464192 0.0698721566584503 39.7440973818106 + 0.0240856090193534 -146.610496223384 0.40070467738754 -87.3880323590418 0.038582147039557 -57.5602036680348 0.520006090163318 28.4058508238878 + 0.0496838963157734 -46.5196528887138 0.415289853803236 -95.9941779818883 + 0.39535666338666 -95.3123939663335 0.103506841081986 24.572923846595 0.520006090163318 28.4058508238878 0.10726577734513 -23.89168866471 + 0.442299196423211 -84.0943994461243 0.124872167944476 -34.6520001941165 + 0.0510467364648147 118.086854855828 0.241785695693201 -118.375403464192 0.0496838963157734 -46.5196528887138 0.442299196423211 -84.0943994461243 + 0.10575611194343 -66.4635372258404 0.610122462428734 19.5283178042624 + 0.237402127151978 -146.104916596137 0.0698721566584503 39.7440973818106 0.415289853803236 -95.9941779818883 0.124872167944476 -34.6520001941165 + 0.610122462428734 19.5283178042624 0.155621990011839 -36.7447573217315 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.6 0.112539826567712 -44.2925010667873 0.614763599035508 2.96981119531836 0.00993948920138976 129.774178223432 0.406042989222333 -111.698346935004 + 0.0476955235426616 85.4675280527159 0.260662205265394 -162.411025178875 + 0.614763599035508 2.96981119531836 0.127386577813286 -27.0081329674 0.416695781740991 -103.750087609067 0.135793338366826 30.0488760849754 + 0.265930674366406 -133.37589367231 0.108388092068288 34.1924874399324 + 0.00993948920138976 129.774178223432 0.416695781740991 -103.750087609067 0.0458740750025076 -21.7605614195275 0.487980596217652 15.6360109821665 + 0.0448977125243597 -42.382037442202 0.424669200746636 -112.895180361617 + 0.406042989222333 -111.698346935004 0.135793338366826 30.0488760849754 0.487980596217652 15.6360109821665 0.124093887354351 -11.7248037788968 + 0.457017770467872 -99.7538449462007 0.131592309739162 -18.5381865751346 + 0.0476955235426616 85.4675280527159 0.265930674366406 -133.37589367231 0.0448977125243597 -42.382037442202 0.457017770467872 -99.7538449462007 + 0.0869338963582919 -62.6280656447193 0.584588044939639 5.78865515974486 + 0.260662205265394 -162.411025178875 0.108388092068288 34.1924874399324 0.424669200746636 -112.895180361617 0.131592309739162 -18.5381865751346 + 0.584588044939639 5.78865515974486 0.150720354865321 -27.8679572915351 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.65 0.0783299767778419 -45.522124288404 0.61376440925362 -8.90848524847727 0.0454938548490827 105.169145370378 0.389004181038572 -125.448869636807 + 0.0495130549964186 89.2686138968451 0.248032748953721 179.35200681877 + 0.61376440925362 -8.90848524847727 0.139005145078045 -29.4013561392481 0.400550328820477 -117.670341586351 0.151891815219869 16.652022895415 + 0.259486932320462 -150.818563036649 0.122226640255672 9.33163444877745 + 0.0454938548490827 105.169145370378 0.400550328820477 -117.670341586351 0.0385798718578333 21.1727670973085 0.493042279034357 4.75623215374579 + 0.0143526964709181 -90.2169353992911 0.396773511523467 -126.24318586313 + 0.389004181038572 -125.448869636807 0.151891815219869 16.652022895415 0.493042279034357 4.75623215374579 0.151053541226295 -22.4703058665567 + 0.439420636563303 -113.601173678315 0.159553508722683 -25.4372777566749 + 0.0495130549964186 89.2686138968451 0.259486932320462 -150.818563036649 0.0143526964709181 -90.2169353992911 0.439420636563303 -113.601173678315 + 0.0596675554926964 -76.2123660175131 0.587629951118329 -5.2410058673179 + 0.248032748953721 179.35200681877 0.122226640255672 9.33163444877745 0.396773511523467 -126.24318586313 0.159553508722683 -25.4372777566749 + 0.587629951118329 -5.2410058673179 0.164405058240248 -36.529939360719 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.7 0.0844999674560314 -19.3671129801239 0.618831034046788 -21.9728247124017 0.0848707913382293 61.2925892343604 0.385499183722643 -137.509690561036 + 0.0704885162063996 61.4930318265815 0.23539168714552 166.206014619515 + 0.618831034046788 -21.9728247124017 0.152529263080357 -29.9019976574591 0.39588404450837 -130.369609845531 0.168323754687389 4.10061941875208 + 0.253529189417867 -165.679751976093 0.139255923785949 -11.8829163194368 + 0.0848707913382293 61.2925892343604 0.39588404450837 -130.369609845531 0.100525798912109 24.5288846516035 0.497196820362243 -8.42673963184218 + 0.0291749785120067 56.0721273441414 0.390998830259932 -137.283973947001 + 0.385499183722643 -137.509690561036 0.168323754687389 4.10061941875208 0.497196820362243 -8.42673963184218 0.173014956331736 -32.3964007368408 + 0.434300210657574 -125.945974763748 0.18479529854839 -33.1488812208523 + 0.0704885162063996 61.4930318265815 0.253529189417867 -165.679751976093 0.0291749785120067 56.0721273441414 0.434300210657574 -125.945974763748 + 0.0296805192870382 -14.3636155036896 0.599436152753679 -18.4251197487363 + 0.23539168714552 166.206014619515 0.139255923785949 -11.8829163194368 0.390998830259932 -137.283973947001 0.18479529854839 -33.1488812208523 + 0.599436152753679 -18.4251197487363 0.170101889168094 -44.5314929590184 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.75 0.111094934222493 -21.3523643615326 0.616617241516235 -36.245224293429 0.100880321237128 28.624373094582 0.39759035287308 -150.548437411244 + 0.0743619436687432 24.5603198214636 0.24307443602469 155.099697430217 + 0.616617241516235 -36.245224293429 0.161235654721589 -35.720153451807 0.404099929075474 -143.489174827816 0.167769107468764 -10.350103915159 + 0.254296719280954 -178.729862345684 0.142074117452184 -34.489206214542 + 0.100880321237128 28.624373094582 0.404099929075474 -143.489174827816 0.140912672347562 4.15215670301143 0.486918782625485 -22.5095621636381 + 0.0502454594757528 23.1686695061317 0.405123070034042 -150.003674381475 + 0.39759035287308 -150.548437411244 0.167769107468764 -10.350103915159 0.486918782625485 -22.5095621636381 0.17843349556273 -45.371773908052 + 0.442509847285119 -138.624610880942 0.194101440024654 -43.7798732559898 + 0.0743619436687432 24.5603198214636 0.254296719280954 -178.729862345684 0.0502454594757528 23.1686695061317 0.442509847285119 -138.624610880942 + 0.0741850542673248 6.3493638966988 0.598995587941789 -33.0985751729761 + 0.24307443602469 155.099697430217 0.142074117452184 -34.489206214542 0.405123070034042 -150.003674381475 0.194101440024654 -43.7798732559898 + 0.598995587941789 -33.0985751729761 0.156091769143311 -53.8935005510349 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.8 0.111576588559763 -24.5499725766195 0.609403844680309 -49.7686284738297 0.0991197132614999 12.2675992915552 0.401438847216893 -164.740689078589 + 0.0614421820831856 -4.56326263988665 0.251909892037527 140.271407011623 + 0.609403844680309 -49.7686284738297 0.162751229067873 -44.8949286009242 0.402943183799318 -157.460001639393 0.1543258571028 -27.2060024467258 + 0.254432103597831 166.562886638361 0.139419049359646 -60.1784904401424 + 0.0991197132614999 12.2675992915552 0.402943183799318 -157.460001639393 0.14657866226447 -7.12075594691832 0.477622884939506 -35.1720742450198 + 0.0440524540658827 12.5108420277581 0.406253609392905 -164.007424787842 + 0.401438847216893 -164.740689078589 0.1543258571028 -27.2060024467258 0.477622884939506 -35.1720742450198 0.171294020313236 -60.7164199920969 + 0.444439454863099 -152.133585873252 0.193488928575901 -56.3315345422819 + 0.0614421820831856 -4.56326263988665 0.254432103597831 166.562886638361 0.0440524540658827 12.5108420277581 0.444439454863099 -152.133585873252 + 0.0992516046915075 0.710612682281955 0.591169112279564 -46.796082558545 + 0.251909892037527 140.271407011623 0.139419049359646 -60.1784904401424 0.406253609392905 -164.007424787842 0.193488928575901 -56.3315345422819 + 0.591169112279564 -46.796082558545 0.133117464521873 -63.6431555544594 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.85 0.117159950017952 -20.8779497983353 0.608947192944809 -63.3009958447409 0.104818849022036 2.5540247686285 0.402578081751003 -177.990333714071 + 0.0503112503766908 -23.7892364984792 0.251497326787061 125.799558526321 + 0.608947192944809 -63.3009958447409 0.137460254909341 -53.9152868073848 0.401415741165004 -169.770210463095 0.117807594333258 -41.9358191447282 + 0.247533511483712 153.404368115561 0.118447962125663 -89.3233255924957 + 0.104818849022036 2.5540247686285 0.401415741165004 -169.770210463095 0.158652943196523 -10.7426319825267 0.47662916637178 -48.6530595659505 + 0.0462498550403121 23.1319582321854 0.407339432851304 -176.323682097886 + 0.402578081751003 -177.990333714071 0.117807594333258 -41.9358191447282 0.47662916637178 -48.6530595659505 0.137490592993096 -76.2843151853553 + 0.446738017137622 -164.59663599729 0.169038709414526 -67.4998721572527 + 0.0503112503766908 -23.7892364984792 0.247533511483712 153.404368115561 0.0462498550403121 23.1319582321854 0.446738017137622 -164.59663599729 + 0.122336594269094 -0.0389443396622938 0.590760206006262 -60.6555479217716 + 0.251497326787061 125.799558526321 0.118447962125663 -89.3233255924957 0.407339432851304 -176.323682097886 0.169038709414526 -67.4998721572527 + 0.590760206006262 -60.6555479217716 0.0875130229805621 -68.0046072428175 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.9 0.129529138803739 -17.3587521804902 0.598958736720118 -78.0521155441069 0.109352420371925 -6.11674501881117 0.417159870614756 167.774437622775 + 0.0372984018352856 -39.875026052995 0.264651942105398 112.439078980576 + 0.598958736720118 -78.0521155441069 0.108931263643184 -49.003093537934 0.420195662451399 176.539121864666 0.0834720343756569 -45.2764237756989 + 0.258483801708821 142.276914219649 0.0876058317577183 -115.411736368533 + 0.109352420371925 -6.11674501881117 0.420195662451399 176.539121864666 0.174370256412824 -14.8275178117948 0.454188347911798 -62.9780888029293 + 0.0554468831528314 29.5265780088591 0.425214863209665 169.124604788627 + 0.417159870614756 167.774437622775 0.0834720343756569 -45.2764237756989 0.454188347911798 -62.9780888029293 0.0938939629051104 -83.4233540681664 + 0.465447285359384 -178.403617349694 0.14229807537355 -69.5246911976102 + 0.0372984018352856 -39.875026052995 0.258483801708821 142.276914219649 0.0554468831528314 29.5265780088591 0.465447285359384 -178.403617349694 + 0.146571585669727 -3.61552092581974 0.572742486617348 -75.575266176793 + 0.264651942105398 112.439078980576 0.0876058317577183 -115.411736368533 0.425214863209665 169.124604788627 0.14229807537355 -69.5246911976102 + 0.572742486617348 -75.575266176793 0.0608196334067644 -32.4193803847412 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +2.95 0.159691324207597 -20.0134314450179 0.57836978935076 -90.728515231359 0.122235755220238 -19.1529231352939 0.410684922354417 151.742485459749 + 0.0354742417882667 -43.7532953326981 0.26996446902164 94.1502801214389 + 0.57836978935076 -90.728515231359 0.112024682717649 -31.9325488822173 0.415630073086609 160.040122270171 0.0718450809517387 -33.3959582324927 + 0.272280834420469 125.160737931588 0.055139840219909 -128.704806718542 + 0.122235755220238 -19.1529231352939 0.415630073086609 160.040122270171 0.201196060528778 -22.1040806853104 0.436278064910908 -73.1498591043666 + 0.0750064927881803 22.4704713124999 0.412297216147214 153.153561957572 + 0.410684922354417 151.742485459749 0.0718450809517387 -33.3959582324927 0.436278064910908 -73.1498591043666 0.0636773573667813 -65.0504727053105 + 0.461078096734937 165.555193987478 0.14562192196826 -63.0400073594542 + 0.0354742417882667 -43.7532953326981 0.272280834420469 125.160737931588 0.0750064927881803 22.4704713124999 0.461078096734937 165.555193987478 + 0.180981504255007 -8.29222469513435 0.548492501646319 -87.3759900596841 + 0.26996446902164 94.1502801214389 0.055139840219909 -128.704806718542 0.412297216147214 153.153561957572 0.14562192196826 -63.0400073594542 + 0.548492501646319 -87.3759900596841 0.111575100975893 -13.9241736815043 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3 0.175195444105825 -29.700532958961 0.580392979741387 -102.951498638892 0.117957908576937 -38.3612582219284 0.396121320752305 138.977429599224 + 0.0364467056135665 -69.9220661136971 0.253997674611873 78.6004126689711 + 0.580392979741387 -102.951498638892 0.142653022504664 -35.0311001561051 0.394478166314184 147.091517169141 0.0772707013152865 -45.7002507040733 + 0.25919926485511 108.477405398161 0.0606953718993061 -134.067803597567 + 0.117957908576937 -38.3612582219284 0.394478166314184 147.091517169141 0.211822745462006 -33.5410582582585 0.449273901838046 -84.7197876616788 + 0.0784096105504885 8.0179886176725 0.394970353099563 141.535393964578 + 0.396121320752305 138.977429599224 0.0772707013152865 -45.7002507040733 0.449273901838046 -84.7197876616788 0.0704193049339012 -59.8689021750799 + 0.441805766800273 152.69659445611 0.171843000729759 -73.2474977156277 + 0.0364467056135665 -69.9220661136971 0.25919926485511 108.477405398161 0.0784096105504885 8.0179886176725 0.441805766800273 152.69659445611 + 0.21201771063865 -19.1501338470858 0.55480757428722 -99.0244687946589 + 0.253997674611873 78.6004126689711 0.0606953718993061 -134.067803597567 0.394970353099563 141.535393964578 0.171843000729759 -73.2474977156277 + 0.55480757428722 -99.0244687946589 0.138227824044034 -29.5753900990106 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.05 0.172516522495109 -33.7179417725656 0.584212410694177 -117.040100982462 0.0924650710455552 -49.061572122243 0.402663099197558 127.098263850047 + 0.021386955549414 -110.948747881562 0.24848128334664 67.312690512406 + 0.584212410694177 -117.040100982462 0.140196526034534 -44.8300093109653 0.395862061549953 136.199567173264 0.053292570390783 -73.545165308951 + 0.247719043342151 97.1255011942389 0.0761767874342411 -168.11616965402 + 0.0924650710455552 -49.061572122243 0.395862061549953 136.199567173264 0.203638382992079 -39.6175582241261 0.451202582752781 -99.5916293218916 + 0.0725942696134722 7.397913243085 0.404492372648123 130.348676585926 + 0.402663099197558 127.098263850047 0.053292570390783 -73.545165308951 0.451202582752781 -99.5916293218916 0.047486737783564 -67.9448650140141 + 0.444904819193416 141.457470451273 0.162388555743624 -90.6715817336654 + 0.021386955549414 -110.948747881562 0.247719043342151 97.1255011942389 0.0725942696134722 7.397913243085 0.444904819193416 141.457470451273 + 0.221885836874466 -29.4685153803303 0.560725630597975 -113.117810359069 + 0.24848128334664 67.312690512406 0.0761767874342411 -168.11616965402 0.404492372648123 130.348676585926 0.162388555743624 -90.6715817336654 + 0.560725630597975 -113.117810359069 0.12344725865408 -36.542281410051 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.1 0.188060895614002 -38.3940688212898 0.576621057223266 -131.830751545233 0.0830909937182605 -56.1047353402059 0.417437774112307 113.521293589274 + 0.00836292337860912 -133.310709314778 0.256648728106339 56.2005316406757 + 0.576621057223266 -131.830751545233 0.106824721045046 -43.1299908410806 0.414299501629406 123.839543129767 0.011709839733229 175.130931364559 + 0.254356497861724 87.3446198250418 0.0957651298972352 143.939348989644 + 0.0830909937182605 -56.1047353402059 0.414299501629406 123.839543129767 0.211417791786279 -46.2635463855901 0.43454264628091 -114.630297529781 + 0.0769030091532881 2.84084791034518 0.425454640388202 117.101829006599 + 0.417437774112307 113.521293589274 0.011709839733229 175.130931364559 0.43454264628091 -114.630297529781 0.0264000770007984 25.7664330135906 + 0.461292200325262 128.716183426398 0.115657928914134 -103.825265719543 + 0.00836292337860912 -133.310709314778 0.254356497861724 87.3446198250418 0.0769030091532881 2.84084791034518 0.461292200325262 128.716183426398 + 0.231560022590196 -38.8550683331704 0.552470175285143 -127.930271912586 + 0.256648728106339 56.2005316406757 0.0957651298972352 143.939348989644 0.425454640388202 117.101829006599 0.115657928914134 -103.825265719543 + 0.552470175285143 -127.930271912586 0.115857679774062 -21.8129708438028 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.15 0.200328310974556 -44.4279638352745 0.546942375487701 -145.679031439294 0.0699678925598499 -57.7413362053675 0.428991695267452 96.9355341568084 + 0.00981070634719097 53.5560720259424 0.281742844761943 41.2306859391483 + 0.546942375487701 -145.679031439294 0.120516608545664 -20.5422538416881 0.430638354780171 107.135962160521 0.0566943691882152 63.3885082862109 + 0.280698929294645 73.361927273705 0.1066109362851 95.6966095544608 + 0.0699678925598499 -57.7413362053675 0.430638354780171 107.135962160521 0.213549761194948 -50.6304465358585 0.397505027937238 -126.646152389341 + 0.0844918391223149 3.6518739131372 0.437491856196207 99.7840751661363 + 0.428991695267452 96.9355341568084 0.0566943691882152 63.3885082862109 0.397505027937238 -126.646152389341 0.102443712965097 27.8000112466409 + 0.475403177626977 113.059102497019 0.0802667569906585 -87.5248601430156 + 0.00981070634719097 53.5560720259424 0.280698929294645 73.361927273705 0.0844918391223149 3.6518739131372 0.475403177626977 113.059102497019 + 0.230160064510315 -46.7000174393035 0.522693889225369 -141.447487110402 + 0.281742844761943 41.2306859391483 0.1066109362851 95.6966095544608 0.437491856196207 99.7840751661363 0.0802667569906585 -87.5248601430156 + 0.522693889225369 -141.447487110402 0.167888265230968 -16.8176723707753 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.2 0.223209991745528 -55.766956260832 0.524890790355551 -155.81468812571 0.0821266937362564 -66.2534610927075 0.407561912797964 79.4326222291553 + 0.0306504625261898 -14.3183701706167 0.290436620226001 20.6082403534942 + 0.524890790355551 -155.81468812571 0.187910616091123 -22.2839745584875 0.407353032030876 89.2312431210243 0.0965097551340182 21.7880904256224 + 0.294102130638254 53.6453343261866 0.106948977687093 47.562051744166 + 0.0821266937362564 -66.2534610927075 0.407353032030876 89.2312431210243 0.245742014375301 -59.5231513062561 0.386228959537705 -133.019087825121 + 0.106408226434842 -11.9871803871076 0.407306395058451 82.1011549921194 + 0.407561912797964 79.4326222291553 0.0965097551340182 21.7880904256224 0.386228959537705 -133.019087825121 0.174416603255475 3.33137974175128 + 0.458715875650222 96.2997194437478 0.117862584554941 -69.720008850742 + 0.0306504625261898 -14.3183701706167 0.294102130638254 53.6453343261866 0.106408226434842 -11.9871803871076 0.458715875650222 96.2997194437478 + 0.244767141248338 -54.0095954438711 0.500925774564832 -151.120172705444 + 0.290436620226001 20.6082403534942 0.106948977687093 47.562051744166 0.407306395058451 82.1011549921194 0.117862584554941 -69.720008850742 + 0.500925774564832 -151.120172705444 0.229748650065161 -30.9864887737657 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.25 0.218125876759128 -77.7978798162042 0.551606904973666 -165.639834915262 0.0898534670342991 -109.347306195416 0.36080865606426 67.644951263013 + 0.0439798255883289 -81.6701633145422 0.256244399589611 0.698499445993199 + 0.551606904973666 -165.639834915262 0.22517131498164 -44.1813551791389 0.353009438724229 78.1620341837127 0.0875066743884298 -22.0524317927362 + 0.266410844064857 33.8034428027859 0.0729903005531747 2.3616312794476 + 0.0898534670342991 -109.347306195416 0.353009438724229 78.1620341837127 0.25746414467083 -82.8785030337375 0.436161016077402 -142.670403489405 + 0.0974761897249667 -47.0621761946469 0.352427137910302 72.2573492873107 + 0.36080865606426 67.644951263013 0.0875066743884298 -22.0524317927362 0.436161016077402 -142.670403489405 0.191553034024065 -24.3280636449168 + 0.413879344476329 84.1253825951965 0.166623153850138 -91.1163821750538 + 0.0439798255883289 -81.6701633145422 0.266410844064857 33.8034428027859 0.0974761897249667 -47.0621761946469 0.413879344476329 84.1253825951965 + 0.260802081076953 -70.0101544467412 0.529056539618337 -160.292832856943 + 0.256244399589611 0.698499445993199 0.0729903005531747 2.3616312794476 0.352427137910302 72.2573492873107 0.166623153850138 -91.1163821750538 + 0.529056539618337 -160.292832856943 0.240691366824794 -54.8016061858141 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.3 0.153457801492122 -98.3656649438033 0.583682288253459 179.07454923069 0.0742026300406149 -178.975497289938 0.361255793973107 61.280932273702 + 0.0382128040531404 -152.675961696114 0.221766057414344 -7.37045492887132 + 0.583682288253459 179.07454923069 0.186936263767281 -61.6009980458186 0.356923754983011 73.5476891562362 0.0351381386237087 -47.7068733947453 + 0.234544674186184 24.241826597335 0.0327883919936496 3.32251539141197 + 0.0742026300406149 -178.975497289938 0.356923754983011 73.5476891562362 0.190785211588414 -107.999602515559 0.466525798527445 -161.00123587266 + 0.0414997097018482 -85.2082193256647 0.363065399521296 67.8705404831168 + 0.361255793973107 61.280932273702 0.0351381386237087 -47.7068733947453 0.466525798527445 -161.00123587266 0.156337379011715 -35.8646024294639 + 0.411046216221367 77.0716910872626 0.151147436358159 -117.958256402713 + 0.0382128040531404 -152.675961696114 0.234544674186184 24.241826597335 0.0414997097018482 -85.2082193256647 0.411046216221367 77.0716910872626 + 0.227079417037192 -90.4174923528735 0.566649512658136 -175.251433043386 + 0.221766057414344 -7.37045492887132 0.0327883919936496 3.32251539141197 0.363065399521296 67.8705404831168 0.151147436358159 -117.958256402713 + 0.566649512658136 -175.251433043386 0.188537511065705 -70.3007290620918 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.35 0.0829706926059301 -100.593191852628 0.587049910127248 163.053431122046 0.0832466692016597 108.435702915255 0.388040814467699 50.6957292745146 + 0.0308141367246686 131.013440209591 0.223553595534665 -12.93921194111 + 0.587049910127248 163.053431122046 0.140028065774423 -64.0780377851235 0.390370976089999 63.4818223722196 0.0180714551999138 45.5446657037304 + 0.232695290380958 17.0335897104 0.0401653567564923 30.3921918301162 + 0.0832466692016597 108.435702915255 0.390370976089999 63.4818223722196 0.105717461197449 -119.376983871921 0.457062404661212 -179.119381463012 + 0.017611751141996 71.0061524499678 0.401555023005724 57.3793097442837 + 0.388040814467699 50.6957292745146 0.0180714551999138 45.5446657037304 0.457062404661212 -179.119381463012 0.142752487548452 -32.9657625866265 + 0.436806321656784 66.9607216597403 0.114145627157773 -136.167992702275 + 0.0308141367246686 131.013440209591 0.232695290380958 17.0335897104 0.017611751141996 71.0061524499678 0.436806321656784 66.9607216597403 + 0.167057313493056 -106.314778317266 0.577011995631262 168.512224848587 + 0.223553595534665 -12.93921194111 0.0401653567564923 30.3921918301162 0.401555023005724 57.3793097442837 0.114145627157773 -136.167992702275 + 0.577011995631262 168.512224848587 0.143158216696226 -73.1478190857818 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.4 0.059135525906848 -77.7193900218851 0.578570386857037 147.411738524779 0.100795396849169 63.2038000401006 0.415288616048479 37.0338090849995 + 0.0262925541821213 59.077514853448 0.245048737249094 -22.0258101913477 + 0.578570386857037 147.411738524779 0.128823991937116 -54.8449817157982 0.423799791251359 49.8795982377372 0.0414556779712342 41.2455098227933 + 0.247535348055264 7.72580374328328 0.0544357401961516 12.7625467556596 + 0.100795396849169 63.2038000401006 0.423799791251359 49.8795982377372 0.0640057516054705 -103.943944801211 0.427635968546349 164.505401018255 + 0.0537591090038361 40.2474186967182 0.436765807500879 42.8708962135739 + 0.415288616048479 37.0338090849995 0.0414556779712342 41.2455098227933 0.427635968546349 164.505401018255 0.157261570012057 -32.8482478445552 + 0.466719860658824 53.8657458070093 0.0820809546502265 -143.061777945587 + 0.0262925541821213 59.077514853448 0.247535348055264 7.72580374328328 0.0537591090038361 40.2474186967182 0.466719860658824 53.8657458070093 + 0.113156468602696 -115.211602328095 0.568115426966889 152.492014167411 + 0.245048737249094 -22.0258101913477 0.0544357401961516 12.7625467556596 0.436765807500879 42.8708962135739 0.0820809546502265 -143.061777945587 + 0.568115426966889 152.492014167411 0.121445240818127 -68.5254403186998 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.45 0.0501246294033953 -55.8290874711239 0.559673035842439 132.79454518996 0.120932961668641 37.4468589250732 0.429450082978637 21.7133705556561 + 0.0270128887579714 10.5431020690027 0.267458478820933 -36.0888506010564 + 0.559673035842439 132.79454518996 0.130115817874689 -51.3352263769994 0.44281753592366 34.2894777509056 0.0473482440450142 33.9349134441433 + 0.266650819579482 -5.49513449749311 0.0542591801641295 -7.41603684063064 + 0.120932961668641 37.4468589250732 0.44281753592366 34.2894777509056 0.049161151031049 -84.4142373922231 0.397254432883673 151.01977152458 + 0.0723922811806388 25.8564208112273 0.451792799256228 27.1404362093383 + 0.429450082978637 21.7133705556561 0.0473482440450142 33.9349134441433 0.397254432883673 151.01977152458 0.168115770177301 -37.944107358739 + 0.484241055950131 39.2022726023372 0.0618114963494239 -143.897099593207 + 0.0270128887579714 10.5431020690027 0.266650819579482 -5.49513449749311 0.0723922811806388 25.8564208112273 0.484241055950131 39.2022726023372 + 0.0674055861267517 -123.496201617088 0.551244810556571 137.898456550219 + 0.267458478820933 -36.0888506010564 0.0542591801641295 -7.41603684063064 0.451792799256228 27.1404362093383 0.0618114963494239 -143.897099593207 + 0.551244810556571 137.898456550219 0.111286546808433 -62.5862879192056 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.5 0.0534728693917811 -34.9139052090323 0.542724256447395 118.522091221289 0.134900262778551 16.1778148357466 0.439470257026627 6.6507564024212 + 0.0299194331339947 -34.7877898282966 0.285452942616244 -50.6721124617881 + 0.542724256447395 118.522091221289 0.122899229163701 -52.1857793025943 0.454986546411594 19.1142179796819 0.0424191480515548 44.8279731699963 + 0.280325538082838 -19.4825151877804 0.0363144245222551 -23.5271438834205 + 0.134900262778551 16.1778148357466 0.454986546411594 19.1142179796819 0.0472952569657124 -68.8712997202872 0.372805007324492 138.059322647816 + 0.0824456673366393 11.6550168213861 0.462868604059938 11.9433821599114 + 0.439470257026627 6.6507564024212 0.0424191480515548 44.8279731699963 0.372805007324492 138.059322647816 0.160659318834817 -43.9299756703234 + 0.496912739581614 24.7081312037619 0.0496380532603681 -152.609371958398 + 0.0299194331339947 -34.7877898282966 0.280325538082838 -19.4825151877804 0.0824456673366393 11.6550168213861 0.496912739581614 24.7081312037619 + 0.02368378080854 -121.983907574652 0.536406598564181 123.538641160297 + 0.285452942616244 -50.6721124617881 0.0363144245222551 -23.5271438834205 0.462868604059938 11.9433821599114 0.0496380532603681 -152.609371958398 + 0.536406598564181 123.538641160297 0.0976834199394918 -54.6676432060765 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.55 0.070138298766205 -21.160717005688 0.529833551618596 105.560429962961 0.146119280171273 -3.29804903542187 0.437439931367024 -7.92172610316074 + 0.0356931942215662 -71.624693094149 0.291857463191078 -66.4586698443158 + 0.529833551618596 105.560429962961 0.124607960349212 -40.8210822226114 0.454676583278158 4.15430852146503 0.0571790128458585 44.5939716077913 + 0.287680144919558 -34.7817029248311 0.0330755204543201 -24.1538330049212 + 0.146119280171273 -3.29804903542187 0.454676583278158 4.15430852146503 0.047206226650522 -58.1317260314308 0.357893312888846 126.203216101366 + 0.0863810423868369 -1.86180534509931 0.464874334330338 -2.67631623310772 + 0.437439931367024 -7.92172610316074 0.0571790128458585 44.5939716077913 0.357893312888846 126.203216101366 0.164035404529448 -45.1714242068642 + 0.501179894567232 10.2837532520408 0.0313665946217931 -135.273329885467 + 0.0356931942215662 -71.624693094149 0.287680144919558 -34.7817029248311 0.0863810423868369 -1.86180534509931 0.501179894567232 10.2837532520408 + 0.0217928856492062 9.39960684248243 0.523344002923084 109.855258102399 + 0.291857463191078 -66.4586698443158 0.0330755204543201 -24.1538330049212 0.464874334330338 -2.67631623310772 0.0313665946217931 -135.273329885467 + 0.523344002923084 109.855258102399 0.113843629702685 -43.3488354521248 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.6 0.0726712927242439 -12.2557239163148 0.519675925388922 90.7555297773605 0.132138243879344 -18.9167058266239 0.451271706776619 -22.2270739003646 + 0.0428280404443599 -122.982878867489 0.307677845370981 -79.8689481126482 + 0.519675925388922 90.7555297773605 0.139869789424076 -42.1548510058275 0.468189272574594 -10.1747116236922 0.050312977890944 50.5657096650012 + 0.295853668998675 -47.8619250404336 0.0124711256848028 -63.8880019540667 + 0.132138243879344 -18.9167058266239 0.468189272574594 -10.1747116236922 0.0236595807716823 -50.9274662424489 0.333728076345501 112.707825717665 + 0.0698732669514569 -12.628663531778 0.479933335883802 -17.9777087489218 + 0.451271706776619 -22.2270739003646 0.050312977890944 50.5657096650012 0.333728076345501 112.707825717665 0.152045899170229 -51.3701117726589 + 0.51409688375092 -4.06540853912634 0.0350316764803982 -138.55134163019 + 0.0428280404443599 -122.982878867489 0.295853668998675 -47.8619250404336 0.0698732669514569 -12.628663531778 0.51409688375092 -4.06540853912634 + 0.051575365380531 16.2318757309222 0.505206987509807 95.273239873176 + 0.307677845370981 -79.8689481126482 0.0124711256848028 -63.8880019540667 0.479933335883802 -17.9777087489218 0.0350316764803982 -138.55134163019 + 0.505206987509807 95.273239873176 0.11935430946033 -40.7645612063155 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.65 0.103195960332469 3.39447487425417 0.491666953598156 77.0570354146616 0.12521392139452 -23.4621665250792 0.455702255597069 -38.8198701666859 + 0.0449158025869675 -173.851459046259 0.328245772585416 -96.9054474524622 + 0.491666953598156 77.0570354146616 0.143175890479363 -41.4780838202995 0.473035895441237 -26.941087438527 0.0656327057833383 63.9853034951815 + 0.313101285805895 -63.1204746701161 0.0170693433012213 99.6820972918495 + 0.12521392139452 -23.4621665250792 0.473035895441237 -26.941087438527 0.0489289937681912 36.829537742012 0.304584061552722 103.380420706124 + 0.0581005520312373 -0.102276556916381 0.47717159038464 -35.2139916637828 + 0.455702255597069 -38.8198701666859 0.0656327057833383 63.9853034951815 0.304584061552722 103.380420706124 0.136032144154769 -47.5492731422943 + 0.518926934032288 -20.0336158968588 0.0213551801809854 -139.779670459818 + 0.0449158025869675 -173.851459046259 0.313101285805895 -63.1204746701161 0.0581005520312373 -0.102276556916381 0.518926934032288 -20.0336158968588 + 0.0877686277791271 20.3861636973854 0.475436447342331 82.3664697441481 + 0.328245772585416 -96.9054474524622 0.0170693433012213 99.6820972918495 0.47717159038464 -35.2139916637828 0.0213551801809854 -139.779670459818 + 0.475436447342331 82.3664697441481 0.142721371485117 -34.2043598123128 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.7 0.16184892983744 -2.12321255658648 0.475697529620586 66.1366944021919 0.147976532627072 -29.7953856269529 0.434432887035151 -54.5416566954257 + 0.0376795656107898 136.712227706537 0.32402853897458 -116.055455754844 + 0.475697529620586 66.1366944021919 0.156304821499345 -42.6522174131632 0.446622096245047 -42.7256942816106 0.0775944844217124 61.6825270266724 + 0.313068197382885 -81.0389555088823 0.0310468049008683 85.1822080383001 + 0.147976532627072 -29.7953856269529 0.446622096245047 -42.7256942816106 0.124714155141022 20.8228618127041 0.310371927663693 96.7394574028626 + 0.0853276404174178 7.06992482434845 0.44356591004476 -50.2843639094295 + 0.434432887035151 -54.5416566954257 0.0775944844217124 61.6825270266724 0.310371927663693 96.7394574028626 0.142598241994859 -44.7711590487018 + 0.498450104927058 -35.3518496555109 0.0301956957158382 -110.906953239771 + 0.0376795656107898 136.712227706537 0.313068197382885 -81.0389555088823 0.0853276404174178 7.06992482434845 0.498450104927058 -35.3518496555109 + 0.146017501916027 14.3354424149472 0.463567761515869 72.2961161735679 + 0.32402853897458 -116.055455754844 0.0310468049008683 85.1822080383001 0.44356591004476 -50.2843639094295 0.0301956957158382 -110.906953239771 + 0.463567761515869 72.2961161735679 0.17614018350096 -41.516755974016 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.75 0.198366174925907 -16.0807684634009 0.473295037450417 52.8763595954623 0.160315268103523 -49.3407326419147 0.428244869822573 -67.5183707421126 + 0.0294224263910647 114.391375879537 0.313562161741198 -130.051177582013 + 0.473295037450417 52.8763595954623 0.142715663300879 -44.1315680812401 0.439369205425806 -54.9033496521452 0.104264635694917 71.6574049619248 + 0.303496410848657 -94.5418648672792 0.0701899308273133 87.4940878232838 + 0.160315268103523 -49.3407326419147 0.439369205425806 -54.9033496521452 0.163096015390424 -0.00427582190214699 0.316828984946237 83.2741752744194 + 0.099075294452802 -11.3323327407428 0.438134480256261 -61.9988853689092 + 0.428244869822573 -67.5183707421126 0.104264635694917 71.6574049619248 0.316828984946237 83.2741752744194 0.129127445022669 -38.5072292726515 + 0.490396976740162 -48.0051708485618 0.0261634131474784 -152.739399803629 + 0.0294224263910647 114.391375879537 0.303496410848657 -94.5418648672792 0.099075294452802 -11.3323327407428 0.490396976740162 -48.0051708485618 + 0.19421433419408 -1.41221872356793 0.467674263328895 59.3832284073203 + 0.313562161741198 -130.051177582013 0.0701899308273133 87.4940878232838 0.438134480256261 -61.9988853689092 0.0261634131474784 -152.739399803629 + 0.467674263328895 59.3832284073203 0.176083023599908 -44.3799451451691 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.8 0.225302126562895 -29.9487987166329 0.461470796621598 41.1627369297177 0.165785025807591 -68.9289886477278 0.413506773387605 -81.9647846309025 + 0.0226813808185539 88.2445524327749 0.307736332115583 -146.247057656963 + 0.461470796621598 41.1627369297177 0.157336433978683 -32.9337916624128 0.430029253794811 -69.0621551653569 0.147140956632328 58.5981572955812 + 0.303910974874514 -108.964032656042 0.109552780823247 60.0200055179518 + 0.165785025807591 -68.9289886477278 0.430029253794811 -69.0621551653569 0.193347622049505 -15.9716461348437 0.318994114611713 72.2245646735808 + 0.104954837713695 -28.6055866866634 0.425412721333927 -75.3559141740011 + 0.413506773387605 -81.9647846309025 0.147140956632328 58.5981572955812 0.318994114611713 72.2245646735808 0.163637880811437 -28.6902128102709 + 0.480348848800162 -61.6740932879045 0.0102608146570693 -102.575236349019 + 0.0226813808185539 88.2445524327749 0.303910974874514 -108.964032656042 0.104954837713695 -28.6055866866634 0.480348848800162 -61.6740932879045 + 0.232404530763181 -15.3509081908667 0.464625177689194 47.3221105858027 + 0.307736332115583 -146.247057656963 0.109552780823247 60.0200055179518 0.425412721333927 -75.3559141740011 0.0102608146570693 -102.575236349019 + 0.464625177689194 47.3221105858027 0.20860477616583 -47.2136497518735 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.85 0.216366511047034 -43.012071923474 0.470122464550559 28.5045365558452 0.147814414978357 -96.2603891124135 0.405520433976559 -92.9760760808403 + 0.0232679170423107 108.377091231065 0.288775901770367 -158.103291435145 + 0.470122464550559 28.5045365558452 0.190867819926324 -36.2822400785188 0.420715912909905 -80.6336862505069 0.1573061375364 46.7520396379302 + 0.295375399147192 -122.173085577919 0.122882190759868 42.0686065067488 + 0.147814414978357 -96.2603891124135 0.420715912909905 -80.6336862505069 0.186874435890633 -27.8342162058332 0.325287261892857 57.023674050871 + 0.0858040675660532 -51.1753468698271 0.428393058583119 -86.0944536801283 + 0.405520433976559 -92.9760760808403 0.1573061375364 46.7520396379302 0.325287261892857 57.023674050871 0.192205947609808 -33.7161277263901 + 0.474985584006957 -73.421878450699 0.020519676775542 -120.378280010263 + 0.0232679170423107 108.377091231065 0.295375399147192 -122.173085577919 0.0858040675660532 -51.1753468698271 0.474985584006957 -73.421878450699 + 0.246426347376854 -29.8855612013906 0.472405216700843 33.6397502070117 + 0.288775901770367 -158.103291435145 0.122882190759868 42.0686065067488 0.428393058583119 -86.0944536801283 0.020519676775542 -120.378280010263 + 0.472405216700843 33.6397502070117 0.219634258692378 -57.147745107083 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.9 0.210938377167562 -49.3514763082711 0.4635650412351 14.4993587770172 0.116350072680453 -117.602928843575 0.415395887773296 -106.337801213089 + 0.0365401723264324 85.7825969595736 0.29802660648174 -169.134817623448 + 0.4635650412351 14.4993587770172 0.210109954040846 -40.4162356073471 0.427801081804167 -93.7221273449372 0.173115509377022 38.8476847415912 + 0.299870803676734 -134.347237311678 0.145385664607851 28.6432188101895 + 0.116350072680453 -117.602928843575 0.427801081804167 -93.7221273449372 0.196966561406336 -31.1231592423355 0.30552151538626 43.1373464659071 + 0.0619076027513117 -59.3366632048123 0.443009138823304 -100.356410696241 + 0.415395887773296 -106.337801213089 0.173115509377022 38.8476847415912 0.30552151538626 43.1373464659071 0.218161544452564 -35.6823957613901 + 0.482633877954898 -86.582214085955 0.00977983594897775 -128.616557441917 + 0.0365401723264324 85.7825969595736 0.299870803676734 -134.347237311678 0.0619076027513117 -59.3366632048123 0.482633877954898 -86.582214085955 + 0.249437123804122 -39.8607069162877 0.461677257526124 19.4124147875629 + 0.29802660648174 -169.134817623448 0.145385664607851 28.6432188101895 0.443009138823304 -100.356410696241 0.00977983594897775 -128.616557441917 + 0.461677257526124 19.4124147875629 0.22485245109702 -61.8589827962286 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +3.95 0.208176044251728 -58.5280157068464 0.45539978649345 2.11042773662216 0.101324878834159 -139.201412698989 0.410327782604921 -120.745508649327 + 0.0375042297090547 58.0474449901031 0.306216533405976 176.23964415038 + 0.45539978649345 2.11042773662216 0.230791692465954 -45.4570378781959 0.421991562398244 -107.717111351413 0.184184552894162 27.871452808193 + 0.305235296029469 -148.540272602516 0.164382469672686 11.5967644178319 + 0.101324878834159 -139.201412698989 0.421991562398244 -107.717111351413 0.216207075076655 -40.6362813403793 0.296010300387557 32.7001615204252 + 0.0538257442668859 -68.4732888768935 0.435166258190144 -115.234631355431 + 0.410327782604921 -120.745508649327 0.184184552894162 27.871452808193 0.296010300387557 32.7001615204252 0.255659794102668 -41.8307513552151 + 0.47847886899749 -100.493480187034 0.0153440632208591 -80.5514894841339 + 0.0375042297090547 58.0474449901031 0.305235296029469 -148.540272602516 0.0538257442668859 -68.4732888768935 0.47847886899749 -100.493480187034 + 0.257026771445466 -49.8573671794261 0.450825498182185 7.19067807048036 + 0.306216533405976 176.23964415038 0.164382469672686 11.5967644178319 0.435166258190144 -115.234631355431 0.0153440632208591 -80.5514894841339 + 0.450825498182185 7.19067807048036 0.242328683666403 -69.033222469268 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4 0.189427140225523 -67.8306827303394 0.460293542132886 -10.4370223293059 0.0938925612405897 -169.76681104785 0.401789329301334 -133.383420239295 + 0.0340685646905982 40.5125860706932 0.303717059294653 162.269799883578 + 0.460293542132886 -10.4370223293059 0.248582418386269 -53.4288771504791 0.413118964537179 -119.824646418406 0.17750449731939 16.7625859332158 + 0.302099996112938 -162.274134094284 0.167355695121245 -5.70188621246037 + 0.0938925612405897 -169.76681104785 0.413118964537179 -119.824646418406 0.215168425179095 -52.1210449314387 0.298361722033729 20.4995254719335 + 0.0431055041976443 -93.9992938094271 0.424471547060099 -127.942129947362 + 0.401789329301334 -133.383420239295 0.17750449731939 16.7625859332158 0.298361722033729 20.4995254719335 0.280139354018729 -51.9438022014677 + 0.471409427182099 -113.061661966285 0.0241791716824661 -108.930811802238 + 0.0340685646905982 40.5125860706932 0.302099996112938 -162.274134094284 0.0431055041976443 -93.9992938094271 0.471409427182099 -113.061661966285 + 0.254180219192036 -61.822818558184 0.45282924537326 -5.16969875128655 + 0.303717059294653 162.269799883578 0.167355695121245 -5.70188621246037 0.424471547060099 -127.942129947362 0.0241791716824661 -108.930811802238 + 0.45282924537326 -5.16969875128655 0.245491939341868 -79.9704222942703 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.05 0.159332845985971 -73.2848992469872 0.467500281326155 -24.8228615984013 0.0940306357939321 151.054246938469 0.405050364757476 -145.021856566956 + 0.0338189192876812 32.5031106569257 0.303065104850489 150.294092373634 + 0.467500281326155 -24.8228615984013 0.24290719056548 -63.6529264759344 0.418612597868557 -130.823501696475 0.156595535953933 11.9132362424129 + 0.300612343993318 -174.187538231602 0.155001380182487 -18.6652552695478 + 0.0940306357939321 151.054246938469 0.418612597868557 -130.823501696475 0.195779260239879 -60.4109086059328 0.294642371291853 5.81961230072317 + 0.0289549824939333 -144.661885709364 0.426319393587683 -139.690861542352 + 0.405050364757476 -145.021856566956 0.156595535953933 11.9132362424129 0.294642371291853 5.81961230072317 0.279696051042023 -61.8081023344995 + 0.474367634390736 -124.948015966486 0.0235726782574473 -158.006742768534 + 0.0338189192876812 32.5031106569257 0.300612343993318 -174.187538231602 0.0289549824939333 -144.661885709364 0.474367634390736 -124.948015966486 + 0.233791151844596 -73.9486395495362 0.456712945220104 -18.8602637782841 + 0.303065104850489 150.294092373634 0.155001380182487 -18.6652552695478 0.426319393587683 -139.690861542352 0.0235726782574473 -158.006742768534 + 0.456712945220104 -18.8602637782841 0.225462282380511 -90.2602402875948 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.1 0.13447334290473 -73.203937624704 0.461702174754009 -39.5306505658683 0.102338331233754 112.825848539448 0.413837436280456 -157.939359612951 + 0.0368028317076264 20.8368981755496 0.310399620988406 137.82833053616 + 0.461702174754009 -39.5306505658683 0.221545403855048 -68.5879329069507 0.433251865960657 -143.627859845169 0.151730315885728 11.2807693803971 + 0.309688481490936 173.518433036478 0.151492770693712 -28.155984743672 + 0.102338331233754 112.825848539448 0.433251865960657 -143.627859845169 0.17755747384826 -64.4004599146627 0.280735025245867 -7.9981061439682 + 0.0326747507828116 146.121115921727 0.432403877856566 -152.310123093195 + 0.413837436280456 -157.939359612951 0.151730315885728 11.2807693803971 0.280735025245867 -7.9981061439682 0.276994962182247 -68.5673285470577 + 0.482108240486345 -137.682139933667 0.0166346448509939 160.215863010377 + 0.0368028317076264 20.8368981755496 0.309688481490936 173.518433036478 0.0326747507828116 146.121115921727 0.482108240486345 -137.682139933667 + 0.201284923271317 -85.0866578237035 0.455420027659851 -32.6860010837221 + 0.310399620988406 137.82833053616 0.151492770693712 -28.155984743672 0.432403877856566 -152.310123093195 0.0166346448509939 160.215863010377 + 0.455420027659851 -32.6860010837221 0.205079924251541 -96.7820985202968 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.15 0.121930200566672 -71.5448936432257 0.4531780106307 -54.0930764608881 0.111727650704127 80.8878300910087 0.425576433689869 -171.36602250081 + 0.0413187259466302 -0.557144659336195 0.323096042049671 125.537787920852 + 0.4531780106307 -54.0930764608881 0.206999708874627 -72.318870611879 0.447150878643274 -157.131607867969 0.143084179845203 9.21660181222236 + 0.3195083943387 160.505471030772 0.141236145755838 -40.599333597361 + 0.111727650704127 80.8878300910087 0.447150878643274 -157.131607867969 0.171312957742097 -67.4785568259366 0.262280332010935 -21.3594776726226 + 0.0479352811937331 103.496542915738 0.445036965491534 -165.39562019099 + 0.425576433689869 -171.36602250081 0.143084179845203 9.21660181222236 0.262280332010935 -21.3594776726226 0.270118800033026 -76.4775768644925 + 0.492563724483894 -150.692603811284 0.0198925479395634 122.398589956098 + 0.0413187259466302 -0.557144659336195 0.3195083943387 160.505471030772 0.0479352811937331 103.496542915738 0.492563724483894 -150.692603811284 + 0.161396102268789 -93.425358680018 0.452000517966075 -47.0867657897364 + 0.323096042049671 125.537787920852 0.141236145755838 -40.599333597361 0.445036965491534 -165.39562019099 0.0198925479395634 122.398589956098 + 0.452000517966075 -47.0867657897364 0.178604863739721 -103.792386524447 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.2 0.105634761777466 -72.2344710546176 0.436721033121337 -68.4094745471834 0.121464910645656 58.131130221086 0.436358933112241 173.926642771639 + 0.0394567404303555 -28.5867768105901 0.342966516857793 111.633581821165 + 0.436721033121337 -68.4094745471834 0.182712048174963 -73.8732867973886 0.460843308821406 -171.857173978629 0.138574164256657 11.9801818714951 + 0.333806187586621 146.727494645207 0.124017824594457 -49.4497914319205 + 0.121464910645656 58.131130221086 0.460843308821406 -171.857173978629 0.161939053573002 -74.7009142266266 0.239453071940438 -32.374571446167 + 0.0627177544940405 83.2432556458391 0.456026357602081 -179.899773442986 + 0.436358933112241 173.926642771639 0.138574164256657 11.9801818714951 0.239453071940438 -32.374571446167 0.252155580201114 -82.7755388469148 + 0.503519536780954 -164.676365809601 0.028157227352501 79.3759720532594 + 0.0394567404303555 -28.5867768105901 0.333806187586621 146.727494645207 0.0627177544940405 83.2432556458391 0.503519536780954 -164.676365809601 + 0.121652083285508 -99.451494233447 0.440407962655856 -61.2651703315798 + 0.342966516857793 111.633581821165 0.124017824594457 -49.4497914319205 0.456026357602081 -179.899773442986 0.028157227352501 79.3759720532594 + 0.440407962655856 -61.2651703315798 0.147386514440337 -105.472456278993 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.25 0.083879158850895 -64.6018363159752 0.420428620116866 -81.5247439638649 0.136509129253191 39.6535594541828 0.438852573880415 159.033416615675 + 0.034385026223166 -55.1151248443645 0.357733107996743 96.3879009174413 + 0.420428620116866 -81.5247439638649 0.164465371644408 -70.2180356216942 0.464007289274554 173.04425143175 0.141902973151492 14.162557621608 + 0.343887618112996 131.62124329163 0.106520627858149 -57.5530544343637 + 0.136509129253191 39.6535594541828 0.464007289274554 173.04425143175 0.138864769643684 -81.5338754614991 0.225599021246191 -41.2850859446537 + 0.0799634459551371 69.2903250590739 0.459558726425115 165.574630915789 + 0.438852573880415 159.033416615675 0.141902973151492 14.162557621608 0.225599021246191 -41.2850859446537 0.232945691015812 -87.9467032675138 + 0.50786762000799 -178.877775537398 0.0352334184809437 50.9867901343201 + 0.034385026223166 -55.1151248443645 0.343887618112996 131.62124329163 0.0799634459551371 69.2903250590739 0.50786762000799 -178.877775537398 + 0.0786484884941445 -100.295917912257 0.429191834958487 -74.7976168414142 + 0.357733107996743 96.3879009174413 0.106520627858149 -57.5530544343637 0.459558726425115 165.574630915789 0.0352334184809437 50.9867901343201 + 0.429191834958487 -74.7976168414142 0.124655021186003 -102.736059390459 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.3 0.0783145656055994 -47.354081299379 0.410590912132438 -94.1195771668817 0.147607727589248 21.4929185141847 0.438863810304681 144.659544638677 + 0.0323610612194287 -87.525251784547 0.367905316372181 81.3031013665588 + 0.410590912132438 -94.1195771668817 0.159602725136961 -62.8650923068771 0.46210995243911 158.829456561068 0.149549770018123 15.8014604742757 + 0.345300458015876 116.793779918499 0.0828471802378125 -63.5474833303829 + 0.147607727589248 21.4929185141847 0.46210995243911 158.829456561068 0.111336389008116 -87.2869414466827 0.217635456947957 -50.7653251892172 + 0.0929196314121857 57.1759893084425 0.464546639893565 151.301550589025 + 0.438863810304681 144.659544638677 0.149549770018123 15.8014604742757 0.217635456947957 -50.7653251892172 0.208261894436807 -91.8616631271135 + 0.511453582949571 167.266235783033 0.0432929833992727 33.4954168463582 + 0.0323610612194287 -87.525251784547 0.345300458015876 116.793779918499 0.0929196314121857 57.1759893084425 0.511453582949571 167.266235783033 + 0.0438451769397322 -81.6569491879921 0.418083519206188 -88.4960862747108 + 0.367905316372181 81.3031013665588 0.0828471802378125 -63.5474833303829 0.464546639893565 151.301550589025 0.0432929833992727 33.4954168463582 + 0.418083519206188 -88.4960862747108 0.107550618792029 -95.2434805426964 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.35 0.0806843476420196 -29.9947216976264 0.400567896840107 -107.954221283717 0.150370323235801 9.27186035603036 0.445145252539011 129.836916288087 + 0.0291324386523692 -142.456825503472 0.384233815754855 66.1244421595725 + 0.400567896840107 -107.954221283717 0.166836024319497 -57.4739283847076 0.471958142795712 144.391138515922 0.162753027437887 17.9587483567196 + 0.353153074722893 103.289098677618 0.0546451521664392 -53.3339368520841 + 0.150370323235801 9.27186035603036 0.471958142795712 144.391138515922 0.0619639387676753 -90.0185340362057 0.203262918094905 -58.5470331172381 + 0.111612213628042 51.3801852466583 0.470501363043825 135.601125175763 + 0.445145252539011 129.836916288087 0.162753027437887 17.9587483567196 0.203262918094905 -58.5470331172381 0.176887530614034 -91.3545229356077 + 0.518824948598657 152.568135152572 0.0594717236944915 18.4105274945621 + 0.0291324386523692 -142.456825503472 0.353153074722893 103.289098677618 0.111612213628042 51.3801852466583 0.518824948598657 152.568135152572 + 0.036909038464776 -16.2818912570608 0.398416239710514 -101.667252653024 + 0.384233815754855 66.1244421595725 0.0546451521664392 -53.3339368520841 0.470501363043825 135.601125175763 0.0594717236944915 18.4105274945621 + 0.398416239710514 -101.667252653024 0.106599647776011 -78.8169823424717 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.4 0.1148084017438 -14.1224141296082 0.381982452947219 -120.369749149553 0.170362140659444 -2.10961381734579 0.439991121884783 113.880290313109 + 0.0244145229600205 157.484053106183 0.395387081071613 48.8832787448757 + 0.381982452947219 -120.369749149553 0.185321132383695 -52.0011719704264 0.469440344949126 128.21785782509 0.188334178343768 15.5518353934151 + 0.36287400584215 87.7427316660315 0.059028321384325 -25.5877332948719 + 0.170362140659444 -2.10961381734579 0.469440344949126 128.21785782509 0.0462088157046145 -20.5425075349905 0.208226194599709 -62.9737748237796 + 0.141733052638709 38.3277120277411 0.457649362187657 119.609191210841 + 0.439991121884783 113.880290313109 0.188334178343768 15.5518353934151 0.208226194599709 -62.9737748237796 0.164620024946463 -83.4467203981361 + 0.512303441085295 137.357803697031 0.0759718946247705 -6.42390244570853 + 0.0244145229600205 157.484053106183 0.36287400584215 87.7427316660315 0.141733052638709 38.3277120277411 0.512303441085295 137.357803697031 + 0.0893024119235183 5.25576425441651 0.383869649580161 -112.791880588677 + 0.395387081071613 48.8832787448757 0.059028321384325 -25.5877332948719 0.457649362187657 119.609191210841 0.0759718946247705 -6.42390244570853 + 0.383869649580161 -112.791880588677 0.140092673265606 -71.2810627169959 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.45 0.163821446495302 -17.5841073437483 0.372387506711557 -131.822645011863 0.188798086545713 -19.2370654302845 0.426827204235622 99.0725355080529 + 0.0232951151254405 111.336424713384 0.391982074384409 31.9580876657347 + 0.372387506711557 -131.822645011863 0.214430777539076 -51.2526802595796 0.455361050162769 113.140501461088 0.207275644984942 9.97325586351396 + 0.362009844696339 72.1349331457545 0.0785532486227395 -16.5693992786702 + 0.188798086545713 -19.2370654302845 0.455361050162769 113.140501461088 0.102539293494791 -7.63728187042583 0.226246090048508 -72.0593370183385 + 0.161190396714865 20.6904461971864 0.439837350197398 105.458465084535 + 0.426827204235622 99.0725355080529 0.207275644984942 9.97325586351396 0.226246090048508 -72.0593370183385 0.171081958498134 -77.2575858860127 + 0.500031824387059 123.247519153482 0.0819755314811118 -29.949377896084 + 0.0232951151254405 111.336424713384 0.362009844696339 72.1349331457545 0.161190396714865 20.6904461971864 0.500031824387059 123.247519153482 + 0.146492001800373 -2.45176000688914 0.381507275023327 -124.019517153908 + 0.391982074384409 31.9580876657347 0.0785532486227395 -16.5693992786702 0.439837350197398 105.458465084535 0.0819755314811118 -29.949377896084 + 0.381507275023327 -124.019517153908 0.17233079382119 -75.9551511705088 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.5 0.203611681483149 -26.5678215699429 0.368310253159224 -143.445932642264 0.19578210357009 -37.9168414392717 0.414602184389192 84.9582374754171 + 0.0246641826039919 77.9264989830971 0.384377136853082 16.0370151432877 + 0.368310253159224 -143.445932642264 0.245291987663365 -54.0174507861114 0.440423645249878 98.9381397782404 0.220776190138953 3.5520095899101 + 0.357478177351709 57.2324971277866 0.102270116741115 -16.7765605475697 + 0.19578210357009 -37.9168414392717 0.440423645249878 98.9381397782404 0.152529857362127 -14.580012350676 0.24158305762276 -83.7061995405031 + 0.168730277431705 3.3074503834848 0.426489971487301 91.9439613131743 + 0.414602184389192 84.9582374754171 0.220776190138953 3.5520095899101 0.24158305762276 -83.7061995405031 0.187791526511923 -73.4790768594239 + 0.489274599639966 109.672210239136 0.0843859947992466 -50.8057983935857 + 0.0246641826039919 77.9264989830971 0.357478177351709 57.2324971277866 0.168730277431705 3.3074503834848 0.489274599639966 109.672210239136 + 0.193952958322404 -13.2140468638426 0.381747247110701 -135.899987686406 + 0.384377136853082 16.0370151432877 0.102270116741115 -16.7765605475697 0.426489971487301 91.9439613131743 0.0843859947992466 -50.8057983935857 + 0.381747247110701 -135.899987686406 0.197047472152824 -83.0609751597157 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.55 0.233389706379268 -37.3504412441744 0.367490381058742 -155.230734661043 0.195670954604444 -57.8108449387898 0.40142822402359 71.2189692282035 + 0.0249161315986032 48.7757112494534 0.374128714018279 0.521693213623643 + 0.367490381058742 -155.230734661043 0.273520361956977 -58.9124815713948 0.424607487268448 85.3186742161354 0.228806684719794 -3.58606102201116 + 0.35136924034182 42.7481178579338 0.126827697196723 -22.8240839615931 + 0.195670954604444 -57.8108449387898 0.424607487268448 85.3186742161354 0.194383587651515 -25.0767293773001 0.256007887969136 -96.6296679905386 + 0.16858856543531 -14.4484237527939 0.412133829438493 78.8090293789479 + 0.40142822402359 71.2189692282035 0.228806684719794 -3.58606102201116 0.256007887969136 -96.6296679905386 0.213576265198592 -73.4221686625848 + 0.477842375415432 96.446547745638 0.0855480259811527 -72.9387894819986 + 0.0249161315986032 48.7757112494534 0.35136924034182 42.7481178579338 0.16858856543531 -14.4484237527939 0.477842375415432 96.446547745638 + 0.232614280776251 -24.4492331725618 0.384771100780216 -147.90663527381 + 0.374128714018279 0.521693213623643 0.126827697196723 -22.8240839615931 0.412133829438493 78.8090293789479 0.0855480259811527 -72.9387894819986 + 0.384771100780216 -147.90663527381 0.217981233309548 -92.4152296293372 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.6 0.250186614913018 -48.9430112881979 0.367354928206065 -167.641888761768 0.187871983170435 -79.4478143649275 0.39049741038454 57.8896275853857 + 0.0229095584494269 24.2122206071046 0.363298012065452 -14.161686058662 + 0.367354928206065 -167.641888761768 0.292014543814855 -64.6525052897609 0.412807020041726 72.4157495219848 0.231568268556903 -9.72905890786783 + 0.344952167898178 29.126041262986 0.149357642479647 -29.6020565819704 + 0.187871983170435 -79.4478143649275 0.412807020041726 72.4157495219848 0.222258716045819 -36.6090427283152 0.26440848339834 -110.582826676559 + 0.159101774555571 -33.0228051567182 0.401419482282253 66.1956646087082 + 0.39049741038454 57.8896275853857 0.231568268556903 -9.72905890786783 0.26440848339834 -110.582826676559 0.238638803917574 -75.7957930920185 + 0.469286525858994 83.7130611207785 0.0817720907147308 -93.6990880915654 + 0.0229095584494269 24.2122206071046 0.344952167898178 29.126041262986 0.159101774555571 -33.0228051567182 0.469286525858994 83.7130611207785 + 0.259822263353182 -35.9993432720924 0.389433138829732 -160.623199950052 + 0.363298012065452 -14.161686058662 0.149357642479647 -29.6020565819704 0.401419482282253 66.1956646087082 0.0817720907147308 -93.6990880915654 + 0.389433138829732 -160.623199950052 0.228895043729494 -102.266410897508 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.65 0.248482101106116 -62.0340349645566 0.371058203566876 -179.746311537228 0.176465186284484 -105.378974982466 0.375679553757765 45.3926349499413 + 0.0159071351994577 -2.3487973991413 0.346205228648056 -28.6252858592408 + 0.371058203566876 -179.746311537228 0.310124402810735 -70.8758002146829 0.398691856372793 59.8560279063204 0.230129847498721 -17.303413105534 + 0.33926234237424 15.5779981572012 0.170169252014239 -40.4525366721562 + 0.176465186284484 -105.378974982466 0.398691856372793 59.8560279063204 0.233009017026392 -49.3081393702063 0.273072126384464 -125.46412528645 + 0.142361159753999 -53.9159308350167 0.388778412347962 54.6005239404574 + 0.375679553757765 45.3926349499413 0.230129847498721 -17.303413105534 0.273072126384464 -125.46412528645 0.266302875420562 -81.537968282209 + 0.460635174591637 71.3469267257876 0.08172970512925 -119.12463913822 + 0.0159071351994577 -2.3487973991413 0.33926234237424 15.5779981572012 0.142361159753999 -53.9159308350167 0.460635174591637 71.3469267257876 + 0.275380743856375 -47.7001519549339 0.396850966354844 -173.624560884913 + 0.346205228648056 -28.6252858592408 0.170169252014239 -40.4525366721562 0.388778412347962 54.6005239404574 0.08172970512925 -119.12463913822 + 0.396850966354844 -173.624560884913 0.236140873354312 -114.671579153123 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.7 0.226228531477122 -73.0448993901703 0.375408621726396 167.027518324666 0.156859977885028 -135.230409338082 0.370412457067757 33.696138628053 + 0.00611190540166996 -1.93645053418448 0.332074051712477 -40.7004139490294 + 0.375408621726396 167.027518324666 0.318089283732693 -77.692460512601 0.391200646054025 48.1970674560975 0.220674377121846 -23.4791649661802 + 0.333868100821864 2.79125950599027 0.182406342809899 -50.473234224773 + 0.156859977885028 -135.230409338082 0.391200646054025 48.1970674560975 0.223263574581503 -59.5383574101394 0.270045255724775 -141.066734074221 + 0.116823385203846 -77.2143252562571 0.389313427457458 43.4634733335302 + 0.370412457067757 33.696138628053 0.220674377121846 -23.4791649661802 0.270045255724775 -141.066734074221 0.282581205159484 -88.0447073577169 + 0.458254554003475 59.4202690370773 0.0738183873556538 -146.479987355403 + 0.00611190540166996 -1.93645053418448 0.333868100821864 2.79125950599027 0.116823385203846 -77.2143252562571 0.458254554003475 59.4202690370773 + 0.276124984955913 -59.1638511287993 0.402685612053235 172.245039461752 + 0.332074051712477 -40.7004139490294 0.182406342809899 -50.473234224773 0.389313427457458 43.4634733335302 0.0738183873556538 -146.479987355403 + 0.402685612053235 172.245039461752 0.224713281174791 -126.901129703833 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.75 0.18465398380498 -81.9325780889964 0.383718035465882 153.591303949095 0.142837591846218 -172.585554991408 0.366747177933404 22.7524975407659 + 0.0118642809495509 93.4313638730327 0.318509900597994 -51.9915735820585 + 0.383718035465882 153.591303949095 0.320849090028322 -85.0194988447521 0.385519779752718 37.2617908717515 0.204139190013669 -29.7219601026248 + 0.328792395627403 -9.54253871672633 0.18862566568509 -62.1631703957289 + 0.142837591846218 -172.585554991408 0.385519779752718 37.2617908717515 0.195974958157229 -66.6535997454377 0.263395216260862 -157.307737276335 + 0.0865222771364028 -106.661434781782 0.394407462991685 32.6651952783341 + 0.366747177933404 22.7524975407659 0.204139190013669 -29.7219601026248 0.263395216260862 -157.307737276335 0.293494419009827 -96.091933329665 + 0.460525193651606 47.7290103616414 0.072966680540986 -176.869849272459 + 0.0118642809495509 93.4313638730327 0.328792395627403 -9.54253871672633 0.0865222771364028 -106.661434781782 0.460525193651606 47.7290103616414 + 0.262383328176183 -69.9432221122438 0.407007892193127 157.483905251309 + 0.318509900597994 -51.9915735820585 0.18862566568509 -62.1631703957289 0.394407462991685 32.6651952783341 0.072966680540986 -176.869849272459 + 0.407007892193127 157.483905251309 0.208916295913688 -140.230253959656 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.8 0.148478963456591 -77.0000634051956 0.388373152455602 137.907737278395 0.124293780058517 145.337187336754 0.383900382495738 11.4853746240004 + 0.0284024996796062 59.7132070772884 0.322270387458564 -60.0481972089294 + 0.388373152455602 137.907737278395 0.308657609364479 -92.5720317665688 0.397769224899332 26.7289071144835 0.180876168448009 -31.6873162537512 + 0.329566424032493 -20.5468384021543 0.182277902120162 -71.4749853691277 + 0.124293780058517 145.337187336754 0.397769224899332 26.7289071144835 0.181316717430058 -63.1618088520356 0.235481705271461 -173.102038483887 + 0.0565119581958083 -140.329823625801 0.420097302564348 20.1530600116178 + 0.383900382495738 11.4853746240004 0.180876168448009 -31.6873162537512 0.235481705271461 -173.102038483887 0.287354088374446 -103.115724549512 + 0.474659190303894 35.3699401531352 0.0689141349693871 144.662804462416 + 0.0284024996796062 59.7132070772884 0.329566424032493 -20.5468384021543 0.0565119581958083 -140.329823625801 0.474659190303894 35.3699401531352 + 0.239848350315006 -78.3971239574905 0.399883377400453 141.678695404419 + 0.322270387458564 -60.0481972089294 0.182277902120162 -71.4749853691277 0.420097302564348 20.1530600116178 0.0689141349693871 144.662804462416 + 0.399883377400453 141.678695404419 0.172241407280065 -152.80163805191 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.85 0.152071010088645 -72.1361115427216 0.376300324617903 121.695321294788 0.112939255494806 110.748556981183 0.404891351187138 -2.99304150302921 + 0.0333431657553042 24.2024062889818 0.351492714571824 -70.8012306056255 + 0.376300324617903 121.695321294788 0.282626677592778 -98.4374987230246 0.421268798668411 13.6973073551285 0.167171823051026 -29.0752727588762 + 0.343013359234917 -31.9926727007845 0.177461570576334 -77.9549526387756 + 0.112939255494806 110.748556981183 0.421268798668411 13.6973073551285 0.19837812297192 -64.7042984927374 0.201867712107155 177.183040415311 + 0.0466580864061945 -176.896256052994 0.438979704201468 4.382108576938 + 0.404891351187138 -2.99304150302921 0.167171823051026 -29.0752727588762 0.201867712107155 177.183040415311 0.28074046152526 -107.967074155712 + 0.488473698086427 21.3266735272879 0.0637296760903734 107.366583887654 + 0.0333431657553042 24.2024062889818 0.343013359234917 -31.9926727007845 0.0466580864061945 -176.896256052994 0.488473698086427 21.3266735272879 + 0.217896650237428 -86.2560002922143 0.380895993952006 127.064043422304 + 0.351492714571824 -70.8012306056255 0.177461570576334 -77.9549526387756 0.438979704201468 4.382108576938 0.0637296760903734 107.366583887654 + 0.380895993952006 127.064043422304 0.13480457958541 -159.463428948219 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.9 0.147050744350051 -78.5205091923623 0.34999925661071 107.583532910473 0.12098601236874 89.3348204376306 0.410432953005035 -19.4823869999255 + 0.0260734063273217 3.40433770078019 0.382327875621337 -85.8404413714245 + 0.34999925661071 107.583532910473 0.254171631951229 -100.056180117091 0.435746468262231 -2.00878315868016 0.169514700137116 -26.667689714203 + 0.361656788130473 -45.7250422829333 0.180348743971376 -84.5348886475054 + 0.12098601236874 89.3348204376306 0.435746468262231 -2.00878315868016 0.196578570748074 -74.8136920054107 0.188531394823971 173.89972152154 + 0.0637034235483017 146.866406331333 0.436164343900889 -12.2161275956142 + 0.410432953005035 -19.4823869999255 0.169514700137116 -26.667689714203 0.188531394823971 173.89972152154 0.282136125833604 -112.304718273624 + 0.490986081413351 6.52700046739548 0.0577558647111033 74.8725176914878 + 0.0260734063273217 3.40433770078019 0.361656788130473 -45.7250422829333 0.0637034235483017 146.866406331333 0.490986081413351 6.52700046739548 + 0.186984515481599 -95.5108771994877 0.362844816837943 114.432730810047 + 0.382327875621337 -85.8404413714245 0.180348743971376 -84.5348886475054 0.436164343900889 -12.2161275956142 0.0577558647111033 74.8725176914878 + 0.362844816837943 114.432730810047 0.108900539689723 -160.507659518855 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +4.95 0.120520348196939 -78.5945769366907 0.333244102655084 96.0385775612995 0.149344317887577 67.7412857544822 0.401815371907546 -34.7190823138243 + 0.024830632660431 3.81052904164105 0.39678874136467 -101.702158152612 + 0.333244102655084 96.0385775612995 0.239270406258792 -99.4188132631913 0.433626697572251 -17.242197707811 0.170569258206756 -26.9623348136373 + 0.371533702200537 -60.420986039233 0.177608810029257 -94.5081456932412 + 0.149344317887577 67.7412857544822 0.433626697572251 -17.242197707811 0.169484675593039 -80.5368516350265 0.194829131166064 168.215465265129 + 0.0935118331451188 115.124472254264 0.423759594094443 -27.1732665981687 + 0.401815371907546 -34.7190823138243 0.170569258206756 -26.9623348136373 0.194829131166064 168.215465265129 0.282156949641055 -118.676577877621 + 0.487218836425957 -7.67571035899894 0.0567614603761776 50.2207460129714 + 0.024830632660431 3.81052904164105 0.371533702200537 -60.420986039233 0.0935118331451188 115.124472254264 0.487218836425957 -7.67571035899894 + 0.142532487494275 -102.864668805629 0.351288818519889 102.330160683643 + 0.39678874136467 -101.702158152612 0.177608810029257 -94.5081456932412 0.423759594094443 -27.1732665981687 0.0567614603761776 50.2207460129714 + 0.351288818519889 102.330160683643 0.0894327140648061 -160.55201235651 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5 0.102852699917892 -71.4534193445895 0.322152397588463 84.0876883009861 0.175620953345248 47.3436131557647 0.394651164150754 -49.4554192716975 + 0.0266311276335088 -0.774421962438717 0.40999780287336 -117.466309958679 + 0.322152397588463 84.0876883009861 0.226987036165337 -98.2075264085405 0.432467502883922 -32.0557633437514 0.174544039862966 -25.3147487112026 + 0.380719126079175 -75.0132236768991 0.164238474026133 -102.330432170021 + 0.175620953345248 47.3436131557647 0.432467502883922 -32.0557633437514 0.141698516352545 -80.1133667923373 0.20665601919845 160.762007959189 + 0.128366890551846 90.0701289810818 0.408125792070158 -41.5385534975347 + 0.394651164150754 -49.4554192716975 0.174544039862966 -25.3147487112026 0.20665601919845 160.762007959189 0.274219344047942 -124.745228362014 + 0.480122539116485 -21.6913448019964 0.0570233312436521 24.5390499593529 + 0.0266311276335088 -0.774421962438717 0.380719126079175 -75.0132236768991 0.128366890551846 90.0701289810818 0.480122539116485 -21.6913448019964 + 0.0895462687094198 -102.278154879275 0.345515397971746 91.0222590828848 + 0.40999780287336 -117.466309958679 0.164238474026133 -102.330432170021 0.408125792070158 -41.5385534975347 0.0570233312436521 24.5390499593529 + 0.345515397971746 91.0222590828848 0.0793887450749919 -154.695241926423 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.05 0.0958405336567151 -55.4678337395019 0.311077517891445 73.4682107850011 0.205005116026111 28.5338651694118 0.38116152868585 -64.2779520206103 + 0.032496619871427 -8.10338652358781 0.417339074388536 -134.086327913053 + 0.311077517891445 73.4682107850011 0.226282208709865 -94.0159348616601 0.424048131237982 -47.4042732029567 0.189692214432065 -26.2496732535549 + 0.386379957460741 -90.3526104332437 0.154987021417301 -107.847912067427 + 0.205005116026111 28.5338651694118 0.424048131237982 -47.4042732029567 0.125662770661256 -71.4143733377004 0.22538132340291 150.909397912968 + 0.159703243806002 67.360014528347 0.390529358795977 -54.619812903956 + 0.38116152868585 -64.2779520206103 0.189692214432065 -26.2496732535549 0.22538132340291 150.909397912968 0.266979844106103 -130.093218306633 + 0.470747359183764 -35.0491359028031 0.0535505768117161 -1.74179732298088 + 0.032496619871427 -8.10338652358781 0.386379957460741 -90.3526104332437 0.159703243806002 67.360014528347 0.470747359183764 -35.0491359028031 + 0.057941409388596 -69.218981079251 0.347545259126999 78.9756038822169 + 0.417339074388536 -134.086327913053 0.154987021417301 -107.847912067427 0.390529358795977 -54.619812903956 0.0535505768117161 -1.74179732298088 + 0.347545259126999 78.9756038822169 0.0805306738118292 -151.825346495041 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.1 0.119066009742716 -43.3045564151448 0.312681811702011 63.4833464520835 0.231893491312751 8.30520002940107 0.361842150006313 -77.5179444140286 + 0.041031486734355 -26.845592220488 0.411684437723282 -150.645183173471 + 0.312681811702011 63.4833464520835 0.245515936698889 -91.9220384318778 0.405762335965798 -61.7074481549881 0.199926151407062 -31.0386250205763 + 0.383692702913832 -105.71005869864 0.148062520040315 -115.473235359078 + 0.231893491312751 8.30520002940107 0.405762335965798 -61.7074481549881 0.136276772407446 -62.109374170334 0.243659097009529 137.635343178153 + 0.182017210412 46.5981553373127 0.376920789314695 -66.006737469419 + 0.361842150006313 -77.5179444140286 0.199926151407062 -31.0386250205763 0.243659097009529 137.635343178153 0.261059973829266 -136.800374373499 + 0.463147099060631 -47.6432095975276 0.0421672773577064 -26.472212801062 + 0.041031486734355 -26.845592220488 0.383692702913832 -105.71005869864 0.182017210412 46.5981553373127 0.463147099060631 -47.6432095975276 + 0.0824787763345085 -35.8248565365145 0.351312210777446 65.7979168892978 + 0.411684437723282 -150.645183173471 0.148062520040315 -115.473235359078 0.376920789314695 -66.006737469419 0.0421672773577064 -26.472212801062 + 0.351312210777446 65.7979168892978 0.0853450004886878 -157.995785052791 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.15 0.150133699342622 -44.9407557841241 0.325813515122549 52.1818951774393 0.246750755307601 -12.9694284396112 0.346538956688151 -88.6098295220605 + 0.0480218238838881 -53.9570850987825 0.395971260924457 -165.939715724551 + 0.325813515122549 52.1818951774393 0.272654631500798 -94.5896874358294 0.385823588095996 -74.0793139968867 0.197376398502814 -36.8296406503479 + 0.374035737142807 -120.185347285917 0.134691371078191 -125.98907594914 + 0.246750755307601 -12.9694284396112 0.385823588095996 -74.0793139968867 0.159206445286448 -62.5761887182606 0.252672227775049 122.183325197469 + 0.192380193351414 27.5639302203459 0.37535042739398 -76.1867115793937 + 0.346538956688151 -88.6098295220605 0.197376398502814 -36.8296406503479 0.252672227775049 122.183325197469 0.248516060251462 -145.538268246039 + 0.461602223019058 -59.6744573419662 0.0232839658208288 -45.8635153341329 + 0.0480218238838881 -53.9570850987825 0.374035737142807 -120.185347285917 0.192380193351414 27.5639302203459 0.461602223019058 -59.6744573419662 + 0.12252166103506 -31.7276091414278 0.352951747796645 51.5731739105232 + 0.395971260924457 -165.939715724551 0.134691371078191 -125.98907594914 0.37535042739398 -76.1867115793937 0.0232839658208288 -45.8635153341329 + 0.352951747796645 51.5731739105232 0.0846985866151641 -172.637433629071 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.2 0.161512576208222 -52.4910507319191 0.339068613672769 37.3501965618739 0.238624481572848 -33.7732164051076 0.352907615211643 -98.6813184494684 + 0.047482602080906 -87.3066970411622 0.383508742297771 -178.245869298503 + 0.339068613672769 37.3501965618739 0.281357438360012 -100.615421701259 0.383024166893903 -84.6032830987926 0.185678152909472 -36.8315877477238 + 0.36710163339717 -132.797095944887 0.0986387025154712 -136.236263657449 + 0.238624481572848 -33.7732164051076 0.383024166893903 -84.6032830987926 0.163828378187536 -70.3768763802842 0.241274201780248 107.90854822121 + 0.190586489679107 11.9094442056721 0.396581646446637 -87.7167573941015 + 0.352907615211643 -98.6813184494684 0.185678152909472 -36.8315877477238 0.241274201780248 107.90854822121 0.209998265368691 -154.752616159721 + 0.471642719891864 -72.3744649371428 0.0180311384923241 5.74664298330258 + 0.047482602080906 -87.3066970411622 0.36710163339717 -132.797095944887 0.190586489679107 11.9094442056721 0.471642719891864 -72.3744649371428 + 0.153783639858151 -35.1642336118564 0.343080159511136 36.5531230495718 + 0.383508742297771 -178.245869298503 0.0986387025154712 -136.236263657449 0.396581646446637 -87.7167573941015 0.0180311384923241 5.74664298330258 + 0.343080159511136 36.5531230495718 0.0624944376330478 166.564017238415 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.25 0.161476852746689 -54.64673034775 0.33452512417198 22.4852854588507 0.224092980501076 -50.8338987737368 0.364671720771269 -112.08963024381 + 0.0419035610395768 -114.239339836972 0.389636279407825 168.794500154946 + 0.33452512417198 22.4852854588507 0.283187950294081 -103.698769407827 0.389329433483951 -97.392021364474 0.197857409019315 -36.4772345932226 + 0.368732082758625 -145.825795433023 0.0676398633206897 -124.060275191782 + 0.224092980501076 -50.8338987737368 0.389329433483951 -97.392021364474 0.152909503064176 -72.5716841877185 0.236907364306144 98.095461625639 + 0.191365298566914 -1.88315921233554 0.410555737909478 -102.662044630707 + 0.364671720771269 -112.08963024381 0.197857409019315 -36.4772345932226 0.236907364306144 98.095461625639 0.170890580191954 -154.695841647662 + 0.475990491862062 -86.3745276909252 0.0273957264526352 -10.283056843649 + 0.0419035610395768 -114.239339836972 0.368732082758625 -145.825795433023 0.191365298566914 -1.88315921233554 0.475990491862062 -86.3745276909252 + 0.182081822472626 -39.5872816940605 0.327665280430988 23.5788117870151 + 0.389636279407825 168.794500154946 0.0676398633206897 -124.060275191782 0.410555737909478 -102.662044630707 0.0273957264526352 -10.283056843649 + 0.327665280430988 23.5788117870151 0.0388519938209085 168.484837829255 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.3 0.16488791579873 -57.1023110453331 0.331955045944014 8.41651890017188 0.209860144379456 -68.9949544914897 0.370003477137292 -125.448022298828 + 0.0399515191889503 -138.965401308463 0.389900050923687 155.11563719708 + 0.331955045944014 8.41651890017188 0.290103762965557 -108.127527178161 0.389855905178857 -110.113152118432 0.205781992507035 -39.9304597288396 + 0.367921121107276 -158.96943374038 0.0634131854686694 -103.717149517998 + 0.209860144379456 -68.9949544914897 0.389855905178857 -110.113152118432 0.148705199775181 -73.5786721086649 0.239033887363934 86.8437798327157 + 0.188167005712988 -17.0010002394595 0.415220454956305 -117.190299706626 + 0.370003477137292 -125.448022298828 0.205781992507035 -39.9304597288396 0.239033887363934 86.8437798327157 0.149009423080978 -151.598433765363 + 0.476445801255502 -100.098393256591 0.0242011650570394 -19.8981149546038 + 0.0399515191889503 -138.965401308463 0.367921121107276 -158.96943374038 0.188167005712988 -17.0010002394595 0.476445801255502 -100.098393256591 + 0.206284369805567 -46.0702634592761 0.317383544902734 11.3314581834904 + 0.389900050923687 155.11563719708 0.0634131854686694 -103.717149517998 0.415220454956305 -117.190299706626 0.0242011650570394 -19.8981149546038 + 0.317383544902734 11.3314581834904 0.0309275109868167 173.671252831959 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.35 0.165932770060683 -57.3100676364689 0.321627556828953 -6.40914480613324 0.187399845482039 -86.9384850548774 0.380295670675583 -139.946914308253 + 0.0377338074488448 -163.286103629303 0.397476465392807 141.971409220936 + 0.321627556828953 -6.40914480613324 0.287212706028462 -112.063925167565 0.397735158012525 -123.233846214267 0.217162299702784 -43.265057669328 + 0.370406664042043 -171.849739933061 0.0820015243079896 -86.1734526419211 + 0.187399845482039 -86.9384850548774 0.397735158012525 -123.233846214267 0.141979972016178 -73.3171546941713 0.240172293660325 76.7030421984254 + 0.179893221271112 -32.7653251673887 0.419012829761066 -132.460072288245 + 0.380295670675583 -139.946914308253 0.217162299702784 -43.265057669328 0.240172293660325 76.7030421984254 0.140360956946292 -142.980175030823 + 0.475308256556539 -113.997216875918 0.0230607944429353 -37.7691828269336 + 0.0377338074488448 -163.286103629303 0.370406664042043 -171.849739933061 0.179893221271112 -32.7653251673887 0.475308256556539 -113.997216875918 + 0.224431330026718 -53.6591237232226 0.309868227745734 -0.28473449942287 + 0.397476465392807 141.971409220936 0.0820015243079896 -86.1734526419211 0.419012829761066 -132.460072288245 0.0230607944429353 -37.7691828269336 + 0.309868227745734 -0.28473449942287 0.0298065294562947 -168.618109563234 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.4 0.174709012350431 -59.6395502130238 0.30798780164166 -19.3854305958626 0.169649053956753 -106.28795343206 0.380033054267315 -155.257941106073 + 0.0391076839927438 178.240134274909 0.405247557569273 127.455459962708 + 0.30798780164166 -19.3854305958626 0.291466268267901 -115.659131373334 0.400128252982253 -137.283028106746 0.224198551413864 -50.1013854197517 + 0.372790493010937 174.916078584704 0.112361709085663 -88.5022145772789 + 0.169649053956753 -106.28795343206 0.400128252982253 -137.283028106746 0.14163612109824 -74.0299675255663 0.24883609368983 65.6241362573816 + 0.165844849548028 -50.8352724313278 0.41298812871794 -147.482256781765 + 0.380033054267315 -155.257941106073 0.224198551413864 -50.1013854197517 0.24883609368983 65.6241362573816 0.155948646314725 -139.476300919062 + 0.471444090064856 -127.451977700669 0.00875684182438943 -85.9092981506905 + 0.0391076839927438 178.240134274909 0.372790493010937 174.916078584704 0.165844849548028 -50.8352724313278 0.471444090064856 -127.451977700669 + 0.233315774438194 -62.444128752287 0.309724229159807 -12.1885305870026 + 0.405247557569273 127.455459962708 0.112361709085663 -88.5022145772789 0.41298812871794 -147.482256781765 0.00875684182438943 -85.9092981506905 + 0.309724229159807 -12.1885305870026 0.04405424088801 178.967429688975 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.45 0.178434034559503 -63.9454906282366 0.295373869010446 -31.7296016696053 0.15161957188679 -129.359054722675 0.375492666569631 -170.417086689525 + 0.0446036531169635 159.936281007695 0.410158084958735 112.686251341144 + 0.295373869010446 -31.7296016696053 0.293654298682543 -120.237722119229 0.401277568646019 -151.337144878697 0.221549042509564 -57.1526303107784 + 0.375634841198221 161.825449104919 0.136695184124451 -96.6210452122105 + 0.15161957188679 -129.359054722675 0.401277568646019 -151.337144878697 0.13623084640134 -76.6466147641553 0.255886207127282 54.0403701047974 + 0.144657647000846 -71.2417200856563 0.406462605631827 -162.227553335405 + 0.375492666569631 -170.417086689525 0.221549042509564 -57.1526303107784 0.255886207127282 54.0403701047974 0.171115528546146 -141.735827581997 + 0.470583805319772 -140.785472468913 0.0134028326418277 116.204785050188 + 0.0446036531169635 159.936281007695 0.375634841198221 161.825449104919 0.144657647000846 -71.2417200856563 0.470583805319772 -140.785472468913 + 0.230062008226402 -71.4343126746902 0.308597187957548 -25.1223891993189 + 0.410158084958735 112.686251341144 0.136695184124451 -96.6210452122105 0.406462605631827 -162.227553335405 0.0134028326418277 116.204785050188 + 0.308597187957548 -25.1223891993189 0.051741505584432 151.378439447262 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.5 0.168234539961453 -70.4804844399414 0.289058857832389 -42.5301284542394 0.140395612296097 -159.443586481211 0.362791571892643 175.085826316188 + 0.0557115572086307 140.070584398096 0.408832474626503 97.4315742733797 + 0.289058857832389 -42.5301284542394 0.296199740499194 -126.256910644971 0.39683898095299 -165.329970284415 0.209125448040359 -64.6590156084583 + 0.378465598084301 148.828052769193 0.153123144002798 -108.121619512516 + 0.140395612296097 -159.443586481211 0.39683898095299 -165.329970284415 0.11965688822599 -82.1567173174103 0.265076988233977 41.4926074565506 + 0.118655300605232 -96.0700348340459 0.394920389859031 -176.548287565547 + 0.362791571892643 175.085826316188 0.209125448040359 -64.6590156084583 0.265076988233977 41.4926074565506 0.184112097125832 -147.754760339601 + 0.470464118764785 -154.220259606689 0.0371166581812702 90.8892192564928 + 0.0557115572086307 140.070584398096 0.378465598084301 148.828052769193 0.118655300605232 -96.0700348340459 0.470464118764785 -154.220259606689 + 0.215624200765542 -80.0387198826641 0.305323187011516 -38.0928353303588 + 0.408832474626503 97.4315742733797 0.153123144002798 -108.121619512516 0.394920389859031 -176.548287565547 0.0371166581812702 90.8892192564928 + 0.305323187011516 -38.0928353303588 0.0626699311117146 123.300901051167 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.55 0.139365944132803 -68.4660183798344 0.292602246609577 -54.5906552948668 0.132363093614074 160.703051601712 0.35217353785025 162.451559185052 + 0.0694095354346786 115.31636942233 0.397112099234592 83.4349771248435 + 0.292602246609577 -54.5906552948668 0.286628762474418 -133.734232715131 0.392868686753097 -178.265231320737 0.181903273292026 -69.5306843246476 + 0.383813140456201 135.974686268622 0.155567063491372 -120.778848176005 + 0.132363093614074 160.703051601712 0.392868686753097 -178.265231320737 0.0838972894943583 -75.4615274771864 0.26600048550874 27.940217414137 + 0.0903260852034346 -128.49242734362 0.384579684051448 170.602004847355 + 0.35217353785025 162.451559185052 0.181903273292026 -69.5306843246476 0.26600048550874 27.940217414137 0.18553034074377 -157.247913384312 + 0.471375176683487 -167.761200449373 0.0693071433672664 68.8793390429178 + 0.0694095354346786 115.31636942233 0.383813140456201 135.974686268622 0.0903260852034346 -128.49242734362 0.471375176683487 -167.761200449373 + 0.189264000274121 -87.6598280019123 0.301988479833525 -51.4414688909678 + 0.397112099234592 83.4349771248435 0.155567063491372 -120.778848176005 0.384579684051448 170.602004847355 0.0693071433672664 68.8793390429178 + 0.301988479833525 -51.4414688909678 0.0843956434790406 90.4300790428489 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.6 0.142174559588207 -56.617190700417 0.291362822114633 -68.0355829104677 0.129615446793054 118.360295734937 0.353061217863193 149.70450506707 + 0.0806960905792384 88.5671426450884 0.394601340000072 71.3755255432459 + 0.291362822114633 -68.0355829104677 0.26506797170122 -140.653890473015 0.396207006911988 168.740896277878 0.156000487742719 -68.9171403022948 + 0.391633754996079 122.970017202084 0.145565613734211 -131.123860959672 + 0.129615446793054 118.360295734937 0.396207006911988 168.740896277878 0.0814361305839429 -41.3236136753011 0.260587481835181 16.3361658317035 + 0.0699030991755309 -171.282097847999 0.38688791310644 157.225713099728 + 0.353061217863193 149.70450506707 0.156000487742719 -68.9171403022948 0.260587481835181 16.3361658317035 0.173225774342863 -165.299328292045 + 0.473462438850323 178.348380459711 0.101343831800103 43.4924960384688 + 0.0806960905792384 88.5671426450884 0.391633754996079 122.970017202084 0.0699030991755309 -171.282097847999 0.473462438850323 178.348380459711 + 0.153532215629946 -92.0806800766073 0.293157843718694 -64.923606019607 + 0.394601340000072 71.3755255432459 0.145565613734211 -131.123860959672 0.38688791310644 157.225713099728 0.101343831800103 43.4924960384688 + 0.293157843718694 -64.923606019607 0.103743108023381 55.533501593777 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.65 0.168068430981945 -54.5807584134065 0.285638484917974 -81.2358838348444 0.135411357543224 82.106648892338 0.354340994030286 135.829554394652 + 0.0868671065842469 62.1455677529479 0.403301368801824 58.6281456612776 + 0.285638484917974 -81.2358838348444 0.235670932749912 -146.561213738 0.402337356705283 155.009151438437 0.139953420917842 -62.924733882299 + 0.401981737489029 109.744610595062 0.1322947772154 -138.888915192453 + 0.135411357543224 82.106648892338 0.402337356705283 155.009151438437 0.127299169485328 -29.5894857281813 0.261057155038931 6.31275028796287 + 0.0680719522180186 142.228657566763 0.385070800530646 142.469383849486 + 0.354340994030286 135.829554394652 0.139953420917842 -62.924733882299 0.261057155038931 6.31275028796287 0.15964185534624 -171.330596200186 + 0.473133577499987 164.018689455468 0.123298452409559 21.083421293622 + 0.0868671065842469 62.1455677529479 0.401981737489029 109.744610595062 0.0680719522180186 142.228657566763 0.473133577499987 164.018689455468 + 0.117697160981792 -89.1766941344047 0.282126120534627 -77.2165049072826 + 0.403301368801824 58.6281456612776 0.1322947772154 -138.888915192453 0.385070800530646 142.469383849486 0.123298452409559 21.083421293622 + 0.282126120534627 -77.2165049072826 0.114512804753296 27.808730514734 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.7 0.182243665792703 -59.0503353041293 0.276810548842141 -93.2872043110411 0.147617947304802 55.4850555210972 0.35200738130388 121.288003941622 + 0.0885090507867031 38.9094605065606 0.414112113946227 44.9473841510326 + 0.276810548842141 -93.2872043110411 0.199340093057809 -149.242044934405 0.406875239795019 140.039508878517 0.141660541204033 -54.2404240375641 + 0.415585785747859 95.7893555101664 0.117489544139413 -144.794698380432 + 0.147617947304802 55.4850555210972 0.406875239795019 140.039508878517 0.167997636573409 -33.9733642565583 0.269914096537596 -3.54818533084101 + 0.0836979099683848 107.452004826957 0.376842957496553 127.714839681483 + 0.35200738130388 121.288003941622 0.141660541204033 -54.2404240375641 0.269914096537596 -3.54818533084101 0.14641293921511 -176.9316321783 + 0.468221629302926 149.450284893221 0.138494097802697 2.8807792331597 + 0.0885090507867031 38.9094605065606 0.415585785747859 95.7893555101664 0.0836979099683848 107.452004826957 0.468221629302926 149.450284893221 + 0.0932764117937512 -75.5457706183568 0.274201508170629 -88.6406525427503 + 0.414112113946227 44.9473841510326 0.117489544139413 -144.794698380432 0.376842957496553 127.714839681483 0.138494097802697 2.8807792331597 + 0.274201508170629 -88.6406525427503 0.122187186015409 8.53901463241491 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.75 0.192579151016017 -62.022862441115 0.276376801099557 -104.704616404008 0.168261145651653 32.2879558616641 0.345323284638762 107.274990899665 + 0.0912624952679197 16.5888804104355 0.423831170385715 30.8863044588122 + 0.276376801099557 -104.704616404008 0.169540336961702 -147.357302254622 0.401695511937804 125.137964732373 0.157380505161037 -48.6156506612999 + 0.425200872139738 81.0543427634748 0.099667626814609 -148.694139541976 + 0.168261145651653 32.2879558616641 0.401695511937804 125.137964732373 0.20360021457718 -39.0828699838597 0.282686132664506 -14.8065318752297 + 0.106080459478366 80.9607528819433 0.367045430121351 113.432686270575 + 0.345323284638762 107.274990899665 0.157380505161037 -48.6156506612999 0.282686132664506 -14.8065318752297 0.129693330865739 177.392921511433 + 0.458844051436927 135.170515677624 0.155076070927083 -13.220417338583 + 0.0912624952679197 16.5888804104355 0.425200872139738 81.0543427634748 0.106080459478366 80.9607528819433 0.458844051436927 135.170515677624 + 0.094666211198872 -52.7109622257415 0.26931762881008 -99.9227265345792 + 0.423831170385715 30.8863044588122 0.099667626814609 -148.694139541976 0.367045430121351 113.432686270575 0.155076070927083 -13.220417338583 + 0.26931762881008 -99.9227265345792 0.136732615794111 -7.61457946374846 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.8 0.200556731638221 -68.1606009685198 0.277386277020676 -117.196362225231 0.181774917662623 10.6907949489362 0.340574194746895 93.6207129784839 + 0.0920977938850819 -6.62127461699768 0.433692113345428 16.5903019825518 + 0.277386277020676 -117.196362225231 0.150456913569392 -141.247728272467 0.395619425013978 110.884834592285 0.181691633725107 -47.1876990065274 + 0.430106929647956 66.3540798422518 0.0814155152909082 -147.658501748086 + 0.181774917662623 10.6907949489362 0.395619425013978 110.884834592285 0.236788781098018 -47.1856303579809 0.294425423039763 -26.6103508488956 + 0.124989311628655 59.736529173004 0.357537849415062 99.3629236048681 + 0.340574194746895 93.6207129784839 0.181691633725107 -47.1876990065274 0.294425423039763 -26.6103508488956 0.110738530209316 174.249414327788 + 0.448578330841757 121.298272186967 0.170019244789575 -30.1238581267923 + 0.0920977938850819 -6.62127461699768 0.430106929647956 66.3540798422518 0.124989311628655 59.736529173004 0.448578330841757 121.298272186967 + 0.124557973537579 -40.2421815264672 0.266051631438003 -111.23375750936 + 0.433692113345428 16.5903019825518 0.0814155152909082 -147.658501748086 0.357537849415062 99.3629236048681 0.170019244789575 -30.1238581267923 + 0.266051631438003 -111.23375750936 0.149103346517385 -25.194028158001 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.85 0.1959377287151 -74.9883744262317 0.276600603750588 -130.237927114039 0.187541490133897 -8.34775312439553 0.338361247084857 79.7177167214661 + 0.0899055182892495 -29.8668135818993 0.445837530568226 2.09797367767573 + 0.276600603750588 -130.237927114039 0.143512221659898 -132.575317345309 0.391970008150367 96.7053491263478 0.21164438330796 -48.9673514500308 + 0.434784254619502 51.9061026688648 0.0670721488922027 -136.448464233861 + 0.187541490133897 -8.34775312439553 0.391970008150367 96.7053491263478 0.257665798112146 -56.5884309819987 0.307167593584389 -38.1494276079987 + 0.139223867105675 42.5823703568588 0.349474417783503 84.940870793727 + 0.338361247084857 79.7177167214661 0.21164438330796 -48.9673514500308 0.307167593584389 -38.1494276079987 0.0932185914336654 175.572610188092 + 0.438912374741174 107.419094278247 0.179824548360002 -47.6157288227511 + 0.0899055182892495 -29.8668135818993 0.434784254619502 51.9061026688648 0.139223867105675 42.5823703568588 0.438912374741174 107.419094278247 + 0.161117631466968 -39.1974198461421 0.26266169251454 -122.210266866702 + 0.445837530568226 2.09797367767573 0.0670721488922027 -136.448464233861 0.349474417783503 84.940870793727 0.179824548360002 -47.6157288227511 + 0.26266169251454 -122.210266866702 0.15074523259717 -42.9272756732211 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.9 0.181436634193742 -81.0179489119303 0.272604504997209 -143.165766275011 0.188384335248059 -25.7022610565046 0.334725271937866 65.0931699855812 + 0.087220846921825 -52.0400313256597 0.459537579929323 -13.2619904418688 + 0.272604504997209 -143.165766275011 0.156086961528565 -123.211888138505 0.386537106054295 81.9632332898067 0.244857822239382 -55.0196377406833 + 0.438961053928062 37.0132962500968 0.0733160581243868 -119.860131332227 + 0.188384335248059 -25.7022610565046 0.386537106054295 81.9632332898067 0.269046122852888 -65.5213976807034 0.32643969096802 -50.2453532087491 + 0.151206837428894 26.723491081804 0.336176602072111 70.0115856743721 + 0.334725271937866 65.0931699855812 0.244857822239382 -55.0196377406833 0.32643969096802 -50.2453532087491 0.0873879854952747 -177.724172368709 + 0.424905624960575 93.621706202529 0.180668253588512 -65.9103507870656 + 0.087220846921825 -52.0400313256597 0.438961053928062 37.0132962500968 0.151206837428894 26.723491081804 0.424905624960575 93.621706202529 + 0.197639939815235 -43.0342592356942 0.263898144744332 -132.545184806007 + 0.459537579929323 -13.2619904418688 0.0733160581243868 -119.860131332227 0.336176602072111 70.0115856743721 0.180668253588512 -65.9103507870656 + 0.263898144744332 -132.545184806007 0.139033955401974 -59.1822132197973 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +5.95 0.158742812672587 -84.9176572287178 0.268218481579363 -155.473291825608 0.184727304180547 -42.7584668890914 0.326246478628262 50.2938264711632 + 0.0870952712127221 -74.7119459082984 0.468543806959683 -29.4350232296168 + 0.268218481579363 -155.473291825608 0.185361218437381 -121.189690876232 0.37658967349075 67.4003319633433 0.266597307820047 -63.7933992279004 + 0.437718114621092 22.1403189345759 0.0899204790243114 -116.015375935548 + 0.184727304180547 -42.7584668890914 0.37658967349075 67.4003319633433 0.275181563241202 -74.8974592455413 0.34642841153319 -63.6802345627124 + 0.156367496417161 10.5372423130374 0.318082561419756 55.7189602397665 + 0.326246478628262 50.2938264711632 0.266597307820047 -63.7933992279004 0.34642841153319 -63.6802345627124 0.0925813920176257 -177.304080113415 + 0.410151362085774 80.6660328617365 0.167511134311603 -83.3112179154927 + 0.0870952712127221 -74.7119459082984 0.437718114621092 22.1403189345759 0.156367496417161 10.5372423130374 0.410151362085774 80.6660328617365 + 0.228860527918125 -50.344038238235 0.270014213352169 -143.609882811989 + 0.468543806959683 -29.4350232296168 0.0899204790243114 -116.015375935548 0.318082561419756 55.7189602397665 0.167511134311603 -83.3112179154927 + 0.270014213352169 -143.609882811989 0.114160331189687 -70.2666792294777 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6 0.133945660622493 -84.8799339696589 0.265811889760632 -167.632907012294 0.175167859263153 -60.559466869556 0.314842158947512 36.0212967096258 + 0.0888946651484135 -99.4051283325022 0.470321997510752 -45.803498317874 + 0.265811889760632 -167.632907012294 0.21210334393715 -125.031929208069 0.365393167774541 53.2971853643046 0.274955782648524 -72.322814216367 + 0.434570791641354 7.68060303653106 0.101217127101055 -117.037453346375 + 0.175167859263153 -60.559466869556 0.365393167774541 53.2971853643046 0.273444522873075 -85.5177963976274 0.363033092409873 -77.7210961157587 + 0.152334336642102 -5.76982975424676 0.300464123050701 42.2496442302334 + 0.314842158947512 36.0212967096258 0.274955782648524 -72.322814216367 0.363033092409873 -77.7210961157587 0.0908335421250316 176.438164400522 + 0.399029393053022 68.1545962912159 0.145023348270241 -96.4341781776838 + 0.0888946651484135 -99.4051283325022 0.434570791641354 7.68060303653106 0.152334336642102 -5.76982975424676 0.399029393053022 68.1545962912159 + 0.249534012846395 -59.336258104701 0.276102250685474 -155.436250205097 + 0.470321997510752 -45.803498317874 0.101217127101055 -117.037453346375 0.300464123050701 42.2496442302334 0.145023348270241 -96.4341781776838 + 0.276102250685474 -155.436250205097 0.0914977251457266 -68.1893597419826 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.05 0.111169759312563 -79.7980696508913 0.262518819656033 -179.964214893474 0.158266677794623 -79.8098940175716 0.304323228320495 21.9929959623574 + 0.0920507062603582 -125.518865335693 0.468302118897155 -61.9875209888183 + 0.262518819656033 -179.964214893474 0.230766202469674 -130.811036688677 0.355244073220674 39.4288816624652 0.277768882422497 -79.9008853868043 + 0.431548232705431 -6.56465257301139 0.112297745525296 -116.673865066254 + 0.158266677794623 -79.8098940175716 0.355244073220674 39.4288816624652 0.259748308713819 -97.7685540824017 0.377908560970419 -91.749428147054 + 0.138371249974931 -22.1303159548395 0.2843607620959 28.7801458865789 + 0.304323228320495 21.9929959623574 0.277768882422497 -79.9008853868043 0.377908560970419 -91.749428147054 0.0798573981949184 172.367278826867 + 0.39004420484523 55.6209855255721 0.125521629244112 -104.209984776307 + 0.0920507062603582 -125.518865335693 0.431548232705431 -6.56465257301139 0.138371249974931 -22.1303159548395 0.39004420484523 55.6209855255721 + 0.257161922442214 -69.3278842567413 0.281849955814992 -167.211718297145 + 0.468302118897155 -61.9875209888183 0.112297745525296 -116.673865066254 0.2843607620959 28.7801458865789 0.125521629244112 -104.209984776307 + 0.281849955814992 -167.211718297145 0.0925779973547286 -58.8463578664285 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.1 0.0942169023244327 -65.074852620626 0.256839541443463 168.51802398974 0.132197818525248 -102.026038852958 0.292174282843201 7.28134996056051 + 0.0991413413555455 -152.935766966012 0.466753133330668 -78.3664108569813 + 0.256839541443463 168.51802398974 0.244562772913278 -137.568408574651 0.345639048829901 25.4278125069261 0.276937824105843 -87.6612175570666 + 0.427728807233688 -20.6677639159342 0.129352285702769 -118.38143147913 + 0.132197818525248 -102.026038852958 0.345639048829901 25.4278125069261 0.230622890078971 -112.563239475369 0.394344120802066 -105.843183449371 + 0.113698029672561 -38.9733454890496 0.265854345875111 14.8751796001018 + 0.292174282843201 7.28134996056051 0.276937824105843 -87.6612175570666 0.394344120802066 -105.843183449371 0.0707451398468705 172.920592733581 + 0.38197941238909 43.1969478141717 0.110629803630067 -109.685041147745 + 0.0991413413555455 -152.935766966012 0.427728807233688 -20.6677639159342 0.113698029672561 -38.9733454890496 0.38197941238909 43.1969478141717 + 0.248944254803435 -79.8240669289047 0.290097800188617 -179.093494059325 + 0.466753133330668 -78.3664108569813 0.129352285702769 -118.38143147913 0.265854345875111 14.8751796001018 0.110629803630067 -109.685041147745 + 0.290097800188617 -179.093494059325 0.106428963563361 -56.6589932072703 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.15 0.107479370482543 -46.1157859068921 0.257734296702875 158.742268017809 0.0989821921725578 -127.564797932155 0.267806642442248 -6.84710516589485 + 0.10852779249862 177.309670134876 0.455960769454327 -96.1378791436475 + 0.257734296702875 158.742268017809 0.251472226579799 -146.053098890932 0.332124773745953 11.0172770326584 0.264954919778853 -95.1688736801607 + 0.424603185455335 -34.583141991326 0.141655070133025 -123.236026072485 + 0.0989821921725578 -127.564797932155 0.332124773745953 11.0172770326584 0.180219465722178 -130.736826319965 0.414189807001744 -121.009066180202 + 0.0765912690487266 -54.5130744264964 0.236517659252359 1.73766174579821 + 0.267806642442248 -6.84710516589485 0.264954919778853 -95.1688736801607 0.414189807001744 -121.009066180202 0.0591326060567538 172.232334535945 + 0.374383671872836 30.6768916556512 0.0930854703279319 -107.85348621722 + 0.10852779249862 177.309670134876 0.424603185455335 -34.583141991326 0.0765912690487266 -54.5130744264964 0.374383671872836 30.6768916556512 + 0.2228212276913 -90.1108310168152 0.301080134070616 168.834628147702 + 0.455960769454327 -96.1378791436475 0.141655070133025 -123.236026072485 0.236517659252359 1.73766174579821 0.0930854703279319 -107.85348621722 + 0.301080134070616 168.834628147702 0.128219452431035 -55.6255873045129 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.2 0.13289600551256 -38.1949943210853 0.271029058494085 147.397378690388 0.06650411424495 -165.672288276492 0.245608580674988 -16.7397914044273 + 0.11736889873887 146.409914542964 0.423929689832126 -112.799653193436 + 0.271029058494085 147.397378690388 0.24264349551847 -155.103259752367 0.312205699504004 -2.36779986800419 0.249324226841558 -99.4444984461246 + 0.421667930618285 -48.6346065903885 0.151526240317533 -124.408525545871 + 0.06650411424495 -165.672288276492 0.312205699504004 -2.36779986800419 0.111113699204023 -157.226114333832 0.424877761505855 -137.44778631725 + 0.0326687624950561 -54.0138988222808 0.208486666387453 -6.42681863295491 + 0.245608580674988 -16.7397914044273 0.249324226841558 -99.4444984461246 0.424877761505855 -137.44778631725 0.0460654520015341 -166.222238366104 + 0.365139757608602 18.4026484836665 0.103197487906172 -97.3952567854812 + 0.11736889873887 146.409914542964 0.421667930618285 -48.6346065903885 0.0326687624950561 -54.0138988222808 0.365139757608602 18.4026484836665 + 0.178774963941964 -98.22184957463 0.316682333197302 155.967038023482 + 0.423929689832126 -112.799653193436 0.151526240317533 -124.408525545871 0.208486666387453 -6.42681863295491 0.103197487906172 -97.3952567854812 + 0.316682333197302 155.967038023482 0.169059743328951 -64.6726261609426 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.25 0.171988264247198 -33.5865625383069 0.279602030593412 133.493686241567 0.0468923376904919 125.762530666702 0.240829179864017 -26.099142269174 + 0.121581389288761 115.793214474056 0.395215308073793 -126.701806258961 + 0.279602030593412 133.493686241567 0.223928951469144 -162.024618077424 0.296714682710515 -13.9092681466444 0.244590259757992 -102.766496500347 + 0.41596983041701 -62.608938080706 0.176549621271184 -126.918426595066 + 0.0468923376904919 125.762530666702 0.296714682710515 -13.9092681466444 0.0433876884742702 126.250555816743 0.424276692389433 -153.400011571232 + 0.0329248851356368 22.9317506635372 0.197321194156431 -12.463471585637 + 0.240829179864017 -26.099142269174 0.244590259757992 -102.766496500347 0.424276692389433 -153.400011571232 0.0685043761669382 -147.337340666047 + 0.357609682997712 6.82453855895535 0.129107229464603 -101.580181523465 + 0.121581389288761 115.793214474056 0.41596983041701 -62.608938080706 0.0329248851356368 22.9317506635372 0.357609682997712 6.82453855895535 + 0.12534559652835 -97.357991445174 0.332868150953794 141.698830190299 + 0.395215308073793 -126.701806258961 0.176549621271184 -126.918426595066 0.197321194156431 -12.463471585637 0.129107229464603 -101.580181523465 + 0.332868150953794 141.698830190299 0.192948158232236 -81.1449862917625 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.3 0.23041630785007 -37.7054408585573 0.279351080327077 120.472890295266 0.0634162015946827 58.0239319893423 0.236836110750491 -37.7633986686126 + 0.122481242266474 87.9477667267936 0.378145583892824 -140.375413752883 + 0.279351080327077 120.472890295266 0.202692131820531 -167.042757068163 0.289764839873752 -25.8368453525387 0.240589631354159 -106.758503787389 + 0.411063656461843 -76.181274235536 0.201609001809677 -133.756162189954 + 0.0634162015946827 58.0239319893423 0.289764839873752 -25.8368453525387 0.0995756606260495 31.7731779833245 0.422852372204208 -168.421520730119 + 0.0660116568790383 23.0433874204634 0.193127895865097 -19.8990291588435 + 0.236836110750491 -37.7633986686126 0.240589631354159 -106.758503787389 0.422852372204208 -168.421520730119 0.095285420255225 -151.099216606894 + 0.35484497534447 -4.80922174164283 0.147925377649424 -108.94995724218 + 0.122481242266474 87.9477667267936 0.411063656461843 -76.181274235536 0.0660116568790383 23.0433874204634 0.35484497534447 -4.80922174164283 + 0.0943989104410083 -77.6893932155176 0.343709931833475 126.663113219417 + 0.378145583892824 -140.375413752883 0.201609001809677 -133.756162189954 0.193127895865097 -19.8990291588435 0.147925377649424 -108.94995724218 + 0.343709931833475 126.663113219417 0.202046201127407 -95.6242840382287 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.35 0.282177491887706 -50.0771944669081 0.285113909294188 108.661659959011 0.0865805343132264 16.5010475404239 0.226850546951211 -48.1831703028308 + 0.121742049170613 61.26671790443 0.357156389232596 -154.709699018591 + 0.285113909294188 108.661659959011 0.182346531699222 -169.100066537688 0.278223436373676 -38.4625249282801 0.239164841327149 -110.422494516331 + 0.406037419932422 -90.0171384744044 0.223343458409232 -141.542151097586 + 0.0865805343132264 16.5010475404239 0.278223436373676 -38.4625249282801 0.185163288584943 1.79066394952685 0.422957204560039 176.030702879359 + 0.0904823795334771 9.97056798422577 0.189104811637281 -26.3486968833201 + 0.226850546951211 -48.1831703028308 0.239164841327149 -110.422494516331 0.422957204560039 176.030702879359 0.121964088119295 -158.679662566886 + 0.351728115508931 -16.5518345666297 0.170578377548868 -117.165759632871 + 0.121742049170613 61.26671790443 0.406037419932422 -90.0171384744044 0.0904823795334771 9.97056798422577 0.351728115508931 -16.5518345666297 + 0.105836607377204 -52.747354621581 0.351983449780931 111.621931318535 + 0.357156389232596 -154.709699018591 0.223343458409232 -141.542151097586 0.189104811637281 -26.3486968833201 0.170578377548868 -117.165759632871 + 0.351983449780931 111.621931318535 0.210342784518586 -109.997487406997 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.4 0.299562925573407 -64.9721030590891 0.296220235011701 96.0174209830606 0.0935287739368412 -12.0572583651691 0.223835630769585 -57.0815829129931 + 0.116663320486998 36.3978369220207 0.33218647822143 -167.678300759125 + 0.296220235011701 96.0174209830606 0.171568192765822 -169.725107781746 0.265230041612979 -49.5813588628332 0.239009085017771 -115.178894508447 + 0.396714594408378 -103.43170119378 0.242542229967929 -150.528742937982 + 0.0935287739368412 -12.0572583651691 0.265230041612979 -49.5813588628332 0.251359633551518 -19.4149759209063 0.414659322946687 160.233988390746 + 0.102579346262202 -7.3266483816775 0.195482312648057 -32.3225123674171 + 0.223835630769585 -57.0815829129931 0.239009085017771 -115.178894508447 0.414659322946687 160.233988390746 0.149163986679499 -170.694636685537 + 0.351824413566729 -27.9947819250833 0.19242827938624 -128.184323883735 + 0.116663320486998 36.3978369220207 0.396714594408378 -103.43170119378 0.102579346262202 -7.3266483816775 0.351824413566729 -27.9947819250833 + 0.144807520982561 -44.268531682406 0.357504569131155 96.2191850835819 + 0.33218647822143 -167.678300759125 0.242542229967929 -150.528742937982 0.195482312648057 -32.3225123674171 0.19242827938624 -128.184323883735 + 0.357504569131155 96.2191850835819 0.211978446907359 -126.026302714785 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.45 0.283807331226441 -78.2731784893559 0.311497831505021 82.3437741100242 0.0874666412260732 -31.5642120817201 0.226776291065446 -66.0585165693217 + 0.110662059439573 13.0898273749836 0.310845583042936 -179.278867651325 + 0.311497831505021 82.3437741100242 0.158589184690169 -171.515076698833 0.257596806903389 -59.8064848921877 0.236081038488733 -119.316979616453 + 0.390923361467606 -115.941700288486 0.256105481200907 -159.406789216957 + 0.0874666412260732 -31.5642120817201 0.257596806903389 -59.8064848921877 0.29261599769822 -36.1850621735309 0.401692647997496 145.135184220766 + 0.100319817875215 -25.0282934053005 0.207256381262303 -40.3809560228202 + 0.226776291065446 -66.0585165693217 0.236081038488733 -119.316979616453 0.401692647997496 145.135184220766 0.169663809282403 176.039391302693 + 0.354421113015063 -40.1033878727819 0.210911279703974 -139.653108695366 + 0.110662059439573 13.0898273749836 0.390923361467606 -115.941700288486 0.100319817875215 -25.0282934053005 0.354421113015063 -40.1033878727819 + 0.182063072119905 -46.5858115416516 0.359359222477738 81.120747398882 + 0.310845583042936 -179.278867651325 0.256105481200907 -159.406789216957 0.207256381262303 -40.3809560228202 0.210911279703974 -139.653108695366 + 0.359359222477738 81.120747398882 0.206613152025057 -142.278080600446 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.5 0.243324388641083 -88.5279924015332 0.32352410792793 66.8910621328385 0.0693898192605074 -44.3577528197274 0.235474233399617 -75.7928668175949 + 0.099857655527358 -9.20905445032574 0.294708485652168 169.73284186385 + 0.32352410792793 66.8910621328385 0.147351533411043 -167.229265321166 0.254648620658926 -70.0945375164102 0.242004348426603 -124.036734981728 + 0.389850920175162 -128.923602857775 0.273131473582766 -169.109315619398 + 0.0693898192605074 -44.3577528197274 0.254648620658926 -70.0945375164102 0.310062029440437 -50.5311953976403 0.388615449947923 130.360468426553 + 0.0861146928604375 -42.9790998733142 0.219509875341342 -48.7061744637462 + 0.235474233399617 -75.7928668175949 0.242004348426603 -124.036734981728 0.388615449947923 130.360468426553 0.190545708655239 162.360302875482 + 0.353491410159539 -52.1812072496988 0.226931044570759 -152.499910531092 + 0.099857655527358 -9.20905445032574 0.389850920175162 -128.923602857775 0.0861146928604375 -42.9790998733142 0.353491410159539 -52.1812072496988 + 0.209631083935214 -51.5018972630926 0.364376841660351 65.9904824268462 + 0.294708485652168 169.73284186385 0.273131473582766 -169.109315619398 0.219509875341342 -48.7061744637462 0.226931044570759 -152.499910531092 + 0.364376841660351 65.9904824268462 0.195786936893402 -159.114291896372 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.55 0.196664802430396 -88.1364453161627 0.330390804131194 51.5555771540972 0.0587876654005976 -30.7765945162499 0.246275164464298 -86.1905587757609 + 0.0908073261388924 -26.3286521995483 0.278438437798993 159.636052312755 + 0.330390804131194 51.5555771540972 0.161266342243282 -163.462425223514 0.251518474743724 -80.4680999858699 0.244430388482651 -131.975496603632 + 0.384627464494139 -142.223513264322 0.282164770823139 178.526696242085 + 0.0587876654005976 -30.7765945162499 0.251518474743724 -80.4680999858699 0.308744109539122 -60.1372942869831 0.372628436041669 115.358720193699 + 0.0635121675759325 -57.9099256533207 0.242427328699836 -57.307714262104 + 0.246275164464298 -86.1905587757609 0.244430388482651 -131.975496603632 0.372628436041669 115.358720193699 0.208701266132861 146.151057755878 + 0.355414587768078 -63.5538198122477 0.232579326721526 -166.031104480425 + 0.0908073261388924 -26.3286521995483 0.384627464494139 -142.223513264322 0.0635121675759325 -57.9099256533207 0.355414587768078 -63.5538198122477 + 0.230048742526698 -57.0971507118025 0.367412025262946 49.7442208301956 + 0.278438437798993 159.636052312755 0.282164770823139 178.526696242085 0.242427328699836 -57.307714262104 0.232579326721526 -166.031104480425 + 0.367412025262946 49.7442208301956 0.1793327753208 -176.208471905419 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.6 0.198193054261536 -85.5833537345349 0.338144924892016 35.4455149316644 0.0789468714302029 -35.9458391872635 0.263658463248627 -97.0014036108787 + 0.0894688643788018 -45.9330553134976 0.268767095167857 151.438391331743 + 0.338144924892016 35.4455149316644 0.181910922753623 -167.593543481873 0.252461435750171 -89.4267449662101 0.233406896941114 -140.713798972485 + 0.37664246536576 -154.699990401908 0.274748428429318 165.365443199099 + 0.0789468714302029 -35.9458391872635 0.252461435750171 -89.4267449662101 0.322256505576085 -68.4656062412059 0.348206685386685 100.578402215202 + 0.0435423081996893 -73.0889406051466 0.274235899924788 -68.8799633910875 + 0.263658463248627 -97.0014036108787 0.233406896941114 -140.713798972485 0.348206685386685 100.578402215202 0.216625082410005 128.53758707929 + 0.364104013641589 -75.1086173377992 0.228206885459133 -178.190521084865 + 0.0894688643788018 -45.9330553134976 0.37664246536576 -154.699990401908 0.0435423081996893 -73.0889406051466 0.364104013641589 -75.1086173377992 + 0.244079453187213 -63.3962210376704 0.362899254549134 33.016169427925 + 0.268767095167857 151.438391331743 0.274748428429318 165.365443199099 0.274235899924788 -68.8799633910875 0.228206885459133 -178.190521084865 + 0.362899254549134 33.016169427925 0.159180964347379 167.742203516541 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.65 0.182978504421463 -92.3235660039741 0.338572456716277 18.3724290278458 0.071380177778218 -54.2873972444377 0.28707197811437 -109.741165509554 + 0.0823610155380478 -69.904960876791 0.269155875117561 143.91370066658 + 0.338572456716277 18.3724290278458 0.193630390015464 -175.993178529177 0.265440849962234 -98.846576715091 0.211815202066606 -147.856179779885 + 0.37274130374555 -166.227614310323 0.251462530449395 152.646393715224 + 0.071380177778218 -54.2873972444377 0.265440849962234 -98.846576715091 0.320670279831311 -80.5902839254329 0.317206506169525 87.4882764513538 + 0.022003718913521 -114.063319550219 0.307091605503809 -82.9456907518759 + 0.28707197811437 -109.741165509554 0.211815202066606 -147.856179779885 0.317206506169525 87.4882764513538 0.213385533422337 110.950035678574 + 0.377054388814429 -87.6839176242118 0.220156157624141 171.749420871458 + 0.0823610155380478 -69.904960876791 0.37274130374555 -166.227614310323 0.022003718913521 -114.063319550219 0.377054388814429 -87.6839176242118 + 0.248062085524892 -70.1793774052916 0.35076237036295 16.4275655906873 + 0.269155875117561 143.91370066658 0.251462530449395 152.646393715224 0.307091605503809 -82.9456907518759 0.220156157624141 171.749420871458 + 0.35076237036295 16.4275655906873 0.142271534084569 153.348410315692 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.7 0.152448632607769 -92.2576226638257 0.330589081616861 1.22236680287361 0.0531690327437864 -58.1340264479451 0.311366108378924 -124.640243447325 + 0.0708866650999237 -92.325141995205 0.284415674124644 136.343198183363 + 0.330589081616861 1.22236680287361 0.192385019523893 174.915250341076 0.285051472933832 -110.563900184049 0.18900034718418 -151.151694845274 + 0.376782633809899 -177.624559602354 0.215698932227519 142.175730839227 + 0.0531690327437864 -58.1340264479451 0.285051472933832 -110.563900184049 0.291766178341947 -91.2894305593208 0.287517783833292 77.2457179744504 + 0.023928559542883 137.304567597864 0.336606457616046 -99.2200864836063 + 0.311366108378924 -124.640243447325 0.18900034718418 -151.151694845274 0.287517783833292 77.2457179744504 0.199687554493445 94.4992434104278 + 0.388824675243972 -101.409375746071 0.213596455315654 163.685304775037 + 0.0708866650999237 -92.325141995205 0.376782633809899 -177.624559602354 0.023928559542883 137.304567597864 0.388824675243972 -101.409375746071 + 0.241872135308859 -76.0934224887116 0.331999009676582 0.515523082448155 + 0.284415674124644 136.343198183363 0.215698932227519 142.175730839227 0.336606457616046 -99.2200864836063 0.213596455315654 163.685304775037 + 0.331999009676582 0.515523082448155 0.130196861778564 139.412393031416 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.75 0.125712680131987 -87.3429270008297 0.314423213176933 -15.3935888102466 0.0376118524900029 -47.5894888482909 0.328307932676326 -141.204960194079 + 0.0589466825299184 -113.54806326753 0.311197978602533 125.569918668102 + 0.314423213176933 -15.3935888102466 0.186102779108008 167.720634757687 0.30288237706047 -124.551697273635 0.178697161683669 -151.99688522634 + 0.386723092719038 170.110772604607 0.180212033021946 135.76078926431 + 0.0376118524900029 -47.5894888482909 0.30288237706047 -124.551697273635 0.250778433918077 -99.6674756006628 0.271370916029083 69.6563372109511 + 0.0552160376538023 95.740827793937 0.352919251419837 -116.297113971452 + 0.328307932676326 -141.204960194079 0.178697161683669 -151.99688522634 0.271370916029083 69.6563372109511 0.183010139368101 81.0368314696672 + 0.394067397234361 -115.72669122027 0.213798827728987 155.652823835038 + 0.0589466825299184 -113.54806326753 0.386723092719038 170.110772604607 0.0552160376538023 95.740827793937 0.394067397234361 -115.72669122027 + 0.229617412184491 -80.5877378296577 0.311255802902431 -13.9873867145223 + 0.311197978602533 125.569918668102 0.180212033021946 135.76078926431 0.352919251419837 -116.297113971452 0.213798827728987 155.652823835038 + 0.311255802902431 -13.9873867145223 0.124357040108039 124.423175687079 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.8 0.111119286176556 -70.2007028165124 0.294487210399448 -30.8070424287754 0.040841994186211 -14.989974037338 0.335890319435353 -157.850425981381 + 0.0475236194647842 -132.175552435455 0.334946952610156 112.549622662274 + 0.294487210399448 -30.8070424287754 0.183436523684541 160.323228522276 0.312441659374625 -139.231103425056 0.173474556935865 -154.800131336756 + 0.394791586574258 156.819223790781 0.149469145548446 130.984941222474 + 0.040841994186211 -14.989974037338 0.312441659374625 -139.231103425056 0.202165006327728 -103.95477042025 0.268969919162834 61.7639743588499 + 0.0881429790600114 73.3904777495964 0.36182197174745 -132.551558626027 + 0.335890319435353 -157.850425981381 0.173474556935865 -154.800131336756 0.268969919162834 61.7639743588499 0.171836941198036 68.0984321245666 + 0.394239041398371 -129.590982873377 0.20907494892054 145.712876190517 + 0.0475236194647842 -132.175552435455 0.394791586574258 156.819223790781 0.0881429790600114 73.3904777495964 0.394239041398371 -129.590982873377 + 0.214148790425756 -83.6319838580264 0.293709832944199 -27.6404264155831 + 0.334946952610156 112.549622662274 0.149469145548446 130.984941222474 0.36182197174745 -132.551558626027 0.20907494892054 145.712876190517 + 0.293709832944199 -27.6404264155831 0.116100726561231 105.642440795125 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.85 0.138369513188761 -53.9629532160183 0.273891276727604 -44.8332653266276 0.0684313673112657 -9.3464361055024 0.336829193905467 -174.196471438416 + 0.0379061499012057 -145.435728301216 0.355478002998549 98.5492466650921 + 0.273891276727604 -44.8332653266276 0.177056435544391 151.78286626089 0.317170980114193 -153.559042593038 0.166588797317151 -156.794347171372 + 0.397886051828011 143.374807806612 0.113542332223461 130.4611891566 + 0.0684313673112657 -9.3464361055024 0.317170980114193 -153.559042593038 0.158342157925199 -99.4935690131476 0.272644942637518 52.9540689182951 + 0.120169492678138 54.4287173755322 0.368043898620306 -148.705386200741 + 0.336829193905467 -174.196471438416 0.166588797317151 -156.794347171372 0.272644942637518 52.9540689182951 0.155468926827369 53.5324572290119 + 0.394433511925797 -143.030914361049 0.19444142419032 137.904908644564 + 0.0379061499012057 -145.435728301216 0.397886051828011 143.374807806612 0.120169492678138 54.4287173755322 0.394433511925797 -143.030914361049 + 0.196215213951077 -84.236868189005 0.276857139017186 -40.7923687328557 + 0.355478002998549 98.5492466650921 0.113542332223461 130.4611891566 0.368043898620306 -148.705386200741 0.19444142419032 137.904908644564 + 0.276857139017186 -40.7923687328557 0.0977645302179933 88.9198098774386 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.9 0.182518177108396 -54.4343886089387 0.258815129233659 -57.8325319157015 0.0938994641442342 -23.619449928601 0.333629281663926 170.550663437208 + 0.0348188975800874 -150.676553351279 0.369368691190031 83.9964401189935 + 0.258815129233659 -57.8325319157015 0.171246049113848 143.843133508283 0.321609101035503 -166.883086748333 0.168131193429626 -158.30243139074 + 0.397189227741223 130.726155408957 0.0888712267090649 146.191517739794 + 0.0938994641442342 -23.619449928601 0.321609101035503 -166.883086748333 0.147865681122952 -86.3665776601739 0.277507469740719 43.0213262807049 + 0.145954503109948 34.8768861736174 0.370075253940519 -164.568573158703 + 0.333629281663926 170.550663437208 0.168131193429626 -158.30243139074 0.277507469740719 43.0213262807049 0.128345892440407 40.8515256927292 + 0.397659180110494 -156.207865168696 0.185387926644174 134.19387776253 + 0.0348188975800874 -150.676553351279 0.397189227741223 130.726155408957 0.145954503109948 34.8768861736174 0.397659180110494 -156.207865168696 + 0.186253117442572 -81.4133136687372 0.261913500564823 -53.2680167700916 + 0.369368691190031 83.9964401189935 0.0888712267090649 146.191517739794 0.370075253940519 -164.568573158703 0.185387926644174 134.19387776253 + 0.261913500564823 -53.2680167700916 0.0800741296910388 82.5519749718851 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +6.95 0.211965905099429 -61.7872724182803 0.244280274155777 -71.2731993584507 0.102953106465894 -41.606675126072 0.334903706687032 155.74631694007 + 0.0413857279972527 -162.20315727836 0.38062760577072 70.058703989087 + 0.244280274155777 -71.2731993584507 0.168199383958223 133.274867135427 0.334047451248753 179.270638108958 0.173007769891407 -163.445903515012 + 0.404900487881353 118.904771415749 0.10435847477133 164.086881579204 + 0.102953106465894 -41.606675126072 0.334047451248753 179.270638108958 0.165649759285482 -80.9105295940646 0.282883498917723 33.6648691196674 + 0.156213223908826 15.9178845447568 0.370463489351822 179.499690960232 + 0.334903706687032 155.74631694007 0.173007769891407 -163.445903515012 0.282883498917723 33.6648691196674 0.101743619438908 36.026601068862 + 0.403824943671234 -170.23288403407 0.191047783007614 129.352695136093 + 0.0413857279972527 -162.20315727836 0.404900487881353 118.904771415749 0.156213223908826 15.9178845447568 0.403824943671234 -170.23288403407 + 0.188998672871482 -79.7996253514149 0.247372436531425 -64.9433810650787 + 0.38062760577072 70.058703989087 0.10435847477133 164.086881579204 0.370463489351822 179.499690960232 0.191047783007614 129.352695136093 + 0.247372436531425 -64.9433810650787 0.081282123104547 82.5822114258502 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7 0.222469319586575 -70.1281511827795 0.226913243586372 -83.8145177221213 0.0980287483287402 -57.8587988353038 0.33630430688117 140.152871534159 + 0.0488513078095691 175.765867317099 0.395385416828746 55.8167988231271 + 0.226913243586372 -83.8145177221213 0.156381505018266 120.039933196371 0.344145132475168 163.779093690542 0.171270682769502 -170.073338684615 + 0.420378759911351 106.040493605608 0.134167280074883 166.463754529058 + 0.0980287483287402 -57.8587988353038 0.344145132475168 163.779093690542 0.178078506672488 -83.1099652653801 0.297366075183629 24.0436124236841 + 0.153658583135709 -0.334986898900237 0.364608781398998 163.529071958468 + 0.33630430688117 140.152871534159 0.171270682769502 -170.073338684615 0.297366075183629 24.0436124236841 0.0859895689815224 36.8290088466457 + 0.404124914719575 175.152372603555 0.193694764875617 121.163109947743 + 0.0488513078095691 175.765867317099 0.420378759911351 106.040493605608 0.153658583135709 -0.334986898900237 0.404124914719575 175.152372603555 + 0.190355476810742 -80.9430206275231 0.23772878361911 -75.2707784749334 + 0.395385416828746 55.8167988231271 0.134167280074883 166.463754529058 0.364608781398998 163.529071958468 0.193694764875617 121.163109947743 + 0.23772878361911 -75.2707784749334 0.0894596596616982 75.8925719988494 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.05 0.215239966816518 -77.3433087990608 0.211572074499146 -94.5282076716339 0.0830541282778579 -72.2196019047302 0.332608201069124 124.250496405664 + 0.0553913991972117 149.949120456281 0.407493412129787 40.7451720172156 + 0.211572074499146 -94.5282076716339 0.137478530263612 107.87514632601 0.346220947471278 147.78464163546 0.166929444528674 -176.855975932788 + 0.434391239777617 91.9842860695089 0.163813711593803 161.513979821496 + 0.0830541282778579 -72.2196019047302 0.346220947471278 147.78464163546 0.174736928536467 -87.4463057289082 0.317385114439557 12.6220533183314 + 0.142896945641658 -13.5523815792798 0.35340621638813 148.254810837827 + 0.332608201069124 124.250496405664 0.166929444528674 -176.855975932788 0.317385114439557 12.6220533183314 0.0775111165725187 42.1395454809177 + 0.399133564561008 160.844339998086 0.190295969152491 112.7170692621 + 0.0553913991972117 149.949120456281 0.434391239777617 91.9842860695089 0.142896945641658 -13.5523815792798 0.399133564561008 160.844339998086 + 0.183953181648048 -82.5180032231047 0.235559623604763 -85.724722112822 + 0.407493412129787 40.7451720172156 0.163813711593803 161.513979821496 0.35340621638813 148.254810837827 0.190295969152491 112.7170692621 + 0.235559623604763 -85.724722112822 0.097043839274112 68.462379412251 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.1 0.197863119041724 -80.6948421774966 0.203504173759655 -104.281582373816 0.0609143138412174 -80.0444623421703 0.32468302043798 108.882664002159 + 0.060019863880209 122.720377066484 0.413051318980553 25.4891619343489 + 0.203504173759655 -104.281582373816 0.120843819640819 96.7010452398187 0.341671398429289 132.543285608202 0.158420598302483 175.134634431434 + 0.442310066796589 77.6447324349962 0.187074307512813 152.641740766024 + 0.0609143138412174 -80.0444623421703 0.341671398429289 132.543285608202 0.158064770594793 -89.0470754245971 0.334865344677863 -0.391692671571887 + 0.130294534575901 -24.1733333741253 0.341455727457097 134.138511658666 + 0.32468302043798 108.882664002159 0.158420598302483 175.134634431434 0.334865344677863 -0.391692671571887 0.080586588191524 49.2866942034734 + 0.393520325584158 147.108949705374 0.182789979337497 104.012433729751 + 0.060019863880209 122.720377066484 0.442310066796589 77.6447324349962 0.130294534575901 -24.1733333741253 0.393520325584158 147.108949705374 + 0.173631391984467 -81.8521935754926 0.237274704440108 -97.1859068048263 + 0.413051318980553 25.4891619343489 0.187074307512813 152.641740766024 0.341455727457097 134.138511658666 0.182789979337497 104.012433729751 + 0.237274704440108 -97.1859068048263 0.107281172668155 60.0763881606766 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.15 0.187615337288652 -80.6348755541905 0.199639823137071 -114.435248809546 0.0449282361598982 -75.6273557552913 0.316318063785867 94.1348756760006 + 0.0613729795925325 96.6191994209657 0.413553675493337 10.6695748242786 + 0.199639823137071 -114.435248809546 0.104836559878288 83.1878056488364 0.337898796707962 117.922617342627 0.142224625552411 167.878403628689 + 0.448062793773711 63.5232202029162 0.200280793371979 142.67502912463 + 0.0449282361598982 -75.6273557552913 0.337898796707962 117.922617342627 0.144231491670405 -84.8480778267126 0.347370445460899 -13.8300198304718 + 0.118156911779882 -34.2425294569807 0.332766406514929 120.638662891475 + 0.316318063785867 94.1348756760006 0.142224625552411 167.878403628689 0.347370445460899 -13.8300198304718 0.0910461648433031 51.6936790378435 + 0.389464151133103 133.47880950028 0.169335969356188 96.0141992292423 + 0.0613729795925325 96.6191994209657 0.448062793773711 63.5232202029162 0.118156911779882 -34.2425294569807 0.389464151133103 133.47880950028 + 0.167174333718896 -78.9107837100277 0.238424756456847 -109.587913116283 + 0.413553675493337 10.6695748242786 0.200280793371979 142.67502912463 0.332766406514929 120.638662891475 0.169335969356188 96.0141992292423 + 0.238424756456847 -109.587913116283 0.116060166170687 50.7021419020133 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.2 0.178784339822231 -82.4891877485694 0.197096340231796 -125.216118014094 0.0334481478888056 -72.9364257447359 0.310693892952018 79.7256896493397 + 0.0624575862726635 75.2791544245098 0.413378804306551 -3.37033633374184 + 0.197096340231796 -125.216118014094 0.0828380180971492 67.7683756884116 0.335893682401965 103.299916796016 0.124646094127459 163.875185577206 + 0.45399826100157 49.4233570683175 0.20657628877328 132.724836337132 + 0.0334481478888056 -72.9364257447359 0.335893682401965 103.299916796016 0.140729669630168 -80.5718903847973 0.356653352504183 -27.0657641794853 + 0.101412256888351 -45.2999053488075 0.327119603131821 107.051620552777 + 0.310693892952018 79.7256896493397 0.124646094127459 163.875185577206 0.356653352504183 -27.0657641794853 0.104010103141416 51.1772472601956 + 0.385400783785237 119.6202111723 0.153717649982532 89.8271563096166 + 0.0624575862726635 75.2791544245098 0.45399826100157 49.4233570683175 0.101412256888351 -45.2999053488075 0.385400783785237 119.6202111723 + 0.166296375315206 -75.3186001881223 0.23761531100124 -122.16002433247 + 0.413378804306551 -3.37033633374184 0.20657628877328 132.724836337132 0.327119603131821 107.051620552777 0.153717649982532 89.8271563096166 + 0.23761531100124 -122.16002433247 0.123480611453206 41.6206545561475 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.25 0.156858558945172 -78.9330074632546 0.193731652117262 -135.24569404429 0.0203660654075987 -19.4884879855698 0.304136575941341 64.5168289675376 + 0.0702875714944244 53.7487221363055 0.416469254306338 -17.484300318056 + 0.193731652117262 -135.24569404429 0.056289709690635 54.8341466202669 0.332320579447266 87.9451752493954 0.111754984478705 162.775621512504 + 0.459425477196409 34.9693483358715 0.207543814473049 122.662643766024 + 0.0203660654075987 -19.4884879855698 0.332320579447266 87.9451752493954 0.130997804234707 -73.565874096888 0.369000001797198 -40.3696468605342 + 0.0793130792140075 -52.0384584724421 0.318082513015548 93.2809317798144 + 0.304136575941341 64.5168289675376 0.111754984478705 162.775621512504 0.369000001797198 -40.3696468605342 0.119734093096722 48.7734538649113 + 0.37715345500032 105.704448727856 0.13889586173503 85.8764045616877 + 0.0702875714944244 53.7487221363055 0.459425477196409 34.9693483358715 0.0793130792140075 -52.0384584724421 0.37715345500032 105.704448727856 + 0.170974613961682 -71.1733396259606 0.238451955530972 -134.358741309126 + 0.416469254306338 -17.484300318056 0.207543814473049 122.662643766024 0.318082513015548 93.2809317798144 0.13889586173503 85.8764045616877 + 0.238451955530972 -134.358741309126 0.129346788572751 33.2568290887467 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.3 0.164241723484408 -69.7405709945627 0.197467520624314 -144.726132671576 0.0536094853573361 -1.25384697023408 0.29209156590224 49.8987641735737 + 0.0782059661824379 26.3672991229947 0.416674065371879 -31.576980643756 + 0.197467520624314 -144.726132671576 0.0301019718693349 54.8173626918652 0.321738114729379 72.7381297329341 0.105266407401946 162.438205952889 + 0.460034488684781 20.356946109091 0.204192795645366 112.317061609854 + 0.0536094853573361 -1.25384697023408 0.321738114729379 72.7381297329341 0.14684063108095 -60.5045046949955 0.378801827521859 -54.7564901420319 + 0.0650229640067875 -53.2222912446765 0.30880332589422 80.6472397834283 + 0.29209156590224 49.8987641735737 0.105266407401946 162.438205952889 0.378801827521859 -54.7564901420319 0.139461924590954 44.6223495329882 + 0.367028774302436 92.597123732613 0.128245258111701 83.4993469357104 + 0.0782059661824379 26.3672991229947 0.460034488684781 20.356946109091 0.0650229640067875 -53.2222912446765 0.367028774302436 92.597123732613 + 0.185878413308625 -68.5713879573968 0.242047579274169 -147.400445373429 + 0.416674065371879 -31.576980643756 0.204192795645366 112.317061609854 0.30880332589422 80.6472397834283 0.128245258111701 83.4993469357104 + 0.242047579274169 -147.400445373429 0.135736096742557 25.2769642754624 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.35 0.184368248441292 -68.4654720731463 0.207162772998173 -155.830157924841 0.0800317415904841 -16.2415544939421 0.280299255938886 36.2728756026452 + 0.0810795496281793 -2.46488808934796 0.417233540531727 -45.4347045363983 + 0.207162772998173 -155.830157924841 0.0218308503296846 103.134668805995 0.308149741321846 58.6013700947063 0.10217140314861 159.832202613565 + 0.456737348177553 6.11029445529588 0.197052432008874 101.142091108101 + 0.0800317415904841 -16.2415544939421 0.308149741321846 58.6013700947063 0.186650271299857 -58.5452258673274 0.380877231978344 -69.3524550251789 + 0.0550394073660545 -57.9191585646004 0.303873693669546 68.6116237161522 + 0.280299255938886 36.2728756026452 0.10217140314861 159.832202613565 0.380877231978344 -69.3524550251789 0.163034937015076 38.0858006771378 + 0.36014025105292 80.1514010828726 0.121500500881521 81.2538184953882 + 0.0810795496281793 -2.46488808934796 0.456737348177553 6.11029445529588 0.0550394073660545 -57.9191585646004 0.36014025105292 80.1514010828726 + 0.203672102820468 -69.6820849255915 0.244354597012217 -161.551387236177 + 0.417233540531727 -45.4347045363983 0.197052432008874 101.142091108101 0.303873693669546 68.6116237161522 0.121500500881521 81.2538184953882 + 0.244354597012217 -161.551387236177 0.141765042909816 17.1035672212666 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.4 0.198006890029045 -70.9539532218598 0.216796810911944 -169.518734654928 0.0930606465190491 -31.4943826160625 0.272630416400159 23.6702296029626 + 0.080022066365936 -30.590606520483 0.416889782559111 -58.9257190230551 + 0.216796810911944 -169.518734654928 0.0386683987140011 119.552238527987 0.297768515184071 45.7071856547789 0.0939544091382023 156.135807762498 + 0.453240392422857 -7.57647161290012 0.180736235001708 88.3267274185422 + 0.0930606465190491 -31.4943826160625 0.297768515184071 45.7071856547789 0.220424826796229 -64.274689820048 0.375308469688735 -83.2459916515931 + 0.0406853709426723 -67.7917275868323 0.305642377153536 56.5366059514458 + 0.272630416400159 23.6702296029626 0.0939544091382023 156.135807762498 0.375308469688735 -83.2459916515931 0.18595715924049 28.2246252054832 + 0.358295795991284 67.6605731735568 0.113186652834565 77.9835853880015 + 0.080022066365936 -30.590606520483 0.453240392422857 -7.57647161290012 0.0406853709426723 -67.7917275868323 0.358295795991284 67.6605731735568 + 0.21598641921214 -73.1368261251984 0.2414378205669 -176.373379188088 + 0.416889782559111 -58.9257190230551 0.180736235001708 88.3267274185422 0.305642377153536 56.5366059514458 0.113186652834565 77.9835853880015 + 0.2414378205669 -176.373379188088 0.145411584310604 7.70490697960442 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.45 0.202924532350338 -73.3116212028855 0.219274061976133 175.967690457243 0.096522596244344 -42.8195798782201 0.270495913585916 10.6545946523429 + 0.077847854148506 -56.9044657680695 0.420568278171701 -72.0992569608309 + 0.219274061976133 175.967690457243 0.0558696495300278 117.110573830905 0.292702851809082 32.6645571391701 0.0870714737201561 157.080986542216 + 0.452305096298737 -21.1190320578847 0.153074742344943 76.6989823423134 + 0.096522596244344 -42.8195798782201 0.292702851809082 32.6645571391701 0.237754069081268 -71.6730502712522 0.369957026395445 -95.8915989103686 + 0.0204422305719027 -78.4284079756233 0.309851481051211 43.3052670970865 + 0.270495913585916 10.6545946523429 0.0870714737201561 157.080986542216 0.369957026395445 -95.8915989103686 0.198275109269247 17.5354386325693 + 0.357432104222335 54.6298843313125 0.103491346799852 78.3472972919692 + 0.077847854148506 -56.9044657680695 0.452305096298737 -21.1190320578847 0.0204422305719027 -78.4284079756233 0.357432104222335 54.6298843313125 + 0.220629917178519 -77.2821785583183 0.233765799218692 169.372388190268 + 0.420568278171701 -72.0992569608309 0.153074742344943 76.6989823423134 0.309851481051211 43.3052670970865 0.103491346799852 78.3472972919692 + 0.233765799218692 169.372388190268 0.140700336588066 -1.07414288023644 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.5 0.209714771078336 -75.4226336022202 0.21830533018129 161.879545257853 0.0989481139511475 -52.6663525818179 0.26931590958732 -2.9491756162365 + 0.0772563343023823 -83.0312963583547 0.427991823877226 -85.4394426076483 + 0.21830533018129 161.879545257853 0.0785125519263948 110.873729874513 0.286893219862942 19.2997827139345 0.0895321721213392 157.184699461167 + 0.451173866646545 -34.7925971703896 0.124072681668272 68.5991058578805 + 0.0989481139511475 -52.6663525818179 0.286893219862942 19.2997827139345 0.244826583926588 -78.8951319568218 0.367762390327886 -108.088446221553 + 0.00191519688380844 83.6482366405582 0.312453234549146 29.3924763488047 + 0.26931590958732 -2.9491756162365 0.0895321721213392 157.184699461167 0.367762390327886 -108.088446221553 0.203737880950189 8.69689982722036 + 0.355666391452549 41.4656881153675 0.103951913256986 81.1620467485728 + 0.0772563343023823 -83.0312963583547 0.451173866646545 -34.7925971703896 0.00191519688380844 83.6482366405582 0.355666391452549 41.4656881153675 + 0.218189749798743 -81.5291662984282 0.224572166560406 155.876200959848 + 0.427991823877226 -85.4394426076483 0.124072681668272 68.5991058578805 0.312453234549146 29.3924763488047 0.103951913256986 81.1620467485728 + 0.224572166560406 155.876200959848 0.133057195136008 -6.04654755162226 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.55 0.21256341940906 -79.1606363888202 0.216242917657442 148.038310847249 0.0954506623398665 -63.2180256182465 0.26739388340378 -16.9668525696723 + 0.0758263714824595 -110.167321117635 0.437379214389344 -99.3843622412467 + 0.216242917657442 148.038310847249 0.10977741559599 98.3679612678126 0.280875167877969 6.44225960896496 0.0925341117561155 150.279841881758 + 0.448471237258629 -48.224461122859 0.101114852819848 62.500673857891 + 0.0954506623398665 -63.2180256182465 0.280875167877969 6.44225960896496 0.238944662254549 -86.4328057378768 0.367579175554167 -120.030293798189 + 0.0286275408239552 80.829593999106 0.312272680366362 15.1428629029841 + 0.26739388340378 -16.9668525696723 0.0925341117561155 150.279841881758 0.367579175554167 -120.030293798189 0.211813343108177 1.2371189022379 + 0.354404250831956 28.2226870574282 0.112492649260616 78.2736432763017 + 0.0758263714824595 -110.167321117635 0.448471237258629 -48.224461122859 0.0286275408239552 80.829593999106 0.354404250831956 28.2226870574282 + 0.206506258255138 -84.9783423694216 0.215001580096797 143.132079527338 + 0.437379214389344 -99.3843622412467 0.101114852819848 62.500673857891 0.312272680366362 15.1428629029841 0.112492649260616 78.2736432763017 + 0.215001580096797 143.132079527338 0.133593609812287 -8.87241883635864 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.6 0.208304287247453 -82.6585608144513 0.212196434463883 134.118777449258 0.0876014223394532 -70.8963255810657 0.265308720115865 -31.0281459867449 + 0.0732136851613714 -135.855696708312 0.444535092728795 -113.633541005027 + 0.212196434463883 134.118777449258 0.140870723198821 80.9602373321443 0.278326730554045 -6.21093757153566 0.0861212935020748 141.223726454521 + 0.447701690454863 -61.3664001701489 0.0774284207775107 55.5241673578709 + 0.0876014223394532 -70.8963255810657 0.278326730554045 -6.21093757153566 0.221008702332877 -91.8323729263666 0.370181789280004 -131.716434298006 + 0.058449024361877 64.7030126066866 0.310212805533376 0.863549868009282 + 0.265308720115865 -31.0281459867449 0.0861212935020748 141.223726454521 0.370181789280004 -131.716434298006 0.221189473640636 -7.60363420759058 + 0.352516109233457 14.6907702358666 0.114062875165334 70.6474963724605 + 0.0732136851613714 -135.855696708312 0.447701690454863 -61.3664001701489 0.058449024361877 64.7030126066866 0.352516109233457 14.6907702358666 + 0.190958893498685 -85.4823549520823 0.206173527451237 131.29094307796 + 0.444535092728795 -113.633541005027 0.0774284207775107 55.5241673578709 0.310212805533376 0.863549868009282 0.114062875165334 70.6474963724605 + 0.206173527451237 131.29094307796 0.137185912465575 -14.9367021673603 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.65 0.20012733387326 -85.2971226341417 0.205838292208363 120.676355494505 0.0796906340949496 -76.6729737685423 0.263676345971404 -45.3193799229333 + 0.0722194379783418 -160.176810400317 0.451107880104368 -127.872523796733 + 0.205838292208363 120.676355494505 0.165783964254227 62.8851554532645 0.27825140881646 -19.1628399632771 0.07513872174422 135.194279001363 + 0.448600873909691 -74.4653454153586 0.0502247075756906 55.09545888403 + 0.0796906340949496 -76.6729737685423 0.27825140881646 -19.1628399632771 0.201148075976398 -94.5826011584868 0.376018073633594 -143.400752455462 + 0.0850712808575363 48.3892471345113 0.307119495469937 -13.444410435905 + 0.263676345971404 -45.3193799229333 0.07513872174422 135.194279001363 0.376018073633594 -143.400752455462 0.22313371185797 -17.4148180427639 + 0.349445496509647 1.14029092925198 0.108777593353688 63.7821255322239 + 0.0722194379783418 -160.176810400317 0.448600873909691 -74.4653454153586 0.0850712808575363 48.3892471345113 0.349445496509647 1.14029092925198 + 0.180017393506376 -83.2215611959727 0.199772623364162 120.021321158976 + 0.451107880104368 -127.872523796733 0.0502247075756906 55.09545888403 0.307119495469937 -13.444410435905 0.108777593353688 63.7821255322239 + 0.199772623364162 120.021321158976 0.133266627264089 -22.1443892537663 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.7 0.190390530855414 -86.9742687915528 0.198226336953524 107.938357004575 0.071826268090485 -80.4389081264577 0.261996567989907 -60.0447655476359 + 0.0717981465775642 175.531941736901 0.458660857064029 -142.297609061022 + 0.198226336953524 107.938357004575 0.182779924612516 45.9118060932386 0.279754921324584 -32.7081651715193 0.0663823704763888 132.14994188478 + 0.451717820500604 -87.5879902912833 0.0338988207197277 79.0633195950395 + 0.071826268090485 -80.4389081264577 0.279754921324584 -32.7081651715193 0.182331206452745 -95.0973533011198 0.385379309686525 -155.177122440275 + 0.10655392375651 33.272483322529 0.302949827527571 -28.0229547353091 + 0.261996567989907 -60.0447655476359 0.0663823704763888 132.14994188478 0.385379309686525 -155.177122440275 0.216882735606753 -26.3971962746983 + 0.346046093012261 -12.5034755677516 0.103975026108312 57.5877077493194 + 0.0717981465775642 175.531941736901 0.451717820500604 -87.5879902912833 0.10655392375651 33.272483322529 0.346046093012261 -12.5034755677516 + 0.17634130049112 -79.8646862414909 0.194548419294073 109.052608015305 + 0.458660857064029 -142.297609061022 0.0338988207197277 79.0633195950395 0.302949827527571 -28.0229547353091 0.103975026108312 57.5877077493194 + 0.194548419294073 109.052608015305 0.126111523489033 -26.7038517196934 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.75 0.179643927078725 -88.2807516799288 0.190842656925819 96.3435364279228 0.0666047133295632 -83.6402209743971 0.258468921505977 -75.1754414514356 + 0.0709762906976403 152.36343796586 0.46487191003868 -157.110749525326 + 0.190842656925819 96.3435364279228 0.192101444922613 31.1873615800201 0.28017591548708 -47.0587093580679 0.0612642248177733 128.473437268063 + 0.456813799649167 -100.954791538005 0.0415884626583563 104.452859137961 + 0.0666047133295632 -83.6402209743971 0.28017591548708 -47.0587093580679 0.168084515941681 -93.322069379287 0.398975477544925 -167.394479534244 + 0.123008705019589 18.5614997364354 0.295189034302984 -42.7735815942198 + 0.258468921505977 -75.1754414514356 0.0612642248177733 128.473437268063 0.398975477544925 -167.394479534244 0.206627553725107 -33.9179232735524 + 0.341134455081822 -26.3389098528075 0.0985958878907989 48.998171042806 + 0.0709762906976403 152.36343796586 0.456813799649167 -100.954791538005 0.123008705019589 18.5614997364354 0.341134455081822 -26.3389098528075 + 0.178837304567322 -76.551572991786 0.191264635100688 98.8763405243717 + 0.46487191003868 -157.110749525326 0.0415884626583563 104.452859137961 0.295189034302984 -42.7735815942198 0.0985958878907989 48.998171042806 + 0.191264635100688 98.8763405243717 0.123232590828389 -30.3987604364164 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.8 0.164503072578064 -88.749654905089 0.18733424181567 85.7024282749766 0.0603405736051828 -89.0634346607461 0.252766465019493 -90.3047947614679 + 0.0707767639376522 130.024178895613 0.467976127263717 -172.015527957698 + 0.18733424181567 85.7024282749766 0.200220124684393 19.643700402038 0.275546382480201 -61.57706524813 0.0559621304821669 118.131782493793 + 0.460785996027523 -114.739414431094 0.0543292594650518 103.931093984183 + 0.0603405736051828 -89.0634346607461 0.275546382480201 -61.57706524813 0.158246152011417 -90.7389568185941 0.413630241826104 179.557071858005 + 0.133309630989885 4.17839591200353 0.284569813852061 -57.0659972908036 + 0.252766465019493 -90.3047947614679 0.0559621304821669 118.131782493793 0.413630241826104 179.557071858005 0.196856730261248 -39.9515352574522 + 0.333710211690165 -39.9994534982629 0.0878507370023308 36.8024971063946 + 0.0707767639376522 130.024178895613 0.460785996027523 -114.739414431094 0.133309630989885 4.17839591200353 0.333710211690165 -39.9994534982629 + 0.186503621841985 -74.1575541484833 0.192680491280466 88.9551286184651 + 0.467976127263717 -172.015527957698 0.0543292594650518 103.931093984183 0.284569813852061 -57.0659972908036 0.0878507370023308 36.8024971063946 + 0.192680491280466 88.9551286184651 0.120882938369851 -36.5598988817355 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.85 0.1469844679881 -86.5637515676628 0.187372268005004 74.1367001367734 0.0520897434023345 -95.1805706994232 0.247359516308409 -105.14425480749 + 0.0697851713699085 108.457869389748 0.469469923284125 173.247361996133 + 0.187372268005004 74.1367001367734 0.215472088012615 8.84666337588156 0.270646056564334 -74.8466551154126 0.0421463973631772 100.449920115973 + 0.461850995842874 -128.282744622392 0.0581046115141064 96.8546056651691 + 0.0520897434023345 -95.1805706994232 0.270646056564334 -74.8466551154126 0.153463558050419 -87.2273830179354 0.424812758936327 166.221541877081 + 0.137826628176942 -10.8922250126307 0.274414510429686 -71.0043081129683 + 0.247359516308409 -105.14425480749 0.0421463973631772 100.449920115973 0.424812758936327 166.221541877081 0.188273301937169 -46.1356502771195 + 0.327024455972604 -53.3625000308056 0.0674562512432457 22.8315780969774 + 0.0697851713699085 108.457869389748 0.461850995842874 -128.282744622392 0.137826628176942 -10.8922250126307 0.327024455972604 -53.3625000308056 + 0.199034319877376 -73.5179406928853 0.197471014576123 78.3134111338273 + 0.469469923284125 173.247361996133 0.0581046115141064 96.8546056651691 0.274414510429686 -71.0043081129683 0.0674562512432457 22.8315780969774 + 0.197471014576123 78.3134111338273 0.109750288778144 -44.2149145745525 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.9 0.129480043281482 -79.3498661720807 0.183583876956607 62.4910899905228 0.0389424648297129 -104.660683564918 0.243538291988846 -120.848013646259 + 0.0695370587079169 88.5218751736351 0.472473921835547 158.477654625719 + 0.183583876956607 62.4910899905228 0.229610344817299 -4.13189424067239 0.272969907041387 -88.5338800116999 0.0209795128936902 80.4910575052926 + 0.466937293489104 -141.60506183038 0.0589275412985572 92.2376966824229 + 0.0389424648297129 -104.660683564918 0.272969907041387 -88.5338800116999 0.150243836004676 -85.5569243323305 0.437840731489094 153.156393121529 + 0.131701682244785 -26.4847945012491 0.262942785731544 -85.3153502333302 + 0.243538291988846 -120.848013646259 0.0209795128936902 80.4910575052926 0.437840731489094 153.156393121529 0.173965675670359 -52.391280473093 + 0.320010262334241 -67.0920263900885 0.0426424376850385 13.1140605342076 + 0.0695370587079169 88.5218751736351 0.466937293489104 -141.60506183038 0.131701682244785 -26.4847945012491 0.320010262334241 -67.0920263900885 + 0.209641326862614 -75.5465039450674 0.203884162937018 67.1895878285743 + 0.472473921835547 158.477654625719 0.0589275412985572 92.2376966824229 0.262942785731544 -85.3153502333302 0.0426424376850385 13.1140605342076 + 0.203884162937018 67.1895878285743 0.0918736997693072 -46.6359538013173 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +7.95 0.126758645853091 -65.1715610694952 0.181924672337165 52.5939719087648 0.0182993584313575 -108.53708067644 0.234188263792244 -137.655571058504 + 0.0706179742556288 68.6147248850678 0.474472455417601 143.113794561577 + 0.181924672337165 52.5939719087648 0.231368955591623 -17.3614620367427 0.273350414447621 -103.818961807009 0.00196571136741618 -5.93063686688572 + 0.474164651169757 -155.504603293332 0.060990690611563 84.404456739352 + 0.0182993584313575 -108.53708067644 0.273350414447621 -103.818961807009 0.140622842937042 -82.5374207288526 0.455372620668841 139.417604720334 + 0.116969138371434 -40.4920502196206 0.245665463104601 -99.3852863305396 + 0.234188263792244 -137.655571058504 0.00196571136741618 -5.93063686688572 0.455372620668841 139.417604720334 0.154802210173479 -55.9253806597047 + 0.308978162495628 -80.7631087643695 0.0215634138892682 12.2944103818044 + 0.0706179742556288 68.6147248850678 0.474164651169757 -155.504603293332 0.116969138371434 -40.4920502196206 0.308978162495628 -80.7631087643695 + 0.212443253610458 -78.1880888135283 0.213359761368715 55.5450433834411 + 0.474472455417601 143.113794561577 0.060990690611563 84.404456739352 0.245665463104601 -99.3852863305396 0.0215634138892682 12.2944103818044 + 0.213359761368715 55.5450433834411 0.0822811947803769 -41.9449522854214 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8 0.149711975263467 -52.0375979101287 0.186670127095506 42.5622190383514 0.012159224979234 8.96493030001727 0.218073042708305 -153.991607662827 + 0.0727871854021272 48.1194062956224 0.46917452478831 127.509067139257 + 0.186670127095506 42.5622190383514 0.223039159145498 -28.9358046604355 0.267695670977245 -119.384991616121 0.0171157656899247 -109.890679806035 + 0.478852098408989 -169.834022076312 0.0597458493452959 71.6542417432403 + 0.012159224979234 8.96493030001727 0.267695670977245 -119.384991616121 0.133388031172069 -74.5615717957893 0.470731538747913 124.711159514966 + 0.0981041825669717 -52.6185986253176 0.225136405469037 -111.655139057394 + 0.218073042708305 -153.991607662827 0.0171157656899247 -109.890679806035 0.470731538747913 124.711159514966 0.138364742317023 -55.1354351876759 + 0.295666287908276 -93.7206133588855 0.00638648451228695 58.5206406641542 + 0.0727871854021272 48.1194062956224 0.478852098408989 -169.834022076312 0.0981041825669717 -52.6185986253176 0.295666287908276 -93.7206133588855 + 0.210493328192082 -80.1182911491936 0.225449930618378 42.7252592850998 + 0.46917452478831 127.509067139257 0.0597458493452959 71.6542417432403 0.225136405469037 -111.655139057394 0.00638648451228695 58.5206406641542 + 0.225449930618378 42.7252592850998 0.0821028388407027 -37.7229332506095 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.05 0.197064686576371 -48.1207550649951 0.194452602532799 31.2602903660709 0.0441828328384523 10.230604605788 0.199211984411545 -169.078968559378 + 0.0754469665999214 26.2407560271516 0.458681938789278 112.384278700483 + 0.194452602532799 31.2602903660709 0.208424003308685 -38.1987396306295 0.25853610851299 -134.464425009207 0.0313818216590431 -120.181691559146 + 0.480112817549748 175.725477303469 0.0551987860392263 54.5575183140919 + 0.0441828328384523 10.230604605788 0.25853610851299 -134.464425009207 0.142722155372243 -63.4020291932719 0.47979506688318 109.51387256642 + 0.0776106077641032 -62.6699586318727 0.207576189537121 -121.730846474508 + 0.199211984411545 -169.078968559378 0.0313818216590431 -120.181691559146 0.47979506688318 109.51387256642 0.132649610255232 -50.1295395464426 + 0.282824448314299 -105.777476845629 0.0136108889081156 131.728749451859 + 0.0754469665999214 26.2407560271516 0.480112817549748 175.725477303469 0.0776106077641032 -62.6699586318727 0.282824448314299 -105.777476845629 + 0.206203347536916 -81.1619468225439 0.237735282450721 28.6072989238652 + 0.458681938789278 112.384278700483 0.0551987860392263 54.5575183140919 0.207576189537121 -121.730846474508 0.0136108889081156 131.728749451859 + 0.237735282450721 28.6072989238652 0.0888290949777648 -36.2845054588011 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.1 0.247662870765598 -52.754408218742 0.203026327679522 18.9694491967621 0.0750765850034755 -5.48374548796346 0.179816228637873 177.376379610498 + 0.0780377830390161 3.32518923095213 0.445720290809451 97.7078345162272 + 0.203026327679522 18.9694491967621 0.192631372028115 -44.6135741355461 0.248618861636452 -148.985773920478 0.0444304363143926 -125.436360155859 + 0.478580591714629 161.417141850376 0.0482076385765773 30.0010095090286 + 0.0750765850034755 -5.48374548796346 0.248618861636452 -148.985773920478 0.17210416680691 -57.1861849640125 0.481984392768371 94.2547486952663 + 0.0569521696242671 -70.3012805846021 0.195901524699361 -129.925514429933 + 0.179816228637873 177.376379610498 0.0444304363143926 -125.436360155859 0.481984392768371 94.2547486952663 0.143670611833222 -46.1113391591283 + 0.272795737139057 -117.039559444651 0.0211039195571427 147.401367749637 + 0.0780377830390161 3.32518923095213 0.478580591714629 161.417141850376 0.0569521696242671 -70.3012805846021 0.272795737139057 -117.039559444651 + 0.20151354824809 -81.2287635171714 0.248197671605023 13.3809197040407 + 0.445720290809451 97.7078345162272 0.0482076385765773 30.0010095090286 0.195901524699361 -129.925514429933 0.0211039195571427 147.401367749637 + 0.248197671605023 13.3809197040407 0.0993393285689065 -42.8412487363419 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.15 0.288018537733935 -60.8950641656704 0.211778361391173 5.53755652819251 0.101475802683676 -22.2322277203218 0.162787513814447 166.270796588309 + 0.0811622323090448 -20.8263048851547 0.42998432146464 83.8068151940922 + 0.211778361391173 5.53755652819251 0.179728613562847 -48.8698269858332 0.238762481979647 -163.075848589239 0.0595277502047562 -129.94747519656 + 0.475874958162732 147.304463070894 0.0415814294203854 -6.8772413283442 + 0.101475802683676 -22.2322277203218 0.238762481979647 -163.075848589239 0.210079727720774 -57.4692247669501 0.477125050627357 79.2262880118114 + 0.0374332367657132 -72.0402826309346 0.194294702678245 -137.008743763726 + 0.162787513814447 166.270796588309 0.0595277502047562 -129.94747519656 0.477125050627357 79.2262880118114 0.163680276680642 -48.0044523743977 + 0.267007321535685 -127.841442298689 0.0335787602607972 163.137420115097 + 0.0811622323090448 -20.8263048851547 0.475874958162732 147.304463070894 0.0374332367657132 -72.0402826309346 0.267007321535685 -127.841442298689 + 0.198029557164836 -80.2277460953159 0.254471139939741 -2.75498451000847 + 0.42998432146464 83.8068151940922 0.0415814294203854 -6.8772413283442 0.194294702678245 -137.008743763726 0.0335787602607972 163.137420115097 + 0.254471139939741 -2.75498451000847 0.100795256885646 -56.7213706311859 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.2 0.312165898471602 -70.6224881715524 0.216266961662792 -8.7578395748172 0.119663888479683 -39.4819237424665 0.154721211794476 156.673435470475 + 0.0836128616915695 -46.5686558734626 0.418598961397613 71.1353865747388 + 0.216266961662792 -8.7578395748172 0.166801152561175 -51.9234345213402 0.231142623266604 -176.838936347132 0.0770377064453056 -138.752247602092 + 0.473482483942162 133.412641439374 0.0402296230864455 -53.3161265190533 + 0.119663888479683 -39.4819237424665 0.231142623266604 -176.838936347132 0.246494840192057 -62.5661767612958 0.467389086804711 65.0891546852357 + 0.0222292069530139 -62.2097621484402 0.202327504026571 -146.080085956701 + 0.154721211794476 156.673435470475 0.0770377064453056 -138.752247602092 0.467389086804711 65.0891546852357 0.178046545966217 -54.1779151783945 + 0.265861169708115 -139.008192761103 0.0556689644398125 160.7493918105 + 0.0836128616915695 -46.5686558734626 0.473482483942162 133.412641439374 0.0222292069530139 -62.2097621484402 0.265861169708115 -139.008192761103 + 0.198362607833682 -78.7502247065007 0.253846199615128 -18.9378453037568 + 0.418598961397613 71.1353865747388 0.0402296230864455 -53.3161265190533 0.202327504026571 -146.080085956701 0.0556689644398125 160.7493918105 + 0.253846199615128 -18.9378453037568 0.0872395022051197 -71.5990447201933 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.25 0.317077410023615 -80.1691836176157 0.216768755307116 -22.2006999647107 0.127614682853643 -55.0688287797449 0.151977786738401 145.089508455406 + 0.0842467596535001 -72.1554572686993 0.417132581161707 58.4786009062112 + 0.216768755307116 -22.2006999647107 0.152619603732709 -50.6582300976091 0.224717633456494 168.553482552744 0.0873552280683323 -150.097837819975 + 0.473034145169471 119.38012409042 0.0474144964161592 -89.5572837966725 + 0.127614682853643 -55.0688287797449 0.224717633456494 168.553482552744 0.270767004403384 -69.7921907691507 0.461459956669978 51.7698071545147 + 0.0142140358585749 -18.468030817229 0.208400922277837 -157.48879519346 + 0.151977786738401 145.089508455406 0.0873552280683323 -150.097837819975 0.461459956669978 51.7698071545147 0.187063481629996 -59.8843269430764 + 0.264009207309978 -150.930141544708 0.071504338155463 149.562635580991 + 0.0842467596535001 -72.1554572686993 0.473034145169471 119.38012409042 0.0142140358585749 -18.468030817229 0.264009207309978 -150.930141544708 + 0.201206745122161 -77.3602086531257 0.250072796930334 -34.03566350992 + 0.417132581161707 58.4786009062112 0.0474144964161592 -89.5572837966725 0.208400922277837 -157.48879519346 0.071504338155463 149.562635580991 + 0.250072796930334 -34.03566350992 0.0712812609320448 -81.5811747261626 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.3 0.308758874564333 -88.5170010791773 0.220236275673201 -34.5574314708791 0.130687057510894 -68.4396751142345 0.145788777923526 132.013849196733 + 0.085597332303202 -96.1379604714207 0.418586044500188 44.9127893433326 + 0.220236275673201 -34.5574314708791 0.155169751488986 -43.940661043849 0.21337027305915 153.247908247895 0.0886938708535264 -156.220610840678 + 0.470332761834482 104.889248904292 0.0633452954130982 -110.581721814971 + 0.130687057510894 -68.4396751142345 0.21337027305915 153.247908247895 0.283858305826351 -77.0316204043694 0.459562808647812 38.2400973627562 + 0.0244324488921284 17.606447316342 0.211155719151059 -168.520318117752 + 0.145788777923526 132.013849196733 0.0886938708535264 -156.220610840678 0.459562808647812 38.2400973627562 0.201951175267429 -66.2789833271089 + 0.259961207609442 -162.331647619525 0.0769771258000808 143.909745726233 + 0.085597332303202 -96.1379604714207 0.470332761834482 104.889248904292 0.0244324488921284 17.606447316342 0.259961207609442 -162.331647619525 + 0.207706052946126 -76.041450559276 0.248822228304002 -48.7967460592516 + 0.418586044500188 44.9127893433326 0.0633452954130982 -110.581721814971 0.211155719151059 -168.520318117752 0.0769771258000808 143.909745726233 + 0.248822228304002 -48.7967460592516 0.0626124602939603 -94.0750876591144 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.35 0.294429348492668 -96.0271611447027 0.229495448171116 -47.8315624885875 0.132114294111177 -81.755296480072 0.135898599532874 120.50999132334 + 0.089517511227854 -119.748469359913 0.416184733641821 30.8415258833615 + 0.229495448171116 -47.8315624885875 0.182493636599998 -41.6924440231142 0.196557278763249 139.172555155357 0.0959460240022391 -155.315924184512 + 0.461215525682959 90.4849424932086 0.0896982649211356 -127.742304960025 + 0.132114294111177 -81.755296480072 0.196557278763249 139.172555155357 0.289152458447896 -84.5269175227039 0.454668290523416 24.4441563037432 + 0.037057316704516 18.0835882490593 0.218149288695132 -179.196849771918 + 0.135898599532874 120.50999132334 0.0959460240022391 -155.315924184512 0.454668290523416 24.4441563037432 0.218158329466394 -76.6700220965002 + 0.260163490783619 -172.998089264468 0.0854002722805603 145.794975085919 + 0.089517511227854 -119.748469359913 0.461215525682959 90.4849424932086 0.037057316704516 18.0835882490593 0.260163490783619 -172.998089264468 + 0.218475084222521 -75.8989905027533 0.246496135162632 -64.3134434526626 + 0.416184733641821 30.8415258833615 0.0896982649211356 -127.742304960025 0.218149288695132 -179.196849771918 0.0854002722805603 145.794975085919 + 0.246496135162632 -64.3134434526626 0.0564303110262617 -118.258460989875 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.4 0.273084111902059 -103.677281560563 0.236784019187123 -62.8143749050958 0.129306010054319 -96.102751821852 0.13033847147781 111.178008971637 + 0.0943172264028882 -143.668025147681 0.411324842009891 17.0985506413544 + 0.236784019187123 -62.8143749050958 0.211890336768753 -46.2811520335103 0.181951096841922 127.296670074351 0.115029868473207 -158.15948762248 + 0.449586047370429 76.8856338065846 0.118628703154166 -146.504737500578 + 0.129306010054319 -96.102751821852 0.181951096841922 127.296670074351 0.283486528731463 -92.2999147666554 0.447000345586095 11.1866359703152 + 0.046146413301147 13.3895787371519 0.228226162459843 168.687385961499 + 0.13033847147781 111.178008971637 0.115029868473207 -158.15948762248 0.447000345586095 11.1866359703152 0.222123279457892 -90.0667086646179 + 0.265495828855284 175.596776802612 0.104048983846388 145.318200757302 + 0.0943172264028882 -143.668025147681 0.449586047370429 76.8856338065846 0.046146413301147 13.3895787371519 0.265495828855284 175.596776802612 + 0.22919623984394 -77.3571798739539 0.239405088281121 -79.6711064662157 + 0.411324842009891 17.0985506413544 0.118628703154166 -146.504737500578 0.228226162459843 168.687385961499 0.104048983846388 145.318200757302 + 0.239405088281121 -79.6711064662157 0.0531470774523868 -154.899869816794 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.45 0.242606084636102 -111.293745293748 0.238788750562235 -77.9883263974268 0.122708061160421 -111.251673009664 0.129474435959341 101.282312399155 + 0.0995593272815554 -167.121913586884 0.407591422326981 3.40540621142513 + 0.238788750562235 -77.9883263974268 0.235035632433949 -52.9000716771021 0.172676381839004 115.942476885864 0.133241034693391 -165.526698815255 + 0.441364113183818 63.8209456222811 0.142262610272768 -164.144202979064 + 0.122708061160421 -111.251673009664 0.172676381839004 115.942476885864 0.267771703124181 -99.7272608068341 0.442390814424177 -1.58989988216217 + 0.051948471474661 7.23805676168481 0.235444473227502 155.649104488381 + 0.129474435959341 101.282312399155 0.133241034693391 -165.526698815255 0.442390814424177 -1.58989988216217 0.213749724620049 -103.962522608781 + 0.270376158149123 163.205664234445 0.123324146889362 140.829919532767 + 0.0995593272815554 -167.121913586884 0.441364113183818 63.8209456222811 0.051948471474661 7.23805676168481 0.270376158149123 163.205664234445 + 0.236715295130917 -79.9977379922889 0.231281156807495 -94.0535175193365 + 0.407591422326981 3.40540621142513 0.142262610272768 -164.144202979064 0.235444473227502 155.649104488381 0.123324146889362 140.829919532767 + 0.231281156807495 -94.0535175193365 0.0605486606587104 166.962307132779 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.5 0.201691313945647 -118.87863906831 0.239194769846842 -92.75765492226 0.112969781503536 -128.580212145204 0.129998263571718 90.6756277278078 + 0.105563899291344 169.559722556159 0.402294460698447 -10.396916211628 + 0.239194769846842 -92.75765492226 0.25382179125921 -60.7333950373382 0.164352559762549 104.360787842232 0.148186831737898 -173.818940519166 + 0.435095185498978 50.7437420860492 0.161041034143905 -179.938645462667 + 0.112969781503536 -128.580212145204 0.164352559762549 104.360787842232 0.242953885584666 -106.871762290458 0.44072350179597 -14.4777179096708 + 0.0539406593980844 1.63512678756243 0.240963182086472 142.773795780437 + 0.129998263571718 90.6756277278078 0.148186831737898 -173.818940519166 0.44072350179597 -14.4777179096708 0.198098735243066 -118.412010291906 + 0.273463491862553 150.627176783447 0.141169540188102 135.613750167662 + 0.105563899291344 169.559722556159 0.435095185498978 50.7437420860492 0.0539406593980844 1.63512678756243 0.273463491862553 150.627176783447 + 0.238911879097015 -83.1812123457033 0.225252651262976 -107.996721050491 + 0.402294460698447 -10.396916211628 0.161041034143905 -179.938645462667 0.240963182086472 142.773795780437 0.141169540188102 135.613750167662 + 0.225252651262976 -107.996721050491 0.08026626565167 137.752725452828 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.55 0.147916779836023 -125.267789537054 0.239193501765669 -107.718950423439 0.0997449851321807 -149.825998736741 0.132412567357082 79.6334069092511 + 0.112128153657602 146.09868512391 0.394968290348359 -23.9259054405658 + 0.239193501765669 -107.718950423439 0.264385727675304 -69.4874649992106 0.156436135057266 93.6674295990419 0.1601732425804 177.051150319744 + 0.428665238898863 37.851600006791 0.174940042537098 165.091924151854 + 0.0997449851321807 -149.825998736741 0.156436135057266 93.6674295990419 0.207935362343118 -113.579830566749 0.438899534409105 -27.545722553951 + 0.052423960414101 -1.32030618931771 0.247768698551878 129.929675628654 + 0.132412567357082 79.6334069092511 0.1601732425804 177.051150319744 0.438899534409105 -27.545722553951 0.175639416765263 -133.929879880212 + 0.276812880507714 138.050941274879 0.158064904518067 129.880352379404 + 0.112128153657602 146.09868512391 0.428665238898863 37.851600006791 0.052423960414101 -1.32030618931771 0.276812880507714 138.050941274879 + 0.235030993639053 -86.4826089623374 0.220558475925643 -122.178538947037 + 0.394968290348359 -23.9259054405658 0.174940042537098 165.091924151854 0.247768698551878 129.929675628654 0.158064904518067 129.880352379404 + 0.220558475925643 -122.178538947037 0.107031059563521 116.38602486412 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.6 0.0818100505986298 -123.545864977884 0.236298041723306 -122.99673637467 0.083506272649298 -178.295482597669 0.137092150493231 67.482007631393 + 0.119249083623734 121.676408202758 0.387453379167093 -36.9465253056856 + 0.236298041723306 -122.99673637467 0.265129025641927 -78.0550736192312 0.152375358082073 83.8217379451561 0.166107775812177 167.338302497621 + 0.424368022036672 25.3051572527198 0.181651481038733 150.559165159188 + 0.083506272649298 -178.295482597669 0.152375358082073 83.8217379451561 0.159918533249027 -118.538442281457 0.436155591817626 -40.5307116413298 + 0.05096476735086 2.38483269432875 0.256431452733875 116.519251416513 + 0.137092150493231 67.482007631393 0.166107775812177 167.338302497621 0.436155591817626 -40.5307116413298 0.147545139814942 -150.553197989958 + 0.280929724899327 125.149576802315 0.172963082934397 123.929960577562 + 0.119249083623734 121.676408202758 0.424368022036672 25.3051572527198 0.05096476735086 2.38483269432875 0.280929724899327 125.149576802315 + 0.223429648757599 -89.0034581786777 0.214912223865748 -136.794052560734 + 0.387453379167093 -36.9465253056856 0.181651481038733 150.559165159188 0.256431452733875 116.519251416513 0.172963082934397 123.929960577562 + 0.214912223865748 -136.794052560734 0.136695201308265 99.6851913323014 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.65 0.0449858658427712 -56.5080477275273 0.229873914095223 -137.932328614028 0.0677303873191462 141.664857445187 0.141879482591878 53.5762928439803 + 0.124633424110693 95.5359207073116 0.382383870389855 -49.5372677246362 + 0.229873914095223 -137.932328614028 0.259178755660773 -85.7801782833247 0.152298329347122 73.5230468687683 0.164501112294232 158.480968350728 + 0.423423059397731 12.7861252844991 0.179867475882862 137.039051428784 + 0.0677303873191462 141.664857445187 0.152298329347122 73.5230468687683 0.102088680237278 -113.440289852881 0.434120848620675 -53.3663802719922 + 0.0582448262849558 7.96207045048655 0.264512442802793 102.187647966736 + 0.141879482591878 53.5762928439803 0.164501112294232 158.480968350728 0.434120848620675 -53.3663802719922 0.117210877529713 -168.613679063589 + 0.284232144702089 111.867773122874 0.185753156727688 118.300603771574 + 0.124633424110693 95.5359207073116 0.423423059397731 12.7861252844991 0.0582448262849558 7.96207045048655 0.284232144702089 111.867773122874 + 0.208243989186006 -88.8995894039871 0.206954342418711 -151.41588435113 + 0.382383870389855 -49.5372677246362 0.179867475882862 137.039051428784 0.264512442802793 102.187647966736 0.185753156727688 118.300603771574 + 0.206954342418711 -151.41588435113 0.166395886123098 85.6151127566269 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.7 0.119023253815316 -24.1507811863263 0.22129955697246 -152.099099003037 0.0637331656221303 90.4790093795584 0.144432426943667 38.3792144846452 + 0.126126363312347 68.1053826788176 0.380691443612834 -61.9726067143557 + 0.22129955697246 -152.099099003037 0.248319681240503 -92.9380515261412 0.154451660838509 62.1362227526454 0.158662488158129 151.22290543787 + 0.424921379524729 0.0562732961713667 0.171733864573563 124.583845241731 + 0.0637331656221303 90.4790093795584 0.154451660838509 62.1362227526454 0.0742739261278316 -73.8367923865674 0.433358109944548 -66.1804597020907 + 0.0726551067237218 4.77581956132801 0.269385309698947 87.1637938689427 + 0.144432426943667 38.3792144846452 0.158662488158129 151.22290543787 0.433358109944548 -66.1804597020907 0.0879110635501034 169.8109958187 + 0.286155793415327 98.3830242578955 0.198072572569192 112.818287941949 + 0.126126363312347 68.1053826788176 0.424921379524729 0.0562732961713667 0.0726551067237218 4.77581956132801 0.286155793415327 98.3830242578955 + 0.198918989458855 -85.9033310163411 0.197103693673339 -165.571310991883 + 0.380691443612834 -61.9726067143557 0.171733864573563 124.583845241731 0.269385309698947 87.1637938689427 0.198072572569192 112.818287941949 + 0.197103693673339 -165.571310991883 0.19432774121364 73.0635693707835 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.75 0.205143403164329 -31.0453563192418 0.213681338808248 -165.276419351821 0.0745153798780958 43.7062526190705 0.143100510381171 22.7918592593991 + 0.122343729731316 39.9789116108599 0.381890376280463 -74.6615394099321 + 0.213681338808248 -165.276419351821 0.231509173508359 -99.0973367311737 0.156001995914018 49.5451985895673 0.14948509865043 145.564625343549 + 0.427523988587366 -13.0199171088685 0.156233932804632 113.122295961447 + 0.0745153798780958 43.7062526190705 0.156001995914018 49.5451985895673 0.123815274003206 -45.2712634956488 0.433474476215479 -79.175181220619 + 0.0848925907910011 -6.88050467725891 0.269234965756817 72.0133840162007 + 0.143100510381171 22.7918592593991 0.14948509865043 145.564625343549 0.433474476215479 -79.175181220619 0.0612299208149893 141.193727635572 + 0.286574316853123 84.8982560177242 0.208009543137409 107.45187397314 + 0.122343729731316 39.9789116108599 0.427523988587366 -13.0199171088685 0.0848925907910011 -6.88050467725891 0.286574316853123 84.8982560177242 + 0.20121213969605 -82.4025165717112 0.187255380239655 -178.839830592959 + 0.381890376280463 -74.6615394099321 0.156233932804632 113.122295961447 0.269234965756817 72.0133840162007 0.208009543137409 107.45187397314 + 0.187255380239655 -178.839830592959 0.216284067411422 61.7437815360443 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.8 0.276115356067333 -42.5692831231584 0.208114509623145 -178.34826788896 0.0902146421247379 10.3664641442501 0.139998291835362 8.03338952413179 + 0.114891536577513 12.4783339840001 0.382902303472156 -87.495952079017 + 0.208114509623145 -178.34826788896 0.209919933307752 -102.771994641302 0.155949936374264 36.7288664492125 0.137444033485165 142.416056027308 + 0.42958162717014 -26.3905338506862 0.13421372415028 104.202691330461 + 0.0902146421247379 10.3664641442501 0.155949936374264 36.7288664492125 0.189952079962954 -45.6736180137951 0.4320185930617 -92.3226329656003 + 0.0876066972604098 -21.540209829769 0.266235508970248 57.3179922594703 + 0.139998291835362 8.03338952413179 0.137444033485165 142.416056027308 0.4320185930617 -92.3226329656003 0.0428442185016336 100.489732864264 + 0.28647365189058 71.4670748632675 0.217872927662506 102.868255531923 + 0.114891536577513 12.4783339840001 0.42958162717014 -26.3905338506862 0.0876066972604098 -21.540209829769 0.28647365189058 71.4670748632675 + 0.208992716291597 -80.9623006139018 0.17880986389651 168.358582590167 + 0.382902303472156 -87.495952079017 0.13421372415028 104.202691330461 0.266235508970248 57.3179922594703 0.217872927662506 102.868255531923 + 0.17880986389651 168.358582590167 0.23367983282644 52.5978222659243 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.85 0.32807591341313 -54.5389476609942 0.201531080879826 168.636549651179 0.103795524121605 -13.6718438781098 0.137597116759791 -6.68418756328558 + 0.106534713355623 -13.9551787878751 0.385596095550915 -100.267928758224 + 0.201531080879826 168.636549651179 0.195197420389696 -102.3204992563 0.155582936547438 24.1438493602623 0.127132089775846 144.306098159239 + 0.429341537763322 -40.0137087069294 0.11163137613422 100.17567307269 + 0.103795524121605 -13.6718438781098 0.155582936547438 24.1438493602623 0.246681129607422 -52.7452009023088 0.428875617696571 -105.344340818547 + 0.0825526182088234 -35.8023680278981 0.261333151487602 42.9266088766573 + 0.137597116759791 -6.68418756328558 0.127132089775846 144.306098159239 0.428875617696571 -105.344340818547 0.0383372051391134 52.8062217953015 + 0.285872927054629 58.1268450950999 0.231058069722909 98.1408092339455 + 0.106534713355623 -13.9551787878751 0.429341537763322 -40.0137087069294 0.0825526182088234 -35.8023680278981 0.285872927054629 58.1268450950999 + 0.215934397491243 -80.537125944846 0.171561154049879 155.992416911042 + 0.385596095550915 -100.267928758224 0.11163137613422 100.17567307269 0.261333151487602 42.9266088766573 0.231058069722909 98.1408092339455 + 0.171561154049879 155.992416911042 0.251331156338329 44.5968471409019 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.9 0.360865356078314 -66.1752143666209 0.195089941257554 156.614243065525 0.114152051341371 -31.9070287050281 0.133843959785443 -21.8719834118569 + 0.0995771759865726 -38.6651143451939 0.389931760443555 -113.277406694801 + 0.195089941257554 156.614243065525 0.197238493938214 -101.714216403104 0.156989497838682 11.6535648017441 0.131140472330154 149.663892415507 + 0.425556847383219 -53.3353418071518 0.0952417187161659 100.875650241746 + 0.114152051341371 -31.9070287050281 0.156989497838682 11.6535648017441 0.289909673181066 -61.6425548757359 0.424867661371218 -118.102835761483 + 0.0722252124564939 -50.3009335907481 0.255146070429021 29.2073710323887 + 0.133843959785443 -21.8719834118569 0.131140472330154 149.663892415507 0.424867661371218 -118.102835761483 0.0436119076464708 17.3459083467989 + 0.28640585144957 44.8166590486527 0.244590532142982 92.2250782995596 + 0.0995771759865726 -38.6651143451939 0.425556847383219 -53.3353418071518 0.0722252124564939 -50.3009335907481 0.28640585144957 44.8166590486527 + 0.224585546552471 -80.8192770113436 0.166591619655448 143.645979124431 + 0.389931760443555 -113.277406694801 0.0952417187161659 100.875650241746 0.255146070429021 29.2073710323887 0.244590532142982 92.2250782995596 + 0.166591619655448 143.645979124431 0.266908661643049 36.6796043925934 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +8.95 0.37606898848682 -77.3017212539901 0.192741332511224 145.073296658307 0.123129223000338 -47.4155955616671 0.128114662237676 -36.4361298492374 + 0.09713802565792 -62.2055663035436 0.394243641264613 -126.481325737207 + 0.192741332511224 145.073296658307 0.202947611532115 -104.711755576097 0.160231494951664 -1.99046825866631 0.149642559952937 151.115776929778 + 0.42433661596201 -66.0851885128424 0.0849640529986477 105.099568376751 + 0.123129223000338 -47.4155955616671 0.160231494951664 -1.99046825866631 0.318613867812753 -70.8881284719641 0.421525567750624 -130.496970347108 + 0.0564363972284526 -65.2793977156056 0.250928007206027 16.0312818531017 + 0.128114662237676 -36.4361298492374 0.149642559952937 151.115776929778 0.421525567750624 -130.496970347108 0.0507541794952861 -5.70103696767092 + 0.287310886105921 30.9901938438925 0.254217904896049 85.6942429653607 + 0.09713802565792 -62.2055663035436 0.42433661596201 -66.0851885128424 0.0564363972284526 -65.2793977156056 0.287310886105921 30.9901938438925 + 0.231088308020317 -82.5525106013887 0.161607248241845 130.550634239874 + 0.394243641264613 -126.481325737207 0.0849640529986477 105.099568376751 0.250928007206027 16.0312818531017 0.254217904896049 85.6942429653607 + 0.161607248241845 130.550634239874 0.277587722768077 29.1728821340766 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9 0.375617000772165 -88.0069320637552 0.192981654045617 132.726839519925 0.129276559788458 -62.301482767919 0.123516136610891 -49.8981830194175 + 0.0981281128064527 -86.0063367459946 0.399101610634138 -139.648965592176 + 0.192981654045617 132.726839519925 0.202230032743009 -108.982828950063 0.161049009702114 -16.8481676708817 0.171570138220467 147.651907038885 + 0.426751602230578 -79.1075198025696 0.0833471375672099 111.662018715801 + 0.129276559788458 -62.301482767919 0.161049009702114 -16.8481676708817 0.33410032600337 -80.0446968516294 0.420272984315734 -142.677774036936 + 0.0373445010276266 -79.54829941426 0.248645448764958 2.66017253904703 + 0.123516136610891 -49.8981830194175 0.171570138220467 147.651907038885 0.420272984315734 -142.677774036936 0.0557632221267344 -22.2042778471873 + 0.285646869893667 16.841354805579 0.261382911027263 78.9692586985533 + 0.0981281128064527 -86.0063367459946 0.426751602230578 -79.1075198025696 0.0373445010276266 -79.54829941426 0.285646869893667 16.841354805579 + 0.232029223467694 -84.3083417739336 0.154066372242525 117.423102446385 + 0.399101610634138 -139.648965592176 0.0833471375672099 111.662018715801 0.248645448764958 2.66017253904703 0.261382911027263 78.9692586985533 + 0.154066372242525 117.423102446385 0.285230057366679 22.4153246949548 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.05 0.360385985132031 -98.4382994638176 0.191957003554144 119.640069553885 0.13097334195213 -76.8115727066245 0.121617188484739 -63.5001568009925 + 0.100566460576252 -109.816029586649 0.4064825240327 -152.89277677699 + 0.191957003554144 119.640069553885 0.198113442249932 -113.017725099873 0.159070417576115 -31.6688968063379 0.191633492085735 141.320757439128 + 0.428466119440506 -92.4400383649812 0.0901913909235913 114.442467757079 + 0.13097334195213 -76.8115727066245 0.159070417576115 -31.6688968063379 0.337422198896921 -89.1541196912118 0.421052485983813 -154.738661266456 + 0.0177472148542912 -95.5540910057767 0.246131005431521 -11.1097675315018 + 0.121617188484739 -63.5001568009925 0.191633492085735 141.320757439128 0.421052485983813 -154.738661266456 0.0584063651311108 -34.7812720232543 + 0.282016128539091 2.74412963078859 0.264751448369586 71.4582899704438 + 0.100566460576252 -109.816029586649 0.428466119440506 -92.4400383649812 0.0177472148542912 -95.5540910057767 0.282016128539091 2.74412963078859 + 0.231397722712407 -85.5600242579016 0.144835679876681 105.296930382954 + 0.4064825240327 -152.89277677699 0.0901913909235913 114.442467757079 0.246131005431521 -11.1097675315018 0.264751448369586 71.4582899704438 + 0.144835679876681 105.296930382954 0.290048837177113 15.606079844558 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.1 0.33059416586414 -108.607435967018 0.188845797840488 106.610133056472 0.128165010248964 -91.0375068308399 0.12079094297036 -78.290361564433 + 0.103564743044837 -132.996570819449 0.416358303205877 -166.550095040907 + 0.188845797840488 106.610133056472 0.190567552336149 -117.040452751271 0.156392529495275 -46.3333908291071 0.206724702902479 133.002611064229 + 0.429565890138993 -105.766341524046 0.0965445733067805 111.378119831608 + 0.128165010248964 -91.0375068308399 0.156392529495275 -46.3333908291071 0.328047791062236 -98.2146291328824 0.424590257125637 -166.712575501482 + 0.00404105416804444 132.78373721161 0.241910535352537 -25.1138169183366 + 0.12079094297036 -78.290361564433 0.206724702902479 133.002611064229 0.424590257125637 -166.712575501482 0.0599413442267728 -45.5607357973334 + 0.276874708216354 -11.3573985272946 0.259671219159781 63.4421682520977 + 0.103564743044837 -132.996570819449 0.429565890138993 -105.766341524046 0.00404105416804444 132.78373721161 0.276874708216354 -11.3573985272946 + 0.229664707288876 -86.8051897573476 0.136258460959582 94.7975268786435 + 0.416358303205877 -166.550095040907 0.0965445733067805 111.378119831608 0.241910535352537 -25.1138169183366 0.259671219159781 63.4421682520977 + 0.136258460959582 94.7975268786435 0.286946333834519 8.8161670195955 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.15 0.286790718627839 -118.285324631667 0.184783505634433 94.0856042273672 0.121212634169173 -105.379855584078 0.119100655138592 -94.3670582874283 + 0.107043556542923 -155.385299248737 0.426987868461036 179.181497336625 + 0.184783505634433 94.0856042273672 0.178569084038358 -119.239543877099 0.152918526528326 -61.4305660597912 0.211893763468745 123.70007928198 + 0.43181680022875 -119.226977794421 0.0959432013721897 106.473391215904 + 0.121212634169173 -105.379855584078 0.152918526528326 -61.4305660597912 0.305112028599886 -107.12355347042 0.431957631963623 -178.796267669773 + 0.0248061622297073 80.3981458180636 0.23566854192166 -39.0524319165082 + 0.119100655138592 -94.3670582874283 0.211893763468745 123.70007928198 0.431957631963623 -178.796267669773 0.06107785516462 -57.7400292164201 + 0.269384387911686 -25.4018153602615 0.24420417696552 56.0578457946048 + 0.107043556542923 -155.385299248737 0.43181680022875 -119.226977794421 0.0248061622297073 80.3981458180636 0.269384387911686 -25.4018153602615 + 0.22404339673892 -87.8389228580207 0.130955401748846 85.6189489501209 + 0.426987868461036 179.181497336625 0.0959432013721897 106.473391215904 0.23566854192166 -39.0524319165082 0.24420417696552 56.0578457946048 + 0.130955401748846 85.6189489501209 0.274011930423772 3.18034485803399 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.2 0.230695072353239 -126.843608128059 0.181441332416215 82.2280387227232 0.109482693235279 -120.385831415242 0.115146464314034 -111.373192483452 + 0.110535993906619 -177.472648574524 0.435806475166905 164.300300662212 + 0.181441332416215 82.2280387227232 0.173099035303995 -118.329950921031 0.146181248193472 -76.7352732090638 0.20618475864639 115.583972552866 + 0.432546135523253 -133.104471576644 0.0904366618325362 103.994018815333 + 0.109482693235279 -120.385831415242 0.146181248193472 -76.7352732090638 0.268595445505807 -115.094429574123 0.44259832162012 168.686090881389 + 0.0488566974565285 62.4587795973263 0.227979137018196 -52.7519047871765 + 0.115146464314034 -111.373192483452 0.20618475864639 115.583972552866 0.44259832162012 168.686090881389 0.0592186787211866 -75.0127122702875 + 0.259614981855715 -38.9895454714672 0.221884994243379 50.8702672922936 + 0.110535993906619 -177.472648574524 0.432546135523253 -133.104471576644 0.0488566974565285 62.4587795973263 0.259614981855715 -38.9895454714672 + 0.21598218913476 -86.971670093951 0.129153569420113 76.8252416219005 + 0.435806475166905 164.300300662212 0.0904366618325362 103.994018815333 0.227979137018196 -52.7519047871765 0.221884994243379 50.8702672922936 + 0.129153569420113 76.8252416219005 0.255341937640277 0.147263973801639 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.25 0.165299105933479 -132.644036934052 0.180185994308714 70.5832558569908 0.0921346204715634 -136.180357358644 0.108789261682653 -128.597805014893 + 0.112450454272076 160.303252718773 0.440812394403105 149.052137279985 + 0.180185994308714 70.5832558569908 0.180512966771473 -118.826058953212 0.13677839598951 -90.8869033698028 0.197992635711584 109.98812899035 + 0.428987290848617 -146.962960724604 0.0871707750256547 104.392554066613 + 0.0921346204715634 -136.180357358644 0.13677839598951 -90.8869033698028 0.223020329440224 -120.874963583261 0.454390495707073 155.634402223768 + 0.0716668806351297 44.7764776982702 0.218799918779586 -66.1689892338908 + 0.108789261682653 -128.597805014893 0.197992635711584 109.98812899035 0.454390495707073 155.634402223768 0.0504849421269539 -98.660594007074 + 0.249318415444051 -51.9306366473998 0.20098682288546 48.7151855451715 + 0.112450454272076 160.303252718773 0.428987290848617 -146.962960724604 0.0716668806351297 44.7764776982702 0.249318415444051 -51.9306366473998 + 0.215302320133647 -84.1592347088879 0.130647934069484 68.1571297215739 + 0.440812394403105 149.052137279985 0.0871707750256547 104.392554066613 0.218799918779586 -66.1689892338908 0.20098682288546 48.7151855451715 + 0.130647934069484 68.1571297215739 0.240650098415443 0.428423856791346 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.3 0.096579756847679 -128.909848084396 0.180448671437588 58.8186641484808 0.0696786998286592 -152.467021206559 0.10063951218885 -145.822813661027 + 0.111271249390349 138.097753774893 0.441732099408548 133.664714689361 + 0.180448671437588 58.8186641484808 0.187491962372578 -123.366489858346 0.127668255786142 -103.289917110965 0.193080559266505 105.286616557662 + 0.422673637521038 -160.400933662028 0.0863383852813171 104.016619507165 + 0.0696786998286592 -152.467021206559 0.127668255786142 -103.289917110965 0.174489645655314 -122.799363504559 0.465596421806696 142.10341364141 + 0.0897484800255094 27.4607336270791 0.208365479149035 -79.0084637822895 + 0.10063951218885 -145.822813661027 0.193080559266505 105.286616557662 0.465596421806696 142.10341364141 0.0369523852443914 -131.102855738078 + 0.239886037600588 -64.1888185223167 0.186320522212369 48.747411036545 + 0.111271249390349 138.097753774893 0.422673637521038 -160.400933662028 0.0897484800255094 27.4607336270791 0.239886037600588 -64.1888185223167 + 0.225568079633664 -82.16613143211 0.135989531193995 58.8227375802855 + 0.441732099408548 133.664714689361 0.0863383852813171 104.016619507165 0.208365479149035 -79.0084637822895 0.186320522212369 48.747411036545 + 0.135989531193995 58.8227375802855 0.237453811820796 2.70094619830571 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.35 0.0554351222996672 -82.4434445403713 0.182347948135134 46.5244057612521 0.0434323023523336 -168.618779895866 0.0912133936860774 -162.653920923537 + 0.106036096375933 115.893032926266 0.439117446540713 118.357367807156 + 0.182347948135134 46.5244057612521 0.186162051085285 -128.890441601639 0.121874539323808 -114.019165975867 0.188357444742848 100.505724579707 + 0.416222680460705 -173.113262060883 0.0855479542535359 103.544020129509 + 0.0434323023523336 -168.618779895866 0.121874539323808 -114.019165975867 0.130383569476506 -117.403887008261 0.475647241170227 128.265248820859 + 0.101681610134853 10.5144629583729 0.196513359050256 -91.1711934220389 + 0.0912133936860774 -162.653920923537 0.188357444742848 100.505724579707 0.475647241170227 128.265248820859 0.0270676854234672 176.290526185681 + 0.232072986541449 -76.1698295838787 0.178685155147336 49.7388083718586 + 0.106036096375933 115.893032926266 0.416222680460705 -173.113262060883 0.101681610134853 10.5144629583729 0.232072986541449 -76.1698295838787 + 0.241137081097533 -82.7828824437152 0.144692914530553 48.7481831431663 + 0.439117446540713 118.357367807156 0.0855479542535359 103.544020129509 0.196513359050256 -91.1711934220389 0.178685155147336 49.7388083718586 + 0.144692914530553 48.7481831431663 0.247300942872443 4.40580270836623 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.4 0.104366963467011 -41.0453411892968 0.182768421399673 33.2256280441979 0.0176532051677732 -179.778548216176 0.0810266431103764 -179.231637119887 + 0.0961318192951242 95.2415738622643 0.434123173529035 103.007614169822 + 0.182768421399673 33.2256280441979 0.182444084056937 -133.76168549239 0.121082080521201 -124.931336839795 0.18287747951446 95.9421610065782 + 0.415085053459713 174.702846030332 0.0866132543761454 101.633354613614 + 0.0176532051677732 -179.778548216176 0.121082080521201 -124.931336839795 0.103738770536437 -101.108096463642 0.484346086357681 113.985429627175 + 0.104983290421346 -5.75773254117875 0.184072182632557 -101.218064884422 + 0.0810266431103764 -179.231637119887 0.18287747951446 95.9421610065782 0.484346086357681 113.985429627175 0.0326967985248388 116.73819235519 + 0.22414033932548 -87.6269698491425 0.175357541091373 50.6800575113178 + 0.0961318192951242 95.2415738622643 0.415085053459713 174.702846030332 0.104983290421346 -5.75773254117875 0.22414033932548 -87.6269698491425 + 0.252559357859689 -86.3980789669125 0.159308279350589 36.4833247309696 + 0.434123173529035 103.007614169822 0.0866132543761454 101.633354613614 0.184072182632557 -101.218064884422 0.175357541091373 50.6800575113178 + 0.159308279350589 36.4833247309696 0.260549689800395 4.01788895357667 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.45 0.176213155450242 -40.1345218275413 0.178640454181266 20.2356161061813 0.00463985539881036 -25.5219266579784 0.0698248540691998 164.968094460421 + 0.0872479114552423 77.013524879219 0.42408047159226 87.6295140347086 + 0.178640454181266 20.2356161061813 0.179664725153586 -139.495692805787 0.122290860076917 -137.398103591777 0.176936391441798 91.6203267918306 + 0.419223904372116 162.244242999235 0.0842469815675939 96.2141303035869 + 0.00463985539881036 -25.5219266579784 0.122290860076917 -137.398103591777 0.10268307491517 -78.3752370191087 0.488174357112892 99.3719372778701 + 0.101196538173615 -19.3222795919191 0.179710969685279 -109.232914574231 + 0.0698248540691998 164.968094460421 0.176936391441798 91.6203267918306 0.488174357112892 99.3719372778701 0.0484331245595759 80.509189414669 + 0.219432658550711 -98.2245765440467 0.175400398030974 51.7266995984664 + 0.0872479114552423 77.013524879219 0.419223904372116 162.244242999235 0.101196538173615 -19.3222795919191 0.219432658550711 -98.2245765440467 + 0.250017795505522 -91.0235777016657 0.172897818911718 20.6074345373742 + 0.42408047159226 87.6295140347086 0.0842469815675939 96.2141303035869 0.179710969685279 -109.232914574231 0.175400398030974 51.7266995984664 + 0.172897818911718 20.6074345373742 0.2718701648422 3.14260221571714 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.5 0.240300536933436 -47.1094834404003 0.173452090477335 8.98204330404109 0.0264926957039031 -26.0581366717162 0.0586935914340453 151.51708950771 + 0.0815824922081702 57.683436883848 0.408014694296586 72.829122677038 + 0.173452090477335 8.98204330404109 0.171549697891492 -147.858711134132 0.123324523797562 -151.163626857083 0.171188988534616 87.4272078871163 + 0.425293481157945 149.310193559735 0.0735145125914626 90.4116173367762 + 0.0264926957039031 -26.0581366717162 0.123324523797562 -151.163626857083 0.12931958203667 -61.3719578097948 0.486634219546203 84.8899516065311 + 0.0959217701805463 -30.0301496316584 0.184560677323934 -118.114993465135 + 0.0586935914340453 151.51708950771 0.171188988534616 87.4272078871163 0.486634219546203 84.8899516065311 0.0657445029456411 56.7497093668041 + 0.219550143850142 -108.962512896118 0.18032339770825 52.417895787534 + 0.0815824922081702 57.683436883848 0.425293481157945 149.310193559735 0.0959217701805463 -30.0301496316584 0.219550143850142 -108.962512896118 + 0.235676423642247 -94.1698987889869 0.17894439860933 3.2987534966955 + 0.408014694296586 72.829122677038 0.0735145125914626 90.4116173367762 0.184560677323934 -118.114993465135 0.18032339770825 52.417895787534 + 0.17894439860933 3.2987534966955 0.2862114494324 2.46740844870552 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.55 0.2928248302063 -55.9422724952378 0.17305208202334 -0.58232170956006 0.0485335636100135 -40.1107628236036 0.0503233774847493 140.339391115565 + 0.0750841633222676 34.7313416305558 0.391026212376443 59.3242271198111 + 0.17305208202334 -0.58232170956006 0.149233260959836 -156.679863771566 0.123246096749963 -166.073644082748 0.163720088779524 82.6127354580529 + 0.431804111135171 135.989766815146 0.055817238260122 90.2691563025286 + 0.0485335636100135 -40.1107628236036 0.123246096749963 -166.073644082748 0.17421961832881 -56.1419695586893 0.482392535296493 70.8098598823567 + 0.0922656588357117 -40.1012167691144 0.192152232415469 -129.257020363384 + 0.0503233774847493 140.339391115565 0.163720088779524 82.6127354580529 0.482392535296493 70.8098598823567 0.0804651624889028 36.6389876265757 + 0.221918968476464 -120.558425601765 0.188932962430014 51.4737493731574 + 0.0750841633222676 34.7313416305558 0.431804111135171 135.989766815146 0.0922656588357117 -40.1012167691144 0.221918968476464 -120.558425601765 + 0.217387432342559 -94.5111827772732 0.178539141855379 -13.457168539012 + 0.391026212376443 59.3242271198111 0.055817238260122 90.2691563025286 0.192152232415469 -129.257020363384 0.188932962430014 51.4737493731574 + 0.178539141855379 -13.457168539012 0.307208240783756 0.593012124310567 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.6 0.331634784966999 -65.5804348608238 0.180691037366729 -10.7806340231275 0.0659608015732543 -55.8276274281787 0.0434475533785471 128.638040039017 + 0.0661723290982341 9.80318040757229 0.380406633491228 46.6412619147554 + 0.180691037366729 -10.7806340231275 0.1192006167148 -161.028459165465 0.120414652778229 178.324076240835 0.151065203769482 78.3238912275239 + 0.438031104017608 122.270418292774 0.0405564168775765 107.526365487862 + 0.0659608015732543 -55.8276274281787 0.120414652778229 178.324076240835 0.221377743772914 -58.8410303243934 0.477990746831598 57.0146737595405 + 0.0887951348638208 -51.8371332206756 0.19735160642402 -141.590977429726 + 0.0434475533785471 128.638040039017 0.151065203769482 78.3238912275239 0.477990746831598 57.0146737595405 0.0881902554037489 17.7670492197158 + 0.223940448005015 -132.812612262056 0.196033423381067 49.0229224914232 + 0.0661723290982341 9.80318040757229 0.438031104017608 122.270418292774 0.0887951348638208 -51.8371332206756 0.223940448005015 -132.812612262056 + 0.20344733566671 -91.7703297579952 0.176049137975249 -29.3939389224913 + 0.380406633491228 46.6412619147554 0.0405564168775765 107.526365487862 0.19735160642402 -141.590977429726 0.196033423381067 49.0229224914232 + 0.176049137975249 -29.3939389224913 0.3249952752539 -3.3221582275343 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.65 0.354511719528277 -75.2912157667991 0.191296543737624 -23.161402910945 0.077778234442056 -69.8754351602832 0.0358577405533815 118.450652181866 + 0.0585282752782618 -16.3031504116411 0.374148578285527 33.8483137118441 + 0.191296543737624 -23.161402910945 0.0943970130444698 -158.443299601601 0.114853102906875 163.173960138933 0.136073541459555 76.9297341693606 + 0.44194945199735 108.193050608302 0.0446558064947344 139.45081855352 + 0.077778234442056 -69.8754351602832 0.114853102906875 163.173960138933 0.260627080126604 -64.8739947734077 0.47325980639519 43.3417253734567 + 0.0835106390575674 -65.6745297545662 0.200899355403223 -154.115095015475 + 0.0358577405533815 118.450652181866 0.136073541459555 76.9297341693606 0.47325980639519 43.3417253734567 0.086519293568914 0.302425044227148 + 0.225386754774643 -145.393656018802 0.200955644050884 46.3506319980772 + 0.0585282752782618 -16.3031504116411 0.44194945199735 108.193050608302 0.0835106390575674 -65.6745297545662 0.225386754774643 -145.393656018802 + 0.199616718060027 -87.3125483388972 0.172027174490275 -45.1156014752552 + 0.374148578285527 33.8483137118441 0.0446558064947344 139.45081855352 0.200899355403223 -154.115095015475 0.200955644050884 46.3506319980772 + 0.172027174490275 -45.1156014752552 0.332818302729548 -7.56378591748408 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.7 0.363647189896209 -84.7269579898133 0.19963647539975 -37.3170336626225 0.0862768149692173 -82.8488904643353 0.030140491064493 114.874636734122 + 0.0539428740558746 -45.314174838767 0.368750436770605 21.1443630368997 + 0.19963647539975 -37.3170336626225 0.0792851829731309 -151.306658503658 0.108865127376811 149.247969098421 0.127187208143041 79.2911651836768 + 0.442809722855038 94.0934616975077 0.0682496327968867 151.341648700717 + 0.0862768149692173 -82.8488904643353 0.108865127376811 149.247969098421 0.289083556515065 -72.1344853681704 0.467734324561617 29.8879090303818 + 0.0762010072838323 -81.9539111316857 0.203705000472788 -166.843189101757 + 0.030140491064493 114.874636734122 0.127187208143041 79.2911651836768 0.467734324561617 29.8879090303818 0.0762867643015697 -14.8354332381653 + 0.22600936054191 -158.352705623106 0.20686342636235 43.424577913427 + 0.0539428740558746 -45.314174838767 0.442809722855038 94.0934616975077 0.0762010072838323 -81.9539111316857 0.22600936054191 -158.352705623106 + 0.205440979838035 -83.4571933353597 0.166017099428624 -60.2068780236564 + 0.368750436770605 21.1443630368997 0.0682496327968867 151.341648700717 0.203705000472788 -166.843189101757 0.20686342636235 43.424577913427 + 0.166017099428624 -60.2068780236564 0.335335293909397 -11.2281725228275 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.75 0.358947601521639 -94.2992719976093 0.202635035705683 -51.8186640661629 0.0914779846492768 -96.2398393441532 0.0296254370612488 111.579436199111 + 0.0520947482860649 -76.3307571072946 0.36725279989748 8.65703909057386 + 0.202635035705683 -51.8186640661629 0.0692775985289911 -140.652653029876 0.104331763484788 135.843981031025 0.12782840848976 81.4461036455543 + 0.441918225131798 80.0457666976966 0.0937333440355288 149.277474648654 + 0.0914779846492768 -96.2398393441532 0.104331763484788 135.843981031025 0.305738270391823 -79.8110876899966 0.462797747562246 16.6745015552715 + 0.067313786453562 -100.952039486626 0.20536927958436 -179.560837372896 + 0.0296254370612488 111.579436199111 0.12782840848976 81.4461036455543 0.462797747562246 16.6745015552715 0.0604668759966313 -28.7257188479362 + 0.224729142781815 -171.297894569052 0.211519923277132 39.4927817968622 + 0.0520947482860649 -76.3307571072946 0.441918225131798 80.0457666976966 0.067313786453562 -100.952039486626 0.224729142781815 -171.297894569052 + 0.217094575499194 -81.00316427243 0.160813893991096 -74.6200298175665 + 0.36725279989748 8.65703909057386 0.0937333440355288 149.277474648654 0.20536927958436 -179.560837372896 0.211519923277132 39.4927817968622 + 0.160813893991096 -74.6200298175665 0.332902196811659 -14.6143491143993 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.8 0.337559144401139 -103.614228541139 0.202951638822481 -65.7915908950256 0.0925247190454263 -110.093226040662 0.0304433404393671 101.956435891968 + 0.0536407917406022 -106.753898168453 0.369378193891525 -4.23568494152612 + 0.202951638822481 -65.7915908950256 0.0682698772440746 -126.367658073241 0.101029343666065 122.65508445584 0.133732121231023 81.6284554343427 + 0.438674339911684 66.2185223767686 0.117704474610377 143.089593611438 + 0.0925247190454263 -110.093226040662 0.101029343666065 122.65508445584 0.311083911770279 -87.5653504244566 0.458002242580339 3.64397067151141 + 0.0599991885906122 -123.521049079542 0.20776094089281 167.768325146886 + 0.0304433404393671 101.956435891968 0.133732121231023 81.6284554343427 0.458002242580339 3.64397067151141 0.0376155398474037 -40.991977449542 + 0.224377820921014 175.927914718017 0.214416167348866 35.490569159575 + 0.0536407917406022 -106.753898168453 0.438674339911684 66.2185223767686 0.0599991885906122 -123.521049079542 0.224377820921014 175.927914718017 + 0.233872518969266 -80.566686933417 0.155267794309415 -89.5456099267968 + 0.369378193891525 -4.23568494152612 0.117704474610377 143.089593611438 0.20776094089281 167.768325146886 0.214416167348866 35.490569159575 + 0.155267794309415 -89.5456099267968 0.325801458064112 -16.776324562585 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.85 0.301576207210416 -111.985517144067 0.20152957937496 -79.0778086807146 0.0889895570600469 -124.75791115286 0.0308728369353946 86.2632932548215 + 0.0573792903916158 -135.826327606535 0.373206990366668 -17.6466903814063 + 0.20152957937496 -79.0778086807146 0.075062889378633 -112.908701244041 0.100168991405931 108.554890268475 0.142092370386362 77.7975432658806 + 0.436764481212152 52.7768350279199 0.135775154294073 134.478028217457 + 0.0889895570600469 -124.75791115286 0.100168991405931 108.554890268475 0.303693129149132 -95.395727989856 0.455234397372046 -8.98603662063317 + 0.0569942170262671 -152.707720778824 0.209656389317016 154.495789218785 + 0.0308728369353946 86.2632932548215 0.142092370386362 77.7975432658806 0.455234397372046 -8.98603662063317 0.0133126669244414 -37.0419996477321 + 0.223613211903894 162.354922743892 0.217139335307401 30.4920913696553 + 0.0573792903916158 -135.826327606535 0.436764481212152 52.7768350279199 0.0569942170262671 -152.707720778824 0.223613211903894 162.354922743892 + 0.248510788039344 -82.7920433933153 0.146179543641369 -103.953890595397 + 0.373206990366668 -17.6466903814063 0.135775154294073 134.478028217457 0.209656389317016 154.495789218785 0.217139335307401 30.4920913696553 + 0.146179543641369 -103.953890595397 0.320838489954398 -17.8387722635826 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.9 0.254761434620435 -118.478474394379 0.201670090863056 -91.4654705696952 0.0802513036528718 -139.827945326475 0.0280059279972708 65.2427475225315 + 0.0609534642037439 -162.395956383602 0.376486001851282 -31.8114083545664 + 0.201670090863056 -91.4654705696952 0.0961148239962975 -103.295713139059 0.0984016608421785 92.1898399241123 0.142691160435757 71.1708046794466 + 0.43700987610972 39.1808806773392 0.146451893466537 126.45816346613 + 0.0802513036528718 -139.827945326475 0.0984016608421785 92.1898399241123 0.281994476517719 -102.521555167347 0.457261851072754 -21.6560592993353 + 0.0596838978713998 173.075484196184 0.20887534624943 141.220742571687 + 0.0280059279972708 65.2427475225315 0.142691160435757 71.1708046794466 0.457261851072754 -21.6560592993353 0.0128965236310534 94.7434557206594 + 0.218562730656643 148.623631388021 0.214156247025475 24.7361707676609 + 0.0609534642037439 -162.395956383602 0.43700987610972 39.1808806773392 0.0596838978713998 173.075484196184 0.218562730656643 148.623631388021 + 0.254032914429364 -85.9890726034868 0.136746993391559 -116.558191482502 + 0.376486001851282 -31.8114083545664 0.146451893466537 126.45816346613 0.20887534624943 141.220742571687 0.214156247025475 24.7361707676609 + 0.136746993391559 -116.558191482502 0.31740676038838 -18.1581276032687 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +9.95 0.203113186797732 -121.889434861687 0.203887270617153 -103.978919827072 0.0676035703241199 -155.155004824451 0.0223585694613494 44.0646613302408 + 0.0630626841643224 173.525321046734 0.375431671804618 -46.3743833644531 + 0.203887270617153 -103.978919827072 0.127143131993459 -104.125141990693 0.0938445915595987 74.9155239165137 0.136617912292186 64.8740350633019 + 0.436919658872992 25.3757572376342 0.152204644491286 118.903457955447 + 0.0676035703241199 -155.155004824451 0.0938445915595987 74.9155239165137 0.248678439029088 -107.779669860375 0.461693633352503 -34.7042737093879 + 0.0693325112200521 139.71491567881 0.206751054647666 128.347568233361 + 0.0223585694613494 44.0646613302408 0.136617912292186 64.8740350633019 0.461693633352503 -34.7042737093879 0.040668737961937 99.3471415737776 + 0.210394827360186 135.492952414496 0.20726445558113 19.104187432287 + 0.0630626841643224 173.525321046734 0.436919658872992 25.3757572376342 0.0693325112200521 139.71491567881 0.210394827360186 135.492952414496 + 0.251377321901641 -88.6381070264996 0.129658931415736 -127.450842841441 + 0.375431671804618 -46.3743833644531 0.152204644491286 118.903457955447 0.206751054647666 128.347568233361 0.20726445558113 19.104187432287 + 0.129658931415736 -127.450842841441 0.319651585545705 -17.6473995251472 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 +10 0.151128940650018 -119.440537918207 0.206579963072862 -116.250704140491 0.0519975493228169 -171.001842609445 0.0157944540828917 19.6600621336532 + 0.0625226907923966 152.192606860164 0.370539568695343 -60.8069699991678 + 0.206579963072862 -116.250704140491 0.156626661911104 -110.784207433674 0.0871919766303643 56.9861200781909 0.126188610615037 58.9789782631109 + 0.435875176533359 11.3919892487255 0.151215828958115 112.578915662129 + 0.0519975493228169 -171.001842609445 0.0871919766303643 56.9861200781909 0.209581694556964 -109.23988922435 0.467260847764441 -48.199207532713 + 0.0832327781248696 110.527546305937 0.203898371270225 116.134308947295 + 0.0157944540828917 19.6600621336532 0.126188610615037 58.9789782631109 0.467260847764441 -48.199207532713 0.0697857275226 91.8462759078503 + 0.200159366870976 123.546522909628 0.195461219552829 13.1890075974055 + 0.0625226907923966 152.192606860164 0.435875176533359 11.3919892487255 0.0832327781248696 110.527546305937 0.200159366870976 123.546522909628 + 0.245230548668925 -89.8090598097088 0.127798780722035 -137.314066220437 + 0.370539568695343 -60.8069699991678 0.151215828958115 112.578915662129 0.203898371270225 116.134308947295 0.195461219552829 13.1890075974055 + 0.127798780722035 -137.314066220437 0.328843241464078 -17.5634238814795 +! Gamma 0 0 0 0 0 0 0 0 0 0 0 0 +! Port Impedance 50 0 50 0 50 0 50 0 50 0 50 0 diff --git a/_unittest/example_models/T21/pcieg5_32gt.ami b/_unittest/example_models/T21/pcieg5_32gt.ami new file mode 100644 index 00000000000..75819c32e1b --- /dev/null +++ b/_unittest/example_models/T21/pcieg5_32gt.ami @@ -0,0 +1,30 @@ +|****************************************************************************** +| Spec. AMI model generated by SPISim's BPro, Generated on 20170831143940 +| +| IP of this model belongs to SPISim or its licensed BPro user. +|***************************************************************************** +(ANSYS_PCIeG5_32GT_RX + (Description "Example PCIeG5 Rx 32GT model") + (Reserved_Parameters + (AMI_Version (Usage Info) (Type String) (Value "6.1") (Description "Supported AMI version")) + (Ignore_Bits (Usage Info) (Type Integer) (Default 500) (Description "Ignore four bits to fill up tapped delay line.")) + (Max_Init_Aggressors (Usage Info) (Type Integer) (Default 25) (Description "Number of aggressors is actually unlimited.")) + (Init_Returns_Impulse (Usage Info) (Type Boolean) (Default True) (Description "Both impulse and parameters_out returned.")) + (Supporting_Files (Usage Info) (Type String) (Table ("PCIeG5_32GT.ens")) (Description "CTLE Performance table")) + (GetWave_Exists (Usage Info) (Type Boolean) (Default True) (Description "GetWave is well and truly provided in the module.")) + ) | End Reserved_Parameters + + |**************************************************************************** + | Remove or tamper LICENSE_INFO values will cause simulation being aborted! + |**************************************************************************** + (Model_Specific + (LICENSE_INFO (Usage In) (Type String) (Default "LICENSED_ANSYS_AEDT_E168EFCC0268A84087F7B23B510CB41F") (Description "Licensing info.")) + | ------------------ MAIN Settings ------------------ + (MDL_SUB_MODS (Usage In) (Type String) (Default "CTLE,DFE") (Description "Cascaded stages")) + | ------------------ CTLE Settings ------------------ + (MDL_IDX_FILE (Usage In) (Type String) (Default "PCIeG5_32GT.ens") (Description "Params index table")) + (MDL_IDX_VALU (Usage In) (Type String) (Default "-1") (Description "Params table rowID")) + (ADC (Usage In) (Type Integer) (Range -5 -15 -5) (Default -5) (Description "DC Gain in dB")) + |(CTLE_OUPT_FILE (Usage In) (Type String) (Default "C:/Temp/WorkSpace/SPISim/CST/PCIe/32GT/PCIeG5_32GT.csv") (Description "Output generated FD array for checking purpose")) + ) | End Model_Specific +) | End SPISim_SPEC_AMI diff --git a/_unittest/example_models/T21/pcieg5_32gt.ibs b/_unittest/example_models/T21/pcieg5_32gt.ibs new file mode 100644 index 00000000000..466161d7873 --- /dev/null +++ b/_unittest/example_models/T21/pcieg5_32gt.ibs @@ -0,0 +1,100 @@ +|*************************************************************************** +| +[IBIS Ver] 5.1 +[File name] pcieg5_32gt.ibs +[File rev] 1.00 +[Date] Jan 1, 2017 +[Source] BPro (http://www.spisim.com) +[Copyright] Copyright 2017 ~, SPISim LLC. All right reserved. +| +|*************************************************************************** +| +[Component] Spec_Model +[Manufacturer] SPISim LLC +[Package] +| typ min max +R_pkg 0.0 0.0 0.0 +L_pkg 0.0 0.0 0.0 +C_pkg 0.0 0.0 0.0 +| +|*************************************************************************** +| +[PIN] signal_name model_name R_pin L_pin C_pin +1p TxP Tx NA NA NA +1n TxN Tx NA NA NA +2p RxP Rx NA NA NA +2n RxN Rx NA NA NA +| +|*************************************************************************** +| +[Diff Pin] inv_pin vdiff tdelay_typ tdelay_min tdelay_max +1p 1n 0.1V NA NA NA +2p 2n 0.1V NA NA NA +| +|**************************************************************** +| +[Model] Rx +Model_type Input +| +C_comp 0.00p 0.00p 0.00p +Vinh = 0.55 +Vinl = 0.45 +| +[Temperature_Range] 25 100 0 +[Voltage Range] 1.2 1.14 1.26 +| +| The IV table below is equivalent to 50 ohms single-ended load +[GND Clamp] +-6.6 -0.132 -0.132 -0.132 + 0.0 0.0 0.0 0.0 + 6.6 0.132 0.132 0.132 + +[Power Clamp] +-6.6 0.132e-9 0.132e-9 0.132e-9 + 0.0 0.0 0.0 0.0 + 6.6 -0.132e-9 -0.132e-9 -0.132e-9 + +[Algorithmic Model] +Executable Windows_VisualStudio_32 pcieg5_32gt_WIN32.dll pcieg5_32gt.ami +Executable Windows_VisualStudio_64 pcieg5_32gt_WIN64.dll pcieg5_32gt.ami +Executable Linux_gcc_64 pcieg5_32gt_LX64.so pcieg5_32gt.ami +[End Algorithmic Model] + +| +|*************************************************************************** +| +[Model] Tx +Model_type Output +Polarity Non-Inverting +Enable Active-High +| +Vmeas = 0.55 +| typ min max +C_comp 0 0 0 +[Voltage Range] 1.1 1.0 1.2 +[Temperature Range] 60 100 0 +| +|*************************************************************************** +| +[Pulldown] +-2.500 -5.00000E-02 -5.00000E-02 -5.00000E-02 +0.000 +0.00000E+00 +0.00000E+00 +0.00000E+00 +2.500 +5.00000E-02 +5.00000E-02 +5.00000E-02 +[Pullup] +-2.500 +5.00000E-02 +5.00000E-02 +5.00000E-02 +0.000 +0.00000E+00 +0.00000E+00 +0.00000E+00 +2.500 -5.00000E-02 -5.00000E-02 -5.00000E-02 +| +[Ramp] +dV/dt_r 0.2796/15p 0.2610/23.5p 0.2976/13p +dV/dt_f 0.2796/15p 0.2610/23.5p 0.2976/13p +| +| +[Algorithmic Model] +Executable Windows_VisualStudio_32 pcieg5_32gt_WIN32.dll pcieg5_32gt.ami +Executable Windows_VisualStudio_64 pcieg5_32gt_WIN64.dll pcieg5_32gt.ami +Executable Linux_gcc_64 pcieg5_32gt_LX64.so pcieg5_32gt.ami +[End Algorithmic Model] + +|*************************************************************************** +[End] diff --git a/_unittest/example_models/syslib/Materials.amat b/_unittest/example_models/syslib/Materials.amat index a688590e6d9..a17c11b41af 100644 --- a/_unittest/example_models/syslib/Materials.amat +++ b/_unittest/example_models/syslib/Materials.amat @@ -120,4 +120,4 @@ $begin '$index$' $base_index$(pos=0, lin=1, lvl=0) $index$(pos=318773, lin=11311, lvl=0) $end '$index$' -$end '$index$' +$end '$index$' \ No newline at end of file diff --git a/_unittest/test_01_3dlayout_edb.py b/_unittest/test_01_3dlayout_edb.py index ddfe5002090..25e5e0bf908 100644 --- a/_unittest/test_01_3dlayout_edb.py +++ b/_unittest/test_01_3dlayout_edb.py @@ -192,7 +192,10 @@ def test_04_add_mesh_operations(self): assert setup2 setup1.props["RestrictElem"] = False assert setup1.update() - assert self.aedtapp.mesh.delete_mesh_operations("HFSS", setup1.name) + assert self.aedtapp.mesh.delete_mesh_operations( + "HFSS", + setup1.name, + ) def test_05_change_property(self): ports = self.aedtapp.create_ports_on_component_by_nets( @@ -307,7 +310,7 @@ def test_15_3dplacement(self): def test_16_differential_ports(self): self.aedtapp.set_active_design(self.design_name) - pins = self.aedtapp.modeler.components["R3"].pins + pins = list(self.aedtapp.modeler.components["R3"].pins.keys()) assert self.aedtapp.create_differential_port(pins[0], pins[1], "test_differential", deembed=True) assert "test_differential" in self.aedtapp.port_list @@ -351,7 +354,6 @@ def test_19_dcir(self): assert self.dcir_example_project.post.available_report_quantities(is_siwave_dc=True, context="") assert self.dcir_example_project.post.create_report( self.dcir_example_project.post.available_report_quantities(is_siwave_dc=True, context="RL")[0], - setup_sweep_name="SIwaveDCIR1", domain="DCIR", context="RL", ) @@ -376,3 +378,15 @@ def test_22_change_design_settings(self): assert ( self.aedtapp.get_oo_property_value(self.aedtapp.odesign, "Design Settings", "DCExtrapolation") == "Advanced" ) + + def test_23_dissolve_element(self): + comp = self.aedtapp.modeler.components["D1"] + pins = {name: pin for name, pin in comp.pins.items() if name in ["D1-1", "D1-2", "D1-7"]} + self.aedtapp.dissolve_component("D1") + comp = self.aedtapp.modeler.create_component_on_pins(list(pins.keys())) + nets = [ + list(pins.values())[0].net_name, + list(pins.values())[1].net_name, + ] + assert self.aedtapp.create_ports_on_component_by_nets(comp.name, nets) + assert self.aedtapp.create_pec_on_component_by_nets(comp.name, "GND") diff --git a/_unittest/test_01_Design.py b/_unittest/test_01_Design.py index 54e3654bc7b..7ca301bbfb2 100644 --- a/_unittest/test_01_Design.py +++ b/_unittest/test_01_Design.py @@ -38,8 +38,17 @@ def test_app(self): assert self.aedtapp def test_01_designname(self): - self.aedtapp.design_name = "myname" - assert self.aedtapp.design_name == "myname" + # TODO: Remove subsequent dependence on string "myname" + design_names = ["myname", "design2"] + self.aedtapp.design_name = design_names[0] # Change the design name. + assert self.aedtapp.design_name == design_names[0] + self.aedtapp.insert_design(design_names[1]) # Insert a new design + assert self.aedtapp.design_name == design_names[1] + self.aedtapp.design_name = design_names[0] # Change current design back. + assert len(self.aedtapp.design_list) == 2 # Make sure there are still 2 designs. + assert self.aedtapp.design_list[0] in design_names # Make sure the name is correct. + self.aedtapp.delete_design(design_names[1]) # Delete the 2nd design + assert len(self.aedtapp.design_list) == 1 def test_01_version_id(self): assert self.aedtapp.aedt_version_id diff --git a/_unittest/test_01_GeometryOperators.py b/_unittest/test_01_GeometryOperators.py index 7e05f1c41a5..cd1e88f3ec9 100644 --- a/_unittest/test_01_GeometryOperators.py +++ b/_unittest/test_01_GeometryOperators.py @@ -37,7 +37,7 @@ def test_List2list(self): List_str.Add("two") List_str.Add("three") ls = go.List2list(List_str) - assert type(ls) is list + assert isinstance(ls, list) assert len(ls) == 3 List_float = List[Double]() List_float.Add(1.0) diff --git a/_unittest/test_02_2D_modeler.py b/_unittest/test_02_2D_modeler.py index 0837a6394f8..5fb8cff82cb 100644 --- a/_unittest/test_02_2D_modeler.py +++ b/_unittest/test_02_2D_modeler.py @@ -118,9 +118,9 @@ def test_06_create_circle(self): def test_06a_calculate_radius_2D(self): circle1 = self.aedtapp.modeler.create_circle([0, -2, 0], 3) radius = self.aedtapp.modeler.calculate_radius_2D(circle1.name) - assert type(radius) is float + assert isinstance(radius, float) radius = self.aedtapp.modeler.calculate_radius_2D(circle1.name, True) - assert type(radius) is float + assert isinstance(radius, float) def test_06b_radial_split(self): circle1 = self.aedtapp.modeler.create_circle([0, -2, 0], 3) @@ -194,15 +194,15 @@ def test_12_objects_in_bounding_box(self): objects_xy_4 = self.aedtapp.modeler.objects_in_bounding_box(bounding_box=bounding_box) bounding_box = [-25, -36, -40, 20, 30, 10] objects_xy_6 = self.aedtapp.modeler.objects_in_bounding_box(bounding_box=bounding_box) - assert type(objects_xy_4) is list - assert type(objects_xy_6) is list + assert isinstance(objects_xy_4, list) + assert isinstance(objects_xy_6, list) self.aedtapp.solution_type = "MagnetostaticZ" bounding_box = [-52, -68, 35, 42] objects_z_4 = self.aedtapp.modeler.objects_in_bounding_box(bounding_box=bounding_box) bounding_box = [-25, -36, -40, 20, 30, 10] objects_z_6 = self.aedtapp.modeler.objects_in_bounding_box(bounding_box=bounding_box) - assert type(objects_z_4) is list - assert type(objects_z_6) is list + assert isinstance(objects_z_4, list) + assert isinstance(objects_z_6, list) with pytest.raises(ValueError): bounding_box = [3, 4, 5] self.aedtapp.modeler.objects_in_bounding_box(bounding_box) diff --git a/_unittest/test_02_3D_modeler.py b/_unittest/test_02_3D_modeler.py index dbe348469d1..db48f8b0df3 100644 --- a/_unittest/test_02_3D_modeler.py +++ b/_unittest/test_02_3D_modeler.py @@ -150,7 +150,7 @@ def test_08_duplicate_around_axis(self): num_clones = 3 status, mirror = self.aedtapp.modeler.duplicate_around_axis("outer", udp, 45, num_clones) assert status - assert type(mirror) is list + assert isinstance(mirror, list) assert len(mirror) == num_clones - 1 def test_08_duplicate_along_line(self): @@ -158,7 +158,7 @@ def test_08_duplicate_along_line(self): num_clones = 5 status, mirror = self.aedtapp.modeler.duplicate_along_line("outer", udp, num_clones) assert status - assert type(mirror) is list + assert isinstance(mirror, list) assert len(mirror) == num_clones - 1 def test_09_thicken_sheet(self): @@ -798,7 +798,7 @@ def test_51_imprint_projection(self): def test_52_objects_in_bounding_box(self): bounding_box = [-100, -300, -200, 100, 200, 100] objects_in_bounding_box = self.aedtapp.modeler.objects_in_bounding_box(bounding_box) - assert type(objects_in_bounding_box) is list + assert isinstance(objects_in_bounding_box, list) bounding_box = [0, 0, 0, 0, 0, 0] objects_in_bounding_box = self.aedtapp.modeler.objects_in_bounding_box(bounding_box) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index bd95e52a5e9..c3d5c1943a0 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -92,14 +92,18 @@ def test_02_create_material(self): assert mat1.get_curve_coreloss_type() == "Power Ferrite" assert isinstance(mat1.material_appearance, list) - mat1.material_appearance = [11, 22, 0] - assert mat1.material_appearance == [11, 22, 0] - mat1.material_appearance = ["11", "22", "10"] - assert mat1.material_appearance == [11, 22, 10] + mat1.material_appearance = [11, 22, 0, 0.5] + assert mat1.material_appearance == [11, 22, 0, 0.5] + mat1.material_appearance = ["11", "22", "10", "0.5"] + assert mat1.material_appearance == [11, 22, 10, 0.5] with pytest.raises(ValueError): - mat1.material_appearance = [11, 22, 300] + mat1.material_appearance = [11, 22, 300, 0.5] with pytest.raises(ValueError): - mat1.material_appearance = [11, -22, 0] + mat1.material_appearance = [11, 22, 100, 1.5] + with pytest.raises(ValueError): + mat1.material_appearance = [11, -22, 0, 0.5] + with pytest.raises(ValueError): + mat1.material_appearance = [11, 22, 0, -1] with pytest.raises(ValueError): mat1.material_appearance = [11, 22] diff --git a/_unittest/test_04_SBR.py b/_unittest/test_04_SBR.py index 65878cfd65e..0bdf8a10593 100644 --- a/_unittest/test_04_SBR.py +++ b/_unittest/test_04_SBR.py @@ -56,18 +56,28 @@ def init(self, aedtapp, local_scratch): osmnx.settings.cache_folder = os.path.join(local_scratch.path, "cache") def test_01_open_source(self, source): - assert self.aedtapp.create_sbr_linked_antenna(source, target_cs="feederPosition", fieldtype="farfield") + assert self.aedtapp.create_sbr_linked_antenna(source, target_cs="feederPosition", field_type="farfield") assert len(self.aedtapp.native_components) == 1 + assert self.aedtapp.create_sbr_linked_antenna( + source, target_cs="feederPosition", field_type="farfield", name="LinkedAntenna" + ) + assert len(self.aedtapp.native_components) == 2 + assert self.aedtapp.create_sbr_linked_antenna( + source, target_cs="feederPosition", name="LinkedAntennaNF1", current_conformance=True + ) + assert len(self.aedtapp.native_components) == 3 + assert self.aedtapp.create_sbr_linked_antenna( + source, target_cs="feederPosition", name="LinkedAntennaNF2", current_conformance=False + ) + assert len(self.aedtapp.native_components) == 4 def test_02_add_antennas(self): self.aedtapp.insert_design("add_antennas") dict1 = {"polarization": "Horizontal"} par_beam = self.aedtapp.create_sbr_antenna( - self.aedtapp.SbrAntennas.ParametricBeam, parameters_dict=dict1, antenna_name="TX1" - ) - assert self.aedtapp.create_sbr_antenna( - self.aedtapp.SbrAntennas.ConicalHorn, parameters_dict=dict1, antenna_name="RX1" + self.aedtapp.SbrAntennas.ParametricBeam, parameters=dict1, name="TX1" ) + assert self.aedtapp.create_sbr_antenna(self.aedtapp.SbrAntennas.ConicalHorn, parameters=dict1, name="RX1") par_beam.native_properties["Unit"] = "in" assert par_beam.update() self.aedtapp.modeler.user_defined_components["TX1_1"].native_properties["Unit"] = "mm" @@ -112,7 +122,7 @@ def test_02_add_antennas(self): def test_03_add_ffd_antenna(self): self.aedtapp.insert_design("ffd_antenna") assert self.aedtapp.create_sbr_file_based_antenna( - ffd_full_path=os.path.join(local_path, "example_models", test_subfolder, "test.ffd") + far_field_data=os.path.join(local_path, "example_models", test_subfolder, "test.ffd") ) def test_04_add_environment(self): @@ -154,8 +164,8 @@ def test_08_add_radar(self): "library", "radar_modules", ) - assert self.aedtapp.create_sbr_radar_from_json(radar_lib, radar_name="Example_1Tx_1Rx", speed=3) - assert self.aedtapp.create_sbr_radar_from_json(radar_lib, radar_name="Example_1Tx_4Rx") + assert self.aedtapp.create_sbr_radar_from_json(radar_lib, name="Example_1Tx_1Rx", speed=3) + assert self.aedtapp.create_sbr_radar_from_json(radar_lib, name="Example_1Tx_4Rx") def test_09_add_doppler_sweep(self): setup, sweep = self.aedtapp.create_sbr_pulse_doppler_setup(sweep_time_duration=30) @@ -179,7 +189,7 @@ def test_11_add_sbr_boundaries_in_hfss_solution(self, add_app): # sbr file based antenna should only work for SBR+ solution. assert not hfss_terminal.create_sbr_file_based_antenna( - ffd_full_path=os.path.join(local_path, "example_models", test_subfolder, "test.ffd") + far_field_data=os.path.join(local_path, "example_models", test_subfolder, "test.ffd") ) @pytest.mark.skipif(is_linux, reason="Not supported.") diff --git a/_unittest/test_05_Mesh.py b/_unittest/test_05_Mesh.py index 5bb44abb903..fe73eb8ebce 100644 --- a/_unittest/test_05_Mesh.py +++ b/_unittest/test_05_Mesh.py @@ -61,7 +61,7 @@ def test_03_assign_surface_mesh_manual(self): udp = self.aedtapp.modeler.Position(20, 20, 0) coax_dimension = 200 o = self.aedtapp.modeler.create_cylinder(self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "surface_manual") - surface = self.aedtapp.mesh.assign_surface_mesh_manual(o.id, 1e-6, aspect_ratio=3, meshop_name="Surface_Manual") + surface = self.aedtapp.mesh.assign_surface_mesh_manual(o.id, 1e-6, aspect_ratio=3, name="Surface_Manual") assert "Surface_Manual" in [i.name for i in self.aedtapp.mesh.meshoperations] assert surface.props["SurfDev"] == 1e-6 surface.props["SurfDev"] = 1e-05 @@ -123,7 +123,7 @@ def test_06_curvature_extraction(self): def test_07_maxwell_mesh(self, add_app): m3d = add_app(application=Maxwell3d) o = m3d.modeler.create_box([0, 0, 0], [10, 10, 10], name="Box_Mesh") - rot = m3d.mesh.assign_rotational_layer(o.name, meshop_name="Rotational", total_thickness="5mm") + rot = m3d.mesh.assign_rotational_layer(o.name, total_thickness="5mm", name="Rotational") assert rot.props["Number of Layers"] == "3" rot.props["Number of Layers"] = 1 assert str(rot.props["Number of Layers"]) == m3d.odesign.GetChildObject("Mesh").GetChildObject( @@ -135,14 +135,14 @@ def test_07_maxwell_mesh(self, add_app): rot.name ).GetPropValue("Total Layer Thickness") - edge_cut = m3d.mesh.assign_edge_cut(o.name, meshop_name="Edge") + edge_cut = m3d.mesh.assign_edge_cut(o.name, name="Edge") assert edge_cut.props["Layer Thickness"] == "1mm" edge_cut.props["Layer Thickness"] = "2mm" assert edge_cut.props["Layer Thickness"] == m3d.odesign.GetChildObject("Mesh").GetChildObject( edge_cut.name ).GetPropValue("Layer Thickness") - dens = m3d.mesh.assign_density_control(o.name, maxelementlength=10000, meshop_name="Density") + dens = m3d.mesh.assign_density_control(o.name, maximum_element_length=10000, name="Density") assert dens.props["RestrictMaxElemLength"] assert dens.props["MaxElemLength"] == 10000 diff --git a/_unittest/test_08_Primitives3D.py b/_unittest/test_08_Primitives3D.py index fbccb275aeb..08407b71e86 100644 --- a/_unittest/test_08_Primitives3D.py +++ b/_unittest/test_08_Primitives3D.py @@ -9,6 +9,7 @@ from pyaedt import Icepak from pyaedt import Q2d from pyaedt import generate_unique_name +from pyaedt import is_linux from pyaedt.generic.constants import AXIS from pyaedt.modeler.cad.Primitives import PolylineSegment from pyaedt.modeler.cad.components_3d import UserDefinedComponent @@ -279,7 +280,7 @@ def test_11c_check_object_faces(self): assert isinstance(f.area, float) and f.area > 0 assert o.faces[0].move_with_offset(0.1) assert o.faces[0].move_with_vector([0, 0, 0.01]) - assert type(f.normal) is list + assert isinstance(f.normal, list) def test_11d_check_object_edges(self): o = self.create_copper_box(name="MyBox") @@ -295,7 +296,7 @@ def test_11e_check_object_vertices(self): def test_12_get_objects_in_group(self): objs = self.aedtapp.modeler.get_objects_in_group("Solids") - assert type(objs) is list + assert isinstance(objs, list) def test_13_create_circle(self): udp = self.aedtapp.modeler.Position(5, 3, 8) @@ -1149,18 +1150,22 @@ def test_61_get_closest_edge_to_position(self): my_box = self.create_copper_box("test_closest_edge") assert isinstance(self.aedtapp.modeler.get_closest_edgeid_to_position([0.2, 0, 0]), int) - @pytest.mark.skipif(config["NonGraphical"], reason="Not running in non-graphical mode") + @pytest.mark.skipif(config["NonGraphical"] or is_linux, reason="Not running in non-graphical mode or in Linux") def test_62_import_space_claim(self): self.aedtapp.insert_design("SCImport") assert self.aedtapp.modeler.import_spaceclaim_document(self.scdoc_file) assert len(self.aedtapp.modeler.objects) == 1 + @pytest.mark.skipif(is_linux, reason="Not running in Linux with AEDT 2024R1") def test_63_import_step(self): self.aedtapp.insert_design("StepImport") assert self.aedtapp.modeler.import_3d_cad(self.step_file) assert len(self.aedtapp.modeler.object_names) == 1 def test_64_create_3dcomponent(self): + if is_linux: + self.aedtapp.insert_design("StepImport") + self.create_copper_box("Solid") self.aedtapp.solution_type = "Modal" for i in list(self.aedtapp.modeler.objects.keys()): self.aedtapp.modeler.objects[i].material_name = "copper" @@ -1788,29 +1793,35 @@ def test_85_insert_layoutcomponent(self): ) self.aedtapp.solution_type = "Terminal" comp = self.aedtapp.modeler.insert_layout_component(self.layout_component, name=None, parameter_mapping=False) + assert comp.layout_component.edb_object + comp2 = self.aedtapp.modeler.insert_layout_component(self.layout_component, name=None, parameter_mapping=False) + assert comp2.layout_component.edb_object + assert comp.layout_component.edb_object assert comp.name in self.aedtapp.modeler.layout_component_names assert isinstance(comp, UserDefinedComponent) assert len(self.aedtapp.modeler.user_defined_components[comp.name].parts) == 3 - comp2 = self.aedtapp.modeler.insert_layout_component( + assert comp.layout_component.edb_object + comp3 = self.aedtapp.modeler.insert_layout_component( self.layout_component, name="new_layout", parameter_mapping=True ) - assert isinstance(comp2, UserDefinedComponent) - assert len(comp2.parameters) == 2 - assert comp2.layout_component.show_layout - comp2.layout_component.show_layout = False - assert not comp2.layout_component.show_layout - comp2.layout_component.show_layout = True - comp2.layout_component.fast_transformation = True - assert comp2.layout_component.fast_transformation - comp2.layout_component.fast_transformation = False - assert comp2.layout_component.show_dielectric - comp2.layout_component.show_dielectric = False - assert not comp2.layout_component.show_dielectric - assert comp2.layout_component.display_mode == 0 - comp2.layout_component.display_mode = 1 - assert comp2.layout_component.display_mode == 1 - comp2.layout_component.layers["Trace"] = [True, True, 90] - assert comp2.layout_component.update_visibility() + assert isinstance(comp3, UserDefinedComponent) + assert len(comp3.parameters) == 2 + assert comp3.layout_component.show_layout + comp3.layout_component.show_layout = False + assert not comp3.layout_component.show_layout + comp3.layout_component.show_layout = True + comp3.layout_component.fast_transformation = True + assert comp3.layout_component.fast_transformation + comp3.layout_component.fast_transformation = False + assert comp3.layout_component.show_dielectric + comp3.layout_component.show_dielectric = False + assert not comp3.layout_component.show_dielectric + assert comp3.layout_component.display_mode == 0 + comp3.layout_component.display_mode = 1 + assert comp3.layout_component.display_mode == 1 + comp3.layout_component.layers["Trace"] = [True, True, 90] + assert comp3.layout_component.update_visibility() + assert comp.layout_component.close_edb_object() def test_87_set_mesh_fusion_settings(self): self.aedtapp.insert_design("MeshFusionSettings") @@ -1822,35 +1833,31 @@ def test_87_set_mesh_fusion_settings(self): obj2_3dcomp = self.aedtapp.modeler.replace_3dcomponent( object_list=[box2.name], ) - assert self.aedtapp.set_mesh_fusion_settings(component=obj2_3dcomp.name, volume_padding=None, priority=None) + assert self.aedtapp.set_mesh_fusion_settings(assignment=obj2_3dcomp.name, volume_padding=None, priority=None) assert self.aedtapp.set_mesh_fusion_settings( - component=[obj_3dcomp.name, obj2_3dcomp.name, "Dummy"], volume_padding=None, priority=None + assignment=[obj_3dcomp.name, obj2_3dcomp.name, "Dummy"], volume_padding=None, priority=None ) assert self.aedtapp.set_mesh_fusion_settings( - component=[obj_3dcomp.name, obj2_3dcomp.name], + assignment=[obj_3dcomp.name, obj2_3dcomp.name], volume_padding=[[0, 5, 0, 0, 0, 1], [0, 0, 0, 2, 0, 0]], priority=None, ) assert not self.aedtapp.set_mesh_fusion_settings( - component=[obj_3dcomp.name, obj2_3dcomp.name], volume_padding=[[0, 0, 0, 2, 0, 0]], priority=None + assignment=[obj_3dcomp.name, obj2_3dcomp.name], volume_padding=[[0, 0, 0, 2, 0, 0]], priority=None ) assert self.aedtapp.set_mesh_fusion_settings( - component=[obj_3dcomp.name, obj2_3dcomp.name], volume_padding=None, priority=[obj2_3dcomp.name, "Dummy"] + assignment=[obj_3dcomp.name, obj2_3dcomp.name], volume_padding=None, priority=[obj2_3dcomp.name, "Dummy"] ) assert self.aedtapp.set_mesh_fusion_settings( - component=[obj_3dcomp.name, obj2_3dcomp.name], + assignment=[obj_3dcomp.name, obj2_3dcomp.name], volume_padding=[[0, 5, 0, 0, 0, 1], [10, 0, 0, 2, 0, 0]], priority=[obj_3dcomp.name], ) - assert self.aedtapp.set_mesh_fusion_settings( - component=None, - volume_padding=None, - priority=None, - ) + assert self.aedtapp.set_mesh_fusion_settings(assignment=None, volume_padding=None, priority=None) def test_88_import_primitives_file_json(self): self.aedtapp.insert_design("PrimitiveFromFile") diff --git a/_unittest/test_11_Setup.py b/_unittest/test_11_Setup.py index 608f3e6b527..b97a6c8a584 100644 --- a/_unittest/test_11_Setup.py +++ b/_unittest/test_11_Setup.py @@ -57,9 +57,9 @@ def test_01b_create_hfss_sweep(self): sweep1.props["SaveFields"] = True assert sweep1.update() assert self.aedtapp.get_sweeps("My_HFSS_Setup") - sweep2 = setup1.add_sweep(sweepname="test_sweeptype", sweeptype="invalid") + sweep2 = setup1.add_sweep(name="test_sweeptype", sweep_type="invalid") assert sweep2.props["Type"] == "Interpolating" - sweep3 = setup1.create_frequency_sweep(freqstart=1, freqstop="500MHz") + sweep3 = setup1.create_frequency_sweep(start_frequency=1, stop_frequency="500MHz") assert sweep3.props["Type"] == "Discrete" sweep4 = setup1.create_frequency_sweep("GHz", 23, 25, 401, sweep_type="Fast") assert sweep4.props["Type"] == "Fast" diff --git a/_unittest/test_12_1_PostProcessing.py b/_unittest/test_12_1_PostProcessing.py index d08731659e0..8866fe26f03 100644 --- a/_unittest/test_12_1_PostProcessing.py +++ b/_unittest/test_12_1_PostProcessing.py @@ -92,31 +92,35 @@ def test_01B_Field_Plot(self): mesh_file_path = self.aedtapp.post.export_mesh_obj(setup_name, intrinsic) assert os.path.exists(mesh_file_path) + min_value = self.aedtapp.post.get_scalar_field_value( + "E", "Minimum", setup_name, intrinsics="5GHz", is_vector=True + ) + @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="Not running in ironpython") def test_01_Animate_plt(self): cutlist = ["Global:XY"] phases = [str(i * 5) + "deg" for i in range(2)] model_gif = self.aedtapp.post.plot_animated_field( quantity="Mag_E", - object_list=cutlist, + assignment=cutlist, plot_type="CutPlane", - setup_name=self.aedtapp.nominal_adaptive, + setup=self.aedtapp.nominal_adaptive, intrinsics={"Freq": "5GHz", "Phase": "0deg"}, - export_path=self.local_scratch.path, variation_variable="Phase", - variation_list=phases, + variations=phases, show=False, export_gif=True, + export_path=self.local_scratch.path, ) assert os.path.exists(model_gif.gif_file) setup_name = self.aedtapp.existing_analysis_sweeps[0] intrinsic = {"Freq": "5GHz", "Phase": "180deg"} pl1 = self.aedtapp.post.create_fieldplot_volume("NewObject_IJD39Q", "Mag_E", setup_name, intrinsic) model_gif2 = self.aedtapp.post.animate_fields_from_aedtplt( - plotname=pl1.name, + plot_name=pl1.name, plot_folder=None, variation_variable="Phase", - variation_list=phases, + variations=phases, project_path="", export_gif=False, show=False, @@ -136,9 +140,7 @@ def test_02_export_fields(self): plot2 = self.aedtapp.post.create_fieldplot_volume(vollist, quantity_name2, setup_name, intrinsic) self.aedtapp.post.export_field_jpg( - os.path.join(self.local_scratch.path, "prova2.jpg"), - plot2.name, - plot2.plotFolder, + os.path.join(self.local_scratch.path, "prova2.jpg"), plot2.name, plot2.plot_folder ) assert os.path.exists(os.path.join(self.local_scratch.path, "prova2.jpg")) assert os.path.exists( @@ -225,7 +227,7 @@ def test_07_export_fields_from_Calculator(self): os.path.join(self.local_scratch.path, "Efield.fld"), grid_stop=[5, 5, 5], grid_step=[0.5, 0.5, 0.5], - isvector=True, + is_vector=True, intrinsics="5GHz", ) assert os.path.exists(os.path.join(self.local_scratch.path, "Efield.fld")) @@ -235,10 +237,10 @@ def test_07_export_fields_from_Calculator(self): "Setup1 : LastAdaptive", self.aedtapp.available_variations.nominal_w_values_dict, os.path.join(self.local_scratch.path, "MagEfieldSph.fld"), - gridtype="Spherical", + grid_type="Spherical", grid_stop=[5, 300, 300], grid_step=[5, 50, 50], - isvector=False, + is_vector=False, intrinsics="5GHz", ) assert os.path.exists(os.path.join(self.local_scratch.path, "MagEfieldSph.fld")) @@ -248,10 +250,10 @@ def test_07_export_fields_from_Calculator(self): "Setup1 : LastAdaptive", self.aedtapp.available_variations.nominal_w_values_dict, os.path.join(self.local_scratch.path, "MagEfieldCyl.fld"), - gridtype="Cylindrical", + grid_type="Cylindrical", grid_stop=[5, 300, 5], grid_step=[5, 50, 5], - isvector=False, + is_vector=False, intrinsics="5GHz", ) assert os.path.exists(os.path.join(self.local_scratch.path, "MagEfieldCyl.fld")) @@ -272,11 +274,9 @@ def test_09_manipulate_report(self): assert self.aedtapp.post.create_report( expressions="MaxMagDeltaS", variations={"Pass": ["All"]}, - setup_sweep_name="Setup1 : AdaptivePass", primary_sweep_variable="Pass", report_category="Modal Solution Data", plot_type="Rectangular Plot", - plotname="Solution Convergence Plot", ) new_report = self.aedtapp.post.reports_by_category.modal_solution("dB(S(1,1))") assert new_report.create() @@ -286,6 +286,11 @@ def test_09_manipulate_report(self): assert data.expressions[0] == "S(1,1)" assert len(self.aedtapp.post.all_report_names) > 0 + new_report = self.aedtapp.post.reports_by_category.modal_solution( + "dB(S(1,1))", setup=self.aedtapp.nominal_sweep + ) + assert new_report.create() + def test_09c_import_into_report(self): new_report = self.aedtapp.create_scattering("import_test") csv_file_path = self.aedtapp.post.export_report_to_csv(self.local_scratch.path, "import_test") @@ -501,13 +506,13 @@ def test_14_Field_Ploton_cutplanedesignname(self): assert plot1.update_field_plot_settings() self.aedtapp.logger.info("Generating the image") plot_obj = self.aedtapp.post.plot_field_from_fieldplot( - plotname=plot1.name, + plot_name=plot1.name, project_path=self.local_scratch.path, - meshplot=False, - imageformat="jpg", + mesh_plot=False, + image_format="jpg", view="xy", - show=False, plot_label=plot1.name + " label", + show=False, ) assert os.path.exists(plot_obj.image_file) os.unlink(plot_obj.image_file) @@ -526,13 +531,13 @@ def test_14_Field_Ploton_cutplanedesignname(self): assert os.path.exists(plot_obj.image_file) plot_obj = self.aedtapp.post.plot_field_from_fieldplot( - plotname=plot1.name, + plot_name=plot1.name, project_path=self.local_scratch.path, - meshplot=False, - imageformat="jpg", + mesh_plot=False, + image_format="jpg", view="xy", - show=False, plot_label=plot1.name + " label", + show=False, file_format="aedtplt", ) assert os.path.exists(plot_obj.image_file) @@ -555,13 +560,13 @@ def test_14B_Field_Ploton_Vector(self): "Vector_E", cutlist, "CutPlane", - setup_name=setup_name, + setup=setup_name, intrinsics=intrinsic, - export_path=self.local_scratch.path, mesh_on_fields=False, - imageformat="jpg", view="isometric", show=False, + export_path=self.local_scratch.path, + image_format="jpg", ) assert os.path.exists(plot_obj.image_file) @@ -580,11 +585,11 @@ def test_15_export_plot(self): def test_16_create_field_plot(self): cutlist = ["Global:XY"] plot = self.aedtapp.post._create_fieldplot( - objlist=cutlist, - quantityName="Mag_E", - setup_name=self.aedtapp.nominal_adaptive, + assignment=cutlist, + quantity="Mag_E", + setup=self.aedtapp.nominal_adaptive, intrinsics={}, - listtype="CutPlane", + list_type="CutPlane", ) assert plot @@ -628,7 +633,7 @@ def test_61_export_mesh(self): def test_67_sweep_from_json(self): local_path = os.path.dirname(os.path.realpath(__file__)) dict_vals = read_json(os.path.join(local_path, "example_models", "report_json", "Modal_Report_Simple.json")) - assert self.aedtapp.post.create_report_from_configuration(input_dict=dict_vals) + assert self.aedtapp.post.create_report_from_configuration(report_settings=dict_vals) @pytest.mark.skipif( config["desktopVersion"] < "2022.2", reason="Not working in non graphical in version lower than 2022.2" diff --git a/_unittest/test_12_PostProcessing.py b/_unittest/test_12_PostProcessing.py index aced256c218..fe62f2c793c 100644 --- a/_unittest/test_12_PostProcessing.py +++ b/_unittest/test_12_PostProcessing.py @@ -33,6 +33,7 @@ m2d_file = "m2d_field_lines_test" test_circuit_name = "Switching_Speed_FET_And_Diode" +test_emi_name = "EMI_RCV_241" eye_diagram = "SimpleChannel" ami = "ami" ipk_post_proj = "for_icepak_post" @@ -52,6 +53,12 @@ def circuit_test(add_app): return app +@pytest.fixture(scope="class") +def emi_receiver_test(add_app): + app = add_app(project_name=test_emi_name, design_name="CE_band", application=Circuit, subfolder=test_subfolder) + return app + + @pytest.fixture(scope="class") def diff_test(add_app, circuit_test): app = add_app(project_name=circuit_test.project_name, design_name="diff", application=Circuit, just_open=True) @@ -96,7 +103,7 @@ def ami_test(add_app, q3dtest): @pytest.fixture(scope="class") def array_test(add_app, q3dtest): - app = add_app(project_name=array, subfolder=test_subfolder) + app = add_app(project_name=array, subfolder=test_subfolder, solution_type="Modal") return app @@ -124,9 +131,9 @@ def test_09_manipulate_report(self, field_test): variations=variations, primary_sweep_variable="Phi", secondary_sweep_variable="Theta", + report_category="Far Fields", plot_type="3D Polar Plot", context=context, - report_category="Far Fields", ) assert field_test.post.create_report( "db(GainTotal)", @@ -134,9 +141,9 @@ def test_09_manipulate_report(self, field_test): variations=variations, primary_sweep_variable="Phi", secondary_sweep_variable="Theta", + report_category="Far Fields", plot_type="3D Polar Plot", context="3D", - report_category="Far Fields", ) report = AnsysReport() report.create() @@ -165,6 +172,11 @@ def test_09_manipulate_report_B(self, field_test): ) new_report3.report_type = "Data Table" assert new_report3.create() + new_report4 = field_test.post.reports_by_category.antenna_parameters( + "db(PeakRealizedGain)", infinite_sphere="3D" + ) + new_report4.report_type = "Data Table" + assert new_report4.create() def test_09_manipulate_report_C(self, field_test): variations = field_test.available_variations.nominal_w_values_dict @@ -177,8 +189,8 @@ def test_09_manipulate_report_C(self, field_test): field_test.nominal_adaptive, variations=variations, primary_sweep_variable="Theta", - context="3D", report_category="Far Fields", + context="3D", ) assert data.plot(is_polar=True) assert data.plot_3d() @@ -195,8 +207,8 @@ def test_09_manipulate_report_D(self, field_test): field_test.nominal_adaptive, variations=variations, primary_sweep_variable="Theta", - context=context, report_category="Far Fields", + context=context, ) assert data.plot(is_polar=True) assert data.plot_3d() @@ -205,10 +217,7 @@ def test_09_manipulate_report_D(self, field_test): assert len(data.data_magnitude("GainTotal")) > 0 assert not data.data_magnitude("GainTotal2") assert field_test.post.create_report( - "S(1,1)", - field_test.nominal_sweep, - variations=variations, - plot_type="Smith Chart", + "S(1,1)", field_test.nominal_sweep, variations=variations, plot_type="Smith Chart" ) def test_09_manipulate_report_E(self, field_test): @@ -216,36 +225,39 @@ def test_09_manipulate_report_E(self, field_test): variations2 = field_test.available_variations.nominal_w_values_dict assert field_test.setups[0].create_report( - "Mag_E", - primary_sweep_variable="Distance", - context="Poly1", - report_category="Fields", + "Mag_E", primary_sweep_variable="Distance", report_category="Fields", context="Poly1" ) new_report = field_test.post.reports_by_category.fields("Mag_H", field_test.nominal_adaptive) new_report.variations = variations2 new_report.polyline = "Poly1" assert new_report.create() + new_report = field_test.post.reports_by_category.fields("Mag_H") + new_report.variations = variations2 + new_report.polyline = "Poly1" + assert new_report.create() new_report = field_test.post.reports_by_category.modal_solution("S(1,1)") new_report.report_type = "Smith Chart" assert new_report.create() data = field_test.setups[0].get_solution_data( - "Mag_E", - variations=variations2, - primary_sweep_variable="Theta", - context="Poly1", - report_category="Fields", + "Mag_E", variations=variations2, primary_sweep_variable="Theta", report_category="Fields", context="Poly1" ) assert data.units_sweeps["Phase"] == "deg" assert field_test.post.get_far_field_data( - setup_sweep_name=field_test.nominal_adaptive, expression="RealizedGainTotal", domain="3D" + expressions="RealizedGainTotal", setup_sweep_name=field_test.nominal_adaptive, domain="3D" ) data_farfield2 = field_test.post.get_far_field_data( + expressions="RealizedGainTotal", setup_sweep_name=field_test.nominal_adaptive, - expression="RealizedGainTotal", domain={"Context": "3D", "SourceContext": "1:1"}, ) - assert data_farfield2.plot(math_formula="db20", is_polar=True) + assert data_farfield2.plot(formula="db20", is_polar=True) + + assert field_test.post.reports_by_category.terminal_solution() + + assert not field_test.post.get_solution_data_per_variation( + solution_type="Far Fields", expressions="RealizedGainTotal" + ) def test_09b_export_report_A(self, circuit_test): files = circuit_test.export_results() @@ -300,6 +312,8 @@ def test_17_circuit(self, circuit_test): new_report.time_stop = "190ns" new_report.plot_continous_spectrum = True assert new_report.create() + new_report = circuit_test.post.reports_by_category.spectral(["dB(V(net_11))"]) + assert new_report.create() new_report = circuit_test.post.reports_by_category.spectral(["dB(V(net_11))", "dB(V(Port1))"], "Transient") new_report.window = "Kaiser" new_report.adjust_coherent_gain = False @@ -310,9 +324,7 @@ def test_17_circuit(self, circuit_test): new_report.time_stop = "190ns" new_report.plot_continous_spectrum = False assert new_report.create() - assert circuit_test.post.create_report( - ["dB(V(net_11))", "dB(V(Port1))"], domain="Spectrum", setup_sweep_name="Transient" - ) + assert circuit_test.post.create_report(["dB(V(net_11))", "dB(V(Port1))"], domain="Spectrum") new_report = circuit_test.post.reports_by_category.spectral(None, "Transient") new_report.window = "Hanning" new_report.max_freq = "1GHz" @@ -361,18 +373,18 @@ def test_18_diff_plot(self, diff_test): context="Differential Pairs", ) assert data1.primary_sweep == "Freq" - data1.plot(math_formula="db20") + data1.plot(formula="db20", snapshot_path=os.path.join(self.local_scratch.path, "temp1.jpg")) data1.primary_sweep = "l1" assert data1.primary_sweep == "l1" assert len(data1.data_magnitude()) == 5 - assert data1.plot("S(Diff1, Diff1)") - assert data1.plot(math_formula="db20") - assert data1.plot(math_formula="db10") - assert data1.plot(math_formula="mag") - assert data1.plot(math_formula="re") - assert data1.plot(math_formula="im") - assert data1.plot(math_formula="phasedeg") - assert data1.plot(math_formula="phaserad") + assert data1.plot("S(Diff1, Diff1)", snapshot_path=os.path.join(self.local_scratch.path, "temp2.jpg")) + assert data1.plot(formula="db20", snapshot_path=os.path.join(self.local_scratch.path, "temp3.jpg")) + assert data1.plot(formula="db10", snapshot_path=os.path.join(self.local_scratch.path, "temp4.jpg")) + assert data1.plot(formula="mag", snapshot_path=os.path.join(self.local_scratch.path, "temp5.jpg")) + assert data1.plot(formula="re", snapshot_path=os.path.join(self.local_scratch.path, "temp6.jpg")) + assert data1.plot(formula="im", snapshot_path=os.path.join(self.local_scratch.path, "temp7.jpg")) + assert data1.plot(formula="phasedeg", snapshot_path=os.path.join(self.local_scratch.path, "temp8.jpg")) + assert data1.plot(formula="phaserad", snapshot_path=os.path.join(self.local_scratch.path, "temp9.jpg")) assert diff_test.create_touchstone_report( plot_name="Diff_plot", @@ -392,10 +404,7 @@ def test_55_time_plot(self, sbr_test): sbr_test.analyze(sbr_test.active_setup, use_auto_settings=False) assert sbr_test.setups[0].is_solved solution_data = sbr_test.post.get_solution_data( - expressions=["NearEX", "NearEY", "NearEZ"], - # variations={"_u": ["All"], "_v": ["All"], "Freq": ["All"]}, - context="Near_Field", - report_category="Near Fields", + expressions=["NearEX", "NearEY", "NearEZ"], report_category="Near Fields", context="Near_Field" ) assert solution_data assert len(solution_data.primary_sweep_values) > 0 @@ -405,15 +414,11 @@ def test_55_time_plot(self, sbr_test): t_matrix = solution_data.ifft("NearE", window=True) assert t_matrix.any() frames_list = solution_data.ifft_to_file( - coord_system_center=[-0.15, 0, 0], db_val=True, csv_dir=os.path.join(sbr_test.working_directory, "csv") + coord_system_center=[-0.15, 0, 0], db_val=True, csv_path=os.path.join(sbr_test.working_directory, "csv") ) assert os.path.exists(frames_list) sbr_test.post.plot_scene( - frames_list, - os.path.join(sbr_test.working_directory, "animation.gif"), - norm_index=5, - dy_rng=35, - show=False, + frames_list, os.path.join(sbr_test.working_directory, "animation.gif"), norm_index=5, dy_rng=35, show=False ) assert os.path.exists(os.path.join(sbr_test.working_directory, "animation.gif")) sbr_test.post.plot_scene( @@ -595,13 +600,13 @@ def test_70_far_field_data(self): assert ffdata.origin == [0, 0, 1] img1 = os.path.join(self.local_scratch.path, "ff_2d1.jpg") - ffdata.plot_2d_cut(secondary_sweep_value="all", primary_sweep="Theta", export_image_path=img1) + ffdata.plot_2d_cut(primary_sweep="Theta", secondary_sweep_value="all", image_path=img1) assert os.path.exists(img1) img2 = os.path.join(self.local_scratch.path, "ff_2d2.jpg") - ffdata.plot_2d_cut(secondary_sweep_value=[0, 1], export_image_path=img2) + ffdata.plot_2d_cut(secondary_sweep_value=[0, 1], image_path=img2) assert os.path.exists(img2) img3 = os.path.join(self.local_scratch.path, "ff_2d2.jpg") - ffdata.plot_2d_cut(export_image_path=img3) + ffdata.plot_2d_cut(image_path=img3) assert os.path.exists(img3) curve_2d = ffdata.plot_2d_cut(show=False) assert len(curve_2d[0]) == 3 @@ -610,127 +615,119 @@ def test_70_far_field_data(self): img4 = os.path.join(self.local_scratch.path, "ff_3d1.jpg") ffdata.polar_plot_3d_pyvista( - farfield_quantity="RealizedGain", - convert_to_db=True, + quantity="RealizedGain", + image_path=img4, show=False, - export_image_path=img4, background=[255, 0, 0], show_geometry=False, + convert_to_db=True, ) assert os.path.exists(img4) data_pyvista = ffdata.polar_plot_3d_pyvista( - farfield_quantity="RealizedGain", - convert_to_db=True, - show=False, - background=[255, 0, 0], - show_geometry=False, + quantity="RealizedGain", show=False, background=[255, 0, 0], show_geometry=False, convert_to_db=True ) assert data_pyvista @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="FarFieldSolution not supported by IronPython") def test_71_antenna_plot(self, field_test): - ffdata = field_test.get_antenna_ffd_solution_data(frequencies=30e9, sphere_name="3D") + ffdata = field_test.get_antenna_ffd_solution_data(frequencies=30e9, sphere="3D") ffdata.phase_offset = [0, 90] assert ffdata.phase_offset == [0, 90] ffdata.phase_offset = [0] assert ffdata.phase_offset != [0.0] assert ffdata.plot_farfield_contour( - farfield_quantity="RealizedGain", - convert_to_db=True, + quantity="RealizedGain", title="Contour at {}Hz".format(ffdata.frequency), - export_image_path=os.path.join(self.local_scratch.path, "contour.jpg"), + image_path=os.path.join(self.local_scratch.path, "contour.jpg"), + convert_to_db=True, ) assert os.path.exists(os.path.join(self.local_scratch.path, "contour.jpg")) ffdata.plot_2d_cut( + quantity="RealizedGain", primary_sweep="theta", secondary_sweep_value=[-180, -75, 75], - farfield_quantity="RealizedGain", title="Azimuth at {}Hz".format(ffdata.frequency), - export_image_path=os.path.join(self.local_scratch.path, "2d1.jpg"), + image_path=os.path.join(self.local_scratch.path, "2d1.jpg"), ) assert os.path.exists(os.path.join(self.local_scratch.path, "2d1.jpg")) ffdata.plot_2d_cut( + quantity="RealizedGain", primary_sweep="phi", secondary_sweep_value=30, - farfield_quantity="RealizedGain", title="Azimuth at {}Hz".format(ffdata.frequency), - export_image_path=os.path.join(self.local_scratch.path, "2d2.jpg"), + image_path=os.path.join(self.local_scratch.path, "2d2.jpg"), ) assert os.path.exists(os.path.join(self.local_scratch.path, "2d2.jpg")) ffdata.polar_plot_3d( - farfield_quantity="RealizedGain", - convert_to_db=True, - export_image_path=os.path.join(self.local_scratch.path, "3d1.jpg"), + quantity="RealizedGain", image_path=os.path.join(self.local_scratch.path, "3d1.jpg"), convert_to_db=True ) assert os.path.exists(os.path.join(self.local_scratch.path, "3d1.jpg")) ffdata.polar_plot_3d_pyvista( - farfield_quantity="RealizedGain", - convert_to_db=True, + quantity="RealizedGain", + image_path=os.path.join(self.local_scratch.path, "3d2.jpg"), show=False, - export_image_path=os.path.join(self.local_scratch.path, "3d2.jpg"), + convert_to_db=True, ) assert os.path.exists(os.path.join(self.local_scratch.path, "3d2.jpg")) try: - p = ffdata.polar_plot_3d_pyvista(farfield_quantity="RealizedGain", convert_to_db=True, show=False) + p = ffdata.polar_plot_3d_pyvista(quantity="RealizedGain", show=False, convert_to_db=True) assert isinstance(p, object) except Exception: assert True @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="FarFieldSolution not supported by IronPython") def test_72_antenna_plot(self, array_test): - ffdata = array_test.get_antenna_ffd_solution_data(frequencies=3.5e9, sphere_name="3D") + ffdata = array_test.get_antenna_ffd_solution_data(frequencies=3.5e9, sphere="3D") ffdata.frequency = 3.5e9 assert ffdata.plot_farfield_contour( - farfield_quantity="RealizedGain", - convert_to_db=True, + quantity="RealizedGain", title="Contour at {}Hz".format(ffdata.frequency), - export_image_path=os.path.join(self.local_scratch.path, "contour.jpg"), + image_path=os.path.join(self.local_scratch.path, "contour.jpg"), + convert_to_db=True, ) assert os.path.exists(os.path.join(self.local_scratch.path, "contour.jpg")) ffdata.plot_2d_cut( + quantity="RealizedGain", primary_sweep="theta", secondary_sweep_value=[-180, -75, 75], - farfield_quantity="RealizedGain", title="Azimuth at {}Hz".format(ffdata.frequency), - export_image_path=os.path.join(self.local_scratch.path, "2d1.jpg"), + image_path=os.path.join(self.local_scratch.path, "2d1.jpg"), ) assert os.path.exists(os.path.join(self.local_scratch.path, "2d1.jpg")) ffdata.plot_2d_cut( + quantity="RealizedGain", primary_sweep="phi", secondary_sweep_value=30, - farfield_quantity="RealizedGain", title="Azimuth at {}Hz".format(ffdata.frequency), - export_image_path=os.path.join(self.local_scratch.path, "2d2.jpg"), + image_path=os.path.join(self.local_scratch.path, "2d2.jpg"), ) assert os.path.exists(os.path.join(self.local_scratch.path, "2d2.jpg")) ffdata.polar_plot_3d( - farfield_quantity="RealizedGain", - convert_to_db=True, - export_image_path=os.path.join(self.local_scratch.path, "3d1.jpg"), + quantity="RealizedGain", image_path=os.path.join(self.local_scratch.path, "3d1.jpg"), convert_to_db=True ) assert os.path.exists(os.path.join(self.local_scratch.path, "3d1.jpg")) ffdata.polar_plot_3d_pyvista( - farfield_quantity="RealizedGain", - convert_to_db=True, + quantity="RealizedGain", + image_path=os.path.join(self.local_scratch.path, "3d2.jpg"), show=False, - export_image_path=os.path.join(self.local_scratch.path, "3d2.jpg"), + convert_to_db=True, ) assert os.path.exists(os.path.join(self.local_scratch.path, "3d2.jpg")) - ffdata1 = array_test.get_antenna_ffd_solution_data(frequencies=3.5e9, sphere_name="3D", overwrite=False) + ffdata1 = array_test.get_antenna_ffd_solution_data(frequencies=3.5e9, sphere="3D", overwrite=False) assert ffdata1.plot_farfield_contour( - farfield_quantity="RealizedGain", - convert_to_db=True, + quantity="RealizedGain", title="Contour at {}Hz".format(ffdata1.frequency), - export_image_path=os.path.join(self.local_scratch.path, "contour1.jpg"), + image_path=os.path.join(self.local_scratch.path, "contour1.jpg"), + convert_to_db=True, ) assert os.path.exists(os.path.join(self.local_scratch.path, "contour1.jpg")) @@ -738,35 +735,30 @@ def test_73_ami_solution_data(self, ami_test): ami_test.solution_type = "NexximAMI" assert ami_test.post.get_solution_data( expressions="WaveAfterProbe", - setup_sweep_name="AMIAnalysis", domain="Time", variations=ami_test.available_variations.nominal, ) assert ami_test.post.get_solution_data( expressions="WaveAfterSource", - setup_sweep_name="AMIAnalysis", domain="Time", variations=ami_test.available_variations.nominal, ) assert ami_test.post.get_solution_data( expressions="InitialWave", - setup_sweep_name="AMIAnalysis", domain="Time", variations=ami_test.available_variations.nominal, ) assert ami_test.post.get_solution_data( expressions="WaveAfterChannel", - setup_sweep_name="AMIAnalysis", domain="Time", variations=ami_test.available_variations.nominal, ) assert ami_test.post.get_solution_data( expressions="ClockTics", - setup_sweep_name="AMIAnalysis", domain="Clock Times", variations=ami_test.available_variations.nominal, ) @@ -841,7 +833,7 @@ def test_75_plot_field_line_traces(self, m2dtest): m2dtest.assign_voltage(rect.name, amplitude=0, name="Ground") m2dtest.assign_voltage(circle.name, amplitude=50e6, name="50kV") setup_name = "test" - m2dtest.create_setup(setupname=setup_name) + m2dtest.create_setup(name=setup_name) m2dtest.analyze_setup(setup_name) plot = m2dtest.post.create_fieldplot_line_traces(["Ground", "Electrode"], "Region", plot_name="LineTracesTest4") assert plot @@ -863,26 +855,44 @@ def test_75_plot_field_line_traces(self, m2dtest): el_id = [obj.id for obj in m2dtest.modeler.object_list if obj.name == "Electrode"] plot.seeding_faces.append(el_id[0]) assert plot.update() - plot.volume_indexes.append(el_id[0]) + plot.volumes.append(el_id[0]) plot.update() - plot.surfaces_indexes.append(el_id[0]) + plot.surfaces.append(el_id[0]) plot.update() plot.seeding_faces.append(8) assert not plot.update() - plot.volume_indexes.append(8) + plot.volumes.append(8) assert not plot.update() - plot.surfaces_indexes.append(8) + plot.surfaces.append(8) assert not plot.update() + @pytest.mark.skipif(config["desktopVersion"] < "2024.1", reason="EMI receiver available from 2024R1.") + def test_76_emi_receiver(self, emi_receiver_test): + emi_receiver_test.analyze() + new_report = emi_receiver_test.post.reports_by_category.emi_receiver() + new_report.band = "2" + new_report.emission = "RE" + new_report.time_start = "1ns" + new_report.time_stop = "2us" + new_report.net = "net_invented" + assert new_report.net != "net_invented" + assert new_report.create() + new_report2 = emi_receiver_test.post.reports_by_category.emi_receiver( + ["dBu(Average[net_6])", "dBu(Peak[net_6])", "dBu(QuasiPeak[net_6])", "dBu(RMS[net_6])"], "EMItransient" + ) + assert new_report2.net == "net_6" + new_report2.time_stop = "2.5us" + assert new_report2.create() + def test_98_get_variations(self, field_test): vars = field_test.available_variations.get_variation_strings() assert vars variations = field_test.available_variations.variations() - assert type(variations) is list - assert type(variations[0]) is list + assert isinstance(variations, list) + assert isinstance(variations[0], list) vars_dict = field_test.available_variations.variations(output_as_dict=True) - assert type(vars_dict) is list - assert type(vars_dict[0]) is dict + assert isinstance(vars_dict, list) + assert isinstance(vars_dict[0], dict) def test_z99_delete_variations(self, q3dtest): assert q3dtest.cleanup_solution() @@ -897,8 +907,8 @@ def test_76_ipk_get_scalar_field_value(self, icepak_post): "Heat_Flow_Rate", scalar_function="Integrate", solution=None, - variation_dict={"power_block": "0.25W", "power_source": "0.075W"}, - isvector=False, + variations={"power_block": "0.25W", "power_source": "0.075W"}, + is_vector=False, intrinsics=None, phase=None, object_name="cube2", @@ -909,8 +919,8 @@ def test_76_ipk_get_scalar_field_value(self, icepak_post): "Heat_Flow_Rate", scalar_function="Integrate", solution=None, - variation_dict={"power_block": "0.6W", "power_source": "0.15W"}, - isvector=False, + variations={"power_block": "0.6W", "power_source": "0.15W"}, + is_vector=False, intrinsics=None, phase=None, object_name="cube2", @@ -921,8 +931,8 @@ def test_76_ipk_get_scalar_field_value(self, icepak_post): "Heat_Flow_Rate", scalar_function="Integrate", solution=None, - variation_dict={"power_block": "0.6W", "power_source": "0.15W"}, - isvector=False, + variations={"power_block": "0.6W", "power_source": "0.15W"}, + is_vector=False, intrinsics=None, phase=None, object_name="cube2", @@ -933,8 +943,8 @@ def test_76_ipk_get_scalar_field_value(self, icepak_post): "Temperature", scalar_function="Maximum", solution=None, - variation_dict={"power_block": "0.6W", "power_source": "0.15W"}, - isvector=False, + variations={"power_block": "0.6W", "power_source": "0.15W"}, + is_vector=False, intrinsics=None, phase=None, object_name="cube1", @@ -945,8 +955,8 @@ def test_76_ipk_get_scalar_field_value(self, icepak_post): "Temperature", scalar_function="Maximum", solution=None, - variation_dict={"power_block": "0.6W", "power_source": "0.15W"}, - isvector=False, + variations={"power_block": "0.6W", "power_source": "0.15W"}, + is_vector=False, intrinsics=None, phase=None, object_name="cube2", @@ -957,8 +967,8 @@ def test_76_ipk_get_scalar_field_value(self, icepak_post): "Temperature", scalar_function="Value", solution=None, - variation_dict=None, - isvector=False, + variations=None, + is_vector=False, intrinsics=None, phase=None, object_name="Point1", diff --git a/_unittest/test_14_AedtLogger.py b/_unittest/test_14_AedtLogger.py index e8970cb1976..6693386a6b7 100644 --- a/_unittest/test_14_AedtLogger.py +++ b/_unittest/test_14_AedtLogger.py @@ -226,7 +226,7 @@ class TestLogMessages: """Class used to test log messages.""" def test_log_when_accessing_non_existing_object(self, caplog): - """Check that accessing non existing object log an error message.""" + """Check that accessing a non-existent object logs an error message.""" from pyaedt import Hfss app = Hfss( diff --git a/_unittest/test_16_3d_stackup.py b/_unittest/test_16_3d_stackup.py index a4655f14ae5..0a503983b66 100644 --- a/_unittest/test_16_3d_stackup.py +++ b/_unittest/test_16_3d_stackup.py @@ -3,7 +3,7 @@ @pytest.fixture(scope="class") def aedtapp(add_app): - app = add_app(project_name="Test_16") + app = add_app(project_name="Test_16", solution_type="Modal") return app diff --git a/_unittest/test_20_HFSS.py b/_unittest/test_20_HFSS.py index 3856d3d1b7b..06bfa1f9c8b 100644 --- a/_unittest/test_20_HFSS.py +++ b/_unittest/test_20_HFSS.py @@ -122,14 +122,14 @@ def test_05_create_wave_port_from_sheets(self): assert not self.aedtapp.wave_port(o5) port = self.aedtapp.wave_port( - signal=o5, - deembed=5, + assignment=o5, + reference=[outer_1.name], integration_line=self.aedtapp.AxisDir.XNeg, + modes=2, impedance=40, - num_modes=2, name="sheet1_Port", renormalize=False, - reference=[outer_1.name], + deembed=5, terminals_rename=False, ) @@ -143,15 +143,15 @@ def test_05_create_wave_port_from_sheets(self): self.aedtapp.modeler.subtract(o6, "inner_1", keep_originals=True) port = self.aedtapp.wave_port( - signal=o6, - deembed=0, + assignment=o6, + reference=[outer_1.name], + create_pec_cap=True, integration_line=self.aedtapp.AxisDir.XNeg, + modes=2, impedance=40, - num_modes=2, name="sheet1a_Port", renormalize=True, - reference=[outer_1.name], - create_pec_cap=True, + deembed=0, ) assert port.name == "sheet1a_Port" assert port.name in [i.name for i in self.aedtapp.boundaries] @@ -160,10 +160,7 @@ def test_05_create_wave_port_from_sheets(self): # Get the object for "outer_1". outer_1 = self.aedtapp.modeler["outer_1"] bottom_port = self.aedtapp.wave_port( - outer_1.bottom_face_z, - reference=outer_1.name, - create_pec_cap=True, - name="bottom_probe_port", + outer_1.bottom_face_z, reference=outer_1.name, create_pec_cap=True, name="bottom_probe_port" ) assert bottom_port.name == "bottom_probe_port" pec_objects = self.aedtapp.modeler.get_objects_by_material("pec") @@ -173,13 +170,13 @@ def test_05_create_wave_port_from_sheets(self): udp = self.aedtapp.modeler.Position(200, 0, 0) o6 = self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.YZ, udp, 10, name="sheet2") port = self.aedtapp.wave_port( - signal=o6, - deembed=5, + assignment=o6, integration_line=self.aedtapp.AxisDir.XPos, + modes=2, impedance=40, - num_modes=2, name="sheet2_Port", renormalize=True, + deembed=5, ) assert port.name == "sheet2_Port" assert port.name in [i.name for i in self.aedtapp.boundaries] @@ -189,13 +186,13 @@ def test_05_create_wave_port_from_sheets(self): id7 = self.aedtapp.modeler.create_box([20, 25, 30], [10, 2, 2], matname="Copper") rect = self.aedtapp.modeler.create_rectangle(self.aedtapp.PLANE.YZ, [20, 25, 20], [2, 10]) port3 = self.aedtapp.wave_port( - signal=rect, - deembed=5, + assignment=rect, integration_line=self.aedtapp.AxisDir.ZNeg, + modes=1, impedance=30, - num_modes=1, name="sheet3_Port", renormalize=False, + deembed=5, ) assert port3.name in [i.name for i in self.aedtapp.boundaries] @@ -209,29 +206,26 @@ def test_06a_create_linear_count_sweep(self): assert not self.aedtapp.setups[0].sweeps[0].is_solved assert self.aedtapp.create_linear_count_sweep("MySetup", "GHz", 0.8, 1.2, 401) assert self.aedtapp.create_linear_count_sweep( - setupname="MySetup", - sweepname="MySweep", - unit="MHz", - freqstart=1.1e3, - freqstop=1200.1, + setup="MySetup", + unit="GHz", + start_frequency=1.1e3, + stop_frequency=1200.1, num_of_freq_points=1234, sweep_type="Interpolating", ) assert self.aedtapp.create_linear_count_sweep( - setupname="MySetup", - sweepname="MySweep", + setup="MySetup", unit="MHz", - freqstart=1.1e3, - freqstop=1200.1, + start_frequency=1.1e3, + stop_frequency=1200.1, num_of_freq_points=1234, sweep_type="Interpolating", ) assert self.aedtapp.create_linear_count_sweep( - setupname="MySetup", - sweepname="MySweepFast", + setup="MySetup", unit="MHz", - freqstart=1.1e3, - freqstop=1200.1, + start_frequency=1.1e3, + stop_frequency=1200.1, num_of_freq_points=1234, sweep_type="Fast", ) @@ -240,11 +234,10 @@ def test_06a_create_linear_count_sweep(self): freq_stop = 1200.1 units = "MHz" sweep = self.aedtapp.create_linear_count_sweep( - setupname="MySetup", - sweepname=None, - unit=units, - freqstart=freq_start, - freqstop=freq_stop, + setup="MySetup", + unit="MHz", + start_frequency=freq_start, + stop_frequency=freq_stop, num_of_freq_points=num_points, ) assert sweep.props["RangeCount"] == num_points @@ -255,11 +248,10 @@ def test_06a_create_linear_count_sweep(self): # Create a linear count sweep with the incorrect sweep type. with pytest.raises(AttributeError) as execinfo: self.aedtapp.create_linear_count_sweep( - setupname="MySetup", - sweepname="IncorrectStep", + setup="MySetup", unit="MHz", - freqstart=1.1e3, - freqstop=1200.1, + start_frequency=1.1e3, + stop_frequency=1200.1, num_of_freq_points=1234, sweep_type="Incorrect", ) @@ -269,14 +261,14 @@ def test_06a_create_linear_count_sweep(self): ) self.aedtapp["der_var"] = "1mm" self.aedtapp["der_var2"] = "2mm" - setup2 = self.aedtapp.create_setup("MySetup_2", setuptype=0) + setup2 = self.aedtapp.create_setup("MySetup_2", setup_type=0) assert setup2.add_derivatives("der_var") assert "der_var" in setup2.get_derivative_variables() assert setup2.add_derivatives("der_var2") assert "der_var2" in setup2.get_derivative_variables() assert "der_var" in setup2.get_derivative_variables() setup2.delete() - setup3 = self.aedtapp.create_setup("MySetup_3", setuptype=0) + setup3 = self.aedtapp.create_setup("MySetup_3", setup_type=0) assert setup3.add_derivatives("der_var") assert "der_var" in setup3.get_derivative_variables() assert setup3.add_derivatives("der_var2") @@ -294,11 +286,11 @@ def test_06c_create_linear_step_sweep(self): freq_stop = 1200.1 units = "MHz" sweep = self.aedtapp.create_linear_step_sweep( - setupname="MySetup", - sweepname=None, + setup="MySetup", + name=None, unit=units, - freqstart=freq_start, - freqstop=freq_stop, + start_frequency=freq_start, + stop_frequency=freq_stop, step_size=step_size, ) assert sweep.props["RangeStep"] == str(step_size) + units @@ -311,11 +303,11 @@ def test_06c_create_linear_step_sweep(self): freq_stop = 1305.1 units = "MHz" sweep = self.aedtapp.create_linear_step_sweep( - setupname="MySetup", - sweepname="StepFast", + setup="MySetup", + name="StepFast", unit=units, - freqstart=freq_start, - freqstop=freq_stop, + start_frequency=freq_start, + stop_frequency=freq_stop, step_size=step_size, sweep_type="Fast", ) @@ -327,11 +319,11 @@ def test_06c_create_linear_step_sweep(self): # Create a linear step sweep with the incorrect sweep type. with pytest.raises(AttributeError) as execinfo: self.aedtapp.create_linear_step_sweep( - setupname="MySetup", - sweepname="StepFast", + setup="MySetup", + name="StepFast", unit=units, - freqstart=freq_start, - freqstop=freq_stop, + start_frequency=freq_start, + stop_frequency=freq_stop, step_size=step_size, sweep_type="Incorrect", ) @@ -342,7 +334,7 @@ def test_06c_create_linear_step_sweep(self): def test_06d_create_single_point_sweep(self): assert self.aedtapp.create_single_point_sweep( - setupname="MySetup", + setup="MySetup", unit="MHz", freq=1.2e3, ) @@ -353,22 +345,22 @@ def test_06d_create_single_point_sweep(self): save_single_field=False, ) assert self.aedtapp.create_single_point_sweep( - setupname="MySetup", + setup="MySetup", unit="GHz", freq=[1.1, 1.2, 1.3], ) assert self.aedtapp.create_single_point_sweep( - setupname="MySetup", unit="GHz", freq=[1.1e1, 1.2e1, 1.3e1], save_single_field=[True, False, True] + setup="MySetup", unit="GHz", freq=[1.1e1, 1.2e1, 1.3e1], save_single_field=[True, False, True] ) settings.enable_error_handler = True assert not self.aedtapp.create_single_point_sweep( - setupname="MySetup", unit="GHz", freq=[1, 2e2, 3.4], save_single_field=[True, False] + setup="MySetup", unit="GHz", freq=[1, 2e2, 3.4], save_single_field=[True, False] ) settings.enable_error_handler = False def test_06e_delete_setup(self): setup_name = "SetupToDelete" - setuptd = self.aedtapp.create_setup(setupname=setup_name) + setuptd = self.aedtapp.create_setup(name=setup_name) assert setuptd.name in self.aedtapp.existing_analysis_setups assert self.aedtapp.delete_setup(setup_name) assert setuptd.name not in self.aedtapp.existing_analysis_setups @@ -377,16 +369,16 @@ def test_06f_sweep_add_subrange(self): self.aedtapp.modeler.create_box([0, 0, 20], [10, 10, 5], "box_sweep", "Copper") self.aedtapp.modeler.create_box([0, 0, 30], [10, 10, 5], "box_sweep2", "Copper") self.aedtapp.wave_port( - signal="box_sweep", + assignment="box_sweep", reference="box_sweep2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, + modes=1, impedance=75, - num_modes=1, name="WaveForSweep", renormalize=False, ) - setup = self.aedtapp.create_setup(setupname="MySetupForSweep") + setup = self.aedtapp.create_setup(name="MySetupForSweep") assert not setup.get_sweep() sweep = setup.add_sweep() sweep1 = setup.get_sweep(sweep.name) @@ -403,17 +395,17 @@ def test_06g_sweep_clear_subrange(self): self.aedtapp.modeler.create_box([0, 0, 50], [10, 10, 5], "box_sweep3", "Copper") self.aedtapp.modeler.create_box([0, 0, 60], [10, 10, 5], "box_sweep4", "Copper") self.aedtapp.wave_port( - signal="box_sweep3", + assignment="box_sweep3", reference="box_sweep4", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, + modes=1, impedance=50, - num_modes=1, name="WaveForSweepWithClear", renormalize=False, ) - setup = self.aedtapp.create_setup(setupname="MySetupClearSweep") + setup = self.aedtapp.create_setup(name="MySetupClearSweep") sweep = setup.add_sweep() assert sweep.add_subrange("LinearCount", 1.1, 3.6, 10, "GHz", clear=True) assert sweep.props["RangeType"] == "LinearCount" @@ -484,13 +476,13 @@ def test_08_create_circuit_port_from_edges(self): assert ( self.aedtapp.circuit_port( - e1, e2, name="port10", impedance=50.1, renormalize=False, renorm_impedance="50" + e1, e2, impedance=50.1, name="port10", renormalize=False, renorm_impedance="50" ).name == "port10" ) assert ( self.aedtapp.circuit_port( - e1, e2, name="port11", impedance="50+1i*55", renormalize=True, renorm_impedance=15.4 + e1, e2, impedance="50+1i*55", name="port11", renormalize=True, renorm_impedance=15.4 ).name == "port11" ) @@ -507,11 +499,11 @@ def test_08_create_circuit_port_from_edges(self): self.aedtapp.solution_type = "Terminal" assert ( self.aedtapp.circuit_port( - e1, e2, name="port20", impedance=50.1, renormalize=False, renorm_impedance="50+1i*55" + e1, e2, impedance=50.1, name="port20", renormalize=False, renorm_impedance="50+1i*55" ).name == "port20" ) - bound = self.aedtapp.circuit_port(e1, e2, name="port32", impedance="50.1", renormalize=True) + bound = self.aedtapp.circuit_port(e1, e2, impedance="50.1", name="port32", renormalize=True) assert bound bound.name = "port21" assert bound.update() @@ -522,23 +514,23 @@ def test_09_create_waveport_on_objects(self): box2 = self.aedtapp.modeler.create_box([0, 0, 10], [10, 10, 5], "BoxWG2", "copper") box2.material_name = "Copper" port = self.aedtapp.wave_port( - signal="BoxWG1", + assignment="BoxWG1", reference="BoxWG2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, + modes=1, impedance=50, - num_modes=1, name="Wave1", renormalize=False, ) assert port.name == "Wave1" port2 = self.aedtapp.wave_port( - signal="BoxWG1", + assignment="BoxWG1", reference="BoxWG2", - integration_line=self.aedtapp.AxisDir.XPos, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XPos, + modes=2, impedance=25, - num_modes=2, name="Wave1", renormalize=True, deembed=5, @@ -547,24 +539,24 @@ def test_09_create_waveport_on_objects(self): assert port2.name != "Wave1" and "Wave1" in port2.name self.aedtapp.solution_type = "Terminal" assert self.aedtapp.wave_port( - signal="BoxWG1", + assignment="BoxWG1", reference="BoxWG2", - integration_line=self.aedtapp.AxisDir.XPos, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XPos, + modes=2, impedance=25, - num_modes=2, name="Wave3", renormalize=True, ) self.aedtapp.solution_type = "Modal" assert self.aedtapp.wave_port( - signal="BoxWG1", + assignment="BoxWG1", reference="BoxWG2", - integration_line=self.aedtapp.AxisDir.XPos, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XPos, + modes=2, impedance=25, - num_modes=2, name="Wave4", renormalize=True, deembed=5, @@ -579,11 +571,11 @@ def test_09a_create_waveport_on_true_surface_objects(self): cs, [0, 0, 0], radius=10, height=100, numSides=0, name="outer", matname="Copper" ) port1 = self.aedtapp.wave_port( - signal=o1.name, + assignment=o1.name, reference=o3.name, - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, create_pec_cap=True, + integration_line=self.aedtapp.AxisDir.XNeg, name="P1", ) assert port1.name.startswith("P1") @@ -594,29 +586,29 @@ def test_10_create_lumped_on_objects(self): box2 = self.aedtapp.modeler.create_box([0, 0, 60], [10, 10, 5], "BoxLumped2") box2.material_name = "Copper" port = self.aedtapp.lumped_port( - signal="BoxLumped1", + assignment="BoxLumped1", reference="BoxLumped2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=50, - renormalize=True, name="Lump1xx", + renormalize=True, ) assert not self.aedtapp.lumped_port( - signal="BoxLumped1111", + assignment="BoxLumped1111", reference="BoxLumped2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=50, - renormalize=True, name="Lump1xx", + renormalize=True, ) assert self.aedtapp.lumped_port( - signal="BoxLumped1", + assignment="BoxLumped1", reference="BoxLumped2", - integration_line=self.aedtapp.AxisDir.XPos, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XPos, impedance=50, ) @@ -624,14 +616,14 @@ def test_10_create_lumped_on_objects(self): port.name = "Lump1" assert port.update() port = self.aedtapp.lumped_port( - signal="BoxLumped1", + assignment="BoxLumped1", reference="BoxLumped2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=50, + name="Lump2", renormalize=False, deembed=True, - name="Lump2", ) def test_11_create_circuit_on_objects(self): @@ -652,11 +644,7 @@ def test_12_create_perfects_on_objects(self): self.aedtapp.insert_design("test_12") box1 = self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 5], "perfect1", "Copper") box2 = self.aedtapp.modeler.create_box([0, 0, 10], [10, 10, 5], "perfect2", "copper") - pe = self.aedtapp.create_perfecth_from_objects( - "perfect1", - "perfect2", - self.aedtapp.AxisDir.ZPos, - ) + pe = self.aedtapp.create_perfecth_from_objects("perfect1", "perfect2", self.aedtapp.AxisDir.ZPos) ph = self.aedtapp.create_perfecte_from_objects("perfect1", "perfect2", self.aedtapp.AxisDir.ZNeg) assert pe.name in self.aedtapp.modeler.get_boundaries_name() assert pe.update() @@ -679,14 +667,14 @@ def test_14_create_lumpedrlc_on_objects(self): box1 = self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 5], "rlc1", "Copper") box2 = self.aedtapp.modeler.create_box([0, 0, 10], [10, 10, 5], "rlc2", "copper") imp = self.aedtapp.create_lumped_rlc_between_objects( - box1.name, box2.name, self.aedtapp.AxisDir.XPos, Rvalue=50, Lvalue=1e-9 + box1.name, box2.name, self.aedtapp.AxisDir.XPos, resistance=50, inductance=1e-9 ) assert imp.name in self.aedtapp.modeler.get_boundaries_name() assert imp.update() box3 = self.aedtapp.modeler.create_box([0, 0, 20], [10, 10, 5], "rlc3", "copper") lumped_rlc2 = self.aedtapp.create_lumped_rlc_between_objects( - box2.name, box3.name, self.aedtapp.AxisDir.XPos, Rvalue=50, Lvalue=1e-9, Cvalue=1e-9 + box2.name, box3.name, self.aedtapp.AxisDir.XPos, resistance=50, inductance=1e-9, capacitance=1e-9 ) assert lumped_rlc2.name in self.aedtapp.modeler.get_boundaries_name() assert lumped_rlc2.update() @@ -719,7 +707,7 @@ def test_16_create_impedance_on_sheets(self): impedance_box = self.aedtapp.modeler.create_box([0, -100, 0], [200, 200, 200], "ImpedanceBox") ids = self.aedtapp.modeler.get_object_faces(impedance_box.name)[:3] - imp2 = self.aedtapp.assign_impedance_to_sheet(ids, sourcename="ImpedanceToFaces", resistance=60, reactance=-20) + imp2 = self.aedtapp.assign_impedance_to_sheet(ids, resistance=60, reactance=-20) assert imp2.name in self.aedtapp.modeler.get_boundaries_name() rect2 = self.aedtapp.modeler.create_rectangle( @@ -735,7 +723,9 @@ def test_17_create_lumpedrlc_on_sheets(self): rect = self.aedtapp.modeler.create_rectangle( self.aedtapp.PLANE.XY, [0, 0, 0], [10, 2], name="rlcBound", matname="Copper" ) - imp = self.aedtapp.assign_lumped_rlc_to_sheet(rect.name, self.aedtapp.AxisDir.XPos, Rvalue=50, Lvalue=1e-9) + imp = self.aedtapp.assign_lumped_rlc_to_sheet( + rect.name, self.aedtapp.AxisDir.XPos, resistance=50, inductance=1e-9 + ) names = self.aedtapp.modeler.get_boundaries_name() assert imp.name in self.aedtapp.modeler.get_boundaries_name() @@ -743,14 +733,14 @@ def test_17_create_lumpedrlc_on_sheets(self): self.aedtapp.PLANE.XY, [0, 0, 10], [10, 2], name="rlcBound2", matname="Copper" ) imp = self.aedtapp.assign_lumped_rlc_to_sheet( - rect.name, self.aedtapp.AxisDir.XPos, rlctype="Serial", Rvalue=50, Lvalue=1e-9 + rect.name, self.aedtapp.AxisDir.XPos, rlc_type="Serial", resistance=50, inductance=1e-9 ) names = self.aedtapp.modeler.get_boundaries_name() assert imp.name in self.aedtapp.modeler.get_boundaries_name() assert self.aedtapp.assign_lumped_rlc_to_sheet( - rect.name, [rect.bottom_edge_x.midpoint, rect.bottom_edge_y.midpoint], Lvalue=1e-9 + rect.name, [rect.bottom_edge_x.midpoint, rect.bottom_edge_y.midpoint], inductance=1e-9 ) - assert not self.aedtapp.assign_lumped_rlc_to_sheet(rect.name, [rect.bottom_edge_x.midpoint], Lvalue=1e-9) + assert not self.aedtapp.assign_lumped_rlc_to_sheet(rect.name, [rect.bottom_edge_x.midpoint], inductance=1e-9) def test_17B_update_assignment(self): bound = self.aedtapp.assign_perfecth_to_sheets(self.aedtapp.modeler["My_Box"].faces[0].id) @@ -773,44 +763,44 @@ def test_19_create_lumped_on_sheet(self): self.aedtapp.PLANE.XY, [0, 0, 0], [10, 2], name="lump_port", matname="Copper" ) port = self.aedtapp.lumped_port( - signal=rect.name, - integration_line=self.aedtapp.AxisDir.XNeg, + assignment=rect.name, create_port_sheet=False, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=50, - renormalize=True, name="Lump_sheet", + renormalize=True, ) assert port.name + ":1" in self.aedtapp.excitations port2 = self.aedtapp.lumped_port( - signal=rect.name, - integration_line=self.aedtapp.AxisDir.XNeg, + assignment=rect.name, create_port_sheet=False, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=50, - renormalize=True, name="Lump_sheet2", + renormalize=True, deembed=True, ) assert port2.name + ":1" in self.aedtapp.excitations port3 = self.aedtapp.lumped_port( - signal=rect.name, - integration_line=[rect.bottom_edge_x.midpoint, rect.bottom_edge_y.midpoint], + assignment=rect.name, create_port_sheet=False, + integration_line=[rect.bottom_edge_x.midpoint, rect.bottom_edge_y.midpoint], impedance=50, - renormalize=True, name="Lump_sheet3", + renormalize=True, deembed=True, ) assert port3.name + ":1" in self.aedtapp.excitations assert not self.aedtapp.lumped_port( - signal=rect.name, - integration_line=[rect.bottom_edge_x.midpoint], + assignment=rect.name, create_port_sheet=False, + integration_line=[rect.bottom_edge_x.midpoint], impedance=50, - renormalize=True, name="Lump_sheet4", + renormalize=True, deembed=True, ) @@ -830,6 +820,7 @@ def test_20_create_voltage_on_sheet(self): def test_21_create_open_region(self): assert self.aedtapp.create_open_region("1GHz") + assert len(self.aedtapp.field_setups) == 3 assert self.aedtapp.create_open_region("1GHz", "FEBI") assert self.aedtapp.create_open_region("1GHz", "PML", True, "-z") @@ -868,7 +859,7 @@ def test_30_assign_initial_mesh(self): def test_30a_add_mesh_link(self): self.aedtapp.duplicate_design(self.aedtapp.design_name) self.aedtapp.set_active_design(self.aedtapp.design_list[0]) - assert self.aedtapp.setups[0].add_mesh_link(design_name=self.aedtapp.design_list[1]) + assert self.aedtapp.setups[0].add_mesh_link(design=self.aedtapp.design_list[1]) meshlink_props = self.aedtapp.setups[0].props["MeshLink"] assert meshlink_props["Project"] == "This Project*" assert meshlink_props["PathRelativeTo"] == "TargetProject" @@ -876,25 +867,22 @@ def test_30a_add_mesh_link(self): assert meshlink_props["Soln"] == "MySetup : LastAdaptive" assert sorted(list(meshlink_props["Params"].keys())) == sorted(self.aedtapp.available_variations.variables) assert sorted(list(meshlink_props["Params"].values())) == sorted(self.aedtapp.available_variations.variables) - assert not self.aedtapp.setups[0].add_mesh_link(design_name="") + assert not self.aedtapp.setups[0].add_mesh_link(design="") assert self.aedtapp.setups[0].add_mesh_link( - design_name=self.aedtapp.design_list[1], solution_name="MySetup : LastAdaptive" + design=self.aedtapp.design_list[1], solution="MySetup : LastAdaptive" ) assert not self.aedtapp.setups[0].add_mesh_link( - design_name=self.aedtapp.design_list[1], solution_name="Setup_Test : LastAdaptive" + design=self.aedtapp.design_list[1], solution="Setup_Test : LastAdaptive" ) assert self.aedtapp.setups[0].add_mesh_link( - design_name=self.aedtapp.design_list[1], - parameters_dict=self.aedtapp.available_variations.nominal_w_values_dict, + design=self.aedtapp.design_list[1], parameters=self.aedtapp.available_variations.nominal_w_values_dict ) example_project = os.path.join( local_path, "../_unittest/example_models", test_subfolder, diff_proj_name + ".aedt" ) example_project_copy = os.path.join(self.local_scratch.path, diff_proj_name + "_copy.aedt") shutil.copyfile(example_project, example_project_copy) - assert self.aedtapp.setups[0].add_mesh_link( - design_name=self.aedtapp.design_list[1], project_name=example_project_copy - ) + assert self.aedtapp.setups[0].add_mesh_link(design=self.aedtapp.design_list[1], project=example_project_copy) def test_31_create_microstrip_port(self): self.aedtapp.insert_design("Microstrip") @@ -903,33 +891,33 @@ def test_31_create_microstrip_port(self): sub = self.aedtapp.modeler.create_box([0, 5, -2], [20, 100, 2], name="SUB1", matname="FR4_epoxy") gnd = self.aedtapp.modeler.create_box([0, 5, -2.2], [20, 100, 0.2], name="GND1", matname="FR4_epoxy") port = self.aedtapp.wave_port( - signal=gnd.name, + assignment=gnd.name, reference=ms.name, - integration_line=1, create_port_sheet=True, - is_microstrip=True, + integration_line=1, name="MS1", + is_microstrip=True, ) assert port.name == "MS1" assert port.update() self.aedtapp.solution_type = "Terminal" assert self.aedtapp.wave_port( - signal=gnd.name, + assignment=gnd.name, reference=ms.name, - integration_line=1, create_port_sheet=True, - is_microstrip=True, + integration_line=1, name="MS2", + is_microstrip=True, ) assert self.aedtapp.wave_port( - signal=gnd.name, + assignment=gnd.name, reference=ms.name, - integration_line=1, create_port_sheet=True, - is_microstrip=True, + integration_line=1, + impedance=77, name="MS3", deembed=1, - impedance=77, + is_microstrip=True, ) def test_32_get_property_value(self): @@ -1000,15 +988,15 @@ def test_42_floquet_port(self): box1 = self.aedtapp.modeler.create_box([-100, -100, -100], [200, 200, 200], name="Rad_box2") assert self.aedtapp.create_floquet_port( - box1.faces[0], deembed_dist=1, nummodes=7, reporter_filter=[False, True, False, False, False, False, False] + box1.faces[0], modes=7, deembed_distance=1, reporter_filter=[False, True, False, False, False, False, False] ) assert self.aedtapp.create_floquet_port( - box1.faces[1], deembed_dist=1, nummodes=7, reporter_filter=[False, True, False, False, False, False, False] + box1.faces[1], modes=7, deembed_distance=1, reporter_filter=[False, True, False, False, False, False, False] ) sheet = self.aedtapp.modeler.create_rectangle( self.aedtapp.PLANE.XY, [-100, -100, -100], [200, 200], name="RectangleForSource", matname="Copper" ) - bound = self.aedtapp.create_floquet_port(sheet, deembed_dist=1, nummodes=4, reporter_filter=False) + bound = self.aedtapp.create_floquet_port(sheet, modes=4, deembed_distance=1, reporter_filter=False) assert bound bound.name = "Floquet1" assert bound.update() @@ -1087,34 +1075,34 @@ def test_45_terminal_port(self): box2 = self.aedtapp.modeler.create_box([-100, -100, 20], [200, 200, 25], name="sig", matname="copper") sheet = self.aedtapp.modeler.create_rectangle(self.aedtapp.PLANE.YZ, [-100, -100, 5], [200, 15], "port") port = self.aedtapp.lumped_port( - signal=box1, + assignment=box1, reference=box2.name, - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=75, - renormalize=True, name="Lump1", + renormalize=True, ) assert "Lump1_T1" in self.aedtapp.excitations port2 = self.aedtapp.lumped_port( - signal=sheet.name, + assignment=sheet.name, reference=box1, - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=False, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=33, - renormalize=True, name="Lump_sheet", + renormalize=True, ) assert port2.name + "_T1" in self.aedtapp.excitations port3 = self.aedtapp.lumped_port( - signal=box1, + assignment=box1, reference=box2.name, - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, impedance=50, - renormalize=False, name="Lump3", + renormalize=False, deembed=True, ) assert port3.name + "_T1" in self.aedtapp.excitations @@ -1213,7 +1201,7 @@ def test_49_port_creation_exception(self): assert not self.aedtapp.set_sbr_txrx_settings({"TX1": "RX1"}) # SBR linked antenna can only be created within an SBR+ solution. - assert not self.aedtapp.create_sbr_linked_antenna(self.aedtapp, fieldtype="farfield") + assert not self.aedtapp.create_sbr_linked_antenna(self.aedtapp, field_type="farfield") # Chirp I doppler setup only works within an SBR+ solution. assert self.aedtapp.create_sbr_chirp_i_doppler_setup(sweep_time_duration=20) == (False, False) @@ -1224,28 +1212,26 @@ def test_49_port_creation_exception(self): def test_50_set_differential_pair(self, add_app): hfss1 = add_app(project_name=diff_proj_name, design_name="Hfss_Terminal", subfolder=test_subfolder) assert hfss1.set_differential_pair( - positive_terminal="P2_T1", - negative_terminal="P2_T2", - common_name=None, - diff_name=None, - common_ref_z=34, - diff_ref_z=123, + assignment="P2_T1", + reference="P2_T2", + differential_mode=None, + common_reference=34, + differential_reference=123, active=True, matched=False, ) - assert not hfss1.set_differential_pair(positive_terminal="P2_T1", negative_terminal="P2_T3") + assert not hfss1.set_differential_pair(assignment="P2_T1", reference="P2_T3") hfss2 = add_app(design_name="Hfss_Transient") assert hfss2.set_differential_pair( - positive_terminal="P2_T1", - negative_terminal="P2_T2", - common_name=None, - diff_name=None, - common_ref_z=34, - diff_ref_z=123, + assignment="P2_T1", + reference="P2_T2", + differential_mode=None, + common_reference=34, + differential_reference=123, active=True, matched=False, ) - assert not hfss2.set_differential_pair(positive_terminal="P2_T1", negative_terminal="P2_T3") + assert not hfss2.set_differential_pair(assignment="P2_T1", reference="P2_T3") hfss2.close_project() @pytest.mark.skipif( @@ -1298,7 +1284,7 @@ def test_52_crate_setup_hybrid_sbr(self, add_app): aedtapp.modeler.create_cylinder(aedtapp.AXIS.X, udp, 10, coax_dimension, 0, "outer") aedtapp.hybrid = True assert aedtapp.assign_hybrid_region(["inner"]) - bound = aedtapp.assign_hybrid_region("outer", hybrid_region="IE", boundary_name="new_hybrid") + bound = aedtapp.assign_hybrid_region("outer", name="new_hybrid", hybrid_region="IE") assert bound.props["Type"] == "IE" bound.props["Type"] = "PO" assert bound.props["Type"] == "PO" @@ -1310,21 +1296,16 @@ def test_53_import_source_excitation(self, add_app): time_domain = os.path.join(local_path, "../_unittest/example_models", test_subfolder, "Sinusoidal.csv") box1 = aedtapp.modeler.create_box([0, 0, 0], [10, 20, 20]) - aedtapp.wave_port(signal=box1.bottom_face_x, create_port_sheet=False, name="Port1") + aedtapp.wave_port(assignment=box1.bottom_face_x, create_port_sheet=False, name="Port1") aedtapp.create_setup() assert aedtapp.edit_source_from_file(aedtapp.excitations[0], freq_domain, is_time_domain=False, x_scale=1e9) assert aedtapp.edit_source_from_file( - aedtapp.excitations[0], - time_domain, - is_time_domain=True, - data_format="Voltage", - x_scale=1e-6, - y_scale=1e-3, + aedtapp.excitations[0], time_domain, is_time_domain=True, x_scale=1e-6, y_scale=1e-3, data_format="Voltage" ) aedtapp.close_project(save_project=False) def test_54_assign_symmetry(self, add_app): - aedtapp = add_app(project_name="test_54") + aedtapp = add_app(project_name="test_54", solution_type="Modal") aedtapp.modeler.create_box([0, -100, 0], [200, 200, 200], name="SymmetryForFaces") ids = [i.id for i in aedtapp.modeler["SymmetryForFaces"].faces] assert aedtapp.assign_symmetry(ids) @@ -1402,10 +1383,7 @@ def test_58_create_near_field_line(self): ] line = self.aedtapp.modeler.create_polyline(test_points) bound = self.aedtapp.insert_near_field_line( - line=line.name, - points=1000, - custom_radiation_faces=None, - name=None, + assignment=line.name, points=1000, custom_radiation_faces=None, name=None ) bound.props["NumPts"] = "200" assert bound @@ -1432,8 +1410,17 @@ def test_61_create_lumped_ports_on_object_driven_terminal(self): box1.material_name = "Copper" box2 = self.aedtapp.modeler.create_box([0, 0, 60], [10, 10, 5], "BoxLumped2") box2.material_name = "Copper" - port = self.aedtapp.create_lumped_port_between_objects( - "BoxLumped1", "BoxLumped2", self.aedtapp.AxisDir.XNeg, 50, "Lump1xx", True, False + + _ = self.aedtapp.lumped_port( + signal=box1.name, + reference=box2.name, + create_port_sheet=True, + port_on_plane=True, + integration_line=self.aedtapp.AxisDir.XNeg, + impedance=50, + name="Lump1xx", + renormalize=True, + deembed=False, ) term = [term for term in self.aedtapp.boundaries if term.type == "Terminal"][0] @@ -1456,22 +1443,22 @@ def test_63_set_phase_center_per_port(self): box2 = self.aedtapp.modeler.create_box([0, 0, 10], [10, 10, 5], "BoxWG2", "copper") box2.material_name = "Copper" port = self.aedtapp.wave_port( - signal="BoxWG1", + assignment="BoxWG1", reference="BoxWG2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, + modes=1, impedance=50, - num_modes=1, name="Wave1", renormalize=False, ) port2 = self.aedtapp.wave_port( - signal="BoxWG1", + assignment="BoxWG1", reference="BoxWG2", - integration_line=self.aedtapp.AxisDir.XNeg, create_port_sheet=True, + integration_line=self.aedtapp.AxisDir.XNeg, + modes=1, impedance=50, - num_modes=1, name="Wave2", renormalize=False, ) diff --git a/_unittest/test_21_Circuit.py b/_unittest/test_21_Circuit.py index be0a6a5a264..a9620f5139d 100644 --- a/_unittest/test_21_Circuit.py +++ b/_unittest/test_21_Circuit.py @@ -19,6 +19,7 @@ netlist1 = "netlist_small.cir" netlist2 = "Schematic1.qcv" touchstone = "SSN_ssn.s6p" +touchstone_custom = "SSN_custom.s6p" touchstone2 = "Galileo_V3P3S0.ts" ami_project = "AMI_Example" @@ -49,6 +50,7 @@ def examples(local_scratch): return netlist_file1, netlist_file2, touchstone_file, touchstone_file2 +@pytest.mark.skipif(is_linux, reason="Multiple tests are not passing in Linux with AEDT 2024R1") class TestClass: @pytest.fixture(autouse=True) def init(self, aedtapp, circuitprj, local_scratch, examples): @@ -249,9 +251,9 @@ def test_20_create_AMI_plots(self, add_app): "b_input_15", ami_design.available_variations.nominal, plot_type="Rectangular Stacked Plot", - plot_final_response=True, plot_intermediate_response=True, - plotname=report_name, + plot_final_response=True, + plot_name=report_name, ) == report_name ) @@ -261,7 +263,7 @@ def test_20_create_AMI_plots(self, add_app): assert ami_design.create_setup(setup_name, "NexximQuickEye") assert ( ami_design.post.create_ami_statistical_eye_plot( - "AMIAnalysis", "b_output4_14", ami_design.available_variations.nominal, plotname="MyReport1" + "AMIAnalysis", "b_output4_14", ami_design.available_variations.nominal, plot_name="MyReport1" ) == "MyReport1" ) @@ -270,7 +272,7 @@ def test_20_create_AMI_plots(self, add_app): "Dom_Quick", "b_input_15.int_ami_rx.eye_probe", ami_design.available_variations.nominal, - plotname="MyReportQ", + plot_name="MyReportQ", ) == "MyReportQ" ) @@ -282,7 +284,7 @@ def test_20B_create_AMI_plots(self): "Dom_Verify", "b_input_15.int_ami_rx.eye_probe", self.aedtapp.available_variations.nominal, - plotname="MyReportV", + plot_name="MyReportV", ) == "MyReportV" ) @@ -353,7 +355,6 @@ def test_27_set_differential_pairs(self): diff_name=None, common_ref_z=34, diff_ref_z=123, - active=True, ) assert self.circuitprj.set_differential_pair(positive_terminal="Port3", negative_terminal="Port5") @@ -676,22 +677,21 @@ def test_41_assign_excitations(self, add_app): port.reference_node = "NoNet" port.reference_node = "Z" - assert c.excitation_objets + assert c.excitation_objects setup = c.create_setup() - c.excitations["Port3"].enabled_sources = ["PowerTest"] - assert len(c.excitations["Port3"].enabled_sources) == 1 + c.excitation_objects["Port3"].enabled_sources = ["PowerTest"] + assert len(c.excitation_objects["Port3"].enabled_sources) == 1 setup1 = c.create_setup() setup2 = c.create_setup() - c.excitations["Port3"].enabled_analyses = {"PowerTest": [setup.name, setup2.name]} - assert c.excitations["Port3"].enabled_analyses["PowerTest"][0] == setup.name + c.excitation_objects["Port3"].enabled_analyses = {"PowerTest": [setup.name, setup2.name]} + assert c.excitation_objects["Port3"].enabled_analyses["PowerTest"][0] == setup.name - c.excitations["Port3"].name = "PortTest" + c.excitation_objects["Port3"].name = "PortTest" assert "PortTest" in c.excitations - assert "PortTest" in c.excitation_names - c.excitations["PortTest"].delete() - assert len(c.excitation_objets) == 0 + c.excitation_objects["PortTest"].delete() + assert len(c.excitation_objects) == 0 self.aedtapp.save_project() c = add_app(application=Circuit, design_name="sources") assert c.sources @@ -834,3 +834,56 @@ def test_46_create_vpwl(self): # time and voltage different length myres = self.aedtapp.modeler.schematic.create_voltage_pwl(compname="V3", time_list=[0], voltage_list=[0, 1]) assert myres is False + + def test_47_automatic_lna(self): + touchstone_file = os.path.join(local_path, "example_models", test_subfolder, touchstone_custom) + + status, diff_pairs, comm_pairs = self.aedtapp.create_lna_schematic_from_snp( + touchstone=touchstone_file, + start_frequency=0, + stop_frequency=70, + auto_assign_diff_pairs=True, + separation=".", + pattern=["component", "pin", "net"], + analyze=False, + ) + assert status + + def test_48_automatic_tdr(self): + touchstone_file = os.path.join(local_path, "example_models", test_subfolder, touchstone_custom) + + result, tdr_probe_name = self.aedtapp.create_tdr_schematic_from_snp( + touchstone=touchstone_file, + probe_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], + probe_ref_pins=["A-MII-RXD1_65.SQFP20X20_144.N"], + termination_pins=["A-MII-RXD2_32.SQFP28X28_208.P", "A-MII-RXD2_66.SQFP20X20_144.N"], + differential=True, + design_name="TDR", + rise_time=35, + use_convolution=True, + analyze=False, + ) + assert result + + def test_49_automatic_ami(self): + touchstone_file = os.path.join(local_path, "example_models", test_subfolder, touchstone_custom) + ami_file = os.path.join(local_path, "example_models", test_subfolder, "pcieg5_32gt.ibs") + result, eye_curve_tx, eye_curve_rx = self.aedtapp.create_ami_schematic_from_snp( + touchstone=touchstone_file, + ibis_ami=ami_file, + component_name="Spec_Model", + tx_buffer_name="1p", + rx_buffer_name="2p", + use_ibis_buffer=False, + differential=True, + tx_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], + tx_refs=["A-MII-RXD1_65.SQFP20X20_144.N"], + rx_pins=["A-MII-RXD2_32.SQFP28X28_208.P"], + rx_refs=["A-MII-RXD2_66.SQFP20X20_144.N"], + bit_pattern="random_bit_count=2.5e3 random_seed=1", + unit_interval="31.25ps", + use_convolution=True, + analyze=False, + design_name="AMI", + ) + assert result diff --git a/_unittest/test_22_Circuit_DynamicLink.py b/_unittest/test_22_Circuit_DynamicLink.py index c07b4ac4ddc..006542b7cb4 100644 --- a/_unittest/test_22_Circuit_DynamicLink.py +++ b/_unittest/test_22_Circuit_DynamicLink.py @@ -176,9 +176,9 @@ def test_07_create_page_port_and_interface_port(self): "Port_remove", [hfss3Dlayout_pin2location["J3B2.2.USBH2_DN_CH"][0], hfss3Dlayout_pin2location["J3B2.2.USBH2_DN_CH"][1]], ) - self.aedtapp.excitations[portname.name].delete() + self.aedtapp.excitation_objects[portname.name].delete() - assert "Port_remove" not in self.aedtapp.excitation_names + assert "Port_remove" not in self.aedtapp.excitations @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") def test_08_assign_excitations(self): diff --git a/_unittest/test_27_Maxwell2D.py b/_unittest/test_27_Maxwell2D.py index 625762dcf0f..c7de0e95245 100644 --- a/_unittest/test_27_Maxwell2D.py +++ b/_unittest/test_27_Maxwell2D.py @@ -49,34 +49,34 @@ def test_03_assign_initial_mesh_from_slider(self): assert self.aedtapp.mesh.assign_initial_mesh_from_slider(4) def test_04_create_winding(self): - bounds = self.aedtapp.assign_winding(current_value=20e-3, coil_terminals=["Coil"]) + bounds = self.aedtapp.assign_winding(assignment=["Coil"], current=20e-3) assert bounds o = self.aedtapp.modeler.create_rectangle([0, 0, 0], [3, 1], name="Rectangle2", matname="copper") - bounds = self.aedtapp.assign_winding(current_value=20e-3, coil_terminals=o.id) + bounds = self.aedtapp.assign_winding(assignment=o.id, current=20e-3) assert bounds - bounds = self.aedtapp.assign_winding(current_value="20e-3A", coil_terminals=["Coil"]) + bounds = self.aedtapp.assign_winding(assignment=["Coil"], current="20e-3A") assert bounds - bounds = self.aedtapp.assign_winding(res="1ohm", coil_terminals=["Coil"]) + bounds = self.aedtapp.assign_winding(assignment=["Coil"], resistance="1ohm") assert bounds - bounds = self.aedtapp.assign_winding(ind="1H", coil_terminals=["Coil"]) + bounds = self.aedtapp.assign_winding(assignment=["Coil"], inductance="1H") assert bounds - bounds = self.aedtapp.assign_winding(voltage="10V", coil_terminals=["Coil"]) + bounds = self.aedtapp.assign_winding(assignment=["Coil"], voltage="10V") assert bounds bounds_name = generate_unique_name("Coil") - bounds = self.aedtapp.assign_winding(coil_terminals=["Coil"], name=bounds_name) + bounds = self.aedtapp.assign_winding(assignment=["Coil"], name=bounds_name) assert bounds_name == bounds.name def test_04a_assign_coil(self): - bound = self.aedtapp.assign_coil(input_object=["Coil"]) + bound = self.aedtapp.assign_coil(assignment=["Coil"]) assert bound polarity = "Positive" - bound = self.aedtapp.assign_coil(input_object=["Coil"], polarity=polarity) + bound = self.aedtapp.assign_coil(assignment=["Coil"], polarity=polarity) assert bound.props["PolarityType"] == polarity.lower() polarity = "Negative" - bound = self.aedtapp.assign_coil(input_object=["Coil"], polarity=polarity) + bound = self.aedtapp.assign_coil(assignment=["Coil"], polarity=polarity) assert bound.props["PolarityType"] == polarity.lower() bound_name = generate_unique_name("Coil") - bound = self.aedtapp.assign_coil(input_object=["Coil"], name=bound_name) + bound = self.aedtapp.assign_coil(assignment=["Coil"], name=bound_name) assert bound_name == bound.name def test_05_create_vector_potential(self): @@ -114,7 +114,7 @@ def test_10_assign_torque(self): assert T.props["Objects"][0] == "Rotor_Section1" assert T.props["Is Positive"] assert T.delete() - T = self.aedtapp.assign_torque(input_object="Rotor_Section1", is_positive=False, torque_name="Torque_Test") + T = self.aedtapp.assign_torque(assignment="Rotor_Section1", is_positive=False, torque_name="Torque_Test") assert T.name == "Torque_Test" assert not T.props["Is Positive"] assert T.props["Objects"][0] == "Rotor_Section1" @@ -125,7 +125,7 @@ def test_11_assign_force(self): assert F.props["Objects"][0] == "Magnet2_Section1" assert F.props["Reference CS"] == "Global" assert F.delete() - F = self.aedtapp.assign_force(input_object="Magnet2_Section1", force_name="Force_Test") + F = self.aedtapp.assign_force(assignment="Magnet2_Section1", force_name="Force_Test") assert F.name == "Force_Test" def test_12_assign_current_source(self): @@ -211,24 +211,24 @@ def test_19_matrix(self): self.aedtapp.assign_current("Coil_2", amplitude=1, swap_direction=True, name="Current2") self.aedtapp.assign_current("Coil_3", amplitude=1, swap_direction=True, name="Current3") self.aedtapp.assign_current("Coil_4", amplitude=1, swap_direction=True, name="Current4") - L = self.aedtapp.assign_matrix(sources="Current1") + L = self.aedtapp.assign_matrix(assignment="Current1") assert L.props["MatrixEntry"]["MatrixEntry"][0]["Source"] == "Current1" assert L.delete() L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2"], matrix_name="Test1", turns=2, return_path="Current3" + assignment=["Current1", "Current2"], matrix_name="Test1", turns=2, return_path="Current3" ) assert len(L.props["MatrixEntry"]["MatrixEntry"]) == 2 L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2"], matrix_name="Test2", turns=[2, 1], return_path=["Current3", "Current4"] + assignment=["Current1", "Current2"], matrix_name="Test2", turns=[2, 1], return_path=["Current3", "Current4"] ) assert L.props["MatrixEntry"]["MatrixEntry"][1]["ReturnPath"] == "Current4" L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2"], matrix_name="Test3", turns=[2, 1], return_path=["Current1", "Current1"] + assignment=["Current1", "Current2"], matrix_name="Test3", turns=[2, 1], return_path=["Current1", "Current1"] ) assert not L group_sources = {"Group1_Test": ["Current3", "Current2"]} L = self.aedtapp.assign_matrix( - sources=["Current3", "Current2"], + assignment=["Current3", "Current2"], matrix_name="Test4", turns=[2, 1], return_path=["Current4", "Current1"], @@ -237,7 +237,7 @@ def test_19_matrix(self): assert L.name == "Test4" group_sources = {"Group1_Test": ["Current3", "Current2"], "Group2_Test": ["Current1", "Current2"]} L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2"], + assignment=["Current1", "Current2"], matrix_name="Test5", turns=[2, 1], return_path="infinite", @@ -248,7 +248,7 @@ def test_19_matrix(self): group_sources["Group1_Test"] = ["Current1", "Current3"] group_sources["Group2_Test"] = ["Current2", "Current4"] L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2", "Current3", "Current4"], + assignment=["Current1", "Current2", "Current3", "Current4"], matrix_name="Test6", turns=2, group_sources=group_sources, @@ -257,7 +257,7 @@ def test_19_matrix(self): assert L.props["MatrixGroup"]["MatrixGroup"][0]["GroupName"] == "Group1_Test" group_sources = {"Group1_Test": ["Current1", "Current3"], "Group2_Test": ["Current2", "Current4"]} L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2", "Current3", "Current4"], + assignment=["Current1", "Current2", "Current3", "Current4"], matrix_name="Test7", turns=[5, 1], group_sources=group_sources, @@ -266,7 +266,7 @@ def test_19_matrix(self): assert len(L.props["MatrixGroup"]["MatrixGroup"]) == 2 group_sources = {"Group1_Test": ["Current1", "Current3", "Current2"], "Group2_Test": ["Current2", "Current4"]} L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2", "Current3"], + assignment=["Current1", "Current2", "Current3"], matrix_name="Test8", turns=[2, 1, 2, 3], return_path=["infinite", "infinite", "Current4"], @@ -278,7 +278,7 @@ def test_19_matrix(self): assert L.props["MatrixEntry"]["MatrixEntry"][0]["NumberOfTurns"] == 3 group_sources = {"Group1_Test": ["Current1", "Current3"], "Group2_Test": ["Current2", "Current4"]} L = self.aedtapp.assign_matrix( - sources=["Current1", "Current2", "Current3", "Current4"], + assignment=["Current1", "Current2", "Current3", "Current4"], matrix_name="Test9", turns=[5, 1, 2, 3], group_sources=group_sources, @@ -298,10 +298,10 @@ def test_21_symmetry_multiplier(self): def test_22_eddycurrent(self): self.aedtapp.set_active_design("Basis_Model_For_Test") - assert self.aedtapp.eddy_effects_on(["Coil_1"], activate_eddy_effects=True) + assert self.aedtapp.eddy_effects_on(["Coil_1"], enable_eddy_effects=True) oModule = self.aedtapp.odesign.GetModule("BoundarySetup") assert oModule.GetEddyEffect("Coil_1") - self.aedtapp.eddy_effects_on(["Coil_1"], activate_eddy_effects=False) + self.aedtapp.eddy_effects_on(["Coil_1"], enable_eddy_effects=False) assert not oModule.GetEddyEffect("Coil_1") def test_23_read_motion_boundary(self): @@ -335,16 +335,16 @@ def test_25_export_rl_matrix(self): self.aedtapp.set_active_design("Sinusoidal") assert not self.aedtapp.export_rl_matrix("Test1", " ") self.aedtapp.solution_type = SOLUTIONS.Maxwell2d.EddyCurrentXY - self.aedtapp.assign_matrix(sources=["PM_I1_1_I0", "PM_I1_I0"], matrix_name="Test1") - self.aedtapp.assign_matrix(sources=["Phase_A", "Phase_B", "Phase_C"], matrix_name="Test2") + self.aedtapp.assign_matrix(assignment=["PM_I1_1_I0", "PM_I1_I0"], matrix_name="Test1") + self.aedtapp.assign_matrix(assignment=["Phase_A", "Phase_B", "Phase_C"], matrix_name="Test2") setup_name = "setupTestMatrixRL" - setup = self.aedtapp.create_setup(setupname=setup_name) + setup = self.aedtapp.create_setup(name=setup_name) setup.props["MaximumPasses"] = 2 export_path_1 = os.path.join(self.local_scratch.path, "export_rl_matrix_Test1.txt") assert not self.aedtapp.export_rl_matrix("Test1", export_path_1) assert not self.aedtapp.export_rl_matrix("Test2", export_path_1, False, 10, 3, True) self.aedtapp.validate_simple() - self.aedtapp.analyze_setup(setup_name) + self.aedtapp.analyze_setup(setup_name, num_cores=1) assert self.aedtapp.export_rl_matrix("Test1", export_path_1) assert not self.aedtapp.export_rl_matrix("abcabc", export_path_1) assert os.path.exists(export_path_1) @@ -382,7 +382,7 @@ def test_26_assign_current_density(self): def test_27_add_mesh_link(self): self.aedtapp.save_project(self.aedtapp.project_file) self.aedtapp.set_active_design("Sinusoidal") - assert self.aedtapp.setups[0].add_mesh_link(design_name="Y_Connections") + assert self.aedtapp.setups[0].add_mesh_link(design="Y_Connections") meshlink_props = self.aedtapp.setups[0].props["MeshLink"] assert meshlink_props["Project"] == "This Project*" assert meshlink_props["PathRelativeTo"] == "TargetProject" @@ -390,22 +390,17 @@ def test_27_add_mesh_link(self): assert meshlink_props["Soln"] == "Setup1 : LastAdaptive" assert sorted(list(meshlink_props["Params"].keys())) == sorted(self.aedtapp.available_variations.variables) assert sorted(list(meshlink_props["Params"].values())) == sorted(self.aedtapp.available_variations.variables) - assert not self.aedtapp.setups[0].add_mesh_link(design_name="") - assert self.aedtapp.setups[0].add_mesh_link(design_name="Y_Connections", solution_name="Setup1 : LastAdaptive") - assert not self.aedtapp.setups[0].add_mesh_link( - design_name="Y_Connections", solution_name="Setup_Test : LastAdaptive" - ) + assert not self.aedtapp.setups[0].add_mesh_link(design="") + assert self.aedtapp.setups[0].add_mesh_link(design="Y_Connections", solution="Setup1 : LastAdaptive") + assert not self.aedtapp.setups[0].add_mesh_link(design="Y_Connections", solution="Setup_Test : LastAdaptive") assert self.aedtapp.setups[0].add_mesh_link( - design_name="Y_Connections", - parameters_dict=self.aedtapp.available_variations.nominal_w_values_dict, + design="Y_Connections", parameters=self.aedtapp.available_variations.nominal_w_values_dict ) example_project = os.path.join(local_path, "example_models", test_subfolder, test_name + ".aedt") example_project_copy = os.path.join(self.local_scratch.path, test_name + "_copy.aedt") shutil.copyfile(example_project, example_project_copy) assert os.path.exists(example_project_copy) - assert self.aedtapp.setups[0].add_mesh_link( - design_name="Basis_Model_For_Test", project_name=example_project_copy - ) + assert self.aedtapp.setups[0].add_mesh_link(design="Basis_Model_For_Test", project=example_project_copy) def test_28_set_variable(self): self.aedtapp.variable_manager.set_variable("var_test", expression="123") @@ -420,7 +415,7 @@ def test_31_cylindrical_gap(self): for x in self.aedtapp.mesh.meshoperations[:] if x.type == "Cylindrical Gap Based" or x.type == "CylindricalGap" ] - assert self.aedtapp.mesh.assign_cylindrical_gap("Band", meshop_name="cyl_gap_test") + assert self.aedtapp.mesh.assign_cylindrical_gap("Band", name="cyl_gap_test") assert not self.aedtapp.mesh.assign_cylindrical_gap(["Band", "Region"]) assert not self.aedtapp.mesh.assign_cylindrical_gap("Band") [ @@ -428,7 +423,7 @@ def test_31_cylindrical_gap(self): for x in self.aedtapp.mesh.meshoperations[:] if x.type == "Cylindrical Gap Based" or x.type == "CylindricalGap" ] - assert self.aedtapp.mesh.assign_cylindrical_gap("Band", meshop_name="cyl_gap_test", band_mapping_angle=2) + assert self.aedtapp.mesh.assign_cylindrical_gap("Band", name="cyl_gap_test", band_mapping_angle=2) def test_32_control_program(self): user_ctl_path = "user.ctl" @@ -462,30 +457,26 @@ def test_34_start_continue_from_previous_setup(self): self.aedtapp.set_active_design("Basis_Model_For_Test") assert self.aedtapp.setups[0].start_continue_from_previous_setup( - design_name="design_for_test", solution_name="Setup1 : Transient" + design="design_for_test", solution="Setup1 : Transient" ) assert self.aedtapp.setups[0].props["PrevSoln"]["Project"] == "This Project*" assert self.aedtapp.setups[0].props["PrevSoln"]["Design"] == "design_for_test" assert self.aedtapp.setups[0].props["PrevSoln"]["Soln"] == "Setup1 : Transient" assert self.aedtapp.setups[1].start_continue_from_previous_setup( - design_name="design_for_test", solution_name="Setup1 : Transient", map_variables_by_name=False + design="design_for_test", solution="Setup1 : Transient", map_variables_by_name=False ) assert self.aedtapp.setups[1].props["PrevSoln"]["Project"] == "This Project*" assert self.aedtapp.setups[1].props["PrevSoln"]["Design"] == "design_for_test" assert self.aedtapp.setups[1].props["PrevSoln"]["Soln"] == "Setup1 : Transient" - assert not self.aedtapp.setups[0].start_continue_from_previous_setup( - design_name="", solution_name="Setup1 : Transient" - ) - assert not self.aedtapp.setups[0].start_continue_from_previous_setup( - design_name="design_for_test", solution_name="" - ) - assert not self.aedtapp.setups[0].start_continue_from_previous_setup(design_name="", solution_name="") + assert not self.aedtapp.setups[0].start_continue_from_previous_setup(design="", solution="Setup1 : Transient") + assert not self.aedtapp.setups[0].start_continue_from_previous_setup(design="design_for_test", solution="") + assert not self.aedtapp.setups[0].start_continue_from_previous_setup(design="", solution="") example_project_copy = os.path.join(self.local_scratch.path, test_name + "_copy.aedt") assert os.path.exists(example_project_copy) - self.aedtapp.create_setup(setupname="test_setup") + self.aedtapp.create_setup(name="test_setup") assert self.aedtapp.setups[2].start_continue_from_previous_setup( - design_name="design_for_test", solution_name="Setup1 : Transient", project_name=example_project_copy + design="design_for_test", solution="Setup1 : Transient", project=example_project_copy ) assert self.aedtapp.setups[2].props["PrevSoln"]["Project"] == example_project_copy assert self.aedtapp.setups[2].props["PrevSoln"]["Design"] == "design_for_test" @@ -494,65 +485,67 @@ def test_34_start_continue_from_previous_setup(self): def test_35_solution_types_setup(self, add_app): m2d = add_app(application=Maxwell2d, design_name="test_setups") m2d.solution_type = SOLUTIONS.Maxwell2d.TransientXY - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.TransientZ - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.MagnetostaticXY - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.MagnetostaticZ - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.EddyCurrentXY - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.EddyCurrentZ - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.ElectroStaticXY - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.ElectroStaticZ - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.DCConductionXY - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.DCConductionZ - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.ACConductionXY - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() m2d.solution_type = SOLUTIONS.Maxwell2d.ACConductionZ - setup = m2d.create_setup(setuptype=m2d.solution_type) + setup = m2d.create_setup(setup_type=m2d.solution_type) assert setup setup.delete() def test_36_design_excitations_by_type(self): coils = self.aedtapp.excitations_by_type["Coil"] assert coils - assert len(coils) == len([bound for bound in self.aedtapp.design_excitations if bound.type == "Coil"]) + assert len(coils) == len([bound for bound in self.aedtapp.excitation_objects.values() if bound.type == "Coil"]) currents = self.aedtapp.excitations_by_type["Current"] assert currents - assert len(currents) == len([bound for bound in self.aedtapp.design_excitations if bound.type == "Current"]) + assert len(currents) == len( + [bound for bound in self.aedtapp.excitation_objects.values() if bound.type == "Current"] + ) wdg_group = self.aedtapp.excitations_by_type["Winding Group"] assert wdg_group assert len(wdg_group) == len( - [bound for bound in self.aedtapp.design_excitations if bound.type == "Winding Group"] + [bound for bound in self.aedtapp.excitation_objects.values() if bound.type == "Winding Group"] ) def test_37_boundaries_by_type(self): diff --git a/_unittest/test_28_Maxwell3D.py b/_unittest/test_28_Maxwell3D.py index ca6ce69196a..d72aee67611 100644 --- a/_unittest/test_28_Maxwell3D.py +++ b/_unittest/test_28_Maxwell3D.py @@ -167,43 +167,43 @@ def test_04_coil_terminal(self): def test_05_winding(self): face_id = self.aedtapp.modeler["Coil_Section1"].faces[0].id assert self.aedtapp.assign_winding(face_id) - bounds = self.aedtapp.assign_winding(current_value=20e-3, coil_terminals=face_id) + bounds = self.aedtapp.assign_winding(assignment=face_id, current=20e-3) assert bounds - bounds = self.aedtapp.assign_winding(current_value="20e-3A", coil_terminals=face_id) + bounds = self.aedtapp.assign_winding(assignment=face_id, current="20e-3A") assert bounds - bounds = self.aedtapp.assign_winding(res="1ohm", coil_terminals=face_id) + bounds = self.aedtapp.assign_winding(assignment=face_id, resistance="1ohm") assert bounds - bounds = self.aedtapp.assign_winding(ind="1H", coil_terminals=face_id) + bounds = self.aedtapp.assign_winding(assignment=face_id, inductance="1H") assert bounds - bounds = self.aedtapp.assign_winding(voltage="10V", coil_terminals=face_id) + bounds = self.aedtapp.assign_winding(assignment=face_id, voltage="10V") assert bounds bounds_name = generate_unique_name("Winding") - bounds = self.aedtapp.assign_winding(coil_terminals=face_id, name=bounds_name) + bounds = self.aedtapp.assign_winding(assignment=face_id, name=bounds_name) assert bounds_name == bounds.name def test_05a_assign_coil(self): face_id = self.aedtapp.modeler["Coil_Section1"].faces[0].id - bound = self.aedtapp.assign_coil(input_object=face_id) + bound = self.aedtapp.assign_coil(assignment=face_id) assert bound polarity = "Positive" - bound = self.aedtapp.assign_coil(input_object=face_id, polarity=polarity) + bound = self.aedtapp.assign_coil(assignment=face_id, polarity=polarity) assert not bound.props["Point out of terminal"] polarity = "Negative" - bound = self.aedtapp.assign_coil(input_object=face_id, polarity=polarity) + bound = self.aedtapp.assign_coil(assignment=face_id, polarity=polarity) assert bound.props["Point out of terminal"] bound_name = generate_unique_name("Coil") - bound = self.aedtapp.assign_coil(input_object=face_id, name=bound_name) + bound = self.aedtapp.assign_coil(assignment=face_id, name=bound_name) assert bound_name == bound.name def test_05_draw_region(self): assert self.aedtapp.modeler.create_air_region(*[300] * 6) def test_06_eddycurrent(self): - assert self.aedtapp.eddy_effects_on(["Plate"], activate_eddy_effects=True) + assert self.aedtapp.eddy_effects_on(["Plate"], enable_eddy_effects=True) oModule = self.aedtapp.odesign.GetModule("BoundarySetup") assert oModule.GetEddyEffect("Plate") assert oModule.GetDisplacementCurrent("Plate") - self.aedtapp.eddy_effects_on(["Plate"], activate_eddy_effects=False) + self.aedtapp.eddy_effects_on(["Plate"], enable_eddy_effects=False) assert not oModule.GetEddyEffect("Plate") assert not oModule.GetDisplacementCurrent("Plate") @@ -267,7 +267,7 @@ def test_24_create_edge_cut(self): assert self.aedtapp.mesh.assign_edge_cut(["Coil"]) def test_24_density_control(self): - assert self.aedtapp.mesh.assign_density_control(["Coil"], maxelementlength="2mm", layerNum="3") + assert self.aedtapp.mesh.assign_density_control(["Coil"], maximum_element_length="2mm", layers_number="3") def test_24_density_control(self): assert self.aedtapp.mesh.assign_rotational_layer(["Coil"]) @@ -425,7 +425,7 @@ def test_28_assign_torque(self): assert T.props["Coordinate System"] == "Global" assert T.props["Axis"] == "Z" assert T.delete() - T = self.aedtapp.assign_torque(input_object="Coil", is_positive=False, torque_name="Torque_Test") + T = self.aedtapp.assign_torque(assignment="Coil", is_positive=False, torque_name="Torque_Test") assert not T.props["Is Positive"] assert T.name == "Torque_Test" @@ -436,7 +436,7 @@ def test_29_assign_force(self): assert F.props["Reference CS"] == "Global" assert F.props["Is Virtual"] assert F.delete() - F = self.aedtapp.assign_force(input_object="Coil", is_virtual=False, force_name="Force_Test") + F = self.aedtapp.assign_force(assignment="Coil", is_virtual=False, force_name="Force_Test") assert F.name == "Force_Test" assert not F.props["Is Virtual"] @@ -445,7 +445,7 @@ def test_30_assign_movement(self): self.aedtapp.solution_type = SOLUTIONS.Maxwell3d.Transient self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 10], name="Inner_Box") self.aedtapp.modeler.create_box([0, 0, 0], [30, 20, 20], name="Outer_Box") - bound = self.aedtapp.assign_translate_motion("Outer_Box", mechanical_transient=True, velocity=1) + bound = self.aedtapp.assign_translate_motion("Outer_Box", velocity=1, mechanical_transient=True) assert bound assert bound.props["Velocity"] == "1m_per_sec" @@ -474,18 +474,18 @@ def test_32_matrix(self, add_app): m3d.assign_voltage(rectangle3.faces[0], amplitude=1, name="Voltage3") m3d.assign_voltage(rectangle4.faces[0], amplitude=1, name="Voltage4") - L = m3d.assign_matrix(sources="Voltage1") + L = m3d.assign_matrix(assignment="Voltage1") assert L.props["MatrixEntry"]["MatrixEntry"][0]["Source"] == "Voltage1" assert L.delete() group_sources = "Voltage2" - L = m3d.assign_matrix(sources=["Voltage1", "Voltage3"], matrix_name="Test1", group_sources=group_sources) + L = m3d.assign_matrix(assignment=["Voltage1", "Voltage3"], matrix_name="Test1", group_sources=group_sources) assert L.props["MatrixEntry"]["MatrixEntry"][1]["Source"] == "Voltage3" m3d.solution_type = SOLUTIONS.Maxwell3d.Transient winding1 = m3d.assign_winding("Sheet1", name="Current1") winding2 = m3d.assign_winding("Sheet2", name="Current2") winding3 = m3d.assign_winding("Sheet3", name="Current3") winding4 = m3d.assign_winding("Sheet4", name="Current4") - L = m3d.assign_matrix(sources="Current1") + L = m3d.assign_matrix(assignment="Current1") assert not L def test_32B_matrix(self, add_app): @@ -506,7 +506,7 @@ def test_32B_matrix(self, add_app): m3d.assign_current(rectangle3.faces[0], amplitude=1, name="Cur3") m3d.assign_current(rectangle4.faces[0], amplitude=1, name="Cur4") - L = m3d.assign_matrix(sources=["Cur1", "Cur2", "Cur3"]) + L = m3d.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"]) out = L.join_series(["Cur1", "Cur2"]) assert isinstance(out[0], str) assert isinstance(out[1], str) @@ -518,16 +518,16 @@ def test_32B_matrix(self, add_app): def test_32a_export_rl_matrix(self): self.aedtapp.set_active_design("Matrix2") - L = self.aedtapp.assign_matrix(sources=["Cur1", "Cur2", "Cur3"], matrix_name="matrix_export_test") + L = self.aedtapp.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"], matrix_name="matrix_export_test") L.join_series(["Cur1", "Cur2"], matrix_name="reduced_matrix_export_test") setup_name = "setupTestMatrixRL" - setup = self.aedtapp.create_setup(setupname=setup_name) + setup = self.aedtapp.create_setup(name=setup_name) setup.props["MaximumPasses"] = 2 export_path_1 = os.path.join(self.local_scratch.path, "export_rl_matrix_Test1.txt") assert not self.aedtapp.export_rl_matrix("matrix_export_test", export_path_1) assert not self.aedtapp.export_rl_matrix("matrix_export_test", export_path_1, False, 10, 3, True) self.aedtapp.validate_simple() - self.aedtapp.analyze_setup(setup_name) + self.aedtapp.analyze_setup(setup_name, num_cores=1) assert self.aedtapp.export_rl_matrix("matrix_export_test", export_path_1) assert not self.aedtapp.export_rl_matrix("abcabc", export_path_1) assert os.path.exists(export_path_1) @@ -599,9 +599,7 @@ def test_38_assign_current_density(self): "current_box", "CurrentDensity_2", "40deg", current_density_x="3", current_density_y="4" ) assert self.aedtapp.assign_current_density(["current_box", "current_box2"], "CurrentDensity_3") - assert not self.aedtapp.assign_current_density( - "current_box", "CurrentDensity_4", coordinate_system_cartesian="test" - ) + assert not self.aedtapp.assign_current_density("current_box", "CurrentDensity_4", coordinate_system_type="test") assert not self.aedtapp.assign_current_density("current_box", "CurrentDensity_5", phase="5ang") for bound in self.aedtapp.boundaries: if bound.type == "CurrentDensity": @@ -649,10 +647,7 @@ def test_40_assign_impedance(self): assert self.aedtapp.assign_impedance(impedance_faces, "copper") assert self.aedtapp.assign_impedance(impedance_box, "copper") impedance_assignment = self.aedtapp.assign_impedance( - impedance_box.name, - permeability=1.3, - conductivity=42000000, - impedance_name="ImpedanceExample", + impedance_box.name, permeability=1.3, conductivity=42000000, impedance="ImpedanceExample" ) assert impedance_assignment.name == "ImpedanceExample" impedance_assignment.name = "ImpedanceExampleModified" @@ -663,9 +658,7 @@ def test_40_assign_impedance(self): [-50, -300, -50], [294, 294, 19], name="impedance_box_copper" ) impedance_assignment_copper = self.aedtapp.assign_impedance( - impedance_box_copper.name, - material_name="copper", - impedance_name="ImpedanceExampleCopper", + impedance_box_copper.name, material_name="copper", impedance="ImpedanceExampleCopper" ) assert impedance_assignment_copper.name == "ImpedanceExampleCopper" impedance_assignment_copper.name = "ImpedanceExampleCopperModified" @@ -679,9 +672,9 @@ def test_40_assign_impedance(self): impedance_assignment_copper = self.aedtapp.assign_impedance( impedance_box_copper.name, material_name="copper", - non_linear_permeability=True, conductivity=47000000, - impedance_name="ImpedanceExampleCopperNonLinear", + non_linear_permeability=True, + impedance="ImpedanceExampleCopperNonLinear", ) assert impedance_assignment_copper.name == "ImpedanceExampleCopperNonLinear" impedance_assignment_copper.name = "ImpedanceExampleCopperNonLinearModified" @@ -696,7 +689,7 @@ def test_41_conduction_paths(self): assert len(self.aedtapp.get_conduction_paths()) == 2 def test_43_eddy_effect_transient(self, m3dtransient): - assert m3dtransient.eddy_effects_on(["Rotor"], activate_eddy_effects=True) + assert m3dtransient.eddy_effects_on(["Rotor"], enable_eddy_effects=True) def test_44_assign_master_slave(self, m3dtransient): faces = [ @@ -747,29 +740,26 @@ def test_44_assign_master_slave(self, m3dtransient): def test_45_add_mesh_link(self, m3dtransient): m3dtransient.duplicate_design(m3dtransient.design_name) m3dtransient.set_active_design(m3dtransient.design_list[1]) - assert m3dtransient.setups[0].add_mesh_link(design_name=m3dtransient.design_list[0]) + assert m3dtransient.setups[0].add_mesh_link(design=m3dtransient.design_list[0]) meshlink_props = m3dtransient.setups[0].props["MeshLink"] assert meshlink_props["Project"] == "This Project*" assert meshlink_props["PathRelativeTo"] == "TargetProject" assert meshlink_props["Design"] == m3dtransient.design_list[0] assert meshlink_props["Soln"] == "Setup1 : LastAdaptive" - assert not m3dtransient.setups[0].add_mesh_link(design_name="") + assert not m3dtransient.setups[0].add_mesh_link(design="") assert m3dtransient.setups[0].add_mesh_link( - design_name=m3dtransient.design_list[0], solution_name="Setup1 : LastAdaptive" + design=m3dtransient.design_list[0], solution="Setup1 : LastAdaptive" ) assert not m3dtransient.setups[0].add_mesh_link( - design_name=m3dtransient.design_list[0], solution_name="Setup_Test : LastAdaptive" + design=m3dtransient.design_list[0], solution="Setup_Test : LastAdaptive" ) assert m3dtransient.setups[0].add_mesh_link( - design_name=m3dtransient.design_list[0], - parameters_dict=m3dtransient.available_variations.nominal_w_values_dict, + design=m3dtransient.design_list[0], parameters=m3dtransient.available_variations.nominal_w_values_dict ) example_project = os.path.join(local_path, "example_models", test_subfolder, transient + ".aedt") example_project_copy = os.path.join(self.local_scratch.path, transient + "_copy.aedt") shutil.copyfile(example_project, example_project_copy) - assert m3dtransient.setups[0].add_mesh_link( - design_name=m3dtransient.design_list[0], project_name=example_project_copy - ) + assert m3dtransient.setups[0].add_mesh_link(design=m3dtransient.design_list[0], project=example_project_copy) def test_46_set_variable(self): self.aedtapp.variable_manager.set_variable("var_test", expression="123") @@ -783,7 +773,7 @@ def test_49_cylindrical_gap(self, cyl_gap): for x in cyl_gap.mesh.meshoperations[:] if x.type == "Cylindrical Gap Based" or x.type == "CylindricalGap" ] - assert cyl_gap.mesh.assign_cylindrical_gap("Band", meshop_name="cyl_gap_test") + assert cyl_gap.mesh.assign_cylindrical_gap("Band", name="cyl_gap_test") assert not cyl_gap.mesh.assign_cylindrical_gap(["Band", "Inner_Band"]) assert not cyl_gap.mesh.assign_cylindrical_gap("Band") [ @@ -791,15 +781,13 @@ def test_49_cylindrical_gap(self, cyl_gap): for x in cyl_gap.mesh.meshoperations[:] if x.type == "Cylindrical Gap Based" or x.type == "CylindricalGap" ] - assert cyl_gap.mesh.assign_cylindrical_gap( - "Band", meshop_name="cyl_gap_test", clone_mesh=True, band_mapping_angle=1 - ) + assert cyl_gap.mesh.assign_cylindrical_gap("Band", name="cyl_gap_test", band_mapping_angle=1, clone_mesh=True) [ x.delete() for x in cyl_gap.mesh.meshoperations[:] if x.type == "Cylindrical Gap Based" or x.type == "CylindricalGap" ] - assert cyl_gap.mesh.assign_cylindrical_gap("Band", meshop_name="cyl_gap_test", clone_mesh=False) + assert cyl_gap.mesh.assign_cylindrical_gap("Band", name="cyl_gap_test", clone_mesh=False) [ x.delete() for x in cyl_gap.mesh.meshoperations[:] @@ -807,13 +795,13 @@ def test_49_cylindrical_gap(self, cyl_gap): ] assert cyl_gap.mesh.assign_cylindrical_gap("Band") assert not cyl_gap.mesh.assign_cylindrical_gap( - "Band", meshop_name="cyl_gap_test", clone_mesh=True, band_mapping_angle=7 + "Band", name="cyl_gap_test", band_mapping_angle=7, clone_mesh=True ) assert not cyl_gap.mesh.assign_cylindrical_gap( - "Band", meshop_name="cyl_gap_test", clone_mesh=True, band_mapping_angle=2, moving_side_layers=0 + "Band", name="cyl_gap_test", band_mapping_angle=2, clone_mesh=True, moving_side_layers=0 ) assert not cyl_gap.mesh.assign_cylindrical_gap( - "Band", meshop_name="cyl_gap_test", clone_mesh=True, band_mapping_angle=2, static_side_layers=0 + "Band", name="cyl_gap_test", band_mapping_angle=2, clone_mesh=True, static_side_layers=0 ) def test_50_objects_segmentation(self, cyl_gap): @@ -915,20 +903,12 @@ def test_54_enable_harmonic_force_layout(self, layout_comp): def test_55_tangential_h_field(self, add_app): m3d = add_app(application=Maxwell3d, solution_type="EddyCurrent") box = m3d.modeler.create_box([0, 0, 0], [10, 10, 10]) - assert m3d.assign_tangential_h_field( - box.bottom_face_x, - 1, - 0, - 2, - 0, - ) + assert m3d.assign_tangential_h_field(box.bottom_face_x, 1, 0, 2, 0) def test_56_zero_tangential_h_field(self, add_app): m3d = add_app(application=Maxwell3d, solution_type="EddyCurrent") box = m3d.modeler.create_box([0, 0, 0], [10, 10, 10]) - assert m3d.assign_zero_tangential_h_field( - box.top_face_z, - ) + assert m3d.assign_zero_tangential_h_field(box.top_face_z) def test_57_radiation(self): self.aedtapp.insert_design("Radiation") @@ -948,38 +928,38 @@ def test_57_radiation(self): def test_58_solution_types_setup(self, add_app): m3d = add_app(application=Maxwell3d, design_name="test_setups") - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.Transient - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.EddyCurrent - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.ElectroStatic - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.DCConduction - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.ACConduction - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.ElectroDCConduction - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.ElectricTransient - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() m3d.solution_type = SOLUTIONS.Maxwell3d.TransientAPhiFormulation - setup = m3d.create_setup(setuptype=m3d.solution_type) + setup = m3d.create_setup(setup_type=m3d.solution_type) assert setup setup.delete() diff --git a/_unittest/test_29_Mechanical.py b/_unittest/test_29_Mechanical.py index cd16e1688bf..ca6314ef417 100644 --- a/_unittest/test_29_Mechanical.py +++ b/_unittest/test_29_Mechanical.py @@ -53,12 +53,7 @@ def test_05_assign_load(self, add_app): setup = hfss.create_setup() freq = "1GHz" setup.props["Frequency"] = freq - assert self.aedtapp.assign_em_losses( - hfss.design_name, - hfss.setups[0].name, - "LastAdaptive", - freq, - ) + assert self.aedtapp.assign_em_losses(hfss.design_name, hfss.setups[0].name, "LastAdaptive", freq) def test_06a_create_setup(self): mysetup = self.aedtapp.create_setup() @@ -115,28 +110,25 @@ def test_10_assign_heat_generation(self): def test_11_add_mesh_link(self): self.aedtapp.save_project(self.aedtapp.project_file) self.aedtapp.set_active_design("MechanicalDesign1") - assert self.aedtapp.setups[0].add_mesh_link(design_name="MechanicalDesign2") + assert self.aedtapp.setups[0].add_mesh_link(design="MechanicalDesign2") meshlink_props = self.aedtapp.setups[0].props["MeshLink"] assert meshlink_props["Project"] == "This Project*" assert meshlink_props["PathRelativeTo"] == "TargetProject" assert meshlink_props["Design"] == "MechanicalDesign2" assert meshlink_props["Soln"] == "MySetupAuto : LastAdaptive" assert meshlink_props["Params"] == self.aedtapp.available_variations.nominal_w_values_dict - assert not self.aedtapp.setups[0].add_mesh_link(design_name="") + assert not self.aedtapp.setups[0].add_mesh_link(design="") assert not self.aedtapp.setups[0].add_mesh_link( - design_name="MechanicalDesign2", solution_name="Setup_Test : LastAdaptive" - ) - assert self.aedtapp.setups[0].add_mesh_link( - design_name="MechanicalDesign2", - parameters_dict=self.aedtapp.available_variations.nominal_w_values_dict, + design="MechanicalDesign2", solution="Setup_Test : LastAdaptive" ) assert self.aedtapp.setups[0].add_mesh_link( - design_name="MechanicalDesign2", solution_name="MySetupAuto : LastAdaptive" + design="MechanicalDesign2", parameters=self.aedtapp.available_variations.nominal_w_values_dict ) + assert self.aedtapp.setups[0].add_mesh_link(design="MechanicalDesign2", solution="MySetupAuto : LastAdaptive") example_project = os.path.join(self.local_scratch.path, test_project_name + ".aedt") example_project_copy = os.path.join(self.local_scratch.path, test_project_name + "_copy.aedt") shutil.copyfile(example_project, example_project_copy) - assert self.aedtapp.setups[0].add_mesh_link(design_name="MechanicalDesign2", project_name=example_project_copy) + assert self.aedtapp.setups[0].add_mesh_link(design="MechanicalDesign2", project=example_project_copy) os.remove(example_project_copy) def test_12_transient_thermal(self): diff --git a/_unittest/test_30_Q2D.py b/_unittest/test_30_Q2D.py index fc6bd560c0c..a87266d1d8a 100644 --- a/_unittest/test_30_Q2D.py +++ b/_unittest/test_30_Q2D.py @@ -155,12 +155,12 @@ def test_14_export_matrix_data(self, add_app): os.path.join(self.local_scratch.path, "test_2d.txt"), problem_type="RL", matrix_type="Maxwell, Couple" ) assert q2d.export_matrix_data( - os.path.join(self.local_scratch.path, "test_2d.txt"), problem_type="CG", setup_name="Setup1", sweep="Sweep1" + os.path.join(self.local_scratch.path, "test_2d.txt"), problem_type="CG", setup="Setup1", sweep="Sweep1" ) assert q2d.export_matrix_data( os.path.join(self.local_scratch.path, "test_2d.txt"), problem_type="CG", - setup_name="Setup1", + setup="Setup1", sweep="LastAdaptive", ) assert q2d.export_matrix_data( diff --git a/_unittest/test_35_MaxwellCircuit.py b/_unittest/test_35_MaxwellCircuit.py index 344bc1a98eb..8bdb327a7b2 100644 --- a/_unittest/test_35_MaxwellCircuit.py +++ b/_unittest/test_35_MaxwellCircuit.py @@ -71,6 +71,6 @@ def test_07_export_netlist(self, add_app): m2d.solution_type = SOLUTIONS.Maxwell2d.TransientZ m2d.modeler.create_circle([0, 0, 0], 10, name="Circle_inner") m2d.modeler.create_circle([0, 0, 0], 30, name="Circle_outer") - m2d.assign_coil(input_object=["Circle_inner"]) - m2d.assign_winding(coil_terminals=["Circle_inner"], name="Ext_Wdg", winding_type="External") + m2d.assign_coil(assignment=["Circle_inner"]) + m2d.assign_winding(assignment=["Circle_inner"], winding_type="External", name="Ext_Wdg") assert m2d.edit_external_circuit(netlist_file, self.aedtapp.design_name) diff --git a/_unittest/test_41_3dlayout_modeler.py b/_unittest/test_41_3dlayout_modeler.py index 0c1e5a85229..e4e01b134d1 100644 --- a/_unittest/test_41_3dlayout_modeler.py +++ b/_unittest/test_41_3dlayout_modeler.py @@ -311,12 +311,7 @@ def test_13a_create_edge_port(self): assert len(self.aedtapp.excitations) > 0 time_domain = os.path.join(local_path, "../_unittest/example_models", test_subfolder, "Sinusoidal.csv") assert self.aedtapp.edit_source_from_file( - port_wave.name, - time_domain, - is_time_domain=True, - data_format="Voltage", - x_scale=1e-6, - y_scale=1e-3, + port_wave.name, time_domain, is_time_domain=True, x_scale=1e-6, y_scale=1e-3, data_format="Voltage" ) def test_14a_create_coaxial_port(self): @@ -326,13 +321,13 @@ def test_14a_create_coaxial_port(self): def test_14_create_setup(self): setup_name = "RFBoardSetup" - setup = self.aedtapp.create_setup(setupname=setup_name) + setup = self.aedtapp.create_setup(name=setup_name) assert setup.name == self.aedtapp.existing_analysis_setups[0] assert setup.solver_type == "HFSS" def test_15_edit_setup(self): setup_name = "RFBoardSetup2" - setup2 = self.aedtapp.create_setup(setupname=setup_name) + setup2 = self.aedtapp.create_setup(name=setup_name) assert not setup2.get_sweep() sweep = setup2.add_sweep() @@ -350,7 +345,7 @@ def test_15_edit_setup(self): def test_16_disable_enable_setup(self): setup_name = "RFBoardSetup3" - setup3 = self.aedtapp.create_setup(setupname=setup_name) + setup3 = self.aedtapp.create_setup(name=setup_name) setup3.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["MaxPasses"] = 1 assert setup3.update() assert setup3.disable() @@ -375,47 +370,40 @@ def test_17_get_setup(self): def test_18a_create_linear_count_sweep(self): setup_name = "RF_create_linear_count" - self.aedtapp.create_setup(setupname=setup_name) + self.aedtapp.create_setup(name=setup_name) sweep1 = self.aedtapp.create_linear_count_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", - freqstart=1, - freqstop=10, + start_frequency=1, + stop_frequency=10, num_of_freq_points=1001, - sweepname="RFBoardSweep1", + save_fields=False, sweep_type="Interpolating", - interpolation_tol_percent=0.2, interpolation_max_solutions=111, - save_fields=False, - use_q3d_for_dc=False, ) assert sweep1.props["Sweeps"]["Data"] == "LINC 1GHz 10GHz 1001" sweep2 = self.aedtapp.create_linear_count_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", - freqstart=1, - freqstop=10, + start_frequency=1, + stop_frequency=10, num_of_freq_points=12, - sweepname="RFBoardSweep2", + save_fields=True, sweep_type="Discrete", - interpolation_tol_percent=0.4, interpolation_max_solutions=255, - save_fields=True, - save_rad_fields_only=True, - use_q3d_for_dc=True, ) assert sweep2.props["Sweeps"]["Data"] == "LINC 1GHz 10GHz 12" def test_18b_create_linear_step_sweep(self): setup_name = "RF_create_linear_step" - self.aedtapp.create_setup(setupname=setup_name) + self.aedtapp.create_setup(name=setup_name) sweep3 = self.aedtapp.create_linear_step_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", - freqstart=1, - freqstop=10, + start_frequency=1, + stop_frequency=10, step_size=0.2, - sweepname="RFBoardSweep3", + name="RFBoardSweep3", sweep_type="Interpolating", interpolation_tol_percent=0.4, interpolation_max_solutions=255, @@ -426,24 +414,24 @@ def test_18b_create_linear_step_sweep(self): assert sweep3.props["Sweeps"]["Data"] == "LIN 1GHz 10GHz 0.2GHz" assert sweep3.props["FreqSweepType"] == "kInterpolating" sweep4 = self.aedtapp.create_linear_step_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", - freqstart=1, - freqstop=10, + start_frequency=1, + stop_frequency=10, step_size=0.12, - sweepname="RFBoardSweep4", + name="RFBoardSweep4", sweep_type="Discrete", save_fields=True, ) assert sweep4.props["Sweeps"]["Data"] == "LIN 1GHz 10GHz 0.12GHz" assert sweep4.props["FreqSweepType"] == "kDiscrete" sweep5 = self.aedtapp.create_linear_step_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", - freqstart=1, - freqstop=10, + start_frequency=1, + stop_frequency=10, step_size=0.12, - sweepname="RFBoardSweep4", + name="RFBoardSweep4", sweep_type="Fast", save_fields=True, ) @@ -453,12 +441,12 @@ def test_18b_create_linear_step_sweep(self): # Create a linear step sweep with the incorrect sweep type. with pytest.raises(AttributeError) as execinfo: self.aedtapp.create_linear_step_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", - freqstart=1, - freqstop=10, + start_frequency=1, + stop_frequency=10, step_size=0.12, - sweepname="RFBoardSweep4", + name="RFBoardSweep4", sweep_type="Incorrect", save_fields=True, ) @@ -469,37 +457,37 @@ def test_18b_create_linear_step_sweep(self): def test_18c_create_single_point_sweep(self): setup_name = "RF_create_single_point" - self.aedtapp.create_setup(setupname=setup_name) + self.aedtapp.create_setup(name=setup_name) sweep5 = self.aedtapp.create_single_point_sweep( - setupname=setup_name, + setup=setup_name, unit="MHz", freq=1.23, - sweepname="RFBoardSingle", + name="RFBoardSingle", save_fields=True, ) assert sweep5.props["Sweeps"]["Data"] == "1.23MHz" sweep6 = self.aedtapp.create_single_point_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", freq=[1, 2, 3, 4], - sweepname="RFBoardSingle", + name="RFBoardSingle", save_fields=False, ) assert sweep6.props["Sweeps"]["Data"] == "1GHz 2GHz 3GHz 4GHz" with pytest.raises(AttributeError) as execinfo: self.aedtapp.create_single_point_sweep( - setupname=setup_name, + setup=setup_name, unit="GHz", freq=[], - sweepname="RFBoardSingle", + name="RFBoardSingle", save_fields=False, ) assert execinfo.args[0] == "Frequency list is empty. Specify at least one frequency point." def test_18d_delete_setup(self): setup_name = "SetupToDelete" - setuptd = self.aedtapp.create_setup(setupname=setup_name) + setuptd = self.aedtapp.create_setup(name=setup_name) assert setuptd.name in self.aedtapp.existing_analysis_setups self.aedtapp.delete_setup(setup_name) assert setuptd.name not in self.aedtapp.existing_analysis_setups @@ -583,13 +571,13 @@ def test_33_set_temperature_dependence(self): def test_34_create_additional_setup(self): setup_name = "SiwaveDC" - setup = self.aedtapp.create_setup(setupname=setup_name, setuptype="SiwaveDC3DLayout") + setup = self.aedtapp.create_setup(name=setup_name, setup_type="SiwaveDC3DLayout") assert setup_name == setup.name setup_name = "SiwaveAC" - setup = self.aedtapp.create_setup(setupname=setup_name, setuptype="SiwaveAC3DLayout") + setup = self.aedtapp.create_setup(name=setup_name, setup_type="SiwaveAC3DLayout") assert setup_name == setup.name setup_name = "LNA" - setup = self.aedtapp.create_setup(setupname=setup_name, setuptype="LNA3DLayout") + setup = self.aedtapp.create_setup(name=setup_name, setup_type="LNA3DLayout") assert setup_name == setup.name def test_35a_export_layout(self): @@ -706,8 +694,6 @@ def test_90_set_differential_pairs(self, hfss3dl): diff_name=None, common_ref_z=34, diff_ref_z=123, - active=True, - matched=False, ) assert hfss3dl.set_differential_pair(positive_terminal="Port3", negative_terminal="Port5") assert hfss3dl.get_differential_pairs() diff --git a/_unittest/test_98_Icepak.py b/_unittest/test_98_Icepak.py index 767323cb0c5..5bef6c59f96 100644 --- a/_unittest/test_98_Icepak.py +++ b/_unittest/test_98_Icepak.py @@ -397,7 +397,7 @@ def test_31_automatic_mesh_pcb(self): def test_32_automatic_mesh_3d(self): self.aedtapp.set_active_design("IcepakDesign1") - assert self.aedtapp.mesh.automatic_mesh_3D(accuracy2=1) + assert self.aedtapp.mesh.automatic_mesh_3D(accuracy=1) def test_33_create_source(self): self.aedtapp.modeler.create_box([0, 0, 0], [20, 20, 20], name="boxSource") @@ -1039,9 +1039,9 @@ def test_56_mesh_priority(self): custom_x_resolution=400, custom_y_resolution=500, ) - assert self.aedtapp.mesh.add_priority(entity_type=1, obj_list=self.aedtapp.modeler.object_names, priority=2) + assert self.aedtapp.mesh.add_priority(entity_type=1, assignment=self.aedtapp.modeler.object_names, priority=2) assert self.aedtapp.mesh.add_priority( - entity_type=2, comp_name=self.aedtapp.modeler.user_defined_component_names[0], priority=1 + entity_type=2, component=self.aedtapp.modeler.user_defined_component_names[0], priority=1 ) def test_57_update_source(self): @@ -1247,7 +1247,7 @@ def test_62_get_fans_operating_point(self, add_app): assert len(list(op_dict.keys())) == 2 app.set_active_design("get_fan_op_point1") app.get_fans_operating_point() - app.get_fans_operating_point(timestep="0") + app.get_fans_operating_point(time_step="0") app.close_project() def test_63_generate_mesh(self): @@ -1354,11 +1354,11 @@ def test_68_mesh_priority_3d_comp(self, add_app): design_name="IcepakDesign1", subfolder=test_subfolder, ) - assert app.mesh.add_priority(entity_type=2, comp_name="IcepakDesign1_1", priority=3) + assert app.mesh.add_priority(entity_type=2, component="IcepakDesign1_1", priority=3) - assert app.mesh.add_priority(entity_type=2, comp_name="all_2d_objects1", priority=2) + assert app.mesh.add_priority(entity_type=2, component="all_2d_objects1", priority=2) - assert app.mesh.add_priority(entity_type=2, comp_name="all_3d_objects1", priority=2) + assert app.mesh.add_priority(entity_type=2, component="all_3d_objects1", priority=2) app.close_project(name="3d_comp_mesh_prio_test", save_project=False) diff --git a/_unittest/test_launch_desktop.py b/_unittest/test_launch_desktop.py index 073e0bdeb9d..31cc0f83ddd 100644 --- a/_unittest/test_launch_desktop.py +++ b/_unittest/test_launch_desktop.py @@ -64,7 +64,7 @@ def test_run_desktop_maxwell2d(self): def test_run_desktop_hfss(self): aedtapp = Hfss() assert aedtapp.design_type == "HFSS" - assert "Modal" in aedtapp.solution_type + assert "Terminal" in aedtapp.solution_type def test_run_desktop_maxwell3d(self): aedtapp = Maxwell3d() diff --git a/_unittest_ironpython/run_unittests.py b/_unittest_ironpython/run_unittests.py index 290d36706f4..bc54ac015f0 100644 --- a/_unittest_ironpython/run_unittests.py +++ b/_unittest_ironpython/run_unittests.py @@ -121,7 +121,7 @@ def test_run_desktop_maxwell2d(self): def test_run_desktop_hfss(self): aedtapp = Hfss() self.assertTrue(aedtapp.design_type == "HFSS") - self.assertTrue("Modal" in aedtapp.solution_type) + self.assertTrue("Terminal" in aedtapp.solution_type) self.assertTrue(aedtapp.modeler) self.assertTrue(aedtapp.post) self.assertTrue(aedtapp.materials) diff --git a/_unittest_solvers/conftest.py b/_unittest_solvers/conftest.py index 90bbaf63b55..6d581605884 100644 --- a/_unittest_solvers/conftest.py +++ b/_unittest_solvers/conftest.py @@ -35,7 +35,7 @@ settings.enable_error_handler = False settings.enable_desktop_logs = False settings.desktop_launch_timeout = 180 - +settings.release_on_exception = False from pyaedt.aedt_logger import pyaedt_logger from pyaedt.generic.general_methods import generate_unique_name diff --git a/_unittest_solvers/test_00_analyze.py b/_unittest_solvers/test_00_analyze.py index 4a5e93d7120..4a04533c5f3 100644 --- a/_unittest_solvers/test_00_analyze.py +++ b/_unittest_solvers/test_00_analyze.py @@ -107,29 +107,20 @@ def init(self, local_scratch, icepak_app, hfss3dl_solve): @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="Not supported.") def test_01a_sbr_link_array(self, sbr_platform, array): - assert sbr_platform.create_sbr_linked_antenna(array, target_cs="antenna_CS", fieldtype="farfield") + assert sbr_platform.create_sbr_linked_antenna(array, target_cs="antenna_CS", field_type="farfield") sbr_platform.analyze(num_cores=6) - ffdata = sbr_platform.get_antenna_ffd_solution_data(frequencies=12e9, sphere_name="3D") - ffdata2 = sbr_platform.get_antenna_ffd_solution_data(frequencies=12e9, sphere_name="3D", overwrite=False) - - ffdata.plot_2d_cut( - primary_sweep="theta", - secondary_sweep_value=[75], - theta_scan=20, - farfield_quantity="RealizedGain", - title="Azimuth at {}Hz".format(ffdata.frequency), - quantity_format="dB10", - export_image_path=os.path.join(self.local_scratch.path, "2d1_array.jpg"), - ) + ffdata = sbr_platform.get_antenna_ffd_solution_data(frequencies=12e9, sphere="3D") + ffdata2 = sbr_platform.get_antenna_ffd_solution_data(frequencies=12e9, sphere="3D", overwrite=False) + + ffdata.plot_2d_cut(quantity="RealizedGain", primary_sweep="theta", secondary_sweep_value=[75], theta=20, + title="Azimuth at {}Hz".format(ffdata.frequency), quantity_format="dB10", + image_path=os.path.join(self.local_scratch.path, "2d1_array.jpg")) assert os.path.exists(os.path.join(self.local_scratch.path, "2d1_array.jpg")) - ffdata2.polar_plot_3d_pyvista( - farfield_quantity="RealizedGain", - convert_to_db=True, - show=False, - rotation=[[1, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]], - export_image_path=os.path.join(self.local_scratch.path, "3d2_array.jpg"), - ) + ffdata2.polar_plot_3d_pyvista(quantity="RealizedGain", + rotation=[[1, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]], + image_path=os.path.join(self.local_scratch.path, "3d2_array.jpg"), show=False, + convert_to_db=True) assert os.path.exists(os.path.join(self.local_scratch.path, "3d2_array.jpg")) def test_01b_sbr_create_vrt(self, sbr_app): @@ -181,7 +172,7 @@ def test_02_hfss_export_results(self, hfss_app): hfss_app.add_3d_component_array_from_json(dict_in) exported_files = hfss_app.export_results() assert len(exported_files) == 0 - setup = hfss_app.create_setup(setupname="test") + setup = hfss_app.create_setup(name="test") setup.props["Frequency"] = "1GHz" exported_files = hfss_app.export_results() assert len(exported_files) == 0 @@ -194,14 +185,12 @@ def test_02_hfss_export_results(self, hfss_app): assert len(exported_files) > 0 fld_file1 = os.path.join(self.local_scratch.path, "test_fld_hfss1.fld") - assert hfss_app.post.export_field_file( - quantity_name="Mag_E", filename=fld_file1, obj_list="Box1", intrinsics="1GHz", phase="5deg" - ) + assert hfss_app.post.export_field_file(quantity="Mag_E", output_dir=fld_file1, assignment="Box1", + intrinsics="1GHz", phase="5deg") assert os.path.exists(fld_file1) fld_file2 = os.path.join(self.local_scratch.path, "test_fld_hfss2.fld") - assert hfss_app.post.export_field_file( - quantity_name="Mag_E", filename=fld_file2, obj_list="Box1", intrinsics="1GHz" - ) + assert hfss_app.post.export_field_file(quantity="Mag_E", output_dir=fld_file2, assignment="Box1", + intrinsics="1GHz") assert os.path.exists(fld_file2) def test_03a_icepak_analyze_and_export_summary(self): @@ -289,8 +278,7 @@ def test_03c_icepak_get_monitor_output(self): assert self.icepak_app.monitor.all_monitors["test_monitor"].value() assert self.icepak_app.monitor.all_monitors["test_monitor"].value(quantity="Temperature") assert self.icepak_app.monitor.all_monitors["test_monitor"].value( - setup_name=self.icepak_app.existing_analysis_sweeps[0] - ) + setup=self.icepak_app.existing_analysis_sweeps[0]) assert self.icepak_app.monitor.all_monitors["test_monitor2"].value(quantity="HeatFlowRate") def test_03d_icepak_eval_tempc(self): @@ -302,48 +290,30 @@ def test_03d_icepak_eval_tempc(self): def test_03e_icepak_ExportFLDFil(self): fld_file = os.path.join(self.local_scratch.path, "test_fld.fld") - self.icepak_app.post.export_field_file( - quantity_name="Temp", - solution=self.icepak_app.nominal_sweep, - variation_dict={}, - filename=fld_file, - obj_list="box", - ) + self.icepak_app.post.export_field_file(quantity="Temp", solution=self.icepak_app.nominal_sweep, variations={}, + output_dir=fld_file, assignment="box") assert os.path.exists(fld_file) fld_file_1 = os.path.join(self.local_scratch.path, "test_fld_1.fld") sample_points_file = os.path.join(local_path, "example_models", test_subfolder, "temp_points.pts") - self.icepak_app.post.export_field_file( - quantity_name="Temp", - solution=self.icepak_app.nominal_sweep, - variation_dict=self.icepak_app.available_variations.nominal_w_values_dict, - filename=fld_file_1, - obj_list="box", - sample_points_file=sample_points_file, - ) + self.icepak_app.post.export_field_file(quantity="Temp", solution=self.icepak_app.nominal_sweep, + variations=self.icepak_app.available_variations.nominal_w_values_dict, + output_dir=fld_file_1, assignment="box", + sample_points_file=sample_points_file) assert os.path.exists(fld_file_1) fld_file_2 = os.path.join(self.local_scratch.path, "test_fld_2.fld") - self.icepak_app.post.export_field_file( - quantity_name="Temp", - solution=self.icepak_app.nominal_sweep, - variation_dict=self.icepak_app.available_variations.nominal_w_values_dict, - filename=fld_file_2, - obj_list="box", - sample_points_lists=[[0, 0, 0], [3, 6, 8], [4, 7, 9]], - ) + self.icepak_app.post.export_field_file(quantity="Temp", solution=self.icepak_app.nominal_sweep, + variations=self.icepak_app.available_variations.nominal_w_values_dict, + output_dir=fld_file_2, assignment="box", + sample_points=[[0, 0, 0], [3, 6, 8], [4, 7, 9]]) assert os.path.exists(fld_file_2) cs = self.icepak_app.modeler.create_coordinate_system() fld_file_3 = os.path.join(self.local_scratch.path, "test_fld_3.fld") - self.icepak_app.post.export_field_file( - quantity_name="Temp", - solution=self.icepak_app.nominal_sweep, - variation_dict=self.icepak_app.available_variations.nominal_w_values_dict, - filename=fld_file_3, - obj_list="box", - sample_points_lists=[[0, 0, 0], [3, 6, 8], [4, 7, 9]], - reference_coordinate_system=cs.name, - export_in_si_system=False, - export_field_in_reference=False, - ) + self.icepak_app.post.export_field_file(quantity="Temp", solution=self.icepak_app.nominal_sweep, + variations=self.icepak_app.available_variations.nominal_w_values_dict, + output_dir=fld_file_3, assignment="box", + sample_points=[[0, 0, 0], [3, 6, 8], [4, 7, 9]], + reference_coordinate_system=cs.name, export_in_si_system=False, + export_field_in_reference=False) assert os.path.exists(fld_file_3) def test_04a_3dl_generate_mesh(self): @@ -389,7 +359,7 @@ def test_04h_3dl_get_all_return_loss_list(self): assert self.hfss3dl_solve.get_all_return_loss_list() == ["S(Port1,Port1)", "S(Port2,Port2)"] def test_04i_3dl_get_all_insertion_loss_list(self): - assert self.hfss3dl_solve.get_all_insertion_loss_list() == ["S(Port1,Port1)", "S(Port2,Port2)"] + assert self.hfss3dl_solve.get_all_insertion_loss_list(tx_prefix="Port1", rx_prefix="Port2") == ['S(Port1,Port2)'] def test_04j_3dl_get_next_xtalk_list(self): assert self.hfss3dl_solve.get_next_xtalk_list() == ["S(Port1,Port2)"] @@ -406,14 +376,8 @@ def test_05a_circuit_add_3dlayout_component(self, circuit_app): tx = ports rx = ports insertions = ["dB(S({},{}))".format(i.name, j.name) for i, j in zip(tx, rx)] - assert circuit_app.post.create_report( - insertions, - circuit_app.nominal_adaptive, - plotname="Insertion Losses", - plot_type="Rectangular Plot", - report_category="Standard", - subdesign_id=myedb.id, - ) + assert circuit_app.post.create_report(insertions, circuit_app.nominal_adaptive, report_category="Standard", + plot_type="Rectangular Plot", subdesign_id=myedb.id) new_report = circuit_app.post.reports_by_category.standard(insertions) new_report.sub_design_id = myedb.id assert new_report.create() @@ -433,54 +397,37 @@ def test_05c_circuit_push_excitation(self, circuit_app): def test_05d_circuit_push_excitation_time(self, circuit_app): setup_name = "test_07b_Transient" - setup = circuit_app.create_setup(setup_name, setuptype="NexximTransient") + setup = circuit_app.create_setup(setup_name, setup_type="NexximTransient") assert circuit_app.push_time_excitations(instance_name="U1", setup_name=setup_name) def test_06_m3d_harmonic_forces(self, m3dtransient): - assert m3dtransient.enable_harmonic_force( - ["Stator"], - force_type=2, - window_function="Rectangular", - use_number_of_last_cycles=True, - last_cycles_number=3, - calculate_force="Harmonic", - ) + assert m3dtransient.enable_harmonic_force(["Stator"], force_type=2, window_function="Rectangular", + use_number_of_last_cycles=True, last_cycles_number=3, + calculate_force="Harmonic") m3dtransient.save_project() m3dtransient.analyze(m3dtransient.active_setup, num_cores=2) - assert m3dtransient.export_element_based_harmonic_force( - start_frequency=1, stop_frequency=100, number_of_frequency=None - ) + assert m3dtransient.export_element_based_harmonic_force(start_frequency=1, stop_frequency=100, + number_of_frequency=None) assert m3dtransient.export_element_based_harmonic_force(number_of_frequency=5) def test_07_export_maxwell_fields(self, m3dtransient): m3dtransient.analyze(m3dtransient.active_setup, num_cores=2) fld_file_3 = os.path.join(self.local_scratch.path, "test_fld_3.fld") - assert m3dtransient.post.export_field_file( - quantity_name="Mag_B", - solution=m3dtransient.nominal_sweep, - variation_dict={}, - filename=fld_file_3, - obj_list="Coil_A2", - intrinsics="10ms", - obj_type="Surf", - ) + assert m3dtransient.post.export_field_file(quantity="Mag_B", solution=m3dtransient.nominal_sweep, variations={}, + output_dir=fld_file_3, assignment="Coil_A2", objects_type="Surf", + intrinsics="10ms") assert os.path.exists(fld_file_3) fld_file_4 = os.path.join(self.local_scratch.path, "test_fld_4.fld") - assert not m3dtransient.post.export_field_file( - quantity_name="Mag_B", - solution=m3dtransient.nominal_sweep, - variation_dict=m3dtransient.available_variations.nominal_w_values_dict, - filename=fld_file_4, - obj_list="Coil_A2", - obj_type="invalid", - ) + assert not m3dtransient.post.export_field_file(quantity="Mag_B", solution=m3dtransient.nominal_sweep, + variations=m3dtransient.available_variations.nominal_w_values_dict, + output_dir=fld_file_4, assignment="Coil_A2", + objects_type="invalid") setup = m3dtransient.setups[0] m3dtransient.setups[0].delete() - assert not m3dtransient.post.export_field_file( - quantity_name="Mag_B", variation_dict={}, filename=fld_file_4, obj_list="Coil_A2" - ) + assert not m3dtransient.post.export_field_file(quantity="Mag_B", variations={}, output_dir=fld_file_4, + assignment="Coil_A2") - new_setup = m3dtransient.create_setup(setupname=setup.name, setuptype=setup.setuptype) + new_setup = m3dtransient.create_setup(name=setup.name, setup_type=setup.setuptype) new_setup.props = setup.props new_setup.update() diff --git a/_unittest_solvers/test_01_pdf.py b/_unittest_solvers/test_01_pdf.py index a7d4be96c1e..d5a649143c6 100644 --- a/_unittest_solvers/test_01_pdf.py +++ b/_unittest_solvers/test_01_pdf.py @@ -21,7 +21,7 @@ def aedtapp(add_app): class TestClass(object): def test_create_pdf(self, local_scratch): - report = AnsysReport(project_name="Coaxial", design_name="Design1") + report = AnsysReport(design_name="Design1", project_name="Coaxial") report.aedt_version = desktop_version assert "AnsysTemplate" in report.template_name report.template_name = "AnsysTemplate" diff --git a/_unittest_solvers/test_31_Q3D.py b/_unittest_solvers/test_31_Q3D.py index 5869c08eca5..f9a75a36b1b 100644 --- a/_unittest_solvers/test_31_Q3D.py +++ b/_unittest_solvers/test_31_Q3D.py @@ -75,26 +75,26 @@ def test_06a_create_setup(self): # Create a discrete sweep with the same name of an existing sweep is not possible. assert not self.aedtapp.create_discrete_sweep(mysetup.name, sweepname="mysweep", freqstart=1, units="GHz") assert mysetup.create_linear_step_sweep( - sweepname="StepFast", + name="StepFast", unit="GHz", - freqstart=1, - freqstop=20, + start_frequency=1, + stop_frequency=20, step_size=0.1, sweep_type="Interpolating", ) assert mysetup.create_linear_step_sweep( unit="GHz", - freqstart=1, - freqstop=20, + start_frequency=1, + stop_frequency=20, step_size=0.1, sweep_type="Interpolating", ) with pytest.raises(AttributeError) as execinfo: mysetup.create_linear_step_sweep( - sweepname="invalid_sweep", + name="invalid_sweep", unit="GHz", - freqstart=1, - freqstop=20, + start_frequency=1, + stop_frequency=20, step_size=0.1, sweep_type="Invalid", ) @@ -107,7 +107,7 @@ def test_06a_create_setup(self): ) assert mysetup.create_frequency_sweep( unit="GHz", - sweepname="Sweep1", + name="Sweep1", freqstart=9.5, freqstop="10.5GHz", sweep_type="Interpolating", @@ -292,7 +292,7 @@ def test_14_edit_sources(self, add_app): assert q3d.edit_sources(sources_cg, sources_ac) sources_dc = {"Box1:Source1": "20"} - assert q3d.edit_sources(dcrl=sources_dc) + assert q3d.edit_sources() sources_cg = {"Box2": "2V"} assert not q3d.edit_sources(sources_cg) @@ -307,88 +307,54 @@ def test_14_edit_sources(self, add_app): def test_15_export_matrix_data(self, add_app): q3d = add_app(application=Q3d, project_name=self.test_matrix, just_open=True) q3d.insert_reduced_matrix("JoinSeries", ["Source1", "Sink4"], "JointTest") - q3d.matrices[1].name == "JointTest" + assert q3d.matrices[1].name == "JointTest" q3d.insert_reduced_matrix("JoinParallel", ["Source1", "Source2"], "JointTest2") - q3d.matrices[2].name == "JointTest2" + assert q3d.matrices[2].name == "JointTest2" q3d.insert_reduced_matrix("FloatInfinity", None, "JointTest3") - q3d.matrices[3].name == "JointTest3" + assert q3d.matrices[3].name == "JointTest3" sweep = q3d.setups[0].add_sweep() q3d.analyze_setup(q3d.active_setup, num_cores=6) assert len(sweep.frequencies) > 0 assert sweep.basis_frequencies == [] assert q3d.export_matrix_data(os.path.join(self.local_scratch.path, "test.txt")) assert not q3d.export_matrix_data(os.path.join(self.local_scratch.path, "test.pdf")) - assert not q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), matrix_type="Test" - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - problem_type="C", - matrix_type="Maxwell, Spice, Couple", - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - problem_type="C", - matrix_type="Maxwell, Spice, Couple", - ) - assert not q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - problem_type="AC RL, DC RL", - matrix_type="Maxwell, Spice, Couple", - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), problem_type="AC RL, DC RL" - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - problem_type="AC RL, DC RL", - matrix_type="Maxwell, Couple", - ) - assert not q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - problem_type="AC", - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), setup_name="Setup1", sweep="LastAdaptive" - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), setup_name="Setup1", sweep="Last Adaptive" - ) - assert not q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), setup_name="Setup", sweep="LastAdaptive" - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), reduce_matrix="Original" - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), reduce_matrix="JointTest" - ) - assert not q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), reduce_matrix="JointTest4" - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - setup_name="Setup1", - sweep="LastAdaptive", - freq=1, - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), - setup_name="Setup1", - sweep="LastAdaptive", - freq=1, - freq_unit="kHz", - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), precision=16, field_width=22 - ) + assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + matrix_type="Test") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), problem_type="C", + matrix_type="Maxwell, Spice, Couple") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), problem_type="C", + matrix_type="Maxwell, Spice, Couple") + assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + problem_type="AC RL, DC RL", matrix_type="Maxwell, Spice, Couple") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + problem_type="AC RL, DC RL") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + problem_type="AC RL, DC RL", matrix_type="Maxwell, Couple") + assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + problem_type="AC") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), setup="Setup1", + sweep="LastAdaptive") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), setup="Setup1", + sweep="Last Adaptive") + assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), setup="Setup", + sweep="LastAdaptive") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + reduce_matrix="Original") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + reduce_matrix="JointTest") + assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + reduce_matrix="JointTest4") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), setup="Setup1", + sweep="LastAdaptive", freq=1) + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), setup="Setup1", + sweep="LastAdaptive", freq=1, freq_unit="kHz") + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), precision=16, + field_width=22) assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), precision=16.2) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), use_sci_notation=True - ) - assert q3d.export_matrix_data( - file_name=os.path.join(self.local_scratch.path, "test.txt"), use_sci_notation=False - ) + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + use_sci_notation=True) + assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), + use_sci_notation=False) assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), r_unit="mohm") assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), r_unit="A") assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), l_unit="nH") diff --git a/doc/Makefile b/doc/Makefile index 5e72f039b05..1336617c68a 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -29,11 +29,21 @@ clean: phtml: $(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -j auto +phtml-no-examples: + export PYAEDT_SKIP_EXAMPLE="1" + $(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -j auto + # Build pdf docs. pdf: @$(SPHINXBUILD) -M latex "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) cd $(BUILDDIR)/latex && latexmk -r latexmkrc -pdf *.tex -interaction=nonstopmode || true - (test -f $(BUILDDIR)/latex/pyaedt.pdf && echo pdf exists) || exit 1 + (test -f $(BUILDDIR)/latex/PyAEDT-Documentation-*.pdf && echo pdf exists) || exit 1 + +pdf-no-examples: + export PYAEDT_SKIP_EXAMPLE="1" + @$(SPHINXBUILD) -M latex "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + cd $(BUILDDIR)/latex && latexmk -r latexmkrc -pdf *.tex -interaction=nonstopmode || true + (test -f $(BUILDDIR)/latex/PyAEDT-Documentation-*.pdf && echo pdf exists) || exit 1 # build docs like the CI build cibuild: diff --git a/doc/make.bat b/doc/make.bat index 5c169485edb..226691ae917 100644 --- a/doc/make.bat +++ b/doc/make.bat @@ -33,10 +33,13 @@ goto end %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :pdf +set PYAEDT_SKIP_EXAMPLE=1 + + %SPHINXBUILD% -M latex %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% cd "%BUILDDIR%\latex" for %%f in (*.tex) do ( -pdflatex "%%f" --interaction=nonstopmode) +xelatex "%%f" --interaction=nonstopmode) :end popd diff --git a/doc/source/API/Post.rst b/doc/source/API/Post.rst index 22cc06f0075..440c8251794 100644 --- a/doc/source/API/Post.rst +++ b/doc/source/API/Post.rst @@ -37,7 +37,7 @@ plots in AEDT. They are accessible through the ``post`` property. post = app.post # This call returns a FieldPlot object - plotf = post.create_fieldplot_volume(object_list, quantityname, setup_name, intrinsic_dict) + plotf = post.create_fieldplot_volume(objects, quantity_name, setup_name, intrinsics) # This call returns a SolutionData object my_data = post.get_solution_data(expressions=trace_names) diff --git a/doc/source/User_guide/emit_modeler.rst b/doc/source/User_guide/emit_modeler.rst new file mode 100644 index 00000000000..a0365181733 --- /dev/null +++ b/doc/source/User_guide/emit_modeler.rst @@ -0,0 +1,156 @@ +EMIT modeler +============ +The ``EMIT Modeling`` module includes several classes to enable +modeling in EMIT: + + +* ``modeler`` to return the schematic modeler for an EMIT design. +* ``couplings`` to return a list of all linked couplings within an EMIT design. +* ``version`` to provide the EMIT version information. +* ``set_units`` to set the units globally for the EMIT design. +* ``get_units`` to get the value of the current EMIT design global units. + +EMIT version check and set units example: + +.. code:: python + + import pyaedt + from pyaedt import Emit + + emit = Emit(pyaedt.generate_unique_project_name(), + specified_version="2024.1", non_graphical=False, + new_desktop_session=True, close_on_exit=True) + + # This call returns detailed version info for EMIT + ver = emit.version(detailed=True) + + # This call sets the global units for EMIT + unit_types = ["Power", "Frequency", "Length", "Time"] + unit_vals = ["kW", "kHz", "meter", "ns"] + emit.set_units(unit_types, unit_vals) + + # This call gets all the global units for the EMIT design + all_units = emit.get_units() + + # This call gets the global Frequency units for the EMIT design + freq_units = emit.get_units("Frequency") + + # Close AEDT + emit.release_desktop(close_projects=True, close_desktop=True) + +EMIT-HFSS link creation example: + +.. code:: python + + import os + import pyaedt + from pyaedt import Emit + from pyaedt.generic.filesystem import Scratch + + scratch_path = pyaedt.generate_unique_folder_name() + temp_folder = os.path.join(scratch_path, ("EmitHFSSExample")) + if not os.path.exists(temp_folder): + os.mkdir(temp_folder) + + # Launch AEDT + aedtapp = pyaedt.launch_desktop(specified_version="2024.1", non_graphical=False, + new_desktop_session=True, close_on_exit=True) + + # Verify the ``Cell Phone RFT Defense`` example exists + example_name = "Cell Phone RFI Desense" + example_aedt = example_name + ".aedt" + example_results = example_name + ".aedtresults" + example_lock = example_aedt + ".lock" + example_pdf_file = example_name + " Example.pdf" + + example_dir = os.path.join(aedtapp.install_path, "Examples\\EMIT") + example_project = os.path.join(example_dir, example_aedt) + example_results_folder = os.path.join(example_dir, example_results) + example_pdf = os.path.join(example_dir, example_pdf_file) + + # If the ``Cell Phone RFT Defense`` example is not + # in the installation directory, exit from this example. + if not os.path.exists(example_project): + exit() + + # Copy the project to a temp directory + my_project = os.path.join(temp_folder, example_aedt) + my_results_folder = os.path.join(temp_folder, example_results) + my_project_lock = os.path.join(temp_folder, example_lock) + my_project_pdf = os.path.join(temp_folder, example_pdf_file) + + if os.path.exists(my_project): + os.remove(my_project) + + if os.path.exists(my_project_lock): + os.remove(my_project_lock) + + with Scratch(scratch_path) as local_scratch: + local_scratch.copyfile(example_project, my_project) + local_scratch.copyfolder(example_results_folder, my_results_folder) + if os.path.exists(example_pdf): + local_scratch.copyfile(example_pdf, my_project_pdf) + + emit = Emit(my_project) + + # Remove all existing links + for link in emit.couplings.coupling_names: + emit.couplings.delete_link(link) + + # Add the HFSS design as a coupling in EMIT + for link in emit.couplings.linkable_design_names: + emit.couplings.add_link(link) + + # Get all the antennas in the EMIT design + antennas = emit.couplings.antenna_nodes + for ant in antennas: + print(ant) + + # Close AEDT + emit.release_desktop(close_projects=True, close_desktop=True) + +Create and Analyze an EMIT project: + +.. code:: python + + import pyaedt + from pyaedt import Emit + from pyaedt.emit_core.emit_constants import TxRxMode, ResultType + + emit = Emit(pyaedt.generate_unique_project_name(), + specified_version="2024.1", non_graphical=False, + new_desktop_session=True, close_on_exit=True) + + # Create a radio and connect an antenna to it + rad1 = emit.modeler.components.create_component("New Radio") + ant1 = emit.modeler.components.create_component("Antenna") + if rad1 and ant1: + ant1.move_and_connect_to(rad1) + + # Quickly create 2 more radios with antennas automatically + # connected to them + rad2, ant2 = emit.modeler.components.create_radio_antenna("GPS Receiver") + rad3, ant3 = emit.modeler.components.create_radio_antenna("Bluetooth Low Energy (LE)", "Bluetooth") + + # Create a new ``Revision`` + rev = emit.results.analyze() + + # Get the receive bands enabled for the GPS Rx + rx_bands = rev.get_band_names(rad2.name, TxRxMode.RX) + + # Get the transmit bands enabled for the Bluetooth radio + tx_bands = rev.get_band_names(rad3.name, TxRxMode.TX) + + # Configure the interaction domain that will be analyzed + domain = emit.results.interaction_domain() + domain.set_receiver(rad2.name, rx_bands[0], -1) + domain.set_interferer(rad3.name,tx_bands[0]) + + # Analzye the domain and get the worst case interference + interaction = rev.run(domain) + worst = interaction.get_worst_instance(ResultType.EMI) + emi = worst.get_value(ResultType.EMI) + print("Worst case interference is: {} dB".format(emi)) + + # Close AEDT + emit.release_desktop(close_projects=True, close_desktop=True) \ No newline at end of file diff --git a/doc/source/User_guide/index.rst b/doc/source/User_guide/index.rst index 14b7e795d3a..677cccca066 100644 --- a/doc/source/User_guide/index.rst +++ b/doc/source/User_guide/index.rst @@ -61,6 +61,13 @@ For additional practical demonstrations, see How to generate reports, images, and PDF files. + .. grid-item-card:: EMIT Modeler + :link: emit_modeler + :link-type: doc + :margin: 2 2 0 0 + + How to create and analyze EMIT designs. + .. toctree:: :hidden: :maxdepth: 2 @@ -72,3 +79,4 @@ For additional practical demonstrations, see variables files postprocessing + emit_modeler diff --git a/doc/source/User_guide/modeler.rst b/doc/source/User_guide/modeler.rst index 57feb3883f3..5a2ca96e538 100644 --- a/doc/source/User_guide/modeler.rst +++ b/doc/source/User_guide/modeler.rst @@ -59,7 +59,15 @@ All objects support executing any modeler operation, such as union or subtractio box.subract(cyl) -.. image:: ../Resources/objects_operations.gif - :width: 800 - :alt: Object Modeler Operations +.. only:: latex + + The following demo is presented as an animated GIF. + `View online `_ + if you are reading the PDF version of this documentation. + +.. only:: html + + .. image:: ../Resources/objects_operations.gif + :width: 800 + :alt: Object Modeler Operations diff --git a/doc/source/User_guide/postprocessing.rst b/doc/source/User_guide/postprocessing.rst index 401acf4b5a9..3903a48a8b0 100644 --- a/doc/source/User_guide/postprocessing.rst +++ b/doc/source/User_guide/postprocessing.rst @@ -49,7 +49,7 @@ To access all available category, use the ``reports_by_category`` class. hfss.analyze_nominal() # Create a 3D far field new_report = hfss.post.reports_by_category.far_field(expressions="db(RealizedGainTotal)", - setup_name=hfss.nominal_adaptive) + setup=hfss.nominal_adaptive) You can plot the field plot directly in HFSS and export it to image files. @@ -67,8 +67,8 @@ You can plot the field plot directly in HFSS and export it to image files. # Create a field plot plot1 = hfss.post.create_fieldplot_cutplane(objlist=cutlist, quantityName=quantity_name, - setup_name=setup_name, - intrinsincDict=intrinsic) + setup=setup_name, + intrinsics=intrinsic) .. image:: ../Resources/field_plot.png @@ -92,7 +92,7 @@ PyAEDT leverages PyVista to export and plot fields outside AEDT, generating imag quantity="Mag_E", objects_list=cutlist, plot_type="CutPlane", - setup_name=setup_name, + setup=setup_name, intrinsics=intrinsic ) diff --git a/doc/source/_static/assets/download/.gitignore b/doc/source/_static/assets/download/.gitignore new file mode 100644 index 00000000000..e5af87e9b5d --- /dev/null +++ b/doc/source/_static/assets/download/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!README.md \ No newline at end of file diff --git a/doc/source/_static/assets/download/README.md b/doc/source/_static/assets/download/README.md new file mode 100644 index 00000000000..9a605ff50f7 --- /dev/null +++ b/doc/source/_static/assets/download/README.md @@ -0,0 +1 @@ +Downloadable assets are stored here. diff --git a/doc/source/_static/assets/index_api.png b/doc/source/_static/assets/index_api.png deleted file mode 100644 index 1c4513d3e29..00000000000 Binary files a/doc/source/_static/assets/index_api.png and /dev/null differ diff --git a/doc/source/_static/assets/index_api.svg b/doc/source/_static/assets/index_api.svg deleted file mode 100644 index 06563c92725..00000000000 --- a/doc/source/_static/assets/index_api.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - diff --git a/doc/source/_static/assets/index_contribute.png b/doc/source/_static/assets/index_contribute.png deleted file mode 100644 index b839bf0aa27..00000000000 Binary files a/doc/source/_static/assets/index_contribute.png and /dev/null differ diff --git a/doc/source/_static/assets/index_contribute.svg b/doc/source/_static/assets/index_contribute.svg deleted file mode 100644 index fe8cd3c5429..00000000000 --- a/doc/source/_static/assets/index_contribute.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - diff --git a/doc/source/_static/assets/index_examples.png b/doc/source/_static/assets/index_examples.png deleted file mode 100644 index 0cae884b30f..00000000000 Binary files a/doc/source/_static/assets/index_examples.png and /dev/null differ diff --git a/doc/source/_static/assets/index_examples.svg b/doc/source/_static/assets/index_examples.svg deleted file mode 100644 index d9ed8202a6c..00000000000 --- a/doc/source/_static/assets/index_examples.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/doc/source/_static/assets/index_getting_started.png b/doc/source/_static/assets/index_getting_started.png deleted file mode 100644 index fdf713e072e..00000000000 Binary files a/doc/source/_static/assets/index_getting_started.png and /dev/null differ diff --git a/doc/source/_static/assets/index_getting_started.svg b/doc/source/_static/assets/index_getting_started.svg deleted file mode 100644 index 95fbe4df44d..00000000000 --- a/doc/source/_static/assets/index_getting_started.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - diff --git a/doc/source/_static/assets/index_user_guide.png b/doc/source/_static/assets/index_user_guide.png deleted file mode 100644 index d27305b890b..00000000000 Binary files a/doc/source/_static/assets/index_user_guide.png and /dev/null differ diff --git a/doc/source/_static/assets/index_user_guide.svg b/doc/source/_static/assets/index_user_guide.svg deleted file mode 100644 index acfeaaf2b0c..00000000000 --- a/doc/source/_static/assets/index_user_guide.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - diff --git a/doc/source/conf.py b/doc/source/conf.py index b9d3743588f..8caa09fbebb 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -100,6 +100,7 @@ def setup(app): copyright = f"(c) {datetime.datetime.now().year} ANSYS, Inc. All rights reserved" author = "Ansys Inc." cname = os.getenv("DOCUMENTATION_CNAME", "nocname.com") +switcher_version = get_version_match(__version__) # Check for the local config file, otherwise use default desktop configuration local_config_file = os.path.join(local_path, "local_config.json") @@ -134,6 +135,7 @@ def setup(app): "sphinx.ext.inheritance_diagram", "numpydoc", "ansys_sphinx_theme.extension.linkcode", + "recommonmark", ] # Intersphinx mapping @@ -266,7 +268,7 @@ def setup(app): # necessary for pyvista when building the sphinx gallery pyvista.BUILDING_GALLERY = True - if config["run_examples"]: + if config["run_examples"] and not os.environ.get("PYAEDT_SKIP_EXAMPLE", False): extensions.append("sphinx_gallery.gen_gallery") sphinx_gallery_conf = { @@ -340,6 +342,13 @@ def setup(app): "url": "https://github.com/ansys/pyaedt/discussions", "icon": "fa fa-comment fa-fw", }, + { + "name": "Download documentation in PDF", + # NOTE: Changes to this URL must be reflected in CICD documentation build + "url": f"https://{cname}/version/{switcher_version}/_static/assets/download/pyaedt.pdf", + # noqa: E501 + "icon": "fa fa-file-pdf fa-fw", + }, ], "switcher": { "json_url": f"https://{cname}/versions.json", diff --git a/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py b/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py index 14ab64bc1a7..1d50229b835 100644 --- a/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py +++ b/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py @@ -108,13 +108,13 @@ # ~~~~~~~~~~~~~~~~~~~ # Get current source -current_source = hfss3dl.get_dcir_element_data_current_source(setup_name="my_setup") +current_source = hfss3dl.get_dcir_element_data_current_source(setup="my_setup") print(current_source) # ~~~~~~~~~~~~~~~~~~~ # Get via information -via = hfss3dl.get_dcir_element_data_via(setup_name="my_setup") +via = hfss3dl.get_dcir_element_data_via(setup="my_setup") print(via) @@ -122,10 +122,7 @@ # Get voltage # ~~~~~~~~~~~ # Get voltage from dcir solution data -voltage = hfss3dl.get_dcir_solution_data( - setup_name="my_setup", - show="Sources", - category="Voltage") +voltage = hfss3dl.get_dcir_solution_data(setup="my_setup", show="Sources", category="Voltage") print({expression: voltage.data_magnitude(expression) for expression in voltage.expressions}) ############################################################################### diff --git a/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py b/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py index 0ef1cb7852e..b80d13a75a6 100644 --- a/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py +++ b/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py @@ -89,19 +89,9 @@ # Create a setup and a sweep. setup = h3d.create_setup() -h3d.create_linear_count_sweep( - setupname=setup.name, - unit="GHz", - freqstart=3, - freqstop=7, - num_of_freq_points=1001, - sweepname="sweep1", - sweep_type="Interpolating", - interpolation_tol_percent=1, - interpolation_max_solutions=255, - save_fields=False, - use_q3d_for_dc=False, -) +h3d.create_linear_count_sweep(setup=setup.name, unit="GHz", start_frequency=3, stop_frequency=7, + num_of_freq_points=1001, save_fields=False, sweep_type="Interpolating", + interpolation_tol_percent=1, interpolation_max_solutions=255, use_q3d_for_dc=False) ############################################################################### # Solve and plot results @@ -120,7 +110,7 @@ traces = h3d.get_traces_for_plot(first_element_filter="Port1", category="S") solutions = h3d.post.get_solution_data(expressions=traces) -solutions.plot(math_formula="db20") +solutions.plot(formula="db20") ############################################################################### # Close AEDT diff --git a/examples/01-HFSS3DLayout/Hfss3DComponent.py b/examples/01-HFSS3DLayout/Hfss3DComponent.py index 556920e7980..cd95384f43f 100644 --- a/examples/01-HFSS3DLayout/Hfss3DComponent.py +++ b/examples/01-HFSS3DLayout/Hfss3DComponent.py @@ -119,7 +119,7 @@ rect1 = hfss.modeler.create_rectangle(csPlane=hfss.PLANE.YZ, position=["0.75*dielectric_length", "-5*" + t1.width.name, "0mm"], dimension_list=["15*" + t1.width.name, "-3*" + stackup.thickness.name]) -p1 = hfss.wave_port(signal=rect1, reference="G1", name="P1") +p1 = hfss.wave_port(assignment=rect1, reference="G1", name="P1") ############################################################################### # Set Simulation Boundaries @@ -156,7 +156,7 @@ traces = hfss.get_traces_for_plot(category="S") solutions = hfss.post.get_solution_data(traces) -solutions.plot(traces, math_formula="db20") +solutions.plot(traces, formula="db20") ############################################################################### # Hfss 3D Layout Example @@ -232,7 +232,7 @@ traces = h3d.get_traces_for_plot(category="S") solutions = h3d.post.get_solution_data(traces) -solutions.plot(traces, math_formula="db20") +solutions.plot(traces, formula="db20") h3d.save_project() h3d.release_desktop() diff --git a/examples/01-Modeling-Setup/Optimetrics.py b/examples/01-Modeling-Setup/Optimetrics.py index 4c106df29db..2e3143e9e94 100644 --- a/examples/01-Modeling-Setup/Optimetrics.py +++ b/examples/01-Modeling-Setup/Optimetrics.py @@ -74,7 +74,13 @@ setup = hfss.create_setup() hfss.create_linear_step_sweep( - setupname=setup.name, unit="GHz", freqstart=1, freqstop=5, step_size=0.1, sweepname="Sweep1", save_fields=True + setup_name=setup.name, + unit="GHz", + start_frequency=1, + stop_frequency=5, + step_size=0.1, + sweep_name="Sweep1", + save_fields=True ) ############################################################################### diff --git a/examples/02-HFSS/Array.py b/examples/02-HFSS/Array.py index 31164948db8..6307d5edc36 100644 --- a/examples/02-HFSS/Array.py +++ b/examples/02-HFSS/Array.py @@ -92,8 +92,7 @@ # 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_ffd_solution_data(sphere_name="Infinite Sphere1", setup_name=hfss.nominal_adaptive, - frequencies=[5e9]) +ffdata = hfss.get_antenna_ffd_solution_data(frequencies=[5e9], setup=hfss.nominal_adaptive, sphere="Infinite Sphere1") ########################################################## # Generate contour plot @@ -101,8 +100,7 @@ # Generate a contour plot. You can define the Theta scan # and Phi scan. -ffdata.plot_farfield_contour(farfield_quantity='RealizedGain', - title='Contour at {}Hz'.format(ffdata.frequency)) +ffdata.plot_farfield_contour(quantity='RealizedGain', title='Contour at {}Hz'.format(ffdata.frequency)) ########################################################## # Release AEDT @@ -129,8 +127,7 @@ # Generate a contour plot. You can define the Theta scan # and Phi scan. -ffdata.plot_farfield_contour(farfield_quantity='RealizedGain', - title='Contour at {}Hz'.format(ffdata.frequency)) +ffdata.plot_farfield_contour(quantity='RealizedGain', title='Contour at {}Hz'.format(ffdata.frequency)) ########################################################## # Generate 2D cutout plots @@ -138,14 +135,10 @@ # Generate 2D cutout plots. You can define the Theta scan # and Phi scan. -ffdata.plot_2d_cut(primary_sweep='theta', secondary_sweep_value=[-180, -75, 75], - farfield_quantity='RealizedGain', - title='Azimuth at {}Hz'.format(ffdata.frequency), - quantity_format="dB10") +ffdata.plot_2d_cut(quantity='RealizedGain', primary_sweep='theta', secondary_sweep_value=[-180, -75, 75], + title='Azimuth at {}Hz'.format(ffdata.frequency), quantity_format="dB10") -ffdata.plot_2d_cut(primary_sweep="phi", secondary_sweep_value=30, - farfield_quantity='RealizedGain', - title='Elevation', +ffdata.plot_2d_cut(quantity='RealizedGain', primary_sweep="phi", secondary_sweep_value=30, title='Elevation', quantity_format="dB10") ########################################################## @@ -154,4 +147,4 @@ # Generate 3D polar plots in Matplotlib. You can define # the Theta scan and Phi scan. -ffdata.polar_plot_3d(farfield_quantity='RealizedGain') +ffdata.polar_plot_3d(quantity='RealizedGain') diff --git a/examples/02-HFSS/Create_3d_Component_and_use_it.py b/examples/02-HFSS/Create_3d_Component_and_use_it.py index 6ef39c6552f..f7bc5cf8398 100644 --- a/examples/02-HFSS/Create_3d_Component_and_use_it.py +++ b/examples/02-HFSS/Create_3d_Component_and_use_it.py @@ -80,7 +80,7 @@ # ~~~~~~~~~~~~~~~~ # Wave port can be assigned to a sheet or to a face of an object. -hfss.wave_port(via_outer.bottom_face_z, name="P1", ) +hfss.wave_port(via_outer.bottom_face_z, name="P1") ########################################################## # Create 3D Component diff --git a/examples/02-HFSS/Flex_CPWG.py b/examples/02-HFSS/Flex_CPWG.py index 65cd87afcd7..957b9f00358 100644 --- a/examples/02-HFSS/Flex_CPWG.py +++ b/examples/02-HFSS/Flex_CPWG.py @@ -189,7 +189,7 @@ def create_bending(radius, extension=0): 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) + hfss.wave_port(s.id, reference=reference, name=port_name) ############################################################################### # Create setup and sweep @@ -200,16 +200,8 @@ def create_bending(radius, extension=0): setup["Frequency"] = "2GHz" setup.props["MaximumPasses"] = 10 setup.props["MinimumConvergedPasses"] = 2 -hfss.create_linear_count_sweep( - setupname="setup1", - unit="GHz", - freqstart=1e-1, - freqstop=4, - num_of_freq_points=101, - sweepname="sweep1", - save_fields=False, - sweep_type="Interpolating", -) +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") ############################################################################### # Plot model diff --git a/examples/02-HFSS/HFSS_Choke.py b/examples/02-HFSS/HFSS_Choke.py index 91fb6532f49..a4fe164556b 100644 --- a/examples/02-HFSS/HFSS_Choke.py +++ b/examples/02-HFSS/HFSS_Choke.py @@ -12,7 +12,7 @@ import os import pyaedt -project_name = pyaedt.generate_unique_project_name(project_name="choke") +project_name = pyaedt.generate_unique_project_name(rootname=r"C:\Data\Support\Test", folder_name="choke", project_name="choke") ########################################################## # Set AEDT version @@ -148,7 +148,7 @@ 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", matname="copper") -coat = hfss.assign_coating(ground, isinfgnd=True) +coat = hfss.assign_coating(ground, is_infinite_ground=True) ############################################################################### # Create lumped ports @@ -165,10 +165,8 @@ 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(signal=sheet.name, - name="port_" + str(port_position_list.index(position) + 1), - reference=[ground] - ) + hfss.lumped_port(assignment=sheet.name, reference=[ground], + name="port_" + str(port_position_list.index(position) + 1)) ############################################################################### # Create mesh @@ -180,7 +178,7 @@ mesh_operation_cylinder = hfss.modeler.create_cylinder( "XY", cylinder_position, ground_radius, cylinder_height, numSides=36, name="mesh_cylinder" ) -hfss.mesh.assign_length_mesh([mesh_operation_cylinder], maxlength=15, maxel=None, meshop_name="choke_mesh") +hfss.mesh.assign_length_mesh([mesh_operation_cylinder], maximum_length=15, maximum_elements=None, name="choke_mesh") ############################################################################### @@ -200,16 +198,8 @@ setup = hfss.create_setup("MySetup") setup.props["Frequency"] = "50MHz" setup["MaximumPasses"] = 10 -hfss.create_linear_count_sweep( - setupname=setup.name, - unit="MHz", - freqstart=0.1, - freqstop=100, - num_of_freq_points=100, - sweepname="sweep1", - sweep_type="Interpolating", - save_fields=False, -) +hfss.create_linear_count_sweep(setup=setup.name, units="MHz", start_frequency=0.1, stop_frequency=100, + num_of_freq_points=100, name="sweep1", save_fields=False, sweep_type="Interpolating") ############################################################################### # Save project diff --git a/examples/02-HFSS/HFSS_Dipole.py b/examples/02-HFSS/HFSS_Dipole.py index cf2a2313798..93700435f3a 100644 --- a/examples/02-HFSS/HFSS_Dipole.py +++ b/examples/02-HFSS/HFSS_Dipole.py @@ -67,7 +67,7 @@ # ~~~~~~~~~~~~~~~~~ # Create boundaries. A region with openings is needed to run the analysis. -hfss.create_open_region(Frequency="1GHz") +hfss.create_open_region(frequency="1GHz") ############################################################################### # Plot model @@ -90,18 +90,9 @@ setup = hfss.create_setup("MySetup") setup.props["Frequency"] = "1GHz" setup.props["MaximumPasses"] = 1 -hfss.create_linear_count_sweep( - setupname=setup.name, - unit="GHz", - freqstart=0.5, - freqstop=1.5, - num_of_freq_points=251, - sweepname="sweep1", - sweep_type="Interpolating", - interpolation_tol=3, - interpolation_max_solutions=255, - save_fields=False, -) +hfss.create_linear_count_sweep(setup=setup.name, units="GHz", start_frequency=0.5, stop_frequency=1.5, + num_of_freq_points=251, name="sweep1", save_fields=False, sweep_type="Interpolating", + interpolation_tol=3, interpolation_max_solutions=255) ############################################################################### # Save and run simulation @@ -120,14 +111,8 @@ 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", -) +hfss.post.create_report("db(GainTotal)", hfss.nominal_adaptive, variations, primary_sweep_variable="Theta", + report_category="Far Fields", context="3D") ############################################################################### # Create far fields report using report objects @@ -204,7 +189,7 @@ # Generate a 2D plot using Matplotlib where you specify whether it is a polar # plot or a rectangular plot. -solutions.plot(math_formula="db20", is_polar=True) +solutions.plot(formula="db20", is_polar=True) ########################################################## # Get far field data @@ -213,8 +198,8 @@ # field data is generated port by port and stored in a data class, , user can use this data # once AEDT is released. -ffdata = hfss.get_antenna_ffd_solution_data(sphere_name="Sphere_Custom", setup_name=hfss.nominal_adaptive, - frequencies=["1000MHz"]) +ffdata = hfss.get_antenna_ffd_solution_data(frequencies=["1000MHz"], setup=hfss.nominal_adaptive, + sphere="Sphere_Custom") ########################################################## # Generate 2D cutout plot @@ -222,11 +207,8 @@ # Generate 2D cutout plot. You can define the Theta scan # and Phi scan. -ffdata.plot_2d_cut(primary_sweep="theta", secondary_sweep_value=0, - farfield_quantity='RealizedGain', - title='FarField', - quantity_format="dB20", - is_polar=True) +ffdata.plot_2d_cut(quantity='RealizedGain', primary_sweep="theta", secondary_sweep_value=0, title='FarField', + quantity_format="dB20", is_polar=True) ############################################################################### # Close AEDT diff --git a/examples/02-HFSS/HFSS_FSS_unitcell.py b/examples/02-HFSS/HFSS_FSS_unitcell.py index caac56f878b..182ea23c047 100644 --- a/examples/02-HFSS/HFSS_FSS_unitcell.py +++ b/examples/02-HFSS/HFSS_FSS_unitcell.py @@ -90,7 +90,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Assigning lattice pair boundary automatically detected. -hfss.auto_assign_lattice_pairs(object_to_assign=region.name) +hfss.auto_assign_lattice_pairs(assignment=region.name) ############################################################################### # Assign Floquet port excitation along +Z direction @@ -98,8 +98,8 @@ # Assign Floquet port. id_z_pos = region.top_face_z -hfss.create_floquet_port(id_z_pos, [0, 0, z_max], [0, y_max, z_max], [x_max, 0, z_max], - portname='port_z_max', deembed_dist=10 * bounding_dimensions[2]) +hfss.create_floquet_port(id_z_pos, [0, 0, z_max], [0, y_max, z_max], [x_max, 0, z_max], name='port_z_max', + deembed_distance=10 * bounding_dimensions[2]) ############################################################################### @@ -110,17 +110,9 @@ setup = hfss.create_setup("MySetup") setup.props["Frequency"] = "10GHz" setup.props["MaximumPasses"] = 10 -hfss.create_linear_count_sweep( - setupname=setup.name, - unit="GHz", - freqstart=6, - freqstop=15, - num_of_freq_points=51, - sweepname="sweep1", - sweep_type="Interpolating", - interpolation_tol=6, - save_fields=False, -) +hfss.create_linear_count_sweep(setup=setup.name, units="GHz", start_frequency=6, stop_frequency=15, + num_of_freq_points=51, name="sweep1", save_fields=False, sweep_type="Interpolating", + interpolation_tol=6) ############################################################################### # Create S-parameter report using report objects @@ -137,16 +129,8 @@ str_mag.append("mag(" + i + ")") str_ang.append("ang_deg(" + i + ")") -hfss.post.create_report( - expressions=str_mag, - variations=variation, - plotname="magnitude_plot", -) -hfss.post.create_report( - expressions=str_ang, - variations=variation, - plotname="phase_plot", -) +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 diff --git a/examples/02-HFSS/HFSS_Spiral.py b/examples/02-HFSS/HFSS_Spiral.py index f48d24978a3..a9a3a0e863b 100644 --- a/examples/02-HFSS/HFSS_Spiral.py +++ b/examples/02-HFSS/HFSS_Spiral.py @@ -37,6 +37,7 @@ hfss = pyaedt.Hfss(specified_version=aedt_version, non_graphical=non_graphical, designname="A1", new_desktop_session=True) +hfss.solution_type = "Modal" hfss.modeler.model_units = "um" p = hfss.modeler @@ -105,7 +106,7 @@ def create_line(pts): dimension_list=[width, "Tsub+{}{}".format(gap, hfss.modeler.model_units)], name="port1" ) -hfss.lumped_port(signal="port1", integration_line=pyaedt.constants.AXIS.Z) +hfss.lumped_port(assignment="port1", integration_line=pyaedt.constants.AXIS.Z) ################################################################ # Create port 2 @@ -116,7 +117,7 @@ def create_line(pts): p.create_rectangle(pyaedt.constants.PLANE.YZ, [x1 - 5, y1 - width / 2, -thickness / 2], [width, "-Tsub"], name="port2") -hfss.lumped_port(signal="port2", integration_line=pyaedt.constants.AXIS.Z) +hfss.lumped_port(assignment="port2", integration_line=pyaedt.constants.AXIS.Z) ################################################################ # Create silicon substrate and ground plane @@ -165,10 +166,10 @@ def create_line(pts): # ~~~~~~~~~~~~ # Create the setup and define a frequency sweep to solve the project. -setup1 = hfss.create_setup(setupname="setup1") +setup1 = hfss.create_setup(name="setup1") setup1.props["Frequency"] = "10GHz" -hfss.create_linear_count_sweep(setupname="setup1", unit="GHz", freqstart=1e-3, freqstop=50, num_of_freq_points=451, - sweep_type="Interpolating") +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() @@ -193,7 +194,7 @@ def create_line(pts): # Plot the calculated values in Matplotlib. data = hfss.post.get_solution_data([L_formula, Q_formula]) -data.plot(curves=[L_formula, Q_formula], math_formula="re", xlabel="Freq", ylabel="L and Q") +data.plot(curves=[L_formula, Q_formula], formula="re", x_label="Freq", y_label="L and Q") ################################################################ # Export results to csv file diff --git a/examples/02-HFSS/Probe_Fed_Patch.py b/examples/02-HFSS/Probe_Fed_Patch.py index 03bae1cf75e..626620508bf 100644 --- a/examples/02-HFSS/Probe_Fed_Patch.py +++ b/examples/02-HFSS/Probe_Fed_Patch.py @@ -64,6 +64,7 @@ solution_type="Terminal", designname="patch", non_graphical=non_graphical, + new_desktop_session=True, specified_version=aedt_version) hfss.modeler.model_units = length_units @@ -87,14 +88,14 @@ hfss.assign_radiation_boundary_to_objects(region.name) patch.create_probe_port(ground, rel_x_offset=0.485) -setup = hfss.create_setup(setupname="Setup1", - setuptype="HFSSDriven", +setup = hfss.create_setup(name="Setup1", + setup_type="HFSSDriven", Frequency="10GHz") setup.create_frequency_sweep(unit="GHz", - sweepname="Sweep1", - freqstart=8, - freqstop=12, + name="Sweep1", + start_frequency=8, + stop_frequency=12, sweep_type="Interpolating") hfss.save_project() diff --git a/examples/02-HFSS/Waveguide_Filter.py b/examples/02-HFSS/Waveguide_Filter.py index b80ede20b16..ce05d14a8d3 100644 --- a/examples/02-HFSS/Waveguide_Filter.py +++ b/examples/02-HFSS/Waveguide_Filter.py @@ -65,8 +65,8 @@ specified_version=aedt_version, designname="filter", non_graphical=non_graphical, - new_desktop_session=True, - close_on_exit=True) + new_desktop_session=True) +hfss.solution_type = "Modal" # hfss.settings.enable_debug_methods_argument_logger = False # Only for debugging. @@ -191,9 +191,9 @@ def place_iris(zpos, dz, n): setup.create_frequency_sweep( unit="GHz", - sweepname="Sweep1", - freqstart=9.5, - freqstop=10.5, + name="Sweep1", + start_frequency=9.5, + stop_frequency=10.5, sweep_type="Interpolating", ) @@ -224,13 +224,9 @@ def place_iris(zpos, dz, n): # 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", - object_list=["Global:XZ"], - plot_type="CutPlane", - setup_name=hfss.nominal_adaptive, - intrinsics={"Freq": "9.8GHz", "Phase": "0deg"}, - export_path=hfss.working_directory, - show=False) +plot = hfss.post.plot_field(quantity="Mag_E", assignment=["Global:XZ"], plot_type="CutPlane", + setup=hfss.nominal_adaptive, intrinsics={"Freq": "9.8GHz", "Phase": "0deg"}, show=False, + export_path=hfss.working_directory) ############################################################################### # Save and close the desktop diff --git a/examples/02-SBR+/SBR_Doppler_Example.py b/examples/02-SBR+/SBR_Doppler_Example.py index 2dc6cb02331..f8f31307afc 100644 --- a/examples/02-SBR+/SBR_Doppler_Example.py +++ b/examples/02-SBR+/SBR_Doppler_Example.py @@ -120,13 +120,8 @@ # 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, - radar_name="Example_1Tx_1Rx", - offset=[2.57, 0, 0.54], - use_relative_cs=True, - relative_cs_name=car1.cs_name, -) +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 diff --git a/examples/02-SBR+/SBR_Example.py b/examples/02-SBR+/SBR_Example.py index 21536df865a..11105f1fb96 100644 --- a/examples/02-SBR+/SBR_Example.py +++ b/examples/02-SBR+/SBR_Example.py @@ -55,7 +55,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~ # Define a linked antenna. This is HFSS far field applied to HFSS SBR+. -target.create_sbr_linked_antenna(source, target_cs="feederPosition", fieldtype="farfield") +target.create_sbr_linked_antenna(source, target_cs="feederPosition", field_type="farfield") ############################################################################### # Assign boundaries @@ -96,14 +96,8 @@ 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", -) +target.post.create_report("db(GainTotal)", target.nominal_adaptive, variations=variations, + primary_sweep_variable="Theta", report_category="Far Fields", context="ATK_3D") ############################################################################### # Plot results outside AEDT diff --git a/examples/02-SBR+/SBR_Time_Plot.py b/examples/02-SBR+/SBR_Time_Plot.py index 5abf89a49ad..6384ef137ff 100644 --- a/examples/02-SBR+/SBR_Time_Plot.py +++ b/examples/02-SBR+/SBR_Time_Plot.py @@ -64,17 +64,14 @@ # 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_dir=os.path.join(hfss.working_directory, "csv")) + 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_list=frames_list_file, - output_gif_path=os.path.join(hfss.working_directory, "animation.gif"), - norm_index=15, - dy_rng=35, - show=False, view="xy", zoom=1) +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) hfss.release_desktop() diff --git a/examples/03-Maxwell/Maxwell2D_DCConduction.py b/examples/03-Maxwell/Maxwell2D_DCConduction.py index 6655291464d..2b9828647ae 100644 --- a/examples/03-Maxwell/Maxwell2D_DCConduction.py +++ b/examples/03-Maxwell/Maxwell2D_DCConduction.py @@ -92,14 +92,14 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 1V is the source, 0V ground -m2d.assign_matrix(sources=['1V'], group_sources=['0V'], matrix_name="Matrix1") +m2d.assign_matrix(assignment=['1V'], matrix_name="Matrix1", group_sources=['0V']) ################################################################################## # Assign mesh operation # ~~~~~~~~~~~~~~~~~~~~~ # 3mm on the conductor -m2d.mesh.assign_length_mesh(["ANSYS_LOGO_2D_3"], meshop_name="conductor", maxlength=3, maxel=None) +m2d.mesh.assign_length_mesh(["ANSYS_LOGO_2D_3"], maximum_length=3, maximum_elements=None, name="conductor") ################################################################################## # Create simulation setup and enable expression cache @@ -107,7 +107,7 @@ # Create simulation setup with minimum 4 adaptive passes to ensure convergence. # Enable expression cache to observe the convergence. -setup1 = m2d.create_setup(setupname="Setup1", MinimumPasses=4) +setup1 = m2d.create_setup(name="Setup1", MinimumPasses=4) setup1.enable_expression_cache( # doesn't work? report_type="DCConduction", expressions="1/Matrix1.G(1V,1V)/MaterialThickness", @@ -136,14 +136,9 @@ # Create R. vs. material report variations = {"MaterialIndex": ["All"], "MaterialThickness": ["Nominal"]} -report = m2d.post.create_report( - expressions="1/Matrix1.G(1V,1V)/MaterialThickness", - primary_sweep_variable="MaterialIndex", - report_category="DCConduction", - plot_type="Data Table", - variations=variations, - plotname="Resistance vs. Material", -) +report = m2d.post.create_report(expressions="1/Matrix1.G(1V,1V)/MaterialThickness", variations=variations, + primary_sweep_variable="MaterialIndex", report_category="DCConduction", + plot_type="Data Table", plot_name="Resistance vs. Material") ############################################################################### # Get solution data @@ -183,7 +178,7 @@ # ~~~~~~~~~~~~~ # Plot electric field using pyvista and saving to an image -py_vista_plot = m2d.post.plot_field("Mag_E", conductor_surface, plot_cad_objs=False, show=False) +py_vista_plot = m2d.post.plot_field("Mag_E", conductor_surface, show=False, plot_cad_objs=False) py_vista_plot.isometric_view = False py_vista_plot.camera_position = [0, 0, 7] py_vista_plot.focal_point = [0, 0, 0] @@ -197,16 +192,10 @@ # ~~~~~~~~~~~~~~~ # Plot current density vs the Material index. -animated = m2d.post.plot_animated_field( - quantity="Mag_J", - object_list=conductor_surface, - export_path=results_folder, - variation_variable="MaterialIndex", - variation_list=[0,1,2,3], - show=False, - export_gif=False, - log_scale=True, -) +animated = m2d.post.plot_animated_field(quantity="Mag_J", assignment=conductor_surface, + variation_variable="MaterialIndex", variations=[0, 1, 2, 3], + show=False, log_scale=True, export_gif=False, + export_path=results_folder) animated.isometric_view = False animated.camera_position = [0, 0, 7] animated.focal_point = [0, 0, 0] @@ -227,7 +216,7 @@ # ~~~~~~~~~~~~~~~~~~~ # Generate a PDF report with output of simulation. -pdf_report = AnsysReport(project_name=m2d.project_name, design_name=m2d.design_name, version=aedt_version) +pdf_report = AnsysReport(version=aedt_version, design_name=m2d.design_name, project_name=m2d.project_name) # Customize text font. diff --git a/examples/03-Maxwell/Maxwell2D_Electrostatic.py b/examples/03-Maxwell/Maxwell2D_Electrostatic.py index c25959d110c..57498b5c3f8 100644 --- a/examples/03-Maxwell/Maxwell2D_Electrostatic.py +++ b/examples/03-Maxwell/Maxwell2D_Electrostatic.py @@ -137,14 +137,14 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Assign a surface mesh to the rectangle. -M2D.mesh.assign_surface_mesh_manual(names=['Ground'], surf_dev=0.001) +M2D.mesh.assign_surface_mesh_manual(assignment=['Ground'], surface_deviation=0.001) ################################################################################## # Create, validate and analyze the setup # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create, update, validate and analyze the setup. -setup = M2D.create_setup(setupname=setup_name) +setup = M2D.create_setup(name=setup_name) setup.props['PercentError'] = 0.5 setup.update() M2D.validate_simple() @@ -177,8 +177,7 @@ # 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") + in_volume_tracing_objs="Region", plot_name="LineTracesTest") ################################################################################### # Update Field Line Traces Plot @@ -197,7 +196,7 @@ # Export field line traces plot. # For field lint traces plot, the export file format is ``.fldplt``. -M2D.post.export_field_plot(plotname="LineTracesTest", filepath=M2D.toolkit_directory, file_format="fldplt") +M2D.post.export_field_plot(plot_name="LineTracesTest", output_dir=M2D.toolkit_directory, file_format="fldplt") ########################################################## # Export a field plot to an image file @@ -211,7 +210,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~ # Export the mesh in ``aedtplt`` format. -M2D.post.export_mesh_obj(setup_name=M2D.nominal_adaptive) +M2D.post.export_mesh_obj(setup=M2D.nominal_adaptive) ################################################################################### # Save project and close AEDT diff --git a/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py b/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py index b49e9ca4360..3437fab9a6c 100644 --- a/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py +++ b/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py @@ -388,7 +388,7 @@ def create_cs_magnets(pm_id, cs_name, point_direction): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Assign a motion setup to a ``Band`` object named ``RotatingBand_mid``. -M2D.assign_rotate_motion(band_object='Band', coordinate_system="Global", axis="Z", positive_movement=True, +M2D.assign_rotate_motion(assignment='Band', coordinate_system="Global", axis="Z", positive_movement=True, start_position="InitialPositionMD", angular_velocity="MachineRPM") ########################################################## @@ -465,11 +465,8 @@ def create_cs_magnets(pm_id, cs_name, point_direction): id_bc_2 = mod2D.get_edgeid_from_position( position=[pos_1 + "*cos((360deg/SymmetryFactor))", pos_1 + "*sin((360deg/SymmetryFactor))", 0], obj_name='Region') -M2D.assign_master_slave(master_edge=id_bc_1, slave_edge=id_bc_2, - reverse_master=False, - reverse_slave=True, - same_as_master=False, - bound_name="Matching") +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 @@ -480,7 +477,7 @@ def create_cs_magnets(pm_id, cs_name, point_direction): id_bc_az = mod2D.get_edgeid_from_position( position=[pos_2 + "*cos((360deg/SymmetryFactor/2))", pos_2 + "*sin((360deg/SymmetryFactor)/2)", 0], obj_name='Region') -M2D.assign_vector_potential(id_bc_az, vectorvalue=0, bound_name="VectorPotentialZero") +M2D.assign_vector_potential(id_bc_az, vector_value=0, boundary="VectorPotentialZero") ########################################################## # Create excitations @@ -496,35 +493,33 @@ def create_cs_magnets(pm_id, cs_name, point_direction): # ~~~~~~~~~~~~~~~~~~~~~~~~~~ # Define windings in phase A. -M2D.assign_coil(input_object=["Coil"], conductor_number=6, polarity="Positive", name="CT_Ph1_P2_C1_Go") -M2D.assign_coil(input_object=["Coil_5"], conductor_number=6, polarity="Negative", name="CT_Ph1_P2_C1_Ret") -M2D.assign_winding(coil_terminals=None, winding_type="Current", is_solid=False, - current_value=PhA_current, parallel_branches=1, name="Phase_A") -M2D.add_winding_coils(windingname="Phase_A", coil_names=["CT_Ph1_P2_C1_Go", "CT_Ph1_P2_C1_Ret"]) +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=PhA_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 # ~~~~~~~~~~~~~~~~~~~~~~~~~~ # Define windings in phase B. -M2D.assign_coil(input_object="Coil_3", conductor_number=6, polarity="Positive", name="CT_Ph3_P1_C2_Go") -M2D.assign_coil(input_object="Coil_4", conductor_number=6, polarity="Positive", name="CT_Ph3_P1_C1_Go") -M2D.assign_winding(coil_terminals=None, winding_type="Current", is_solid=False, - current_value=PhB_current, parallel_branches=1, +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=PhB_current, parallel_branches=1, name="Phase_B") -M2D.add_winding_coils(windingname="Phase_B", coil_names=["CT_Ph3_P1_C2_Go", "CT_Ph3_P1_C1_Go"]) +M2D.add_winding_coils(assignment="Phase_B", coils=["CT_Ph3_P1_C2_Go", "CT_Ph3_P1_C1_Go"]) ########################################################## # Define windings in phase C # ~~~~~~~~~~~~~~~~~~~~~~~~~~ # Define windings in phase C. -M2D.assign_coil(input_object="Coil_1", conductor_number=6, polarity="Negative", name="CT_Ph2_P2_C2_Ret") -M2D.assign_coil(input_object="Coil_2", conductor_number=6, polarity="Negative", name="CT_Ph2_P2_C1_Ret") -M2D.assign_winding(coil_terminals=None, winding_type="Current", is_solid=False, - current_value=PhC_current, parallel_branches=1, +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=PhC_current, parallel_branches=1, name="Phase_C") -M2D.add_winding_coils(windingname="Phase_C", coil_names=["CT_Ph2_P2_C2_Ret", "CT_Ph2_P2_C1_Ret"]) +M2D.add_winding_coils(assignment="Phase_C", coils=["CT_Ph2_P2_C2_Ret", "CT_Ph2_P2_C1_Ret"]) ########################################################## # Assign total current on PMs @@ -540,9 +535,9 @@ def create_cs_magnets(pm_id, cs_name, point_direction): # ~~~~~~~~~~~~~~~~~~~~~~ # Create the mesh operations. -M2D.mesh.assign_length_mesh(id_coils, isinside=True, maxlength=3, maxel=None, meshop_name="coils") -M2D.mesh.assign_length_mesh(stator_id, isinside=True, maxlength=3, maxel=None, meshop_name="stator") -M2D.mesh.assign_length_mesh(rotor_id, isinside=True, maxlength=3, maxel=None, meshop_name="rotor") +M2D.mesh.assign_length_mesh(id_coils, inside_selection=True, maximum_length=3, maximum_elements=None, name="coils") +M2D.mesh.assign_length_mesh(stator_id, inside_selection=True, maximum_length=3, maximum_elements=None, name="stator") +M2D.mesh.assign_length_mesh(rotor_id, inside_selection=True, maximum_length=3, maximum_elements=None, name="rotor") ########################################################## # Turn on eddy effects @@ -585,7 +580,7 @@ def create_cs_magnets(pm_id, cs_name, point_direction): # ~~~~~~~~~~~~~~~~~~~~~~~~~ # Create the setup and validate it. -setup = M2D.create_setup(setupname=setup_name) +setup = M2D.create_setup(name=setup_name) setup.props["StopTime"] = "StopTime" setup.props["TimeStep"] = "TimeStep" setup.props["SaveFieldsType"] = "None" @@ -692,9 +687,9 @@ def create_cs_magnets(pm_id, cs_name, point_direction): 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, plotname=v) + 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 @@ -723,11 +718,8 @@ def create_cs_magnets(pm_id, cs_name, point_direction): # formerly created when the section is applied. faces_reg = mod2D.get_object_faces(object_list[1].name) # Region -plot1 = M2D.post.create_fieldplot_surface(objlist=faces_reg, - quantityName='Flux_Lines', - intrinsincDict={ - "Time": M2D.variable_manager.variables["StopTime"].evaluated_value}, - plot_name="Flux_Lines") +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 diff --git a/examples/03-Maxwell/Maxwell2D_Transient.py b/examples/03-Maxwell/Maxwell2D_Transient.py index 7014226eae3..2c84ff1995d 100644 --- a/examples/03-Maxwell/Maxwell2D_Transient.py +++ b/examples/03-Maxwell/Maxwell2D_Transient.py @@ -106,9 +106,8 @@ # ~~~~~~~~~~~~~~~~~~~~~~~ # Create a rectangular plot. -maxwell_2d.post.create_report( - "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", plotname="Winding Plot 1" -) +maxwell_2d.post.create_report("InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", + plot_name="Winding Plot 1") ############################################################################### # Solve model @@ -128,16 +127,9 @@ timesteps = [str(i * 2e-4) + "s" for i in range(11)] id_list = [f.id for f in face_lists] -gif = maxwell_2d.post.plot_animated_field( - quantity="Mag_B", - object_list=id_list, - plot_type="Surface", - intrinsics={"Time": "0s"}, - variation_variable="Time", - variation_list=timesteps, - show=False, - export_gif=False, -) +gif = maxwell_2d.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] diff --git a/examples/03-Maxwell/Maxwell3DTeam7.py b/examples/03-Maxwell/Maxwell3DTeam7.py index 08c7ce89066..995eb40d259 100644 --- a/examples/03-Maxwell/Maxwell3DTeam7.py +++ b/examples/03-Maxwell/Maxwell3DTeam7.py @@ -70,7 +70,7 @@ dc_freq = 0.1 stop_freq = 50 -setup = m3d.create_setup(setupname="Setup1") +setup = m3d.create_setup(name="Setup1") setup.props["Frequency"] = "200Hz" setup.props["HasSweepSetup"] = True setup.add_eddy_current_sweep("LinearStep", dc_freq, stop_freq, stop_freq - dc_freq, clear=True) @@ -155,7 +155,7 @@ Coil_Excitation = 2742 m3d["Coil_Excitation"] = str(Coil_Excitation) + "A" -m3d.assign_current(object_list="Coil_Section1", amplitude="Coil_Excitation", solid=False) +m3d.assign_current(assignment="Coil_Section1", amplitude="Coil_Excitation", solid=False) m3d.modeler.set_working_coordinate_system("Global") ########################################################################################### @@ -191,10 +191,9 @@ # for all parts. The setting for eddy effect is ignored for the stranded conductor type # used in the coil. -m3d.eddy_effects_on(object_list="Plate") -m3d.eddy_effects_on(object_list=["Coil", "Region", "Line_A1_B1mesh", "Line_A2_B2mesh"], - activate_eddy_effects=False, - activate_displacement_current=False) +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 @@ -398,14 +397,8 @@ "Phase": ["0deg", "90deg"], "Coil_Excitation": ["All"], } - report = m3d.post.create_report( - plotname=plot_name, - report_category="Fields", - context="Line_" + t[3:8], - primary_sweep_variable="Distance", - variations=variations, - expressions=t[0:2], - ) + report = m3d.post.create_report(expressions=t[0:2], variations=variations, primary_sweep_variable="Distance", + report_category="Fields", context="Line_" + t[3:8], plot_name=plot_name) file_path = os.path.join(temp_dir.name, str(dataset[i]) + ".csv") report.import_traces(file_path, plot_name) @@ -424,9 +417,9 @@ surf_list = m3d.modeler.get_object_faces("Plate") intrinsic_dict = {"Freq": "200Hz", "Phase": "0deg"} -m3d.post.create_fieldplot_surface(surf_list, "Mag_J", intrinsincDict=intrinsic_dict, plot_name="Mag_J") -m3d.post.create_fieldplot_surface(surf_list, "Mag_B", intrinsincDict=intrinsic_dict, plot_name="Mag_B") -m3d.post.create_fieldplot_surface(surf_list, "Mesh", intrinsincDict=intrinsic_dict, plot_name="Mesh") +m3d.post.create_fieldplot_surface(surf_list, "Mag_J", intrinsics=intrinsic_dict, plot_name="Mag_J") +m3d.post.create_fieldplot_surface(surf_list, "Mag_B", intrinsics=intrinsic_dict, plot_name="Mag_B") +m3d.post.create_fieldplot_surface(surf_list, "Mesh", intrinsics=intrinsic_dict, plot_name="Mesh") #################################################################################################### # Release AEDT and clean up temporary directory diff --git a/examples/03-Maxwell/Maxwell3D_Choke.py b/examples/03-Maxwell/Maxwell3D_Choke.py index 29ee2b5232e..7e07b04fb99 100644 --- a/examples/03-Maxwell/Maxwell3D_Choke.py +++ b/examples/03-Maxwell/Maxwell3D_Choke.py @@ -176,18 +176,10 @@ # Create the mesh operation. mesh = m3d.mesh -mesh.assign_skin_depth( - names=[first_winding_list[0], second_winding_list[0], third_winding_list[0]], - skindepth=0.20, - triangulation_max_length="10mm", - meshop_name="skin_depth", -) -mesh.assign_surface_mesh_manual( - [first_winding_list[0], second_winding_list[0], third_winding_list[0]], - surf_dev=None, - normal_dev="30deg", - meshop_name="surface_approx", -) +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([first_winding_list[0], second_winding_list[0], third_winding_list[0]], + surface_deviation=None, normal_dev="30deg", name="surface_approx") ############################################################################### # Create boundaries diff --git a/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py b/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py index d4a1479bb86..64b43f2650f 100644 --- a/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py +++ b/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py @@ -97,7 +97,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Add a mesh refinement to the ladder plate. -m3d.mesh.assign_length_mesh("LadderPlate", maxlength=3, maxel=None, meshop_name="Ladder_Mesh") +m3d.mesh.assign_length_mesh("LadderPlate", maximum_length=3, maximum_elements=None, name="Ladder_Mesh") ################################################################################ # Draw search coil and assign excitation @@ -115,7 +115,7 @@ m3d.modeler.section("SearchCoil", "YZ") m3d.modeler.separate_bodies("SearchCoil_Section1") m3d.modeler.delete("SearchCoil_Section1_Separate1") -m3d.assign_current(object_list=["SearchCoil_Section1"], amplitude=1260, solid=False, name="SearchCoil_Excitation") +m3d.assign_current(assignment=["SearchCoil_Section1"], amplitude=1260, solid=False, name="SearchCoil_Excitation") ################################################################################ # Draw a line for plotting Bz @@ -141,7 +141,7 @@ # ~~~~~~~~~~~~~~~~~~~~ # Add a Maxwell 3D setup with frequency points at 50 Hz and 200 Hz. -setup = m3d.create_setup(setupname="Setup1") +setup = m3d.create_setup(name="Setup1") setup.props["Frequency"] = "200Hz" setup.props["HasSweepSetup"] = True setup.add_eddy_current_sweep(range_type="LinearStep", start=50, end=200, count=150, clear=True) @@ -152,8 +152,8 @@ # 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(object_list=["LadderPlate"], activate_eddy_effects=True, activate_displacement_current=True) -m3d.eddy_effects_on(object_list=["SearchCoil"], activate_eddy_effects=False, activate_displacement_current=True) +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 @@ -192,14 +192,8 @@ # 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)", - report_category="Fields", - context="Line_AB", - variations=variations, - primary_sweep_variable="Distance", - plotname="mag(Bz) Along 'Line_AB' Coil", -) +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 @@ -237,7 +231,7 @@ ladder_plate = m3d.modeler.objects_by_name["LadderPlate"] intrinsic_dict = {"Freq": "50Hz", "Phase": "0deg"} -m3d.post.create_fieldplot_surface(ladder_plate.faces, "Mag_J", intrinsincDict=intrinsic_dict, plot_name="Mag_J") +m3d.post.create_fieldplot_surface(ladder_plate.faces, "Mag_J", intrinsics=intrinsic_dict, plot_name="Mag_J") ############################################################################### # Release AEDT diff --git a/examples/04-Icepak/Icepak_Example.py b/examples/04-Icepak/Icepak_Example.py index bb70475ceb3..b77ad5cfb55 100644 --- a/examples/04-Icepak/Icepak_Example.py +++ b/examples/04-Icepak/Icepak_Example.py @@ -72,7 +72,7 @@ # ~~~~~~~~~~~~~~~~~~~ # Assign a mesh region to the heat sink and CPU. -mesh_region = ipk.mesh.assign_mesh_region(objectlist=["HEAT_SINK", "CPU"]) +mesh_region = ipk.mesh.assign_mesh_region(assignment=["HEAT_SINK", "CPU"]) mesh_region.UserSpecifiedSettings = True mesh_region.MaxElementSizeX = "3.35mm" mesh_region.MaxElementSizeY = "1.75mm" diff --git a/examples/04-Icepak/Sherlock_Example.py b/examples/04-Icepak/Sherlock_Example.py index 1e474fd9721..56cd9407386 100644 --- a/examples/04-Icepak/Sherlock_Example.py +++ b/examples/04-Icepak/Sherlock_Example.py @@ -221,7 +221,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ plot1 = ipk.post.create_fieldplot_surface(ipk.modeler["COMP_U10"].faces, "SurfTemperature") -ipk.post.plot_field("SurfPressure",ipk.modeler["COMP_U10"].faces,export_path=ipk.working_directory, show=False) +ipk.post.plot_field("SurfPressure", ipk.modeler["COMP_U10"].faces, show=False, export_path=ipk.working_directory) ############################################################################### diff --git a/examples/05-Q3D/Q2D_Armoured_Cable.py b/examples/05-Q3D/Q2D_Armoured_Cable.py index 0b4800a79bf..0f486ee4574 100644 --- a/examples/05-Q3D/Q2D_Armoured_Cable.py +++ b/examples/05-Q3D/Q2D_Armoured_Cable.py @@ -226,8 +226,8 @@ # Insert setup and frequency sweep # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -q2d_setup = q2d.create_setup(setupname=setup_name) -q2d_sweep = q2d_setup.add_sweep(sweepname=sweep_name) +q2d_setup = q2d.create_setup(name=setup_name) +q2d_sweep = q2d_setup.add_sweep(name=sweep_name) ########################################################## # Analyze setup @@ -245,12 +245,8 @@ # Add a Q3D dynamic component # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -tb.add_q3d_dynamic_component(project_name, - q2d_design_name, - setup_name, - sweep_name, - model_depth=lumped_length, - coupling_matrix_name="Original") +tb.add_q3d_dynamic_component(project_name, q2d_design_name, setup_name, sweep_name, coupling_matrix_name="Original", + model_depth=lumped_length) ########################################################## # Save project and release desktop diff --git a/examples/05-Q3D/Q2D_Example_CPWG.py b/examples/05-Q3D/Q2D_Example_CPWG.py index 70674645cdb..d57cfdb86f9 100644 --- a/examples/05-Q3D/Q2D_Example_CPWG.py +++ b/examples/05-Q3D/Q2D_Example_CPWG.py @@ -190,9 +190,9 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create the setup, analyze it, and plot solution data. -setup = q.create_setup(setupname="new_setup") +setup = q.create_setup(name="new_setup") -sweep = setup.add_sweep(sweepname="sweep1", sweeptype="Discrete") +sweep = setup.add_sweep(name="sweep1", sweep_type="Discrete") sweep.props["RangeType"] = "LinearStep" sweep.props["RangeStart"] = "1GHz" sweep.props["RangeStep"] = "100MHz" diff --git a/examples/05-Q3D/Q2D_Example_Stripline.py b/examples/05-Q3D/Q2D_Example_Stripline.py index ac56e9bd024..0b72537f491 100644 --- a/examples/05-Q3D/Q2D_Example_Stripline.py +++ b/examples/05-Q3D/Q2D_Example_Stripline.py @@ -198,10 +198,10 @@ # Create a setup, analyze, and plot solution data. # Create a setup. -setup = q.create_setup(setupname="new_setup") +setup = q.create_setup(name="new_setup") # Add a sweep. -sweep = setup.add_sweep(sweepname="sweep1", sweeptype="Discrete") +sweep = setup.add_sweep(name="sweep1", sweep_type="Discrete") sweep.props["RangeType"] = "LinearStep" sweep.props["RangeStart"] = "1GHz" sweep.props["RangeStep"] = "100MHz" @@ -215,7 +215,7 @@ q.analyze() plot_sources = matrix.get_sources_for_plot(category="Z0") a = q.post.get_solution_data(expressions=plot_sources, context=matrix.name) -a.plot(snapshot_path=os.path.join(q.working_directory, "plot.jpg")) # Save plot as jpg +a.plot(snapshot_path=os.path.join(q.working_directory, "plot.jpg")) # Save plot as jpg # Add a parametric sweep and analyze. parametric = q.parametrics.add(sweep_var="sig_bot_w", start_point=75, end_point=100, step=5, diff --git a/examples/05-Q3D/Q3D_DC_IR.py b/examples/05-Q3D/Q3D_DC_IR.py index f727bdb2559..c1cbbd280b7 100644 --- a/examples/05-Q3D/Q3D_DC_IR.py +++ b/examples/05-Q3D/Q3D_DC_IR.py @@ -214,19 +214,10 @@ # ~~~~~~~~ # Compute ACL solutions and plot them. -plot1 = q3d.post.create_fieldplot_surface(q3d.modeler.get_objects_by_material("copper"), quantityName=drop_name, - intrinsincDict={"Freq": "1GHz"}) - -q3d.post.plot_field_from_fieldplot( - plot1.name, - project_path=q3d.working_directory, - meshplot=False, - imageformat="jpg", - view="isometric", - show=False, - plot_cad_objs=False, - log_scale=False, -) +plot1 = q3d.post.create_fieldplot_surface(q3d.modeler.get_objects_by_material("copper"), quantity=drop_name) + +q3d.post.plot_field_from_fieldplot(plot1.name, project_path=q3d.working_directory, mesh_plot=False, image_format="jpg", + view="isometric", show=False, plot_cad_objs=False, log_scale=False) ############################################################################### # Computing Voltage on Source Circles diff --git a/examples/05-Q3D/Q3D_Example.py b/examples/05-Q3D/Q3D_Example.py index a062303fd4d..793ff31dd24 100644 --- a/examples/05-Q3D/Q3D_Example.py +++ b/examples/05-Q3D/Q3D_Example.py @@ -147,7 +147,7 @@ # Create a rectangular plot and a data table. q.post.create_report(expressions=data_plot_self) -q.post.create_report(expressions=data_plot_mutual, context="Original", plot_type="Data Table") +q.post.create_report(expressions=data_plot_mutual, plot_type="Data Table", context="Original") ############################################################################### # Solve setup diff --git a/examples/06-Multiphysics/Hfss_Icepak_Coupling.py b/examples/06-Multiphysics/Hfss_Icepak_Coupling.py index 6dac5618f11..56258e08585 100644 --- a/examples/06-Multiphysics/Hfss_Icepak_Coupling.py +++ b/examples/06-Multiphysics/Hfss_Icepak_Coupling.py @@ -118,8 +118,8 @@ # edit or review parameter values. aedtapp.mesh.assign_initial_mesh_from_slider(level=6) -aedtapp.mesh.assign_model_resolution(names=[o1.name, o3.name], defeature_length=None) -aedtapp.mesh.assign_length_mesh(names=o2.faces, isinside=False, maxlength=1, maxel=2000) +aedtapp.mesh.assign_model_resolution(assignment=[o1.name, o3.name], defeature_length=None) +aedtapp.mesh.assign_length_mesh(assignment=o2.faces, inside_selection=False, maximum_length=1, maximum_elements=2000) ############################################################################### # Create excitations @@ -129,18 +129,10 @@ # the faces. It also assigns a port to this face. If ``add_pec_cap=True``, the method # creates a PEC cap. -aedtapp.wave_port(signal="inner", - reference="outer", - integration_line=1, - create_port_sheet=True, - create_pec_cap=True, - name="P1") -aedtapp.wave_port(signal="inner", - reference="outer", - integration_line=4, - create_pec_cap=True, - create_port_sheet=True, - name="P2") +aedtapp.wave_port(assignment="inner", reference="outer", create_port_sheet=True, create_pec_cap=True, + integration_line=1, name="P1") +aedtapp.wave_port(assignment="inner", reference="outer", create_port_sheet=True, create_pec_cap=True, + integration_line=4, name="P2") port_names = aedtapp.get_all_sources() aedtapp.modeler.fit_all() @@ -163,7 +155,7 @@ # ~~~~~~~~~~~~ # Create a sweep. A sweep is created with default values. -sweepname = aedtapp.create_linear_count_sweep(setupname="MySetup", unit="GHz", freqstart=0.8, freqstop=1.2, +sweepname = aedtapp.create_linear_count_sweep(setup="MySetup", units="GHz", start_frequency=0.8, stop_frequency=1.2, num_of_freq_points=401, sweep_type="Interpolating") ################################################################################ @@ -182,8 +174,8 @@ # Link sources to the EM losses. surfaceobj = ["inner", "outer"] -ipkapp.assign_em_losses(designname=aedtapp.design_name, setupname="MySetup", sweepname="LastAdaptive", - map_frequency="1GHz", surface_objects=surfaceobj, paramlist=["$coax_dimension", "inner"]) +ipkapp.assign_em_losses(design=aedtapp.design_name, setup="MySetup", sweep="LastAdaptive", map_frequency="1GHz", + surface_objects=surfaceobj, parameters=["$coax_dimension", "inner"]) ################################################################################# # Edit gravity setting @@ -257,16 +249,8 @@ if not os.path.exists(results_folder): os.mkdir(results_folder) -aedtapp.post.plot_field_from_fieldplot( - plot1.name, - project_path=results_folder, - meshplot=False, - imageformat="jpg", - view="isometric", - show=False, - plot_cad_objs=False, - log_scale=False, -) +aedtapp.post.plot_field_from_fieldplot(plot1.name, project_path=results_folder, mesh_plot=False, image_format="jpg", + view="isometric", show=False, plot_cad_objs=False, log_scale=False) ################################################################################ # Generate animation from field plots @@ -279,19 +263,11 @@ cutlist = ["Global:XY"] phases = [str(i * 5) + "deg" for i in range(18)] -animated = aedtapp.post.plot_animated_field( - quantity="Mag_E", - object_list=cutlist, - plot_type="CutPlane", - setup_name=aedtapp.nominal_adaptive, - intrinsics={"Freq": "1GHz", "Phase": "0deg"}, - export_path=results_folder, - variation_variable="Phase", - variation_list=phases, - show=False, - export_gif=False, - log_scale=True, -) +animated = aedtapp.post.plot_animated_field(quantity="Mag_E", assignment=cutlist, plot_type="CutPlane", + setup=aedtapp.nominal_adaptive, + intrinsics={"Freq": "1GHz", "Phase": "0deg"}, variation_variable="Phase", + variations=phases, show=False, log_scale=True, export_gif=False, + export_path=results_folder) animated.gif_file = os.path.join(aedtapp.working_directory, "animate.gif") # animated.camera_position = [0, 0, 300] # animated.focal_point = [0, 0, 0] @@ -325,17 +301,14 @@ cxt = ["Domain:=", "Sweep"] families = ["Freq:=", ["All"]] my_data = aedtapp.post.get_solution_data(expressions=trace_names) -my_data.plot(trace_names, "db20", - xlabel="Frequency (Ghz)", - ylabel="SParameters(dB)", - title="Scattering Chart", +my_data.plot(trace_names, "db20", x_label="Frequency (Ghz)", y_label="SParameters(dB)", title="Scattering Chart", snapshot_path=os.path.join(results_folder, "Touchstone_from_matplotlib.jpg")) ################################################################################ # Generate pdf report # ~~~~~~~~~~~~~~~~~~~ # Generate a pdf report with output of simultion. -report = AnsysReport(project_name=aedtapp.project_name, design_name=aedtapp.design_name, version=aedt_version) +report = AnsysReport(version=aedt_version, design_name=aedtapp.design_name, project_name=aedtapp.project_name) report.create() report.add_section() report.add_chapter("Hfss Results") diff --git a/examples/06-Multiphysics/Hfss_Mechanical.py b/examples/06-Multiphysics/Hfss_Mechanical.py index ed08b23ebe4..e5105a8dd99 100644 --- a/examples/06-Multiphysics/Hfss_Mechanical.py +++ b/examples/06-Multiphysics/Hfss_Mechanical.py @@ -96,7 +96,7 @@ # Create a setup. setup_name = "MySetup" -LNA_setup = circuit.create_setup(setupname=setup_name) +LNA_setup = circuit.create_setup(name=setup_name) bw_start = 4.3 bw_stop = 4.4 n_points = 1001 @@ -128,13 +128,8 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get losses from HFSS and assign the convection to Mechanical. -mech.assign_em_losses( - designname=hfss.design_name, - setupname=hfss.setups[0].name, - sweepname="LastAdaptive", - map_frequency=hfss.setups[0].props["Frequency"], - surface_objects=hfss.get_all_conductors_names(), -) +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(objects_list=[mech.modeler[el].top_face_y, mech.modeler[el].bottom_face_y], @@ -158,7 +153,7 @@ surfaces = [] for name in mech.get_all_conductors_names(): surfaces.extend(mech.modeler.get_object_faces(name)) -mech.post.create_fieldplot_surface(objlist=surfaces, quantityName="Temperature") +mech.post.create_fieldplot_surface(assignment=surfaces, quantity="Temperature") ############################################################################### # Release AEDT diff --git a/examples/06-Multiphysics/MRI.py b/examples/06-Multiphysics/MRI.py index c251debc3b1..a9bd86e2068 100644 --- a/examples/06-Multiphysics/MRI.py +++ b/examples/06-Multiphysics/MRI.py @@ -106,21 +106,14 @@ # Plot averagedSAR on GlobalYZ plane # Draw Point1 at origin of the implant coordinate system -hfss.sar_setup(-1, Average_SAR_method=1, TissueMass=1, MaterialDensity=1, ) -hfss.post.create_fieldplot_cutplane(objlist="implant:YZ", - quantityName="Average_SAR", - filter_objects=["implant_box"]) +hfss.sar_setup(-1, tissue_mass=1, material_density=1, average_sar_method=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([0, 0, 0], name="Point1") -hfss.post.plot_field(quantity="Average_SAR", - object_list="implant:YZ", - plot_type="CutPlane", - show_legend=False, - filter_objects=["implant_box"], - show=False - ) +hfss.post.plot_field(quantity="Average_SAR", assignment="implant:YZ", plot_type="CutPlane", show=False, + show_legend=False, filter_objects=["implant_box"]) ############################################################################### # Adjust Input Power to MRI Coil @@ -174,13 +167,9 @@ # Link sources to the EM losses. # Assign external convection. -exc = mech.assign_em_losses( - designname=hfss.design_name, - setupname=hfss.setups[0].name, - sweepname="LastAdaptive", - map_frequency=hfss.setups[0].props["Frequency"], - surface_objects=mech.get_all_conductors_names(), -) +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(mech.modeler["Region"].faces, convection_value=1) ################################################################################ @@ -214,23 +203,17 @@ # Plot Temperature on cut plane. # Plot Temperature on point. -mech.post.create_fieldplot_cutplane("implant:YZ", "Temperature", filter_objects=["implant_box"], - intrinsincDict={"Time": "10s"}) +mech.post.create_fieldplot_cutplane("implant:YZ", "Temperature", filter_objects=["implant_box"]) mech.save_project() data = mech.post.get_solution_data("Temperature", primary_sweep_variable="Time", context="Point1", report_category="Fields") #data.plot() -mech.post.plot_animated_field(quantity="Temperature", - object_list="implant:YZ", - plot_type="CutPlane", - intrinsics={"Time": "10s"}, - variation_variable="Time", - variation_list=["10s", "20s", "30s", "40s", "50s", "60s"], - filter_objects=["implant_box"], - show=False - ) +mech.post.plot_animated_field(quantity="Temperature", assignment="implant:YZ", plot_type="CutPlane", + intrinsics={"Time": "10s"}, variation_variable="Time", + variations=["10s", "20s", "30s", "40s", "50s", "60s"], + show=False, filter_objects=["implant_box"]) ############################################################################### # Thermal Simulation @@ -254,13 +237,9 @@ # Link sources to the EM losses. # Assign external convection. -exc = ipk.assign_em_losses( - designname=hfss.design_name, - setupname=hfss.setups[0].name, - sweepname="LastAdaptive", - map_frequency=hfss.setups[0].props["Frequency"], - surface_objects=ipk.get_all_conductors_names(), -) +exc = 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 @@ -305,8 +284,7 @@ # Plot Temperature on monitor point. ipk.analyze(num_cores=4,num_tasks=4) -ipk.post.create_fieldplot_cutplane("implant:YZ", "Temperature", filter_objects=["implant_box"], - intrinsincDict={"Time": "0s"}) +ipk.post.create_fieldplot_cutplane("implant:YZ", "Temperature", filter_objects=["implant_box"]) ipk.save_project() data = ipk.post.get_solution_data("Point1.Temperature", primary_sweep_variable="Time", report_category="Monitor") diff --git a/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py b/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py index 44c2322a664..ddec3ecb525 100644 --- a/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py +++ b/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py @@ -98,14 +98,10 @@ no_turns = 20 coil_current = 10 -m3d.assign_coil(["Coil_terminal"], conductor_number=no_turns, name="Coil_terminal") -m3d.assign_winding( - is_solid=False, - current_value=coil_current, - name="Winding1", -) +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(windingname="Winding1", coil_names=["Coil_terminal"]) +m3d.add_winding_coils(assignment="Winding1", coils=["Coil_terminal"]) ############################################################################### # Assign mesh operations @@ -113,12 +109,8 @@ # Mesh operations are not necessary in eddy current solver because of auto-adaptive meshing. # However, with appropriate mesh operations, less adaptive passes are needed. -m3d.mesh.assign_length_mesh( - ["Core"], maxlength=15, meshop_name="Inside_Core", maxel=None -) -m3d.mesh.assign_length_mesh( - ["Coil"], maxlength=30, meshop_name="Inside_Coil", maxel=None -) +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 temperature coefficient @@ -148,7 +140,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Simulation frequency 150kHz. -setup = m3d.create_setup(setupname="Setup1") +setup = m3d.create_setup(name="Setup1") setup.props["Frequency"] = "150kHz" m3d.analyze_setup("Setup1") @@ -197,12 +189,7 @@ # ~~~~~~~~~~~~~~~ # Map ohmic losses from Maxwell to the Icepak design. -ipk.assign_em_losses( - designname="1 Maxwell", - setupname=m3d.setups[0].name, - sweepname="LastAdaptive", - object_list=["Coil"], -) +ipk.assign_em_losses(design="1 Maxwell", setup=m3d.setups[0].name, sweep="LastAdaptive", assignment=["Coil"]) ############################################################################### # Boundary conditions @@ -255,17 +242,11 @@ for name in ["Coil", "Core"]: surface_list.extend(ipk.modeler.get_object_faces(name)) -surf_temperature = ipk.post.create_fieldplot_surface( - surface_list, - quantityName="SurfTemperature", - plot_name="Surface Temperature" -) +surf_temperature = ipk.post.create_fieldplot_surface(surface_list, quantity="SurfTemperature", + plot_name="Surface Temperature") -velocity_cutplane = ipk.post.create_fieldplot_cutplane( - objlist=["Global:XZ"], - quantityName="Velocity Vectors", - plot_name="Velocity Vectors" - ) +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") diff --git a/examples/07-Circuit/Circuit_AMI.py b/examples/07-Circuit/Circuit_AMI.py index 2801fadb066..f90e8e5b0b3 100644 --- a/examples/07-Circuit/Circuit_AMI.py +++ b/examples/07-Circuit/Circuit_AMI.py @@ -64,8 +64,7 @@ plot_name = "WaveAfterProbe" cir.solution_type = "NexximAMI" -original_data = cir.post.get_solution_data(expressions=plot_name, - setup_sweep_name="AMIAnalysis", domain="Time", +original_data = cir.post.get_solution_data(expressions=plot_name, domain="Time", variations=cir.available_variations.nominal) original_data_value = original_data.full_matrix_real_imag[0] original_data_sweep = original_data.primary_sweep_values @@ -89,7 +88,7 @@ setup_name = "AMIAnalysis" ignore_bits = 100 unit_interval = 0.1e-9 -sample_waveform = cir.post.sample_ami_waveform(setupname=setup_name, probe_name=probe_name, source_name=source_name, +sample_waveform = cir.post.sample_ami_waveform(setup=setup_name, probe=probe_name, source=source_name, variation_list_w_value=cir.available_variations.nominal, unit_interval=unit_interval, ignore_bits=ignore_bits, plot_type=plot_type) @@ -134,7 +133,7 @@ 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.plot(np.array(list(original_data_zoom.index.values)), original_data_zoom.values) ax.set_title('WaveAfterProbe') ax.set_xlabel(original_data.units_sweeps["Time"]) ax.set_ylabel(original_data.units_data[plot_name]) @@ -172,7 +171,8 @@ plot_name = "V(b_input_43.int_ami_rx.eye_probe.out)" cir.solution_type = "NexximTransient" original_data = cir.post.get_solution_data(expressions=plot_name, - setup_sweep_name="NexximTransient", domain="Time", + domain="Time", + setup_sweep_name="NexximTransient", variations=cir.available_variations.nominal) ############################################################################### @@ -242,7 +242,7 @@ 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.plot(original_sweep_zoom, original_data_zoom_array[:, 1]) ax.set_title(plot_name) ax.set_xlabel(waveform_sweep_unit) ax.set_ylabel(waveform_unit) diff --git a/examples/07-Circuit/Circuit_Example.py b/examples/07-Circuit/Circuit_Example.py index 0c12afdcb36..ab3b61c2c64 100644 --- a/examples/07-Circuit/Circuit_Example.py +++ b/examples/07-Circuit/Circuit_Example.py @@ -87,9 +87,9 @@ # ~~~~~~~~~~~~~~~~~~~~~~ # Create a transient setup. -setup2 = aedt_app.create_setup(setupname="MyTransient", setuptype=aedt_app.SETUPS.NexximTransient) +setup2 = aedt_app.create_setup(name="MyTransient", setup_type=aedt_app.SETUPS.NexximTransient) setup2.props["TransientData"] = ["0.01ns", "200ns"] -setup3 = aedt_app.create_setup(setupname="MyDC", setuptype=aedt_app.SETUPS.NexximDC) +setup3 = aedt_app.create_setup(name="MyDC", setup_type=aedt_app.SETUPS.NexximDC) ############################################################################### # Solve transient setup @@ -104,9 +104,7 @@ # ~~~~~~~~~~~~~ # Create a report that plots solution data. -solutions = aedt_app.post.get_solution_data( - expressions=aedt_app.get_traces_for_plot(category="S"), -) +solutions = aedt_app.post.get_solution_data(expressions=aedt_app.get_traces_for_plot(category="S")) solutions.enable_pandas_output = True real, imag = solutions.full_matrix_real_imag print(real) diff --git a/examples/07-Circuit/Circuit_Transient.py b/examples/07-Circuit/Circuit_Transient.py index 6ecb283abf7..3ef5308466c 100644 --- a/examples/07-Circuit/Circuit_Transient.py +++ b/examples/07-Circuit/Circuit_Transient.py @@ -91,7 +91,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~ # Create a transient analysis setup and analyze it. -trans_setup = cir.create_setup(setupname="TransientRun", setuptype="NexximTransient") +trans_setup = cir.create_setup(name="TransientRun", setup_type="NexximTransient") trans_setup.props["TransientData"] = ["0.01ns", "200ns"] cir.analyze_setup("TransientRun") diff --git a/examples/07-Circuit/Reports.py b/examples/07-Circuit/Reports.py index b4a27dcd0a0..baf0118c3e7 100644 --- a/examples/07-Circuit/Reports.py +++ b/examples/07-Circuit/Reports.py @@ -57,7 +57,7 @@ # notes and edit axes, the grid, and the legend. You can create custom reports # in non-graphical mode in AEDT 2023 R2 and later. -report1 = cir.post.create_report_from_configuration(os.path.join(project_path,'Spectrum_CISPR_Basic.json')) +report1 = cir.post.create_report_from_configuration(os.path.join(project_path, 'Spectrum_CISPR_Basic.json')) out = cir.post.export_report_to_jpg(cir.working_directory, report1.plot_name) Image(out) @@ -66,7 +66,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~ # Every aspect of the report can be customized. -report1_full = cir.post.create_report_from_configuration(os.path.join(project_path,'Spectrum_CISPR_Custom.json')) +report1_full = cir.post.create_report_from_configuration(os.path.join(project_path, 'Spectrum_CISPR_Custom.json')) out = cir.post.export_report_to_jpg(cir.working_directory, report1_full.plot_name) Image(out) ############################################################################### @@ -80,7 +80,7 @@ props = pyaedt.general_methods.read_json(os.path.join(project_path, 'Transient_CISPR_Custom.json')) -report2 = cir.post.create_report_from_configuration(input_dict=props, solution_name="NexximTransient") +report2 = cir.post.create_report_from_configuration(report_settings=props, solution_name="NexximTransient") out = cir.post.export_report_to_jpg(cir.working_directory, report2.plot_name) Image(out) @@ -92,7 +92,7 @@ props["expressions"] = {"V(Battery)": {}, "V(U1_VDD)": {}} props["plot_name"] = "Battery Voltage" -report3 = cir.post.create_report_from_configuration(input_dict=props, solution_name="NexximTransient") +report3 = cir.post.create_report_from_configuration(report_settings=props, solution_name="NexximTransient") out = cir.post.export_report_to_jpg(cir.working_directory, report3.plot_name) Image(out) diff --git a/examples/07-Circuit/Virtual_Compliance.py b/examples/07-Circuit/Virtual_Compliance.py index 12a734d5d06..f0317eb8315 100644 --- a/examples/07-Circuit/Virtual_Compliance.py +++ b/examples/07-Circuit/Virtual_Compliance.py @@ -62,6 +62,7 @@ h3d.setups[0].sweeps[0].props["EnforceCausality"] = True h3d.setups[0].sweeps[0].update() h3d.analyze() +h3d = pyaedt.Hfss3dLayout(specified_version=241) touchstone_path = h3d.export_touchstone() ############################################################################### @@ -71,56 +72,31 @@ # and generate frequency domain reports. cir = pyaedt.Circuit(projectname=h3d.project_name, designname="Touchstone") - -############################################################################### -# Add dynamic link object -# ~~~~~~~~~~~~~~~~~~~~~~~ -# Add the layout project as a dynamic link object -# so that if modifications are made, the circuit -# is always linked to the updated version of the results. - -sub = cir.modeler.components.add_subcircuit_3dlayout("main_cutout") - -############################################################################### -# Add ports and differential pairs -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Add a port for each layout port and rename it for circuit compatibility. -# Then, create differential pairs, which are useful for generating differential S-parameters. - -ports = [] -for pin in sub.pins: - ports.append(cir.modeler.components.create_interface_port(name=pin.name.replace(".", "_"), location=pin.location)) - -for pin in ports: - pin_name = pin.name.split("_") - if pin_name[-1] == "P": - component = pin_name[0] - suffix = pin_name[-2] if "X" in pin_name[-2] else pin_name[-3] - for neg_pin in ports: - neg_pin_name = neg_pin.name.split("_") - suffix_neg = neg_pin_name[-2] if "X" in neg_pin_name[-2] else neg_pin_name[-3] - if neg_pin_name[0] == component and suffix_neg == suffix and neg_pin.name[-1] == "N": - cir.set_differential_pair( - positive_terminal=pin.name, - negative_terminal=neg_pin.name, - common_name=f"COMMON_{component}_{suffix}", - diff_name=f"{component}_{suffix}", - common_ref_z=25, - diff_ref_z=100, - active=True, - ) - break - -############################################################################### -# Create setup, analyze, and plot -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Create a setup and then analyze and plot the data. - -setup1 = cir.create_setup() -setup1.props["SweepDefinition"]["Data"] = "LINC 0GHz 70GHz 1001" - -cir.analyze() - +status, diff_pairs, comm_pairs = cir.create_lna_schematic_from_snp(touchstone=touchstone_path, + start_frequency=0, + stop_frequency=70, + auto_assign_diff_pairs=True, + separation=".", + pattern=["component", "pin", "net"], + analyze=True + ) + +insertion = cir.get_all_insertion_loss_list(trlist=diff_pairs, + reclist=diff_pairs, + tx_prefix="X1", + rx_prefix="U1", + math_formula="dB", + net_list=["RX0", "RX1", "RX2", "RX3"] + ) +return_diff = cir.get_all_return_loss_list(excitation_names=diff_pairs, + excitation_name_prefix="X1", + math_formula="dB", + net_list=["RX0", "RX1", "RX2", "RX3"] + ) +return_comm = cir.get_all_return_loss_list(excitation_names=comm_pairs, + excitation_name_prefix="COMMON_X1", + math_formula="dB", + net_list=["RX0", "RX1", "RX2", "RX3"]) ############################################################################### # Create TDR project # ~~~~~~~~~~~~~~~~~~ @@ -128,89 +104,41 @@ # the TDR measurement on a differential pair. # The original circuit schematic is duplicated and modified to achieve this target. -cir.duplicate_design("TDR") -cir.set_active_design("TDR") - -############################################################################### -# Replace ports with TDR probe -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Delete the ports on the selected differential pair. -# Place and connect a differential TDR probe to the pins of the layout object. - -cir.modeler.components.delete_component("X1_A2_PCIe_Gen4_RX0_P") -cir.modeler.components.delete_component("IPort@X1_A3_PCIe_Gen4_RX0_N") -sub = cir.modeler.components.get_component("main_cutout1") - -dif_end = cir.modeler.components.components_catalog["TDR_Differential_Ended"] - -new_tdr_comp = dif_end.place("Tdr_probe", [-0.05, 0.01], angle=-90) -p_pin = [i for i in sub.pins if i.name.replace(".", "_") == "X1_A2_PCIe_Gen4_RX0_P"][0] -n_pin = [i for i in sub.pins if i.name.replace(".", "_") == "X1_A3_PCIe_Gen4_RX0_N"][0] -new_tdr_comp.pins[0].connect_to_component(p_pin) -new_tdr_comp.pins[1].connect_to_component(n_pin) -new_tdr_comp.parameters["Pulse_repetition"] = "2ms" -new_tdr_comp.parameters["Rise_time"] = "35ps" - -############################################################################### -# Create setup, analyze, and plot -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# First, delete the LNA setup. Next, create a -# transient setup and then analyze and plot the data. - -cir.delete_setup(cir.setups[0].name) -setup2 = cir.create_setup(setupname="MyTransient", setuptype=cir.SETUPS.NexximTransient) -setup2.props["TransientData"] = ["0.01ns", "10ns"] -cir.oanalysis.AddAnalysisOptions(["NAME:DataBlock", "DataBlockID:=", 8, "Name:=", "Nexxim Options", - ["NAME:ModifiedOptions", "ts_convolution:=", True, ]]) -setup2.props["OptionName"] = "Nexxim Options" -tdr_probe_name = f'O(A{new_tdr_comp.id}:zdiff)' -cir.analyze() +result, tdr_probe_name = cir.create_tdr_schematic_from_snp(touchstone=touchstone_path, + probe_pins=["X1.A2.PCIe_Gen4_RX0_P"], + probe_ref_pins=["X1.A3.PCIe_Gen4_RX0_N"], + termination_pins=["U1.AP26.PCIe_Gen4_RX0_P", + "U1.AN26.PCIe_Gen4_RX0_N"], + differential=True, + design_name="TDR", + rise_time=35, + use_convolution=True, + analyze=True, + ) ############################################################################### # Create AMI project # ~~~~~~~~~~~~~~~~~~ # Create an Ibis AMI project to compute an eye diagram simulation and retrieve # eye mask violations. +result, eye_curve_tx, eye_curve_rx = cir.create_ami_schematic_from_snp(touchstone=touchstone_path, + ibis_ami=os.path.join(projectdir, "models", "pcieg5_32gt.ibs"), + component_name="Spec_Model", + tx_buffer_name="1p", + rx_buffer_name="2p", + use_ibis_buffer=False, + differential=True, + tx_pins=["U1.AM25.PCIe_Gen4_TX0_CAP_P"], + tx_refs=["U1.AL25.PCIe_Gen4_TX0_CAP_N"], + rx_pins=["X1.B2.PCIe_Gen4_TX0_P"], + rx_refs=["X1.B3.PCIe_Gen4_TX0_N"], + bit_pattern="random_bit_count=2.5e3 random_seed=1", + unit_interval="31.25ps", + use_convolution=True, + analyze=True, + design_name="AMI", + ) -cir = pyaedt.Circuit(projectname=h3d.project_name, designname="AMI") -sub = cir.modeler.components.create_touchstone_component(touchstone_path) - -############################################################################### -# Replace ports with Ibis models -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Place and connect differential TX and RX Ibis models to the pins of the layout object. - -p_pin1 = [i for i in sub.pins if i.name.replace(".", "_") == "U1_AM25_PCIe_Gen4_TX0_CAP_P"][0] -n_pin1 = [i for i in sub.pins if i.name.replace(".", "_") == "U1_AL25_PCIe_Gen4_TX0_CAP_N"][0] -p_pin2 = [i for i in sub.pins if i.name.replace(".", "_") == "X1_B2_PCIe_Gen4_TX0_P"][0] -n_pin2 = [i for i in sub.pins if i.name.replace(".", "_") == "X1_B3_PCIe_Gen4_TX0_N"][0] - -ibis = cir.get_ibis_model_from_file(os.path.join(projectdir, "models", "pcieg5_32gt.ibs"), is_ami=True) -tx = ibis.components["Spec_Model"].pins["1p_Spec_Model_pcieg5_32gt_diff"].insert(-0.05, 0.01) -rx = ibis.components["Spec_Model"].pins["2p_Spec_Model_pcieg5_32gt_diff"].insert(0.05, 0.01, 180) - -tx_eye_name = tx.parameters["probe_name"] - -tx.pins[0].connect_to_component(p_pin1) -tx.pins[1].connect_to_component(n_pin1) -rx.pins[0].connect_to_component(p_pin2) -rx.pins[1].connect_to_component(n_pin2) -tx.parameters["UIorBPSValue"] = "31.25ps" -tx.parameters["BitPattern"] = "random_bit_count=2.5e3 random_seed=1" - -############################################################################### -# Create setup, analyze, and plot -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# First delete the LNA setup. Next, create a -# transient setup and then analyze and plot the data. - -setup_ami = cir.create_setup("AMI", "NexximAMI") -cir.oanalysis.AddAnalysisOptions(["NAME:DataBlock", "DataBlockID:=", 8, "Name:=", "Nexxim Options", - ["NAME:ModifiedOptions", "ts_convolution:=", True, ]]) -setup_ami.props["OptionName"] = "Nexxim Options" - -setup_ami.props["DataBlockSize"] = 1000 -setup_ami.analyze() cir.save_project() ############################################################################### @@ -249,13 +177,13 @@ # v.project_file = cir.project_file -v.reports["insertion losses"].design_name = "Touchstone" -v.reports["return losses"].design_name = "Touchstone" -v.reports["common mode return losses"].design_name = "Touchstone" +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 = "Touchstone" +v.parameters["erl"].design_name = "LNA" v.specs_folder = os.path.join(workdir, 'readme_pictures') ############################################################################### @@ -264,17 +192,18 @@ # Change the trace name with projects and users. # Reuse the compliance template and update traces accordingly. -v.reports["insertion losses"].traces = [ - "dB(S(U1_RX0,X1_RX0))", - "dB(S(U1_RX1,X1_RX1))", - "dB(S(U1_RX3,X1_RX3))" -] -v.reports["eye1"].traces = [tx_eye_name] -v.reports["eye3"].traces = [tx_eye_name] -v.reports["tdr from circuit"].traces = [tdr_probe_name] +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"], + ["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]] ############################################################################### diff --git a/examples/07-EMIT/EMIT_HFSS_Example.py b/examples/07-EMIT/EMIT_HFSS_Example.py index cb0745f1c36..e33ebfc1e66 100644 --- a/examples/07-EMIT/EMIT_HFSS_Example.py +++ b/examples/07-EMIT/EMIT_HFSS_Example.py @@ -117,7 +117,7 @@ ############################################################################### # Run EMIT simulation # ~~~~~~~~~~~~~~~~~~~ -# Run the EMIT simulation. This portion of the EMIT API is not yet implemented. +# Run the EMIT simulation. # # This part of the example requires Ansys AEDT 2023 R2. diff --git a/examples/07-TwinBuilder/01-RC_Circuit_Example.py b/examples/07-TwinBuilder/01-RC_Circuit_Example.py index b9ea8696501..0deec81cc46 100644 --- a/examples/07-TwinBuilder/01-RC_Circuit_Example.py +++ b/examples/07-TwinBuilder/01-RC_Circuit_Example.py @@ -99,7 +99,7 @@ C_Value = "C1.V" x = tb.post.get_solution_data([E_Value, C_Value], "TR", "Time") -x.plot([E_Value, C_Value], xlabel="Time", ylabel="Capacitor Voltage vs Input Pulse") +x.plot([E_Value, C_Value], x_label="Time", y_label="Capacitor Voltage vs Input Pulse") tb.save_project() diff --git a/pyaedt/application/Analysis.py b/pyaedt/application/Analysis.py index 1f0df1b21bf..35ec1b435c8 100644 --- a/pyaedt/application/Analysis.py +++ b/pyaedt/application/Analysis.py @@ -13,7 +13,6 @@ import shutil import tempfile import time -import warnings from pyaedt import is_ironpython from pyaedt import is_linux @@ -122,6 +121,7 @@ def __init__( port, aedt_process_id, ) + self._excitation_objects = {} self._setup = None if setup_name: self.active_setup = setup_name @@ -290,30 +290,6 @@ def active_setup(self, setup_name): else: raise AttributeError("No setup defined") - @property - def analysis_setup(self): - """Analysis setup. - - .. deprecated:: 0.6.53 - Use :func:`active_setup` property instead. - - Returns - ------- - str - Name of the active or first analysis setup. - - References - ---------- - - >>> oModule.GetAllSolutionSetups() - """ - warnings.warn("`analysis_setup` is deprecated. Use `active_setup` property instead.", DeprecationWarning) - return self.active_setup - - @analysis_setup.setter - def analysis_setup(self, setup_name): - self.active_setup = setup_name - @property def existing_analysis_sweeps(self): """Existing analysis sweeps. @@ -477,6 +453,46 @@ def excitations(self): except Exception: return [] + @property + def excitations_by_type(self): + """Design excitations by type. + + Returns + ------- + dict + Dictionary of excitations. + """ + _dict_out = {} + for bound in self.excitation_objects.values(): + if bound.type in _dict_out: + _dict_out[bound.type].append(bound) + else: + _dict_out[bound.type] = [bound] + return _dict_out + + @property + def excitation_objects(self): + """Get all excitation. + + Returns + ------- + dict + List of excitation boundaries. Excitations with multiple modes will return one + excitation for each mode. + + References + ---------- + + >>> oModule.GetExcitations + """ + exc_names = self.excitations[::] + + for el in self.boundaries: + if el.name in exc_names: + self._excitation_objects[el.name] = el + + return self._excitation_objects + @pyaedt_function_handler() def get_traces_for_plot( self, @@ -1181,13 +1197,13 @@ def get_sweeps(self, name): sweeps = self.oanalysis.GetSweeps(name) return list(sweeps) - @pyaedt_function_handler() - def export_parametric_results(self, sweepname, filename, exportunits=True): + @pyaedt_function_handler(sweepname="sweep") + def export_parametric_results(self, sweep, filename, exportunits=True): """Export a list of all parametric variations solved for a sweep to a CSV file. Parameters ---------- - sweepname : str + sweep : str Name of the optimetrics sweep. filename : str Full path and name for the CSV file. @@ -1206,7 +1222,7 @@ def export_parametric_results(self, sweepname, filename, exportunits=True): >>> oModule.ExportParametricResults """ - self.ooptimetrics.ExportParametricResults(sweepname, filename, exportunits) + self.ooptimetrics.ExportParametricResults(sweep, filename, exportunits) return True @pyaedt_function_handler() @@ -1232,24 +1248,24 @@ def generate_unique_setup_name(self, setup_name=None): index += 1 return setup_name - @pyaedt_function_handler() - def _create_setup(self, setupname="MySetupAuto", setuptype=None, props=None): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def _create_setup(self, name="MySetupAuto", setup_type=None, props=None): if props is None: props = {} - if setuptype is None: - setuptype = self.design_solutions.default_setup - name = self.generate_unique_setup_name(setupname) - if setuptype == 0: - setup = SetupHFSSAuto(self, setuptype, name) - elif setuptype == 4: - setup = SetupSBR(self, setuptype, name) - elif setuptype in [5, 6, 7, 8, 9, 10, 56, 58, 59]: - setup = SetupMaxwell(self, setuptype, name) - elif setuptype in [14]: - setup = SetupQ3D(self, setuptype, name) + if setup_type is None: + setup_type = self.design_solutions.default_setup + name = self.generate_unique_setup_name(name) + if setup_type == 0: + setup = SetupHFSSAuto(self, setup_type, name) + elif setup_type == 4: + setup = SetupSBR(self, setup_type, name) + elif setup_type in [5, 6, 7, 8, 9, 10, 56, 58, 59]: + setup = SetupMaxwell(self, setup_type, name) + elif setup_type == 14: + setup = SetupQ3D(self, setup_type, name) else: - setup = SetupHFSS(self, setuptype, name) + setup = SetupHFSS(self, setup_type, name) if self.design_type == "HFSS": # Handle the situation when ports have not been defined. @@ -1321,13 +1337,13 @@ def _create_setup(self, setupname="MySetupAuto", setuptype=None, props=None): return setup - @pyaedt_function_handler() - def delete_setup(self, setupname): + @pyaedt_function_handler(setupname="name") + def delete_setup(self, name): """Delete a setup. Parameters ---------- - setupname : str + name : str Name of the setup. Returns @@ -1346,28 +1362,28 @@ def delete_setup(self, setupname): >>> import pyaedt >>> hfss = pyaedt.Hfss() - >>> setup1 = hfss.create_setup(setupname='Setup1') - >>> hfss.delete_setup(setupname='Setup1') + >>> setup1 = hfss.create_setup(name='Setup1') + >>> hfss.delete_setup() ... PyAEDT INFO: Sweep was deleted correctly. """ - if setupname in self.existing_analysis_setups: - self.oanalysis.DeleteSetups([setupname]) + if name in self.existing_analysis_setups: + self.oanalysis.DeleteSetups([name]) for s in self._setups: - if s.name == setupname: + if s.name == name: self._setups.remove(s) return True return False - @pyaedt_function_handler() - def edit_setup(self, setupname, properties_dict): + @pyaedt_function_handler(setupname="name", properties_dict="properties") + def edit_setup(self, name, properties): """Modify a setup. Parameters ---------- - setupname : str + name : str Name of the setup. - properties_dict : dict + properties : dict Dictionary containing the property to update with the value. Returns @@ -1381,18 +1397,18 @@ def edit_setup(self, setupname, properties_dict): """ setuptype = self.design_solutions.default_setup - setup = Setup(self, setuptype, setupname, isnewsetup=False) - setup.update(properties_dict) - self.active_setup = setupname + setup = Setup(self, setuptype, name) + setup.update(properties) + self.active_setup = name return setup - @pyaedt_function_handler() - def get_setup(self, setupname): + @pyaedt_function_handler(setupname="name") + def get_setup(self, name): """Get the setup from the current design. Parameters ---------- - setupname : str + name : str Name of the setup. Returns @@ -1404,17 +1420,17 @@ def get_setup(self, setupname): if self.solution_type == "SBR+": setuptype = 4 - setup = SetupSBR(self, setuptype, setupname, isnewsetup=False) + setup = SetupSBR(self, setuptype, name, is_new_setup=False) elif self.design_type in ["Q3D Extractor", "2D Extractor", "HFSS"]: - setup = SetupHFSS(self, setuptype, setupname, isnewsetup=False) + setup = SetupHFSS(self, setuptype, name, is_new_setup=False) if setup.props and setup.props.get("SetupType", "") == "HfssDrivenAuto": - setup = SetupHFSSAuto(self, 0, setupname, isnewsetup=False) + setup = SetupHFSSAuto(self, 0, name, is_new_setup=False) elif self.design_type in ["Maxwell 2D", "Maxwell 3D"]: - setup = SetupMaxwell(self, setuptype, setupname, isnewsetup=False) + setup = SetupMaxwell(self, setuptype, name, is_new_setup=False) else: - setup = Setup(self, setuptype, setupname, isnewsetup=False) + setup = Setup(self, setuptype, name, is_new_setup=False) if setup.props: - self.active_setup = setupname + self.active_setup = name return setup @pyaedt_function_handler() @@ -1492,15 +1508,15 @@ def get_output_variable(self, variable, solution=None): ) return value - @pyaedt_function_handler() - def get_object_material_properties(self, object_list=None, prop_names=None): + @pyaedt_function_handler(object_list="assignment") + def get_object_material_properties(self, assignment=None, prop_names=None): """Retrieve the material properties for a list of objects and return them in a dictionary. This high-level function ignores objects with no defined material properties. Parameters ---------- - object_list : list, optional + assignment : list, optional List of objects to get material properties for. The default is ``None``, in which case material properties are retrieved for all objects. prop_names : str or list @@ -1512,18 +1528,18 @@ def get_object_material_properties(self, object_list=None, prop_names=None): dict Dictionary of objects with material properties. """ - if object_list: - if not isinstance(object_list, list): - object_list = [object_list] + if assignment: + if not isinstance(assignment, list): + assignment = [assignment] else: - object_list = self.modeler.object_names + assignment = self.modeler.object_names if prop_names: if not isinstance(prop_names, list): prop_names = [prop_names] dict = {} - for entry in object_list: + for entry in assignment: mat_name = self.modeler[entry].material_name mat_props = self._materials[mat_name] if prop_names is None: @@ -1534,81 +1550,6 @@ def get_object_material_properties(self, object_list=None, prop_names=None): dict[entry][prop_name] = mat_props._props[prop_name] return dict - @pyaedt_function_handler() - def analyze_all(self): - """Analyze all setups in a design. - - .. deprecated:: 0.6.52 - Use :func:`analyze` method instead. - - Returns - ------- - bool - ``True`` when simulation is finished. - """ - warnings.warn("`analyze_all` is deprecated. Use `analyze` method instead.", DeprecationWarning) - self.odesign.AnalyzeAll() - return True - - @pyaedt_function_handler() - def analyze_from_initial_mesh(self): - """Revert the solution to the initial mesh and re-run the solve. - - .. deprecated:: 0.6.52 - Use :func:`analyze` method instead. - - Returns - ------- - bool - ``True`` when successful, ``False`` when failed. - - References - ---------- - - >>> oModule.RevertSetupToInitial - >>> oDesign.Analyze - """ - warnings.warn("`analyze_from_initial_mesh` is deprecated. Use `analyze` method instead.", DeprecationWarning) - - self.oanalysis.RevertSetupToInitial(self._setup) - self.analyze(self.active_setup) - return True - - @pyaedt_function_handler() - def analyze_nominal(self, num_cores=1, num_tasks=1, num_gpu=0, acf_file=None, use_auto_settings=True): - """Solve the nominal design. - - .. deprecated:: 0.6.52 - Use :func:`analyze` method instead. - - Parameters - ---------- - num_cores : int, optional - Number of simulation cores. Default is ``1``. - num_tasks : int, optional - Number of simulation tasks. Default is ``1``. - num_gpu : int, optional - Number of simulation graphic processing units to use. Default is ``0``. - acf_file : str, optional - Full path to the custom ACF file. - use_auto_settings : bool, optional - Set ``True`` to use automatic settings for HPC. The option is only considered for setups - that support automatic settings. - - Returns - ------- - bool - ``True`` when successful, ``False`` when failed. - - References - ---------- - - >>> oDesign.Analyze - """ - warnings.warn("`analyze_nominal` is deprecated. Use `analyze` method instead.", DeprecationWarning) - - return self.analyze(self.active_setup, num_cores, num_tasks, num_gpu, acf_file, use_auto_settings) - @pyaedt_function_handler() def analyze( self, @@ -2050,7 +1991,7 @@ def solve_in_batch( if machine == "localhost": while not os.path.exists(queue_file): time.sleep(0.5) - with open(queue_file, "r") as f: + with open_file(queue_file, "r") as f: lines = f.readlines() for line in lines: if "JobID" in line: diff --git a/pyaedt/application/Analysis3D.py b/pyaedt/application/Analysis3D.py index 0416ae6804b..38d8b39859b 100644 --- a/pyaedt/application/Analysis3D.py +++ b/pyaedt/application/Analysis3D.py @@ -280,13 +280,13 @@ def plot( show_grid=show_grid, ) - @pyaedt_function_handler() - def export_mesh_stats(self, setup_name, variation_string="", mesh_path=None): + @pyaedt_function_handler(setup_name="setup") + def export_mesh_stats(self, setup, variation_string="", mesh_path=None): """Export mesh statistics to a file. Parameters ---------- - setup_name : str + setup : str Setup name. variation_string : str, optional Variation list. The default is ``""``. @@ -305,7 +305,7 @@ def export_mesh_stats(self, setup_name, variation_string="", mesh_path=None): """ if not mesh_path: mesh_path = os.path.join(self.working_directory, "meshstats.ms") - self.odesign.ExportMeshStats(setup_name, variation_string, mesh_path) + self.odesign.ExportMeshStats(setup, variation_string, mesh_path) return mesh_path @pyaedt_function_handler() diff --git a/pyaedt/application/Analysis3DLayout.py b/pyaedt/application/Analysis3DLayout.py index d90148023d4..aa240af0d0e 100644 --- a/pyaedt/application/Analysis3DLayout.py +++ b/pyaedt/application/Analysis3DLayout.py @@ -148,7 +148,7 @@ def excitations(self): Returns ------- list - List of excitation names. Excitations with multiple modes will return one + Excitation list. Excitations with multiple modes return one excitation for each mode. References @@ -158,35 +158,6 @@ def excitations(self): """ return list(self.oboundary.GetAllPortsList()) - @property - def get_all_sparameter_list(self, excitation_names=[]): - """List of all S parameters for a list of excitations. - - Parameters - ---------- - excitation_names : list, optional - List of excitations. The default is ``[]``, in which case - the S parameters for all excitations are to be provided. - For example, ``["1", "2"]``. - - Returns - ------- - list - List of strings representing the S parameters of the excitations. - For example, ``["S(1, 1)", "S(1, 2)", S(2, 2)]``. - - """ - if not excitation_names: - excitation_names = self.excitations - spar = [] - k = 0 - for i in excitation_names: - k = excitation_names.index(i) - while k < len(excitation_names): - spar.append("S({},{})".format(i, excitation_names[k])) - k += 1 - return spar - @pyaedt_function_handler() def change_design_settings(self, settings): """Set HFSS 3D Layout Design Settings. @@ -207,13 +178,13 @@ def change_design_settings(self, settings): self.odesign.DesignOptions(arg) return True - @pyaedt_function_handler() - def export_mesh_stats(self, setup_name, variation_string="", mesh_path=None): + @pyaedt_function_handler(setup_name="setup") + def export_mesh_stats(self, setup, variation_string="", mesh_path=None): """Export mesh statistics to a file. Parameters ---------- - setup_name : str + setup : str Setup name. variation_string : str, optional Variation List. @@ -232,155 +203,9 @@ def export_mesh_stats(self, setup_name, variation_string="", mesh_path=None): """ if not mesh_path: mesh_path = os.path.join(self.working_directory, "meshstats.ms") - self.odesign.ExportMeshStats(setup_name, variation_string, mesh_path) + self.odesign.ExportMeshStats(setup, variation_string, mesh_path) return mesh_path - @pyaedt_function_handler() - def get_all_return_loss_list(self, excitation_names=[], excitation_name_prefix=""): - """Retrieve a list of all return losses for a list of excitations. - - Parameters - ---------- - excitation_names : list, optional - List of excitations. The default is ``[]``, in which case - the return losses for all excitations are to be provided. - For example, ``["1", "2"]``. - excitation_name_prefix : string, optional - Prefix to add to the excitation names. The default is ``""``. - - Returns - ------- - list - List of strings representing the return losses of the excitations. - For example, ``["S(1, 1)", "S(2, 2)"]``. - - References - ---------- - - >>> oModule.GetAllPorts - """ - if not excitation_names: - excitation_names = self.excitations - if excitation_name_prefix: - excitation_names = [i for i in excitation_names if excitation_name_prefix.lower() in i.lower()] - spar = [] - for i in excitation_names: - spar.append("S({},{})".format(i, i)) - return spar - - @pyaedt_function_handler() - def get_all_insertion_loss_list(self, trlist=[], reclist=[], tx_prefix="", rx_prefix=""): - """Retrieve a list of all insertion losses from two lists of excitations (driver and receiver). - - Parameters - ---------- - trlist : list, optional - List of drivers. The default is ``[]``. For example, ``["1"]``. - reclist : list, optional - List of receivers. The default is ``[]``. The number of drivers equals - the number of receivers. For example, ``["2"]``. - tx_prefix : str, optional - Prefix to add to driver names. For example, ``"DIE"``. The default is ``""``. - rx_prefix : str, optional - Prefix to add to receiver names. For example, ``"BGA"``. The default is ``""``. - - Returns - ------- - list - List of strings representing insertion losses of the excitations. - For example, ``["S(1, 2)"]``. - - References - ---------- - - >>> oModule.GetAllPorts - """ - spar = [] - if not trlist: - trlist = [i for i in self.excitations if tx_prefix in i] - if not reclist: - reclist = [i for i in self.excitations if rx_prefix in i] - if len(trlist) != len(reclist): - self.logger.error("The TX and RX lists should be same length.") - return False - for i, j in zip(trlist, reclist): - spar.append("S({},{})".format(i, j)) - return spar - - @pyaedt_function_handler() - def get_next_xtalk_list(self, trlist=[], tx_prefix=""): - """Retrieve a list of all the near end XTalks from a list of excitations (driver and receiver). - - Parameters - ---------- - trlist : list, optional - List of drivers. The default is ``[]``. For example, ``["1", "2", "3"]``. - tx_prefix : str, optional - Prefix to add to driver names. For example, ``"DIE"``. The default is ``""``. - - Returns - ------- - list - List of strings representing near end XTalks of the excitations. - For example, ``["S(1, 2)", "S(1, 3)", "S(2, 3)"]``. - - References - ---------- - - >>> oModule.GetAllPorts - """ - next_xtalks = [] - if not trlist: - trlist = [i for i in self.excitations if tx_prefix in i] - for i in trlist: - k = trlist.index(i) + 1 - while k < len(trlist): - next_xtalks.append("S({},{})".format(i, trlist[k])) - k += 1 - return next_xtalks - - @pyaedt_function_handler() - def get_fext_xtalk_list(self, trlist=None, reclist=None, tx_prefix="", rx_prefix="", skip_same_index_couples=True): - """Retrieve a list of all the far end XTalks from two lists of exctitations (driver and receiver). - - Parameters - ---------- - trlist : list, optional - List of drivers. The default is ``[]``. For example, ``["1", "2"]``. - reclist : list, optional - List of receivers. The default is ``[]``. For example, ``["3", "4"]``. - tx_prefix : str, optional - Prefix to add to the driver names. For example, ``"DIE"``. The default is ``""``. - rx_prefix : str, optional - Prefix to add to the receiver names. For examples, ``"BGA"``. The default is ``""``. - skip_same_index_couples : bool, optional - Whether to skip driver and receiver couples with the same index position. - The default is ``True``, in which case the drivers and receivers - with the same index position are considered insertion losses and - excluded from the list. - - Returns - ------- - list - List of strings representing the far end XTalks of the excitations. - For example, ``["S(1, 4)", "S(2, 3)"]``. - - References - ---------- - - >>> oModule.GetAllPorts - """ - fext = [] - if trlist is None: - trlist = [i for i in self.excitations if tx_prefix in i] - if reclist is None: - reclist = [i for i in self.excitations if rx_prefix in i] - for i in trlist: - for k in reclist: - if not skip_same_index_couples or reclist.index(k) != trlist.index(i): - fext.append("S({},{})".format(i, k)) - return fext - @property def modeler(self): """Modeler object. @@ -427,15 +252,15 @@ def existing_analysis_setups(self): return list(setups) return [] - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create a setup. Parameters ---------- - setupname : str, optional + name : str, optional Name of the new setup. The default is ``"MySetupAuto"``. - setuptype : str, optional + setup_type : str, optional Type of the setup. The default is ``None``, in which case the default type is applied. **kwargs : dict, optional @@ -457,14 +282,14 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Hfss3dLayout >>> app = Hfss3dLayout() - >>> app.create_setup(setupname="Setup1", MeshSizeFactor=2,SingleFrequencyDataList__AdaptiveFrequency="5GHZ") + >>> app.create_setup(name="Setup1",MeshSizeFactor=2,SingleFrequencyDataList__AdaptiveFrequency="5GHZ") """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) - name = self.generate_unique_setup_name(setupname) - setup = Setup3DLayout(self, setuptype, name) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) + name = self.generate_unique_setup_name(name) + setup = Setup3DLayout(self, setup_type, name) tmp_setups = self.setups setup.create() setup.auto_update = False @@ -482,15 +307,15 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): self._setups = tmp_setups + [setup] return setup - @pyaedt_function_handler() - def get_setup(self, setupname, setuptype=None): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def get_setup(self, name, setup_type=None): """Retrieve a setup. Parameters ---------- - setupname : str + name : str Name of the setup. - setuptype : SETUPS, optional + setup_type : SETUPS, optional Type of the setup. The default is ``None``, in which case the default type is applied. @@ -500,22 +325,22 @@ def get_setup(self, setupname, setuptype=None): Setup object. """ - if setuptype is None: - setuptype = self.design_solutions.default_setup + if setup_type is None: + setup_type = self.design_solutions.default_setup for setup in self._setups: - if setupname == setup.name: + if name == setup.name: return setup - setup = Setup3DLayout(self, setuptype, setupname, isnewsetup=False) - self.active_setup = setupname + setup = Setup3DLayout(self, setup_type, name, is_new_setup=False) + self.active_setup = name return setup - @pyaedt_function_handler() - def delete_setup(self, setupname): + @pyaedt_function_handler(setupname="name") + def delete_setup(self, name): """Delete a setup. Parameters ---------- - setupname : str + name : str Name of the setup. Returns @@ -534,15 +359,15 @@ def delete_setup(self, setupname): >>> import pyaedt >>> hfss3dlayout = pyaedt.Hfss3dLayout() - >>> setup1 = hfss3dlayout.create_setup(setupname='Setup1') - >>> hfss3dlayout.delete_setup(setupname='Setup1') + >>> setup1 = hfss3dlayout.create_setup(name='Setup1') + >>> hfss3dlayout.delete_setup() ... PyAEDT INFO: Sweep was deleted correctly. """ - if setupname in self.existing_analysis_setups: - self.osolution.Delete(setupname) + if name in self.existing_analysis_setups: + self.osolution.Delete(name) for s in self.setups: - if s.name == setupname: + if s.name == name: self.setups.remove(s) return True return False diff --git a/pyaedt/application/AnalysisNexxim.py b/pyaedt/application/AnalysisNexxim.py index 229bffc7f08..02271d31321 100644 --- a/pyaedt/application/AnalysisNexxim.py +++ b/pyaedt/application/AnalysisNexxim.py @@ -69,13 +69,13 @@ def __init__( self._modeler = self.modeler self._post = self.post - @pyaedt_function_handler() - def delete_setup(self, setupname): + @pyaedt_function_handler(setupname="name") + def delete_setup(self, name): """Delete a setup. Parameters ---------- - setupname : str + name : str Name of the setup. Returns @@ -88,10 +88,10 @@ def delete_setup(self, setupname): >>> oModule.RemoveSimSetup """ - if setupname in self.existing_analysis_setups: - self.oanalysis.RemoveSimSetup([setupname]) + if name in self.existing_analysis_setups: + self.oanalysis.RemoveSimSetup([name]) for s in self.setups: - if s.name == setupname: + if s.name == name: self.setups.remove(s) return True return False @@ -287,7 +287,7 @@ def sources(self): return props @property - def excitation_names(self): + def excitations(self): """List of port names. Returns @@ -304,36 +304,24 @@ def excitation_names(self): return ports @property - def excitation_objets(self): + def excitation_objects(self): """List of port objects. Returns ------- - list + dict List of port objects. """ - return [self.excitations[name] for name in self.excitations] - - @property - def excitations(self): - """Get all ports. - - Returns - ------- - list - List of ports. - - """ props = {} if not self._internal_excitations: - for port in self.excitation_names: + for port in self.excitations: props[port] = Excitations(self, port) self._internal_excitations = props else: props = self._internal_excitations - if not sorted(list(props.keys())) == sorted(self.excitation_names): + if not sorted(list(props.keys())) == sorted(self.excitations): a = set(str(x) for x in props.keys()) - b = set(str(x) for x in self.excitation_names) + b = set(str(x) for x in self.excitations) if len(a) == len(b): unmatched_new_name = list(b - a)[0] unmatched_old_name = list(a - b)[0] @@ -342,208 +330,22 @@ def excitations(self): else: if len(a) > len(b): for old_port in props.keys(): - if old_port not in self.excitation_names: + if old_port not in self.excitations: del props[old_port] return props else: - for new_port in self.excitation_names: + for new_port in self.excitations: if new_port not in props.keys(): props[new_port] = Excitations(self, new_port) return props - @property - def get_all_sparameter_list(self, excitation_names=[]): - """List of all S parameters for a list of excitations. - - Parameters - ---------- - excitation_names : list, optional - List of excitations. The default value is ``[]``, in which case - the S parameters for all excitations are to be provided. - For example, ``["1", "2"]``. - - Returns - ------- - list of str - List of strings representing the S parameters of the excitations. - For example, ``"S(1,1)", "S(1,2)", "S(2,2)"``. - - """ - if not excitation_names: - excitation_names = list(self.excitations.keys()) - spar = [] - k = 0 - for i in excitation_names: - k = excitation_names.index(i) - while k < len(excitation_names): - spar.append("S({},{})".format(i, excitation_names[k])) - k += 1 - return spar - - @pyaedt_function_handler() - def get_all_return_loss_list(self, excitation_names=None, excitation_name_prefix=""): - """Retrieve a list of all return losses for a list of exctitations. - - Parameters - ---------- - excitation_names : list, optional - List of excitations. The default is ``None``, in which case - the return losses for all excitations are to be provided. - For example ``["1", "2"]``. - excitation_name_prefix : string, optional - Prefix to add to the excitation names. The default is ``""``, - - Returns - ------- - list of str - List of strings representing the return losses of the excitations. - For example ``["S(1, 1)", S(2, 2)]``. - - References - ---------- - - >>> oEditor.GetAllPorts - """ - if excitation_names == None: - excitation_names = [] - - if not excitation_names: - excitation_names = list(self.excitations.keys()) - if excitation_name_prefix: - excitation_names = [i for i in excitation_names if excitation_name_prefix.lower() in i.lower()] - spar = [] - for i in excitation_names: - spar.append("S({},{})".format(i, i)) - return spar - - @pyaedt_function_handler() - def get_all_insertion_loss_list(self, trlist=None, reclist=None, tx_prefix="", rx_prefix=""): - """Retrieve a list of all insertion losses from two lists of excitations (driver and receiver). - - Parameters - ---------- - trlist : list, optional - List of drivers. The default is ``[]``. For example, ``["1"]``. - reclist : list, optional - List of receivers. The default is ``[]``. The number of drivers equals - the number of receivers. For example, ``["2"]``. - tx_prefix : str, optional - Prefix to add to driver names. For example, ``"DIE"``. The default is ``""``. - rx_prefix : str, optional - Prefix to add to receiver names. For example, ``"BGA"``. The default is ``""``. - - Returns - ------- - list of str - List of strings representing insertion losses of the excitations. - For example, ``["S(1,2)"]``. - - References - ---------- - - >>> oEditor.GetAllPorts - """ - if trlist == None: - trlist = [] - if reclist == None: - reclist = [] - - spar = [] - if not trlist: - trlist = [i for i in list(self.excitations.keys()) if tx_prefix in i] - if not reclist: - reclist = [i for i in list(self.excitations.keys()) if rx_prefix in i] - if len(trlist) != len(reclist): - self.logger.error("The TX and RX lists should be the same length.") - return False - for i, j in zip(trlist, reclist): - spar.append("S({},{})".format(i, j)) - return spar - - @pyaedt_function_handler() - def get_next_xtalk_list(self, trlist=[], tx_prefix=""): - """Retrieve a list of all the near end XTalks from a list of excitations (driver and receiver). - - Parameters - ---------- - trlist : list, optional - List of drivers. The default is ``[]``. For example, - ``["1", "2", "3"]``. - tx_prefix : str, optional - Prefix to add to driver names. For example, ``"DIE"``. The default is ``""``. - - Returns - ------- - list of str - List of strings representing near end XTalks of the excitations. - For example, ``["S(1, 2)", "S(1, 3)", "S(2, 3)"]``. - - References - ---------- - - >>> oEditor.GetAllPorts - """ - next_xtalks = [] - if not trlist: - trlist = [i for i in list(self.excitations.keys()) if tx_prefix in i] - for i in trlist: - k = trlist.index(i) + 1 - while k < len(trlist): - next_xtalks.append("S({},{})".format(i, trlist[k])) - k += 1 - return next_xtalks - - @pyaedt_function_handler() - def get_fext_xtalk_list(self, trlist=None, reclist=None, tx_prefix="", rx_prefix="", skip_same_index_couples=True): - """Retrieve a list of all the far end XTalks from two lists of exctitations (driver and receiver). - - Parameters - ---------- - trlist : list, optional - List of drivers. The default is ``[]``. For example, - ``["1", "2"]``. - reclist : list, optional - List of receiver. The default is ``[]``. For example, - ``["3", "4"]``. - tx_prefix : str, optional - Prefix for driver names. For example, ``"DIE"``. The default is ``""``. - rx_prefix : str, optional - Prefix for receiver names. For examples, ``"BGA"`` The default is ``""``. - skip_same_index_couples : bool, optional - Whether to skip driver and receiver couples with the same index position. - The default is ``True``, in which case the drivers and receivers - with the same index position are considered insertion losses and - excluded from the list. - - Returns - ------- - list of str - List of strings representing the far end XTalks of the excitations. - For example, ``["S(1, 4)", "S(2, 3)"]``. - - References - ---------- - - >>> oEditor.GetAllPorts - """ - fext = [] - if trlist is None: - trlist = [i for i in list(self.excitations.keys()) if tx_prefix in i] - if reclist is None: - reclist = [i for i in list(self.excitations.keys()) if rx_prefix in i] - for i in trlist: - for k in reclist: - if not skip_same_index_couples or reclist.index(k) != trlist.index(i): - fext.append("S({},{})".format(i, k)) - return fext - - @pyaedt_function_handler() - def get_setup(self, setupname): + @pyaedt_function_handler(setupname="name") + def get_setup(self, name): """Retrieve the setup from the current design. Parameters ---------- - setupname : str + name : str Name of the setup. Returns @@ -552,20 +354,20 @@ def get_setup(self, setupname): Setup object. """ - setup = SetupCircuit(self, self.solution_type, setupname, isnewsetup=False) + setup = SetupCircuit(self, self.solution_type, name, is_new_setup=False) if setup.props: - self.active_setup = setupname + self.active_setup = name return setup - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create a setup. Parameters ---------- - setupname : str, optional + name : str, optional Name of the new setup. The default is ``"MySetupAuto"``. - setuptype : str, optional + setup_type : str, optional Type of the setup. The default is ``None``, in which case the default type is applied. **kwargs : dict, optional @@ -596,14 +398,14 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Circuit >>> app = Circuit() - >>> app.create_setup(setupname="Setup1", setuptype=app.SETUPS.NexximLNA, Data="LINC 0GHz 4GHz 501") + >>> app.create_setup(name="Setup1",setup_type=app.SETUPS.NexximLNA,Data="LINC 0GHz 4GHz 501") """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) - name = self.generate_unique_setup_name(setupname) - setup = SetupCircuit(self, setuptype, name) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) + name = self.generate_unique_setup_name(name) + setup = SetupCircuit(self, setup_type, name) tmp_setups = self.setups setup.create() setup.auto_update = False diff --git a/pyaedt/application/AnalysisTwinBuilder.py b/pyaedt/application/AnalysisTwinBuilder.py index 3472c40047b..85d9dc246a0 100644 --- a/pyaedt/application/AnalysisTwinBuilder.py +++ b/pyaedt/application/AnalysisTwinBuilder.py @@ -120,15 +120,15 @@ def post(self): return self._post - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create a setup. Parameters ---------- - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - setuptype : str + setup_type : str Type of the setup. The default is ``None``, in which case the default type is applied. **kwargs : dict, optional @@ -142,12 +142,12 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): :class:`pyaedt.modules.SolveSetup.SetupCircuit` Setup object. """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) - name = self.generate_unique_setup_name(setupname) - setup = SetupCircuit(self, setuptype, name) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) + name = self.generate_unique_setup_name(name) + setup = SetupCircuit(self, setup_type, name) tmp_setups = self.setups setup.create() setup.auto_update = False diff --git a/pyaedt/application/Design.py b/pyaedt/application/Design.py index d14f2c8e52c..c5329c23793 100644 --- a/pyaedt/application/Design.py +++ b/pyaedt/application/Design.py @@ -323,6 +323,14 @@ def boundaries(self): for region in hybrid_regions: bb.append(region) bb.append("FE-BI") + current_excitations = [] + current_excitation_types = [] + if "GetExcitations" in self.oboundary.__dir__(): + ee = list(self.oboundary.GetExcitations()) + current_excitations = [i.split(":")[0] for i in ee[::2]] + current_excitation_types = ee[1::2] + ff = [i.split(":")[0] for i in ee] + bb.extend(ff) # Parameters and Motion definitions if self.design_type in ["Maxwell 3D", "Maxwell 2D"]: @@ -360,7 +368,12 @@ def boundaries(self): current_boundaries = bb[::2] current_types = bb[1::2] - + check_boundaries = list(current_boundaries[:]) + list(self.ports[:]) + self.excitations[:] + if "nets" in dir(self): + check_boundaries += self.nets + for k in list(self._boundaries.keys())[:]: + if k not in check_boundaries: + del self._boundaries[k] for boundary, boundarytype in zip(current_boundaries, current_types): if boundary in self._boundaries: continue @@ -378,12 +391,12 @@ def boundaries(self): self._boundaries[boundary] = NetworkObject(self, boundary) else: self._boundaries[boundary] = BoundaryObject(self, boundary, boundarytype=boundarytype) - - excitations = self.design_excitations - for exc in excitations: - if not self._boundaries or exc.name not in list(self._boundaries.keys()): - self._boundaries[exc.name] = exc - + try: + for k, v in zip(current_excitations, current_excitation_types): + if k not in self._boundaries: + self._boundaries[k] = BoundaryObject(self, k, boundarytype=v) + except Exception: + pass return list(self._boundaries.values()) @property @@ -403,71 +416,30 @@ def boundaries_by_type(self): return _dict_out @property - def excitations_by_type(self): - """Design excitations by type. - - Returns - ------- - dict - Dictionary of excitations. - """ - _dict_out = {} - for bound in self.design_excitations: - if bound.type in _dict_out: - _dict_out[bound.type].append(bound) - else: - _dict_out[bound.type] = [bound] - return _dict_out - - @property - def design_excitations(self): + def ports(self): """Design excitations. Returns ------- list - List of :class:`pyaedt.modules.Boundary.BoundaryObject`. + Port names. """ - design_excitations = {} + design_excitations = [] if "GetExcitations" in self.oboundary.__dir__(): ee = list(self.oboundary.GetExcitations()) - current_boundaries = [i.split(":")[0] for i in ee[::2]] current_types = ee[1::2] for i in set(current_types): new_port = [] if "GetExcitationsOfType" in self.oboundary.__dir__(): new_port = list(self.oboundary.GetExcitationsOfType(i)) if new_port: - current_boundaries = current_boundaries + new_port + design_excitations += new_port current_types = current_types + [i] * len(new_port) - - for boundary, boundarytype in zip(current_boundaries, current_types): - design_excitations[boundary] = BoundaryObject(self, boundary, boundarytype=boundarytype) - if ( - design_excitations[boundary].object_properties - and design_excitations[boundary].object_properties.props["Type"] == "Terminal" - ): # pragma: no cover - props_terminal = OrderedDict() - props_terminal["TerminalResistance"] = design_excitations[boundary].object_properties.props[ - "Terminal Renormalizing Impedance" - ] - props_terminal["ParentBndID"] = design_excitations[boundary].object_properties.props["Port Name"] - design_excitations[boundary] = BoundaryObject( - self, boundary, props=props_terminal, boundarytype="Terminal" - ) + return design_excitations elif "GetAllPortsList" in self.oboundary.__dir__() and self.design_type in ["HFSS 3D Layout Design"]: - for port in self.oboundary.GetAllPortsList(): - if port in self._boundaries: - continue - bound = self._update_port_info(port) - if bound: - design_excitations[port] = bound - - if design_excitations: - return list(design_excitations.values()) - + return self.oboundary.GetAllPortsList() return [] @property @@ -540,8 +512,7 @@ def project_properties(self): and settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists(self.project_file) ): - local_path = os.path.join(settings.remote_rpc_session_temp_folder, os.path.split(self.project_file)[-1]) - file_path = check_and_download_file(local_path, self.project_file) + file_path = check_and_download_file(self.project_file) try: settings._project_properties[os.path.normpath(self.project_file)] = load_entire_aedt_file(file_path) except Exception: @@ -632,16 +603,21 @@ def design_name(self, new_name): if ";" in new_name: new_name = new_name.split(";")[1] - self.odesign.RenameDesignInstance(self.design_name, new_name) - timeout = 5.0 - timestep = 0.1 - while new_name not in [ - i.GetName() if ";" not in i.GetName() else i.GetName().split(";")[1] - for i in list(self._oproject.GetDesigns()) - ]: - time.sleep(timestep) - timeout -= timestep - assert timeout >= 0 + # If new_name is the name of an existing design, set the current + # design to this design. + if new_name in self.design_list: + self.set_active_design(new_name) + else: # Otherwise rename the current design. + self.odesign.RenameDesignInstance(self.design_name, new_name) + timeout = 5.0 + timestep = 0.1 + while new_name not in [ + i.GetName() if ";" not in i.GetName() else i.GetName().split(";")[1] + for i in list(self._oproject.GetDesigns()) + ]: + time.sleep(timestep) + timeout -= timestep + assert timeout >= 0 @property def design_list(self): @@ -1566,7 +1542,7 @@ def _arg_with_units(self, value, units=None): """ if units is None: units = self.modeler.model_units - if type(value) is str: + if isinstance(value, str): try: float(value) val = "{0}{1}".format(value, units) @@ -3307,6 +3283,8 @@ def _insert_design(self, design_type, design_name=None): else: if design_type == "HFSS" and self._aedt_version < "2021.2": new_design = self._oproject.InsertDesign(design_type, unique_design_name, "DrivenModal", "") + elif design_type == "HFSS" and self._aedt_version < "2024.1": + new_design = self._oproject.InsertDesign(design_type, unique_design_name, "HFSS Modal Network", "") else: new_design = self._oproject.InsertDesign( design_type, unique_design_name, self.default_solution_type, "" diff --git a/pyaedt/application/analysis_hf.py b/pyaedt/application/analysis_hf.py new file mode 100644 index 00000000000..b6a1e60d455 --- /dev/null +++ b/pyaedt/application/analysis_hf.py @@ -0,0 +1,362 @@ +from pyaedt.generic.general_methods import pyaedt_function_handler + + +class ScatteringMethods(object): + """Class containing all methods related to scattering matrix management that are common to Hfss, Circuit and + Hfss3dLayout classes. + """ + + def __init__(self, app): + self._app = app + + @property + def get_all_sparameter_list(self, excitation_names=None): + """List of all S parameters for a list of excitations. + + Parameters + ---------- + excitation_names : list, optional + List of excitations. The default is ``None``, in which case + the S parameters for all excitations are to be provided. + For example, ``["1", "2"]``. + + Returns + ------- + list + Strings representing the S parameters of the excitations. + For example, ``["S(1, 1)", "S(1, 2)", S(2, 2)]``. + + """ + if not excitation_names: + excitation_names = self._app.excitations + spar = [] + k = 0 + for i in excitation_names: + k = excitation_names.index(i) + while k < len(excitation_names): + spar.append("S({},{})".format(i, excitation_names[k])) + k += 1 + return spar + + @pyaedt_function_handler() + def get_all_return_loss_list( + self, excitation_names=None, excitation_name_prefix="", math_formula="", net_list=None + ): + """Get a list of all return losses for a list of excitations. + + Parameters + ---------- + excitation_names : list, optional + List of excitations. The default is ``None``, in which case + the return losses for all excitations are provided. + For example ``["1", "2"]``. + excitation_name_prefix : string, optional + Prefix to add to the excitation names. The default is ``""``, + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. + net_list : list, optional + List of nets to filter the output. The default is ``None``, in which case all parameters are returned. + + Returns + ------- + list of str + List of strings representing the return losses of the excitations. + For example, ``["S(1, 1)", S(2, 2)]``. + + References + ---------- + + >>> oEditor.GetAllPorts + """ + if excitation_names == None: + excitation_names = [] + + if not excitation_names: + excitation_names = list(self._app.excitations) + if excitation_name_prefix: + excitation_names = [i for i in excitation_names if excitation_name_prefix.lower() in i.lower()] + spar = [] + for i in excitation_names: + if not net_list or (net_list and [net for net in net_list if net in i]): + if math_formula: + spar.append("{}(S({},{}))".format(math_formula, i, i)) + else: + spar.append("S({},{})".format(i, i)) + return spar + + @pyaedt_function_handler() + def get_all_insertion_loss_list( + self, trlist=None, reclist=None, tx_prefix="", rx_prefix="", math_formula="", net_list=None + ): + """Get a list of all insertion losses from two lists of excitations (driver and receiver). + + Parameters + ---------- + trlist : list, optional + List of drivers. The default is ``[]``. For example, ``["1"]``. + reclist : list, optional + List of receivers. The default is ``[]``. The number of drivers equals + the number of receivers. For example, ``["2"]``. + tx_prefix : str, optional + Prefix to add to driver names. For example, ``"DIE"``. The default is ``""``. + rx_prefix : str, optional + Prefix to add to receiver names. For example, ``"BGA"``. The default is ``""``. + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. + net_list : list, optional + List of nets to filter the output. The default is ``None``, in which + case all parameters are returned. + + Returns + ------- + list of str + List of strings representing insertion losses of the excitations. + For example, ``["S(1,2)"]``. + + References + ---------- + + >>> oEditor.GetAllPorts + """ + if trlist is None: + trlist = [i for i in list(self._app.excitations)] + + if reclist is None: + reclist = [i for i in list(self._app.excitations)] + if tx_prefix: + trlist = [i for i in trlist if i.startswith(tx_prefix)] + if rx_prefix: + reclist = [i for i in reclist if i.startswith(rx_prefix)] + spar = [] + if not net_list and len(trlist) != len(reclist): + self.logger.error("The TX and RX lists should be the same length.") + return False + if net_list: + for el in net_list: + x = [i for i in trlist if el in i] + y = [i for i in reclist if el in i] + for x1 in x: + for y1 in y: + if x1[-2:] == y1[-2:]: + if math_formula: + spar.append("{}(S({},{}))".format(math_formula, x1, y1)) + else: + spar.append("S({},{})".format(x1, y1)) + break + else: + for i, j in zip(trlist, reclist): + if math_formula: + spar.append("{}(S({},{}))".format(math_formula, i, j)) + else: + spar.append("S({},{})".format(i, j)) + return spar + + @pyaedt_function_handler() + def get_next_xtalk_list(self, trlist=None, tx_prefix="", math_formula="", net_list=None): + """Get a list of all the near end XTalks from a list of excitations (driver and receiver). + + Parameters + ---------- + trlist : list, optional + List of drivers. The default is ``None``. For example, + ``["1", "2", "3"]``. + tx_prefix : str, optional + Prefix to add to driver names. For example, ``"DIE"``. The default is ``""``. + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. + net_list : list, optional + List of nets to filter the output. The default is ``None``, in which case + all parameters are returned. + + Returns + ------- + list of str + List of strings representing near end XTalks of the excitations. + For example, ``["S(1, 2)", "S(1, 3)", "S(2, 3)"]``. + + References + ---------- + + >>> oEditor.GetAllPorts + """ + next_xtalks = [] + if not trlist: + trlist = [i for i in list(self._app.excitations) if tx_prefix in i] + for i in trlist: + if not net_list or (net_list and [net for net in net_list if net in i]): + k = trlist.index(i) + 1 + while k < len(trlist): + if math_formula: + next_xtalks.append("{}(S({},{}))".format(math_formula, i, trlist[k])) + else: + next_xtalks.append("S({},{})".format(i, trlist[k])) + k += 1 + return next_xtalks + + @pyaedt_function_handler() + def get_fext_xtalk_list( + self, + trlist=None, + reclist=None, + tx_prefix="", + rx_prefix="", + skip_same_index_couples=True, + math_formula="", + net_list=None, + ): + """Geta list of all the far end XTalks from two lists of excitations (driver and receiver). + + Parameters + ---------- + trlist : list, optional + List of drivers. The default is ``[]``. For example, + ``["1", "2"]``. + reclist : list, optional + List of receiver. The default is ``[]``. For example, + ``["3", "4"]``. + tx_prefix : str, optional + Prefix for driver names. For example, ``"DIE"``. The default is ``""``. + rx_prefix : str, optional + Prefix for receiver names. For examples, ``"BGA"`` The default is ``""``. + skip_same_index_couples : bool, optional + Whether to skip driver and receiver couples with the same index position. + The default is ``True``, in which case the drivers and receivers + with the same index position are considered insertion losses and + excluded from the list. + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. + net_list : list, optional + List of nets to filter the output. The default is ``None``, in which case all + parameters are returned. + + Returns + ------- + list of str + List of strings representing the far end XTalks of the excitations. + For example, ``["S(1, 4)", "S(2, 3)"]``. + + References + ---------- + + >>> oEditor.GetAllPorts + """ + + fext = [] + if trlist is None: + trlist = [i for i in list(self._app.excitations) if tx_prefix in i] + if reclist is None: + reclist = [i for i in list(self._app.excitations) if rx_prefix in i] + for i in trlist: + if not net_list or (net_list and [net for net in net_list if net in i]): + for k in reclist: + if not skip_same_index_couples or reclist.index(k) != trlist.index(i): + if math_formula: + fext.append("{}(S({},{}))".format(math_formula, i, k)) + else: + fext.append("S({},{})".format(i, k)) + return fext + + @pyaedt_function_handler() + def get_touchstone_data(self, setup_name=None, sweep_name=None, variations=None): + """ + Return a Touchstone data plot. + + Parameters + ---------- + setup_name : list + Name of the setup. + sweep_name : str, optional + Name of the sweep. The default value is ``None``. + variations : dict, optional + Dictionary of variation names. The default value is ``None``. + + Returns + ------- + :class:`pyaedt.generic.touchstone_parser.TouchstoneData` + Class containing all requested data. + + References + ---------- + + >>> oModule.GetSolutionDataPerVariation + """ + from pyaedt.generic.touchstone_parser import TouchstoneData + + if not setup_name: + setup_name = self._app.setups[0].name + + if self._app.design_type != "Circuit Design" and not sweep_name: + for setup in self._app.setups: + if setup.name == setup_name: + sweep_name = setup.sweeps[0].name + solution = "{} : {}".format(setup_name, sweep_name) + else: + solution = setup_name + s_parameters = [] + expression = self._app.get_traces_for_plot(category="S") + sol_data = self._app.post.get_solution_data(expression, solution, variations=variations) + for i in range(sol_data.number_of_variations): + sol_data.set_active_variation(i) + s_parameters.append(TouchstoneData(solution_data=sol_data)) + return s_parameters + + @pyaedt_function_handler() + def export_touchstone( + self, + setup_name=None, + sweep_name=None, + file_name=None, + variations=None, + variations_value=None, + renormalization=False, + impedance=None, + gamma_impedance_comments=False, + ): + """Export a Touchstone file. + + Parameters + ---------- + setup_name : str, optional + Name of the setup that has been solved. + sweep_name : str, optional + Name of the sweep that has been solved. + file_name : str, optional + Full path and name for the Touchstone file. + The default is ``None``, in which case the Touchstone file is exported to + the working directory. + variations : list, optional + List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``. + The default is ``None``. + variations_value : list, optional + List of all parameter variation values. For example, ``["22cel", "100"]``. + The default is ``None``. + renormalization : bool, optional + Perform renormalization before export. + The default is ``False``. + impedance : float, optional + Real impedance value in ohm, for renormalization, if not specified considered 50 ohm. + The default is ``None``. + gamma_impedance_comments : bool, optional + Include Gamma and Impedance values in comments. + The default is ``False``. + + Returns + ------- + str + Filename when successful, ``False`` when failed. + + References + ---------- + + >>> oDesign.ExportNetworkData + """ + return self._app._export_touchstone( + setup_name=setup_name, + sweep_name=sweep_name, + file_name=file_name, + variations=variations, + variations_value=variations_value, + renormalization=renormalization, + impedance=impedance, + comments=gamma_impedance_comments, + ) diff --git a/pyaedt/application/design_solutions.py b/pyaedt/application/design_solutions.py index 01a6d25183e..979ab40c3f2 100644 --- a/pyaedt/application/design_solutions.py +++ b/pyaedt/application/design_solutions.py @@ -10,7 +10,7 @@ "Maxwell Circuit": "", "2D Extractor": "Open", "Q3D Extractor": "Q3D Extractor", - "HFSS": "HFSS Modal Network", + "HFSS": "HFSS Terminal Network", "Icepak": "SteadyState", "RMxprtSolution": "GRM", "ModelCreation": "GRM", @@ -761,16 +761,16 @@ def composite(self, val): self._composite = val self.solution_type = self.solution_type - @pyaedt_function_handler() - def set_auto_open(self, enable=True, boundary_type="Radiation"): - """Set Hfss auto open type. + @pyaedt_function_handler(boundary_type="opening_type") + def set_auto_open(self, enable=True, opening_type="Radiation"): + """Set HFSS auto open type. Parameters ---------- enable : bool, optional - Either to enable or not auto open. The default is ``True``. - boundary_type : str, optional - Boundary Type to be used with auto open. Default is `"Radiation"`. + Whether to enable auto open. The default is ``True``. + opening_type : str, optional + Boundary type to use with auto open. The default is `"Radiation"`. Returns ------- @@ -781,7 +781,7 @@ def set_auto_open(self, enable=True, boundary_type="Radiation"): options = ["NAME:Options", "EnableAutoOpen:=", enable] if enable: options.append("BoundaryType:=") - options.append(boundary_type) + options.append(opening_type) self._solution_options[self.solution_type]["options"] = options self.solution_type = self.solution_type return True diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 29c595b3336..f35a8c12e5d 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -11,8 +11,10 @@ from pyaedt import Hfss3dLayout from pyaedt.application.AnalysisNexxim import FieldAnalysisCircuit +from pyaedt.application.analysis_hf import ScatteringMethods from pyaedt.generic import ibis_reader from pyaedt.generic.DataHandlers import from_rkm_to_aedt +from pyaedt.generic.constants import unit_converter from pyaedt.generic.filesystem import search_files from pyaedt.generic.general_methods import generate_unique_name from pyaedt.generic.general_methods import open_file @@ -27,7 +29,7 @@ from pyaedt.modules.CircuitTemplates import SourceKeys -class Circuit(FieldAnalysisCircuit, object): +class Circuit(FieldAnalysisCircuit, ScatteringMethods): """Provides the Circuit application interface. Parameters @@ -148,7 +150,7 @@ def __init__( port, aedt_process_id, ) - + ScatteringMethods.__init__(self, self) self.onetwork_data_explorer = self._desktop.GetTool("NdExplorer") def _init_from_design(self, *args, **kwargs): @@ -804,51 +806,11 @@ def import_touchstone_solution(self, filename, solution_name="Imported_Data"): self.logger.info("Touchstone file was correctly imported into %s", self.design_name) return portnames - @pyaedt_function_handler() - def export_touchstone( - self, setup_name=None, sweep_name=None, file_name=None, variations=None, variations_value=None - ): - """Export the Touchstone file to a local folder. - - Parameters - ---------- - setup_name : str, optional - Name of the setup that has been solved. - sweep_name : str, optional - Name of the sweep that has been solved. - file_name : str, optional - Full path and name for the Touchstone file. - The default is ``None``, in which case the file is exported to the working directory. - variations : list, optional - List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``. - The default is ``None``. - variations_value : list, optional - List of all parameter variation values. For example, ``["22cel", "100"]``. - The default is ``None``. - - Returns - ------- - str - File name when successful, ``False`` when failed. - - References - ---------- - - >>> oDesign.ExportNetworkData - """ - return self._export_touchstone( - setup_name=setup_name, - sweep_name=sweep_name, - file_name=file_name, - variations=variations, - variations_value=variations_value, - ) - - @pyaedt_function_handler() + @pyaedt_function_handler(designname="design", setupname="setup") def export_fullwave_spice( self, - designname=None, - setupname=None, + design=None, + setup=None, is_solution_file=False, filename=None, passivity=False, @@ -866,10 +828,10 @@ def export_fullwave_spice( Parameters ---------- - designname : str, optional + design : str, optional Name of the design or the full path to the solution file if it is an imported file. The default is ``None``. - setupname : str, optional + setup : str, optional Name of the setup if it is a design. The default is ``None``. is_solution_file : bool, optional Whether it is an imported solution file. The default is ``False``. @@ -900,20 +862,20 @@ def export_fullwave_spice( >>> oDesign.ExportFullWaveSpice """ - if not designname: - designname = self.design_name + if not design: + design = self.design_name if not filename: filename = os.path.join(self.working_directory, self.design_name + ".sp") if is_solution_file: - setupname = designname - designname = "" + setup = design + design = "" else: - if not setupname: - setupname = self.nominal_sweep + if not setup: + setup = self.nominal_sweep self.onetwork_data_explorer.ExportFullWaveSpice( - designname, + design, is_solution_file, - setupname, + setup, "", [], [ @@ -1019,44 +981,9 @@ def create_touchstone_report( if differential_pairs: dif = "Differential Pairs" return self.post.create_report( - curvenames, solution_name, variations=variations, plotname=plot_name, context=dif, subdesign_id=subdesign_id + curvenames, solution_name, variations=variations, context=dif, subdesign_id=subdesign_id ) - @pyaedt_function_handler() - def get_touchstone_data(self, setup_name=None, variation_dict=None): - """ - Return a Touchstone data plot. - - Parameters - ---------- - setup_name : str, optional - Name of the solution. The default value is ``None``. - variation_dict : dict, optional - Dictionary of variation names. The default value is ``None``. - - Returns - ------- - :class:`pyaedt.generic.touchstone_parser.TouchstoneData` - Class containing all requested data. - - References - ---------- - - >>> oModule.GetSolutionDataPerVariation - """ - from pyaedt.generic.touchstone_parser import TouchstoneData - - if not setup_name: - setup_name = self.existing_analysis_sweeps[0] - - s_parameters = [] - expression = self.get_traces_for_plot(category="S") - sol_data = self.post.get_solution_data(expression, setup_name, variations=variation_dict) - for i in range(sol_data.number_of_variations): - sol_data.set_active_variation(i) - s_parameters.append(TouchstoneData(solution_data=sol_data)) - return s_parameters - @pyaedt_function_handler() def push_excitations(self, instance_name, thevenin_calculation=False, setup_name="LinearFrequency"): """Push excitations for a linear frequency setup. @@ -1237,8 +1164,8 @@ def assign_voltage_sinusoidal_excitation_to_ports(self, ports): source_v = self.create_source(source_type="VoltageSin") for port in ports: - self.excitations[port].enabled_sources.append(source_v.name) - self.excitations[port].update() + self.excitation_objects[port].enabled_sources.append(source_v.name) + self.excitation_objects[port].update() return source_v @pyaedt_function_handler() @@ -1262,8 +1189,8 @@ def assign_current_sinusoidal_excitation_to_ports(self, ports): """ source_i = self.create_source(source_type="CurrentSin") for port in ports: - self.excitations[port].enabled_sources.append(source_i.name) - self.excitations[port].update() + self.excitation_objects[port].enabled_sources.append(source_i.name) + self.excitation_objects[port].update() return source_i @pyaedt_function_handler() @@ -1287,8 +1214,8 @@ def assign_power_sinusoidal_excitation_to_ports(self, ports): """ source_p = self.create_source(source_type="PowerSin") for port in ports: - self.excitations[port].enabled_sources.append(source_p.name) - self.excitations[port].update() + self.excitation_objects[port].enabled_sources.append(source_p.name) + self.excitation_objects[port].update() return source_p @pyaedt_function_handler() @@ -1316,15 +1243,15 @@ def assign_voltage_frequency_dependent_excitation_to_ports(self, ports, filepath self.logger.error("Introduced file is not correct. Check path and format.") return False - if not all(elem in self.excitation_names for elem in ports): + if not all(elem in self.excitations for elem in ports): self.logger.error("Defined ports do not exist") return False source_freq = self.create_source(source_type="VoltageFrequencyDependent") source_freq.fds_filename = filepath for port in ports: - self.excitations[port].enabled_sources.append(source_freq.name) - self.excitations[port].update() + self.excitation_objects[port].enabled_sources.append(source_freq.name) + self.excitation_objects[port].update() return source_freq @pyaedt_function_handler() @@ -1441,7 +1368,7 @@ def set_differential_pair( def load_diff_pairs_from_file(self, filename): """Load differtential pairs definition from a file. - You can use the the ``save_diff_pairs_to_file`` method to obtain the file format. + You can use the ``save_diff_pairs_to_file`` method to obtain the file format. New definitions are added only if they are compatible with the existing definitions in the project. Parameters @@ -1687,3 +1614,414 @@ def import_edb_in_circuit(self, edb_path): hfss_3d_layout_model = self.modeler.schematic.add_subcircuit_3dlayout(hfss.design_name) hfss.close_project(save_project=False) return hfss_3d_layout_model + + @pyaedt_function_handler() + def create_tdr_schematic_from_snp( + self, + touchstone, + probe_pins, + probe_ref_pins=None, + termination_pins=None, + differential=True, + rise_time=30, + use_convolution=True, + analyze=True, + design_name="LNA", + ): + """Create a schematic from a Touchstone file and automatically setup a TDR transient analysis. + + Parameters + ---------- + touchstone : str + Full path to the sNp file. + probe_pins : list + Pins to attach to the probe components. + probe_ref_pins : list, optional + Reference pins to attach to probe components. The default is ``None``. + This parameter is valid only in differential TDR probes. + termination_pins : list, optional + Pins to terminate. The default is ``None``. + differential : bool, optional + Whether the buffers are differential. The default is ``True``. If ``False``, the + pins are single ended. + rise_time : float, int, optional + Rise time of the input pulse in picoseconds. The default is ``30``. + use_convolution : bool, optional + Whether to use convolution for the Touchstone file. The default is ``True``. + If ``False``, state-space is used. + analyze : bool + Whether to automatically assign differential pairs. The default is ``False``. + design_name : str, optional + New schematic name. The default is ``"LNA"``. + + Returns + ------- + + """ + if design_name in self.design_list: + self.logger.warning("Design already exists. renaming.") + design_name = generate_unique_name(design_name) + self.insert_design(design_name) + if isinstance(touchstone, type(Hfss3dLayout)): + touchstone_path = touchstone.export_touchstone() + else: + touchstone_path = touchstone + + sub = self.modeler.components.create_touchstone_component(touchstone_path) + center_x = sub.location[0] + center_y = sub.location[1] + left = 0 + delta_y = -1 * sub.location[1] - 2000 - 50 * len(probe_pins) + if differential: + tdr_probe = self.modeler.components.components_catalog["TDR_Differential_Ended"] + else: + tdr_probe = self.modeler.components.components_catalog["TDR_Single_Ended"] + tdr_probe_names = [] + for i, probe_pin in enumerate(probe_pins): + pos_y = unit_converter(delta_y - left * 1000, input_units="mil", output_units=self.modeler.schematic_units) + left += 1 + new_tdr_comp = tdr_probe.place("Tdr_probe", [center_x, center_y + pos_y], angle=-90) + try: + if isinstance(probe_pin, int): + p_pin = probe_pin + if differential: + n_pin = probe_ref_pins[i] + else: + p_pin = [k for k in sub.pins if k.name == probe_pin][0] + if differential: + n_pin = [k for k in sub.pins if k.name == probe_ref_pins[i]][0] + except IndexError: + self.logger.error("Failed to retrieve the pins.") + return False + for pin in sub.pins: + if not termination_pins or (pin.name in termination_pins): + loc = pin.location + loc1 = unit_converter(1500, input_units="mil", output_units=self.modeler.schematic_units) + if loc[0] < center_x: + p1 = self.modeler.components.create_interface_port( + name=pin.name, location=[loc[0] - loc1, loc[1]] + ) + else: + p1 = self.modeler.components.create_interface_port( + name=pin.name, location=[loc[0] + loc1, loc[1]] + ) + p1.pins[0].connect_to_component(pin, use_wire=True) + + _, first, second = new_tdr_comp.pins[0].connect_to_component(p_pin) + self.modeler.move(first, [0, 100], "mil") + if second.pins[0].location[0] > center_x: + self.modeler.move(second, [1000, 0], "mil") + else: + self.modeler.move(second, [-1000, 0], "mil") + if differential: + _, first, second = new_tdr_comp.pins[1].connect_to_component(n_pin) + self.modeler.move(first, [0, -100], "mil") + if second.pins[0].location[0] > center_x: + self.modeler.move(second, [1000, 0], "mil") + else: + self.modeler.move(second, [-1000, 0], "mil") + new_tdr_comp.parameters["Pulse_repetition"] = "{}ms".format(rise_time * 1e5) + new_tdr_comp.parameters["Rise_time"] = "{}ps".format(rise_time) + if differential: + tdr_probe_names.append("O(A{}:zdiff)".format(new_tdr_comp.id)) + else: + tdr_probe_names.append("O(A{}:zl)".format(new_tdr_comp.id)) + + setup = self.create_setup(name="Transient_TDR", setup_type=self.SETUPS.NexximTransient) + setup.props["TransientData"] = ["{}ns".format(rise_time / 4), "{}ns".format(rise_time * 1000)] + if use_convolution: + self.oanalysis.AddAnalysisOptions( + [ + "NAME:DataBlock", + "DataBlockID:=", + 8, + "Name:=", + "Nexxim Options", + [ + "NAME:ModifiedOptions", + "ts_convolution:=", + True, + ], + ] + ) + setup.props["OptionName"] = "Nexxim Options" + if analyze: + self.analyze() + for trace in tdr_probe_names: + self.post.create_report(trace) + return True, tdr_probe_names + + @pyaedt_function_handler() + def create_lna_schematic_from_snp( + self, + touchstone, + start_frequency=0, + stop_frequency=30, + auto_assign_diff_pairs=False, + separation=".", + pattern=None, + analyze=True, + design_name="LNA", + ): + """Create a schematic from a Touchstone file and automatically set up an LNA analysis. + + This method optionally assigns differential pairs automatically based on name pattern. + + Parameters + ---------- + touchstone : str + Full path to the sNp file. + start_frequency : int, float, optional + Start frequency in GHz of the LNA setup. The default is ``0``. + stop_frequency : int, float, optional + Stop frequency in GHz of the LNA setup. The default is ``30``. + auto_assign_diff_pairs : bool + Whether to automatically assign differential pairs. The default is ``False``. + separation : str, optional + Character to use to separate port names. The default is ``"."``. + pattern : list, optional + Port name pattern. The default is ``["component", "pin", "net"]``. + analyze : bool + Whether to automatically assign differential pairs. The default is ``False``. + design_name : str, optional + New schematic name. The default is ``"LNA"``. + + Returns + ------- + (bool, list, list) + First argument is ``True`` if succeeded. + Second and third argument are respectively names of the differential and common mode pairs. + """ + if pattern is None: + pattern = ["component", "pin", "net"] + if design_name in self.design_list: + self.logger.warning("Design already exists. renaming.") + design_name = generate_unique_name(design_name) + self.insert_design(design_name) + if isinstance(touchstone, type(Hfss3dLayout)): + touchstone_path = touchstone.export_touchstone() + else: + touchstone_path = touchstone + + sub = self.modeler.components.create_touchstone_component(touchstone_path) + + ports = [] + center = sub.location[0] + left = 0 + right = 0 + start = 1500 + for pin in sub.pins: + loc = pin.location + if loc[0] < center: + delta = unit_converter(start + left * 200, input_units="mil", output_units=self.modeler.schematic_units) + new_loc = [loc[0] - delta, loc[1]] + left += 1 + else: + delta = unit_converter( + start + right * 200, input_units="mil", output_units=self.modeler.schematic_units + ) + new_loc = [loc[0] + delta, loc[1]] + right += 1 + port = self.modeler.components.create_interface_port(name=pin.name, location=new_loc) + port.pins[0].connect_to_component(component_pin=pin, use_wire=True) + ports.append(port) + diff_pairs = [] + comm_pairs = [] + if auto_assign_diff_pairs: + for pin in ports: + pin_name = pin.name.split(separation) + if pin_name[-1][-1] == "P": + component = pin_name[pattern.index("component")] + net = pin_name[pattern.index("net")] + for neg_pin in ports: + neg_pin_name = neg_pin.name.split(separation) + component_neg = neg_pin_name[pattern.index("component")] + + net_neg = neg_pin_name[pattern.index("net")] + + if component_neg == component and net_neg != net and net_neg[:-1] == net[:-1]: + self.set_differential_pair( + positive_terminal=pin.name, + negative_terminal=neg_pin.name, + common_name="COMMON_{}_{}".format(component, net), + diff_name="{}_{}".format(component, net), + common_ref_z=25, + diff_ref_z=100, + active=True, + ) + diff_pairs.append("{}_{}".format(component, net)) + comm_pairs.append("COMMON_{}_{}".format(component, net)) + break + setup1 = self.create_setup() + setup1.props["SweepDefinition"]["Data"] = "LINC {}GHz {}GHz 1001".format(start_frequency, stop_frequency) + if analyze: + self.analyze() + return True, diff_pairs, comm_pairs + + @pyaedt_function_handler() + def create_ami_schematic_from_snp( + self, + touchstone, + ibis_ami, + component_name, + tx_buffer_name, + rx_buffer_name, + tx_pins, + tx_refs, + rx_pins, + rx_refs, + use_ibis_buffer=True, + differential=True, + bit_pattern=None, + unit_interval=None, + use_convolution=True, + analyze=False, + design_name="AMI", + ): + """Create a schematic from a Touchstone file and automatically set up an IBIS-AMI analysis. + + Parameters + ---------- + touchstone : str + Full path to the sNp file. + ibis_ami : str + Full path to the IBIS file. + component_name : str + Component name in the IBIS file to assign to components. + tx_buffer_name : str + Transmission buffer name. + rx_buffer_name : str + Receiver buffer name + tx_pins : list + Pins to assign the transmitter IBIS. + tx_refs : list + Reference pins to assign the transmitter IBIS. This parameter is only used in + a differential configuration. + rx_pins : list + Pins to assign the receiver IBIS. + rx_refs : list + Reference pins to assign the receiver IBIS. This parameter is only used + in a differential configuration. + use_ibis_buffer : bool, optional + Whether to use the IBIS buffer. The default is ``True``. If ``False``, pins are used. + differential : bool, optional + Whether the buffers are differential. The default is ``True``. If ``False``, + the buffers are single-ended. + bit_pattern : str, optional + IBIS bit pattern. + unit_interval : str, optional + Unit interval of the bit pattern. + use_convolution : bool, optional + Whether to use convolution for the Touchstone file. The default is + ``True``. If ``False``, state-space is used. + analyze : bool + Whether to automatically assign differential pairs. The default is ``False``. + design_name : str, optional + New schematic name. The default is ``"LNA"``. + + + Returns + ------- + (bool, list, list) + First argument is ``True`` if successful. + Second and third arguments are respectively the names of the tx and rx mode probes. + """ + if design_name in self.design_list: + self.logger.warning("Design already exists. renaming.") + design_name = generate_unique_name(design_name) + self.insert_design(design_name) + if isinstance(touchstone, type(Hfss3dLayout)): + touchstone_path = touchstone.export_touchstone() + else: + touchstone_path = touchstone + + sub = self.modeler.components.create_touchstone_component(touchstone_path) + center_x = sub.location[0] + center_y = sub.location[1] + left = 0 + delta_y = -1 * sub.location[1] - 2000 - 50 * len(tx_pins) + ibis = self.get_ibis_model_from_file(ibis_ami, is_ami=True) + tx_eye_names = [] + rx_eye_names = [] + for j in range(len(tx_pins)): + pos_x = unit_converter(2000, input_units="mil", output_units=self.modeler.schematic_units) + pos_y = unit_converter(delta_y - left * 800, input_units="mil", output_units=self.modeler.schematic_units) + left += 1 + + p_pin1 = [i for i in sub.pins if i.name == tx_pins[j]][0] + p_pin2 = [i for i in sub.pins if i.name == rx_pins[j]][0] + if differential: + n_pin1 = [i for i in sub.pins if i.name == tx_refs[j]][0] + n_pin2 = [i for i in sub.pins if i.name == rx_refs[j]][0] + + if use_ibis_buffer: + buf = [k for k in ibis.components[component_name].buffer.keys() if k.startswith(tx_buffer_name + "_")] + if differential: + buf = [k for k in buf if k.endswith("diff")] + tx = ibis.components[component_name].buffer[buf[0]].insert(center_x - pos_x, center_y + pos_y) + buf = [k for k in ibis.components[component_name].buffer.keys() if k.startswith(rx_buffer_name + "_")] + if differential: + buf = [k for k in buf if k.endswith("diff")] + rx = ibis.components[component_name].buffer[buf[0]].insert(center_x + pos_x, center_y + pos_y, 180) + else: + buf = [k for k in ibis.components[component_name].pins.keys() if k.startswith(tx_buffer_name + "_")] + if differential: + buf = [k for k in buf if k.endswith("diff")] + tx = ibis.components[component_name].pins[buf[0]].insert(center_x - pos_x, center_y + pos_y) + buf = [k for k in ibis.components[component_name].pins.keys() if k.startswith(rx_buffer_name + "_")] + if differential: + buf = [k for k in buf if k.endswith("diff")] + rx = ibis.components[component_name].pins[buf[0]].insert(center_x + pos_x, center_y + pos_y, 180) + + tx_eye_names.append(tx.parameters["probe_name"]) + rx_eye_names.append(rx.parameters["source_name"]) + _, first, second = tx.pins[0].connect_to_component(p_pin1, page_port_angle=180) + self.modeler.move(first, [0, 100], "mil") + if second.pins[0].location[0] > center_x: + self.modeler.move(second, [1000, 0], "mil") + else: + self.modeler.move(second, [-1000, 0], "mil") + _, first, second = rx.pins[0].connect_to_component(p_pin2, page_port_angle=0) + self.modeler.move(first, [0, -100], "mil") + if second.pins[0].location[0] > center_x: + self.modeler.move(second, [1000, 0], "mil") + else: + self.modeler.move(second, [-1000, 0], "mil") + if differential: + _, first, second = tx.pins[1].connect_to_component(n_pin1, page_port_angle=180) + self.modeler.move(first, [0, -100], "mil") + if second.pins[0].location[0] > center_x: + self.modeler.move(second, [1000, 0], "mil") + else: + self.modeler.move(second, [-1000, 0], "mil") + _, first, second = rx.pins[1].connect_to_component(n_pin2, page_port_angle=0) + self.modeler.move(first, [0, 100], "mil") + if second.pins[0].location[0] > center_x: + self.modeler.move(second, [1000, 0], "mil") + else: + self.modeler.move(second, [-1000, 0], "mil") + if unit_interval: + tx.parameters["UIorBPSValue"] = unit_interval + if bit_pattern: + tx.parameters["BitPattern"] = "random_bit_count=2.5e3 random_seed=1" + + setup_ami = self.create_setup("AMI", "NexximAMI") + if use_convolution: + self.oanalysis.AddAnalysisOptions( + [ + "NAME:DataBlock", + "DataBlockID:=", + 8, + "Name:=", + "Nexxim Options", + [ + "NAME:ModifiedOptions", + "ts_convolution:=", + True, + ], + ] + ) + setup_ami.props["OptionName"] = "Nexxim Options" + if analyze: + setup_ami.analyze() + return True, tx_eye_names, rx_eye_names diff --git a/pyaedt/common_rpc.py b/pyaedt/common_rpc.py index 59d9c9483cf..b53a519c420 100644 --- a/pyaedt/common_rpc.py +++ b/pyaedt/common_rpc.py @@ -119,9 +119,11 @@ def pyaedt_service_manager(port=17878, aedt_version=None, student_version=False): - """Starts an RPyC server on CPython and listens on a specified port. + """Starts the PyAEDT service manager using RPyC server on CPython. - This method must run on a server machine. + This method, which must run on a server machine, is used as a service on the + server machine to listen on a dedicated port for inbound requests to launch + a new server connection and launch AEDT. Parameters ---------- @@ -252,7 +254,7 @@ def launch_server(port=18000, ansysem_path=None, non_graphical=False, threaded=T def create_session(server_name, client_port=None, launch_aedt_on_server=False, aedt_port=None, non_graphical=True): """ - Connect to an existing AEDT server session. + Connect to an existing AEDT server session and create a new client session from it. Parameters ---------- @@ -266,9 +268,10 @@ def create_session(server_name, client_port=None, launch_aedt_on_server=False, a Aedt Grpc port on server. non_graphical : bool, optional Aedt Non Graphical Flag. + Returns ------- - RPyC object. + RPyC client object. """ try: client = rpyc.connect( @@ -314,7 +317,7 @@ def connect(server_name, aedt_client_port): Returns ------- - RPyC object. + RPyC client object. """ try: client = rpyc.connect( diff --git a/pyaedt/desktop.py b/pyaedt/desktop.py index dc086fbdb90..112d8cfe65e 100644 --- a/pyaedt/desktop.py +++ b/pyaedt/desktop.py @@ -40,6 +40,7 @@ from pyaedt import __version__ from pyaedt import pyaedt_function_handler from pyaedt.generic.desktop_sessions import _desktop_sessions +from pyaedt.generic.desktop_sessions import _edb_sessions from pyaedt.generic.general_methods import active_sessions from pyaedt.generic.general_methods import com_active_sessions from pyaedt.generic.general_methods import get_string_version @@ -470,6 +471,7 @@ def __new__(cls, *args, **kwargs): pyaedt_logger.info("Initializing new Desktop session.") return object.__new__(cls) + @pyaedt_function_handler() def __init__( self, specified_version=None, @@ -935,13 +937,24 @@ def _initialize( last_session = list(_desktop_sessions.values())[-1] all_desktop = [i for i in last_session.odesktop.GetRunningInstancesMgr().GetAllRunningInstances()] for desktop in all_desktop: - if port and desktop.GetGrpcServerPort() == port: - self.isoutsideDesktop = True - self.odesktop = desktop - self.aedt_process_id = self.odesktop.GetProcessID() - self.is_grpc_api = True - last_session.parent_desktop_id.append(self.aedt_process_id) - return True + try: + if port and desktop.GetGrpcServerPort() == port: + self.isoutsideDesktop = True + self.odesktop = desktop + self.aedt_process_id = self.odesktop.GetProcessID() + self.is_grpc_api = True + last_session.parent_desktop_id.append(self.aedt_process_id) + return True + except: + messages = desktop.GetMessages("", "", 0) + for message in messages: + if " GRPC server running on port: " in message and str(port) in message: + self.isoutsideDesktop = True + self.odesktop = desktop + self.aedt_process_id = self.odesktop.GetProcessID() + self.is_grpc_api = True + last_session.parent_desktop_id.append(self.aedt_process_id) + return True if new_session: self.launched_by_pyaedt = new_session oapp = python_grpc_wrapper.CreateAedtApplication(machine, port, non_graphical, new_session) @@ -1460,6 +1473,13 @@ def release_desktop(self, close_projects=True, close_on_exit=True): if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma: no cover close_projects = True close_on_exit = True + + for edb_object in _edb_sessions: + try: + edb_object.close() + except Exception: + self.logger.warning("Failed to close Edb object.") + if close_projects: projects = self.odesktop.GetProjectList() for project in projects: @@ -1471,7 +1491,10 @@ def release_desktop(self, close_projects=True, close_on_exit=True): if not result: self.logger.error("Error releasing desktop.") return False - self.logger.info("Desktop has been released") + if close_on_exit: + self.logger.info("Desktop has been released and closed.") + else: + self.logger.info("Desktop has been released.") del _desktop_sessions[self.aedt_process_id] props = [a for a in dir(self) if not a.startswith("__")] for a in props: @@ -1632,7 +1655,7 @@ def change_registry_from_file(self, registry_file, make_active=True): try: self.odesktop.SetRegistryFromFile(registry_file) if make_active: - with open(registry_file, "r") as f: + with open_file(registry_file, "r") as f: for line in f: stripped_line = line.strip() if "ConfigName" in stripped_line: @@ -1780,8 +1803,8 @@ def add_script_to_menu( dst = os.path.join(tool_dir, file_name.replace("_", " ") + ".py") if not os.path.isfile(src): raise FileNotFoundError("File not found: {}".format(src)) - with open(src, "r") as build_file: - with open(dst, "w") as out_file: + with open_file(src, "r") as build_file: + with open_file(dst, "w") as out_file: self.logger.info("Building to " + dst) build_file_data = build_file.read() build_file_data = ( @@ -2084,10 +2107,10 @@ def get_ansyscloud_job_info(self, job_id=None, job_name=None): # pragma: no cov elif job_id: command = [command, "jobinfo", "-i", job_id] cloud_info = os.path.join(tempfile.gettempdir(), generate_unique_name("job_info")) - with open(cloud_info, "w") as outfile: + with open_file(cloud_info, "w") as outfile: subprocess.Popen(" ".join(command), stdout=outfile).wait() out = {} - with open(cloud_info, "r") as infile: + with open_file(cloud_info, "r") as infile: lines = infile.readlines() for i in lines: if ":" in i.strip(): @@ -2190,11 +2213,11 @@ def get_available_cloud_config(self, region="westeurope"): # pragma: no cover ver = self.aedt_version_id.replace(".", "R") command = [command, "getQueues", "-p", "AEDT", "-v", ver, "--details"] cloud_info = os.path.join(tempfile.gettempdir(), generate_unique_name("cloud_info")) - with open(cloud_info, "w") as outfile: + with open_file(cloud_info, "w") as outfile: subprocess.Popen(" ".join(command), stdout=outfile).wait() dict_out = {} - with open(cloud_info, "r") as infile: + with open_file(cloud_info, "r") as infile: lines = infile.readlines() for i in range(len(lines)): line = lines[i].strip() diff --git a/pyaedt/downloads.py b/pyaedt/downloads.py index 1e6110f245f..2efd3cfc20e 100644 --- a/pyaedt/downloads.py +++ b/pyaedt/downloads.py @@ -7,6 +7,7 @@ from pyaedt.generic.general_methods import is_ironpython from pyaedt.generic.general_methods import is_linux +from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.generic.general_methods import settings from pyaedt.misc import list_installed_ansysem @@ -25,14 +26,16 @@ def delete_downloads(): shutil.rmtree(EXAMPLES_PATH, ignore_errors=True) -def _get_file_url(directory, filename=None): - if not filename: +@pyaedt_function_handler(filename="name") +def _get_file_url(directory, name=None): + if not name: return EXAMPLE_REPO + "/".join([directory]) else: - return EXAMPLE_REPO + "/".join([directory, filename]) + return EXAMPLE_REPO + "/".join([directory, name]) -def _retrieve_file(url, filename, directory, destination=None, local_paths=None): +@pyaedt_function_handler(filename="name") +def _retrieve_file(url, name, directory, destination=None, local_paths=None): """Download a file from a URL.""" if local_paths is None: @@ -41,7 +44,7 @@ def _retrieve_file(url, filename, directory, destination=None, local_paths=None) # First check if file has already been downloaded if not destination: destination = EXAMPLES_PATH - local_path = os.path.join(destination, directory, os.path.basename(filename)) + local_path = os.path.join(destination, directory, os.path.basename(name)) local_path_no_zip = local_path.replace(".zip", "") if os.path.isfile(local_path_no_zip) or os.path.isdir(local_path_no_zip): local_paths.append(local_path_no_zip) @@ -106,6 +109,8 @@ def _retrieve_folder(url, directory, destination=None, local_paths=None): local_path = os.path.join(destination, directory[7:]) else: local_path = os.path.join(destination, directory) + # Ensure that "/" is parsed as a path delimiter. + local_path = os.path.join(*local_path.split("/")) if is_ironpython: return False @@ -117,7 +122,7 @@ def _retrieve_folder(url, directory, destination=None, local_paths=None): try: os.mkdir(local_path) except FileNotFoundError: - os.makedirs(local_path) + os.makedirs(local_path) # Create directory recursively if the path doesn't exist. try: tree = [i for i in data if '"payload"' in i][0] @@ -134,20 +139,21 @@ def _retrieve_folder(url, directory, destination=None, local_paths=None): return False -def _download_file(directory, filename=None, destination=None, local_paths=None): +@pyaedt_function_handler(filename="name") +def _download_file(directory, name=None, destination=None, local_paths=None): if local_paths is None: local_paths = [] - if not filename: + if not name: if not directory.startswith("pyaedt/"): directory = "pyaedt/" + directory _retrieve_folder(EXAMPLE_REPO, directory, destination, local_paths) else: if directory.startswith("pyaedt/"): - url = _get_file_url(directory, filename) + url = _get_file_url(directory, name) directory = directory[7:] else: - url = _get_file_url("pyaedt/" + directory, filename) - _retrieve_file(url, filename, directory, destination, local_paths) + url = _get_file_url("pyaedt/" + directory, name) + _retrieve_file(url, name, directory, destination, local_paths) if settings.remote_rpc_session: remote_path = os.path.join(settings.remote_rpc_session_temp_folder, os.path.split(local_paths[-1])[-1]) if not settings.remote_rpc_session.filemanager.pathexists(settings.remote_rpc_session_temp_folder): @@ -728,25 +734,31 @@ def download_twin_builder_data(file_name, force_download=False, destination=None return os.path.join(destination, "twin_builder") -def download_file(directory, filename=None, destination=None): +@pyaedt_function_handler(filename="name") +def download_file(directory, name=None, destination=None): """ - Download file from directory. + Download a file or files from the online examples repository. - Files are downloaded to a destination. If filename is not specified, the full directory will be downloaded. + Files are downloaded from the + :ref:`example-data`_ repository + to a local destination. If ``name`` is not specified, the full directory path + will be copied to the local drive. Parameters ---------- directory : str - Directory name. - filename : str, optional - File name to download. The default is all files inside directory. + Directory name in the Ansys ``example-data`` repository. If the ``pyaed/`` prefix + is not part of ``directory`` it will be prepended. + name : str, optional + File name to download. By default all files in ``directory`` + will be downloaded. destination : str, optional - Path where files will be downloaded. Default is user temp folder. + Path where the files will be saved locally. Default is the user temp folder. Returns ------- str - Path to the example file. + Path to the local example file or folder. Examples -------- @@ -758,8 +770,8 @@ def download_file(directory, filename=None, destination=None): 'C:/Users/user/AppData/local/temp/PyAEDTExamples/motorcad' """ local_paths = [] - _download_file(directory, filename, destination, local_paths) - if filename: + _download_file(directory, name, destination, local_paths) + if name: return list(set(local_paths))[0] else: if not destination: diff --git a/pyaedt/emit.py b/pyaedt/emit.py index b5c5d552857..70b37b3fa13 100644 --- a/pyaedt/emit.py +++ b/pyaedt/emit.py @@ -30,10 +30,6 @@ class Emit(Design, object): solution_type : str, optional Solution type to apply to the design. The default is ``None``, in which case the default type is applied. - setup_name : str, optional - Name of the setup to use as the nominal. The default is - ``None``, in which case the active setup is used or - nothing is used. specified_version : str, int, float, optional Version of AEDT to use. The default is ``None``, in which case the active setup is used or the latest installed version is @@ -85,16 +81,16 @@ class Emit(Design, object): Once the schematic is generated, the ``Emit`` object can be analyzed to generate a revision. Each revision is added as an element of the ``Emit`` object member's - revisions_list. + ``Results.revisions`` list. - >>> aedtapp.analyze() + >>> revision = aedtapp.results.analyze() A revision within PyAEDT is analogous to a revision in AEDT. An interaction domain must be defined and then used as the input to the run command used on that revision. - >>> domain = aedtapp.interaction_domain() + >>> domain = aedtapp.results.interaction_domain() >>> domain.rx_radio_name = "UE - HandHeld" - >>> interaction = aedtapp.revisions_list[0].run(domain) + >>> interaction = revision.run(domain) The output of the run command is an ``interaction`` object. This object summarizes the interaction data that is defined in the interaction domain. @@ -109,7 +105,6 @@ def __init__( projectname=None, designname=None, solution_type=None, - setup_name=None, specified_version=None, non_graphical=False, new_desktop_session=True, @@ -215,7 +210,7 @@ def version(self, detailed=False): @pyaedt_function_handler() def set_units(self, unit_type, unit_value): - """Set units for the component. + """Set units for the EMIT design. Parameters ---------- @@ -277,7 +272,7 @@ def set_units(self, unit_type, unit_value): @pyaedt_function_handler() def get_units(self, unit_type=""): - """Get units for the component. + """Get units for the EMIT design. Parameters ---------- diff --git a/pyaedt/emit_core/results/revision.py b/pyaedt/emit_core/results/revision.py index 309de2105f6..5df33cbca7a 100644 --- a/pyaedt/emit_core/results/revision.py +++ b/pyaedt/emit_core/results/revision.py @@ -437,7 +437,6 @@ def interference_type_classification(self, domain, use_filter=False, filter_list # Get project results and radios modeRx = TxRxMode.RX modeTx = TxRxMode.TX - mode_power = ResultType.POWER_AT_RX tx_interferer = InterfererType().TRANSMITTERS rx_radios = self.get_receiver_names() tx_radios = self.get_interferer_names(tx_interferer) @@ -497,9 +496,7 @@ def interference_type_classification(self, domain, use_filter=False, filter_list # should just be skipped continue else: - tx_prob = ( - instance.get_largest_problem_type(ResultType.EMI).replace(" ", "").split(":")[1] - ) + tx_prob = instance.get_largest_emi_problem_type().replace(" ", "").split(":")[1] power = instance.get_value(ResultType.EMI) if ( rx_start_freq - rx_channel_bandwidth / 2 @@ -521,7 +518,7 @@ def interference_type_classification(self, domain, use_filter=False, filter_list if power > max_power and in_filters: max_power = power largest_rx_prob = rx_prob - prob = instance.get_largest_problem_type(ResultType.EMI) + prob = instance.get_largest_emi_problem_type() largest_tx_prob = prob.replace(" ", "").split(":") if max_power > -200: diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index 52410bcacb5..37a1cecb4d4 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -117,7 +117,7 @@ def _dict2arg(d, arg_out): arg_out.append(arg) elif v is None: arg_out.append(["NAME:" + k]) - elif type(v) is list and len(v) > 0 and isinstance(v[0], (OrderedDict, dict)): + elif isinstance(v, list) and len(v) > 0 and isinstance(v[0], (OrderedDict, dict)): for el in v: arg = ["NAME:" + k] _dict2arg(el, arg) @@ -317,7 +317,7 @@ def unique_string_list(element_list, only_string=True): raise Exception(error_message) if only_string: - non_string_entries = [x for x in element_list if type(x) is not str] + non_string_entries = [x for x in element_list if not isinstance(x, str)] assert not non_string_entries, "Invalid list entries {} are not a string!".format(non_string_entries) return element_list @@ -532,14 +532,14 @@ def str_to_bool(s): - Otherwise, the input value is passed through the method unchanged. """ - if type(s) == str: + if isinstance(s, str): if s.lower() in ["true", "yes", "y", "1"]: return True elif s.lower() in ["false", "no", "n", "0"]: return False else: return s - elif type(s) == int: + elif isinstance(s, int): return False if s == 0 else True diff --git a/pyaedt/generic/LoadAEDTFile.py b/pyaedt/generic/LoadAEDTFile.py index c9cbc828e24..b679456cb04 100644 --- a/pyaedt/generic/LoadAEDTFile.py +++ b/pyaedt/generic/LoadAEDTFile.py @@ -417,7 +417,7 @@ def _walk_through_structure(keyword, save_dict, design_name=None): # recompose value if list if saved_value: # makes the value a list, if it's not already - if type(saved_value) is not list: + if not isinstance(saved_value, list): saved_value = [saved_value] saved_value.append(save_dict[keyword]) save_dict[keyword] = saved_value diff --git a/pyaedt/generic/com_parameters.py b/pyaedt/generic/com_parameters.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/pyaedt/generic/compliance.py b/pyaedt/generic/compliance.py index ad22ce2e9ce..091488d7a3c 100644 --- a/pyaedt/generic/compliance.py +++ b/pyaedt/generic/compliance.py @@ -453,7 +453,7 @@ def _create_aedt_reports(self, pdf_report): sw_name = self._get_sweep_name(_design, local_config.get("solution_name", None)) _design.logger.info(f"Creating report {name}") aedt_report = _design.post.create_report_from_configuration( - input_dict=local_config, solution_name=sw_name + report_settings=local_config, solution_name=sw_name ) if not aedt_report: # pragma: no cover _design.logger.error(f"Failed to create report {name}") @@ -504,7 +504,7 @@ def _create_aedt_reports(self, pdf_report): sw_name = self._get_sweep_name(_design, local_config.get("solution_name", None)) _design.logger.info(f"Creating report {name} for trace {trace}") aedt_report = _design.post.create_report_from_configuration( - input_dict=local_config, solution_name=sw_name + report_settings=local_config, solution_name=sw_name ) if report_type != "contour eye diagram": aedt_report.hide_legend() @@ -559,7 +559,7 @@ def _create_aedt_reports(self, pdf_report): write_csv(os.path.join(self._output_folder, f"{name}{trace}_pass_fail.csv"), table) if report_type in ["eye diagram", "statistical eye"]: - _design.logger.info(f"Adding eye measurements") + _design.logger.info("Adding eye measurements.") table = self._add_eye_measurement(aedt_report, pdf_report, image_name) write_csv(os.path.join(self._output_folder, f"{name}{trace}_eye_meas.csv"), table) if self.local_config.get("delete_after_export", True): @@ -602,7 +602,7 @@ def _create_parameters(self, pdf_report): spisim.touchstone_file = _design.export_touchstone() if not isinstance(trace_pin[0], int): try: - ports = list(_design.excitations.keys()) + ports = list(_design.excitations) thrus4p = [ports.index(i) for i in trace_pin] trace_pin = thrus4p except IndexError: @@ -691,6 +691,7 @@ def _add_statistical_violations(self, report, pdf_report, image_name, local_conf self._desktop_class.logger.error(msg) return mag_data = {i: k for i, k in sols.full_matrix_real_imag[0][sols.expressions[0]].items() if k > 0} + # mag_data is a dictionary. The key isa tuple (__AMPLITUDE, __UI), and the value is the eye value. mystr = "Eye Mask Violation:" result_value = "PASS" points_to_check = [i[::-1] for i in local_config["eye_mask"]["points"]] @@ -711,13 +712,14 @@ def _add_statistical_violations(self, report, pdf_report, image_name, local_conf if result_value == "FAIL": result_value = f"FAIL on {num_failed} points." pass_fail_table.append([mystr, result_value]) - + result_value = "PASS" if local_config["eye_mask"]["enable_limits"]: mystr = "Upper/Lower Mask Violation:" for point in mag_data: + # checking if amplitude is overcoming limits. if ( - point[1] > local_config["eye_mask"]["upper_limit"] - or point[1] < local_config["eye_mask"]["lower_limit"] + point[0] > local_config["eye_mask"]["upper_limit"] + or point[0] < local_config["eye_mask"]["lower_limit"] ): result_value = "FAIL" break diff --git a/pyaedt/generic/configurations.py b/pyaedt/generic/configurations.py index ad1dcaf5a03..c5a1a0cdbfa 100644 --- a/pyaedt/generic/configurations.py +++ b/pyaedt/generic/configurations.py @@ -16,6 +16,7 @@ from pyaedt.generic.LoadAEDTFile import load_keyword_in_aedt_file from pyaedt.generic.general_methods import GrpcApiError from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.generic.general_methods import read_configuration_file from pyaedt.generic.general_methods import write_configuration_file @@ -906,7 +907,7 @@ def _update_boundaries(self, name, props): bound.props["Modes"] = BoundaryProps(bound, modes) bound.auto_update = True if bound.create(): - self._app.boundaries.append(bound) + self._app._boundaries[bound.name] = bound if props["BoundType"] in ["Coil Terminal", "Coil", "CoilTerminal"]: winding_name = "" for b in self._app.boundaries: @@ -950,7 +951,7 @@ def _update_setup(self, name, props): if self._app.design_type == "Q3D Extractor": setup = self._app.create_setup(name, props=props) else: - setup = self._app.create_setup(name, setuptype=props["SetupType"], props=props) + setup = self._app.create_setup(name, setup_type=props["SetupType"], props=props) if setup: self._app.logger.info("Setup {} added.".format(name)) return True @@ -1232,7 +1233,7 @@ def _export_general(self, dict_out): if list(self._app.output_variables): oo_out = os.path.join(tempfile.gettempdir(), generate_unique_name("oo") + ".txt") self._app.ooutput_variable.ExportOutputVariables(oo_out) - with open(oo_out, "r") as f: + with open_file(oo_out, "r") as f: lines = f.readlines() for line in lines: line_split = line.split(" ") diff --git a/pyaedt/generic/design_types.py b/pyaedt/generic/design_types.py index 30bca970151..8ed99e2f2a8 100644 --- a/pyaedt/generic/design_types.py +++ b/pyaedt/generic/design_types.py @@ -402,7 +402,6 @@ def Emit( projectname=None, designname=None, solution_type=None, - setup_name=None, specified_version=None, non_graphical=False, new_desktop_session=False, @@ -428,10 +427,6 @@ def Emit( solution_type : str, optional Solution type to apply to the design. The default is ``None``, in which case the default type is applied. - setup_name : str, optional - Name of the setup to use as the nominal. The default is - ``None``, in which case the active setup is used or - nothing is used. specified_version : str, int, float, optional Version of AEDT to use. The default is ``None``, in which case the active setup is used or the latest installed version is @@ -511,7 +506,6 @@ def Emit( projectname=projectname, designname=designname, solution_type=solution_type, - setup_name=setup_name, specified_version=specified_version, non_graphical=non_graphical, new_desktop_session=new_desktop_session, @@ -1770,8 +1764,10 @@ def get_pyaedt_app(project_name=None, design_name=None, desktop=None): from pyaedt.generic.desktop_sessions import _desktop_sessions odesktop = None + process_id = None if desktop: odesktop = desktop.odesktop + process_id = desktop.aedt_process_id elif _desktop_sessions and project_name: for desktop in list(_desktop_sessions.values()): if project_name in list(desktop.project_list()): @@ -1783,6 +1779,8 @@ def get_pyaedt_app(project_name=None, design_name=None, desktop=None): odesktop = sys.modules["__main__"].oDesktop # ironpython else: raise AttributeError("No Desktop Present.") + if not process_id: + process_id = odesktop.GetProcessID() if project_name and project_name not in odesktop.GetProjectList(): raise AttributeError("Project {} doesn't exist in current desktop.".format(project_name)) if not project_name: @@ -1808,5 +1806,5 @@ def get_pyaedt_app(project_name=None, design_name=None, desktop=None): if design_type in list(app_map.keys()): version = odesktop.GetVersion().split(".") v = ".".join([version[0], version[1]]) - return app_map[design_type](project_name, design_name, specified_version=v) + return app_map[design_type](project_name, design_name, specified_version=v, aedt_process_id=process_id) return None diff --git a/pyaedt/generic/desktop_sessions.py b/pyaedt/generic/desktop_sessions.py index 4b8bcb2e23f..87032cbae18 100644 --- a/pyaedt/generic/desktop_sessions.py +++ b/pyaedt/generic/desktop_sessions.py @@ -2,3 +2,5 @@ # When AEDT will support multiple desktops, it will be filled with additional properties and methods _desktop_sessions = {} + +_edb_sessions = [] diff --git a/pyaedt/generic/general_methods.py b/pyaedt/generic/general_methods.py index 0d36228f1f5..a286641a2f7 100644 --- a/pyaedt/generic/general_methods.py +++ b/pyaedt/generic/general_methods.py @@ -198,41 +198,67 @@ def _check_types(arg): return "" -def _function_handler_wrapper(user_function): +def raise_exception(e): + if not settings.enable_error_handler: + if settings.release_on_exception: + from pyaedt.generic.desktop_sessions import _desktop_sessions + + for v in list(_desktop_sessions.values())[:]: + v.release_desktop(v.launched_by_pyaedt, v.launched_by_pyaedt) + raise e + else: + return False + + +def _function_handler_wrapper(user_function, **deprecated_kwargs): + def wrapper(*args, **kwargs): - if not settings.enable_error_handler: - result = user_function(*args, **kwargs) - return result - else: - try: - settings.time_tick = time.time() - out = user_function(*args, **kwargs) - if settings.enable_debug_logger or settings.enable_debug_edb_logger: - _log_method(user_function, args, kwargs) - return out - except MethodNotSupportedError: - message = "This method is not supported in current AEDT design type." - if settings.enable_screen_logs: - pyaedt_logger.error("**************************************************************") - pyaedt_logger.error( - "PyAEDT error on method {}: {}. Check again".format(user_function.__name__, message) - ) - pyaedt_logger.error("**************************************************************") - pyaedt_logger.error("") - if settings.enable_file_logs: - settings.error(message) - return False - except GrpcApiError: - _exception(sys.exc_info(), user_function, args, kwargs, "AEDT grpc API call Error") - return False - except BaseException: - _exception(sys.exc_info(), user_function, args, kwargs, str(sys.exc_info()[1]).capitalize()) - return False + + if deprecated_kwargs and kwargs: + deprecate_kwargs(user_function.__name__, kwargs, deprecated_kwargs) + try: + settings.time_tick = time.time() + out = user_function(*args, **kwargs) + if settings.enable_debug_logger or settings.enable_debug_edb_logger: + _log_method(user_function, args, kwargs) + return out + except MethodNotSupportedError as e: + message = "This method is not supported in current AEDT design type." + if settings.enable_screen_logs: + pyaedt_logger.error("**************************************************************") + pyaedt_logger.error( + "PyAEDT error on method {}: {}. Check again".format(user_function.__name__, message) + ) + pyaedt_logger.error("**************************************************************") + pyaedt_logger.error("") + if settings.enable_file_logs: + settings.error(message) + raise_exception(e) + except GrpcApiError as e: + _exception(sys.exc_info(), user_function, args, kwargs, "AEDT grpc API call Error") + raise_exception(e) + except BaseException as e: + _exception(sys.exc_info(), user_function, args, kwargs, str(sys.exc_info()[1]).capitalize()) + raise_exception(e) return wrapper -def pyaedt_function_handler(direct_func=None): +def deprecate_kwargs(func_name, kwargs, aliases): + """Use helper function for deprecating function arguments.""" + for alias, new in aliases.items(): + if alias in kwargs: + if new in kwargs: + msg = "{} received both {} and {} as arguments!\n".format(func_name, alias, new) + msg += "{} is deprecated, use {} instead.".format(alias, new) + raise TypeError(msg) + pyaedt_logger.warning( + '`{}` is deprecated as an argument to `{}`; use" f" `{}` instead.'.format(alias, func_name, new) + ) + kwargs[new] = kwargs.pop(alias) + + +def pyaedt_function_handler(direct_func=None, **deprecated_kwargs): """Provides an exception handler, logging mechanism, and argument converter for client-server communications. @@ -242,13 +268,13 @@ def pyaedt_function_handler(direct_func=None): """ if callable(direct_func): user_function = direct_func - wrapper = _function_handler_wrapper(user_function) + wrapper = _function_handler_wrapper(user_function, **deprecated_kwargs) return update_wrapper(wrapper, user_function) elif direct_func is not None: raise TypeError("Expected first argument to be a callable, or None") def decorating_function(user_function): - wrapper = _function_handler_wrapper(user_function) + wrapper = _function_handler_wrapper(user_function, **deprecated_kwargs) return update_wrapper(wrapper, user_function) return decorating_function @@ -258,7 +284,7 @@ def decorating_function(user_function): def check_numeric_equivalence(a, b, relative_tolerance=1e-7): """Check if two numeric values are equivalent to within a relative tolerance. - Paraemters + Parameters ---------- a : int, float Reference value to compare to. @@ -281,17 +307,20 @@ def check_numeric_equivalence(a, b, relative_tolerance=1e-7): @pyaedt_function_handler() -def check_and_download_file(local_path, remote_path, overwrite=True): +def _check_path(path_to_check): + return path_to_check.replace("\\", "/") if path_to_check[0] != "\\" else path_to_check + + +@pyaedt_function_handler() +def check_and_download_file(remote_path, overwrite=True): """Check if a file is remote and either download it or return the path. Parameters ---------- - local_path : str - Local path to save the file to. remote_path : str Path to the remote file. overwrite : bool, optional - Whether to overwrite the file if it already exits locally. + Whether to overwrite the file if it already exists locally. The default is ``True``. Returns @@ -299,9 +328,11 @@ def check_and_download_file(local_path, remote_path, overwrite=True): str """ if settings.remote_rpc_session: - remote_path = remote_path.replace("\\", "/") if remote_path[0] != "\\" else remote_path - settings.remote_rpc_session.filemanager.download_file(remote_path, local_path, overwrite=overwrite) - return local_path + remote_path = _check_path(remote_path) + local_path = os.path.join(settings.remote_rpc_session_temp_folder, os.path.split(remote_path)[-1]) + if settings.remote_rpc_session.filemanager.pathexists(remote_path): + settings.remote_rpc_session.filemanager.download_file(remote_path, local_path, overwrite=overwrite) + return local_path return remote_path @@ -333,7 +364,7 @@ def check_and_download_folder(local_path, remote_path, overwrite=True): remote_path : str Path to the remote folder. overwrite : bool, optional - Whether to overwrite the folder if it already exits locally. + Whether to overwrite the folder if it already exists locally. The default is ``True``. Returns @@ -347,7 +378,7 @@ def check_and_download_folder(local_path, remote_path, overwrite=True): return remote_path -def open_file(file_path, file_options="r"): +def open_file(file_path, file_options="r", encoding=None, override_existing=True): """Open a file and return the object. Parameters @@ -356,27 +387,44 @@ def open_file(file_path, file_options="r"): Full absolute path to the file (either local or remote). file_options : str, optional Options for opening the file. + encoding : str, optional + Name of the encoding used to decode or encode the file. + The default is ``None``, which means a platform-dependent encoding is used. You can + specify any encoding supported by Python. + override_existing : bool, optional + Whether to override an existing file if opening a file in write mode on a remote + machine. The default is ``True``. Returns ------- object Opened file. """ + if is_ironpython: + return open(file_path, file_options) + + file_path = str(file_path) file_path = file_path.replace("\\", "/") if file_path[0] != "\\" else file_path + dir_name = os.path.dirname(file_path) if "r" in file_options: if os.path.exists(file_path): - return open(file_path, file_options) + return open(file_path, file_options, encoding=encoding) elif settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists( file_path ): # pragma: no cover local_file = os.path.join(tempfile.gettempdir(), os.path.split(file_path)[-1]) settings.remote_rpc_session.filemanager.download_file(file_path, local_file) - return open(local_file, file_options) + return open(local_file, file_options, encoding=encoding) elif os.path.exists(dir_name): - return open(file_path, file_options) + return open(file_path, file_options, encoding=encoding) elif settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists(dir_name): - return settings.remote_rpc_session.open_file(file_path, file_options) + if "w" in file_options: + return settings.remote_rpc_session.create_file( + file_path, file_options, encoding=encoding, override=override_existing + ) + else: + return settings.remote_rpc_session.open_file(file_path, file_options, encoding=encoding) else: settings.logger.error("The file or folder %s does not exist", dir_name) @@ -421,7 +469,7 @@ def read_json(fn): dict """ json_data = {} - with open(fn) as json_file: + with open_file(fn) as json_file: try: json_data = json.load(json_file) except json.JSONDecodeError as e: # pragma: no cover @@ -820,7 +868,7 @@ def is_array(a): except (ValueError, TypeError, NameError, SyntaxError): return False else: - if type(v) is list: + if isinstance(v, list): return True else: return False @@ -839,6 +887,11 @@ def is_project_locked(project_path): bool ``True`` when successful, ``False`` when failed. """ + if settings.remote_rpc_session: + if settings.remote_rpc_session.filemanager.pathexists(project_path + ".lock"): + return True + else: + return False return check_if_path_exists(project_path + ".lock") @@ -859,6 +912,9 @@ def remove_project_lock(project_path): bool ``True`` when successful, ``False`` when failed. """ + if settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists(project_path + ".lock"): + settings.remote_rpc_session.filemanager.unlink(project_path + ".lock") + return True if os.path.exists(project_path + ".lock"): os.remove(project_path + ".lock") return True @@ -880,6 +936,7 @@ def read_csv(filename, encoding="utf-8"): list """ + filename = check_and_download_file(filename) lines = [] with codecs.open(filename, "rb", encoding) as csvfile: @@ -905,6 +962,7 @@ def read_csv_pandas(filename, encoding="utf-8"): :class:`pandas.DataFrame` """ + filename = check_and_download_file(filename) try: import pandas as pd @@ -947,6 +1005,7 @@ def read_xlsx(filename): list """ + filename = check_and_download_file(filename) try: import pandas as pd @@ -1111,17 +1170,17 @@ def _create_json_file(json_dict, full_json_path): if not os.path.exists(os.path.dirname(full_json_path)): os.makedirs(os.path.dirname(full_json_path)) if not is_ironpython: - with open(full_json_path, "w") as fp: + with open_file(full_json_path, "w") as fp: json.dump(json_dict, fp, indent=4) else: temp_path = full_json_path.replace(".json", "_temp.json") - with open(temp_path, "w") as fp: + with open_file(temp_path, "w") as fp: json.dump(json_dict, fp, indent=4) - with open(temp_path, "r") as file: + with open_file(temp_path, "r") as file: filedata = file.read() filedata = filedata.replace("True", "true") filedata = filedata.replace("False", "false") - with open(full_json_path, "w") as file: + with open_file(full_json_path, "w") as file: file.write(filedata) os.remove(temp_path) return True @@ -1609,7 +1668,7 @@ def tech_to_control_file(tech_path, unit="nm", control_path=None): Out xml file. """ result = [] - with open(tech_path) as f: + with open_file(tech_path) as f: vals = list(CSS4_COLORS.values()) id_layer = 0 for line in f: @@ -1630,7 +1689,7 @@ def tech_to_control_file(tech_path, unit="nm", control_path=None): unit = line_split[1] if not control_path: control_path = os.path.splitext(tech_path)[0] + ".xml" - with open(control_path, "w") as f: + with open_file(control_path, "w") as f: f.write('\n') f.write(' \n') f.write("\n") @@ -1937,7 +1996,7 @@ def _check_installed_version(install_path, long_version): product_list_path = os.path.join(install_path, "config", "ProductList.txt") if os.path.isfile(product_list_path): try: - with open(product_list_path, "r") as f: + with open_file(product_list_path, "r") as f: install_version = f.readline().strip()[-6:] if install_version == long_version: return True diff --git a/pyaedt/generic/ibis_reader.py b/pyaedt/generic/ibis_reader.py index 4a9b4a0f7ed..3ab2b6ed525 100644 --- a/pyaedt/generic/ibis_reader.py +++ b/pyaedt/generic/ibis_reader.py @@ -7,7 +7,7 @@ from pyaedt.aedt_logger import pyaedt_logger as logger from pyaedt.generic.general_methods import check_and_download_file from pyaedt.generic.general_methods import check_if_path_exists -from pyaedt.generic.settings import settings +from pyaedt.generic.general_methods import open_file class Component: @@ -799,11 +799,8 @@ def parse_ibis_file(self): ibis_name = pyaedt.generic.general_methods.get_filename_without_extension(self._filename) ibis = Ibis(ibis_name, self._circuit) - if settings.remote_rpc_session_temp_folder: - local_path = os.path.join(settings.remote_rpc_session_temp_folder, os.path.split(self._filename)[-1]) - file_to_open = check_and_download_file(local_path, self._filename) - else: - file_to_open = self._filename + + check_and_download_file(self._filename) # Read *.ibis file. ibis_info = ibis_parsing(self._filename) @@ -899,13 +896,10 @@ def read_model(self, ibis, model_list): elif is_started_with(model_spec.lower(), "enable ", True): model.enable = model_spec.split()[-1].strip() - model_info_lower = {key.lower(): value for key, value in model_info.items()} - if "gnd clamp" in [key.lower() for key in model_info.keys()]: model.clamp = True if "algorithmic model" in [key.lower() for key in model_info.keys()]: matching_key = next((key for key in model_info.keys() if "algorithmic model" in key.lower()), None) - ami_info = model_info[matching_key][matching_key].split() model.ami = model_info[matching_key][matching_key].split() ibis.AMI = True else: @@ -1222,11 +1216,7 @@ def parse_ibis_file(self): ami_name = pyaedt.generic.general_methods.get_filename_without_extension(self._filename) ibis = AMI(ami_name, self._circuit) - if settings.remote_rpc_session_temp_folder: - local_path = os.path.join(settings.remote_rpc_session_temp_folder, os.path.split(self._filename)[-1]) - file_to_open = check_and_download_file(local_path, self._filename) - else: - file_to_open = self._filename + check_and_download_file(self._filename) # Read *.ibis file. ibis_info = ibis_parsing(self._filename) @@ -1342,10 +1332,10 @@ def ibis_parsing(file): """ ibis = {} # OPEN AND READ IBIS FILE - with open(file, "r") as fp: + with open_file(file, "r") as fp: ibis_data = list(enumerate(fp)) - with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ibis_v7.json"), "r") as f: + with open_file(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ibis_v7.json"), "r") as f: ibis_ref = json.load(f) ibis_ref = lowercase_json(ibis_ref) diff --git a/pyaedt/generic/pdf.py b/pyaedt/generic/pdf.py index 9c067177a3b..0120e0a43a2 100644 --- a/pyaedt/generic/pdf.py +++ b/pyaedt/generic/pdf.py @@ -8,6 +8,7 @@ from pyaedt import __version__ from pyaedt.generic.constants import unit_converter +from pyaedt.generic.general_methods import open_file @dataclass @@ -77,7 +78,7 @@ def read_template(self, template_file): if template_file: self.report_specs.template_name = template_file if os.path.exists(self.report_specs.template_name): - with open(self.report_specs.template_name, "r") as f: + with open_file(self.report_specs.template_name, "r") as f: tdata = json.load(f) self.report_specs = ReportSpec(**tdata) @@ -258,10 +259,9 @@ def add_project_info(self, design): msg = f"Furthermore, the layout has {stats.num_nets} nets, {stats.num_traces} traces," msg += f" {stats.num_vias} vias. The stackup total thickness is {stats.stackup_thickness}." image_path = os.path.join(design.working_directory, "model.jpg") - design.modeler.edb.nets.plot( - save_plot=image_path, - ) - self.add_image(image_path, "Model Image") + design.modeler.edb.nets.plot(save_plot=image_path) + if os.path.exists(image_path): + self.add_image(image_path, "Model Image") elif design.design_type in ["Circuit Design"]: msg = f"The schematic has {len(design.modeler.components.components)} components." self.add_text(msg) @@ -574,7 +574,7 @@ def p(section, **kwargs): for section in self._outline: link = self.add_link() self.set_link(link, page=section.page_number) - string1 = f'{" " * section.level * 2} {section.name}' + string1 = f'{" " * section.level * 2} {section.name}'[:70] string2 = f"Page {section.page_number}" self.set_x(self.l_margin * 2) self.cell( diff --git a/pyaedt/generic/plot.py b/pyaedt/generic/plot.py index 20556436c8d..ce95fcd9c6a 100644 --- a/pyaedt/generic/plot.py +++ b/pyaedt/generic/plot.py @@ -445,7 +445,7 @@ def plot_2d_chart(plot_data, size=(2000, 1000), show_legend=True, xlabel="", yla else: x = np.array([i for i, j in zip(plo_obj[0], plo_obj[1]) if j]) y = np.array([i for i in plo_obj[1] if i]) - ax.plot(x, y, label=label) + ax.plot(x, y) label_id += 1 ax.set(xlabel=xlabel, ylabel=ylabel, title=title) @@ -1516,14 +1516,19 @@ def __call__(self, state): ) @pyaedt_function_handler() - def plot(self, export_image_path=None): + def plot(self, export_image_path=None, show=True): """Plot the current available Data. With `s` key a screenshot is saved in export_image_path or in tempdir. Parameters ---------- - export_image_path : str - Path to image to save. + export_image_path : str, optional + Path to image to save. Default is None + show : bool, optional + Whether to display the pyvista plot. + When False, a :class::pyvista.Plotter object is created + and assigned to the pv property so that it can be + modified further. Default is True. Returns ------- @@ -1645,9 +1650,9 @@ def s_callback(): # pragma: no cover self.pv.add_key_event("s", s_callback) if export_image_path: self.pv.show(screenshot=export_image_path, full_screen=True) - elif self.is_notebook: # pragma: no cover + elif show and self.is_notebook: # pragma: no cover self.pv.show() # pragma: no cover - else: + elif show: self.pv.show(full_screen=True) # pragma: no cover self.image_file = export_image_path diff --git a/pyaedt/generic/settings.py b/pyaedt/generic/settings.py index e7bc5d02a93..5260b7bab88 100644 --- a/pyaedt/generic/settings.py +++ b/pyaedt/generic/settings.py @@ -24,6 +24,7 @@ def __init__(self): self._enable_debug_internal_methods_logger = False self._enable_debug_logger = False self._enable_error_handler = True + self._release_on_exception = True self._aedt_version = None self._aedt_install_dir = None self._use_multi_desktop = False @@ -72,6 +73,20 @@ def __init__(self): self.__lazy_load = True self.__objects_lazy_load = False + @property + def release_on_exception(self): + """ + + Returns + ------- + + """ + return self._release_on_exception + + @release_on_exception.setter + def release_on_exception(self, value): + self._release_on_exception = value + @property def objects_lazy_load(self): """Flag for enabling and disabling the lazy load. diff --git a/pyaedt/generic/spisim.py b/pyaedt/generic/spisim.py index 9509ec770e9..9593205a78f 100644 --- a/pyaedt/generic/spisim.py +++ b/pyaedt/generic/spisim.py @@ -15,6 +15,7 @@ from pyaedt import pyaedt_function_handler from pyaedt import settings from pyaedt.generic.general_methods import env_value +from pyaedt.generic.general_methods import open_file from pyaedt.misc import current_version from pyaedt.misc.spisim_com_configuration_files.com_parameters import COMParametersVer3p4 @@ -73,10 +74,10 @@ def _compute_spisim(self, parameter, out_file="", touchstone_file="", config_fil my_env.update(settings.aedt_environment_variables) if is_linux: # pragma: no cover command.append("&") - with open(out_processing, "w") as outfile: + with open_file(out_processing, "w") as outfile: subprocess.Popen(command, env=my_env, stdout=outfile, stderr=outfile).wait() # nosec else: - with open(out_processing, "w") as outfile: + with open_file(out_processing, "w") as outfile: subprocess.Popen(" ".join(command), env=my_env, stdout=outfile, stderr=outfile).wait() # nosec return out_processing @@ -84,7 +85,7 @@ def _compute_spisim(self, parameter, out_file="", touchstone_file="", config_fil def _get_output_parameter_from_result(self, out_file, parameter_name): if parameter_name == "ERL": try: - with open(out_file, "r") as infile: + with open_file(out_file, "r") as infile: lines = infile.read() parmDat = lines.split("[ParmDat]:", 1)[1] for keyValu in parmDat.split(","): @@ -100,7 +101,7 @@ def _get_output_parameter_from_result(self, out_file, parameter_name): return False elif parameter_name == "COM": try: - with open(out_file, "r") as infile: + with open_file(out_file, "r") as infile: txt = infile.read() i = 0 com_results = [] @@ -201,7 +202,7 @@ def compute_erl( "NCYCLES": 1000, } if config_file: - with open(config_file, "r") as fp: + with open_file(config_file, "r") as fp: lines = fp.readlines() for line in lines: if not line.startswith("#") and "=" in line: @@ -239,7 +240,7 @@ def compute_erl( cfg_dict["NCYCLES"] = reflections_length if reflections_length is not None else cfg_dict["NCYCLES"] new_cfg_file = os.path.join(self.working_directory, "spisim_erl.cfg").replace("\\", "/") - with open(new_cfg_file, "w") as fp: + with open_file(new_cfg_file, "w") as fp: for k, v in cfg_dict.items(): fp.write("# {}: {}\n".format(k, k)) fp.write("{} = {}\n".format(k, v)) @@ -371,7 +372,7 @@ def detect_encoding(file_path, expected_pattern="", re_flags=0): """Check encoding of a file.""" for encoding in ("utf-8", "utf_16_le", "cp1252", "cp1250", "shift_jis"): try: - with open(file_path, "r", encoding=encoding) as f: + with open_file(file_path, "r", encoding=encoding) as f: lines = f.read() f.seek(0) except UnicodeDecodeError: diff --git a/pyaedt/hfss.py b/pyaedt/hfss.py index a94d78c642a..da25281f5f5 100644 --- a/pyaedt/hfss.py +++ b/pyaedt/hfss.py @@ -10,6 +10,7 @@ import warnings from pyaedt.application.Analysis3D import FieldAnalysis3D +from pyaedt.application.analysis_hf import ScatteringMethods from pyaedt.generic.DataHandlers import _dict2arg from pyaedt.generic.DataHandlers import str_to_bool from pyaedt.generic.constants import INFINITE_SPHERE_TYPE @@ -30,7 +31,7 @@ from pyaedt.modules.SetupTemplates import SetupKeys -class Hfss(FieldAnalysis3D, object): +class Hfss(FieldAnalysis3D, ScatteringMethods): """Provides the HFSS application interface. This class allows you to create an interactive instance of HFSS and @@ -192,6 +193,7 @@ def __init__( port, aedt_process_id, ) + ScatteringMethods.__init__(self, self) self._field_setups = [] self.component_array = {} self.component_array_names = list(self.get_oo_name(self.odesign, "Model")) @@ -270,15 +272,15 @@ def composite(self): def composite(self, value): self.design_solutions.composite = value - @pyaedt_function_handler() - def set_auto_open(self, enable=True, boundary_type="Radiation"): + @pyaedt_function_handler(boundary_type="opening_type") + def set_auto_open(self, enable=True, opening_type="Radiation"): """Set the HFSS auto open type. Parameters ---------- enable : bool, optional Whether to enable the HFSS auto open option. The default is ``True``. - boundary_type : str, optional + opening_type : str, optional Boundary type to use with auto open. Options are ``"Radiation"``, ``"FEBI"``, and ``"PML"``. The default is ``"Radiation"``. @@ -291,11 +293,11 @@ def set_auto_open(self, enable=True, boundary_type="Radiation"): -------- Enable auto open type for the PML boundary. - >>> hfss.set_auto_open(True, "PML") + >>> hfss.set_auto_open(True,"PML") """ - if enable and boundary_type not in ["Radiation", "FEBI", "PML"]: + if enable and opening_type not in ["Radiation", "FEBI", "PML"]: raise AttributeError("Wrong boundary type. Check Documentation for valid inputs") - return self.design_solutions.set_auto_open(enable=enable, boundary_type=boundary_type) + return self.design_solutions.set_auto_open(enable=enable, opening_type=opening_type) @pyaedt_function_handler() def _get_unique_source_name(self, source_name, root_name): @@ -360,15 +362,16 @@ def _create_boundary(self, name, props, boundary_type): return result - @pyaedt_function_handler() - def _create_lumped_driven(self, objectname, int_line_start, int_line_stop, impedance, portname, renorm, deemb): + @pyaedt_function_handler(objectname="assignment", portname="port_name") + def _create_lumped_driven(self, assignment, int_line_start, int_line_stop, impedance, port_name, renorm, deemb): + assignment = self.modeler.convert_to_selections(assignment, True) start = [str(i) + self.modeler.model_units for i in int_line_start] stop = [str(i) + self.modeler.model_units for i in int_line_stop] props = OrderedDict({}) - if isinstance(objectname, str): - props["Objects"] = [objectname] + if isinstance(assignment[0], str): + props["Objects"] = assignment else: - props["Faces"] = [objectname] + props["Faces"] = assignment props["DoDeembed"] = deemb props["RenormalizeAllTerminals"] = renorm if renorm: @@ -403,14 +406,14 @@ def _create_lumped_driven(self, objectname, int_line_start, int_line_stop, imped props["ShowReporterFilter"] = False props["ReporterFilter"] = [True] props["Impedance"] = str(impedance) + "ohm" - return self._create_boundary(portname, props, "Lumped Port") + return self._create_boundary(port_name, props, "Lumped Port") - @pyaedt_function_handler() + @pyaedt_function_handler(objectname="assignment", portname="port_name") def _create_port_terminal( self, - objectname, + assignment, int_line_stop, - portname, + port_name, renorm=True, deembed=None, iswaveport=False, @@ -419,12 +422,12 @@ def _create_port_terminal( ): ref_conductors = self.modeler.convert_to_selections(int_line_stop, True) props = OrderedDict() - props["Faces"] = int(objectname) + props["Faces"] = int(assignment) props["IsWavePort"] = iswaveport props["ReferenceConductors"] = ref_conductors props["RenormalizeModes"] = True ports = list(self.oboundary.GetExcitationsOfType("Terminal")) - boundary = self._create_boundary(portname, props, "AutoIdentify") + boundary = self._create_boundary(port_name, props, "AutoIdentify") if boundary: new_ports = list(self.oboundary.GetExcitationsOfType("Terminal")) terminals = [i for i in new_ports if i not in ports] @@ -468,7 +471,7 @@ def _create_port_terminal( except Exception: # pragma: no cover self.logger.warning("Failed to change normalization.") if terminals_rename: - new_name = portname + "_T" + str(count) + new_name = port_name + "_T" + str(count) terminal_name = new_name properties = [ "NAME:AllTabs", @@ -489,7 +492,7 @@ def _create_port_terminal( boundary.type = "Wave Port" else: boundary.type = "Lumped Port" - props["Faces"] = [objectname] + props["Faces"] = [assignment] if iswaveport: props["NumModes"] = 1 props["UseLineModeAlignment"] = 1 @@ -511,9 +514,9 @@ def _create_port_terminal( return boundary - @pyaedt_function_handler() - def _create_circuit_port(self, edgelist, impedance, name, renorm, deemb, renorm_impedance=""): - edgelist = self.modeler.convert_to_selections(edgelist, True) + @pyaedt_function_handler(edgelist="assignment") + def _create_circuit_port(self, assignment, impedance, name, renorm, deemb, renorm_impedance=""): + edgelist = self.modeler.convert_to_selections(assignment, True) props = OrderedDict( { "Edges": edgelist, @@ -536,14 +539,14 @@ def _create_circuit_port(self, edgelist, impedance, name, renorm, deemb, renorm_ props["TerminalIDList"] = [] return self._create_boundary(name, props, "Circuit Port") - @pyaedt_function_handler() + @pyaedt_function_handler(objectname="assignment", portname="port_name") def _create_waveport_driven( self, - objectname, + assignment, int_line_start=None, int_line_stop=None, impedance=50, - portname="", + port_name="", renorm=True, nummodes=1, deemb_distance=0, @@ -558,12 +561,12 @@ def _create_waveport_driven( useintline = False props = OrderedDict({}) # Used to create the argument to pass to native api: oModule.AssignWavePort() - if isinstance(objectname, int): # Assumes a Face ID is passed in objectname - props["Faces"] = [objectname] - elif isinstance(objectname, list): # Assume [x, y, z] point is passed in objectname - props["Faces"] = self.modeler.get_faceid_from_position(objectname) + if isinstance(assignment, int): # Assumes a Face ID is passed in objectname + props["Faces"] = [assignment] + elif isinstance(assignment, list): # Assume [x, y, z] point is passed in objectname + props["Faces"] = self.modeler.get_faceid_from_position(assignment) else: - props["Objects"] = [objectname] + props["Objects"] = [assignment] props["NumModes"] = nummodes props["UseLineModeAlignment"] = False @@ -574,8 +577,6 @@ def _create_waveport_driven( props["DoDeembed"] = False props["RenormalizeAllTerminals"] = renorm modes = OrderedDict({}) - arg2 = [] - arg2.append("NAME:Modes") i = 1 report_filter = [] while i <= nummodes: @@ -606,58 +607,75 @@ def _create_waveport_driven( props["ShowReporterFilter"] = False props["ReporterFilter"] = report_filter props["UseAnalyticAlignment"] = False - return self._create_boundary(portname, props, "Wave Port") - - @pyaedt_function_handler() + return self._create_boundary(port_name, props, "Wave Port") + + @pyaedt_function_handler( + obj="assignment", + mat="material", + cond="conductivity", + perm="permittivity", + usethickness="use_thickness", + isinfgnd="is_infinite_ground", + istwoside="is_two_side", + isInternal="is_internal", + issheelElement="is_shell_element", + usehuray="use_huray", + ) def assign_coating( self, - obj, - mat=None, - cond=58000000, - perm=1, - usethickness=False, + assignment, + material=None, + conductivity=58000000, + permittivity=1, + use_thickness=False, thickness="0.1mm", roughness="0um", - isinfgnd=False, - istwoside=False, - isInternal=True, - issheelElement=False, - usehuray=False, + is_infinite_ground=False, + is_two_side=False, + is_internal=True, + is_shell_element=False, + use_huray=False, radius="0.5um", ratio="2.9", + name=None, ): """Assign finite conductivity to one or more objects or faces of a given material. Parameters ---------- - obj : str or list + assignment : str or list One or more objects or faces to assign finite conductivity to. - mat : str, optional + material : str, optional Material to use. The default is ``None``. - cond : float, optional - If no material is provided, a conductivity value must be supplied. The default is ``58000000``. - perm : float, optional - If no material is provided, a permittivity value must be supplied. The default is ``1``. - usethickness : bool, optional + conductivity : float, optional + Conductivity. The default is ``58000000``. + If no material is provided, a value must be supplied. + permittivity : float, optional + Permittivity. The default is ``1``. If no + material is provided, a value must be supplied. + use_thickness : bool, optional Whether to use thickness. The default is ``False``. thickness : str, optional Thickness value if ``usethickness=True``. The default is ``"0.1mm"``. roughness : str, optional Roughness value with units. The default is ``"0um"``. - isinfgnd : bool, optional + is_infinite_ground : bool, optional Whether the finite conductivity is an infinite ground. The default is ``False``. - istwoside : bool, optional + is_two_side : bool, optional Whether the finite conductivity is two-sided. The default is ``False``. - isInternal : bool, optional + is_internal : bool, optional Whether the finite conductivity is internal. The default is ``True``. - issheelElement : bool, optional + is_shell_element : bool, optional + Whether the finite conductivity is a shell element. The default is ``False``. - usehuray : bool, optional - Whether to use an Huray coefficient. The default is ``False``. + use_huray : bool, optional + Whether to use a Huray coefficient. The default is ``False``. radius : str, optional Radius value if ``usehuray=True``. The default is ``"0.5um"``. ratio : str, optional Ratio value if ``usehuray=True``. The default is ``"2.9"``. + name : str + Name of the boundary. Returns ------- @@ -674,6 +692,7 @@ def assign_coating( Create two cylinders in the XY working plane and assign a copper coating of 0.2 mm to the inner cylinder and outer face. + >>> from pyaedt import Hfss >>> hfss = Hfss() >>> origin = hfss.modeler.Position(0, 0, 0) @@ -683,11 +702,11 @@ def assign_coating( >>> outer = hfss.modeler.create_cylinder( ... hfss.PLANE.XY, origin, 4, 200, 0, "outer" ... ) - >>> coat = hfss.assign_coating(["inner", outer.faces[2].id], "copper", usethickness=True, thickness="0.2mm") + >>> coat = hfss.assign_coating(["inner", outer.faces[2].id], "copper", use_thickness=True, thickness="0.2mm") """ - userlst = self.modeler.convert_to_selections(obj, True) + userlst = self.modeler.convert_to_selections(assignment, True) lstobj = [] lstface = [] for selection in userlst: @@ -708,62 +727,60 @@ def assign_coating( props["Faces"] = lstface lstface = [str(i) for i in lstface] listobjname = listobjname + "_" + "_".join(lstface) - if mat: - if self.materials[mat]: + if material: + if self.materials[material]: props["UseMaterial"] = True - props["Material"] = self.materials[mat].name + props["Material"] = self.materials[material].name else: return False else: props["UseMaterial"] = False - props["Conductivity"] = str(cond) - props["Permeability"] = str(str(perm)) - props["UseThickness"] = usethickness - if usethickness: + props["Conductivity"] = str(conductivity) + props["Permeability"] = str(str(permittivity)) + props["UseThickness"] = use_thickness + if use_thickness: props["Thickness"] = thickness - if usehuray: + if use_huray: props["Radius"] = str(radius) props["Ratio"] = str(ratio) props["InfGroundPlane"] = False else: props["Roughness"] = roughness - props["InfGroundPlane"] = isinfgnd - props["IsTwoSided"] = istwoside + props["InfGroundPlane"] = is_infinite_ground + props["IsTwoSided"] = is_two_side - if istwoside: - props["IsShellElement"] = issheelElement + if is_two_side: + props["IsShellElement"] = is_shell_element else: - props["IsInternal"] = isInternal - return self._create_boundary("Coating_" + listobjname[1:], props, "Finite Conductivity") - - # TODO: Extract name and type from **kwargs to pass them to create_setup() as setuptype and setupname + props["IsInternal"] = is_internal + if not name: + name = "Coating_" + listobjname[1:] + return self._create_boundary(name, props, "Finite Conductivity") - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create an analysis setup for HFSS. - Optional arguments are passed along with ``setuptype`` and ``setupname``. Keyword - names correspond to the ``setuptype`` - corresponding to the native AEDT API. The list of - keywords here is not exhaustive. + Optional arguments are passed along with ``setup_type`` and ``name``. Keyword + names correspond to the ``setup_type`` corresponding to the native AEDT API. + The list of keywords here is not exhaustive. .. note:: This method overrides the ``Analysis.setup()`` method for the HFSS app. Parameters ---------- - setuptype : str, optional - Type of the setup. Based on the solution type, options are + name : str, optional + Name of the setup. The default is ``"Setup1"``. + setup_type : str, optional + Type of the setup, which is based on the solution type. Options are ``"HFSSDrivenAuto"``, ``"HFSSDrivenDefault"``, ``"HFSSEigen"``, ``"HFSSTransient"``, and ``"HFSSSBR"``. The default is ``"HFSSDrivenAuto"``. - setupname : str, optional - Name of the setup. The default is ``"Setup1"``. **kwargs : dict, optional Extra arguments to set up the circuit. Available keys depend on the setup chosen. For more information, see :doc:`../SetupTemplatesHFSS`. - Returns ------- :class:`pyaedt.modules.SolveSetup.SetupHFSS`, :class:`pyaedt.modules.SolveSetup.SetupHFSSAuto` @@ -779,14 +796,14 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Hfss >>> hfss = Hfss() - >>> hfss.create_setup(setupname="Setup1", setuptype="HFSSDriven", Frequency="10GHz") + >>> hfss.create_setup(name="Setup1",setup_type="HFSSDriven",Frequency="10GHz") """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: @@ -805,15 +822,17 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): setup.update() return setup - @pyaedt_function_handler() + @pyaedt_function_handler( + setupname="setup", unit="units", freqstart="start_frequency", freqstop="stop_frequency", sweepname="name" + ) def create_linear_count_sweep( self, - setupname, - unit, - freqstart, - freqstop, + setup, + units, + start_frequency, + stop_frequency, num_of_freq_points=None, - sweepname=None, + name=None, save_fields=True, save_rad_fields=False, sweep_type="Discrete", @@ -824,21 +843,21 @@ def create_linear_count_sweep( Parameters ---------- - setupname : str + setup : str Name of the setup. - unit : str + units : str Unit of the frequency. For example, ``"MHz"`` or ``"GHz"``. - freqstart : float + start_frequency : float Starting frequency of the sweep, such as ``1``. - freqstop : float + stop_frequency : float Stopping frequency of the sweep. num_of_freq_points : int Number of frequency points in the range. The default is ``401`` for ``sweep_type = "Interpolating"``. The defaults are "Fast"`` and ``5`` for ``sweep_type = ""Discrete"``. - sweepname : str, optional + name : str, optional Name of the sweep. The default is ``None``, in which - case the default name is automatically assigned. + case a name is automatically assigned. save_fields : bool, optional Whether to save the fields. The default is ``True``. save_rad_fields : bool, optional @@ -870,10 +889,7 @@ def create_linear_count_sweep( named ``"LinearCountSweep"``. >>> setup = hfss.create_setup("LinearCountSetup") - >>> linear_count_sweep = hfss.create_linear_count_sweep(setupname="LinearCountSetup", - ... sweepname="LinearCountSweep", - ... unit="MHz", freqstart=1.1e3, - ... freqstop=1200.1, num_of_freq_points=1658) + >>> linear_count_sweep = hfss.create_linear_count_sweep(,,, >>> type(linear_count_sweep) @@ -889,26 +905,24 @@ def create_linear_count_sweep( "Invalid value for `sweep_type`. The value must be 'Discrete', 'Interpolating', or 'Fast'." ) - if sweepname is None: - sweepname = generate_unique_name("Sweep") + if name is None: + name = generate_unique_name("Sweep") - if setupname not in self.setup_names: + if setup not in self.setup_names: return False for s in self.setups: - if s.name == setupname: + if s.name == setup: setupdata = s - if sweepname in [sweep.name for sweep in setupdata.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self.logger.warning( - "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname - ) - sweepdata = setupdata.add_sweep(sweepname, sweep_type) + if name in [sweep.name for sweep in setupdata.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = setupdata.add_sweep(name, sweep_type) if not sweepdata: return False sweepdata.props["RangeType"] = "LinearCount" - sweepdata.props["RangeStart"] = str(freqstart) + unit - sweepdata.props["RangeEnd"] = str(freqstop) + unit + sweepdata.props["RangeStart"] = str(start_frequency) + units + sweepdata.props["RangeEnd"] = str(stop_frequency) + units sweepdata.props["RangeCount"] = num_of_freq_points sweepdata.props["Type"] = sweep_type if sweep_type == "Interpolating": @@ -919,19 +933,21 @@ def create_linear_count_sweep( sweepdata.props["SaveFields"] = save_fields sweepdata.props["SaveRadFields"] = save_rad_fields sweepdata.update() - self.logger.info("Linear count sweep {} has been correctly created.".format(sweepname)) + self.logger.info("Linear count sweep {} has been correctly created.".format(name)) return sweepdata return False - @pyaedt_function_handler() + @pyaedt_function_handler( + setupname="setup", freqstart="start_frequency", freqstop="stop_frequency", sweepname="name" + ) def create_linear_step_sweep( self, - setupname, + setup, unit, - freqstart, - freqstop, + start_frequency, + stop_frequency, step_size, - sweepname=None, + name=None, save_fields=True, save_rad_fields=False, sweep_type="Discrete", @@ -940,18 +956,19 @@ def create_linear_step_sweep( Parameters ---------- - setupname : str + setup : str Name of the setup. unit : str Unit of the frequency. For example, ``"MHz"`` or ``"GHz"``. - freqstart : float + start_frequency : float Starting frequency of the sweep. - freqstop : float + stop_frequency : float Stopping frequency of the sweep. step_size : float Frequency size of the step. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in + which case a name is automatically assigned. save_fields : bool, optional Whether to save fields. The default is ``True``. save_rad_fields : bool, optional @@ -977,10 +994,9 @@ def create_linear_step_sweep( named ``"LinearStepSweep"``. >>> setup = hfss.create_setup("LinearStepSetup") - >>> linear_step_sweep = hfss.create_linear_step_sweep(setupname="LinearStepSetup", - ... sweepname="LinearStepSweep", - ... unit="MHz", freqstart=1.1e3, - ... freqstop=1200.1, step_size=153.8) + >>> linear_step_sweep = hfss.create_linear_step_sweep(setup="LinearStepSetup", unit="MHz", + ... start_frequency=1.1e3, stop_frequency=1200.1, + ... step_size=153.8) >>> type(linear_step_sweep) @@ -989,32 +1005,34 @@ def create_linear_step_sweep( raise AttributeError( "Invalid value for `sweep_type`. The value must be 'Discrete', 'Interpolating', or 'Fast'." ) - if sweepname is None: - sweepname = generate_unique_name("Sweep") + if name is None: + sweep_name = generate_unique_name("Sweep") + else: + sweep_name = name - if setupname not in self.setup_names: + if setup not in self.setup_names: return False for s in self.setups: - if s.name == setupname: + if s.name == setup: return s.create_linear_step_sweep( unit=unit, - freqstart=freqstart, - freqstop=freqstop, + start_frequency=start_frequency, + stop_frequency=stop_frequency, step_size=step_size, - sweepname=sweepname, + name=sweep_name, save_fields=save_fields, save_rad_fields=save_rad_fields, sweep_type=sweep_type, ) return False - @pyaedt_function_handler() + @pyaedt_function_handler(setupname="setup", sweepname="name") def create_single_point_sweep( self, - setupname, + setup, unit, freq, - sweepname=None, + name=None, save_single_field=True, save_fields=False, save_rad_fields=False, @@ -1023,14 +1041,15 @@ def create_single_point_sweep( Parameters ---------- - setupname : str + setup : str Name of the setup. unit : str Unit of the frequency. For example, ``"MHz"`` or ``"GHz"``. freq : float, list Frequency of the single point or list of frequencies to create distinct single points. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in + which case a name is automatically assigned. save_single_field : bool, list, optional Whether to save the fields of the single point. The default is ``True``. If a list is specified, the length must be the same as the list of frequencies. @@ -1057,15 +1076,15 @@ def create_single_point_sweep( named ``"SinglePointSweep"``. >>> setup = hfss.create_setup("LinearStepSetup") - >>> single_point_sweep = hfss.create_single_point_sweep(setupname="LinearStepSetup", - ... sweepname="SinglePointSweep", - ... unit="MHz", freq=1.1e3) + >>> single_point_sweep = hfss.create_single_point_sweep(setup="LinearStepSetup",unit="MHz",freq=1.1e3) >>> type(single_point_sweep) """ - if sweepname is None: - sweepname = generate_unique_name("SinglePoint") + if name is None: + sweep_name = generate_unique_name("SinglePoint") + else: + sweep_name = name if isinstance(save_single_field, list): if not isinstance(freq, list) or len(save_single_field) != len(freq): @@ -1075,71 +1094,75 @@ def create_single_point_sweep( if isinstance(freq, list): if not freq: raise AttributeError("Frequency list is empty. Specify at least one frequency point.") - freq0 = freq.pop(0) + _ = freq.pop(0) if freq: add_subranges = True - else: - freq0 = freq if isinstance(save_single_field, list): - save0 = save_single_field.pop(0) + _ = save_single_field.pop(0) else: save0 = save_single_field if add_subranges: save_single_field = [save0] * len(freq) - if setupname not in self.setup_names: + if setup not in self.setup_names: return False for s in self.setups: - if s.name == setupname: + if s.name == setup: return s.create_single_point_sweep( unit=unit, freq=freq, - sweepname=sweepname, + name=sweep_name, save_single_field=save_single_field, save_fields=save_fields, save_rad_fields=save_rad_fields, ) return False - @pyaedt_function_handler() + @pyaedt_function_handler(source_object="assignment", solution="setup", fieldtype="field_type", source_name="name") def create_sbr_linked_antenna( self, - source_object, + assignment, target_cs="Global", - solution=None, - fieldtype="nearfield", + setup=None, + field_type="nearfield", use_composite_ports=False, use_global_current=True, - current_conformance="Disable", + current_conformance=False, thin_sources=True, power_fraction="0.95", visible=True, + name=None, ): """Create a linked antennas. Parameters ---------- - source_object : pyaedt.Hfss + assignment : pyaedt.Hfss Source object. target_cs : str, optional Target coordinate system. The default is ``"Global"``. - solution : optional - The default is ``None``. - fieldtype : str, optional + setup : optional + Name of the setup. The default is ``None``, in which + case a name is automatically assigned. + field_type : str, optional + Field type. The options are ``"nearfield"`` and ``"farfield"``. The default is ``"nearfield"``. use_composite_ports : bool, optional Whether to use composite ports. The default is ``False``. use_global_current : bool, optional Whether to use the global current. The default is ``True``. - current_conformance, str optional - The default is ``"Disable"``. + current_conformance : bool, optional + Whether to enable current conformance. The default is ``False``. thin_sources : bool, optional - The default is ``True``. + Whether to enable thin sources. The default is ``True``. power_fraction : str, optional The default is ``"0.95"``. visible : bool, optional. - Visualize source objects in target design. The default is ``True``. + Whether to make source objects in the target design visible. The default is ``True``. + name : str, optional + Name of the source. + The default is ``None`` in which case a name is automatically assigned. References ---------- @@ -1155,24 +1178,27 @@ def create_sbr_linked_antenna( ... specified_version="2021.2", new_desktop_session=False) # doctest: +SKIP >>> source = Hfss(projectname=source_project, designname="feeder", ... specified_version="2021.2", new_desktop_session=False) # doctest: +SKIP - >>> target.create_sbr_linked_antenna(source, target_cs="feederPosition", - ... fieldtype="farfield") # doctest: +SKIP + >>> target.create_sbr_linked_antenna(source,target_cs="feederPosition",field_type="farfield") # doctest: +SKIP """ if self.solution_type != "SBR+": self.logger.error("Native components only apply to the SBR+ solution.") return False - compName = source_object.design_name - uniquename = generate_unique_name(compName) - if source_object.project_name == self.project_name: + + if name is None: + uniquename = generate_unique_name(assignment.design_name) + else: + uniquename = generate_unique_name(name) + + if assignment.project_name == self.project_name: project_name = "This Project*" else: - project_name = os.path.join(source_object.project_path, source_object.project_name + ".aedt") - design_name = source_object.design_name - if not solution: - solution = source_object.nominal_adaptive + project_name = os.path.join(assignment.project_path, assignment.project_name + ".aedt") + design_name = assignment.design_name + if not setup: + setup = assignment.nominal_adaptive params = OrderedDict({}) - pars = source_object.available_variations.nominal_w_values_dict + pars = assignment.available_variations.nominal_w_values_dict for el in pars: params[el] = pars[el] native_props = OrderedDict( @@ -1183,23 +1209,26 @@ def create_sbr_linked_antenna( "Project": project_name, "Product": "HFSS", "Design": design_name, - "Soln": solution, + "Soln": setup, "Params": params, "ForceSourceToSolve": True, "PreservePartnerSoln": True, "PathRelativeTo": "TargetProject", - "FieldType": fieldtype, + "FieldType": field_type, "UseCompositePort": use_composite_ports, "SourceBlockageStructure": OrderedDict({"NonModelObject": []}), } ) - if fieldtype == "nearfield": + if field_type == "nearfield": native_props["UseGlobalCurrentSrcOption"] = use_global_current - native_props["Current Source Conformance"] = current_conformance + if current_conformance: + native_props["Current Source Conformance"] = "Enable" + else: + native_props["Current Source Conformance"] = "Disable" native_props["Thin Sources"] = thin_sources native_props["Power Fraction"] = power_fraction if visible: - native_props["VisualizationObjects"] = source_object.modeler.solid_names + native_props["VisualizationObjects"] = assignment.modeler.solid_names return self._create_native_component( "Linked Antenna", target_cs, self.modeler.model_units, native_props, uniquename ) @@ -1404,16 +1433,16 @@ class SBRAntennaDefaults: "File Based Antenna": 8, } - @pyaedt_function_handler() + @pyaedt_function_handler(model_units="units", parameters_dict="parameters", antenna_name="name") def create_sbr_antenna( self, antenna_type=SbrAntennas.ConicalHorn, target_cs=None, - model_units=None, - parameters_dict=None, + units=None, + parameters=None, use_current_source_representation=False, is_array=False, - antenna_name=None, + name=None, ): """Create a parametric beam antennas in SBR+. @@ -1425,18 +1454,18 @@ def create_sbr_antenna( target_cs : str, optional Target coordinate system. The default is ``None``, in which case the active coodiante system is used. - model_units : str, optional + units : str, optional Model units to apply to the object. The default is ``None``, in which case the active modeler units are applied. - parameters_dict : dict, optional + parameters : dict, optional Dictionary of parameters. The default is ``None``. use_current_source_representation : bool, optional Whether to use the current source representation. The default is ``False``. is_array : bool, optional - The default is ``False``. - antenna_name : str, optional + Whether to define an array. The default is ``False``. + name : str, optional Name of the 3D component. The default is ``None``, in which case the - name is auto-generated based on the antennas type. + name is auto-generated based on the antenna type. Returns ------- @@ -1454,9 +1483,7 @@ def create_sbr_antenna( >>> hfss = Hfss(solution_type="SBR+") # doctest: +SKIP PyAEDT INFO: Added design 'HFSS_IPO' of type HFSS. >>> parm = {"polarization": "Vertical"} # doctest: +SKIP - >>> par_beam = hfss.create_sbr_antenna(hfss.SbrAntennas.ShortDipole, - ... parameters_dict=parm, - ... antenna_name="TX1") # doctest: +SKIP + >>> par_beam = hfss.create_sbr_antenna(hfss.SbrAntennas.ShortDipole,parameters=parm,name="TX1") """ if self.solution_type != "SBR+": @@ -1512,28 +1539,28 @@ def create_sbr_antenna( parameters_defaults["Array Weight Cosine Exp"] = 1 parameters_defaults["Array Differential Pattern Type"] = 0 if is_array: - antenna_name = generate_unique_name("pAntArray") - if parameters_dict: - for el, value in parameters_dict.items(): + name = generate_unique_name("pAntArray") + if parameters: + for el, value in parameters.items(): parameters_defaults[el] = value - return self._create_native_component(antenna_type, target_cs, model_units, parameters_defaults, antenna_name) + return self._create_native_component(antenna_type, target_cs, units, parameters_defaults, name) - @pyaedt_function_handler() + @pyaedt_function_handler(ffd_full_path="far_field_data", model_units="units", antenna_name="name") def create_sbr_file_based_antenna( self, - ffd_full_path, + far_field_data, antenna_size="1mm", antenna_impedance="50ohm", representation_type="Far Field", target_cs=None, - model_units=None, - antenna_name=None, + units=None, + name=None, ): - """Create a linked antennas. + """Create a linked antenna. Parameters ---------- - ffd_full_path : str + far_field_data : str Full path to the FFD file. antenna_size : str, optional Antenna size with units. The default is ``"1mm"``. @@ -1545,12 +1572,12 @@ def create_sbr_file_based_antenna( target_cs : str, optional Target coordinate system. The default is ``None``, in which case the active coordinate system is used. - model_units : str, optional + units : str, optional Model units to apply to the object. The default is ``None``, in which case the active modeler units are applied. - antenna_name : str, optional + name : str, optional Name of the 3D component. The default is ``None``, in which case - the name is auto-generated based on the antennas type. + the name is auto-generated based on the antenna type. Returns ------- @@ -1580,13 +1607,13 @@ def create_sbr_file_based_antenna( "Size": antenna_size, "MatchedPortImpedance": antenna_impedance, "Representation": representation_type, - "ExternalFile": ffd_full_path, + "ExternalFile": far_field_data, } ) - if not antenna_name: - antenna_name = generate_unique_name(os.path.basename(ffd_full_path).split(".")[0]) + if not name: + name = generate_unique_name(os.path.basename(far_field_data).split(".")[0]) - return self._create_native_component("File Based Antenna", target_cs, model_units, par_dicts, antenna_name) + return self._create_native_component("File Based Antenna", target_cs, units, par_dicts, name) @pyaedt_function_handler() def set_sbr_txrx_settings(self, txrx_settings): @@ -1617,146 +1644,8 @@ def set_sbr_txrx_settings(self, txrx_settings): id_ += 1 return self._create_boundary("SBRTxRxSettings", props, "SBRTxRxSettings") - @pyaedt_function_handler() - def create_circuit_port_between_objects( - self, startobj, endobject, axisdir=0, impedance=50, portname=None, renorm=True, renorm_impedance=50, deemb=False - ): - """Create a circuit port taking the closest edges of two objects. - - .. deprecated:: 0.6.70 - Use :func:`circuit_port` method instead. - - Parameters - ---------- - startobj : - Starting object for the integration line. - endobject : - Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. - The default is ``Application.AxisDir.XNeg``. - impedance : float, optional - Port impedance. The default is ``50``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - renorm_impedance : float or str, optional - Renormalize impedance. The default is ``50``. - deemb : bool, optional - Whether to deembed the port. The default is ``False``. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Boundary object. - - References - ---------- - - >>> oModule.AssignCircuitPort - - Examples - -------- - - Create two boxes for creating a circuit port named ``'CircuitExample'``. - - >>> box1 = hfss.modeler.create_box([0, 0, 80], [10, 10, 5], - ... "BoxCircuit1", "copper") - >>> box2 = hfss.modeler.create_box([0, 0, 100], [10, 10, 5], - ... "BoxCircuit2", "copper") - >>> hfss.create_circuit_port_between_objects("BoxCircuit1", "BoxCircuit2", - ... hfss.AxisDir.XNeg, 50, - ... "CircuitExample", True, 50, False) - 'CircuitExample' - - """ - warnings.warn("Use :func:`circuit_port` method instead.", DeprecationWarning) - return self.circuit_port( - signal=startobj, - reference=endobject, - port_location=axisdir, - impedance=impedance, - name=portname, - renormalize=renorm, - renorm_impedance=renorm_impedance, - deembed=deemb, - ) - - @pyaedt_function_handler() - def create_lumped_port_between_objects( - self, startobj, endobject, axisdir=0, impedance=50, portname=None, renorm=True, deemb=False, port_on_plane=True - ): - """Create a lumped port taking the closest edges of two objects. - - .. deprecated:: 0.6.70 - Use :func:`lumped_port` method instead. - - Parameters - ---------- - startobj : - Starting object for the integration line. - endobject : - Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. - The default is ``Application.AxisDir.XNeg``. - impedance : float, optional - Port impedance. The default is ``50``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - deemb : bool, optional - Whether to deembed the port. The default is ``False``. - port_on_plane : bool, optional - Whether to create the source on the plane orthogonal to ``AxisDir``. - The default is ``True``. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Boundary object. - - References - ---------- - - >>> oModule.AssignLumpedPort - - Examples - -------- - - Create two boxes that will be used to create a lumped port - named ``'LumpedPort'``. - - >>> box1 = hfss.modeler.create_box([0, 0, 50], [10, 10, 5], - ... "BoxLumped1","copper") - >>> box2 = hfss.modeler.create_box([0, 0, 60], [10, 10, 5], - ... "BoxLumped2", "copper") - >>> hfss.create_lumped_port_between_objects("BoxLumped1", "BoxLumped2", - ... hfss.AxisDir.XNeg, 50, - ... "LumpedPort", True, False) - PyAEDT INFO: Connection Correctly created - 'LumpedPort' - - """ - warnings.warn("Use :func:`lumped_port` method instead.", DeprecationWarning) - return self.lumped_port( - signal=startobj, - reference=endobject, - create_port_sheet=True, - port_on_plane=port_on_plane, - integration_line=axisdir, - impedance=impedance, - name=portname, - renormalize=renorm, - deembed=deemb, - ) - - @pyaedt_function_handler() - def create_spiral_lumped_port(self, start_object, end_object, port_width=None): + @pyaedt_function_handler(start_object="assignment", end_object="reference", port_width="width") + def create_spiral_lumped_port(self, assignment, reference, width=None, name=None): """Create a spiral lumped port between two adjacent objects. The two objects must have two adjacent, parallel, and identical faces. @@ -1765,16 +1654,17 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): Parameters ---------- - start_object : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` First solid connected to the spiral port. - - end_object : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + reference : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Second object connected to the spiral port. - - port_width : float, optional + width : float, optional Width of the spiral port. - If not specified the width will be calculated based on the object dimensions. + If a width is not specified, it is calculated based on the object dimensions. The default is ``None``. + name : str, optional + Port name. The default is ``None``. + Returns ------- @@ -1789,18 +1679,18 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): >>> box1 = aedtapp.modeler.create_box([-100, -100, 0], [200, 200, 5], name="gnd2z", matname="copper") >>> box2 = aedtapp.modeler.create_box([-100, -100, 20], [200, 200, 25], name="sig2z", matname="copper") >>> aedtapp.modeler.fit_all() - >>> portz = aedtapp.create_spiral_lumped_port(box1, box2) + >>> portz = aedtapp.create_spiral_lumped_port(box1,box2) """ if not "Terminal" in self.solution_type: raise Exception("This method can be used only in Terminal solutions.") - start_object = self.modeler.convert_to_selections(start_object) - end_object = self.modeler.convert_to_selections(end_object) + assignment = self.modeler.convert_to_selections(assignment) + reference = self.modeler.convert_to_selections(reference) # find the closest faces (based on face center) closest_distance = 1e9 closest_faces = [] - for face1 in self.modeler[start_object].faces: - for face2 in self.modeler[end_object].faces: + for face1 in self.modeler[assignment].faces: + for face2 in self.modeler[reference].faces: facecenter_distance = GeometryOperators.points_distance(face1.center, face2.center) if facecenter_distance <= closest_distance: closest_distance = facecenter_distance @@ -1829,8 +1719,8 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): move_vector_mid = GeometryOperators.v_prod(0.5, move_vector) # fmt: off - if port_width: - spiral_width = port_width + if width: + spiral_width = width filling = 1.5 else: # get face bounding box @@ -1838,13 +1728,13 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): for i in range(3): for v in closest_faces[0].vertices: face_bb[i] = min(face_bb[i], v.position[i]) - face_bb[i+3] = max(face_bb[i+3], v.position[i]) + face_bb[i + 3] = max(face_bb[i + 3], v.position[i]) # get the ratio in 2D - bb_dim = [abs(face_bb[i]-face_bb[i+3]) for i in range(3) if abs(face_bb[i]-face_bb[i+3]) > 1e-12] - bb_ratio = max(bb_dim)/min(bb_dim) + bb_dim = [abs(face_bb[i] - face_bb[i + 3]) for i in range(3) if abs(face_bb[i] - face_bb[i + 3]) > 1e-12] + bb_ratio = max(bb_dim) / min(bb_dim) if bb_ratio > 2: spiral_width = min(bb_dim) / 12 - filling = -0.2828*bb_ratio**2 + 3.4141*bb_ratio - 4.197 + filling = -0.2828 * bb_ratio ** 2 + 3.4141 * bb_ratio - 4.197 print(filling) else: vertex_coordinates = [] @@ -1856,8 +1746,8 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): spiral_width = min(segments_lengths) / 15 filling = 1.5 # fmt: on - - name = generate_unique_name("P", n=3) + if not name: + name = generate_unique_name("P", n=3) spiral = self.modeler.create_spiral_on_face(closest_faces[0], spiral_width, filling_factor=filling) spiral.name = name @@ -1907,7 +1797,7 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): xsection_type="Line", xsection_orient=orient, xsection_width=closest_distance / 2, - name=start_object + "_sheet", + name=assignment + "_sheet", ) # create second polyline to join spiral with conductor face @@ -1925,39 +1815,42 @@ def create_spiral_lumped_port(self, start_object, end_object, port_width=None): xsection_type="Line", xsection_orient=orient, xsection_width=closest_distance / 2, - name=end_object + "_sheet", + name=reference + "_sheet", ) # assign pec to created polylines - self.assign_perfecte_to_sheets(poly1, sourcename=start_object) - self.assign_perfecte_to_sheets(poly2, sourcename=end_object) + self.assign_perfecte_to_sheets(poly1, name=assignment) + self.assign_perfecte_to_sheets(poly2, name=reference) # create lumped port on spiral port = self.lumped_port(spiral, reference=[poly2.name], name=name) return port - @pyaedt_function_handler() - def create_voltage_source_from_objects(self, startobj, endobject, axisdir=0, sourcename=None, source_on_plane=True): + @pyaedt_function_handler(startobj="assignment", endobject="reference", sourcename="name", axisdir="start_direction") + def create_voltage_source_from_objects( + self, assignment, reference, start_direction=0, name=None, source_on_plane=True + ): """Create a voltage source taking the closest edges of two objects. Parameters ---------- - startobj : - Starting object for the integration line. - endobject : - Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for - ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, - ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. The default - is ``Application.AxisDir.XNeg``. - sourcename : str, optional + assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + First object connected to the voltage source. + reference : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + Second object connected to the voltage source. + start_direction : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional + Start direction for the port location. + It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, + ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. + The default is ``Application.AxisDir.XNeg``. + name : str, optional Name of the source. The default is ``None``. source_on_plane : bool, optional Whether to create the source on the plane orthogonal to ``AxisDir``. The default is ``True``. + Returns ------- :class:`pyaedt.modules.Boundary.BoundaryObject` @@ -1977,42 +1870,44 @@ def create_voltage_source_from_objects(self, startobj, endobject, axisdir=0, sou ... "BoxVolt1", "copper") >>> box2 = hfss.modeler.create_box([30, 0, 10], [40, 10, 5], ... "BoxVolt2", "copper") - >>> v1 = hfss.create_voltage_source_from_objects("BoxVolt1", "BoxVolt2", - ... hfss.AxisDir.XNeg, - ... "VoltageSource") + >>> v1 = hfss.create_voltage_source_from_objects("BoxVolt1","BoxVolt2",hfss.AxisDir.XNeg,"VoltageSource") PyAEDT INFO: Connection Correctly created - """ - if not self.modeler.does_object_exists(startobj) or not self.modeler.does_object_exists(endobject): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects doesn't exists. Check and retry") return False if self.solution_type in ["Modal", "Terminal", "Transient Network"]: sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - startobj, endobject, axisdir, source_on_plane + assignment, reference, start_direction, source_on_plane ) - sourcename = self._get_unique_source_name(sourcename, "Voltage") - return self.create_source_excitation(sheet_name, point0, point1, sourcename, sourcetype="Voltage") + name = self._get_unique_source_name(name, "Voltage") + return self.create_source_excitation(sheet_name, point0, point1, name, source_type="Voltage") return False # pragma: no cover - @pyaedt_function_handler() - def create_current_source_from_objects(self, startobj, endobject, axisdir=0, sourcename=None, source_on_plane=True): + @pyaedt_function_handler(startobj="assignment", endobject="reference", sourcename="name", axisdir="start_direction") + def create_current_source_from_objects( + self, assignment, reference, start_direction=0, name=None, source_on_plane=True + ): """Create a current source taking the closest edges of two objects. Parameters ---------- - startobj : - Starting object for the integration line. - endobject : - Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. - The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional + assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + First object connected to the current source. + reference : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + Second object connected to the current source. + start_direction : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional + Start direction for the port location. + It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, + ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. + The default is ``Application.AxisDir.XNeg``. + name : str, optional Name of the source. The default is ``None``. source_on_plane : bool, optional - Whether to create the source on the plane orthogonal to ``axisdir``. The default is ``True``. + Whether to create the source on the plane orthogonal to + the start direction. The default is ``True``. + Returns ------- @@ -2033,40 +1928,36 @@ def create_current_source_from_objects(self, startobj, endobject, axisdir=0, sou ... "BoxCurrent1", "copper") >>> box2 = hfss.modeler.create_box([30, 0, 30], [40, 10, 5], ... "BoxCurrent2", "copper") - >>> i1 = hfss.create_current_source_from_objects("BoxCurrent1", "BoxCurrent2", - ... hfss.AxisDir.XPos, - ... "CurrentSource") + >>> i1 = hfss.create_current_source_from_objects("BoxCurrent1","BoxCurrent2",hfss.AxisDir.XPos,"CurrentSource") PyAEDT INFO: Connection created 'CurrentSource' correctly. - """ - if not self.modeler.does_object_exists(startobj) or not self.modeler.does_object_exists(endobject): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects do not exist. Check and retry.") return False if self.solution_type in ["Modal", "Terminal", "Transient Network"]: sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - startobj, endobject, axisdir, source_on_plane + assignment, reference, start_direction, source_on_plane ) - sourcename = self._get_unique_source_name(sourcename, "Current") - return self.create_source_excitation(sheet_name, point0, point1, sourcename, sourcetype="Current") + name = self._get_unique_source_name(name, "Current") + return self.create_source_excitation(sheet_name, point0, point1, name, source_type="Current") return False # pragma: no cover - @pyaedt_function_handler() - def create_source_excitation(self, sheet_name, point1, point2, sourcename, sourcetype="Voltage"): + @pyaedt_function_handler(sheet_name="assignment", sourcename="name", sourcetype="source_type") + def create_source_excitation(self, assignment, point1, point2, name, source_type="Voltage"): """Create a source excitation. Parameters ---------- - sheet_name : str + assignment : str Name of the sheet. - point1 : - - point2 : - - sourcename : str + point1 : list + First point of the source excitation. + point2 : list + Second point of the source excitation. + name : str Name of the source. - - sourcetype : str, optional + source_type : str, optional Type of the source. The default is ``"Voltage"``. Returns @@ -2081,108 +1972,20 @@ def create_source_excitation(self, sheet_name, point1, point2, sourcename, sourc >>> oModule.AssignCurrent """ - props = OrderedDict({"Objects": [sheet_name], "Direction": OrderedDict({"Start": point1, "End": point2})}) - return self._create_boundary(sourcename, props, sourcetype) - - @pyaedt_function_handler() - def create_wave_port_between_objects( - self, - startobj, - endobject, - axisdir=0, - impedance=50, - nummodes=1, - portname=None, - renorm=True, - deembed_dist=0, - port_on_plane=True, - add_pec_cap=False, - ): - """Create a waveport taking the closest edges of two objects. - - .. deprecated:: 0.6.62 - Use :func:`wave_port` metho instead. + props = OrderedDict({"Objects": [assignment], "Direction": OrderedDict({"Start": point1, "End": point2})}) + return self._create_boundary(name, props, source_type) - Parameters - ---------- - startobj : - Starting object for the integration line. - endobject : - Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. - The default is ``Application.AxisDir.XNeg``. - impedance : float, optional - Port impedance. The default is ``50``. - nummodes : int, optional - Number of modes. The default is ``1``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - deembed_dist : float, optional - Deembed distance in millimeters. The default is ``0``, - in which case deembed is disabled. - port_on_plane : bool, optional - Whether to create the port on the plane orthogonal to ``AxisDir``. The default is ``True``. - add_pec_cap : bool, optional - The default is ``False``. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Boundary object. - - References - ---------- - - >>> oModule.AssignWavePort - - Examples - -------- - - Create two boxes that will be used to create a wave port - named ``'Wave Port'``. - - >>> box1 = hfss.modeler.create_box([0,0,0], [10,10,5], - ... "BoxWave1", "copper") - >>> box2 = hfss.modeler.create_box([0, 0, 10], [10, 10, 5], - ... "BoxWave2", "copper") - >>> wave_port = hfss.create_wave_port_between_objects("BoxWave1", "BoxWave2", - ... hfss.AxisDir.XNeg, 50, 1, - ... "Wave Port", False) - PyAEDT INFO: Connection Correctly created - - """ - warnings.warn( - "`create_wave_port_between_objects` is deprecated. Use `wave_port` property instead.", DeprecationWarning - ) - return self.wave_port( - signal=startobj, - reference=endobject, - integration_line=axisdir, - create_port_sheet=True, - impedance=impedance, - num_modes=nummodes, - name=portname, - renormalize=renorm, - deembed=deembed_dist, - port_on_plane=port_on_plane, - add_pec_cap=add_pec_cap, - ) - - @pyaedt_function_handler() + @pyaedt_function_handler(face="assignment", nummodes="modes", portname="name", renorm="renormalize") def create_floquet_port( self, - face, + assignment, lattice_origin=None, lattice_a_end=None, lattice_b_end=None, - nummodes=2, - portname=None, - renorm=True, - deembed_dist=0, + modes=2, + name=None, + renormalize=True, + deembed_distance=0, reporter_filter=True, lattice_cs="Global", ): @@ -2190,7 +1993,7 @@ def create_floquet_port( Parameters ---------- - face : + assignment : Face or sheet to apply the floquet port to. lattice_origin : list List of ``[x,y,z]`` coordinates for the lattice A-B origin. The default is ``None``, @@ -2201,13 +2004,13 @@ def create_floquet_port( lattice_b_end : list List of ``[x,y,z]`` coordinates for the lattice B end point. The default is ``None``, in which case the method tries to compute the A-B automatically. - nummodes : int, optional + modes : int, optional Number of modes. The default is ``2``. - portname : str, optional + name : str, optional Name of the port. The default is ``None``. - renorm : bool, optional + renormalize : bool, optional Whether to renormalize the mode. The default is ``True``. - deembed_dist : float, str, optional + deembed_distance : float, str, optional Deembed distance in millimeters. The default is ``0``, in which case deembed is disabled. reporter_filter : bool, list of bool @@ -2228,30 +2031,30 @@ def create_floquet_port( >>> oModule.AssignFloquetPort """ - face_id = self.modeler.convert_to_selections(face, True) + face_id = self.modeler.convert_to_selections(assignment, True) props = OrderedDict({}) if isinstance(face_id[0], int): props["Faces"] = face_id else: props["Objects"] = face_id - props["NumModes"] = nummodes - if deembed_dist: + props["NumModes"] = modes + if deembed_distance: props["DoDeembed"] = True - props["DeembedDist"] = self.modeler._arg_with_dim(deembed_dist) + props["DeembedDist"] = self.modeler._arg_with_dim(deembed_distance) else: props["DoDeembed"] = False props["DeembedDist"] = "0mm" - props["RenormalizeAllTerminals"] = renorm + props["RenormalizeAllTerminals"] = renormalize props["Modes"] = OrderedDict({}) - for i in range(1, 1 + nummodes): + for i in range(1, 1 + modes): props["Modes"]["Mode{}".format(i)] = OrderedDict({}) props["Modes"]["Mode{}".format(i)]["ModeNum"] = i props["Modes"]["Mode{}".format(i)]["UseIntLine"] = False props["Modes"]["Mode{}".format(i)]["CharImp"] = "Zpi" props["ShowReporterFilter"] = True if isinstance(reporter_filter, bool): - props["ReporterFilter"] = [reporter_filter for i in range(nummodes)] + props["ReporterFilter"] = [reporter_filter for i in range(modes)] else: props["ReporterFilter"] = reporter_filter if not lattice_a_end or not lattice_origin or not lattice_b_end: @@ -2267,25 +2070,25 @@ def create_floquet_port( props["LatticeBVector"]["Coordinate System"] = lattice_cs props["LatticeBVector"]["Start"] = lattice_origin props["LatticeBVector"]["End"] = lattice_b_end - if not portname: - portname = generate_unique_name("Floquet") - return self._create_boundary(portname, props, "Floquet Port") + if not name: + name = generate_unique_name("Floquet") + return self._create_boundary(name, props, "Floquet Port") - @pyaedt_function_handler() + @pyaedt_function_handler(face_couple="assignment", pair_name="name") def assign_lattice_pair( self, - face_couple, + assignment, reverse_v=False, phase_delay="UseScanAngle", phase_delay_param1="0deg", phase_delay_param2="0deg", - pair_name=None, + name=None, ): """Assign a lattice pair to a couple of faces. Parameters ---------- - face_couple : list + assignment : list List of two faces to assign the lattice pair to. reverse_v : bool, optional Whether to reverse the V vector. The default is `False`. @@ -2309,7 +2112,7 @@ def assign_lattice_pair( - V value if the approach is ``"UseScanUV"``. The default is ``0deg``. - pair_name : str, optional + name : str, optional Boundary name. Returns @@ -2323,7 +2126,7 @@ def assign_lattice_pair( >>> oModule.AssignLatticePair """ props = OrderedDict({}) - face_id = self.modeler.convert_to_selections(face_couple, True) + face_id = self.modeler.convert_to_selections(assignment, True) props["Faces"] = face_id props["ReverseV"] = reverse_v @@ -2336,17 +2139,17 @@ def assign_lattice_pair( props["ScanV"] = phase_delay_param2 else: props["Phase"] = phase_delay_param1 - if not pair_name: - pair_name = generate_unique_name("LatticePair") - return self._create_boundary(pair_name, props, "Lattice Pair") + if not name: + name = generate_unique_name("LatticePair") + return self._create_boundary(name, props, "Lattice Pair") - @pyaedt_function_handler() - def auto_assign_lattice_pairs(self, object_to_assign, coordinate_system="Global", coordinate_plane="XY"): + @pyaedt_function_handler(object_to_assign="assignment") + def auto_assign_lattice_pairs(self, assignment, coordinate_system="Global", coordinate_plane="XY"): """Assign lattice pairs to a geometry automatically. Parameters ---------- - object_to_assign : str, Object3d + assignment : str, :class:`pyaedt.modeler.cad.object3d.Object3d` Object to assign a lattice to. coordinate_system : str, optional Coordinate system to look for the lattice on. @@ -2364,34 +2167,36 @@ def auto_assign_lattice_pairs(self, object_to_assign, coordinate_system="Global" >>> oModule.AutoIdentifyLatticePair """ - objectname = self.modeler.convert_to_selections(object_to_assign, True) + objectname = self.modeler.convert_to_selections(assignment, True) boundaries = list(self.oboundary.GetBoundaries()) self.oboundary.AutoIdentifyLatticePair("{}:{}".format(coordinate_system, coordinate_plane), objectname[0]) boundaries = [i for i in list(self.oboundary.GetBoundaries()) if i not in boundaries] bounds = [i for i in boundaries if boundaries.index(i) % 2 == 0] return bounds - @pyaedt_function_handler() + @pyaedt_function_handler( + face="assignment", primary_name="primary", coord_name="coordinate_system", secondary_name="name" + ) def assign_secondary( self, - face, - primary_name, + assignment, + primary, u_start, u_end, reverse_v=False, phase_delay="UseScanAngle", phase_delay_param1="0deg", phase_delay_param2="0deg", - coord_name="Global", - secondary_name=None, + coordinate_system="Global", + name=None, ): """Assign the secondary boundary condition. Parameters ---------- - face : int, FacePrimitive + assignment : int, FacePrimitive Face to assign the lattice pair to. - primary_name : str + primary : str Name of the primary boundary to couple. u_start : list List of ``[x,y,z]`` values for the starting point of the U vector. @@ -2418,10 +2223,11 @@ def assign_secondary( - V value if the approach is ``"UseScanUV"``. The default is ``0deg``. - coord_name : str, optional + coordinate_system : str, optional Name of the coordinate system for U coordinates. - secondary_name : str, optional - Name of the boundary. The default is ``None``. + name : str, optional + Name of the boundary. The default is ``None``, + in which case a name is automatically assigned. Returns ------- @@ -2434,7 +2240,7 @@ def assign_secondary( >>> oModule.AssignSecondary """ props = OrderedDict({}) - face_id = self.modeler.convert_to_selections(face, True) + face_id = self.modeler.convert_to_selections(assignment, True) if isinstance(face_id[0], str): props["Objects"] = face_id @@ -2442,12 +2248,12 @@ def assign_secondary( props["Faces"] = face_id props["CoordSysVector"] = OrderedDict({}) - props["CoordSysVector"]["Coordinate System"] = coord_name + props["CoordSysVector"]["Coordinate System"] = coordinate_system props["CoordSysVector"]["Origin"] = u_start props["CoordSysVector"]["UPos"] = u_end props["ReverseV"] = reverse_v - props["Primary"] = primary_name + props["Primary"] = primary props["PhaseDelay"] = phase_delay if phase_delay == "UseScanAngle": props["Phi"] = phase_delay_param1 @@ -2457,17 +2263,17 @@ def assign_secondary( props["ScanV"] = phase_delay_param2 else: props["Phase"] = phase_delay_param1 - if not secondary_name: - secondary_name = generate_unique_name("Secondary") - return self._create_boundary(secondary_name, props, "Secondary") + if not name: + name = generate_unique_name("Secondary") + return self._create_boundary(name, props, "Secondary") - @pyaedt_function_handler() - def assign_primary(self, face, u_start, u_end, reverse_v=False, coord_name="Global", primary_name=None): + @pyaedt_function_handler(face="assignment", coord_name="coordinate_system", primary_name="name") + def assign_primary(self, assignment, u_start, u_end, reverse_v=False, coordinate_system="Global", name=None): """Assign the primary boundary condition. Parameters ---------- - face : int, FacePrimitive + assignment : int, FacePrimitive Face to assign the lattice pair to. u_start : list List of ``[x,y,z]`` values for the starting point of the U vector. @@ -2475,11 +2281,12 @@ def assign_primary(self, face, u_start, u_end, reverse_v=False, coord_name="Glob List of ``[x,y,z]`` values for the ending point of the U vector. reverse_v : bool, optional Whether to reverse the V vector. The default is `False`. - coord_name : str, optional + coordinate_system : str, optional Name of the coordinate system for the U coordinates. The default is ``"Global"``. - primary_name : str, optional - Name of the boundary. The default is ``None``. # TODO: Add names of allowed values to docstring. + name : str, optional + Name of the boundary. The default is ``None``, + in which case a name is automatically assigned. Returns ------- @@ -2492,7 +2299,7 @@ def assign_primary(self, face, u_start, u_end, reverse_v=False, coord_name="Glob >>> oModule.AssignPrimary """ props = OrderedDict({}) - face_id = self.modeler.convert_to_selections(face, True) + face_id = self.modeler.convert_to_selections(assignment, True) if isinstance(face_id[0], str): props["Objects"] = face_id @@ -2500,12 +2307,12 @@ def assign_primary(self, face, u_start, u_end, reverse_v=False, coord_name="Glob props["Faces"] = face_id props["ReverseV"] = reverse_v props["CoordSysVector"] = OrderedDict({}) - props["CoordSysVector"]["Coordinate System"] = coord_name + props["CoordSysVector"]["Coordinate System"] = coordinate_system props["CoordSysVector"]["Origin"] = u_start props["CoordSysVector"]["UPos"] = u_end - if not primary_name: - primary_name = generate_unique_name("Primary") - return self._create_boundary(primary_name, props, "Primary") + if not name: + name = generate_unique_name("Primary") + return self._create_boundary(name, props, "Primary") def _create_pec_cap(self, sheet_name, obj_name, pecthick): """Create a PEC object to back a wave port. @@ -2556,121 +2363,38 @@ def _create_pec_cap(self, sheet_name, obj_name, pecthick): out_obj.material_name = "pec" return True - @pyaedt_function_handler() - def create_wave_port_microstrip_between_objects( - self, - startobj, - endobject, - axisdir=0, - impedance=50, - nummodes=1, - portname=None, - renorm=True, - deembed_dist=0, - vfactor=3, - hfactor=5, - ): - """Create a waveport taking the closest edges of two objects. - - .. deprecated:: 0.6.62 - `create_wave_port_microstrip_between_objects` is deprecated. Use `wave_port` property instead. - - Parameters - ---------- - startobj : - Starting object for the integration line. This is typically the reference plane. - endobject : - Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. - The default is ``Application.AxisDir.XNeg``. - impedance : float, optional - Port impedance. The default is ``50``. - nummodes : int, optional - Number of modes. The default is ``1``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - deembed_dist : float, optional - Deembed distance in millimeters. The default is ``0``, - in which case deembed is disabled. - vfactor : int, optional - Port vertical factor. The default is ``3``. - hfactor : int, optional - Port horizontal factor. The default is ``5``. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Port object. - - References - ---------- - - >>> oModule.AssignWavePort - - Examples - -------- - - Create a wave port supported by a microstrip line. - - >>> ms = hfss.modeler.create_box([4, 5, 0], [1, 100, 0.2], - ... name="MS1", matname="copper") - >>> sub = hfss.modeler.create_box([0, 5, -2], [20, 100, 2], - ... name="SUB1", matname="FR4_epoxy") - >>> gnd = hfss.modeler.create_box([0, 5, -2.2], [20, 100, 0.2], - ... name="GND1", matname="FR4_epoxy") - >>> port = hfss.create_wave_port_microstrip_between_objects("GND1", "MS1", - ... portname="MS1", - ... axisdir=1) - PyAEDT INFO: Connection correctly created. - - """ - warnings.warn( - "`create_wave_port_microstrip_between_objects` is deprecated. Use `wave_port` property instead.", - DeprecationWarning, - ) - return self.wave_port( - signal=startobj, - reference=endobject, - integration_line=axisdir, - create_port_sheet=True, - impedance=impedance, - num_modes=nummodes, - name=portname, - renormalize=renorm, - deembed=deembed_dist, - is_microstrip=True, - vfactor=vfactor, - hfactor=hfactor, - ) - - @pyaedt_function_handler() + @pyaedt_function_handler( + startobj="assignment", + endobj="reference", + sourcename="name", + is_infinite_gnd="is_infinite_ground", + bound_on_plane="is_boundary_on_plane", + axisdir="start_direction", + ) def create_perfecte_from_objects( - self, startobj, endobject, axisdir=0, sourcename=None, is_infinite_gnd=False, bound_on_plane=True + self, assignment, reference, start_direction=0, name=None, is_infinite_ground=False, is_boundary_on_plane=True ): """Create a Perfect E taking the closest edges of two objects. Parameters ---------- - startobj : + assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Starting object for the integration line. - endobject : + reference : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for + start_direction : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional + Start direction for the boundary location. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional - Perfect E name. The default is ``None``. - is_infinite_gnd : bool, optional + name : str, optional + Perfect E name. The default is ``None``, in which + case a name is automatically assigned. + is_infinite_ground : bool, optional Whether the Perfect E is an infinite ground. The default is ``False``. - bound_on_plane : bool, optional + is_boundary_on_plane : bool, optional Whether to create the Perfect E on the plane orthogonal to - ``AxisDir``. The default is ``True``. + the axis direction. The default is ``True``. Returns ------- @@ -2691,47 +2415,56 @@ def create_perfecte_from_objects( ... "perfect1", "Copper") >>> box2 = hfss.modeler.create_box([0, 0, 10], [10, 10, 5], ... "perfect2", "copper") - >>> perfect_e = hfss.create_perfecte_from_objects("perfect1", "perfect2", - ... hfss.AxisDir.ZNeg, "PerfectE") + >>> perfect_e = hfss.create_perfecte_from_objects("perfect1","perfect2",hfss.AxisDir.ZNeg,"PerfectE") PyAEDT INFO: Connection Correctly created >>> type(perfect_e) """ - if not self.modeler.does_object_exists(startobj) or not self.modeler.does_object_exists(endobject): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects do not exist. Check and retry.") return False if self.solution_type in ["Modal", "Terminal", "Transient Network"]: sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - startobj, endobject, axisdir, bound_on_plane + assignment, reference, start_direction, is_boundary_on_plane ) - if not sourcename: - sourcename = generate_unique_name("PerfE") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) - return self.create_boundary(self.BoundaryType.PerfectE, sheet_name, sourcename, is_infinite_gnd) + if not name: + name = generate_unique_name("PerfE") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) + return self.create_boundary(self.BoundaryType.PerfectE, sheet_name, name, is_infinite_ground) return False - @pyaedt_function_handler() - def create_perfecth_from_objects(self, startobj, endobject, axisdir=0, sourcename=None, bound_on_plane=True): + @pyaedt_function_handler( + startobj="assignment", + endobject="reference", + sourcename="name", + bound_on_plane="is_boundary_on_plane", + axisdir="start_direction", + ) + def create_perfecth_from_objects( + self, assignment, reference, start_direction=0, name=None, is_boundary_on_plane=True + ): """Create a Perfect H taking the closest edges of two objects. Parameters ---------- - startobj : + assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Starting object for the integration line. - endobject : + reference : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, + start_direction : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional + Start direction for the boundary location. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional - Perfect H name. The default is ``None``. - bound_on_plane : bool, optional - Whether to create the Perfect H on the plane orthogonal to ``AxisDir``. The default is ``True``. + name : str, optional + Perfect H name. The default is ``None``, + in which case a name is automatically assigned. + is_boundary_on_plane : bool, optional + Whether to create the Perfect H on the plane + orthogonal to the axis direction. The default is ``True``. Returns ------- @@ -2752,44 +2485,49 @@ def create_perfecth_from_objects(self, startobj, endobject, axisdir=0, sourcenam ... "perfect1", "Copper") >>> box2 = hfss.modeler.create_box([0, 0, 30], [10, 10, 5], ... "perfect2", "copper") - >>> perfect_h = hfss.create_perfecth_from_objects("perfect1", "perfect2", - ... hfss.AxisDir.ZNeg, "Perfect H") + >>> perfect_h = hfss.create_perfecth_from_objects("perfect1","perfect2",hfss.AxisDir.ZNeg,"Perfect H") PyAEDT INFO: Connection Correctly created >>> type(perfect_h) """ - if not self.modeler.does_object_exists(startobj) or not self.modeler.does_object_exists(endobject): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects do not exist. Check and retry.") return False if self.solution_type in ["Modal", "Terminal", "Transient Network"]: sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - startobj, endobject, axisdir, bound_on_plane + assignment, reference, start_direction, is_boundary_on_plane ) - if not sourcename: - sourcename = generate_unique_name("PerfH") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) - return self.create_boundary(self.BoundaryType.PerfectH, sheet_name, sourcename) + if not name: + name = generate_unique_name("PerfH") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) + return self.create_boundary(self.BoundaryType.PerfectH, sheet_name, name) return None - @pyaedt_function_handler() - def sar_setup(self, Tissue_object_List_ID=-1, TissueMass=1, MaterialDensity=1, voxel_size=1, Average_SAR_method=0): + @pyaedt_function_handler( + Tissue_object_List_ID="assignment", + TissueMass="tissue_mass", + MaterialDensity="material_density", + Average_SAR_method="average_sar_method", + ) + def sar_setup(self, assignment=-1, tissue_mass=1, material_density=1, voxel_size=1, average_sar_method=0): """Define SAR settings. Parameters ---------- - Tissue_object_List_ID : int, optional - The default is ``-1`` to not specify the object. - TissueMass : float, optional - The default is ``1``. - MaterialDensity : optional - The default is ``1``. + assignment : int, optional + Object ID. The default is ``-1`` to not specify the object. + tissue_mass : float, optional + Mass of tissue in grams. The default is ``1``. + material_density : optional + Density of material in gram/cm^3. The default is ``1``. voxel_size : optional - The default is ``1``. - Average_SAR_method : optional + Size of a voxel in millimeters. The default is ``1``. + average_sar_method : optional + SAR method. There are two options, ``0`` for IEEE Standard 1528 and ``1`` for the standard Ansys method. The default is ``0``. Returns @@ -2802,24 +2540,26 @@ def sar_setup(self, Tissue_object_List_ID=-1, TissueMass=1, MaterialDensity=1, v >>> oDesign.SARSetup """ - self.odesign.SARSetup(TissueMass, MaterialDensity, Tissue_object_List_ID, voxel_size, Average_SAR_method) - self.logger.info("SAR Settings correctly applied.") + self.odesign.SARSetup(tissue_mass, material_density, assignment, voxel_size, average_sar_method) + self.logger.info("SAR settings are correctly applied.") return True - @pyaedt_function_handler() - def create_open_region(self, Frequency="1GHz", Boundary="Radiation", ApplyInfiniteGP=False, GPAXis="-z"): + @pyaedt_function_handler( + Frequency="frequency", Boundary="boundary", ApplyInfiniteGP="apply_infinite_ground", GPAXis="gp_axis" + ) + def create_open_region(self, frequency="1GHz", boundary="Radiation", apply_infinite_ground=False, gp_axis="-z"): """Create an open region on the active editor. Parameters ---------- - Frequency : str, optional + frequency : str, optional Frequency with units. The default is ``"1GHz"``. - Boundary : str, optional + boundary : str, optional Type of the boundary. The default is ``"Radiation"``. - ApplyInfiniteGP : bool, optional + apply_infinite_ground : bool, optional Whether to apply an infinite ground plane. The default is ``False``. - GPAXis : str, optional - The default is ``"-z"``. + gp_axis : str, optional + Open region direction. The default is ``"-z"``. Returns ------- @@ -2831,55 +2571,75 @@ def create_open_region(self, Frequency="1GHz", Boundary="Radiation", ApplyInfini >>> oModule.CreateOpenRegion """ - vars = ["NAME:Settings", "OpFreq:=", Frequency, "Boundary:=", Boundary, "ApplyInfiniteGP:=", ApplyInfiniteGP] - if ApplyInfiniteGP: + vars = [ + "NAME:Settings", + "OpFreq:=", + frequency, + "Boundary:=", + boundary, + "ApplyInfiniteGP:=", + apply_infinite_ground, + ] + if apply_infinite_ground: vars.append("Direction:=") - vars.append(GPAXis) + vars.append(gp_axis) self.omodelsetup.CreateOpenRegion(vars) self.logger.info("Open Region correctly created.") + self.save_project() return True - @pyaedt_function_handler() + @pyaedt_function_handler( + startobj="assignment", + endobj="reference", + sourcename="name", + rlctype="rlc_type", + Rvalue="resistance", + Lvalue="inductance", + Cvalue="capacitance", + bound_on_plane="is_boundary_on_plane", + axisdir="start_direction", + ) def create_lumped_rlc_between_objects( self, - startobj, - endobject, - axisdir=0, - sourcename=None, - rlctype="Parallel", - Rvalue=None, - Lvalue=None, - Cvalue=None, - bound_on_plane=True, + assignment, + reference, + start_direction=0, + name=None, + rlc_type="Parallel", + resistance=None, + inductance=None, + capacitance=None, + is_boundary_on_plane=True, ): """Create a lumped RLC taking the closest edges of two objects. Parameters ---------- - startobj : + assignment : Starting object for the integration line. - endobject : + reference : Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, + start_direction : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional + Start direction for the boundary location.. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional - Perfect H name. The default is ``None``. - rlctype : str, optional + name : str, optional + Perfect H name. The default is ``None``, in which + case a name is automatically assigned. + rlc_type : str, optional Type of the RLC. Options are ``"Parallel"`` and ``"Serial"``. The default is ``"Parallel"``. - Rvalue : optional + resistance : optional Resistance value in ohms. The default is ``None``, in which case this parameter is disabled. - Lvalue : optional + inductance : optional Inductance value in H. The default is ``None``, in which case this parameter is disabled. - Cvalue : optional + capacitance : optional Capacitance value in F. The default is ``None``, in which case this parameter is disabled. - bound_on_plane : bool, optional + is_boundary_on_plane : bool, optional Whether to create the boundary on the plane orthogonal to ``AxisDir``. The default is ``True``. @@ -2902,70 +2662,77 @@ def create_lumped_rlc_between_objects( ... "rlc1", "copper") >>> box2 = hfss.modeler.create_box([0, 0, 60], [10, 10, 5], ... "rlc2", "copper") - >>> rlc = hfss.create_lumped_rlc_between_objects("rlc1", "rlc2", hfss.AxisDir.XPos, - ... "Lumped RLC", Rvalue=50, - ... Lvalue=1e-9, Cvalue = 1e-6) + >>> rlc = hfss.create_lumped_rlc_between_objects("rlc1","rlc2",hfss.AxisDir.XPos,"Lumped RLC",resistance=50, + ... inductance=1e-9, capacitance=1e-6) PyAEDT INFO: Connection Correctly created """ - if not self.modeler.does_object_exists(startobj) or not self.modeler.does_object_exists(endobject): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects do not exist. Check and retry.") return False - if self.solution_type in ["Modal", "Terminal", "Transient Network"] and (Rvalue or Lvalue or Cvalue): + if self.solution_type in ["Modal", "Terminal", "Transient Network"] and ( + resistance or inductance or capacitance + ): sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - startobj, endobject, axisdir, bound_on_plane + assignment, reference, start_direction, is_boundary_on_plane ) - if not sourcename: - sourcename = generate_unique_name("Lump") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) + if not name: + name = generate_unique_name("Lump") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) start = [str(i) + self.modeler.model_units for i in point0] stop = [str(i) + self.modeler.model_units for i in point1] props = OrderedDict() props["Objects"] = [sheet_name] props["CurrentLine"] = OrderedDict({"Start": start, "End": stop}) - props["RLC Type"] = rlctype - if Rvalue: + props["RLC Type"] = rlc_type + if resistance: props["UseResist"] = True - props["Resistance"] = str(Rvalue) + "ohm" - if Lvalue: + props["Resistance"] = str(resistance) + "ohm" + if inductance: props["UseInduct"] = True - props["Inductance"] = str(Lvalue) + "H" - if Cvalue: + props["Inductance"] = str(inductance) + "H" + if capacitance: props["UseCap"] = True - props["Capacitance"] = str(Cvalue) + "farad" + props["Capacitance"] = str(capacitance) + "farad" - return self._create_boundary(sourcename, props, "Lumped RLC") + return self._create_boundary(name, props, "Lumped RLC") return False - @pyaedt_function_handler() + @pyaedt_function_handler( + startobj="start_assignment", + endobject="end_assignment", + axisdir="start_direction", + sourcename="source_name", + is_infground="is_infinite_ground", + ) def create_impedance_between_objects( self, - startobj, - endobject, - axisdir=0, - sourcename=None, + start_assignment, + end_assignment, + start_direction=0, + source_name=None, resistance=50, reactance=0, - is_infground=False, + is_infinite_ground=False, bound_on_plane=True, ): """Create an impedance taking the closest edges of two objects. Parameters ---------- - startobj : + start_assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Starting object for the integration line. - endobject : + end_assignment : str or int or :class:`pyaedt.modeler.cad.object3d.Object3d` Ending object for the integration line. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It should be one of the values for ``Application.AxisDir``, + start_direction : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional + Start direction for the boundary location. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional + source_name : str, optional Name of the impedance. The default is ``None``. resistance : float, optional Resistance value in ohms. The default is ``50``. If ``None``, @@ -2973,7 +2740,7 @@ def create_impedance_between_objects( reactance : optional Reactance value in ohms. The default is ``0``. If ``None``, this parameter is disabled. - is_infground : bool, optional + is_infinite_ground : bool, optional Whether the impendance is an infinite ground. The default is ``False``. bound_on_plane : bool, optional Whether to create the impedance on the plane orthogonal to ``AxisDir``. @@ -3004,46 +2771,58 @@ def create_impedance_between_objects( """ - if not self.modeler.does_object_exists(startobj) or not self.modeler.does_object_exists(endobject): + if not self.modeler.does_object_exists(start_assignment) or not self.modeler.does_object_exists(end_assignment): self.logger.error("One or both objects do not exist. Check and retry.") return False if self.solution_type in ["Modal", "Terminal", "Transient Network"]: sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - startobj, endobject, axisdir, bound_on_plane + start_assignment, end_assignment, start_direction, bound_on_plane ) - if not sourcename: - sourcename = generate_unique_name("Imped") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) + if not source_name: + source_name = generate_unique_name("Imped") + elif source_name in self.modeler.get_boundaries_name(): + source_name = generate_unique_name(source_name) props = OrderedDict( { "Objects": [sheet_name], "Resistance": str(resistance), "Reactance": str(reactance), - "InfGroundPlane": is_infground, + "InfGroundPlane": is_infinite_ground, } ) - return self._create_boundary(sourcename, props, "Impedance") + return self._create_boundary(source_name, props, "Impedance") return False - @pyaedt_function_handler() + @pyaedt_function_handler(sheet_name="assignment", boundary_name="name", is_inifinite_gnd="is_inifinite_ground") def create_boundary( - self, boundary_type=BoundaryType.PerfectE, sheet_name=None, boundary_name="", is_infinite_gnd=False + self, boundary_type=BoundaryType.PerfectE, assignment=None, name=None, is_inifinite_ground=False ): - """Create a boundary given specific inputs. + """Assign a boundary condition to a sheet or surface. This method is generally + used by other methods in the ``Hfss`` class such as the :meth:``Hfss.assign_febi`` + or :meth:``Hfss.assign_radiation_boundary_to_faces`` method. Parameters ---------- - boundary_type : str, optional - Boundary type object. Options are ``"Perfect E"``, ``"Perfect H"``, ``"Aperture"``, and - ``"Radiation"``. The default is ``PerfectE``. - sheet_name : in, str, or list, optional - Name of the sheet. It can be an integer (face ID), a string (sheet), or a list of integers - and strings. The default is ``None``. - boundary_name : str, optional - Name of the boundary. The default is ``""``. - is_infinite_gnd : bool, optional + boundary_type : int, optional + Type of boundary condition to assign to a sheet or surface. The + default is ``Hfss.BoundaryType.PerfectE``. Options are the properties of the + :class:``Hfss.BoundaryType`` class. For example: + + - ``Hfss.BoundaryType.PerfectE`` + - ``Hfss.BoundaryType.PerfectH`` + - ``Hfss.BoundaryType.Radiation`` + - ``Hfss.BoundaryType.Impedance`` + - ``Hfss.BoundaryType.LumpedRLC`` + - ``Hfss.BoundaryType.FEBI`` + + assignment : int, str, or list, optional + Name of the sheet or face to assign the boundary condition to. The + default is ``None``. You can provide an integer (face ID), a string (sheet), + or a list of integers and strings. + name : str, optional + Name of the boundary. The default is ``None``. + is_inifinite_ground : bool, optional Whether the boundary is an infinite ground. The default is ``False``. Returns @@ -3054,15 +2833,15 @@ def create_boundary( """ props = {} - sheet_name = self.modeler.convert_to_selections(sheet_name, True) - if type(sheet_name) is list: - if type(sheet_name[0]) is str: - props["Objects"] = sheet_name + assignment = self.modeler.convert_to_selections(assignment, True) + if type(assignment) is list: + if type(assignment[0]) is str: + props["Objects"] = assignment else: - props["Faces"] = sheet_name + props["Faces"] = assignment if boundary_type == self.BoundaryType.PerfectE: - props["InfGroundPlane"] = is_infinite_gnd + props["InfGroundPlane"] = is_inifinite_ground boundary_type = "Perfect E" elif boundary_type == self.BoundaryType.PerfectH: boundary_type = "Perfect H" @@ -3080,7 +2859,7 @@ def create_boundary( boundary_type = "FE-BI" else: return None - return self._create_boundary(boundary_name, props, boundary_type) + return self._create_boundary(name, props, boundary_type) @pyaedt_function_handler() def _get_reference_and_integration_points(self, sheet, axisdir, obj_name=None): @@ -3122,250 +2901,20 @@ def _get_reference_and_integration_points(self, sheet, axisdir, obj_name=None): int_stop = max_point return refid, int_start, int_stop - @pyaedt_function_handler() - def create_wave_port_from_sheet( - self, - sheet, - deemb=0, - axisdir=None, - impedance=50, - nummodes=1, - portname=None, - renorm=True, - terminal_references=None, - ): - """Create a waveport on sheet objects created starting from sheets. - - .. deprecated:: 0.6.62 - `create_wave_port_from_sheet` is deprecated. Use `wave_port` property instead. - - Parameters - ---------- - sheet : str or int or list or :class:`pyaedt.modeler.cad.object3d.Object3d` - Name of the sheet. - deemb : float, optional - Deembedding value distance in model units. The default is ``0``. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. It is used to auto evaluate the integration line. - If set to ``None`` the integration line is not defined. - It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. - The default is ``None`` and no integration line is defined. - impedance : float, optional - Port impedance. The default is ``50``. - nummodes : int, optional - Number of modes. The default is ``1``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - terminal_references : list, optional - For a driven-terminal simulation, list of conductors for port terminal definitions. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Boundary object. - - References - ---------- - - >>> oModule.AssignWavePort - - Examples - -------- - - Create a circle sheet for creating a wave port named ``'WavePortFromSheet'``. - - >>> origin_position = hfss.modeler.Position(0, 0, 0) - >>> circle = hfss.modeler.create_circle(hfss.PLANE.YZ, - ... origin_position, 10, name="WaveCircle") - >>> hfss.solution_type = "Modal" - >>> port = hfss.create_wave_port_from_sheet(circle, 5, hfss.AxisDir.XNeg, 40, 2, - ... "WavePortFromSheet", True) - >>> port[0].name - 'WavePortFromSheet' - - """ - warnings.warn( - "`create_wave_port_from_sheet` is deprecated. Use `wave_port` property instead.", DeprecationWarning - ) - return self.wave_port( - signal=sheet, - reference=terminal_references, - integration_line=axisdir, - create_port_sheet=False, - impedance=impedance, - num_modes=nummodes, - name=portname, - renormalize=renorm, - deembed=deemb, - ) - - @pyaedt_function_handler() - def create_wave_port( - self, - port_item, # Item to use for wave port creation - int_start, - int_stop, - deemb=0, - axisdir=None, - impedance=50, - nummodes=1, - portname=None, - renorm=True, - terminal_references=None, - ): - """Assign a wave port to a face given a point on the face. - - .. deprecated:: 0.6.62 - `create_wave_port` is deprecated. Use `wave_port` property instead. - - Parameters - ---------- - port_item : list, int - Item for defining where to create the port. - If a list is passed, then Cartesian [x,y,z] coordinates of a point on the face are - expected. If an integer is passed, it is assumed to be a face ID. - deemb : float, optional - Deembedding value distance in model units. The default is ``0``. - axisdir : int or :class:`pyaedt.application.Analysis.Analysis.AxisDir`, optional - Position of the port. This parameter is used to automatically evaluate - the integration line. The default is ``None``, in which case no integration - line is defined. This parameter should be set to one of the values - for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, - ``XPos``, ``YPos``, and ``ZPos``. - - impedance : float, optional - Port impedance. The default is ``50``. - nummodes : int, optional - Number of modes. The default is ``1``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - terminal_references : list, optional - For a driven-terminal simulation, list of conductors for port terminal definitions. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Boundary object. - - References - ---------- - - >>> oModule.AssignWavePort - - Examples - -------- - - Create a circle sheet for creating a wave port named ``'WavePortFromSheet'``. - - >>> hfss.modeler.model_units("in") - >>> hfss.modeler.create_box([-0.2, -0.45, -1], [0.4, 0.9, 2], name="Xband_WG", matname="vacuum") - >>> setup = hfss.create_setup("Setup1") - >>> setup["Frequency"] = "10GHz" - >>> ports = [ hfss.create_wave_port([0, "a/2", "-wg_len/2"], portname="Port1", deembed=False), - >>> ... hfss.create_wave_port([0, "a/2", "wg_len/2"], portname="Port2", deembed=False) ] - >>> [print(name) for p.name in ports] - - """ - warnings.warn("`create_wave_port` is deprecated. Use `wave_port` property instead.", DeprecationWarning) - return self.wave_port( - signal=port_item, - reference=terminal_references, - integration_line=[int_start, int_stop], - create_port_sheet=True, - impedance=impedance, - num_modes=nummodes, - name=portname, - renormalize=renorm, - deembed=deemb, - ) - - @pyaedt_function_handler() - def create_lumped_port_to_sheet( - self, sheet_name, axisdir=0, impedance=50, portname=None, renorm=True, deemb=False, reference_object_list=[] - ): - """Create a lumped port taking one sheet. - - .. deprecated:: 0.6.62 - `create_lumped_port_to_sheet` is deprecated. Use `lumped` property instead. - - Parameters - ---------- - sheet_name : str - Name of the sheet. - axisdir : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional - Direction of the integration line. It should be one of the values for ``Application.AxisDir``, - which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. It also accepts the list - of the start point and end point with the format [[xstart, ystart, zstart], [xend, yend, zend]]. - The default is ``Application.AxisDir.XNeg``. - impedance : float, optional - Port impedance. The default is ``50``. - portname : str, optional - Name of the port. The default is ``None``. - renorm : bool, optional - Whether to renormalize the mode. The default is ``True``. - deemb : bool, optional - Whether to deembed the port. The default is ``False``. - reference_object_list : list, optional - For a driven terminal solution only, a list of reference conductors. The default is ``[]``. - - Returns - ------- - :class:`pyaedt.modules.Boundary.BoundaryObject` - Boundary object. - - References - ---------- - - >>> oModule.AssignLumpedPort - - Examples - -------- - - Create a rectangle sheet for creating a lumped port named ``'LumpedPortFromSheet'``. - - >>> rectangle = hfss.modeler.create_rectangle(hfss.PLANE.XY, - ... [0, 0, 0], [10, 2], name="lump_port", - ... matname="copper") - >>> h1 = hfss.create_lumped_port_to_sheet(rectangle.name, hfss.AxisDir.XNeg, 50, - ... "LumpedPortFromSheet", True, False) - >>> h2 = hfss.create_lumped_port_to_sheet(rectangle.name, [rectangle.bottom_edge_x.midpoint, - ... rectangle.bottom_edge_y.midpoint], 50, "LumpedPortFromSheet", True, - ... False) - - """ - warnings.warn( - "`create_lumped_port_to_sheet` is deprecated. Use `lumped_port` property instead.", DeprecationWarning - ) - return self.lumped_port( - signal=sheet_name, - reference=reference_object_list, - integration_line=axisdir, - create_port_sheet=False, - impedance=impedance, - name=portname, - renormalize=renorm, - deembed=deemb, - ) - - @pyaedt_function_handler() - def assign_voltage_source_to_sheet(self, sheet_name, axisdir=0, sourcename=None): + @pyaedt_function_handler(sheet_name="assignment", sourcename="name", axisdir="start_direction") + def assign_voltage_source_to_sheet(self, assignment, start_direction=0, name=None): """Create a voltage source taking one sheet. Parameters ---------- - sheet_name : str + assignment : str Name of the sheet to apply the boundary to. - axisdir : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional + start_direction : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional Direction of the integration line. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. It also accepts the list of the start point and end point with the format [[xstart, ystart, zstart], [xend, yend, zend]] The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional + name : str, optional Name of the source. The default is ``None``. Returns @@ -3386,40 +2935,39 @@ def assign_voltage_source_to_sheet(self, sheet_name, axisdir=0, sourcename=None) >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, ... [0, 0, -70], [10, 2], name="VoltageSheet", ... matname="copper") - >>> v1 = hfss.assign_voltage_source_to_sheet(sheet.name, hfss.AxisDir.XNeg, "VoltageSheetExample") - >>> v2 = hfss.assign_voltage_source_to_sheet(sheet.name, [sheet.bottom_edge_x.midpoint, - ... sheet.bottom_edge_y.midpoint], 50, "LumpedPortFromSheet", True, - ... False) + >>> v1 = hfss.assign_voltage_source_to_sheet(sheet.name,hfss.AxisDir.XNeg,"VoltageSheetExample") + >>> v2 = hfss.assign_voltage_source_to_sheet(sheet.name,[sheet.bottom_edge_x.midpoint, + ... sheet.bottom_edge_y.midpoint],50) """ if self.solution_type in ["Modal", "Terminal", "Transient Network"]: - if isinstance(axisdir, list): - if len(axisdir) != 2 or len(axisdir[0]) != len(axisdir[1]): + if isinstance(start_direction, list): + if len(start_direction) != 2 or len(start_direction[0]) != len(start_direction[1]): self.logger.error("List of coordinates is not set correctly") return False - point0 = axisdir[0] - point1 = axisdir[1] + point0 = start_direction[0] + point1 = start_direction[1] else: - point0, point1 = self.modeler.get_mid_points_on_dir(sheet_name, axisdir) - sourcename = self._get_unique_source_name(sourcename, "Voltage") - return self.create_source_excitation(sheet_name, point0, point1, sourcename, sourcetype="Voltage") + point0, point1 = self.modeler.get_mid_points_on_dir(assignment, start_direction) + name = self._get_unique_source_name(name, "Voltage") + return self.create_source_excitation(assignment, point0, point1, name, source_type="Voltage") return False - @pyaedt_function_handler() - def assign_current_source_to_sheet(self, sheet_name, axisdir=0, sourcename=None): + @pyaedt_function_handler(sheet_name="assignment", sourcename="name", axisdir="start_direction") + def assign_current_source_to_sheet(self, assignment, start_direction=0, name=None): """Create a current source taking one sheet. Parameters ---------- - sheet_name : str + assignment : str Name of the sheet to apply the boundary to. - axisdir : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional + start_direction : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional Direction of the integration line. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. It also accepts the list of the start point and end point with the format [[xstart, ystart, zstart], [xend, yend, zend]] The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional + name : str, optional Name of the source. The default is ``None``. Returns @@ -3439,37 +2987,37 @@ def assign_current_source_to_sheet(self, sheet_name, axisdir=0, sourcename=None) >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, [0, 0, -50], ... [5, 1], name="CurrentSheet", matname="copper") - >>> hfss.assign_current_source_to_sheet(sheet.name, hfss.AxisDir.XNeg, "CurrentSheetExample") + >>> hfss.assign_current_source_to_sheet(sheet.name,hfss.AxisDir.XNeg,"CurrentSheetExample") 'CurrentSheetExample' - >>> c1 = hfss.assign_current_source_to_sheet(sheet.name, [sheet.bottom_edge_x.midpoint, + >>> c1 = hfss.assign_current_source_to_sheet(sheet.name,[sheet.bottom_edge_x.midpoint, ... sheet.bottom_edge_y.midpoint]) """ if self.solution_type in ["Modal", "Terminal", "Transient Network"]: - if isinstance(axisdir, list): - if len(axisdir) != 2 or len(axisdir[0]) != len(axisdir[1]): + if isinstance(start_direction, list): + if len(start_direction) != 2 or len(start_direction[0]) != len(start_direction[1]): self.logger.error("List of coordinates is not set correctly") return False - point0 = axisdir[0] - point1 = axisdir[1] + point0 = start_direction[0] + point1 = start_direction[1] else: - point0, point1 = self.modeler.get_mid_points_on_dir(sheet_name, axisdir) - sourcename = self._get_unique_source_name(sourcename, "Current") - return self.create_source_excitation(sheet_name, point0, point1, sourcename, sourcetype="Current") + point0, point1 = self.modeler.get_mid_points_on_dir(assignment, start_direction) + name = self._get_unique_source_name(name, "Current") + return self.create_source_excitation(assignment, point0, point1, name, source_type="Current") return False - @pyaedt_function_handler() - def assign_perfecte_to_sheets(self, sheet_list, sourcename=None, is_infinite_gnd=False): + @pyaedt_function_handler(sheet_list="assignment", sourcename="name", is_infinite_gnd="is_infinite_ground") + def assign_perfecte_to_sheets(self, assignment, name=None, is_infinite_ground=False): """Create a Perfect E taking one sheet. Parameters ---------- - sheet_list : str or list - Name of the sheet or list to apply the boundary to. - sourcename : str, optional + assignment : str or list + One or more names of the sheets to apply the boundary to. + name : str, optional Name of the Perfect E source. The default is ``None``. - is_infinite_gnd : bool, optional + is_infinite_ground : bool, optional Whether the Perfect E is an infinite ground. The default is ``False``. Returns @@ -3489,29 +3037,29 @@ def assign_perfecte_to_sheets(self, sheet_list, sourcename=None, is_infinite_gnd >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, [0, 0, -90], ... [10, 2], name="PerfectESheet", matname="Copper") - >>> perfect_e_from_sheet = hfss.assign_perfecte_to_sheets(sheet.name, "PerfectEFromSheet") + >>> perfect_e_from_sheet = hfss.assign_perfecte_to_sheets(sheet.name,"PerfectEFromSheet") >>> type(perfect_e_from_sheet) """ - sheet_list = self.modeler.convert_to_selections(sheet_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self.solution_type in ["Modal", "Terminal", "Transient Network", "SBR+", "Eigenmode"]: - if not sourcename: - sourcename = generate_unique_name("PerfE") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) - return self.create_boundary(self.BoundaryType.PerfectE, sheet_list, sourcename, is_infinite_gnd) + if not name: + name = generate_unique_name("PerfE") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) + return self.create_boundary(self.BoundaryType.PerfectE, assignment, name, is_infinite_ground) return None - @pyaedt_function_handler() - def assign_perfecth_to_sheets(self, sheet_list, sourcename=None): + @pyaedt_function_handler(sheet_list="assignment", sourcename="name") + def assign_perfecth_to_sheets(self, assignment, name=None): """Assign a Perfect H to sheets. Parameters ---------- - sheet_list : list + assignment : list List of sheets to apply the boundary to. - sourcename : str, optional + name : str, optional Perfect H name. The default is ``None``. Returns @@ -3531,46 +3079,61 @@ def assign_perfecth_to_sheets(self, sheet_list, sourcename=None): >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, [0, 0, -90], ... [10, 2], name="PerfectHSheet", matname="Copper") - >>> perfect_h_from_sheet = hfss.assign_perfecth_to_sheets(sheet.name, "PerfectHFromSheet") + >>> perfect_h_from_sheet = hfss.assign_perfecth_to_sheets(sheet.name,"PerfectHFromSheet") >>> type(perfect_h_from_sheet) """ if self.solution_type in ["Modal", "Terminal", "Transient Network", "SBR+", "Eigenmode"]: - if not sourcename: - sourcename = generate_unique_name("PerfH") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) - return self.create_boundary(self.BoundaryType.PerfectH, sheet_list, sourcename) + if not name: + name = generate_unique_name("PerfH") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) + return self.create_boundary(self.BoundaryType.PerfectH, assignment, name) return None - @pyaedt_function_handler() + @pyaedt_function_handler( + sheet_name="assignment", + sourcename="name", + rlctype="rlc_type", + Rvalue="resistance", + Lvalue="inductance", + Cvalue="capacitance", + axisdir="start_direction", + ) def assign_lumped_rlc_to_sheet( - self, sheet_name, axisdir=0, sourcename=None, rlctype="Parallel", Rvalue=None, Lvalue=None, Cvalue=None + self, + assignment, + start_direction=0, + name=None, + rlc_type="Parallel", + resistance=None, + inductance=None, + capacitance=None, ): """Create a lumped RLC taking one sheet. Parameters ---------- - sheet_name : str + assignment : str Name of the sheet to apply the boundary to. - axisdir : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional + start_direction : int, :class:`pyaedt.application.Analysis.Analysis.AxisDir` or list, optional Direction of the integration line. It should be one of the values for ``Application.AxisDir``, which are: ``XNeg``, ``YNeg``, ``ZNeg``, ``XPos``, ``YPos``, and ``ZPos``. It also accepts the list of the start point and end point with the format [[xstart, ystart, zstart], [xend, yend, zend]] The default is ``Application.AxisDir.XNeg``. - sourcename : str, optional + name : str, optional Lumped RLC name. The default is ``None``. - rlctype : str, optional + rlc_type : str, optional Type of the RLC. Options are ``"Parallel"`` and ``"Serial"``. The default is ``"Parallel"``. - Rvalue : float, optional + resistance : float, optional Resistance value in ohms. The default is ``None``, in which case this parameter is disabled. - Lvalue : optional + inductance : float, optional Inductance value in Henry (H). The default is ``None``, in which case this parameter is disabled. - Cvalue : optional + capacitance : float, optional Capacitance value in farads (F). The default is ``None``, in which case this parameter is disabled. @@ -3592,59 +3155,59 @@ def assign_lumped_rlc_to_sheet( >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, ... [0, 0, -90], [10, 2], name="RLCSheet", ... matname="Copper") - >>> lumped_rlc_to_sheet = hfss.assign_lumped_rlc_to_sheet(sheet.name, hfss.AxisDir.XPos, - ... Rvalue=50, Lvalue=1e-9, - ... Cvalue=1e-6) + >>> lumped_rlc_to_sheet = hfss.assign_lumped_rlc_to_sheet(sheet.name,hfss.AxisDir.XPos,resistance=50, + ... inductance=1e-9,capacitance=1e-6) >>> type(lumped_rlc_to_sheet) - >>> h2 = hfss.assign_lumped_rlc_to_sheet(sheet.name, [sheet.bottom_edge_x.midpoint, - ... sheet.bottom_edge_y.midpoint], Rvalue=50, Lvalue=1e-9, Cvalue=1e-6) + >>> h2 = hfss.assign_lumped_rlc_to_sheet(sheet.name,[sheet.bottom_edge_x.midpoint, + ... sheet.bottom_edge_y.midpoint],resistance=50,inductance=1e-9, + ... capacitance=1e-6) """ if self.solution_type in ["Eigenmode", "Modal", "Terminal", "Transient Network", "SBR+"] and ( - Rvalue or Lvalue or Cvalue + resistance or inductance or capacitance ): - if isinstance(axisdir, list): - if len(axisdir) != 2 or len(axisdir[0]) != len(axisdir[1]): + if isinstance(start_direction, list): + if len(start_direction) != 2 or len(start_direction[0]) != len(start_direction[1]): self.logger.error("List of coordinates is not set correctly") return False - point0 = axisdir[0] - point1 = axisdir[1] + point0 = start_direction[0] + point1 = start_direction[1] else: - point0, point1 = self.modeler.get_mid_points_on_dir(sheet_name, axisdir) + point0, point1 = self.modeler.get_mid_points_on_dir(assignment, start_direction) - if not sourcename: - sourcename = generate_unique_name("Lump") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) + if not name: + name = generate_unique_name("Lump") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) start = [str(i) + self.modeler.model_units for i in point0] stop = [str(i) + self.modeler.model_units for i in point1] props = OrderedDict() - props["Objects"] = [sheet_name] + props["Objects"] = [assignment] props["CurrentLine"] = OrderedDict({"Start": start, "End": stop}) - props["RLC Type"] = rlctype - if Rvalue: + props["RLC Type"] = rlc_type + if resistance: props["UseResist"] = True - props["Resistance"] = str(Rvalue) + "ohm" - if Lvalue: + props["Resistance"] = str(resistance) + "ohm" + if inductance: props["UseInduct"] = True - props["Inductance"] = str(Lvalue) + "H" - if Cvalue: + props["Inductance"] = str(inductance) + "H" + if capacitance: props["UseCap"] = True - props["Capacitance"] = str(Cvalue) + "F" - return self._create_boundary(sourcename, props, "Lumped RLC") + props["Capacitance"] = str(capacitance) + "F" + return self._create_boundary(name, props, "Lumped RLC") return False - @pyaedt_function_handler() - def assign_impedance_to_sheet(self, sheet_name, sourcename=None, resistance=50, reactance=0, is_infground=False): + @pyaedt_function_handler(sheet_name="assignment", sourcename="name", is_infground="is_inifinite_ground") + def assign_impedance_to_sheet(self, assignment, name=None, resistance=50, reactance=0, is_inifinite_ground=False): """Create an impedance taking one sheet. Parameters ---------- - sheet_name : str or list - Name of the sheet or list to apply the boundary to. - sourcename : str, optional + assignment : str or list + One or more names of the sheets to apply the boundary to. + name : str, optional Name of the impedance. The default is ``None``. resistance : optional Resistance value in ohms. The default is ``50``. If ``None``, @@ -3652,7 +3215,7 @@ def assign_impedance_to_sheet(self, sheet_name, sourcename=None, resistance=50, reactance : optional Reactance value in ohms. The default is ``0``. If ``None``, this parameter is disabled. - is_infground : bool, optional + is_inifinite_ground : bool, optional Whether the impedance is an infinite ground. The default is ``False``. Returns @@ -3673,19 +3236,19 @@ def assign_impedance_to_sheet(self, sheet_name, sourcename=None, resistance=50, >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, ... [0, 0, -90], [10, 2], name="ImpedanceSheet", ... matname="Copper") - >>> impedance_to_sheet = hfss.assign_impedance_to_sheet(sheet.name, "ImpedanceFromSheet", 100, 50) + >>> impedance_to_sheet = hfss.assign_impedance_to_sheet(sheet.name,"ImpedanceFromSheet",100,50) >>> type(impedance_to_sheet) """ if self.solution_type in ["Modal", "Terminal", "Transient Network"]: - if not sourcename: - sourcename = generate_unique_name("Imped") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) + if not name: + name = generate_unique_name("Imped") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) - objects = self.modeler.convert_to_selections(sheet_name, True) + objects = self.modeler.convert_to_selections(assignment, True) props = OrderedDict( { @@ -3700,22 +3263,30 @@ def assign_impedance_to_sheet(self, sheet_name, sourcename=None, resistance=50, ) props["Resistance"] = str(resistance) props["Reactance"] = str(reactance) - props["InfGroundPlane"] = is_infground + props["InfGroundPlane"] = is_inifinite_ground - return self._create_boundary(sourcename, props, "Impedance") + return self._create_boundary(name, props, "Impedance") return False - @pyaedt_function_handler() + @pyaedt_function_handler( + sheet_name="assignment", sourcename="name", is_infground="is_infinite_ground", reference_cs="coordinate_system" + ) def assign_impedance_to_sheet( - self, sheet_name, sourcename=None, resistance=50.0, reactance=0.0, is_infground=False, reference_cs="Global" + self, + assignment, + name=None, + resistance=50.0, + reactance=0.0, + is_infinite_ground=False, + coordinate_system="Global", ): """Create an impedance taking one sheet. Parameters ---------- - sheet_name : str or list - Name of the sheet or list to apply the boundary to. - sourcename : str, optional + assignment : str or list + One or more names of the sheets to apply the boundary to. + name : str, optional Name of the impedance. The default is ``None``. resistance : float or list, optional Resistance value in ohms. The default is ``50.0``. @@ -3725,9 +3296,9 @@ def assign_impedance_to_sheet( Reactance value in ohms. The default is ``0.0``. If a list of four elements is passed, an anisotropic impedance is assigned with the following order, [``Zxx``, ``Zxy``, ``Zyx``, ``Zyy``]. - is_infground : bool, optional + is_infinite_ground : bool, optional Whether the impedance is an infinite ground. The default is ``False``. - reference_cs : str, optional + coordinate_system : str, optional Name of the coordinate system for the XY plane. The default is ``"Global"``. This parameter is only used for anisotropic impedance assignment. @@ -3749,25 +3320,27 @@ def assign_impedance_to_sheet( >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, ... [0, 0, -90], [10, 2], name="ImpedanceSheet", ... matname="Copper") - >>> impedance_to_sheet = hfss.assign_impedance_to_sheet(sheet.name, "ImpedanceFromSheet", 100, 50) + >>> impedance_to_sheet = hfss.assign_impedance_to_sheet(sheet.name,"ImpedanceFromSheet",100,50) Create a sheet and use it to create an anisotropic impedance. >>> sheet = hfss.modeler.create_rectangle(hfss.PLANE.XY, ... [0, 0, -90], [10, 2], name="ImpedanceSheet", ... matname="Copper") - >>> anistropic_impedance_to_sheet = hfss.assign_impedance_to_sheet(sheet.name, "ImpedanceFromSheet", - ... [377, 0, 0, 377], [0, 50, 0, 0]) + >>> anistropic_impedance_to_sheet = hfss.assign_impedance_to_sheet(sheet.name, + ... "ImpedanceFromSheet", + ... [377, 0, 0, 377], + ... [0, 50, 0, 0]) """ if self.solution_type in ["Modal", "Terminal", "Transient Network"]: - if not sourcename: - sourcename = generate_unique_name("Imped") - elif sourcename in self.modeler.get_boundaries_name(): - sourcename = generate_unique_name(sourcename) + if not name: + name = generate_unique_name("Imped") + elif name in self.modeler.get_boundaries_name(): + name = generate_unique_name(name) - objects = self.modeler.convert_to_selections(sheet_name, True) + objects = self.modeler.convert_to_selections(assignment, True) props = OrderedDict( { @@ -3783,8 +3356,8 @@ def assign_impedance_to_sheet( if isinstance(resistance, list) and isinstance(reactance, list): if len(resistance) == 4 and len(reactance) == 4: - props["UseInfiniteGroundPlane"] = is_infground - props["CoordSystem"] = reference_cs + props["UseInfiniteGroundPlane"] = is_infinite_ground + props["CoordSystem"] = coordinate_system props["HasExternalLink"] = False props["ZxxResistance"] = str(resistance[0]) props["ZxxReactance"] = str(reactance[0]) @@ -3797,21 +3370,23 @@ def assign_impedance_to_sheet( else: self.logger.error("Number of elements in resistance and reactance must be four.") return False - return self._create_boundary(sourcename, props, "Anisotropic Impedance") + return self._create_boundary(name, props, "Anisotropic Impedance") else: props["Resistance"] = str(resistance) props["Reactance"] = str(reactance) - props["InfGroundPlane"] = is_infground - return self._create_boundary(sourcename, props, "Impedance") + props["InfGroundPlane"] = is_infinite_ground + return self._create_boundary(name, props, "Impedance") return False - @pyaedt_function_handler() + @pyaedt_function_handler( + edge_signale="assignment", edge_gnd="reference", port_name="name", port_impedance="impedance" + ) def create_circuit_port_from_edges( self, - edge_signal, - edge_gnd, - port_name="", - port_impedance="50", + assignment, + reference, + name="", + impedance="50", renormalize=False, renorm_impedance="50", deembed=False, @@ -3824,13 +3399,13 @@ def create_circuit_port_from_edges( Parameters ---------- - edge_signal : int + assignment : int Edge ID of the signal. - edge_gnd : int + reference : int Edge ID of the ground. - port_name : str, optional + name : str, optional Name of the port. The default is ``""``. - port_impedance : int, str, or float, optional + impedance : int, str, or float, optional Impedance. The default is ``"50"``. You can also enter a string that looks like this: ``"50+1i*55"``. renormalize : bool, optional @@ -3869,33 +3444,35 @@ def create_circuit_port_from_edges( >>> edges2 = hfss.modeler.get_object_edges(rectangle2.id) >>> second_edge = edges2[0] >>> hfss.solution_type = "Modal" - >>> hfss.create_circuit_port_from_edges(first_edge, second_edge, port_name="PortExample", - ... port_impedance=50.1, renormalize=False, + >>> hfss.create_circuit_port_from_edges(first_edge,second_edge, + ... name="PortExample", + ... impedance=50.1, + ... renormalize=False, ... renorm_impedance="50") 'PortExample' """ warnings.warn("Use :func:`circuit_port` method instead.", DeprecationWarning) return self.circuit_port( - signal=edge_signal, - reference=edge_gnd, + assignment=assignment, + reference=reference, port_location=0, - impedance=port_impedance, - name=port_name, + impedance=impedance, + name=name, renormalize=renormalize, renorm_impedance=renorm_impedance, deembed=deembed, ) - @pyaedt_function_handler() + @pyaedt_function_handler(excitations="assignment") def edit_sources( - self, excitations, include_port_post_processing=True, max_available_power=None, use_incident_voltage=False + self, assignment, include_port_post_processing=True, max_available_power=None, use_incident_voltage=False ): """Set up the power loaded for HFSS postprocessing in multiple sources simultaneously. Parameters ---------- - excitations : dict + assignment : dict Dictionary of input sources to modify module and phase. Dictionary values can be: - 1 value to setup 0deg as default @@ -3909,13 +3486,13 @@ def edit_sources( Examples -------- >>> sources = {"Port1:1": ("0W", "0deg"), "Port2:1": ("1W", "90deg")} - >>> hfss.edit_sources(sources, include_port_post_processing=True) + >>> hfss.edit_sources(sources,include_port_post_processing=True) >>> sources = {"Box2_T1": ("0V", "0deg", True), "Box1_T1": ("1V", "90deg")} - >>> hfss.edit_sources(sources, max_available_power="2W", use_incident_voltage=True) + >>> hfss.edit_sources(sources,max_available_power="2W",use_incident_voltage=True) """ data = {i: ("0W", "0deg", False) for i in self.excitations} - for key, value in excitations.items(): + for key, value in assignment.items(): data[key] = value setting = [] for key, vals in data.items(): @@ -3959,17 +3536,17 @@ def edit_sources( self.osolution.EditSources(arg) return True - @pyaedt_function_handler() - def edit_source(self, portandmode=None, powerin="1W", phase="0deg"): + @pyaedt_function_handler(portandmode="assignment", powerin="power") + def edit_source(self, assignment=None, power="1W", phase="0deg"): """Set up the power loaded for HFSS postprocessing. Parameters ---------- - portandmode : str, optional + assignment : str, optional Port name and mode. For example, ``"Port1:1"``. The port name must be defined if the solution type is other than Eigenmodal. This parameter is ignored if the solution type is Eigenmodal. - powerin : str, optional + power : str, optional Power in watts (W) or the project variable to put as stored energy in the project. The default is ``"1W"``. phase : str, optional @@ -3995,36 +3572,35 @@ def edit_source(self, portandmode=None, powerin="1W", phase="0deg"): ... [-20, 0, 0], 10, ... name="sheet_for_source") >>> hfss.solution_type = "Modal" - >>> wave_port = hfss.create_wave_port_from_sheet(sheet, 5, hfss.AxisDir.XNeg, 40, - ... 2, "SheetWavePort", True) - >>> hfss.edit_source("SheetWavePort" + ":1", "10W") + >>> wave_port = hfss.create_wave_port_from_sheet(sheet,5,hfss.AxisDir.XNeg,40,2,"SheetWavePort",True) + >>> hfss.edit_source("SheetWavePort" + ":1","10W") PyAEDT INFO: Setting up power to "SheetWavePort:1" = 10W True """ if self.solution_type != "Eigenmode": - if portandmode is None: + if assignment is None: self.logger.error("Port and mode must be defined for solution type {}".format(self.solution_type)) return False - self.logger.info('Setting up power to "{}" = {}'.format(portandmode, powerin)) + self.logger.info('Setting up power to "{}" = {}'.format(assignment, power)) self.osolution.EditSources( [ ["IncludePortPostProcessing:=", True, "SpecifySystemPower:=", False], - ["Name:=", portandmode, "Magnitude:=", powerin, "Phase:=", phase], + ["Name:=", assignment, "Magnitude:=", power, "Phase:=", phase], ] ) else: - self.logger.info("Setting up power to Eigenmode = {}".format(powerin)) + self.logger.info("Setting up power to Eigenmode = {}".format(power)) self.osolution.EditSources( - [["FieldType:=", "EigenStoredEnergy"], ["Name:=", "Modes", "Magnitudes:=", [powerin]]] + [["FieldType:=", "EigenStoredEnergy"], ["Name:=", "Modes", "Magnitudes:=", [power]]] ) return True - @pyaedt_function_handler() + @pyaedt_function_handler(portandmode="assignment") def edit_source_from_file( self, - portandmode, + assignment, file_name, is_time_domain=True, x_scale=1, @@ -4038,7 +3614,7 @@ def edit_source_from_file( Parameters ---------- - portandmode : str + assignment : str Port name and mode. For example, ``"Port1:1"``. The port name must be defined if the solution type is other than Eigenmodal. file_name : str @@ -4075,8 +3651,8 @@ def edit_source_from_file( encoding=encoding, out_mag=out, ) - ds_name_mag = "ds_" + portandmode.replace(":", "_mode_") + "_Mag" - ds_name_phase = "ds_" + portandmode.replace(":", "_mode_") + "_Angle" + ds_name_mag = "ds_" + assignment.replace(":", "_mode_") + "_Mag" + ds_name_phase = "ds_" + assignment.replace(":", "_mode_") + "_Angle" if self.dataset_exists(ds_name_mag, False): self.design_datasets[ds_name_mag].x = freq self.design_datasets[ds_name_mag].y = mag @@ -4095,7 +3671,7 @@ def edit_source_from_file( ["IncludePortPostProcessing:=", True, "SpecifySystemPower:=", False], [ "Name:=", - portandmode, + assignment, "Magnitude:=", "pwl({}, Freq)".format(ds_name_mag), "Phase:=", @@ -4122,22 +3698,24 @@ def edit_sources_from_file(self, file_name): self.osolution.LoadSourceWeights(file_name) return True - @pyaedt_function_handler() - def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue=1): + @pyaedt_function_handler( + inputlist="assignment", internalExtr="extrude_internally", internalvalue="internal_extrusion" + ) + def thicken_port_sheets(self, assignment, value, extrude_internally=True, internal_extrusion=1): """Create thickened sheets over a list of input port sheets. This method is built to work with the output of ``modeler.find_port_faces``. Parameters ---------- - inputlist : list + assignment : list List of the sheets to thicken. value : Value in millimeters for thickening the faces. - internalExtr : bool, optional - Whether to extrude the sheets internally (vgoing into the model). + extrude_internally : bool, optional + Whether to extrude the sheets internally (going into the model). The default is ``True``. - internalvalue : optional + internal_extrusion : int, optional Value in millimeters for thickening the sheets internally if ``internalExtr=True``. The default is ``1``. @@ -4161,9 +3739,12 @@ def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue >>> sheet_for_thickness = hfss.modeler.create_circle(hfss.PLANE.YZ, ... [60, 60, 60], 10, ... name="SheetForThickness") - >>> port_for_thickness = hfss.create_wave_port_from_sheet(sheet_for_thickness, 5, hfss.AxisDir.XNeg, - ... 40, 2, "WavePortForThickness", True) - >>> hfss.thicken_port_sheets(["SheetForThickness"], 2) + >>> port_for_thickness = hfss.create_wave_port_from_sheet(sheet_for_thickness,5, + ... hfss.AxisDir.XNeg, + ... 40, + ... 2, + ... "WavePortForThickness",True) + >>> hfss.thicken_port_sheets(["SheetForThickness"],2) PyAEDT INFO: done {} @@ -4174,7 +3755,7 @@ def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue aedt_bounding_box = self.modeler.get_model_bounding_box() aedt_bounding_dim = self.modeler.get_bounding_dimension() directions = {} - for el in inputlist: + for el in assignment: objID = self.modeler.oeditor.GetFaceIDs(el) faceCenter = self.modeler.oeditor.GetFaceCenter(int(objID[0])) directionfound = False @@ -4204,7 +3785,7 @@ def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue directionfound = True else: l = l + min(aedt_bounding_dim) / 2 - for el in inputlist: + for el in assignment: objID = self.modeler.oeditor.GetFaceIDs(el) maxarea = 0 for f in objID: @@ -4247,7 +3828,7 @@ def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue # ports_ID[el] = int(f) except Exception: pass - if internalExtr: + if extrude_internally: objID2 = self.modeler.oeditor.GetFaceIDs(el) for fid in objID2: try: @@ -4262,7 +3843,7 @@ def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue "MoveAlongNormalFlag:=", True, "OffsetDistance:=", - str(internalvalue) + "mm", + str(internal_extrusion) + "mm", "MoveVectorX:=", "0mm", "MoveVectorY:=", @@ -4279,17 +3860,17 @@ def thicken_port_sheets(self, inputlist, value, internalExtr=True, internalvalue # self.modeler_oproject.ClearMessages() return ports_ID - @pyaedt_function_handler() - def validate_full_design(self, dname=None, outputdir=None, ports=None): + @pyaedt_function_handler(dname="design", ouputdir="ouput_dir") + def validate_full_design(self, design=None, ouput_dir=None, ports=None): """Validate a design based on an expected value and save information to the log file. Parameters ---------- - dname : str, optional + design : str, optional Name of the design to validate. The default is ``None``, in which case the current design is used. - outputdir : str, optional + ouput_dir : str, optional Directory to save the log file to. The default is ``None``, in which case the current project path is used. ports : int, optional @@ -4322,19 +3903,19 @@ def validate_full_design(self, dname=None, outputdir=None, ports=None): self.logger.info("Design validation checks.") validation_ok = True val_list = [] - if not dname: - dname = self.design_name - if not outputdir: - outputdir = self.working_directory + if not design: + design = self.design_name + if not ouput_dir: + ouput_dir = self.working_directory pname = self.project_name - validation_log_file = os.path.join(outputdir, pname + "_" + dname + "_validation.log") + validation_log_file = os.path.join(ouput_dir, pname + "_" + design + "_validation.log") # Desktop Messages msg = "Desktop messages:" val_list.append(msg) - temp_msg = list(self._desktop.GetMessages(pname, dname, 0)) + temp_msg = list(self._desktop.GetMessages(pname, design, 0)) if temp_msg: - temp2_msg = [i.strip("Project: " + pname + ", Design: " + dname + ", ").strip("\r\n") for i in temp_msg] + temp2_msg = [i.strip("Project: " + pname + ", Design: " + design + ", ").strip("\r\n") for i in temp_msg] val_list.extend(temp2_msg) # Run design validation and write out the lines to the log. @@ -4412,24 +3993,24 @@ def validate_full_design(self, dname=None, outputdir=None, ports=None): f.write("%s\n" % item) return val_list, validation_ok # Return all the information in a list for later use. - @pyaedt_function_handler() + @pyaedt_function_handler(plot_name="plot", sweep_name="sweep", port_names="ports", port_excited="ports_excited") def create_scattering( - self, plot_name="S Parameter Plot Nominal", sweep_name=None, port_names=None, port_excited=None, variations=None + self, plot="S Parameter Plot Nominal", sweep=None, ports=None, ports_excited=None, variations=None ): """Create an S-parameter report. Parameters ---------- - plot_name : str, optional + plot : str, optional Name of the plot. The default is ``"S Parameter Plot Nominal"``. - sweep_name : str, optional + sweep : str, optional Name of the sweep. The default is ``None``. - port_names : list, optional + ports : list, optional List of port names. The first index, i, in S[i,j]. - The default is ``None``. (include only self-terms) - port_excited : list or str, optional + The default is ``None``. + ports_excited : list or str, optional List of port names. The seconds index, j in S[i,j]. - The default is ``None``. (include only self-terms) + The default is ``None``. variations : str, optional The default is ``None``. @@ -4446,10 +4027,10 @@ def create_scattering( Examples -------- - Create ad S-parameter plot named ``"S Parameter Plot Nominal"`` for a 3-port network. + Create an S-parameter plot named ``"S Parameter Plot Nominal"`` for a 3-port network. plotting S11, S21, S31. The port names are ``P1``, ``P2``, and ``P3``. - >>> hfss.create_scattering(port_names=["P1", "P2", "P3"], port_excited=["P1", "P1", "P1"]) + >>> hfss.create_scattering(ports=["P1", "P2", "P3"],ports_excited=["P1", "P1", "P1"]) True """ @@ -4459,30 +4040,30 @@ def create_scattering( solution_data = "Modal Solution Data" elif "Terminal" in self.solution_type: solution_data = "Terminal Solution Data" - if not port_names: - port_names = self.excitations - if not port_excited: - port_excited = port_names - traces = ["dB(S(" + p + "," + q + "))" for p, q in zip(list(port_names), list(port_excited))] + if not ports: + ports = self.excitations + if not ports_excited: + ports_excited = ports + traces = ["dB(S(" + p + "," + q + "))" for p, q in zip(list(ports), list(ports_excited))] return self.post.create_report( - traces, sweep_name, variations=variations, report_category=solution_data, plotname=plot_name + traces, sweep, variations=variations, report_category=solution_data, plot_name=plot ) - @pyaedt_function_handler() - def create_qfactor_report(self, project_dir, outputlist, setupname, plotname, Xaxis="X"): + @pyaedt_function_handler(outputlist="output", setupname="setup", plotname="name", Xaxis="x_axis") + def create_qfactor_report(self, project_dir, output, setup, name, x_axis="X"): """Export a CSV file of the EigenQ plot. Parameters ---------- project_dir : str Directory to export the CSV file to. - outputlist : list + output : list Output quantity, which in this case is the Q-factor. - setupname : str + setup : str Name of the setup to generate the report from. - plotname : str + name : str Name of the plot. - Xaxis : str, optional + x_axis : str, optional Value for the X axis. The default is ``"X"``. Returns @@ -4499,69 +4080,14 @@ def create_qfactor_report(self, project_dir, outputlist, setupname, plotname, Xa npath = project_dir # Setup arguments list for createReport function - args = [Xaxis + ":=", ["All"]] - args2 = ["X Component:=", Xaxis, "Y Component:=", outputlist] + args = [x_axis + ":=", ["All"]] + args2 = ["X Component:=", x_axis, "Y Component:=", output] self.post.post_oreport_setup.CreateReport( - plotname, "Eigenmode Parameters", "Rectangular Plot", setupname + " : LastAdaptive", [], args, args2, [] + name, "Eigenmode Parameters", "Rectangular Plot", setup + " : LastAdaptive", [], args, args2, [] ) return True - @pyaedt_function_handler() - def export_touchstone( - self, - setup_name=None, - sweep_name=None, - file_name=None, - variations=None, - variations_value=None, - renormalization=False, - impedance=None, - comments=False, - ): - """Export the Touchstone file to a local folder. - - Parameters - ---------- - setup_name : str, optional - Name of the setup that has been solved. - sweep_name : str, optional - Name of the sweep that has been solved. - file_name : str, optional - Full path and name for the Touchstone file. - The default is ``None``, in which case the file is exported to the working directory. - variations : list, optional - List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``. - The default is ``None``. - variations_value : list, optional - List of all parameter variation values. For example, ``["22cel", "100"]``. - The default is ``None``. - renormalization : bool, optional - Perform renormalization before export. - The default is ``False``. - impedance : float, optional - Real impedance value in ohm, for renormalization, if not specified considered 50 ohm. - The default is ``None``. - comments : bool, optional - Include Gamma and Impedance values in comments. - The default is ``False``. - - Returns - ------- - bool - ``True`` when successful, ``False`` when failed. - """ - return self._export_touchstone( - setup_name=setup_name, - sweep_name=sweep_name, - file_name=file_name, - variations=variations, - variations_value=variations_value, - renormalization=renormalization, - impedance=impedance, - comments=comments, - ) - @pyaedt_function_handler() def set_export_touchstone(self, activate, export_dir=""): """Set automatic export of the Touchstone file after simulation. @@ -4598,16 +4124,16 @@ def set_export_touchstone(self, activate, export_dir=""): self.odesign.SetDesignSettings(settings) return True - @pyaedt_function_handler() - def assign_radiation_boundary_to_objects(self, obj_names, boundary_name=""): + @pyaedt_function_handler(obh_names="assignment", boundary_name="name") + def assign_radiation_boundary_to_objects(self, assignment, name=None): """Assign a radiation boundary to one or more objects (usually airbox objects). Parameters ---------- - obj_names : str or list or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : str or list or int or :class:`pyaedt.modeler.cad.object3d.Object3d` One or more object names or IDs. - boundary_name : str, optional - Name of the boundary. The default is ``""``. + name : str, optional + Name of the boundary. The default is ``None``, in which case a name is automatically assigned. Returns ------- @@ -4632,25 +4158,26 @@ def assign_radiation_boundary_to_objects(self, obj_names, boundary_name=""): """ - object_list = self.modeler.convert_to_selections(obj_names, return_list=True) - if boundary_name: - rad_name = boundary_name + object_list = self.modeler.convert_to_selections(assignment, return_list=True) + if name: + rad_name = name else: rad_name = generate_unique_name("Rad_") return self.create_boundary(self.BoundaryType.Radiation, object_list, rad_name) - @pyaedt_function_handler() - def assign_hybrid_region(self, obj_names, boundary_name="", hybrid_region="SBR+"): + @pyaedt_function_handler(obj_names="assignment", boundary_name="name") + def assign_hybrid_region(self, assignment, name=None, hybrid_region="SBR+"): """Assign a hybrid region to one or more objects. Parameters ---------- - obj_names : str or list or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : str or list or int or :class:`pyaedt.modeler.cad.object3d.Object3d` One or more object names or IDs. - boundary_name : str, optional - Name of the boundary. The default is ``""``. + name : str, optional + Name of the boundary. The default is ``None``, in which case a name is automatically assigned. hybrid_region : str, optional - Hybrid region to assign. Options are ``"SBR+"``, ``"IE"``, ``"PO"``. The default is `"SBR+"``. + Hybrid region to assign. The default is `"SBR+"``. Options are ``"IE"``, ``"PO"`` + and ``"SBR+"``. Returns ------- @@ -4675,9 +4202,9 @@ def assign_hybrid_region(self, obj_names, boundary_name="", hybrid_region="SBR+" """ - object_list = self.modeler.convert_to_selections(obj_names, return_list=True) - if boundary_name: - region_name = boundary_name + object_list = self.modeler.convert_to_selections(assignment, return_list=True) + if name: + region_name = name else: region_name = generate_unique_name("Hybrid_") bound = self.create_boundary(self.BoundaryType.Hybrid, object_list, region_name) @@ -4685,16 +4212,16 @@ def assign_hybrid_region(self, obj_names, boundary_name="", hybrid_region="SBR+" bound.props["Type"] = hybrid_region return bound - @pyaedt_function_handler() - def assign_febi(self, obj_names, boundary_name=""): + @pyaedt_function_handler(obj_names="assignment", boundary_name="name") + def assign_febi(self, assignment, name=None): """Assign an FE-BI region to one or more objects. Parameters ---------- - obj_names : str or list or int or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : str or list or int or :class:`pyaedt.modeler.cad.object3d.Object3d` One or more object names or IDs. - boundary_name : str, optional - Name of the boundary. The default is ``""``, in which case a name is automatically assigned. + name : str, optional + Name of the boundary. The default is ``None``, in which case a name is automatically assigned. Returns ------- @@ -4719,25 +4246,25 @@ def assign_febi(self, obj_names, boundary_name=""): """ - object_list = self.modeler.convert_to_selections(obj_names, return_list=True) - if boundary_name: - region_name = boundary_name + object_list = self.modeler.convert_to_selections(assignment, return_list=True) + if name: + region_name = name else: region_name = generate_unique_name("FEBI_") bound = self.create_boundary(self.BoundaryType.FEBI, object_list, region_name) return bound - @pyaedt_function_handler() - def assign_radiation_boundary_to_faces(self, faces_id, boundary_name=""): + @pyaedt_function_handler(faces_id="assignment", boundary_name="name") + def assign_radiation_boundary_to_faces(self, assignment, name=None): """Assign a radiation boundary to one or more faces. Parameters ---------- - faces_id : + assignment : Face ID to assign the boundary condition to. - boundary_name : str, optional - Name of the boundary. The default is ``""``. + name : str, optional + Name of the boundary. The default is ``None``. Returns ------- @@ -4763,9 +4290,9 @@ def assign_radiation_boundary_to_faces(self, faces_id, boundary_name=""): """ - faces_list = self.modeler.convert_to_selections(faces_id, True) - if boundary_name: - rad_name = boundary_name + faces_list = self.modeler.convert_to_selections(assignment, True) + if name: + rad_name = name else: rad_name = generate_unique_name("Rad_") return self.create_boundary(self.BoundaryType.Radiation, faces_list, rad_name) @@ -4817,20 +4344,20 @@ def _create_sbr_doppler_setup( setup1.auto_update = True return setup1 - @pyaedt_function_handler() - def _create_sbr_doppler_sweep(self, setupname, time_var, tstart, tstop, tsweep, parametric_name): + @pyaedt_function_handler(setupname="setup") + def _create_sbr_doppler_sweep(self, setup, time_var, tstart, tstop, tsweep, parametric_name): time_start = self.modeler._arg_with_dim(tstart, "s") time_sweep = self.modeler._arg_with_dim(tsweep, "s") time_stop = self.modeler._arg_with_dim(tstop, "s") sweep_range = "LIN {} {} {}".format(time_start, time_stop, time_sweep) return self.parametrics.add( - time_var, tstart, time_stop, tsweep, "LinearStep", setupname, parametricname=parametric_name + time_var, tstart, time_stop, tsweep, "LinearStep", setup, parametricname=parametric_name ) - @pyaedt_function_handler() + @pyaedt_function_handler(time_var="time_variable", setup_name="setup") def create_sbr_chirp_i_doppler_setup( self, - time_var=None, + time_variable=None, sweep_time_duration=0, center_freq=76.5, resolution=1, @@ -4842,13 +4369,13 @@ def create_sbr_chirp_i_doppler_setup( max_bounces=5, include_coupling_effects=False, doppler_ad_sampling_rate=20, - setup_name=None, + setup=None, ): - """Create an SBR+ Chirp I Setup. + """Create an SBR+ Chirp I setup. Parameters ---------- - time_var : str, optional + time_variable : str, optional Name of the time variable. The default is ``None``, in which case a search for the first time variable is performed. sweep_time_duration : float, optional @@ -4875,7 +4402,7 @@ def create_sbr_chirp_i_doppler_setup( doppler_ad_sampling_rate : float, optional Doppler AD sampling rate to use if ``include_coupling_effects`` is ``True``. The default is ``20``. - setup_name : str, optional + setup : str, optional Name of the setup. The default is ``None``, in which case the active setup is used. Returns @@ -4893,25 +4420,25 @@ def create_sbr_chirp_i_doppler_setup( if self.solution_type != "SBR+": self.logger.error("Method applies only to the SBR+ solution.") return False, False - if not setup_name: - setup_name = generate_unique_name("ChirpI") + if not setup: + setup = generate_unique_name("ChirpI") parametric_name = generate_unique_name("PulseSweep") else: - parametric_name = generate_unique_name(setup_name) + parametric_name = generate_unique_name(setup) - if not time_var: + if not time_variable: for var_name, var in self.variable_manager.independent_variables.items(): if var.unit_system == "Time": - time_var = var_name + time_variable = var_name break - if not time_var: + if not time_variable: self.logger.error( "No time variable is found. Set up or explicitly assign a time variable to the method." ) raise ValueError("No time variable is found.") setup = self._create_sbr_doppler_setup( "ChirpI", - time_var=time_var, + time_var=time_variable, center_freq=center_freq, resolution=resolution, period=period, @@ -4922,20 +4449,20 @@ def create_sbr_chirp_i_doppler_setup( max_bounces=max_bounces, include_coupling_effects=include_coupling_effects, doppler_ad_sampling_rate=doppler_ad_sampling_rate, - setup_name=setup_name, + setup_name=setup, ) if sweep_time_duration > 0: sweeptime = math.ceil(300000000 / (2 * center_freq * 1000000000 * velocity_resolution) * 1000) / 1000 sweep = self._create_sbr_doppler_sweep( - setup.name, time_var, 0, sweep_time_duration, sweeptime, parametric_name + setup.name, time_variable, 0, sweep_time_duration, sweeptime, parametric_name ) return setup, sweep return setup, False - @pyaedt_function_handler() + @pyaedt_function_handler(time_var="time_variable", setup_name="setup") def create_sbr_chirp_iq_doppler_setup( self, - time_var=None, + time_variable=None, sweep_time_duration=0, center_freq=76.5, resolution=1, @@ -4947,13 +4474,13 @@ def create_sbr_chirp_iq_doppler_setup( max_bounces=5, include_coupling_effects=False, doppler_ad_sampling_rate=20, - setup_name=None, + setup=None, ): - """Create an SBR+ Chirp IQ Setup. + """Create an SBR+ Chirp IQ setup. Parameters ---------- - time_var : str, optional + time_variable : str, optional Name of the time variable. The default is ``None``, in which case a search for the first time variable is performed. sweep_time_duration : float, optional @@ -4980,7 +4507,7 @@ def create_sbr_chirp_iq_doppler_setup( doppler_ad_sampling_rate : float, optional Doppler AD sampling rate to use if ``include_coupling_effects`` is ``True``. The default is ``20``. - setup_name : str, optional + setup : str, optional Name of the setup. The default is ``None``, in which case the active setup is used. @@ -4998,21 +4525,21 @@ def create_sbr_chirp_iq_doppler_setup( if self.solution_type != "SBR+": self.logger.error("Method applies only to the SBR+ solution.") return False, False - if not setup_name: - setup_name = generate_unique_name("ChirpIQ") + if not setup: + setup = generate_unique_name("ChirpIQ") parametric_name = generate_unique_name("PulseSweep") else: - parametric_name = generate_unique_name(setup_name) - if not time_var: + parametric_name = generate_unique_name(setup) + if not time_variable: for var_name, var in self.variable_manager.independent_variables.items(): if var.unit_system == "Time": - time_var = var_name + time_variable = var_name break - if not time_var: + if not time_variable: raise ValueError("No Time Variable Found") setup = self._create_sbr_doppler_setup( "ChirpIQ", - time_var=time_var, + time_var=time_variable, center_freq=center_freq, resolution=resolution, period=period, @@ -5023,22 +4550,22 @@ def create_sbr_chirp_iq_doppler_setup( max_bounces=max_bounces, include_coupling_effects=include_coupling_effects, doppler_ad_sampling_rate=doppler_ad_sampling_rate, - setup_name=setup_name, + setup_name=setup, ) if sweep_time_duration > 0: sweeptime = math.ceil(300000000 / (2 * center_freq * 1000000000 * velocity_resolution) * 1000) / 1000 sweep = self._create_sbr_doppler_sweep( - setup.name, time_var, 0, sweep_time_duration, sweeptime, parametric_name + setup.name, time_variable, 0, sweep_time_duration, sweeptime, parametric_name ) return setup, sweep return setup, False - @pyaedt_function_handler() + @pyaedt_function_handler(time_var="time_variable", center_freq="frequency", setup_name="setup") def create_sbr_pulse_doppler_setup( self, - time_var=None, + time_variable=None, sweep_time_duration=0, - center_freq=76.5, + frequency=76.5, resolution=1, period=200, velocity_resolution=0.4, @@ -5046,19 +4573,19 @@ def create_sbr_pulse_doppler_setup( max_velocity=20, ray_density_per_wavelength=0.2, max_bounces=5, - setup_name=None, + setup=None, ): """Create an SBR+ pulse Doppler setup. Parameters ---------- - time_var : str, optional + time_variable : str, optional Name of the time variable. The default is ``None``, in which case a search for the first time variable is performed. sweep_time_duration : float, optional Duration of the sweep time. The default is ``0``. If a value greater than ``0`` is specified, a parametric sweep is created. - center_freq : float, optional + frequency : float, optional Center frequency in gigahertz (GHz). The default is ``76.5``. resolution : float, optional Doppler resolution in meters (m). The default is ``1``. @@ -5077,7 +4604,7 @@ def create_sbr_pulse_doppler_setup( Doppler ray density per wavelength. The default is ``0.2``. max_bounces : int, optional Maximum number of bounces. The default is ``5``. - setup_name : str, optional + setup : str, optional Name of the setup. The default is ``None``, in which case the active setup is used. @@ -5095,23 +4622,23 @@ def create_sbr_pulse_doppler_setup( if self.solution_type != "SBR+": self.logger.error("Method Applies only to SBR+ Solution.") return False, False - if not setup_name: - setup_name = generate_unique_name("PulseSetup") + if not setup: + setup = generate_unique_name("PulseSetup") parametric_name = generate_unique_name("PulseSweep") else: - parametric_name = generate_unique_name(setup_name) + parametric_name = generate_unique_name(setup) - if not time_var: + if not time_variable: for var_name, var in self.variable_manager.independent_variables.items(): if var.unit_system == "Time": - time_var = var_name + time_variable = var_name break - if not time_var: + if not time_variable: raise ValueError("No Time Variable Found") setup = self._create_sbr_doppler_setup( "PulseDoppler", - time_var=time_var, - center_freq=center_freq, + time_var=time_variable, + center_freq=frequency, resolution=resolution, period=period, velocity_resolution=velocity_resolution, @@ -5119,21 +4646,21 @@ def create_sbr_pulse_doppler_setup( max_velocity=max_velocity, ray_density_per_wavelength=ray_density_per_wavelength, max_bounces=max_bounces, - setup_name=setup_name, + setup_name=setup, ) if sweep_time_duration > 0: - sweeptime = math.ceil(300000000 / (2 * center_freq * 1000000000 * velocity_resolution) * 1000) / 1000 + sweeptime = math.ceil(300000000 / (2 * frequency * 1000000000 * velocity_resolution) * 1000) / 1000 sweep = self._create_sbr_doppler_sweep( - setup.name, time_var, 0, sweep_time_duration, sweeptime, parametric_name + setup.name, time_variable, 0, sweep_time_duration, sweeptime, parametric_name ) return setup, sweep return setup, False - @pyaedt_function_handler() + @pyaedt_function_handler(radar_name="name") def create_sbr_radar_from_json( - self, radar_file, radar_name, offset=[0, 0, 0], speed=0.0, use_relative_cs=False, relative_cs_name=None + self, radar_file, name, offset=None, speed=0.0, use_relative_cs=False, relative_cs_name=None ): - """Create an SBR+ radar from a JSON file. + """Create an SBR+ radar setup from a JSON file. Example of input JSON file: @@ -5173,7 +4700,7 @@ def create_sbr_radar_from_json( ---------- radar_file : str Path to the directory with the radar file. - radar_name : str + name : str Name of the radar file. offset : list, optional Offset relative to the global coordinate system. @@ -5198,6 +4725,8 @@ def create_sbr_radar_from_json( >>> oModule.SetSBRTxRxSettings >>> oEditor.CreateGroup """ + if offset is None: + offset = [0, 0, 0] from pyaedt.modeler.advanced_cad.actors import Radar self.modeler._initialize_multipart() @@ -5207,7 +4736,7 @@ def create_sbr_radar_from_json( use_motion = abs(speed) > 0.0 r = Radar( radar_file, - name=radar_name, + name=name, motion=use_motion, offset=offset, speed=speed, @@ -5539,10 +5068,10 @@ def insert_near_field_rectangle( return bound return False - @pyaedt_function_handler() + @pyaedt_function_handler(line="assignment") def insert_near_field_line( self, - line, + assignment, points=1000, custom_radiation_faces=None, name=None, @@ -5554,7 +5083,7 @@ def insert_near_field_line( Parameters ---------- - line : str + assignment : str Polyline name. points : float, str, optional Number of points. The default value is ``1000``. @@ -5579,7 +5108,7 @@ def insert_near_field_line( props["CustomRadiationSurface"] = "" props["NumPts"] = points - props["Line"] = line + props["Line"] = assignment bound = NearFieldSetup(self, name, props, "NearFieldLine") if bound.create(): @@ -5630,15 +5159,22 @@ def set_sbr_current_sources_options(self, conformance=False, thin_sources=False, self.logger.info("SBR+ current source options correctly applied.") return True - @pyaedt_function_handler() + @pyaedt_function_handler( + positive_terminal="assignment", + negative_terminal="reference", + common_name="common_mode", + diff_name="differential_mode", + common_ref="common_reference", + diff_ref_z="differential_reference", + ) def set_differential_pair( self, - positive_terminal, - negative_terminal, - common_name=None, - diff_name=None, - common_ref_z=25, - diff_ref_z=100, + assignment, + reference, + common_mode=None, + differential_mode=None, + common_reference=25, + differential_reference=100, active=True, matched=False, ): @@ -5650,17 +5186,17 @@ def set_differential_pair( Parameters ---------- - positive_terminal : str + assignment : str Name of the terminal to use as the positive terminal. - negative_terminal : str + reference : str Name of the terminal to use as the negative terminal. - common_name : str, optional + common_mode : str, optional Name for the common mode. The default is ``None``, in which case a unique name is assigned. - diff_name : str, optional + differential_mode : str, optional Name for the differential mode. The default is ``None``, in which case a unique name is assigned. - common_ref_z : float, optional + common_reference : float, optional Reference impedance for the common mode in ohms. The default is ``25``. - diff_ref_z : float, optional + differential_reference : float, optional Reference impedance for the differential mode in ohms. The default is ``100``. active : bool, optional Whether the differential pair is active. The default is ``True``. @@ -5681,16 +5217,18 @@ def set_differential_pair( raise AttributeError("Differential pairs can be defined only in Terminal and Transient solution types.") props = OrderedDict() - props["PosBoundary"] = positive_terminal - props["NegBoundary"] = negative_terminal - if not common_name: + props["PosBoundary"] = assignment + props["NegBoundary"] = reference + if not common_mode: common_name = generate_unique_name("Comm") + else: + common_name = common_mode props["CommonName"] = common_name - props["CommonRefZ"] = str(common_ref_z) + "ohm" - if not diff_name: - diff_name = generate_unique_name("Diff") - props["DiffName"] = diff_name - props["DiffRefZ"] = str(diff_ref_z) + "ohm" + props["CommonRefZ"] = str(common_reference) + "ohm" + if not differential_mode: + differential_mode = generate_unique_name("Diff") + props["DiffName"] = differential_mode + props["DiffRefZ"] = str(differential_reference) + "ohm" props["IsActive"] = active props["UseMatched"] = matched arg = ["NAME:" + generate_unique_name("Pair")] @@ -5714,17 +5252,17 @@ def set_differential_pair( else: return False - @pyaedt_function_handler() - def add_3d_component_array_from_json(self, json_file, array_name=None): - """Add or edit a new 3D component array from a JSON file or TOML file. + @pyaedt_function_handler(array_name="name", json_file="input_data") + def add_3d_component_array_from_json(self, input_data, name=None): + """Add or edit a 3D component array from a JSON file or TOML file. The 3D component is placed in the layout if it is not present. Parameters ---------- - json_file : str, dict + input_data : str, dict Full path to either the JSON file or dictionary containing the array information. - array_name : str, optional - Name of the boundary to create or edit. + name : str, optional + Name of the boundary to add or edit. Returns ------- @@ -5769,14 +5307,14 @@ def add_3d_component_array_from_json(self, json_file, array_name=None): >>> component_array = hfss_app.add_3d_component_array_from_json(dict_in) """ self.hybrid = True - if isinstance(json_file, dict): - json_dict = json_file + if isinstance(input_data, dict): + json_dict = input_data else: - json_dict = read_configuration_file(json_file) - if not array_name and self.omodelsetup.IsArrayDefined(): - array_name = self.omodelsetup.GetArrayNames()[0] - elif not array_name: - array_name = generate_unique_name("Array") + json_dict = read_configuration_file(input_data) + if not name and self.omodelsetup.IsArrayDefined(): + name = self.omodelsetup.GetArrayNames()[0] + elif not name: + name = generate_unique_name("Array") cells_names = {} cells_color = {} @@ -5823,9 +5361,9 @@ def add_3d_component_array_from_json(self, json_file, array_name=None): secondary_lattice = self.omodelsetup.GetLatticeVectors()[1] args = [ - "NAME:" + array_name, + "NAME:" + name, "Name:=", - array_name, + name, "UseAirObjects:=", json_dict.get("useairobjects", True), "RowPrimaryBnd:=", @@ -5884,16 +5422,16 @@ def add_3d_component_array_from_json(self, json_file, array_name=None): self.omodelsetup.AssignArray(args) # Save project, because coordinate system information can not be obtained from AEDT API self.save_project() - self.component_array[array_name] = ComponentArray(self, array_name) - self.component_array_names = [array_name] - return self.component_array[array_name] + self.component_array[name] = ComponentArray(self, name) + self.component_array_names = [name] + return self.component_array[name] - @pyaedt_function_handler() + @pyaedt_function_handler(setup_name="setup", sphere_name="sphere") def get_antenna_ffd_solution_data( self, frequencies, - setup_name=None, - sphere_name=None, + setup=None, + sphere=None, variations=None, overwrite=True, ): @@ -5905,9 +5443,9 @@ def get_antenna_ffd_solution_data( ---------- frequencies : float, list Frequency value or list of frequencies to compute far field data. - setup_name : str, optional + setup : str, optional Name of the setup to use. The default is ``None,`` in which case ``nominal_adaptive`` is used. - sphere_name : str, optional + sphere : str, optional Infinite sphere to use. The default is ``None``, in which case an existing sphere is used or a new one is created. variations : dict, optional @@ -5924,32 +5462,32 @@ def get_antenna_ffd_solution_data( if not variations: variations = self.available_variations.nominal_w_values_dict_w_dependent - if not setup_name: - setup_name = self.nominal_adaptive - if sphere_name: + if not setup: + setup = self.nominal_adaptive + if sphere: names = [i.name for i in self.field_setups] - if sphere_name in names: - self.logger.info("Far field sphere %s is assigned", sphere_name) + if sphere in names: + self.logger.info("Far field sphere %s is assigned", sphere) else: self.insert_infinite_sphere( - x_start=0, x_stop=180, x_step=5, y_start=-180, y_stop=180, y_step=5, name=sphere_name + x_start=0, x_stop=180, x_step=5, y_start=-180, y_stop=180, y_step=5, name=sphere ) - self.logger.info("Far field sphere %s is created.", sphere_name) + self.logger.info("Far field sphere %s is created.", sphere) elif self.field_setups: - sphere_name = self.field_setups[0].name - self.logger.info("No far field sphere is defined. Using %s", sphere_name) + sphere = self.field_setups[0].name + self.logger.info("No far field sphere is defined. Using %s", sphere) else: - sphere_name = "Infinite Sphere1" + sphere = "Infinite Sphere1" self.insert_infinite_sphere( - x_start=0, x_stop=180, x_step=5, y_start=-180, y_stop=180, y_step=5, name=sphere_name + x_start=0, x_stop=180, x_step=5, y_start=-180, y_stop=180, y_step=5, name=sphere ) - self.logger.info("Far field sphere %s is created.", setup_name) + self.logger.info("Far field sphere %s is created.", setup) return FfdSolutionDataExporter( self, - sphere_name=sphere_name, - setup_name=setup_name, + sphere_name=sphere, + setup_name=setup, frequencies=frequencies, variations=variations, overwrite=overwrite, @@ -5975,17 +5513,17 @@ def set_material_threshold(self, threshold=100000): except Exception: return False - @pyaedt_function_handler() - def assign_symmetry(self, entity_list, symmetry_name=None, is_perfect_e=True): + @pyaedt_function_handler(entity_list="assignment", simmetry_name="name") + def assign_symmetry(self, assignment, name=None, is_perfect_e=True): """Assign symmetry to planar entities. Parameters ---------- - entity_list : list + assignment : list List of IDs or :class:`pyaedt.modeler.Object3d.FacePrimitive`. - symmetry_name : str, optional + name : str, optional Name of the boundary. - If not provided it's automatically generated. + If a name is not provided, one is automatically generated. is_perfect_e : bool, optional Type of symmetry plane the boundary represents: Perfect E or Perfect H. The default value is ``True`` (Perfect E). @@ -6018,17 +5556,17 @@ def assign_symmetry(self, entity_list, symmetry_name=None, is_perfect_e=True): self.logger.error("Symmetry is only available with 'Modal' and 'Eigenmode' solution types.") return False - if symmetry_name is None: - symmetry_name = generate_unique_name("Symmetry") + if name is None: + name = generate_unique_name("Symmetry") - if not isinstance(entity_list, list): + if not isinstance(assignment, list): self.logger.error("Entities have to be provided as a list.") return False - entity_list = self.modeler.convert_to_selections(entity_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) - props = OrderedDict({"Name": symmetry_name, "Faces": entity_list, "IsPerfectE": is_perfect_e}) - return self._create_boundary(symmetry_name, props, "Symmetry") + props = OrderedDict({"Name": name, "Faces": assignment, "IsPerfectE": is_perfect_e}) + return self._create_boundary(name, props, "Symmetry") except Exception: return False @@ -6107,9 +5645,9 @@ def set_phase_center_per_port(self, coordinate_system=None): self.logger.warning("Set phase center is not supported by AEDT COM API. Set phase center manually.") return False - port_names = [] - for exc in self.design_excitations: - port_names.append(exc.name) + port_names = self.ports[::] + # for exc in self.design_excitations: + # port_names.append(exc.name) if not port_names: # pragma: no cover return False @@ -6133,56 +5671,14 @@ def set_phase_center_per_port(self, coordinate_system=None): return False return True - @pyaedt_function_handler() - def get_touchstone_data(self, setup_name, sweep_name=None, variation_dict=None): - """ - Return a Touchstone data plot. - - Parameters - ---------- - setup_name : list - List of the curves to plot. - sweep_name : str, optional - Name of the solution. The default value is ``None``. - variation_dict : dict, optional - Dictionary of variation names. The default value is ``None``. - - Returns - ------- - :class:`pyaedt.generic.touchstone_parser.TouchstoneData` - Class containing all requested data. - - References - ---------- - - >>> oModule.GetSolutionDataPerVariation - """ - from pyaedt.generic.touchstone_parser import TouchstoneData - - if not setup_name: - setup_name = self.setups[0].name - - if not sweep_name: - for setup in self.setups: - if setup.name == setup_name: - sweep_name = setup.sweeps[0].name - s_parameters = [] - solution = "{} : {}".format(setup_name, sweep_name) - expression = self.get_traces_for_plot(category="S") - sol_data = self.post.get_solution_data(expression, solution, variations=variation_dict) - for i in range(sol_data.number_of_variations): - sol_data.set_active_variation(i) - s_parameters.append(TouchstoneData(solution_data=sol_data)) - return s_parameters - - @pyaedt_function_handler() - def parse_hdm_file(self, filename): + @pyaedt_function_handler(filename="file_name") + def parse_hdm_file(self, file_name): """Parse an HFSS SBR+ or Creeping Waves ``hdm`` file. Parameters ---------- - filename : str - File to parse. + file_name : str + Name of the file to parse. Returns ------- @@ -6191,17 +5687,17 @@ def parse_hdm_file(self, filename): from pyaedt.sbrplus.hdm_parser import Parser - if os.path.exists(filename): - return Parser(filename).parse_message() + if os.path.exists(file_name): + return Parser(file_name).parse_message() return False - @pyaedt_function_handler() - def get_hdm_plotter(self, filename=None): - """Get the ``HDMPlotter``. + @pyaedt_function_handler(filename="file_name") + def get_hdm_plotter(self, file_name=None): + """Get the HDM plotter``. Parameters ---------- - filename : str, optional + file_name : str, optional Returns @@ -6212,19 +5708,16 @@ def get_hdm_plotter(self, filename=None): from pyaedt.sbrplus.plot import HDMPlotter hdm = HDMPlotter() - files = self.post.export_model_obj( - export_as_single_objects=True, - air_objects=False, - ) + files = self.post.export_model_obj(export_as_single_objects=True, air_objects=False) for file in files: hdm.add_cad_model(file[0], file[1], file[2], self.modeler.model_units) - hdm.add_hdm_bundle_from_file(filename) + hdm.add_hdm_bundle_from_file(file_name) return hdm - @pyaedt_function_handler() + @pyaedt_function_handler(signal="assignment") def circuit_port( self, - signal, + assignment, reference, port_location=0, impedance=50, @@ -6239,7 +5732,7 @@ def circuit_port( Parameters ---------- - signal : int or :class:`pyaedt.modeler.cad.object3d.Object3d` or + assignment : int or :class:`pyaedt.modeler.cad.object3d.Object3d` or :class:`pyaedt.modeler.cad.FacePrimitive`or :class:`pyaedt.modeler.cad.EdgePrimitive` Signal object. reference : int or :class:`pyaedt.modeler.cad.object3d.Object3d` or @@ -6291,29 +5784,31 @@ def circuit_port( >>> edges2 = hfss.modeler.get_object_edges(rectangle2.id) >>> second_edge = edges2[0] >>> hfss.solution_type = "Modal" - >>> hfss.circuit_port(first_edge, second_edge, name="PortExample", - ... impedance=50.1, renormalize=False, + >>> hfss.circuit_port(first_edge,second_edge, + ... impedance=50.1, + ... name="PortExample", + ... renormalize=False, ... renorm_impedance="50") 'PortExample' """ if self.solution_type in ["Modal", "Terminal", "Transient Network"]: - if not self.modeler.does_object_exists(signal) or not self.modeler.does_object_exists(reference): - out = self.modeler.convert_to_selections([signal, reference], True) + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): + out = self.modeler.convert_to_selections([assignment, reference], True) if isinstance(out[0], str) or isinstance(out[1], str): self.logger.error("Failed to create circuit port.") return False else: - out, parallel = self.modeler.find_closest_edges(signal, reference, port_location) + out, parallel = self.modeler.find_closest_edges(assignment, reference, port_location) name = self._get_unique_source_name(name, "Port") return self._create_circuit_port( out, impedance, name, renormalize, deembed, renorm_impedance=renorm_impedance ) return False - @pyaedt_function_handler() + @pyaedt_function_handler(signal="assignment") def lumped_port( self, - signal, + assignment, reference=None, create_port_sheet=False, port_on_plane=True, @@ -6328,7 +5823,7 @@ def lumped_port( Parameters ---------- - signal : str, int, list, :class:`pyaedt.modeler.cad.object3d.Object3d` or + assignment : str, int, list, :class:`pyaedt.modeler.cad.object3d.Object3d` or :class:`pyaedt.modeler.elements3d.FacePrimitive` Main object for port creation or starting object for the integration line. reference : int, list or :class:`pyaedt.modeler.cad.object3d.Object3d` @@ -6369,37 +5864,35 @@ def lumped_port( ... "BoxLumped1","copper") >>> box2 = hfss.modeler.create_box([0, 0, 60], [10, 10, 5], ... "BoxLumped2", "copper") - >>> hfss.lumped_port("BoxLumped1", "BoxLumped2", - ... hfss.AxisDir.XNeg, 50, - ... "LumpedPort", True, False) + >>> hfss.lumped_port("BoxLumped1","BoxLumped2",hfss.AxisDir.XNeg,50,"LumpedPort",True,False) PyAEDT INFO: Connection Correctly created 'LumpedPort' """ if create_port_sheet: - signal = self.modeler.convert_to_selections(signal) + assignment = self.modeler.convert_to_selections(assignment) reference = self.modeler.convert_to_selections(reference) - if not self.modeler.does_object_exists(signal) or not self.modeler.does_object_exists(reference): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects do not exist. Check and retry.") return False sheet_name, point0, point1 = self.modeler._create_sheet_from_object_closest_edge( - signal, reference, integration_line, port_on_plane + assignment, reference, integration_line, port_on_plane ) else: - if isinstance(signal, list): - objs = self.modeler.get_faceid_from_position(signal) + if isinstance(assignment, list): + objs = self.modeler.get_faceid_from_position(assignment) if len(objs) == 1: - signal = objs[0] + assignment = objs[0] elif len(objs) > 1: - self.logger.warning("More than 1 face found. Getting first.") - signal = objs[0] + self.logger.warning("More than one face was found. Getting the first one.") + assignment = objs[0] else: self.logger.error("No Faces found on given location.") return False - sheet_name = self.modeler.convert_to_selections(signal, False) + sheet_name = self.modeler.convert_to_selections(assignment, False) if isinstance(integration_line, list): if len(integration_line) != 2 or len(integration_line[0]) != len(integration_line[1]): - self.logger.error("List of coordinates is not set correctly") + self.logger.error("List of coordinates is not set correctly.") return False point0 = integration_line[0] point1 = integration_line[1] @@ -6428,16 +5921,16 @@ def lumped_port( ) return False - @pyaedt_function_handler() + @pyaedt_function_handler(signal="assignment", num_modes="modes") def wave_port( self, - signal, + assignment, reference=None, create_port_sheet=False, create_pec_cap=False, integration_line=0, port_on_plane=True, - num_modes=1, + modes=1, impedance=50, name=None, renormalize=True, @@ -6451,7 +5944,7 @@ def wave_port( Parameters ---------- - signal : int, str, :class:`pyaedt.modeler.cad.object3d.Object3d` or + assignment : int, str, :class:`pyaedt.modeler.cad.object3d.Object3d` or :class:`pyaedt.modeler.elements3d.FacePrimitive` Main object for port creation or starting object for the integration line. reference : int, str, list or :class:`pyaedt.modeler.cad.object3d.Object3d` @@ -6471,10 +5964,11 @@ def wave_port( The default is ``True``. impedance : float, optional Port impedance. The default is ``50``. - num_modes : int, optional + modes : int, optional Number of modes. The default is ``1``. name : str, optional - name of the port. The default is ``None``. + Name of the port. The default is ``None``, in which + case a name is automatically assigned. renormalize : bool, optional Whether to renormalize the mode. The default is ``True``. deembed : float, optional @@ -6510,41 +6004,39 @@ def wave_port( ... name="SUB1", matname="FR4_epoxy") >>> gnd = hfss.modeler.create_box([0, 5, -2.2], [20, 100, 0.2], ... name="GND1", matname="FR4_epoxy") - >>> port = hfss.wave_port("GND1", "MS1", - ... name="MS1", - ... integration_line=1) + >>> port = hfss.wave_port("GND1","MS1",integration_line=1,name="MS1") PyAEDT INFO: Connection correctly created. """ oname = "" if create_port_sheet: - if not self.modeler.does_object_exists(signal) or not self.modeler.does_object_exists(reference): + if not self.modeler.does_object_exists(assignment) or not self.modeler.does_object_exists(reference): self.logger.error("One or both objects do not exist. Check and retry.") return False - elif isinstance(signal, cad.elements3d.FacePrimitive): - port_sheet = signal.create_object() + elif isinstance(assignment, cad.elements3d.FacePrimitive): + port_sheet = assignment.create_object() oname = port_sheet.name if is_microstrip: sheet_name, int_start, int_stop = self.modeler._create_microstrip_sheet_from_object_closest_edge( - signal, reference, integration_line, vfactor, hfactor + assignment, reference, integration_line, vfactor, hfactor ) else: sheet_name, int_start, int_stop = self.modeler._create_sheet_from_object_closest_edge( - signal, reference, integration_line, port_on_plane + assignment, reference, integration_line, port_on_plane ) else: - if isinstance(signal, list): - objs = self.modeler.get_faceid_from_position(signal) + if isinstance(assignment, list): + objs = self.modeler.get_faceid_from_position(assignment) if len(objs) == 1: - signal = objs[0] + assignment = objs[0] elif len(objs) > 1: - self.logger.warning("More than 1 face found. Getting first.") - signal = objs[0] + self.logger.warning("More than one face found. Getting first.") + assignment = objs[0] else: - self.logger.error("No Faces found on given location.") + self.logger.error("No faces were found on given location.") return False - sheet_name = self.modeler.convert_to_selections(signal, True)[0] + sheet_name = self.modeler.convert_to_selections(assignment, True)[0] if isinstance(sheet_name, int): try: # NOte: if isinstance(sheet_name, cad.elements3d.FacePrimitive) then @@ -6586,14 +6078,14 @@ def wave_port( face = sheet_name dist = math.sqrt(self.modeler[face].faces[0].area) # TODO: Move this into _create_pec_cap if settings.aedt_version > "2022.2": - self._create_pec_cap(face, signal, -dist / 10) + self._create_pec_cap(face, assignment, -dist / 10) else: - self._create_pec_cap(face, signal, dist / 10) + self._create_pec_cap(face, assignment, dist / 10) name = self._get_unique_source_name(name, "Port") if "Modal" in self.solution_type: return self._create_waveport_driven( - sheet_name, int_start, int_stop, impedance, name, renormalize, num_modes, deembed + sheet_name, int_start, int_stop, impedance, name, renormalize, modes, deembed ) elif reference: if isinstance(sheet_name, int): @@ -6637,11 +6129,11 @@ def set_radiated_power_calc_method(self, method="Auto"): self.oradfield.EditRadiatedPowerCalculationMethod(method) return True - @pyaedt_function_handler() - def set_mesh_fusion_settings(self, component=None, volume_padding=None, priority=None): + @pyaedt_function_handler(component="assignment") + def set_mesh_fusion_settings(self, assignment=None, volume_padding=None, priority=None): # type: (list|str, list, list) -> bool - """Set mesh fusion settings in Hfss. + """Set mesh fusion settings in HFSS. component : list, optional List of active 3D Components. @@ -6667,19 +6159,18 @@ def set_mesh_fusion_settings(self, component=None, volume_padding=None, priority >>> import pyaedt >>> app = pyaedt.Hfss() - >>> app.set_mesh_fusion_settings(component=["Comp1", "Comp2"], - ... volume_padding=[[0,0,0,0,0,0], [0,0,5,0,0,0]], - ... priority=["Comp1"]) + >>> app.set_mesh_fusion_settings(assignment=["Comp1", "Comp2"], + >>> volume_padding=[[0,0,0,0,0,0], [0,0,5,0,0,0]],priority=["Comp1"]) """ arg = ["NAME:AllSettings"] arg2 = ["NAME:MeshAssembly"] arg3 = ["NAME:Priority Components"] - if component and not isinstance(component, list): - component = [component] + if assignment and not isinstance(assignment, list): + assignment = [assignment] - if not volume_padding and component: - for comp in component: + if not volume_padding and assignment: + for comp in assignment: if comp in self.modeler.user_defined_component_names: mesh_assembly_arg = ["NAME:" + comp] mesh_assembly_arg.append("MeshAssemblyBoundingVolumePadding:=") @@ -6688,9 +6179,9 @@ def set_mesh_fusion_settings(self, component=None, volume_padding=None, priority else: self.logger.warning(comp + " does not exist.") - elif component and isinstance(volume_padding, list) and len(volume_padding) == len(component): + elif assignment and isinstance(volume_padding, list) and len(volume_padding) == len(assignment): count = 0 - for comp in component: + for comp in assignment: padding = [str(pad) for pad in volume_padding[count]] if comp in self.modeler.user_defined_component_names: mesh_assembly_arg = ["NAME:" + comp] @@ -6700,14 +6191,14 @@ def set_mesh_fusion_settings(self, component=None, volume_padding=None, priority else: self.logger.warning("{0} does not exist".format(str(comp))) count += 1 - elif component and isinstance(volume_padding, list) and len(volume_padding) != len(component): + elif assignment and isinstance(volume_padding, list) and len(volume_padding) != len(assignment): self.logger.error("Volume padding length is different than component list length.") return False if priority and not isinstance(priority, list): priority = [priority] - if component and priority: + if assignment and priority: for p in priority: if p in self.modeler.user_defined_component_names: arg3.append(p) diff --git a/pyaedt/hfss3dlayout.py b/pyaedt/hfss3dlayout.py index 5b4add8890c..d1c60a88b57 100644 --- a/pyaedt/hfss3dlayout.py +++ b/pyaedt/hfss3dlayout.py @@ -10,6 +10,7 @@ from pyaedt import is_ironpython from pyaedt.application.Analysis3DLayout import FieldAnalysis3DLayout +from pyaedt.application.analysis_hf import ScatteringMethods from pyaedt.generic.general_methods import generate_unique_name from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import parse_excitation_file @@ -20,7 +21,7 @@ from pyaedt.modules.Boundary import BoundaryObject3dLayout -class Hfss3dLayout(FieldAnalysis3DLayout): +class Hfss3dLayout(FieldAnalysis3DLayout, ScatteringMethods): """Provides the HFSS 3D Layout application interface. This class inherits all objects that belong to HFSS 3D Layout, including EDB @@ -144,6 +145,7 @@ def __init__( port, aedt_process_id, ) + ScatteringMethods.__init__(self, self) def _init_from_design(self, *args, **kwargs): self.__init__(*args, **kwargs) @@ -354,8 +356,8 @@ def create_wave_port_from_two_conductors(self, primivitivenames=[""], edgenumber if len(a) > 0: bound = self._update_port_info(a[0]) if bound: - self.boundaries.append(bound) - return self.boundaries[-1] + self._boundaries[bound.name] = bound + return bound else: return False else: @@ -363,6 +365,25 @@ def create_wave_port_from_two_conductors(self, primivitivenames=[""], edgenumber else: return False + @pyaedt_function_handler() + def dissolve_component(self, component_name): + """Dissolve a component and remove it from 3D Layout. + + Parameters + ---------- + component_name : str + Name of the component. + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + + + """ + self.oeditor.DissolveComponents(["NAME:elements", component_name]) + return True + @pyaedt_function_handler() def create_ports_on_component_by_nets( self, @@ -407,9 +428,43 @@ def create_ports_on_component_by_nets( ports.append(bound) return ports + @pyaedt_function_handler() + def create_pec_on_component_by_nets( + self, + component_name, + nets, + ): + """Create a PEC connection on a component for a list of nets. + + Parameters + ---------- + component_name : str + Component name. + nets : str, list + Nets to include. + + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + + References + ---------- + + >>> oEditor.CreateEdgePort + """ + if isinstance(nets, list): + pass + else: + nets = [nets] + net_array = ["NAME:Nets"] + nets + self.oeditor.CreatePortsOnComponentsByNet(["NAME:Components", component_name], net_array, "PEC", "0", "0", "0") + return True + @pyaedt_function_handler() def create_differential_port(self, via_signal, via_reference, port_name, deembed=True): - """Create a new differential port. + """Create a differential port. Parameters ---------- @@ -449,8 +504,8 @@ def create_differential_port(self, via_signal, via_reference, port_name, deembed ) bound = self._update_port_info(port_name) if bound: - self.boundaries.append(bound) - return self.boundaries[-1] + self._boundaries[bound.name] = bound + return bound else: return False else: @@ -769,68 +824,7 @@ def create_scattering( port_excited = port_names traces = ["dB(S(" + p + "," + q + "))" for p, q in zip(list(port_names), list(port_excited))] return self.post.create_report( - traces, sweep_name, variations=variations, report_category=solution_data, plotname=plot_name - ) - - @pyaedt_function_handler() - def export_touchstone( - self, - setup_name=None, - sweep_name=None, - file_name=None, - variations=None, - variations_value=None, - renormalization=False, - impedance=None, - gamma_impedance_comments=False, - ): - """Export a Touchstone file. - - Parameters - ---------- - setup_name : str, optional - Name of the setup that has been solved. - sweep_name : str, optional - Name of the sweep that has been solved. - file_name : str, optional - Full path and name for the Touchstone file. - The default is ``None``, in which case the Touchstone file is exported to - the working directory. - variations : list, optional - List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``. - The default is ``None``. - variations_value : list, optional - List of all parameter variation values. For example, ``["22cel", "100"]``. - The default is ``None``. - renormalization : bool, optional - Perform renormalization before export. - The default is ``False``. - impedance : float, optional - Real impedance value in ohm, for renormalization, if not specified considered 50 ohm. - The default is ``None``. - gamma_impedance_comments : bool, optional - Include Gamma and Impedance values in comments. - The default is ``False``. - - Returns - ------- - str - Filename when successful, ``False`` when failed. - - References - ---------- - - >>> oDesign.ExportNetworkData - """ - return self._export_touchstone( - setup_name=setup_name, - sweep_name=sweep_name, - file_name=file_name, - variations=variations, - variations_value=variations_value, - renormalization=renormalization, - impedance=impedance, - comments=gamma_impedance_comments, + traces, sweep_name, variations=variations, report_category=solution_data, plot_name=plot_name ) @pyaedt_function_handler() @@ -903,15 +897,17 @@ def set_meshing_settings(self, mesh_method="Phi", enable_intersections_check=Tru self.odesign.DesignOptions(settings, 0) return True - @pyaedt_function_handler() + @pyaedt_function_handler( + setupname="setup", freqstart="start_frequency", freqstop="stop_frequency", sweepname="name" + ) def create_linear_count_sweep( self, - setupname, + setup, unit, - freqstart, - freqstop, + start_frequency, + stop_frequency, num_of_freq_points, - sweepname=None, + name=None, save_fields=True, save_rad_fields_only=False, sweep_type="Interpolating", @@ -923,18 +919,19 @@ def create_linear_count_sweep( Parameters ---------- - setupname : str + setup : str Name of the setup to attach to the sweep. unit : str Unit of the frequency. For example, ``"MHz"`` or ``"GHz"``. - freqstart : float + start_frequency : float Starting frequency of the sweep. - freqstop : float + stop_frequency : float Stopping frequency of the sweep. num_of_freq_points : int Number of frequency points in the range. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save fields for a discrete sweep only. The default is ``True``. @@ -968,8 +965,10 @@ def create_linear_count_sweep( raise AttributeError( "Invalid value for `sweep_type`. The value must be 'Discrete', 'Interpolating', or 'Fast'." ) - if sweepname is None: - sweepname = generate_unique_name("Sweep") + if name is None: + sweep_name = generate_unique_name("Sweep") + else: + sweep_name = name interpolation = False if sweep_type == "Interpolating": @@ -982,39 +981,41 @@ def create_linear_count_sweep( interpolation_tol = interpolation_tol_percent / 100.0 for s in self.setups: - if s.name == setupname: + if s.name == setup: setupdata = s - if sweepname in [sweep.name for sweep in setupdata.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) + if sweep_name in [sweep.name for sweep in setupdata.sweeps]: + oldname = sweep_name + sweep_name = generate_unique_name(oldname) self.logger.warning( - "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname + "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweep_name ) - sweep = setupdata.add_sweep(sweepname=sweepname) - if not sweep: + name = setupdata.add_sweep(name=sweep_name) + if not name: return False - sweep.change_range("LinearCount", freqstart, freqstop, num_of_freq_points, unit) - sweep.props["GenerateSurfaceCurrent"] = save_fields - sweep.props["SaveRadFieldsOnly"] = save_rad_fields_only - sweep.props["FastSweep"] = interpolation - sweep.props["SAbsError"] = interpolation_tol - sweep.props["EnforcePassivity"] = interpolation - sweep.props["UseQ3DForDC"] = use_q3d_for_dc - sweep.props["MaxSolutions"] = interpolation_max_solutions - sweep.update() - self.logger.info("Linear count sweep %s has been correctly created.", sweepname) - return sweep + name.change_range("LinearCount", start_frequency, stop_frequency, num_of_freq_points, unit) + name.props["GenerateSurfaceCurrent"] = save_fields + name.props["SaveRadFieldsOnly"] = save_rad_fields_only + name.props["FastSweep"] = interpolation + name.props["SAbsError"] = interpolation_tol + name.props["EnforcePassivity"] = interpolation + name.props["UseQ3DForDC"] = use_q3d_for_dc + name.props["MaxSolutions"] = interpolation_max_solutions + name.update() + self.logger.info("Linear count sweep %s has been correctly created.", sweep_name) + return name return False - @pyaedt_function_handler() + @pyaedt_function_handler( + setupname="setup", freqstart="start_frequency", freqstop="stop_frequency", sweepname="name" + ) def create_linear_step_sweep( self, - setupname, + setup, unit, - freqstart, - freqstop, + start_frequency, + stop_frequency, step_size, - sweepname=None, + name=None, save_fields=True, save_rad_fields_only=False, sweep_type="Interpolating", @@ -1026,18 +1027,19 @@ def create_linear_step_sweep( Parameters ---------- - setupname : str + setup : str Name of the setup to attach to the sweep. unit : str Unit of the frequency. For example, ``"MHz"`` or ``"GHz"``. - freqstart : float + start_frequency : float Starting frequency of the sweep. - freqstop : float + stop_frequency : float Stopping frequency of the sweep. step_size : float Frequency size of the step. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save fields for a discrete sweep only. The default is ``True``. @@ -1071,8 +1073,10 @@ def create_linear_step_sweep( raise AttributeError( "Invalid value for `sweep_type`. The value must be 'Discrete', 'Interpolating', or 'Fast'." ) - if sweepname is None: - sweepname = generate_unique_name("Sweep") + if name is None: + sweep_name = generate_unique_name("Sweep") + else: + sweep_name = name interpolation = False if sweep_type == "Interpolating": @@ -1085,18 +1089,18 @@ def create_linear_step_sweep( interpolation_tol = interpolation_tol_percent / 100.0 for s in self.setups: - if s.name == setupname: + if s.name == setup: setupdata = s - if sweepname in [sweep.name for sweep in setupdata.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) + if sweep_name in [sweep.name for sweep in setupdata.sweeps]: + oldname = sweep_name + sweep_name = generate_unique_name(oldname) self.logger.warning( - "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname + "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweep_name ) - sweep = setupdata.add_sweep(sweepname=sweepname, sweeptype=sweep_type) + sweep = setupdata.add_sweep(name=sweep_name, sweep_type=sweep_type) if not sweep: return False - sweep.change_range("LinearStep", freqstart, freqstop, step_size, unit) + sweep.change_range("LinearStep", start_frequency, stop_frequency, step_size, unit) sweep.props["GenerateSurfaceCurrent"] = save_fields sweep.props["SaveRadFieldsOnly"] = save_rad_fields_only sweep.props["FastSweep"] = interpolation @@ -1105,17 +1109,17 @@ def create_linear_step_sweep( sweep.props["UseQ3DForDC"] = use_q3d_for_dc sweep.props["MaxSolutions"] = interpolation_max_solutions sweep.update() - self.logger.info("Linear step sweep %s has been correctly created.", sweepname) + self.logger.info("Linear step sweep %s has been correctly created.", sweep_name) return sweep return False - @pyaedt_function_handler() + @pyaedt_function_handler(setupname="setup", sweepname="name") def create_single_point_sweep( self, - setupname, + setup, unit, freq, - sweepname=None, + name=None, save_fields=False, save_rad_fields_only=False, ): @@ -1123,14 +1127,15 @@ def create_single_point_sweep( Parameters ---------- - setupname : str + setup : str Name of the setup. unit : str Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. freq : float, list Frequency of the single point or list of frequencies to create distinct single points. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save fields for all points and subranges defined in the sweep. The default is ``False``. save_rad_fields_only : bool, optional @@ -1146,8 +1151,10 @@ def create_single_point_sweep( >>> oModule.AddSweep """ - if sweepname is None: - sweepname = generate_unique_name("SinglePoint") + if name is None: + sweep_name = generate_unique_name("SinglePoint") + else: + sweep_name = name add_subranges = False if isinstance(freq, list): @@ -1159,26 +1166,26 @@ def create_single_point_sweep( else: freq0 = freq - if setupname not in self.setup_names: + if setup not in self.setup_names: return False for s in self.setups: - if s.name == setupname: + if s.name == setup: setupdata = s - if sweepname in [sweep.name for sweep in setupdata.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) + if sweep_name in [sweep.name for sweep in setupdata.sweeps]: + oldname = sweep_name + sweep_name = generate_unique_name(oldname) self.logger.warning( - "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname + "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweep_name ) - sweepdata = setupdata.add_sweep(sweepname, "Discrete") + sweepdata = setupdata.add_sweep(sweep_name, "Discrete") sweepdata.change_range("SinglePoint", freq0, unit=unit) sweepdata.props["GenerateSurfaceCurrent"] = save_fields sweepdata.props["SaveRadFieldsOnly"] = save_rad_fields_only sweepdata.update() if add_subranges: for f in freq: - sweepdata.add_subrange(rangetype="SinglePoint", start=f, unit=unit) - self.logger.info("Single point sweep %s has been correctly created.", sweepname) + sweepdata.add_subrange(range_type="SinglePoint", start=f, unit=unit) + self.logger.info("Single point sweep %s has been correctly created.", sweep_name) return sweepdata return False @@ -2032,8 +2039,8 @@ def edit_source_from_file( self.logger.error("Port not found.") return False - @pyaedt_function_handler() - def get_dcir_solution_data(self, setup_name, show="RL", category="Loop_Resistance"): + @pyaedt_function_handler(setup_name="setup") + def get_dcir_solution_data(self, setup, show="RL", category="Loop_Resistance"): """Retrieve dcir solution data. Available element_names are dependent on element_type as below. Sources ["Voltage", "Current", "Power"] "RL" ['Loop Resistance', 'Path Resistance', 'Resistance', 'Inductance'] @@ -2043,7 +2050,7 @@ def get_dcir_solution_data(self, setup_name, show="RL", category="Loop_Resistanc Parameters ---------- - setup_name : str + setup : str Name of the setup. show : str, optional Type of the element. Options are ``"Sources"`, ``"RL"`, ``"Vias"``, ``"Bondwires"``, and ``"Probes"``. @@ -2065,57 +2072,15 @@ def get_dcir_solution_data(self, setup_name, show="RL", category="Loop_Resistanc context=show, is_siwave_dc=True, quantities_category=category ) - return self.post.get_solution_data(all_quantities, setup_sweep_name=setup_name, domain="DCIR", context=show) - - @pyaedt_function_handler() - def get_touchstone_data(self, setup_name=None, sweep_name=None, variations=None): - """ - Return a Touchstone data plot. - - Parameters - ---------- - setup_name : list - Name of the setup. - sweep_name : str, optional - Name of the sweep. The default value is ``None``. - variations : dict, optional - Dictionary of variation names. The default value is ``None``. + return self.post.get_solution_data(all_quantities, setup_sweep_name=setup, domain="DCIR", context=show) - Returns - ------- - :class:`pyaedt.generic.touchstone_parser.TouchstoneData` - Class containing all requested data. - - References - ---------- - - >>> oModule.GetSolutionDataPerVariation - """ - from pyaedt.generic.touchstone_parser import TouchstoneData - - if not setup_name: - setup_name = self.setups[0].name - - if not sweep_name: - for setup in self.setups: - if setup.name == setup_name: - sweep_name = setup.sweeps[0].name - s_parameters = [] - solution = "{} : {}".format(setup_name, sweep_name) - expression = self.get_traces_for_plot(category="S") - sol_data = self.post.get_solution_data(expression, solution, variations=variations) - for i in range(sol_data.number_of_variations): - sol_data.set_active_variation(i) - s_parameters.append(TouchstoneData(solution_data=sol_data)) - return s_parameters - - @pyaedt_function_handler() - def get_dcir_element_data_loop_resistance(self, setup_name): + @pyaedt_function_handler(setup_name="setup") + def get_dcir_element_data_loop_resistance(self, setup): """Get dcir element data loop resistance. Parameters ---------- - setup_name : str + setup : str Name of the setup. Returns ------- @@ -2126,7 +2091,7 @@ def get_dcir_element_data_loop_resistance(self, setup_name): return False import pandas as pd - solution_data = self.get_dcir_solution_data(setup_name=setup_name, show="RL", category="Loop Resistance") + solution_data = self.get_dcir_solution_data(setup=setup, show="RL", category="Loop Resistance") terms = [] pattern = r"LoopRes\((.*?)\)" @@ -2151,13 +2116,13 @@ def get_dcir_element_data_loop_resistance(self, setup_name): df.index = terms return df - @pyaedt_function_handler() - def get_dcir_element_data_current_source(self, setup_name): + @pyaedt_function_handler(setup_name="setup") + def get_dcir_element_data_current_source(self, setup): """Get dcir element data current source. Parameters ---------- - setup_name : str + setup : str Name of the setup. Returns ------- @@ -2168,7 +2133,7 @@ def get_dcir_element_data_current_source(self, setup_name): return False import pandas as pd - solution_data = self.get_dcir_solution_data(setup_name=setup_name, show="Sources", category="Voltage") + solution_data = self.get_dcir_solution_data(setup=setup, show="Sources", category="Voltage") terms = [] pattern = r"^V\((.*?)\)" for t_name in solution_data.expressions: @@ -2187,13 +2152,13 @@ def get_dcir_element_data_current_source(self, setup_name): df.index = terms return df - @pyaedt_function_handler() - def get_dcir_element_data_via(self, setup_name): + @pyaedt_function_handler(setup_name="setup") + def get_dcir_element_data_via(self, setup): """Get dcir element data via. Parameters ---------- - setup_name : str + setup : str Name of the setup. Returns ------- @@ -2208,7 +2173,7 @@ def get_dcir_element_data_via(self, setup_name): df = None for cat in cates: data = {cat: []} - solution_data = self.get_dcir_solution_data(setup_name=setup_name, show="Vias", category=cat) + solution_data = self.get_dcir_solution_data(setup=setup, show="Vias", category=cat) tmp_via_names = [] pattern = r"\((.*?)\)" for t_name in solution_data.expressions: diff --git a/pyaedt/icepak.py b/pyaedt/icepak.py index 1e53b66e877..4d5a4c1821a 100644 --- a/pyaedt/icepak.py +++ b/pyaedt/icepak.py @@ -223,7 +223,6 @@ def assign_grille( air_faces, free_loss_coeff=True, free_area_ratio=0.8, - resistance_type=0, external_temp="AmbientTemp", expternal_pressure="AmbientPressure", x_curve=["0", "1", "2"], @@ -241,14 +240,6 @@ def assign_grille( the free loss coefficient is not used. free_area_ratio : float, str Free loss coefficient value. The default is ``0.8``. - resistance_type : int, optional - Type of the resistance. Options are: - - - ``0`` for ``"Perforated Thin Vent"`` - - ``1`` for ``"Circular Metal Wire Screen"`` - - ``2`` for ``"Two-Plane Screen Cyl. Bars"`` - - The default is ``0`` for ``"Perforated Thin Vent"``. external_temp : str, optional External temperature. The default is ``"AmbientTemp"``. expternal_pressure : str, optional @@ -346,15 +337,15 @@ def assign_openings(self, air_faces): return bound return None - @pyaedt_function_handler() + @pyaedt_function_handler(setup_name="setup") def assign_2way_coupling( - self, setup_name=None, number_of_iterations=2, continue_ipk_iterations=True, ipk_iterations_per_coupling=20 + self, setup=None, number_of_iterations=2, continue_ipk_iterations=True, ipk_iterations_per_coupling=20 ): """Assign two-way coupling to a setup. Parameters ---------- - setup_name : str, optional + setup : str, optional Name of the setup. The default is ``None``, in which case the active setup is used. number_of_iterations : int, optional Number of iterations. The default is ``2``. @@ -376,18 +367,18 @@ def assign_2way_coupling( Examples -------- - >>> icepak.assign_2way_coupling("Setup1", 1, True, 10) + >>> icepak.assign_2way_coupling("Setup1",1,True,10) True """ - if not setup_name: + if not setup: if self.setups: - setup_name = self.setups[0].name + setup = self.setups[0].name else: self.logger.error("No setup is defined.") return False self.oanalysis.AddTwoWayCoupling( - setup_name, + setup, [ "NAME:Options", "NumCouplingIters:=", @@ -1426,8 +1417,7 @@ def create_parametric_heatsink_on_face( else: self[name_map[var_name]] = self.modeler._arg_with_dim(var) - if numcolumn_perside > 1: - self[name_map["NumColumnsPerSide"]] = numcolumn_perside + self[name_map["NumColumnsPerSide"]] = numcolumn_perside if symmetric: if relative: self[name_map["SymSeparation_Factor"]] = symmetric_separation @@ -1552,17 +1542,16 @@ def create_parametric_heatsink_on_face( name_map["_num"] + "*2", True, ) - if numcolumn_perside > 0: - self.modeler.duplicate_along_line( - fin_base.name, - self.Position( - name_map["FinLength"] + "+" + name_map["ColumnSeparation"], - name_map["FinLength"] + "*sin(" + name_map["PatternAngle"] + "*3.14/180)", - 0, - ), - name_map["NumColumnsPerSide"], - True, - ) + self.modeler.duplicate_along_line( + fin_base.name, + self.Position( + name_map["FinLength"] + "+" + name_map["ColumnSeparation"], + name_map["FinLength"] + "*sin(" + name_map["PatternAngle"] + "*3.14/180)", + 0, + ), + name_map["NumColumnsPerSide"], + True, + ) cs = self.modeler.oeditor.GetActiveCoordinateSystem() cs_ymax = self.modeler.create_coordinate_system( self.Position(0, name_map["HSHeight"] + "/2", 0), @@ -1743,27 +1732,31 @@ def edit_design_settings( ) return True - @pyaedt_function_handler() + @pyaedt_function_handler(designname="design", + setupname="setup", + sweepname="sweep", + paramlist="parameters", + object_list="assignment") def assign_em_losses( self, - designname="HFSSDesign1", - setupname="Setup1", - sweepname="LastAdaptive", + design="HFSSDesign1", + setup="Setup1", + sweep="LastAdaptive", map_frequency=None, surface_objects=None, source_project_name=None, - paramlist=None, - object_list=None, + parameters=None, + assignment=None, ): """Map EM losses to an Icepak design. Parameters ---------- - designname : string, optional + design : string, optional Name of the design with the source mapping. The default is ``"HFSSDesign1"``. - setupname : str, optional + setup : str, optional Name of the EM setup. The default is ``"Setup1"``. - sweepname : str, optional + sweep : str, optional Name of the EM sweep to use for the mapping. The default is ``"LastAdaptive"``. map_frequency : str, optional String containing the frequency to map. The default is ``None``. @@ -1773,14 +1766,15 @@ def assign_em_losses( source_project_name : str, optional Name of the source project. The default is ``None``, in which case the source from the same project is used. - paramlist : list, dict, optional - List of all parameters to map from source and Icepak design. The default is ``None``. + parameters : list, dict, optional + List of all parameters to map from source and Icepak design. + The default is ``None``, in which case the variables are set to their values (no mapping). If ``None`` the variables are set to their values (no mapping). - If it is a list, the specified variables in the icepak design are mapped to variables + If a list is provided, the specified variables in the Icepak design are mapped to variables in the source design having the same name. - If it is a dictionary, it is possible to map variables to the source design having a different name. + If a dictionary is provided, it is possible to map variables to the source design having a different name. The dictionary structure is {"source_design_variable": "icepak_variable"}. - object_list : list, optional + assignment : list, optional List of objects. The default is ``None``. Returns @@ -1795,8 +1789,8 @@ def assign_em_losses( """ if surface_objects is None: surface_objects = [] - if object_list is None: - object_list = [] + if assignment is None: + assignment = [] self.logger.info("Mapping EM losses.") @@ -1807,12 +1801,12 @@ def assign_em_losses( # # Generate a list of model objects from the lists made previously and use to map the HFSS losses into Icepak # - if not object_list: - all_objects = self.modeler.object_names - if "Region" in all_objects: - all_objects.remove("Region") + if not assignment: + assignment = self.modeler.object_names + if "Region" in assignment: + assignment.remove("Region") else: - all_objects = object_list[:] + assignment = assignment[:] surfaces = surface_objects if map_frequency: @@ -1824,20 +1818,20 @@ def assign_em_losses( for el in self.available_variations.nominal_w_values_dict: argparam[el] = self.available_variations.nominal_w_values_dict[el] - if paramlist and isinstance(paramlist, list): - for el in paramlist: + if parameters and isinstance(parameters, list): + for el in parameters: argparam[el] = el - elif paramlist and isinstance(paramlist, dict): - for el in paramlist: - argparam[el] = paramlist[el] + elif parameters and isinstance(parameters, dict): + for el in parameters: + argparam[el] = parameters[el] props = OrderedDict( { - "Objects": all_objects, + "Objects": assignment, "Project": project_name, "Product": "ElectronicsDesktop", - "Design": designname, - "Soln": setupname + " : " + sweepname, + "Design": design, + "Soln": setup + " : " + sweep, "Params": argparam, "ForceSourceToSolve": True, "PreservePartnerSoln": True, @@ -1851,7 +1845,7 @@ def assign_em_losses( bound = BoundaryObject(self, name, props, "EMLoss") if bound.create(): self._boundaries[bound.name] = bound - self.logger.info("EM losses mapped from design: %s.", designname) + self.logger.info("EM losses mapped from design: %s.", design) return bound return False @@ -4057,11 +4051,11 @@ def assign_stationary_wall_with_htc( shell_conduction=shell_conduction, ) - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create an analysis setup for Icepak. - Optional arguments are passed along with ``setuptype`` and ``setupname``. Keyword - names correspond to the ``setuptype`` + Optional arguments are passed along with ``setup_type`` and ``name``. Keyword + names correspond to the ``setup_type`` corresponding to the native AEDT API. The list of keywords here is not exhaustive. @@ -4070,11 +4064,11 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): Parameters ---------- - setuptype : int, str, optional + name : str, optional + Name of the setup. The default is ``"Setup1"``. + setup_type : int, str, optional Type of the setup. Options are ``"IcepakSteadyState"`` and ``"IcepakTransient"``. The default is ``"IcepakSteadyState"``. - setupname : str, optional - Name of the setup. The default is ``"Setup1"``. **kwargs : dict, optional Available keys depend on setup chosen. For more information, see @@ -4095,17 +4089,17 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Icepak >>> app = Icepak() - >>> app.create_setup(setupname="Setup1", setuptype="TransientTemperatureOnly", MaxIterations=20) + >>> app.create_setup(setup_type="TransientTemperatureOnly",name="Setup1",MaxIterations=20) """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) if "props" in kwargs: - return self._create_setup(setupname=setupname, setuptype=setuptype, props=kwargs["props"]) + return self._create_setup(name=name, setup_type=setup_type, props=kwargs["props"]) else: - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: @@ -4603,8 +4597,8 @@ def assign_hollow_block( bound = BoundaryObject(self, boundary_name, props, "Block") return _create_boundary(bound) - @pyaedt_function_handler() - def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=None, design_variation=None): + @pyaedt_function_handler(timestep="time_step") + def get_fans_operating_point(self, export_file=None, setup_name=None, time_step=None, design_variation=None): """ Get operating point of the fans in the design. @@ -4616,7 +4610,7 @@ def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=N setup_name : str, optional Setup name from which to determine the fans' operating point. The default is ``None``, in which case the first available setup is used. - timestep : str, optional + time_step : str, optional Time, with units, at which to determine the fans' operating point. The default is ``None``, in which case the first available timestep is used. This argument is only relevant in transient simulations. @@ -4646,7 +4640,7 @@ def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=N >>> filename, vol_flow_name, p_rise_name, op_dict= ipk.post.get_fans_operating_point() """ - return self.post.get_fans_operating_point(export_file, setup_name, timestep, design_variation) + return self.post.get_fans_operating_point(export_file, setup_name, time_step, design_variation) @pyaedt_function_handler() def assign_free_opening( diff --git a/pyaedt/maxwell.py b/pyaedt/maxwell.py index 158b444cebb..1c0e4df5195 100644 --- a/pyaedt/maxwell.py +++ b/pyaedt/maxwell.py @@ -11,6 +11,7 @@ from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.constants import SOLUTIONS from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.generic.general_methods import read_configuration_file from pyaedt.generic.general_methods import write_configuration_file @@ -185,19 +186,19 @@ def apply_skew( props.update(arg_slice_table) return self.change_design_settings(props) - @pyaedt_function_handler() - def set_core_losses(self, objects, value=False): + @pyaedt_function_handler(objects="assignment", value="core_loss_on_field") + def set_core_losses(self, assignment, core_loss_on_field=False): """Whether to enable core losses for a set of objects. - For ``EddyCurrent`` and ``Transient`` solver designs, core losses calulcations + For ``EddyCurrent`` and ``Transient`` solver designs, core losses calculations may be included in the simulation on any object that has a corresponding core loss definition (with core loss coefficient settings) in the material library. Parameters ---------- - objects : list, str + assignment : list, str List of object to apply core losses to. - value : bool, optional + core_loss_on_field : bool, optional Whether to enable ``Consider core loss effect on field`` for the given list. The default is ``False``. @@ -216,22 +217,22 @@ def set_core_losses(self, objects, value=False): Set core losses in Maxwell 3D. >>> from pyaedt import Maxwell3d - >>> maxwell_3d = Maxwell3d() - >>> maxwell_3d.set_core_losses(["PQ_Core_Bottom", "PQ_Core_Top"], True) - + >>> m3d = Maxwell3d() + >>> m3d.set_core_losses(assignment=["PQ_Core_Bottom", "PQ_Core_Top"],core_loss_on_field=True) + >>> m3d.release_desktop(True, True) """ if self.solution_type in ["EddyCurrent", "Transient"]: - objects = self.modeler.convert_to_selections(objects, True) - self.oboundary.SetCoreLoss(objects, value) + assignment = self.modeler.convert_to_selections(assignment, True) + self.oboundary.SetCoreLoss(assignment, core_loss_on_field) return True else: raise Exception("Core losses is only available with `EddyCurrent` and `Transient` solutions.") return False - @pyaedt_function_handler() + @pyaedt_function_handler(sources="assignment") def assign_matrix( self, - sources, + assignment, matrix_name=None, turns=None, return_path=None, @@ -247,7 +248,7 @@ def assign_matrix( Parameters ---------- - sources : list, str + assignment : list, str List of sources to assign a matrix to. matrix_name : str, optional Name of the matrix. The default is ``None``. @@ -276,30 +277,31 @@ def assign_matrix( -------- Set matrix in a Maxwell magnetostatic analysis. - >>> m2d = Maxwell2d(solution_type="MagnetostaticXY", close_on_exit=True, specified_version="2022.1") + >>> from pyaedt import Maxwell2d + >>> m2d = Maxwell2d(solution_type="MagnetostaticXY",specified_version="2022.1",close_on_exit=True) >>> coil1 = m2d.modeler.create_rectangle([0, 1.5, 0], [8, 3], is_covered=True, name="Coil_1") >>> coil2 = m2d.modeler.create_rectangle([8.5, 1.5, 0], [8, 3], is_covered=True, name="Coil_2") >>> coil3 = m2d.modeler.create_rectangle([16, 1.5, 0], [8, 3], is_covered=True, name="Coil_3") >>> coil4 = m2d.modeler.create_rectangle([32, 1.5, 0], [8, 3], is_covered=True, name="Coil_4") - >>> current1 = m2d.assign_current("Coil_1", amplitude=1, swap_direction=False, name="Current1") - >>> current2 = m2d.assign_current("Coil_2", amplitude=1, swap_direction=True, name="Current2") - >>> current3 = m2d.assign_current("Coil_3", amplitude=1, swap_direction=True, name="Current3") - >>> current4 = m2d.assign_current("Coil_4", amplitude=1, swap_direction=True, name="Current4") + >>> current1 = m2d.assign_current(assignment="Coil_1",amplitude=1,swap_direction=False,name="Current1") + >>> current2 = m2d.assign_current(assignment="Coil_2",amplitude=1,swap_direction=True,name="Current2") + >>> current3 = m2d.assign_current(assignment="Coil_3",amplitude=1,swap_direction=True,name="Current3") + >>> current4 = m2d.assign_current(assignment="Coil_4",amplitude=1,swap_direction=True,name="Current4") >>> group_sources = {"Group1_Test": ["Current1", "Current3"], "Group2_Test": ["Current2", "Current4"]} >>> selection = ['Current1', 'Current2', 'Current3', 'Current4'] >>> turns = [5, 1, 2, 3] - >>> L = m2d.assign_matrix(sources=selection, matrix_name="Test2", turns=turns, group_sources=group_sources) + >>> L = m2d.assign_matrix(assignment=selection,matrix_name="Test2",turns=turns,group_sources=group_sources) Set matrix in a Maxwell DC Conduction analysis. - >>> m2d.assign_voltage(["Port1"], amplitude=1, name="1V") - >>> m2d.assign_voltage(["Port2"], amplitude=0, name="0V") - >>> m2d.assign_matrix(sources=['1V'], group_sources=['0V'], matrix_name="Matrix1") - + >>> m2d.assign_voltage(["Port1"],amplitude=1,name="1V") + >>> m2d.assign_voltage(["Port2"],amplitude=0,name="0V") + >>> m2d.assign_matrix(assignment=['1V'],matrix_name="Matrix1",group_sources=['0V']) + >>> m2d.release_desktop(True, True) """ - sources = self.modeler.convert_to_selections(sources, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self.solution_type in ["Electrostatic", "ACConduction", "DCConduction"]: - turns = ["1"] * len(sources) + turns = ["1"] * len(assignment) branches = None if self.design_type == "Maxwell 2D": if group_sources: @@ -308,7 +310,7 @@ def assign_matrix( group_sources = group_sources[first_key] self.logger.warning("First Ground is selected") group_sources = self.modeler.convert_to_selections(group_sources, True) - if any(item in group_sources for item in sources): + if any(item in group_sources for item in assignment): self.logger.error("Ground must be different than selected sources") return False else: @@ -320,7 +322,7 @@ def assign_matrix( if isinstance(group_sources, (dict, OrderedDict)): new_group = group_sources.copy() for element in new_group: - if not all(item in sources for item in group_sources[element]): + if not all(item in assignment for item in group_sources[element]): self.logger.warning("Sources in group " + element + " are not selected") group_sources.pop(element) if not branches or len(group_sources) != len( @@ -345,31 +347,31 @@ def assign_matrix( else: group_sources = None branches = None - turns = ["1"] * len(sources) + turns = ["1"] * len(assignment) self.logger.info("Infinite is the only return path option in EddyCurrent.") - return_path = ["infinite"] * len(sources) + return_path = ["infinite"] * len(assignment) if self.solution_type not in ["Transient", "ElectricTransient"]: if not matrix_name: matrix_name = generate_unique_name("Matrix") - if not turns or len(sources) != len(self.modeler.convert_to_selections(turns, True)): + if not turns or len(assignment) != len(self.modeler.convert_to_selections(turns, True)): if turns: turns = self.modeler.convert_to_selections(turns, True) - num = abs(len(sources) - len(self.modeler.convert_to_selections(turns, True))) - if len(sources) < len(self.modeler.convert_to_selections(turns, True)): + num = abs(len(assignment) - len(self.modeler.convert_to_selections(turns, True))) + if len(assignment) < len(self.modeler.convert_to_selections(turns, True)): turns = turns[:-num] else: new_element = [turns[0]] * num turns.extend(new_element) else: - turns = ["1"] * len(sources) + turns = ["1"] * len(assignment) else: turns = self.modeler.convert_to_selections(turns, True) - if not return_path or len(sources) != len(self.modeler.convert_to_selections(return_path, True)): - return_path = ["infinite"] * len(sources) + if not return_path or len(assignment) != len(self.modeler.convert_to_selections(return_path, True)): + return_path = ["infinite"] * len(assignment) else: return_path = self.modeler.convert_to_selections(return_path, True) - if any(item in return_path for item in sources): + if any(item in return_path for item in assignment): self.logger.error("Return path specified must not be included in sources") return False @@ -380,19 +382,19 @@ def assign_matrix( else: props = OrderedDict({"MatrixEntry": OrderedDict({"MatrixEntry": []}), "MatrixGroup": []}) - for element in range(len(sources)): + for element in range(len(assignment)): if self.solution_type == "Magnetostatic" and self.design_type == "Maxwell 2D": prop = OrderedDict( { - "Source": sources[element], + "Source": assignment[element], "NumberOfTurns": turns[element], "ReturnPath": return_path[element], } ) elif self.solution_type == "EddyCurrent": - prop = OrderedDict({"Source": sources[element], "ReturnPath": return_path[element]}) + prop = OrderedDict({"Source": assignment[element], "ReturnPath": return_path[element]}) else: - prop = OrderedDict({"Source": sources[element], "NumberOfTurns": turns[element]}) + prop = OrderedDict({"Source": assignment[element], "NumberOfTurns": turns[element]}) props["MatrixEntry"]["MatrixEntry"].append(prop) if group_sources: @@ -460,9 +462,9 @@ def setup_ctrlprog( source_dir = self.pyaedt_dir if os.path.exists(ctl_file_path) and keep_modifications: - with open(ctl_file_path, "r") as fi: + with open_file(ctl_file_path, "r") as fi: existing_data = fi.readlines() - with open(ctl_file_path, "w") as fo: + with open_file(ctl_file_path, "w") as fo: first_line = True for line in existing_data: if first_line: @@ -499,19 +501,23 @@ def setup_ctrlprog( ) return True - @pyaedt_function_handler() - def eddy_effects_on(self, object_list, activate_eddy_effects=True, activate_displacement_current=True): + @pyaedt_function_handler( + object_list="assignment", + activate_eddy_effects="enable_eddy_effects", + activate_displacement_current="enable_displacement_current", + ) + def eddy_effects_on(self, assignment, enable_eddy_effects=True, enable_displacement_current=True): """Assign eddy effects on a list of objects. For Eddy Current solvers only, you must specify the displacement current on the model objects. Parameters ---------- - object_list : list, str + assignment : list, str List of objects to assign eddy effects to. - activate_eddy_effects : bool, optional + enable_eddy_effects : bool, optional Whether to activate eddy effects. The default is ``True``. - activate_displacement_current : bool, optional + enable_displacement_current : bool, optional Whether to activate the displacement current. The default is ``True``. Valid only for Eddy Current solvers. @@ -529,20 +535,20 @@ def eddy_effects_on(self, object_list, activate_eddy_effects=True, activate_disp EddyVector = ["NAME:EddyEffectVector"] if self.modeler._is3d: - if not activate_eddy_effects: - activate_displacement_current = False + if not enable_eddy_effects: + enable_displacement_current = False for obj in solid_objects_names: if self.solution_type == "EddyCurrent": - if obj in object_list: + if obj in assignment: EddyVector.append( [ "NAME:Data", "Object Name:=", obj, "Eddy Effect:=", - activate_eddy_effects, + enable_eddy_effects, "Displacement Current:=", - activate_displacement_current, + enable_displacement_current, ] ) else: @@ -558,14 +564,14 @@ def eddy_effects_on(self, object_list, activate_eddy_effects=True, activate_disp ] ) if self.solution_type == "Transient": - if obj in object_list: + if obj in assignment: EddyVector.append( [ "NAME:Data", "Object Name:=", obj, "Eddy Effect:=", - activate_eddy_effects, + enable_eddy_effects, ] ) else: @@ -580,14 +586,14 @@ def eddy_effects_on(self, object_list, activate_eddy_effects=True, activate_disp ) else: for obj in solid_objects_names: - if obj in object_list: + if obj in assignment: EddyVector.append( [ "NAME:Data", "Object Name:=", obj, "Eddy Effect:=", - activate_eddy_effects, + enable_eddy_effects, ] ) else: @@ -603,15 +609,15 @@ def eddy_effects_on(self, object_list, activate_eddy_effects=True, activate_disp self.oboundary.SetEddyEffect(["NAME:Eddy Effect Setting", EddyVector]) return True - @pyaedt_function_handler() - def setup_y_connection(self, windings_name=None): - """Setup the Y connection. + @pyaedt_function_handler(windings_name="assignment") + def setup_y_connection(self, assignment=None): + """Set up the Y connection. Parameters ---------- - windings_name : list, optional + assignment : list, optional List of windings. For example, ``["PhaseA", "PhaseB", "PhaseC"]``. - The default value is ``None``, in which case the design has no Y connection. + The default is ``None``, in which case the design has no Y connection. Returns ------- @@ -629,30 +635,31 @@ def setup_y_connection(self, windings_name=None): This creates one ``YConnection`` group containing these three phases. >>> from pyaedt import Maxwell2d - >>> aedtapp = Maxwell2d("Motor_EM_R2019R3.aedt") - >>> aedtapp.set_active_design("Basis_Model_For_Test") - >>> aedtapp.setup_y_connection(["PhaseA", "PhaseB", "PhaseC"]) + >>> m2d = Maxwell2d("Motor_EM_R2019R3.aedt") + >>> m2d.set_active_design("Basis_Model_For_Test") + >>> m2d.setup_y_connection(["PhaseA", "PhaseB", "PhaseC"]) + >>> m2d.release_desktop(True, True) """ if self.solution_type not in ["Transient"]: self.logger.error("Y connections only available for Transient solutions.") return False - if windings_name: - connection = ["NAME:YConnection", "Windings:=", ",".join(windings_name)] - windings = ["NAME:YConnection", connection] - self.oboundary.SetupYConnection(windings) + if assignment: + connection = ["NAME:YConnection", "Windings:=", ",".join(assignment)] + assignment = ["NAME:YConnection", connection] + self.oboundary.SetupYConnection(assignment) else: self.oboundary.SetupYConnection() return True - @pyaedt_function_handler() - def assign_current(self, object_list, amplitude=1, phase="0deg", solid=True, swap_direction=False, name=None): + @pyaedt_function_handler(object_list="assignment") + def assign_current(self, assignment, amplitude=1, phase="0deg", solid=True, swap_direction=False, name=None): """Assign the source of the current. Parameters ---------- - object_list : list, str + assignment : list, str List of objects to assign the current source to. amplitude : float or str, optional Current amplitude. The default is ``1A``. @@ -684,9 +691,10 @@ def assign_current(self, object_list, amplitude=1, phase="0deg", solid=True, swa -------- >>> from pyaedt import Maxwell3d - >>> app = pyaedt.Maxwell3d(solution_type="ElectroDCConduction") - >>> cylinder= app.modeler.create_cylinder("X", [0,0,0],10, 100, 250) - >>> current = app.assign_current(cylinder.top_face_x.id, amplitude= "2mA") + >>> m3d = Maxwell3d(solution_type="ElectroDCConduction") + >>> cylinder= m3d.modeler.create_cylinder("X", [0,0,0],10, 100, 250) + >>> current = m3d.assign_current(cylinder.top_face_x.id,amplitude="2mA") + >>> m3d.release_desktop(True, True) """ if isinstance(amplitude, (int, float)): @@ -695,19 +703,19 @@ def assign_current(self, object_list, amplitude=1, phase="0deg", solid=True, swa if not name: name = generate_unique_name("Current") - object_list = self.modeler.convert_to_selections(object_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self.is3d: - if type(object_list[0]) is int: + if type(assignment[0]) is int: props = OrderedDict( { - "Faces": object_list, + "Faces": assignment, "Current": amplitude, } ) else: props = OrderedDict( { - "Objects": object_list, + "Objects": assignment, "Current": amplitude, } ) @@ -723,8 +731,8 @@ def assign_current(self, object_list, amplitude=1, phase="0deg", solid=True, swa props["IsSolid"] = solid props["Point out of terminal"] = swap_direction else: - if type(object_list[0]) is str: - props = OrderedDict({"Objects": object_list, "Current": amplitude, "IsPositive": swap_direction}) + if type(assignment[0]) is str: + props = OrderedDict({"Objects": assignment, "Current": amplitude, "IsPositive": swap_direction}) else: self.logger.warning("Input must be a 2D object.") return False @@ -734,10 +742,10 @@ def assign_current(self, object_list, amplitude=1, phase="0deg", solid=True, swa return bound return False - @pyaedt_function_handler() + @pyaedt_function_handler(band_object="assignment") def assign_translate_motion( self, - band_object, + assignment, coordinate_system="Global", axis="Z", positive_movement=True, @@ -758,7 +766,7 @@ def assign_translate_motion( Parameters ---------- - band_object : str + assignment : str Object container. coordinate_system : str, optional Coordinate system name. The default is ``"Global"``. @@ -808,7 +816,7 @@ def assign_translate_motion( assert self.solution_type == SOLUTIONS.Maxwell3d.Transient, "Motion applies only to the Transient setup." if not motion_name: motion_name = generate_unique_name("Motion") - object_list = self.modeler.convert_to_selections(band_object, True) + object_list = self.modeler.convert_to_selections(assignment, True) props = OrderedDict( { "Move Type": "Translate", @@ -834,10 +842,10 @@ def assign_translate_motion( return bound return False - @pyaedt_function_handler() + @pyaedt_function_handler(band_object="assignment") def assign_rotate_motion( self, - band_object, + assignment, coordinate_system="Global", axis="Z", positive_movement=True, @@ -858,7 +866,7 @@ def assign_rotate_motion( Parameters ---------- - band_object : str, + assignment : str, Object container. coordinate_system : str, optional Coordinate system name. The default is ``"Global"``. @@ -906,7 +914,7 @@ def assign_rotate_motion( assert self.solution_type == SOLUTIONS.Maxwell3d.Transient, "Motion applies only to the Transient setup." names = list(self.omodelsetup.GetMotionSetupNames()) motion_name = "MotionSetup" + str(len(names) + 1) - object_list = self.modeler.convert_to_selections(band_object, True) + object_list = self.modeler.convert_to_selections(assignment, True) props = OrderedDict( { "Move Type": "Rotate", @@ -932,13 +940,13 @@ def assign_rotate_motion( return bound return False - @pyaedt_function_handler() - def assign_voltage(self, face_list, amplitude=1, name=None): - """Assign a voltage source to a list of faces in Maxwell 3D or a list of Objects in Maxwell 2D. + @pyaedt_function_handler(face_list="assignment") + def assign_voltage(self, assignment, amplitude=1, name=None): + """Assign a voltage source to a list of faces in Maxwell 3D or a list of objects in Maxwell 2D. Parameters ---------- - face_list : list + assignment : list List of faces or objects to assign a voltage source to. amplitude : float, optional Voltage amplitude in mV. The default is ``1``. @@ -961,33 +969,33 @@ def assign_voltage(self, face_list, amplitude=1, name=None): if not name: name = generate_unique_name("Voltage") - face_list = self.modeler.convert_to_selections(face_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self.design_type == "Maxwell 2D": - props = OrderedDict({"Objects": face_list, "Value": amplitude}) + props = OrderedDict({"Objects": assignment, "Value": amplitude}) else: - if len(face_list) == 1: - if isinstance(face_list[0], str) and face_list[0] in self.modeler.object_names: - props = OrderedDict({"Objects": face_list, "Voltage": amplitude}) + if len(assignment) == 1: + if isinstance(assignment[0], str) and assignment[0] in self.modeler.object_names: + props = OrderedDict({"Objects": assignment, "Voltage": amplitude}) else: - props = OrderedDict({"Faces": face_list, "Value": amplitude}) + props = OrderedDict({"Faces": assignment, "Value": amplitude}) else: - props = OrderedDict({"Faces": face_list, "Voltage": amplitude}) + props = OrderedDict({"Faces": assignment, "Voltage": amplitude}) bound = BoundaryObject(self, name, props, "Voltage") if bound.create(): self._boundaries[bound.name] = bound return bound return False - @pyaedt_function_handler() - def assign_voltage_drop(self, face_list, amplitude=1, swap_direction=False, name=None): + @pyaedt_function_handler(face_list="assignment") + def assign_voltage_drop(self, assignment, amplitude=1, swap_direction=False, name=None): """Assign a voltage drop across a list of faces to a specific value. The voltage drop applies only to sheet objects. Parameters ---------- - face_list : list + assignment : list List of faces to assign a voltage drop to. amplitude : float, optional Voltage amplitude in mV. The default is ``1``. @@ -1012,24 +1020,24 @@ def assign_voltage_drop(self, face_list, amplitude=1, swap_direction=False, name if not name: name = generate_unique_name("VoltageDrop") - face_list = self.modeler.convert_to_selections(face_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) - props = OrderedDict({"Faces": face_list, "Voltage Drop": amplitude, "Point out of terminal": swap_direction}) + props = OrderedDict({"Faces": assignment, "Voltage Drop": amplitude, "Point out of terminal": swap_direction}) bound = BoundaryObject(self, name, props, "VoltageDrop") if bound.create(): self._boundaries[bound.name] = bound return bound return False - @pyaedt_function_handler() + @pyaedt_function_handler(coil_terminals="assignment", current_value="current", res="resistance", ind="inductance") def assign_winding( self, - coil_terminals=None, + assignment=None, winding_type="Current", is_solid=True, - current_value=1, - res=0, - ind=0, + current=1, + resistance=0, + inductance=0, voltage=0, parallel_branches=1, phase=0, @@ -1039,7 +1047,7 @@ def assign_winding( Parameters ---------- - coil_terminals : list, optional + assignment : list, optional List of faces to create the coil terminal on. The default is ``None``. winding_type : str, optional @@ -1048,12 +1056,12 @@ def assign_winding( is_solid : bool, optional Whether the winding is the solid type. The default is ``True``. If ``False``, the winding is the stranded type. - current_value : float, optional + current : float, optional Value of the current in amperes. The default is ``1``. - res : float, optional + resistance : float, optional Resistance in ohms. The default is ``0``. - ind : float, optional - Henry (H). The default is ``0``. + inductance : float, optional + Inductance in Henry (H). The default is ``0``. voltage : float, optional Voltage value. The default is ``0``. parallel_branches : int, optional @@ -1082,9 +1090,9 @@ def assign_winding( { "Type": winding_type, "IsSolid": is_solid, - "Current": self.modeler._arg_with_dim(current_value, "A"), - "Resistance": self.modeler._arg_with_dim(res, "ohm"), - "Inductance": self.modeler._arg_with_dim(ind, "H"), + "Current": self.modeler._arg_with_dim(current, "A"), + "Resistance": self.modeler._arg_with_dim(resistance, "ohm"), + "Inductance": self.modeler._arg_with_dim(inductance, "H"), "Voltage": self.modeler._arg_with_dim(voltage, "V"), "ParallelBranchesNum": str(parallel_branches), "Phase": self.modeler._arg_with_dim(phase, "deg"), @@ -1093,12 +1101,12 @@ def assign_winding( bound = BoundaryObject(self, name, props, "Winding") if bound.create(): self._boundaries[bound.name] = bound - if coil_terminals is None: - coil_terminals = [] - if type(coil_terminals) is not list: - coil_terminals = [coil_terminals] + if assignment is None: + assignment = [] + if type(assignment) is not list: + assignment = [assignment] coil_names = [] - for coil in coil_terminals: + for coil in assignment: c = self.assign_coil(coil) if c: coil_names.append(c.name) @@ -1108,15 +1116,15 @@ def assign_winding( return bound return False - @pyaedt_function_handler() - def add_winding_coils(self, windingname, coil_names): + @pyaedt_function_handler(windingname="assignment", coil_names="coils") + def add_winding_coils(self, assignment, coils): """Add coils to the winding. Parameters ---------- - windingname : str + assignment : str Name of the winding. - coil_names : list + coils : list List of the coil names. Returns @@ -1131,20 +1139,20 @@ def add_winding_coils(self, windingname, coil_names): >>> oModule.AddWindingCoils """ if self.modeler._is3d: - self.oboundary.AddWindingTerminals(windingname, coil_names) + self.oboundary.AddWindingTerminals(assignment, coils) else: - self.oboundary.AddWindingCoils(windingname, coil_names) + self.oboundary.AddWindingCoils(assignment, coils) return True - @pyaedt_function_handler() - def assign_coil(self, input_object, conductor_number=1, polarity="Positive", name=None): + @pyaedt_function_handler(input_object="assignment", conductor_number="conductors_number") + def assign_coil(self, assignment, conductors_number=1, polarity="Positive", name=None): """Assign coils to a list of objects or face IDs. Parameters ---------- - input_object : list + assignment : list List of objects or face IDs. - conductor_number : int, optional + conductors_number : int, optional Number of conductors. The default is ``1``. polarity : str, optional Type of the polarity. The default is ``"Positive"``. @@ -1167,22 +1175,22 @@ def assign_coil(self, input_object, conductor_number=1, polarity="Positive", nam else: point = True - input_object = self.modeler.convert_to_selections(input_object, True) + assignment = self.modeler.convert_to_selections(assignment, True) if not name: name = generate_unique_name("Coil") - if type(input_object[0]) is str: + if type(assignment[0]) is str: if self.modeler._is3d: props2 = OrderedDict( - {"Objects": input_object, "Conductor number": str(conductor_number), "Point out of terminal": point} + {"Objects": assignment, "Conductor number": str(conductors_number), "Point out of terminal": point} ) bound = BoundaryObject(self, name, props2, "CoilTerminal") else: props2 = OrderedDict( { - "Objects": input_object, - "Conductor number": str(conductor_number), + "Objects": assignment, + "Conductor number": str(conductors_number), "PolarityType": polarity.lower(), } ) @@ -1190,7 +1198,7 @@ def assign_coil(self, input_object, conductor_number=1, polarity="Positive", nam else: if self.modeler._is3d: props2 = OrderedDict( - {"Faces": input_object, "Conductor number": str(conductor_number), "Point out of terminal": point} + {"Faces": assignment, "Conductor number": str(conductors_number), "Point out of terminal": point} ) bound = BoundaryObject(self, name, props2, "CoilTerminal") @@ -1202,8 +1210,8 @@ def assign_coil(self, input_object, conductor_number=1, polarity="Positive", nam return bound return False - @pyaedt_function_handler() - def assign_force(self, input_object, reference_cs="Global", is_virtual=True, force_name=None): + @pyaedt_function_handler(input_object="assignment", reference_cs="coordinate_system") + def assign_force(self, assignment, coordinate_system="Global", is_virtual=True, force_name=None): """Assign a force to one or more objects. Force assignment can be calculated based upon the solver type. @@ -1214,9 +1222,9 @@ def assign_force(self, input_object, reference_cs="Global", is_virtual=True, for Parameters ---------- - input_object : str, list + assignment : str, list One or more objects to assign the force to. - reference_cs : str, optional + coordinate_system : str, optional Name of the reference coordinate system. The default is ``"Global"``. is_virtual : bool, optional Whether the force is virtual. The default is ``True.`` @@ -1239,11 +1247,13 @@ def assign_force(self, input_object, reference_cs="Global", is_virtual=True, for Assign virtual force to a magnetic object: + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() >>> iron_object = m3d.modeler.create_box([0, 0, 0], [2, 10, 10], name="iron") >>> magnet_object = m3d.modeler.create_box([10, 0, 0], [2, 10, 10], name="magnet") >>> m3d.assign_material(iron_object, "iron") >>> m3d.assign_material(magnet_object, "NdFe30") - >>> m3d.assign_force("iron", force_name="force_iron", is_virtual=True) + >>> m3d.assign_force("iron",is_virtual=True,force_name="force_iron") Assign Lorentz force to a conductor: @@ -1251,27 +1261,28 @@ def assign_force(self, input_object, reference_cs="Global", is_virtual=True, for >>> conductor2 = m3d.modeler.create_box([10, 0, 0], [1, 1, 10], name="conductor2") >>> m3d.assign_material(conductor1, "copper") >>> m3d.assign_material(conductor2, "copper") - >>> m3d.assign_force("conductor1", force_name="force_copper", is_virtual=False) # conductor, use Lorentz force + >>> m3d.assign_force("conductor1",is_virtual=False,force_name="force_copper") # conductor, use Lorentz force + >>> m3d.release_desktop(True, True) """ if self.solution_type not in ["ACConduction", "DCConduction"]: - input_object = self.modeler.convert_to_selections(input_object, True) + assignment = self.modeler.convert_to_selections(assignment, True) if not force_name: force_name = generate_unique_name("Force") if self.design_type == "Maxwell 3D": prop = OrderedDict( { "Name": force_name, - "Reference CS": reference_cs, + "Reference CS": coordinate_system, "Is Virtual": is_virtual, - "Objects": input_object, + "Objects": assignment, } ) else: prop = OrderedDict( { "Name": force_name, - "Reference CS": reference_cs, - "Objects": input_object, + "Reference CS": coordinate_system, + "Objects": assignment, } ) @@ -1280,12 +1291,12 @@ def assign_force(self, input_object, reference_cs="Global", is_virtual=True, for self._boundaries[bound.name] = bound return bound else: - self.logger.error("Solution Type has not Matrix Parameter") + self.logger.error("Solution type has no 'Matrix' parameter.") return False - @pyaedt_function_handler() + @pyaedt_function_handler(input_object="assignment", reference_cs="coordinate_system") def assign_torque( - self, input_object, reference_cs="Global", is_positive=True, is_virtual=True, axis="Z", torque_name=None + self, assignment, coordinate_system="Global", is_positive=True, is_virtual=True, axis="Z", torque_name=None ): """Assign a torque to one or more objects. @@ -1297,9 +1308,9 @@ def assign_torque( Parameters ---------- - input_object : str or list + assignment : str or list One or more objects to assign the torque to. - reference_cs : str, optional + coordinate_system : str, optional Name of the reference coordinate system. The default is ``"Global"``. is_positive : bool, optional Whether the torque is positive. The default is ``True``. @@ -1324,7 +1335,7 @@ def assign_torque( if self.solution_type not in ["ACConduction", "DCConduction"]: if self.solution_type == "Transient": is_virtual = True - input_object = self.modeler.convert_to_selections(input_object, True) + assignment = self.modeler.convert_to_selections(assignment, True) if not torque_name: torque_name = generate_unique_name("Torque") if self.design_type == "Maxwell 3D": @@ -1332,19 +1343,19 @@ def assign_torque( { "Name": torque_name, "Is Virtual": is_virtual, - "Coordinate System": reference_cs, + "Coordinate System": coordinate_system, "Axis": axis, "Is Positive": is_positive, - "Objects": input_object, + "Objects": assignment, } ) else: prop = OrderedDict( { "Name": torque_name, - "Coordinate System": reference_cs, + "Coordinate System": coordinate_system, "Is Positive": is_positive, - "Objects": input_object, + "Objects": assignment, } ) @@ -1406,15 +1417,15 @@ def analyze_from_zero(self): self.analyze() return True - @pyaedt_function_handler() - def set_initial_angle(self, motion_setup, val): + @pyaedt_function_handler(val="angle") + def set_initial_angle(self, motion_setup, angle): """Set the initial angle. Parameters ---------- motion_setup : str Name of the motion setup. - val : float + angle : float Value of the angle in degrees. Returns @@ -1433,14 +1444,14 @@ def set_initial_angle(self, motion_setup, val): [ "NAME:Maxwell2D", ["NAME:PropServers", "ModelSetup:" + motion_setup], - ["NAME:ChangedProps", ["NAME:Initial Position", "Value:=", val]], + ["NAME:ChangedProps", ["NAME:Initial Position", "Value:=", angle]], ], ] ) return True - @pyaedt_function_handler() - def assign_symmetry(self, entity_list, symmetry_name=None, is_odd=True): + @pyaedt_function_handler(entity_list="assignment") + def assign_symmetry(self, assignment, symmetry_name=None, is_odd=True): """Assign symmetry boundary. This boundary condition defines a plane of geometric or magnetic symmetry in a structure. @@ -1448,7 +1459,7 @@ def assign_symmetry(self, entity_list, symmetry_name=None, is_odd=True): Parameters ---------- - entity_list : list + assignment : list List IDs or :class:`pyaedt.modeler.Object3d.EdgePrimitive` or :class:`pyaedt.modeler.Object3d.FacePrimitive`. symmetry_name : str, optional @@ -1472,13 +1483,13 @@ def assign_symmetry(self, entity_list, symmetry_name=None, is_odd=True): if symmetry_name is None: symmetry_name = generate_unique_name("Symmetry") - if entity_list: + if assignment: if self.design_type == "Maxwell 2D": - entity_list = self.modeler.convert_to_selections(entity_list, True) - prop = OrderedDict({"Name": symmetry_name, "Edges": entity_list, "IsOdd": is_odd}) + assignment = self.modeler.convert_to_selections(assignment, True) + prop = OrderedDict({"Name": symmetry_name, "Edges": assignment, "IsOdd": is_odd}) else: - entity_list = self.modeler.convert_to_selections(entity_list, True) - prop = OrderedDict({"Name": symmetry_name, "Faces": entity_list, "IsOdd": is_odd}) + assignment = self.modeler.convert_to_selections(assignment, True) + prop = OrderedDict({"Name": symmetry_name, "Faces": assignment, "IsOdd": is_odd}) else: msg = "At least one edge must be provided." ValueError(msg) @@ -1491,18 +1502,22 @@ def assign_symmetry(self, entity_list, symmetry_name=None, is_odd=True): except Exception: return False - @pyaedt_function_handler() + @pyaedt_function_handler( + entities="assignment", + coordinate_system_name="coordinate_system", + coordinate_system_cartesian="coordinate_system_type", + ) def assign_current_density( self, - entities, + assignment, current_density_name=None, phase="0deg", current_density_x="0", current_density_y="0", current_density_z="0", current_density_2d="0", - coordinate_system_name="Global", - coordinate_system_cartesian="Cartesian", + coordinate_system="Global", + coordinate_system_type="Cartesian", ): """Assign current density to a single or list of entities. @@ -1510,7 +1525,7 @@ def assign_current_density( Parameters ---------- - entities : list + assignment : list Objects to assign the current to. current_density_name : str, optional Current density name. @@ -1531,10 +1546,10 @@ def assign_current_density( current_density_2d : str, optional Current density 2D value. Default value is 0 A/m2. - coordinate_system_name : str, optional + coordinate_system : str, optional Coordinate system name. Default value is 'Global'. - coordinate_system_cartesian : str, optional + coordinate_system_type : str, optional Coordinate system cartesian. Possible values can be ``"Cartesian"``, ``"Cylindrical"``, and ``"Spherical"``. Default value is ``"Cartesian"``. @@ -1550,11 +1565,11 @@ def assign_current_density( if re.compile(r"(\d+)\s*(\w+)").match(phase).groups()[1] not in ["deg", "degmin", "degsec", "rad"]: self.logger.error("Invalid phase unit.") return False - if coordinate_system_cartesian not in ["Cartesian", "Cylindrical", "Spherical"]: + if coordinate_system_type not in ["Cartesian", "Cylindrical", "Spherical"]: self.logger.error("Invalid coordinate system.") return False - objects_list = self.modeler.convert_to_selections(entities, True) + objects_list = self.modeler.convert_to_selections(assignment, True) try: if self.modeler._is3d: @@ -1571,8 +1586,8 @@ def assign_current_density( "CurrentDensityX": current_density_x, "CurrentDensityY": current_density_y, "CurrentDensityZ": current_density_z, - "CoordinateSystem Name": coordinate_system_name, - "CoordinateSystem Type": coordinate_system_cartesian, + "CoordinateSystem Name": coordinate_system, + "CoordinateSystem Type": coordinate_system_type, } ) bound = BoundaryObject(self, current_density_group_names[0], props, "CurrentDensityGroup") @@ -1584,8 +1599,8 @@ def assign_current_density( "CurrentDensityX": current_density_x, "CurrentDensityY": current_density_y, "CurrentDensityZ": current_density_z, - "CoordinateSystem Name": coordinate_system_name, - "CoordinateSystem Type": coordinate_system_cartesian, + "CoordinateSystem Name": coordinate_system, + "CoordinateSystem Type": coordinate_system_type, } ) bound = BoundaryObject(self, current_density_name, props, "CurrentDensity") @@ -1627,8 +1642,8 @@ def assign_current_density( self.logger.error("Current density can only be applied to Eddy current or magnetostatic solution types.") return False - @pyaedt_function_handler() - def assign_radiation(self, input_object, radiation_name=None): + @pyaedt_function_handler(input_object="assignment", radiation_name="radiation") + def assign_radiation(self, assignment, radiation=None): """Assign radiation boundary to one or more objects. Radiation assignment can be calculated based upon the solver type. @@ -1636,9 +1651,9 @@ def assign_radiation(self, input_object, radiation_name=None): Parameters ---------- - input_object : str, list + assignment : str, list One or more objects to assign the radiation to. - radiation_name : str, optional + radiation : str, optional Name of the force. The default is ``None``, in which case the default name is used. @@ -1657,35 +1672,38 @@ def assign_radiation(self, input_object, radiation_name=None): Assign radiation boundary to one box and one face: + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() >>> box1 = m3d.modeler.create_box([0, 0, 0], [2, 10, 10]) >>> box2 = m3d.modeler.create_box([10, 0, 0], [2, 10, 10]) - >>> m3d.assign_radiation([box1, box2.faces[0]], force_name="radiation_boundary") + >>> m3d.assign_radiation([box1, box2.faces[0]]) + >>> m3d.release_desktop(True, True) """ if self.solution_type in ["EddyCurrent"]: - if not radiation_name: - radiation_name = generate_unique_name("Radiation") - elif radiation_name in self.modeler.get_boundaries_name(): - radiation_name = generate_unique_name(radiation_name) + if not radiation: + radiation = generate_unique_name("Radiation") + elif radiation in self.modeler.get_boundaries_name(): + radiation = generate_unique_name(radiation) - listobj = self.modeler.convert_to_selections(input_object, True) + listobj = self.modeler.convert_to_selections(assignment, True) props = {"Objects": [], "Faces": []} for sel in listobj: if isinstance(sel, str): props["Objects"].append(sel) elif isinstance(sel, int): props["Faces"].append(sel) - bound = BoundaryObject(self, radiation_name, props, "Radiation") + bound = BoundaryObject(self, radiation, props, "Radiation") if bound.create(): self._boundaries[bound.name] = bound return bound self.logger.error("Excitation applicable only to Eddy current.") return False - @pyaedt_function_handler() + @pyaedt_function_handler(objects="assignment") def enable_harmonic_force( self, - objects, + assignment, force_type=0, window_function="Rectangular", use_number_of_last_cycles=True, @@ -1696,16 +1714,16 @@ def enable_harmonic_force( Parameters ---------- - objects : list + assignment : list List of object names for force calculations. force_type : int, optional - Force Type. ``0`` for Objects, ``1`` for Surface, ``2`` for volumetric. + Force type. Options are ``0`` for objects, ``1`` for surface, and ``2`` for volumetric. window_function : str, optional Windowing function. Default is ``"Rectangular"``. Available options are: ``"Rectangular"``, ``"Tri"``, ``"Van Hann"``, ``"Hamming"``, ``"Blackman"``, ``"Lanczos"``, ``"Welch"``. use_number_of_last_cycles : bool, optional - Use number Of last cycles for force calculations. Default is ``True``. + Use number of last cycles for force calculations. Default is ``True``. last_cycles_number : int, optional Defines the number of cycles to compute if `use_number_of_last_cycle` is ``True``. calculate_force : sr, optional @@ -1722,11 +1740,11 @@ def enable_harmonic_force( if self.solution_type != "Transient": self.logger.error("This methods work only with Maxwell Transient Analysis.") return False - objects = self.modeler.convert_to_selections(objects, True) + assignment = self.modeler.convert_to_selections(assignment, True) self.odesign.EnableHarmonicForceCalculation( [ "EnabledObjects:=", - objects, + assignment, "ForceType:=", force_type, "WindowFunctionType:=", @@ -1751,10 +1769,10 @@ def enable_harmonic_force( ) return True - @pyaedt_function_handler() + @pyaedt_function_handler(layout_component_name="assignment") def enable_harmonic_force_on_layout_component( self, - layout_component_name, + assignment, nets, force_type=0, window_function="Rectangular", @@ -1772,10 +1790,10 @@ def enable_harmonic_force_on_layout_component( Parameters ---------- - layout_component_name : str - Name of layout component to apply harmonic forces. + assignment : str + Name of layout component to apply harmonic forces to. nets : dict - Dictionary containing nets and layers on which enable harmonic forces. + Dictionary containing nets and layers to enable harmonic forces on. force_type : int, optional Force Type. ``0`` for Objects, ``1`` for Surface, ``2`` for volumetric. window_function : str, optional @@ -1835,7 +1853,7 @@ def enable_harmonic_force_on_layout_component( args2 = [ "NAME:NetsAndLayersChoices", [ - "NAME:" + layout_component_name, + "NAME:" + assignment, [ "NAME:NetLayerSetMap", ], @@ -1850,11 +1868,11 @@ def enable_harmonic_force_on_layout_component( self.odesign.EnableHarmonicForceCalculation(args) return True - @pyaedt_function_handler() + @pyaedt_function_handler(setup_name="setup") def export_element_based_harmonic_force( self, output_directory=None, - setup_name=None, + setup=None, start_frequency=None, stop_frequency=None, number_of_frequency=None, @@ -1864,8 +1882,8 @@ def export_element_based_harmonic_force( Parameters ---------- output_directory : str, optional - The path for the output directory. If ``None`` pyaedt working dir will be used. - setup_name : str, optional + Path for the output directory. If ``None`` pyaedt working dir will be used. + setup : str, optional Name of the solution setup. If ``None``, the nominal setup is used. start_frequency : float, optional When a float is entered the Start-Stop Frequency approach is used. @@ -1884,8 +1902,8 @@ def export_element_based_harmonic_force( return False if not output_directory: output_directory = self.working_directory - if not setup_name: - setup_name = self.setups[0].name + if not setup: + setup = self.setups[0].name freq_option = 1 f1 = -1 f2 = -1 @@ -1896,7 +1914,7 @@ def export_element_based_harmonic_force( elif number_of_frequency: freq_option = 3 f1 = number_of_frequency - self.odesign.ExportElementBasedHarmonicForce(output_directory, setup_name, freq_option, f1, f2) + self.odesign.ExportElementBasedHarmonicForce(output_directory, setup, freq_option, f1, f2) return output_directory @pyaedt_function_handler @@ -1946,22 +1964,23 @@ def edit_external_circuit(self, netlist_file_path, schematic_design_name): self.oboundary.EditExternalCircuit(netlist_file_path, sources_array, sources_type_array, [], []) return True - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create an analysis setup for Maxwell 3D or 2D. - Optional arguments are passed along with ``setuptype`` and ``setupname``. + Optional arguments are passed using the ``setup_type`` and ``name`` + parameters. Keyword names correspond to the ``setuptype`` corresponding to the native AEDT API. The list of keywords here is not exhaustive. Parameters ---------- - setuptype : int, str, optional + setup_type : int, str, optional Type of the setup. Depending on the solution type, options are ``"AC Conduction"``, ``"DC Conduction"``, ``"EddyCurrent"``, ``"Electric Transient"``, ``"Electrostatic"``, ``"Magnetostatic"``, and ``Transient"``. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"Setup1"``. **kwargs : dict, optional Available keys depend on the setup chosen. @@ -1979,18 +1998,18 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): Examples -------- >>> from pyaedt import Maxwell3d - >>> app = Maxwell3d() - >>> app.create_setup(setupname="My_Setup", setuptype="EddyCurrent", MaximumPasses=10, PercentError=2 ) - + >>> m3d = Maxwell3d() + >>> m3d.create_setup(name="My_Setup",setup_type="EddyCurrent",MaximumPasses=10,PercentError=2) + >>> m3d.release_desktop(True, True) """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) if "props" in kwargs: - return self._create_setup(setupname=setupname, setuptype=setuptype, props=kwargs["props"]) + return self._create_setup(name=name, setup_type=setup_type, props=kwargs["props"]) else: - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: @@ -2064,13 +2083,13 @@ class Maxwell3d(Maxwell, FieldAnalysis3D, object): project, which is named ``mymaxwell.aedt``. >>> from pyaedt import Maxwell3d - >>> aedtapp = Maxwell3d("mymaxwell.aedt") + >>> m3d = Maxwell3d("mymaxwell.aedt") PyAEDT INFO: Added design ... - Create an instance of Maxwell 3D using the 2023 R2 release and open + Create an instance of Maxwell 3D using the 2024 R1 release and open the specified project, which is named ``mymaxwell2.aedt``. - >>> aedtapp = Maxwell3d(specified_version="2023.2", projectname="mymaxwell2.aedt") + >>> m3d = Maxwell3d(specified_version="2024.1", projectname="mymaxwell2.aedt") PyAEDT INFO: Added design ... """ @@ -2118,10 +2137,10 @@ def __init__( Maxwell.__init__(self) def _init_from_design(self, *args, **kwargs): - self.__init__(*args, **kwargs) + self.__init__(**kwargs) - @pyaedt_function_handler() - def assign_insulating(self, geometry_selection, insulation_name=None): + @pyaedt_function_handler(geometry_selection="assignment", insulation_name="insulation") + def assign_insulating(self, assignment, insulation=None): """Create an insulating boundary condition. This boundary condition is used to model very thin sheets of perfectly insulating material between @@ -2129,10 +2148,10 @@ def assign_insulating(self, geometry_selection, insulation_name=None): Parameters ---------- - geometry_selection : str or int + assignment : str or int Objects or faces to apply the insulating boundary to. - insulation_name : str, optional - Name of the insulation. The default is ``None`` in which case a unique name is chosen. + insulation : str, optional + Name of the insulation. The default is ``None``, in which case a unique name is assigned. Returns ------- @@ -2149,9 +2168,11 @@ def assign_insulating(self, geometry_selection, insulation_name=None): Create a box and assign insulating boundary to it. - >>> insulated_box = maxwell3d_app.modeler.create_box([50, 0, 50], [294, 294, 19], name="InsulatedBox") - >>> insulating_assignment = maxwell3d_app.assign_insulating(insulated_box, "InsulatingExample") - >>> type(insulating_assignment) + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> insulated_box = m3d.modeler.create_box([50, 0, 50], [294, 294, 19], name="InsulatedBox") + >>> insulating_assignment = m3d.assign_insulating(assignment=insulated_box,insulation="InsulatingExample") + >>> m3d.release_desktop(True, True) """ if self.solution_type in [ @@ -2161,12 +2182,12 @@ def assign_insulating(self, geometry_selection, insulation_name=None): "DCConduction", "ElectroDCConduction", ]: - if not insulation_name: - insulation_name = generate_unique_name("Insulation") - elif insulation_name in self.modeler.get_boundaries_name(): - insulation_name = generate_unique_name(insulation_name) + if not insulation: + insulation = generate_unique_name("Insulation") + elif insulation in self.modeler.get_boundaries_name(): + insulation = generate_unique_name(insulation) - listobj = self.modeler.convert_to_selections(geometry_selection, True) + listobj = self.modeler.convert_to_selections(assignment, True) props = {"Objects": [], "Faces": []} for sel in listobj: if isinstance(sel, str): @@ -2174,18 +2195,18 @@ def assign_insulating(self, geometry_selection, insulation_name=None): elif isinstance(sel, int): props["Faces"].append(sel) - return self._create_boundary(insulation_name, props, "Insulating") + return self._create_boundary(insulation, props, "Insulating") return False - @pyaedt_function_handler() + @pyaedt_function_handler(geometry_selection="assignment", impedance_name="impedance") def assign_impedance( self, - geometry_selection, + assignment, material_name=None, permeability=0.0, conductivity=None, non_linear_permeability=False, - impedance_name=None, + impedance=None, ): """Create an impedance boundary condition for Transient or Eddy Current solvers. @@ -2194,11 +2215,11 @@ def assign_impedance( Parameters ---------- - geometry_selection : str + assignment : str Faces or objects to apply the impedance boundary to. material_name : str, optional - If it is different from ``None``, then material properties values will be extracted from - the named material in the list of materials available. The default value is ``None``. + Material name. The default is ``None``. If other than ``None``, material properties values are extracted + from the named material in the list of materials available. The default value is ``None``. permeability : float, optional Permeability of the material.The default value is ``0.0``. conductivity : float, optional @@ -2206,8 +2227,8 @@ def assign_impedance( non_linear_permeability : bool, optional If the option ``material_name`` is activated, the permeability can either be linear or not. The default value is ``False``. - impedance_name : str, optional - Name of the impedance. The default is ``None`` in which case a unique name is chosen. + impedance : str, optional + Name of the impedance. The default is ``None``, in which case a unique name is assigned. Returns ------- @@ -2224,24 +2245,24 @@ def assign_impedance( Create a box and assign impedance boundary to the faces. + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() >>> shield = m3d.modeler.create_box([-50, -50, -50], [294, 294, 19], name="shield") >>> shield_faces = m3d.modeler.select_allfaces_fromobjects(["shield"]) - >>> impedance_assignment = m3d.assign_impedance(shield_faces, "ShieldImpedance") - - - + >>> impedance_assignment = m3d.assign_impedance(assignment=shield_faces,impedance="ShieldImpedance") + >>> m3d.release_desktop(True, True) """ if self.solution_type in [ "EddyCurrent", "Transient", ]: - if not impedance_name: - impedance_name = generate_unique_name("Impedance") - elif impedance_name in self.modeler.get_boundaries_name(): - impedance_name = generate_unique_name(impedance_name) + if not impedance: + impedance = generate_unique_name("Impedance") + elif impedance in self.modeler.get_boundaries_name(): + impedance = generate_unique_name(impedance) - listobj = self.modeler.convert_to_selections(geometry_selection, True) + listobj = self.modeler.convert_to_selections(assignment, True) props = {"Objects": [], "Faces": []} for sel in listobj: if isinstance(sel, str): @@ -2260,16 +2281,16 @@ def assign_impedance( props["Permeability"] = permeability props["Conductivity"] = conductivity - return self._create_boundary(impedance_name, props, "Impedance") + return self._create_boundary(impedance, props, "Impedance") return False - @pyaedt_function_handler() - def assign_current_density_terminal(self, entities, current_density_name=None): + @pyaedt_function_handler(entities="assignment") + def assign_current_density_terminal(self, assignment, current_density_name=None): """Assign current density terminal to a single or list of entities for an Eddy Current or Magnetostatic solver. Parameters ---------- - entities : list + assignment : list Objects to assign the current to. current_density_name : str, optional Current density name. @@ -2284,7 +2305,7 @@ def assign_current_density_terminal(self, entities, current_density_name=None): if current_density_name is None: current_density_name = generate_unique_name("CurrentDensity") - objects_list = self.modeler.convert_to_selections(entities, True) + objects_list = self.modeler.convert_to_selections(assignment, True) existing_2d_objects_list = [x.name for x in self.modeler.object_list if not x.is3d] if [x for x in objects_list if x not in existing_2d_objects_list]: @@ -2364,11 +2385,11 @@ def get_conduction_paths(self): except Exception: return conduction_paths - @pyaedt_function_handler() + @pyaedt_function_handler(master_entity="independent", slave_entity="dependent") def assign_master_slave( self, - master_entity, - slave_entity, + independent, + dependent, u_vector_origin_coordinates_master, u_vector_pos_coordinates_master, u_vector_origin_coordinates_slave, @@ -2382,9 +2403,9 @@ def assign_master_slave( Parameters ---------- - master_entity : int + independent : int ID of the master entity. - slave_entity : int + dependent : int ID of the slave entity. u_vector_origin_coordinates_master : list Master's list of U vector origin coordinates. @@ -2416,8 +2437,8 @@ def assign_master_slave( >>> oModule.AssignDependent """ try: - master_entity = self.modeler.convert_to_selections(master_entity, True) - slave_entity = self.modeler.convert_to_selections(slave_entity, True) + independent = self.modeler.convert_to_selections(independent, True) + dependent = self.modeler.convert_to_selections(dependent, True) if not bound_name: bound_name_m = generate_unique_name("Independent") bound_name_s = generate_unique_name("Dependent") @@ -2455,7 +2476,7 @@ def assign_master_slave( } ) props2 = OrderedDict( - {"Faces": master_entity, "CoordSysVector": u_master_vector_coordinates, "ReverseV": reverse_master} + {"Faces": independent, "CoordSysVector": u_master_vector_coordinates, "ReverseV": reverse_master} ) bound = BoundaryObject(self, bound_name_m, props2, "Independent") if bound.create(): @@ -2471,7 +2492,7 @@ def assign_master_slave( props2 = OrderedDict( { - "Faces": slave_entity, + "Faces": dependent, "CoordSysVector": u_slave_vector_coordinates, "ReverseU": reverse_slave, "Independent": bound_name_m, @@ -2487,14 +2508,14 @@ def assign_master_slave( except Exception: return False, False - @pyaedt_function_handler - def assign_flux_tangential(self, objects_list, flux_name=None): + @pyaedt_function_handler(objects_list="assignment") + def assign_flux_tangential(self, assignment, flux_name=None): # type : (list, str = None) -> pyaedt.modules.Boundary.BoundaryObject """Assign a flux tangential boundary for a transient A-Phi solver. Parameters ---------- - objects_list : list + assignment : list List of objects to assign the flux tangential boundary condition to. flux_name : str, optional Name of the flux tangential boundary. The default is ``None``, @@ -2515,14 +2536,17 @@ def assign_flux_tangential(self, objects_list, flux_name=None): Create a box and assign a flux tangential boundary to one of its faces. - >>> box = maxwell3d_app.modeler.create_box([50, 0, 50], [294, 294, 19], name="Box") - >>> flux_tangential = maxwell3d_app.assign_flux_tangential(box.faces[0], "FluxExample") + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> box = m3d.modeler.create_box([50, 0, 50], [294, 294, 19], name="Box") + >>> flux_tangential = m3d.assign_flux_tangential(box.faces[0],"FluxExample") + >>> m3d.release_desktop(True, True) """ if self.solution_type != "TransientAPhiFormulation": self.logger.error("Flux tangential boundary can only be assigned to a transient APhi solution type.") return False - objects_list = self.modeler.convert_to_selections(objects_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) if not flux_name: flux_name = generate_unique_name("FluxTangential") @@ -2530,14 +2554,14 @@ def assign_flux_tangential(self, objects_list, flux_name=None): flux_name = generate_unique_name(flux_name) props = {"NAME": flux_name, "Faces": []} - for sel in objects_list: + for sel in assignment: props["Faces"].append(sel) return self._create_boundary(flux_name, props, "FluxTangential") - @pyaedt_function_handler + @pyaedt_function_handler(nets_layers_mapping="net_layers", reference_cs="coordinate_system") def assign_layout_force( - self, nets_layers_mapping, component_name, reference_cs="Global", force_name=None, include_no_layer=True + self, net_layers, component_name, coordinate_system="Global", force_name=None, include_no_layer=True ): # type: (dict, str, str, str, bool) -> bool """Assign the layout force to a component in a Transient A-Phi solver. @@ -2545,14 +2569,14 @@ def assign_layout_force( Parameters ---------- - nets_layers_mapping : dict - Each pair represents the object(s) in the intersection of corresponding layer and net. - Net name is dictionary's key, layers name is the list of layer names. + net_layers : dict + Each pair represents the objects in the intersection of the corresponding net and layer. + The layer name is from the list of layer names. The net name is the dictionary's key. component_name : str - Name of the 3d component to assign the layout force to. - reference_cs : str, optional + Name of the 3D component to assign the layout force to. + coordinate_system : str, optional Reference coordinate system. - If not provided the global one will be set. + If not provided, the global one is used. force_name : str, optional Name of the layout force. If not provided a random name will be generated. @@ -2573,18 +2597,20 @@ def assign_layout_force( -------- Create a dictionary to give as an input to assign_layout_force method. - >>> nets_layers = {} - >>> nets_layers[""] = ["PWR","TOP","UNNAMED_000","UNNAMED_002"] - >>> nets_layers["GND"] = ["LYR_1","LYR_2","UNNAMED_006"] + >>> nets_layers = {"": ["PWR","TOP","UNNAMED_000","UNNAMED_002"], + >>> "GND": ["LYR_1","LYR_2","UNNAMED_006"]} + >>> Assign layout force to a component. + >>> from pyaedt import Maxwell3d >>> m3d = Maxwell3d() - >>> m3d.assign_layout_force(nets_layers_mapping=nets_layers, component_name="LC1_1") + >>> m3d.assign_layout_force(net_layers=nets_layers,component_name="LC1_1") + >>> m3d.release_desktop(True, True) """ - for key in nets_layers_mapping.keys(): - if not isinstance(nets_layers_mapping[key], list): - nets_layers_mapping[key] = list(nets_layers_mapping[key]) + for key in net_layers.keys(): + if not isinstance(net_layers[key], list): + net_layers[key] = list(net_layers[key]) if component_name not in self.modeler.user_defined_component_names: self.logger.error("Provided component name doesn't exist in current design.") @@ -2594,7 +2620,7 @@ def assign_layout_force( force_name = generate_unique_name("Layout_Force") nets_layers_props = None - for key, valy in nets_layers_mapping.items(): + for key, valy in net_layers.items(): layers = valy[:] if include_no_layer: layers = layers[:] + [""] @@ -2605,7 +2631,7 @@ def assign_layout_force( props = OrderedDict( { - "Reference CS": reference_cs, + "Reference CS": coordinate_system, "NetsAndLayersChoices": OrderedDict( {component_name: OrderedDict({"NetLayerSetMap": nets_layers_props})} ), @@ -2616,10 +2642,10 @@ def assign_layout_force( self._boundaries[bound.name] = bound return bound - @pyaedt_function_handler() + @pyaedt_function_handler(faces="assignment") def assign_tangential_h_field( self, - faces, + assignment, x_component_real=0, x_component_imag=0, y_component_real=0, @@ -2634,7 +2660,7 @@ def assign_tangential_h_field( Parameters ---------- - faces : list of int or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : list of int or :class:`pyaedt.modeler.cad.object3d.Object3d` List of objects to assign an end connection to. x_component_real : float, str, optional X component value real part. The default is ``0``. @@ -2671,18 +2697,18 @@ def assign_tangential_h_field( if self.solution_type not in ["EddyCurrent", "Magnetostatic"]: self.logger.error("Tangential H Field is applicable only to Eddy current.") return False - objects = self.modeler.convert_to_selections(faces, True) + assignment = self.modeler.convert_to_selections(assignment, True) if not bound_name: bound_name = generate_unique_name("TangentialHField") props = OrderedDict( { - "Faces": objects, + "Faces": assignment, } ) - if isinstance(objects[0], str): + if isinstance(assignment[0], str): props = OrderedDict( { - "Objects": objects, + "Objects": assignment, } ) props["ComponentXReal"] = x_component_real @@ -2691,8 +2717,8 @@ def assign_tangential_h_field( props["ComponentYReal"] = y_component_real if self.solution_type == "EddyCurrent": props["ComponentYImag"] = y_component_imag - if not origin and isinstance(objects[0], int): - edges = self.modeler.get_face_edges(objects[0]) + if not origin and isinstance(assignment[0], int): + edges = self.modeler.get_face_edges(assignment[0]) origin = self.oeditor.GetEdgePositionAtNormalizedParameter(edges[0], 0) if not u_pos: u_pos = self.oeditor.GetEdgePositionAtNormalizedParameter(edges[0], 1) @@ -2705,15 +2731,15 @@ def assign_tangential_h_field( return bound return False - @pyaedt_function_handler() - def assign_zero_tangential_h_field(self, faces, bound_name=None): + @pyaedt_function_handler(faces="assignment", bound_name="boundary") + def assign_zero_tangential_h_field(self, assignment, boundary=None): """Assign a zero tangential H field boundary to a list of faces. Parameters ---------- - faces : list of int or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : list of int or :class:`pyaedt.modeler.cad.object3d.Object3d` List of objects to assign an end connection to. - bound_name : str, optional + boundary : str, optional Name of the end connection boundary. The default is ``None``, in which case the default name is used. @@ -2730,15 +2756,15 @@ def assign_zero_tangential_h_field(self, faces, bound_name=None): if self.solution_type not in ["EddyCurrent"]: self.logger.error("Tangential H Field is applicable only to Eddy current.") return False - objects = self.modeler.convert_to_selections(faces, True) - if not bound_name: - bound_name = generate_unique_name("ZeroTangentialHField") + assignment = self.modeler.convert_to_selections(assignment, True) + if not boundary: + boundary = generate_unique_name("ZeroTangentialHField") props = OrderedDict( { - "Faces": objects, + "Faces": assignment, } ) - bound = BoundaryObject(self, bound_name, props, "Zero Tangential H Field") + bound = BoundaryObject(self, boundary, props, "Zero Tangential H Field") if bound.create(): self._boundaries[bound.name] = bound return bound @@ -2808,18 +2834,18 @@ class Maxwell2d(Maxwell, FieldAnalysis3D, object): not exist. >>> from pyaedt import Maxwell2d - >>> aedtapp = Maxwell2d() + >>> m2d = Maxwell2d() Create an instance of Maxwell 2D and link to a project named ``projectname``. If this project does not exist, create one with this name. - >>> aedtapp = Maxwell2d(projectname) + >>> m2d = Maxwell2d(projectname) Create an instance of Maxwell 2D and link to a design named ``designname`` in a project named ``projectname``. - >>> aedtapp = Maxwell2d(projectname,designame) + >>> m2d = Maxwell2d(projectname,designname) """ @@ -2873,7 +2899,7 @@ def __init__( Maxwell.__init__(self) def _init_from_design(self, *args, **kwargs): - self.__init__(*args, **kwargs) + self.__init__(**kwargs) @property def xy_plane(self): @@ -2901,15 +2927,15 @@ def model_depth(self, value): value = self.modeler._arg_with_dim(value, self.modeler.model_units) self.change_design_settings({"ModelDepth": value}) - @pyaedt_function_handler() - def generate_design_data(self, linefilter=None, objectfilter=None): - """Generate a generic set of design data and store it in the extension directory as ``design_data.json``. + @pyaedt_function_handler(linefilter="line_filter", objectfilter="object_filter") + def generate_design_data(self, line_filter=None, object_filter=None): + """Generate a generic set of design data and store it in the extension directory in a ``design_data.json`` file. Parameters ---------- - linefilter : optional + line_filter : optional The default is ``None``. - objectfilter : optional + object_filter : optional The default is ``None``. Returns @@ -2929,8 +2955,8 @@ def convert(obj): return obj solid_bodies = self.modeler.solid_bodies - if objectfilter: - solid_ids = [i for i, j in self.modeler._object_names_to_ids.items() if j.name in objectfilter] + if object_filter: + solid_ids = [i for i, j in self.modeler._object_names_to_ids.items() if j.name in object_filter] else: solid_ids = [i for i in list(self.modeler._object_names_to_ids.keys())] self.design_data = { @@ -2943,7 +2969,7 @@ def convert(obj): "Symmetry": self.symmetry_multiplier, "ModelDepth": self.model_depth, "ObjectList": solid_ids, - "LineList": self.modeler.vertex_data_of_lines(linefilter), + "LineList": self.modeler.vertex_data_of_lines(line_filter), "VarList": self.variable_manager.variable_names, "Setups": self.existing_analysis_setups, "MaterialProperties": self.get_object_material_properties(solid_bodies), @@ -2966,15 +2992,15 @@ def read_design_data(self): design_file = os.path.join(self.working_directory, "design_data.json") return read_configuration_file(design_file) - @pyaedt_function_handler() - def assign_balloon(self, edge_list, bound_name=None): + @pyaedt_function_handler(edge_list="assignment", bound_name="boundary") + def assign_balloon(self, assignment, boundary=None): """Assign a balloon boundary to a list of edges. Parameters ---------- - edge_list : list + assignment : list List of edges. - bound_name : str, optional + boundary : str, optional Name of the boundary. The default is ``None``, in which case the default name is used. @@ -2988,32 +3014,32 @@ def assign_balloon(self, edge_list, bound_name=None): >>> oModule.AssignBalloon """ - edge_list = self.modeler.convert_to_selections(edge_list, True) + assignment = self.modeler.convert_to_selections(assignment, True) - if not bound_name: - bound_name = generate_unique_name("Balloon") + if not boundary: + boundary = generate_unique_name("Balloon") - props2 = OrderedDict({"Edges": edge_list}) - bound = BoundaryObject(self, bound_name, props2, "Balloon") + props2 = OrderedDict({"Edges": assignment}) + bound = BoundaryObject(self, boundary, props2, "Balloon") if bound.create(): self._boundaries[bound.name] = bound return bound return False - @pyaedt_function_handler() - def assign_vector_potential(self, input_edge, vectorvalue=0, bound_name=None): + @pyaedt_function_handler(input_edge="assignment", vectorvalue="vector_value", bound_name="boundary") + def assign_vector_potential(self, assignment, vector_value=0, boundary=None): """Assign a vector potential boundary condition to specified edges. This method is valid for Maxwell 2D Eddy Current, Magnetostatic, and Transient solvers. Parameters ---------- - input_edge : list + assignment : list List of edge names or edge IDs to assign a vector to. - vectorvalue : float, optional + vector_value : float, optional Value of the vector. The default is ``0``. - bound_name : str, optional + boundary : str, optional Name of the boundary. The default is ``None``, in which case the default name is used. @@ -3027,32 +3053,32 @@ def assign_vector_potential(self, input_edge, vectorvalue=0, bound_name=None): >>> oModule.AssignVectorPotential """ - input_edge = self.modeler.convert_to_selections(input_edge, True) + assignment = self.modeler.convert_to_selections(assignment, True) - if not bound_name: - bound_name = generate_unique_name("Vector") - if type(input_edge[0]) is str: - props2 = OrderedDict({"Objects": input_edge, "Value": str(vectorvalue), "CoordinateSystem": ""}) + if not boundary: + boundary = generate_unique_name("Vector") + if type(assignment[0]) is str: + props2 = OrderedDict({"Objects": assignment, "Value": str(vector_value), "CoordinateSystem": ""}) else: - props2 = OrderedDict({"Edges": input_edge, "Value": str(vectorvalue), "CoordinateSystem": ""}) - bound = BoundaryObject(self, bound_name, props2, "Vector Potential") + props2 = OrderedDict({"Edges": assignment, "Value": str(vector_value), "CoordinateSystem": ""}) + bound = BoundaryObject(self, boundary, props2, "Vector Potential") if bound.create(): self._boundaries[bound.name] = bound return bound return False - @pyaedt_function_handler() + @pyaedt_function_handler(master_edge="independent", slave_edge="dependent", bound_name="boundary") def assign_master_slave( - self, master_edge, slave_edge, reverse_master=False, reverse_slave=False, same_as_master=True, bound_name=None + self, independent, dependent, reverse_master=False, reverse_slave=False, same_as_master=True, boundary=None ): """Assign dependent and independent boundary conditions to two edges of the same object. Parameters ---------- - master_edge : int + independent : int ID of the master edge. - slave_edge : int + dependent : int ID of the slave edge. reverse_master : bool, optional Whether to reverse the master edge to the V direction. The default is ``False``. @@ -3060,7 +3086,7 @@ def assign_master_slave( Whether to reverse the master edge to the U direction. The default is ``False``. same_as_master : bool, optional Whether the B-Field of the slave edge and master edge are the same. The default is ``True``. - bound_name : str, optional + boundary : str, optional Name of the master boundary. The default is ``None``, in which case the default name is used. The name of the slave boundary has a ``_dep`` suffix. @@ -3074,22 +3100,22 @@ def assign_master_slave( >>> oModule.AssignIndependent >>> oModule.AssignDependent """ - master_edge = self.modeler.convert_to_selections(master_edge, True) - slave_edge = self.modeler.convert_to_selections(slave_edge, True) - if not bound_name: + independent = self.modeler.convert_to_selections(independent, True) + dependent = self.modeler.convert_to_selections(dependent, True) + if not boundary: bound_name_m = generate_unique_name("Independent") bound_name_s = generate_unique_name("Dependent") else: - bound_name_m = bound_name - bound_name_s = bound_name + "_dep" - props2 = OrderedDict({"Edges": master_edge, "ReverseV": reverse_master}) + bound_name_m = boundary + bound_name_s = boundary + "_dep" + props2 = OrderedDict({"Edges": independent, "ReverseV": reverse_master}) bound = BoundaryObject(self, bound_name_m, props2, "Independent") if bound.create(): self._boundaries[bound.name] = bound props2 = OrderedDict( { - "Edges": slave_edge, + "Edges": dependent, "ReverseU": reverse_slave, "Independent": bound_name_m, "SameAsMaster": same_as_master, @@ -3103,13 +3129,13 @@ def assign_master_slave( return bound, False return False, False - @pyaedt_function_handler() - def assign_end_connection(self, objects, resistance=0, inductance=0, bound_name=None): + @pyaedt_function_handler(objects="assignment", bound_name="boundary") + def assign_end_connection(self, assignment, resistance=0, inductance=0, boundary=None): """Assign an end connection to a list of objects. Parameters ---------- - objects : list of int or str or :class:`pyaedt.modeler.cad.object3d.Object3d` + assignment : list of int or str or :class:`pyaedt.modeler.cad.object3d.Object3d` List of objects to assign an end connection to. resistance : float or str, optional Resistance value. If float is provided, the units are assumed to be ohms. @@ -3117,7 +3143,7 @@ def assign_end_connection(self, objects, resistance=0, inductance=0, bound_name= inductance : float or str, optional Inductance value. If a float is provided, the units are assumed to Henry (H). The default value is ``0``. - bound_name : str, optional + boundary : str, optional Name of the end connection boundary. The default is ``None``, in which case the default name is used. @@ -3134,21 +3160,21 @@ def assign_end_connection(self, objects, resistance=0, inductance=0, bound_name= if self.solution_type not in ["EddyCurrent", "Transient"]: self.logger.error("Excitation applicable only to Eddy current or Transient Solver.") return False - if len(objects) < 2: + if len(assignment) < 2: self.logger.error("At least 2 objects are needed.") return False - objects = self.modeler.convert_to_selections(objects, True) - if not bound_name: - bound_name = generate_unique_name("EndConnection") + assignment = self.modeler.convert_to_selections(assignment, True) + if not boundary: + boundary = generate_unique_name("EndConnection") props = OrderedDict( { - "Objects": objects, + "Objects": assignment, "ResistanceValue": self.modeler._arg_with_dim(resistance, "ohm"), "InductanceValue": self.modeler._arg_with_dim(inductance, "H"), } ) - bound = BoundaryObject(self, bound_name, props, "EndConnection") + bound = BoundaryObject(self, boundary, props, "EndConnection") if bound.create(): self._boundaries[bound.name] = bound return bound diff --git a/pyaedt/mechanical.py b/pyaedt/mechanical.py index 8dc0a4816c6..b4523073a81 100644 --- a/pyaedt/mechanical.py +++ b/pyaedt/mechanical.py @@ -131,27 +131,33 @@ def __init__( def _init_from_design(self, *args, **kwargs): self.__init__(*args, **kwargs) - @pyaedt_function_handler() + @pyaedt_function_handler( + designname="design", + setupname="setup", + sweepname="sweep", + paramlist="parameters", + object_list="assignment", + ) def assign_em_losses( self, - designname="HFSSDesign1", - setupname="Setup1", - sweepname="LastAdaptive", + design="HFSSDesign1", + setup="Setup1", + sweep="LastAdaptive", map_frequency=None, surface_objects=None, source_project_name=None, - paramlist=None, - object_list=None, + parameters=None, + assignment=None, ): """Map EM losses to a Mechanical design. Parameters ---------- - designname : str, optional + design : str, optional Name of the design of the source mapping. The default is ``"HFSSDesign1"``. - setupname : str, optional + setup : str, optional Name of the EM setup. The default is ``"Setup1"``. - sweepname : str, optional + sweep : str, optional Name of the EM sweep to use for the mapping. The default is ``"LastAdaptive"``. map_frequency : str, optional Frequency to map. The default is ``None``. The value must be ``None`` for @@ -161,9 +167,9 @@ def assign_em_losses( source_project_name : str, optional Name of the source project. The default is ``None``, in which case the source from the same project is used. - paramlist : list, optional + parameters : list, optional List of all parameters in the EM to map. The default is ``None``. - object_list : list, optional + assignment : list, optional The default is ``None``. Returns @@ -177,14 +183,14 @@ def assign_em_losses( """ if surface_objects is None: surface_objects = [] - if paramlist is None: - paramlist = [] - if object_list is None: - object_list = [] + if parameters is None: + parameters = [] + if assignment is None: + assignment = [] assert "Thermal" in self.solution_type, "This method works only in a Mechanical Thermal analysis." - self.logger.info("Mapping HFSS EM Lossess") + self.logger.info("Mapping HFSS EM Loss") oName = self.project_name if oName == source_project_name or source_project_name is None: projname = "This Project*" @@ -193,10 +199,10 @@ def assign_em_losses( # # Generate a list of model objects from the lists made previously and use to map the HFSS losses into Icepak. # - if not object_list: + if not assignment: allObjects = self.modeler.object_names else: - allObjects = object_list[:] + allObjects = assignment[:] surfaces = surface_objects if map_frequency: intr = [map_frequency] @@ -207,7 +213,7 @@ def assign_em_losses( for el in self.available_variations.nominal_w_values_dict: argparam[el] = self.available_variations.nominal_w_values_dict[el] - for el in paramlist: + for el in parameters: argparam[el] = el props = OrderedDict( @@ -216,8 +222,8 @@ def assign_em_losses( "allObjects": False, "Project": projname, "projname": "ElectronicsDesktop", - "Design": designname, - "Soln": setupname + " : " + sweepname, + "Design": design, + "Soln": setup + " : " + sweep, "Params": argparam, "ForceSourceToSolve": True, "PreservePartnerSoln": True, @@ -232,19 +238,25 @@ def assign_em_losses( bound = BoundaryObject(self, name, props, "EMLoss") if bound.create(): self._boundaries[bound.name] = bound - self.logger.info("EM losses mapped from design %s.", designname) + self.logger.info("EM losses mapped from design %s.", design) return bound return False - @pyaedt_function_handler() + @pyaedt_function_handler( + designname="design", + setupname="setup", + sweepname="sweep", + paramlist="parameters", + object_list="assignment", + ) def assign_thermal_map( self, object_list, - designname="IcepakDesign1", - setupname="Setup1", - sweepname="SteadyState", + design="IcepakDesign1", + setup="Setup1", + sweep="SteadyState", source_project_name=None, - paramlist=None, + parameters=None, ): """Map thermal losses to a Mechanical design. @@ -255,16 +267,16 @@ def assign_thermal_map( ---------- object_list : list - designname : str, optional + design : str, optional Name of the design with the source mapping. The default is ``"IcepakDesign1"``. - setupname : str, optional + setup : str, optional Name of the EM setup. The default is ``"Setup1"``. - sweepname : str, optional + sweep : str, optional Name of the EM sweep to use for the mapping. The default is ``"SteadyState"``. source_project_name : str, optional Name of the source project. The default is ``None``, in which case the source from the same project is used. - paramlist : list, optional + parameters : list, optional List of all parameters in the EM to map. The default is ``None``. Returns @@ -277,12 +289,12 @@ def assign_thermal_map( >>> oModule.AssignThermalCondition """ - if paramlist is None: - paramlist = [] + if parameters is None: + parameters = [] assert self.solution_type == "Structural", "This method works only in a Mechanical Structural analysis." - self.logger.info("Mapping HFSS EM Lossess") + self.logger.info("Mapping HFSS EM Loss") oName = self.project_name if oName == source_project_name or source_project_name is None: projname = "This Project*" @@ -300,7 +312,7 @@ def assign_thermal_map( for el in self.available_variations.nominal_w_values_dict: argparam[el] = self.available_variations.nominal_w_values_dict[el] - for el in paramlist: + for el in parameters: argparam[el] = el props = OrderedDict( @@ -309,8 +321,8 @@ def assign_thermal_map( "Uniform": False, "Project": projname, "Product": "ElectronicsDesktop", - "Design": designname, - "Soln": setupname + " : " + sweepname, + "Design": design, + "Soln": setup + " : " + sweep, "Params": argparam, "ForceSourceToSolve": True, "PreservePartnerSoln": True, @@ -322,7 +334,7 @@ def assign_thermal_map( bound = BoundaryObject(self, name, props, "ThermalCondition") if bound.create(): self._boundaries[bound.name] = bound - self.logger.info("Thermal conditions are mapped from design %s.", designname) + self.logger.info("Thermal conditions are mapped from design %s.", design) return bound return True @@ -367,8 +379,8 @@ def assign_uniform_convection( props = {} objects_list = self.modeler.convert_to_selections(objects_list, True) - if type(objects_list) is list: - if type(objects_list[0]) is str: + if isinstance(objects_list, list): + if isinstance(objects_list[0], str): props["Objects"] = objects_list else: props["Faces"] = objects_list @@ -416,8 +428,8 @@ def assign_uniform_temperature(self, objects_list, temperature="AmbientTemp", bo props = {} objects_list = self.modeler.convert_to_selections(objects_list, True) - if type(objects_list) is list: - if type(objects_list[0]) is str: + if isinstance(objects_list, list): + if isinstance(objects_list[0], str): props["Objects"] = objects_list else: props["Faces"] = objects_list @@ -632,23 +644,21 @@ def assign_heat_generation(self, objects_list, value, boundary_name=""): return bound return False - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setupname="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create an analysis setup for Mechanical. - Optional arguments are passed along with ``setuptype`` and ``setupname``. Keyword - names correspond to the ``setuptype`` - corresponding to the native AEDT API. The list of + Optional arguments are passed along with ``setup_type`` and ``name``. Keyword + names correspond to the ``setup_type`` corresponding to the native AEDT API. The list of keywords here is not exhaustive. - Parameters ---------- - setuptype : int, str, optional + name : str, optional + Name of the setup. The default is ``"Setup1"``. + setup_type : int, str, optional Type of the setup. Options are ``"IcepakSteadyState"`` and ``"IcepakTransient"``. The default is ``"IcepakSteadyState"``. - setupname : str, optional - Name of the setup. The default is ``"Setup1"``. **kwargs : dict, optional Available keys depend on the setup chosen. For more information, see :doc:`../SetupTemplatesMechanical`. @@ -668,17 +678,17 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Mechanical >>> app = Mechanical() - >>> app.create_setup(setupname="Setup1", MaxModes=6)) + >>> app.create_setup(name="Setup1",MaxModes=6) """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) if "props" in kwargs: - return self._create_setup(setupname=setupname, setuptype=setuptype, props=kwargs["props"]) + return self._create_setup(name=name, setup_type=setup_type, props=kwargs["props"]) else: - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: diff --git a/pyaedt/modeler/advanced_cad/parts.py b/pyaedt/modeler/advanced_cad/parts.py index 939a3fd5843..526a811eb78 100644 --- a/pyaedt/modeler/advanced_cad/parts.py +++ b/pyaedt/modeler/advanced_cad/parts.py @@ -487,16 +487,10 @@ def _insert(self, app, target_cs=None, units=None): units = self._multiparts.units if self._compdef["ffd_name"]: ffd = os.path.join(self._compdef["part_folder"], self._compdef["ffd_name"] + ".ffd") - a = app.create_sbr_file_based_antenna( - ffd_full_path=ffd, model_units=units, target_cs=target_cs, antenna_name=self.name - ) + a = app.create_sbr_file_based_antenna(far_field_data=ffd, target_cs=target_cs, units=units, name=self.name) else: a = app.create_sbr_antenna( - self._antenna_type(app), - model_units=units, - parameters_dict=self.params, - target_cs=target_cs, - antenna_name=self.name, + self._antenna_type(app), target_cs=target_cs, units=units, parameters=self.params, name=self.name ) return a diff --git a/pyaedt/modeler/advanced_cad/stackup_3d.py b/pyaedt/modeler/advanced_cad/stackup_3d.py index 1c043f58c51..f84d0e2711e 100644 --- a/pyaedt/modeler/advanced_cad/stackup_3d.py +++ b/pyaedt/modeler/advanced_cad/stackup_3d.py @@ -2451,10 +2451,7 @@ def create_probe_port(self, reference_layer, rel_x_offset=0, rel_y_offset=0, r=0 # Assign port. Find the face with the minimum z-position. self.application.wave_port( - probe_feed_outer.bottom_face_z, - reference=probe_feed_outer.name, - create_pec_cap=True, - name="Probe_Port", + probe_feed_outer.bottom_face_z, reference=probe_feed_outer.name, create_pec_cap=True, name="Probe_Port" ) def create_lumped_port(self, reference_layer, opposite_side=False, port_name=None, axisdir=None): @@ -2514,9 +2511,9 @@ def create_lumped_port(self, reference_layer, opposite_side=False, port_name=Non if self.application.solution_type == "Modal": if axisdir is None: axisdir = self.application.AxisDir.ZPos - port = self.application.lumped_port(rect.name, name=port_name, integration_line=axisdir) + port = self.application.lumped_port(rect.name, integration_line=axisdir, name=port_name) elif self.application.solution_type == "Terminal": - port = self.application.lumped_port(rect.name, name=port_name, reference=[reference_layer.name]) + port = self.application.lumped_port(rect.name, reference=[reference_layer.name], name=port_name) return port def quarter_wave_feeding_line(self, impedance_to_adapt=50): @@ -3254,10 +3251,16 @@ def create_lumped_port(self, reference_layer, opposite_side=False, port_name=Non if self.application.solution_type == "Modal": if axisdir is None: axisdir = self.application.AxisDir.ZPos - port = self.application.create_lumped_port_to_sheet(port.name, portname=port_name, axisdir=axisdir) + port = self.application.lumped_port( + signal=port.name, name=port_name, integration_line=axisdir, create_port_sheet=False + ) elif self.application.solution_type == "Terminal": - port = self.application.create_lumped_port_to_sheet( - port.name, portname=port_name, reference_object_list=[reference_layer.name] + port = self.application.lumped_port( + signal=port.name, + name=port_name, + integration_line=axisdir, + create_port_sheet=False, + reference=[reference_layer.name], ) return port diff --git a/pyaedt/modeler/cad/Modeler.py b/pyaedt/modeler/cad/Modeler.py index 56622395c8d..f346c2342b3 100644 --- a/pyaedt/modeler/cad/Modeler.py +++ b/pyaedt/modeler/cad/Modeler.py @@ -614,13 +614,13 @@ def _get_type_from_id(self, obj_id): @pyaedt_function_handler() def _get_type_from_object(self, obj): """Get the entity type from the object.""" - if type(obj) is FacePrimitive: + if isinstance(obj, FacePrimitive): return "Face" - elif type(obj) is EdgePrimitive: + elif isinstance(obj, EdgePrimitive): return "Edge" - elif type(obj) is VertexPrimitive: + elif isinstance(obj, VertexPrimitive): return "Vertex" - elif type(obj) is Object3d: + elif isinstance(obj, Object3d): return "3dObject" else: # pragma: no cover raise ValueError("Cannot detect the entity type.") diff --git a/pyaedt/modeler/cad/Primitives.py b/pyaedt/modeler/cad/Primitives.py index dca244e91b0..9292fde8307 100644 --- a/pyaedt/modeler/cad/Primitives.py +++ b/pyaedt/modeler/cad/Primitives.py @@ -2423,7 +2423,7 @@ def get_objects_in_group(self, group): >>> oEditor.GetObjectsInGroup """ - if type(group) is not str: + if not isinstance(group, str): raise ValueError("Group name must be a string") group_objs = list(self.oeditor.GetObjectsInGroup(group)) if not group_objs: @@ -2451,7 +2451,7 @@ def get_group_bounding_box(self, group): >>> oEditor.GetObjectsInGroup >>> oEditor.GetModelBoundingBox """ - if type(group) is not str: + if not isinstance(group, str): raise ValueError("Group name must be a string") group_objs = list(self.oeditor.GetObjectsInGroup(group)) if not group_objs: @@ -4605,7 +4605,6 @@ def import_3d_cad( >>> oEditor.Import """ - if str(healing) in ["0", "1"]: warnings.warn( "Assigning `0` or `1` to `healing` option is deprecated. Assign `True` or `False` instead.", @@ -4966,7 +4965,7 @@ def get_faces_from_materials(self, mats): sel = [] objs = [] - if type(mats) is str: + if isinstance(mats, str): mats = [mats] for mat in mats: objs.extend(list(self.oeditor.GetObjectsByMaterial(mat.lower()))) @@ -6233,10 +6232,8 @@ def create_region(self, pad_value=300, pad_type="Percentage Offset", region_name is_percentage = True if kwarg.get("pad_percent", False): pad_percent = kwarg["pad_percent"] - else: - pad_percent = 300 - pad_value = pad_percent - if isinstance(pad_value, list): + pad_value = pad_percent + if isinstance(pad_value, list) and len(pad_value) < 6: pad_value = [pad_value[i // 2 + 3 * (i % 2)] for i in range(6)] pad_type = ["Absolute Offset", "Percentage Offset"][int(is_percentage)] @@ -8383,7 +8380,7 @@ def _crosssection_arguments(self, type, orient, width, topwidth, height, num_seg def _arg_with_dim(self, value, units=None): if units is None: units = self.model_units - if type(value) is str: + if isinstance(value, str): try: float(value) val = "{0}{1}".format(value, units) diff --git a/pyaedt/modeler/cad/Primitives2D.py b/pyaedt/modeler/cad/Primitives2D.py index 6efc7737b99..2222b4f72db 100644 --- a/pyaedt/modeler/cad/Primitives2D.py +++ b/pyaedt/modeler/cad/Primitives2D.py @@ -281,17 +281,26 @@ def create_regular_polygon( return self._create_object(new_object_name, **kwargs) @pyaedt_function_handler() - def create_region(self, pad_percent=300, is_percentage=True): + def create_region(self, pad_value=300, pad_type="Percentage Offset", region_name="Region", **kwarg): """Create an air region. Parameters ---------- - pad_percent : float, str, list of floats or list of str, optional - Same padding is applied if not a list. The default is ``300``. - If a list of floats or strings, interpret as adding ``["+X", "+Y", "-X", "-Y"]`` for XY geometry mode, - and ``["+R", "+Z", "-Z"]`` for RZ geometry mode. - is_percentage : bool, optional - Whether the region definition is a percentage or absolute value. The default is `True``. + pad_value : float, str, list of floats or list of str, optional + Padding values to apply. If a list is not provided, the same + value is applied to all padding directions. If a list of floats + or strings is provided, the values are + interpreted as padding for ``["+X", "-X", "+Y", "-Y", "+Z", "-Z"]``. + pad_type : str, optional + Padding definition. The default is ``"Percentage Offset"``. + Options are ``"Absolute Offset"``, + ``"Absolute Position"``, ``"Percentage Offset"``, and + ``"Transverse Percentage Offset"``. When using a list, + different padding types can be provided for different + directions. + region_name : str, optional + Region name. The default is ``None``, in which case the name + is generated automatically. Returns ------- @@ -303,19 +312,35 @@ def create_region(self, pad_percent=300, is_percentage=True): >>> oEditor.CreateRegion """ - if not isinstance(pad_percent, list): - pad_percent = [pad_percent] * 4 + # backward compatibility + if kwarg: + if "is_percentage" in kwarg.keys(): + is_percentage = kwarg["is_percentage"] + else: + is_percentage = True + if kwarg.get("pad_percent", False): + pad_percent = kwarg["pad_percent"] + pad_value = pad_percent + if isinstance(pad_value, list) and len(pad_value) < 6: + pad_value = [pad_value[i // 2 + 3 * (i % 2)] for i in range(6)] + pad_type = ["Absolute Offset", "Percentage Offset"][int(is_percentage)] + + if isinstance(pad_type, bool): + pad_type = ["Absolute Offset", "Percentage Offset"][int(pad_type)] + + if not isinstance(pad_value, list): + pad_value = [pad_value] * 4 if self._app.design_type == "2D Extractor" or ( self._app.design_type == "Maxwell 2D" and self._app.odesign.GetGeometryMode() == "XY" ): - if len(pad_percent) != 4: + if len(pad_value) != 4: self.logger.error("Wrong padding list provided. Four values have to be provided.") return False - pad_percent = [pad_percent[0], pad_percent[2], pad_percent[1], pad_percent[3], 0, 0] + pad_value = [pad_value[0], pad_value[2], pad_value[1], pad_value[3], 0, 0] else: - if len(pad_percent) < 3: + if len(pad_value) < 3: self.logger.error("Wrong padding list provided. Three values have to be provided for RZ geometry.") return False - pad_percent = [pad_percent[0], 0, 0, 0, pad_percent[1], pad_percent[2]] + pad_value = [pad_value[0], 0, 0, 0, pad_value[1], pad_value[2]] - return self._create_region(pad_percent, ["Absolute Offset", "Percentage Offset"][int(is_percentage)]) + return self._create_region(pad_value, pad_type, region_name, region_type="Region") diff --git a/pyaedt/modeler/cad/Primitives3D.py b/pyaedt/modeler/cad/Primitives3D.py index f92ea1afb97..050ba9e0f87 100644 --- a/pyaedt/modeler/cad/Primitives3D.py +++ b/pyaedt/modeler/cad/Primitives3D.py @@ -14,7 +14,9 @@ from pyaedt import Edb from pyaedt import Icepak from pyaedt.generic import LoadAEDTFile +from pyaedt.generic.desktop_sessions import _edb_sessions from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import generate_unique_project_name from pyaedt.generic.general_methods import normalize_path from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler @@ -287,7 +289,6 @@ def create_polyhedron(self, cs_axis=None, center_position=(0.0, 0.0, 0.0), start ... start_position=[0,5,0], height=0.5, ... num_sides=8, name="mybox", matname="copper") """ - test = cs_axis cs_axis = GeometryOperators.cs_axis_str(cs_axis) if len(center_position) != 3: self.logger.error("The ``center_position`` argument must be a valid three-element list.") @@ -672,19 +673,19 @@ def create_bondwire(self, start_position, end_position, h1=0.2, h2=0, alpha=80, first_argument.append("YDir:="), first_argument.append(y_length) first_argument.append("ZDir:="), first_argument.append(z_length) distance = ( - "sqrt((" - + str(x_position_end) - + "-(" - + str(x_position) - + ")) ** 2 + (" - + str(y_position_end) - + "-(" - + str(y_position) - + ")) ** 2 + ( " - + str(z_position_end) - + "-(" - + str(z_position) - + ")) ** 2) meter" + "sqrt((" + + str(x_position_end) + + "-(" + + str(x_position) + + ")) ** 2 + (" + + str(y_position_end) + + "-(" + + str(y_position) + + ")) ** 2 + ( " + + str(z_position_end) + + "-(" + + str(z_position) + + ")) ** 2) meter" ) first_argument.append("Distance:="), first_argument.append(distance) @@ -837,7 +838,7 @@ def create_circle(self, cs_plane, position, radius, numSides=0, is_covered=True, @pyaedt_function_handler() def create_ellipse( - self, cs_plane, position, major_radius, ratio, is_covered=True, name=None, matname=None, **kwargs + self, cs_plane, position, major_radius, ratio, is_covered=True, name=None, matname=None, **kwargs ): """Create an ellipse. @@ -1154,11 +1155,11 @@ def create_helix(self, polyline_name, position, x_start_dir, y_start_dir, z_star @pyaedt_function_handler() def create_udm( - self, - udmfullname, - udm_params_list, - udm_library="syslib", - name=None, + self, + udmfullname, + udm_params_list, + udm_library="syslib", + name=None, ): """Create a user-defined model. @@ -1361,15 +1362,15 @@ def _create_reference_cs_from_3dcomp(self, udm_obj, password): @pyaedt_function_handler() def insert_3d_component( - self, - comp_file, - geo_params=None, - sz_mat_params="", - sz_design_params="", - targetCS="Global", - name=None, - password="", - auxiliary_dict=False, + self, + comp_file, + geo_params=None, + sz_mat_params="", + sz_design_params="", + targetCS="Global", + name=None, + password="", + auxiliary_dict=False, ): """Insert a new 3D component. @@ -1416,8 +1417,7 @@ def insert_3d_component( if "IsEncrypted" in line: line_list = line.split("=") if line_list[1] in ["true", "True", True] and password == "": - self.logger.error("Password can't be an empty string.") - return False + self.logger.warning("Encrypted model.") aedt_fh.close() vArg1 = ["NAME:InsertComponentData"] sz_geo_params = "" @@ -1493,9 +1493,9 @@ def insert_3d_component( aux_dict["coordinatesystems"].pop(cs) if aux_dict["coordinatesystems"][udm_obj.name + "_" + cs]["Reference CS"] != "Global": aux_dict["coordinatesystems"][udm_obj.name + "_" + cs]["Reference CS"] = ( - udm_obj.name - + "_" - + aux_dict["coordinatesystems"][udm_obj.name + "_" + cs]["Reference CS"] + udm_obj.name + + "_" + + aux_dict["coordinatesystems"][udm_obj.name + "_" + cs]["Reference CS"] ) for _, ncdict in aux_dict["native components"].items(): for _, inst_dict in ncdict["Instances"].items(): @@ -1517,7 +1517,7 @@ def insert_3d_component( self._app.configurations.options.import_native_components = True self._app.configurations.options.import_monitor = True temp_dict_file = os.path.join(self._app.toolkit_directory, generate_unique_name("tempdict_")) - with open(temp_dict_file, "w") as f: + with open_file(temp_dict_file, "w") as f: json.dump(temp_dict, f) exclude_set = set([obj.name for _, obj in self._app.modeler.objects.items()]) old_udm = set(list(self._app.modeler.user_defined_components)) @@ -1533,7 +1533,7 @@ def insert_3d_component( if cs.ref_cs == "Global": cs.ref_cs = targetCS if aux_dict.get("monitors", None): - temp_proj_name = self._app._generate_unique_project_name() + temp_proj_name = generate_unique_project_name() ipkapp_temp = Icepak(projectname=os.path.join(self._app.toolkit_directory, temp_proj_name)) ipkapp_temp.delete_design(ipkapp_temp.design_name) self._app.oproject.CopyDesign(self._app.design_name) @@ -1561,20 +1561,20 @@ def insert_3d_component( for i in ["FaceKeyIDMap", "EdgeKeyIDMap", "VertexKeyIDMap", "BodyKeyIDMap"]: try: dict_str = ( - "{" - + ",".join(part["Operations"]["Operation"]["OperationIdentity"][i]) - .replace("'", '"') - .replace("=", ":") - + "}" + "{" + + ",".join(part["Operations"]["Operation"]["OperationIdentity"][i]) + .replace("'", '"') + .replace("=", ":") + + "}" ) except KeyError: # TODO: fix reading AEDT for key, mon in part["Operations"]["Operation"]["OperationIdentity"].items(): if i in key: keyarr = key.split("(") dict_str = ( - "{" - + "{}: {}".format(keyarr[1], mon.replace(")", "")).replace("'", '"') - + "}" + "{" + + "{}: {}".format(keyarr[1], mon.replace(")", "")).replace("'", '"') + + "}" ) break mapping_dict[i].update(json.loads(dict_str)) @@ -1638,13 +1638,13 @@ def insert_3d_component( @pyaedt_function_handler() def insert_layout_component( - self, - comp_file, - coordinate_system="Global", - name=None, - parameter_mapping=False, - layout_coordinate_systems=[], - reference_coordinate_system="Global" + self, + comp_file, + coordinate_system="Global", + name=None, + parameter_mapping=False, + layout_coordinate_systems=None, + reference_coordinate_system="Global" ): """Insert a new layout component. @@ -1681,6 +1681,8 @@ def insert_layout_component( >>> comp = app.modeler.insert_layout_component(layout_component) """ + if layout_coordinate_systems is None: + layout_coordinate_systems = [] if self._app.solution_type != "Terminal" and self._app.solution_type != "TransientAPhiFormulation": self.logger.warning("Solution type must be terminal in HFSS or APhi in Maxwell") return False @@ -1725,24 +1727,40 @@ def insert_layout_component( ) aedb_component_path = normalize_path(aedb_component_path) - component_obj = Edb( - edbpath=aedb_component_path, - isreadonly=True, - edbversion=self._app._aedt_version, - student_version=self._app.student_version, - ) - - # Extract and map parameters + is_edb_open = False parameters = {} - for param in component_obj.design_variables: - parameters[param] = [param + "_" + name, component_obj.design_variables[param].value_string] - if parameter_mapping: - self._app[param + "_" + name] = component_obj.design_variables[param].value_string + component_cs = [] + for edb_object in _edb_sessions: + if edb_object.edbpath == aedb_component_path: + is_edb_open = True + # Extract and map parameters + for param in edb_object.design_variables: + parameters[param] = [param + "_" + name, edb_object.design_variables[param].value_string] + if parameter_mapping: + self._app[param + "_" + name] = edb_object.design_variables[param].value_string + # Get coordinate systems + component_cs = list(edb_object.components.instances.keys()) + break + + if not is_edb_open: + component_obj = Edb( + edbpath=aedb_component_path, + isreadonly=True, + edbversion=self._app._aedt_version, + student_version=self._app.student_version, + ) + + # Extract and map parameters + parameters = {} + for param in component_obj.design_variables: + parameters[param] = [param + "_" + name, component_obj.design_variables[param].value_string] + if parameter_mapping: + self._app[param + "_" + name] = component_obj.design_variables[param].value_string - # Get coordinate systems - component_cs = list(component_obj.components.instances.keys()) + # Get coordinate systems + component_cs = list(component_obj.components.instances.keys()) - component_obj.close_edb() + component_obj.close() vArg1 = ["NAME:InsertNativeComponentData"] vArg1.append("TargetCS:=") @@ -1878,9 +1896,10 @@ def insert_layout_component( self._create_object(new_name) udm_obj = self._create_user_defined_component(new_object_name) - + _ = udm_obj.layout_component.edb_object if name: udm_obj.name = name + udm_obj.layout_component._name = name except Exception: # pragma: no cover udm_obj = False @@ -1919,7 +1938,7 @@ def _check_actor_folder(self, actor_folder): self.logger.error("Folder {} does not exist.".format(actor_folder)) return False if not any(fname.endswith(".json") for fname in os.listdir(actor_folder)) or not any( - fname.endswith(".a3dcomp") for fname in os.listdir(actor_folder) + fname.endswith(".a3dcomp") for fname in os.listdir(actor_folder) ): self.logger.error("At least one json and one a3dcomp file is needed.") return False @@ -1934,15 +1953,15 @@ def _initialize_multipart(self): @pyaedt_function_handler() def add_person( - self, - actor_folder, - speed=0.0, - global_offset=[0, 0, 0], - yaw=0, - pitch=0, - roll=0, - relative_cs_name=None, - actor_name=None, + self, + actor_folder, + speed=0.0, + global_offset=[0, 0, 0], + yaw=0, + pitch=0, + roll=0, + relative_cs_name=None, + actor_name=None, ): """Add a Walking Person Multipart from 3D Components. @@ -2042,15 +2061,15 @@ def add_person( @pyaedt_function_handler() def add_vehicle( - self, - actor_folder, - speed=0, - global_offset=[0, 0, 0], - yaw=0, - pitch=0, - roll=0, - relative_cs_name=None, - actor_name=None, + self, + actor_folder, + speed=0, + global_offset=[0, 0, 0], + yaw=0, + pitch=0, + roll=0, + relative_cs_name=None, + actor_name=None, ): """Add a Moving Vehicle Multipart from 3D Components. @@ -2132,16 +2151,16 @@ def add_vehicle( @pyaedt_function_handler() def add_bird( - self, - actor_folder, - speed=0, - global_offset=[0, 0, 0], - yaw=0, - pitch=0, - roll=0, - flapping_rate=50, - relative_cs_name=None, - actor_name=None, + self, + actor_folder, + speed=0, + global_offset=[0, 0, 0], + yaw=0, + pitch=0, + roll=0, + flapping_rate=50, + relative_cs_name=None, + actor_name=None, ): """Add a Bird Multipart from 3D Components. @@ -2248,9 +2267,10 @@ def add_bird( @pyaedt_function_handler() def add_environment( - self, env_folder, global_offset=[0, 0, 0], yaw=0, pitch=0, roll=0, relative_cs_name=None, environment_name=None + self, env_folder, global_offset=[0, 0, 0], yaw=0, pitch=0, roll=0, relative_cs_name=None, + environment_name=None ): - """Add an Environment Multipart Component from Json file. + """Add an Environment Multipart Component from JSON file. .. code-block:: json @@ -2474,7 +2494,7 @@ def create_choke(self, json_file): ) self.logger.info("Creating single winding") list_duplicated_object = [] - if type(list_object[0]) == list: + if isinstance(list_object[0], list): for i in range(len(list_object)): success = list_object[i][0].set_crosssection_properties( type=section, width=w_dia, num_seg=segment_number @@ -2489,7 +2509,7 @@ def create_choke(self, json_file): number_duplication = int(key) if number_duplication >= 2: if values["Mode"]["Common"] and number_duplication == 2: - if type(list_object[0]) == list: + if isinstance(list_object[0], list): for i in range(len(list_object)): duplication = self.create_polyline( position_list=list_object[i][1], name=name_wind, matname=material_wind @@ -2510,7 +2530,7 @@ def create_choke(self, json_file): success = duplication.set_crosssection_properties(type=section, width=w_dia, num_seg=segment_number) list_duplicated_object.append([duplication, duplication_points]) else: - if type(list_object[0]) == list: + if isinstance(list_object[0], list): for j in range(number_duplication - 1): for i in range(len(list_object)): duplication = self.create_polyline( @@ -2603,20 +2623,20 @@ def _make_winding(self, name, material, in_rad, out_rad, height, teta, turns, ch @pyaedt_function_handler() def _make_double_linked_winding( - self, - name, - material, - in_rad, - out_rad, - height, - w_dia, - teta, - teta_in_wind, - turns, - turns_in_wind, - chamfer, - chamf_in_wind, - sr, + self, + name, + material, + in_rad, + out_rad, + height, + w_dia, + teta, + teta_in_wind, + turns, + turns_in_wind, + chamfer, + chamf_in_wind, + sr, ): list_object = self._make_double_winding( name, @@ -2662,22 +2682,22 @@ def _make_double_linked_winding( @pyaedt_function_handler() def _make_triple_linked_winding( - self, - name, - material, - in_rad, - out_rad, - height, - w_dia, - teta, - teta_mid_wind, - teta_in_wind, - turns, - turns_mid_wind, - turns_in_wind, - chamfer, - chamf_in_wind, - sr, + self, + name, + material, + in_rad, + out_rad, + height, + w_dia, + teta, + teta_mid_wind, + teta_in_wind, + turns, + turns_mid_wind, + turns_in_wind, + chamfer, + chamf_in_wind, + sr, ): list_object = self._make_triple_winding( name, @@ -2737,21 +2757,21 @@ def _make_triple_linked_winding( @pyaedt_function_handler() def _make_double_winding( - self, - name, - material, - in_rad, - out_rad, - height, - w_dia, - teta, - teta_in_wind, - turns, - turns_in_wind, - chamfer, - chamf_in_wind, - sr, - sep_layer, + self, + name, + material, + in_rad, + out_rad, + height, + w_dia, + teta, + teta_in_wind, + turns, + turns_in_wind, + chamfer, + chamf_in_wind, + sr, + sep_layer, ): chamf = self._make_winding_follow_chamfer(chamfer, sr, w_dia, 3) in_rad_in_wind = in_rad + sr * w_dia @@ -2775,23 +2795,23 @@ def _make_double_winding( @pyaedt_function_handler() def _make_triple_winding( - self, - name, - material, - in_rad, - out_rad, - height, - w_dia, - teta, - teta_mid_wind, - teta_in_wind, - turns, - turns_mid_wind, - turns_in_wind, - chamfer, - chamf_in_wind, - sr, - sep_layer, + self, + name, + material, + in_rad, + out_rad, + height, + w_dia, + teta, + teta_mid_wind, + teta_in_wind, + turns, + turns_mid_wind, + turns_in_wind, + chamfer, + chamf_in_wind, + sr, + sep_layer, ): chamf = self._make_winding_follow_chamfer(chamfer, sr, w_dia, 5) chamf_mid_wind = self._make_winding_follow_chamfer(chamfer, sr, w_dia, 3) @@ -2929,15 +2949,15 @@ def check_choke_values(self, json_file, create_another_file=True): for f_key in values.keys(): count_true = False if ( - f_key == "Number of Windings" - or f_key == "Layer" - or f_key == "Layer Type" - or f_key == "Similar Layer" - or f_key == "Mode" - or f_key == "Wire Section" + f_key == "Number of Windings" + or f_key == "Layer" + or f_key == "Layer Type" + or f_key == "Similar Layer" + or f_key == "Mode" + or f_key == "Wire Section" ): for s_key in values[f_key].keys(): - if type(values[f_key][s_key]) == bool: + if isinstance(values[f_key][s_key], bool): if count_true: values[f_key][s_key] = False if values[f_key][s_key]: @@ -3290,7 +3310,7 @@ def check_choke_values(self, json_file, create_another_file=True): @pyaedt_function_handler() def _make_winding_follow_chamfer(self, chamfer, sr, wire_diameter, layer_number): w_rad_inc = layer_number * sr * wire_diameter / 2 - distance = sqrt(2 * w_rad_inc**2) - w_rad_inc + sqrt(2 * chamfer**2) / 2 + distance = sqrt(2 * w_rad_inc ** 2) - w_rad_inc + sqrt(2 * chamfer ** 2) / 2 return sqrt(2) * distance @pyaedt_function_handler() diff --git a/pyaedt/modeler/cad/components_3d.py b/pyaedt/modeler/cad/components_3d.py index 89fe4271804..b4971146540 100644 --- a/pyaedt/modeler/cad/components_3d.py +++ b/pyaedt/modeler/cad/components_3d.py @@ -8,6 +8,7 @@ from pyaedt import Edb from pyaedt import pyaedt_function_handler +from pyaedt.generic.desktop_sessions import _edb_sessions from pyaedt.generic.general_methods import _uname from pyaedt.modeler.cad.elements3d import BinaryTreeNode from pyaedt.modeler.cad.elements3d import _dict2arg @@ -893,7 +894,7 @@ def edit_definition(self, password=""): # design_name = project.GetDesigns()[0].GetName() # else: # design_name = project.GetActiveDesign().GetName() - return get_pyaedt_app(project_name, design_name) + return get_pyaedt_app(project_name, design_name, desktop=self._primitives._app.desktop_class) return False @@ -921,9 +922,57 @@ def __init__(self, component): self.layers = {} self.nets = {} self.objects = {} - if self.edb_definition: + self._edb_object = None + self._edb_path = None + if self.edb_definition and self.edb_path: self._get_edb_info() + @property + def edb_path(self): + """EDB path. + + Returns + ------- + str + EDB file path. + + """ + return self._edb_path + + @property + def edb_object(self): + """EDB object. + + Returns + ------- + :class:`pyaedt.edb.Edb` + EDB object. + + """ + if not self._edb_object: + aedb_component_path = self._edb_path + + for edb_object in _edb_sessions: + if edb_object.edbpath == aedb_component_path: + self._edb_object = edb_object + return self._edb_object + + if not aedb_component_path or not os.path.exists(aedb_component_path): # pragma: no cover + return False + + app = Edb( + edbpath=aedb_component_path, + isreadonly=False, + edbversion=self._primitives._app._aedt_version, + student_version=self._primitives._app.student_version, + ) + + _edb_sessions.append(app) + + self._edb_object = app + + return self._edb_object + @property def edb_definition(self): """Edb definition. @@ -940,6 +989,20 @@ def edb_definition(self): self._primitives.oeditor, self._component.definition_name, key ) self._edb_definition = edb_definition + aedb_folder = os.path.abspath( + os.path.join( + self._primitives._app.project_path, + self._primitives._app.project_name + ".aedb", + "LayoutComponents", + edb_definition, + ) + ) + if os.path.exists(aedb_folder): + subdirs = next(os.walk(aedb_folder))[1] + for subdir in subdirs: + if subdir.endswith(".aedb"): + self._edb_path = os.path.abspath(os.path.join(aedb_folder, subdir)) + break return edb_definition else: return None @@ -1058,35 +1121,29 @@ def display_mode(self, display_mode): self._display_mode = display_mode @pyaedt_function_handler() - def _get_edb_info(self): - """Get Edb information.""" - - # Open Layout component and get information - aedb_component_path = os.path.join( - self._primitives._app.project_file[:-1] + "b", - "LayoutComponents", - self._edb_definition, - self._edb_definition + ".aedb", - ) - - if not os.path.exists(aedb_component_path): # pragma: no cover + def close_edb_object(self): + """Close EDB object.""" + if self.edb_object: + try: + self.edb_object.close() + return True + except Exception: # pragma: no cover + self._logger.error("EDB object cannot be closed.") + return False + else: # pragma: no cover + self._logger.warning("EDB object was not created.") return False - component_obj = Edb( - edbpath=aedb_component_path, - isreadonly=True, - edbversion=self._primitives._app._aedt_version, - student_version=self._primitives._app.student_version, - ) - - # Get objects, nets and layers - self.nets = {key: [True, False, 60] for key in component_obj.nets.netlist} - self.layers = {key: [True, False, 60] for key in list(component_obj.stackup.stackup_layers.keys())} - self.objects = {key: [True, False, 60] for key in list(component_obj.components.instances.keys())} - - component_obj.close_edb() - - return True + @pyaedt_function_handler() + def _get_edb_info(self): + """Get EDB information.""" + if self.edb_object: + self.nets = {key: [True, False, 60] for key in self.edb_object.nets.netlist} + self.layers = {key: [True, False, 60] for key in list(self.edb_object.stackup.stackup_layers.keys())} + self.objects = {key: [True, False, 60] for key in list(self.edb_object.components.instances.keys())} + return True + else: # pragma: no cover + return False @pyaedt_function_handler() def update_visibility(self): diff --git a/pyaedt/modeler/cad/elements3d.py b/pyaedt/modeler/cad/elements3d.py index 577aa1940bc..86728471185 100644 --- a/pyaedt/modeler/cad/elements3d.py +++ b/pyaedt/modeler/cad/elements3d.py @@ -50,7 +50,7 @@ def _dict2arg(d, arg_out): arg_out.append(arg) elif v is None: arg_out.append(["NAME:" + k]) - elif type(v) is list and len(v) > 0 and isinstance(v[0], (OrderedDict, dict)): + elif isinstance(v, list) and len(v) > 0 and isinstance(v[0], (OrderedDict, dict)): for el in v: arg = ["NAME:" + k] _dict2arg(el, arg) @@ -58,7 +58,7 @@ def _dict2arg(d, arg_out): else: arg_out.append(k + ":=") - if type(v) is EdgePrimitive or type(v) is FacePrimitive or type(v) is VertexPrimitive: + if isinstance(v, (EdgePrimitive, FacePrimitive, VertexPrimitive)): arg_out.append(v.id) else: arg_out.append(v) @@ -905,10 +905,8 @@ def normal(self): n = GeometryOperators.v_cross(cv1, cv2) normal = GeometryOperators.normalize_vector(n) - """ - Try to move the face center twice, the first with the normal vector, and the second with its inverse. - Measures which is closer to the center point of the bounding box. - """ + # Try to move the face center twice, the first with the normal vector, and the second with its inverse. + # Measures which is closer to the center point of the bounding box. inv_norm = [-i for i in normal] mv1 = GeometryOperators.v_sum(fc, normal) mv2 = GeometryOperators.v_sum(fc, inv_norm) @@ -929,7 +927,7 @@ def create_object(self, non_model=False): :class:`pyaedt.modeler.cad.object3d.Object3d` 3D object. non_model : bool, optional - Either if create the new object as model or non-model. Default is `False`. + Either to create the new object as model or non-model. Default is ``False``. References ---------- diff --git a/pyaedt/modeler/cad/object3d.py b/pyaedt/modeler/cad/object3d.py index ce8fd8a3cc4..b7a529eaa57 100644 --- a/pyaedt/modeler/cad/object3d.py +++ b/pyaedt/modeler/cad/object3d.py @@ -2,11 +2,11 @@ """ This module contains these classes: `Components3DLayout`,`CircuitComponent', `EdgePrimitive`, `EdgeTypePrimitive`, `FacePrimitive`, `Geometries3DLayout`, -`Nets3DLayout`, `Objec3DLayout`, `Object3d`, `Padstack`, `PDSHole`, `PDSLayer`, +`Nets3DLayout`, `Object3DLayout`, `Object3d`, `Padstack`, `PDSHole`, `PDSLayer`, `Pins3DLayout', and `VertexPrimitive`. This module provides methods and data structures for managing all properties of -objects (points, lines, sheeets, and solids) within the AEDT 3D Modeler. +objects (points, lines, sheets, and solids) within the AEDT 3D Modeler. """ from __future__ import absolute_import # noreorder @@ -693,7 +693,7 @@ def top_edge_y(self): @property def bottom_edge_y(self): - """Bottom edge in the X direction of the object. Midpoint is used as criteria to find the edge. + """Bottom edge in the Y direction of the object. Midpoint is used as criteria to find the edge. Returns ------- diff --git a/pyaedt/modeler/circuits/PrimitivesCircuit.py b/pyaedt/modeler/circuits/PrimitivesCircuit.py index ff46a7c9e99..df733a3ee39 100644 --- a/pyaedt/modeler/circuits/PrimitivesCircuit.py +++ b/pyaedt/modeler/circuits/PrimitivesCircuit.py @@ -233,7 +233,7 @@ def add_pin_iports(self, name, id_num): return True @pyaedt_function_handler() - def create_interface_port(self, name, location=[], angle=0): + def create_interface_port(self, name, location=None, angle=0): """Create an interface port. Parameters @@ -255,7 +255,10 @@ def create_interface_port(self, name, location=[], angle=0): >>> oEditor.CreateIPort """ - if name in self._app.excitation_names: + if location is None: + location = [] + + if name in self._app.excitations: self.logger.warning("Port name already assigned.") return False @@ -270,7 +273,7 @@ def create_interface_port(self, name, location=[], angle=0): # return id, self.components[id].composed_name for el in self.components: if ("IPort@" + name + ";" + str(id)) in self.components[el].composed_name: - return self._app.excitations[name] + return self._app.excitation_objects[name] return False @pyaedt_function_handler() @@ -309,7 +312,7 @@ def create_page_port(self, name, location=[], angle=0): return self.components[id] @pyaedt_function_handler() - def create_gnd(self, location=[], angle=0): + def create_gnd(self, location=None, angle=0): """Create a ground. Parameters @@ -328,6 +331,9 @@ def create_gnd(self, location=[], angle=0): ---------- >>> oEditor.CreateGround """ + if location is None: + location = [] + xpos, ypos = self._get_location(location) id = self.create_unique_id() @@ -630,7 +636,7 @@ def _parse_ports_name(file, num_terminal): def create_touchstone_component( self, model_name, - location=[], + location=None, angle=0, show_bitmap=True, ): @@ -670,6 +676,8 @@ def create_touchstone_component( >>> s_parameter_path = os.path.join("your_path", "s_param_file_name.s4p") >>> circuit_comp = comps.create_touchstone_component(s_parameter_path, location=[0.0, 0.0], show_bitmap=False) """ + if location is None: + location = [] xpos, ypos = self._get_location(location) id = self.create_unique_id() if os.path.exists(model_name): @@ -1231,7 +1239,7 @@ def props(self): return self._props @pyaedt_function_handler() - def place(self, inst_name, location=[], angle=0, use_instance_id_netlist=False): + def place(self, inst_name, location=None, angle=0, use_instance_id_netlist=False): """Create a component from a library. Parameters @@ -1256,6 +1264,8 @@ def place(self, inst_name, location=[], angle=0, use_instance_id_netlist=False): >>> oEditor.CreateComponent """ + if location is None: + location = [] return self._component_manager.create_component( inst_name=inst_name, component_library=self.component_library, diff --git a/pyaedt/modeler/circuits/PrimitivesEmit.py b/pyaedt/modeler/circuits/PrimitivesEmit.py index 98b1c68c137..34f65476fce 100644 --- a/pyaedt/modeler/circuits/PrimitivesEmit.py +++ b/pyaedt/modeler/circuits/PrimitivesEmit.py @@ -1133,7 +1133,7 @@ def set_channel_sampling(self, sampling_type="Uniform", percentage=None, max_cha self._set_prop_value(sampling_props) @pyaedt_function_handler() - def _set_prop_value(self, props={}): + def _set_prop_value(self, props=None): """Sets the property values for this node. Parameters @@ -1146,11 +1146,13 @@ def _set_prop_value(self, props={}): ------- None """ + if props is None: + props = {} comp_name = self.parent_component.name prop_list = ["NAME:properties"] for prop_name, value in props.items(): prop_list.append("{}:=".format(prop_name)) - if type(value) is not str: + if not isinstance(value, str): raise TypeError("Value for key {} is not a string.".format(prop_name)) prop_list.append(value) properties_to_set = [ diff --git a/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py b/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py index 637c97f2299..866cff70164 100644 --- a/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py +++ b/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py @@ -142,7 +142,7 @@ def create_inductor(self, compname=None, value=50, location=None, angle=0, use_i return id @pyaedt_function_handler() - def create_capacitor(self, compname=None, value=50, location=[], angle=0, use_instance_id_netlist=False): + def create_capacitor(self, compname=None, value=50, location=None, angle=0, use_instance_id_netlist=False): """Create a capacitor. Parameters @@ -168,6 +168,8 @@ def create_capacitor(self, compname=None, value=50, location=[], angle=0, use_in >>> oEditor.CreateComponent """ + if location is None: + location = [] id = self.create_component( compname, component_library="Passive Elements", @@ -222,7 +224,7 @@ def create_diode(self, compname=None, location=None, angle=0, use_instance_id_ne return id @pyaedt_function_handler() - def create_winding(self, compname=None, location=[], angle=0, use_instance_id_netlist=False): + def create_winding(self, compname=None, location=None, angle=0, use_instance_id_netlist=False): """Create an NPN transistor. Parameters @@ -246,6 +248,8 @@ def create_winding(self, compname=None, location=[], angle=0, use_instance_id_ne >>> oEditor.CreateComponent """ + if location is None: + location = [] id = self.create_component( compname, component_library="Dedicated Elements", diff --git a/pyaedt/modeler/circuits/PrimitivesNexxim.py b/pyaedt/modeler/circuits/PrimitivesNexxim.py index 6c59e50e5d9..262fe58b639 100644 --- a/pyaedt/modeler/circuits/PrimitivesNexxim.py +++ b/pyaedt/modeler/circuits/PrimitivesNexxim.py @@ -54,7 +54,7 @@ def __getitem__(self, partname): :class:`pyaedt.modeler.cad.object3dcircuit.CircuitComponent` Circuit Component Object. """ - if type(partname) is int: + if isinstance(partname, int): return self.components[partname] for el in self.components: if self.components[el].name == partname or self.components[el].composed_name == partname or el == partname: @@ -601,7 +601,7 @@ def create_field_model(self, design_name, solution_name, pin_names, model_type=" return False @pyaedt_function_handler() - def create_resistor(self, compname=None, value=50, location=[], angle=0, use_instance_id_netlist=False): + def create_resistor(self, compname=None, value=50, location=None, angle=0, use_instance_id_netlist=False): """Create a resistor. Parameters @@ -628,6 +628,8 @@ def create_resistor(self, compname=None, value=50, location=[], angle=0, use_ins >>> oEditor.CreateComponent """ + if location is None: + location = [] cmpid = self.create_component( compname, location=location, angle=angle, use_instance_id_netlist=use_instance_id_netlist ) @@ -636,7 +638,7 @@ def create_resistor(self, compname=None, value=50, location=[], angle=0, use_ins return cmpid @pyaedt_function_handler() - def create_inductor(self, compname=None, value=50, location=[], angle=0, use_instance_id_netlist=False): + def create_inductor(self, compname=None, value=50, location=None, angle=0, use_instance_id_netlist=False): """Create an inductor. Parameters @@ -663,6 +665,8 @@ def create_inductor(self, compname=None, value=50, location=[], angle=0, use_ins >>> oEditor.CreateComponent """ + if location is None: + location = [] cmpid = self.create_component( compname, component_library="Inductors", @@ -807,7 +811,9 @@ def create_voltage_probe(self, probe_name=None, location=None, angle=0, use_inst return cmpid @pyaedt_function_handler() - def create_current_pulse(self, compname=None, value_lists=[], location=[], angle=0, use_instance_id_netlist=False): + def create_current_pulse( + self, compname=None, value_lists=None, location=None, angle=0, use_instance_id_netlist=False + ): """Create a current pulse. Parameters @@ -834,6 +840,10 @@ def create_current_pulse(self, compname=None, value_lists=[], location=[], angle >>> oEditor.CreateComponent """ + if value_lists is None: + value_lists = [] + if location is None: + location = [] cmpid = self.create_component( compname, component_library="Independent Sources", @@ -861,7 +871,9 @@ def create_current_pulse(self, compname=None, value_lists=[], location=[], angle return cmpid @pyaedt_function_handler() - def create_voltage_pulse(self, compname=None, value_lists=[], location=[], angle=0, use_instance_id_netlist=False): + def create_voltage_pulse( + self, compname=None, value_lists=None, location=None, angle=0, use_instance_id_netlist=False + ): """Create a voltage pulse. Parameters @@ -888,6 +900,10 @@ def create_voltage_pulse(self, compname=None, value_lists=[], location=[], angle >>> oEditor.CreateComponent """ + if value_lists is None: + value_lists = [] + if location is None: + location = [] cmpid = self.create_component( compname, component_library="Independent Sources", @@ -970,7 +986,7 @@ def create_voltage_pwl( return cmpid @pyaedt_function_handler() - def create_current_dc(self, compname=None, value=1, location=[], angle=0, use_instance_id_netlist=False): + def create_current_dc(self, compname=None, value=1, location=None, angle=0, use_instance_id_netlist=False): """Create a current DC source. Parameters @@ -997,6 +1013,8 @@ def create_current_dc(self, compname=None, value=1, location=[], angle=0, use_in >>> oEditor.CreateComponent """ + if location is None: + location = [] cmpid = self.create_component( compname, component_library="Independent Sources", @@ -1060,7 +1078,7 @@ def create_coupling_inductors( return cmpid @pyaedt_function_handler() - def create_diode(self, compname=None, model_name="required", location=[], angle=0, use_instance_id_netlist=False): + def create_diode(self, compname=None, model_name="required", location=None, angle=0, use_instance_id_netlist=False): """Create a diode. Parameters @@ -1087,6 +1105,8 @@ def create_diode(self, compname=None, model_name="required", location=[], angle= >>> oEditor.CreateComponent """ + if location is None: + location = [] cmpid = self.create_component( compname, component_library="Diodes", @@ -1100,7 +1120,7 @@ def create_diode(self, compname=None, model_name="required", location=[], angle= return cmpid @pyaedt_function_handler() - def create_npn(self, compname=None, value=None, location=[], angle=0, use_instance_id_netlist=False): + def create_npn(self, compname=None, value=None, location=None, angle=0, use_instance_id_netlist=False): """Create an NPN transistor. Parameters @@ -1127,6 +1147,8 @@ def create_npn(self, compname=None, value=None, location=[], angle=0, use_instan >>> oEditor.CreateComponent """ + if location is None: + location = [] id = self.create_component( compname, component_library="BJTs", @@ -1140,7 +1162,7 @@ def create_npn(self, compname=None, value=None, location=[], angle=0, use_instan return id @pyaedt_function_handler() - def create_pnp(self, compname=None, value=50, location=[], angle=0, use_instance_id_netlist=False): + def create_pnp(self, compname=None, value=50, location=None, angle=0, use_instance_id_netlist=False): """Create a PNP transistor. Parameters @@ -1167,6 +1189,8 @@ def create_pnp(self, compname=None, value=50, location=[], angle=0, use_instance >>> oEditor.CreateComponent """ + if location is None: + location = [] id = self.create_component( compname, component_library="BJTs", diff --git a/pyaedt/modeler/circuits/object3dcircuit.py b/pyaedt/modeler/circuits/object3dcircuit.py index d93f50df5ac..035ef031c7d 100644 --- a/pyaedt/modeler/circuits/object3dcircuit.py +++ b/pyaedt/modeler/circuits/object3dcircuit.py @@ -132,7 +132,9 @@ def _get_deltas(self, point, move_x=True, move_y=True, positive=True, units=1): return deltax, deltay @pyaedt_function_handler() - def connect_to_component(self, component_pin, page_name=None, use_wire=False, wire_name="", clearance_units=1): + def connect_to_component( + self, component_pin, page_name=None, use_wire=False, wire_name="", clearance_units=1, page_port_angle=None + ): """Connect schematic components. Parameters @@ -147,9 +149,12 @@ def connect_to_component(self, component_pin, page_name=None, use_wire=False, wi The default is ``False``, in which case a page port is used. Note that if wires are used but not well placed, shorts can result. wire_name : str, optional - Wire name used only when user_wire is ``True``. Default value is ``""``. + Wire name used only when ``user_wire=True``. The default is ``""``. clearance_units : int, optional Number of snap units (100mil each) around the object to overcome pins and wires. + page_port_angle : int, optional + Page port angle on the source pin. The default is ``None``, in which case + the angle is automatically computed. Returns ------- @@ -272,7 +277,9 @@ def connect_to_component(self, component_pin, page_name=None, use_wire=False, wi ) except Exception: x_loc = float(self._circuit_comp.location[0]) - if self.location[0] < x_loc: + if page_port_angle is not None: + angle = page_port_angle * math.pi / 180 + elif self.location[0] < x_loc: angle = comp_angle else: angle = math.pi + comp_angle @@ -295,7 +302,7 @@ def connect_to_component(self, component_pin, page_name=None, use_wire=False, wi page_name, location=cmp.location, angle=angle ) if ret1 and ret2: - return True + return True, ret1, ret2 else: return False @@ -328,7 +335,7 @@ def __setitem__(self, key, value): self._tab, self._component.composed_name, key, str(value) ) dict.__setitem__(self, key, value) - except: + except Exception: self._component._circuit_components.logger.warning( "Property %s has not been edited.Check if readonly", key ) @@ -781,7 +788,7 @@ def set_property(self, property_name, property_value): >>> oEditor.ChangeProperty """ - if type(property_name) is list: + if isinstance(property_name, list): for p, v in zip(property_name, property_value): v_prop = ["NAME:" + p, "Value:=", v] self.change_property(v_prop) diff --git a/pyaedt/modeler/geometry_operators.py b/pyaedt/modeler/geometry_operators.py index 51d68d124ca..d55705d34c7 100644 --- a/pyaedt/modeler/geometry_operators.py +++ b/pyaedt/modeler/geometry_operators.py @@ -74,7 +74,7 @@ def parse_dim_arg(string, scale_to_unit=None, variable_manager=None): >>> 2.0 """ - if type(string) is not str: + if not isinstance(string, str): try: return float(string) except ValueError: # pragma: no cover @@ -712,7 +712,7 @@ def is_projection_inside(a1, a2, b1, b2): Returns ------- bool - ``True`` when the projected segment is inside the other segmennt, ``False`` otherwise. + ``True`` when the projected segment is inside the other segment, ``False`` otherwise. """ if not GeometryOperators.is_parallel(a1, a2, b1, b2): @@ -1351,7 +1351,7 @@ def cs_xy_pointing_expression(yaw, pitch, roll): @pyaedt_function_handler() def get_numeric(s): """Convert a string to a numeric value. Discard the suffix.""" - if type(s) == str: + if isinstance(s, str): if s == "Global": return 0.0 else: @@ -1389,14 +1389,14 @@ def numeric_cs(cs_in): cs_in : List of str or str ``["x", "y", "z"]`` or "Global". """ - if type(cs_in) is str: + if isinstance(cs_in, str): if cs_in == "Global": return [0.0, 0.0, 0.0] else: return None - elif type(cs_in) is list: + elif isinstance(cs_in, list): if len(cs_in) == 3: - return [GeometryOperators.get_numeric(s) if type(s) is str else s for s in cs_in] + return [GeometryOperators.get_numeric(s) if isinstance(s, str) else s for s in cs_in] else: return [0, 0, 0] @@ -1558,6 +1558,8 @@ def point_in_polygon(point, polygon, tolerance=1e-8): The method implements the radial algorithm (https://es.wikipedia.org/wiki/Algoritmo_radial) + This version supports also self-intersecting polygons. + point : List List of ``[x, y]`` coordinates. polygon : List @@ -1591,9 +1593,10 @@ def point_in_polygon(point, polygon, tolerance=1e-8): if abs(abs(a) - math.pi) < tol: return 0 asum += a + r = asum % (2*math.pi) if abs(asum) < tol: return -1 - elif abs(abs(asum) - 2*math.pi) < tol: + elif r < tol or (2*math.pi - r) < tol: return 1 else: # pragma: no cover raise Exception("Unexpected error!") diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py index 0830c547e29..1d6579b23d9 100644 --- a/pyaedt/modeler/modeler3d.py +++ b/pyaedt/modeler/modeler3d.py @@ -9,6 +9,7 @@ from pyaedt.application.Variables import generate_validation_errors from pyaedt.generic.general_methods import GrpcApiError from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.modeler.cad.Primitives3D import Primitives3D from pyaedt.modeler.geometry_operators import GeometryOperators @@ -330,7 +331,7 @@ def create_3dcomponent( datasets.update(self._app.design_datasets) if native_components is None: native_components = self._app.native_components - with open(configfile) as f: + with open_file(configfile) as f: config_dict = json.load(f) out_dict = {} if monitor_objects: @@ -370,7 +371,7 @@ def create_3dcomponent( for cs in list(out_dict["coordinatesystems"]): if cs not in cs_set: del out_dict["coordinatesystems"][cs] - with open(auxiliary_dict, "w") as outfile: + with open_file(auxiliary_dict, "w") as outfile: json.dump(out_dict, outfile) if not os.path.isdir(os.path.dirname(component_file)): self.logger.warning("Folder '" + os.path.dirname(component_file) + "' doesn't exist.") @@ -763,7 +764,7 @@ def create_waveguide( if wg_direction_axis == self._app.AXIS.Z: airbox = self.create_box(origin, [w, h, wg_length]) - if type(wg_thickness) is str: + if isinstance(wg_thickness, str): origin[0] = str(origin[0]) + "-" + wg_thickness origin[1] = str(origin[1]) + "-" + wg_thickness else: @@ -773,7 +774,7 @@ def create_waveguide( elif wg_direction_axis == self._app.AXIS.Y: airbox = self.create_box(origin, [w, wg_length, h]) - if type(wg_thickness) is str: + if isinstance(wg_thickness, str): origin[0] = str(origin[0]) + "-" + wg_thickness origin[2] = str(origin[2]) + "-" + wg_thickness else: @@ -782,7 +783,7 @@ def create_waveguide( else: airbox = self.create_box(origin, [wg_length, w, h]) - if type(wg_thickness) is str: + if isinstance(wg_thickness, str): origin[2] = str(origin[2]) + "-" + wg_thickness origin[1] = str(origin[1]) + "-" + wg_thickness else: @@ -900,7 +901,7 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import self.logger.reset_timer() self.logger.info("Loading file") - with open(file_path, "r") as f: + with open_file(file_path, "r") as f: lines = f.read().splitlines() id = 0 for lk in range(len(lines)): @@ -1089,7 +1090,7 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import if import_solids and nas_to_dict["Solids"]: self.logger.reset_timer() self.logger.info("Loading solids") - for solid_pid in nas_to_dict["Solids"].keys(): + for solid_pid in nas_to_dict["Solids"]: for solid in nas_to_dict["Solids"][solid_pid]: points = [nas_to_dict["Points"][id] for id in solid[1:]] if solid[0] == "CPENTA": @@ -1240,7 +1241,7 @@ def import_from_openstreet_map( "parts": parts_dict, } - with open(json_path, "w", encoding="utf-8") as f: + with open_file(json_path, "w", encoding="utf-8") as f: json.dump(scene, f, indent=4) self.logger.info("Done...") @@ -1267,10 +1268,7 @@ def import_from_openstreet_map( if not os.path.exists(parts_dict[part]["file_name"]): continue obj_names = [i for i in self.object_names] - self.import_3d_cad( - parts_dict[part]["file_name"], - create_lightweigth_part=create_lightweigth_part, - ) + self.import_3d_cad(parts_dict[part]["file_name"], create_lightweigth_part=create_lightweigth_part) added_objs = [i for i in self.object_names if i not in obj_names] if part == "terrain": transparency = 0.2 diff --git a/pyaedt/modeler/modelerpcb.py b/pyaedt/modeler/modelerpcb.py index 7689ebd47bf..71b571e7b88 100644 --- a/pyaedt/modeler/modelerpcb.py +++ b/pyaedt/modeler/modelerpcb.py @@ -213,7 +213,7 @@ def obounding_box(self, object_name): def _arg_with_dim(self, value, units=None): if units is None: units = self.model_units - if type(value) is str: + if isinstance(value, str): try: float(value) val = "{0}{1}".format(value, units) @@ -914,7 +914,7 @@ def set_spice_model(self, component_name, model_path, model_name=None, subcircui pinNames.remove(pinNames[0]) pinNames.remove(pinNames[0]) break - componentPins = self.components[component_name].pins + componentPins = list(self.components[component_name].pins.keys()) componentPins.reverse() if not pin_map: pin_map = [] diff --git a/pyaedt/modeler/pcb/Primitives3DLayout.py b/pyaedt/modeler/pcb/Primitives3DLayout.py index 8541a0ae6cd..93535a557a6 100644 --- a/pyaedt/modeler/pcb/Primitives3DLayout.py +++ b/pyaedt/modeler/pcb/Primitives3DLayout.py @@ -752,7 +752,7 @@ def padstacks(self): self._padstacks[name] = Padstack(name, self.opadstackmanager, self.model_units) for prop in props: - if type(prop) is str: + if isinstance(prop, str): if prop == "mat:=": self._padstacks[name].mat = props[props.index(prop) + 1] elif prop == "plt:=": @@ -1381,14 +1381,7 @@ def place_3d_component( Returns ------- - - """ - """ - - :param component_path: - :param number_of_terminals: - :param placement_layer: - :return: + :class:`pyaedt.modeler.pcb.object3dlayout.ComponentsSubCircuit3DLayout` """ if not component_name: component_name = os.path.basename(component_path).split(".")[0] @@ -1489,6 +1482,60 @@ def place_3d_component( self.oeditor.CreatePortsOnComponentsByNet(["NAME:Components", comp.name], [], "Port", "0", "0", "0") return comp # + @pyaedt_function_handler() + def create_component_on_pins( + self, + pins, + definition_name=None, + component_type="Other", + ref_des="U100", + ): + """Create a component based on a pin list. + + Parameters + ---------- + pins : list + Pins to include in the new component. + definition_name : str, optional + Name of the component definition. If no name is provided, a + name is automatically assigned. + component_type : str, optional + Component type. The default is ``"Other"``. + ref_des : str, optional + Reference designator. The default is ``"U100"``. + + Returns + ------- + :class:`pyaedt.modeler.cad.object3dlayout.Components3DLayout` + + """ + if not definition_name: + definition_name = generate_unique_name("COMP") + placement_layer = list(self.layers.signals.keys())[0] + for pin in self.pins.items(): + if pin[0] == pins[0]: + placement_layer = pin[1].start_layer + break + comp_name = self.modeler.oeditor.CreateComponent( + [ + "NAME:Contents", + "isRCS:=", + True, + "definition_name:=", + definition_name, + "type:=", + component_type, + "ref_des:=", + ref_des, + "placement_layer:=", + placement_layer, + "elements:=", + pins, + ] + ) + comp = Components3DLayout(self, comp_name.split(";")[-1]) + return comp + def create_text(self, text, position, placement_layer="PostProcessing", angle=0, font_size=12): """Create a text primitive object. diff --git a/pyaedt/modeler/pcb/object3dlayout.py b/pyaedt/modeler/pcb/object3dlayout.py index 63f53f469ec..42965095a27 100644 --- a/pyaedt/modeler/pcb/object3dlayout.py +++ b/pyaedt/modeler/pcb/object3dlayout.py @@ -15,7 +15,7 @@ from pyaedt.modeler.geometry_operators import GeometryOperators -class Objec3DLayout(object): +class Object3DLayout(object): """Manages properties of objects in HFSS 3D Layout. Parameters @@ -431,13 +431,14 @@ def is_parallel(self): return self.rlc_model_type[6] -class Components3DLayout(Objec3DLayout, object): +class Components3DLayout(Object3DLayout, object): """Contains components in HFSS 3D Layout.""" def __init__(self, primitives, name="", edb_object=None): - Objec3DLayout.__init__(self, primitives, "component") + Object3DLayout.__init__(self, primitives, "component") self.name = name self.edb_object = edb_object + self._pins = {} @property def part(self): @@ -629,7 +630,13 @@ def set_die_type( @pyaedt_function_handler() def set_solderball( - self, solderball_type="Cyl", diameter="0.1mm", mid_diameter="0.1mm", height="0.2mm", material="solder" + self, + solderball_type="Cyl", + diameter="0.1mm", + mid_diameter="0.1mm", + height="0.2mm", + material="solder", + reference_offset=None, ): """Set solderball on the active component. @@ -648,6 +655,8 @@ def set_solderball( Ball height. The default is height="0.2mm". material : str, optional Ball material. The default is ``"solder"``. + reference_offset : str, optional. + Reference offset for port creation. The default is ``"0mm"`` Returns ------- @@ -656,28 +665,30 @@ def set_solderball( """ if self._part_type_id not in [0, 4, 5]: return False + props = self._oeditor.GetComponentInfo(self.name) + model = "" + for p in props: + if "PortProp(" in p: + model = p + break + s = r".+PortProp\(rh='(.+?)', rsa=(.+?), rsx='(.+?)', rsy='(.+?)'\)" + m = re.search(s, model) + rsx = "0" + rsy = "0" + rsa = True + rh = "0" + if m: + rh = m.group(1) + rsx = m.group(3) + rsy = m.group(4) + if m.group(2) == "false": + rsa = False + if reference_offset: + rh = reference_offset if self._part_type_id == 4: prop_name = "ICProp:=" if not self.die_enabled: self.set_die_type() - props = self._oeditor.GetComponentInfo(self.name) - model = "" - for p in props: - if "PortProp(" in p: - model = p - break - s = r".+PortProp\(rh='(.+?)', rsa=(.+?), rsx='(.+?)', rsy='(.+?)'\)" - m = re.search(s, model) - rh = "0" - rsx = "0" - rsy = "0" - rsa = True - if m: - rh = m.group(1) - rsx = m.group(3) - rsy = m.group(4) - if m.group(2) == "false": - rsa = False s = r".+DieProp\(dt=(.+?), do=(.+?), dh='(.+?)', lid=(.+?)\)" m = re.search(s, model) dt = 0 @@ -739,6 +750,8 @@ def set_solderball( "sbn:=", material, ], + "PortProp:=", + ["rh:=", rh, "rsa:=", rsa, "rsx:=", rsx, "rsy:=", rsy], ], ], ] @@ -750,9 +763,13 @@ def pins(self): Returns ------- - List of str + dict + Dictionary of pins. """ - return list(self._oeditor.GetComponentPins(self.name)) + if self._pins: + return self._pins + self._pins = {i: Pins3DLayout(self._primitives, i) for i in list(self._oeditor.GetComponentPins(self.name))} + return self._pins @property def model(self): @@ -789,11 +806,11 @@ def components(self): return comps -class Pins3DLayout(Objec3DLayout, object): +class Pins3DLayout(Object3DLayout, object): """Contains the pins in HFSS 3D Layout.""" def __init__(self, primitives, name="", component_name=None, is_pin=True): - Objec3DLayout.__init__(self, primitives, "pin" if is_pin else "via") + Object3DLayout.__init__(self, primitives, "pin" if is_pin else "via") self.componentname = "-".join(name.split("-")[:-1]) if not component_name else component_name self.name = name self.is_pin = is_pin @@ -847,11 +864,11 @@ def holediam(self): return self._oeditor.GetPropertyValue("BaseElementTab", self.name, "HoleDiameter") -class Geometries3DLayout(Objec3DLayout, object): +class Geometries3DLayout(Object3DLayout, object): """Contains geometries in HFSS 3D Layout.""" def __init__(self, primitives, name, prim_type="poly", is_void=False): - Objec3DLayout.__init__(self, primitives, prim_type) + Object3DLayout.__init__(self, primitives, prim_type) self.is_void = is_void self._name = name @@ -1655,7 +1672,7 @@ def move(self, new_position): return True -class ComponentsSubCircuit3DLayout(Objec3DLayout, object): +class ComponentsSubCircuit3DLayout(Object3DLayout, object): """Contains 3d Components in HFSS 3D Layout. Parameters @@ -1668,7 +1685,7 @@ class ComponentsSubCircuit3DLayout(Objec3DLayout, object): """ def __init__(self, primitives, name=""): - Objec3DLayout.__init__(self, primitives, "component") + Object3DLayout.__init__(self, primitives, "component") self.name = name @property diff --git a/pyaedt/modeler/schematic.py b/pyaedt/modeler/schematic.py index cdd05a11613..02810f4a1f2 100644 --- a/pyaedt/modeler/schematic.py +++ b/pyaedt/modeler/schematic.py @@ -446,7 +446,7 @@ def _get_components_selections(self, selections, return_as_list=True): def _arg_with_dim(self, value, units=None): if units is None: units = self.schematic_units - if type(value) is str: + if isinstance(value, str): try: float(value) val = "{0}{1}".format(value, units) diff --git a/pyaedt/modules/AdvancedPostProcessing.py b/pyaedt/modules/AdvancedPostProcessing.py index 17c51454c4c..a2b76fb55f3 100644 --- a/pyaedt/modules/AdvancedPostProcessing.py +++ b/pyaedt/modules/AdvancedPostProcessing.py @@ -129,13 +129,9 @@ def get_efields_data(self, setup_sweep_name="", ff_setup="Infinite Sphere1", fre ) self.post_osolution.EditSources(edit_sources_ctxt) - ctxt = ["Context:=", ff_setup] - - sweeps = ["Theta:=", ["All"], "Phi:=", ["All"], "Freq:=", [freq]] - trace_name = "rETheta" solnData = self.get_far_field_data( - setup_sweep_name=setup_sweep_name, domain=ff_setup, expression=trace_name + expressions=trace_name, setup_sweep_name=setup_sweep_name, domain=ff_setup ) data = solnData.nominal_variation @@ -152,7 +148,7 @@ def get_efields_data(self, setup_sweep_name="", ff_setup="Infinite Sphere1", fre trace_name = "rEPhi" solnData = self.get_far_field_data( - setup_sweep_name=setup_sweep_name, domain=ff_setup, expression=trace_name + expressions=trace_name, setup_sweep_name=setup_sweep_name, domain=ff_setup ) data = solnData.nominal_variation @@ -208,9 +204,7 @@ def get_model_plotter_geometries( files = [] if get_objects_from_aedt and self._app.solution_type not in ["HFSS3DLayout", "HFSS 3D Layout Design"]: files = self.export_model_obj( - obj_list=objects, - export_as_single_objects=plot_as_separate_objects, - air_objects=plot_air_objects, + assignment=objects, export_as_single_objects=plot_as_separate_objects, air_objects=plot_air_objects ) model = ModelPlotter() @@ -310,13 +304,13 @@ def plot_model_obj( model.clean_cache_and_files(clean_cache=False) return model - @pyaedt_function_handler() + @pyaedt_function_handler(plotname="plot_name", meshplot="mesh_plot", imageformat="image_format") def plot_field_from_fieldplot( self, - plotname, + plot_name, project_path="", - meshplot=False, - imageformat="jpg", + mesh_plot=False, + image_format="jpg", view="isometric", plot_label="Temperature", plot_folder=None, @@ -339,14 +333,14 @@ def plot_field_from_fieldplot( Parameters ---------- - plotname : str + plot_name : str Name of the field plot to export. project_path : str, optional Path for saving the image file. The default is ``""``. - meshplot : bool, optional + mesh_plot : bool, optional Whether to create and plot the mesh over the fields. The default is ``False``. - imageformat : str, optional + image_format : str, optional Format of the image file. Options are ``"jpg"``, ``"png"``, ``"svg"``, and ``"webp"``. The default is ``"jpg"``. @@ -398,9 +392,9 @@ def plot_field_from_fieldplot( else: self.ofieldsreporter.UpdateQuantityFieldsPlots(plot_folder) - if self.field_plots[plotname].field_type == "DC R/L Fields": + if self.field_plots[plot_name].field_type == "DC R/L Fields": file_format = "fldplt" - file_to_add = self.export_field_plot(plotname, self._app.working_directory, file_format=file_format) + file_to_add = self.export_field_plot(plot_name, self._app.working_directory, file_format=file_format) model = self.get_model_plotter_geometries( generate_mesh=False, get_objects_from_aedt=plot_cad_objs, @@ -416,7 +410,7 @@ def plot_field_from_fieldplot( model.add_field_from_file( file_to_add, coordinate_units=self.modeler.model_units, - show_edges=meshplot, + show_edges=mesh_plot, log_scale=log_scale, ) if plot_label: @@ -433,18 +427,18 @@ def plot_field_from_fieldplot( model.range_min = scale_min model.range_max = scale_max if project_path: - model.plot(os.path.join(project_path, plotname + "." + imageformat)) + model.plot(os.path.join(project_path, plot_name + "." + image_format)) elif show: model.plot() return model - @pyaedt_function_handler() + @pyaedt_function_handler(object_list="assignment", imageformat="image_format", setup_name="setup") def plot_field( self, quantity, - object_list, + assignment, plot_type="Surface", - setup_name=None, + setup=None, intrinsics=None, mesh_on_fields=False, view="isometric", @@ -455,13 +449,13 @@ def plot_field( plot_cad_objs=True, log_scale=False, export_path="", - imageformat="jpg", + image_format="jpg", keep_plot_after_generation=False, dark_mode=False, show_bounding=False, show_grid=False, show_legend=True, - filter_objects=[], + filter_objects=None, plot_as_separate_objects=True, ): """Create a field plot using Python PyVista and export to an image file (JPG or PNG). @@ -472,12 +466,13 @@ def plot_field( Parameters ---------- quantity : str - Quantity to plot (e.g. ``"Mag_E"``). - object_list : str, list - Objects or faces to which apply the Field Plot. + Quantity to plot. For example, ``"Mag_E"``. + assignment : str, list + One or more objects or faces to apply the field plot to. plot_type : str, optional - Plot type. Options are ``"Surface"``, ``"Volume"``, ``"CutPlane"``. - setup_name : str, optional + Plot type. The default is ``Surface``. Options are + ``"CutPlane"``, ``"Surface"``, and ``"Volume"``. + setup : str, optional Setup and sweep name on which create the field plot. Default is None for nominal setup usage. intrinsics : dict, optional. Intrinsic dictionary that is needed for the export. @@ -501,7 +496,7 @@ def plot_field( Whether to plot fields in log scale. The default is ``False``. export_path : str, optional Image export path. Default is ``None`` to not export the image. - imageformat : str, optional + image_format : str, optional Format of the image file. Options are ``"jpg"``, ``"png"``, ``"svg"``, and ``"webp"``. The default is ``"jpg"``. @@ -525,23 +520,25 @@ def plot_field( :class:`pyaedt.generic.plot.ModelPlotter` Model Object. """ + if filter_objects is None: + filter_objects = [] if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma: no cover show = False - if not setup_name: - setup_name = self._app.existing_analysis_sweeps[0] + if not setup: + setup = self._app.existing_analysis_sweeps[0] if not intrinsics: for i in self._app.setups: - if i.name == setup_name.split(" : ")[0]: + if i.name == setup.split(" : ")[0]: intrinsics = i.default_intrinsics # file_to_add = [] if plot_type == "Surface": - plotf = self.create_fieldplot_surface(object_list, quantity, setup_name, intrinsics) + plotf = self.create_fieldplot_surface(assignment, quantity, setup, intrinsics) elif plot_type == "Volume": - plotf = self.create_fieldplot_volume(object_list, quantity, setup_name, intrinsics) + plotf = self.create_fieldplot_volume(assignment, quantity, setup, intrinsics) else: plotf = self.create_fieldplot_cutplane( - object_list, quantity, setup_name, intrinsics, filter_objects=filter_objects + assignment, quantity, setup, intrinsics, filter_objects=filter_objects ) # if plotf: # file_to_add = self.export_field_plot(plotf.name, self._app.working_directory, plotf.name) @@ -550,7 +547,7 @@ def plot_field( plotf.name, export_path, mesh_on_fields, - imageformat, + image_format, view, plot_label if plot_label else quantity, None, @@ -569,16 +566,16 @@ def plot_field( plotf.delete() return model - @pyaedt_function_handler() + @pyaedt_function_handler(object_list="assignment", variation_list="variations", setup_name="setup") def plot_animated_field( self, quantity, - object_list, + assignment, plot_type="Surface", - setup_name=None, + setup=None, intrinsics=None, variation_variable="Phi", - variation_list=["0deg"], + variations=None, view="isometric", show=True, scale_min=None, @@ -603,21 +600,21 @@ def plot_animated_field( Parameters ---------- quantity : str - Quantity to plot (e.g. ``"Mag_E"``). - object_list : list, str - List of objects or faces to which apply the Field Plot. + Quantity to plot (for example, ``"Mag_E"``). + assignment : list, str + One or more objects or faces to apply the field plot to. plot_type : str, optional - Plot type. Options are ``"Surface"``, ``"Volume"``, ``"CutPlane"``. - setup_name : str, optional + Plot type. The default is ``Surface``. Options are + ``"CutPlane"``, ``"Surface"``, and ``"Volume"``. + setup : str, optional Setup and sweep name on which create the field plot. Default is None for nominal setup usage. intrinsics : dict, optional. Intrinsic dictionary that is needed for the export. The default is ``None`` which try to retrieve intrinsics from setup. variation_variable : str, optional Variable to vary. The default is ``"Phi"``. - variation_list : list, optional - List of variation values with units. The default is - ``["0deg"]``. + variations : list, optional + List of variation values with units. The default is ``["0deg"]``. view : str, optional View to export. Options are ``"isometric"``, ``"xy"``, ``"xz"``, ``"yz"``. show : bool, optional @@ -656,6 +653,8 @@ def plot_animated_field( :class:`pyaedt.generic.plot.ModelPlotter` Model Object. """ + if variations is None: + variations = ["0deg"] if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma: no cover show = False if intrinsics is None: @@ -670,18 +669,18 @@ def plot_animated_field( is_intrinsics = True if variation_variable in self._app.variable_manager.independent_variables: is_intrinsics = False - for el in variation_list: + for el in variations: if is_intrinsics: intrinsics[variation_variable] = el else: self._app[variation_variable] = el if plot_type == "Surface": - plotf = self.create_fieldplot_surface(object_list, quantity, setup_name, intrinsics) + plotf = self.create_fieldplot_surface(assignment, quantity, setup, intrinsics) elif plot_type == "Volume": - plotf = self.create_fieldplot_volume(object_list, quantity, setup_name, intrinsics) + plotf = self.create_fieldplot_volume(assignment, quantity, setup, intrinsics) else: plotf = self.create_fieldplot_cutplane( - object_list, quantity, setup_name, intrinsics, filter_objects=filter_objects + assignment, quantity, setup, intrinsics, filter_objects=filter_objects ) if plotf: file_to_add = self.export_field_plot(plotf.name, export_path, plotf.name + str(v)) @@ -716,14 +715,13 @@ def plot_animated_field( model.animate() return model - @pyaedt_function_handler() + @pyaedt_function_handler(plotname="plot_name", variation_list="variations") def animate_fields_from_aedtplt( self, - plotname, + plot_name, plot_folder=None, - meshplot=False, variation_variable="Phase", - variation_list=["0deg"], + variations=["0deg"], project_path="", export_gif=False, show=True, @@ -738,23 +736,21 @@ def animate_fields_from_aedtplt( Parameters ---------- - plotname : str + plot_name : str Name of the plot or the name of the object. plot_folder : str, optional Name of the folder in which the plot resides. The default is ``None``. variation_variable : str, optional Variable to vary. The default is ``"Phase"``. - variation_list : list, optional + variations : list, optional List of variation values with units. The default is ``["0deg"]``. project_path : str, optional - Path for the export. The default is ``""`` which export file in working_directory. - meshplot : bool, optional - The default is ``False``. Valid from Version 2021.2. + Path for the export. The default is ``""``, in which case the file is exported + to the working directory. export_gif : bool, optional - The default is ``False``. - show=False, + Whether to export the GIF file. The default is ``False``. show : bool, optional Generate the animation without showing an interactive plot. The default is ``True``. dark_mode : bool, optional @@ -777,24 +773,24 @@ def animate_fields_from_aedtplt( fields_to_add = [] if not project_path: project_path = self._app.working_directory - for el in variation_list: - if plotname in self.field_plots and variation_variable in self.field_plots[plotname].intrinsincList: - self.field_plots[plotname].intrinsincList[variation_variable] = el - self.field_plots[plotname].update() + for el in variations: + if plot_name in self.field_plots and variation_variable in self.field_plots[plot_name].intrinsics: + self.field_plots[plot_name].intrinsics[variation_variable] = el + self.field_plots[plot_name].update() else: self._app._odesign.ChangeProperty( [ "NAME:AllTabs", [ "NAME:FieldsPostProcessorTab", - ["NAME:PropServers", "FieldsReporter:" + plotname], + ["NAME:PropServers", "FieldsReporter:" + plot_name], ["NAME:ChangedProps", ["NAME:" + variation_variable, "Value:=", el]], ], ] ) fields_to_add.append( self.export_field_plot( - plotname, project_path, plotname + variation_variable + str(el), file_format="case" + plot_name, project_path, plot_name + variation_variable + str(el), file_format="case" ) ) @@ -813,100 +809,6 @@ def animate_fields_from_aedtplt( model.animate() return model - @pyaedt_function_handler() - def animate_fields_from_aedtplt_2( - self, - quantityname, - object_list, - plottype, - meshplot=False, - setup_name=None, - intrinsic_dict={}, - variation_variable="Phi", - variation_list=["0deg"], - project_path="", - export_gif=False, - show=True, - zoom=None, - log_scale=False, - dark_mode=False, - show_grid=False, - show_bounding=False, - ): - """Generate a field plot to an animated gif file using PyVista. - - .. deprecated:: 0.6.83 - No need to use primitives anymore. You can instantiate primitives methods directly from modeler instead. - - .. note:: - The PyVista module rebuilds the mesh and the overlap fields on the mesh. - - This method creates the plot and exports it. - It is an alternative to the method :func:`animate_fields_from_aedtplt`, - which uses an existing plot. - - Parameters - ---------- - quantityname : str - Name of the plot or the name of the object. - object_list : list, optional - Name of the ``folderplot`` folder. - plottype : str - Type of the plot. Options are ``"Surface"``, ``"Volume"``, and - ``"CutPlane"``. - meshplot : bool, optional - The default is ``False``. - setup_name : str, optional - Name of the setup (sweep) to use for the export. The default is - ``None``. - intrinsic_dict : dict, optional - Intrinsic dictionary that is needed for the export. - The default is ``{}``. - variation_variable : str, optional - Variable to vary. The default is ``"Phi"``. - variation_list : list, option - List of variation values with units. The default is - ``["0deg"]``. - project_path : str, optional - Path for the export. The default is ``""`` which export file in working_directory. - export_gif : bool, optional - Whether to export to a GIF file. The default is ``False``, - in which case the plot is exported to a JPG file. - show : bool, optional - Generate the animation without showing an interactive plot. The default is ``True``. - zoom : float, optional - Zoom factor. - log_scale : bool, optional - Whether to plot fields in log scale. The default is ``True``. - - Returns - ------- - :class:`pyaedt.generic.plot.ModelPlotter` - Model Object. - """ - warnings.warn( - "`animate_fields_from_aedtplt_2` is deprecated. Use `plot_animated_field` property instead.", - DeprecationWarning, - ) - - return self.plot_animated_field( - quantity=quantityname, - object_list=object_list, - plot_type=plottype, - setup_name=setup_name, - intrinsics=intrinsic_dict, - variation_variable=variation_variable, - variation_list=variation_list, - export_path=project_path, - log_scale=log_scale, - show=show, - export_gif=export_gif, - zoom=zoom, - show_bounding=show_bounding, - show_grid=show_grid, - dark_mode=dark_mode, - ) - @pyaedt_function_handler() def create_3d_plot( self, solution_data, nominal_sweep=None, nominal_value=None, primary_sweep="Theta", secondary_sweep="Phi" @@ -937,11 +839,11 @@ def create_3d_plot( solution_data.primary_sweep = primary_sweep return solution_data.plot_3d(x_axis=primary_sweep, y_axis=secondary_sweep) - @pyaedt_function_handler() + @pyaedt_function_handler(frames_list="frames", output_gif_path="gif_path") def plot_scene( self, - frames_list, - output_gif_path, + frames, + gif_path, norm_index=0, dy_rng=0, fps=30, @@ -956,13 +858,13 @@ def plot_scene( Parameters ---------- - frames_list : list or str - File list containing animation frames to plot in csv format or - path to a txt index file containing full path to csv files. - output_gif_path : str - Full path to output gif file. + frames : list or str + File list containing animation frames to plot in CSV format or + path to a text index file containing the full path to CSV files. + gif_path : str + Full path for outputting the GIF file. norm_index : int, optional - Pick the frame to use to normalize your images. + Frame to use to normalize your images. Data is already saved as dB : 100 for usual traffic scenes. dy_rng : int, optional Specify how many dB below you would like to specify the range_min. @@ -985,16 +887,16 @@ def plot_scene( ------- """ - if isinstance(frames_list, str) and os.path.exists(frames_list): - with open_file(frames_list, "r") as f: + if isinstance(frames, str) and os.path.exists(frames): + with open_file(frames, "r") as f: lines = f.read() temp_list = lines.splitlines() frames_paths_list = [i for i in temp_list] - elif isinstance(frames_list, str): + elif isinstance(frames, str): self.logger.error("Path doesn't exists") return False else: - frames_paths_list = frames_list + frames_paths_list = frames scene = self.get_model_plotter_geometries(generate_mesh=False) norm_data = np.loadtxt(frames_paths_list[norm_index], skiprows=1, delimiter=",") @@ -1018,7 +920,7 @@ def plot_scene( scene.zoom = zoom scene.bounding_box = False scene.color_bar = False - scene.gif_file = output_gif_path # This gif may be a bit slower so we can speed it up a bit + scene.gif_file = gif_path # This GIF file may be a bit slower so it can be speed it up a bit scene.convert_fields_in_db = convert_fields_in_db scene.log_multiplier = log_multiplier scene.animate() @@ -1032,8 +934,8 @@ def __init__(self, app): def create_field_summary(self): return FieldSummary(self._app) - @pyaedt_function_handler() - def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=None, design_variation=None): + @pyaedt_function_handler(timestep="time_step", design_variation="variation") + def get_fans_operating_point(self, export_file=None, setup_name=None, time_step=None, variation=None): """ Get the operating point of the fans in the design. @@ -1045,11 +947,11 @@ def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=N setup_name : str, optional Setup name to determine the operating point of the fans. The default is ``None``, in which case the first available setup is used. - timestep : str, optional + time_step : str, optional Time, with units, at which to determine the operating point of the fans. The default is ``None``, in which case the first available timestep is used. This parameter is only relevant in transient simulations. - design_variation : str, optional + variation : str, optional Design variation to determine the operating point of the fans from. The default is ``None``, in which case the nominal variation is used. @@ -1084,31 +986,31 @@ def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=N export_file = os.path.join(path, file_name + ".csv") if setup_name is None: setup_name = "{} : {}".format(self._app.get_setups()[0], self._app.solution_type) - if timestep is None: - timestep = "" + if time_step is None: + time_step = "" if self._app.solution_type == "Transient": self._app.logger.warning("No timestep is specified. First timestep is exported.") else: if not self._app.solution_type == "Transient": self._app.logger.warning("Simulation is steady-state. Timestep argument is ignored.") - timestep = "" - if design_variation is None: - design_variation = "" + time_step = "" + if variation is None: + variation = "" self._app.osolution.ExportFanOperatingPoint( [ "SolutionName:=", setup_name, "DesignVariationKey:=", - design_variation, + variation, "ExportFilePath:=", export_file, "Overwrite:=", True, "TimeStep:=", - timestep, + time_step, ] ) - with open(export_file, "r") as f: + with open_file(export_file, "r") as f: reader = csv.reader(f) for line in reader: if "Fan Instances" in line: @@ -1120,7 +1022,7 @@ def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=N @pyaedt_function_handler def _parse_field_summary_content(self, fs, setup_name, design_variation, quantity_name): - content = fs.get_field_summary_data(setup_name=setup_name, design_variation=design_variation) + content = fs.get_field_summary_data(setup=setup_name, variation=design_variation) pattern = r"\[([^]]*)\]" match = re.search(pattern, content["Quantity"][0]) if match: @@ -1132,23 +1034,23 @@ def _parse_field_summary_content(self, fs, setup_name, design_variation, quantit return {i: content[i][0] for i in ["Total", "Unit"]} return {i: content[i][0] for i in ["Min", "Max", "Mean", "Stdev", "Unit"]} - @pyaedt_function_handler() + @pyaedt_function_handler(faces_list="faces", quantity_name="quantity", design_variation="variation") def evaluate_faces_quantity( self, - faces_list, - quantity_name, + faces, + quantity, side="Default", setup_name=None, - design_variation=None, + variations=None, ref_temperature="", ): """Export the field surface output. Parameters ---------- - faces_list : list + faces : list List of faces to apply. - quantity_name : str + quantity : str Name of the quantity to export. side : str, optional Which side of the mesh face to use. The default is ``Default``. @@ -1156,7 +1058,7 @@ def evaluate_faces_quantity( setup_name : str, optional Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``. The default is ``None``, in which case the active setup and active sweep are used. - design_variation : dict, optional + variations : dict, optional Dictionary of parameters defined for the specific setup with values. The default is ``{}``. ref_temperature: str, optional Reference temperature to use for heat transfer coefficient computation. The default is ``""``. @@ -1175,36 +1077,34 @@ def evaluate_faces_quantity( >>> oModule.ExportFieldsSummary """ - if design_variation is None: - design_variation = {} - facelist_name = generate_unique_name(quantity_name) - self._app.modeler.create_face_list(faces_list, facelist_name) + if variations is None: + variations = {} + facelist_name = generate_unique_name(quantity) + self._app.modeler.create_face_list(faces, facelist_name) fs = self.create_field_summary() - fs.add_calculation( - "Object", "Surface", facelist_name, quantity_name, side=side, ref_temperature=ref_temperature - ) - out = self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name) + fs.add_calculation("Object", "Surface", facelist_name, quantity, side=side, ref_temperature=ref_temperature) + out = self._parse_field_summary_content(fs, setup_name, variations, quantity) self._app.oeditor.Delete(["NAME:Selections", "Selections:=", facelist_name]) return out - @pyaedt_function_handler() + @pyaedt_function_handler(boundary_name="boundary", quantity_name="quantity", design_variation="variations") def evaluate_boundary_quantity( self, - boundary_name, - quantity_name, + boundary, + quantity, side="Default", volume=False, setup_name=None, - design_variation=None, + variations=None, ref_temperature="", ): """Export the field output on a boundary. Parameters ---------- - boundary_name : str + boundary : str Name of boundary to perform the computation on. - quantity_name : str + quantity : str Name of the quantity to export. side : str, optional Side of the mesh face to use. The default is ``"Default"``. @@ -1216,7 +1116,7 @@ def evaluate_boundary_quantity( setup_name : str, optional Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``. The default is ``None``, in which case the active setup and active sweep are used. - design_variation : dict, optional + variations : dict, optional Dictionary of parameters defined for the specific setup with values. The default is ``{}``. ref_temperature: str, optional Reference temperature to use for heat transfer coefficient computation. The default is ``""``. @@ -1234,36 +1134,36 @@ def evaluate_boundary_quantity( >>> oModule.ExportFieldsSummary """ - if design_variation is None: - design_variation = {} + if variations is None: + variations = {} fs = self.create_field_summary() fs.add_calculation( "Boundary", ["Surface", "Volume"][int(volume)], - boundary_name, - quantity_name, + boundary, + quantity, side=side, ref_temperature=ref_temperature, ) - return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name) + return self._parse_field_summary_content(fs, setup_name, variations, quantity) - @pyaedt_function_handler() + @pyaedt_function_handler(monitor_name="monitor", quantity_name="quantity", design_variation="variations") def evaluate_monitor_quantity( self, - monitor_name, - quantity_name, + monitor, + quantity, side="Default", setup_name=None, - design_variation=None, + variations=None, ref_temperature="", ): """Export monitor field output. Parameters ---------- - monitor_name : str + monitor : str Name of monitor to perform the computation on. - quantity_name : str + quantity : str Name of the quantity to export. side : str, optional Side of the mesh face to use. The default is ``"Default"``. @@ -1271,7 +1171,7 @@ def evaluate_monitor_quantity( setup_name : str, optional Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``. The default is ``None``, in which case the active setup and active sweep are used. - design_variation : dict, optional + variations : dict, optional Dictionary of parameters defined for the specific setup with values. The default is ``{}``. ref_temperature: str, optional Reference temperature to use for heat transfer coefficient computation. The default is ``""``. @@ -1290,24 +1190,22 @@ def evaluate_monitor_quantity( >>> oModule.ExportFieldsSummary """ - if design_variation is None: - design_variation = {} + if variations is None: + variations = {} if settings.aedt_version < "2024.1": raise NotImplementedError("Monitors are not supported in field summary in versions earlier than 2024 R1.") else: # pragma: no cover - if self._app.monitor.face_monitors.get(monitor_name, None): + if self._app.monitor.face_monitors.get(monitor, None): field_type = "Surface" - elif self._app.monitor.point_monitors.get(monitor_name, None): + elif self._app.monitor.point_monitors.get(monitor, None): field_type = "Volume" else: - raise AttributeError("Monitor {} is not found in the design.".format(monitor_name)) + raise AttributeError("Monitor {} is not found in the design.".format(monitor)) fs = self.create_field_summary() - fs.add_calculation( - "Monitor", field_type, monitor_name, quantity_name, side=side, ref_temperature=ref_temperature - ) - return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name) + fs.add_calculation("Monitor", field_type, monitor, quantity, side=side, ref_temperature=ref_temperature) + return self._parse_field_summary_content(fs, setup_name, variations, quantity) - @pyaedt_function_handler() + @pyaedt_function_handler(design_variation="variations") def evaluate_object_quantity( self, object_name, @@ -1315,7 +1213,7 @@ def evaluate_object_quantity( side="Default", volume=False, setup_name=None, - design_variation=None, + variations=None, ref_temperature="", ): """Export the field output on or in an object. @@ -1334,7 +1232,7 @@ def evaluate_object_quantity( setup_name : str, optional Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``. The default is ``None``, in which case the active setup and active sweep are used. - design_variation : dict, optional + variations : dict, optional Dictionary of parameters defined for the specific setup with values. The default is ``{}``. ref_temperature: str, optional Reference temperature to use for heat transfer coefficient computation. The default is ``""``. @@ -1353,8 +1251,8 @@ def evaluate_object_quantity( >>> oModule.ExportFieldsSummary """ - if design_variation is None: - design_variation = {} + if variations is None: + variations = {} fs = self.create_field_summary() fs.add_calculation( "Boundary", @@ -1364,4 +1262,4 @@ def evaluate_object_quantity( side=side, ref_temperature=ref_temperature, ) - return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name) + return self._parse_field_summary_content(fs, setup_name, variations, quantity_name) diff --git a/pyaedt/modules/Boundary.py b/pyaedt/modules/Boundary.py index c32f37e690c..da0a283cf22 100644 --- a/pyaedt/modules/Boundary.py +++ b/pyaedt/modules/Boundary.py @@ -95,9 +95,7 @@ def delete(self): self._app.o_maxwell_parameters.DeleteParameters([self.name]) else: self._app.oboundary.DeleteBoundaries([self.name]) - for el in self._app.boundaries[:]: - if el.name == self.name: - del self._app._boundaries[el.name] + self._app.boundaries return True def _get_boundary_data(self, ds): @@ -354,7 +352,7 @@ class BoundaryObject(BoundaryCommon, object): >>> origin = hfss.modeler.Position(0, 0, 0) >>> inner = hfss.modeler.create_cylinder(hfss.PLANE.XY, origin, 3, 200, 0, "inner") >>> inner_id = hfss.modeler.get_obj_id("inner") - >>> coat = hfss.assign_coating([inner_id], "copper", usethickness=True, thickness="0.2mm") + >>> coat = hfss.assign_coating([inner_id],"copper",use_thickness=True,thickness="0.2mm") """ def __init__(self, app, name, props=None, boundarytype=None, auto_update=True): @@ -830,10 +828,10 @@ def update_assignment(self): if "Faces" in self.props: faces = self.props["Faces"] faces_out = [] - if type(faces) is not list: + if not isinstance(faces, list): faces = [faces] for f in faces: - if type(f) is EdgePrimitive or type(f) is FacePrimitive or type(f) is VertexPrimitive: + if isinstance(f, (EdgePrimitive, FacePrimitive, VertexPrimitive)): faces_out.append(f.id) else: faces_out.append(f) @@ -1940,14 +1938,14 @@ def name(self, source_name): original_name = self._name self._name = source_name for port in self._app.excitations: - if original_name in self._app.excitations[port].props["EnabledPorts"]: - self._app.excitations[port].props["EnabledPorts"] = [ + if original_name in self._app.excitation_objects[port].props["EnabledPorts"]: + self._app.excitation_objects[port].props["EnabledPorts"] = [ w.replace(original_name, source_name) - for w in self._app.excitations[port].props["EnabledPorts"] + for w in self._app.excitation_objects[port].props["EnabledPorts"] ] - if original_name in self._app.excitations[port].props["EnabledAnalyses"]: - self._app.excitations[port].props["EnabledAnalyses"][source_name] = ( - self._app.excitations[port].props["EnabledAnalyses"].pop(original_name) + if original_name in self._app.excitation_objects[port].props["EnabledAnalyses"]: + self._app.excitation_objects[port].props["EnabledAnalyses"][source_name] = ( + self._app.excitation_objects[port].props["EnabledAnalyses"].pop(original_name) ) self.update(original_name) else: @@ -2124,7 +2122,7 @@ def update(self, original_name=None, new_source=None): for source_name in self._app.sources: excitation_source = [] for port in self._app.excitations: - if source_name in self._app.excitations[port]._props["EnabledPorts"]: + if source_name in self._app.excitation_objects[port]._props["EnabledPorts"]: excitation_source.append(port) arg3.append(source_name + ":=") arg3.append(excitation_source) @@ -2146,9 +2144,9 @@ def update(self, original_name=None, new_source=None): for source_name in self._app.sources: arg6 = ["NAME:" + source_name] for port in self._app.excitations: - if source_name in self._app.excitations[port]._props["EnabledAnalyses"]: + if source_name in self._app.excitation_objects[port]._props["EnabledAnalyses"]: arg6.append(port + ":=") - arg6.append(self._app.excitations[port]._props["EnabledAnalyses"][source_name]) + arg6.append(self._app.excitation_objects[port]._props["EnabledAnalyses"][source_name]) else: arg6.append(port + ":=") arg6.append([]) @@ -2179,10 +2177,10 @@ def delete(self): """ self._app.modeler._odesign.DeleteSource(self.name) for port in self._app.excitations: - if self.name in self._app.excitations[port].props["EnabledPorts"]: - self._app.excitations[port].props["EnabledPorts"].remove(self.name) - if self.name in self._app.excitations[port].props["EnabledAnalyses"]: - del self._app.excitations[port].props["EnabledAnalyses"][self.name] + if self.name in self._app.excitation_objects[port].props["EnabledPorts"]: + self._app.excitation_objects[port].props["EnabledPorts"].remove(self.name) + if self.name in self._app.excitation_objects[port].props["EnabledAnalyses"]: + del self._app.excitation_objects[port].props["EnabledAnalyses"][self.name] return True @pyaedt_function_handler() @@ -3205,7 +3203,7 @@ def name(self): @name.setter def name(self, port_name): - if port_name not in self._app.excitation_names: + if port_name not in self._app.excitations: if port_name != self._name: # Take previous properties self._app.odesign.RenamePort(self._name, port_name) @@ -4319,7 +4317,7 @@ def update(self): self.delete() try: self.create() - self._app.boundaries.append(self) + self._app._boundaries[self.name] = self return True except Exception: # pragma : no cover self._app.odesign.Undo() diff --git a/pyaedt/modules/CableModeling.py b/pyaedt/modules/CableModeling.py index 17b0f41ccc6..afab70bf56a 100644 --- a/pyaedt/modules/CableModeling.py +++ b/pyaedt/modules/CableModeling.py @@ -5,6 +5,7 @@ from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.LoadAEDTFile import load_entire_aedt_file from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import read_configuration_file @@ -1409,6 +1410,6 @@ def _cable_properties_parser(self, omodule, working_dir): omodule.ExportCableLibrary(file_path_export) file_path_export_as_json = os.path.join(working_dir, "export_cable_library_as_json_test.json") data = load_entire_aedt_file(file_path_export) - with open(file_path_export_as_json, "w") as f: + with open_file(file_path_export_as_json, "w") as f: json.dump(data, f) return data diff --git a/pyaedt/modules/DesignXPloration.py b/pyaedt/modules/DesignXPloration.py index 8c8d870ac64..d39385af798 100644 --- a/pyaedt/modules/DesignXPloration.py +++ b/pyaedt/modules/DesignXPloration.py @@ -6,6 +6,7 @@ from pyaedt.generic.DataHandlers import _dict2arg from pyaedt.generic.general_methods import PropsManager from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.modules.OptimetricsTemplates import defaultdoeSetup from pyaedt.modules.OptimetricsTemplates import defaultdxSetup @@ -70,7 +71,7 @@ def __init__(self, p_app, name, dictinputs, optimtype): setups = inputd["Sim. Setups"] for el in setups: try: - if type(self._app.design_properties["SolutionManager"]["ID Map"]["Setup"]) is list: + if isinstance(self._app.design_properties["SolutionManager"]["ID Map"]["Setup"], list): for setup in self._app.design_properties["SolutionManager"]["ID Map"]["Setup"]: if setup["I"] == el: setups[setups.index(el)] = setup["I"] @@ -1213,7 +1214,7 @@ def add_from_file(self, filename, parametricname=None): setup = SetupParam(self._app, parametricname, optim_type="OptiParametric") setup.auto_update = False setup.props["Sim. Setups"] = [setup_defined.name for setup_defined in self._app.setups] - with open(filename, "r") as csvfile: + with open_file(filename, "r") as csvfile: csvreader = csv.DictReader(csvfile) first_data_line = next(csvreader) setup.props["Sweeps"] = {"SweepDefinition": OrderedDict()} diff --git a/pyaedt/modules/LayerStackup.py b/pyaedt/modules/LayerStackup.py index b3b9bca69d6..d823baffe53 100644 --- a/pyaedt/modules/LayerStackup.py +++ b/pyaedt/modules/LayerStackup.py @@ -908,7 +908,7 @@ def _arg_with_dim(self, value, units=None): """ if units is None: units = self.LengthUnit - if type(value) is str: + if isinstance(value, str): try: float(value) val = "{0}{1}".format(value, units) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 7e1c28a1edb..256be73b51a 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -1301,6 +1301,7 @@ def __init__(self, materiallib, name, props=None, material_update=True): self._material_appearance.append(self._props["AttachedData"]["MatAppearanceData"]["Red"]) self._material_appearance.append(self._props["AttachedData"]["MatAppearanceData"]["Green"]) self._material_appearance.append(self._props["AttachedData"]["MatAppearanceData"]["Blue"]) + self._material_appearance.append(self._props["AttachedData"]["MatAppearanceData"].get("Transparency", 0.0)) else: vals = list(CSS4_COLORS.values()) if (materiallib._color_id) >= len(vals): @@ -1308,6 +1309,7 @@ def __init__(self, materiallib, name, props=None, material_update=True): h = vals[materiallib._color_id].lstrip("#") self._material_appearance = list(int(h[i : i + 2], 16) for i in (0, 2, 4)) materiallib._color_id += 1 + self._material_appearance.append(0) self._props["AttachedData"] = OrderedDict( { "MatAppearanceData": OrderedDict( @@ -1316,6 +1318,7 @@ def __init__(self, materiallib, name, props=None, material_update=True): "Red": self._material_appearance[0], "Green": self._material_appearance[1], "Blue": self._material_appearance[2], + "Transparency": self._material_appearance[3], } ) } @@ -1366,46 +1369,61 @@ def _update_material(self): @property def material_appearance(self): - """Material Appearance specified as an RGB list. + """Material appearance specified as a list where the first three items are + RGB color and the fourth one is transparency. Returns ------- list - Color of the material in RGB. Values are in the range ``[0, 255]``. + Color of the material in RGB and transparency. + Color values are in the range ``[0, 255]``. + Transparency is a float in the range ``[0,1]``. Examples -------- - Create a new material with color ``[0, 153, 153]`` (darker cyan). + Create a material with color ``[0, 153, 153]`` (darker cyan) and transparency ``0.5``. >>> from pyaedt import Hfss >>> hfss = Hfss(specified_version="2021.2") >>> mat1 = hfss.materials.add_material("new_material") - >>> rgbcolor = mat1.material_appearance - >>> mat1.material_appearance = [0, 153, 153] + >>> appearance_props = mat1.material_appearance + >>> mat1.material_appearance = [0, 153, 153, 0.5] """ return self._material_appearance @material_appearance.setter - def material_appearance(self, rgb): - if not isinstance(rgb, (list, tuple)): - raise TypeError("`material_apperance` must be a list or tuple") - if len(rgb) != 3: - raise ValueError("`material_appearance` must be three items (RGB)") - value_int = [] - for rgb_item in rgb: - rgb_int = int(rgb_item) - if rgb_int < 0 or rgb_int > 255: - raise ValueError("RGB value must be between 0 and 255") - value_int.append(rgb_int) - self._material_appearance = value_int + def material_appearance(self, appearance_props): + if not isinstance(appearance_props, (list, tuple)): + raise TypeError("`material_appearance` must be a list or tuple.") + if len(appearance_props) != 3 and len(appearance_props) != 4: + raise ValueError("`material_appearance` must be four items (R, G, B, transparency).") + elif len(appearance_props) == 3: + transparency_value = self.material_appearance[3] + msg = "Only RGB specified. Transparency is set to " + str(transparency_value) + self.logger.info(msg) + appearance_props.append(transparency_value) + value = [] + for i in range(len(appearance_props)): + if i < 3: + rgb_int = int(appearance_props[i]) + if rgb_int < 0 or rgb_int > 255: + raise ValueError("RGB value must be between 0 and 255.") + value.append(rgb_int) + else: + transparency = float(appearance_props[i]) + if transparency < 0 or transparency > 1: + raise ValueError("Transparency value must be between 0 and 1.") + value.append(transparency) + self._material_appearance = value self._props["AttachedData"] = OrderedDict( { "MatAppearanceData": OrderedDict( { "property_data": "appearance_data", - "Red": value_int[0], - "Green": value_int[1], - "Blue": value_int[2], + "Red": value[0], + "Green": value[1], + "Blue": value[2], + "Transparency": value[3], } ) } diff --git a/pyaedt/modules/Mesh.py b/pyaedt/modules/Mesh.py index fe043e28c4a..b0902dc8620 100644 --- a/pyaedt/modules/Mesh.py +++ b/pyaedt/modules/Mesh.py @@ -244,10 +244,10 @@ def update_assignment(self): if "Faces" in self.props: faces = self.props["Faces"] faces_out = [] - if type(faces) is not list: + if not isinstance(faces, list): faces = [faces] for f in faces: - if type(f) is EdgePrimitive or type(f) is FacePrimitive or type(f) is VertexPrimitive: + if isinstance(f, (EdgePrimitive, FacePrimitive, VertexPrimitive)): faces_out.append(f.id) else: faces_out.append(f) @@ -323,9 +323,9 @@ class Mesh(object): Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> cylinder = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> model_resolution = aedtapp.mesh.assign_model_resolution(cylinder, 1e-4, "ModelRes1") + >>> hfss = Hfss() + >>> cylinder = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> model_resolution = hfss.mesh.assign_model_resolution(cylinder,1e-4,"ModelRes1") """ def __init__(self, app): @@ -358,10 +358,10 @@ def __getitem__(self, part_id): Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> cylinder = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> mr1 = aedtapp.mesh.assign_model_resolution(cylinder, 1e-4, "ModelRes1") - >>> mr2 = aedtapp.mesh[mr1.name] + >>> hfss = Hfss() + >>> cylinder = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> mr1 = hfss.mesh.assign_model_resolution(cylinder,1e-4,"ModelRes1") + >>> mr2 = hfss.mesh[mr1.name] """ if part_id in self.meshoperation_names: @@ -384,10 +384,10 @@ def meshoperations(self): Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> o = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> mr1 = aedtapp.mesh.assign_model_resolution(o, 1e-4, "ModelRes1") - >>> mesh_operations_list = aedtapp.mesh.meshoperations + >>> hfss = Hfss() + >>> o = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> mr1 = hfss.mesh.assign_model_resolution(o,1e-4,"ModelRes1") + >>> mesh_operations_list = hfss.mesh.meshoperations """ if self._meshoperations is None: self._meshoperations = self._get_design_mesh_operations() @@ -414,11 +414,11 @@ def meshoperation_names(self): Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> o = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> mr1 = aedtapp.mesh.assign_model_resolution(o, 1e-4, "ModelRes1") - >>> mr2 = aedtapp.mesh.assign_model_resolution(o, 1e-2, "ModelRes2") - >>> mesh_operations_names = aedtapp.mesh.meshoperation_names + >>> hfss = Hfss() + >>> o = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> mr1 = hfss.mesh.assign_model_resolution(o,1e-4,"ModelRes1") + >>> mr2 = hfss.mesh.assign_model_resolution(o,1e-2,"ModelRes2") + >>> mesh_operations_names = hfss.mesh.meshoperation_names """ if self._app._is_object_oriented_enabled(): return list(self._app.odesign.GetChildObject("Mesh").GetChildNames()) @@ -536,17 +536,17 @@ def _get_design_mesh_operations(self): pass return meshops - @pyaedt_function_handler() - def assign_surface_mesh(self, names, level, meshop_name=None): + @pyaedt_function_handler(names="assignment", meshop_name="name") + def assign_surface_mesh(self, assignment, level, name=None): """Assign a surface mesh level to one or more objects. Parameters ---------- - names : list + assignment : list One or more names of the objects. level : int Level of the surface mesh. Options are ``1`` through ``10`` - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -564,21 +564,21 @@ def assign_surface_mesh(self, names, level, meshop_name=None): Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> o = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> surface = aedtapp.mesh.assign_surface_mesh(o.id, 3, "Surface") + >>> hfss = Hfss() + >>> o = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> surface = hfss.mesh.assign_surface_mesh(o.id,3,"Surface") """ - names = self.modeler.convert_to_selections(names, True) - if meshop_name: + assignment = self.modeler.convert_to_selections(assignment, True) + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("SurfApprox") - self.logger.info("Assigning Mesh Level " + str(level) + " to " + str(names)) - names = self._app.modeler.convert_to_selections(names, True) + name = generate_unique_name("SurfApprox") + self.logger.info("Assigning Mesh Level " + str(level) + " to " + str(assignment)) + assignment = self._app.modeler.convert_to_selections(assignment, True) - if isinstance(names[0], int): + if isinstance(assignment[0], int): seltype = "Faces" else: seltype = "Objects" @@ -586,30 +586,32 @@ def assign_surface_mesh(self, names, level, meshop_name=None): { "Type": "SurfApproxBased", "CurvedSurfaceApproxChoice": "UseSlider", - seltype: names, + seltype: assignment, "SliderMeshSettings": level, } ) - mop = MeshOperation(self, meshop_name, props, "SurfApproxBased") + mop = MeshOperation(self, name, props, "SurfApproxBased") mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_surface_mesh_manual(self, names, surf_dev=None, normal_dev=None, aspect_ratio=None, meshop_name=None): + @pyaedt_function_handler(names="assignment", surf_dev="surface_deviation", meshop_name="name") + def assign_surface_mesh_manual( + self, assignment, surface_deviation=None, normal_dev=None, aspect_ratio=None, name=None + ): """Assign a surface mesh to a list of faces. Parameters ---------- - names : list or str or :class:`pyaedt.modeler.elements3d.FacePrimitive` + assignment : list or str or :class:`pyaedt.modeler.elements3d.FacePrimitive` List of faces to apply the surface mesh to. - surf_dev : float or str, optional - Surface deviation. The default is ``None``. Allowed values are float, number with units or `"inf"`. + surface_deviation : float or str, optional + Surface deviation. The default is ``None``. You can specify a float value, a number with units, or `"inf"`. normal_dev : float or str, optional Normal deviation. The default is ``None``. aspect_ratio : int, optional Aspect ratio. The default is ``None``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -627,27 +629,26 @@ def assign_surface_mesh_manual(self, names, surf_dev=None, normal_dev=None, aspe Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> o = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> surface = self.aedtapp.mesh.assign_surface_mesh_manual(o.id, 1e-6, aspect_ratio=3, - ... meshop_name="Surface_Manual") + >>> hfss = Hfss() + >>> o = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> surface = hfss.mesh.assign_surface_mesh_manual(o.id,1e-6,aspect_ratio=3,name="Surface_Manual") """ - names = self.modeler.convert_to_selections(names, True) - if meshop_name: + assignment = self.modeler.convert_to_selections(assignment, True) + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("ModelResolution") + name = generate_unique_name("ModelResolution") surf_dev_enable = 2 normal_dev_enable = 2 aspect_ratio_enable = 2 - if not surf_dev: + if not surface_deviation: surf_dev_enable = 0 - surf_dev = "0.0001mm" - elif surf_dev == "inf": + surface_deviation = "0.0001mm" + elif surface_deviation == "inf": surf_dev_enable = 1 if not normal_dev: normal_dev_enable = 1 @@ -660,10 +661,10 @@ def assign_surface_mesh_manual(self, names, surf_dev=None, normal_dev=None, aspe props = OrderedDict( { "Type": "SurfApproxBased", - "Objects": names, + "Objects": assignment, "CurvedSurfaceApproxChoice": "ManualSettings", "SurfDevChoice": surf_dev_enable, - "SurfDev": surf_dev, + "SurfDev": surface_deviation, "NormalDevChoice": normal_dev_enable, "NormalDev": normal_dev, "AspectRatioChoice": aspect_ratio_enable, @@ -671,23 +672,23 @@ def assign_surface_mesh_manual(self, names, surf_dev=None, normal_dev=None, aspe } ) - mop = MeshOperation(self, meshop_name, props, "SurfApproxBased") + mop = MeshOperation(self, name, props, "SurfApproxBased") mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_model_resolution(self, names, defeature_length=None, meshop_name=None): + @pyaedt_function_handler(names="assignment", meshop_name="name") + def assign_model_resolution(self, assignment, defeature_length=None, name=None): """Assign the model resolution. Parameters ---------- - names : list + assignment : list List of objects to defeature. defeature_length : float, optional Defeaturing length in millimeters. The default is ``None``, in which case automatic defeaturing is used. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -705,34 +706,34 @@ def assign_model_resolution(self, names, defeature_length=None, meshop_name=None Basic usage demonstrated with an HFSS design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> o = aedtapp.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) - >>> surface = aedtapp.mesh.assign_model_resolution(o, 1e-4, "ModelRes1") + >>> hfss = Hfss() + >>> o = hfss.modeler.create_cylinder(0, [0, 0, 0], 3, 20, 0) + >>> surface = hfss.mesh.assign_model_resolution(o,1e-4,"ModelRes1") """ - names = self.modeler.convert_to_selections(names, True) - if meshop_name: + assignment = self.modeler.convert_to_selections(assignment, True) + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("ModelResolution") - for name in names: + name = generate_unique_name("ModelResolution") + for name in assignment: if isinstance(name, int): self.logger.error("Mesh Operation Applies to Objects only") return False if defeature_length is None: - props = OrderedDict({"Objects": names, "UseAutoLength": True}) + props = OrderedDict({"Objects": assignment, "UseAutoLength": True}) else: props = OrderedDict( { "Type": "DefeatureBased", - "Objects": names, + "Objects": assignment, "UseAutoLength": False, "DefeatureLength": str(defeature_length) + "mm", } ) - mop = MeshOperation(self, meshop_name, props, "DefeatureBased") + mop = MeshOperation(self, name, props, "DefeatureBased") mop.create() self.meshoperations.append(mop) return mop @@ -829,16 +830,16 @@ def assign_initial_mesh_from_slider( self.omeshmodule.InitialMeshSettings(args) return True - @pyaedt_function_handler() - def assign_surf_priority_for_tau(self, object_lists, surfpriority=0): + @pyaedt_function_handler(object_lists="assignment", surfpriority="surface_priority") + def assign_surf_priority_for_tau(self, assignment, surface_priority=0): """Assign a surface representation priority for the TAU mesh. Parameters ---------- - object_lists : list + assignment : list List of objects to apply a surface representation priority to. - surfpriority : int, optional + surface_priority : int, optional Surface representation priority. The default is ``0``. Returns @@ -852,7 +853,9 @@ def assign_surf_priority_for_tau(self, object_lists, surfpriority=0): >>> oModule.AssignSurfPriorityForTauOp """ meshop_name = generate_unique_name("SurfaceRepPriority") - props = OrderedDict({"Type": "SurfaceRepPriority", "Objects": object_lists, "SurfaceRepPriority": surfpriority}) + props = OrderedDict( + {"Type": "SurfaceRepPriority", "Objects": assignment, "SurfaceRepPriority": surface_priority} + ) mop = MeshOperation(self, meshop_name, props, "SurfaceRepPriority") mop.create() self.meshoperations.append(mop) @@ -865,7 +868,7 @@ def generate_mesh(self, name): Parameters ---------- name : str - Name of the design. + Name of the simulation setup. Returns ------- @@ -876,6 +879,16 @@ def generate_mesh(self, name): ---------- >>> oDesign.GenerateMesh + + Examples + -------- + + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> m3d.create_setup(setupname="Setup1") + >>> m3d.mesh.assign_length_mesh(maxlength=5, maxel="None") + >>> m3d.mesh.generate_mesh("Setup1") + """ return self._odesign.GenerateMesh(name) == 0 @@ -916,23 +929,29 @@ def delete_mesh_operations(self, mesh_type=None): return True - @pyaedt_function_handler() - def assign_length_mesh(self, names, isinside=True, maxlength=1, maxel=1000, meshop_name=None): + @pyaedt_function_handler( + names="assignment", + isinside="inside_selection", + maxlength="maximum_length", + maxel="maximum_elements", + meshop_name="name", + ) + def assign_length_mesh(self, assignment, inside_selection=True, maximum_length=1, maximum_elements=1000, name=None): """Assign a length for the model resolution. Parameters ---------- - names : list, str + assignment : list, str List of object names or face IDs. - isinside : bool, optional + inside_selection : bool, optional Whether the length mesh is inside the selection. The default is ``True``. - maxlength : str, float, optional + maximum_length : str, float, optional Maximum element length. The default is ``1``. When ``None``, this parameter is disabled. - maxel : int, optional + maximum_elements : int, optional Maximum number of elements. The default is ``1000``. When ``None``, this parameter is disabled. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -945,34 +964,34 @@ def assign_length_mesh(self, names, isinside=True, maxlength=1, maxel=1000, mesh >>> oModule.AssignLengthOp """ - names = self.modeler.convert_to_selections(names, True) - if meshop_name: + assignment = self.modeler.convert_to_selections(assignment, True) + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("length") + name = generate_unique_name("length") - if maxlength is None: + if maximum_length is None: restrictlength = False else: restrictlength = True - length = self.modeler.modeler_variable(maxlength) + length = self.modeler.modeler_variable(maximum_length) - if maxel is None: + if maximum_elements is None: restrictel = False numel = "1000" else: restrictel = True - numel = str(maxel) - if maxlength is None and maxel is None: + numel = str(maximum_elements) + if maximum_length is None and maximum_elements is None: self.logger.error("mesh not assigned due to incorrect settings") return - names = self._app.modeler.convert_to_selections(names, True) + assignment = self._app.modeler.convert_to_selections(assignment, True) - if isinstance(names[0], int) and not isinside: + if isinstance(assignment[0], int) and not inside_selection: seltype = "Faces" - elif isinstance(names[0], str): + elif isinstance(assignment[0], str): seltype = "Objects" else: seltype = None @@ -982,9 +1001,9 @@ def assign_length_mesh(self, names, isinside=True, maxlength=1, maxel=1000, mesh props = OrderedDict( { "Type": "LengthBased", - "RefineInside": isinside, + "RefineInside": inside_selection, "Enabled": True, - seltype: names, + seltype: assignment, "RestrictElem": restrictel, "NumMaxElem": numel, "RestrictLength": restrictlength, @@ -992,7 +1011,7 @@ def assign_length_mesh(self, names, isinside=True, maxlength=1, maxel=1000, mesh } ) - mop = MeshOperation(self, meshop_name, props, "LengthBased") + mop = MeshOperation(self, name, props, "LengthBased") for meshop in self.meshoperations[:]: if meshop.name == mop.name: meshop.delete() @@ -1001,33 +1020,40 @@ def assign_length_mesh(self, names, isinside=True, maxlength=1, maxel=1000, mesh self.meshoperations.append(mop) return mop - @pyaedt_function_handler() + @pyaedt_function_handler( + names="assignment", + skindepth="skin_depth", + maxelements="maximum_elements", + triangulation_max_length="0.1mm", + numlayers="layers_number", + meshop_name="name", + ) def assign_skin_depth( self, - names, - skindepth="0.2mm", - maxelements=None, + assignment, + skin_depth="0.2mm", + maximum_elements=None, triangulation_max_length="0.1mm", - numlayers="2", - meshop_name=None, + layers_number="2", + name=None, ): """Assign a skin depth for the mesh refinement. Parameters ---------- - names : list + assignment : list List of the object names or face IDs. - skindepth : str, float, optional + skin_depth : str, float, optional Skin depth value. It can be either provided as a float or as a string. The default is ``"0.2mm"``. - maxelements : int, optional + maximum_elements : int, optional Maximum number of elements. The default is ``None``, which means this parameter is disabled. triangulation_max_length : str, optional Maximum surface triangulation length with units. The default is ``"0.1mm"``. - numlayers : str, optional + layers_number : str, optional Number of layers. The default is ``"2"``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1040,27 +1066,27 @@ def assign_skin_depth( >>> oModule.AssignSkinDepthOp """ - names = self.modeler.convert_to_selections(names, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self._app.design_type != "HFSS" and self._app.design_type != "Maxwell 3D": raise MethodNotSupportedError - if meshop_name: + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("SkinDepth") + name = generate_unique_name("SkinDepth") - if maxelements is None: + if maximum_elements is None: restrictlength = False - maxelements = "1000" + maximum_elements = "1000" else: restrictlength = True - names = self._app.modeler.convert_to_selections(names, True) + assignment = self._app.modeler.convert_to_selections(assignment, True) - if isinstance(names[0], int): + if isinstance(assignment[0], int): seltype = "Faces" - elif isinstance(names[0], str): + elif isinstance(assignment[0], str): seltype = "Objects" else: seltype = None @@ -1072,31 +1098,31 @@ def assign_skin_depth( { "Type": "SkinDepthBased", "Enabled": True, - seltype: names, + seltype: assignment, "RestrictElem": restrictlength, - "NumMaxElem": str(maxelements), - "SkinDepth": skindepth, + "NumMaxElem": str(maximum_elements), + "SkinDepth": skin_depth, "SurfTriMaxLength": triangulation_max_length, - "NumLayers": numlayers, + "NumLayers": layers_number, } ) - mop = MeshOperation(self, meshop_name, props, "SkinDepthBased") + mop = MeshOperation(self, name, props, "SkinDepthBased") mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_curvilinear_elements(self, names, enable=True, meshop_name=None): + @pyaedt_function_handler(names="assignment", meshop_name="name") + def assign_curvilinear_elements(self, assignment, enable=True, name=None): """Assign curvilinear elements. Parameters ---------- - names : list + assignment : list List of objects or faces. enable : bool, optional Whether to apply curvilinear elements. The default is ``True``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1109,45 +1135,47 @@ def assign_curvilinear_elements(self, names, enable=True, meshop_name=None): >>> oModule.AssignApplyCurvlinearElementsOp """ - names = self.modeler.convert_to_selections(names, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self._app.design_type != "HFSS" and self._app.design_type != "Maxwell 3D": raise MethodNotSupportedError - if meshop_name: + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("CurvilinearElements") - names = self._app.modeler.convert_to_selections(names, True) + name = generate_unique_name("CurvilinearElements") + assignment = self._app.modeler.convert_to_selections(assignment, True) - if isinstance(names[0], int): + if isinstance(assignment[0], int): seltype = "Faces" - elif isinstance(names[0], str): + elif isinstance(assignment[0], str): seltype = "Objects" else: seltype = None if seltype is None: self.logger.error("Error in Assignment") return - props = OrderedDict({"Type": "Curvilinear", seltype: names, "Apply": enable}) - mop = MeshOperation(self, meshop_name, props, "Curvilinear") + props = OrderedDict({"Type": "Curvilinear", seltype: assignment, "Apply": enable}) + mop = MeshOperation(self, name, props, "Curvilinear") mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_curvature_extraction(self, names, disable_for_faceted_surf=True, meshop_name=None): + @pyaedt_function_handler( + names="assignment", disable_for_faceted_surf="disabled_for_faceted", meshoperation_names="name" + ) + def assign_curvature_extraction(self, assignment, disabled_for_faceted=True, name=None): """Assign curvature extraction. Parameters ---------- - names : list + assignment : list List of objects or faces. - disable_for_faceted_surf : bool, optional + disabled_for_faceted : bool, optional Whether curvature extraction is enabled for faceted surfaces. The default is ``True``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1160,20 +1188,20 @@ def assign_curvature_extraction(self, names, disable_for_faceted_surf=True, mesh >>> oModule.AssignCurvatureExtractionOp """ - names = self.modeler.convert_to_selections(names, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self._app.solution_type != "SBR+": raise MethodNotSupportedError - if meshop_name: + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("CurvilinearElements") - names = self._app.modeler.convert_to_selections(names, True) - if isinstance(names[0], int): + name = generate_unique_name("CurvilinearElements") + assignment = self._app.modeler.convert_to_selections(assignment, True) + if isinstance(assignment[0], int): seltype = "Faces" - elif isinstance(names[0], str): + elif isinstance(assignment[0], str): seltype = "Objects" else: seltype = None @@ -1181,27 +1209,27 @@ def assign_curvature_extraction(self, names, disable_for_faceted_surf=True, mesh self.logger.error("Error in Assignment") return props = OrderedDict( - {"Type": "CurvatureExtraction", seltype: names, "DisableForFacetedSurfaces": disable_for_faceted_surf} + {"Type": "CurvatureExtraction", seltype: assignment, "DisableForFacetedSurfaces": disabled_for_faceted} ) - mop = MeshOperation(self, meshop_name, props, "CurvatureExtraction") + mop = MeshOperation(self, name, props, "CurvatureExtraction") mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_rotational_layer(self, names, num_layers=3, total_thickness="1mm", meshop_name=None): + @pyaedt_function_handler(names="assignment", num_layers="layers_number", meshop_name="name") + def assign_rotational_layer(self, assignment, layers_number=3, total_thickness="1mm", name=None): """Assign a rotational layer mesh. Parameters ---------- - names : list + assignment : list List of objects. - num_layers : int, optional + layers_number : int, optional Number of layers to create in the radial direction, starting from the faces most adjacent to the band. The default is ``3``, which is the maximum. total_thickness : str, optional Total thickness of all layers with units. The default is ``"1mm"``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1214,43 +1242,43 @@ def assign_rotational_layer(self, names, num_layers=3, total_thickness="1mm", me >>> oModule.AssignRotationalLayerOp """ - names = self.modeler.convert_to_selections(names, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self._app.design_type != "Maxwell 3D": raise MethodNotSupportedError - if meshop_name: + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("RotationalLayer") + name = generate_unique_name("RotationalLayer") seltype = "Objects" props = OrderedDict( { "Type": "RotationalLayerMesh", - seltype: names, - "Number of Layers": str(num_layers), + seltype: assignment, + "Number of Layers": str(layers_number), "Total Layer Thickness": total_thickness, } ) - mop = MeshOperation(self, meshop_name, props, "RotationalLayerMesh") + mop = MeshOperation(self, name, props, "RotationalLayerMesh") mop.create() mop.props["Total Layer Thickness"] = total_thickness self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_edge_cut(self, names, layer_thickness="1mm", meshop_name=None): + @pyaedt_function_handler(names="assignment", meshop_name="name") + def assign_edge_cut(self, assignment, layer_thickness="1mm", name=None): """Assign an edge cut layer mesh. Parameters ---------- - names : list + assignment : list List of objects. layer_thickness : Thickness of the layer with units. The default is ``"1mm"``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1263,42 +1291,46 @@ def assign_edge_cut(self, names, layer_thickness="1mm", meshop_name=None): >>> oModule.AssignRotationalLayerOp """ - names = self.modeler.convert_to_selections(names, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self._app.design_type != "Maxwell 3D": raise MethodNotSupportedError - if meshop_name: + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("EdgeCut") + name = generate_unique_name("EdgeCut") seltype = "Objects" - props = OrderedDict({"Type": "EdgeCutLayerMesh", seltype: names, "Layer Thickness": layer_thickness}) + props = OrderedDict({"Type": "EdgeCutLayerMesh", seltype: assignment, "Layer Thickness": layer_thickness}) - mop = MeshOperation(self, meshop_name, props, "EdgeCutLayerMesh") + mop = MeshOperation(self, name, props, "EdgeCutLayerMesh") mop.create() mop.props["Layer Thickness"] = layer_thickness self.meshoperations.append(mop) return mop - @pyaedt_function_handler() - def assign_density_control(self, names, refine_inside=True, maxelementlength=None, layerNum=None, meshop_name=None): + @pyaedt_function_handler( + names="assignment", maxelementlength="maximum_element_length", layerNum="layers_number", meshop_name="name" + ) + def assign_density_control( + self, assignment, refine_inside=True, maximum_element_length=None, layers_number=None, name=None + ): """Assign density control. Parameters ---------- - names : list + assignment : list List of objects. refine_inside : bool, optional Whether to refine inside objects. The default is ``True``. - maxelementlength : str, optional + maximum_element_length : str, optional Maximum element length with units. The default is ``None``, which disables this parameter. - layerNum : int, optional + layers_number : int, optional Number of layers. The default is ``None``, which disables this parameter. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1311,50 +1343,50 @@ def assign_density_control(self, names, refine_inside=True, maxelementlength=Non >>> oModule.AssignDensityControlOp """ - names = self.modeler.convert_to_selections(names, True) + assignment = self.modeler.convert_to_selections(assignment, True) if self._app.design_type != "Maxwell 3D": raise MethodNotSupportedError - if meshop_name: + if name: for m in self.meshoperations: - if meshop_name == m.name: - meshop_name = generate_unique_name(meshop_name) + if name == m.name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("CloneMeshDensity") + name = generate_unique_name("CloneMeshDensity") seltype = "Objects" - if not maxelementlength: + if not maximum_element_length: restr = False restrval = "0mm" else: restr = True - restrval = maxelementlength - if not layerNum: + restrval = maximum_element_length + if not layers_number: restrlay = False restrlaynum = "1" else: restrlay = True - restrlaynum = str(layerNum) + restrlaynum = str(layers_number) props = OrderedDict( { "Type": "DensityControlBased", "RefineInside": refine_inside, - seltype: names, + seltype: assignment, "RestrictMaxElemLength": restr, "MaxElemLength": restrval, "RestrictLayersNum": restrlay, "LayersNum": restrlaynum, } ) - mop = MeshOperation(self, meshop_name, props, "DensityControlBased") + mop = MeshOperation(self, name, props, "DensityControlBased") mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() + @pyaedt_function_handler(obj="entity", meshop_name="name") def assign_cylindrical_gap( self, - obj, - meshop_name=None, + entity, + name=None, band_mapping_angle=None, clone_mesh=False, moving_side_layers=1, @@ -1364,9 +1396,9 @@ def assign_cylindrical_gap( Parameters ---------- - obj : int or str or :class:`pyaedt.modeler.cad.object3d.Object3d` + entity : int or str or :class:`pyaedt.modeler.cad.object3d.Object3d` Object to assign cylindrical gap to. - meshop_name : str, optional + name : str, optional Name of the mesh. The default is ``None``, in which case the default name is used. clone_mesh : bool, optional @@ -1408,8 +1440,8 @@ def assign_cylindrical_gap( if self._app.design_type != "Maxwell 2D" and self._app.design_type != "Maxwell 3D": raise MethodNotSupportedError - obj = self.modeler.convert_to_selections(obj, True) - if len(obj) > 1: + entity = self.modeler.convert_to_selections(entity, True) + if len(entity) > 1: self.logger.error("Cylindrical gap treatment cannot be assigned to multiple objects.") raise ValueError if [x for x in self.meshoperations if x.type == "Cylindrical Gap Based" or x.type == "CylindricalGap"]: @@ -1418,8 +1450,8 @@ def assign_cylindrical_gap( if band_mapping_angle and band_mapping_angle > 3: self.logger.error("Band mapping angle must be between 0.0005 and 3 deg.") raise ValueError - if not meshop_name: - meshop_name = generate_unique_name("CylindricalGap") + if not name: + name = generate_unique_name("CylindricalGap") if self._app.design_type == "Maxwell 3D": if moving_side_layers < 1: @@ -1432,8 +1464,8 @@ def assign_cylindrical_gap( band_mapping_angle = 3 props = OrderedDict( { - "Name": meshop_name, - "Objects": obj, + "Name": name, + "Objects": entity, "CloneMesh": clone_mesh, "BandMappingAngle": str(band_mapping_angle) + "deg", "MovingSideLayers": moving_side_layers, @@ -1448,13 +1480,13 @@ def assign_cylindrical_gap( band_mapping_angle = 3 props = OrderedDict( { - "Name": meshop_name, - "Objects": obj, + "Name": name, + "Objects": entity, "UseBandMappingAngle": use_band_mapping_angle, "BandMappingAngle": str(band_mapping_angle) + "deg", } ) - mesh_operation = MeshOperation(self, meshop_name, props, "CylindricalGap") + mesh_operation = MeshOperation(self, name, props, "CylindricalGap") mesh_operation.create() self.meshoperations.append(mesh_operation) return mesh_operation diff --git a/pyaedt/modules/Mesh3DLayout.py b/pyaedt/modules/Mesh3DLayout.py index 1ae1601947a..67b845d223d 100644 --- a/pyaedt/modules/Mesh3DLayout.py +++ b/pyaedt/modules/Mesh3DLayout.py @@ -175,15 +175,15 @@ def omeshmodule(self): """ return self._app.omeshmodule - @pyaedt_function_handler() - def delete_mesh_operations(self, setup_name, mesh_name): + @pyaedt_function_handler(setup_name="setup", mesh_name="name") + def delete_mesh_operations(self, setup, name): """Remove mesh operations from a setup. Parameters ---------- - setup_name : str + setup : str Name of the setup. - mesh_name : str + name : str Name of the mesh. Returns @@ -197,7 +197,7 @@ def delete_mesh_operations(self, setup_name, mesh_name): >>> oModule.DeleteMeshOperation """ for el in self.meshoperations: - if el.hfss_setup_name == setup_name and el.name == mesh_name: + if el.hfss_setup_name == setup and el.name == name: el.delete() self.meshoperations.remove(el) @@ -224,29 +224,35 @@ def _get_design_mesh_operations(self): pass return meshops - @pyaedt_function_handler() - def assign_length_mesh( - self, setupname, layer_name, net_name, isinside=True, maxlength=1, maxel=1000, meshop_name=None - ): + @pyaedt_function_handler( + setupname="setup", + layer_name="layer", + net_name="net", + isinside="is_inside", + maxlength="maximum_length", + maxel="maximum_elements", + meshop_name="name", + ) + def assign_length_mesh(self, setup, layer, net, is_inside=True, maximum_length=1, maximum_elements=1000, name=None): """Assign mesh length. Parameters ---------- - setupname : str + setup : str Name of the HFSS setup to apply. - layer_name : str + layer : str Name of the layer. - net_name : str + net : str Name of the net. - isinside : bool, optional + is_inside : bool, optional Whether the mesh length is inside the selection. The default is ``True``. - maxlength : float, optional + maximum_length : float, optional Maximum length of the element. The default is ``1`` When ``None``, this parameter is disabled. - maxel : int, optional + maximum_elements : int, optional Maximum number of elements. The default is ``1000``. When ``None``, this parameter is disabled. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -259,37 +265,37 @@ def assign_length_mesh( >>> oModule.AddMeshOperation """ - if meshop_name: + if name: for el in self.meshoperations: - if el.name == meshop_name: - meshop_name = generate_unique_name(meshop_name) + if el.name == name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("Length") + name = generate_unique_name("Length") - if maxlength is None: + if maximum_length is None: restrictlength = False else: restrictlength = True - length = self.modeler.modeler_variable(maxlength) + length = self.modeler.modeler_variable(maximum_length) - if maxel is None: + if maximum_elements is None: restrictel = False numel = "1000" else: restrictel = True - numel = str(maxel) - if maxlength is None and maxel is None: + numel = str(maximum_elements) + if maximum_length is None and maximum_elements is None: self.logger.error("mesh not assigned due to incorrect settings") return - if isinstance(layer_name, list) and isinstance(net_name, list): + if isinstance(layer, list) and isinstance(net, list): assignment = OrderedDict({"MeshEntityInfo": []}) - for l, n in zip(layer_name, net_name): + for l, n in zip(layer, net): meshbody = OrderedDict({"Id": -1, "Nam": "", "Layer": l, "Net": n, "OrigNet": n}) assignment["MeshEntityInfo"].append( OrderedDict({"IsFcSel": False, "EntID": -1, "FcIDs": [], "MeshBody": meshbody, "BBox": []}) ) else: - meshbody = OrderedDict({"Id": -1, "Nam": "", "Layer": layer_name, "Net": net_name, "OrigNet": net_name}) + meshbody = OrderedDict({"Id": -1, "Nam": "", "Layer": layer, "Net": net, "OrigNet": net}) assignment = OrderedDict( { "MeshEntityInfo": OrderedDict( @@ -300,7 +306,7 @@ def assign_length_mesh( props = OrderedDict( { "Type": "LengthBased", - "RefineInside": isinside, + "RefineInside": is_inside, "Enabled": True, "Assignment": assignment, "Region": "", @@ -311,42 +317,50 @@ def assign_length_mesh( } ) - mop = Mesh3DOperation(self, setupname, meshop_name, props) + mop = Mesh3DOperation(self, setup, name, props) mop.create() self.meshoperations.append(mop) return mop - @pyaedt_function_handler() + @pyaedt_function_handler( + setupname="setup", + layer_name="layer", + net_name="net", + skindepth="skin_depth", + maxelements="maximum_elements", + numlayers="layers_number", + meshop_name="name", + ) def assign_skin_depth( self, - setupname, - layer_name, - net_name, - skindepth=1, - maxelements=None, + setup, + layer, + net, + skin_depth=1, + maximum_elements=None, triangulation_max_length=0.1, - numlayers="2", - meshop_name=None, + layers_number="2", + name=None, ): """Assign skin depth to the mesh. Parameters ---------- - setupname : str + setup : str Name of the setup. - layer_name : str + layer : str Name of the layer. - net_name : str + net : str Name of the net. - skindepth : int, optional + skin_depth : int, optional Depth of the skin. The default is ``1``. - maxelements : float, optional + maximum_elements : float, optional Maximum element length. The default is ``None``, which disables this parameter. triangulation_max_length : float, optional Maximum surface triangulation length. The default is ``0.1``. - numlayers : str, optional + layers_number : str, optional Number of layers. The default is ``"2"``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -359,21 +373,21 @@ def assign_skin_depth( >>> oModule.AddMeshOperation """ - if meshop_name: + if name: for el in self.meshoperations: - if el.name == meshop_name: - meshop_name = generate_unique_name(meshop_name) + if el.name == name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("SkinDepth") + name = generate_unique_name("SkinDepth") - if maxelements is None: + if maximum_elements is None: restrictlength = False - maxelements = "1000" + maximum_elements = "1000" else: restrictlength = True - skindepth = self.modeler.modeler_variable(skindepth) + skin_depth = self.modeler.modeler_variable(skin_depth) triangulation_max_length = self.modeler.modeler_variable(triangulation_max_length) - meshbody = OrderedDict({"Id": -1, "Nam": "", "Layer": layer_name, "Net": net_name, "OrigNet": net_name}) + meshbody = OrderedDict({"Id": -1, "Nam": "", "Layer": layer, "Net": net, "OrigNet": net}) assignment = OrderedDict( { "MeshEntityInfo": OrderedDict( @@ -387,15 +401,15 @@ def assign_skin_depth( "Enabled": True, "Assignment": assignment, "Region": "", - "SkinDepth": skindepth, + "SkinDepth": skin_depth, "SurfTriMaxLength": triangulation_max_length, - "NumLayers": numlayers, + "NumLayers": layers_number, "RestrictElem": restrictlength, - "NumMaxElem": maxelements, + "NumMaxElem": maximum_elements, } ) - mop = Mesh3DOperation(self, setupname, meshop_name, props) + mop = Mesh3DOperation(self, setup, name, props) mop.create() self.meshoperations.append(mop) return mop diff --git a/pyaedt/modules/MeshIcepak.py b/pyaedt/modules/MeshIcepak.py index 5ddfcdff78b..ae868d9946c 100644 --- a/pyaedt/modules/MeshIcepak.py +++ b/pyaedt/modules/MeshIcepak.py @@ -620,6 +620,7 @@ def update(self): """ args = ["NAME:Settings"] args += self.settings.parse_settings() + args += ["UserSpecifiedSettings:=", self.manual_settings] try: self._app.omeshmodule.EditGlobalMeshRegion(args) return True @@ -746,7 +747,7 @@ def update(self): args = ["NAME:" + self.name, "Enable:=", self.enable] args += self.settings.parse_settings() args += self._parse_assignment_value() - args += ["UserSpecifiedSettings:=", not self.manual_settings] + args += ["UserSpecifiedSettings:=", self.manual_settings] try: self._app.omeshmodule.EditMeshRegion(self.name, args) return True @@ -1050,8 +1051,8 @@ def _get_design_mesh_regions(self): return meshops - @pyaedt_function_handler() - def assign_mesh_level(self, mesh_order, meshop_name=None): + @pyaedt_function_handler(meshop_name="name") + def assign_mesh_level(self, mesh_order, name=None): """Assign a mesh level to objects. Parameters @@ -1059,7 +1060,7 @@ def assign_mesh_level(self, mesh_order, meshop_name=None): mesh_order : dict Dictionary where the key is the object name and the value is the mesh level. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1079,28 +1080,28 @@ def assign_mesh_level(self, mesh_order, meshop_name=None): level_order[mesh_order[obj]].append(obj) list_meshops = [] for level in level_order: - if meshop_name: - meshop_name = generate_unique_name(meshop_name, "L_" + str(level)) + if name: + name = generate_unique_name(name, "L_" + str(level)) else: - meshop_name = generate_unique_name("Icepak", "L_" + str(level)) + name = generate_unique_name("Icepak", "L_" + str(level)) props = OrderedDict({"Enable": True, "Level": str(level), "Objects": level_order[level]}) - mop = MeshOperation(self, meshop_name, props, "Icepak") + mop = MeshOperation(self, name, props, "Icepak") mop.create() self.meshoperations.append(mop) - list_meshops.append(meshop_name) + list_meshops.append(name) return list_meshops - @pyaedt_function_handler() - def assign_mesh_from_file(self, objects, filename, meshop_name=None): - """Assign a mesh from file to objects. + @pyaedt_function_handler(objects="assignment", filename="file_name", meshop_name="name") + def assign_mesh_from_file(self, assignment, file_name, name=None): + """Assign a mesh from a file to objects. Parameters ---------- - objects : list - List of objects to which apply the mesh file. - filename : str - Full path to .msh file. - meshop_name : str, optional + assignment : list + List of objects to apply the mesh file to. + file_name : str + Full path to the mesh (MSH) file. + name : str, optional Name of the mesh operations. Default is ``None``. Returns @@ -1113,22 +1114,22 @@ def assign_mesh_from_file(self, objects, filename, meshop_name=None): >>> oModule.AssignMeshOperation """ - objs = self._app.modeler.convert_to_selections(objects, True) - if meshop_name: - meshop_name = generate_unique_name("MeshFile") + objs = self._app.modeler.convert_to_selections(assignment, True) + if name: + name = generate_unique_name("MeshFile") else: - meshop_name = generate_unique_name("MeshFile") + name = generate_unique_name("MeshFile") props = OrderedDict({"Enable": True, "MaxLevel": str(0), "MinLevel": str(0), "Objects": objs}) props["Local Mesh Parameters Enabled"] = False props["Mesh Reuse Enabled"] = True - props["Mesh Reuse File"] = filename + props["Mesh Reuse File"] = file_name props["Local Mesh Parameters Type"] = "3DPolygon Local Mesh Parameters" props["Height count"] = "0" props["Top height"] = "0mm" props["Top ratio"] = "0" props["Bottom height"] = "0mm" props["Bottom ratio"] = "0" - mop = MeshOperation(self, meshop_name, props, "Icepak") + mop = MeshOperation(self, name, props, "Icepak") if mop.create(): self.meshoperations.append(mop) return mop @@ -1175,16 +1176,16 @@ def automatic_mesh_pcb(self, accuracy=2): self.global_mesh_region.update() return True - @pyaedt_function_handler() - def automatic_mesh_3D(self, accuracy2, stairStep=True): + @pyaedt_function_handler(accuracy2="accuracy", stairStep="enable_stair_step") + def automatic_mesh_3D(self, accuracy, enable_stair_step=True): """Create a generic custom mesh for a custom 3D object. Parameters ---------- - accuracy2 : int + accuracy : int Type of the mesh. Options are ``1``, ``2``, and ``3``, which represent respectively a coarse, standard, or very accurate mesh. - stairStep : bool, optional + enable_stair_step : bool, optional Whether to enable a stair step. The default is ``True``. Returns @@ -1197,9 +1198,9 @@ def automatic_mesh_3D(self, accuracy2, stairStep=True): >>> oModule.EditMeshOperation """ - xsize = self.boundingdimension[0] / (10 * accuracy2 * accuracy2) - ysize = self.boundingdimension[1] / (10 * accuracy2 * accuracy2) - zsize = self.boundingdimension[2] / (10 * accuracy2) + xsize = self.boundingdimension[0] / (10 * accuracy * accuracy) + ysize = self.boundingdimension[1] / (10 * accuracy * accuracy) + zsize = self.boundingdimension[2] / (10 * accuracy) self.global_mesh_region.MaxElementSizeX = xsize self.global_mesh_region.MaxElementSizeY = ysize self.global_mesh_region.MaxElementSizeZ = zsize @@ -1207,12 +1208,12 @@ def automatic_mesh_3D(self, accuracy2, stairStep=True): self.global_mesh_region.MinGapX = str(xsize / 100) self.global_mesh_region.MinGapY = str(ysize / 100) self.global_mesh_region.MinGapZ = str(zsize / 100) - self.global_mesh_region.StairStepMeshing = stairStep + self.global_mesh_region.StairStepMeshing = enable_stair_step self.global_mesh_region.update() return True - @pyaedt_function_handler() - def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): + @pyaedt_function_handler(obj_list="assignment", comp_name="component") + def add_priority(self, entity_type, assignment=None, component=None, priority=3): """Add priority to objects. Parameters @@ -1220,10 +1221,10 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): entity_type : int Type of the entity. Options are ``1`` and ``2``, which represent respectively an object and a component. - obj_list : list + assignment : list List of 3D objects, which can include conductors and dielectrics. - If the user pass a non 3D object, it will be excluded. - comp_name : str, optional + If a non-3D object is passed, it is excluded. + component : str, optional Name of the component. The default is ``None``. priority : int, optional Level of priority. The default is ``3``. @@ -1243,8 +1244,8 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): >>> from pyaedt import Icepak >>> app = Icepak() - >>> app.mesh.add_priority(entity_type=1, obj_list=app.modeler.object_names, priority=3) - >>> app.mesh.add_priority(entity_type=2, comp_name=app.modeler.user_defined_component_names[0], priority=2) + >>> app.mesh.add_priority(entity_type=1,assignment=app.modeler.object_names,priority=3) + >>> app.mesh.add_priority(entity_type=2,component=app.modeler.user_defined_component_names[0],priority=2) """ i = priority @@ -1252,10 +1253,10 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): if entity_type == 1: non_user_defined_component_parts = self._app.modeler.oeditor.GetChildNames() new_obj_list = [] - for comp in obj_list: + for comp in assignment: if comp != "Region" and comp in non_user_defined_component_parts: new_obj_list.append(comp) - objects = ", ".join(new_obj_list) + assignment = ", ".join(new_obj_list) if not new_obj_list: return False prio = [ @@ -1263,7 +1264,7 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): "EntityType:=", "Object", "EntityList:=", - objects, + assignment, "PriorityNumber:=", i, "PriorityListType:=", @@ -1272,7 +1273,7 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): self._priorities_args.append(prio) args += self._priorities_args elif entity_type == 2: - o = self.modeler.user_defined_components[comp_name] + o = self.modeler.user_defined_components[component] if (all(part.is3d for part in o.parts.values()) is False) and ( any(part.is3d for part in o.parts.values()) is True ): @@ -1281,7 +1282,7 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): "EntityType:=", "Component", "EntityList:=", - comp_name, + component, "PriorityNumber:=", i, "PriorityListType:=", @@ -1292,7 +1293,7 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): "EntityType:=", "Component", "EntityList:=", - comp_name, + component, "PriorityNumber:=", i, "PriorityListType:=", @@ -1306,7 +1307,7 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): "EntityType:=", "Component", "EntityList:=", - comp_name, + component, "PriorityNumber:=", i, "PriorityListType:=", @@ -1319,7 +1320,7 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): "EntityType:=", "Component", "EntityList:=", - comp_name, + component, "PriorityNumber:=", i, "PriorityListType:=", @@ -1332,13 +1333,13 @@ def add_priority(self, entity_type, obj_list=None, comp_name=None, priority=3): self.modeler.oeditor.UpdatePriorityList(args) return True - @pyaedt_function_handler() - def assign_mesh_region(self, objectlist=None, level=5, name=None, **kwargs): + @pyaedt_function_handler(objectlist="assignment") + def assign_mesh_region(self, assignment=None, level=5, name=None, **kwargs): """Assign a predefined surface mesh level to an object. Parameters ---------- - objectlist : list, optional + assignment : list, optional List of objects to apply the mesh region to. The default is ``None``, in which case all objects are selected. level : int, optional @@ -1358,9 +1359,9 @@ def assign_mesh_region(self, objectlist=None, level=5, name=None, **kwargs): """ if not name: name = generate_unique_name("MeshRegion") - if objectlist is None: - objectlist = [i for i in self.modeler.object_names] - meshregion = MeshRegion(self._app, objectlist, name) + if assignment is None: + assignment = [i for i in self.modeler.object_names] + meshregion = MeshRegion(self._app, assignment, name) meshregion.manual_settings = False meshregion.Level = level all_objs = [i for i in self.modeler.object_names] @@ -1370,7 +1371,7 @@ def assign_mesh_region(self, objectlist=None, level=5, name=None, **kwargs): objectlist2 = self.modeler.object_names added_obj = [i for i in objectlist2 if i not in all_objs] if not added_obj: - added_obj = [i for i in objectlist2 if i not in all_objs or i in objectlist] + added_obj = [i for i in objectlist2 if i not in all_objs or i in assignment] meshregion.Objects = added_obj meshregion.SubModels = None meshregion.update() @@ -1401,14 +1402,19 @@ def generate_mesh(self, name=None): name = [] return self._odesign.GenerateMesh(name) == 0 - @pyaedt_function_handler() + @pyaedt_function_handler( + groupName="group_name", + localMeshParamEn="enable_local_mesh_parameters", + localMeshParameters="local_mesh_parameters", + meshop_name="name", + ) def assign_mesh_level_to_group( self, mesh_level, - groupName, - localMeshParamEn=False, - localMeshParameters="No local mesh parameters", - meshop_name=None, + group_name, + enable_local_mesh_parameters=False, + local_mesh_parameters="No local mesh parameters", + name=None, ): """Assign a mesh level to a group. @@ -1416,13 +1422,13 @@ def assign_mesh_level_to_group( ---------- mesh_level : int Level of mesh to assign. Options are ``1`` through ``5``. - groupName : str + group_name : str Name of the group. - localMeshParamEn : bool, optional + enable_local_mesh_parameters : bool, optional The default is ``False``. - localMeshParameters : str, optional + local_mesh_parameters : str, optional The default is ``"No Local Mesh Parameters"``. - meshop_name : str, optional + name : str, optional Name of the mesh operation. The default is ``None``. Returns @@ -1434,22 +1440,22 @@ def assign_mesh_level_to_group( >>> oModule.AssignMeshOperation """ - if meshop_name: + if name: for el in self.meshoperations: - if el.name == meshop_name: - meshop_name = generate_unique_name(meshop_name) + if el.name == name: + name = generate_unique_name(name) else: - meshop_name = generate_unique_name("MeshLevel") + name = generate_unique_name("MeshLevel") props = OrderedDict( { "Enable": True, "Level": mesh_level, - "Local Mesh Parameters Enabled": localMeshParamEn, - "Groups": [str(groupName)], - "Local Mesh Parameters Type": localMeshParameters, + "Local Mesh Parameters Enabled": enable_local_mesh_parameters, + "Groups": [str(group_name)], + "Local Mesh Parameters Type": local_mesh_parameters, } ) - mop = MeshOperation(self, meshop_name, props, "Icepak") + mop = MeshOperation(self, name, props, "Icepak") mop.create() self.meshoperations.append(mop) return mop diff --git a/pyaedt/modules/PostProcessor.py b/pyaedt/modules/PostProcessor.py index 2a4e22eda24..bacd04d5d46 100644 --- a/pyaedt/modules/PostProcessor.py +++ b/pyaedt/modules/PostProcessor.py @@ -13,6 +13,7 @@ import csv import os import random +import re import string import tempfile @@ -37,10 +38,10 @@ from enum import Enum import pandas as pd - except ImportError: + except ImportError: # pragma: no cover pd = None Enum = None -else: +else: # pragma: no cover Enum = object TEMPLATES_BY_DESIGN = { @@ -76,7 +77,7 @@ "Spectrum", ], "Icepak": ["Monitor", "Fields"], - "Circuit Design": ["Standard", "Eye Diagram", "Statistical Eye", "Spectrum"], + "Circuit Design": ["Standard", "Eye Diagram", "Statistical Eye", "Spectrum", "EMIReceiver"], "HFSS 3D Layout": ["Standard", "Fields", "Spectrum"], "HFSS 3D Layout Design": ["Standard", "Fields", "Spectrum"], "Mechanical": ["Standard", "Fields"], @@ -101,6 +102,7 @@ "AMI Contour": rt.AMIConturEyeDiagram, "Eigenmode Parameters": rt.Standard, "Spectrum": rt.Spectral, + "EMIReceiver": rt.EMIReceiver, } @@ -119,14 +121,16 @@ def _retrieve_default_expressions(self, expressions, report, setup_sweep_name): setup_only_name = setup_sweep_name.split(":")[0].strip() get_setup = self._post_app._app.get_setup(setup_only_name) is_siwave_dc = False - if "SolveSetupType" in get_setup.props and get_setup.props["SolveSetupType"] == "SiwaveDCIR": + if ( + "SolveSetupType" in get_setup.props and get_setup.props["SolveSetupType"] == "SiwaveDCIR" + ): # pragma: no cover is_siwave_dc = True return self._post_app.available_report_quantities( solution=setup_sweep_name, context=report._context, is_siwave_dc=is_siwave_dc ) - @pyaedt_function_handler() - def standard(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def standard(self, expressions=None, setup=None): """Create a standard or default report object. Parameters @@ -134,10 +138,11 @@ def standard(self, expressions=None, setup_name=None): expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -148,36 +153,37 @@ def standard(self, expressions=None, setup_name=None): >>> from pyaedt import Circuit >>> cir = Circuit(my_project) - >>> report = cir.post.reports_by_category.standard("dB(S(1,1))", "LNA") + >>> report = cir.post.reports_by_category.standard("dB(S(1,1))","LNA") >>> report.create() >>> solutions = report.get_solution_data() - >>> report2 = cir.post.reports_by_category.standard(["dB(S(2,1))", "dB(S(2,2))"] , "LNA") + >>> report2 = cir.post.reports_by_category.standard(["dB(S(2,1))", "dB(S(2,2))"],"LNA") """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep rep = None if "Standard" in self._templates: - rep = rt.Standard(self._post_app, "Standard", setup_name) + rep = rt.Standard(self._post_app, "Standard", setup) elif self._post_app._app.design_solutions.report_type: - rep = rt.Standard(self._post_app, self._post_app._app.design_solutions.report_type, setup_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) + rep = rt.Standard(self._post_app, self._post_app._app.design_solutions.report_type, setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) return rep - @pyaedt_function_handler() - def monitor(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def monitor(self, expressions=None, setup=None): """Create an Icepak Monitor Report object. Parameters ---------- expressions : str or list - Expression List to add into the report. The expression can be any of the available formula + One or more expressions to add to the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -191,28 +197,32 @@ def monitor(self, expressions=None, setup_name=None): >>> report = ipk.post.reports_by_category.monitor(["monitor_surf.Temperature","monitor_point.Temperature"]) >>> report = report.create() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Monitor" in self._templates: - rep = rt.Standard(self._post_app, "Monitor", setup_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep = rt.Standard(self._post_app, "Monitor", setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def fields(self, expressions=None, setup_name=None, polyline=None): + @pyaedt_function_handler(setup_name="setup") + def fields(self, expressions=None, setup=None, polyline=None): """Create a Field Report object. Parameters ---------- expressions : str or list - Expression List to add into the report. The expression can be any of the available formula + One or more expressions to add to the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + polyline : str, optional + Name of the polyline to plot the field on. + If a name is not provided, the report might be incorrect. + The default value is ``None``. Returns ------- @@ -222,34 +232,38 @@ def fields(self, expressions=None, setup_name=None, polyline=None): -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.fields("Mag_E", "Setup : LastAdaptive", "Polyline1") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.fields("Mag_E", "Setup : LastAdaptive", "Polyline1") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Fields" in self._templates: - rep = rt.Fields(self._post_app, "Fields", setup_name) + rep = rt.Fields(self._post_app, "Fields", setup) rep.polyline = polyline - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def cg_fields(self, expressions=None, setup_name=None, polyline=None): - """Create a CG Field Report object in Q3d and Q2D. + @pyaedt_function_handler(setup_name="setup") + def cg_fields(self, expressions=None, setup=None, polyline=None): + """Create a CG Field Report object in Q3D and Q2D. Parameters ---------- expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + polyline : str, optional + Name of the polyline to plot the field on. + If a name is not provided, the report might be incorrect. + The default value is ``None``. Returns ------- @@ -259,34 +273,38 @@ def cg_fields(self, expressions=None, setup_name=None, polyline=None): -------- >>> from pyaedt import Q3d - >>> app = Q3d(my_project) - >>> report = app.post.reports_by_category.cg_fields("SmoothQ", "Setup : LastAdaptive", "Polyline1") + >>> q3d = Q3d(my_project) + >>> report = q3d.post.reports_by_category.cg_fields("SmoothQ", "Setup : LastAdaptive", "Polyline1") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "CG Fields" in self._templates: - rep = rt.Fields(self._post_app, "CG Fields", setup_name) + rep = rt.Fields(self._post_app, "CG Fields", setup) rep.polyline = polyline - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def dc_fields(self, expressions=None, setup_name=None, polyline=None): - """Create a DC Field Report object in Q3d. + @pyaedt_function_handler(setup_name="setup") + def dc_fields(self, expressions=None, setup=None, polyline=None): + """Create a DC Field Report object in Q3D. Parameters ---------- expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + polyline : str, optional + Name of the polyline to plot the field on. + If a name is not provided, the report might be incorrect. + The default value is ``None``. Returns ------- @@ -296,34 +314,38 @@ def dc_fields(self, expressions=None, setup_name=None, polyline=None): -------- >>> from pyaedt import Q3d - >>> app = Q3d(my_project) - >>> report = app.post.reports_by_category.dc_fields("Mag_VolumeJdc", "Setup : LastAdaptive", "Polyline1") + >>> q3d = Q3d(my_project) + >>> report = q3d.post.reports_by_category.dc_fields("Mag_VolumeJdc", "Setup : LastAdaptive", "Polyline1") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "DC R/L Fields" in self._templates: - rep = rt.Fields(self._post_app, "DC R/L Fields", setup_name) + rep = rt.Fields(self._post_app, "DC R/L Fields", setup) rep.polyline = polyline - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def rl_fields(self, expressions=None, setup_name=None, polyline=None): - """Create an AC RL Field Report object in Q3d and Q2D. + @pyaedt_function_handler(setup_name="setup") + def rl_fields(self, expressions=None, setup=None, polyline=None): + """Create an AC RL Field Report object in Q3D and Q2D. Parameters ---------- expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + polyline : str, optional + Name of the polyline to plot the field on. + If a name is not provided, the report might be incorrect. + The default value is ``None``. Returns ------- @@ -333,26 +355,25 @@ def rl_fields(self, expressions=None, setup_name=None, polyline=None): -------- >>> from pyaedt import Q3d - >>> app = Q3d(my_project) - >>> report = app.post.reports_by_category.rl_fields("Mag_SurfaceJac", "Setup : LastAdaptive", "Polyline1") + >>> q3d = Q3d(my_project) + >>> report = q3d.post.reports_by_category.rl_fields("Mag_SurfaceJac", "Setup : LastAdaptive", "Polyline1") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "AC R/L Fields" in self._templates or "RL Fields" in self._templates: if self._post_app._app.design_type == "Q3D Extractor": - rep = rt.Fields(self._post_app, "AC R/L Fields", setup_name) + rep = rt.Fields(self._post_app, "AC R/L Fields", setup) else: - rep = rt.Fields(self._post_app, "RL Fields", setup_name) + rep = rt.Fields(self._post_app, "RL Fields", setup) rep.polyline = polyline - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def far_field(self, expressions=None, setup_name=None, sphere_name=None, source_context=None): + @pyaedt_function_handler(setup_name="setup") + def far_field(self, expressions=None, setup=None, sphere_name=None, source_context=None): """Create a Far Field Report object. Parameters @@ -360,10 +381,11 @@ def far_field(self, expressions=None, setup_name=None, sphere_name=None, source_ expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. sphere_name : str, optional Name of the sphere to create the far field on. source_context : str, optional @@ -377,25 +399,24 @@ def far_field(self, expressions=None, setup_name=None, sphere_name=None, source_ -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.far_field("GainTotal", "Setup : LastAdaptive", "3D_Sphere") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.far_field("GainTotal", "Setup : LastAdaptive", "3D_Sphere") >>> report.primary_sweep = "Phi" >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Far Fields" in self._templates: - rep = rt.FarField(self._post_app, "Far Fields", setup_name) + rep = rt.FarField(self._post_app, "Far Fields", setup) rep.far_field_sphere = sphere_name rep.source_context = source_context - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def antenna_parameters(self, expressions=None, setup_name=None, sphere_name=None): + @pyaedt_function_handler(setup_name="setup", sphere_name="infinite_sphere") + def antenna_parameters(self, expressions=None, setup=None, infinite_sphere=None): """Create an Antenna Parameters Report object. Parameters @@ -403,12 +424,13 @@ def antenna_parameters(self, expressions=None, setup_name=None, sphere_name=None expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. - sphere_name : str, optional - Name of the sphere on which compute antenna parameters. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + infinite_sphere : str, optional + Name of the sphere to compute antenna parameters on. Returns ------- @@ -418,22 +440,21 @@ def antenna_parameters(self, expressions=None, setup_name=None, sphere_name=None -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.antenna_parameters("GainTotal", "Setup : LastAdaptive", "3D_Sphere") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.antenna_parameters("GainTotal", "Setup : LastAdaptive", "3D_Sphere") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Antenna Parameters" in self._templates: - rep = rt.AntennaParameters(self._post_app, "Antenna Parameters", setup_name, sphere_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep = rt.AntennaParameters(self._post_app, "Antenna Parameters", setup, infinite_sphere) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def near_field(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def near_field(self, expressions=None, setup=None): """Create a Field Report object. Parameters @@ -441,10 +462,11 @@ def near_field(self, expressions=None, setup_name=None): expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -454,23 +476,22 @@ def near_field(self, expressions=None, setup_name=None): -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.near_field("GainTotal", "Setup : LastAdaptive", "NF_1") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.near_field("GainTotal", "Setup : LastAdaptive", "NF_1") >>> report.primary_sweep = "Phi" >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Near Fields" in self._templates: - rep = rt.NearField(self._post_app, "Near Fields", setup_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep = rt.NearField(self._post_app, "Near Fields", setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def modal_solution(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def modal_solution(self, expressions=None, setup=None): """Create a Standard or Default Report object. Parameters @@ -478,10 +499,11 @@ def modal_solution(self, expressions=None, setup_name=None): expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -491,22 +513,21 @@ def modal_solution(self, expressions=None, setup_name=None): -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.modal_solution("dB(S(1,1))") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.modal_solution("dB(S(1,1))") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Modal Solution Data" in self._templates: - rep = rt.Standard(self._post_app, "Modal Solution Data", setup_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep = rt.Standard(self._post_app, "Modal Solution Data", setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def terminal_solution(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def terminal_solution(self, expressions=None, setup=None): """Create a Standard or Default Report object. Parameters @@ -514,10 +535,11 @@ def terminal_solution(self, expressions=None, setup_name=None): expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -527,22 +549,21 @@ def terminal_solution(self, expressions=None, setup_name=None): -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.terminal_solution("dB(S(1,1))") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.terminal_solution("dB(S(1,1))") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Terminal Solution Data" in self._templates: - rep = rt.Standard(self._post_app, "Terminal Solution Data", setup_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep = rt.Standard(self._post_app, "Terminal Solution Data", setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def eigenmode(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def eigenmode(self, expressions=None, setup=None): """Create a Standard or Default Report object. Parameters @@ -550,10 +571,11 @@ def eigenmode(self, expressions=None, setup_name=None): expressions : str or list Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -563,22 +585,21 @@ def eigenmode(self, expressions=None, setup_name=None): -------- >>> from pyaedt import Hfss - >>> app = Hfss(my_project) - >>> report = app.post.reports_by_category.eigenmode("dB(S(1,1))") + >>> hfss = Hfss(my_project) + >>> report = hfss.post.reports_by_category.eigenmode("dB(S(1,1))") >>> report.create() >>> solutions = report.get_solution_data() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None if "Eigenmode Parameters" in self._templates: - rep = rt.Standard(self._post_app, "Eigenmode Parameters", setup_name) - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - - return rep - return + rep = rt.Standard(self._post_app, "Eigenmode Parameters", setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep - @pyaedt_function_handler() - def statistical_eye_contour(self, expressions=None, setup_name=None, quantity_type=3): + @pyaedt_function_handler(setup_name="setup") + def statistical_eye_contour(self, expressions=None, setup=None, quantity_type=3): """Create a standard statistical AMI contour plot. Parameters @@ -586,7 +607,7 @@ def statistical_eye_contour(self, expressions=None, setup_name=None, quantity_ty expressions : str Expression to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional + setup : str, optional Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` setup is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is either the sweep @@ -614,27 +635,27 @@ def statistical_eye_contour(self, expressions=None, setup_name=None, quantity_ty >>> new_eye.create() """ - if not setup_name: + if not setup: for setup in self._post_app._app.setups: if "AMIAnalysis" in setup.props: - setup_name = setup.name - if not setup_name: + setup = setup.name + if not setup: self._post_app._app.logger.error("AMI analysis is needed to create this report.") return False if isinstance(expressions, list): expressions = expressions[0] report_cat = "Standard" - rep = rt.AMIConturEyeDiagram(self._post_app, report_cat, setup_name) + rep = rt.AMIConturEyeDiagram(self._post_app, report_cat, setup) rep.quantity_type = quantity_type - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) return rep return - @pyaedt_function_handler() + @pyaedt_function_handler(setup_name="setup") def eye_diagram( - self, expressions=None, setup_name=None, quantity_type=3, statistical_analysis=True, unit_interval="1ns" + self, expressions=None, setup=None, quantity_type=3, statistical_analysis=True, unit_interval="1ns" ): """Create a Standard or Default Report object. @@ -643,10 +664,11 @@ def eye_diagram( expressions : str Expression to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. quantity_type : int, optional For AMI Analysis only, specify the quantity type. Options are: 0 for Initial Wave, 1 for Wave after Source, 2 for Wave after Channel and 3 for Wave after Probe. Default is 3. @@ -671,31 +693,31 @@ def eye_diagram( >>> new_eye.create() """ - if not setup_name: - setup_name = self._post_app._app.nominal_sweep + if not setup: + setup = self._post_app._app.nominal_sweep if "Eye Diagram" in self._templates: - if "AMIAnalysis" in self._post_app._app.get_setup(setup_name).props: + if "AMIAnalysis" in self._post_app._app.get_setup(setup).props: report_cat = "Eye Diagram" if statistical_analysis: report_cat = "Statistical Eye" - rep = rt.AMIEyeDiagram(self._post_app, report_cat, setup_name) + rep = rt.AMIEyeDiagram(self._post_app, report_cat, setup) rep.quantity_type = quantity_type - expressions = self._retrieve_default_expressions(expressions, rep, setup_name) + expressions = self._retrieve_default_expressions(expressions, rep, setup) if isinstance(expressions, list): rep.expressions = expressions[0] return rep else: - rep = rt.EyeDiagram(self._post_app, "Eye Diagram", setup_name) + rep = rt.EyeDiagram(self._post_app, "Eye Diagram", setup) rep.unit_interval = unit_interval - rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) return rep return - @pyaedt_function_handler() - def spectral(self, expressions=None, setup_name=None): + @pyaedt_function_handler(setup_name="setup") + def spectral(self, expressions=None, setup=None): """Create a Spectral Report object. Parameters @@ -703,10 +725,11 @@ def spectral(self, expressions=None, setup_name=None): expressions : str or list, optional Expression List to add into the report. The expression can be any of the available formula you can enter into the Electronics Desktop Report Editor. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. Returns ------- @@ -720,14 +743,62 @@ def spectral(self, expressions=None, setup_name=None): >>> new_eye = cir.post.reports_by_category.spectral("V(Vout)") >>> new_eye.create() + """ + if not setup: + setup = self._post_app._app.nominal_sweep + rep = None + if "Spectrum" in self._templates: + rep = rt.Spectral(self._post_app, "Spectrum", setup) + rep.expressions = self._retrieve_default_expressions(expressions, rep, setup) + return rep + + @pyaedt_function_handler() + def emi_receiver(self, expressions=None, setup_name=None): + """Create an EMI receiver report. + + Parameters + ---------- + expressions : str or list, optional + One or more expressions to add into the report. An expression can be any of the formulas that + can be entered into the Electronics Desktop Report Editor. + setup_name : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is either the sweep name + to use in the export or ``LastAdaptive``. + + Returns + ------- + :class:`pyaedt.modules.report_templates.EMIReceiver` + + Examples + -------- + + >>> from pyaedt import Circuit + >>> cir= Circuit() + >>> new_eye = cir.post.emi_receiver() + >>> new_eye.create() + """ if not setup_name: setup_name = self._post_app._app.nominal_sweep - if "Spectrum" in self._templates: - rep = rt.Spectral(self._post_app, "Spectrum", setup_name) + rep = None + if "EMIReceiver" in self._templates and self._post_app._app.desktop_class.aedt_version_id > "2023.2": + rep = rt.EMIReceiver(self._post_app, setup_name) + if not expressions: + expressions = "Average[{}]".format(rep.net) + else: + if not isinstance(expressions, list): + expressions = [expressions] + pattern = r"\w+\[(.*?)\]" + for expression in expressions: + match = re.search(pattern, expression) + if match: + net_name = match.group(1) + rep.net = net_name rep.expressions = self._retrieve_default_expressions(expressions, rep, setup_name) - return rep - return + + return rep orientation_to_view = { @@ -748,7 +819,7 @@ def _convert_dict_to_report_sel(sweeps): sweep_list = [] for el in sweeps: sweep_list.append(el + ":=") - if type(sweeps[el]) is list: + if isinstance(sweeps[el], list): sweep_list.append(sweeps[el]) else: sweep_list.append([sweeps[el]]) @@ -775,7 +846,7 @@ class PostProcessorCommon(object): -------- >>> from pyaedt import Q3d >>> q3d = Q3d() - >>> q3d = q.post.get_solution_data(expression="C(Bar1,Bar1)", domain="Original") + >>> q3d = q.post.get_solution_data(domain="Original") """ def __init__(self, app): @@ -819,7 +890,7 @@ def update_report_dynamically(self, value): self._app.odesktop.SetRegistryInt( "Desktop/Settings/ProjectOptions/{}/UpdateReportsDynamicallyOnEdits".format(self._app.design_type), 1 ) - else: + else: # pragma: no cover self._app.odesktop.SetRegistryInt( "Desktop/Settings/ProjectOptions/{}/UpdateReportsDynamicallyOnEdits".format(self._app.design_type), 0 ) @@ -846,7 +917,7 @@ def available_display_types(self, report_category=None): report_category = self.available_report_types[0] if report_category: return list(self.oreportsetup.GetAvailableDisplayTypes(report_category)) - return [] + return [] # pragma: no cover @pyaedt_function_handler() def available_quantities_categories( @@ -905,7 +976,7 @@ def available_quantities_categories( if solution and report_category and display_type: return list(self.oreportsetup.GetAllCategories(report_category, display_type, solution, context)) - return [] + return [] # pragma: no cover @pyaedt_function_handler() def available_report_quantities( @@ -981,7 +1052,7 @@ def available_report_quantities( report_category, display_type, solution, context, quantities_category ) ) - return [] + return [] # pragma: no cover @pyaedt_function_handler() def available_report_solutions(self, report_category=None): @@ -1006,7 +1077,7 @@ def available_report_solutions(self, report_category=None): report_category = self.available_report_types[0] if report_category: return list(self.oreportsetup.GetAvailableSolutions(report_category)) - return None + return None # pragma: no cover @pyaedt_function_handler() def _get_plot_inputs(self): @@ -1093,13 +1164,13 @@ def all_report_names(self): """ return list(self.oreportsetup.GetAllReportNames()) - @pyaedt_function_handler() - def copy_report_data(self, PlotName): + @pyaedt_function_handler(PlotName="plot_name") + def copy_report_data(self, plot_name): """Copy report data as static data. Parameters ---------- - PlotName : str + plot_name : str Name of the report. Returns @@ -1113,7 +1184,7 @@ def copy_report_data(self, PlotName): >>> oModule.CopyReportsData >>> oModule.PasteReports """ - self.oreportsetup.CopyReportsData([PlotName]) + self.oreportsetup.CopyReportsData([plot_name]) self.oreportsetup.PasteReports() return True @@ -1144,12 +1215,12 @@ def delete_report(self, plot_name=None): self.plots.remove(plot) else: self.oreportsetup.DeleteAllReports() - if is_ironpython: + if is_ironpython: # pragma: no cover del self.plots[:] else: self.plots.clear() return True - except Exception: + except Exception: # pragma: no cover return False @pyaedt_function_handler() @@ -1182,27 +1253,27 @@ def rename_report(self, plot_name, new_name): except Exception: return False - @pyaedt_function_handler() + @pyaedt_function_handler(soltype="solution_type", ctxt="context", expression="expressions") def get_solution_data_per_variation( - self, soltype="Far Fields", setup_sweep_name="", ctxt=None, sweeps=None, expression="" + self, solution_type="Far Fields", setup_sweep_name="", context=None, sweeps=None, expressions="" ): """Retrieve solution data for each variation. Parameters ---------- - soltype : str, optional + solution_type : str, optional Type of the solution. For example, ``"Far Fields"`` or ``"Modal Solution Data"``. The default is ``"Far Fields"``. setup_sweep_name : str, optional Name of the setup for computing the report. The default is ``""``, in which case ``"nominal adaptive"`` is used. - ctxt : list, optional + context : list, optional List of context variables. The default is ``None``. sweeps : dict, optional Dictionary of variables and values. The default is ``None``, in which case this list is used: ``{'Theta': 'All', 'Phi': 'All', 'Freq': 'All'}``. - expression : str or list, optional + expressions : str or list, optional One or more traces to include. The default is ``""``. Returns @@ -1217,16 +1288,18 @@ def get_solution_data_per_variation( """ if sweeps is None: sweeps = {"Theta": "All", "Phi": "All", "Freq": "All"} - if not ctxt: - ctxt = [] - if not isinstance(expression, list): - expression = [expression] + if not context: + context = [] + if not isinstance(expressions, list): + expressions = [expressions] if not setup_sweep_name: setup_sweep_name = self._app.nominal_adaptive sweep_list = _convert_dict_to_report_sel(sweeps) try: data = list( - self.oreportsetup.GetSolutionDataPerVariation(soltype, setup_sweep_name, ctxt, sweep_list, expression) + self.oreportsetup.GetSolutionDataPerVariation( + solution_type, setup_sweep_name, context, sweep_list, expressions + ) ) self.logger.info("Solution Data Correctly Loaded.") return SolutionData(data) @@ -1325,16 +1398,16 @@ def export_report_to_file( """ npath = output_dir - if "." not in extension: + if "." not in extension: # pragma: no cover extension = "." + extension supported_ext = [".csv", ".tab", ".txt", ".exy", ".dat", ".rdat"] - if extension not in supported_ext: + if extension not in supported_ext: # pragma: no cover msg = "Extension {} is not supported. Use one of {}".format(extension, ", ".join(supported_ext)) raise ValueError(msg) file_path = os.path.join(npath, plot_name + extension) - if unique_file: + if unique_file: # pragma: no cover while os.path.exists(file_path): file_name = generate_unique_name(plot_name) file_path = os.path.join(npath, file_name + extension) @@ -1402,13 +1475,13 @@ def export_report_to_csv( use_trace_number_format=use_trace_number_format, ) - @pyaedt_function_handler() - def export_report_to_jpg(self, project_dir, plot_name, width=0, height=0): + @pyaedt_function_handler(project_dir="project_path") + def export_report_to_jpg(self, project_path, plot_name, width=0, height=0): """Export the SParameter plot to a JPG file. Parameters ---------- - project_dir : str + project_path : str Path to the project directory. plot_name : str Name of the plot to export. @@ -1428,7 +1501,7 @@ def export_report_to_jpg(self, project_dir, plot_name, width=0, height=0): >>> oModule.ExportImageToFile """ # path - npath = project_dir + npath = project_path file_name = os.path.join(npath, plot_name + ".jpg") # name of the image file if self._app.desktop_class.non_graphical: # pragma: no cover if width == 0: @@ -1438,7 +1511,7 @@ def export_report_to_jpg(self, project_dir, plot_name, width=0, height=0): self.oreportsetup.ExportImageToFile(plot_name, file_name, width, height) return True - @pyaedt_function_handler() + @pyaedt_function_handler(plotname="plot_name") def _get_report_inputs( self, expressions, @@ -1452,7 +1525,7 @@ def _get_report_inputs( context=None, subdesign_id=None, polyline_points=0, - plotname=None, + plot_name=None, only_get_method=False, ): ctxt = [] @@ -1563,8 +1636,8 @@ def _get_report_inputs( modal_data = self._app.design_solutions.report_type else: modal_data = report_category - if not plotname: - plotname = generate_unique_name("Plot") + if not plot_name: + plot_name = generate_unique_name("Plot") arg = ["X Component:=", primary_sweep_variable, "Y Component:=", expressions] if plot_type in ["3D Polar Plot", "3D Spherical Plot"]: @@ -1595,9 +1668,9 @@ def _get_report_inputs( "Z Component:=", expressions, ] - return [plotname, modal_data, plot_type, setup_sweep_name, ctxt, families_input, arg] + return [plot_name, modal_data, plot_type, setup_sweep_name, ctxt, families_input, arg] - @pyaedt_function_handler() + @pyaedt_function_handler(plotname="plot_name") def create_report( self, expressions=None, @@ -1611,9 +1684,9 @@ def create_report( context=None, subdesign_id=None, polyline_points=1001, - plotname=None, + plot_name=None, ): - """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plots or data tables. + """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plot, or a data table. Parameters ---------- @@ -1639,13 +1712,15 @@ def create_report( plot_type : str, optional The format of Data Visualization. Default is ``Rectangular Plot``. context : str, optional - The default is ``None``. It can be `None`, `"Differential Pairs"`,`"RL"`, - `"Sources"`, `"Vias"`,`"Bondwires"`, `"Probes"` for Hfss3dLayout or - Reduce Matrix Name for Q2d/Q3d solution or Infinite Sphere name for Far Fields Plot. - plotname : str, optional + The default is ``None``. + - For HFSS 3D Layout, options are ``"Bondwires"``, ``"Differential Pairs"``, + ``None``, ``"Probes"``, ``"RL"``, ``"Sources"``, and ``"Vias"``. + - For Q2D or Q3D, specify the name of a reduced matrix. + - For a far fields plot, specify the name of an infinite sphere. + plot_name : str, optional Name of the plot. The default is ``None``. polyline_points : int, optional, - Number of points on which create the report for plots on polylines. + Number of points to create the report for plots on polylines on. subdesign_id : int, optional Specify a subdesign ID to export a Touchstone file of this subdesign. Valid for Circuit Only. The default value is ``None``. @@ -1665,36 +1740,29 @@ def create_report( Examples -------- >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> aedtapp.post.create_report("dB(S(1,1))") - - >>> variations = aedtapp.available_variations.nominal_w_values_dict + >>> hfss = Hfss() + >>> hfss.post.create_report("dB(S(1,1))") + >>> variations = hfss.available_variations.nominal_w_values_dict >>> variations["Theta"] = ["All"] >>> variations["Phi"] = ["All"] >>> variations["Freq"] = ["30GHz"] - >>> aedtapp.post.create_report( - ... "db(GainTotal)", - ... aedtapp.nominal_adaptive, - ... variations=variations, - ... primary_sweep_variable="Phi", - ... secondary_sweep_variable="Theta", - ... plot_type="3D Polar Plot", - ... context="3D", - ... report_category="Far Fields", - ...) + >>> hfss.post.create_report(expressions="db(GainTotal)", + ... setup_sweep_name=hfss.nominal_adaptive, + ... variations=variations, + ... primary_sweep_variable="Phi", + ... secondary_sweep_variable="Theta", + ... report_category="Far Fields", + ... plot_type="3D Polar Plot", + ... context="3D") - >>> aedtapp.post.create_report( - ... "S(1,1)", - ... aedtapp.nominal_sweep, - ... variations=variations, - ... plot_type="Smith Chart", - ...) + >>> hfss.post.create_report("S(1,1)",hfss.nominal_sweep,variations=variations,plot_type="Smith Chart") >>> from pyaedt import Maxwell2d - >>> maxwell_2d = Maxwell2d() - >>> maxwell_2d.post.create_report( - ... "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", plotname="Winding Plot 1" - ... ) + >>> m2d = Maxwell2d() + >>> m2d.post.create_report(expressions="InputCurrent(PHA)", + ... domain="Time", + ... primary_sweep_variable="Time", + ... plot_name="Winding Plot 1") """ if not setup_sweep_name: setup_sweep_name = self._app.nominal_sweep @@ -1787,7 +1855,7 @@ def create_report( if context in self.modeler.line_names or context in self.modeler.point_names: report.polyline = context - result = report.create(plotname) + result = report.create(plot_name) if result: return report return False @@ -1817,9 +1885,10 @@ def get_solution_data( One or more formulas to add to the report. Example is value ``"dB(S(1,1))"`` or a list of values. Default is `None` which will return all traces. setup_sweep_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. domain : str, optional Plot Domain. Options are "Sweep" for frequency domain related results and "Time" for transient related data. variations : dict, optional @@ -1872,16 +1941,15 @@ def get_solution_data( Examples -------- >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> aedtapp.post.create_report("dB(S(1,1))") - - >>> variations = aedtapp.available_variations.nominal_w_values_dict + >>> hfss = Hfss() + >>> hfss.post.create_report("dB(S(1,1))") + >>> variations = hfss.available_variations.nominal_w_values_dict >>> variations["Theta"] = ["All"] >>> variations["Phi"] = ["All"] >>> variations["Freq"] = ["30GHz"] - >>> data1 = aedtapp.post.get_solution_data( + >>> data1 = hfss.post.get_solution_data( ... "GainTotal", - ... aedtapp.nominal_adaptive, + ... hfss.nominal_adaptive, ... variations=variations, ... primary_sweep_variable="Phi", ... secondary_sweep_variable="Theta", @@ -1889,16 +1957,16 @@ def get_solution_data( ... report_category="Far Fields", ...) - >>> data2 =aedtapp.post.get_solution_data( + >>> data2 =hfss.post.get_solution_data( ... "S(1,1)", - ... aedtapp.nominal_sweep, + ... hfss.nominal_sweep, ... variations=variations, ...) >>> data2.plot() >>> from pyaedt import Maxwell2d - >>> maxwell_2d = Maxwell2d() - >>> data3 = maxwell_2d.post.get_solution_data( + >>> m2d = Maxwell2d() + >>> data3 = m2d.post.get_solution_data( ... "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", ... ) >>> data3.plot("InputCurrent(PHA)") @@ -1906,10 +1974,8 @@ def get_solution_data( >>> from pyaedt import Circuit >>> circuit = Circuit() >>> context = {"algorithm": "FFT", "max_frequency": "100MHz", "time_stop": "2.5us", "time_start": "0ps"} - >>> spectralPlotData = circuit.post.get_solution_data( - ... expressions="V(Vprobe1)", primary_sweep_variable="Spectrum", domain="Spectral", - ... context=context - ...) + >>> spectralPlotData = circuit.post.get_solution_data(expressions="V(Vprobe1)", domain="Spectral", + ... primary_sweep_variable="Spectrum", context=context) """ expressions = [expressions] if isinstance(expressions, str) else expressions if not setup_sweep_name: @@ -2003,17 +2069,18 @@ def get_solution_data( solution_data = report.get_solution_data() return solution_data - @pyaedt_function_handler() - def create_report_from_configuration(self, input_file=None, input_dict=None, solution_name=None): + @pyaedt_function_handler(input_dict="report_settings") + def create_report_from_configuration(self, input_file=None, report_settings=None, solution_name=None): """Create a report based on a JSON file, TOML file, or dictionary of properties. Parameters ---------- input_file : str, optional Path to the JSON or TOML file containing report settings. - input_dict : dict, optional + report_settings : dict, optional Dictionary containing report settings. - solution_name : setup name to use. + solution_name : str, optional + Setup name to use. Returns ------- @@ -2024,17 +2091,17 @@ def create_report_from_configuration(self, input_file=None, input_dict=None, sol -------- >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> aedtapp.post.create_report_from_configuration(r'C:\\temp\\my_report.json', - ... solution_name="Setup1 : LastAdpative") + >>> hfss = Hfss() + >>> hfss.post.create_report_from_configuration(r'C:\\temp\\my_report.json', + >>> solution_name="Setup1 : LastAdpative") """ - if not input_dict and not input_file: # pragma: no cover + if not report_settings and not input_file: # pragma: no cover self.logger.error("Either a JSON file or a dictionary must be passed as input.") return False if input_file: props = read_configuration_file(input_file) else: - props = input_dict + props = report_settings _dict_items_to_list_items(props, "expressions") if not solution_name: solution_name = self._app.nominal_sweep @@ -2088,8 +2155,8 @@ class PostProcessor(PostProcessorCommon, object): Basic usage demonstrated with an HFSS, Maxwell, or any other design: >>> from pyaedt import Hfss - >>> aedtapp = Hfss() - >>> post = aedtapp.post + >>> hfss = Hfss() + >>> post = hfss.post """ def __init__(self, app): @@ -2157,7 +2224,7 @@ def _get_base_name(self, setup): else: sim_data = self._app.design_properties["SolutionManager"] if "SimSetup" in sim_data: - if isinstance(sim_data["SimSetup"], list): + if isinstance(sim_data["SimSetup"], list): # pragma: no cover for solution in sim_data["SimSetup"]: base_name = solution["Name"] if isinstance(solution["Solution"], (dict, OrderedDict)): @@ -2180,7 +2247,7 @@ def _get_base_name(self, setup): if sol["ID"] == setups_data[setup]["SolutionId"]: base_name += " : " + sol["Name"] return base_name - return "" + return "" # pragma: no cover @pyaedt_function_handler() def _get_intrinsic(self, setup): @@ -2191,23 +2258,23 @@ def _get_intrinsic(self, setup): for intr in intrinsics: if isinstance(intr, list) and len(intr) == 2: intr_dict[intr[0]] = intr[1].replace("\\", "").replace("'", "") - return intr_dict + return intr_dict # pragma: no cover - @pyaedt_function_handler() - def _get_volume_objects(self, list_objs): + @pyaedt_function_handler(list_objs="assignment") + def _get_volume_objects(self, assignment): if self._app.solution_type not in ["HFSS3DLayout", "HFSS 3D Layout Design"]: obj_list = [] editor = self._app._odesign.SetActiveEditor("3D Modeler") - for obj in list_objs: + for obj in assignment: obj_list.append(editor.GetObjectNameByID(int(obj))) if obj_list: return obj_list else: - return list_objs + return assignment - @pyaedt_function_handler() - def _get_surface_objects(self, list_objs): - faces = [int(i) for i in list_objs] + @pyaedt_function_handler(list_objs="assignment") + def _get_surface_objects(self, assignment): + faces = [int(i) for i in assignment] if self._app.solution_type not in ["HFSS3DLayout", "HFSS 3D Layout Design"]: planes = self._get_cs_plane_ids() objs = [] @@ -2221,7 +2288,7 @@ def _get_surface_objects(self, list_objs): @pyaedt_function_handler() def _get_cs_plane_ids(self): name2refid = {-4: "Global:XY", -3: "Global:YZ", -2: "Global:XZ"} - if self._app.design_properties and "ModelSetup" in self._app.design_properties: + if self._app.design_properties and "ModelSetup" in self._app.design_properties: # pragma: no cover cs = self._app.design_properties["ModelSetup"]["GeometryCore"]["GeometryOperations"]["CoordinateSystems"] for ds in cs: try: @@ -2231,7 +2298,7 @@ def _get_cs_plane_ids(self): name2refid[cs_id] = name + ":XY" name2refid[cs_id + 1] = name + ":YZ" name2refid[cs_id + 2] = name + ":XZ" - elif type(cs[ds]) is list: + elif isinstance(cs[ds], list): for el in cs[ds]: cs_id = el["XYPlaneID"] name = el["Attributes"]["Name"] @@ -2256,30 +2323,28 @@ def _get_fields_plot(self): if isinstance(setups_data[setup], (OrderedDict, dict)) and "PlotDefinition" in setup: plot_name = setups_data[setup]["PlotName"] plots[plot_name] = FieldPlot(self) - plots[plot_name].solutionName = self._get_base_name(setup) - plots[plot_name].quantityName = self.ofieldsreporter.GetFieldPlotQuantityName( + plots[plot_name].solution = self._get_base_name(setup) + plots[plot_name].quantity = self.ofieldsreporter.GetFieldPlotQuantityName( setups_data[setup]["PlotName"] ) - plots[plot_name].intrinsincList = self._get_intrinsic(setup) + plots[plot_name].intrinsics = self._get_intrinsic(setup) list_objs = setups_data[setup]["FieldPlotGeometry"][1:] while list_objs: id = list_objs[0] num_objects = list_objs[2] if id == 64: - plots[plot_name].volume_indexes = self._get_volume_objects( - list_objs[3 : num_objects + 3] - ) + plots[plot_name].volumes = self._get_volume_objects(list_objs[3 : num_objects + 3]) elif id == 128: out, faces = self._get_surface_objects(list_objs[3 : num_objects + 3]) if out == "CutPlane": - plots[plot_name].cutplane_indexes = faces + plots[plot_name].cutplanes = faces else: - plots[plot_name].surfaces_indexes = faces + plots[plot_name].surfaces = faces elif id == 256: - plots[plot_name].line_indexes = self._get_volume_objects(list_objs[3 : num_objects + 3]) + plots[plot_name].lines = self._get_volume_objects(list_objs[3 : num_objects + 3]) list_objs = list_objs[num_objects + 3 :] plots[plot_name].name = setups_data[setup]["PlotName"] - plots[plot_name].plotFolder = setups_data[setup]["PlotFolder"] + plots[plot_name].plot_folder = setups_data[setup]["PlotFolder"] surf_setts = setups_data[setup]["PlotOnSurfaceSettings"] plots[plot_name].Filled = surf_setts["Filled"] plots[plot_name].IsoVal = surf_setts["IsoValType"] @@ -2299,13 +2364,13 @@ def _get_fields_plot(self): return plots # TODO: define a fields calculator module and make robust !! - @pyaedt_function_handler() - def volumetric_loss(self, object_name): + @pyaedt_function_handler(object_name="assignment") + def volumetric_loss(self, assignment): """Use the field calculator to create a variable for volumetric losses. Parameters ---------- - object_name : str + assignment : str Name of the object to compute volumetric losses on. Returns @@ -2323,23 +2388,23 @@ def volumetric_loss(self, object_name): """ oModule = self.ofieldsreporter oModule.EnterQty("OhmicLoss") - oModule.EnterVol(object_name) + oModule.EnterVol(assignment) oModule.CalcOp("Integrate") - name = "P_{}".format(object_name) # Need to check for uniqueness ! + name = "P_{}".format(assignment) # Need to check for uniqueness ! oModule.AddNamedExpression(name, "Fields") return name - @pyaedt_function_handler() - def change_field_property(self, plotname, propertyname, propertyval): + @pyaedt_function_handler(plotname="plot_name", propertyname="property_name", propertyval="property_value") + def change_field_property(self, plot_name, property_name, property_value): """Modify a field plot property. Parameters ---------- - plotname : str + plot_name : str Name of the field plot. - propertyname : str + property_name : str Name of the property. - propertyval : + property_value : Value for the property. Returns @@ -2357,20 +2422,20 @@ def change_field_property(self, plotname, propertyname, propertyval): "NAME:AllTabs", [ "NAME:FieldsPostProcessorTab", - ["NAME:PropServers", "FieldsReporter:" + plotname], - ["NAME:ChangedProps", ["NAME:" + propertyname, "Value:=", propertyval]], + ["NAME:PropServers", "FieldsReporter:" + plot_name], + ["NAME:ChangedProps", ["NAME:" + property_name, "Value:=", property_value]], ], ] ) - @pyaedt_function_handler() + @pyaedt_function_handler(quantity_name="quantity", variation_dict="variations", isvector="is_vector") def get_scalar_field_value( self, - quantity_name, + quantity, scalar_function="Maximum", solution=None, - variation_dict=None, - isvector=False, + variations=None, + is_vector=False, intrinsics=None, phase=None, object_name="AllObjects", @@ -2381,22 +2446,22 @@ def get_scalar_field_value( Parameters ---------- - quantity_name : str + quantity : str Name of the quantity to export. For example, ``"Temp"``. scalar_function : str, optional The name of the scalar function. For example, ``"Maximum"``, ``"Integrate"``. The default is ``"Maximum"``. solution : str, optional Name of the solution in the format ``"solution : sweep"``. The default is ``None``. - variation_dict : dict, optional + variations : dict, optional Dictionary of all variation variables with their values. e.g. ``['power_block:=', ['0.6W'], 'power_source:=', ['0.15W']]`` The default is ``None``. - isvector : bool, optional + is_vector : bool, optional Whether the quantity is a vector. The default is ``False``. intrinsics : str, optional - This parameter is mandatory for a frequency field - calculation. The default is ``None``. + This parameter is mandatory for a frequency field calculation. + The default is ``None``. phase : str, optional Field phase. The default is ``None``. object_name : str, optional @@ -2425,25 +2490,25 @@ def get_scalar_field_value( >>> oModule.ClcEval >>> GetTopEntryValue """ - self.logger.info("Exporting {} field. Be patient".format(quantity_name)) + self.logger.info("Exporting {} field. Be patient".format(quantity)) if not solution: solution = self._app.existing_analysis_sweeps[0] self.ofieldsreporter.CalcStack("clear") - if isvector: + if is_vector: try: - self.ofieldsreporter.EnterQty(quantity_name) + self.ofieldsreporter.EnterQty(quantity) except Exception: - self.ofieldsreporter.CopyNamedExprToStack(quantity_name) + self.ofieldsreporter.CopyNamedExprToStack(quantity) self.ofieldsreporter.CalcOp("Smooth") self.ofieldsreporter.EnterScalar(0) self.ofieldsreporter.CalcOp("AtPhase") self.ofieldsreporter.CalcOp("Mag") else: try: - self.ofieldsreporter.EnterQty(quantity_name) + self.ofieldsreporter.EnterQty(quantity) except Exception: - self.logger.info("Quantity {} not present. Trying to get it from Stack".format(quantity_name)) - self.ofieldsreporter.CopyNamedExprToStack(quantity_name) + self.logger.info("Quantity {} not present. Trying to get it from Stack".format(quantity)) + self.ofieldsreporter.CopyNamedExprToStack(quantity) obj_list = object_name if scalar_function: if object_type == "volume": @@ -2457,23 +2522,23 @@ def get_scalar_field_value( self.ofieldsreporter.EnterPoint(obj_list) self.ofieldsreporter.CalcOp(scalar_function) - if not variation_dict: - variation_dict = self._app.available_variations.nominal_w_values_dict + if not variations: + variations = self._app.available_variations.nominal_w_values_dict variation = [] - for el, value in variation_dict.items(): + for el, value in variations.items(): variation.append(el + ":=") variation.append(value) if intrinsics: - if "Transient" in solution: + if "Transient" in solution: # pragma: no cover variation.append("Time:=") variation.append(intrinsics) else: variation.append("Freq:=") variation.append(intrinsics) variation.append("Phase:=") - if phase: + if phase: # pragma: no cover variation.append(phase) else: variation.append("0deg") @@ -2490,19 +2555,25 @@ def get_scalar_field_value( self.ofieldsreporter.CalcStack("clear") return float(value) - @pyaedt_function_handler() + @pyaedt_function_handler( + quantity_name="quantity", + variation_dict="variations", + filename="file_name", + gridtype="grid_type", + isvector="is_vector", + ) def export_field_file_on_grid( self, - quantity_name, + quantity, solution=None, - variation_dict=None, - filename=None, - gridtype="Cartesian", + variations=None, + file_name=None, + grid_type="Cartesian", grid_center=None, grid_start=None, grid_stop=None, grid_step=None, - isvector=False, + is_vector=False, intrinsics=None, phase=None, export_with_sample_points=True, @@ -2514,17 +2585,18 @@ def export_field_file_on_grid( Parameters ---------- - quantity_name : str + quantity : str Name of the quantity to export. For example, ``"Temp"``. solution : str, optional Name of the solution in the format ``"solution : sweep"``. The default is ``None``. - variation_dict : dict, optional + variations : dict, optional Dictionary of all variation variables with their values. The default is ``None``. - filename : str, optional + file_name : str, optional Full path and name to save the file to. - The default is ``None`` which export file in working_directory. - gridtype : str, optional + The default is ``None``, in which case the file is exported + to the working directory. + grid_type : str, optional Type of the grid to export. The default is ``"Cartesian"``. grid_center : list, optional The ``[x, y, z]`` coordinates for the center of the grid. @@ -2539,11 +2611,11 @@ def export_field_file_on_grid( grid_step : list, optional The ``[x, y, z]`` coordinates for the step size of the grid. The default is ``[0, 0, 0]``. - isvector : bool, optional + is_vector : bool, optional Whether the quantity is a vector. The default is ``False``. intrinsics : str, optional - This parameter is mandatory for a frequency field - calculation. The default is ``None``. + This parameter is mandatory for a frequency field calculation. + The default is ``None``. phase : str, optional Field phase. The default is ``None``. export_with_sample_points : bool, optional @@ -2581,7 +2653,7 @@ def export_field_file_on_grid( >>> var = hfss.available_variations.nominal_w_values >>> setup = "Setup1 : LastAdaptive" >>> path = "Field.fld" - >>> hfss.post.export_field_file_on_grid("E", setup, var, path, 'Cartesian', [0, 0, 0], intrinsics="8GHz") + >>> hfss.post.export_field_file_on_grid("E",setup,var,path,'Cartesian',[0, 0, 0],intrinsics="8GHz") """ if grid_step is None: grid_step = [0, 0, 0] @@ -2591,21 +2663,21 @@ def export_field_file_on_grid( grid_stop = [0, 0, 0] if grid_center is None: grid_center = [0, 0, 0] - self.logger.info("Exporting %s field. Be patient", quantity_name) + self.logger.info("Exporting %s field. Be patient", quantity) if not solution: solution = self._app.existing_analysis_sweeps[0] - if not filename: - filename = os.path.join( - self._app.working_directory, "{}_{}.fld".format(quantity_name, solution.replace(" : ", "_")) + if not file_name: + file_name = os.path.join( + self._app.working_directory, "{}_{}.fld".format(quantity, solution.replace(" : ", "_")) ) - elif os.path.isdir(filename): - filename = os.path.join(filename, "{}_{}.fld".format(quantity_name, solution.replace(" : ", "_"))) + elif os.path.isdir(file_name): + file_name = os.path.join(file_name, "{}_{}.fld".format(quantity, solution.replace(" : ", "_"))) self.ofieldsreporter.CalcStack("clear") try: - self.ofieldsreporter.EnterQty(quantity_name) + self.ofieldsreporter.EnterQty(quantity) except Exception: - self.ofieldsreporter.CopyNamedExprToStack(quantity_name) - if isvector: + self.ofieldsreporter.CopyNamedExprToStack(quantity) + if is_vector: self.ofieldsreporter.CalcOp("Smooth") if phase: self.ofieldsreporter.EnterScalar(0) @@ -2613,17 +2685,17 @@ def export_field_file_on_grid( self.ofieldsreporter.CalcOp("Mag") units = self.modeler.model_units ang_units = "deg" - if gridtype == "Cartesian": + if grid_type == "Cartesian": grid_center = ["0mm", "0mm", "0mm"] grid_start_wu = [str(i) + units for i in grid_start] grid_stop_wu = [str(i) + units for i in grid_stop] grid_step_wu = [str(i) + units for i in grid_step] - elif gridtype == "Cylindrical": + elif grid_type == "Cylindrical": grid_center = [str(i) + units for i in grid_center] grid_start_wu = [str(grid_start[0]) + units, str(grid_start[1]) + ang_units, str(grid_start[2]) + units] grid_stop_wu = [str(grid_stop[0]) + units, str(grid_stop[1]) + ang_units, str(grid_stop[2]) + units] grid_step_wu = [str(grid_step[0]) + units, str(grid_step[1]) + ang_units, str(grid_step[2]) + units] - elif gridtype == "Spherical": + elif grid_type == "Spherical": grid_center = [str(i) + units for i in grid_center] grid_start_wu = [str(grid_start[0]) + units, str(grid_start[1]) + ang_units, str(grid_start[2]) + ang_units] grid_stop_wu = [str(grid_stop[0]) + units, str(grid_stop[1]) + ang_units, str(grid_stop[2]) + ang_units] @@ -2632,11 +2704,11 @@ def export_field_file_on_grid( self.logger.error("Error in the type of the grid.") return False - if not variation_dict: - variation_dict = self._app.available_variations.nominal_w_values_dict + if not variations: + variations = self._app.available_variations.nominal_w_values_dict variation = [] - for el, value in variation_dict.items(): + for el, value in variations.items(): variation.append(el + ":=") variation.append(value) @@ -2666,34 +2738,41 @@ def export_field_file_on_grid( ] self.ofieldsreporter.ExportOnGrid( - filename, + file_name, grid_start_wu, grid_stop_wu, grid_step_wu, solution, variation, export_options, - gridtype, + grid_type, grid_center, False, ) - if os.path.exists(filename): - return filename + if os.path.exists(file_name): + return file_name return False # pragma: no cover - @pyaedt_function_handler() + @pyaedt_function_handler( + quantity_name="quantity", + variation_dict="variations", + filename="output_dir", + obj_list="assignment", + obj_type="objects_type", + sample_points_lists="sample_points", + ) def export_field_file( self, - quantity_name, + quantity, solution=None, - variation_dict=None, - filename=None, - obj_list="AllObjects", - obj_type="Vol", + variations=None, + output_dir=None, + assignment="AllObjects", + objects_type="Vol", intrinsics=None, phase=None, sample_points_file=None, - sample_points_lists=None, + sample_points=None, export_with_sample_points=True, reference_coordinate_system="Global", export_in_si_system=True, @@ -2703,30 +2782,31 @@ def export_field_file( Parameters ---------- - quantity_name : + quantity : Name of the quantity to export. For example, ``"Temp"``. solution : str, optional Name of the solution in the format ``"solution: sweep"``. The default is ``None``. - variation_dict : dict, optional + variations : dict, optional Dictionary of all variation variables with their values. The default is ``None``. - filename : str, optional + output_dir : str, optional Full path and name to save the file to. The default is ``None`` which export file in working_directory. - obj_list : str, optional + assignment : str, optional List of objects to export. The default is ``"AllObjects"``. - obj_type : str, optional - Type of objects to export. Options are ``"Vol"`` for volume and - ``"Surf"`` for surface. The default is ``"Vol"``. + objects_type : str, optional + Type of objects to export. The default is ``"Vol"``. + Options are ``"Surf"`` for surface and ``"Vol"`` for + volume. intrinsics : str, optional - This parameter is mandatory for a frequency or transient field - calculation. The default is ``None``. + This parameter is mandatory for a frequency or transient field calculation. + The default is ``None``. phase : str, optional Field phase. The default is ``None``. sample_points_file : str, optional Name of the file with sample points. The default is ``None``. - sample_points_lists : list, optional + sample_points : list, optional List of the sample points. The default is ``None``. export_with_sample_points : bool, optional Whether to include the sample points in the file to export. @@ -2757,29 +2837,29 @@ def export_field_file( >>> oModule.CalculatorWrite >>> oModule.ExportToFile """ - self.logger.info("Exporting %s field. Be patient", quantity_name) + self.logger.info("Exporting %s field. Be patient", quantity) if not solution: if not self._app.existing_analysis_sweeps: self.logger.error("There are no existing sweeps.") return False solution = self._app.existing_analysis_sweeps[0] - if not filename: + if not output_dir: appendix = "" ext = ".fld" - filename = os.path.join(self._app.working_directory, solution.replace(" : ", "_") + appendix + ext) + output_dir = os.path.join(self._app.working_directory, solution.replace(" : ", "_") + appendix + ext) else: - filename = filename.replace("//", "/").replace("\\", "/") + output_dir = output_dir.replace("//", "/").replace("\\", "/") self.ofieldsreporter.CalcStack("clear") try: - self.ofieldsreporter.EnterQty(quantity_name) + self.ofieldsreporter.EnterQty(quantity) except Exception: - self.ofieldsreporter.CopyNamedExprToStack(quantity_name) + self.ofieldsreporter.CopyNamedExprToStack(quantity) - if not variation_dict: - variation_dict = self._app.available_variations.nominal_w_values_dict + if not variations: + variations = self._app.available_variations.nominal_w_values_dict variation = [] - for el, value in variation_dict.items(): + for el, value in variations.items(): variation.append(el + ":=") variation.append(value) @@ -2795,16 +2875,16 @@ def export_field_file( variation.append(phase) else: variation.append("0deg") - if not sample_points_file and not sample_points_lists: - if obj_type == "Vol": - self.ofieldsreporter.EnterVol(obj_list) - elif obj_type == "Surf": - self.ofieldsreporter.EnterSurf(obj_list) + if not sample_points_file and not sample_points: + if objects_type == "Vol": + self.ofieldsreporter.EnterVol(assignment) + elif objects_type == "Surf": + self.ofieldsreporter.EnterSurf(assignment) else: self.logger.error("No correct choice.") return False self.ofieldsreporter.CalcOp("Value") - self.ofieldsreporter.CalculatorWrite(filename, ["Solution:=", solution], variation) + self.ofieldsreporter.CalculatorWrite(output_dir, ["Solution:=", solution], variation) elif sample_points_file: export_options = [ "NAME:ExportOption", @@ -2818,7 +2898,7 @@ def export_field_file( export_field_in_reference, ] self.ofieldsreporter.ExportToFile( - filename, + output_dir, sample_points_file, solution, variation, @@ -2828,7 +2908,7 @@ def export_field_file( sample_points_file = os.path.join(self._app.working_directory, "temp_points.pts") with open_file(sample_points_file, "w") as f: f.write("Unit={}\n".format(self.model_units)) - for point in sample_points_lists: + for point in sample_points: f.write(" ".join([str(i) for i in point]) + "\n") export_options = [ "NAME:ExportOption", @@ -2842,32 +2922,29 @@ def export_field_file( export_field_in_reference, ] self.ofieldsreporter.ExportToFile( - filename, + output_dir, sample_points_file, solution, variation, export_options, ) - if os.path.exists(filename): - return filename + if os.path.exists(output_dir): + return output_dir return False # pragma: no cover - @pyaedt_function_handler() - def export_field_plot(self, plotname, filepath, filename="", file_format="aedtplt"): + @pyaedt_function_handler(plotname="plot_name", filepath="output_dir", filename="file_name") + def export_field_plot(self, plot_name, output_dir, file_name="", file_format="aedtplt"): """Export a field plot. Parameters ---------- - plotname : str + plot_name : str Name of the plot. - - filepath : str + output_dir : str Path for saving the file. - - filename : str, optional - Name of the file. The default is ``""``. - + file_name : str, optional + Name of the file. The default is ``""``, in which case a name is automatically assigned. file_format : str, optional Name of the file extension. The default is ``"aedtplt"``. Options are ``"case"`` and ``"fldplt"``. @@ -2880,15 +2957,15 @@ def export_field_plot(self, plotname, filepath, filename="", file_format="aedtpl ---------- >>> oModule.ExportFieldPlot """ - if not filename: - filename = plotname - filepath = os.path.join(filepath, filename + "." + file_format) + if not file_name: + file_name = plot_name + output_dir = os.path.join(output_dir, file_name + "." + file_format) try: - self.ofieldsreporter.ExportFieldPlot(plotname, False, filepath) + self.ofieldsreporter.ExportFieldPlot(plot_name, False, output_dir) if settings.remote_rpc_session_temp_folder: # pragma: no cover - local_path = os.path.join(settings.remote_rpc_session_temp_folder, filename + "." + file_format) - filepath = check_and_download_file(local_path, filepath) - return filepath + local_path = os.path.join(settings.remote_rpc_session_temp_folder, file_name + "." + file_format) + output_dir = check_and_download_file(local_path, output_dir) + return output_dir except Exception: # pragma: no cover self.logger.error("{} file format is not supported for this plot.".format(file_format)) return False @@ -2952,17 +3029,25 @@ def change_field_plot_scale(self, plot_name, minimum_value, maximum_value, is_lo self.ofieldsreporter.SetPlotFolderSettings(plot_name, args) return True - @pyaedt_function_handler() + @pyaedt_function_handler(objlist="assignment", quantityName="quantity", listtype="list_type", setup_name="setup") def _create_fieldplot( - self, objlist, quantityName, setup_name, intrinsics, listtype, plot_name=None, filter_boxes=[], field_type=None + self, + assignment, + quantity, + setup, + intrinsics, + list_type, + plot_name=None, + filter_boxes=None, + field_type=None, ): - if not listtype.startswith("Layer") and self._app.design_type != "HFSS 3D Layout Design": - objlist = self._app.modeler.convert_to_selections(objlist, True) - if not setup_name: - setup_name = self._app.existing_analysis_sweeps[0] + if not list_type.startswith("Layer") and self._app.design_type != "HFSS 3D Layout Design": + assignment = self._app.modeler.convert_to_selections(assignment, True) + if not setup: + setup = self._app.existing_analysis_sweeps[0] if not intrinsics: for i in self._app.setups: - if i.name == setup_name.split(" : ")[0]: + if i.name == setup.split(" : ")[0]: intrinsics = i.default_intrinsics self._desktop.CloseAllWindows() try: @@ -2974,79 +3059,56 @@ def _create_fieldplot( char_set = string.ascii_uppercase + string.digits if not plot_name: - plot_name = quantityName + "_" + "".join(random.sample(char_set, 6)) - if listtype == "CutPlane": - plot = FieldPlot( - self, - cutplanelist=objlist, - solutionName=setup_name, - quantityName=quantityName, - intrinsincList=intrinsics, - ) - elif listtype == "FacesList": + plot_name = quantity + "_" + "".join(random.sample(char_set, 6)) + filter_boxes = [] if filter_boxes is None else filter_boxes + if list_type == "CutPlane": + plot = FieldPlot(self, cutplanes=assignment, solution=setup, quantity=quantity, intrinsics=intrinsics) + elif list_type == "FacesList": + plot = FieldPlot(self, surfaces=assignment, solution=setup, quantity=quantity, intrinsics=intrinsics) + elif list_type == "ObjList": + plot = FieldPlot(self, objects=assignment, solution=setup, quantity=quantity, intrinsics=intrinsics) + elif list_type == "Line": + plot = FieldPlot(self, lines=assignment, solution=setup, quantity=quantity, intrinsics=intrinsics) + elif list_type.startswith("Layer"): plot = FieldPlot( self, - surfacelist=objlist, - solutionName=setup_name, - quantityName=quantityName, - intrinsincList=intrinsics, - ) - elif listtype == "ObjList": - plot = FieldPlot( - self, - objlist=objlist, - solutionName=setup_name, - quantityName=quantityName, - intrinsincList=intrinsics, - ) - elif listtype == "Line": - plot = FieldPlot( - self, - linelist=objlist, - solutionName=setup_name, - quantityName=quantityName, - intrinsincList=intrinsics, - ) - elif listtype.startswith("Layer"): - plot = FieldPlot( - self, - layers_nets=objlist, - solutionName=setup_name, - quantityName=quantityName, - intrinsincList=intrinsics, - layers_plot_type=listtype, + solution=setup, + quantity=quantity, + intrinsics=intrinsics, + layer_nets=assignment, + layer_plot_type=list_type, ) if self._app.design_type == "Q3D Extractor": # pragma: no cover plot.field_type = field_type plot.name = plot_name - plot.plotFolder = plot_name + plot.plot_folder = plot_name plot.filter_boxes = filter_boxes plt = plot.create() if "Maxwell" in self._app.design_type and "Transient" in self.post_solution_type: - self.ofieldsreporter.SetPlotsViewSolutionContext([plot_name], setup_name, "Time:" + intrinsics["Time"]) + self.ofieldsreporter.SetPlotsViewSolutionContext([plot_name], setup, "Time:" + intrinsics["Time"]) if plt: self.field_plots[plot_name] = plot return plot else: return False - @pyaedt_function_handler() + @pyaedt_function_handler(quantityName="quantity", setup_name="setup") def _create_fieldplot_line_traces( self, seeding_faces_ids, in_volume_tracing_ids, surface_tracing_ids, - quantityName, - setup_name, + quantity, + setup, intrinsics, plot_name=None, field_type="", ): - if not setup_name: - setup_name = self._app.existing_analysis_sweeps[0] + if not setup: + setup = self._app.existing_analysis_sweeps[0] if not intrinsics: for i in self._app.setups: - if i.name == setup_name.split(" : ")[0]: + if i.name == setup.split(" : ")[0]: intrinsics = i.default_intrinsics self._desktop.CloseAllWindows() try: @@ -3058,51 +3120,52 @@ def _create_fieldplot_line_traces( char_set = string.ascii_uppercase + string.digits if not plot_name: - plot_name = quantityName + "_" + "".join(random.sample(char_set, 6)) + plot_name = quantity + "_" + "".join(random.sample(char_set, 6)) plot = FieldPlot( self, - objlist=in_volume_tracing_ids, - surfacelist=surface_tracing_ids, - solutionName=setup_name, - quantityName=quantityName, - intrinsincList=intrinsics, - seedingFaces=seeding_faces_ids, + objects=in_volume_tracing_ids, + surfaces=surface_tracing_ids, + solution=setup, + quantity=quantity, + intrinsics=intrinsics, + seeding_faces=seeding_faces_ids, ) if field_type: plot.field_type = field_type plot.name = plot_name - plot.plotFolder = plot_name + plot.plot_folder = plot_name plt = plot.create() if "Maxwell" in self._app.design_type and self.post_solution_type == "Transient": - self.ofieldsreporter.SetPlotsViewSolutionContext([plot_name], setup_name, "Time:" + intrinsics["Time"]) + self.ofieldsreporter.SetPlotsViewSolutionContext([plot_name], setup, "Time:" + intrinsics["Time"]) if plt: self.field_plots[plot_name] = plot return plot else: return False - @pyaedt_function_handler() + @pyaedt_function_handler(objlist="assignment", quantityName="quantity", setup_name="setup") def create_fieldplot_line( - self, objlist, quantityName, setup_name=None, intrinsincDict=None, plot_name=None, field_type="DC R/L Fields" + self, assignment, quantity, setup=None, intrinsics=None, plot_name=None, field_type="DC R/L Fields" ): """Create a field plot of the line. Parameters ---------- - objlist : list - List of polyline to plot. - quantityName : str + assignment : list + List of polylines to plot. + quantity : str Name of the quantity to plot. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. - intrinsincDict : dict, optional - Dictionary containing all intrinsic variables. The default - is ``{}``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + intrinsics : dict, optional + Dictionary containing all intrinsic variables. + The default is ``None``. plot_name : str, optional - Name of the fieldplot to create. + Name of the field plot to create. field_type : str, optional Field type to plot. Valid only for Q3D Field plots. @@ -3116,23 +3179,21 @@ def create_fieldplot_line( >>> oModule.CreateFieldPlot """ - if intrinsincDict is None: - intrinsincDict = {} + if intrinsics is None: + intrinsics = {} if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] - return self._create_fieldplot( - objlist, quantityName, setup_name, intrinsincDict, "Line", plot_name, field_type=field_type - ) + return self._create_fieldplot(assignment, quantity, setup, intrinsics, "Line", plot_name, field_type=field_type) - @pyaedt_function_handler() + @pyaedt_function_handler(IntrinsincDict="intrinsics", setup_name="setup") def create_fieldplot_line_traces( self, seeding_faces, in_volume_tracing_objs=None, surface_tracing_objs=None, - setup_name=None, - intrinsinc_dict=None, + setup=None, + intrinsics=None, plot_name=None, field_type="DC R/L Fields", ): @@ -3147,12 +3208,12 @@ def create_fieldplot_line_traces( List of the in-volume tracing objects. surface_tracing_objs : list List of the surface tracing objects. - setup_name : str, optional + setup : str, optional Name of the setup in the format ``"setupName : sweepName"``. The default is ``None``. - intrinsinc_dict : dict, optional - Dictionary containing all intrinsic variables. The default - is ``{}``. + intrinsics : dict, optional + Dictionary containing all intrinsic variables. + The default is ``None``. plot_name : str, optional Name of the field plot to create. The default is ``None``. field_type : str, optional @@ -3171,8 +3232,8 @@ def create_fieldplot_line_traces( if self._app.solution_type != "Electrostatic": self.logger.error("Field line traces is valid only for electrostatic solution") return False - if intrinsinc_dict is None: - intrinsinc_dict = {} + if intrinsics is None: + intrinsics = {} if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] @@ -3227,15 +3288,15 @@ def create_fieldplot_line_traces( in_volume_tracing_ids, surface_tracing_ids, "FieldLineTrace", - setup_name, - intrinsinc_dict, + setup, + intrinsics, plot_name, field_type=field_type, ) - @pyaedt_function_handler() + @pyaedt_function_handler(quantity_name="quantity", setup_name="setup") def create_fieldplot_layers_nets( - self, layers_nets, quantity_name, setup_name=None, intrinsics=None, plot_on_surface=True, plot_name=None + self, layers_nets, quantity, setup=None, intrinsics=None, plot_on_surface=True, plot_name=None ): # pragma: no cover # type: (list, str, str, dict, bool, str) -> FieldPlot """Create a field plot of stacked layer plot. @@ -3247,16 +3308,16 @@ def create_fieldplot_layers_nets( layers_nets : list List of layers and nets to plot. For example: ``[["Layer1", "GND", "PWR"], ["Layer2", "VCC"], ...]``. - quantity_name : str + quantity : str Name of the quantity to plot. - setup_name : str, optional + setup : str, optional Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` setup is used. Make sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. intrinsics : dict, optional - Dictionary containing all intrinsic variables. The default - is ``{}``. + Dictionary containing all intrinsic variables. + The default is ``None``. plot_on_surface : bool, optional Whether the plot is to be on the surface or volume of traces. plot_name : str, optional @@ -3283,42 +3344,45 @@ def create_fieldplot_layers_nets( self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] if self._app.design_type == "HFSS 3D Layout Design": - if not setup_name: - setup_name = self._app.existing_analysis_sweeps[0] + if not setup: + setup = self._app.existing_analysis_sweeps[0] lst = [] for layer in layers_nets: for el in layer[1:]: - get_ids = self._odesign.GetGeometryIdsForNetLayerCombination(el, layer[0], setup_name) + get_ids = self._odesign.GetGeometryIdsForNetLayerCombination(el, layer[0], setup) if isinstance(get_ids, (tuple, list)) and len(get_ids) > 2: lst.extend([int(i) for i in get_ids[2:]]) - return self._create_fieldplot(lst, quantity_name, setup_name, intrinsics, "FacesList", plot_name) + return self._create_fieldplot(lst, quantity, setup, intrinsics, "FacesList", plot_name) if plot_on_surface: plot_type = "LayerNetsExtFace" else: plot_type = "LayerNets" - return self._create_fieldplot(layers_nets, quantity_name, setup_name, intrinsics, plot_type, plot_name) + return self._create_fieldplot(layers_nets, quantity, setup, intrinsics, plot_type, plot_name) - @pyaedt_function_handler() + @pyaedt_function_handler( + objlist="assignment", quantityName="quantity", IntrinsincDict="intrinsics", setup_name="setup" + ) def create_fieldplot_surface( - self, objlist, quantityName, setup_name=None, intrinsincDict=None, plot_name=None, field_type="DC R/L Fields" + self, assignment, quantity, setup=None, intrinsics=None, plot_name=None, field_type="DC R/L Fields" ): """Create a field plot of surfaces. Parameters ---------- - objlist : list + assignment : list List of surfaces to plot. - quantityName : str + quantity : str Name of the quantity to plot. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. - intrinsincDict : dict, optional - Dictionary containing all intrinsic variables. The default - is ``{}``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + intrinsics : dict, optional + Dictionary containing all intrinsic variables. + The default is ``None``. plot_name : str, optional - Name of the fieldplot to create. + Name of the field plot to create. field_type : str, optional Field type to plot. Valid only for Q3D Field plots. @@ -3332,55 +3396,58 @@ def create_fieldplot_surface( >>> oModule.CreateFieldPlot """ - if intrinsincDict is None: - intrinsincDict = {} + if intrinsics is None: + intrinsics = {} if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] - if not isinstance(objlist, (list, tuple)): - objlist = [objlist] + if not isinstance(assignment, (list, tuple)): + assignment = [assignment] new_obj_list = [] - for obj in objlist: + for obj in assignment: if isinstance(obj, (int, FacePrimitive)): new_obj_list.append(obj) elif self._app.modeler[obj]: new_obj_list.extend([face for face in self._app.modeler[obj].faces if face.id not in new_obj_list]) return self._create_fieldplot( - new_obj_list, quantityName, setup_name, intrinsincDict, "FacesList", plot_name, field_type=field_type + new_obj_list, quantity, setup, intrinsics, "FacesList", plot_name, field_type=field_type ) - @pyaedt_function_handler() + @pyaedt_function_handler( + objlist="assignment", quantityName="quantity", IntrinsincDict="intrinsics", setup_name="setup" + ) def create_fieldplot_cutplane( self, - objlist, - quantityName, - setup_name=None, - intrinsincDict=None, + assignment, + quantity, + setup=None, + intrinsics=None, plot_name=None, - filter_objects=[], + filter_objects=None, field_type="DC R/L Fields", ): """Create a field plot of cut planes. Parameters ---------- - objlist : list + assignment : list List of cut planes to plot. - quantityName : str + quantity : str Name of the quantity to plot. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. - intrinsincDict : dict, optional + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` setup + is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, + where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. + intrinsics : dict, optional Dictionary containing all intrinsic variables. - The default is ``{}``. + The default is ``None``. plot_name : str, optional - Name of the fieldplot to create. + Name of the field plot to create. filter_objects : list, optional Objects list on which filter the plot. + The default value is ``None``, in which case an empty list is passed. field_type : str, optional - Field type to plot. Valid only for Q3D Field plots. + Field type to plot. This parameter is valid only for Q3D field plots. Returns ------- @@ -3392,51 +3459,48 @@ def create_fieldplot_cutplane( >>> oModule.CreateFieldPlot """ - if intrinsincDict is None: - intrinsincDict = {} + if intrinsics is None: + intrinsics = {} if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] if filter_objects: filter_objects = self._app.modeler.convert_to_selections(filter_objects, True) return self._create_fieldplot( - objlist, - quantityName, - setup_name, - intrinsincDict, + assignment, + quantity, + setup, + intrinsics, "CutPlane", plot_name, filter_boxes=filter_objects, field_type=field_type, ) - @pyaedt_function_handler() + @pyaedt_function_handler( + objlist="assignment", quantityName="quantity", IntrinsincDict="intrinsics", setup_name="setup" + ) def create_fieldplot_volume( - self, - objlist, - quantityName, - setup_name=None, - intrinsincDict=None, - plot_name=None, - field_type="DC R/L Fields", + self, assignment, quantity, setup=None, intrinsics=None, plot_name=None, field_type="DC R/L Fields" ): """Create a field plot of volumes. Parameters ---------- - objlist : list + assignment : list List of volumes to plot. - quantityName : + quantity : Name of the quantity to plot. - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. - intrinsincDict : dict, optional - Dictionary containing all intrinsic variables. The default - is ``{}``. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + intrinsics : dict, optional + Dictionary containing all intrinsic variables. + The default is ``None``. plot_name : str, optional - Name of the fieldplot to create. + Name of the field plot to create. Returns ------- @@ -3448,21 +3512,21 @@ def create_fieldplot_volume( >>> oModule.CreateFieldPlot """ - if intrinsincDict is None: - intrinsincDict = {} + if intrinsics is None: + intrinsics = {} if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] return self._create_fieldplot( - objlist, quantityName, setup_name, intrinsincDict, "ObjList", plot_name, field_type=field_type + assignment, quantity, setup, intrinsics, "ObjList", plot_name, field_type=field_type ) - @pyaedt_function_handler() + @pyaedt_function_handler(fileName="file_name", plotName="plot_name", foldername="folder_name") def export_field_jpg( self, - fileName, - plotName, - foldername, + file_name, + plot_name, + folder_name, orientation="isometric", width=1920, height=1080, @@ -3477,11 +3541,11 @@ def export_field_jpg( Parameters ---------- - fileName : str + file_name : str Full path and name to save the JPG file to. - plotName : str + plot_name : str Name of the plot. - foldername : str + folder_name : str Name of the folder plot. orientation : str, optional Name of the orientation to apply. The default is ``"isometric"``. @@ -3535,15 +3599,15 @@ def export_field_jpg( ] view = orientation_to_view.get(orientation, "iso") cs = self.modeler.create_coordinate_system(origin=center, mode="view", view=view) - self.ofieldsreporter.ExportPlotImageToFile(fileName, foldername, plotName, cs.name) + self.ofieldsreporter.ExportPlotImageToFile(file_name, folder_name, plot_name, cs.name) cs.delete() else: self.export_model_picture( - full_name=fileName, + full_name=file_name, width=width, height=height, orientation=orientation, - field_selections=plotName, + field_selections=plot_name, selections=selections, show_axis=show_axis, show_grid=show_grid, @@ -3555,7 +3619,7 @@ def export_field_jpg( self._primitives[solid].display_wireframe = False else: self.ofieldsreporter.ExportPlotImageWithViewToFile( - fileName, foldername, plotName, width, height, orientation + file_name, folder_name, plot_name, width, height, orientation ) return True @@ -3702,11 +3766,9 @@ def export_model_picture( self.oeditor.ExportModelImageToFile(full_name, width, height, arg) return full_name - @pyaedt_function_handler() - def get_far_field_data( - self, expression="GainTotal", setup_sweep_name="", domain="Infinite Sphere1", families_dict=None - ): - """Generate far field data using ``GetSolutionDataPerVariation``. + @pyaedt_function_handler(expression="expressions", families_dict="sweeps") + def get_far_field_data(self, expressions="GainTotal", setup_sweep_name="", domain="Infinite Sphere1", sweeps=None): + """Generate far field data using the ``GetSolutionDataPerVariation()`` method. This method returns the data ``solData``, ``ThetaVals``, ``PhiVals``, ``ScanPhiVals``, ``ScanThetaVals``, and @@ -3714,14 +3776,14 @@ def get_far_field_data( Parameters ---------- - expression : str or list, optional + expressions : str or list, optional One or more formulas to add to the report. The default is ``"GainTotal"``. setup_sweep_name : str, optional Name of the setup for computing the report. The default is ``""``, in which case the nominal sweep is used. domain : str, dict, optional Context type (sweep or time). The default is ``"Infinite Sphere1"``. - families_dict : dict, optional + sweeps : dict, optional Dictionary of variables and values. The default is ``{"Freq": ["All"]}``. Returns @@ -3733,58 +3795,60 @@ def get_far_field_data( >>> oModule.GetSolutionDataPerVariation """ - if type(expression) is not list: - expression = [expression] + if not isinstance(expressions, list): + expressions = [expressions] if not setup_sweep_name: setup_sweep_name = self._app.nominal_adaptive - if families_dict is None: - families_dict = {"Theta": ["All"], "Phi": ["All"], "Freq": ["All"]} + if sweeps is None: + sweeps = {"Theta": ["All"], "Phi": ["All"], "Freq": ["All"]} context = ["Context:=", domain] if isinstance(domain, dict): if "Context" in domain.keys() and "SourceContext" in domain.keys(): context = ["Context:=", domain["Context"], "Context:=", domain["SourceContext"]] solution_data = self.get_solution_data_per_variation( - "Far Fields", setup_sweep_name, context, families_dict, expression + "Far Fields", setup_sweep_name, context, sweeps, expressions ) if not solution_data: print("No Data Available. Check inputs") return False return solution_data - @pyaedt_function_handler() - def export_model_obj(self, obj_list=None, export_path=None, export_as_single_objects=False, air_objects=False): + @pyaedt_function_handler(obj_list="assignment") + def export_model_obj(self, assignment=None, export_path=None, export_as_single_objects=False, air_objects=False): """Export the model. Parameters ---------- - obj_list : list, optional - List of objects to export. Export every model object except 3D ones, vacuum and air objects. + assignment : list, optional + List of objects to export. Export every model object except 3D ones and + vacuum and air objects. export_path : str, optional - Full path of the exported obj file. + Full path of the exported OBJ file. export_as_single_objects : bool, optional - Define if the model will be exported as single obj or list of objs for each object. + Whether to export the model as single object. The default is ``False``, in which + case is exported asa list of objects for each object. air_objects : bool, optional - Define if air and vacuum objects will be exported. + Whether to export air and vacuum objects. The default is ``False``. Returns ------- list - Files obj path. + List of paths for OBJ files. """ - if obj_list and not isinstance(obj_list, (list, tuple)): - obj_list = [obj_list] + if assignment and not isinstance(assignment, (list, tuple)): + assignment = [assignment] assert self._app._aedt_version >= "2021.2", self.logger.error("Object is supported from AEDT 2021 R2.") if not export_path: export_path = self._app.working_directory - if not obj_list: + if not assignment: self._app.modeler.refresh_all_ids() non_model = self._app.modeler.non_model_objects[:] - obj_list = [i for i in self._app.modeler.object_names if i not in non_model] + assignment = [i for i in self._app.modeler.object_names if i not in non_model] if not air_objects: - obj_list = [ + assignment = [ i - for i in obj_list + for i in assignment if not self._app.modeler[i].is3d or ( self._app.modeler[i].material_name.lower() != "vacuum" @@ -3793,12 +3857,11 @@ def export_model_obj(self, obj_list=None, export_path=None, export_as_single_obj ] if export_as_single_objects: files_exported = [] - for el in obj_list: + for el in assignment: fname = os.path.join(export_path, "{}.obj".format(el)) self._app.modeler.oeditor.ExportModelMeshToFile(fname, [el]) - if settings.remote_rpc_session_temp_folder: - local_path = "{}/{}".format(settings.remote_rpc_session_temp_folder, "{}.obj".format(el)) - fname = check_and_download_file(local_path, fname) + + fname = check_and_download_file(fname) if not self._app.modeler[el].display_wireframe: transp = 0.6 @@ -3811,27 +3874,29 @@ def export_model_obj(self, obj_list=None, export_path=None, export_as_single_obj return files_exported else: fname = os.path.join(export_path, "Model_AllObjs_AllMats.obj") - self._app.modeler.oeditor.ExportModelMeshToFile(fname, obj_list) + self._app.modeler.oeditor.ExportModelMeshToFile(fname, assignment) return [[fname, "aquamarine", 0.3]] - @pyaedt_function_handler() - def export_mesh_obj(self, setup_name=None, intrinsic_dict=None): - """Export the mesh in ``aedtplt`` format. + @pyaedt_function_handler(setup_name="setup") + def export_mesh_obj(self, setup=None, intrinsics=None): + """Export the mesh in AEDTPLT format. The mesh has to be available in the selected setup. - If a parametric model is provided user can choose the mesh to export providing a specific set of variations. + If a parametric model is provided, you can choose the mesh to export by providing a specific set of variations. This method applies only to ``Hfss``, ``Q3d``, ``Q2D``, ``Maxwell3d``, ``Maxwell2d``, ``Icepak`` and ``Mechanical`` objects. This method is calling ``create_fieldplot_surface`` to create a mesh plot and ``export_field_plot`` to export it as ``aedtplt`` file. Parameters ---------- - setup_name : str, optional - Name of the setup. The default is ``None`` which automatically take ``nominal_adaptive`` setup. - Please make sure to build a setup string in the form of ``"SetupName : SetupSweep"`` - where ``SetupSweep`` is the Sweep name to use in the export or ``LastAdaptive``. - intrinsic_dict : dict, optional. + setup : str, optional + Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` + setup is used. Be sure to build a setup string in the form of + ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to + use in the export or ``LastAdaptive``. + intrinsics : dict, optional. Intrinsic dictionary that is needed for the export. - The default is ``{}`` which assumes no variables are present in the dict or nominal values are used. + The default is ``None``, which assumes that no variables are present in + the dictionary or nominal values are used. Returns ------- @@ -3844,23 +3909,23 @@ def export_mesh_obj(self, setup_name=None, intrinsic_dict=None): >>> hfss = Hfss() >>> hfss.analyze() >>> # Export report using defaults. - >>> hfss.post.export_mesh_obj(setup_name=None, intrinsic_dict=None) + >>> hfss.post.export_mesh_obj(setup=None,intrinsics=None) >>> # Export report using arguments. - >>> hfss.post.export_mesh_obj(setup_name="MySetup : LastAdaptive", intrinsic_dict={"w1":"5mm", "l1":"3mm"}) + >>> hfss.post.export_mesh_obj(setup="MySetup : LastAdaptive",intrinsics={"w1":"5mm", "l1":"3mm"}) """ - if intrinsic_dict is None: - intrinsic_dict = {} + if intrinsics is None: + intrinsics = {} project_path = self._app.working_directory - if not setup_name: - setup_name = self._app.nominal_adaptive + if not setup: + setup = self._app.nominal_adaptive face_lists = [] obj_list = self._app.modeler.object_names for el in obj_list: object3d = self._app.modeler[el] if not object3d.is3d or object3d.material_name not in ["vacuum", "air"]: face_lists += [i.id for i in object3d.faces] - plot = self.create_fieldplot_surface(face_lists, "Mesh", setup_name, intrinsic_dict) + plot = self.create_fieldplot_surface(face_lists, "Mesh", setup, intrinsics) if plot: file_to_add = self.export_field_plot(plot.name, project_path) plot.delete() @@ -4236,6 +4301,7 @@ def extract_dataset_info(boundary_obj, units_input="W", boundary="Power"): self.logger.info("The total power is {} {}".format(str(round(sum(power_dict_obj.values()), 3)), units)) return power_dict_obj, sum(power_dict_obj.values()), power_dict, sum(power_dict.values()) + @pyaedt_function_handler() def create_creeping_plane_visual_ray_tracing( self, max_frequency="1GHz", @@ -4285,6 +4351,7 @@ def create_creeping_plane_visual_ray_tracing( vrt.create() return vrt + @pyaedt_function_handler() def create_creeping_point_visual_ray_tracing( self, max_frequency="1GHz", @@ -4317,10 +4384,7 @@ def create_creeping_point_visual_ray_tracing( """ if custom_location is None: custom_location = [0, 0, 0] - vrt = VRTFieldPlot( - self, - is_creeping_wave=True, - ) + vrt = VRTFieldPlot(self, is_creeping_wave=True) vrt.max_frequency = max_frequency vrt.sample_density = sample_density vrt.ray_density = ray_density @@ -4331,6 +4395,7 @@ def create_creeping_point_visual_ray_tracing( vrt.create() return vrt + @pyaedt_function_handler() def create_sbr_plane_visual_ray_tracing( self, max_frequency="1GHz", @@ -4404,6 +4469,7 @@ def create_sbr_plane_visual_ray_tracing( vrt.create() return vrt + @pyaedt_function_handler() def create_sbr_point_visual_ray_tracing( self, max_frequency="1GHz", @@ -4491,22 +4557,23 @@ class CircuitPostProcessor(PostProcessorCommon, object): def __init__(self, app): PostProcessorCommon.__init__(self, app) + @pyaedt_function_handler(setupname="setup", plotname="plot_name") def create_ami_initial_response_plot( self, - setupname, + setup, ami_name, variation_list_w_value, plot_type="Rectangular Plot", plot_initial_response=True, plot_intermediate_response=False, plot_final_response=False, - plotname=None, + plot_name=None, ): """Create an AMI initial response plot. Parameters ---------- - setupname : str + setup : str Name of the setup. ami_name : str AMI probe name to use. @@ -4522,16 +4589,17 @@ def create_ami_initial_response_plot( Set whether to plot the intermediate input response. Default is ``False``. plot_final_response : bool, optional Set whether to plot the final input response. Default is ``False``. - plotname : str, optional - The plot name. Default is a unique name. + plot_name : str, optional + Plot name. The default is ``None``, in which case + a unique name is automatically assigned. Returns ------- str Name of the plot. """ - if not plotname: - plotname = generate_unique_name("AMIAnalysis") + if not plot_name: + plot_name = generate_unique_name("AMIAnalysis") variations = ["__InitialTime:=", ["All"]] i = 0 for a in variation_list_w_value: @@ -4554,10 +4622,10 @@ def create_ami_initial_response_plot( if plot_final_response: ycomponents.append("FinalImpulseResponse<{}.int_ami_rx>".format(ami_name)) self.oreportsetup.CreateReport( - plotname, + plot_name, "Standard", plot_type, - setupname, + setup, [ "NAME:Context", "SimValueContext:=", @@ -4596,26 +4664,29 @@ def create_ami_initial_response_plot( variations, ["X Component:=", "__InitialTime", "Y Component:=", ycomponents], ) - return plotname + return plot_name + @pyaedt_function_handler(setupname="setup", plotname="plot_name") def create_ami_statistical_eye_plot( - self, setupname, ami_name, variation_list_w_value, ami_plot_type="InitialEye", plotname=None + self, setup, ami_name, variation_list_w_value, ami_plot_type="InitialEye", plot_name=None ): """Create an AMI statistical eye plot. Parameters ---------- - setupname : str + setup : str Name of the setup. ami_name : str AMI probe name to use. variation_list_w_value : list Variations with relative values. ami_plot_type : str, optional - String containing the report AMI type. Default is ``"InitialEye"``. It can be ``"EyeAfterSource"``, - ``"EyeAfterChannel"`` or ``"EyeAfterProbe"``. - plotname : str, optional - The name of the plot. Defaults to a unique name starting with ``"Plot"``. + String containing the report AMI type. The default is ``"InitialEye"``. + Options are ``"EyeAfterChannel"``, ``"EyeAfterProbe"````"EyeAfterSource"``, + and ``"InitialEye"``.. + plot_name : str, optional + Plot name. The default is ``None``, in which case + a unique name starting with ``"Plot"`` is automatically assigned. Returns ------- @@ -4627,8 +4698,8 @@ def create_ami_statistical_eye_plot( >>> oModule.CreateReport """ - if not plotname: - plotname = generate_unique_name("AMYAanalysis") + if not plot_name: + plot_name = generate_unique_name("AMYAanalysis") variations = [ "__UnitInterval:=", ["All"], @@ -4663,10 +4734,10 @@ def create_ami_statistical_eye_plot( elif ami_plot_type == "EyeAfterProbe": ami_id = "3" self.oreportsetup.CreateReport( - plotname, + plot_name, "Statistical Eye", "Statistical Eye Plot", - setupname, + setup, [ "NAME:Context", "SimValueContext:=", @@ -4702,21 +4773,22 @@ def create_ami_statistical_eye_plot( variations, ["X Component:=", "__UnitInterval", "Y Component:=", "__Amplitude", "Eye Diagram Component:=", ycomponents], ) - return plotname + return plot_name - def create_statistical_eye_plot(self, setupname, probe_names, variation_list_w_value, plotname=None): + @pyaedt_function_handler(setupname="setup", plotname="plot_name") + def create_statistical_eye_plot(self, setup, probe_names, variation_list_w_value, plot_name=None): """Create a statistical QuickEye, VerifEye, and/or Statistical Eye plot. Parameters ---------- - setupname : str + setup : str Name of the setup. probe_names : str or list - Name of the probe to plot in the EYE diagram. + One or more names of the probes to plot in the eye diagram. variation_list_w_value : list List of variations with relative values. - plotname : str, optional - The name of the plot. + plot_name : str, optional + Plot name. The default is ``None``, in which case a name is automatically assigned. Returns ------- @@ -4728,8 +4800,8 @@ def create_statistical_eye_plot(self, setupname, probe_names, variation_list_w_v >>> oModule.CreateReport """ - if not plotname: - plotname = generate_unique_name("AMIAanalysis") + if not plot_name: + plot_name = generate_unique_name("AMIAanalysis") variations = [ "__UnitInterval:=", ["All"], @@ -4755,10 +4827,10 @@ def create_statistical_eye_plot(self, setupname, probe_names, variation_list_w_v ycomponents = [probe_names] self.oreportsetup.CreateReport( - plotname, + plot_name, "Statistical Eye", "Statistical Eye Plot", - setupname, + setup, [ "NAME:Context", "SimValueContext:=", @@ -4794,8 +4866,9 @@ def create_statistical_eye_plot(self, setupname, probe_names, variation_list_w_v variations, ["X Component:=", "__UnitInterval", "Y Component:=", "__Amplitude", "Eye Diagram Component:=", ycomponents], ) - return plotname + return plot_name + @pyaedt_function_handler() def sample_waveform( self, waveform_data, @@ -4833,8 +4906,9 @@ def sample_waveform( Examples -------- - >>> aedtapp = Circuit() - >>> aedtapp.post.sample_ami_waveform(setup_name, probe_name, source_name, aedtapp.available_variations.nominal) + >>> from pyaedt import Circuit + >>> circuit = Circuit() + >>> circuit.post.sample_ami_waveform(setup_name,probe_name,source_name,circuit.available_variations.nominal) """ @@ -4883,11 +4957,12 @@ def sample_waveform( return pd.Series(new_voltage, index=tic_in_s) return outputdata + @pyaedt_function_handler(setupname="setup", probe_name="probe", source_name="source") def sample_ami_waveform( self, - setupname, - probe_name, - source_name, + setup, + probe, + source, variation_list_w_value, unit_interval=1e-9, ignore_bits=0, @@ -4898,11 +4973,11 @@ def sample_ami_waveform( Parameters ---------- - setupname : str + setup : str Name of the setup. - probe_name : str + probe : str Name of the AMI probe. - source_name : str + source : str Name of the AMI source. variation_list_w_value : list Variations with relative values. @@ -4925,23 +5000,23 @@ def sample_ami_waveform( Examples -------- - >>> aedtapp = Circuit() - >>> aedtapp.post.sample_ami_waveform(setupname, probe_name, source_name, aedtapp.available_variations.nominal) + >>> circuit = Circuit() + >>> circuit.post.sample_ami_waveform(setupname,probe_name,source_name,circuit.available_variations.nominal) """ initial_solution_type = self.post_solution_type self._app.solution_type = "NexximAMI" if plot_type == "InitialWave" or plot_type == "WaveAfterSource": - plot_expression = [plot_type + "<" + source_name + ".int_ami_tx>"] + plot_expression = [plot_type + "<" + source + ".int_ami_tx>"] elif plot_type == "WaveAfterChannel" or plot_type == "WaveAfterProbe": - plot_expression = [plot_type + "<" + probe_name + ".int_ami_rx>"] + plot_expression = [plot_type + "<" + probe + ".int_ami_rx>"] else: plot_expression = [ - "InitialWave<" + source_name + ".int_ami_tx>", - "WaveAfterSource<" + source_name + ".int_ami_tx>", - "WaveAfterChannel<" + probe_name + ".int_ami_rx>", - "WaveAfterProbe<" + probe_name + ".int_ami_rx>", + "InitialWave<" + source + ".int_ami_tx>", + "WaveAfterSource<" + source + ".int_ami_tx>", + "WaveAfterChannel<" + probe + ".int_ami_rx>", + "WaveAfterProbe<" + probe + ".int_ami_rx>", ] waveform = [] waveform_sweep = [] @@ -4949,7 +5024,7 @@ def sample_ami_waveform( waveform_sweep_unit = [] for exp in plot_expression: waveform_data = self.get_solution_data( - expressions=exp, setup_sweep_name=setupname, domain="Time", variations=variation_list_w_value + expressions=exp, setup_sweep_name=setup, domain="Time", variations=variation_list_w_value ) samples_per_bit = 0 for sample in waveform_data.primary_sweep_values: @@ -4972,10 +5047,10 @@ def sample_ami_waveform( tics = clock_tics if not clock_tics: - clock_expression = "ClockTics<" + probe_name + ".int_ami_rx>" + clock_expression = "ClockTics<" + probe + ".int_ami_rx>" clock_tic = self.get_solution_data( expressions=clock_expression, - setup_sweep_name=setupname, + setup_sweep_name=setup, domain="Clock Times", variations=variation_list_w_value, ) @@ -5026,7 +5101,7 @@ def sample_ami_waveform( "MassFlowRate", "VolumeFlowRate", "MassFlux", - "ViscocityRatio", + "ViscosityRatio", "WallYPlus", "TKE", "Epsilon", @@ -5119,22 +5194,22 @@ def add_calculation( ) # TODO : last argument not documented return True - @pyaedt_function_handler() - def get_field_summary_data(self, setup_name=None, design_variation={}, intrinsic_value="", pandas_output=False): + @pyaedt_function_handler(IntrinsincDict="intrinsics", setup_name="setup", design_variation="variation") + def get_field_summary_data(self, setup=None, variation=None, intrinsics="", pandas_output=False): """ Get field summary output computation. Parameters ---------- - setup_name : str, optional + setup : str, optional Setup name to use for the computation. The default is ``None``, in which case the nominal variation is used. - design_variation : dict, optional + variation : dict, optional Dictionary containing the design variation to use for the computation. The default is ``{}``, in which case nominal variation is used. - intrinsic_value : str, optional + intrinsics : str, optional Intrinsic values to use for the computation. The default is ``""``, - suitable when no frequency needs to be selected. + which is suitable when no frequency needs to be selected. pandas_output : bool, optional Whether to use pandas output. The default is ``False``, in which case the dictionary output is used. @@ -5145,10 +5220,12 @@ def get_field_summary_data(self, setup_name=None, design_variation={}, intrinsic Output type depending on the Boolean ``pandas_output`` parameter. The output consists of information exported from the field summary. """ + if variation is None: + variation = {} with tempfile.NamedTemporaryFile(mode="w+", delete=False) as temp_file: temp_file.close() - self.export_csv(temp_file.name, setup_name, design_variation, intrinsic_value) - with open(temp_file.name, "r") as f: + self.export_csv(temp_file.name, setup, variation, intrinsics) + with open_file(temp_file.name, "r") as f: for _ in range(4): _ = next(f) reader = csv.DictReader(f) @@ -5163,46 +5240,48 @@ def get_field_summary_data(self, setup_name=None, design_variation={}, intrinsic return pd.DataFrame.from_dict(out_dict) return out_dict - @pyaedt_function_handler() - def export_csv(self, filename, setup_name=None, design_variation={}, intrinsic_value=""): + @pyaedt_function_handler(filename="output_file", design_variation="variations", setup_name="setup") + def export_csv(self, output_file, setup=None, variations=None, intrinsics=""): """ Get the field summary output computation. Parameters ---------- - filename : str + output_file : str Path and filename to write the output file to. - setup_name : str, optional + setup : str, optional Setup name to use for the computation. The default is ``None``, in which case the nominal variation is used. - design_variation : dict, optional + variations : dict, optional Dictionary containing the design variation to use for the computation. The default is ``{}``, in which case the nominal variation is used. - intrinsic_value : str, optional + intrinsics : str, optional Intrinsic values to use for the computation. The default is ``""``, - suitable when no frequency needs to be selected. + which is suitable when no frequency needs to be selected. Returns ------- bool ``True`` when successful, ``False`` when failed. """ - if not setup_name: - setup_name = self._app.nominal_sweep + if variations is None: + variations = {} + if not setup: + setup = self._app.nominal_sweep dv_string = "" - for el in design_variation: - dv_string += el + "='" + design_variation[el] + "' " - self._create_field_summary(setup_name, dv_string) + for el in variations: + dv_string += el + "='" + variations[el] + "' " + self._create_field_summary(setup, dv_string) self._app.osolution.ExportFieldsSummary( [ "SolutionName:=", - setup_name, + setup, "DesignVariationKey:=", dv_string, "ExportFileName:=", - filename, + output_file, "IntrinsicValue:=", - intrinsic_value, + intrinsics, ] ) return True diff --git a/pyaedt/modules/SolveSetup.py b/pyaedt/modules/SolveSetup.py index b5e18865b83..6f5cfafdadf 100644 --- a/pyaedt/modules/SolveSetup.py +++ b/pyaedt/modules/SolveSetup.py @@ -31,22 +31,22 @@ class CommonSetup(PropsManager, object): - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): self.auto_update = False self._app = None self.p_app = app - if solutiontype is None: + if solution_type is None: self.setuptype = self.p_app.design_solutions.default_setup - elif isinstance(solutiontype, int): - self.setuptype = solutiontype - elif solutiontype in SetupKeys.SetupNames: - self.setuptype = SetupKeys.SetupNames.index(solutiontype) + elif isinstance(solution_type, int): + self.setuptype = solution_type + elif solution_type in SetupKeys.SetupNames: + self.setuptype = SetupKeys.SetupNames.index(solution_type) else: - self.setuptype = self.p_app.design_solutions._solution_options[solutiontype]["default_setup"] - self._setupname = setupname + self.setuptype = self.p_app.design_solutions._solution_options[solution_type]["default_setup"] + self._name = name self.props = {} self.sweeps = [] - self._init_props(isnewsetup) + self._init_props(is_new_setup) self.auto_update = True @property @@ -138,8 +138,8 @@ def analyze( ) @pyaedt_function_handler() - def _init_props(self, isnewsetup=False): - if isnewsetup: + def _init_props(self, is_new_setup=False): + if is_new_setup: setup_template = SetupKeys.get_setup_templates()[self.setuptype] self.props = SetupProps(self, setup_template) else: @@ -177,7 +177,7 @@ def is_solved(self): Returns ------- bool - `True` if solutions are available. + ``True`` if solutions are available, ``False`` otherwise. """ if self.p_app.design_solutions.default_adaptive: expressions = [ @@ -187,12 +187,12 @@ def is_solved(self): ) ] sol = self.p_app.post.reports_by_category.standard( - setup_name="{} : {}".format(self.name, self.p_app.design_solutions.default_adaptive), expressions=expressions[0], + setup="{} : {}".format(self.name, self.p_app.design_solutions.default_adaptive), ) else: expressions = [i for i in self.p_app.post.available_report_quantities(solution=self.name)] - sol = self.p_app.post.reports_by_category.standard(setup_name=self.name, expressions=expressions[0]) + sol = self.p_app.post.reports_by_category.standard(expressions=expressions[0], setup=self.name) if identify_setup(self.props): sol.domain = "Time" return True if sol.get_solution_data() else False @@ -214,14 +214,14 @@ def omodule(self): @property def name(self): """Name.""" - return self._setupname + return self._name @name.setter def name(self, name): - self._setupname = name + self._name = name self.props["Name"] = name - @pyaedt_function_handler() + @pyaedt_function_handler(sweep_name="sweep") def get_solution_data( self, expressions=None, @@ -232,7 +232,7 @@ def get_solution_data( context=None, polyline_points=1001, math_formula=None, - sweep_name=None, + sweep=None, ): """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. Data to be retrieved from Electronics Desktop are any simulation results available in that @@ -275,8 +275,8 @@ def get_solution_data( This parameter is valid for ``Fields`` plot only. math_formula : str, optional One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. - sweep_name : str, optional - Name of the sweep adaptive setup from which get solutions. Default is ``LastAdaptive``. + sweep : str, optional + Name of the sweep adaptive setup to get solutions from. the default is ``LastAdaptive``. Returns ------- @@ -298,41 +298,27 @@ def get_solution_data( >>> variations["Theta"] = ["All"] >>> variations["Phi"] = ["All"] >>> variations["Freq"] = ["30GHz"] - >>> data1 = aedtapp.post.get_solution_data( - ... "GainTotal", - ... aedtapp.nominal_adaptive, - ... variations=variations, - ... primary_sweep_variable="Phi", - ... secondary_sweep_variable="Theta", - ... context="3D", - ... report_category="Far Fields", - ...) - - >>> data2 =aedtapp.post.get_solution_data( - ... "S(1,1)", - ... aedtapp.nominal_sweep, - ... variations=variations, - ...) + >>> data1 = aedtapp.post.get_solution_data("GainTotal", aedtapp.nominal_adaptive, + ... variations=variations, primary_sweep_variable="Phi", + ... report_category="Far Fields", context="3D") + + >>> data2 =aedtapp.post.get_solution_data("S(1,1)",aedtapp.nominal_sweep,variations=variations) >>> data2.plot() >>> from pyaedt import Maxwell2d >>> maxwell_2d = Maxwell2d() - >>> data3 = maxwell_2d.post.get_solution_data( - ... "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", - ... ) + >>> data3 = maxwell_2d.post.get_solution_data("InputCurrent(PHA)",domain="Time",primary_sweep_variable="Time") >>> data3.plot("InputCurrent(PHA)") >>> from pyaedt import Circuit >>> circuit = Circuit() >>> context = {"algorithm": "FFT", "max_frequency": "100MHz", "time_stop": "2.5us", "time_start": "0ps"} - >>> spectralPlotData = circuit.post.get_solution_data( - ... expressions="V(Vprobe1)", primary_sweep_variable="Spectrum", domain="Spectral", - ... context=context - ...) + >>> spectralPlotData = circuit.post.get_solution_data(expressions="V(Vprobe1)", domain="Spectral", + ... primary_sweep_variable="Spectrum", context=context) """ - if sweep_name: + if sweep: setup_sweep_name = [ - i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0] and sweep_name in i + i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0] and sweep in i ] else: setup_sweep_name = [i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0]] @@ -346,11 +332,11 @@ def get_solution_data( context=context, polyline_points=polyline_points, math_formula=math_formula, - setup_sweep_name=setup_sweep_name[0], + setup_sweep_name=sweep, ) return None - @pyaedt_function_handler() + @pyaedt_function_handler(sweep_name="sweep", plotname="name") def create_report( self, expressions=None, @@ -363,10 +349,10 @@ def create_report( context=None, subdesign_id=None, polyline_points=1001, - plotname=None, - sweep_name=None, + name=None, + sweep=None, ): - """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plots or data tables. + """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plot, or data table. Parameters ---------- @@ -393,16 +379,17 @@ def create_report( The default is ``None``. It can be `None`, `"Differential Pairs"`,`"RL"`, `"Sources"`, `"Vias"`,`"Bondwires"`, `"Probes"` for Hfss3dLayout or Reduce Matrix Name for Q2d/Q3d solution or Infinite Sphere name for Far Fields Plot. - plotname : str, optional + name : str, optional Name of the plot. The default is ``None``. polyline_points : int, optional, - Number of points on which create the report for plots on polylines. + Number of points for creating the report for plots on polylines. subdesign_id : int, optional - Specify a subdesign ID to export a Touchstone file of this subdesign. Valid for Circuit Only. + Specify a subdesign ID to export a Touchstone file of this subdesign to. + This parameter is valid only for a circuit. The default value is ``None``. context : str, optional - sweep_name : str, optional - Name of the sweep adaptive setup from which get solutions. Default is ``LastAdaptive``. + sweep : str, optional + Name of the sweep adaptive setup to get solutions from. The default is ``LastAdaptive``. Returns ------- @@ -422,21 +409,13 @@ def create_report( >>> aedtapp.post.create_report("dB(S(1,1))") >>> variations = aedtapp.available_variations.nominal_w_values_dict - >>> aedtapp.post.setups[0].create_report( - ... "dB(S(1,1))", - ... variations=variations, - ... primary_sweep_variable="Freq", - ...) - - >>> aedtapp.post.create_report( - ... "S(1,1)", - ... variations=variations, - ... plot_type="Smith Chart", - ...) - """ - if sweep_name: + >>> aedtapp.post.setups[0].create_report("dB(S(1,1))",variations=variations,primary_sweep_variable="Freq") + + >>> aedtapp.post.create_report("S(1,1)",variations=variations,plot_type="Smith Chart") + """ + if sweep: setup_sweep_name = [ - i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0] and sweep_name in i + i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0] and sweep in i ] else: setup_sweep_name = [i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0]] @@ -451,8 +430,6 @@ def create_report( plot_type=plot_type, context=context, polyline_points=polyline_points, - plotname=plotname, - setup_sweep_name=setup_sweep_name[0], ) return None @@ -462,20 +439,20 @@ class Setup(CommonSetup): Parameters ---------- - app : :class:`pyaedt.application.Analysis3D.FieldAnalysis3D` + app : :class:`pyaedt.application.Analysis.Analysis` Inherited app object. - solutiontype : int, str + solution_type : int, str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True``. If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - CommonSetup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + CommonSetup.__init__(self, app, solution_type, name, is_new_setup) @pyaedt_function_handler() def create(self): @@ -602,7 +579,7 @@ def _expression_cache( isconvergence = isconvergence_list[i] else: isconvergence = isconvergence_list - if type(intrinsics_list) is list: + if isinstance(intrinsics_list, list): intrinsics = intrinsics_list[i] else: intrinsics = intrinsics_list @@ -723,13 +700,13 @@ def enable_expression_cache( self.omodule.EditSetup(self.name, arg) return True - @pyaedt_function_handler() - def enable(self, setup_name=None): + @pyaedt_function_handler(setup_name="name") + def enable(self, name=None): """Enable a setup. Parameters ---------- - setup_name : str, optional + name : str, optional Name of the setup. The default is ``None``. Returns @@ -742,19 +719,19 @@ def enable(self, setup_name=None): >>> oModule.EditSetup """ - if not setup_name: - setup_name = self.name + if not name: + name = self.name - self.omodule.EditSetup(setup_name, ["NAME:" + setup_name, "IsEnabled:=", True]) + self.omodule.EditSetup(name, ["NAME:" + name, "IsEnabled:=", True]) return True - @pyaedt_function_handler() - def disable(self, setup_name=None): + @pyaedt_function_handler(setup_name="name") + def disable(self, name=None): """Disable a setup. Parameters ---------- - setup_name : str, optional + name : str, optional Name of the setup. The default is ``None``. Returns @@ -767,19 +744,21 @@ def disable(self, setup_name=None): >>> oModule.EditSetup """ - if not setup_name: - setup_name = self.name + if not name: + name = self.name - self.omodule.EditSetup(setup_name, ["NAME:" + setup_name, "IsEnabled:", False]) + self.omodule.EditSetup(name, ["NAME:" + name, "IsEnabled:", False]) return True - @pyaedt_function_handler() + @pyaedt_function_handler( + design_name="design", solution_name="solution", parameters_dict="parameters", project_name="project" + ) def add_mesh_link( self, - design_name, - solution_name=None, - parameters_dict=None, - project_name="This Project*", + design, + solution=None, + parameters=None, + project="This Project*", force_source_to_solve=True, preserve_partner_solution=True, apply_mesh_operations=True, @@ -789,15 +768,15 @@ def add_mesh_link( Parameters ---------- - design_name : str + design : str Name of the design. - solution_name : str, optional - Name of the solution in the format ``"setupname : solutionname"``. - If ``None`` the default value is ``setupname : LastAdaptive``. - parameters_dict : dict, optional + solution : str, optional + Name of the solution in the format ``"setup_name : solution_name"``. + If ``None``, the default value is ``setup_name : LastAdaptive``. + parameters : dict, optional Dictionary of the parameters. - If ``None`` the default value is `appname.available_variations.nominal_w_values_dict`. - project_name : str, optional + If ``None``, the default is `appname.available_variations.nominal_w_values_dict`. + project : str, optional Name of the project with the design. The default is ``"This Project*"``. However, you can supply the full path and name to another project. force_source_to_solve : bool, optional @@ -834,48 +813,47 @@ def add_mesh_link( design_type = self.p_app.design_type meshlinks["Product"] = design_type # design name - if not design_name or design_name is None: + if not design or design is None: raise ValueError("Provide design name to add mesh link to.") - elif design_name not in self.p_app.design_list: + elif design not in self.p_app.design_list: raise ValueError("Design does not exist in current project.") else: - meshlinks["Design"] = design_name + meshlinks["Design"] = design # project name - if project_name != "This Project*": - if os.path.exists(project_name): - meshlinks["Project"] = project_name + if project != "This Project*": + if os.path.exists(project): + meshlinks["Project"] = project meshlinks["PathRelativeTo"] = "SourceProduct" else: raise ValueError("Project file path provided does not exist.") else: - meshlinks["Project"] = project_name + meshlinks["Project"] = project meshlinks["PathRelativeTo"] = "TargetProject" # if self.p_app.solution_type == "SBR+": meshlinks["ImportMesh"] = True # solution name - if solution_name is None: + if solution is None: meshlinks["Soln"] = "{} : LastAdaptive".format( - self.p_app.oproject.GetDesign(design_name).GetChildObject("Analysis").GetChildNames()[0] + self.p_app.oproject.GetDesign(design).GetChildObject("Analysis").GetChildNames()[0] ) elif ( - solution_name.split()[0] - in self.p_app.oproject.GetDesign(design_name).GetChildObject("Analysis").GetChildNames() + solution.split()[0] in self.p_app.oproject.GetDesign(design).GetChildObject("Analysis").GetChildNames() ): - meshlinks["Soln"] = "{} : LastAdaptive".format(solution_name.split()[0]) + meshlinks["Soln"] = "{} : LastAdaptive".format(solution.split()[0]) else: raise ValueError("Setup does not exist in current design.") # parameters meshlinks["Params"] = OrderedDict({}) - if parameters_dict is None: - parameters_dict = self.p_app.available_variations.nominal_w_values_dict - for el in parameters_dict: + if parameters is None: + parameters = self.p_app.available_variations.nominal_w_values_dict + for el in parameters: meshlinks["Params"][el] = el else: - for el in parameters_dict: + for el in parameters: if el in list(self._app.available_variations.nominal_w_values_dict.keys()): meshlinks["Params"][el] = el else: - meshlinks["Params"][el] = parameters_dict[el] + meshlinks["Params"][el] = parameters[el] meshlinks["ForceSourceToSolve"] = force_source_to_solve meshlinks["PreservePartnerSoln"] = preserve_partner_solution meshlinks["ApplyMeshOp"] = apply_mesh_operations @@ -888,14 +866,16 @@ def add_mesh_link( self.auto_update = auto_update return False - @pyaedt_function_handler() + @pyaedt_function_handler( + design_name="design", solution_name="solution", parameters_dict="parameters", project_name="project" + ) def start_continue_from_previous_setup( self, - design_name, - solution_name, + design, + solution, map_variables_by_name=True, - parameters_dict=None, - project_name="This Project*", + parameters=None, + project="This Project*", force_source_to_solve=True, preserve_partner_solution=True, ): @@ -903,19 +883,19 @@ def start_continue_from_previous_setup( Parameters ---------- - design_name : str + design : str Name of the design. - solution_name : str, optional - Name of the solution in the format ``"setupname : solutionname"``. + solution : str, optional + Name of the solution in the format ``"setup_name : solution_name"``. For example, ``"Setup1 : Transient", "MySetup : LastAdaptive"``. map_variables_by_name : bool, optional Whether variables are mapped by name from the source design. The default is ``True``. - parameters_dict : dict, optional + parameters : dict, optional Dictionary of the parameters. This parameter is not considered if - ``map_variables_by_name = True``. If ``None``, the default value is + ``map_variables_by_name=True``. If ``None``, the default is ``appname.available_variations.nominal_w_values_dict``. - project_name : str, optional + project : str, optional Name of the project with the design. The default is ``"This Project*"``. However, you can supply the full path and name to another project. force_source_to_solve : bool, optional @@ -937,7 +917,7 @@ def start_continue_from_previous_setup( -------- >>> m2d = pyaedt.Maxwell2d() >>> setup = m2d.get_setup("Setup1") - >>> setup.start_continue_from_previous_setup(design_name="IM", solution_name="Setup1 : Transient") + >>> setup.start_continue_from_previous_setup(design="IM",solution="Setup1 : Transient") """ @@ -948,44 +928,44 @@ def start_continue_from_previous_setup( # parameters params = OrderedDict({}) if map_variables_by_name: - parameters_dict = self.p_app.available_variations.nominal_w_values_dict - for k, v in parameters_dict.items(): + parameters = self.p_app.available_variations.nominal_w_values_dict + for k, v in parameters.items(): params[k] = k - elif parameters_dict is None: - parameters_dict = self.p_app.available_variations.nominal_w_values_dict - for k, v in parameters_dict.items(): + elif parameters is None: + parameters = self.p_app.available_variations.nominal_w_values_dict + for k, v in parameters.items(): params[k] = v else: - for k, v in parameters_dict.items(): + for k, v in parameters.items(): if k in list(self._app.available_variations.nominal_w_values_dict.keys()): params[k] = v else: - params[k] = parameters_dict[v] + params[k] = parameters[v] prev_solution = OrderedDict({}) # project name - if project_name != "This Project*": - if os.path.exists(project_name): - prev_solution["Project"] = project_name + if project != "This Project*": + if os.path.exists(project): + prev_solution["Project"] = project self.props["PathRelativeTo"] = "SourceProduct" else: raise ValueError("Project file path provided does not exist.") else: - prev_solution["Project"] = project_name + prev_solution["Project"] = project self.props["PathRelativeTo"] = "TargetProject" # design name - if not design_name or design_name is None: + if not design or design is None: raise ValueError("Provide design name to add mesh link to.") - elif design_name not in self.p_app.design_list: + elif design not in self.p_app.design_list: raise ValueError("Design does not exist in current project.") else: - prev_solution["Design"] = design_name + prev_solution["Design"] = design # solution name - if solution_name: - prev_solution["Soln"] = solution_name + if solution: + prev_solution["Soln"] = solution else: raise ValueError("Provide a valid solution name.") @@ -1017,30 +997,30 @@ class SetupCircuit(CommonSetup): ---------- app : :class:`pyaedt.application.AnalysisNexxim.FieldAnalysisCircuit` Inherited app object. - solutiontype : str, int + solution_type : str, int Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True.`` If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - CommonSetup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + CommonSetup.__init__(self, app, solution_type, name, is_new_setup) - @pyaedt_function_handler() - def _init_props(self, isnewsetup=False): + @pyaedt_function_handler(isnewsetup="is_new_setup") + def _init_props(self, is_new_setup=False): props = {} - if isnewsetup: + if is_new_setup: setup_template = SetupKeys.get_setup_templates()[self.setuptype] self.props = SetupProps(self, setup_template) else: self.props = SetupProps(self, OrderedDict()) try: setups_data = self.p_app.design_properties["SimSetups"]["SimSetup"] - if type(setups_data) is not list: + if not isinstance(setups_data, list): setups_data = [setups_data] for setup in setups_data: if self.name == setup["Name"]: @@ -1489,13 +1469,13 @@ def enable_expression_cache( self.omodule.EditSetup(self.name, arg) return True - @pyaedt_function_handler() - def enable(self, setup_name=None): + @pyaedt_function_handler(setup_name="name") + def enable(self, name=None): """Enable a setup. Parameters ---------- - setup_name : str, optional + name : str, optional Name of the setup. The default is ``None``. Returns @@ -1508,18 +1488,18 @@ def enable(self, setup_name=None): >>> oModule.EditSetup """ - if not setup_name: - setup_name = self.name - self._odesign.EnableSolutionSetup(setup_name, True) + if not name: + name = self.name + self._odesign.EnableSolutionSetup(name, True) return True - @pyaedt_function_handler() - def disable(self, setup_name=None): + @pyaedt_function_handler(setup_name="name") + def disable(self, name=None): """Disable a setup. Parameters ---------- - setup_name : str, optional + name : str, optional Name of the setup. The default is ``None``. Returns @@ -1532,9 +1512,9 @@ def disable(self, setup_name=None): >>> oModule.EditSetup """ - if not setup_name: - setup_name = self.name - self._odesign.EnableSolutionSetup(setup_name, False) + if not name: + name = self.name + self._odesign.EnableSolutionSetup(name, False) return True @pyaedt_function_handler() @@ -1546,9 +1526,9 @@ def get_solution_data( primary_sweep_variable=None, report_category=None, context=None, - subdesign_id=None, polyline_points=1001, math_formula=None, + sweep=None, ): """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. Data to be retrieved from Electronics Desktop are any simulation results available in that @@ -1588,14 +1568,12 @@ def get_solution_data( 3. Reduce Matrix Name for Q2d/Q3d solution 4. Infinite Sphere name for Far Fields Plot. 5. Dictionary. If dictionary is passed, key is the report property name and value is property value. - subdesign_id : int, optional - Subdesign ID for exporting a Touchstone file of this subdesign. - This parameter is valid for ``Circuit`` only. - The default value is ``None``. + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. polyline_points : int, optional Number of points on which to create the report for plots on polylines. This parameter is valid for ``Fields`` plot only. - math_formula : str, optional + sweep : str, optional One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. @@ -1616,10 +1594,9 @@ def get_solution_data( primary_sweep_variable=primary_sweep_variable, report_category=report_category, context=context, - subdesign_id=subdesign_id, polyline_points=polyline_points, math_formula=math_formula, - setup_sweep_name=self.name, + sweep=sweep, ) @pyaedt_function_handler() @@ -1635,7 +1612,7 @@ def create_report( context=None, subdesign_id=None, polyline_points=1001, - plotname=None, + name=None, ): """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plots or data tables. @@ -1664,10 +1641,10 @@ def create_report( The default is ``None``. It can be `None`, `"Differential Pairs"`,`"RL"`, `"Sources"`, `"Vias"`,`"Bondwires"`, `"Probes"` for Hfss3dLayout or Reduce Matrix Name for Q2d/Q3d solution or Infinite Sphere name for Far Fields Plot. - plotname : str, optional + name : str, optional Name of the plot. The default is ``None``. polyline_points : int, optional, - Number of points on which create the report for plots on polylines. + Number of points for creating the report for plots on polylines. subdesign_id : int, optional Specify a subdesign ID to export a Touchstone file of this subdesign. Valid for Circuit Only. The default value is ``None``. @@ -1693,10 +1670,8 @@ def create_report( report_category=report_category, plot_type=plot_type, context=context, - polyline_points=polyline_points, - plotname=plotname, subdesign_id=subdesign_id, - setup_sweep_name=self.name, + polyline_points=polyline_points, ) @@ -1707,22 +1682,22 @@ class Setup3DLayout(CommonSetup): ---------- app : :class:`pyaedt.application.Analysis3DLayout.FieldAnalysis3DLayout` Inherited app object. - solutiontype : int or str + solution_type : int or str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True.`` If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - CommonSetup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + CommonSetup.__init__(self, app, solution_type, name, is_new_setup) - @pyaedt_function_handler() - def _init_props(self, isnewsetup=False): - if isnewsetup: + @pyaedt_function_handler(isnewsetup="is_new_setup") + def _init_props(self, is_new_setup=False): + if is_new_setup: setup_template = SetupKeys.get_setup_templates()[self.setuptype] self.props = SetupProps(self, setup_template) else: @@ -1753,24 +1728,18 @@ def is_solved(self): if self.props.get("SolveSetupType", "HFSS") == "HFSS": combined_name = "{} : Last Adaptive".format(self.name) expressions = [i for i in self.p_app.post.available_report_quantities(solution=combined_name)] - sol = self._app.post.reports_by_category.standard(setup_name=combined_name, expressions=expressions[0]) + sol = self._app.post.reports_by_category.standard(expressions=expressions[0], setup=combined_name) elif self.props.get("SolveSetupType", "HFSS") == "SIwave": combined_name = "{} : {}".format(self.name, self.sweeps[0].name) expressions = [i for i in self.p_app.post.available_report_quantities(solution=combined_name)] - sol = self._app.post.reports_by_category.standard( - setup_name=combined_name, - expressions=expressions[0], - ) + sol = self._app.post.reports_by_category.standard(expressions=expressions[0], setup=combined_name) elif self.props.get("SolveSetupType", "HFSS") == "SIwaveDCIR": expressions = self.p_app.post.available_report_quantities(solution=self.name, is_siwave_dc=True) - sol = self._app.post.reports_by_category.standard( - setup_name=self.name, - expressions=expressions[0], - ) + sol = self._app.post.reports_by_category.standard(expressions=expressions[0], setup=self.name) else: expressions = [i for i in self.p_app.post.available_report_quantities(solution=self.name)] - sol = self._app.post.reports_by_category.standard(setup_name=self.name, expressions=expressions[0]) + sol = self._app.post.reports_by_category.standard(expressions=expressions[0], setup=self.name) if identify_setup(self.props): sol.domain = "Time" return True if sol.get_solution_data() else False @@ -2150,15 +2119,16 @@ def export_to_q3d(self, file_fullname, keep_net_name=False): self.p_app.logger.error("Exporting layout while keeping net name is not supported with IronPython") return succeeded - @pyaedt_function_handler() - def add_sweep(self, sweepname=None, sweeptype="Interpolating"): + @pyaedt_function_handler(sweepname="name", sweeptype="sweep_type") + def add_sweep(self, name=None, sweep_type="Interpolating"): """Add a frequency sweep. Parameters ---------- - sweepname : str, optional - Name of the sweep. The default is ``None``. - sweeptype : str, optional + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. + sweep_type : str, optional Type of the sweep. Options are ``"Fast"``, ``"Interpolating"``, and ``"Discrete"``. The default is ``"Interpolating"``. @@ -2173,22 +2143,23 @@ def add_sweep(self, sweepname=None, sweeptype="Interpolating"): >>> oModule.AddSweep """ - if not sweepname: - sweepname = generate_unique_name("Sweep") - sweep_n = SweepHFSS3DLayout(self, sweepname, sweeptype) + if not name: + name = generate_unique_name("Sweep") + sweep_n = SweepHFSS3DLayout(self, name, sweep_type) if sweep_n.create(): self.sweeps.append(sweep_n) return sweep_n return False - @pyaedt_function_handler() - def get_sweep(self, sweepname=None): + @pyaedt_function_handler(sweepname="name") + def get_sweep(self, name=None): """Return frequency sweep object of a given sweep. Parameters ---------- - sweepname : str, optional - Name of the sweep. the default is ``None`` which returns the first sweep. + name : str, optional + Name of the sweep. The default is ``None``, in which case + the first sweep is used. Returns ------- @@ -2199,12 +2170,12 @@ def get_sweep(self, sweepname=None): >>> h3d = Hfss3dLayout() >>> setup = h3d.get_setup('Pyaedt_setup') >>> sweep = setup.get_sweep('Sweep1') - >>> sweep.add_subrange("LinearCount", 0, 10, 1, "Hz") - >>> sweep.add_subrange("LogScale", 10, 1E8, 100, "Hz") + >>> sweep.add_subrange("LinearCount",0,10,1,"Hz") + >>> sweep.add_subrange("LogScale",10,1E8,100,"Hz") """ - if sweepname: + if name: for sweep in self.sweeps: - if sweepname == sweep.name: + if name == sweep.name: return sweep else: if self.sweeps: @@ -2255,20 +2226,20 @@ class SetupHFSS(Setup, object): Parameters ---------- - app : :class:`pyaedt.application.Analysis3D.FieldAnalysis3D` + app : :class:`pyaedt.application.Analysis.Analysis` Inherited app object. - solutiontype : int, str + solution_type : int, str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True``. If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - Setup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + Setup.__init__(self, app, solution_type, name, is_new_setup) @pyaedt_function_handler() def get_derivative_variables(self): @@ -2309,14 +2280,14 @@ def add_derivatives(self, derivative_list): self.auto_update = True return self.update() - @pyaedt_function_handler() + @pyaedt_function_handler(freqstart="start_frequency", freqstop="stop_frequency", sweepname="name") def create_frequency_sweep( self, unit=None, - freqstart=1, - freqstop=10, + start_frequency=1.0, + stop_frequency=10.0, num_of_freq_points=None, - sweepname=None, + name=None, save_fields=True, save_rad_fields=False, sweep_type="Discrete", @@ -2328,19 +2299,20 @@ def create_frequency_sweep( Parameters ---------- unit : str, optional - Frequency Units. The default is ``None`` which takes the Default Desktop units. - freqstart : float, str, optional - Starting frequency of the sweep. The default is ``1``. - If a unit is passed with number, such as ``"1MHz"``, the unit will be ignored. - freqstop : float, str, optional - Stopping frequency of the sweep. The default is ``10``. + Unit of the frequency.. The default is ``None``, in which case the default desktop units are used. + start_frequency : float, str, optional + Starting frequency of the sweep. The default is ``1.0``. + If a unit is passed with number, such as ``"1MHz"``, the unit is ignored. + stop_frequency : float, str, optional + Stopping frequency of the sweep. The default is ``10.0``. If a unit is passed with number, such as ``"1MHz"`, the unit is ignored. num_of_freq_points : int Number of frequency points in the range. The default is ``401`` for a sweep type of ``"Interpolating"`` or ``"Fast"``. The default is ``5`` for a sweep type of ``"Discrete"``. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save the fields. The default is ``True``. save_rad_fields : bool, optional @@ -2372,10 +2344,7 @@ def create_frequency_sweep( named ``"LinearCountSweep"``. >>> setup = hfss.create_setup("LinearCountSetup") - >>> linear_count_sweep = hfss.create_linear_count_sweep(setupname="LinearCountSetup", - ... sweepname="LinearCountSweep", - ... unit="MHz", freqstart=1.1e3, - ... freqstop=1200.1, num_of_freq_points=1658) + >>> linear_count_sweep = setup.create_linear_count_sweep(,, >>> type(linear_count_sweep) @@ -2388,21 +2357,21 @@ def create_frequency_sweep( elif sweep_type == "Discrete": num_of_freq_points = num_of_freq_points or 5 else: # pragma: no cover - raise ValueError("Invalid `sweep_type`. It has to be either 'Discrete', 'Interpolating', or 'Fast'") + raise ValueError("Invalid `sweep_type`. It has to be 'Discrete', 'Interpolating', or 'Fast'") - if sweepname is None: - sweepname = generate_unique_name("Sweep") + if name is None: + name = generate_unique_name("Sweep") - if sweepname in [sweep.name for sweep in self.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname) - sweepdata = self.add_sweep(sweepname, sweep_type) + if name in [sweep.name for sweep in self.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = self.add_sweep(name, sweep_type) if not sweepdata: return False sweepdata.props["RangeType"] = "LinearCount" - sweepdata.props["RangeStart"] = self.p_app.value_with_units(freqstart, unit, "Frequency") - sweepdata.props["RangeEnd"] = self.p_app.value_with_units(freqstop, unit, "Frequency") + sweepdata.props["RangeStart"] = self.p_app.value_with_units(start_frequency, unit, "Frequency") + sweepdata.props["RangeEnd"] = self.p_app.value_with_units(stop_frequency, unit, "Frequency") sweepdata.props["RangeCount"] = num_of_freq_points sweepdata.props["Type"] = sweep_type @@ -2414,17 +2383,17 @@ def create_frequency_sweep( sweepdata.props["SaveFields"] = save_fields sweepdata.props["SaveRadFields"] = save_rad_fields sweepdata.update() - self._app.logger.info("Linear count sweep {} has been correctly created".format(sweepname)) + self._app.logger.info("Linear count sweep {} has been correctly created".format(name)) return sweepdata - @pyaedt_function_handler() + @pyaedt_function_handler(freqstart="start_frequency", freqstop="stop_frequency", sweepname="name") def create_linear_step_sweep( self, unit="GHz", - freqstart=0.1, - freqstop=2, + start_frequency=0.1, + stop_frequency=2.0, step_size=0.05, - sweepname=None, + name=None, save_fields=True, save_rad_fields=False, sweep_type="Discrete", @@ -2435,14 +2404,15 @@ def create_linear_step_sweep( ---------- unit : str Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. - freqstart : float - Starting frequency of the sweep. - freqstop : float - Stopping frequency of the sweep. - step_size : float - Frequency size of the step. - sweepname : str, optional - Name of the sweep. The default is ``None``. + start_frequency : float, optional + Starting frequency of the sweep. The default is ``0.1``. + stop_frequency : float, optional + Stopping frequency of the sweep. The default is ``2.0``. + step_size : float, optional + Frequency size of the step. The default is ``0.05``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save the fields. The default is ``True``. save_rad_fields : bool, optional @@ -2468,28 +2438,28 @@ def create_linear_step_sweep( named ``"LinearStepSweep"``. >>> setup = hfss.create_setup("LinearStepSetup") - >>> linear_step_sweep = setup.create_linear_step_sweep(sweepname="LinearStepSweep", - ... unit="MHz", freqstart=1.1e3, - ... freqstop=1200.1, step_size=153.8) + >>> linear_step_sweep = setup.create_linear_step_sweep(name="LinearStepSweep", + ... unit="MHz", start_frequency=1.1e3, + ... stop_frequency=1200.1, step_size=153.8) >>> type(linear_step_sweep) """ if sweep_type not in ["Discrete", "Interpolating", "Fast"]: raise AttributeError("Invalid in `sweep_type`. It has to either 'Discrete', 'Interpolating', or 'Fast'") - if sweepname is None: - sweepname = generate_unique_name("Sweep") - - if sweepname in [sweep.name for sweep in self.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname) - sweepdata = self.add_sweep(sweepname, sweep_type) + if name is None: + name = generate_unique_name("Sweep") + + if name in [sweep.name for sweep in self.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = self.add_sweep(name, sweep_type) if not sweepdata: return False sweepdata.props["RangeType"] = "LinearStep" - sweepdata.props["RangeStart"] = str(freqstart) + unit - sweepdata.props["RangeEnd"] = str(freqstop) + unit + sweepdata.props["RangeStart"] = str(start_frequency) + unit + sweepdata.props["RangeEnd"] = str(stop_frequency) + unit sweepdata.props["RangeStep"] = str(step_size) + unit sweepdata.props["SaveFields"] = save_fields sweepdata.props["SaveRadFields"] = save_rad_fields @@ -2501,15 +2471,15 @@ def create_linear_step_sweep( sweepdata.props["InterpMinSolns"] = 0 sweepdata.props["InterpMinSubranges"] = 1 sweepdata.update() - self._app.logger.info("Linear step sweep {} has been correctly created".format(sweepname)) + self._app.logger.info("Linear step sweep {} has been correctly created".format(name)) return sweepdata - @pyaedt_function_handler() + @pyaedt_function_handler(sweepname="name") def create_single_point_sweep( self, unit="GHz", freq=1, - sweepname=None, + name=None, save_single_field=True, save_fields=False, save_rad_fields=False, @@ -2518,17 +2488,16 @@ def create_single_point_sweep( Parameters ---------- - setupname : str - Name of the setup. unit : str Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. freq : float, list Frequency of the single point or list of frequencies to create distinct single points. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_single_field : bool, list, optional Whether to save the fields of the single point. The default is ``True``. - If a list is specified, the length must be the same as freq length. + If a list is specified, the length must be the same as the frequency length. save_fields : bool, optional Whether to save the fields for all points and subranges defined in the sweep. The default is ``False``. save_rad_fields : bool, optional @@ -2551,15 +2520,13 @@ def create_single_point_sweep( named ``"SinglePointSweep"``. >>> setup = hfss.create_setup("LinearStepSetup") - >>> single_point_sweep = hfss.create_single_point_sweep(setupname="LinearStepSetup", - ... sweepname="SinglePointSweep", - ... unit="MHz", freq=1.1e3) + >>> single_point_sweep = setup.create_single_point_sweep(name="SinglePointSweep", unit="MHz", freq=1.1e3) >>> type(single_point_sweep) """ - if sweepname is None: - sweepname = generate_unique_name("SinglePoint") + if name is None: + name = generate_unique_name("SinglePoint") if isinstance(save_single_field, list): if not isinstance(freq, list) or len(save_single_field) != len(freq): @@ -2582,11 +2549,11 @@ def create_single_point_sweep( if add_subranges: save_single_field = [save0] * len(freq) - if sweepname in [sweep.name for sweep in self.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname) - sweepdata = self.add_sweep(sweepname, "Discrete") + if name in [sweep.name for sweep in self.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = self.add_sweep(name, "Discrete") sweepdata.props["RangeType"] = "SinglePoints" sweepdata.props["RangeStart"] = str(freq0) + unit sweepdata.props["RangeEnd"] = str(freq0) + unit @@ -2598,18 +2565,19 @@ def create_single_point_sweep( for f, s in zip(freq, save_single_field): sweepdata.add_subrange(rangetype="SinglePoints", start=f, unit=unit, save_single_fields=s) sweepdata.update() - self._app.logger.info("Single point sweep {} has been correctly created".format(sweepname)) + self._app.logger.info("Single point sweep {} has been correctly created".format(name)) return sweepdata - @pyaedt_function_handler() - def add_sweep(self, sweepname=None, sweeptype="Interpolating"): + @pyaedt_function_handler(sweepname="name", sweeptype="sweep_type") + def add_sweep(self, name=None, sweep_type="Interpolating"): """Add a sweep to the project. Parameters ---------- - sweepname : str, optional - Name of the sweep. The default is ``None``. - sweeptype : str, optional + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. + sweep_type : str, optional Type of the sweep. The default is ``"Interpolating"``. Returns @@ -2622,30 +2590,31 @@ def add_sweep(self, sweepname=None, sweeptype="Interpolating"): >>> oModule.InsertFrequencySweep """ - if not sweepname: - sweepname = generate_unique_name("Sweep") + if not name: + name = generate_unique_name("Sweep") if self.setuptype == 7: self._app.logger.warning("This method only applies to HFSS and Q3D. Use add_eddy_current_sweep method.") return False if self.setuptype <= 4: - sweep_n = SweepHFSS(self, sweepname=sweepname, sweeptype=sweeptype) + sweep_n = SweepHFSS(self, name=name, sweep_type=sweep_type) elif self.setuptype in [14, 30, 31]: - sweep_n = SweepMatrix(self, sweepname=sweepname, sweeptype=sweeptype) + sweep_n = SweepMatrix(self, name=name, sweep_type=sweep_type) else: - self._app.logger.warning("This method only applies to HFSS, Q2D and Q3D.") + self._app.logger.warning("This method only applies to HFSS, Q2D, and Q3D.") return False sweep_n.create() self.sweeps.append(sweep_n) return sweep_n - @pyaedt_function_handler() - def get_sweep(self, sweepname=None): + @pyaedt_function_handler(sweepname="name") + def get_sweep(self, name=None): """Return frequency sweep object of a given sweep. Parameters ---------- - sweepname : str, optional - Name of the sweep. the default is ``None`` which returns the first sweep. + name : str, optional + Name of the sweep. The default is ``None``, in which case the + first sweep is used. Returns ------- @@ -2656,12 +2625,12 @@ def get_sweep(self, sweepname=None): >>> hfss = Hfss() >>> setup = hfss.get_setup('Pyaedt_setup') >>> sweep = setup.get_sweep('Sweep1') - >>> sweep.add_subrange("LinearCount", 0, 10, 1, "Hz") - >>> sweep.add_subrange("LogScale", 10, 1E8, 100, "Hz") + >>> sweep.add_subrange("LinearCount",0,10,1,"Hz") + >>> sweep.add_subrange("LogScale",10,1E8,100,"Hz") """ - if sweepname: + if name: for sweep in self.sweeps: - if sweepname == sweep.name: + if name == sweep.name: return sweep else: if self.sweeps: @@ -2691,13 +2660,13 @@ def get_sweep_names(self): """ return self.omodule.GetSweeps(self.name) - @pyaedt_function_handler() - def delete_sweep(self, sweepname): + @pyaedt_function_handler(sweepname="name") + def delete_sweep(self, name): """Delete a sweep. Parameters ---------- - sweepname : str + name : str Name of the sweep. Returns @@ -2716,15 +2685,15 @@ def delete_sweep(self, sweepname): >>> import pyaedt >>> hfss = pyaedt.Hfss() - >>> setup1 = hfss.create_setup(setupname='Setup1') + >>> setup1 = hfss.create_setup(name='Setup1') >>> setup1.create_frequency_sweep( "GHz", 24, 24.25, 26, "Sweep1", sweep_type="Fast", ) >>> setup1.delete_sweep("Sweep1") """ - if sweepname in self.get_sweep_names(): - self.sweeps = [sweep for sweep in self.sweeps if sweep.name != sweepname] - self.omodule.DeleteSweep(self.name, sweepname) + if name in self.get_sweep_names(): + self.sweeps = [sweep for sweep in self.sweeps if sweep.name != name] + self.omodule.DeleteSweep(self.name, name) return True return False @@ -2854,20 +2823,20 @@ class SetupHFSSAuto(Setup, object): Parameters ---------- - app : :class:`pyaedt.application.Analysis3D.FieldAnalysis3D` + app : :class:`pyaedt.application.Analysis.Analysis` Inherited app object. - solutiontype : int, str + solution_type : int, str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True``. If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - Setup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + Setup.__init__(self, app, solution_type, name, is_new_setup) @pyaedt_function_handler() def get_derivative_variables(self): @@ -2908,13 +2877,13 @@ def add_derivatives(self, derivative_list): self.auto_update = True return self.update() - @pyaedt_function_handler() - def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear=False): + @pyaedt_function_handler(rangetype="range_type") + def add_subrange(self, range_type, start, end=None, count=None, unit="GHz", clear=False): """Add a subrange to the sweep. Parameters ---------- - rangetype : str + range_type : str Type of the subrange. Options are ``"LinearCount"``, ``"LinearStep"``, and ``"LogScale"``. start : float @@ -2935,27 +2904,27 @@ def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear """ if clear: - self.props["Sweeps"]["Sweep"]["RangeType"] = rangetype + self.props["Sweeps"]["Sweep"]["RangeType"] = range_type self.props["Sweeps"]["Sweep"]["RangeStart"] = str(start) + unit - if rangetype == "LinearCount": + if range_type == "LinearCount": self.props["Sweeps"]["Sweep"]["RangeEnd"] = str(end) + unit self.props["Sweeps"]["Sweep"]["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": self.props["Sweeps"]["Sweep"]["RangeEnd"] = str(end) + unit self.props["Sweeps"]["Sweep"]["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": self.props["Sweeps"]["Sweep"]["RangeEnd"] = str(end) + unit self.props["Sweeps"]["Sweep"]["RangeSamples"] = count self.props["Sweeps"]["Sweep"]["SweepRanges"] = {"Subrange": []} return self.update() - sweep_range = {"RangeType": rangetype, "RangeStart": str(start) + unit} - if rangetype == "LinearCount": + sweep_range = {"RangeType": range_type, "RangeStart": str(start) + unit} + if range_type == "LinearCount": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeCount"] = self.props["RangeCount"] sweep_range["RangeSamples"] = count @@ -2966,16 +2935,16 @@ def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear self.props["Sweeps"]["Sweep"]["SweepRanges"]["Subrange"].append(sweep_range) return self.update() - @pyaedt_function_handler() - def enable_adaptive_setup_single(self, freq=None, max_passes=None, max_delta_s=None): + @pyaedt_function_handler(freq="frequency") + def enable_adaptive_setup_single(self, frequency=None, max_passes=None, max_delta_s=None): """Enable HFSS single frequency setup. Parameters ---------- - freq : float, str, optional - Frequency at which to set the adaptive convergence. - The default is ``None`` which will not update the value in setup. - You can enter a float value in (GHz) or a string. + frequency : float, str, optional + Frequency to set the adaptive convergence at. + The default is ``None``, in which case the value in the setup is + not updated. You can specify a float value (GHz) or a string. max_passes : int, optional Maximum number of adaptive passes. The default is ``None`` which will not update the value in setup. max_delta_s : float, optional @@ -2991,10 +2960,10 @@ def enable_adaptive_setup_single(self, freq=None, max_passes=None, max_delta_s=N return False self.auto_update = False self.props["SolveType"] = "Single" - if isinstance(freq, (int, float)): - freq = "{}GHz".format(freq) - if freq: - self.props["Frequency"] = freq + if isinstance(frequency, (int, float)): + frequency = "{}GHz".format(frequency) + if frequency: + self.props["Frequency"] = frequency if max_passes: self.props["MaximumPasses"] = max_passes if max_delta_s: @@ -3002,17 +2971,18 @@ def enable_adaptive_setup_single(self, freq=None, max_passes=None, max_delta_s=N self.auto_update = True return self.update() - @pyaedt_function_handler() - def enable_adaptive_setup_broadband(self, low_frequency, high_frquency, max_passes=6, max_delta_s=0.02): + @pyaedt_function_handler(high_frquency="high_frequency") + def enable_adaptive_setup_broadband(self, low_frequency, high_frequency, max_passes=6, max_delta_s=0.02): """Enable HFSS broadband setup. Parameters ---------- low_frequency : float, str - Lower Frequency at which set the adaptive convergence. - It can be float (GHz) or str. - high_frquency : float, str - Lower Frequency at which set the adaptive convergence. It can be float (GHz) or str. + Lower frequency to set the adaptive convergence at. + You can specify a float value (GHz) or a string. + high_frequency : float, str + Lower frequency to set the adaptive convergence at. You can + specify a float value (GHz) or a string. max_passes : int, optional Maximum number of adaptive passes. The default is ``6``. max_delta_s : float, optional @@ -3032,10 +3002,10 @@ def enable_adaptive_setup_broadband(self, low_frequency, high_frquency, max_pass del self.props["MultipleAdaptiveFreqsSetup"][el] if isinstance(low_frequency, (int, float)): low_frequency = "{}GHz".format(low_frequency) - if isinstance(high_frquency, (int, float)): - high_frquency = "{}GHz".format(high_frquency) + if isinstance(high_frequency, (int, float)): + high_frequency = "{}GHz".format(high_frequency) self.props["MultipleAdaptiveFreqsSetup"]["Low"] = low_frequency - self.props["MultipleAdaptiveFreqsSetup"]["High"] = high_frquency + self.props["MultipleAdaptiveFreqsSetup"]["High"] = high_frequency self.props["MaximumPasses"] = max_passes self.props["MaxDeltaS"] = max_delta_s self.auto_update = True @@ -3088,28 +3058,28 @@ class SetupSBR(Setup, object): Parameters ---------- - app : :class:`pyaedt.application.Analysis3D.FieldAnalysis3D` + app : :class:`pyaedt.application.Analysis.Analysis` Inherited app object. - solutiontype : int, str + solution_type : int, str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True``. If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - Setup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + Setup.__init__(self, app, solution_type, name, is_new_setup) - @pyaedt_function_handler() - def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear=False): + @pyaedt_function_handler(rangetype="range_type") + def add_subrange(self, range_type, start, end=None, count=None, unit="GHz", clear=False): """Add a subrange to the sweep. Parameters ---------- - rangetype : str + range_type : str Type of the subrange. Options are ``"LinearCount"``, ``"LinearStep"``, and ``"LogScale"``. start : float @@ -3130,27 +3100,27 @@ def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear """ if clear: - self.props["Sweeps"]["Sweep"]["RangeType"] = rangetype + self.props["Sweeps"]["Sweep"]["RangeType"] = range_type self.props["Sweeps"]["Sweep"]["RangeStart"] = str(start) + unit - if rangetype == "LinearCount": + if range_type == "LinearCount": self.props["Sweeps"]["Sweep"]["RangeEnd"] = str(end) + unit self.props["Sweeps"]["Sweep"]["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": self.props["Sweeps"]["Sweep"]["RangeEnd"] = str(end) + unit self.props["Sweeps"]["Sweep"]["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": self.props["Sweeps"]["Sweep"]["RangeEnd"] = str(end) + unit self.props["Sweeps"]["Sweep"]["RangeSamples"] = count self.props["Sweeps"]["Sweep"]["SweepRanges"] = {"Subrange": []} return self.update() - sweep_range = {"RangeType": rangetype, "RangeStart": str(start) + unit} - if rangetype == "LinearCount": + sweep_range = {"RangeType": range_type, "RangeStart": str(start) + unit} + if range_type == "LinearCount": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeCount"] = self.props["RangeCount"] sweep_range["RangeSamples"] = count @@ -3167,20 +3137,20 @@ class SetupMaxwell(Setup, object): Parameters ---------- - app : :class:`pyaedt.application.Analysis3D.FieldAnalysis3D` + app : :class:`pyaedt.application.Analysis.Analysis` Inherited app object. - solutiontype : int, str + solution_type : int, str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True``. If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - Setup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + Setup.__init__(self, app, solution_type, name, is_new_setup) @pyaedt_function_handler() def add_eddy_current_sweep( @@ -3196,9 +3166,9 @@ def add_eddy_current_sweep( start : float Starting frequency. end : float, optional - Stopping frequency. Required for ``rangetype="LinearCount"|"LinearStep"|"LogScale"``. + Stopping frequency. Required for ``range_type="LinearCount"|"LinearStep"|"LogScale"``. count : int or float, optional - Frequency count or frequency step. Required for ``rangetype="LinearCount"|"LinearStep"|"LogScale"``. + Frequency count or frequency step. Required for ``range_type="LinearCount"|"LinearStep"|"LogScale"``. units : str, optional Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. The default is ``"Hz"``. clear : bool, optional @@ -3309,30 +3279,30 @@ class SetupQ3D(Setup, object): ---------- app : :class:`pyaedt.application.Analysis3D.FieldAnalysis3D` Inherited app object. - solutiontype : int, str + solution_type : int, str Type of the setup. - setupname : str, optional + name : str, optional Name of the setup. The default is ``"MySetupAuto"``. - isnewsetup : bool, optional + is_new_setup : bool, optional Whether to create the setup from a template. The default is ``True``. If ``False``, access is to the existing setup. """ - def __init__(self, app, solutiontype, setupname="MySetupAuto", isnewsetup=True): - Setup.__init__(self, app, solutiontype, setupname, isnewsetup) + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): + Setup.__init__(self, app, solution_type, name, is_new_setup) self._dc_enabled = True self._ac_rl_enbled = True self._capacitance_enabled = True - @pyaedt_function_handler() + @pyaedt_function_handler(freqstart="start_frequency", freqstop="stop_frequency", sweepname="name") def create_frequency_sweep( self, unit=None, - freqstart=0, - freqstop=20, + start_frequency=0.0, + stop_frequency=20.0, num_of_freq_points=None, - sweepname=None, + name=None, save_fields=True, sweep_type="Discrete", interpolation_tol=0.5, @@ -3343,19 +3313,20 @@ def create_frequency_sweep( Parameters ---------- unit : str, optional - Frequency units. The default is ``None`` which takes the Default Desktop units. - freqstart : float, str, optional - Starting frequency of the sweep. The default is ``0``. + Frequency units. The default is ``None``, in which case the default desktop units are used. + start_frequency : float, str, optional + Starting frequency of the sweep. The default is ``0.0``. If a unit is passed with the number, such as``"1MHz"``, the unit is ignored. - freqstop : float, str, optional - Stopping frequency of the sweep. The default is ``20``. + stop_frequency : float, str, optional + Stopping frequency of the sweep. The default is ``20.0``. If a unit is passed with the number, such as ``"1MHz"``, the unit is ignored. num_of_freq_points : int Number of frequency points in the range. The default is ``401`` for a sweep type of ``"Interpolating"`` or ``"Fast"``. The default is ``5`` for a sweep type of ``"Discrete"``. - sweepname : str, optional - Name of the sweep. The default is ``None``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save the fields. The default is ``True``. sweep_type : str, optional @@ -3382,7 +3353,8 @@ def create_frequency_sweep( >>> from pyaedt import Q3d >>> q3d = Q3d() >>> setup = q3d.create_setup("LinearCountSetup") - >>> sweep = setup.create_frequency_sweep(unit="GHz", freqstart=0.5, freqstop=1.5, sweepname="Sweep1") + >>> sweep = setup.create_frequency_sweep(unit="GHz", start_frequency=0.5, + ... stop_frequency=1.5, name="Sweep1") >>> q3d.release_desktop(True, True) """ if sweep_type in ["Interpolating", "Fast"]: @@ -3392,19 +3364,19 @@ def create_frequency_sweep( else: raise AttributeError("Invalid in `sweep_type`. It has to be either 'Discrete', 'Interpolating', or 'Fast'") - if sweepname is None: - sweepname = generate_unique_name("Sweep") + if name is None: + name = generate_unique_name("Sweep") - if sweepname in [sweep.name for sweep in self.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname) - sweepdata = self.add_sweep(sweepname, sweep_type) + if name in [sweep.name for sweep in self.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = self.add_sweep(name, sweep_type) if not sweepdata: return False sweepdata.props["RangeType"] = "LinearCount" - sweepdata.props["RangeStart"] = self.p_app.value_with_units(freqstart, unit, "Frequency") - sweepdata.props["RangeEnd"] = self.p_app.value_with_units(freqstop, unit, "Frequency") + sweepdata.props["RangeStart"] = self.p_app.value_with_units(start_frequency, unit, "Frequency") + sweepdata.props["RangeEnd"] = self.p_app.value_with_units(stop_frequency, unit, "Frequency") sweepdata.props["RangeCount"] = num_of_freq_points sweepdata.props["Type"] = sweep_type if sweep_type == "Interpolating": @@ -3415,34 +3387,35 @@ def create_frequency_sweep( sweepdata.props["SaveFields"] = save_fields if sweep_type == "Discrete" else False sweepdata.props["SaveRadFields"] = False sweepdata.update() - self._app.logger.info("Linear count sweep {} has been correctly created".format(sweepname)) + self._app.logger.info("Linear count sweep {} has been correctly created".format(name)) return sweepdata - @pyaedt_function_handler() + @pyaedt_function_handler(freqstart="start_frequency", freqstop="stop_frequency", sweepname="name") def create_linear_step_sweep( self, unit="GHz", - freqstart=0, - freqstop=2, + start_frequency=0.0, + stop_frequency=2.0, step_size=0.05, - sweepname=None, + name=None, save_fields=True, sweep_type="Discrete", ): - """Create a Sweep with a specified frequency step. + """Create a sweep with a specified frequency step. Parameters ---------- - unit : str - Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. - freqstart : float - Starting frequency of the sweep. - freqstop : float - Stopping frequency of the sweep. - step_size : float - Frequency size of the step. - sweepname : str, optional - Name of the sweep. The default is ``None``. + unit : str, optional + Unit of the frequency. The default is ``"GHz"``. + start_frequency : float, optional + Starting frequency of the sweep. The default is ``0.0``. + stop_frequency : float, optional + Stopping frequency of the sweep. The default is ``2.0``. + step_size : float, optional + Frequency size of the step. The default is ``0.05``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_fields : bool, optional Whether to save the fields. The default is ``True``. sweep_type : str, optional @@ -3466,27 +3439,27 @@ def create_linear_step_sweep( >>> from pyaedt import Q3d >>> q3d = Q3d() >>> setup = q3d.create_setup("LinearStepSetup") - >>> linear_step_sweep = setup.create_linear_step_sweep(sweepname="LinearStepSweep", - ... unit="MHz", freqstart=1.1e3, - ... freqstop=1200.1, step_size=153.8) + >>> linear_step_sweep = setup.create_linear_step_sweep(name="LinearStepSweep", + ... unit="MHz", start_frequency=1.1e3, + ... stop_frequency=1200.1, step_size=153.8) >>> type(linear_step_sweep) >>> q3d.release_desktop(True, True) """ if sweep_type not in ["Discrete", "Interpolating", "Fast"]: raise AttributeError("Invalid in `sweep_type`. It has to be either 'Discrete', 'Interpolating', or 'Fast'") - if sweepname is None: - sweepname = generate_unique_name("Sweep") - - if sweepname in [sweep.name for sweep in self.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname) - sweepdata = self.add_sweep(sweepname, sweep_type) + if name is None: + name = generate_unique_name("Sweep") + + if name in [sweep.name for sweep in self.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = self.add_sweep(name, sweep_type) if not sweepdata: return False sweepdata.props["RangeType"] = "LinearStep" - sweepdata.props["RangeStart"] = str(freqstart) + unit - sweepdata.props["RangeEnd"] = str(freqstop) + unit + sweepdata.props["RangeStart"] = str(start_frequency) + unit + sweepdata.props["RangeEnd"] = str(stop_frequency) + unit sweepdata.props["RangeStep"] = str(step_size) + unit sweepdata.props["SaveFields"] = save_fields if sweep_type == "Discrete" else False sweepdata.props["SaveRadFields"] = False @@ -3498,31 +3471,34 @@ def create_linear_step_sweep( sweepdata.props["InterpMinSolns"] = 0 sweepdata.props["InterpMinSubranges"] = 1 sweepdata.update() - self._app.logger.info("Linear step sweep {} has been correctly created".format(sweepname)) + self._app.logger.info("Linear step sweep {} has been correctly created".format(name)) return sweepdata - @pyaedt_function_handler() + @pyaedt_function_handler(sweepname="name") def create_single_point_sweep( self, unit="GHz", - freq=1, - sweepname=None, + freq=1.0, + name=None, save_single_field=True, save_fields=False, ): - """Create a Sweep with a single frequency point. + """Create a sweep with a single frequency point. Parameters ---------- - unit : str - Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. - freq : float, list - Frequency of the single point or list of frequencies to create distinct single points. - sweepname : str, optional - Name of the sweep. The default is ``None``. + unit : str, optional + Unit of the frequency. The default is ``"GHz"``. + freq : float, list, optional + One or more frequencies for creating distinct single points. + The default is ``1.0``. + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. save_single_field : bool, list, optional Whether to save the fields of the single point. The default is ``True``. - If a list is specified, the length must be the same as freq length. + If a list is specified, the length must be the same as the + frequency length. save_fields : bool, optional Whether to save the fields for all points and subranges defined in the sweep. The default is ``False``. @@ -3542,14 +3518,14 @@ def create_single_point_sweep( >>> from pyaedt import Q3d >>> q3d = Q3d() >>> setup = q3d.create_setup("SinglePointSetup") - >>> single_point_sweep = setup.create_single_point_sweep(setupname="SinglePointSetup", - ... sweepname="SinglePointSweep", + >>> single_point_sweep = setup.create_single_point_sweep( + ... name="SinglePointSweep", ... unit="MHz", freq=1.1e3) >>> type(single_point_sweep) >>> q3d.release_desktop(True, True) """ - if sweepname is None: - sweepname = generate_unique_name("SinglePoint") + if name is None: + name = generate_unique_name("SinglePoint") if isinstance(save_single_field, list): if not isinstance(freq, list) or len(save_single_field) != len(freq): @@ -3572,11 +3548,11 @@ def create_single_point_sweep( if add_subranges: save_single_field = [save0] * len(freq) - if sweepname in [sweep.name for sweep in self.sweeps]: - oldname = sweepname - sweepname = generate_unique_name(oldname) - self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweepname) - sweepdata = self.add_sweep(sweepname, "Discrete") + if name in [sweep.name for sweep in self.sweeps]: + oldname = name + name = generate_unique_name(oldname) + self._app.logger.warning("Sweep %s is already present. Sweep has been renamed in %s.", oldname, name) + sweepdata = self.add_sweep(name, "Discrete") sweepdata.props["RangeType"] = "SinglePoints" sweepdata.props["RangeStart"] = str(freq0) + unit sweepdata.props["RangeEnd"] = str(freq0) + unit @@ -3588,18 +3564,19 @@ def create_single_point_sweep( for f, s in zip(freq, save_single_field): sweepdata.add_subrange(rangetype="SinglePoints", start=f, unit=unit, save_single_fields=s) sweepdata.update() - self._app.logger.info("Single point sweep {} has been correctly created".format(sweepname)) + self._app.logger.info("Single point sweep {} has been correctly created".format(name)) return sweepdata - @pyaedt_function_handler() - def add_sweep(self, sweepname=None, sweeptype="Interpolating"): + @pyaedt_function_handler(sweepname="name", sweeptype="sweep_type") + def add_sweep(self, name=None, sweep_type="Interpolating"): """Add a sweep to the project. Parameters ---------- - sweepname : str, optional - Name of the sweep. The default is ``None``. - sweeptype : str, optional + name : str, optional + Name of the sweep. The default is ``None``, in which + case a name is automatically assigned. + sweep_type : str, optional Type of the sweep. The default is ``"Interpolating"``. Returns @@ -3612,17 +3589,17 @@ def add_sweep(self, sweepname=None, sweeptype="Interpolating"): >>> oModule.InsertFrequencySweep """ - if not sweepname: - sweepname = generate_unique_name("Sweep") + if not name: + name = generate_unique_name("Sweep") if self.setuptype == 7: self._app.logger.warning("This method only applies to HFSS and Q3D. Use add_eddy_current_sweep method.") return False if self.setuptype <= 4: - sweep_n = SweepHFSS(self, sweepname=sweepname, sweeptype=sweeptype) + sweep_n = SweepHFSS(self, name=name, sweep_type=sweep_type) elif self.setuptype in [14, 30, 31]: - sweep_n = SweepMatrix(self, sweepname=sweepname, sweeptype=sweeptype) + sweep_n = SweepMatrix(self, name=name, sweep_type=sweep_type) else: - self._app.logger.warning("This method only applies to HFSS, Q2D and Q3D.") + self._app.logger.warning("This method only applies to HFSS, Q2D, and Q3D.") return False sweep_n.create() self.sweeps.append(sweep_n) @@ -3632,14 +3609,15 @@ def add_sweep(self, sweepname=None, sweeptype="Interpolating"): break return sweep_n - @pyaedt_function_handler() - def get_sweep(self, sweepname=None): - """Return frequency sweep object of a given sweep. + @pyaedt_function_handler(sweepname="name") + def get_sweep(self, name=None): + """Get the frequency sweep object of a given sweep. Parameters ---------- - sweepname : str, optional - Name of the sweep. the default is ``None`` which returns the first sweep. + name : str, optional + Name of the sweep. The default is ``None``, in which case the + first sweep is used. Returns ------- @@ -3650,15 +3628,15 @@ def get_sweep(self, sweepname=None): >>> from pyaedt import Q3d >>> q3d = Q3d() >>> setup = q3d.create_setup() - >>> sweep = setup.create_frequency_sweep(sweepname="Sweep1") - >>> sweep.add_subrange("LinearCount", 0, 10, 1, "Hz") - >>> sweep.add_subrange("LogScale", 10, 1E8, 100, "Hz") + >>> sweep = setup.create_frequency_sweep(name="Sweep1") + >>> sweep.add_subrange("LinearCount",0,10,1,"Hz") + >>> sweep.add_subrange("LogScale",10,1E8,100,"Hz") >>> sweep = setup.get_sweep("Sweep1") >>> q3d.release_desktop(True, True) """ - if sweepname: + if name: for sweep in self.sweeps: - if sweepname == sweep.name: + if name == sweep.name: return sweep else: if self.sweeps: diff --git a/pyaedt/modules/SolveSweeps.py b/pyaedt/modules/SolveSweeps.py index 1a28cde82d6..f1ec3a54016 100644 --- a/pyaedt/modules/SolveSweeps.py +++ b/pyaedt/modules/SolveSweeps.py @@ -62,13 +62,11 @@ class SweepHFSS(object): Parameters ---------- - app : :class 'pyaedt.modules.SolveSetup.Setup' + setup : :class 'pyaedt.modules.SolveSetup.Setup' Setup to use for the analysis. - setupname : str - Name of the setup. - sweepname : str + name : str Name of the sweep. - sweeptype : str, optional + sweep_type : str, optional Type of the sweep. Options are ``"Fast"``, ``"Interpolating"``, and ``"Discrete"``. The default is ``"Interpolating"``. props : dict, optional @@ -78,46 +76,34 @@ class SweepHFSS(object): Examples -------- >>> hfss = Hfss(specified_version=version, projectname=proj, designname=gtemDesign, solution_type=solutiontype, - setup_name=setupname, new_desktop_session=False, close_on_exit=False) + setup_name=setup_name, new_desktop_session=False, close_on_exit=False) >>> hfss_setup = hfss.setups[0] - >>> hfss_sweep = SweepHFSS(hfss_setup, 'Sweep', sweeptype ='Interpolating', props=None) + >>> hfss_sweep = SweepHFSS(hfss_setup, 'Sweep', sweep_type ='Interpolating', props=None) """ - def __init__(self, setup, sweepname, sweeptype="Interpolating", props=None, **kwargs): - if "app" in kwargs: - warnings.warn( - "`app` is deprecated since v0.6.22. Use `setup` instead.", - DeprecationWarning, - ) - setup = kwargs["app"] - if "setupname" in kwargs: - warnings.warn( - "`setupname` is deprecated since v0.6.22. It is no longer required.", - DeprecationWarning, - ) - + def __init__(self, setup, name, sweep_type="Interpolating", props=None): self._app = setup self.oanalysis = setup.omodule self.props = {} - self.setupname = setup.name - self.name = sweepname + self.setup_name = setup.name + self.name = name if props: self.props = props else: self.props = copy.deepcopy(SweepHfss3D) # for t in SweepHfss3D: # _tuple2dict(t, self.props) - if SequenceMatcher(None, sweeptype.lower(), "interpolating").ratio() > 0.8: - sweeptype = "Interpolating" - elif SequenceMatcher(None, sweeptype.lower(), "discrete").ratio() > 0.8: - sweeptype = "Discrete" - elif SequenceMatcher(None, sweeptype.lower(), "fast").ratio() > 0.8: - sweeptype = "Fast" + if SequenceMatcher(None, sweep_type.lower(), "interpolating").ratio() > 0.8: + sweep_type = "Interpolating" + elif SequenceMatcher(None, sweep_type.lower(), "discrete").ratio() > 0.8: + sweep_type = "Discrete" + elif SequenceMatcher(None, sweep_type.lower(), "fast").ratio() > 0.8: + sweep_type = "Fast" else: warnings.warn("Invalid sweep type. `Interpolating` will be set as the default.") - sweeptype = "Interpolating" - self.props["Type"] = sweeptype + sweep_type = "Interpolating" + self.props["Type"] = sweep_type @property def is_solved(self): @@ -128,7 +114,7 @@ def is_solved(self): bool `True` if solutions are available. """ - sol = self._app.p_app.post.reports_by_category.standard(setup_name="{} : {}".format(self.setupname, self.name)) + sol = self._app.p_app.post.reports_by_category.standard(setup="{} : {}".format(self.setup_name, self.name)) if identify_setup(self.props): sol.domain = "Time" return True if sol.get_solution_data() else False @@ -143,7 +129,7 @@ def frequencies(self): list of float Frequency points. """ - sol = self._app.p_app.post.reports_by_category.standard(setup_name="{} : {}".format(self.setupname, self.name)) + sol = self._app.p_app.post.reports_by_category.standard(setup="{} : {}".format(self.setup_name, self.name)) soldata = sol.get_solution_data() if soldata and "Freq" in soldata.intrinsics: return soldata.intrinsics["Freq"] @@ -180,7 +166,7 @@ def basis_frequencies(self): count = 0 for el in self._app.p_app.setups: - if el.name == self.setupname: + if el.name == self.setup_name: for sweep in el.sweeps: if sweep.name == self.name: return fr[count] if len(fr) >= count + 1 else [] @@ -190,29 +176,29 @@ def basis_frequencies(self): count += 1 return [] - @pyaedt_function_handler() - def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", save_single_fields=False, clear=False): + @pyaedt_function_handler(rangetype="range_type") + def add_subrange(self, range_type, start, end=None, count=None, unit="GHz", save_single_fields=False, clear=False): """Add a range to the sweep. Parameters ---------- - rangetype : str + range_type : str Type of the range. Options are ``"LinearCount"``, ``"LinearStep"``, ``"LogScale"``, and ``"SinglePoints"``. start : float Starting frequency. end : float, optional Stopping frequency. The default value is ``None``. A value is required for - ``rangetype="LinearCount"|"LinearStep"|"LogScale"``. + ``range_type="LinearCount"|"LinearStep"|"LogScale"``. count : int or float, optional Frequency count or frequency step. The default is ``None``. A value is required for - ``rangetype="LinearCount"|"LinearStep"|"LogScale"``. + ``range_type="LinearCount"|"LinearStep"|"LogScale"``. unit : str, optional Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. The default is ``"GHz"``. save_single_fields : bool, optional Whether to save the fields of the single point. The default is ``False``. - This parameter is sed only for ``rangetype="SinglePoints"``. - clear : boolean, optional + This parameter is used only for ``range_type="SinglePoints"``. + clear : bool, optional Whether to suppress all other subranges except the current one under creation. The default value is ``False``. @@ -225,48 +211,48 @@ def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", save_ -------- Create a setup in an HFSS design and add multiple sweep ranges. - >>> setup = hfss.create_setup(setupname="MySetup") + >>> setup = hfss.create_setup(setup_name="MySetup") >>> sweep = setup.add_sweep() >>> sweep.change_type("Interpolating") >>> sweep.change_range("LinearStep", 1.1, 2.1, 0.4, "GHz") - >>> sweep.add_subrange("LinearCount", 1, 1.5, 5, "MHz") - >>> sweep.add_subrange("LogScale", 1, 3, 10, "GHz") + >>> sweep.add_subrange("LinearCount",1,1.5,5,"MHz") + >>> sweep.add_subrange("LogScale",1,3,10,"GHz") """ - if rangetype == "LinearCount" or rangetype == "LinearStep" or rangetype == "LogScale": + if range_type == "LinearCount" or range_type == "LinearStep" or range_type == "LogScale": if not end or not count: raise AttributeError("Parameters 'end' and 'count' must be present.") if clear: - self.props["RangeType"] = rangetype + self.props["RangeType"] = range_type self.props["RangeStart"] = str(start) + unit - if rangetype == "LinearCount": + if range_type == "LinearCount": self.props["RangeEnd"] = str(end) + unit self.props["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": self.props["RangeEnd"] = str(end) + unit self.props["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": self.props["RangeEnd"] = str(end) + unit self.props["RangeSamples"] = count - elif rangetype == "SinglePoints": + elif range_type == "SinglePoints": self.props["RangeEnd"] = str(start) + unit self.props["SaveSingleField"] = save_single_fields self.props["SweepRanges"] = {"Subrange": []} return self.update() - interval = {"RangeType": rangetype, "RangeStart": str(start) + unit} - if rangetype == "LinearCount": + interval = {"RangeType": range_type, "RangeStart": str(start) + unit} + if range_type == "LinearCount": interval["RangeEnd"] = str(end) + unit interval["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": interval["RangeEnd"] = str(end) + unit interval["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": interval["RangeEnd"] = str(end) + unit interval["RangeCount"] = self.props["RangeCount"] interval["RangeSamples"] = count - elif rangetype == "SinglePoints": + elif range_type == "SinglePoints": interval["RangeEnd"] = str(start) + unit interval["SaveSingleField"] = save_single_fields if not self.props.get("SweepRanges", None): @@ -288,7 +274,7 @@ def create(self): ``True`` when successful, ``False`` when failed. """ - self.oanalysis.InsertFrequencySweep(self.setupname, self._get_args()) + self.oanalysis.InsertFrequencySweep(self.setup_name, self._get_args()) return True @pyaedt_function_handler() @@ -301,7 +287,7 @@ def update(self): ``True`` when successful, ``False`` when failed. """ - self.oanalysis.EditFrequencySweep(self.setupname, self.name, self._get_args()) + self.oanalysis.EditFrequencySweep(self.setup_name, self.name, self._get_args()) return True @@ -333,13 +319,11 @@ class SweepHFSS3DLayout(object): Parameters ---------- - app : :class 'pyaedt.modules.SolveSetup.Setup' + setup : :class 'pyaedt.modules.SolveSetup.Setup' Setup to use for the analysis. - setupname : str - Name of the setup. - sweepname : str + name : str Name of the sweep. - sweeptype : str, optional + sweep_type : str, optional Type of the sweep. Options are ``"Interpolating"`` and ``"Discrete"``. The default is ``"Interpolating"``. save_fields : bool, optional Whether to save the fields. The default is ``True``. @@ -349,24 +333,12 @@ class SweepHFSS3DLayout(object): """ - def __init__(self, setup, sweepname, sweeptype="Interpolating", save_fields=True, props=None, **kwargs): - if "app" in kwargs: - warnings.warn( - "`app` is deprecated since v0.6.22. Use `setup` instead.", - DeprecationWarning, - ) - setup = kwargs["app"] - if "setupname" in kwargs: - warnings.warn( - "`setupname` is deprecated since v0.6.22. It is no longer required.", - DeprecationWarning, - ) - + def __init__(self, setup, name, sweep_type="Interpolating", save_fields=True, props=None, **kwargs): self._app = setup self.oanalysis = setup.omodule self.props = {} - self.setupname = setup.name - self.name = sweepname + self.setup_name = setup.name + self.name = name if props: self.props = props else: @@ -376,27 +348,27 @@ def __init__(self, setup, sweepname, sweeptype="Interpolating", save_fields=True self.props = copy.deepcopy(Sweep3DLayout) # for t in props: # _tuple2dict(t, self.props) - if SequenceMatcher(None, sweeptype.lower(), "interpolating").ratio() > 0.8: - sweeptype = "kInterpolating" - elif SequenceMatcher(None, sweeptype.lower(), "discrete").ratio() > 0.8: - sweeptype = "kDiscrete" - elif SequenceMatcher(None, sweeptype.lower(), "fast").ratio() > 0.8: - sweeptype = "kBroadbandFast" + if SequenceMatcher(None, sweep_type.lower(), "interpolating").ratio() > 0.8: + sweep_type = "kInterpolating" + elif SequenceMatcher(None, sweep_type.lower(), "discrete").ratio() > 0.8: + sweep_type = "kDiscrete" + elif SequenceMatcher(None, sweep_type.lower(), "fast").ratio() > 0.8: + sweep_type = "kBroadbandFast" else: warnings.warn("Sweep type is invalid. `kInterpolating` is set as the default.") - sweeptype = "kInterpolating" - self.props["FreqSweepType"] = sweeptype + sweep_type = "kInterpolating" + self.props["FreqSweepType"] = sweep_type self.props["GenerateSurfaceCurrent"] = save_fields @property def combined_name(self): - """Compute the setupname : sweepname string. + """Compute the setup_name : sweep_name string. Returns ------- str """ - return "{} : {}".format(self.setupname, self.name) + return "{} : {}".format(self.setup_name, self.name) @property def is_solved(self): @@ -408,20 +380,18 @@ def is_solved(self): `True` if solutions are available. """ expressions = [i for i in self.p_app.post.available_report_quantities(solution=self.combined_name)] - sol = self._app._app.post.reports_by_category.standard( - setup_name=self.combined_name, expressions=expressions[0] - ) + sol = self._app._app.post.reports_by_category.standard(expressions=expressions[0], setup=self.combined_name) if identify_setup(self.props): sol.domain = "Time" return True if sol.get_solution_data() else False - @pyaedt_function_handler() - def change_type(self, sweeptype): + @pyaedt_function_handler(sweeptype="sweep_type") + def change_type(self, sweep_type): """Change the type of the sweep. Parameters ---------- - sweeptype : str + sweep_type : str Type of the sweep. Options are ``"Interpolating"`` and ``"Discrete"``. The default is ``"Interpolating"``. @@ -430,9 +400,9 @@ def change_type(self, sweeptype): bool ``True`` when successful, ``False`` when failed. """ - if sweeptype == "Interpolating": + if sweep_type == "Interpolating": self.props["FastSweep"] = True - elif sweeptype == "Discrete": + elif sweep_type == "Discrete": self.props["FastSweep"] = False else: raise AttributeError("Allowed sweep type options are 'Interpolating' and 'Discrete'.") @@ -458,13 +428,13 @@ def set_save_fields(self, save_fields, save_rad_fields=False): self.props["SaveRadFieldsOnly"] = save_rad_fields return self.update() - @pyaedt_function_handler() - def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz"): + @pyaedt_function_handler(rangetype="range_type") + def add_subrange(self, range_type, start, end=None, count=None, unit="GHz"): """Add a subrange to the sweep. Parameters ---------- - rangetype : str + range_type : str Type of the subrange. Options are ``"LinearCount"``, ``"SinglePoint"``, ``"LinearStep"``, and ``"LogScale"``. start : float @@ -485,36 +455,36 @@ def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz"): ``True`` when successful, ``False`` when failed. """ try: - if rangetype == "SinglePoint" and self.props["FreqSweepType"] == "kInterpolating": - raise AttributeError("'SinglePoint is allowed only when sweeptype is 'Discrete'.'") - if rangetype == "LinearCount" or rangetype == "LinearStep" or rangetype == "LogScale": + if range_type == "SinglePoint" and self.props["FreqSweepType"] == "kInterpolating": + raise AttributeError("'SinglePoint is allowed only when sweep_type is 'Discrete'.'") + if range_type == "LinearCount" or range_type == "LinearStep" or range_type == "LogScale": if not end or not count: raise AttributeError("Parameters 'end' and 'count' must be present.") - if rangetype == "LinearCount": + if range_type == "LinearCount": sweep_range = " LINC " + str(start) + unit + " " + str(end) + unit + " " + str(count) - elif rangetype == "LinearStep": + elif range_type == "LinearStep": sweep_range = " LIN " + str(start) + unit + " " + str(end) + unit + " " + str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": sweep_range = " DEC " + str(start) + unit + " " + str(end) + unit + " " + str(count) - elif rangetype == "SinglePoint": + elif range_type == "SinglePoint": sweep_range = " " + str(start) + unit else: raise AttributeError( - 'Allowed rangetype are "LinearCount", "SinglePoint", "LinearStep", and "LogScale".' + 'Allowed range_type are "LinearCount", "SinglePoint", "LinearStep", and "LogScale".' ) self.props["Sweeps"]["Data"] += sweep_range return self.update() except Exception: return False - @pyaedt_function_handler() - def change_range(self, rangetype, start, end=None, count=None, unit="GHz"): + @pyaedt_function_handler(rangetype="range_type") + def change_range(self, range_type, start, end=None, count=None, unit="GHz"): """Change the range of the sweep. Parameters ---------- - rangetype : str + range_type : str Type of the subrange. Options are ``"LinearCount"``, ``"SinglePoint"``, ``"LinearStep"``, and ``"LogScale"``. start : float @@ -535,16 +505,16 @@ def change_range(self, rangetype, start, end=None, count=None, unit="GHz"): ``True`` when successful, ``False`` when failed. """ - if rangetype == "LinearCount": + if range_type == "LinearCount": sweep_range = "LINC " + str(start) + unit + " " + str(end) + unit + " " + str(count) - elif rangetype == "LinearStep": + elif range_type == "LinearStep": sweep_range = "LIN " + str(start) + unit + " " + str(end) + unit + " " + str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": sweep_range = "DEC " + str(start) + unit + " " + str(end) + unit + " " + str(count) - elif rangetype == "SinglePoint": + elif range_type == "SinglePoint": sweep_range = str(start) + unit else: - raise AttributeError('Allowed rangetype are "LinearCount", "SinglePoint", "LinearStep", and "LogScale".') + raise AttributeError('Allowed range_type are "LinearCount", "SinglePoint", "LinearStep", and "LogScale".') self.props["Sweeps"]["Data"] = sweep_range return self.update() @@ -558,7 +528,7 @@ def create(self): ``True`` when successful, ``False`` when failed. """ - self.oanalysis.AddSweep(self.setupname, self._get_args()) + self.oanalysis.AddSweep(self.setup_name, self._get_args()) return True @pyaedt_function_handler() @@ -571,7 +541,7 @@ def update(self): ``True`` when successful, ``False`` when failed. """ - self.oanalysis.EditSweep(self.setupname, self.name, self._get_args()) + self.oanalysis.EditSweep(self.setup_name, self.name, self._get_args()) return True @pyaedt_function_handler() @@ -602,13 +572,11 @@ class SweepMatrix(object): Parameters ---------- - app : :class 'pyaedt.modules.SolveSetup.Setup' + setup : :class 'pyaedt.modules.SolveSetup.Setup' Setup used for the analysis. - setupname : str - Name of the setup. - sweepname : str + name : str Name of the sweep. - sweeptype : str, optional + sweep_type : str, optional Type of the sweep. Options are ``"Fast"``, ``"Interpolating"``, and ``"Discrete"``. The default is ``"Interpolating"``. props : dict @@ -617,28 +585,17 @@ class SweepMatrix(object): """ - def __init__(self, setup, sweepname, sweeptype="Interpolating", props=None, **kwargs): - if "app" in kwargs: - warnings.warn( - "`app` is deprecated since v0.6.22. Use `setup` instead.", - DeprecationWarning, - ) - setup = kwargs["app"] - if "setupname" in kwargs: - warnings.warn( - "`setupname` is deprecated since v0.6.22. It is no longer required.", - DeprecationWarning, - ) + def __init__(self, setup, name, sweep_type="Interpolating", props=None): self._app = setup self.oanalysis = setup.omodule - self.setupname = setup.name - self.name = sweepname + self.setup_name = setup.name + self.name = name self.props = {} if props: self.props = props else: - self.props["Type"] = sweeptype - if sweeptype == "Discrete": + self.props["Type"] = sweep_type + if sweep_type == "Discrete": self.props["isenabled"] = True self.props["RangeType"] = "LinearCount" self.props["RangeStart"] = "2.5GHz" @@ -672,7 +629,7 @@ def is_solved(self): bool `True` if solutions are available. """ - sol = self._app.p_app.post.reports_by_category.standard(setup_name="{} : {}".format(self.setupname, self.name)) + sol = self._app.p_app.post.reports_by_category.standard(setup="{} : {}".format(self.setup_name, self.name)) return True if sol.get_solution_data() else False @property @@ -685,7 +642,7 @@ def frequencies(self): list of float Frequency points. """ - sol = self._app.p_app.post.reports_by_category.standard(setup_name="{} : {}".format(self.setupname, self.name)) + sol = self._app.p_app.post.reports_by_category.standard(setup="{} : {}".format(self.setup_name, self.name)) soldata = sol.get_solution_data() if soldata and "Freq" in soldata.intrinsics: return soldata.intrinsics["Freq"] @@ -722,7 +679,7 @@ def basis_frequencies(self): count = 0 for el in self._app.p_app.setups: - if el.name == self.setupname: + if el.name == self.setup_name: for sweep in el.sweeps: if sweep.name == self.name: return fr[count] if len(fr) >= count + 1 else [] @@ -732,13 +689,13 @@ def basis_frequencies(self): count += 1 return [] - @pyaedt_function_handler() - def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear=False, **kwargs): + @pyaedt_function_handler(rangetype="range_type") + def add_subrange(self, range_type, start, end=None, count=None, unit="GHz", clear=False, **kwargs): """Add a subrange to the sweep. Parameters ---------- - rangetype : str + range_type : str Type of the subrange. Options are ``"LinearCount"``, ``"LinearStep"``, and ``"LogScale"``. start : float @@ -760,30 +717,30 @@ def add_subrange(self, rangetype, start, end=None, count=None, unit="GHz", clear """ if "type" in kwargs: - warnings.warn("'type' has been deprecated. Use 'rangetype' instead.", DeprecationWarning) - rangetype = kwargs["type"] + warnings.warn("'type' has been deprecated. Use 'range_type' instead.", DeprecationWarning) + range_type = kwargs["type"] if clear: - self.props["RangeType"] = rangetype + self.props["RangeType"] = range_type self.props["RangeStart"] = str(start) + unit - if rangetype == "LinearCount": + if range_type == "LinearCount": self.props["RangeEnd"] = str(end) + unit self.props["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": self.props["RangeEnd"] = str(end) + unit self.props["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": self.props["RangeEnd"] = str(end) + unit self.props["RangeSamples"] = count self.props["SweepRanges"] = {"Subrange": []} return self.update() - sweep_range = {"RangeType": rangetype, "RangeStart": str(start) + unit} - if rangetype == "LinearCount": + sweep_range = {"RangeType": range_type, "RangeStart": str(start) + unit} + if range_type == "LinearCount": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeCount"] = count - elif rangetype == "LinearStep": + elif range_type == "LinearStep": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeStep"] = str(count) + unit - elif rangetype == "LogScale": + elif range_type == "LogScale": sweep_range["RangeEnd"] = str(end) + unit sweep_range["RangeCount"] = self.props["RangeCount"] sweep_range["RangeSamples"] = count @@ -802,7 +759,7 @@ def create(self): ``True`` when successful, ``False`` when failed. """ - self.oanalysis.InsertSweep(self.setupname, self._get_args()) + self.oanalysis.InsertSweep(self.setup_name, self._get_args()) return True @pyaedt_function_handler() @@ -815,7 +772,7 @@ def update(self): ``True`` when successful, ``False`` when failed. """ - self.oanalysis.EditSweep(self.setupname, self.name, self._get_args()) + self.oanalysis.EditSweep(self.setup_name, self.name, self._get_args()) return True diff --git a/pyaedt/modules/monitor_icepak.py b/pyaedt/modules/monitor_icepak.py index 78585984bb2..43c4ae2320e 100644 --- a/pyaedt/modules/monitor_icepak.py +++ b/pyaedt/modules/monitor_icepak.py @@ -747,8 +747,8 @@ def type(self): """ return self._type - @pyaedt_function_handler - def value(self, quantity=None, setup_name=None, design_variation_dict=None, si_out=True): + @pyaedt_function_handler(setup_name="setup") + def value(self, quantity=None, setup=None, design_variation_dict=None, si_out=True): """ Get a list of values obtained from the monitor object. If the simulation is steady state, the list will contain just one element. @@ -760,10 +760,10 @@ def value(self, quantity=None, setup_name=None, design_variation_dict=None, si_o all monitored quantity will be considered. design_variation_dict : dict, optional Dictionary containing the project and design variables and values. If this parameter - is not provided, all variations will be considered. - setup_name : str, optional - String that specifies the name of the setup from which to extract the monitor value. - If this parameter is not provided, the first one of the design will be selected. + is not provided, all variations are considered. + setup : str, optional + Name of the setup to extract the monitor value from. + If this parameter is not provided, the first setup of the design is used. si_out : bool, optional Whether to return the values of th monitor object in SI units. Default is ``True``. @@ -773,8 +773,8 @@ def value(self, quantity=None, setup_name=None, design_variation_dict=None, si_o Dictionary containing the variables names and values and the monitor values for each variation. """ - if not setup_name: - setup_name = self._app.existing_analysis_sweeps[0] + if not setup: + setup = self._app.existing_analysis_sweeps[0] design_variation = [] if not design_variation_dict: design_variation_dict = {k: ["All"] for k in self._app.variable_manager.variables.keys()} @@ -787,7 +787,7 @@ def value(self, quantity=None, setup_name=None, design_variation_dict=None, si_o for q in quantity: for i, monitor_result_obj in enumerate( self._app.oreportsetup.GetSolutionDataPerVariation( - "Monitor", setup_name, [], design_variation, "{}.{}".format(self.name, q) + "Monitor", setup, [], design_variation, "{}.{}".format(self.name, q) ) ): variation_a = { diff --git a/pyaedt/modules/report_templates.py b/pyaedt/modules/report_templates.py index d26c98e1091..c656bc92c1b 100644 --- a/pyaedt/modules/report_templates.py +++ b/pyaedt/modules/report_templates.py @@ -1058,7 +1058,7 @@ def _convert_dict_to_report_sel(self, sweeps): if el in [self.primary_sweep, self.secondary_sweep]: continue sweep_list.append(el + ":=") - if type(sweeps[el]) is list: + if isinstance(sweeps[el], list): sweep_list.append(sweeps[el]) else: sweep_list.append([sweeps[el]]) @@ -3786,3 +3786,223 @@ def create(self, plot_name=None): self._post.plots.append(self) self._is_created = True return True + + +class EMIReceiver(CommonReport): + """Provides for managing EMI receiver reports.""" + + def __init__(self, app, setup_name, expressions=None): + CommonReport.__init__(self, app, "EMIReceiver", setup_name, expressions) + self.logger = app.logger + self.domain = "EMI Receiver" + self.available_nets = [] + self._net = "0" + for comp in app.modeler.components.components.values(): + if comp.name == "CompInst@EMI_RCVR": + self.available_nets.append(comp.pins[0].net) + if self.available_nets: + self._net = self.available_nets[0] + self.time_start = "0ns" + self.time_stop = "200ns" + self._emission = "CE" + self.overlap_rate = 95 + self.band = "0" + self.primary_sweep = "Freq" + + @property + def net(self): + """Net attached to the EMI receiver. + + Returns + ------- + str + """ + return self._net + + @net.setter + def net(self, value): + if value not in self.available_nets: + self.logger.error("Net not available.") + else: + self._net = value + + @property + def band(self): + """Band attached to the EMI receiver. + + Returns + ------- + str + """ + return self.props["context"].get("band", None) + + @band.setter + def band(self, value): + self.props["context"]["band"] = value + + @property + def emission(self): + """Emission test. + + Options are ``"CE"`` and ``"RE"``. + + Returns + ------- + str + """ + return self._emission + + @emission.setter + def emission(self, value): + if value == "CE": + self._emission = value + self.props["context"]["emission"] = "0" + elif value == "RE": + self._emission = value + self.props["context"]["emission"] = "1" + else: + self.logger.error("Emission must be 'CE' or 'RE', value '{}' is not valid.".format(value)) + + @property + def time_start(self): + """Time start value. + + Returns + ------- + str + """ + return self.props["context"].get("time_start", None) + + @time_start.setter + def time_start(self, value): + self.props["context"]["time_start"] = value + + @property + def time_stop(self): + """Time stop value. + + Returns + ------- + str + """ + return self.props["context"].get("time_stop", None) + + @time_stop.setter + def time_stop(self, value): + self.props["context"]["time_stop"] = value + + @property + def _context(self): + + if self.emission == "CE": + em = "0" + else: + em = "1" + + arg = [ + "NAME:Context", + "SimValueContext:=", + [ + 55830, + 0, + 2, + 0, + False, + False, + -1, + 1, + 0, + 1, + 1, + self.net, + 0, + 0, + "BAND", + False, + self.band, + "CG", + False, + "1", + "EM", + False, + em, + "KP", + False, + "0", + "NUMLEVELS", + False, + "0", + "OR", + False, + str(self.overlap_rate), + "RBW", + False, + "9000Hz", + "SIG", + False, + "0", + "TCT", + False, + "1ms", + "TDT", + False, + "160ms", + "TE", + False, + self.time_stop, + "TS", + False, + self.time_start, + "WT", + False, + "6", + "WW", + False, + "100", + ], + ] + return arg + + @property + def _trace_info(self): + if isinstance(self.expressions, list): + return self.expressions + else: + return [self.expressions] + + @pyaedt_function_handler() + def create(self, plot_name=None): + """Create an EMI receiver report. + + Parameters + ---------- + plot_name : str, optional + Plot name. The default is ``None``, in which case + the default name is used. + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + """ + if not plot_name: + self.plot_name = generate_unique_name("Plot") + else: + self.plot_name = plot_name + self._post.oreportsetup.CreateReport( + self.plot_name, + "Standard", + self.report_type, + self.setup, + self._context, + self._convert_dict_to_report_sel(self.variations), + [ + "X Component:=", + self.primary_sweep, + "Y Component:=", + self._trace_info, + ], + ) + self._post.plots.append(self) + self._is_created = True + return self diff --git a/pyaedt/modules/solutions.py b/pyaedt/modules/solutions.py index 866836f4be7..828e4bbbfb6 100644 --- a/pyaedt/modules/solutions.py +++ b/pyaedt/modules/solutions.py @@ -15,6 +15,7 @@ from pyaedt.generic.constants import db10 from pyaedt.generic.constants import db20 from pyaedt.generic.constants import unit_converter +from pyaedt.generic.general_methods import check_and_download_file from pyaedt.generic.general_methods import check_and_download_folder from pyaedt.generic.general_methods import conversion_function from pyaedt.generic.general_methods import open_file @@ -128,26 +129,26 @@ def _get_variations(self): variations_lists.append(variations) return variations_lists - @pyaedt_function_handler() - def variation_values(self, variation_name): + @pyaedt_function_handler(variation_name="variation") + def variation_values(self, variation): """Get the list of the specific variation available values. Parameters ---------- - variation_name : str + variation : str Name of variation to return. Returns ------- list """ - if variation_name in self.intrinsics: - return self.intrinsics[variation_name] + if variation in self.intrinsics: + return self.intrinsics[variation] else: vars_vals = [] for el in self.variations: - if variation_name in el and el[variation_name] not in vars_vals: - vars_vals.append(el[variation_name]) + if variation in el and el[variation] not in vars_vals: + vars_vals.append(el[variation]) return vars_vals @property @@ -451,17 +452,18 @@ def data_magnitude(self, expression=None, convert_to_SI=False): return sol @staticmethod - @pyaedt_function_handler() - def _convert_list_to_SI(datalist, dataunits, units): + @pyaedt_function_handler(datalist="data", dataunits="data_units") + def _convert_list_to_SI(data, data_units, units): """Convert a data list to the SI unit system. Parameters ---------- - datalist : list + data : list List of data to convert. - dataunits : - - units : + data_units : str + Data units. + units : str + SI units to convert data into. Returns @@ -470,9 +472,9 @@ def _convert_list_to_SI(datalist, dataunits, units): List of the data converted to the SI unit system. """ - sol = datalist - if dataunits in AEDT_UNITS and units in AEDT_UNITS[dataunits]: - sol = [i * AEDT_UNITS[dataunits][units] for i in datalist] + sol = data + if data_units in AEDT_UNITS and units in AEDT_UNITS[data_units]: + sol = [i * AEDT_UNITS[data_units][units] for i in data] return sol @pyaedt_function_handler() @@ -664,13 +666,13 @@ def data_imag(self, expression=None, convert_to_SI=False): expression = self.active_expression temp = self._variation_tuple() - solution_Data = self._solutions_imag[expression] + solution_data = self._solutions_imag[expression] sol = [] position = list(self._sweeps_names).index(self.primary_sweep) for el in self.primary_sweep_values: temp[position] = el try: - sol.append(solution_Data[tuple(temp)]) + sol.append(solution_data[tuple(temp)]) except KeyError: sol.append(None) if convert_to_SI and self._quantity(self.units_data[expression]): @@ -744,15 +746,15 @@ def export_data_to_csv(self, output, delimiter=";"): return write_csv(output, list_full, delimiter=delimiter) - @pyaedt_function_handler() + @pyaedt_function_handler(math_formula="formula", xlabel="x_label", ylabel="y_label") def plot( self, curves=None, - math_formula=None, + formula=None, size=(2000, 1000), show_legend=True, - xlabel="", - ylabel="", + x_label="", + y_label="", title="", snapshot_path=None, is_polar=False, @@ -762,21 +764,26 @@ def plot( Parameters ---------- curves : list - Curves to be plotted. If None, the first curve will be plotted. - math_formula : str , optional - Mathematical formula to apply to the plot curve. - Valid values are `"re"`, `"im"`, `"db20"`, `"db10"`, `"abs"`, `"mag"`, `"phasedeg"`, `"phaserad"`. - `None` value will plot only real value of the data stored in solution data. + Curves to be plotted. The default is ``None``, in which case + the first curve is plotted. + formula : str , optional + Mathematical formula to apply to the plot curve. The default is ``None``, + in which case only real value of the data stored in the solution data is plotted. + Options are ``"abs"``, ``"db10"``, ``"db20"``, ``"im"``, ``"mag"``, ``"phasedeg"``, + ``"phaserad"``, and ``"re"``. + size : tuple, optional - Image size in pixel (width, height). + Image size in pixels (width, height). show_legend : bool - Either to show legend or not. Flag will be ignored if number of curves to plot is greater than 15. - xlabel : str + Whether to show the legend. The default is ``True``. + This parameter is ignored if the number of curves to plot is + greater than 15. + x_label : str Plot X label. - ylabel : str + y_label : str Plot Y label. title : str - Plot Title label. + Plot title label. snapshot_path : str Full path to image file if a snapshot is needed. is_polar : bool, optional @@ -800,45 +807,45 @@ def plot( else: sw = self.primary_sweep_values for curve in curves: - if not math_formula: + if not formula: data_plot.append([sw, self.data_real(curve), curve]) - elif math_formula == "re": - data_plot.append([sw, self.data_real(curve), "{}({})".format(math_formula, curve)]) - elif math_formula == "im": - data_plot.append([sw, self.data_imag(curve), "{}({})".format(math_formula, curve)]) - elif math_formula == "db20": - data_plot.append([sw, self.data_db20(curve), "{}({})".format(math_formula, curve)]) - elif math_formula == "db10": - data_plot.append([sw, self.data_db10(curve), "{}({})".format(math_formula, curve)]) - elif math_formula == "mag": - data_plot.append([sw, self.data_magnitude(curve), "{}({})".format(math_formula, curve)]) - elif math_formula == "phasedeg": - data_plot.append([sw, self.data_phase(curve, False), "{}({})".format(math_formula, curve)]) - elif math_formula == "phaserad": - data_plot.append([sw, self.data_phase(curve, True), "{}({})".format(math_formula, curve)]) - if not xlabel: - xlabel = sweep_name - if not ylabel: - ylabel = math_formula + elif formula == "re": + data_plot.append([sw, self.data_real(curve), "{}({})".format(formula, curve)]) + elif formula == "im": + data_plot.append([sw, self.data_imag(curve), "{}({})".format(formula, curve)]) + elif formula == "db20": + data_plot.append([sw, self.data_db20(curve), "{}({})".format(formula, curve)]) + elif formula == "db10": + data_plot.append([sw, self.data_db10(curve), "{}({})".format(formula, curve)]) + elif formula == "mag": + data_plot.append([sw, self.data_magnitude(curve), "{}({})".format(formula, curve)]) + elif formula == "phasedeg": + data_plot.append([sw, self.data_phase(curve, False), "{}({})".format(formula, curve)]) + elif formula == "phaserad": + data_plot.append([sw, self.data_phase(curve, True), "{}({})".format(formula, curve)]) + if not x_label: + x_label = sweep_name + if not y_label: + y_label = formula if not title: title = "Simulation Results Plot" if len(data_plot) > 15: show_legend = False if is_polar: - return plot_polar_chart(data_plot, size, show_legend, xlabel, ylabel, title, snapshot_path) + return plot_polar_chart(data_plot, size, show_legend, x_label, y_label, title, snapshot_path) else: - return plot_2d_chart(data_plot, size, show_legend, xlabel, ylabel, title, snapshot_path) + return plot_2d_chart(data_plot, size, show_legend, x_label, y_label, title, snapshot_path) - @pyaedt_function_handler() + @pyaedt_function_handler(xlabel="x_label", ylabel="y_label", math_formula="formula") def plot_3d( self, curve=None, x_axis="Theta", y_axis="Phi", - xlabel="", - ylabel="", + x_label="", + y_label="", title="", - math_formula=None, + formula=None, size=(2000, 1000), snapshot_path=None, ): @@ -849,18 +856,24 @@ def plot_3d( curve : str Curve to be plotted. If None, the first curve will be plotted. x_axis : str, optional - X Axis sweep. Default is `"Theta"`. + X-axis sweep. The default is ``"Theta"``. y_axis : str, optional - Y Axis sweep. Default is `"Phi"`. - math_formula : str , optional - Mathematical formula to apply to the plot curve. - Valid values are `"re"`, `"im"`, `"db20"`, `"db10"`, `"abs"`, `"mag"`, `"phasedeg"`, `"phaserad"`. + Y-axis sweep. The default is ``"Phi"``. + x_label : str + Plot X label. + y_label : str + Plot Y label. + title : str + Plot title label. + formula : str , optional + Mathematical formula to apply to the plot curve. The default is ``None``. + Options are `"abs"``, ``"db10"``, ``"db20"``, ``"im"``, ``"mag"``, ``"phasedeg"``, + ``"phaserad"``, and ``"re"``. size : tuple, optional - Image size in pixel (width, height). - snapshot_path : str + Image size in pixels (width, height). The default is ``(2000, 1000)``. + snapshot_path : str, optional Full path to image file if a snapshot is needed. - is_polar : bool, optional - Set to `True` if this is a polar plot. + The default is ``None``. Returns ------- @@ -872,8 +885,8 @@ def plot_3d( if not curve: curve = self.active_expression - if not math_formula: - math_formula = "mag" + if not formula: + formula = "mag" theta = self.variation_values(x_axis) y_axis_val = self.variation_values(y_axis) @@ -883,19 +896,19 @@ def plot_3d( self.active_variation[y_axis] = el phi.append(el * math.pi / 180) - if math_formula == "re": + if formula == "re": r.append(self.data_real(curve)) - elif math_formula == "im": + elif formula == "im": r.append(self.data_imag(curve)) - elif math_formula == "db20": + elif formula == "db20": r.append(self.data_db20(curve)) - elif math_formula == "db10": + elif formula == "db10": r.append(self.data_db10(curve)) - elif math_formula == "mag": + elif formula == "mag": r.append(self.data_magnitude(curve)) - elif math_formula == "phasedeg": + elif formula == "phasedeg": r.append(self.data_phase(curve, False)) - elif math_formula == "phaserad": + elif formula == "phaserad": r.append(self.data_phase(curve, True)) active_sweep = self.active_intrinsic[self.primary_sweep] position = self.variation_values(self.primary_sweep).index(active_sweep) @@ -905,13 +918,13 @@ def plot_3d( new_r.append([el[position]]) r = new_r data_plot = [theta, phi, r] - if not xlabel: - xlabel = x_axis - if not ylabel: - ylabel = y_axis + if not x_label: + x_label = x_axis + if not y_label: + y_label = y_axis if not title: title = "Simulation Results Plot" - return plot_3d_chart(data_plot, size, xlabel, ylabel, title, snapshot_path) + return plot_3d_chart(data_plot, size, x_label, y_label, title, snapshot_path) @pyaedt_function_handler() def ifft(self, curve_header="NearE", u_axis="_u", v_axis="_v", window=False): @@ -939,60 +952,60 @@ def ifft(self, curve_header="NearE", u_axis="_u", v_axis="_v", window=False): freq = self.variation_values("Freq") if self.enable_pandas_output: - E_realx = np.reshape(self._solutions_real[curve_header + "X"].copy().values, (len(freq), len(v), len(u))) - E_imagx = np.reshape(self._solutions_imag[curve_header + "X"].copy().values, (len(freq), len(v), len(u))) - E_realy = np.reshape(self._solutions_real[curve_header + "Y"].copy().values, (len(freq), len(v), len(u))) - E_imagy = np.reshape(self._solutions_imag[curve_header + "Y"].copy().values, (len(freq), len(v), len(u))) - E_realz = np.reshape(self._solutions_real[curve_header + "Z"].copy().values, (len(freq), len(v), len(u))) - E_imagz = np.reshape(self._solutions_imag[curve_header + "Z"].copy().values, (len(freq), len(v), len(u))) + e_real_x = np.reshape(self._solutions_real[curve_header + "X"].copy().values, (len(freq), len(v), len(u))) + e_imag_x = np.reshape(self._solutions_imag[curve_header + "X"].copy().values, (len(freq), len(v), len(u))) + e_real_y = np.reshape(self._solutions_real[curve_header + "Y"].copy().values, (len(freq), len(v), len(u))) + e_imag_y = np.reshape(self._solutions_imag[curve_header + "Y"].copy().values, (len(freq), len(v), len(u))) + e_real_z = np.reshape(self._solutions_real[curve_header + "Z"].copy().values, (len(freq), len(v), len(u))) + e_imag_z = np.reshape(self._solutions_imag[curve_header + "Z"].copy().values, (len(freq), len(v), len(u))) else: - vals_real_Ex = [j for j in self._solutions_real[curve_header + "X"].values()] - vals_imag_Ex = [j for j in self._solutions_imag[curve_header + "X"].values()] - vals_real_Ey = [j for j in self._solutions_real[curve_header + "Y"].values()] - vals_imag_Ey = [j for j in self._solutions_imag[curve_header + "Y"].values()] - vals_real_Ez = [j for j in self._solutions_real[curve_header + "Z"].values()] - vals_imag_Ez = [j for j in self._solutions_imag[curve_header + "Z"].values()] - - E_realx = np.reshape(vals_real_Ex, (len(freq), len(v), len(u))) - E_imagx = np.reshape(vals_imag_Ex, (len(freq), len(v), len(u))) - E_realy = np.reshape(vals_real_Ey, (len(freq), len(v), len(u))) - E_imagy = np.reshape(vals_imag_Ey, (len(freq), len(v), len(u))) - E_realz = np.reshape(vals_real_Ez, (len(freq), len(v), len(u))) - E_imagz = np.reshape(vals_imag_Ez, (len(freq), len(v), len(u))) - - Temp_E_compx = E_realx + 1j * E_imagx # Here is the complex FD data matrix, ready for transforming - Temp_E_compy = E_realy + 1j * E_imagy - Temp_E_compz = E_realz + 1j * E_imagz - - E_compx = np.zeros((len(freq), len(v), len(u)), dtype="complex_") - E_compy = np.zeros((len(freq), len(v), len(u)), dtype="complex_") - E_compz = np.zeros((len(freq), len(v), len(u)), dtype="complex_") + vals_e_real_x = [j for j in self._solutions_real[curve_header + "X"].values()] + vals_e_imag_x = [j for j in self._solutions_imag[curve_header + "X"].values()] + vals_e_real_y = [j for j in self._solutions_real[curve_header + "Y"].values()] + vals_e_imag_y = [j for j in self._solutions_imag[curve_header + "Y"].values()] + vals_e_real_z = [j for j in self._solutions_real[curve_header + "Z"].values()] + vals_e_imag_z = [j for j in self._solutions_imag[curve_header + "Z"].values()] + + e_real_x = np.reshape(vals_e_real_x, (len(freq), len(v), len(u))) + e_imag_x = np.reshape(vals_e_imag_x, (len(freq), len(v), len(u))) + e_real_y = np.reshape(vals_e_real_y, (len(freq), len(v), len(u))) + e_imag_y = np.reshape(vals_e_imag_y, (len(freq), len(v), len(u))) + e_real_z = np.reshape(vals_e_real_z, (len(freq), len(v), len(u))) + e_imag_z = np.reshape(vals_e_imag_z, (len(freq), len(v), len(u))) + + temp_e_comp_x = e_real_x + 1j * e_imag_x # Here is the complex FD data matrix, ready for transforming + temp_e_comp_y = e_real_y + 1j * e_imag_y + temp_e_comp_z = e_real_z + 1j * e_imag_z + + e_comp_x = np.zeros((len(freq), len(v), len(u)), dtype="complex_") + e_comp_y = np.zeros((len(freq), len(v), len(u)), dtype="complex_") + e_comp_z = np.zeros((len(freq), len(v), len(u)), dtype="complex_") if window: timewin = np.hanning(len(freq)) for row in range(0, len(v)): for col in range(0, len(u)): - E_compx[:, row, col] = np.multiply(Temp_E_compx[:, row, col], timewin) - E_compy[:, row, col] = np.multiply(Temp_E_compy[:, row, col], timewin) - E_compz[:, row, col] = np.multiply(Temp_E_compz[:, row, col], timewin) + e_comp_x[:, row, col] = np.multiply(temp_e_comp_x[:, row, col], timewin) + e_comp_y[:, row, col] = np.multiply(temp_e_comp_y[:, row, col], timewin) + e_comp_z[:, row, col] = np.multiply(temp_e_comp_z[:, row, col], timewin) else: - E_compx = Temp_E_compx - E_compy = Temp_E_compy - E_compz = Temp_E_compz - - E_time_x = np.fft.ifft(np.fft.fftshift(E_compx, 0), len(freq), 0, None) - E_time_y = np.fft.ifft(np.fft.fftshift(E_compy, 0), len(freq), 0, None) - E_time_z = np.fft.ifft(np.fft.fftshift(E_compz, 0), len(freq), 0, None) - E_time = np.zeros((np.size(freq), np.size(v), np.size(u))) + e_comp_x = temp_e_comp_x + e_comp_y = temp_e_comp_y + e_comp_z = temp_e_comp_z + + e_time_x = np.fft.ifft(np.fft.fftshift(e_comp_x, 0), len(freq), 0, None) + e_time_y = np.fft.ifft(np.fft.fftshift(e_comp_y, 0), len(freq), 0, None) + e_time_z = np.fft.ifft(np.fft.fftshift(e_comp_z, 0), len(freq), 0, None) + e_time = np.zeros((np.size(freq), np.size(v), np.size(u))) for i in range(0, len(freq)): - E_time[i, :, :] = np.abs( - np.sqrt(np.square(E_time_x[i, :, :]) + np.square(E_time_y[i, :, :]) + np.square(E_time_z[i, :, :])) + e_time[i, :, :] = np.abs( + np.sqrt(np.square(e_time_x[i, :, :]) + np.square(e_time_y[i, :, :]) + np.square(e_time_z[i, :, :])) ) - self._ifft = E_time + self._ifft = e_time return self._ifft - @pyaedt_function_handler() + @pyaedt_function_handler(csv_dir="csv_path", name_str="csv_file_header") def ifft_to_file( self, u_axis="_u", @@ -1000,10 +1013,10 @@ def ifft_to_file( coord_system_center=None, db_val=False, num_frames=None, - csv_dir=None, - name_str="res_", + csv_path=None, + csv_file_header="res_", ): - """Save IFFT Matrix to a list of csv files (one per time step). + """Save IFFT matrix to a list of CSV files (one per time step). Parameters ---------- @@ -1014,13 +1027,13 @@ def ifft_to_file( coord_system_center : list, optional List of UV GlobalCS Center. db_val : bool, optional - Either if data has to be exported in db or not. + Whether data must be exported into a database. The default is ``False``. num_frames : int, optional - Number of frames to export. - csv_dir : str - Output path - name_str : str, optional - csv file header. + Number of frames to export. The default is ``None``. + csv_path : str, optional + Output path. The default is ``None``. + csv_file_header : str, optional + CSV file header. The default is ``"res_"``. Returns ------- @@ -1041,15 +1054,15 @@ def ifft_to_file( else: frames = t_matrix.shape[0] csv_list = [] - if os.path.exists(csv_dir): - files = [os.path.join(csv_dir, f) for f in os.listdir(csv_dir) if name_str in f and ".csv" in f] + if os.path.exists(csv_path): + files = [os.path.join(csv_path, f) for f in os.listdir(csv_path) if csv_file_header in f and ".csv" in f] for file in files: os.remove(file) else: - os.mkdir(csv_dir) + os.mkdir(csv_path) for frame in range(frames): - output = os.path.join(csv_dir, name_str + str(frame) + ".csv") + output = os.path.join(csv_path, csv_file_header + str(frame) + ".csv") list_full = [["x", "y", "z", "val"]] for i, y in enumerate(y_c_list): for j, x in enumerate(x_c_list): @@ -1065,7 +1078,7 @@ def ifft_to_file( write_csv(output, list_full, delimiter=",") csv_list.append(output) - txt_file_name = csv_dir + "fft_list.txt" + txt_file_name = csv_path + "fft_list.txt" textfile = open_file(txt_file_name, "w") for element in csv_list: @@ -1097,12 +1110,12 @@ class FfdSolutionData(object): >>> setup_name = "Setup1 : LastAdaptive" >>> frequencies = [77e9] >>> sphere = "3D" - >>> data = app.get_antenna_ffd_solution_data(frequencies, setup_name, sphere) + >>> data = app.get_antenna_ffd_solution_data(frequencies,setup_name,sphere) >>> eep_files = data.eep_files >>> frequencies = data.frequencies >>> app.release_desktop() >>> farfield_data = FfdSolutionData(frequencies=frequencies, eep_files=eep_files) - >>> farfield_data.polar_plot_3d_pyvista(qty_str="rETotal", quantity_format="dB10") + >>> farfield_data.polar_plot_3d_pyvista(quantity_format="dB10",qty_str="rETotal") """ def __init__( @@ -1158,7 +1171,7 @@ def __init__( for eep in eep_files: metadata_file = os.path.join(os.path.dirname(eep), "eep.json") if os.path.exists(metadata_file): - with open(metadata_file) as f: + with open_file(metadata_file) as f: # Load JSON data from file metadata = json.load(f) self.model_info.append(metadata["model_info"]) @@ -1387,13 +1400,13 @@ def _phase_shift_steering(self, a, b, theta=0.0, phi=0.0): lattice_vector = self._lattice_vector[self._freq_index] - Ax, Ay, Bx, By = [lattice_vector[0], lattice_vector[1], lattice_vector[3], lattice_vector[4]] + a_x, a_y, b_x, b_y = [lattice_vector[0], lattice_vector[1], lattice_vector[3], lattice_vector[4]] - phase_shift_A = -((Ax * k * np.sin(theta) * np.cos(phi)) + (Ay * k * np.sin(theta) * np.sin(phi))) + phase_shift_a = -((a_x * k * np.sin(theta) * np.cos(phi)) + (a_y * k * np.sin(theta) * np.sin(phi))) - phase_shift_B = -((Bx * k * np.sin(theta) * np.cos(phi)) + (By * k * np.sin(theta) * np.sin(phi))) + phase_shift_b = -((b_x * k * np.sin(theta) * np.cos(phi)) + (b_y * k * np.sin(theta) * np.sin(phi))) - phase_shift = a * phase_shift_A + b * phase_shift_B + phase_shift = a * phase_shift_a + b * phase_shift_b return np.rad2deg(phase_shift) @@ -1504,15 +1517,18 @@ def combine_farfield(self, phi_scan=0, theta_scan=0): return farfield_data # fmt: off - @pyaedt_function_handler() + @pyaedt_function_handler(farfield_quantity="quantity", + phi_scan="phi", + theta_scan="theta", + export_image_path="image_path") def plot_farfield_contour( self, - farfield_quantity="RealizedGain", - phi_scan=0, - theta_scan=0, + quantity="RealizedGain", + phi=0, + theta=0, title="RectangularPlot", quantity_format="dB10", - export_image_path=None, + image_path=None, levels=64, show=True, **kwargs @@ -1522,13 +1538,13 @@ def plot_farfield_contour( Parameters ---------- - farfield_quantity : str, optional + quantity : str, optional Far field quantity to plot. The default is ``"RealizedGain"``. Available quantities are: ``"RealizedGain"``, ``"RealizedGain_Phi"``, ``"RealizedGain_Theta"``, ``"rEPhi"``, ``"rETheta"``, and ``"rETotal"``. - phi_scan : float, int, optional + phi : float, int, optional Phi scan angle in degrees. The default is ``0``. - theta_scan : float, int, optional + theta : float, int, optional Theta scan angle in degrees. The default is ``0``. title : str, optional Plot title. The default is ``"RectangularPlot"``. @@ -1536,7 +1552,7 @@ def plot_farfield_contour( Conversion data function. Available functions are: ``"abs"``, ``"ang"``, ``"dB10"``, ``"dB20"``, ``"deg"``, ``"imag"``, ``"norm"``, and ``"real"``. - export_image_path : str, optional + image_path : str, optional Full path for the image file. The default is ``None``, in which case the file is not exported. levels : int, optional Color map levels. The default is ``64``. @@ -1558,7 +1574,7 @@ def plot_farfield_contour( >>> setup_name = "Setup1 : LastAdaptive" >>> frequencies = [77e9] >>> sphere = "3D" - >>> data = app.get_antenna_ffd_solution_data(frequencies, setup_name, sphere) + >>> data = app.get_antenna_ffd_solution_data(frequencies,setup_name,sphere) >>> data.plot_farfield_contour() """ @@ -1567,19 +1583,19 @@ def plot_farfield_contour( self.logger.warning("`convert_to_db` is deprecated since v0.7.8. Use `quantity_format` instead.") quantity_format = "dB10" if kwargs["convert_to_db"] else "abs" elif k == "qty_str": # pragma: no cover - self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `farfield_quantity` instead.") - farfield_quantity = kwargs["qty_str"] + self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `quantity` instead.") + quantity = kwargs["qty_str"] else: # pragma: no cover msg = "{} not valid.".format(k) self.logger.error(msg) raise TypeError(msg) - data = self.combine_farfield(phi_scan, theta_scan) - if farfield_quantity not in data: # pragma: no cover + data = self.combine_farfield(phi, theta) + if quantity not in data: # pragma: no cover self.logger.error("Far field quantity is not available.") return False - data_to_plot = data[farfield_quantity] + data_to_plot = data[quantity] data_to_plot = conversion_function(data_to_plot, quantity_format) if not isinstance(data_to_plot, np.ndarray): # pragma: no cover self.logger.error("Wrong format quantity") @@ -1595,23 +1611,26 @@ def plot_farfield_contour( ylabel="Phi (degree)", title=title, levels=levels, - snapshot_path=export_image_path, + snapshot_path=image_path, ) else: return data_to_plot # fmt: off - @pyaedt_function_handler() + @pyaedt_function_handler(farfield_quantity="quantity", + phi_scan="phi", + theta_scan="theta", + export_image_path="image_path") def plot_2d_cut( self, - farfield_quantity="RealizedGain", + quantity="RealizedGain", primary_sweep="phi", secondary_sweep_value=0, - phi_scan=0, - theta_scan=0, + phi=0, + theta=0, title="Far Field Cut", quantity_format="dB10", - export_image_path=None, + image_path=None, show=True, is_polar=False, **kwargs @@ -1621,7 +1640,7 @@ def plot_2d_cut( Parameters ---------- - farfield_quantity : str, optional + quantity : str, optional Quantity to plot. The default is ``"RealizedGain"``. Available quantities are: ``"RealizedGain"``, ``"RealizedGain_Theta"``, ``"RealizedGain_Phi"``, ``"rETotal"``, ``"rETheta"``, and ``"rEPhi"``. @@ -1630,9 +1649,9 @@ def plot_2d_cut( secondary_sweep_value : float, list, string, optional List of cuts on the secondary sweep to plot. The default is ``0``. Options are `"all"`, a single value float, or a list of float values. - phi_scan : float, int, optional + phi : float, int, optional Phi scan angle in degrees. The default is ``0``. - theta_scan : float, int, optional + theta : float, int, optional Theta scan angle in degrees. The default is ``0``. title : str, optional Plot title. The default is ``"RectangularPlot"``. @@ -1640,7 +1659,7 @@ def plot_2d_cut( Conversion data function. Available functions are: ``"abs"``, ``"ang"``, ``"dB10"``, ``"dB20"``, ``"deg"``, ``"imag"``, ``"norm"``, and ``"real"``. - export_image_path : str, optional + image_path : str, optional Full path for the image file. The default is ``None``, in which case an image in not exported. show : bool, optional Whether to show the plot. The default is ``True``. @@ -1663,8 +1682,8 @@ def plot_2d_cut( >>> setup_name = "Setup1 : LastAdaptive" >>> frequencies = [77e9] >>> sphere = "3D" - >>> data = app.get_antenna_ffd_solution_data(frequencies, setup_name, sphere) - >>> data.plot_2d_cut(theta_scan=20) + >>> data = app.get_antenna_ffd_solution_data(frequencies,setup_name,sphere) + >>> data.plot_2d_cut(theta=20) """ @@ -1673,19 +1692,19 @@ def plot_2d_cut( self.logger.warning("`convert_to_db` is deprecated since v0.7.8. Use `quantity_format` instead.") quantity_format = "dB10" if kwargs["convert_to_db"] else "abs" elif k == "qty_str": # pragma: no cover - self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `farfield_quantity` instead.") - farfield_quantity = kwargs["qty_str"] + self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `quantity` instead.") + quantity = kwargs["qty_str"] else: # pragma: no cover msg = "{} not valid.".format(k) self.logger.error(msg) raise TypeError(msg) - data = self.combine_farfield(phi_scan, theta_scan) - if farfield_quantity not in data: # pragma: no cover + data = self.combine_farfield(phi, theta) + if quantity not in data: # pragma: no cover self.logger.error("Far field quantity not available") return False - data_to_plot = data[farfield_quantity] + data_to_plot = data[quantity] curves = [] if primary_sweep == "phi": @@ -1735,33 +1754,36 @@ def plot_2d_cut( return plot_polar_chart( curves, xlabel=x_key, - ylabel=farfield_quantity, + ylabel=quantity, title=title, - snapshot_path=export_image_path, + snapshot_path=image_path, show_legend=show_legend, ) else: return plot_2d_chart( curves, xlabel=x_key, - ylabel=farfield_quantity, + ylabel=quantity, title=title, - snapshot_path=export_image_path, + snapshot_path=image_path, show_legend=show_legend, ) else: return curves # fmt: off - @pyaedt_function_handler() + @pyaedt_function_handler(farfield_quantity="quantity", + phi_scan="phi", + theta_scan="theta", + export_image_path="image_path") def polar_plot_3d( self, - farfield_quantity="RealizedGain", - phi_scan=0, - theta_scan=0, + quantity="RealizedGain", + phi=0, + theta=0, title="3D Plot", quantity_format="dB10", - export_image_path=None, + image_path=None, show=True, **kwargs ): @@ -1770,13 +1792,13 @@ def polar_plot_3d( Parameters ---------- - farfield_quantity : str, optional + quantity : str, optional Far field quantity to plot. The default is ``"RealizedGain"``. Available quantities are: ``"RealizedGain"``, ``"RealizedGain_Phi"``, ``"RealizedGain_Theta"``, ``"rEPhi"``, ``"rETheta"``, and ``"rETotal"``. - phi_scan : float, int, optional + phi : float, int, optional Phi scan angle in degree. The default is ``0``. - theta_scan : float, int, optional + theta : float, int, optional Theta scan angle in degree. The default is ``0``. title : str, optional Plot title. The default is ``"3D Plot"``. @@ -1784,7 +1806,7 @@ def polar_plot_3d( Conversion data function. Available functions are: ``"abs"``, ``"ang"``, ``"dB10"``, ``"dB20"``, ``"deg"``, ``"imag"``, ``"norm"``, and ``"real"``. - export_image_path : str, optional + image_path : str, optional Full path for the image file. The default is ``None``, in which case a file is not exported. show : bool, optional Whether to show the plot. The default is ``True``. @@ -1804,8 +1826,8 @@ def polar_plot_3d( >>> setup_name = "Setup1 : LastAdaptive" >>> frequencies = [77e9] >>> sphere = "3D" - >>> data = app.get_antenna_ffd_solution_data(frequencies, setup_name, sphere) - >>> data.polar_plot_3d(theta_scan=10) + >>> data = app.get_antenna_ffd_solution_data(frequencies,setup_name,sphere) + >>> data.polar_plot_3d(theta=10) """ for k in kwargs: @@ -1813,19 +1835,19 @@ def polar_plot_3d( self.logger.warning("`convert_to_db` is deprecated since v0.7.8. Use `quantity_format` instead.") quantity_format = "dB10" if kwargs["convert_to_db"] else "abs" elif k == "qty_str": # pragma: no cover - self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `farfield_quantity` instead.") - farfield_quantity = kwargs["qty_str"] + self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `quantity` instead.") + quantity = kwargs["qty_str"] else: # pragma: no cover msg = "{} not valid.".format(k) self.logger.error(msg) raise TypeError(msg) - data = self.combine_farfield(phi_scan, theta_scan) - if farfield_quantity not in data: # pragma: no cover + data = self.combine_farfield(phi, theta) + if quantity not in data: # pragma: no cover self.logger.error("Far field quantity is not available.") return False - ff_data = conversion_function(data[farfield_quantity], quantity_format) + ff_data = conversion_function(data[quantity], quantity_format) if not isinstance(ff_data, np.ndarray): # pragma: no cover self.logger.error("Format of the quantity is wrong.") return False @@ -1844,18 +1866,18 @@ def polar_plot_3d( y = r * np.sin(theta_grid) * np.sin(phi_grid) z = r * np.cos(theta_grid) if show: - plot_3d_chart([x, y, z], xlabel="Theta", ylabel="Phi", title=title, snapshot_path=export_image_path) + plot_3d_chart([x, y, z], xlabel="Theta", ylabel="Phi", title=title, snapshot_path=image_path) else: return x, y, z # fmt: off - @pyaedt_function_handler() + @pyaedt_function_handler(farfield_quantity="quantity", export_image_path="image_path") def polar_plot_3d_pyvista( self, - farfield_quantity="RealizedGain", + quantity="RealizedGain", quantity_format="dB10", rotation=None, - export_image_path=None, + image_path=None, show=True, show_as_standalone=False, pyvista_object=None, @@ -1870,7 +1892,7 @@ def polar_plot_3d_pyvista( Parameters ---------- - farfield_quantity : str, optional + quantity : str, optional Quantity to plot. The default is ``"RealizedGain"``. Available quantities are: ``"RealizedGain"``, ``"RealizedGain_Theta"``, ``"RealizedGain_Phi"``, ``"rETotal"``, ``"rETheta"``, and ``"rEPhi"``. @@ -1878,7 +1900,7 @@ def polar_plot_3d_pyvista( Conversion data function. Available functions are: ``"abs"``, ``"ang"``, ``"dB10"``, ``"dB20"``, ``"deg"``, ``"imag"``, ``"norm"``, and ``"real"``. - export_image_path : str, optional + image_path : str, optional Full path for the image file. The default is ``None``, in which case a file is not exported. rotation : list, optional Far field rotation matrix. The matrix contains three vectors, around x, y, and z axes. @@ -1913,8 +1935,8 @@ def polar_plot_3d_pyvista( >>> setup_name = "Setup1 : LastAdaptive" >>> frequencies = [77e9] >>> sphere = "3D" - >>> data = app.get_antenna_ffd_solution_data(frequencies, setup_name, sphere) - >>> data.polar_plot_3d_pyvista(qty_str="RealizedGain", quantity_format="dB10") + >>> data = app.get_antenna_ffd_solution_data(frequencies,setup_name,sphere) + >>> data.polar_plot_3d_pyvista(quantity_format="dB10",qty_str="RealizedGain") """ for k in kwargs: @@ -1922,8 +1944,8 @@ def polar_plot_3d_pyvista( self.logger.warning("`convert_to_db` is deprecated since v0.7.8. Use `quantity_format` instead.") quantity_format = "dB10" if kwargs["convert_to_db"] else "abs" elif k == "qty_str": # pragma: no cover - self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `farfield_quantity` instead.") - farfield_quantity = kwargs["qty_str"] + self.logger.warning("`qty_str` is deprecated since v0.7.8. Use `quantity` instead.") + quantity = kwargs["qty_str"] else: # pragma: no cover msg = "{} not valid.".format(k) self.logger.error(msg) @@ -1939,17 +1961,17 @@ def polar_plot_3d_pyvista( text_color = "black" farfield_data = self.combine_farfield(phi_scan=0, theta_scan=0) - if farfield_quantity not in farfield_data: # pragma: no cover + if quantity not in farfield_data: # pragma: no cover self.logger.error("Far field quantity is not available.") return False self.farfield_data = farfield_data - self.mesh = self.get_far_field_mesh(farfield_quantity=farfield_quantity, quantity_format=quantity_format) + self.mesh = self.get_far_field_mesh(quantity=quantity, quantity_format=quantity_format) rotation_euler = self._rotation_to_euler_angles(rotation) * 180 / np.pi - if not export_image_path and not show: + if not image_path and not show: off_screen = False else: off_screen = not show @@ -1962,7 +1984,7 @@ def polar_plot_3d_pyvista( else: # pragma: no cover p = pyvista_object - uf = UpdateBeamForm(self, farfield_quantity, quantity_format) + uf = UpdateBeamForm(self, quantity, quantity_format) default_background = [255, 255, 255] axes_color = [i / 255 for i in default_background] @@ -2019,7 +2041,7 @@ def polar_plot_3d_pyvista( ) cad_mesh = self._get_geometry() - data = conversion_function(self.farfield_data[farfield_quantity], function_str=quantity_format) + data = conversion_function(self.farfield_data[quantity], function_str=quantity_format) if not isinstance(data, np.ndarray): # pragma: no cover self.logger.error("Wrong format quantity") return False @@ -2081,8 +2103,8 @@ def scale(value=1): p.add_text("Show Geometry", position=(70, 75), color=text_color, font_size=10) - if export_image_path: - p.show(screenshot=export_image_path) + if image_path: + p.show(screenshot=image_path) return True elif show: # pragma: no cover p.show() @@ -2108,7 +2130,7 @@ def _init_ffd(self, eep_file_info): valid_ffd = True if os.path.exists(eep_file_info[all_ports[0]][0]): - with open(eep_file_info[all_ports[0]][0], "r") as reader: + with open_file(eep_file_info[all_ports[0]][0], "r") as reader: theta = [int(i) for i in reader.readline().split()] phi = [int(i) for i in reader.readline().split()] reader.close() @@ -2138,13 +2160,13 @@ def _init_ffd(self, eep_file_info): return True - @pyaedt_function_handler() - def get_far_field_mesh(self, farfield_quantity="RealizedGain", quantity_format="dB10", **kwargs): + @pyaedt_function_handler(farfield_quantity="quantity") + def get_far_field_mesh(self, quantity="RealizedGain", quantity_format="dB10", **kwargs): """Generate a PyVista ``UnstructuredGrid`` object that represents the far field mesh. Parameters ---------- - farfield_quantity : str, optional + quantity : str, optional Far field quantity to plot. The default is ``"RealizedGain"``. Available quantities are: ``"RealizedGain"``, ``"RealizedGain_Phi"``, ``"RealizedGain_Theta"``, ``"rEPhi"``, ``"rETheta"``, and ``"rETotal"``. @@ -2168,11 +2190,11 @@ def get_far_field_mesh(self, farfield_quantity="RealizedGain", quantity_format=" self.logger.error(msg) raise TypeError(msg) - if farfield_quantity not in self.farfield_data: + if quantity not in self.farfield_data: self.logger.error("Far field quantity is not available.") return False - data = self.farfield_data[farfield_quantity] + data = self.farfield_data[quantity] ff_data = conversion_function(data, quantity_format) @@ -2202,7 +2224,7 @@ def _read_eep_files(self, eep_path): """ self._eep_file_info_list.append({}) if os.path.exists(eep_path): - with open(eep_path, "r") as reader: + with open_file(eep_path, "r") as reader: lines = [line.split(None) for line in reader] lines = lines[1:] # remove header for pattern in lines: @@ -2423,8 +2445,8 @@ class FfdSolutionDataExporter(FfdSolutionData): >>> setup_name = "Setup1 : LastAdaptive" >>> frequencies = [77e9] >>> sphere = "3D" - >>> data = app.get_antenna_ffd_solution_data(frequencies, setup_name, sphere) - >>> data.polar_plot_3d_pyvista(qty_str="rETotal", quantity_format="dB10") + >>> data = app.get_antenna_ffd_solution_data(frequencies,setup_name,sphere) + >>> data.polar_plot_3d_pyvista(quantity_format="dB10",qty_str="rETotal") """ @@ -2529,7 +2551,7 @@ def _export_all_ffd(self): ] items["lattice_vector"] = component_array.lattice_vector() - with open(metadata_file_name, "w") as f: + with open_file(metadata_file_name, "w") as f: json.dump(items, f, indent=2) elapsed_time = time.time() - time_before self._app.logger.info("Exporting embedded element patterns.... Done: %s seconds", elapsed_time) @@ -2582,13 +2604,14 @@ class UpdateBeamForm: and ``"real"``. """ + @pyaedt_function_handler(farfield_quantity="quantity") def __init__(self, ff, farfield_quantity="RealizedGain", quantity_format="abs"): self.output = ff.mesh self._phi = 0 self._theta = 0 # default parameters self.ff = ff - self.farfield_quantity = farfield_quantity + self.quantity = farfield_quantity self.quantity_format = quantity_format @pyaedt_function_handler() @@ -2596,7 +2619,7 @@ def _update_both(self): """Update far field.""" self.ff.farfield_data = self.ff.combine_farfield(phi_scan=self._phi, theta_scan=self._theta) - self.ff.mesh = self.ff.get_far_field_mesh(self.farfield_quantity, self.quantity_format) + self.ff.mesh = self.ff.get_far_field_mesh(self.quantity, self.quantity_format) self.output.copy_from(self.ff.mesh) return @@ -2620,45 +2643,57 @@ class FieldPlot: Parameters ---------- postprocessor : :class:`pyaedt.modules.PostProcessor.PostProcessor` - objlist : list + objects : list List of objects. - solutionName : str + solution : str Name of the solution. - quantityName : str + quantity : str Name of the plot or the name of the object. - intrinsincList : dict, optional + intrinsics : dict, optional Name of the intrinsic dictionary. The default is ``{}``. """ + @pyaedt_function_handler( + objlist="objects", + surfacelist="surfaces", + linelist="lines", + cutplanelist="cutplanes", + solutionName="solution", + quantityName="quantity", + IntrinsincList="intrinsics", + seedingFaces="seeding_faces", + layers_nets="layer_nets", + layers_plot_type="layer_plot_type", + ) def __init__( self, postprocessor, - objlist=[], - surfacelist=[], - linelist=[], - cutplanelist=[], - solutionName="", - quantityName="", - intrinsincList={}, - seedingFaces=[], - layers_nets=[], - layers_plot_type="LayerNetsExtFace", + objects=[], + surfaces=[], + lines=[], + cutplanes=[], + solution="", + quantity="", + intrinsics={}, + seeding_faces=[], + layer_nets=[], + layer_plot_type="LayerNetsExtFace", ): self._postprocessor = postprocessor self.oField = postprocessor.ofieldsreporter - self.volume_indexes = objlist - self.surfaces_indexes = surfacelist - self.line_indexes = linelist - self.cutplane_indexes = cutplanelist - self.layers_nets = layers_nets - self.layers_plot_type = layers_plot_type - self.seeding_faces = seedingFaces - self.solutionName = solutionName - self.quantityName = quantityName - self.intrinsincList = intrinsincList + self.volumes = objects + self.surfaces = surfaces + self.lines = lines + self.cutplanes = cutplanes + self.layer_nets = layer_nets + self.layer_plot_type = layer_plot_type + self.seeding_faces = seeding_faces + self.solution = solution + self.quantity = quantity + self.intrinsics = intrinsics self.name = "Field_Plot" - self.plotFolder = "Field_Plot" + self.plot_folder = "Field_Plot" self.Filled = False self.IsoVal = "Fringe" self.SmoothShade = True @@ -2704,32 +2739,32 @@ def filter_boxes(self, val): def plotGeomInfo(self): """Plot geometry information.""" idx = 0 - if self.volume_indexes: + if self.volumes: idx += 1 - if self.surfaces_indexes: + if self.surfaces: idx += 1 - if self.cutplane_indexes: + if self.cutplanes: idx += 1 - if self.line_indexes: + if self.lines: idx += 1 - if self.layers_nets: + if self.layer_nets: idx += 1 info = [idx] - if self.volume_indexes: + if self.volumes: info.append("Volume") info.append("ObjList") - info.append(len(self.volume_indexes)) - for index in self.volume_indexes: + info.append(len(self.volumes)) + for index in self.volumes: info.append(str(index)) - if self.surfaces_indexes: + if self.surfaces: model_faces = [] nonmodel_faces = [] if self._postprocessor._app.design_type == "HFSS 3D Layout Design": - model_faces = [str(i) for i in self.surfaces_indexes] + model_faces = [str(i) for i in self.surfaces] else: models = self._postprocessor.modeler.model_objects - for index in self.surfaces_indexes: + for index in self.surfaces: try: if isinstance(index, FacePrimitive): index = index.id @@ -2751,26 +2786,26 @@ def plotGeomInfo(self): info.append(len(nonmodel_faces)) for index in nonmodel_faces: info.append(index) - if self.cutplane_indexes: + if self.cutplanes: info.append("Surface") info.append("CutPlane") - info.append(len(self.cutplane_indexes)) - for index in self.cutplane_indexes: + info.append(len(self.cutplanes)) + for index in self.cutplanes: info.append(str(index)) - if self.line_indexes: + if self.lines: info.append("Line") - info.append(len(self.line_indexes)) - for index in self.line_indexes: + info.append(len(self.lines)) + for index in self.lines: info.append(str(index)) - if self.layers_nets: - if self.layers_plot_type == "LayerNets": + if self.layer_nets: + if self.layer_plot_type == "LayerNets": info.append("Volume") info.append("LayerNets") else: info.append("Surface") info.append("LayerNetsExtFace") - info.append(len(self.layers_nets)) - for index in self.layers_nets: + info.append(len(self.layer_nets)) + for index in self.layer_nets: info.append(index[0]) info.append(len(index[1:])) info.extend(index[1:]) @@ -2786,18 +2821,18 @@ def intrinsicVar(self): List or dictionary of the variables for the field plot. """ var = "" - if type(self.intrinsincList) is list: + if isinstance(self.intrinsics, list): l = 0 - while l < len(self.intrinsincList): - val = self.intrinsincList[l + 1] - if ":=" in self.intrinsincList[l] and isinstance(self.intrinsincList[l + 1], list): - val = self.intrinsincList[l + 1][0] - ll = self.intrinsincList[l].split(":=") + while l < len(self.intrinsics): + val = self.intrinsics[l + 1] + if ":=" in self.intrinsics[l] and isinstance(self.intrinsics[l + 1], list): + val = self.intrinsics[l + 1][0] + ll = self.intrinsics[l].split(":=") var += ll[0] + "='" + str(val) + "' " l += 2 else: - for a in self.intrinsincList: - var += a + "='" + str(self.intrinsincList[a]) + "' " + for a in self.intrinsics: + var += a + "='" + str(self.intrinsics[a]) + "' " return var @property @@ -2809,11 +2844,7 @@ def plotsettings(self): list List of plot settings. """ - if ( - self.surfaces_indexes - or self.cutplane_indexes - or (self.layers_nets and self.layers_plot_type == "LayerNetsExtFace") - ): + if self.surfaces or self.cutplanes or (self.layer_nets and self.layer_plot_type == "LayerNetsExtFace"): arg = [ "NAME:PlotOnSurfaceSettings", "Filled:=", @@ -2846,7 +2877,7 @@ def plotsettings(self): "GridColor:=", self.GridColor, ] - elif self.line_indexes: + elif self.lines: arg = [ "NAME:PlotOnLineSettings", ["NAME:LineSettingsID", "Width:=", self.LineWidth, "Style:=", self.LineStyle], @@ -2901,11 +2932,11 @@ def surfacePlotInstruction(self): out = [ "NAME:" + self.name, "SolutionName:=", - self.solutionName, + self.solution, "QuantityName:=", - self.quantityName, + self.quantity, "PlotFolder:=", - self.plotFolder, + self.plot_folder, ] if self.field_type: out.extend(["FieldType:=", self.field_type]) @@ -2950,7 +2981,7 @@ def surfacePlotInstructionLineTraces(self): out = [ "NAME:" + self.name, "SolutionName:=", - self.solutionName, + self.solution, "UserSpecifyName:=", 0, "UserSpecifyFolder:=", @@ -2958,7 +2989,7 @@ def surfacePlotInstructionLineTraces(self): "QuantityName:=", "QuantityName_FieldLineTrace", "PlotFolder:=", - self.plotFolder, + self.plot_folder, ] if self.field_type: out.extend(["FieldType:=", self.field_type]) @@ -2975,9 +3006,9 @@ def surfacePlotInstructionLineTraces(self): "Seeding Markers:=", [0], "Surface Tracing Objects:=", - self.surfaces_indexes, + self.surfaces, "Volume Tracing Objects:=", - self.volume_indexes, + self.volumes, "Seeding Sampling Option:=", self.SeedingSamplingOption, "Seeding Points Number:=", @@ -3112,28 +3143,28 @@ def update(self): self.seeding_faces.remove(face) return False self.seeding_faces[0] = len(self.seeding_faces) - 1 - if self.volume_indexes[0] != len(self.volume_indexes) - 1: - for obj in self.volume_indexes[1:]: + if self.volumes[0] != len(self.volumes) - 1: + for obj in self.volumes[1:]: if not isinstance(obj, int): self._postprocessor.logger.error("Provide valid object id for in-volume object.") return False else: if obj not in list(self._postprocessor._app.modeler.objects.keys()): self._postprocessor.logger.error("Invalid object id.") - self.volume_indexes.remove(obj) + self.volumes.remove(obj) return False - self.volume_indexes[0] = len(self.volume_indexes) - 1 - if self.surfaces_indexes[0] != len(self.surfaces_indexes) - 1: - for obj in self.surfaces_indexes[1:]: + self.volumes[0] = len(self.volumes) - 1 + if self.surfaces[0] != len(self.surfaces) - 1: + for obj in self.surfaces[1:]: if not isinstance(obj, int): self._postprocessor.logger.error("Provide valid object id for surface object.") return False else: if obj not in list(self._postprocessor._app.modeler.objects.keys()): self._postprocessor.logger.error("Invalid object id.") - self.surfaces_indexes.remove(obj) + self.surfaces.remove(obj) return False - self.surfaces_indexes[0] = len(self.surfaces_indexes) - 1 + self.surfaces[0] = len(self.surfaces) - 1 self.oField.ModifyFieldPlot(self.name, self.surfacePlotInstructionLineTraces) else: self.oField.ModifyFieldPlot(self.name, self.surfacePlotInstruction) @@ -3216,7 +3247,7 @@ def change_plot_scale(self, minimum_value, maximum_value, is_log=False, is_db=Fa 1, ] ] - self.oField.SetPlotFolderSettings(self.plotFolder, args) + self.oField.SetPlotFolderSettings(self.plot_folder, args) return True @pyaedt_function_handler() @@ -3252,18 +3283,19 @@ def export_image(self, full_path=None, width=1920, height=1080, orientation="iso >>> oModule.ExportModelImageToFile >>> oModule.ExportPlotImageWithViewToFile """ - self.oField.UpdateQuantityFieldsPlots(self.plotFolder) + self.oField.UpdateQuantityFieldsPlots(self.plot_folder) if not full_path: full_path = os.path.join(self._postprocessor._app.working_directory, self.name + ".png") status = self._postprocessor.export_field_jpg( full_path, self.name, - self.plotFolder, + self.plot_folder, orientation=orientation, width=width, height=height, display_wireframe=display_wireframe, ) + full_path = check_and_download_file(full_path) if status: return full_path else: @@ -3313,7 +3345,7 @@ def export_image_from_aedtplt( meshplot=plot_mesh, imageformat="jpg", view=view, - plot_label=self.quantityName, + plot_label=self.quantity, show=False, scale_min=scale_min, scale_max=scale_max, @@ -3331,7 +3363,7 @@ class VRTFieldPlot: postprocessor : :class:`pyaedt.modules.PostProcessor.PostProcessor` is_creeping_wave : bool Whether it is a creeping wave model or not. - quantity_name : str, optional + quantity : str, optional Name of the plot or the name of the object. max_frequency : str, optional Maximum Frequency. The default is ``"1GHz"``. @@ -3339,26 +3371,27 @@ class VRTFieldPlot: Ray Density. The default is ``2``. bounces : int, optional Maximum number of bounces. The default is ``5``. - intrinsinc_list : dict, optional + intrinsics : dict, optional Name of the intrinsic dictionary. The default is ``{}``. """ + @pyaedt_function_handler(quantity_name="quantity") def __init__( self, postprocessor, is_creeping_wave=False, - quantity_name="QuantityName_SBR", + quantity="QuantityName_SBR", max_frequency="1GHz", ray_density=2, bounces=5, - intrinsinc_list={}, + intrinsics={}, ): self.is_creeping_wave = is_creeping_wave self._postprocessor = postprocessor self._ofield = postprocessor.ofieldsreporter - self.quantity_name = quantity_name - self.intrinsics = intrinsinc_list + self.quantity = quantity + self.intrinsics = intrinsics self.name = "Field_Plot" self.plot_folder = "Field_Plot" self.max_frequency = max_frequency @@ -3417,7 +3450,7 @@ def _create_args(self): "UserSpecifyFolder:=", 0, "QuantityName:=", - self.quantity_name, + self.quantity, "PlotFolder:=", "Visual Ray Trace SBR", "IntrinsicVar:=", @@ -3487,7 +3520,7 @@ def _create_args_creeping(self): "UserSpecifyFolder:=", 0, "QuantityName:=", - self.quantity_name, + self.quantity, "PlotFolder:=", "Visual Ray Trace CW", "IntrinsicVar:=", @@ -3566,21 +3599,22 @@ def delete(self): self._ofield.DeleteFieldPlot([self.name]) return True - @pyaedt_function_handler() - def export(self, path_to_hdm_file=None): + @pyaedt_function_handler(path_to_hdm_file="path") + def export(self, path=None): """Export the Visual Ray Tracing to ``hdm`` file. Parameters ---------- - path_to_hdm_file : str, optional - Full path to output file. If ``None``, the file will be exported in working directory. + path : str, optional + Full path to the output file. The default is ``None``, in which case the file is + exported to the working directory. Returns ------- str Path to the file. """ - if not path_to_hdm_file: - path_to_hdm_file = os.path.join(self._postprocessor._app.working_directory, self.name + ".hdm") - self._ofield.ExportFieldPlot(self.name, False, path_to_hdm_file) - return path_to_hdm_file + if not path: + path = os.path.join(self._postprocessor._app.working_directory, self.name + ".hdm") + self._ofield.ExportFieldPlot(self.name, False, path) + return path diff --git a/pyaedt/q3d.py b/pyaedt/q3d.py index ea6253555dd..ba919aa1172 100644 --- a/pyaedt/q3d.py +++ b/pyaedt/q3d.py @@ -83,18 +83,22 @@ def __init__( for el in list(self.omatrix.ListReduceMatrixes()): self.matrices.append(Matrix(self, el)) - @property - def excitations(self): - """Get all excitation names. + @pyaedt_function_handler() + def sources(self, matrix_index=0, is_gc_sources=True): + """List of matrix sources. + + Parameters + ---------- + matrix_index : int, optional + Matrix index in matrices list. Default is ``0`` to use main matrix with no reduction. + is_gc_sources : bool, + In Q3d, define if to return GC sources or RL sources. Default `True`. Returns ------- - list - List of excitation names. Excitations with multiple modes will return one - excitation for each mode. - + List """ - return self.matrices[0].sources(False) + return self.matrices[matrix_index].sources(is_gc_sources=is_gc_sources) @pyaedt_function_handler() def insert_reduced_matrix( @@ -160,7 +164,7 @@ def get_all_sources(self): >>> oModule.GetAllSources """ - return self.excitations + return self.sources(0, False) @pyaedt_function_handler() def get_traces_for_plot( @@ -209,13 +213,13 @@ def get_traces_for_plot( category=category, ) - @pyaedt_function_handler() - def export_mesh_stats(self, setup_name, variation_string="", mesh_path=None, setup_type="CG"): + @pyaedt_function_handler(setup_name="setup") + def export_mesh_stats(self, setup, variation_string="", mesh_path=None, setup_type="CG"): """Export mesh statistics to a file. Parameters ---------- - setup_name : str + setup : str Setup name. variation_string : str, optional Variation list. The default is ``""``. @@ -237,7 +241,7 @@ def export_mesh_stats(self, setup_name, variation_string="", mesh_path=None, set """ if not mesh_path: mesh_path = os.path.join(self.working_directory, "meshstats.ms") - self.odesign.ExportMeshStats(setup_name, variation_string, setup_type, mesh_path) + self.odesign.ExportMeshStats(setup, variation_string, setup_type, mesh_path) return mesh_path @pyaedt_function_handler() @@ -277,17 +281,15 @@ def edit_sources( >>> sources_cg = {"Box1": ("1V", "0deg"), "Box1_2": "1V"} >>> sources_acrl = {"Box1:Source1": ("5A", "0deg")} >>> sources_dcrl = {"Box1_1:Source2": ("5V", "0deg")} - >>> hfss.edit_sources(sources_cg, sources_acrl, sources_dcrl) + >>> hfss.edit_sources(sources_cg,sources_acrl,sources_dcrl) """ setting_AC = [] setting_CG = [] setting_DC = [] if cg: net_list = ["NAME:Source Names"] - if self.default_solution_type == "Q3D Extractor": - excitation = self.nets - else: - excitation = self.excitations + + excitation = self.excitations for key, value in cg.items(): if key not in excitation: @@ -322,8 +324,8 @@ def edit_sources( if acrl: source_list = ["NAME:Source Names"] unit = "V" + excitation = self.sources(0, False) for key, value in acrl.items(): - excitation = self.excitations if key not in excitation: self.logger.error("Not existing excitation " + key) return False @@ -362,8 +364,8 @@ def edit_sources( if dcrl and self.default_solution_type == "Q3D Extractor": unit = "V" source_list = ["NAME:Source Names"] + excitation = self.sources(0, False) for key, value in dcrl.items(): - excitation = self.excitations if key not in excitation: self.logger.error("Not existing excitation " + key) return False @@ -393,12 +395,13 @@ def edit_sources( return True + @pyaedt_function_handler(setup_name="setup") def export_matrix_data( self, file_name, problem_type=None, variations=None, - setup_name=None, + setup=None, sweep=None, reduce_matrix=None, r_unit="ohm", @@ -408,7 +411,7 @@ def export_matrix_data( freq=None, freq_unit=None, matrix_type=None, - export_AC_DC_res=False, + export_ac_dc_res=False, precision=None, field_width=None, use_sci_notation=True, @@ -429,7 +432,7 @@ def export_matrix_data( variations : str, optional Design variation. The default is ``None``, in which case the current nominal variation is used. - setup_name : str, optional + setup : str, optional Setup name. The default value is ``None``, in which case the first analysis setup is used. sweep : str, optional @@ -457,12 +460,11 @@ def export_matrix_data( Frequency unit. The default value is ``None``, in which case the default unit is used. matrix_type : str, optional - Matrix Type. - Possible Values are "Maxwell", "Spice" and "Couple". - The default value is ``None``. - export_AC_DC_res : bool, optional - Whether to add the AC and DC res. - The default value is ``False``. + Matrix type. The default is ``None``. + Options are ``"Couple"``, ``"Maxwell"``, and ``"Spice"``. + export_ac_dc_res : bool, optional + Whether to add the AC and DC resistance. + The default is ``False``. precision : int, optional Precision format. The default value is ``15``. @@ -558,10 +560,10 @@ def export_matrix_data( variations_list.append(variation) variations = ",".join(variations_list) - if setup_name is None: - setup_name = self.active_setup - elif setup_name != self.active_setup: - self.logger.error("Setup named: %s is invalid. Provide a valid analysis setup name.", setup_name) + if setup is None: + setup = self.active_setup + elif setup != self.active_setup: + self.logger.error("Setup named: %s is invalid. Provide a valid analysis setup name.", setup) return False if sweep is None: sweep = self.design_solutions.default_adaptive @@ -570,7 +572,7 @@ def export_matrix_data( if sweep.replace(" ", "") not in sweep_array: self.logger.error("Sweep is invalid. Provide a valid sweep.") return False - analysis_setup = setup_name + " : " + sweep.replace(" ", "") + analysis_setup = setup + " : " + sweep.replace(" ", "") if reduce_matrix is None: reduce_matrix = "Original" @@ -621,9 +623,7 @@ def export_matrix_data( freq = ( re.compile(r"(\d+)\s*(\w+)") .match( - self.modeler._odesign.GetChildObject("Analysis") - .GetChildObject(setup_name) - .GetPropValue("Adaptive Freq") + self.modeler._odesign.GetChildObject("Analysis").GetChildObject(setup).GetPropValue("Adaptive Freq") ) .groups()[0] ) @@ -631,8 +631,8 @@ def export_matrix_data( if freq_unit != self.odesktop.GetDefaultUnit("Frequency") and freq_unit is not None: freq = go.parse_dim_arg("{}{}".format(freq, freq_unit), self.odesktop.GetDefaultUnit("Frequency")) - if export_AC_DC_res is None: - export_AC_DC_res = False + if export_ac_dc_res is None: + export_ac_dc_res = False if precision is None: precision = 15 @@ -700,7 +700,7 @@ def export_matrix_data( length_setting, length, matrix_type, - export_AC_DC_res, + export_ac_dc_res, precision, field_width, use_sci_notation, @@ -723,7 +723,7 @@ def export_matrix_data( g_unit, freq, matrix_type, - export_AC_DC_res, + export_ac_dc_res, precision, field_width, use_sci_notation, @@ -1788,7 +1788,7 @@ def create_frequency_sweep(self, setupname, units=None, freqstart=0, freqstop=1, ------- >>> from pyaedt import Q3d >>> q3d = Q3d() - >>> setup1 = q3d.create_setup(setupname="Setup1") + >>> setup1 = q3d.create_setup(name="Setup1") >>> sweep1 = setup1.create_frequency_sweep(unit="GHz", freqstart=0.5, freqstop=1.5, sweepname="Sweep1") >>> q3d.release_desktop(True, True) @@ -1859,7 +1859,7 @@ def create_discrete_sweep( ------- >>> from pyaedt import Q3d >>> q3d = Q3d() - >>> setup1 = q3d.create_setup(setupname="Setup1") + >>> setup1 = q3d.create_setup(name="Setup1") >>> sweep1 = setup1.create_frequency_sweep(unit="GHz", ... freqstart=0.5, ... freqstop=1.5, @@ -1974,17 +1974,16 @@ def set_material_thresholds( except Exception: return False - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", **kwargs): + @pyaedt_function_handler(setupname="name") + def create_setup(self, name="MySetupAuto", **kwargs): """Create an analysis setup for Q3D Extractor. - Optional arguments are passed along with the ``setupname`` parameter. - + Optional arguments are passed along with the ``name`` parameter. Parameters ---------- - setupname : str, optional + name : str, optional Name of the setup. The default is "Setup1". **kwargs : dict, optional Available keys depend on the setup chosen. @@ -2005,15 +2004,15 @@ def create_setup(self, setupname="MySetupAuto", **kwargs): >>> from pyaedt import Q3d >>> app = Q3d() - >>> app.create_setup(setupname="Setup1", DC__MinPass=2) + >>> app.create_setup(name="Setup1",DC__MinPass=2) """ - setuptype = self.design_solutions.default_setup + setup_type = self.design_solutions.default_setup if "props" in kwargs: - return self._create_setup(setupname=setupname, setuptype=setuptype, props=kwargs["props"]) + return self._create_setup(name=name, setup_type=setup_type, props=kwargs["props"]) else: - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: @@ -2490,28 +2489,26 @@ def toggle_conductor_type(self, conductor_name, new_type): self.logger.error("Error in updating conductor type") return False - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(setup_name="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create an analysis setup for 2D Extractor. - Optional arguments are passed along with the ``setuptype`` and ``setupname`` - parameters. Keyword names correspond to the ``setuptype`` + Optional arguments are passed along with the ``setup_type`` and ``name`` + parameters. Keyword names correspond to the ``setup_type`` corresponding to the native AEDT API. The list of keywords here is not exhaustive. - Parameters ---------- - setuptype : int, str, optional + name : str, optional + Name of the setup. The default is "Setup1". + setup_type : int, str, optional Type of the setup. Options are "IcepakSteadyState" and "IcepakTransient". The default is "IcepakSteadyState". - setupname : str, optional - Name of the setup. The default is "Setup1". **kwargs : dict, optional Available keys depend on the setup chosen. For more information, see :doc:`../SetupTemplatesQ3D`. - Returns ------- :class:`pyaedt.modules.SolveSetup.SetupHFSS` @@ -2527,17 +2524,17 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Q2d >>> app = Q2d() - >>> app.create_setup(setupname="Setup1", RLDataBlock__MinPass=2)) + >>> app.create_setup(name="Setup1",RLDataBlock__MinPass=2) """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) if "props" in kwargs: - return self._create_setup(setupname=setupname, setuptype=setuptype, props=kwargs["props"]) + return self._create_setup(name=name, setup_type=setup_type, props=kwargs["props"]) else: - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: diff --git a/pyaedt/rmxprt.py b/pyaedt/rmxprt.py index d018528eac5..3ed62c4855b 100644 --- a/pyaedt/rmxprt.py +++ b/pyaedt/rmxprt.py @@ -4,6 +4,7 @@ from pyaedt.application.AnalysisRMxprt import FieldAnalysisRMxprt from pyaedt.generic.general_methods import pyaedt_function_handler +from pyaedt.modules.SetupTemplates import SetupKeys class RMXprtModule(object): @@ -249,27 +250,26 @@ def design_type(self): def design_type(self, value): self.design_solutions.design_type = value - @pyaedt_function_handler() - def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): + @pyaedt_function_handler(name="name", setuptype="setup_type") + def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs): """Create an analysis setup for RmXport. - Optional arguments are passed along with the ``setuptype`` and ``setupname`` - parameters. Keyword names correspond to the ``setuptype`` + Optional arguments are passed along with the ``setup_type`` and ``name`` + parameters. Keyword names correspond to the ``setup_type`` corresponding to the native AEDT API. The list of keywords here is not exhaustive. Parameters ---------- - setuptype : int, str, optional + name : str, optional + Name of the setup. The default is "Setup1". + setup_type : int, str, optional Type of the setup. Options are "IcepakSteadyState" and "IcepakTransient". The default is "IcepakSteadyState". - setupname : str, optional - Name of the setup. The default is "Setup1". **kwargs : dict, optional Available keys depend on the setup chosen. For more information, see :doc:`../SetupTemplatesRmxprt`. - Returns ------- :class:`pyaedt.modules.SolveSetup.SetupHFSS` @@ -285,17 +285,17 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, **kwargs): >>> from pyaedt import Hfss >>> hfss = Hfss() - >>> hfss.create_setup(setupname="Setup1", setuptype="HFSSDriven", Frequency="10GHz") + >>> hfss.create_setup(name="Setup1",setup_type="HFSSDriven",Frequency="10GHz") """ - if setuptype is None: - setuptype = self.design_solutions.default_setup - elif setuptype in SetupKeys.SetupNames: - setuptype = SetupKeys.SetupNames.index(setuptype) + if setup_type is None: + setup_type = self.design_solutions.default_setup + elif setup_type in SetupKeys.SetupNames: + setup_type = SetupKeys.SetupNames.index(setup_type) if "props" in kwargs: - return self._create_setup(setupname=setupname, setuptype=setuptype, props=kwargs["props"]) + return self._create_setup(name=name, setup_type=setup_type, props=kwargs["props"]) else: - setup = self._create_setup(setupname=setupname, setuptype=setuptype) + setup = self._create_setup(name=name, setup_type=setup_type) setup.auto_update = False for arg_name, arg_value in kwargs.items(): if setup[arg_name] is not None: diff --git a/pyaedt/rpc/rpyc_services.py b/pyaedt/rpc/rpyc_services.py index 7c782bd90af..015fc8c6154 100644 --- a/pyaedt/rpc/rpyc_services.py +++ b/pyaedt/rpc/rpyc_services.py @@ -147,11 +147,11 @@ def _download_dir(self, remotepath, localpath, overwrite=True): i += 1 logger.info("Directory %s downloaded. %s files copied", localpath, i) - def open_file(self, remote_file, open_options="r"): - return self.client.root.open(remote_file, open_options=open_options) + def open_file(self, remote_file, open_options="r", encoding=None): + return self.client.root.open(remote_file, open_options=open_options, encoding=encoding) - def create_file(self, remote_file, create_options="w"): - return self.client.root.open(remote_file, open_options=create_options) + def create_file(self, remote_file, create_options="w", encoding=None, override=True): + return self.client.root.create(remote_file, open_options=create_options, encoding=encoding, override=override) def makedirs(self, remotepath): if self.client.root.pathexists(remotepath): @@ -172,6 +172,10 @@ def pathexists(self, remotepath): if self.client.root.pathexists(remotepath): return True return False + def unlink(self, remotepath): + if self.client.root.unlink(remotepath): + return True + return False def normpath(self, remotepath): return self.client.root.normpath(remotepath) def isdir(self, remotepath): @@ -1025,15 +1029,15 @@ def edb(edbpath=None, use_ppe=use_ppe, ) @staticmethod - def exposed_open(filename, open_options="rb"): - f = open(filename, open_options) + def exposed_open(filename, open_options="rb", encoding=None): + f = open(filename, open_options, encoding=encoding) return rpyc.restricted(f, ["read", "readlines", "close"], []) @staticmethod - def exposed_create(filename,create_options="wb"): - if os.path.exists(filename): + def exposed_create(filename,create_options="wb", encoding=None, override=True): + if os.path.exists(filename) and not override: return "File already exists" - f = open(filename, create_options) + f = open(filename, create_options, encoding=encoding) return rpyc.restricted(f, ["read", "readlines", "write", "writelines", "close"], []) @staticmethod @@ -1055,6 +1059,12 @@ def exposed_pathexists(remotepath): return True return False + @staticmethod + def exposed_unlink(remotepath): + if os.unlink(remotepath): + return True + return False + @staticmethod def exposed_isdir(remotepath): return os.path.isdir(remotepath) diff --git a/pyaedt/twinbuilder.py b/pyaedt/twinbuilder.py index 989c4f02059..68eaf02a7be 100644 --- a/pyaedt/twinbuilder.py +++ b/pyaedt/twinbuilder.py @@ -10,6 +10,7 @@ from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.general_methods import generate_unique_name from pyaedt.generic.general_methods import is_number +from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler @@ -154,7 +155,7 @@ def create_schematic_from_netlist(self, file_to_import): ypos = 0 delta = 0.0508 use_instance = True - with open(file_to_import, "r") as f: + with open_file(file_to_import, "r") as f: for line in f: mycomp = None fields = line.split(" ") @@ -313,13 +314,13 @@ def set_sim_setup_parameter(self, var_str, expression, analysis_name="TR"): ) return True - @pyaedt_function_handler() + @pyaedt_function_handler(setup_name="setup", sweep_name="sweep") def add_q3d_dynamic_component( self, source_project, source_design_name, - setup_name, - sweep_name, + setup, + sweep, coupling_matrix_name, model_depth="1meter", maximum_order=10000, @@ -336,11 +337,11 @@ def add_q3d_dynamic_component( source_project : str Source project name or project path. source_design_name : str - Source Design name in specified project. - setup_name : str + Source design name. + setup : str Setup name. - sweep_name : str - Sweep name + sweep : str + Sweep name. coupling_matrix_name : str Coupling matrix name. model_depth : str, optional @@ -379,10 +380,12 @@ def add_q3d_dynamic_component( References ---------- + >>> oComponentManager.AddDynamicNPortData Examples -------- + Create an instance of Twin Builder. >>> from pyaedt import TwinBuilder @@ -390,17 +393,12 @@ def add_q3d_dynamic_component( Add a Q2D dynamic link component. - >>> tb.add_q3d_dynamic_component("Q2D_ArmouredCableExample", - ... "2D_Extractor_Cable", - ... "MySetupAuto", - ... "sweep1", - ... "Original", - ... "100mm") + >>> tb.add_q3d_dynamic_component("Q2D_ArmouredCableExample", "2D_Extractor_Cable", "MySetupAuto", "sweep1", + ... "Original","100mm") >>> tb.release_desktop() """ dkp = self.desktop_class is_loaded = False - app = None if os.path.isfile(source_project): project_path = source_project project_name = os.path.splitext(os.path.basename(source_project))[0] @@ -417,13 +415,14 @@ def add_q3d_dynamic_component( raise ValueError("Invalid project name or path provided.") if app is None: # pragma: no cover raise ValueError("Invalid project or design name.") + setup_name = setup setup = [s for s in app.setups if s.name == setup_name] if not setup: raise ValueError("Invalid setup in selected design.") else: - sweeps = [s for s in app.get_sweeps(setup_name) if s == sweep_name] + sweeps = [s for s in app.get_sweeps(setup_name) if s == sweep] if sweeps: # pragma: no cover - coupling_solution_name = "{} : {}".format(setup_name, sweep_name) + coupling_solution_name = "{} : {}".format(setup_name, sweep) else: # pragma: no cover raise ValueError("Invalid sweep name.") if not [m for m in app.matrices if m.name == coupling_matrix_name]: @@ -447,7 +446,7 @@ def add_q3d_dynamic_component( if not is_number(value) and not unit: raise TypeError("Model depth must be provided as a string with value and unit.") design_type = "Q2D" - signal_list = [e.name for e in app.design_excitations if e.type == "SignalLine"] + signal_list = [k for k, v in app.excitation_objects.items() if v.type == "SignalLine"] for signal in signal_list: port_info_list_A.append("OnePortInfo:=") port_info_list_B.append("OnePortInfo:=") diff --git a/pyproject.toml b/pyproject.toml index 614073dea19..b8043411ccd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ dependencies = [ tests = [ "imageio>=2.30.0,<2.35", "ipython>=7.30.0,<8.24", - "joblib>=1.0.0,<1.4", + "joblib>=1.0.0,<1.5", "matplotlib>=3.5.0,<3.9", "mock>=5.1.0,<5.2", "numpy>=1.20.0,<2", @@ -72,7 +72,7 @@ doc = [ "ipython>=7.34.0; python_version == '3.7'", "ipython>=8.13.0,<8.24; python_version > '3.7'", #"ipywidgets>=8.0.0,<8.2", - "joblib>=1.3.0,<1.4", + "joblib>=1.3.0,<1.5", "jupyterlab>=4.0.0,<4.3", "matplotlib>=3.5.0,<3.9", "nbsphinx>=0.9.0,<0.10", @@ -82,14 +82,14 @@ doc = [ "pypandoc>=1.10.0,<1.14", #"pytest-sphinx", "pyvista>=0.38.0,<0.44", - #"recommonmark", + "recommonmark", #"scikit-learn", "scikit-rf>=0.30.0,<0.33", "Sphinx==5.3.0; python_version == '3.7'", "Sphinx>=7.1.0,<7.3; python_version > '3.7'", "sphinx-autobuild==2021.3.14; python_version == '3.7'", "sphinx-autobuild==2021.3.14; python_version == '3.8'", - "sphinx-autobuild==2024.2.4; python_version > '3.8'", + "sphinx-autobuild==2024.4.13; python_version > '3.8'", #"sphinx-autodoc-typehints", "sphinx-copybutton>=0.5.0,<0.6", "sphinx-gallery>=0.14.0,<0.16", @@ -111,7 +111,7 @@ doc-noexamples = [ "Sphinx>=7.1.0,<7.3; python_version > '3.7'", "sphinx-autobuild==2021.3.14; python_version == '3.7'", "sphinx-autobuild==2021.3.14; python_version == '3.8'", - "sphinx-autobuild==2024.2.4; python_version > '3.8'", + "sphinx-autobuild==2024.4.13; python_version > '3.8'", #"sphinx-autodoc-typehints", "sphinx-copybutton>=0.5.0,<0.6", "sphinx-gallery>=0.14.0,<0.16",