Search code examples
pythonabaqus

Getting element density from abaqus output database using python scripting


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?


Solution

  • The properties are associated something like this:

    • sectionAssignment connects section to set
    • set is the container for element
    • section connects sectionAssignment to material
    • instance is connected to part (could be from a part from another model)
    • part is connected to model
    • model is connected to section

    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:

    1. Find the parts which the instances were created from.
    2. Find the models which contain these parts.
    3. Look for all sections with material_name in these parts, and store all the sectionNames associated with this section
    4. Look for all sectionAssignments which references these sectionNames
    5. Under each of these sectionAssignments, there is an associated region object which has the name (as a string) of an elementSet and the name of a part. Get all the elements from this elementSet in this part.

    Cleanup:

    1. Use the Python set object to remove any multiple references to the same element.
    2. 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.