问题
I'm trying to get the element density from the abaqus output database. I know you can request a field output for the volume using 'EVOL', is something similar possible for the density?
I'm afraid it's not because of this: Getting element mass in Abaqus postprocessor
What would be the most efficient way to get the density? Look for every element in which section set it is?
回答1:
The properties are associated something like this:
sectionAssignment
connectssection
toset
set
is the container forelement
section
connectssectionAssignment
tomaterial
instance
is connected topart
(could be from a part from another model)part
is connected tomodel
model
is connected tosection
Use the .inp
or .cae
file if you can. The following gets it from an opened cae
file. To thoroughly get elements
from materials
, you would do something like the following, assuming you're starting your search in rootAssembly.instances
:
- Find the
parts
which theinstances
were created from. - Find the
models
which contain theseparts
. - Look for all
sections
withmaterial_name
in theseparts
, and store all thesectionNames
associated with this section - Look for all
sectionAssignments
which references thesesectionNames
- Under each of these
sectionAssignments
, there is an associatedregion
object which has the name (as a string) of anelementSet
and the name of apart
. Get all theelements
from thiselementSet
in thispart
.
Cleanup:
- Use the Python
set
object to remove any multiple references to the same element. - Multiply the number of elements in this set by the number of identical part instances that refer to this material in
rootAssembly
.
E.g., for some cae
model variable called model
:
model_part_repeats = {}
model_part_elemLabels = {}
for instance in model.rootAssembly.instances.values():
p = instance.part.name
m = instance.part.modelName
try:
model_part_repeats[(m, p)] += 1
continue
except KeyError:
model_part_repeats[(m, p)] = 1
# Get all sections in model
sectionNames = []
for s in mdb.models[m].sections.values():
if s.material == material_name: # material_name is already known
# This is a valid section - search for section assignments
# in part for this section, and then the associated set
sectionNames.append(s.name)
if sectionNames:
labels = []
for sa in mdb.models[m].parts[p].sectionAssignments:
if sa.sectionName in sectionNames:
eset = sa.region[0]
labels = labels + [e.label for e in mdb.models[m].parts[p].sets[eset].elements]
labels = list(set(labels))
model_part_elemLabels[(m,p)] = labels
else:
model_part_elemLabels[(m,p)] = []
num_elements_with_material = sum([model_part_repeats[k]*len(model_part_elemLabels[k]) for k in model_part_repeats])
Finally, grab the material density associated with material_name
then multiply it by num_elements_with_material
.
Of course, this method will be extremely slow for larger models, and it is more advisable to use string techniques on the .inp
file for faster performance.
回答2:
Found a solution, I don't know if it's the fastest but it works:
odb_file_path=r'your_path\file.odb'
odb = session.openOdb(name=odb_file_path)
instance = odb.rootAssembly.instances['MY_PART']
material_name = instance.elements[0].sectionCategory.name[8:-2]
density=odb.materials[material_name].density.table[0][0])
note: the 'name' attribute will give you a string like, 'solid MATERIALNAME'. So I just cut out the part of the string that gave me the real material name. So it's the sectionCategory attribute of an OdbElementObject that is the answer.
EDIT: This doesn't seem to work after all, it turns out that it gives all elements the same material name, being the name of the first material.
来源:https://stackoverflow.com/questions/49346825/getting-element-density-from-abaqus-output-database-using-python-scripting