Search code examples
pythonabaqus

Abaqus visualize density


I'm trying to optimize the porosity distribution of a certain material. I would like to visualize the results. I can visualize the different materials using 'visualize->material' however he gives every material a random color. I would like the least dense materials to be blue and the densest to be red. So the same as for the stress plots.

Is there a way to do this in Abaqus?

If there's no simple way to do this in the GUI, I was wondering would it be possible by using scripting? I tried to change a single color which resulted in the following code:

session.viewports['Viewport: 1'].enableMultipleColors()
session.viewports['Viewport: 1'].setColor(initialColor='#BDBDBD')
cmap=session.viewports['Viewport: 1'].colorMappings['Material']
session.viewports['Viewport: 1'].setColor(colorMapping=cmap)
session.viewports['Viewport: 1'].disableMultipleColors()
session.viewports['Viewport: 1'].enableMultipleColors()
session.viewports['Viewport: 1'].setColor(initialColor='#BDBDBD')
cmap = session.viewports['Viewport: 1'].colorMappings['Material']
cmap.updateOverrides(overrides={'IMPLANT_MATERIAL0':(True, '#FF0000', 
    'Default', '#FF0000')})
session.viewports['Viewport: 1'].setColor(colorMapping=cmap)
session.viewports['Viewport: 1'].disableMultipleColors()
session.viewports['Viewport: 1'].enableMultipleColors()
session.viewports['Viewport: 1'].setColor(initialColor='#BDBDBD')
cmap = session.viewports['Viewport: 1'].colorMappings['Material']
session.viewports['Viewport: 1'].setColor(colorMapping=cmap)
session.viewports['Viewport: 1'].disableMultipleColors()

Solution

  • If you're looking for something like stress plot visualisation, you'll have to write your own FieldOutput data. It's generally easier to output the data directly to an external visualiser, but it's possible (if not a bit convoluted) to do this in Abaqus.

    The general process is this:

    1. Generate a FieldOutput object; syntax is FO = odbModel.steps.values()[-1].frames[-1].FieldOutput(name=data_name, description=data_description, type=SCALAR), where

      • odbModel is an opened Odb object,
      • steps.values()[-1] or a named step steps[...] is the step you want to output to,
      • frames[-1] is the last frame (or a frame of your choice) that you want to output to in this step,
      • data_name and data_description are strings (for stress contour plots, data_name would be equivalent to the label S in the odb output)
      • SCALAR is a parameter from the abaqusConstants module
    2. Get the rootAssembly.instance objects, and their associated element elementSets and sectionAssignments which have clear links to a section with a material which has a density attribute.

    3. Update the FieldOutput object with the addData command; syntax is addData(position=CENTROID, instance=instance, labels=labels, data=data)
      • CENTROID is a parameter from the abaqusConstants module (assuming you just want to have element densities at the element centroid; you can stick them at integration points too, if you really wanted)
      • instance is the instance associated with the element set (or more generally the region assigned with this material)
      • labels is an iterable (list, tuple) of integers specifying the element labels of the associated instance for which the data is to be written at
      • data is an iterable of iterables of floats, specifying the data. In your case, a single density value means that data is an iterable of length-1 iterables, each containing one value of density. The length of data must be equal to the length of labels, as each member of data exactly corresponds to the elementLabel in the same position in labels.

    Example script below (WARNING: Heavily recommend backing up the .odb in case something didn't turn out right)

    import odbAccess
    from abaqusConstants import SCALAR, CENTROID # Import constants
    
    odbModel = odbAccess.openOdb(odb_file_path) # Put the file path of the `odb` in odb_file_path
    
    FO = odbModel.steps.values()[-1].frames[-1].FieldOutput(name='Density', description='', type=SCALAR)
    
    # Loop through `rootAssembly.instances`
    for instance in odbModel.rootAssembly.instances.values():
    
        valid_materials = [] # Valid material names which have `density`
    
        # Loop through `instance.sectionAssignments` to check if the associated `section` has a `material` with the attribute `density`
        for i in range(len(instance.sectionAssignments)):
            sectionName = instance.sectionAssignments[i].sectionName
            matName = odbModel.sections[sectionName].material
            if hasattr(odbModel.materials[matName], 'density'):
                valid_materials.append(matName)
    
        sectionNames = [] # Build list of valid section names which are associated with a material which has the attribute `density`
    
        for s in odbModel.sections.values():
            if s.material in valid_materials:
                sectionNames.append(s.name)
    
        if sectionNames:
    
            # Loop through `sectionAssignments` and get all the `elementLabels` in the `region` of the `sectionAssignment`
            for sa in instance.sectionAssignments:
                sa_labels = []
                if sa.sectionName in sectionNames:
    
                    # Get labels
                    if sa.region.elements is not None:
                        for e in sa.region.elements:
                            sa_labels.append(e.label)
    
                    # Get material
                    matName = odbModel.sections[sa.sectionName].material
                    sa_data = [(odbModel.materials[matName].density.table[0][0],)]*len(sa_labels)
    
                    # Update `fieldOutput` object
                    FO.addData(position=CENTROID, instance=instance, labels=sa_labels, data=sa_data)
    
    # Save odb model. The FieldOutput object only exists as reference from `FO` unless the odb model is saved.
    odbModel.save()
    odbModel.close()
    odbModel = odbAccess.openOdb(odb_file_path) # Reopen the model for visualisation. If you can't find the data_name in the list, expand the model to the step and frame for which the data is saved.
    

    I don't work with density, but here's an example output for Young's modulus for a model with two materials assigned to various elements.

    enter image description here