Stress-strain data from ABAQUS simulations using Python

Reading time ~5 minutes

The post describes a Python script for obtaining stress–strain data from ABAQUS simulations with representative volume elements of heterogeneous microstructures.

Intro

There are cases when you may not want to use ABAQUS/CAE to get stress–strain curves from your output database containing the finite element (FE) simulation results, such as

  1. The model is too big for ABAQUS/CAE to handle averaging over elements
  2. You are tired of clicking on ABAQUS/CAE menu over and over again after each simulation run
  3. You have many files to post-process

ABAQUS offers powerful scripting interface, which is a perfect solution for such cases.

Background

The scripts described here were written specifically for finite element (FE) simulations of deformation of representative volume elements (RVE) of polycrystalline or multiphase microstructures, where one usually has a single part deformed through velocities or displacements applied on control nodes. Nevertheless, it is hoped that the scripts will be also useful for a more general class of FE simulations.

With the deformation of an RVE in mind, the stress–strain data can be obtained by averaging components of the stress and strain tensors over all integration points in each element (in the case of full integration) and then over all elements in the model (or in a region of the model specified in an Element Set), i.e.

for stress tensor and

for strain tensor.

Here is the number of integration points in the model (or region of the model), and are the stress and strain tensor components at an integration point . Note that these equations assume that all elements are of identical size, otherwise it is necessary to introduce weights into the equations.

Now as we have averaged components of the tensors, we can get equivalent stress and strain as follows:

for stress and

for strain.

Implementation in Python

The calculation described above is implemented in a Python function called odb2ss available on GitHub here. To get the equivalent stress and strain for all time frames available in your odb, call of the function will look like this:

eqStress, eqStrain = odb2ss(fname,instanceName,setName)

where fname is the file name of the output database (without extension, e.g. ‘test’), instanceName is the Instance name of your part of interest (e.g. ‘PART-1-1’), and setName is the name of the Element Set that contains the region for which calculations shall be done.

As a result of this function call, you will have equivalent stress and strain stored in variables eqStress and eqStrain. You can plot them immediately in Python if you have matplotlib module installed or just save the data to a text file and plot it using your favorite software. To save the data to a text file, add the following line to the script.

np.savetxt(txtFileName, zip(eqStrain,eqStress))

Batch post-processing

If you have a bunch of output databases (i.e. odb files) for which you want to get stress–strain data, copy the aba-ss.py file to the folder containing your odb files and add a snippet that finds all the odb files and calls odb2ss function in a for-loop over all odb files.

import glob

# Find odb files
files2search = '*.odb'
odbFiles = glob.glob(files2search)
odbFiles.sort()

# Start a loop over odb files
for i,f in enumerate(odbFiles):

# Get file name without extension
fname = os.path.splitext(f)[0]

# Get equivalent stress, strain from odb
eqStress, eqStrain = odb2ss(fname)

# Save results to npy
np.savetxt(fname + '.out', zip(eqStrain,eqStress))

Some caveats and features

Here are a couple of useful things to know about odb2ss function.

Stress and strain measures

In this implementation, equivalent stresses and strains are calculated from stress and strain tensors stored in ABAQUS output field variables S and LE (logarithmic strain). If you are happy with this choice, you need to request field output for these variables with a desired frequency before running the FE simulation.

Here is a portion of the input file responsible for field output and example of the element output request containing LE and S variables.

** FIELD OUTPUT: STR-STR
**
*Output, field, time interval=1.0
*Node Output
U,
*Element Output, directions=YES
EE, ER, LE, PE, PEEQ, S

To calculate equivalent strain from any other strain tensor, replace LE with the desired variable in the following line in odb2ss function:

# Get strain
varName = 'LE' # put your favorite strain tensor here
tensor = getSymTensorData(varName, myFrame, myInstance, mySet, numElements)
strain = getFullTensorData(tensor)

Similarly, you can access any other tensor or scalar field data from the odb for purposes other than getting the stress–strain curve. For scalars, there is a function getScalarData in the same Python file, which will return a scalar quantity averaged over all elements in the requested element set.

Run-time messages

The script writes some runtime messages to a file odb_aba-ss.txt created in the folder where aba-ss.py was run. In this file, you can see some useful information, such as, for which Step and Instance the calculations are carried out as well as how many time frames are available in your odb.

Here is an example of run-time messages if the script has completed with no errors

odb was successfully opened at test.odb
Working with step Deformation and instance PART-1-1
Number of frames: 3
Current time frame:  0.0000
Current time frame:  1.0000
Current time frame:  2.0000
Done with test, spent 6.86 min

The script will also try to catch the most frequent errors – Instance and Element Set specified do not exist in the odb. If these errors happen, the script will say so in this text file and will tell you the right names of the Instances and Sets available in the odb.

Default values for instance and set

The function is defined with ‘ALLELEMENTS’ as a default name of the Element Set name for which calculation is performed. Also, the first Instance available in the odb is chosen as default. For example, if I have an odb with a single Instance PART-1-1, the following two calls of the function will yield exactly the same results

eqStress, eqStrain = odb2ss(fname,'PART-1-1','ALLELEMENTS')
eqStress, eqStrain = odb2ss(fname)

I have the first Instance and ‘ALLELEMENTS’ Set as default simply because, in most cases, I have a single part and thus a single Instance (my RVE) and ‘ALLELELEMENTS’ is the Element Set that for which I want to do the calculation most frequently (i.e. over the whole RVE). You can easily change them to your favorite Instance and Element Set names in the following lines of the code.

# The first instance is default if None provided
if instanceName == None:
instanceName = myOdb.rootAssembly.instances.keys()[0] # put your favorite instance here

# 'AllElements' set is default if None provided
if mySetName == None:
mySetName = 'ALLELEMENTS' # put your favorite element set here

P.S. Running Python scripts in ABAQUS

If you are not sure how to run the scripts described above, here is a tip. There are two options in running Python scripts in ABAQUS environment.

  1. From ABAQUS command line:
    abaqus viewer noGUI=script.py
    
  2. From ABAQUS/CAE: Go to File -> Run Script… and navigate to the script you need, e.g. aba-ss.py.

Final note: aba-ss.py may not work in old versions of ABAQUS that do not have numpy module in their Python distribtutions.

EBSD data analytics for quantification of UFG microstructures

Slides presented at EMI-2016 conference (Metz, France), October 2016. Continue reading

ABAQUS mesh from EBSD using MTEX

Published on July 12, 2016

Research Overview

Published on July 01, 2016