├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── ci-build.yml │ └── update-gh-pages.yml ├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── README.rst ├── doc ├── .vale.ini ├── Makefile ├── make.bat ├── source │ ├── _static │ │ ├── ansys_logo_transparent_white.png │ │ ├── css │ │ │ ├── blog_sidebar.css │ │ │ └── projects_sidebar.css │ │ ├── icons │ │ │ ├── ai-ml.svg │ │ │ ├── ansys-icon-dark.svg │ │ │ ├── ansys-icon-light.svg │ │ │ ├── connect.svg │ │ │ ├── design.svg │ │ │ ├── digital-twins.svg │ │ │ ├── dme.svg │ │ │ ├── electromagnetics.svg │ │ │ ├── embedded-software.svg │ │ │ ├── fluids.svg │ │ │ ├── materials.svg │ │ │ ├── optics.svg │ │ │ ├── platform.svg │ │ │ ├── semiconductors.svg │ │ │ ├── sound.svg │ │ │ └── structures.svg │ │ ├── js │ │ │ ├── blog_sidebar.js │ │ │ └── projects_sidebar.js │ │ ├── landing-page │ │ │ ├── css │ │ │ │ ├── carousel.css │ │ │ │ ├── style.css │ │ │ │ └── testimonials.css │ │ │ └── js │ │ │ │ ├── blogs.js │ │ │ │ ├── project_cards.js │ │ │ │ ├── testimonials.js │ │ │ │ └── testimonials.json │ │ ├── pyansys_banner.svg │ │ ├── pyansys_dark.png │ │ └── thumbnails │ │ │ ├── 5gwizard.png │ │ │ ├── ansys-python-manager.png │ │ │ ├── intro.png │ │ │ ├── pyacp.png │ │ │ ├── pyaedt.png │ │ │ ├── pyansys-cheat-sheets.png │ │ │ ├── pyansys-common.png │ │ │ ├── pyansys-geometry.png │ │ │ ├── pyansys-math.png │ │ │ ├── pyansys-sound.png │ │ │ ├── pyconceptev.png │ │ │ ├── pydpf-composites.png │ │ │ ├── pydpf-core.png │ │ │ ├── pydpf-post.png │ │ │ ├── pydyna.png │ │ │ ├── pydynamicreporting.png │ │ │ ├── pyedb.png │ │ │ ├── pyensight.png │ │ │ ├── pyfluent-parametric.png │ │ │ ├── pyfluent-visualization.png │ │ │ ├── pyfluent.png │ │ │ ├── pygranta.png │ │ │ ├── pymapdl.png │ │ │ ├── pymapdl_dark.png │ │ │ ├── pymapdl_reader.png │ │ │ ├── pymechanical.png │ │ │ ├── pymodelcenter.png │ │ │ ├── pymotorcad.png │ │ │ ├── pyoptislang.png │ │ │ ├── pyprimemesh.png │ │ │ ├── pyrocky.png │ │ │ ├── pyscadeone.png │ │ │ ├── pysherlock.png │ │ │ ├── pysimai.png │ │ │ ├── pyspeos.png │ │ │ ├── pystk.png │ │ │ ├── pysystem-coupling.png │ │ │ ├── pyturbogrid.png │ │ │ └── pytwin.png │ ├── _templates │ │ ├── blog_sidebar.html │ │ ├── footer_center.html │ │ ├── footer_left.html │ │ ├── footer_right.html │ │ └── projects_sidebar.html │ ├── blog.rst │ ├── blog │ │ └── 2025-09-30-newsletter.rst │ ├── conf.py │ ├── getting-started.rst │ ├── getting-started │ │ ├── about.rst │ │ ├── install.rst │ │ └── prerequisites.rst │ ├── index.rst │ ├── links.rst │ └── projects.rst └── styles │ ├── .gitignore │ └── config │ └── vocabularies │ └── ANSYS │ ├── accept.txt │ └── reject.txt ├── ignore_words.txt ├── projects.yaml ├── pyproject.toml ├── src └── pyansys │ └── __init__.py └── tools ├── catsitemap.py └── links.py /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto !eol -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | directory: "/" 5 | insecure-external-code-execution: allow 6 | schedule: 7 | interval: "daily" 8 | groups: 9 | deps: 10 | patterns: 11 | - "*" 12 | 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | schedule: 16 | interval: "daily" 17 | groups: 18 | actions: 19 | patterns: 20 | - "*" 21 | -------------------------------------------------------------------------------- /.github/workflows/ci-build.yml: -------------------------------------------------------------------------------- 1 | name: GitHub CI 2 | on: 3 | pull_request: 4 | types: [opened, reopened, synchronize, edited, closed] 5 | workflow_dispatch: 6 | push: 7 | tags: 8 | - "*" 9 | branches: 10 | - main 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | env: 17 | PACKAGE_NAME: pyansys 18 | PACKAGE_NAMESPACE: pyansys 19 | MAIN_PYTHON_VERSION: '3.11' 20 | DOCUMENTATION_CNAME: "docs.pyansys.com" 21 | GITHUB_TOKEN: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 22 | 23 | jobs: 24 | check-vulnerabilities: 25 | name: Check third-party dependencies for vulnerabilities 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: PyAnsys Vulnerability Check (on PRs) 29 | if: github.event_name == 'pull_request' 30 | uses: ansys/actions/check-vulnerabilities@v10 31 | with: 32 | python-version: ${{ env.MAIN_PYTHON_VERSION }} 33 | python-package-name: ${{ env.PACKAGE_NAME }} 34 | token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 35 | dev-mode: true 36 | 37 | - name: PyAnsys Vulnerability Check (any other case) 38 | if: github.event_name != 'pull_request' 39 | uses: ansys/actions/check-vulnerabilities@v10 40 | with: 41 | python-version: ${{ env.MAIN_PYTHON_VERSION }} 42 | python-package-name: ${{ env.PACKAGE_NAME }} 43 | token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 44 | 45 | check-licenses: 46 | name: Check depencencies' licenses 47 | runs-on: ubuntu-latest 48 | if: github.event.action != 'closed' 49 | steps: 50 | - name: PyAnsys Licenses Check 51 | uses: ansys/actions/check-licenses@v10 52 | with: 53 | python-version: ${{ env.MAIN_PYTHON_VERSION }} 54 | target: "all" 55 | whitelist-license-check: "attrs,referencing,jeepney,paramiko,ansys-dpf-post" # This has MIT license but fails the check, paramiko and ansys-dpf-post need to be removed eventually from the whitelist 56 | 57 | docs-style: 58 | name: Documentation Style Check 59 | if: github.event.action != 'closed' 60 | runs-on: ubuntu-latest 61 | steps: 62 | - name: PyAnsys documentation style checks 63 | uses: ansys/actions/doc-style@v10 64 | with: 65 | token: ${{ secrets.GITHUB_TOKEN }} 66 | 67 | smoke-tests-core: 68 | name: Build core PyAnsys packages 69 | if: github.event.action != 'closed' 70 | runs-on: ${{ matrix.os }} 71 | strategy: 72 | fail-fast: false 73 | matrix: 74 | os: [windows-latest, ubuntu-latest] 75 | python-version: ['3.10', '3.11', '3.12', '3.13'] 76 | 77 | steps: 78 | - uses: actions/checkout@v5 79 | 80 | - name: Install the latest version of uv and set the python version 81 | uses: astral-sh/setup-uv@v7 82 | with: 83 | python-version: ${{ matrix.python-version }} 84 | cache-dependency-glob: '**/pyproject.toml' 85 | activate-environment: true 86 | 87 | - name: Install core PyAnsys packages 88 | run: | 89 | uv pip install . 90 | 91 | - name: Smoke test 92 | run: python -c "from ${{ env.PACKAGE_NAMESPACE }} import __version__; print(__version__)" 93 | 94 | smoke-tests-extras: 95 | name: Build extras PyAnsys packages 96 | if: github.event.action != 'closed' 97 | runs-on: ${{ matrix.os }} 98 | needs: [smoke-tests-core] 99 | strategy: 100 | fail-fast: false 101 | matrix: 102 | os: [windows-latest, ubuntu-latest] 103 | python-version: ['3.10', '3.11', '3.12', '3.13'] 104 | extras-version: ['fluent-all', 'mapdl-all', 'tools'] 105 | 106 | steps: 107 | - uses: actions/checkout@v5 108 | 109 | - name: Install the latest version of uv and set the python version 110 | uses: astral-sh/setup-uv@v7 111 | with: 112 | python-version: ${{ matrix.python-version }} 113 | cache-dependency-glob: '**/pyproject.toml' 114 | activate-environment: true 115 | 116 | - name: Install ${{ matrix.extras-version }} PyAnsys packages 117 | run: | 118 | uv pip install .[${{ matrix.extras-version }}] 119 | 120 | - name: Smoke test 121 | run: python -c "from ${{ env.PACKAGE_NAMESPACE }} import __version__; print(__version__)" 122 | 123 | wheelhouse-all: 124 | name: Build PyAnsys package wheelhouse 125 | if: github.event.action != 'closed' 126 | runs-on: ${{ matrix.os }} 127 | needs: [smoke-tests-core] 128 | strategy: 129 | fail-fast: false 130 | matrix: 131 | os: [windows-latest, ubuntu-latest, macos-latest] 132 | python-version: ['3.10', '3.11', '3.12', '3.13'] 133 | 134 | steps: 135 | - name: Build wheelhouse and perform smoke test 136 | uses: ansys/actions/build-wheelhouse@v10 137 | with: 138 | library-name: ${{ env.PACKAGE_NAME }} 139 | operating-system: ${{ runner.os }} 140 | python-version: ${{ matrix.python-version }} 141 | target: "all" 142 | whitelist-license-check: "attrs,referencing,jeepney" # This has MIT license but fails the check 143 | 144 | - name: List dependencies (pip freeze) 145 | run: | 146 | pip freeze > all-deps-${{ runner.os }}-${{ matrix.python-version }}.txt 147 | cat all-deps-${{ runner.os }}-${{ matrix.python-version }}.txt 148 | 149 | - name: Upload dependencies list 150 | uses: actions/upload-artifact@v5 151 | with: 152 | name: all-deps-${{ runner.os }}-${{ matrix.python-version }} 153 | path: all-deps-${{ runner.os }}-${{ matrix.python-version }}.txt 154 | retention-days: 7 155 | 156 | docs-build: 157 | name: Building Documentation 158 | if: github.event.action != 'closed' 159 | runs-on: ubuntu-latest 160 | needs: [docs-style] 161 | 162 | steps: 163 | - name: Build documentation 164 | uses: ansys/actions/doc-build@v10 165 | with: 166 | python-version: ${{ env.MAIN_PYTHON_VERSION }} 167 | dependencies: "build-essential zip pandoc texlive-latex-extra latexmk texlive-pstricks" 168 | skip-dependencies-cache: true 169 | env: 170 | GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }} 171 | 172 | doc-deploy-dev: 173 | name: "Deploy development docs" 174 | if: github.ref == 'refs/heads/main' 175 | runs-on: ubuntu-latest 176 | needs: [package] 177 | steps: 178 | - name: Deploy the latest documentation 179 | uses: ansys/actions/doc-deploy-dev@v10 180 | with: 181 | cname: ${{ env.DOCUMENTATION_CNAME }} 182 | token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 183 | bot-user: ${{ secrets.PYANSYS_CI_BOT_USERNAME }} 184 | bot-email: ${{ secrets.PYANSYS_CI_BOT_EMAIL }} 185 | 186 | adapt-landing-page-dev: 187 | uses: ./.github/workflows/update-gh-pages.yml 188 | needs: [doc-deploy-dev] 189 | secrets: inherit 190 | 191 | package: 192 | name: Package library 193 | runs-on: ubuntu-latest 194 | needs: [docs-build, smoke-tests-core] 195 | steps: 196 | - name: Build library source and wheel artifacts 197 | uses: ansys/actions/build-library@v10 198 | with: 199 | library-name: ${{ env.PACKAGE_NAME }} 200 | python-version: ${{ env.MAIN_PYTHON_VERSION }} 201 | 202 | doc-deploy-pr: 203 | name: "Deploy PR documentation" 204 | runs-on: ubuntu-latest 205 | needs: [docs-build] 206 | # Run when the PR is closed i.e. when docs job is skipped 207 | if: always() && (needs.docs-build.result == 'success' || needs.docs-build.result == 'skipped') 208 | steps: 209 | - uses: ansys/actions/doc-deploy-pr@v10 210 | with: 211 | cname: ${{ env.DOCUMENTATION_CNAME }} 212 | token: ${{ secrets.GITHUB_TOKEN }} 213 | bot-user: ${{ secrets.PYANSYS_CI_BOT_USERNAME }} 214 | bot-email: ${{ secrets.PYANSYS_CI_BOT_EMAIL }} 215 | maximum-pr-doc-deployments: 20 216 | 217 | release: 218 | name: Release project 219 | if: github.event_name == 'push' && contains(github.ref, 'refs/tags') 220 | needs: [package, smoke-tests-extras, wheelhouse-all] 221 | runs-on: ubuntu-latest 222 | permissions: 223 | contents: write 224 | steps: 225 | - name: Release to PyPI repository 226 | uses: ansys/actions/release-pypi-public@v10 227 | with: 228 | library-name: ${{ env.PACKAGE_NAME }} 229 | twine-username: __token__ 230 | twine-token: ${{ secrets.PYPI_TOKEN }} 231 | 232 | - name: Release to GitHub 233 | uses: ansys/actions/release-github@v10 234 | with: 235 | library-name: ${{ env.PACKAGE_NAME }} 236 | additional-artifacts: 'all-deps-Linux-3.10 all-deps-Linux-3.11 all-deps-Linux-3.12 all-deps-Linux-3.13 all-deps-Windows-3.10 all-deps-Windows-3.11 all-deps-Windows-3.12 all-deps-Windows-3.13 all-deps-macOS-3.10 all-deps-macOS-3.11 all-deps-macOS-3.12 all-deps-macOS-3.13' 237 | token: ${{ secrets.GITHUB_TOKEN }} 238 | 239 | docs-release: 240 | name: Deploy release docs 241 | runs-on: ubuntu-latest 242 | needs: [release] 243 | steps: 244 | - name: Deploy the latest release documentation 245 | uses: ansys/actions/doc-deploy-stable@v10 246 | with: 247 | cname: ${{ env.DOCUMENTATION_CNAME }} 248 | token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 249 | bot-user: ${{ secrets.PYANSYS_CI_BOT_USERNAME }} 250 | bot-email: ${{ secrets.PYANSYS_CI_BOT_EMAIL }} 251 | 252 | adapt-landing-page-release: 253 | uses: ./.github/workflows/update-gh-pages.yml 254 | needs: [docs-release] 255 | secrets: inherit 256 | 257 | automerge-prs: 258 | name: Automerge PRs 259 | runs-on: ubuntu-latest 260 | needs: [package, wheelhouse-all] 261 | if: github.event_name == 'pull_request' 262 | permissions: 263 | contents: write 264 | pull-requests: write 265 | steps: 266 | - name: Automerge PRs 267 | uses: ansys/actions/hk-automerge-prs@v10 268 | with: 269 | approver: ${{ secrets.PYANSYS_CI_BOT_USERNAME }} 270 | approver-token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 271 | -------------------------------------------------------------------------------- /.github/workflows/update-gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Custom Github pages post-processing 2 | 3 | on: 4 | workflow_dispatch: 5 | workflow_call: 6 | push: 7 | tags: 8 | - "*" 9 | schedule: 10 | - cron: "* 3 * * 5" 11 | 12 | env: 13 | MAIN_PYTHON_VERSION: '3.13' 14 | 15 | jobs: 16 | update-gh-pages: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Install Python 21 | uses: actions/setup-python@v6 22 | with: 23 | python-version: ${{ env.MAIN_PYTHON_VERSION }} 24 | 25 | - name: Install Python dependencies 26 | run: | 27 | python -m pip install --upgrade pip 28 | python -m pip install requests 29 | 30 | - name: Checkout repository 31 | uses: actions/checkout@v5 32 | 33 | - name: Copy tools folder to /tmp and run sitemap script 34 | working-directory: /tmp 35 | run: | 36 | cp -r /home/runner/work/pyansys/pyansys/tools/ . 37 | python ./tools/catsitemap.py 38 | 39 | - name: Checkout repository gh-pages branch 40 | uses: actions/checkout@v5 41 | with: 42 | ref: gh-pages 43 | 44 | - name: Replace 'version/stable' with 'version/dev' in index.html 45 | run: | 46 | # Replace landing page with the dev version 47 | cp version/dev/index.html index.html 48 | sed -i 's/href="\([^:"]*\)"/href="version\/dev\/\1"/g' index.html 49 | sed -i 's/src="\([^:"]*\)"/src="version\/dev\/\1"/g' index.html 50 | sed -i 's/action="search.html"/action="version\/dev\/\search.html"/g' index.html 51 | sed -i 's|||g' index.html 52 | sed -i '/const ADVANCE_SEARCH_PATH = "search.html";/s|search.html|version/dev/search.html|' index.html 53 | # Update JS variables pointing to static values 54 | sed -i 's|const SEARCH_FILE = ".*_static/search.json";|const SEARCH_FILE = "version/dev/_static/search.json";|g' index.html 55 | sed -i 's|const PROJECTS_FILE = "_static/projects.json"|const PROJECTS_FILE = "version/dev/_static/projects.json"|' index.html 56 | # Replace "version/stable" with "version/dev" in the sitemap.xml 57 | sed -i 's/version\/stable/version\/dev/g' sitemap.xml 58 | 59 | - name: Move sitemaps/ to gh-pages root 60 | run: | 61 | rm -rf sitemaps/ && mv /tmp/sitemaps/ . 62 | 63 | - name: "Commit changes" 64 | uses: EndBug/add-and-commit@v9 65 | with: 66 | default_author: github_actions 67 | message: "update index.html and sitemaps folder" 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/python 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | wheelhouse/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | cover/ 58 | .cov 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | doc/_build/ 79 | doc/**/_autosummary 80 | doc/source/examples/* 81 | doc/source/tmp_pyproject.toml 82 | 83 | # PyBuilder 84 | .pybuilder/ 85 | target/ 86 | 87 | # Jupyter Notebook 88 | .ipynb_checkpoints 89 | 90 | # IPython 91 | profile_default/ 92 | ipython_config.py 93 | 94 | # pyenv 95 | # For a library or package, you might want to ignore these files since the code is 96 | # intended to run in multiple environments; otherwise, check them in: 97 | # .python-version 98 | 99 | # pipenv 100 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 101 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 102 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 103 | # install all needed dependencies. 104 | #Pipfile.lock 105 | 106 | # poetry 107 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 108 | # This is especially recommended for binary packages to ensure reproducibility, and is more 109 | # commonly ignored for libraries. 110 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 111 | #poetry.lock 112 | 113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 114 | __pypackages__/ 115 | 116 | # Celery stuff 117 | celerybeat-schedule 118 | celerybeat.pid 119 | 120 | # SageMath parsed files 121 | *.sage.py 122 | 123 | # Environments 124 | .env 125 | .venv 126 | env/ 127 | venv/ 128 | ENV/ 129 | env.bak/ 130 | venv.bak/ 131 | 132 | # Spyder project settings 133 | .spyderproject 134 | .spyproject 135 | 136 | # Rope project settings 137 | .ropeproject 138 | 139 | # mkdocs documentation 140 | /site 141 | 142 | # mypy 143 | .mypy_cache/ 144 | .dmypy.json 145 | dmypy.json 146 | 147 | # Pyre type checker 148 | .pyre/ 149 | 150 | # pytype static type analyzer 151 | .pytype/ 152 | 153 | # Cython debug symbols 154 | cython_debug/ 155 | 156 | #VSCode 157 | .vscode 158 | 159 | # PyCharm 160 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 162 | # and can be added to the global gitignore or merged into this file. For a more nuclear 163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 164 | #.idea/ 165 | 166 | # End of https://www.toptal.com/developers/gitignore/api/python 167 | 168 | # Ignore generated project.json file used by documentation 169 | doc/source/_static/projects.json 170 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | 3 | - repo: https://github.com/astral-sh/ruff-pre-commit 4 | rev: v0.14.2 5 | hooks: 6 | - id: ruff 7 | - id: ruff-format 8 | 9 | - repo: https://github.com/codespell-project/codespell 10 | rev: v2.4.1 11 | hooks: 12 | - id: codespell 13 | args: ["--ignore-words=ignore_words.txt"] 14 | exclude: "doc/source/_static" 15 | 16 | - repo: https://github.com/pycqa/pydocstyle 17 | rev: 6.3.0 18 | hooks: 19 | - id: pydocstyle 20 | additional_dependencies: [toml] 21 | exclude: "tests/" 22 | 23 | - repo: https://github.com/pre-commit/pre-commit-hooks 24 | rev: v6.0.0 25 | hooks: 26 | - id: check-merge-conflict 27 | - id: debug-statements 28 | - id: check-yaml 29 | - id: trailing-whitespace 30 | 31 | # this validates our github workflow files 32 | - repo: https://github.com/python-jsonschema/check-jsonschema 33 | rev: 0.34.1 34 | hooks: 35 | - id: check-github-workflows 36 | 37 | - repo: https://github.com/ansys/pre-commit-hooks 38 | rev: v0.5.2 39 | hooks: 40 | - id: add-license-headers 41 | args: 42 | - --start_year=2022 43 | 44 | - repo: https://github.com/pre-commit/mirrors-prettier 45 | rev: 'v4.0.0-alpha.8' 46 | hooks: 47 | - id: prettier 48 | types_or: [css, javascript] 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | PyAnsys metapackage 2 | =================== 3 | |pyansys| |python| |pypi| |downloads| |GH-CI| |MIT| |Ruff| |pre-commit| 4 | 5 | .. |pyansys| image:: https://img.shields.io/badge/Py-Ansys-ffc107.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABDklEQVQ4jWNgoDfg5mD8vE7q/3bpVyskbW0sMRUwofHD7Dh5OBkZGBgW7/3W2tZpa2tLQEOyOzeEsfumlK2tbVpaGj4N6jIs1lpsDAwMJ278sveMY2BgCA0NFRISwqkhyQ1q/Nyd3zg4OBgYGNjZ2ePi4rB5loGBhZnhxTLJ/9ulv26Q4uVk1NXV/f///////69du4Zdg78lx//t0v+3S88rFISInD59GqIH2esIJ8G9O2/XVwhjzpw5EAam1xkkBJn/bJX+v1365hxxuCAfH9+3b9/+////48cPuNehNsS7cDEzMTAwMMzb+Q2u4dOnT2vWrMHu9ZtzxP9vl/69RVpCkBlZ3N7enoDXBwEAAA+YYitOilMVAAAAAElFTkSuQmCC 6 | :target: https://docs.pyansys.com/ 7 | :alt: PyAnsys 8 | 9 | .. |python| image:: https://img.shields.io/pypi/pyversions/pyansys?logo=pypi 10 | :target: https://pypi.org/project/pyansys/ 11 | :alt: Python 12 | 13 | .. |pypi| image:: https://img.shields.io/pypi/v/pyansys.svg?logo=python&logoColor=white 14 | :target: https://pypi.org/project/pyansys/ 15 | :alt: PyPI 16 | 17 | .. |downloads| image:: https://img.shields.io/pypi/dm/pyansys.svg 18 | :target: https://pypi.org/project/pyansys/ 19 | :alt: PyPI Downloads 20 | 21 | .. |GH-CI| image:: https://github.com/ansys/pyansys/actions/workflows/ci-build.yml/badge.svg 22 | :target: https://github.com/ansys/pyansys/actions/workflows/ci-build.yml 23 | :alt: GH-CI 24 | 25 | .. |MIT| image:: https://img.shields.io/badge/License-MIT-yellow.svg 26 | :target: https://opensource.org/licenses/MIT 27 | :alt: MIT 28 | 29 | .. |Ruff| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json 30 | :target: https://github.com/astral-sh/ruff 31 | :alt: Ruff 32 | 33 | .. |pre-commit| image:: https://results.pre-commit.ci/badge/github/pyansys/pyansys/main.svg 34 | :target: https://results.pre-commit.ci/latest/github/pyansys/pyansys/main 35 | :alt: pre-commit.ci status 36 | 37 | Welcome to the PyAnsys metapackage repository. The ``pyansys`` metapackage 38 | provides a single package of collected PyAnsys packages that ensures compatibility 39 | of these packages amongst themselves and the Ansys product release that they are linked to. 40 | 41 | .. image:: https://raw.githubusercontent.com/ansys/pyansys/main/doc/source/_static/pyansys_dark.png 42 | :target: https://docs.pyansys.com 43 | :alt: PyAnsys 44 | 45 | The ``pyansys`` metapackage ensures compatibility between these PyAnsys packages: 46 | 47 | - `PyACP `_: Pythonic interface to Ansys Composite PrepPost (ACP). 48 | - `PyAdditive `_: Pythonic interface to the Ansys Additive service. 49 | - `PyAEDT `_: Pythonic interface to Ansys Electronics Desktop (AEDT). 50 | - `PyAnsys Geometry `_: Pythonic interface to the Ansys Geometry service. 51 | - `PyAnsys Math `_: Pythonic interface to PyAnsys Math libraries. 52 | - `PyAnsys Sound `_: Pythonic interface to Ansys Sound. 53 | - `PyConceptEV `_: Pythonic interface to Ansys ConceptEV library. 54 | - `PyDPF - Core `_: Pythonic interface to the Data Processing Framework (DPF) for building advanced and customized workflows. 55 | - `PyDPF - Post `_: Pythonic interface to access and post process Ansys solver result files. 56 | - `PyDPF - Composites `_: Pythonic interface to postprocess layered and short-fiber composite models. 57 | - `PyDYNA `_: Pythonic interface to build the Ansys DYNA input deck, submit it to the Ansys LS-DYNA solver, and postprocess its results. 58 | - `PyDynamicReporting `_: Pythonic interface to Ansys Dynamic Reporting for service and control of its database and reports. 59 | - `PyEDB `_: Pythonic interface to the Ansys Electronics Database (EDB) client library. 60 | - `PyEDB - Core `_: Pythonic interface to Ansys Electronics Database (EDB). 61 | - `PyEnSight `_: Pythonic interface to EnSight, the Ansys simulation postprocessor. 62 | - `PyFluent `_: Pythonic interface to Ansys Fluent. 63 | - `PyFluent - Visualization `_: Pythonic interface to visualize Ansys Fluent simulations. 64 | - `PyGranta `_: Pythonic interface to Ansys Granta MI services. 65 | - `PyHPS `_: A Python client for Ansys HPC Platform Services (HPS). 66 | - `PyMAPDL `_: Pythonic interface to Ansys MAPDL (Mechanical APDL). 67 | - `PyMAPDL Reader `_: Pythonic interface to read legacy MAPDL result files (MAPDL 14.5 and later). 68 | - `PyMechanical `_: Pythonic interface to Ansys Mechanical. 69 | - `PyModelCenter `_: Pythonic interface for Ansys ModelCenter 70 | - `PyMotorCAD `_: Pythonic interface to Ansys Motor-CAD. 71 | - `PyOptislang `_: Pythonic interface to Ansys optislang. 72 | - `PyPIM `_: Pythonic interface to communicate with the Ansys PIM (Product Instance Management) API. 73 | - `PyPrimeMesh `_: Python library to acquire geometries and prepare surface and volume meshes for multiple solvers. 74 | - `PyRocky `_: Python library to communicate with Ansys Rocky using Rocky PrePost API. 75 | - `PyScadeOne `_: Pythonic interface for Ansys Scade One. 76 | - `PySeascape `_: Pythonic interface to communicate with Ansys RedHawkSC and TotemSC. 77 | - `PySherlock `_: Pythonic interface to communicate with Ansys Sherlock. 78 | - `PySimAI `_: Pythonic interface to use SimAI. 79 | - `PySpeos `_: Python library that gathers functionalities and tools based on Speos software remote API. 80 | - `PySystemCoupling `_: Pythonic interface to communicate with Ansys System Coupling. 81 | - `PyTurboGrid `_: Pythonic interface to Ansys TurboGrid, a high-quality turbomachinery meshing software app. 82 | - `PyTwin `_: Pythonic interface to communicate with consumption workflows for Ansys digital twins. 83 | - `PyWorkbench `_: Pythonic interface to Ansys Workbench. 84 | - `Shared Components `_: Shared Ansys software components to enable package interoperability and minimize maintenance. 85 | 86 | Other tools delivered as part of the metapackage are: 87 | 88 | - `Ansys FileTransfer Tool `_: Simple gRPC API tool for moving files between a client and a remote server. 89 | - `Ansys Local Product Launcher `_: Python utility for launching Ansys products on a local machine and configuring their launch settings. 90 | - `Ansys Tools Path `_: Library to locate Ansys products in a local machine. 91 | - `Ansys Tools Protobuf Compilation Helper `_: Utility library to compile ``.proto`` files to Python source when building the package wheel. 92 | - `Ansys Tools Visualization Interface `_: Python interface between PyAnsys libraries and plotting backends 93 | - `PyAnsys Tools Report `_: Tool for reporting your Python environment's package versions and hardware resources in a standardized way. 94 | - `PyAnsys Tools Variable Interop `_: Tool for defining basic variables, types, metadata, and values intended to provide interoperability between all products. 95 | - `PyAnsys Tools Versioning `_: Tool for backwards and forwards server support. 96 | - `PyAnsys Units `_: Pythonic interface for units, unit systems, and unit conversions. 97 | - `PyMaterials Manager `_: Python package for unifying material management across the Ansys portfolio. 98 | 99 | Much effort is underway to continue expanding and developing packages in the 100 | `PyAnsys GitHub `__ account. On the ``Issues`` page 101 | for each package, you can post issues and request new features. You can also feel 102 | free to post a question on the `Ansys Developer Forums `_. 103 | 104 | By default, the PyAnsys metapackage installs these core modules: 105 | 106 | - `PyACP`_ 107 | - `PyAdditive`_ 108 | - `PyAEDT`_ 109 | - `PyAnsys Geometry`_ 110 | - `PyAnsys Math`_ 111 | - `PyAnsys Sound`_ 112 | - `PyConceptEV`_ 113 | - `PyDPF - Core`_ 114 | - `PyDPF - Post`_ 115 | - `PyDPF - Composites`_ 116 | - `PyDYNA`_ 117 | - `PyDynamicReporting`_ 118 | - `PyEDB`_ 119 | - `PyEDB - Core`_ 120 | - `PyEnSight`_ 121 | - `PyFluent`_ 122 | - `PyGranta`_ 123 | - `PyHPS`_ 124 | - `PyMAPDL`_ 125 | - `PyMechanical`_ 126 | - `PyMotorCAD`_ 127 | - `PyOptislang`_ 128 | - `PyPIM`_ 129 | - `PyPrimeMesh`_ 130 | - `PyRocky`_ 131 | - `PySeascape`_ 132 | - `PySherlock`_ 133 | - `PySimAI`_ 134 | - `PySpeos`_ 135 | - `PySystemCoupling`_ 136 | - `PyTurboGrid`_ 137 | - `PyTwin`_ 138 | - `PyWorkbench`_ 139 | - `Shared Components`_ 140 | 141 | Additionally, the ``pyansys`` metapackage contains certain extra targets that 142 | can be installed upon request: 143 | 144 | - **mapdl-all**: This target installs the core packages and `PyMAPDL Reader`_. 145 | - **fluent-all**: This target installs the core packages, and `PyFluent - Visualization`_. 146 | - **tools**: This target installs the core packages, `Ansys FileTransfer Tool`_, `Ansys Local Product Launcher`_, `Ansys Tools Path`_, `Ansys Tools Protobuf Compilation Helper`_, `PyAnsys Tools Report`_, `PyAnsys Tools Variable Interop`_, `PyAnsys Tools Versioning`_, `PyAnsys Units`_, and `PyMaterials Manager`_. 147 | - **all**: This target installs all extra ``pyansys`` packages. 148 | 149 | Package installation 150 | -------------------- 151 | 152 | Two installation modes are provided: user and offline. 153 | 154 | User mode installation 155 | ^^^^^^^^^^^^^^^^^^^^^^ 156 | 157 | Before installing the ``pyansys`` metapackage in user mode, ensure that you have 158 | the latest version of `pip `_ with this command: 159 | 160 | .. code:: bash 161 | 162 | python -m pip install -U pip 163 | 164 | Then, install the ``pyansys`` metapackage with this command: 165 | 166 | .. code:: bash 167 | 168 | python -m pip install pyansys 169 | 170 | If you are interested in **installing an extra target** such as ``fluent-all``, 171 | you use a command like this: 172 | 173 | .. code:: bash 174 | 175 | python -m pip install pyansys[fluent-all] 176 | 177 | If you are interested in **installing a specific version** such as ``2023.1.0``, 178 | you use a command like this: 179 | 180 | .. code:: bash 181 | 182 | python -m pip install pyansys==2023.1.0 183 | 184 | Offline mode installation 185 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 186 | 187 | If you lack an internet connection on your installation machine, the recommended way of installing 188 | the ``pyansys`` metapackage is downloading the wheelhouse archive from the 189 | `Releases Page `_ for your corresponding machine architecture. 190 | 191 | Each wheelhouse archive contains all the Python wheels necessary to install the ``pyansys`` metapackage from 192 | scratch on Windows, Linux, and MacOS from Python 3.10 to 3.13. You can install this on an isolated system with 193 | a fresh Python installation or on a virtual environment. 194 | 195 | For example, on Linux with Python 3.10, unzip the wheelhouse archive and install it with the following 196 | commands: 197 | 198 | .. code:: bash 199 | 200 | unzip pyansys-v2025.1.dev0-wheelhouse-Linux-3.10-core.zip wheelhouse 201 | pip install pyansys -f wheelhouse --no-index --upgrade --ignore-installed 202 | 203 | If you're on Windows with Python 3.10, unzip to a wheelhouse directory and then install using 204 | the same ``pip`` command as in the previous example. 205 | 206 | Consider installing using a `virtual environment `_. 207 | 208 | Versioning system 209 | ----------------- 210 | 211 | The ``pyansys`` metapackage follows a semantic-like versioning system, though it has been adapted to the 212 | Ansys product release mechanism. Thus, this kind of versioning system is followed: 213 | 214 | .. code:: bash 215 | 216 | XXXX.Y.ZZ 217 | 218 | Where: 219 | 220 | - ``XXXX`` is the Ansys product release year (for example, 2022). 221 | - ``Y`` is the Ansys product release within the same year (for example, 1, which relates to R1). 222 | - ``ZZ`` is a patched version to the ``pyansys`` metapackage, if any. 223 | 224 | Consequently, the first ``pyansys`` metapackage compatible with the 2024 R2 release would be: 225 | 226 | .. code:: bash 227 | 228 | 2024.2.0 229 | 230 | Any subsequent patched version of this package would be: 231 | 232 | .. code:: bash 233 | 234 | 2024.2.1 235 | 2024.2.2 236 | 2024.2.3 237 | ... 238 | 239 | You can request a specific version install when using ``pip`` to install 240 | your package: 241 | 242 | .. code:: bash 243 | 244 | python -m pip install pyansys==2024.2.0 245 | 246 | License and acknowledgments 247 | --------------------------- 248 | All PyAnsys libraries are licensed under the MIT license. 249 | 250 | PyAnsys libraries make no commercial claim over Ansys whatsoever. 251 | These libraries extend the functionality of Ansys products by 252 | adding Python interfaces to legally obtained software products 253 | without changing the core behaviors or licenses of the original 254 | software. 255 | 256 | For more information on Ansys products, visit the `Ansys web site `_. 257 | -------------------------------------------------------------------------------- /doc/.vale.ini: -------------------------------------------------------------------------------- 1 | # Core settings 2 | # ============= 3 | 4 | # Location of our `styles` 5 | StylesPath = "styles" 6 | 7 | # The options are `suggestion`, `warning`, or `error` (defaults to “warning”). 8 | MinAlertLevel = warning 9 | 10 | # By default, `code` and `tt` are ignored. 11 | IgnoredScopes = code, tt 12 | 13 | # By default, `script`, `style`, `pre`, and `figure` are ignored. 14 | SkippedScopes = script, style, pre, figure 15 | 16 | # WordTemplate specifies what Vale will consider to be an individual word. 17 | WordTemplate = \b(?:%s)\b 18 | 19 | # List of Packages to be used for our guidelines 20 | Packages = Google 21 | 22 | # Define the Ansys vocabulary 23 | Vocab = ANSYS 24 | 25 | [*.{md,rst}] 26 | 27 | # Apply the following styles 28 | BasedOnStyles = Vale, Google 29 | 30 | # Removing Google-specific rule - Not applicable under some circumstances 31 | Google.WordList = NO 32 | Google.Colons = NO 33 | Vale.Terms = NO 34 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 20 | 21 | # Customized PDF build 22 | pdf: 23 | @$(SPHINXBUILD) -M latex "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 24 | cd $(BUILDDIR)/latex && latexmk -r latexmkrc -pdf *.tex -interaction=nonstopmode || true 25 | (test -f $(BUILDDIR)/latex/pyansys.pdf && echo pdf exists) || exit 1 26 | 27 | clean: 28 | rm -rf $(BUILDDIR) 29 | -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.https://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /doc/source/_static/ansys_logo_transparent_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/ansys_logo_transparent_white.png -------------------------------------------------------------------------------- /doc/source/_static/css/blog_sidebar.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --blog-card-bg: #fff; 3 | --blog-card-radius: 0.75rem; 4 | --blog-card-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1); 5 | --blog-card-padding: 1rem; 6 | --blog-image-height: 11.25rem; /* 180px */ 7 | --blog-image-radius: 0.5rem; 8 | --blog-title-size: 1.125rem; 9 | --blog-title-weight: bold; 10 | --blog-title-margin: 0.625rem 0; 11 | --blog-meta-size: 0.875rem; 12 | --blog-meta-color: #666; 13 | --blog-meta-margin: 0 0 0.625rem; 14 | --blog-meta-li-margin: 0 0 0.25rem 0; 15 | --read-more-color: #0066cc; 16 | --read-more-weight: bold; 17 | --collapsible-bg: #f8f9fa; 18 | --collapsible-active-bg: #e9ecef; 19 | --collapsible-padding: 0.625rem; 20 | --collapsible-font-weight: bold; 21 | --collapsible-transition: background-color 0.3s; 22 | --collapsible-arrow-transition: transform 0.3s ease; 23 | --collapsible-content-padding: 0.3125rem 0.9375rem; 24 | --checkbox-wrapper-margin: 0 0 0.3125rem 0; 25 | --show-more-color: #007bff; 26 | --show-more-padding: 0.3125rem; 27 | --show-more-font-size: 0.9em; 28 | --blog-container-gap: 1.25rem; 29 | --blog-container-padding: 1.25rem; 30 | --blog-container-max-width: 75rem; 31 | } 32 | 33 | #blog-container { 34 | display: grid; 35 | grid-template-columns: repeat(auto-fill, minmax(17.5rem, 1fr)); /* 280px */ 36 | gap: var(--blog-container-gap); 37 | padding: var(--blog-container-padding); 38 | max-width: var(--blog-container-max-width); 39 | margin: auto; 40 | } 41 | 42 | .blog-card { 43 | background-color: var(--blog-card-bg); 44 | border-radius: var(--blog-card-radius); 45 | overflow: hidden; 46 | box-shadow: var(--blog-card-shadow); 47 | transition: transform 0.2s ease; 48 | padding: var(--blog-card-padding); 49 | } 50 | 51 | .blog-card:hover { 52 | transform: translateY(-0.3125rem); /* -5px */ 53 | } 54 | 55 | .blog-card .blog-image { 56 | width: 100%; 57 | height: var(--blog-image-height); 58 | object-fit: cover; 59 | border-radius: var(--blog-image-radius); 60 | margin-bottom: 0.75rem; 61 | } 62 | 63 | .blog-card .blog-title { 64 | font-size: var(--blog-title-size); 65 | font-weight: var(--blog-title-weight); 66 | margin: var(--blog-title-margin); 67 | } 68 | 69 | .blog-meta { 70 | list-style: none; 71 | padding: 0; 72 | margin: var(--blog-meta-margin); 73 | font-size: var(--blog-meta-size); 74 | color: var(--blog-meta-color); 75 | } 76 | 77 | .blog-meta li { 78 | margin-bottom: 0.25rem; 79 | } 80 | 81 | .read-more { 82 | color: var(--read-more-color); 83 | font-weight: var(--read-more-weight); 84 | text-decoration: none; 85 | } 86 | 87 | .read-more:hover { 88 | text-decoration: underline; 89 | } 90 | 91 | .collapsible { 92 | background-color: transparent; 93 | cursor: pointer; 94 | padding: var(--collapsible-padding); 95 | font-weight: var(--collapsible-font-weight); 96 | border: none; 97 | width: 100%; 98 | text-align: left; 99 | outline: none; 100 | transition: var(--collapsible-transition); 101 | display: flex; 102 | justify-content: space-between; 103 | align-items: center; 104 | } 105 | 106 | .collapsible.active { 107 | background-color: var(--collapsible-active-bg); 108 | } 109 | 110 | .arrow { 111 | transition: var(--collapsible-arrow-transition); 112 | } 113 | 114 | .collapsible.active .arrow { 115 | transform: rotate(180deg); 116 | } 117 | 118 | .collapsible-content { 119 | padding: var(--collapsible-content-padding); 120 | display: block; /* OPEN by default */ 121 | } 122 | 123 | .checkbox-wrapper { 124 | margin-bottom: 0.3125rem; 125 | } 126 | 127 | .show-more-btn { 128 | display: block; 129 | color: var(--show-more-color); 130 | background: none; 131 | border: none; 132 | cursor: pointer; 133 | padding: var(--show-more-padding); 134 | font-size: var(--show-more-font-size); 135 | } 136 | -------------------------------------------------------------------------------- /doc/source/_static/css/projects_sidebar.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --sidebar-margin-top: 2rem; 3 | --sidebar-padding-x: 2rem; 4 | --sidebar-section-margin-bottom: 2rem; 5 | --sidebar-section-gap: 0.25rem; 6 | --show-more-margin-top: 1rem; 7 | --sidebar-section-font-size: 0.85rem; 8 | --row-margin-y: 0.3125rem; 9 | --row-padding: 0.25rem; 10 | --input-margin-right: 0.625rem; 11 | --input-size: 1rem; 12 | --count-margin-left: auto; 13 | --count-bg: var(--ast-sidebar-hover-background); 14 | --count-radius: 50%; 15 | --count-padding: 0.25rem 0.75rem; 16 | --selected-gap: 0.5rem; 17 | --remove-family-color: black; 18 | --remove-family-weight: bold; 19 | --projects-grid-gap: 2rem; 20 | --projects-margin-bottom: 1.5rem; 21 | --project-card-radius: 0.5rem; 22 | --project-card-bg: #fff; 23 | --project-title-size: 1.2rem; 24 | --project-title-weight: bold; 25 | --project-title-padding: 0.5rem 0 0.5rem 1rem; 26 | --project-description-margin-top: 1rem; 27 | --project-description-padding: 0.5rem 0 0.5rem 1rem; 28 | --sd-bg-muted-radius: 999px; 29 | --sd-bg-muted-font-size: 0.75rem; 30 | --sd-bg-muted-line-height: 1rem; 31 | --selected-tag-padding: 0.25rem 0.5rem; 32 | --selected-tag-radius: 0.25rem; 33 | --selected-tag-margin: 0.25em; 34 | --selected-tag-weight: 600; 35 | --ansys-icon-size: 1.5rem; 36 | --ansys-icon-margin-right: 0.3125rem; 37 | --ansys-icon-padding: 0rem; 38 | --project-thumbnail-radius: 0.5rem; 39 | } 40 | 41 | html { 42 | overflow-y: scroll !important; 43 | } 44 | 45 | .projects-page-sidebar { 46 | margin-top: var(--sidebar-margin-top); 47 | display: flex; 48 | flex-direction: column; 49 | padding: 0 var(--sidebar-padding-x); 50 | } 51 | .projects-page-sidebar-section { 52 | margin-bottom: var(--sidebar-section-margin-bottom); 53 | font-weight: 700; 54 | display: flex; 55 | flex-direction: column; 56 | gap: var(--sidebar-section-gap); 57 | } 58 | 59 | .show-more { 60 | margin-top: var(--show-more-margin-top); 61 | } 62 | 63 | .projects-page-sidebar-section span { 64 | font-size: var(--sidebar-section-font-size); 65 | } 66 | 67 | .family-row, 68 | .tag-row { 69 | display: flex; 70 | align-items: center; 71 | margin: var(--row-margin-y) 0; 72 | font-weight: 400; 73 | padding: var(--row-padding); 74 | } 75 | 76 | .family-row input, 77 | .tag-row input { 78 | margin-right: var(--input-margin-right); 79 | height: var(--input-size); 80 | width: var(--input-size); 81 | } 82 | 83 | .family-count, 84 | .tag-count { 85 | margin-left: var(--count-margin-left); 86 | background-color: var(--count-bg); 87 | border-radius: var(--count-radius); 88 | padding: var(--count-padding); 89 | } 90 | .selected-families { 91 | display: flex; 92 | flex-direction: row; 93 | flex-wrap: wrap; 94 | gap: var(--selected-gap); 95 | } 96 | 97 | .remove-family { 98 | cursor: pointer; 99 | color: var(--remove-family-color); 100 | font-weight: var(--remove-family-weight); 101 | } 102 | 103 | .projects { 104 | display: grid; 105 | grid-template-columns: repeat(3, 1fr); 106 | gap: var(--projects-grid-gap); 107 | margin-bottom: var(--projects-margin-bottom); 108 | } 109 | 110 | .project-card { 111 | display: flex; 112 | flex-direction: column; 113 | border-radius: var(--project-card-radius); 114 | background-color: var(--project-card-bg); 115 | } 116 | .project-card:hover { 117 | cursor: pointer; 118 | } 119 | 120 | .project-thumbnail { 121 | padding: 0; 122 | border-top-right-radius: var(--project-thumbnail-radius); 123 | border-top-left-radius: var(--project-thumbnail-radius); 124 | } 125 | 126 | .project-title { 127 | font-size: var(--project-title-size); 128 | font-weight: var(--project-title-weight); 129 | margin-bottom: 0; 130 | padding: var(--project-title-padding); 131 | } 132 | 133 | .project-description { 134 | margin-top: var(--project-description-margin-top); 135 | padding: var(--project-description-padding); 136 | } 137 | .sd-bg-muted { 138 | background-color: var(--ast-sidebar-hover-background) !important; 139 | border-radius: var(--sd-bg-muted-radius); 140 | font-size: var(--sd-bg-muted-font-size); 141 | line-height: var(--sd-bg-muted-line-height); 142 | } 143 | 144 | [data-theme="dark"] .sd-bg-muted { 145 | background-color: #3d3d3d !important; 146 | } 147 | 148 | @media screen and (max-width: 48rem) { 149 | .projects { 150 | grid-template-columns: 1fr; 151 | } 152 | 153 | .projects-page-sidebar { 154 | padding: 1rem; 155 | } 156 | 157 | .project-card { 158 | margin: 0 auto; 159 | width: 90%; 160 | } 161 | } 162 | 163 | .selected-tag, 164 | .selected-family { 165 | display: inline-block; 166 | background-color: var(--ast-sidebar-hover-background); 167 | padding: var(--selected-tag-padding); 168 | border-radius: var(--selected-tag-radius); 169 | margin: var(--selected-tag-margin); 170 | font-weight: var(--selected-tag-weight); 171 | } 172 | 173 | .ansys-icon { 174 | width: var(--ansys-icon-size); 175 | height: var(--ansys-icon-size); 176 | margin-right: var(--ansys-icon-margin-right); 177 | vertical-align: middle; 178 | padding: var(--ansys-icon-padding); 179 | } 180 | -------------------------------------------------------------------------------- /doc/source/_static/icons/ai-ml.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /doc/source/_static/icons/ansys-icon-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/ansys-icon-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /doc/source/_static/icons/connect.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/design.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/source/_static/icons/dme.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 31 | 33 | 35 | 36 | 41 | 43 | 45 | 49 | 53 | 54 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /doc/source/_static/icons/electromagnetics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/embedded-software.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/fluids.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/source/_static/icons/materials.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/optics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /doc/source/_static/icons/platform.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 81 | -------------------------------------------------------------------------------- /doc/source/_static/icons/semiconductors.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/sound.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/icons/structures.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_static/js/blog_sidebar.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | const state = { 3 | products: new Set(), 4 | industries: new Set(), 5 | tags: new Set(), 6 | }; 7 | const blogContainer = document.getElementById("blog-container"); 8 | let allPosts = {}; 9 | 10 | function createCheckbox(name, containerId, type) { 11 | const id = `${type}-${name}`; 12 | 13 | console.log(`Creating checkbox for ${name} in ${containerId}`); 14 | const wrapper = document.createElement("div"); 15 | wrapper.className = "checkbox-wrapper"; 16 | 17 | const input = document.createElement("input"); 18 | input.type = "checkbox"; 19 | input.id = id; 20 | input.value = name; 21 | input.style.marginRight = "5px"; 22 | 23 | const label = document.createElement("label"); 24 | label.setAttribute("for", id); 25 | label.textContent = name; 26 | label.style.cursor = "pointer"; 27 | 28 | input.addEventListener("change", () => { 29 | if (input.checked) { 30 | state[type].add(name); 31 | } else { 32 | state[type].delete(name); 33 | } 34 | updateVisiblePosts(); 35 | updateTagFilter(); 36 | // updateProductFilter(); 37 | updateIndustryFilter(); 38 | }); 39 | 40 | wrapper.appendChild(input); 41 | wrapper.appendChild(label); 42 | 43 | const container = document.querySelector( 44 | `#${containerId} .collapsible-content`, 45 | ); 46 | if (container) container.appendChild(wrapper); 47 | } 48 | 49 | function generateFilters(data) { 50 | const products = new Set(); 51 | const industries = new Set(); 52 | const tags = new Set(); 53 | 54 | for (const key in data) { 55 | const post = data[key]; 56 | 57 | (post.products || "") 58 | .split(",") 59 | .map((p) => p.trim()) 60 | .filter(Boolean) 61 | .forEach((p) => products.add(p)); 62 | (post.industries || "") 63 | .split(",") 64 | .map((c) => c.trim()) 65 | .filter(Boolean) 66 | .forEach((c) => industries.add(c)); 67 | (post.tags || "") 68 | .split(",") 69 | .map((t) => t.trim()) 70 | .filter(Boolean) 71 | .forEach((t) => tags.add(t)); 72 | } 73 | 74 | [...products] 75 | .sort() 76 | .forEach((p) => createCheckbox(p, "product-filters", "products")); 77 | [...industries] 78 | .sort() 79 | .forEach((i) => createCheckbox(i, "industry-filters", "industries")); 80 | [...tags].sort().forEach((t) => createCheckbox(t, "tag-filters", "tags")); 81 | } 82 | 83 | function updateTagFilter() { 84 | const selectedProducts = [...state.products]; 85 | const selectedIndustries = [...state.industries]; 86 | 87 | for (const label of document.querySelectorAll("#tag-filters label")) { 88 | const checkbox = label.querySelector("input[type=checkbox]"); 89 | const value = checkbox.value; 90 | 91 | let isVisible = false; 92 | 93 | for (const key in allPosts) { 94 | const post = allPosts[key]; 95 | const postTags = (post.tags || "").split(",").map((t) => t.trim()); 96 | const postProducts = (post.products || "") 97 | .split(",") 98 | .map((p) => p.trim()); 99 | const postIndustries = (post.industries || "") 100 | .split(",") 101 | .map((c) => c.trim()); 102 | 103 | const matchProduct = 104 | selectedProducts.length === 0 || 105 | postProducts.some((p) => selectedProducts.includes(p)); 106 | const matchIndustry = 107 | selectedIndustries.length === 0 || 108 | postIndustries.some((c) => selectedIndustries.includes(c)); 109 | const matchTag = postTags.includes(value); 110 | 111 | if (matchProduct && matchIndustry && matchTag) { 112 | isVisible = true; 113 | break; 114 | } 115 | } 116 | 117 | label.style.display = isVisible ? "block" : "none"; 118 | } 119 | } 120 | 121 | function updateIndustryFilter() { 122 | const selectedTags = [...state.tags]; 123 | const selectedProducts = [...state.products]; 124 | const industrySet = new Set(); 125 | 126 | for (const key in allPosts) { 127 | const post = allPosts[key]; 128 | const postIndustries = (post.industries || "") 129 | .split(",") 130 | .map((c) => c.trim()); 131 | const postProducts = (post.products || "") 132 | .split(",") 133 | .map((p) => p.trim()); 134 | const matchTag = 135 | selectedTags.length === 0 || 136 | (post.tags || "") 137 | .split(",") 138 | .map((t) => t.trim()) 139 | .some((t) => selectedTags.includes(t)); 140 | const matchProduct = 141 | selectedProducts.length === 0 || 142 | postProducts.some((p) => selectedProducts.includes(p)); 143 | 144 | if (matchTag && matchProduct) { 145 | postIndustries.filter(Boolean).forEach((c) => industrySet.add(c)); 146 | } 147 | } 148 | 149 | const container = document.querySelector( 150 | "#industry-filters .collapsible-content", 151 | ); 152 | if (!container) return; 153 | 154 | container.innerHTML = ""; 155 | [...industrySet] 156 | .sort() 157 | .forEach((c) => createCheckbox(c, "industry-filters", "industries")); 158 | } 159 | 160 | function updateVisiblePosts() { 161 | if (!blogContainer) return; 162 | blogContainer.innerHTML = ""; 163 | 164 | for (const key in allPosts) { 165 | const post = allPosts[key]; 166 | const postProducts = (post.products || "") 167 | .split(",") 168 | .map((p) => p.trim()); 169 | const postIndustries = (post.industries || "") 170 | .split(",") 171 | .map((c) => c.trim()); 172 | const postTags = (post.tags || "").split(",").map((t) => t.trim()); 173 | 174 | const matchProduct = 175 | state.products.size === 0 || 176 | postProducts.some((p) => state.products.has(p)); 177 | const matchIndustry = 178 | state.industries.size === 0 || 179 | postIndustries.some((c) => state.industries.has(c)); 180 | const matchTag = 181 | state.tags.size === 0 || postTags.some((t) => state.tags.has(t)); 182 | 183 | if (matchProduct && matchIndustry && matchTag) { 184 | const postCard = document.createElement("div"); 185 | postCard.className = "project-card sd-card sd-shadow-sm sd-card-hover"; 186 | postCard.onclick = () => (window.location.href = `${key}`); 187 | 188 | const description = post.description || ""; 189 | const shortDescription = 190 | description.length > 100 191 | ? description.slice(0, 100) + "..." 192 | : description; 193 | 194 | postCard.innerHTML = ` 195 | ${post.image ? `${post.title || key}` : ""} 196 |
197 |

${post.title || key}

198 |

${shortDescription}

199 |

200 | ${post.author || "PyAnsys Team"}
201 | ${post.date || "Unknown Date"} 202 |

203 | Read More 204 |
205 | `; 206 | blogContainer.appendChild(postCard); 207 | } 208 | } 209 | } 210 | 211 | function setupCollapsibles() { 212 | document.querySelectorAll(".collapsible").forEach((button) => { 213 | button.addEventListener("click", function () { 214 | this.classList.toggle("active"); 215 | const content = this.nextElementSibling; 216 | content.style.display = 217 | content.style.display === "block" ? "none" : "block"; 218 | }); 219 | }); 220 | } 221 | 222 | let basePath = "version/dev/"; 223 | if ( 224 | window.location.pathname.includes("version/dev") || 225 | window.location.pathname.includes("version/stable") || 226 | window.location.pathname.includes("pull/") 227 | ) { 228 | basePath = ""; 229 | } 230 | const BASE_PATH = basePath; 231 | const BLOG_FILE = `${BASE_PATH}_static/blog_metadata.json`; 232 | 233 | fetch(BLOG_FILE) 234 | .then((res) => res.json()) 235 | .then((data) => { 236 | allPosts = data; 237 | setupCollapsibles(); 238 | generateFilters(data); 239 | updateVisiblePosts(); 240 | }); 241 | }); 242 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/css/carousel.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS Variables 3 | * Centralized theme variables for 4 | * carousel items, content, buttons, 5 | * background, and step-by-step layout. 6 | */ 7 | :root { 8 | /* Carousel Item */ 9 | --carousel-item-height: 30rem; 10 | --carousel-item-color: #fff; 11 | --carousel-item-border: thin solid #000; 12 | --carousel-gradient: linear-gradient( 13 | to right, 14 | rgba(0, 0, 0, 1), 15 | rgba(0, 0, 0, 0.1) 16 | ); 17 | 18 | /* Carousel Content */ 19 | --carousel-content-padding: 0.75rem; 20 | --carousel-content-margin-left: 0.75rem; 21 | --carousel-h2-size: 2.5rem; 22 | --carousel-h2-color: #fff; 23 | --carousel-p-margin: 2rem 0; 24 | --carousel-p-size: 1rem; 25 | --carousel-p-color: #fff; 26 | 27 | /* Buttons */ 28 | --btn-bg: #fff; 29 | --btn-color: #000; 30 | --btn-radius: 0.25rem; 31 | --btn-size: 0.75rem; 32 | --btn-weight: bold; 33 | --btn-padding: 0.75rem 1.25rem; 34 | --btn-mr: 1rem; 35 | --btn-hover-bg: #939393; 36 | 37 | /* Carousel Background */ 38 | --carousel-bg-height: 15rem; 39 | --carousel-bg-animation: slideBackground 15s infinite; 40 | 41 | /* Step Section */ 42 | --steps-gap: 1.25rem; 43 | --step-gap: 0.9375rem; 44 | --step-mt: 1rem; 45 | --step-width: 31.25rem; 46 | 47 | /* Step Icons */ 48 | --icon-bg: #f3f0fa; 49 | --icon-color: #6a1b9a; 50 | --icon-size: 1.25rem; 51 | --icon-dim: 2.5rem; 52 | --icon-radius: 0.5rem; 53 | 54 | /* Step Text */ 55 | --text-h4-m: 0 1rem 1rem 0; 56 | --text-h4-weight: bold; 57 | } 58 | 59 | /** 60 | * Carousel Item 61 | */ 62 | .carousel-item { 63 | height: var(--carousel-item-height); 64 | color: var(--carousel-item-color); 65 | border: var(--carousel-item-border); 66 | position: relative; 67 | } 68 | 69 | /** 70 | * Carousel Item Overlay 71 | */ 72 | .carousel-item::before { 73 | z-index: 1; 74 | position: absolute; 75 | content: ""; 76 | top: 0; 77 | right: 0; 78 | bottom: 0; 79 | left: 0; 80 | background: var(--carousel-gradient); 81 | } 82 | 83 | /** 84 | * Carousel Content 85 | */ 86 | .carousel-content { 87 | padding: var(--carousel-content-padding); 88 | margin-left: var(--carousel-content-margin-left); 89 | position: relative; 90 | z-index: 2; 91 | } 92 | 93 | /** 94 | * Carousel Content Headings 95 | */ 96 | .carousel-content h2 { 97 | font-size: var(--carousel-h2-size); 98 | color: var(--carousel-h2-color); 99 | } 100 | 101 | /** 102 | * Carousel Content Paragraphs 103 | */ 104 | .carousel-content p { 105 | margin: var(--carousel-p-margin); 106 | font-size: var(--carousel-p-size); 107 | color: var(--carousel-p-color); 108 | } 109 | 110 | /** 111 | * Carousel Content Buttons 112 | */ 113 | .carousel-content .btn-custom { 114 | background-color: var(--btn-bg); 115 | color: var(--btn-color); 116 | border: none; 117 | border-radius: var(--btn-radius); 118 | font-size: var(--btn-size); 119 | font-weight: var(--btn-weight); 120 | padding: var(--btn-padding); 121 | text-transform: uppercase; 122 | margin-right: var(--btn-mr); 123 | cursor: pointer; 124 | transition: background-color 0.3s ease; 125 | } 126 | 127 | /** 128 | * Carousel Content Buttons - Hover 129 | */ 130 | .carousel-content .btn-custom:hover { 131 | background-color: var(--btn-hover-bg); 132 | color: var(--btn-color); 133 | } 134 | 135 | /** 136 | * Carousel Content Responsive 137 | */ 138 | @media (max-width: 1200px) { 139 | .carousel-content .btn-custom { 140 | padding: 0.4rem; 141 | margin-right: 0.25rem; 142 | } 143 | .carousel-content p { 144 | margin: 1rem 0; 145 | } 146 | .carousel-content h2 { 147 | margin: 0 0 0.5rem 0; 148 | } 149 | } 150 | 151 | /** 152 | * Carousel Background 153 | */ 154 | @keyframes slideBackground { 155 | 0% { 156 | background-image: url("https://images.ansys.com/is/image/ansys/engineers-around-ev-design?wid=1850&fmt=png-alpha&op_usm=0.9,1.0,20,0&fit=constrain,0"); 157 | } 158 | 33% { 159 | background-image: url("https://images.ansys.com/is/image/ansys/ansys-homepage-hero-space?wid=1850&fmt=png-alpha&op_usm=0.9,1.0,20,0&fit=constrain,0"); 160 | } 161 | 66% { 162 | background-image: url("https://images.ansys.com/is/image/ansys/homepage-carousel-autonomous-w1920xh675v3?wid=1850&fmt=png-alpha&op_usm=0.9,1.0,20,0&fit=constrain,0"); 163 | } 164 | 100% { 165 | background-image: url("https://images.ansys.com/is/image/ansys/hero-optic-lidar-2?wid=1850&fmt=png-alpha&op_usm=0.9,1.0,20,0&fit=constrain,0"); 166 | } 167 | } 168 | 169 | /** 170 | * Carousel Background Container 171 | */ 172 | .carousel-background { 173 | height: var(--carousel-bg-height); 174 | display: flex; 175 | align-items: center; 176 | justify-content: flex-start; 177 | background-size: cover; 178 | background-position: center; 179 | animation: var(--carousel-bg-animation); 180 | } 181 | 182 | /** 183 | * Simulation Steps Section 184 | */ 185 | .simulation-steps { 186 | display: flex; 187 | flex-direction: column; 188 | gap: var(--steps-gap); 189 | } 190 | 191 | /** 192 | * Step Layout 193 | */ 194 | .step { 195 | display: flex; 196 | align-items: flex-start; 197 | gap: var(--step-gap); 198 | margin-top: var(--step-mt); 199 | width: var(--step-width); 200 | } 201 | 202 | /** 203 | * Step Icons 204 | */ 205 | .step .icon { 206 | background: var(--icon-bg); 207 | color: var(--icon-color); 208 | font-size: var(--icon-size); 209 | width: var(--icon-dim); 210 | height: var(--icon-dim); 211 | border-radius: var(--icon-radius); 212 | display: flex; 213 | justify-content: center; 214 | align-items: center; 215 | flex-shrink: 0; 216 | } 217 | 218 | /** 219 | * Step Text 220 | */ 221 | .step .text h4 { 222 | margin: var(--text-h4-m); 223 | font-weight: var(--text-h4-weight); 224 | } 225 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/css/style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS Variables 3 | * Centralized theme variables for 4 | * standardizing card styles, layout spacing, 5 | * background, and step-by-step layout. 6 | */ 7 | :root { 8 | /* Card */ 9 | --card-bg: #fff; 10 | --card-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.05); 11 | --card-radius: 0.5rem; 12 | 13 | /* Landing Page */ 14 | --landing-gap: 1.5rem; 15 | --landing-gap-mobile: 1rem; 16 | --landing-mb: 2rem; 17 | --landing-mb-mobile: 1rem; 18 | --page-width: min(100%, 96.875rem); /* 1550px */ 19 | 20 | /* Thumbnails */ 21 | --thumbnail-padding: 1.5rem; 22 | --thumbnail-radius: 0.5rem; 23 | 24 | /* Footer */ 25 | --footer-border: 0.75rem solid #ffc107; 26 | --footer-bg: #000; 27 | --footer-color: #fff; 28 | --footer-gap: 0.75rem; 29 | --footer-social-icon-size: 1.25rem; 30 | --footer-social-icon-height: 1.5rem; 31 | --footer-social-gap: 0.75rem; 32 | 33 | /* Swiper */ 34 | --swiper-slide-mb: 1.25rem; 35 | --swiper-pagination-active: #ffb71b; 36 | 37 | /* Forms */ 38 | --form-width: 30rem; 39 | --form-height: 10rem; 40 | 41 | /* Badges */ 42 | --badge-mr: 0.3125rem; 43 | 44 | /* Workflow CTA */ 45 | --workflow-cta-mt: 2.5rem; 46 | --workflow-cta-mb: 2rem; 47 | --workflow-cta-padding: 1.5rem 2rem; 48 | --workflow-cta-bg: #ececec; 49 | --workflow-cta-radius: 1.5rem; 50 | --workflow-cta-gap: 2rem; 51 | --workflow-cta-icon-size: 3rem; 52 | --workflow-cta-icon-gap: 0.625rem; 53 | 54 | /* Workflow CTA Button */ 55 | --workflow-cta-btn-h: 2.5rem; 56 | --workflow-cta-btn-maxw: 17.5rem; 57 | --workflow-cta-btn-padding: 0.5rem 1rem; 58 | --workflow-cta-btn-bg: #fff; 59 | --workflow-cta-btn-color: #000; 60 | --workflow-cta-btn-radius: 0.25rem; 61 | --workflow-cta-btn-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.2); 62 | --workflow-cta-btn-hover-bg: #ececec; 63 | 64 | /* Stars */ 65 | --star-text-color: #353535; 66 | } 67 | 68 | /** 69 | * Dark Theme Variables 70 | */ 71 | html[data-theme="dark"] { 72 | --card-bg: #1e1e1e; 73 | --card-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.5); 74 | --footer-bg: #121212; 75 | --footer-color: #fff; 76 | --workflow-cta-bg: #353535; 77 | --workflow-cta-btn-bg: #000; 78 | --workflow-cta-btn-color: #fff; 79 | --workflow-cta-btn-border: 1px solid #353535; 80 | --workflow-cta-btn-hover-bg: #ccc; 81 | --star-text-color: #ececec; 82 | } 83 | 84 | /** 85 | * Card Styles 86 | */ 87 | .testimonial-card { 88 | background: var(--card-bg); 89 | box-shadow: var(--card-shadow); 90 | border-radius: var(--card-radius); 91 | height: 100%; 92 | } 93 | 94 | /** 95 | * Landing Page Layout 96 | */ 97 | .projects-landingpage, 98 | .blogs-landingpage { 99 | display: grid; 100 | grid-template-columns: repeat(4, 1fr); 101 | gap: var(--landing-gap); 102 | margin-bottom: var(--landing-mb); 103 | } 104 | 105 | @media (max-width: 1200px) { 106 | .projects-landingpage, 107 | .blogs-landingpage { 108 | grid-template-columns: repeat(2, 1fr); 109 | gap: var(--landing-gap-mobile); 110 | } 111 | } 112 | 113 | .bd-page-width { 114 | max-width: var(--page-width) !important; 115 | } 116 | 117 | /** 118 | * Thumbnails 119 | */ 120 | .project-lp-thumbnail { 121 | padding: var(--thumbnail-padding); 122 | border-radius: var(--thumbnail-radius); 123 | } 124 | 125 | .project-card .sd-card { 126 | padding: var(--thumbnail-padding); 127 | } 128 | 129 | /** 130 | * Footer 131 | */ 132 | .bd-footer { 133 | border-top: var(--footer-border); 134 | width: 100%; 135 | color: var(--footer-color); 136 | background-color: var(--footer-bg); 137 | } 138 | 139 | .footer-left h4, 140 | .footer-right h4 { 141 | color: var(--footer-color); 142 | } 143 | 144 | .bd-footer a { 145 | color: var(--footer-color); 146 | } 147 | 148 | .footer-ansys-logo { 149 | width: 6.34375rem; /* 101.5px */ 150 | object-fit: contain; 151 | } 152 | 153 | .carousel { 154 | background-color: var(--footer-bg) !important; 155 | } 156 | 157 | /** 158 | * Footer Links 159 | */ 160 | .external-link { 161 | display: inline-flex; 162 | align-items: center; 163 | text-decoration: none; 164 | gap: 0.5rem; 165 | } 166 | 167 | .external-link .link-text { 168 | display: inline-block; 169 | width: 7.5rem; 170 | white-space: nowrap; 171 | overflow: hidden; 172 | text-overflow: ellipsis; 173 | } 174 | 175 | .external-link i { 176 | font-size: 0.85rem; 177 | } 178 | 179 | .footer-right { 180 | display: flex; 181 | align-items: center; 182 | gap: var(--footer-gap); 183 | justify-content: flex-end; 184 | width: 100%; 185 | } 186 | 187 | /** 188 | * Swiper (Project Carousel) 189 | */ 190 | .swiper-wrapper { 191 | display: flex; 192 | align-items: stretch; 193 | } 194 | 195 | .swiper-slide { 196 | display: flex; 197 | } 198 | 199 | .swiper-slide .project-card { 200 | height: 29.375rem; /* Already in rem */ 201 | display: flex; 202 | flex-direction: column; 203 | overflow: hidden; 204 | margin-bottom: var(--swiper-slide-mb); 205 | } 206 | 207 | .swiper-pagination { 208 | position: initial !important; 209 | } 210 | 211 | /** 212 | * General Overrides 213 | */ 214 | .bd-header-article { 215 | display: none !important; 216 | } 217 | 218 | .bd-main .bd-content { 219 | display: flex !important; 220 | height: 100% !important; 221 | justify-content: center !important; 222 | } 223 | 224 | .bd-main .bd-content .bd-article-container { 225 | width: 100% !important; 226 | } 227 | 228 | .center { 229 | margin: 0 auto !important; 230 | } 231 | 232 | #hero-image { 233 | transition: opacity 0.5s ease-in-out; 234 | opacity: 1; 235 | } 236 | 237 | .fade-out { 238 | opacity: 0; 239 | } 240 | 241 | .fade-in { 242 | opacity: 1; 243 | } 244 | 245 | /** 246 | * Contact Us 247 | */ 248 | .mb-3 .form-control { 249 | width: var(--form-width); 250 | } 251 | 252 | textarea.form-control { 253 | height: var(--form-height); 254 | } 255 | 256 | .swiper-pagination-clickable .swiper-pagination-bullet-active { 257 | background: var(--swiper-pagination-active) !important; 258 | } 259 | 260 | /** 261 | * Footer Social Icons 262 | */ 263 | .footer-right { 264 | display: flex; 265 | align-items: center; 266 | gap: 0.5rem; 267 | justify-content: flex-end; 268 | width: 100%; 269 | } 270 | 271 | .footer-right .social-icons { 272 | display: flex; 273 | gap: 0.5rem; 274 | } 275 | 276 | .footer-right .social-icons .icon { 277 | display: inline-block; 278 | width: var(--footer-social-icon-size); 279 | height: var(--footer-social-icon-height); 280 | background-size: contain; 281 | background-repeat: no-repeat; 282 | background-position: center; 283 | transition: background-image 0.2s; 284 | } 285 | 286 | .footer-right .social-icons .icon-youtube { 287 | background-image: url(https://www.ansys.com/etc.clientlibs/ansysincprogram/clientlibs/clientlib-site/resources/images/icon-youtube-white.png); 288 | width: 1.8125rem; /* Already in rem */ 289 | } 290 | 291 | .footer-right .social-icons .icon-youtube:hover { 292 | background-image: url(https://www.ansys.com/etc.clientlibs/ansysincprogram/clientlibs/clientlib-site/resources/images/icon-youtube-color.png); 293 | } 294 | 295 | .footer-right .social-icons .icon-facebook { 296 | background-image: url(https://www.ansys.com/etc.clientlibs/ansysincprogram/clientlibs/clientlib-site/resources/images/icon-facebook-white.png); 297 | } 298 | 299 | .footer-right .social-icons .icon-facebook:hover { 300 | background-image: url(https://www.ansys.com/etc.clientlibs/ansysincprogram/clientlibs/clientlib-site/resources/images/icon-facebook-color.png); 301 | } 302 | 303 | .footer-right .social-icons .icon-linkedin { 304 | background-image: url(https://www.ansys.com/etc.clientlibs/ansysincprogram/clientlibs/clientlib-site/resources/images/icon-linkedin-white.png); 305 | } 306 | 307 | .footer-right .social-icons .icon-linkedin:hover { 308 | background-image: url(https://www.ansys.com/etc.clientlibs/ansysincprogram/clientlibs/clientlib-site/resources/images/icon-linkedin-color.png); 309 | } 310 | 311 | .footer-right .social-icons .icon-github { 312 | background: none; 313 | font-size: 1.375rem; 314 | color: #fff; 315 | } 316 | 317 | .footer-right .social-icons .icon-github:hover { 318 | color: #000; 319 | } 320 | 321 | /** 322 | * Features Section 323 | */ 324 | .step .icon { 325 | background: var(--workflow-cta-bg); 326 | color: var(--workflow-cta-btn-color); 327 | } 328 | 329 | .sd-badge { 330 | margin-right: var(--badge-mr); 331 | } 332 | 333 | @media (max-width: 600px) { 334 | .blog-meta-row { 335 | flex-direction: column !important; 336 | align-items: flex-start !important; 337 | gap: 0.2rem; 338 | } 339 | } 340 | 341 | /** 342 | * PyAnsys Landing Page 343 | */ 344 | .workflow-cta { 345 | margin: var(--workflow-cta-mt) 0 var(--workflow-cta-mb) 0; 346 | padding: var(--workflow-cta-padding); 347 | background: var(--workflow-cta-bg); 348 | border-radius: var(--workflow-cta-radius); 349 | display: flex; 350 | align-items: flex-start; 351 | justify-content: space-between; 352 | gap: var(--workflow-cta-gap); 353 | } 354 | 355 | .workflow-cta-left { 356 | display: flex; 357 | align-items: flex-start; 358 | gap: 1rem; 359 | flex: 1; 360 | min-width: 18.75rem; 361 | } 362 | 363 | .workflow-cta-icon { 364 | margin-top: 0.2rem; 365 | display: flex; 366 | width: var(--workflow-cta-icon-size); 367 | height: var(--workflow-cta-icon-size); 368 | justify-content: center; 369 | align-items: center; 370 | gap: var(--workflow-cta-icon-gap); 371 | aspect-ratio: 1/1; 372 | background: var(--workflow-cta-btn-bg); 373 | } 374 | 375 | .workflow-cta-title { 376 | margin: 0 0 0.5rem 0; 377 | } 378 | 379 | .workflow-cta-btn-container { 380 | align-self: flex-start; 381 | } 382 | 383 | .workflow-cta-btn { 384 | display: flex; 385 | height: var(--workflow-cta-btn-h); 386 | max-width: var(--workflow-cta-btn-maxw); 387 | padding: var(--workflow-cta-btn-padding); 388 | justify-content: center; 389 | align-items: center; 390 | background: var(--workflow-cta-btn-bg); 391 | color: var(--workflow-cta-btn-color) !important; 392 | border-radius: var(--workflow-cta-btn-radius); 393 | box-shadow: var(--workflow-cta-btn-shadow); 394 | border-color: var(--workflow-cta-btn-bg); 395 | text-decoration: none; 396 | } 397 | 398 | .workflow-cta-btn:hover { 399 | background: var(--workflow-cta-btn-hover-bg) !important; 400 | } 401 | 402 | /** 403 | * GitHub Stars 404 | */ 405 | .star-starcount-wrapper { 406 | display: inline-flex; 407 | align-items: center; 408 | gap: 0.375rem; 409 | vertical-align: middle; 410 | } 411 | 412 | /** 413 | * Project Card Star Badge 414 | */ 415 | .project-star-badge { 416 | color: #615655; 417 | position: absolute; 418 | top: 0.75rem; /* Already in rem */ 419 | right: 1rem; /* Already in rem */ 420 | background: #f7f7f7; 421 | box-shadow: 422 | 0 0.0625rem 0.125rem 0 rgba(0, 0, 0, 0.08), 423 | 0 0.125rem 0.25rem 0 rgba(0, 0, 0, 0.12); /* 1px = 0.0625rem, 2px = 0.125rem, 4px = 0.25rem */ 424 | border-radius: 0.5rem; /* Already in rem */ 425 | display: flex; 426 | align-items: center; 427 | gap: 0.125rem; /* Already in rem */ 428 | z-index: 2; 429 | padding: 0 0.25rem; /* Already in rem */ 430 | } 431 | 432 | .project-star-count { 433 | font-weight: 600; 434 | } 435 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/css/testimonials.css: -------------------------------------------------------------------------------- 1 | /* CSS Variables */ 2 | :root { 3 | --testimonial-bg: #fff; 4 | --testimonial-radius: 0.5rem; 5 | --testimonial-padding: 1rem; 6 | --testimonial-shadow: 0 0.125rem 0.375rem rgba(0, 0, 0, 0.1); 7 | --testimonial-text-align: left; 8 | --logo-wrap-height: 6.25rem; /* 100px */ 9 | --logo-wrap-margin-bottom: 1rem; 10 | --logo-img-max-height: 5rem; /* 80px */ 11 | --swiper-slide-height: auto; 12 | --st0-fill: #000; 13 | --testimonials-logo-bg: #fff; 14 | --swiper-pagination-bullet-inactive-color: #000; 15 | } 16 | 17 | html[data-theme="dark"] { 18 | --testimonial-bg: #1e1e1e; 19 | --testimonial-shadow: 0 0.125rem 0.375rem rgba(0, 0, 0, 0.5); 20 | --st0-fill: #fff; 21 | --testimonials-logo-bg: #e0d3d3; 22 | --swiper-pagination-bullet-inactive-color: #ececec; 23 | } 24 | 25 | /* Testimonial Card */ 26 | .testimonial { 27 | background: var(--testimonial-bg); 28 | border-radius: var(--testimonial-radius); 29 | padding: var(--testimonial-padding); 30 | box-shadow: var(--testimonial-shadow); 31 | text-align: var(--testimonial-text-align); 32 | height: 100%; 33 | } 34 | 35 | /* Logo Section */ 36 | .logo-wrap { 37 | height: var(--logo-wrap-height); 38 | display: flex; 39 | justify-content: center; 40 | align-items: center; 41 | margin-bottom: var(--logo-wrap-margin-bottom); 42 | } 43 | .logo-wrap img { 44 | max-height: var(--logo-img-max-height); 45 | object-fit: contain; 46 | } 47 | 48 | /* Swiper Slide */ 49 | .swiper-slide { 50 | height: var(--swiper-slide-height) !important; 51 | } 52 | 53 | /* SVG Fill */ 54 | .st0 { 55 | fill: var(--st0-fill); 56 | } 57 | 58 | .logo-wrap { 59 | background: var(--testimonials-logo-bg); 60 | } 61 | 62 | .swiper-pagination-bullet { 63 | background: var(--st0-fill); 64 | } 65 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/js/blogs.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function () { 2 | let blogsJs_basePath = "version/dev/"; 3 | if ( 4 | window.location.pathname.includes("version/dev") || 5 | window.location.pathname.includes("version/stable") || 6 | window.location.pathname.includes("pull/") 7 | ) { 8 | blogsJs_basePath = ""; 9 | } 10 | fetch(`${blogsJs_basePath}_static/blog_metadata.json`) 11 | .then((response) => response.json()) 12 | .then((data) => { 13 | const container = document.getElementById("blogs-landingpage"); 14 | if (!container) return; 15 | 16 | // Sort blogs by date (descending) and take the latest 4 17 | // also takes its key 18 | const blogs = Object.entries(data) 19 | .sort(([, a], [, b]) => new Date(b.date) - new Date(a.date)) 20 | .slice(0, 4) 21 | .map(([key, value]) => ({ key, ...value })); 22 | 23 | blogs.forEach((blog) => { 24 | const card = document.createElement("div"); 25 | card.className = "project-card sd-card sd-shadow-sm sd-card-hover"; 26 | // blog link is the key of the dict 27 | card.onclick = () => { 28 | window.location.href = `${blogsJs_basePath}${blog.key}`; 29 | }; 30 | 31 | // Normalize tags to array 32 | let tags = []; 33 | if (Array.isArray(blog.products)) { 34 | tags = blog.products; 35 | } else if (typeof blog.products === "string") { 36 | tags = blog.products.split(",").map((t) => t.trim()); 37 | } 38 | 39 | const description = blog.description || ""; 40 | const shortDescription = 41 | description.length > 100 42 | ? description.slice(0, 100) + "..." 43 | : description; 44 | 45 | // Key is the link to the docs 46 | 47 | card.innerHTML = ` 48 | ${blog.title} 49 |
50 |

51 | ${tags 52 | .map( 53 | (tag) => 54 | `${tag}`, 55 | ) 56 | .join("")} 57 |

58 |

${blog.title}

59 |

60 | A${blog.author || "PyAnsys Team"} 61 | ${blog.date || "Unknown Date"} 62 |

63 |

${shortDescription}

64 |
65 | `; 66 | 67 | container.appendChild(card); 68 | }); 69 | }) 70 | .catch((error) => { 71 | // Optionally log or display error 72 | console.error("Failed to load blog metadata:", error); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/js/project_cards.js: -------------------------------------------------------------------------------- 1 | const swiper = new Swiper(".swiper", { 2 | slidesPerView: 4, 3 | slidesPerGroup: 4, 4 | spaceBetween: 20, 5 | loop: false, 6 | autoplay: { 7 | delay: 5000, 8 | disableOnInteraction: false, 9 | }, 10 | pagination: { 11 | el: ".swiper-pagination", 12 | clickable: true, 13 | }, 14 | breakpoints: { 15 | 320: { slidesPerView: 1, slidesPerGroup: 1 }, 16 | 768: { slidesPerView: 2, slidesPerGroup: 2 }, 17 | 1024: { slidesPerView: 4, slidesPerGroup: 4 }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/js/testimonials.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function () { 2 | // Use a unique variable name to avoid conflicts 3 | let testimonialsBasePath = "version/dev/"; 4 | if ( 5 | window.location.pathname.includes("version/dev") || 6 | window.location.pathname.includes("version/stable") || 7 | window.location.pathname.includes("pull/") 8 | ) { 9 | testimonialsBasePath = ""; 10 | } 11 | const BASE_PATH = testimonialsBasePath; 12 | fetch(`${BASE_PATH}_static/landing-page/js/testimonials.json`) 13 | .then((r) => r.json()) 14 | .then((data) => { 15 | const wrapper = document.getElementById("testimonials-wrapper"); 16 | if (!wrapper) return; 17 | 18 | data.forEach((t) => { 19 | const slide = document.createElement("div"); 20 | slide.className = "swiper-slide"; 21 | 22 | const card = document.createElement("div"); 23 | card.className = "testimonial d-flex flex-column h-100 p-3"; 24 | 25 | // logo 26 | if (t.logo) { 27 | const logoWrap = document.createElement("div"); 28 | logoWrap.className = "logo-wrap mb-2 text-center"; 29 | const img = document.createElement("img"); 30 | img.src = t.logo; 31 | img.alt = t.author || "Logo"; 32 | logoWrap.appendChild(img); 33 | card.appendChild(logoWrap); 34 | } 35 | 36 | // content 37 | const content = document.createElement("p"); 38 | content.className = "flex-grow-1 mb-2"; 39 | content.textContent = t.content || ""; 40 | card.appendChild(content); 41 | 42 | // author 43 | if (t.author) { 44 | const author = document.createElement("h6"); 45 | author.className = "fw-bold mb-0 mt-2 text-end"; 46 | author.textContent = t.author; 47 | card.appendChild(author); 48 | } 49 | 50 | slide.appendChild(card); 51 | wrapper.appendChild(slide); 52 | }); 53 | 54 | // Only initialize Swiper if not already initialized 55 | if (!window.testimonialsSwiperInitialized) { 56 | new Swiper("#testimonials-swiper", { 57 | slidesPerView: 3, 58 | slidesPerGroup: 3, 59 | spaceBetween: 20, 60 | loop: false, 61 | autoplay: { 62 | delay: 5000, 63 | disableOnInteraction: false, 64 | }, 65 | pagination: { 66 | el: ".swiper-pagination", 67 | clickable: true, 68 | }, 69 | breakpoints: { 70 | 320: { slidesPerView: 1, slidesPerGroup: 1 }, 71 | 768: { slidesPerView: 2, slidesPerGroup: 2 }, 72 | 1024: { slidesPerView: 3, slidesPerGroup: 3 }, 73 | }, 74 | }); 75 | window.testimonialsSwiperInitialized = true; 76 | } 77 | }) 78 | .catch((err) => console.error("Testimonials error:", err)); 79 | }); 80 | -------------------------------------------------------------------------------- /doc/source/_static/landing-page/js/testimonials.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "author": "Actemium", 4 | "content": "PyAnsys played a pivotal role in the optimization of our industrial cooling applications, recognized with the Environmental Award for Technological Breakthrough 2024.", 5 | "logo": "https://www.actemium.es/app/uploads/sites/203/2022/10/logo-actemium@3x.png" 6 | }, 7 | { 8 | "author": "NVIDIA", 9 | "content": "PyAnsys leverages NVIDIA Omniverse to seamlessly integrate with solvers, delivering the visualizations that customers need.", 10 | "logo": "https://nvidianews.nvidia.com/_gallery/get_file/?file_id=544a6120f6091d588d000048" 11 | }, 12 | { 13 | "author": "STMicroelectronics", 14 | "content": "PyAnsys is a game-changing tool for anyone in simulation and design. It offers significant reductions in design time, enhanced consistency, and streamlined operations. It reinforces STMicroelectronics' commitment to quality.", 15 | "logo": "https://www.st.com/content/dam/st-crew/st-logo-blue.svg" 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /doc/source/_static/pyansys_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/pyansys_dark.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/5gwizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/5gwizard.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/ansys-python-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/ansys-python-manager.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/intro.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyacp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyacp.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyaedt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyaedt.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyansys-cheat-sheets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyansys-cheat-sheets.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyansys-common.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyansys-common.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyansys-geometry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyansys-geometry.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyansys-math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyansys-math.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyansys-sound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyansys-sound.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyconceptev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyconceptev.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pydpf-composites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pydpf-composites.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pydpf-core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pydpf-core.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pydpf-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pydpf-post.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pydyna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pydyna.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pydynamicreporting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pydynamicreporting.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyedb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyedb.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyensight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyensight.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyfluent-parametric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyfluent-parametric.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyfluent-visualization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyfluent-visualization.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyfluent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyfluent.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pygranta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pygranta.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pymapdl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pymapdl.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pymapdl_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pymapdl_dark.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pymapdl_reader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pymapdl_reader.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pymechanical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pymechanical.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pymodelcenter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pymodelcenter.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pymotorcad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pymotorcad.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyoptislang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyoptislang.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyprimemesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyprimemesh.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyrocky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyrocky.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyscadeone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyscadeone.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pysherlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pysherlock.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pysimai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pysimai.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyspeos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyspeos.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pystk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pystk.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pysystem-coupling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pysystem-coupling.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pyturbogrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pyturbogrid.png -------------------------------------------------------------------------------- /doc/source/_static/thumbnails/pytwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/source/_static/thumbnails/pytwin.png -------------------------------------------------------------------------------- /doc/source/_templates/blog_sidebar.html: -------------------------------------------------------------------------------- 1 |
2 |

Filters

3 | 4 | 5 |
6 | 9 |
10 |
11 | 12 | 13 |
14 | 17 |
18 |
19 | 20 | 21 |
22 | 25 |
26 |
27 | 28 |
29 | 30 | 42 | -------------------------------------------------------------------------------- /doc/source/_templates/footer_center.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/source/_templates/footer_left.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/source/_templates/footer_right.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /doc/source/_templates/projects_sidebar.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | Product families 6 |
7 | 8 |
9 | Show more 10 |
11 | 12 |
13 | 14 | 15 |
16 | Tags 17 |
18 | 19 |
20 | Show more 21 |
22 | 23 | 38 | 39 |
40 | 41 | 44 | 45 | -------------------------------------------------------------------------------- /doc/source/blog.rst: -------------------------------------------------------------------------------- 1 | .. _ref_blog: 2 | 3 | Blog 4 | #### 5 | 6 | Welcome to the blog of PyAnsys. This section contains articles, tutorials, and 7 | news related to the PyAnsys ecosystem. If you have any suggestions or would 8 | like to showcase your work, please contact `pyansys.core@ansys.com 9 | `_. 10 | 11 | .. raw:: html 12 | 13 |
14 | 15 |
16 | 17 | .. toctree:: 18 | :maxdepth: 2 19 | :hidden: 20 | 21 | blog/2025-09-30-newsletter 22 | 23 | -------------------------------------------------------------------------------- /doc/source/blog/2025-09-30-newsletter.rst: -------------------------------------------------------------------------------- 1 | .. meta:: 2 | :author: PyAnsys Core Team 3 | :date: 2025-09-30 4 | :categories: Newsletter 5 | :tags: news 6 | :industries: General 7 | :products: PyAnsys 8 | :image: thumbnails/pyansys-common.png 9 | :title: Newsletter 2025-09-30 10 | :description: The PyAnsys landing page has been redesigned for improved 11 | usability, navigation, and accessibility, based on community 12 | feedback and collaboration. 13 | 14 | Newsletter 2025-09-30 15 | ##################### 16 | 17 | Welcome to the first newsletter article of the PyAnsys ecosystem. In this 18 | article, the new landing page of the project is presented together with the 19 | latest updates on its documentation. 20 | 21 | A new landing page 22 | ================== 23 | 24 | Over the last months, the PyAnsys Core Team has been working on enhancing the 25 | landing page of the project. The new landing page contains the following 26 | elements: 27 | 28 | - A hero section containing key links 29 | - A carousel presenting different projects in a dynamic way 30 | - A section listing the latest articles on this blog 31 | - A testimonials section 32 | 33 | 34 | Other updates 35 | ============= 36 | 37 | The landing page is not the only section that has been enhanced. The top 38 | navigation bar contains now four main sections: 39 | 40 | - :ref:`Home `: for quickly accessing the main page of the project 41 | - :ref:`Getting started `: for quick access to installation instructions and tutorials 42 | - :ref:`Projects `: for quickly finding the projects that fit your needs 43 | - :ref:`Blog `: containing articles and news about the ecosystem 44 | -------------------------------------------------------------------------------- /doc/source/getting-started.rst: -------------------------------------------------------------------------------- 1 | .. _ref_getting-started: 2 | 3 | Getting started 4 | =============== 5 | 6 | This page helps you quickly get started with PyAnsys. It lists all the 7 | prerequisites and guides you step by step to install the project on your 8 | platform. 9 | 10 | .. grid:: 1 1 3 3 11 | 12 | .. grid-item-card:: :fa:`info-circle` About PyAnsys 13 | :link: getting-started/about 14 | :link-type: doc 15 | :padding: 2 2 2 2 16 | 17 | Learn more about PyAnsys and its ecosystem 18 | 19 | .. grid-item-card:: :fa:`tasks` Prerequisites 20 | :link: getting-started/prerequisites 21 | :link-type: doc 22 | :padding: 2 2 2 2 23 | 24 | What you need prior installing PyAnsys 25 | 26 | .. grid-item-card:: :fa:`download` Install 27 | :link: getting-started/install 28 | :link-type: doc 29 | :padding: 2 2 2 2 30 | 31 | Guidelines on how to install PyAnsys in your system 32 | 33 | .. toctree:: 34 | :maxdepth: 3 35 | :hidden: 36 | 37 | About 38 | Prerequisites 39 | Install 40 | 41 | -------------------------------------------------------------------------------- /doc/source/getting-started/about.rst: -------------------------------------------------------------------------------- 1 | About 2 | ##### 3 | 4 | PyAnsys is a collection of Python libraries and tools developed by `ANSYS, 5 | Inc.`_ It provides access to `Ansys products`_ by using a Python interface, 6 | enabling users to perform engineering simulations, data processing, and 7 | automation tasks. 8 | 9 | To ease the installation of the libraries and tools, PyAnsys provides a Python 10 | metapackage. This ensures compatibility between its projects. 11 | 12 | Key features of PyAnsys 13 | ======================= 14 | 15 | PyAnsys shines in the following areas: 16 | 17 | - **Automation of workflows:** PyAnsys enables users to automate repetitive or 18 | complex simulation tasks. 19 | 20 | - **Integration with the Python ecosystem:** users can leverage the Python 21 | ecosystem. 22 | 23 | - **Cross-product functionality:** PyAnsys provides Python APIs for various 24 | Ansys services and products. By allowing users to interact with multiple 25 | products in a single environment, PyAnsys enables users to streamline their 26 | workflows. 27 | 28 | The PyAnsys ecosystem 29 | ===================== 30 | 31 | PyAnsys libraries can be classified into wrappers and tools. 32 | 33 | **Wrappers** are Python libraries that provide direct access to Ansys products. 34 | Communication between the product and the library is performed via `gRPC 35 | `_. Therefore, users can have the product installed remotely and connect 36 | to that remote instance. 37 | 38 | **Tools** are Python libraries that provide additional functionality to the 39 | wrappers. 40 | -------------------------------------------------------------------------------- /doc/source/getting-started/install.rst: -------------------------------------------------------------------------------- 1 | Install PyAnsys 2 | ############### 3 | 4 | The PyAnsys metapackage is distributed as a Python library. Its installation 5 | follows the standard Python package installation process. 6 | 7 | Online installation 8 | =================== 9 | 10 | Download and install PyAnsys from `PyPI`_: 11 | 12 | .. tab-set:: 13 | 14 | .. tab-item:: :fab:`windows` **Windows** 15 | :name: windows 16 | 17 | .. code-block:: bash 18 | 19 | python -m pip install pyansys 20 | 21 | .. tab-item:: :fab:`apple` **MacOS** 22 | :name: macos 23 | 24 | .. code-block:: bash 25 | 26 | python -m pip install pyansys 27 | 28 | .. tab-item:: :fab:`linux` **Linux** 29 | :name: linux 30 | 31 | .. code-block:: bash 32 | 33 | python -m pip install pyansys 34 | 35 | The PyAnsys |version| metapackage includes the following projects: 36 | 37 | .. jinja:: dependencies 38 | 39 | .. raw:: html 40 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | {% for project, version in dependencies.items() %} 58 | 59 | 60 | 61 | 62 | {% endfor %} 63 | 64 |
PyAnsys projectVersion
{{ project }}{{ version }}
65 | 66 | Additional targets 67 | ------------------ 68 | 69 | The PyAnsys metapackage contains various targets for installing additional 70 | libraries and tools. 71 | 72 | .. jinja:: optional_dependencies 73 | 74 | .. tab-set:: 75 | 76 | {% for target, dependencies in optional_dependencies.items() %} 77 | 78 | .. tab-item:: {{ target }} 79 | 80 | Install by running: 81 | 82 | .. code-block:: bash 83 | 84 | python -m pip install pyansys[{{ target }}] 85 | 86 | .. raw:: html 87 | 88 | 89 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | {% for project, version in dependencies.items() %} 105 | 106 | 107 | 108 | 109 | {% endfor %} 110 | 111 |
PyAnsys projectVersion
{{ project }}{{ version }}
112 | 113 | 114 | 115 | 116 | {% endfor %} 117 | 118 | 119 | Offline installation 120 | ==================== 121 | 122 | Start by downloading the wheelhouse artifact for your platform: 123 | 124 | .. jinja:: wheelhouse 125 | 126 | .. csv-table:: 127 | :header-rows: 1 128 | :widths: 16, 28, 28, 28, 28 129 | 130 | :fas:`laptop` Platform, 131 | {%- for python in SUPPORTED_PYTHON_VERSIONS -%} 132 | :fab:`python` Python {{ python }} 133 | {%- if not loop.last -%},{%- endif -%} 134 | {% endfor %} 135 | {% for platform, icon in wheelhouse.items() -%} 136 | :fab:`{{ icon }}` {{ platform }}, 137 | {%- for python in SUPPORTED_PYTHON_VERSIONS -%} 138 | {%- if "dev" in VERSION -%} 139 | `Download wheelhouse `__ 140 | {%- else -%} 141 | `Download wheelhouse `__ 142 | {%- endif -%} 143 | {%- if not loop.last -%},{%- endif -%} 144 | {% endfor %} 145 | {% endfor %} 146 | 147 | Next, decompress the artifacts: 148 | 149 | .. code-block:: bash 150 | 151 | unzip wheelhouse 152 | 153 | Finally, install the PyAnsys metapackage using previously downloaded wheelhouse: 154 | 155 | .. code-block:: bash 156 | 157 | python -m pip install pyansys -f wheelhouse --no-index --upgrade --ignore-installed 158 | 159 | 160 | .. DO NOT MODIFY THE FOLLOWING SECTION 161 | 162 | .. raw:: html 163 | 164 | 165 | -------------------------------------------------------------------------------- /doc/source/getting-started/prerequisites.rst: -------------------------------------------------------------------------------- 1 | Prerequisites 2 | ############# 3 | 4 | You need to have the following prerequisites to get started with PyAnsys: 5 | 6 | - A valid Python version 7 | - A licensed version of Ansys 8 | 9 | Download and install Ansys 10 | ========================== 11 | 12 | Download Ansys software from the `Ansys Customer Portal`_. Ensure you have a 13 | license to use the software. 14 | 15 | Download and install Python 16 | =========================== 17 | 18 | Download and install the latest stable version of Python from the 19 | `https://www.python.org/downloads `_. 20 | 21 | Supported Python versions 22 | ------------------------- 23 | 24 | The PyAnsys ecosystem follows `SPEC-0`_ for Python version support. This 25 | implies that PyAnsys packages drop support for a Python version three years 26 | after their initial release: 27 | 28 | .. mermaid:: 29 | :caption: Python versions supported by SPEC-0 policy (red line) and PyAnsys Python versions supported (color coded) 30 | :alt: Current Python versions supported by the PyAnsys metapackage 31 | :align: center 32 | 33 | gantt 34 | title Python versions supported by SPEC-0 policy (red line) and PyAnsys Python versions supported 35 | dateFormat YYYY-MM-DD 36 | axisFormat %Y-%m 37 | 38 | Python 3.7 :done, des1, 2018-06-27, 3y 39 | Python 3.8 :done, des2, 2019-10-14, 3y 40 | Python 3.9 :done, des3, 2020-10-05, 3y 41 | Python 3.10 :active, des4, 2021-10-04, 3y 42 | Python 3.11 :active, des5, 2022-10-24, 3y 43 | Python 3.12 :active, des6, 2023-10-02, 3y 44 | Python 3.13 :active, des7, 2024-10-01, 3y 45 | Python 3.14 :crit, des8, 2025-10-07, 3y 46 | 47 | In previous diagram: 48 | 49 | * Python versions in gray are no longer supported 50 | * Python versions in light blue are currently supported 51 | * Python versions in dark blue are not supported yet 52 | 53 | .. note:: 54 | 55 | Adoption and deprecation of Python versions in the PyAnsys ecosystem are 56 | tentative. Delays may occur due to third party dependencies. 57 | 58 | Below you can find a list of the Python versions supported by each PyAnsys 59 | metapackage release: 60 | 61 | .. jinja:: releases 62 | 63 | .. raw:: html 64 | 65 | 66 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | {% for release in table_data %} 84 | 85 | 86 | 87 | 88 | 89 | 90 | {% endfor %} 91 | 92 |
PyAnsys versionMin. Python versionMax. Python versionDownload
{{ release.version }}{{ release.python.lower }}{{ release.python.upper }}{{ release.link }}
93 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. _ref_index: 2 | 3 | .. title:: PyAnsys 4 | 5 | .. jinja:: project_context 6 | 7 | .. raw:: html 8 | 9 | 10 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |
34 | 35 | 36 | 39 |
40 |
41 |

PyAnsys workflows

42 |
43 | Your gateway to advanced engineering automation. Discover how to seamlessly combine multiple PyAnsys libraries to build powerful, real-world simulation and data processing pipelines. 44 |
45 |
46 | 51 |
52 |
53 | 54 | 55 |
56 |

PyAnsys libraries 57 | More libraries 58 |

59 |
60 |
61 | {% for project, metadata in projects['projects'].items() %} 62 | {% set families = metadata.get('families', ['Other']) %} 63 | {% set family_display = families[0] | lower | replace(' ', '-') %} 64 | {% set tags = metadata.get('tags', []) %} 65 |
66 |
73 | 74 |
75 |

{{ metadata['name'] }}

76 |

{{ metadata['description'] }}

77 |

78 | {% for family in families %} 79 | {{ family }} 80 | {% endfor %} 81 | {% for tag in metadata['tags'] %} 82 | {{ tag }} 83 | {% endfor %} 84 |

85 |
86 |
87 |
88 | {% endfor %} 89 |
90 | 91 |
92 |
93 | 94 | 95 |
96 | 97 | 98 |
99 |

Recent blogs 100 | 101 | More blogs 102 |

103 |
104 |
105 | 106 | 107 | 108 |
109 |

How we support our users all over the world

110 |
111 |
112 |
113 |
114 | 115 |
116 |
117 |

Pre simulation

118 |

Define your simulation setup by specifying the geometry in a flexible, parametric format.

119 |
120 |
121 |
122 |
123 | 124 |
125 |
126 |

During simulation

127 |

Run high-fidelity simulations and gather comprehensive results that reflect the dynamics of your system.

128 |
129 |
130 |
131 |
132 | 133 |
134 |
135 |

Post simulation

136 |

Extract, visualize, and interpret key data from your simulation to drive the next phase of your project.

137 |
138 |
139 |
140 | 141 |
142 |
143 |
144 | 145 |
146 | 147 |
148 |
149 |
150 |
151 |
152 | 153 | .. toctree:: 154 | :maxdepth: 2 155 | :hidden: 156 | 157 | getting-started 158 | projects 159 | blog 160 | -------------------------------------------------------------------------------- /doc/source/links.rst: -------------------------------------------------------------------------------- 1 | .. Getting started 2 | .. _mapdl_course: https://www.ansys.com/training-center/course-catalog/structures/ansys-mechanical-advanced-use-of-mapdl-in-mechanical 3 | .. _ansys_fluent_page: https://www.ansys.com/products/fluids/ansys-fluent 4 | .. _ansys_aedt_page: https://www.ansys.com/products/electronics/ansys-maxwell 5 | .. _dpf_post_gh: https://github.com/ansys/pydpf-post 6 | .. _grpc: https://grpc.io/ 7 | .. _ansys_students: https://www.ansys.com/academic/students 8 | .. _pip: https://pypi.org/project/pip/ 9 | .. _pyansys_releases: https://github.com/ansys/pyansys/releases 10 | .. _venv_docs: https://docs.python.org/3/library/venv.html 11 | 12 | .. ANSYS and products 13 | .. _ANSYS, Inc.: https://www.ansys.com 14 | .. _Ansys: https://www.ansys.com 15 | .. _Ansys products: https://www.ansys.com/products 16 | .. _Ansys Customer Portal: https://download.ansys.com 17 | 18 | .. Python libraries 19 | .. _Python: https://www.python.org/ 20 | .. _PyPI: https://pypi.org/ 21 | .. _Numpy: https://numpy.org/ 22 | .. _SciPy: https://www.scipy.org/ 23 | .. _Pandas: https://pandas.pydata.org/ 24 | .. _Matplotlib: https://matplotlib.org/ 25 | .. _PyVista: https://docs.pyvista.org/ 26 | .. _Pydata Sphinx Theme: https://pydata-sphinx-theme.readthedocs.io/en/stable/ 27 | 28 | .. PEPs, NEPs, and SPECs 29 | .. _NEP 29: https://numpy.org/neps/nep-0029-deprecation_policy.html 30 | .. _SPEC-0: https://scientific-python.org/specs/spec-0000/ 31 | 32 | .. Contacts and support 33 | .. _PyAnsys support: mailto:pyansys.core@ansys.com 34 | .. _Github issues: https://github.com/ansys/pyansys/issues 35 | .. _PyAnsys discussions: https://github.com/ansys/pyansys/discussions 36 | .. _Developer Forum: https://discuss.ansys.com/ 37 | -------------------------------------------------------------------------------- /doc/source/projects.rst: -------------------------------------------------------------------------------- 1 | .. _ref_projects: 2 | 3 | Projects 4 | ######## 5 | 6 | .. jinja:: project_context 7 | 8 | .. raw:: html 9 | 10 |
11 | {% for project, metadata in projects['projects'].items() %} 12 | 13 | {% set families = metadata.get('families', ['Other']) %} 14 | {% set family_attr = families | join(',') | lower | replace(' ', '-') %} 15 | {% set family_display = families[0] | lower | replace(' ', '-') %} 16 | {% set tags = metadata.get('tags', []) %} 17 | 18 |
25 | {% if metadata.get('github_stars', 0) > 0 %} 26 | 27 | 28 | {{ metadata.get('github_stars', 0) }} 29 | 30 | {% endif %} 31 | 32 |
33 |

34 | {{ metadata['name'] }} 35 |

36 |

37 | {% for family in families %} 38 | {{ family }} 39 | {% endfor %} 40 | {% for tag in metadata['tags'] %} 41 | {{ tag }} 42 | {% endfor %} 43 |

44 |

{{ metadata['description'] }}

45 | {% if metadata.get('github_stars', 0) > 0 %} 46 | {% endif %} 47 | 48 | 49 |
50 |
51 | 52 | {% endfor %} 53 |
54 | -------------------------------------------------------------------------------- /doc/styles/.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | !**/ANSYS/accept.txt 3 | !**/ANSYS/reject.txt 4 | !.gitignore -------------------------------------------------------------------------------- /doc/styles/config/vocabularies/ANSYS/accept.txt: -------------------------------------------------------------------------------- 1 | ANSYS 2 | Ansys 3 | ansys 4 | API 5 | postprocessing 6 | PyAnsys 7 | (?i)Python 8 | Pythonic 9 | PyAEDT 10 | DPF 11 | PyMAPDL 12 | PyMAPDL Reader 13 | PyDPF - Core 14 | PyDPF - Post 15 | PyDPF - Composites 16 | PyDPF 17 | PyFluent 18 | PyPIM 19 | metapackage 20 | PyTwin 21 | toolkits 22 | -------------------------------------------------------------------------------- /doc/styles/config/vocabularies/ANSYS/reject.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/pyansys/aa1d74774a20d03343c11f7480f0259096fa7fd7/doc/styles/config/vocabularies/ANSYS/reject.txt -------------------------------------------------------------------------------- /ignore_words.txt: -------------------------------------------------------------------------------- 1 | parm 2 | pres 3 | WAN 4 | filname 5 | ans 6 | tread 7 | wan 8 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["flit_core >=3.2,<4"] 3 | build-backend = "flit_core.buildapi" 4 | 5 | [project] 6 | # Check https://flit.readthedocs.io/en/latest/pyproject_toml.html for all available sections 7 | name = "pyansys" 8 | version = "2025.1.dev0" 9 | description = "Pythonic interfaces to Ansys products" 10 | readme = "README.rst" 11 | requires-python = ">=3.10,<4" 12 | license = { file = "LICENSE" } 13 | authors = [{ name = "ANSYS, Inc.", email = "pyansys.core@ansys.com" }] 14 | maintainers = [{ name = "ANSYS, Inc.", email = "pyansys.core@ansys.com" }] 15 | classifiers = [ 16 | "Development Status :: 4 - Beta", 17 | "Intended Audience :: Science/Research", 18 | "Topic :: Scientific/Engineering :: Information Analysis", 19 | "License :: OSI Approved :: MIT License", 20 | "Operating System :: OS Independent", 21 | "Programming Language :: Python :: 3.10", 22 | "Programming Language :: Python :: 3.11", 23 | "Programming Language :: Python :: 3.12", 24 | "Programming Language :: Python :: 3.13", 25 | ] 26 | 27 | dependencies = [ 28 | "ansys-acp-core==0.2.1", 29 | "ansys-additive-core==0.20.0", 30 | "ansys-conceptev-core==0.9.4", 31 | "ansys-dpf-composites==0.7.0", 32 | "ansys-dpf-core==0.14.2", 33 | "ansys-dpf-post==0.10.1", 34 | "ansys-dyna-core==0.9.0", 35 | "ansys-dynamicreporting-core==0.10.3; python_version<'3.13'", 36 | "ansys-edb-core==0.2.1", 37 | "ansys-fluent-core==0.35.0", 38 | "ansys-geometry-core==0.12.1", 39 | "ansys-hps-client==0.11.1", 40 | "ansys-hps-data-transfer-client==0.3.1", 41 | "ansys-mapdl-core==0.71.0", 42 | "ansys-math-core==0.2.4", 43 | "ansys-mechanical-core==0.11.34", 44 | "ansys-meshing-prime==0.9.3", 45 | "ansys-modelcenter-workflow==0.1.1", 46 | "ansys-motorcad-core==0.7.4", 47 | "ansys-optislang-core==1.1.0", 48 | "ansys-platform-instancemanagement==1.1.2", 49 | "ansys-pyensight-core==0.10.16", 50 | "ansys-rocky-core==0.3.2", 51 | "ansys-seascape==0.2.0", 52 | "ansys-sherlock-core==0.9.0", 53 | "ansys-simai-core==0.3.5", 54 | "ansys-sound-core==0.2.1", 55 | "ansys-speos-core==0.6.3", 56 | "ansys-stk==0.2.0", 57 | "ansys-systemcoupling-core==0.10.1", 58 | "ansys-turbogrid-core==0.5.4", 59 | "ansys-workbench-core==0.9.0", 60 | "pyaedt==0.21.3", 61 | "pyedb==0.61.0", 62 | "pygranta==2025.2.1", 63 | "pytwin==0.10.2", 64 | ] 65 | 66 | [project.optional-dependencies] 67 | mapdl-all = ["ansys-mapdl-reader==0.55.1"] 68 | fluent-all = ["ansys-fluent-visualization==0.22.1"] 69 | tools = [ 70 | "ansys-materials-manager==0.3.1", 71 | "ansys-tools-filetransfer==0.1.1", 72 | "ansys-tools-local-product-launcher==0.1.1", 73 | "ansys-tools-path==0.7.3", 74 | # "ansys-tools-protoc-helper==0.4.0; python_version<='3.10'", 75 | "ansys-tools-visualization-interface==0.12.1", 76 | "ansys-units==0.8.1", 77 | "pyansys-tools-report==0.8.2", 78 | "pyansys-tools-versioning==0.6.0", 79 | "pyansys-tools-variableinterop==0.1.1", 80 | ] 81 | all = [ 82 | # MAPDL - ALL 83 | "ansys-mapdl-reader==0.55.1", 84 | # FLUENT - ALL 85 | "ansys-fluent-visualization==0.22.1", 86 | # TOOLS 87 | "ansys-materials-manager==0.3.1", 88 | "ansys-tools-filetransfer==0.1.1", 89 | "ansys-tools-local-product-launcher==0.1.1", 90 | "ansys-tools-path==0.7.3", 91 | # "ansys-tools-protoc-helper==0.4.0; python_version<='3.10'", 92 | "ansys-tools-visualization-interface==0.12.1", 93 | "ansys-units==0.8.1", 94 | "pyansys-tools-report==0.8.2", 95 | "pyansys-tools-versioning==0.6.0", 96 | "pyansys-tools-variableinterop==0.1.1", 97 | ] 98 | doc = [ 99 | "Sphinx==8.2.3", 100 | "ansys-sphinx-theme==1.6.3", 101 | "Jinja2 ==3.1.6", 102 | "Pillow==12.0.0", 103 | "PyGithub==2.8.1", 104 | "sphinx-copybutton==0.5.2", 105 | "sphinx-design==0.6.1", 106 | "sphinxcontrib-mermaid==1.0.0", 107 | "sphinx-jinja==2.0.2", 108 | ] 109 | 110 | [project.urls] 111 | Source = "https://github.com/ansys/pyansys" 112 | Documentation = "https://docs.pyansys.com" 113 | 114 | [tool.flit.module] 115 | name = "pyansys" 116 | 117 | [tool.ruff] 118 | line-length = 100 119 | fix = true 120 | 121 | [tool.ruff.format] 122 | quote-style = "double" 123 | indent-style = "space" 124 | docstring-code-format = true 125 | docstring-code-line-length = "dynamic" 126 | 127 | [tool.ruff.lint] 128 | select = [ 129 | "E", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w 130 | "F", # pyflakes, see https://docs.astral.sh/ruff/rules/#pyflakes-f 131 | "I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i 132 | "N", # pep8-naming, see https://docs.astral.sh/ruff/rules/#pep8-naming-n 133 | "PTH", # flake8-use-pathlib, https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth 134 | "TD", # flake8-todos, https://docs.astral.sh/ruff/rules/#flake8-todos-td 135 | ] 136 | ignore = [ 137 | "TD002", # Missing author in TODOs comment 138 | ] 139 | 140 | [tool.ruff.lint.pydocstyle] 141 | convention = "numpy" 142 | 143 | [tool.ruff.lint.isort] 144 | combine-as-imports = true 145 | force-sort-within-sections = true 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /src/pyansys/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """PyAnsys general package __init__ file.""" 24 | 25 | import importlib.metadata as importlib_metadata 26 | 27 | # Read from the pyproject.toml 28 | # major, minor, patch 29 | __version__ = importlib_metadata.version("pyansys") 30 | -------------------------------------------------------------------------------- /tools/catsitemap.py: -------------------------------------------------------------------------------- 1 | """Script for automatic generation/download of sitemaps for pyansys projects. 2 | 3 | Intended for the pyansys project and to be used with the update-gh-pages 4 | workflow. 5 | 6 | """ 7 | 8 | from pathlib import Path 9 | from xml.dom import minidom 10 | import xml.etree.ElementTree as ET 11 | 12 | from links import LINKS 13 | import requests 14 | 15 | 16 | def download_file(url: str, dest_path: Path) -> None: 17 | """Given a sitemap url, this function downloads the file into (dest_path). 18 | 19 | Parameters 20 | ---------- 21 | url : str 22 | The url of the sitemap file to be downloaded 23 | dest_path : Path 24 | The destination path to save the downloaded file 25 | 26 | Raises 27 | ------ 28 | requests.exceptions.Timeout 29 | Raises this exception when accessing a link takes too long 30 | """ 31 | # Send the request 32 | response = requests.get(url, stream=True, timeout=30) 33 | 34 | # Write the file content to the specified location 35 | with dest_path.open(mode="w", encoding="utf-8") as file: 36 | file.write(response.text) 37 | 38 | 39 | def extract_urls_and_headers(links_dict: dict) -> tuple: 40 | """Extract valid project names and sitemap urls from metadata dictionary. 41 | 42 | Parameters 43 | ---------- 44 | links_dict : dict 45 | Dictionary containing metadata of projects 46 | 47 | Returns 48 | ------- 49 | tuple 50 | Contains the list of project names and the list of sitemap urls 51 | """ 52 | valid_project_names = [] 53 | valid_urls = [] 54 | for project_name, url in links_dict.items(): 55 | # The form of url is "https://subdomain.docs.pyansys.com/version/stable 56 | # where subdomain may contain nested subdomains depending on the project 57 | # see links.py from which LINKS was imported for examples 58 | if url is None: 59 | continue 60 | # url is changed to "https://subdomain.docs.pyansys.com/sitemap.xml 61 | # this is general form of the link to the sitemap file of each project 62 | updated_url = url.split("docs.pyansys.com")[0] + "docs.pyansys.com/sitemap.xml" 63 | if requests.get(url).status_code == 404: 64 | continue 65 | else: 66 | valid_project_names.append(project_name) 67 | valid_urls.append(updated_url) 68 | 69 | return valid_project_names, valid_urls 70 | 71 | 72 | def generate_sitemap_index(project_names: list, dest_path: Path) -> None: 73 | """Generate the global sitemap file which will point to all other sitemaps. 74 | 75 | Parameters 76 | ---------- 77 | project_names : list 78 | List of project names with a downloadable sitemap file 79 | dest_path : Path 80 | The destination path to save the generated sitemap file 81 | """ 82 | # Create the root element with namespace 83 | sitemap_index = ET.Element("sitemapindex", xmlns="http://www.sitemaps.org/schemas/sitemap/0.9") 84 | 85 | # Create sitemap elements for each URL 86 | for project in project_names: 87 | # Modify the url to point to the correct gh-pages directory 88 | modified_url = f"https://docs.pyansys.com/sitemap/{project}_sitemap.xml" 89 | 90 | sitemap = ET.SubElement(sitemap_index, "sitemap") 91 | loc = ET.SubElement(sitemap, "loc") 92 | loc.text = modified_url 93 | 94 | # Format XML with indentation 95 | rough_string = ET.tostring(sitemap_index, "utf-8") 96 | reparsed = minidom.parseString(rough_string) 97 | pretty_xml = reparsed.toprettyxml(indent=" ") 98 | 99 | # Create the tree and write to XML file 100 | with dest_path.open(mode="w", encoding="utf-8") as file: 101 | file.write(pretty_xml) 102 | 103 | 104 | if __name__ == "__main__": 105 | # Create path 106 | folder_path = Path() / "sitemaps" 107 | folder_path.mkdir(parents=True, exist_ok=True) 108 | 109 | # Get actual valid URLS and corresponding project names 110 | project_names, project_urls = extract_urls_and_headers(LINKS) 111 | 112 | # Generate global sitemap file 113 | file_path = folder_path / "globalsitemap.xml" 114 | generate_sitemap_index(project_names, file_path) 115 | 116 | for ith_url, url in enumerate(project_urls): 117 | file_path = folder_path / (project_names[ith_url] + "_sitemap.xml") 118 | download_file(url, file_path) 119 | -------------------------------------------------------------------------------- /tools/links.py: -------------------------------------------------------------------------------- 1 | """ 2 | Script for automatic replacement of released links. 3 | 4 | Usage is very simple. Just run the script. 5 | 6 | .. code:: python 7 | 8 | python links.py 9 | """ 10 | 11 | from pathlib import Path 12 | import re 13 | 14 | ROOT_DIR = Path(__file__).parent.parent 15 | """Root directory of the project relative to this file.""" 16 | 17 | PYPROJECT_TOML_FILE = ROOT_DIR / "pyproject.toml" 18 | """Path to pyproject.toml file.""" 19 | 20 | DOCS_DIRECTORY = ROOT_DIR / "doc" / "source" 21 | """Path to the documentation source directory""" 22 | 23 | LINKS = { 24 | "ansys-acp-core": None, # Once stable release is out "https://acp.docs.pyansys.com/version/stable", # noqa: E501 25 | "ansys-additive-core": "https://additive.docs.pyansys.com/version/stable", 26 | "ansys-conceptev-core": "https://conceptev.docs.pyansys.com/version/stable", 27 | "ansys-dpf-composites": "https://composites.dpf.docs.pyansys.com/version/stable", # noqa: E501 28 | "ansys-dpf-core": "https://dpf.docs.pyansys.com/version/stable", 29 | "ansys-dpf-post": "https://post.docs.pyansys.com/version/stable", 30 | "ansys-dpf-gate": None, 31 | "ansys-dyna-core": "https://dyna.docs.pyansys.com/version/stable", 32 | "ansys-dynamicreporting-core": "https://dynamicreporting.docs.pyansys.com/version/stable", # noqa: E501 33 | "ansys-edb-core": "https://edb.core.docs.pyansys.com/version/stable", 34 | "ansys-geometry-core": "https://geometry.docs.pyansys.com/version/stable", 35 | "ansys-fluent-core": "https://fluent.docs.pyansys.com/version/stable", 36 | "ansys-hps-client": "https://hps.docs.pyansys.com/version/stable", 37 | "ansys-hps-data-transfer-client": "https://data-transfer.hps.docs.pyansys.com/version/stable", # noqa: E501 38 | "ansys-mapdl-core": "https://mapdl.docs.pyansys.com/version/stable", 39 | "ansys-math-core": "https://math.docs.pyansys.com/version/stable", 40 | "ansys-sound-core": "https://sound.docs.pyansys.com/version/stable", 41 | "ansys-mechanical-core": "https://mechanical.docs.pyansys.com/version/stable", # noqa: E501 42 | "ansys-meshing-prime": "https://prime.docs.pyansys.com/version/stable", 43 | "ansys-modelcenter-workflow": "https://modelcenter.docs.pyansys.com/version/stable", # noqa: E501 44 | "ansys-motorcad-core": "https://motorcad.docs.pyansys.com/version/stable", 45 | "ansys-openapi-common": None, 46 | "ansys-optislang-core": "https://optislang.docs.pyansys.com/version/stable", 47 | "ansys-platform-instancemanagement": "https://pypim.docs.pyansys.com/version/stable", # noqa: E501 48 | "ansys-pyensight-core": "https://ensight.docs.pyansys.com/version/stable", 49 | "ansys-rocky-core": "https://rocky.docs.pyansys.com/version/stable", 50 | "ansys-seascape": "https://seascape.docs.pyansys.com/version/stable", 51 | "ansys-sherlock-core": "https://sherlock.docs.pyansys.com/version/stable", 52 | "ansys-simai-core": "https://simai.docs.pyansys.com/version/stable", 53 | "ansys-speos-core": "https://speos.docs.pyansys.com/version/stable", 54 | "ansys-systemcoupling-core": "https://systemcoupling.docs.pyansys.com/version/stable", # noqa: E501 55 | "ansys-turbogrid-core": "https://turbogrid.docs.pyansys.com/version/stable", 56 | "ansys-workbench-core": "https://workbench.docs.pyansys.com/version/stable", 57 | "pyedb": "https://edb.docs.pyansys.com/version/stable", 58 | "pyaedt": "https://aedt.docs.pyansys.com/version/stable", 59 | "pygranta": "https://grantami.docs.pyansys.com/version/stable", 60 | "pytwin": "https://twin.docs.pyansys.com/version/stable", 61 | # MAPDL - ALL 62 | "ansys-mapdl-reader": "https://reader.docs.pyansys.com/version/stable", 63 | # FLUENT - ALL 64 | "ansys-fluent-visualization": "https://visualization.fluent.docs.pyansys.com/version/stable", # noqa: E501 65 | # TOOLS 66 | "ansys-materials-manager": "https://manager.materials.docs.pyansys.com/version/stable", 67 | "ansys-tools-filetransfer": "https://filetransfer.tools.docs.pyansys.com/version/stable", # noqa: E501 68 | "ansys-tools-local-product-launcher": "https://local-product-launcher.tools.docs.pyansys.com/version/stable", # noqa: E501 69 | "ansys-tools-path": "https://path.tools.docs.pyansys.com/version/stable", 70 | "ansys-tools-protoc-helper": None, 71 | "ansys-tools-visualization-interface": "https://visualization-interface.tools.docs.pyansys.com/version/stable", # noqa: E501 72 | "ansys-units": "https://units.docs.pyansys.com/version/stable", 73 | "pyansys-tools-report": "https://report.tools.docs.pyansys.com/version/stable", # noqa: E501 74 | "pyansys-tools-versioning": "https://versioning.tools.docs.pyansys.com/version/stable", # noqa: E501 75 | "pyansys-tools-variableinterop": "https://variableinterop.docs.pyansys.com/version/stable", # noqa: E501 76 | } 77 | """Dictionary with PyAnsys packages and their multi-version docs site.""" 78 | 79 | 80 | def retrieve_major_minor(package: str): 81 | """Extract the major and minor version of a pinned package. 82 | 83 | Notes 84 | ----- 85 | This function navigates to the package's pyproject.toml file 86 | 87 | and processes it to retrieve the desired major, minor version. 88 | 89 | 90 | Parameters 91 | ---------- 92 | package : str 93 | The package to be searched for. 94 | 95 | 96 | Returns 97 | ------- 98 | tuple of (int, int) 99 | The major and minor versions of the package. 100 | 101 | """ 102 | with PYPROJECT_TOML_FILE.open("r") as file: 103 | content = file.read() 104 | pattern = r"\b" + re.escape(package) + r"==(\d+)\.(\d+)" 105 | match = re.search(pattern, content) 106 | 107 | if match: 108 | major_version = int(match.group(1)) 109 | minor_version = int(match.group(2)) 110 | return (major_version, minor_version) 111 | 112 | return (None, None) 113 | 114 | 115 | def search_and_replace(link: str, new_link: str): 116 | """Replace existing link with the newly provided link. 117 | 118 | Parameters 119 | ---------- 120 | link : str 121 | The link to be searched for. 122 | new_link : str 123 | The link to replace the existing one. 124 | """ 125 | # Traverse the docs directory 126 | for root, _, files in DOCS_DIRECTORY.walk(): 127 | # Skip the _static subdirectory 128 | if "_static" in root.parts: 129 | continue 130 | 131 | # Process the files 132 | for file in files: 133 | file_path = root / file 134 | content = file_path.read_text(encoding="utf-8") 135 | 136 | # Search for the link in the content, replace and save 137 | if link in content: 138 | new_content = content.replace(link, new_link) 139 | file_path.write_text(new_content, "utf-8") 140 | 141 | print(f"Replaced '{link}' with '{new_link}' in file: {file_path}") # noqa: E501 142 | 143 | 144 | def released_docs(): 145 | """Update links for released documentation. 146 | 147 | Notes 148 | ----- 149 | Links are expected to point to a certain version when released 150 | inside the metapackage, and not to the latest stable version. This 151 | module takes care of updating the links automatically. The script has to 152 | be run locally and the changes have to be committed to the release branch 153 | prior to releasing. 154 | """ 155 | # Loop over all the above defined packages 156 | for key, value in LINKS.items(): 157 | # Packages that are not adapted to multi-version have a None 158 | # link associated as its value... skip them. 159 | if value is None: 160 | continue 161 | 162 | # Retrieve the major and minor versions of the package 163 | major, minor = retrieve_major_minor(key) 164 | 165 | if major is None and minor is None: 166 | # No match found for the link... throw message 167 | print(f"Error retrieving minor/major version of {key}... Skipping.") # noqa: E501 168 | continue 169 | 170 | # Define the new link 171 | link_root = value.split("/version/")[0] 172 | new_link = f"{link_root}/version/{major}.{minor}" 173 | 174 | # Search and replace through all our docs links 175 | search_and_replace(value, new_link) 176 | 177 | 178 | if __name__ == "__main__": 179 | released_docs() 180 | --------------------------------------------------------------------------------