I'm new in contributing to this forum, but is has helped me tremendously in the past with all the questions and answers that are already on here. Unfortunately I was not able to find an answer to what feels to be a very 'basic' question, hopefully someone is able to help me. Currently I have a python script for Abaqus, where part of that script will find the maximum stress in a propeller blade. To do this I loop trough all the elements with multiple composite-plies in the elements. This works, but it takes too long for large models with multiple load cases. Does anyone know a smarter/faster way of doing the same? Or, to ask in a different way, is there a way to do the same without multiple looping through all elements in the model? My original/current code:
for key in Steps:
S=odb1.steps[key].frames[-1].fieldOutputs['S']
S11=S.getScalarField(componentLabel="S11").getSubset(region=blade, position=CENTROID).values
for v in S11:
S_11_Static = v.data
if S_11_Static > S_11_Max_static[key]:
S_11_Max_static[key] = S_11_Static
if S_11_Static < S_11_Min_static[key]:
S_11_Min_static[key] = S_11_Static
logging.info(key+' min values is'+str(S_11_Min_static[key]))
logging.info(key+' max values is'+str(S_11_Max_static[key]))
for x in range (1, numberOfFrequencies+1):
S=odb1.steps['EigenFrequency_'+key].frames[x].fieldOutputs['S']
S11=S.getScalarField(componentLabel="S11").getSubset(region=blade, position=CENTROID).values
for v in S11:
S_11_Static = v.data
if S_11_Static > S_11_Max_Freq[key]['freq_'+str(x)]:
S_11_Max_Freq[key]['freq_'+str(x)] = S_11_Static
if S_11_Static < S_11_Min_Freq[key]['freq_'+str(x)]:
S_11_Min_Freq[key]['freq_'+str(x)] = S_11_Static
logging.info(key+' min/max values are extracted, including EigenFrequencies')
logging.info('All min/max values are extracted')
thank you in advance, Tim
What I have tried: I tried googling. I have tried to incorporate the get-max-value-loop in a loop that I have to run through anyway, but since I need the max values a priori, this didn't work, because the backward correction when updating max values was not robust enough.
You can simply make use of bulkDataBlocks
. It is an array representation of the data. As it is an array, all the information related to the data, i.e. data, node/element labels, and so on, you will get in the form of an array. Then, you can simply use function from numpy
to manipulate this data.
For ex:
# Access the field output
stress = odb1.steps[key].frames[-1].fieldOutputs['S']
s11 = stress.getScalarField(componentLabel="S11").getSubset(region=blade, position=CENTROID)
# Use bulkDataBlocks
s11_array = s11.bulkDataBlocks[0].data
# Manipulate the data using NumPy
import numpy
numpy.max(s11_array) # --> max value
numpy.argmax(s11_array) # --> max value index
# Similarly you can access element/node labels
s11_el_labels = s11.bulkDataBlocks[0].elementLabels
One more important thing about bulkDataBlocks
objects:
All elements in a class correspond to the same element type and material.
Meaning:
If, for example, s11
field object calculated above has data for multiple materials or element type, then each data will be stored separately as an element in the bulkDataBlocks
object.
To access the data, you just need to loop it:
all_data = []
for ib in range(len(s11.bulkDataBlocks)):
all_data += list(s11.bulkDataBlocks[ib].data)
all_data = numpy.array(all_data)
One last thing, this functionality may not be available in the older Abaqus version, for ex. 6.12 or 2012 version.