Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "run" library to pydyna #545

Merged
merged 9 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
name: documentation-pdf
path: doc/_build/latex/*.pdf
retention-days: 7

- name: Extract the server logs
if: always()
run: |
Expand All @@ -111,7 +111,7 @@ jobs:
with:
name: server_output_docs.txt
path: server_output.txt

- name: DPF Logs (on screen)
if: always()
run: |
Expand Down Expand Up @@ -188,9 +188,46 @@ jobs:
path: .cov/html
retention-days: 7

run-testing:
name: Test the "run" subpackage
runs-on: ubuntu-latest
needs: [code-style]
container:
image: ghcr.io/ansys/mechanical:24.1.0
options: --entrypoint /bin/bash

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
apt update
apt install --reinstall ca-certificates
apt install software-properties-common git -y
add-apt-repository ppa:deadsnakes/ppa -y
apt install python3.11 python3.11-venv -y
python3.11 -m ensurepip --default-pip
python3.11 -m pip install --upgrade pip
python3.11 -m venv /env
- name: Install library
run: |
. /env/bin/activate
pip install .[tests]
- name: Unit testing
env:
ANSYSLI_SERVERS: 2325@${{secrets.LICENSE_SERVER}}
ANSYSLMD_LICENSE_FILE: 1055@${{secrets.LICENSE_SERVER}}
LSTC_LICENSE: ansys
run: |
. /env/bin/activate
save-ansys-path --name dyna /install/ansys_inc/v241/ansys/bin/linx64/lsdyna_dp.e
pytest -m run
build-library:
name: "Build library"
needs: [doc, tests]
needs: [doc, tests, run-testing]
runs-on: ubuntu-latest
steps:
- uses: ansys/actions/build-library@v8
Expand Down
8 changes: 5 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ Overview
========
PyDYNA is a Pythonic package for providing a more convenient and complete way to
build an Ansys DYNA input deck, submit it to the Ansys LS-DYNA solver, and
finally postprocess the results.
finally postprocess the results.

PyDYNA contains two submodules, ``ansys.dyna.core.pre`` and ``ansys.dyna.core.solver``
PyDYNA contains three submodules, ``ansys.dyna.core.pre``, ``ansys.dyna.core.solver``, and ``ansys.dyna.core.run``.

- ``pre``: This module provides highly abstracted APIs for creating and
setting up DYNA input decks. There are many classes supported, namely,
Expand All @@ -52,6 +52,8 @@ PyDYNA contains two submodules, ``ansys.dyna.core.pre`` and ``ansys.dyna.core.so
``solver`` service provides a way to push input files to the LS-DYNA solver, monitor the state
of the running job, change the value of a load curve and finally retrieve result files back from
the server
- ``run``: This module provides the ability to start the LS-DYNA solver. This does not require any
client-server library or Docker container.

Once you have results, you can use the Ansys Data Processing Framework (DPF),
which is designed to provide numerical simulation users and engineers
Expand Down Expand Up @@ -80,7 +82,7 @@ development version or previously released versions.
On the `PyDYNA Issues <https://github.com/ansys/pydyna/issues>`_ page, you can create issues to
report bugs and request new features. On the `PyDYNA Discussions <https://github.com/ansys/pydyna/discussions>`_
page or the `Discussions <https://discuss.ansys.com/>`_ page on the Ansys Developer portal,
you can post questions, share ideas, and get community feedback.
you can post questions, share ideas, and get community feedback.

To reach the project support team, email `[email protected] <[email protected]>`_.

Expand Down
25 changes: 25 additions & 0 deletions doc/source/getting-started/RUN_README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Use PyDYNA to run LSDYNA locally
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Run LS-DYNA using ansys.dyna.core.run
*************************************

.. code:: python

import os
from ansys.dyna.core.run import run_dyna

dynafile = "input.k"
working_directory = os.path.getcwd()
filepath = run_dyna(dynafile, working_directory=dynadir)

......

How it works
************

``run_dyna`` attempts to find an installation of the LS-DYNA solver on your machine.
It uses the Python dependency ``ansys-tools-path`` to discover where LS-DYNA is installed.
After installing ``ansys-tools-path``, the location of LS-DYNA can be saved by running
``save-ansys-path --name dyna {path/to/dyna}`` so that subsequent usages of ``run_dyna``
will look there.

Check warning on line 25 in doc/source/getting-started/RUN_README.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] doc/source/getting-started/RUN_README.rst#L25

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "doc/source/getting-started/RUN_README.rst", "range": {"start": {"line": 25, "column": 1}}}, "severity": "WARNING"}
14 changes: 11 additions & 3 deletions doc/source/getting-started/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ page on the Ansys website.

Installation
============
PyDYNA consists of two modules, ``ansys.dyna.core.pre`` and ``ansys.dyna.core.solver``.
Both these modules are gRPC enabled and hence need to be run using server-client connection.
PyDYNA consists of three modules, ``ansys.dyna.core.pre``, ``ansys.dyna.core.solver``, and
``ansys.dyna.core.run``.

``ansys.dyna.core.pre`` and ``ansys.dyna.core.solver`` use gRPC and hence need to be run
using server-client connection.

Install the client
------------------
Expand Down Expand Up @@ -80,7 +83,7 @@ with these commands:
If you're on Windows with Python 3.9, unzip the wheelhouse archive to a ``wheelhouse``
directory and install PyDYNA using the preceding command.

Run PyDYNA server locally
Run PyDYNA server locally
-------------------------
Launching the servers directly on local machines.

Expand All @@ -96,6 +99,11 @@ PyDYNA server can be run in a Docker container.

.. include:: ../../../docker/solver/README.rst

Run DYNA using ``ansys.dyna.core.run`` on a local machine,
this does not require Docker.

.. include:: ./RUN_README.rst

Example
-------

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ classifiers = [

dependencies = ["ansys-dpf-core>=0.7.2",
"ansys-api-dyna==0.4.1",
"ansys-platform-instancemanagement~=1.0",
"ansys-tools-path==0.6.0",
"ansys-platform-instancemanagement~=1.0",
"pyvista>=0.43.4",
]

Expand Down
3 changes: 3 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
markers =
run: tests that exercise the `run` subpackage
24 changes: 24 additions & 0 deletions src/ansys/dyna/core/run/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from .local_solver import run_dyna # noqa: F401
from .options import MemoryUnit, MpiOption, Precision # noqa: F401
39 changes: 39 additions & 0 deletions src/ansys/dyna/core/run/base_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""Base runner class."""

from ansys.dyna.core.run.options import MemoryUnit, MpiOption, Precision


class BaseRunner:
def __init__(self, **kwargs):
# TODO - split mpi option into precision?
self.mpi_option = kwargs.get("mpi_option", MpiOption.SMP)
self.ncpu = kwargs.get("ncpu", 1)
self.memory = kwargs.get("memory", 20)
self.memory_unit = kwargs.get("memory_unit", MemoryUnit.MB)
self.precision = kwargs.get("precision", Precision.DOUBLE)

def get_memory_string(self) -> str:
unit = {MemoryUnit.MB: "m", MemoryUnit.GB: "G"}[self.memory_unit]
return f"{self.memory}{unit}"
85 changes: 85 additions & 0 deletions src/ansys/dyna/core/run/linux_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os

from ansys.tools.path import get_dyna_path, get_latest_ansys_installation
from ansys.tools.path.path import _get_unified_install_base_for_version

from ansys.dyna.core.run.base_runner import BaseRunner
from ansys.dyna.core.run.options import MpiOption, Precision


class LinuxRunner(BaseRunner):
"""Linux implementation to Run LS-DYNA. Tested with a custom exutable
and when LS-DYNA is installed as part of the unified Ansys installation
"""

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.executable = kwargs.get("executable", None)
version = kwargs.get("version", None)
self._find_solver(version, self.executable)

def set_input(self, input_file: str, working_directory: str) -> None:
self.input_file = input_file
self.working_directory = working_directory

def _find_solver(self, version: int, executable: str) -> None:
atp_dyna_path = get_dyna_path(find=False, allow_input=False)
if executable is not None:
# User passed in executable directly. Use that.
if os.path.isfile(executable):
self.solver = executable
elif atp_dyna_path is not None:
# User stored dyna solver in ansys-tools-path, use that
self.solver = atp_dyna_path
elif version is not None:
# User passed in the version, compute the path to the dyna solver from the
# unified installation
# of that version
install_loc, _ = _get_unified_install_base_for_version(version)
self.solver = os.path.join(install_loc, "ansys", "bin", "linx64", self._get_exe_name())
else:
# User passed nothing, find the dyna solver from the latest unified installation
install_loc, _ = get_latest_ansys_installation()
self.solver = os.path.join(install_loc, "ansys", "bin", "linx64", self._get_exe_name())

def _get_exe_name(self) -> str:
exe_name = {
(MpiOption.SMP, Precision.SINGLE): "lsdyna_sp.e",
(MpiOption.SMP, Precision.DOUBLE): "lsdyna_dp.e",
(MpiOption.MPP_INTEL_MPI, Precision.SINGLE): "lsdyna_sp_mpp.e",
(MpiOption.MPP_INTEL_MPI, Precision.DOUBLE): "lsdyna_dp_mpp.e",
}[(self.mpi_option, self.precision)]
return exe_name

def run(self) -> None:
os.chdir(self.working_directory)
if self.mpi_option == MpiOption.MPP_INTEL_MPI:
os.system(
f"mpirun -np {self.ncpu} {self.solver} i={self.input_file} memory={self.get_memory_string()}" # noqa: E501
)
else:
os.system(
f"{self.solver} i={self.input_file} ncpu={self.ncpu} memory={self.get_memory_string()}" # noqa: E501
)
Loading
Loading