Abaqus visualize density

浪子不回头ぞ 提交于 2019-12-08 00:51:50

问题


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()

回答1:


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.




回答2:


It's probably not the perfect method but this works. Limitations:

-You need to manually put in the amount of materials.

-Your materials should be ranked according to density(mat1,mat2->density1

-You should put your material name in the script (in my case it was 'Implant')

Suggestions for improvement are always welcome, this was just quick and dirty.

from math import floor

diminishing_factor = 10 #This factor diminishes the amount of colors to: 
amount of materials/diminishing factor. This is necessary
#because apparently abaqus can only handle a limited amount of colors (+-50)

def create_color_lst(amount_of_mat):

    color_lst=[]

    total_length = 256*4-1 #0 telt ook dus -1
    interval = floor(total_length/(amount_of_mat-1)) #*10 because we'll give 
    10 consequent materials the same color, because abaqus can't handle it
    for i in range(0,amount_of_mat):
        pos = int(floor(i/diminishing_factor))*diminishing_factor*interval
        if pos<256: #Green is rising
            col_pos=pos
            code = (0,col_pos,255)
        elif pos<512: #Blue is diminishing
            col_pos=pos-255
            code = (0,255,255-col_pos)
        elif pos<768:
            col_pos = pos - 511
            code = (col_pos,255,0)
        elif pos<1024:
            col_pos = pos - 767
            code = (255,255-col_pos,0)
        else:
            raise ValueError('Color position is too high: '+str(pos))
        hex_code='#%02x%02x%02x' % code
        color_lst.append(hex_code.upper())
    return color_lst

def update_colors(color_lst):
    session.viewports['Viewport: 1'].enableMultipleColors()
    session.viewports['Viewport: 1'].setColor(initialColor='#BDBDBD')
    cmap = session.viewports['Viewport: 1'].colorMappings['Material']
    for i in range(0,amount_of_mat):
        material = 'IMPLANT_MATERIAL'+str(i)
        cmap.updateOverrides(overrides={material:(True, color_lst[i],
            'Default', color_lst[i])})
        if i%10==0:
            print(i)
    session.viewports['Viewport: 1'].setColor(colorMapping=cmap)
    session.viewports['Viewport: 1'].disableMultipleColors()


amount_of_mat=494 #We can't get this you should always check this! (you 
probably could but I'm to lazy to search it)


color_lst = create_color_lst(amount_of_mat) #Creates a list with strings 
that contain the color names

update_colors(color_lst) #Updates the display (it's possible that you still 
need to go to the display color dialog and press apply)


来源:https://stackoverflow.com/questions/49509158/abaqus-visualize-density

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!