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.
Buckling_Beer_Can
John_Reid_Pendulum
John_Reid_Pipe
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) ......
The function of launch_dynapre() can download and start the preprocessing server automatically.
Start PyDYNA solver server locally#
Prerequisites#
Start server on Windows#
If you want to start the server on Windows,please ensure that you have installed the ANSYS locally.
Start server on Linux(Centos7)#
If you want to start the server on Linux,please ensure that you have installed the Open MPI package.
yum install openmpi3 openmpi3-dev
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)
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 thedocker/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:
In your terminal, go to the
docker
directory.Run the following Docker command, replacing
<DOCKERFILE_NAME>
withDockerfile
and<DOCKER_IMAGE_TAG>
withlatest
.docker build -t ghcr.io/ansys/ls-pre:<DOCKER_IMAGE_TAG> -f <DOCKERFILE_NAME> .
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:
Run this Docker command:
docker run -d -p 50051:50051 ghcr.io/ansys/ls-pre
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.
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.
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 thedocker/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:
In your terminal, go to the
pydyna/docker/solver
directory.Run this Docker command:
docker build -t dyna_solver_v04 .
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.
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.
In the
docker-compose.yml
file, replace<license_server_name>
with the correct license server hosting the LS-DYNA license.In your terminal, go to the
docker/solver
directory and run this Docker command:docker compose up -d
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.