Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Fast Python ODB Access in Abaqus

Status
Not open for further replies.

bigmanrunning

Mechanical
Mar 22, 2011
10
Hi Guys,

I have a number of SDV values that I integrate over the volume of a specimen for each time increment. The simulations I'm running can have a few hundred time increments and the arrays for each SDV value has about 0.5 million elements. I utilize numPy for all calculations, which is fast, but most of the script time is taken up reading values from odb to numpy arrays. Slice array transfers aren't supported for odb access, so I am curious if anyone has found an efficient method of reading large amounts of data from odb to arrays?

The way I read from odb currently is:

for i in range(1,frameLen,strid):
# Set the current frame and time values #
currentFrame = odb.steps[step1.name].frames

PMicroValues = currentFrame.fieldOutputs['SDV506'].values

# Initialize in the first step #
if i == 1:
length = len(currentFrame.fieldOutputs['SDV506'].values)
PMicroData = np.empty(length)

for j in range(0,length):
PMicroData[j] = PMicroValues[j].data
 
Replies continue below

Recommended for you

I should have posted the code as a block.

Code:
for i in range(1,frameLen,strid):
   # Set the current frame and time values #
    currentFrame = odb.steps[step1.name].frames[i]

   PMicroValues = currentFrame.fieldOutputs['SDV506'].values

   # Initialize in the first step #
   if i == 1:
       length = len(currentFrame.fieldOutputs['SDV506'].values)
       PMicroData = np.empty(length)

   for j in range(0,length):
       PMicroData[j] = PMicroValues[j].data
 
I've been stuck in the same boat lately with reading values from ODB's, and I don't think there's a faster way to actually read the values with Python. You could get a slight improvement by creating a "frame repository" prior to the first loop, i.e.:


Code:
frameRep = odb.steps[step1.name].frames
for i in range(1,frameLen,strid):
   # Set the current frame and time values #
    currentFrame = frameRep[i]
   ...

but that's obviously not what's dominating the script speed. Two suggestions come to mind on how to improve the process:

1) Switch to C++. I know it's faster, but I don't know by how much, and have yet to experiment with it to compare the improvements.

2) Since you're reading from a bunch of separate frames, it's pretty easy to "parallelize" the script by calling multiple instances of Abaqus from the command line. Have each script handle a subset of frame intervals, write to separate databases or files, and then load the data separately in your computation script - file I/O time should be fractions of a second, compared to minutes/hours spent reading the .odb. I don't know what the practical upper limit is on having multiple Abaqus kernels running, but I'm sure you could get at least 3 or 4 going without an issue.
 
Hello everyone!

I badly want your help!
I am required to extract the fieldOutput(Acoustic Pressure) for only 2 nodes(Eg, NodeLabel=32078 and NodeLabel=33789), which I am struggling to achieve. I have the Python script which extracts the Acoustic Pressure for all the nodes and it is working fine, but I need only 2 nodes with the Acoustic Pressure value and not all nodes!
The script for extracting Acoustic pressure for all nodes is :

from odbAccess import *
from abaqusConstants import *
import part

jobname = 'working-copy'
stepname = 'Acoustic Pressure'
resultfile_name = 'Pressure' # file to be written in


odb_file = jobname + '.odb'
inp_file = jobname + '.inp'

odb = openOdb(odb_file,readOnly=True)
number_freq = len(odb.steps[stepname].frames)
assembly = odb.rootAssembly


for i in xrange(number_freq): # for all frequencies calculated in step
f=odb.steps[stepname].frames.frequency
if f>0:
result_file = resultfile_name + '_' + str(f) + '.txt'
file_results = open(result_file,'w+')
number_nodes=len(odb.steps[stepname].frames.fieldOutputs['POR'].values)
data_i=odb.steps[stepname].frames.fieldOutputs['POR']
for ii in xrange(number_nodes): # for all nodes in model (nodes of different parts together in one list)
part=data_i.values[ii].instance.name
nodeID=data_i.values[ii].nodeLabel
u=data_i.values[ii].data
ui=data_i.values[ii].conjugateData
file_results.write('%10i %13E %13E\n' % (nodeID,u,ui))

# close file where it was written in
file_results.close()

# ***************************************************************************************************************************

Can you please help me to modify this script such that it extracts Acoustic Pressure for 2 specific nodes!

Thanks In Advance!!


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor