“ 这篇文章主要探讨odb结果文件位移值和应力值的存储方式。”
01
—
链接odb文件
可以使用ABAQUS提供的odbAccess内部的openOdb, 打开指定目录的odb文件, 如:
from odbAccess import openOdb
file = r"W:\CAE Project\2021\2021-04-06-G2021houqiao\Job-G202-versus.odb"
o = openOdb(path = file)
将openOdb的返回值赋予变量o, 该变量(或者说对象)存储了odb内所有的数据, 一切后处理的二次开发均是针对该对象的操作.
02
—
场变量的存储
以通用隐式分析步为例, 位移值与应力值均属于场变量, 每一个step的每一个increment都输出属于自己的场变量结果, 而increment在odb中对应的是frames:
steps = o.steps
#根据step名称获取对应的step
step = steps["Step-6p0"]
#假设我们只关心该step最后一个增量步的结果
f1 = step.frames[-1]
#使用这个方法查看对象内部属性
f1.__members__
['associatedFrame', 'cyclicModeNumber', 'description',
'domain', 'fieldOutputs', 'frameId', 'frameValue',
'frequency', 'incrementNumber', 'isImaginary',
'loadCase', 'mode']
从上面的输出结果可以看出, 在对象f1内存在我们想要提取的目标数据存储的位置fieldOutputs, 我们来获取这个属性, 并使用prettyPrint进行预览:
fop = f1.fieldOutputs
from textRepr import prettyPrint
prettyPrint(fop)
"""
{'AC YIELD': 'FieldOutput object',
'CF': 'FieldOutput object',
'CM': 'FieldOutput object',
'COPEN ASSEMBLY_SURF-GROUND-SLAVE-1/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'COPEN ASSEMBLY_SURF-GROUND-SLAVE-2/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'COPEN ASSEMBLY_SURF-LOAD-SLAVE-1/ASSEMBLY_SURF-LOAD-MASTER-1': 'FieldOutput object',
'COPEN ASSEMBLY_SURF-LOAD-SLAVE-2/ASSEMBLY_SURF-LOAD-MASTER-2': 'FieldOutput object',
'CPRESS ASSEMBLY_SURF-GROUND-SLAVE-1/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CPRESS ASSEMBLY_SURF-GROUND-SLAVE-2/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CPRESS ASSEMBLY_SURF-LOAD-SLAVE-1/ASSEMBLY_SURF-LOAD-MASTER-1': 'FieldOutput object',
'CPRESS ASSEMBLY_SURF-LOAD-SLAVE-2/ASSEMBLY_SURF-LOAD-MASTER-2': 'FieldOutput object',
'CSHEAR1 ASSEMBLY_SURF-GROUND-SLAVE-1/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSHEAR1 ASSEMBLY_SURF-GROUND-SLAVE-2/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSHEAR1 ASSEMBLY_SURF-LOAD-SLAVE-1/ASSEMBLY_SURF-LOAD-MASTER-1': 'FieldOutput object',
'CSHEAR1 ASSEMBLY_SURF-LOAD-SLAVE-2/ASSEMBLY_SURF-LOAD-MASTER-2': 'FieldOutput object',
'CSHEAR2 ASSEMBLY_SURF-GROUND-SLAVE-1/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSHEAR2 ASSEMBLY_SURF-GROUND-SLAVE-2/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSHEAR2 ASSEMBLY_SURF-LOAD-SLAVE-1/ASSEMBLY_SURF-LOAD-MASTER-1': 'FieldOutput object',
'CSHEAR2 ASSEMBLY_SURF-LOAD-SLAVE-2/ASSEMBLY_SURF-LOAD-MASTER-2': 'FieldOutput object',
'CSLIP1 ASSEMBLY_SURF-GROUND-SLAVE-1/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSLIP1 ASSEMBLY_SURF-GROUND-SLAVE-2/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSLIP1 ASSEMBLY_SURF-LOAD-SLAVE-1/ASSEMBLY_SURF-LOAD-MASTER-1': 'FieldOutput object',
'CSLIP1 ASSEMBLY_SURF-LOAD-SLAVE-2/ASSEMBLY_SURF-LOAD-MASTER-2': 'FieldOutput object',
'CSLIP2 ASSEMBLY_SURF-GROUND-SLAVE-1/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSLIP2 ASSEMBLY_SURF-GROUND-SLAVE-2/ASSEMBLY_SURF-GROUND-MASTER': 'FieldOutput object',
'CSLIP2 ASSEMBLY_SURF-LOAD-SLAVE-1/ASSEMBLY_SURF-LOAD-MASTER-1': 'FieldOutput object',
'CSLIP2 ASSEMBLY_SURF-LOAD-SLAVE-2/ASSEMBLY_SURF-LOAD-MASTER-2': 'FieldOutput object',
'LE': 'FieldOutput object',
'PE': 'FieldOutput object',
'PEEQ': 'FieldOutput object',
'PEMAG': 'FieldOutput object',
'RF': 'FieldOutput object',
'RM': 'FieldOutput object',
'S': 'FieldOutput object',
'U': 'FieldOutput object',
'UR': 'FieldOutput object'}
"""
可以看出所有的输出场变量均在其中
03
—
位移值
在有限元理论中, 仿真计算结果的位移值是存储在节点内的, ABAQUS也不例外, 其位移结果是按节点存放的. 我们获取位移结果:
fopU = fop['U']
prettyPrint(fopU)
"""
({'baseElementTypes': 'tuple object',
'bulkDataBlocks': 'Sequence object',
'componentLabels': 'tuple object',
'description': 'Spatial displacement',
'isComplex': OFF,
'locations': 'FieldLocationArray object',
'name': 'U',
'type': VECTOR,
'validInvariants': 'tuple object',
'values': 'FieldValueArray object'})
"""
可以观察到此次的打印类型与上一次并不一致, prettyPrint(fop)打印结果是{}, 而prettyPrint(fopU)打印结果是({}), 我们查看他们各自的类型可以知道:
fop为Repository类型, 可以通过键值获取
fopU为FieldOutput类型, 可以通过属性获取
所以我们可以查看该帧一共有多少节点数据:
len(fopU.values)
# 如果这里不小心输出了fopU.values, 由于数据量太大, 可能导致ABAQUS卡死
到这里还没有最终完成位移值的探索, 因为我们还没有获取到位移值, 我们查看fopU.values的类型为FieldValueArray, 那么它就应该支持索引取值(其必然继承python的array), 我们考察其第100个对象:
vtest = fopU.values[100]
prettyPrint(vtest)
"""
({'baseElementType': '',
'conjugateData': None,
'conjugateDataDouble': 'unknown',
'data': 'ndarray object',
'dataDouble': 'unknown',
'elementLabel': None,
'face': None,
'instance': 'OdbInstance object',
'integrationPoint': None,
'inv3': None,
'localCoordSystem': None,
'localCoordSystemDouble': 'unknown',
'magnitude': 7.98967,
'maxInPlanePrincipal': None,
'maxPrincipal': None,
'midPrincipal': None,
'minInPlanePrincipal': None,
'minPrincipal': None,
'mises': None,
'nodeLabel': 1,
'outOfPlanePrincipal': None,
'position': NODAL,
'precision': SINGLE_PRECISION,
'press': None,
'sectionPoint': None,
'tresca': None,
'type': VECTOR})
"""
经过对每个属性的研究可以得出, magnitude存放位移值, data存放全局坐标系下的各位移分量值:
vtest.magnitude
# 8.06194400787354
vtest.data
# array([0.0241295695304871, 0.487015426158905, 8.04718399047852], 'f')
04
—
应力值
ABAQUS的计算结果的应力值存放在积分点处, 而积分点是按照单元组织的, 所以可以间接的认为应力值存放于单元内部. 我们获取应力结果:
fopS = fop['S']
prettyPrint(fopS)
"""
({'baseElementTypes': 'tuple object',
'bulkDataBlocks': 'Sequence object',
'componentLabels': 'tuple object',
'description': 'Stress components',
'isComplex': OFF,
'locations': 'FieldLocationArray object',
'name': 'S',
'type': TENSOR_3D_PLANAR,
'validInvariants': 'tuple object',
'values': 'FieldValueArray object'})
"""
可以发现其类型与fopU一致均为FieldOutput, 然后我们采取与位移值相同的处理方法:
stest = fopS.values[100]
prettyPrint(stest)
"""
({'baseElementType': 'S3R',
'conjugateData': None,
'conjugateDataDouble': 'unknown',
'data': 'ndarray object',
'dataDouble': 'unknown',
'elementLabel': 101,
'face': None,
'instance': 'OdbInstance object',
'integrationPoint': 1,
'inv3': 91.7217,
'localCoordSystem': 'tuple object',
'localCoordSystemDouble': 'unknown',
'magnitude': None,
'maxInPlanePrincipal': 169.491,
'maxPrincipal': 169.491,
'midPrincipal': 72.7809,
'minInPlanePrincipal': 72.7809,
'minPrincipal': 0.0,
'mises': 147.271,
'nodeLabel': None,
'outOfPlanePrincipal': 0.0,
'position': INTEGRATION_POINT,
'precision': SINGLE_PRECISION,
'press': -80.7574,
'sectionPoint': 'SectionPoint object',
'tresca': 169.491,
'type': TENSOR_3D_PLANAR})
"""
其具体数据的获取方法也与位移值相同.
第5部分的正文内容从这里开始。