GIF may be an ancient format but occasionally animating simulation results in GIF is effective. A typical way in Abaqus to generate an animation of simulation results in GIF would be to transform the AVI format animation, by default produced, to GIF using some transformation tools, such as EZGIF. This note explores an alternative workflow that exploits Abaqus Python scripting to save a time sequence of images from Abaqus and generate animation in GIF by a Python library imageio. The benefit of this workflow is some special effects can be implemented, besides the format transformation. For example, the workflow allows us to add and change annotations or change viewpoint and view angle in the animation. I hope this workflow can overcome some limitations of Abaqus’ default animate tool and give analysts a bit more freedom to better express their visualization intentions.
The basic idea of the workflow is to
- use Abaqus Python scripting to generate a time sequence of images of deformation, and
- generate the animation in GIF by the Python library imageio.
We need to first install imageio and its dependency.
Install imageio
- Install Python
- Imageio depends on NumPy and Pillow. So install them by pip:
python -m pip install --user numpy pip install pillow
- Install imageio by pip:
pip install imageio
Workflow
1. Saving a time sequence of images
Abaqus has the setFrame
method to display the result in a frame of a step of an ODB. Arguments to setFrame, frame
and step
, are of two integer indexes:
session.viewports['Viewport: 1'].odbDisplay.setFrame(step=s, frame=f)
Abaqus has the printToFile
method to save the image of a frame to a file. We choose to use PNG
as the image format:
session.printToFile(fileName=str(file), format=PNG, canvasObjects=(session.viewports['Viewport: 1'], ))
We take advantage of those two methods and loop over each frame of each step of an ODB, so that a time sequence of images of each frame of an ODB can be saved. Here is a typical code snippet, the file names of images are accumulative frame number:
from odbAccess import *
import visualization
from abaqusConstants import *
odb = openOdb('Job.odb', readOnly=True)
stepRepo = odb.steps
s = 0
file = 0
for stepKey in stepRepo.keys():
step = stepRepo[stepKey]
for f in range(len(step.frames)):
session.viewports['Viewport: 1'].odbDisplay.setFrame(step=s, frame=f)
session.printOptions.setValues(vpDecorations=OFF)
session.printToFile(fileName=str(file), format=PNG, canvasObjects=(session.viewports['Viewport: 1'], ))
file += 1
This code actually handles frames of every step if the model has multiple steps.
It should be noted the selection of field quantity for display is not included in the script, so before running, we should as usual choose the field quantity we would like to show in the animation and click ‘Plot the Contours on Deformed Shape’ button to let iteration of each frame take effect.
2. Generating GIF using imageio
To generate a GIF animation from a stack of images, we first read all image files, just produced, into a list images
; and then use mimwrite
method to generate the animation in GIF. mimwrite
has the float argument fps
to control the frame rate of animation. Here is a typical code snippet to read frame-number-named images and generate GIF:
import imageio
images = []
for i in range(28):
images.append(imageio.imread(str(i)+'.png'))
imageio.mimwrite('animation.gif', images, fps=10, subrectangles=True)
Examples
Annotation following movement of a node
The annotation tool in Abaqus uses canvas coordinates rather than model coordinates by default, hence, the annotation cannot change its location if we use the typical animate tool. But a use case of movable annotation is, in the case of animating an airbag deployment simulation, I wanted to annotate the center node with its label number during the course of deformation and make an animation. Since the default animate tool won’t do, I formed the above workflow and added few lines of code to annotate the center node at its location in each frame of the deformation. The produced animation is shown below. The source code can be found in this post.
Highlight closest node to a spatial location
When developing python scripts that extract Eulerian results, one of the methods requires finding the closest node to a spatial location. To visualize the method for the post, I wanted to highlight the different closest node as the mesh moves in the animation. This workflow was used and combined with the function developed to find and highlight the closest node to make the below animation.
360° view of results
The default animate tools in Abaqus can animate scale factor, time history, and harmonic results, but cannot animate the change of viewpoint and angle of view. Occasionally, changing viewpoint and view angle helps to show a comprehensive deformed shape and the mapped field quantity. The following animation was made with the above workflow to implement a 360° view of a deployed airbag. The source code can be found in this post.
Optimization
A typical size of the GIF animation produced by this workflow would be few megabytes. Here are few optimization tips to reduce the file size.
- Skipping some framesIf only for the purposes of communicating simulation results, we can safely skip some middle frames in making animation, without an obvious hurt in the graphic quality, especially when the simulation request enough frames of results. This would reduce the number of frames in the animation, hence, reduce the size of the GIF animation. We can tweak the loop
range(len(step.frames))
to something like thisfor f in range(0, len(step.frames), 2):
to skip the second frame of every two frames.
- Optimization on the produced GIFWe’ve used the
subrectangles
option in generating animation in imageio, to reduce file size. The online tool EZGIF also has some optimization algorithms to further reduce the size fo GIF file. By these means, we can usually reduce the animation GIF to less than 1 MB.
Pingback: Making Annotation Follow Node Movement in Abaqus | increments
Pingback: Scripting for 360° View of Results in Abaqus | increments
Pingback: Making Annotation Follow Node Movement in Abaqus - increments