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 中也可以(如果不是有点复杂的话)执行此操作。
大致流程是这样的:
生成一个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_name
和 data_description
是字符串(对于应力等值线图,data_name
相当于 odb 输出中的标签 S
)
SCALAR
是来自 abaqusConstants
模块的参数
获取 rootAssembly.instance
对象及其关联元素 elementSet
s 和 sectionAssignment
s,它们与带有 section
的明确链接=29=] 具有 density
属性。
- 使用
addData
命令更新FieldOutput
对象;语法是 addData(position=CENTROID, instance=instance, labels=labels, data=data)
CENTROID
是来自 abaqusConstants
模块的参数(假设您只想在元素质心处拥有元素密度;如果您真的想要,也可以将它们粘贴在积分点上)
instance
是与元素集关联的实例(或者更一般地,region
分配给这个 material)
labels
是整数的可迭代(list
、tuple
),指定要在 写入数据的关联实例的元素标签
data
是 float
的可迭代对象的可迭代对象,指定数据。在您的情况下,单个密度值意味着 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 分配给各种元素。
我正在尝试优化某个 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 中也可以(如果不是有点复杂的话)执行此操作。
大致流程是这样的:
生成一个
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_name
和data_description
是字符串(对于应力等值线图,data_name
相当于 odb 输出中的标签S
)SCALAR
是来自abaqusConstants
模块的参数
获取
rootAssembly.instance
对象及其关联元素elementSet
s 和sectionAssignment
s,它们与带有section
的明确链接=29=] 具有density
属性。- 使用
addData
命令更新FieldOutput
对象;语法是addData(position=CENTROID, instance=instance, labels=labels, data=data)
CENTROID
是来自abaqusConstants
模块的参数(假设您只想在元素质心处拥有元素密度;如果您真的想要,也可以将它们粘贴在积分点上)instance
是与元素集关联的实例(或者更一般地,region
分配给这个 material)labels
是整数的可迭代(list
、tuple
),指定要在 写入数据的关联实例的元素标签
data
是float
的可迭代对象的可迭代对象,指定数据。在您的情况下,单个密度值意味着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 分配给各种元素。