Getting started#

To use the solver features of PyDYNA, you must have a valid LS-DYNA license.

For information on getting a licensed copy of LS-DYNA, see the Ansys LS-DYNA page on the Ansys website.

Installation#

PyDYNA consists of four modules, ansys.dyna.core.pre, ansys.dyna.core.solver, ansys.dyna.core.run, and ansys.dyna.core.keywords.

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

Install the client#

The ansys.dyna.core package supports Python 3.9 through Python 3.12 on Windows, Linux, and MacOS.

You should consider installing PyDYNA in a virtual environment. For more information, see Python’s venv – Creation of virtual environments.

PyDYNA has three installation modes: user, developer, and offline.

Install in user mode#

Before installing PyDYNA in user mode, make sure you have the latest version of pip with this command:

python -m pip install -U pip

Then, install PyDYNA with this command:

python -m pip install ansys-dyna-core

Install in developer mode#

Installing PyDYNA in developer mode allows you to modify the source and enhance it.

Note

Before contributing to the project, ensure that you are thoroughly familiar with the PyAnsys Developer’s Guide.

Start by cloning and installing the repository with these commands:

git clone https://github.com/pyansys/pyDyna
cd pyDyna
pip install -e .

Install in offline mode#

If you lack an internet connection on your installation machine, you should install PyDYNA by downloading the wheelhouse archive for your corresponding machine architecture from the Releases Page.

Each wheelhouse archive contains all the Python wheels necessary to install PyDYNA from scratch on Windows and Linux for Python 3.9 through 3.12. You can install PyDYNA on an isolated system with a fresh Python installation or on a virtual environment.

For example, on Linux with Python 3.9, unzip the wheelhouse archive and install PyDYNA with these commands:

unzip ansys-dyna-core-v0.3.dev0-wheelhouse-Linux-3.9.zip -d wheelhouse
pip install ansys-dyna-core -f wheelhouse --no-index --upgrade --ignore-installed

If you’re on Windows with Python 3.9, unzip the wheelhouse archive to a wheelhouse directory and install PyDYNA using the preceding command.

Working with LS-DYNA keywords#

The keywords module can be used to interact with LS-DYNA keywords.

Getting started#

Overview#

The keywords` module of PyDyna provides Python libraries to build an Ansys LS-DYNA keyword deck.

Usage#

Here’s an example of how you can generate a *SECTION_TSHELL` keyword:

>>> from ansys.dyna.core.keywords import keywords
>>> shell = keywords.SectionTShell()
>>> shell
*SECTION_TSHELL
$#   secid    elform      shrf       nip     propt        qr     icomp    tshear
                   1       1.0         2       1.0         0         0         0

Examples#

Examples showing end-to-end workflows for using PyDyna - write a deck using the keywords module and run the solver using the run module.

  1. Buckling_Beer_Can

  2. John_Reid_Pendulum

  3. John_Reid_Pipe

  4. Taylor_Bar

Run PyDYNA server locally#

Launching the servers directly on local machines.

Start PyDYNA preprocessing server locally#

Run an example on the client side#

hostname = "localhost"
if len(sys.argv) > 1:
    hostname = sys.argv[1]
    solution = launch_dynapre(ip = hostname)
    ......
  1. The function of launch_dynapre() can download and start the preprocessing server automatically.

Start PyDYNA solver server locally#

Prerequisites#

Start server on Windows#
  1. If you want to start the server on Windows,please ensure that you have installed the ANSYS locally.

Start server on Linux(Centos7)#
  1. If you want to start the server on Linux,please ensure that you have installed the Open MPI package.

    yum install openmpi3 openmpi3-dev
    
  2. set environment variable for Open MPI

    export LD_LIBRARY_PATH=/usr/lib64/openmpi3/lib:$LD_LIBRARY_PATH
    export PATH=/usr/lib64/openmpi3/bin:$PATH
    

Run an example on the client side#

import ansys.dyna.core.solver as solver

hostname = "localhost"
port = "5000"
dyna=launch_dyna(ip = hostname,port = port)     # connect to the server
dyna.push("./output/ball_plate.k")        # push an input file
dyna.start_locally(input = "ball_plate.k",nproc=1)
  1. The function of DynaSolver() can download and start the solver server automatically.

Run PyDYNA Server in a Docker container#

PyDYNA server can be run in a Docker container.

Build the Docker image for the pre service#

You must build the Docker image for the PyDYNA pre service and then run the image as a container.

Prerequisites#

  • Ensure that you have cloned the PyDYNA repository locally with these commands:

    git clone https://github.com/pyansys/pydyna.git
    cd pydyna
    

    The docker file in the docker/pre directory is used to build the Linux-based Docker image.

  • If you are building the image on Windows, ensure that the Windows Subsystem for Linux (WSL) is installed. For installation information, see Microsoft’s Install Linux on Windows with WSL.

  • Install docker engine. Based on the Linux distro you can use the corresponding installation instructions from this page.

  • Download the latest Linux release artifacts for the pre Docker container: linux-binaries.zip.

  • Move this ZIP file to the docker/pre directory.

Once all prerequisites are met, you can build the Docker container for the pre service.

Build the Docker container for the pre service#

To build the Docker image, perform these steps:

  1. In your terminal, go to the docker directory.

  2. Run the following Docker command, replacing <DOCKERFILE_NAME> with Dockerfile and <DOCKER_IMAGE_TAG> with latest.

    docker build -t ghcr.io/ansys/ls-pre:<DOCKER_IMAGE_TAG> -f <DOCKERFILE_NAME> .
    
  3. Check that the image has been built successfully by running this command:

    docker images
    

    Your output should look similar to this:

    >>> REPOSITORY                                               TAG                                IMAGE ID       CREATED          SIZE
    >>> ghcr.io/ansys/ls-pre                                     *******-latest                     ............   X seconds ago    188MB
    >>> ......                                                   ......                             ............   ..............   ......
    

Run the image as a container#

Once the Docker image of the pre service is built successfully, perform these steps to run this image as a container:

  1. Run this Docker command:

    docker run -d -p 50051:50051 ghcr.io/ansys/ls-pre
    
  2. Check that the image is running successfully by running this command.

    docker ps
    

    Your output should look similar to this:

    >>> CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                           NAMES
    >>> c77ffd67f9fa   ghcr.io/ansys/ls-pre   "python3 ./linux-bin…"   7 seconds ago   Up 7 seconds   0.0.0.0:50051->50051/tcp, :::50051->50051/tcp   hardcore_margulis
    

Alternatively, you can start the container for the pre service from a docker-compose.yml file.

  1. Ensure that Docker Compose has been installed on your computer. If Docker Compose is not installed, see Overview of installing Docker Compose in the Docker documentation.

  2. In your terminal, go to the docker/pre directory and run this Docker command:

docker compose up -d

Copy files from Docker#

To copy files back from the pre docker container to your host machine use the command below:

docker cp <containerId>:/file/path/within/container /host/target/path

The path within the container is /server/output.

Build the Docker image for the solver service#

You must build the Docker image for the PyDYNA solver service and then run the image as a container.

Prerequisites#

  • Ensure that you have cloned the PyDYNA repository locally with these commands:

    git clone https://github.com/pyansys/pydyna.git
    cd pydyna
    

    The docker file in the docker/solver directory is used to build the Linux-based Docker image.

  • If you are building the image on Windows, ensure that the Windows Subsystem for Linux (WSL) is installed. For installation information, see Microsoft’s Install Linux on Windows with WSL.

  • Install docker engine. Based on the Linux distro you can use the corresponding installation instructions from this page.

  • Download the latest Linux release artifacts for the solver Docker container: mppdyna_docker_centos7.zip.

  • Move this ZIP file to the docker/solver directory.

    The files in this folder should look similar to this:

    >>> Dockerfile README.rst docker-compose.yml  mppdyna_docker_centos7.zip
    

Once all prerequisites are met, you can build the Docker image for the solver service.

Build the Docker image#

To build the Docker image for the solver service, perform these steps:

  1. In your terminal, go to the pydyna/docker/solver directory.

  2. Run this Docker command:

    docker build -t dyna_solver_v04 .
    
  3. Check that the image has been built successfully by running this command:

    docker images
    

    Your output should look similar to this:

    >>> REPOSITORY                        TAG                                        IMAGE ID       CREATED          SIZE
    >>> dyna_solver_v04                   latest                                     defbadbeee8e   16 minutes ago   730MB
    >>> ......                                                   ......                             ............   ..............   ......
    

Start the container from a docker-compose.yml file#

Alternatively, you can start the container for the pre service from a docker-compose.yml file.

  1. Ensure that Docker Compose has been installed on your computer. If Docker Compose is not installed, see Overview of installing Docker Compose in the Docker documentation.

  2. In the docker-compose.yml file, replace <license_server_name> with the correct license server hosting the LS-DYNA license.

  3. In your terminal, go to the docker/solver directory and run this Docker command:

    docker compose up -d
    
  4. Check that the image is running successfully by running this command.

    docker ps
    

    Your output should look similar to this:

    >>> CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS         PORTS                            NAMES
    >>> be84c95db31d   dyna_solver_v04   "/ansys_inc/server.p…"   18 minutes ago   Up 8 seconds   22/tcp, 0.0.0.0:5000->5000/tcp   mppdyna_docker_centos7_dyna_1
    

Copy files from Docker#

To copy files back from the solver container to your host machine use the command below:

docker cp <containerId>:/file/path/within/container /host/target/path

The path within the container is /rundir.

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

Use PyDYNA to run LSDYNA locally#

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

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 look there.

Keyword and run example#

The next few sections show how to generate, preview, solve, and review a Taylor bar impact problem. An example of a sweep over impact velocities for this problem can be found in this repository at examples/Taylor_Bar/plot_taylor_bar_example.py.

Preprocessing#

The following code describes an LS-DYNA Model for a Taylor bar impact problem. It assumes that the mesh file taylor_bar_mesh.k exists in the working directory. This mesh file can be found in this repository at examples/Taylor_Bar/taylor_bar_mesh.k.

import pandas as pd

from ansys.dyna.core import Deck, keywords as kwd

# construct a new Deck
deck = Deck()

# Define material
mat_1 = kwd.Mat003(mid=1)
mat_1.ro = 7.85000e-9
mat_1.e = 150000.0
mat_1.pr = 0.34
mat_1.sigy = 390.0
mat_1.etan = 90.0

# Define section
sec_1 = kwd.SectionSolid(secid=1)
sec_1.elform = 1

# Define part
part_1 = kwd.Part()
part_1.parts = pd.DataFrame({"pid": [1], "mid": [mat_1.mid], "secid": [sec_1.secid]})

# Define coordinate system
cs_1 = kwd.DefineCoordinateSystem(cid=1)
cs_1.xl = 1.0
cs_1.yp = 1.0

 # Define initial velocity
init_vel = kwd.InitialVelocityGeneration()
init_vel.id = part_1.parts["pid"][0]
init_vel.styp = 2
init_vel.vy = 300.0e3 # mm/s
init_vel.icid = cs_1.cid

# Define box for node set
box_1 = kwd.DefineBox(boxid=1, xmn=-500, xmx=500, ymn=39.0, ymx=40.1, zmn=-500, zmx=500)

# Create node set
set_node_1 = kwd.SetNodeGeneral()
set_node_1.sid = 1
set_node_1.option = "BOX"
set_node_1.e1 = box_1.boxid

# Define rigid wall
rw = kwd.RigidwallPlanar(id=1)
rw.nsid = set_node_1.sid
rw.yt = box_1.ymx
rw.yh = box_1.ymn

# Define control termination
control_term = kwd.ControlTermination(endtim=8.00000e-5, dtmin=0.001)

# Define database cards
deck_dt_out = 8.00000e-8
deck_glstat = kwd.DatabaseGlstat(dt=deck_dt_out, binary=3)
deck_matsum = kwd.DatabaseMatsum(dt=deck_dt_out, binary=3)
deck_nodout = kwd.DatabaseNodout(dt=deck_dt_out, binary=3)
deck_elout = kwd.DatabaseElout(dt=deck_dt_out, binary=3)
deck_rwforc = kwd.DatabaseRwforc(dt=deck_dt_out, binary=3)
deck_d3plot = kwd.DatabaseBinaryD3Plot(dt=4.00000e-6)

# Define deck history node
deck_hist_node_1 = kwd.DatabaseHistoryNodeSet(id1=set_node_1.sid)

# Insert all these cards into the Deck
deck.extend(
    [
        deck_glstat,
        deck_matsum,
        deck_nodout,
        deck_elout,
        deck_rwforc,
        deck_d3plot,
        set_node_1,
        control_term,
        rw,
        box_1,
        init_vel,
        cs_1,
        part_1,
        mat_1,
        sec_1,
        deck_hist_node_1,
    ]
)

# Add keyword that imports the mesh
deck.append(kwd.Include(filename="taylor_bar_mesh.k"))

Preview#

The following code opens a 3D graphics window to preview the mesh for the LS-DYNA Model

# Preview the model
deck.plot()

Write to file#

The following code writes the LS-DYNA model to an input.k keyword file in the working directory.

# Convert deck to string
deck_string = deck.write()

# Create LS-DYNA input deck
with open("input.k", "w") as file_handle:
    file_handle.write(deck_string)

Solve#

The following code runs LS-DYNA using the input.k file.

import os

from ansys.dyna.core.run import run_dyna

# Run LS-DYNA
run_dyna("input.k")

# Confirm that the results exist
assert os.path.isfile("d3plot")
assert os.path.isfile("lsrun.out.txt")

Post processing#

The following code processes results and generates a line chart of Time vs. Energy from the impact. This requires an installation of a matplotlib backend.

import matplotlib.pyplot as plt
import ansys.dpf.core as dpf

ds = dpf.DataSources()
ds.set_result_file_path("d3plot", "d3plot")
model = dpf.Model(ds)

gke_op = dpf.operators.result.global_kinetic_energy()
gke_op.inputs.data_sources.connect(ds)
gke = gke_op.eval()
field = gke.get_field(0)
ke_data = field.data

time_data = model.metadata.time_freq_support.time_frequencies.data_as_list

plt.plot(time_data, ke_data, "b", label="Kinetic Energy")
plt.xlabel("Time (s)")
plt.ylabel("Energy (mJ)")
plt.show()

Pre and solver example#

The next few sections show how to preprocessing, solve, and postprocessing a ball plate example.

Preprocessing#

The following code processes a ball plate example. In the repository, you can get the input file from src/ansys/dyna/core/pre/examples/explicit/ball_plate/ball_plate.k and the Python file from examples/Explicit/ball_plate.py.

import os
import sys
from ansys.dyna.core.pre import launch_dynapre
from ansys.dyna.core.pre.dynamech import (
    DynaMech,
    Velocity,
    PartSet,
    ShellPart,
    SolidPart,
    NodeSet,
    Contact,
    ContactSurface,
    ShellFormulation,
    SolidFormulation,
    ContactType,
    AnalysisType
)
from ansys.dyna.core.pre.dynamaterial import (
    MatRigid,
    MatPiecewiseLinearPlasticity,
)
from ansys.dyna.core.pre import examples

hostname = "localhost"
if len(sys.argv) > 1:
    hostname = sys.argv[1]
solution = launch_dynapre(ip = hostname)

fns = []
path = examples.ball_plate + os.sep
fns.append(path+"ball_plate.k")
solution.open_files(fns)

solution.set_termination(termination_time=10)

ballplate = DynaMech(AnalysisType.NONE)
solution.add(ballplate)

matrigid = MatRigid(mass_density=7.83e-6, young_modulus=207, poisson_ratio=0.3)
matplastic = MatPiecewiseLinearPlasticity(mass_density=7.83e-6, young_modulus=207, yield_stress=0.2, tangent_modulus=2)

plate = ShellPart(1)
plate.set_element_formulation(ShellFormulation.BELYTSCHKO_TSAY)
plate.set_material(matplastic)
plate.set_thickness(1)
plate.set_integration_points(5)
ballplate.parts.add(plate)

ball = SolidPart(2)
ball.set_material(matrigid)
ball.set_element_formulation(SolidFormulation.CONSTANT_STRESS_SOLID_ELEMENT)
ballplate.parts.add(ball)

selfcontact = Contact(type=ContactType.AUTOMATIC)
surf1 = ContactSurface(PartSet([1, 2]))
selfcontact.set_slave_surface(surf1)
ballplate.contacts.add(selfcontact)

spc = [34,35,51,52,68,69,85,86,102,103,119,120,136,137,153,154,170,171,187,188,204,205,221,222,238,239,255,256]
for i in range(1,19):
    spc.append(i)
for i in range(272,290):
    spc.append(i)
ballplate.boundaryconditions.create_spc(NodeSet(spc),rx=False,ry=False,rz=False)

for i in range(1,1652):
    ballplate.initialconditions.create_velocity_node(i,trans=Velocity(0, 0, -10))

solution.set_output_database(glstat=0.1, matsum=0.1, sleout=0.1)
solution.create_database_binary(dt=1)
serverpath = solution.save_file()

serveroutfile = '/'.join((serverpath,"ball_plate.k"))
downloadpath = os.path.join(os.getcwd(), "output")
if not os.path.exists(downloadpath):
    os.makedirs(downloadpath)
downloadfile = os.path.join(downloadpath,"ball_plate.k")
solution.download(serveroutfile,downloadfile)

Solve#

The following code solves this basic ball plate example. In the repository, you can get the Python file from examples/solver/ball_plate_solver.py.

import ansys.dyna.core.solver as solver

hostname = "localhost"
port = "5000"
dyna=launch_dyna(ip = hostname,port = port)            # connect to the container
dyna.push("./output/ball_plate.k")                            # push an input file
dyna.start(4)                                   # start 4 ranks of mppdyna
dyna.run("i=ball_plate.k memory=10m ncycle=20000")   # begin execution

Post processing#

The following code processes results from the solve of this basic ball plate example:

from ansys.dpf import core as dpf
import os

ds = dpf.DataSources()
data_path = os.path.join(os.getcwd(), 'd3plot')
ds.set_result_file_path(data_path, 'd3plot')

model = dpf.Model(ds)
# Extract displacements for all time steps from d3plot
D = model.results.displacement.on_all_time_freqs().eval()
D.animate()

stress = dpf.operators.result.stress()
stress.inputs.data_sources(ds)
stress.inputs.time_scoping([12])
stress.connect(25, [1])
stress.inputs.requested_location.connect("Nodal")
fields = stress.outputs.fields_container()

shell_layer_extract = dpf.operators.utility.change_shell_layers()
shell_layer_extract.inputs.fields_container.connect(fields)
print(shell_layer_extract.inputs.e_shell_layer)
shell_layer_extract.inputs.e_shell_layer.connect(0)
fields_top = shell_layer_extract.outputs.fields_container_as_fields_container()
print(fields_top)
fields_top.animate()

For more examples, see Examples in the PyDYNA documentation.