Abaqus 可视化密度

Abaqus visualize density

我正在尝试优化某个 material 的孔隙率分布。我想可视化结果。我可以使用 'visualize->material' 可视化不同的 material,但是他给每个 material 随机颜色。我希望密度最小的 material 是蓝色,密度最大的是红色。因此与应力图相同。

有没有办法在 Abaqus 中做到这一点?

如果在 GUI 中没有简单的方法可以做到这一点,我想知道是否可以通过使用脚本来实现?我尝试更改一种颜色,结果出现以下代码:

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

这可能不是完美的方法,但它确实有效。 限制:

-您需要手动输入material的数量。

-你的material应该按照密度排序(mat1,mat2->density1

-您应该在脚本中输入您的 material 名称(在我的例子中是 'Implant')

随时欢迎提出改进建议,这既快速又肮脏。

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)

如果您正在寻找压力图可视化之类的东西,则必须编写自己的 FieldOutput 数据。将数据直接输出到外部可视化工具通常更容易,但在 Abaqus 中也可以(如果不是有点复杂的话)执行此操作。

大致流程是这样的:

  1. 生成一个FieldOutput对象;语法是 FO = odbModel.steps.values()[-1].frames[-1].FieldOutput(name=data_name, description=data_description, type=SCALAR),其中

    • odbModel是一个打开的Odb对象,
    • steps.values()[-1] 或命名步骤 steps[...] 是您要输出到的步骤,
    • frames[-1]是这一步要输出到的最后一帧(或者你选择的一帧),
    • data_namedata_description 是字符串(对于应力等值线图,data_name 相当于 odb 输出中的标签 S
    • SCALAR 是来自 abaqusConstants 模块的参数
  2. 获取 rootAssembly.instance 对象及其关联元素 elementSets 和 sectionAssignments,它们与带有 section 的明确链接=29=] 具有 density 属性。

  3. 使用addData命令更新FieldOutput对象;语法是 addData(position=CENTROID, instance=instance, labels=labels, data=data)
    • CENTROID 是来自 abaqusConstants 模块的参数(假设您只想在元素质心处拥有元素密度;如果您真的想要,也可以将它们粘贴在积分点上)
    • instance 是与元素集关联的实例(或者更一般地,region 分配给这个 material)
    • labels 是整数的可迭代(listtuple),指定要在
    • 写入数据的关联实例的元素标签
    • datafloat 的可迭代对象的可迭代对象,指定数据。在您的情况下,单个密度值意味着 data 是长度为 1 的可迭代对象的可迭代对象,每个包含一个密度值。 data 的长度必须等于 labels 的长度,因为 data 的每个成员都与 labels 中相同位置的 elementLabel 完全对应。

下面的示例脚本(警告:强烈建议备份 .odb 以防出现问题)

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.

我不使用密度,但这是一个模型的杨氏模量输出示例,其中两个 material 分配给各种元素。