Skip to content

Commit 142a15c

Browse files
updates
1 parent 8ea67e5 commit 142a15c

File tree

1 file changed

+75
-50
lines changed

1 file changed

+75
-50
lines changed

examples/14-lsdyna/01-lsdyna_beam.py

Lines changed: 75 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
"""
2424
.. _lsdyna_operators:
2525
26-
Results extraction and analysis from LS-DYNA sources
27-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26+
Beam results manipulations
27+
--------------------------
2828
2929
This example provides an overview of the LS-DYNA beam results manipulations.
3030
@@ -40,12 +40,12 @@
4040
from ansys.dpf.core import operators as ops
4141

4242
###############################################################################
43-
# d3plot file results extraction
44-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43+
# d3plot file data extraction
44+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4545
# Create the model and print its contents. This LS-DYNA d3plot file contains
4646
# several individual results, each at different times. The d3plot file does not
4747
# contain information related to Units.
48-
48+
#
4949
# In this case, as the simulation was run through Mechanical, a ''file.actunits''
5050
# file is produced. If this file is supplemented in the data_sources, the units
5151
# will be correctly fetched for all results in the file as well as for the mesh.
@@ -58,58 +58,67 @@
5858
print(my_model)
5959

6060
###############################################################################
61+
# Exploring the mesh
62+
# ~~~~~~~~~~~~~~~~~~
63+
#
6164
# The model has solid (3D) elements and beam (1D) elements. Some of the results
6265
# only apply to one type of elements (such as the stress tensor for solids, or
6366
# the axial force for beams, for example).
64-
67+
#
6568
# By splitting the mesh by element shape we see that the ball is made by the solid
6669
# 3D elements and the plate by the beam 1D elements
67-
68-
# Define the analysis mesh
70+
#
71+
# - Define the analysis mesh
6972
my_meshed_region = my_model.metadata.meshed_region
7073

71-
# Get separate meshes for each body
74+
# - Get separate meshes for each body
7275
my_meshes = ops.mesh.split_mesh(
7376
mesh=my_meshed_region, property=dpf.common.elemental_properties.element_shape
7477
).eval()
7578

76-
# Define the meshes for each body in separate variables
79+
# - Define the meshes for each body in separate variables
7780
ball_mesh = my_meshes.get_mesh(label_space_or_index={"body": 1, "elshape": 1})
7881
plate_mesh = my_meshes.get_mesh(label_space_or_index={"body": 2, "elshape": 2})
7982

80-
# print(my_meshes)
83+
print(my_meshes)
8184

8285
###############################################################################
83-
# Ball
86+
# Plate mesh
8487

85-
print("Ball mesh", "\n", ball_mesh, "\n")
86-
ball_mesh.plot(title="Ball mesh", text="Ball mesh")
88+
print("Plate mesh", "\n", plate_mesh)
89+
plate_mesh.plot(title="Plate mesh", text="Plate mesh")
8790

8891
###############################################################################
89-
# Plate
92+
# Ball mesh
9093

91-
print("Plate mesh", "\n", plate_mesh)
92-
plate_mesh.plot(title="Plate mesh", text="Plate mesh")
94+
print("Ball mesh", "\n", ball_mesh, "\n")
95+
ball_mesh.plot(title="Ball mesh", text="Ball mesh")
9396

9497
###############################################################################
95-
# Define the mesh scoping to use it with the operators
98+
# Scoping
99+
# ~~~~~~~
100+
#
101+
# - Define the mesh scoping to use it with the operators
96102
my_meshes_scoping = ops.scoping.split_on_property_type(mesh=my_meshed_region).eval()
97103

98-
# Define the mesh scoping for each body/element shape in separate variables
104+
###############################################################################
105+
# - Define the mesh scoping for each body/element shape in separate variables
99106
ball_scoping = my_meshes_scoping.get_scoping(label_space_or_index={"elshape": 1})
100107
plate_scoping = my_meshes_scoping.get_scoping(label_space_or_index={"elshape": 2})
101108

102-
# We will plot the results in a mesh deformed by the displacement. The displacement
103-
# is in a nodal location, so we need to define a nodal scoping for the palte
109+
###############################################################################
110+
# - We will plot the results in a mesh deformed by the displacement.
111+
# The displacement is in a nodal location, so we need to define a nodal scoping for the plate
104112
plate_scoping_nodal = dpf.operators.scoping.transpose(
105113
mesh_scoping=plate_scoping, meshed_region=my_meshed_region
106114
).eval()
107115

108116
###############################################################################
109-
117+
# Beam results
118+
# ~~~~~~~~~~~~
110119
# The next manipulations can be applied to the following beam operators
111120
# that handle the correspondent results :
112-
121+
#
113122
# - beam_axial_force: Beam Axial Force
114123
# - beam_s_shear_force: Beam S Shear Force
115124
# - beam_t_shear_force: Beam T Shear Force
@@ -121,10 +130,10 @@
121130
# - beam_tr_shear_stress: Beam Tr Shear Stress
122131
# - beam_axial_plastic_strain: Beam Axial Plastic Strain
123132
# - beam_axial_total_strain: Beam Axial Total Strain
124-
133+
#
125134
# We do not demonstrate separately how to use each of them in this example
126-
# once they have similar methods. We .... in the beam stress and forces results
127-
135+
# once they have similar methods.
136+
#
128137
# So, if you want to operate on other operator, uou just need to change their
129138
# scripting name in the code lines.
130139

@@ -137,22 +146,22 @@
137146

138147
# 2) Prepare the collections to store the results for each time step
139148

140-
# To compare the results in the same image you have to copy the mesh for each plot
149+
# a. To compare the results in the same image you have to copy the mesh for each plot
141150
plate_meshes = dpf.MeshesContainer()
142151
plate_meshes.add_label("time")
143152

144-
# The displacements for each time steps to deform the mesh accordingly
153+
# b. The displacements for each time steps to deform the mesh accordingly
145154
plate_displacements = dpf.FieldsContainer()
146155
plate_displacements.add_label(label="time")
147156

148-
# The axial force results for each time steps. Here
157+
# c. The axial force results for each time steps. Here
149158
plate_axial_force = dpf.FieldsContainer()
150159
plate_axial_force.add_label(label="time")
151160

152-
# 3) Use the :class: `Plotter <ansys.dpf.core.plotter.DpfPlotter>` class
153-
# to add the plots in the same image
161+
# 3) Use the Plotter class to add the plots in the same image
154162
comparison_plot = dpf.plotter.DpfPlotter()
155163

164+
# Side bar arguments definition
156165
side_bar_args = dict(
157166
title="Beam axial force (N)", fmt="%.2e", title_font_size=15, label_font_size=15
158167
)
@@ -161,9 +170,9 @@
161170
# It represents the distance between the meshes
162171
j = -400
163172

173+
# 5) Copy the mesh of interest. Here it is the plate mesh that we copy along the X axis
164174
# Here we use a loop where each iteration correspond to the manipulations for a given time step
165175

166-
# 5) Copy the mesh of interest. Here it is the plate mesh that we copy along the X axis
167176
for i in time_steps_set: # Loop through the time steps
168177
# Copy the mesh
169178
plate_meshes.add_mesh(label_space={"time": i}, mesh=plate_mesh.deep_copy())
@@ -213,18 +222,19 @@
213222
# 12) Increment the coordinate value for the loop
214223
j = j - 400
215224

225+
216226
# Visualise the plot
217227
comparison_plot.show_figure()
218228

219229
###############################################################################
220230
# Plot a graph over time for the elements with max and min results values
221231
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
222-
232+
#
223233
# Here we make a workflow with a more verbose approach. This is useful because we use operators
224234
# having several matching inputs or outputs. So the connexions are more clear, and it is
225235
# easier to use and reuse the workflow.
226-
227-
# Find the element with the max values over all the time steps and return its ID
236+
#
237+
# The following workflow finds the element with the max values over all the time steps and return its ID
228238

229239
# Define the workflow object
230240
max_workflow = dpf.Workflow()
@@ -249,8 +259,13 @@
249259
max_workflow.set_output_name("max_entity_scoping", max_scop.outputs.mesh_scoping_as_scoping)
250260

251261
###############################################################################
262+
# Using the workflow to the stresses results on the plate:
263+
#
264+
# - Extract the results
265+
252266
# Get all the time steps
253267
time_all = my_model.metadata.time_freq_support.time_frequencies
268+
254269
# Extract all the stresses results on the plate
255270
plate_beam_axial_stress = my_model.results.beam_axial_stress(
256271
time_scoping=time_all, mesh_scoping=plate_scoping
@@ -262,21 +277,30 @@
262277
time_scoping=time_all, mesh_scoping=plate_scoping
263278
).eval()
264279

265-
# List of operators to simplify the code
280+
###############################################################################
281+
# - As we will use the workflow for different results operators we group them and
282+
# use a loop through the group. Here we prepare where the workflow outputs will be stored
283+
284+
# List of operators to be used in the workflow
266285
beam_stresses = [plate_beam_axial_stress, plate_beam_rs_shear_stress, plate_beam_tr_shear_stress]
267286
graph_labels = [
268287
"Beam axial stress",
269288
"Beam rs shear stress",
270289
"Beam tr shear stress",
271290
]
272-
# List of elements ids
291+
292+
# List of elements ids that we will get from the workflow
273293
max_stress_elements_ids = []
294+
274295
# Scopings container
275296
max_stress_elements_scopings = dpf.ScopingsContainer()
276297
max_stress_elements_scopings.add_label("stress_result")
277298

278-
# Loop through each stress result that gets the elements with maximum solicitation id, re-escope the fields
279-
# container to keep only the data for this element, and finally plot a stress x time graph
299+
###############################################################################
300+
# - The following loop:
301+
# a) Goes through each stress result and get the element id with maximum solicitation
302+
# b) Re-escope the fields container to keep only the data for this element
303+
# c) Plot a stress x time graph
280304

281305
for j in range(0, len(beam_stresses)): # Loop through each stress result
282306
# Use the pre-defined workflow to define the element with maximum solicitation
@@ -309,6 +333,7 @@
309333
label=f"{graph_labels[j]}, element id:{max_stress_elements_ids[j][0]}",
310334
)
311335

336+
# Graph formatting
312337
plt.title("Beam stresses evolution")
313338
plt.xlabel("Time (s)")
314339
plt.ylabel("Beam stresses (MPa)")
@@ -318,17 +343,17 @@
318343
###############################################################################
319344
# Results coordinates system
320345
# ~~~~~~~~~~~~~~~~~~~~~~~~~~
321-
322-
# The results are given in the Cartesian coordinates system by default.
323-
324-
# The beam results are given directly in the local directions. For example the beam stresses:
325-
326-
# We have the axial stress, given in the beam axis, and the stresses defined in the
327-
# cross-section directions, tr stress in the transverse direction (t) and rs stress
328-
# perpendicular to the tr direction (s).
329-
330-
# Those results are given as scalars.
331-
346+
#
347+
# The general results are given in the Cartesian coordinates system by default.
348+
#
349+
# The beam results are given directly in the local directions as scalars.
350+
# For example the beam stresses we have:
351+
#
352+
# - The axial stress, given in the beam axis
353+
# - The stresses defined in the cross-section directions: tr stress in the transverse
354+
# direction (t) and rs stress perpendicular to the tr direction (s).
355+
#
356+
#
332357
# Unfortunately there are no operators for LS-DYNA files that directly allows you to:
333358
# - Rotate results from local coordinate system to global coordinate system;
334359
# - Extract the rotation matrix between the local and global coordinate systems;

0 commit comments

Comments
 (0)