ABAQUS脚本计算微动遇OdiError数值溢出/下溢问题求助
Abaqus脚本计算微动时的OdiError问题解决
问题背景
作为Abaqus脚本新手,尝试利用COPEN、CSLIP1和CSLIP2场输出计算微动位移,编写了对应脚本,但执行后报错:OdiError: Expression evaluates to an overflow or underflow。
原脚本:
from abaqusConstants import * from odbAccess import * from odbMaterial import * from odbSection import * from math import * from copy import deepcopy from caeModules import * from driverUtils import executeOnCaeStartup from numpy import fabs as fabs import numpy as np from types import IntType odb = session.openOdb(name='E:\\PDP02.odb', readOnly=FALSE) odb = session.odbs['E:\\PDP02.odb'] print odb.rootAssembly.instances.keys() grout_instance = odb.rootAssembly.instances['PROX-1#PROXIMAL-1'] keys = odb.steps.keys() for key in keys: step = odb.steps[key] for frame in step.frames: print frame.description Copen = frame.fieldOutputs['COPEN'] Cslip1 = frame.fieldOutputs['CSLIP1'] Cslip2 = frame.fieldOutputs['CSLIP2'] Micromotion = sqrt(power(Copen,2)+power(Cslip1,2)+power(Cslip2,2)) #Micromotion =sqrt(power(Cslip2,2)) #float(Micromotion) frame.FieldOutput(name='Micromotion', description='Average Micromotion', field=Micromotion) odb.update() odb.save()
错误原因分析
- FieldOutput对象运算的局限性:Abaqus的
FieldOutput是批量场数据对象,直接用math模块的power、sqrt函数处理时,无法识别并跳过数据中的异常值(如NaN、无穷大),容易触发数值溢出/下溢。 - 未处理无效接触数据:部分单元或节点的接触场输出(COPEN、CSLIP1/2)可能因接触未生效存在无效值,直接参与平方和开方运算会引发数值异常。
- 函数适配问题:
math模块函数仅适合单个数值运算,不支持批量场数据的向量运算,强制处理会导致计算逻辑错误。
修正方案
- 提取场输出的数值数组,用NumPy进行向量运算,便于异常值处理;
- 添加异常值过滤逻辑,替换NaN、无穷大等无效值;
- 将计算结果重新封装为
FieldOutput对象后写入ODB文件。
修正后的脚本
from abaqusConstants import * from odbAccess import * import numpy as np # 打开ODB文件 odb_path = 'E:\\PDP02.odb' odb = session.openOdb(name=odb_path, readOnly=FALSE) # 遍历所有分析步和帧 for step_name in odb.steps.keys(): step = odb.steps[step_name] for frame in step.frames: print(frame.description) # 获取接触场输出 copen = frame.fieldOutputs['COPEN'] cslip1 = frame.fieldOutputs['CSLIP1'] cslip2 = frame.fieldOutputs['CSLIP2'] # 提取数值数组(确保三个场输出的位置/单元完全对应) copen_vals = np.array([v.data for v in copen.values]) cslip1_vals = np.array([v.data for v in cslip1.values]) cslip2_vals = np.array([v.data for v in cslip2.values]) # 计算微动位移,处理数值精度问题 sum_sq = copen_vals**2 + cslip1_vals**2 + cslip2_vals**2 # 替换因精度产生的负数,避免开方报错 sum_sq[sum_sq < 0] = 0 micromotion_vals = np.sqrt(sum_sq) # 过滤NaN和无穷大值,替换为0 micromotion_vals = np.nan_to_num(micromotion_vals, nan=0.0, posinf=0.0, neginf=0.0) # 创建新的标量场输出 micromotion_field = frame.FieldOutput( name='Micromotion', description='Micromotion calculated from COPEN, CSLIP1, CSLIP2', type=SCALAR ) # 将计算结果写入场输出,匹配原数据的位置信息 for idx, val in enumerate(copen.values): micromotion_field.addData( position=val.position, instance=val.instance, labels=val.labels, data=micromotion_vals[idx] ) # 保存并关闭ODB文件 odb.save() odb.close()
额外注意事项
- 确认COPEN、CSLIP1、CSLIP2三个场输出的位置(节点/单元)、实例、标签完全对应,避免数值错位;
- 可通过
val.status过滤无效接触状态的数据,进一步提升计算准确性; - 操作前备份原ODB文件,防止数据损坏。
内容的提问来源于stack exchange,提问作者manniblaq
相关产品推荐
相关产品推荐

