Abaqus可视化密度

2024-10-01 02:24:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我想优化某种材料的孔隙率分布。我希望看到结果。我可以使用“visualize->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()

Tags: 颜色sessioncmapmaterial材料viewport材质setcolor
2条回答

如果你正在寻找类似压力图可视化的东西,你就得写你自己的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]是在这一步中要输出到的最后一帧(或您选择的帧)
    • ^{{cdb}中的{label}与
    • SCALARabaqusConstants模块的参数
  2. 获取rootAssembly.instance对象及其关联元素elementSets和sectionAssignment,它们与具有material属性的material有明确链接。

  3. addData命令更新FieldOutput对象;语法是addData(position=CENTROID, instance=instance, labels=labels, data=data)
    • CENTROIDabaqusConstants模块中的一个参数(假设你只想在元素质心处有元素密度;如果你真的想要的话,你也可以把它们粘在积分点上)
    • instance是与元素集相关联的实例(或者更广泛地说,是与此材质分配的region
    • labels是一个整数的iterable(listtuple),指定要在其中写入数据的关联实例的元素标签
    • datafloats的iterable的iterable,指定数据。在您的例子中,一个单一的密度值意味着data是一个长度为1个iterable的iterable,每个包含一个density值。data的长度必须等于labels的长度,因为{}的每个成员都与{}中相同位置的{}完全对应。在

下面的脚本示例(警告:强烈建议备份.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.

我不研究密度,但这里有一个例子,输出一个模型的杨氏模量,其中两种材质被指定给不同的元素。在

enter image description here

这可能不是一个完美的方法,但这是有效的。 限制:

-您需要手动放入材料量。在

-您的材料应根据密度进行排序(mat1,mat2->density1

-你应该在脚本中写上你的材料名称(在我的例子中是“植入物”)

对改进的建议总是受欢迎的,这是快速和肮脏的。在

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)

相关问题 更多 >