“ 这篇文章主要探讨odb结果文件位移值和应力值的存储方式。”
01
—
链接odb文件
可以使用ABAQUS提供的odbAccess内部的openOdb, 打开指定目录的odb文件, 如:
from odbAccess import openOdbfile = 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名称获取对应的stepstep = 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.fieldOutputsfrom textRepr import prettyPrintprettyPrint(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.06194400787354vtest.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部分的正文内容从这里开始。