目 录
Blog Links
一、前言
高周疲劳 ( high cycle fatigue, HCF ): 在循环应力水平较低时,弹性应变起主导作用,此时疲劳寿命较长,断裂前的应力循环次数 𝑛 ≥ 5×104,断裂应力水平较低,明显低于屈服强度,𝜎 < 𝑓y 。(应力疲劳),高周疲劳失效时,应力水平低,疲劳寿命长。
本文以力学中最简单的自由端受动载的悬臂梁为例,介绍 nCodeDL 执行高周疲劳分析的简要流程。nCodeDL 所需的输入文件之一是各单位荷载作用下悬臂梁的有限元结果文件,该文件可由大型通用有限元分析软件 ANSYS 或 Abaqus 计算得到。本文还介绍了创建有限元结果文件的基本流程,其中,ANSYS 有限元模型由 APDL 命令流创建,Abaqus 有限元模型由 Python 脚本创建,具体详见本文第二部分。
1.1 问题概述
悬臂梁长度为 360 mm,其横截面尺寸为 H×B = 12mm×6mm。材料为钢材,牌号为 Q235B,其弹性模量为 200 Gpa,泊松比设置为 0 (实际上为0.3) 。在动荷载施加前,悬臂梁上作用有轴向 720 N 的预压力,竖向 10 N 的恒荷载,如下图所示。
在材料力学中,推导梁的弯曲正应力时,除了采用平截面假定外,还默认材料的泊松比为 0,即认为横截面两个方向上的变形相互独立互不影响。因此,为了能严格的和理论解答做对比,在有限元建模时,材料的泊松比设置为 0。
1.2 交变载荷谱
在悬臂梁自由端作用有动荷载,且 6 个自由度方向上的动荷载均为 标准正弦 荷载,荷载幅值如表 1 所示。
荷载分量 | 单位 | 荷载幅值1 | 荷载幅值2 | 荷载幅值3 |
---|---|---|---|---|
Fx | N | 350 | 700 | 1050 |
Fy | N | 13 | 26 | 39 |
Fz | N | 6 | 12 | 18 |
Mx | N·mm | 800 | 1600 | 2400 |
My | N·mm | 500 | 1000 | 1500 |
Mz | N·mm | 750 | 1500 | 2250 |
假设荷载幅值1、2 和 3 的循环次数分别为 1000 次、2000 次 和 3000 次, 且荷载的作用频率很低,可忽略荷载作用过程中悬臂梁产生的惯性力,悬臂梁的自振频率与动载作用频率也不相接近,即不会发生共振现象。
1.3 单位荷载取值
采用 nCodeDL 进行疲劳分析时,所需要的输入文件之一是单位荷载作用下的有限元结果文件,该文件可来自 ANSYS、Abaqus 、MSC.NASTRAN 、IDEAS 和 LS-Dyna 等有限元分析软件。
本文所需的有限元结果文件分别来自 ANSYS 和 Abaqus,即本文详细说明 ANSYS + nCode 和 Abaqus + nCode 进行疲劳分析的基本流程。有限元分析时,各单位荷载按表 2 选取。
荷载分量 | 单位荷载取值 | 荷载幅值1比例系数 | 荷载幅值2比例系数 | 荷载幅值3比例系数 |
---|---|---|---|---|
Fx | 100 N | 3.5 | 7.0 | 10.5 |
Fy | 1 N | 13 | 26 | 39 |
Fz | 1 N | 6 | 12 | 18 |
Mx | 1000 N·mm | 0.8 | 1.6 | 2.4 |
My | 1000 N·mm | 0.5 | 1.0 | 1.5 |
Mz | 1000 N·mm | 0.75 | 1.5 | 2.25 |
由上可得最终用于疲劳计算的荷载时序 *(实际为比例系数),将其存储到 txt 中,相应的文件名为 TSLoads-Amp1-1000.txt、TSLoads-Amp2-2000.txt 和 TSLoads-Amp3-3000.txt,如下图所示。
若存在非线性分析,如初始分析步为螺栓预紧力的施加,则单位荷载个数应为 12 个,即每个自由度上正反两个方向各取一个,6 个自由度总计 12 个,将得到 12 个分析结果,在 6 个自由度上的动荷载同样要做正反两个方向上的拆分,正向动荷载匹配正向单位力作用下的有限元结果,负向动荷载匹配负向单位力作用下的有限元结果,具体操作本文不做赘述,详见博客: nCodeDL 高周疲劳 分析实例 法兰连接 。 (哈哈,这篇博客找不到吧,因为还没写,为啥没写? 因为懒!)
1.4 材料力学解答
轴向预应力 P、竖向恒荷载 G 及表 2 中各单位荷载单独作用下,悬臂梁中最大正应力理论解及(ANSYS)有限元解如表 3 所示。
荷载名称 | 荷载数值 | 理论解最大正应力 Sx N/mm2 | 有限元解最大正应力 Sx N/mm2 |
---|---|---|---|
P | -720 N | -10 | -10 |
G | -10 N | 25 | 25.004 |
Fx | 100 N | 1.389 | 1.390 |
Fy | 1 N | 2.5 | 2.500 |
Fz | 1 N | 5 | 5.000 |
Mx | 1000 N·mm | — | 4.054 |
My | 1000 N·mm | 13.889 | 14.025 |
Mz | 1000 N·mm | 6.944 | 6.974 |
1.5 nCode输入文件/分析流程
采用 nCodeDL 进行疲劳分析所需要的文件主要有:.rst文件/.odb文件、.mxd文件、.3st文件 。其中,.rst文件/.odb文件为有限元结果文件,来自相应分析软件进行的单位荷载作用下的有限元分析;.mxd文件为用户自定义材料属性文件,该文件描述材料的 SN 曲线;.3st文件为疲劳荷载时序文件,用于描述作用在结构/构件上的疲劳荷载情况。
二、有限元分析
2.1 模型信息
为了能更广泛的说明疲劳分析中所能遇到的各种问题,本文在创建有限元模型时,将悬臂梁分为前中后三个部分,如下图所示。每个部分单独创建材料、组件/部件等,其基本信息见表 4 和表 5 。
梁段 | 组件名称 | 单元类型号 | 材料号 |
---|---|---|---|
前梁段 | PartAElems | 219 | 107 |
中梁段 | PartBElems | 250 | 132 |
后梁段 | PartCElems | 272 | 159 |
梁段 | 部件名称 | 单元集合名称(装配层面) | 材料名称 | 实体截面名称 |
---|---|---|---|---|
前梁段 | PartA | PartAElems | Q235-MatA-107 | Sec-3D-107 |
中梁段 | PartB | PartBElems | Q235-MatB-132 | Sec-3D-132 |
后梁段 | PartC | PartBElems | Q235-MatC-159 | Sec-3D-159 |
2.2 荷载工况
工况名称 | 加载信息 | 描述 | 备注 |
---|---|---|---|
LoadCase-00 | P + G | 轴向预压力荷载 + 竖向恒荷载 | P = -720 N G = -10 N |
LoadCase-01 | P + G + Fx | 轴向预压力荷载 + 竖向恒荷载 + 沿 x 轴方向单位集中力 | Fx = 100 N |
LoadCase-02 | P + G + Fy | 轴向预压力荷载 + 竖向恒荷载 + 沿 y 轴方向单位集中力 | Fy = 1 N |
LoadCase-03 | P + G + Fz | 轴向预压力荷载 + 竖向恒荷载 + 沿 z 轴方向单位集中力 | Fz =1 N |
LoadCase-04 | P + G + Mx | 轴向预压力荷载 + 竖向恒荷载 + 绕 x 轴方向的单位扭矩 | Mx = 1000 N·mm |
LoadCase-05 | P + G + My | 轴向预压力荷载 + 竖向恒荷载 + 绕 y 轴方向的单位弯矩 | My = 1000 N·mm |
LoadCase-06 | P + G + Mz | 轴向预压力荷载 + 竖向恒荷载 + 绕 z 轴方向的单位弯矩 | Mz = 1000 N·mm |
2.3 ANSYS/APDL
rst文件的创建。APDL命令流如下。
特别注意,同一构件的不同部分,无法通过赋予不同的材料编号、单元类型号等方式,在 nCode 中进行识别,只能拆成不同的部分建模 (可能是版本问题/非绝对)。
2.3.1 前处理
FINISH
/CLEAR
! Units: mm, N
L = 360 ! Length
H = 12 ! Height
B = 6 ! Width
E = 200000 ! Young’s modulus
nu = 0 ! Poisson’s ratio
NumX = 10 ! Number of elements in x direction
NumY = 2 ! Number of elements in y direction
NumZ = 2 ! Number of elements in z direction
/PREP7
! 1. 定义几何体
BLOCK, 0, L, -H/2, H/2, -B/2, B/2 ! 创建六面体
/VIEW,, 1, 1, 1 ! 设置视图
VPLOT ! Plot Volumes
! 2. 定义单元属性
ET, 219, SOLID186 ! 定义219号单元
KEYOPT,219,2,0 ! 186减缩积分单元
MP, EX, 107, E ! 定义107号材料
MP, NUXY, 107, nu
ET, 250, SOLID186 ! 定义250号单元
KEYOPT,250,2,0 ! 186减缩积分单元
MP, EX, 132, E ! 定义132号材料
MP, NUXY, 132, nu
ET, 272, SOLID186 ! 定义272号单元
KEYOPT,272,2,0 ! 186减缩积分单元
MP, EX, 159, E ! 定义159号材料
MP, NUXY, 159, nu
! 3. 划分网格
TYPE, 219 ! 激活单元类型号
MAT, 107 ! 激活材料编号
ALLSEL,ALL ! 全显示
LSEL,S,LENGTH,,H ! 按长度选线
LESIZE,ALL, , ,NumY, , , , ,0 ! 布种子
ALLSEL,ALL
LSEL,S,LENGTH,,B ! 按长度选线
LESIZE,ALL, , ,NumZ, , , , ,0 ! 布种子
ALLSEL,ALL
LSEL,S,LENGTH,,L ! 按长度选线
LESIZE,ALL, , ,NumX, , , , ,0 ! 布种子
ALLSEL,ALL
VSWEEP,ALL ! 扫略分网
! 4. 定义组件
NSEL, S, LOC, X, -1,0.3*L+1
ESLN,S,1
CM,PartAElems,ELEM ! 创建组件PartAElems(前梁段)
ALLSEL,ALL
NSEL, S, LOC, X, 0.3*L+1-1,0.7*L+1
ESLN,S,1
CM,PartBElems,ELEM ! 创建组件PartBElems(中梁段)
ALLSEL,ALL
NSEL, S, LOC, X, 0.7*L-1,L+1
ESLN,S,1
CM,PartCElems,ELEM ! 创建组件PartBElems(后梁段)
ALLSEL,ALL
! 5. 修改属性
ALLSEL,ALL
CMSEL,S,PartBElems
EMODIF,ALL,TYPE,250
EMODIF,ALL,MAT,132
ALLSEL,ALL
CMSEL,S,PartCElems
EMODIF,ALL,TYPE,272
EMODIF,ALL,MAT,159
ALLSEL,ALL
! 6. 创建加载点
R,1 ! 定义新实常数
ET,4,TARGE170 ! 定义目标面单元 - 连续面
KEYOPT,4,2,1 ! Boundary conditions for rigid target nodes: Specified by user.
ET,5,CONTA174 ! 定义接触面单元 - 离散面
KEYOPT,5,2,2 ! MPC
KEYOPT,5,4,1 ! On nodal point - normal from contact surface
KEYOPT,5,12,5 ! Behavior of contact surface: Bonded (always).
N1 = NODE(L,0,0) ! 获取结点(L,0,0)的编号
NSEL,S,NODE, ,N1 ! 新建选择集,选择编号为N1结点。
CM,loadNode,Node ! 为加载点创建一组件
ALLSEL,ALL ! 全显示
REAL,1 ! 激活实常数
TYPE,4 ! 激活目标单元类型号
TSHAP,PILO
E,N1 ! 创建目标单元
ALLSEL,ALL ! 退出选择集,显示全部。
REAL,1 ! 激活实常数
TYPE,5 ! 激活目标单元类型号
NSEL,S,LOC,X,L ! 选择梁端部截面上全部结点
ESURF ! 在存在已选单元的自由面上生成重叠单元,即创建接触单元。
ALLSEL,ALL ! 全显示
EPLOT
FINISH
/SOLU
! 7. 指定边界条件 (Fixed end)
NSEL, S, LOC, X, 0
D, ALL, ALL, 0
ALLSEL,ALL ! 全显示
FINISH
/PNUM,MAT,1 ! 按材料号显示模型
/NUMBER,1 ! 仅显示颜色
/REPLOT
ALLSEL,ALL ! 全选 select all entities
CDWRITE,DB,'CantileverBeam','cdb' ! 当前模型另存为 CantileverBeam.cdb 文件
2.3.2 加载与求解
- 轴向预压力+竖向恒荷载工况
/FILNAME,LoadCase-00,0 ! 设置Jobname为LoadCase-00
/SOLU
! 8. 施加集中荷载
P = -720
G = -10
F, loadNode, FX, P
F, loadNode, FY, G
! 9. 设置分析选项
ANTYPE,STATIC ! 静力分析
EQSLV,PCG,1E-4 ! 方程求解类型: PCG求解, 精度/容差为1E-4 。
NSUBST,2,2,2 ! 子步设置: 2个子步, 最大2, 最小2,相当于固定子步。
TIME,1 ! Sets the time for a load step.
! 10. 设置场输出
OUTRES,ERASE
OUTRES,ALL,NONE
OUTRES,STRS,LAST,PartAElems ! 仅输出每个荷载步最后一荷载子步的应力场数据
OUTRES,STRS,LAST,PartCElems ! 仅输出每个荷载步最后一荷载子步的应力场数据
ALLSEL,ALL ! 全显示
! 11. 提交作业进行求解
SOLVE
FINISH
/POST1
/VIEW,, 1, 1, 1
PLNSOL, S, X
FINISH
- 各方向单位荷载工况
FINISH
/CLEAR
/PREP7
SHPP,OFF,,NOWARN ! 关闭单元形状检测警告
CDREAD,DB,'CantileverBeam','cdb' ! 导入CantileverBeam.cdb文件
ALLSEL,ALL
EPLOT
*DIM,FLab,CHAR,6 ! 定义名称为FLab字符型数组
*SET,FLab(1),'Fx' ! Force label:Fx
*SET,FLab(2),'Fy' ! Force label:Fy
*SET,FLab(3),'Fz' ! Force label:Fz
*SET,FLab(4),'Mx' ! Force label:Mx
*SET,FLab(5),'My' ! Force label:My
*SET,FLab(6),'Mz' ! force label:Mz
*DIM,FVal,ARRAY,6 ! 定义名称为FVal数值型数组
*SET,FVal(1),100 ! Force value:Fx = 100 N
*SET,FVal(2),1 ! Force value:Fy = 100 N
*SET,FVal(3),1 ! Force value:Fz = 100 N
*SET,FVal(4),1000 ! Force value:Mx = 1000 N-mm
*SET,FVal(5),1000 ! Force value:My = 1000 N-mm
*SET,FVal(6),1000 ! Force value:Mz = 1000 N-mm
*DO,i,1,6,1
FINISH
/FILNAME,LoadCase-0%i%,0 ! 设置 Job Name
/SOLU ! 访问求解器
/DELETE,'para','txt',''
PARSAVE,SCALAR,para,txt
PARRES,CHANGE,'para','txt',''
! 12. 设置分析选项
ANTYPE,STATIC ! 静力分析
EQSLV,PCG,1E-4 ! 方程求解类型: PCG求解, 精度/容差为1E-4 。
NSUBST,2,2,2 ! 子步设置: 2个子步, 最大2, 最小2,相当于固定子步。
TIME,i ! Sets the time for a load step.
! 13. 设置场输出
OUTRES,ERASE
OUTRES,ALL,NONE
OUTRES,STRS,LAST,PartAElems ! 仅输出每个荷载步最后一荷载子步的应力场数据
OUTRES,STRS,LAST,PartCElems ! 仅输出每个荷载步最后一荷载子步的应力场数据
ALLSEL,ALL ! 全显示
! 14. 施加荷载
FDELE,ALL,ALL ! 删除结点上作用的全部荷载
F,loadNode,FLab(i),FVal(i)
ALLSEL,ALL
! 15. 提交作业进行求解
SOLVE
FINISH
! 16. 删除多余文件
/DELETE,,'esav'
/DELETE,,'mntr'
/DELETE,,'pcs'
/DELETE,,'stat'
*ENDDO
2.3.3 结果分析
/COM, 提取各工况最大正应力Sx值
FINISH
*DIM,SigmaMax,ARRAY,1,7 ! 定义名称为SigmaMax数值型数组
/POST1
*DO,i,0,6,1
INRES,ALL
FILE, LoadCase-0%i%, rst
SET, LAST
PLNSOL, S, X
*GET, Par, PLNSOL, 0, MAX
SigmaMax(1,i+1) = Par
*ENDDO
/COM,提取各工况265号结点处的正应力Sx值
FINISH
*DIM,SigmaN265A,ARRAY,1,7 ! 定义名称为SigmaN265A数值型数组
/POST1
*DO,i,0,6,1
INRES,ALL
FILE, LoadCase-0%i%, rst
SET, LAST
*GET, par, NODE, 265, S, X
SigmaN265A(1,i+1) = par
*ENDDO
荷载信息 | 荷载数值 | 理论解 N/mm2 | ANSYS解 N/mm2 |
---|---|---|---|
P + G | -720 N / -10 N | 15 | 15.004 |
Fx | 100 N | 1.389 | 1.390 |
Fy | 1 N | 2.5 | 2.500 |
Fz | 1 N | 5 | 5.000 |
Mx | 1000 N·mm | — | 4.054 |
My | 1000 N·mm | 13.889 | 14.025 |
Mz | 1000 N·mm | 6.944 | 6.974 |
在上图中,SigmaN265A(1,4) = 1.997190702E-5 。
2.3.4 rst的合并
为了方便与 Abaqus 结果进行对比,现将多个 .rst 合并为一个 .rst 文件。以下命令流实现各工况结果的相加 (布尔运算),并存储在 nCodeInput.rst 文件中。且仅输出前梁段和后梁段的应力计算结果。
FINISH
/CLEAR
/PREP7
SHPP,OFF,,NOWARN ! 关闭单元形状检测警告
CDREAD,DB,'CantileverBeam','cdb'
ALLSEL,ALL
EPLOT
FINISH
/COPY, 'LoadCase-00','rst','','nCodeInput','rst',''
/POST1
*DO,i,1,6,1
INRES,ALL
FILE,LoadCase-0%i%,'rst',''
LCDEF,1,1
FILE,'nCodeInput','rst',''
LCDEF,2,1
ALLSEL,ALL
LCFACT,2,1.0
LCASE,1
LCOPER,ADD,2
RAPPND,i+1,i+1
ALLSEL,ALL
*ENDDO
集合名称 | 工况名称 | 加载信息 | 描述 | 备注 |
---|---|---|---|---|
Set 1 | LoadCase-00 | P + G | 轴向预压力荷载 + 竖向恒荷载 | P = -720 N G = -10 N |
Set 2 | LoadCase-01 | P + G + Fx | 轴向预压力荷载 + 竖向恒荷载 + 沿 x 轴方向单位集中力 | Fx = 100 N |
Set 3 | LoadCase-02 | P + G + Fy | 轴向预压力荷载 + 竖向恒荷载 + 沿 y 轴方向单位集中力 | Fy = 1 N |
Set 4 | LoadCase-03 | P + G + Fz | 轴向预压力荷载 + 竖向恒荷载 + 沿 z 轴方向单位集中力 | Fz =1 N |
Set 5 | LoadCase-04 | P + G + Mx | 轴向预压力荷载 + 竖向恒荷载 + 绕 x 轴方向的单位扭矩 | Mx = 1000 N·mm |
Set 6 | LoadCase-05 | P + G + My | 轴向预压力荷载 + 竖向恒荷载 + 绕 y 轴方向的单位弯矩 | My = 1000 N·mm |
Set 7 | LoadCase-06 | P + G + Mz | 轴向预压力荷载 + 竖向恒荷载 + 绕 z 轴方向的单位弯矩 | Mz = 1000 N·mm |
nCodeInput.rst 文件中,各 Set 内 265 号结点处的正应力 Sx 值,如下表所示。
FINISH
*DIM,SigmaN265B,ARRAY,1,7 ! 定义名称为SigmaN265B数值型数组
/POST1
*DO,i,1,7,1
INRES,ALL
FILE, 'nCodeInput','rst'
SET,,, ,,, ,i
*GET, par, NODE, 265, S, X
SigmaN265B(1,i) = par
*ENDDO
2.4 Abaqus/Python
odb文件的创建。Pyhon脚本如下,以下 Python 代码,按顺序复制后,粘贴到 Abaqus/CAE 中的命令行接口中运行。
了解 Abaqus/CAE 命令行接口 ,详见博客: Abaqus 二次开发 基本概念 >> 三、Abaqus脚本 >> 3.3. 命令行接口 。
2.4.1 前处理
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Python Version: 2.7.3
Abaqus/CAE 6.14-1
Email: liyang@alu.hit.edu.cn
=============================
"""
from abaqus import *
from abaqusConstants import *
from caeModules import *
from odbAccess import *
from driverUtils import executeOnCaeStartup
import regionToolset
# Units: mm, N
L = 360 # Length
H = 12 # Height
B = 6 # Width
E = 200000 # Young’s modulus
nu = 0 # Poisson’s ratio
NumX1 = 3 # Number of elements in x direction/前梁段长度方向网格数目
NumX2 = 4 # Number of elements in x direction/中梁段长度方向网格数目
NumX3 = 3 # Number of elements in x direction/后梁段长度方向网格数目
NumY = 2 # Number of elements in y direction/高度方向网格数目
NumZ = 2 # Number of elements in z direction/宽度方向网格数目
# 1.创建草图
currmdb = mdb.models["Model-1"]
skh = currmdb.ConstrainedSketch(name="Sketch-1", sheetSize=500.0)
skh.setPrimaryObject(option=STANDALONE)
skh.rectangle(point1=(-0.5 * B, -0.5 * H), point2=(0.5 * B, 0.5 * H))
skh.unsetPrimaryObject()
# 2.创建部件
lengths = [0.3 * L, 0.4 * L, 0.3 * L]
prtnames = ["PartA", "PartB", "PartC"]
for i in range(3):
length, prtname, = lengths[i], prtnames[i]
prt = currmdb.Part(name=prtname, dimensionality=THREE_D, type=DEFORMABLE_BODY)
prt = currmdb.parts[prtname]
prt.BaseSolidExtrude(sketch=skh, depth=length)
# 3.划分网格
NumXs = [NumX1, NumX2, NumX3]
for i in range(3):
length, NumX, prtname, = lengths[i], NumXs[i], prtnames[i]
prt = currmdb.parts[prtname]
es = prt.edges
xMin, xMax, yMin, yMax, zMin, zMax = 0, B, -H, H, -1, 0.5 * length
e1 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e1, number=NumY, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, 0, -H, H, -1, 0.5 * length
e2 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e2, number=NumY, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = 0, B, -H, H, 0.5 * length, 2 * length
e3 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e3, number=NumY, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, 0, -H, H, 0.5 * length, 2 * length
e4 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e4, number=NumY, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, B, 0, H, -1, 0.5 * length
e5 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e5, number=NumZ, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, B, -H, 0, -1, 0.5 * length
e6 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e6, number=NumZ, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, B, 0, H, 0.5 * length, 2 * length
e7 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e7, number=NumZ, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, B, -H, 0, 0.5 * length, 2 * length
e8 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e7, number=NumZ, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = 0, B, 0, H, -1, 2 * length
e9 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e9, number=NumX, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, 0, 0, H, -1, 2 * length
e10 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e10, number=NumX, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = 0, B, -H, 0, -1, 2 * length
e11 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e11, number=NumX, constraint=FIXED)
xMin, xMax, yMin, yMax, zMin, zMax = -B, 0, -H, 0, -1, 2 * length
e12 = es.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
prt.seedEdgeByNumber(edges=e12, number=NumX, constraint=FIXED)
prt.generateMesh()
elemType1 = mesh.ElemType(elemCode=C3D20R, elemLibrary=STANDARD)
prt = currmdb.parts[prtname]
cs = prt.cells
prt.setElementType(regions=(cs,), elemTypes=(elemType1,))
# 4.创建及指定材性
matnames = ["Q235-MatA-107", "Q235-MatB-132", "Q235-MatC-159"]
secnames = ["Sec-3D-107", "Sec-3D-132", "Sec-3D-159"]
for i in range(3):
matname = matnames[i]
secname = secnames[i]
prtname = prtnames[i]
currmdb.Material(name=matname)
currmdb.materials[matname].Elastic(table=((E, nu),))
currmdb.HomogeneousSolidSection(name=secname, material=matname, thickness=None)
prt = currmdb.parts[prtname]
cs = prt.cells
region = prt.Set(cells=cs, name="Set-1")
prt = currmdb.parts[prtname]
prt.SectionAssignment(region=region, sectionName=secname, offset=0.0, offsetType=MIDDLE_SURFACE,
offsetField='', thicknessAssignment=FROM_SECTION)
# 5.装配
istnames = prtnames
for i in range(3):
istname, prtname = istnames[i], prtnames[i]
asm = currmdb.rootAssembly
if i == 0:
asm.DatumCsysByDefault(CARTESIAN)
prt = currmdb.parts[prtname]
asm.Instance(name=istname, part=prt, dependent=ON)
## 5.1旋转
asm = currmdb.rootAssembly
asm.rotate(instanceList=istnames, axisPoint=(0.0, 0.0, 0.0),
axisDirection=(0.0, 1.0, 0.0), angle=90.0)
## 5.2平移
asm = currmdb.rootAssembly
for i in range(3):
istname = istnames[i]
x = sum(lengths[:i])
asm.translate(instanceList=(istname,), vector=(x, 0.0, 0.0))
# 6.创建集合
## 6.1 单元集合
setnames = ["PartAElems", "PartBElems", "PartCElems"]
for i in range(3):
istname = istnames[i]
asm = currmdb.rootAssembly
elems = asm.instances[istname].elements
asm.Set(elements=elems, name=setnames[i])
## 6.2 绑定面集合
for i in range(3):
prtname = prtnames[i]
length = lengths[i]
NumX = NumXs[i]
asm = currmdb.rootAssembly
elems = asm.instances[prtname].elements
if i < 2:
xMin, xMax, yMin, yMax, zMin, zMax = sum(lengths[:i]) + (
NumX - 1.5) * length / NumX, 2 * L, -H, H, -B, B
sltelems = elems.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin,
zMax=zMax)
name = "Surf-M-%s" % (i + 1)
asm.Surface(face3Elements=sltelems, name=name)
if i > 0:
xMin, xMax = sum(lengths[:i]) - 0.5 * length / NumX, sum(lengths[:i]) + 1.5 * length / NumX
yMin, yMax, zMin, zMax = -H, H, -B, B
sltelems = elems.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin,
zMax=zMax)
name = "Surf-S-%s" % (i)
asm.Surface(face5Elements=sltelems, name=name)
## 6.3 边界条件结点集合
asm = currmdb.rootAssembly
nds = asm.instances['PartA'].nodes
xMin, xMax, yMin, yMax, zMin, zMax = -0.1, 0.1, -H, H, -B, B
sltnds = nds.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
asm.Set(nodes=sltnds, name='BCNodes')
## 6.4 加载面结点集合
asm = currmdb.rootAssembly
nds = asm.instances['PartC'].nodes
xMin, xMax, yMin, yMax, zMin, zMax = L - 0.1, L + 0.1, -H, H, -B, B
sltnds = nds.getByBoundingBox(xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=zMin, zMax=zMax)
asm.Set(nodes=sltnds, name='SlaveLoadNodes')
## 6.5 加载参考点
asm = currmdb.rootAssembly
asm.ReferencePoint(point=(L, 0.0, 0.0))
# 7.创建Tie约束及耦合
asm = currmdb.rootAssembly
region1 = asm.surfaces['Surf-M-1']
region2 = asm.surfaces['Surf-S-1']
currmdb.Tie(name='Constraint-1', master=region1, slave=region2, positionToleranceMethod=COMPUTED,
adjust=ON, tieRotations=ON, thickness=ON)
asm = currmdb.rootAssembly
region1 = asm.surfaces['Surf-M-2']
region2 = asm.surfaces['Surf-S-2']
currmdb.Tie(name='Constraint-2', master=region1, slave=region2, positionToleranceMethod=COMPUTED,
adjust=ON,
tieRotations=ON, thickness=ON)
asm = currmdb.rootAssembly
rps = asm.referencePoints
rpnums = rps.keys()
sltrp = rps[rpnums[0]]
refPoints1 = (sltrp,)
region1 = asm.Set(referencePoints=refPoints1, name='loadNode')
region2 = asm.sets['SlaveLoadNodes']
currmdb.Coupling(name='Constraint-3', controlPoint=region1,
surface=region2, influenceRadius=WHOLE_SURFACE, couplingType=KINEMATIC,
localCsys=None, u1=ON, u2=ON, u3=ON, ur1=ON, ur2=ON, ur3=ON)
# 8.定义边界条件
asm = currmdb.rootAssembly
region = asm.sets['BCNodes']
currmdb.DisplacementBC(name='BC-1', createStepName='Initial', region=region, u1=SET, u2=SET, u3=SET,
ur1=SET, ur2=SET, ur3=SET, amplitude=UNSET, distributionType=UNIFORM,
fieldName='', localCsys=None)
2.4.2 加载与求解
# 9.定义静力通用分析步
currmdb.StaticStep(name="Step-1", previous="Initial")
for i in range(6):
name = "Step-%s" %(i+2)
prev = "Step-%s" %(i+1)
currmdb.StaticStep(name=name, previous=prev)
# 10.施加各工况荷载
P, G = -720, -10
Fx, Fy, Fz = 100, 1, 1
Mx, My, Mz = 1000, 1000, 1000
asm = currmdb.rootAssembly
region = asm.sets['loadNode']
# 10.1 P+G
name, stepname = "Load-1", "Step-1"
currmdb.ConcentratedForce(name=name, createStepName=stepname, region=region, cf1=P, cf2=G, cf3=0,
distributionType=UNIFORM, field='', localCsys=None)
# 10.2 单位荷载步/Fx
name, stepname = "Load-2", "Step-2"
currmdb.ConcentratedForce(name=name, createStepName=stepname, region=region, cf1=Fx, cf2=0, cf3=0,
distributionType=UNIFORM, field='', localCsys=None)
currmdb.loads["Load-2"].deactivate("Step-3") # 荷载不向后续荷载步传递/仅在本荷载步起作用
# 10.3 单位荷载步/Fy
name, stepname = "Load-3", "Step-3"
currmdb.ConcentratedForce(name=name, createStepName=stepname, region=region, cf1=0, cf2=Fy, cf3=0,
distributionType=UNIFORM, field='', localCsys=None)
currmdb.loads["Load-3"].deactivate("Step-4") # 荷载不向后续荷载步传递/仅在本荷载步起作用
# 10.4 单位荷载步/Fz
name, stepname = "Load-4", "Step-4"
currmdb.ConcentratedForce(name=name, createStepName=stepname, region=region, cf1=0, cf2=0, cf3=Fz,
distributionType=UNIFORM, field='', localCsys=None)
currmdb.loads["Load-4"].deactivate("Step-5") # 荷载不向后续荷载步传递/仅在本荷载步起作用
# 10.5 单位荷载步/Mx
name, stepname = "Load-5", "Step-5"
currmdb.Moment(name=name, createStepName=stepname, region=region, cm1=Mx, cm2=0, cm3=0,
distributionType=UNIFORM, field='', localCsys=None)
currmdb.loads["Load-5"].deactivate("Step-6") # 荷载不向后续荷载步传递/仅在本荷载步起作用
# 10.6 单位荷载步/My
name, stepname = "Load-6", "Step-6"
currmdb.Moment(name=name, createStepName=stepname, region=region, cm1=0, cm2=My, cm3=0,
distributionType=UNIFORM, field='', localCsys=None)
currmdb.loads["Load-6"].deactivate("Step-7") # 荷载不向后续荷载步传递/仅在本荷载步起作用
# 10.7 单位荷载步/Mz
name, stepname = "Load-7", "Step-7"
currmdb.Moment(name=name, createStepName=stepname, region=region, cm1=0, cm2=0, cm3=Mz,
distributionType=UNIFORM, field='', localCsys=None)
# 11.定义场输出
asm = currmdb.rootAssembly
region = asm.sets['PartAElems']
currmdb.FieldOutputRequest(name='F-Output-1', createStepName='Step-1',
variables=('S', 'MISES', 'MISESMAX'), region=region,
sectionPoints=DEFAULT, rebar=EXCLUDE)
region = asm.sets['PartCElems']
currmdb.FieldOutputRequest(name='F-Output-2', createStepName='Step-1',
variables=('S', 'MISES', 'MISESMAX'), region=region,
sectionPoints=DEFAULT, rebar=EXCLUDE)
mdb.models["Model-1"].setValues(noPartsInputFile=ON) # 防止inp导入HyperMesh中各种错乱
# 12.创建作业/提交计算
jobname = "nCodeInput"
mdb.Job(name="nCodeInput", model='Model-1', description='', type=ANALYSIS, atTime=None,
waitMinutes=0, waitHours=0, queue=None, memory=90, memoryUnits=PERCENTAGE,
getMemoryFromAnalysis=True, explicitPrecision=SINGLE,
nodalOutputPrecision=SINGLE, echoPrint=OFF, modelPrint=OFF, contactPrint=OFF,
historyPrint=OFF, userSubroutine='', scratch='', resultsFormat=ODB,
multiprocessingMode=DEFAULT, numCpus=1, numGPUs=0)
mdb.jobs[jobname].submit(consistencyChecking=OFF)
mdb.models["Model-1"].setValues(noPartsInputFile=ON) # 防止inp导入HyperMesh中各种错乱
# noPartsInputFile
# A Boolean specifying whether an input file should be written without parts and assemblies. The default value is OFF.
参考博客: Abaqus inp文件导入hypermesh显示很乱 。
2.4.3 结果分析
荷载信息 | 荷载数值 | 理论解 N/mm2 | Abaqus解 N/mm2 |
---|---|---|---|
P + G | -720 N / -10 N | 15 | 15.0037 |
P + G + Fx | 100 N | 16.389 | 16.3926 |
P + G + Fy | 1 N | 12.5 | 12.5033 |
P + G + Fz | 1 N | 15 | 15.0037 |
P + G + Mx | 1000 N·mm | — | 15.0037 |
P + G + My | 1000 N·mm | 15 | 15.0037 |
P + G + Mz | 1000 N·mm | 8.056 | 8.05923 |
2.5 结果对比
通过以上分析,现已得到两个有限元结果文件,即 nCodeInput.rst 和 nCodeInput.odb,它们是同一个问题 (悬臂梁自由端受载) 采用不同有限元软件 (ANSYS与Abaqus) 分析而得的计算结果文件。
目的: 一是方便彼此对比计算结果有无差错,二是借此能详细介绍采用不同结果文件执行疲劳分析的具体操作流程。
2.5.1 结果-工况对应关系
在两个结果文件 (.rst和.odb) 中, 各结果集 (ANSYS) / 各分析步上的计算结果 (Abaqus) 与各荷载工况有如下对应关系,见表 10 。
工况名称 | 结果集名称 | 分析步名称 | 加载信息 | 描述 | 荷载值 |
---|---|---|---|---|---|
LoadCase-00 | Set 1 | Step-1 | P + G | 轴向预压力荷载 + 竖向恒荷载 | P = -720 N G = -10 N |
LoadCase-01 | Set 2 | Step-2 | P + G + Fx | 轴向预压力荷载 + 竖向恒荷载 + 沿 x 轴方向单位集中力 | Fx = 100 N |
LoadCase-02 | Set 3 | Step-3 | P + G + Fy | 轴向预压力荷载 + 竖向恒荷载 + 沿 y 轴方向单位集中力 | Fy = 1 N |
LoadCase-03 | Set 4 | Step-4 | P + G + Fz | 轴向预压力荷载 + 竖向恒荷载 + 沿 z 轴方向单位集中力 | Fz =1 N |
LoadCase-04 | Set 5 | Step-5 | P + G + Mx | 轴向预压力荷载 + 竖向恒荷载 + 绕 x 轴方向的单位扭矩 | Mx = 1000 N·mm |
LoadCase-05 | Set 6 | Step-6 | P + G + My | 轴向预压力荷载 + 竖向恒荷载 + 绕 y 轴方向的单位弯矩 | My = 1000 N·mm |
LoadCase-06 | Set 7 | Step-7 | P + G + Mz | 轴向预压力荷载 + 竖向恒荷载 + 绕 z 轴方向的单位弯矩 | Mz = 1000 N·mm |
2.5.2 监测点正应力对比
为了验证上述有限元分析的准确性,可通过对比悬臂梁上某点处应力的有限元解答与材料力学理论解答间的误差的方式加以证明。本文选取悬臂梁固定端截面上边缘中点为监测点,此点沿 x 方向正应力的材料力学解答 (理论解) 与有限元解答 (ANSYS/Abaqus) 如表 11 所示,监测点位置如下图所示。
工况名称 | 结果集名称 | 分析步名称 | 加载信息 | 材料力学解答 | ANSYS解答 | Abaqus解答 |
---|---|---|---|---|---|---|
LoadCase-00 | Set 1 | Step-1 | P + G | 15 | 15.003664016724 | 15.0037 |
LoadCase-01 | Set 2 | Step-2 | P + G + Fx | 16.389 | 16.392553329468 | 16.3926 |
LoadCase-02 | Set 3 | Step-3 | P + G + Fy | 12.5 | 12.503297328949 | 12.5033 |
LoadCase-03 | Set 4 | Step-4 | P + G + Fz | 15 | 15.003683567047 | 15.0037 |
LoadCase-04 | Set 5 | Step-5 | P + G + Mx | 15 | 15.003950119019 | 15.0037 |
LoadCase-05 | Set 6 | Step-6 | P + G + My | 15 | 15.003848075867 | 15.0037 |
LoadCase-06 | Set 7 | Step-7 | P + G + Mz | 8.056 | 8.0588736534119 | 8.05923 |
由上表可以看到,各工况下监测点沿 x 方向的正应了的有限元解答与材料力学的理论解答基本一致,这说明上述有限元分析流程完全合理,各种参数设置准确无误。(结论下的有点早)
2.5.3 Mises应力云图对比
特定点处某一方向上应力的有限元解答与材力解答基本一致,还不足以说明上述 ANSYS 及 Abaqus 有限元分析的绝对准确无误,下面我们通过对比两种有限元分析软件得到的前梁段 Mises 应力云图,来说明以上有限元分析的合理性 (指分析流程和参数设置),以工况 LoadCase-02 为例,Mises 应力云图,如下图所示。
在 Abaqus 中,绘制应力云图前,需将 Avg 值调整为 100%,使得同一结点上由不同单元计算得到的应力值均参与平均。这是由于在 Abaqus 中并没有明显的结点解与单元解的区分,而是通过调整 Avg 值来调整云图显示的连续程度,Avg 值越大云图的连续性越好,当 Avg = 0 时,即与 ANSYS 中的单元解概念相对应;当 Avg = 100% 时,即与 ANSYS 中的结点解概念相对应。此处,我们对比结点解的 Mises 应力云图,故而 Avg 值要调整为 100%。在 Abaqus 中,Avg 的默认值为 75% 。
了解更多详见: 1. abaqus应力值导出并进行后处理(同一节点多个应力值如何处理?);
2. [前处理] 请问:AVG:75%是什么含义 【见1-9楼】;
由上图可以看到,Mises 应力云图存在明显差异,尤其是显示的 Mises 应力最小值,ANSYS 分析结果为 5.75036,Abaqus 分析结果为 0.249,两者相差约 23 倍,显然难以接受。
直觉告诉我们,一定是有什么地方没有设置对,事实上,直觉是对的。原来造成这一现象的原因是: 在默认情况下, ANSYS 为了节约内存,不显示/绘制高阶单元边中结点信息,而 Abaqus 默认情况下是显示的。因此,我们需要手动设置 ANSYS 高级绘图功能,其命令流如下:
/GRAPHICS,POWER ! 开启 PowerGraphics Display
/EFACET,2 ! 对于二阶单元,输出中间结点信息。
! /EFACET,1 ! 对于二阶单元,不输出中间结点信息。
/REPLOT ! Replot
由此可得,在工况 LoadCase-02 荷载作用下,由 ANSYS 和 Abaqus 绘制的前梁段 Mises 应力云图,如下图所示。
由上图可以看出,两软件绘制的 Mises 应力云图几乎完全一致,至此,我们可以得出结论: 上述有限元分析流程完全合理,各种参数设置准确无误。
2.6 疲劳计算用有限元结果文件的生成
事实上,以上两个有限元结果文件,即 nCodeInput.rst 和 nCodeInput.odb,还不能直接用于疲劳计算,需要将 LoadCase-01 ~ LoadCase-06 各工况中因预应力 P 及恒荷载 G 而产生的应力扣除。
为啥不直接计算单位荷载作用结果? 因为,初始工况 LoadCase-00 不一定是线性分析步,有可能非线性的,如螺栓预紧力的施加。
2.6.1 rst文件的生成
在 nCodeInput.rst 中,仅单位荷载作用下的有限元结果按如下所示命令流得到,并存储在结果集 Set 8 ~ Set 13 中。
特别注意: 尽量启动一个新的 ANSYS 界面运行以下命令流,否则容易报错,运行命令流前最好备份 nCodeInput.rst 文件。
FINISH
/CLEAR
/PREP7
SHPP,OFF,,NOWARN ! 关闭单元形状检测警告
CDREAD,DB,'CantileverBeam','cdb'
ALLSEL,ALL
EPLOT
FINISH
/POST1
*DO,i,1,6,1
INRES,ALL
FILE,'nCodeInput','rst',''
LCDEF,1,1
FILE,'nCodeInput','rst',''
LCDEF,2,i+1
ALLSEL,ALL
LCFACT,1,-1.0
LCASE,2
LCOPER,ADD,1
RAPPND,i+7,i+7
ALLSEL,ALL
*ENDDO
2.6.2 odb文件的生成
在 nCodeInput.odb 中,仅单位荷载作用下的有限元结果按如下所示 Python 脚本得到,并存储在分析步 Step 8 ~ Step 13 上。
特别注意: 尽量启动一个新的 Abaqus/CAE 界面运行以下Python 代码,否则容易报错,运行代码前最好备份 nCodeInput.odb 文件。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Python Version: 2.7.3
Abaqus/CAE 6.14-1
Email: liyang@alu.hit.edu.cn
=============================
"""
from abaqus import *
from abaqusConstants import *
from caeModules import *
from odbAccess import *
from driverUtils import executeOnCaeStartup
import regionToolset
odbpath = r"C:\Temp\nCodeInput.odb"
odb = openOdb(odbpath,readOnly=False) # odb文件/指定odb文件为读写模式
asm = odb.rootAssembly
steps = odb.steps
stepnames = steps.keys()
print(stepnames)
frame1 = odb.steps["Step-1"].frames[-1]
stress1 = frame1.fieldOutputs["S"] # 分析步最后一帧应力场数据
for i in range(6):
stepname = "Step-%s" % (i + 2)
newstepname = "Step-%s" % (i + 8)
time = 1.0 # 分析步时间
frame2 = odb.steps[stepname].frames[-1]
stress2 = frame2.fieldOutputs["S"]
stress3 = stress2 - stress1 # 对应数据相
step = odb.Step(name=newstepname, description="", domain=TIME, timePeriod=time)
frame = step.Frame(incrementNumber=1, frameValue=1.0, )
frame.FieldOutput(field=stress3, name="S")
odb.save()
odb.close()
由以上 命令流/Python脚本 即可创建最终用于疲劳分析的有限元结果文件:nCodeInput.rst 和 nCodeInput.odb ,文件内各结果集/分析步与荷载工况的对应关系如下表所示。
在 nCodeInput.rst 中,仅 Set 1、Set 7 ~ Set 13 最终用于疲劳计算,其中,Set 1 为初始恒荷载作用下的有限元结果,Set 7 ~ Set 13 为在初始分析步的基础上,各单位荷载作用下应力增量的有限元结果。同理,在 nCodeInput.odb 中,仅 Step 1、Step 7 ~ Step 13 最终用于疲劳计算,其中,Step 1 为初始恒荷载作用下的有限元结果,Step 7 ~ Step 13 为在初始分析步的基础上,各单位荷载作用下应力增量的有限元结果。
工况名称 | 结果集名称 | 分析步名称 | 加载信息 | 描述 | 荷载值 |
---|---|---|---|---|---|
LoadCase-00 | Set 1 | Step-1 | P + G | 轴向预压力荷载 + 竖向恒荷载 | P = -720 N G = -10 N |
LoadCase-01 | Set 2 | Step-2 | P + G + Fx | 轴向预压力荷载 + 竖向恒荷载 + 沿 x 轴方向单位集中力 | Fx = 100 N |
LoadCase-02 | Set 3 | Step-3 | P + G + Fy | 轴向预压力荷载 + 竖向恒荷载 + 沿 y 轴方向单位集中力 | Fy = 1 N |
LoadCase-03 | Set 4 | Step-4 | P + G + Fz | 轴向预压力荷载 + 竖向恒荷载 + 沿 z 轴方向单位集中力 | Fz =1 N |
LoadCase-04 | Set 5 | Step-5 | P + G + Mx | 轴向预压力荷载 + 竖向恒荷载 + 绕 x 轴方向的单位扭矩 | Mx = 1000 N·mm |
LoadCase-05 | Set 6 | Step-6 | P + G + My | 轴向预压力荷载 + 竖向恒荷载 + 绕 y 轴方向的单位弯矩 | My = 1000 N·mm |
LoadCase-06 | Set 7 | Step-7 | P + G + Mz | 轴向预压力荷载 + 竖向恒荷载 + 绕 z 轴方向的单位弯矩 | Mz = 1000 N·mm |
LoadCase-07 | Set 8 | Step-8 | Fx | 沿 x 轴方向单位集中力 | Fx = 100 N |
LoadCase-08 | Set 9 | Step-9 | Fy | 沿 y 轴方向单位集中力 | Fy = 1 N |
LoadCase-09 | Set 10 | Step-10 | Fz | 沿 z 轴方向单位集中力 | Fz =1 N |
LoadCase-10 | Set 11 | Step-11 | Mx | 绕 x 轴方向的单位扭矩 | Mx = 1000 N·mm |
LoadCase-11 | Set 12 | Step-12 | My | 绕 y 轴方向的单位弯矩 | My = 1000 N·mm |
LoadCase-12 | Set 13 | Step-13 | Mz | 绕 z 轴方向的单位弯矩 | Mz = 1000 N·mm |
三、FEInput/有限元结果的导入
现将有限元结果文件 nCodeInput.rst 和 nCodeInput.odb 分别拖入到有限元输入图形符号 FEInput1 中,以确定 rst 内各结果集合与其导入到 nCodeDL 后结果间的对应关系,.odb 内各分析不上的计算结果与其导入到 nCodeDL 后结果间的对应关系。
各种有限元结果文件导入到 nCodeDL 后,都将转化成 Result Case 形式展示。因此,我们必须清楚在原有限元结果文件中各荷载工况下的计算结果,与 Result Case 中对应关系 。
3.1 结果间的对应关系
工况名称 | 加载信息 | ANSYS .rst文件中结果集名称 | Abaqus .odb文件中分析步名称 | nCode FEInput中结果工况名称 |
---|---|---|---|---|
LoadCase-00 | P + G | Set 1 | Step-1 | LoadCase – 1 |
LoadCase-01 | P + G + Fx | Set 2 | Step-2 | LoadCase – 2 |
LoadCase-02 | P + G + Fy | Set 3 | Step-3 | LoadCase – 3 |
LoadCase-03 | P + G + Fz | Set 4 | Step-4 | LoadCase – 4 |
LoadCase-04 | P + G + Mx | Set 5 | Step-5 | LoadCase – 5 |
LoadCase-05 | P + G + My | Set 6 | Step-6 | LoadCase – 6 |
LoadCase-06 | P + G + Mz | Set 7 | Step-7 | LoadCase – 7 |
LoadCase-07 | Fx | Set 8 | Step-8 | LoadCase – 8 |
LoadCase-08 | Fy | Set 9 | Step-9 | LoadCase – 9 |
LoadCase-09 | Fz | Set 10 | Step-10 | LoadCase – 10 |
LoadCase-10 | Mx | Set 11 | Step-11 | LoadCase – 11 |
LoadCase-11 | My | Set 12 | Step-12 | LoadCase – 12 |
LoadCase-12 | Mz | Set 13 | Step-13 | LoadCase – 13 |
3.2 群组/Groups
DesignLife 可以将有限元模型分成不同的群组,所有下游操作均在所选组内进行。即给定分析域,有些次要位置没必要分析,可在群组中将其剔除。通常,我们以材料区分不同的计算区域。
若显示组内信息没有变化,则将 rst 文件重新命名后再导入。
| 梁段 | ANSYS 材料号 | nCodeDL 材料组名称 |
|–|–|–|–|
| 前梁段 | 107 | MAT_107 |
| 中梁段 | 132 | MAT_132 |
| 后梁段 | 159 | MAT_159 |
| 梁段 | ANSYS 材料号 | nCodeDL 材料组名称 |
|–|–|–|–|
| 前梁段 | Q235-MatA-107 | Q235-MATA-107 |
| 中梁段 | Q235-MatB-132 | Q235-MATB-132 |
| 后梁段 | Q235-MatC-159 | Q235-MATC-159 |
由上可知,ANSYS 中所定义的材料,在导入 nCodeDL 后,其材料群组名称为 MAT_材料号;Abaqus 中所定义的材料,在导入 nCodeDL 后,其材料群组名称即为 Abaqus 中所定义的材料名称,但字母全部变为大写。
四、MXD材料数据库
MXD database—This is the database format supported in GlyphWorks and DesignLife; data can be entered into the database using the nCode MaterialsManager. A valid material name corresponding to a database entry must be specifiedin the MaterialName property.
本文主要介绍以批处理方式创建 .mxd 文件,以 GUI 方式创建 .mxd 文件详见: nCodeDL 疲劳分析 简明教程 >> 三、材料映射 Material Mapping >> 3.1.3 创建自定义材料属性 .mxd 文件 。
The program runs from within the nCode GUI. It can also be run as a separate executable called ncmatdbt , which allows a subset of management commands to be used in batch on MXD material databases.
帮助文档: MaterialsManager User Guide (matsman.pdf) 。
4.1 材性.xml文件的创建
XML 指可扩展标记语言(Extensible Markup Language),是一种标记语言,它的设计宗旨是传输数据,而非显示数据。
XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。XML 没什么特别的,它仅仅是纯文本而已,任何文本编辑器均可以创建和边界 xml 文件。
可扩展标记语言 (XML) 于 1998 年 2 月 10 日成为 W3C 的推荐标准。XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。更多详见:XML 教程 。
在 nCode MaterialsManager 模块中,可以通过导入记录着材料疲劳属性数据的 .xml 文创建 MXD 材料数据库即 .mxd 文件,其 GUI 操作如下图所示。
在本文中,记录着材料疲劳属性数据的 .xml 文件由 Python 脚本创建,.xml 文件被命名为 Q235MatFatProps,其内定义的 S-N 曲线类型为 nCode SN Mean Stress Curve。创建 Q235MatFatProps.xml 文件的部分 Python 代码如下。
完整代码详见: nCodeDL 疲劳分析 各种代码 (私密博客,暂未公开,见谅) 。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Author: DalNur
Email: liyang@alu.hit.edu.cn
=============================
"""
def create_mfp_xml_file(xmlpath, MatFatProps):
"""创建材料疲劳属性的.xml文件/mfp - material fatigue properties
:param path: 创建的xml文件的绝对路径。
:param MatFatProps: 写入xml文件中的材料疲劳属性数据字典。
"""
blank4, blank8, blank12 = 4 * " ", 8 * " ", 12 * " "
with open(xmlpath, "w", encoding='utf-8')as f:
f.write('<nCodeMaterialImport Version="1">' + "\n")
f.write(blank4 + "<Objects>" + "\n")
......
for matname in MatFatProps.keys():
UST, E, MaterialType = MatFatProps[matname]
......
f.write(blank12 + '<property Name="Comments" Value="DalNur"/>' + "\n")
f.write(blank12 + '<property Name="E" Units="MPA" Value="%s"/>' % E + "\n")
......
f.write(blank12 + '<property Name="MaterialType" Value="%s"/>' % MaterialType + "\n")
f.write(blank12 + '<property Name="Ne" Units="CYCLES" Value="%s"/>' % Ne + "\n")
f.write(blank12 + '<property Name="Nfc" Units="CYCLES" Value="%s"/>' % Nfc + "\n")
f.write(blank12 + '<property Name="References" Value="GB 50017 DalNur"/>' + "\n")
......
f.write(blank4 + '</Objects>' + "\n")
f.write("</nCodeMaterialImport>")
if __name__ == "__main__":
MatFatProps = {}
# 材料1/以下数据均为虚构
MatName = "001_42CrMo_Mean_Curve"
UST, E, MaterialType = 435, 2.06E5, "14"
Nfc, Ne, SEls = 1E30, 1E30, 0
MeanStressPoints = {"-430": [[28.666627, 346], [9.566, 1.152104E6], [1.1919651, 3.35E18]], }
MatFatProps[MatName] = [UST, E, MaterialType, Nfc, Ne, SEls, MeanStressPoints]
xmlpath = r"D:\nCodeDL\Q235MatFatProps.xml "
create_mfp_xml_file(xmlpath, MatFatProps)
4.2 执行.xml转.mxd的Batch文件的创建/.bat文件
上述 Q235MatFatProps.xml 文件创建完成后,可通过 Batch Operation 方式创建 MXD 材料数据库即 .mxd 文件,并将其命名为 Q235MatFatProps.mxd 。
生成 Q235MatFatProps.mxd 的批处理文件即 .bat 文件亦可由 Python 创建,本处略。
完整代码详见: nCodeDL 疲劳分析 各种代码 。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Author: DalNur
Email: liyang@alu.hit.edu.cn
=============================
"""
def create_bat_file_4_mxd(batpath, mxdpath, xmlpath, xxxx):
"""创建生成mxd文件的bat文件/4=for
:param batpath: 创建的bat文件的绝对路径。
:param mxdpath: 创建的mxd文件的绝对路径。
:param xmlpath: 已存在的xml文件的绝对路径。
:param xxxx: Everything搜索。
"""
pass
双击 create_xml_file.bat 文件,即可执行由 Q235MatFatProps.xml 文件创建 Q235MatFatProps.mxd 文件,运行后将创建如下图所示的 3 个文件,其中,batlog.lst 文件为运行 bat 文件的日志文件,记录着 bat 文件执行的基本信息,如报错等;MaterialImport.log 为 nCode 程序由 xml 文件创建 .mxd 文件的日志文件;Q235MatFatProps.mxd 为最终创建的用于疲劳计算的材料库文件。
在 nCode MaterialsManager 模块中,可打开 Q235MatFatProps.mxd 文件,如下图所示。
五、载荷时序的处理
为了节约计算成本,需要对原始的一般时序荷载进行过滤加工,如过滤掉对疲劳影响很小的荷载工况,过滤掉时序中的毛刺等等。
5.1 雨流计数
雨流计数法 是 20 世纪 50 年代由英国的两位工程师 M.Matsuishi 和 T.Endo 提出来的。该计数法的主要功能是把实测载荷历程简化为若干个载荷循环,供疲劳寿命估算和编制疲劳试验载荷谱使用。它以双参数法为基础,考虑了动强度 (幅值) 和静强度 (均值) 两个变量,符合疲劳载荷本身固有的特性。雨流计数法主要用于工程界,特别在疲劳寿命计算中运用非常广泛。
完整代码详见: nCodeDL 疲劳分析 各种代码 。
5.2 原始载荷时序的过滤
毛刺过滤:去掉非峰谷值点、去掉相邻点间毛刺。
完整代码详见: nCodeDL 疲劳分析 各种代码 。
5.3 过滤后载荷时序的拆分
存在非线性分析时,荷载时序需正负拆分。
完整代码详见: nCodeDL 疲劳分析 各种代码 。
5.4 计算用时序荷载的创建
本文以 .txt 的时序荷载文件为例,介绍 nCode 是如何将其转化为求解器接受的 .s3t 文件的, .s3t 文件为二进制文件。
以 GUI 方式创建 .s3t 文件详见: nCodeDL 疲劳分析 简明教程 >> 四、载荷映射 Load Mapping >> 4.2 时序载荷映射 >> 4.2.1 创建时序通道 .s3t 文件 。
本文主要介绍以批处理的方式执行 .txt 格式的时序荷载文件转化为求解器接受的 .s3t 时序荷载文件。
5.4.1 设置文件的创建/.ast文件
运行如下代码即可创建 txt 载荷时序转换 s3t 载荷时序的设置文件 txt2s3t.ats 。
path = r"D:\nCodeDL"
atsname = "txt2s3t.ats"
atspath = path + "\\" + atsname
NumberOfHeaderLines = 1
create_ats_file_4_s3t(atspath, NumberOfHeaderLines)
完整代码详见: nCodeDL 疲劳分析 各种代码 。
5.4.2 txt转s3t的脚本文件的创建/.script文件
运行如下代码即可创建 txt 载荷时序转换 s3t 载荷时序的脚本文件 txt2s3t.script 。
path = r"D:\nCodeDL"
txtnames = ["TSLoads-Amp1-1000.txt", "TSLoads-Amp2-2000.txt", "TSLoads-Amp3-3000.txt"]
txtpaths = [path + "\\" + i for i in txtnames]
s3tnames = ["DalNur-" + i for i in txtnames]
counts = [1000, 2000, 3000, ]
scriptname = "txt2s3t.script"
scriptpath = path + "\\" + scriptname
create_script_file_4_s3t(scriptpath, txtpaths)
完整代码详见: nCodeDL 疲劳分析 各种代码 。
5.4.3 执行txt转s3t的Batch文件的创建/.bat文件
运行如下代码即可创建启动执行 txt 载荷时序转换 s3t 载荷时序的 .bat 文件 txt2s3t.bat 。
path = r"D:\nCodeDL"
batname = "txt2s3t.bat"
scriptname = "txt2s3t.script"
flowname = "txt2s3t.flo"
xxx = r"xxxxxxxxxxxxxxxxxxxxxxxxx"
batpath = path + "\\" + batname
scriptpath = path + "\\" + scriptname
flowpath = path + "\\" + flowname
create_bat_file_4_s3t(batpath, flowpath, scriptpath, xxx)
完整代码详见: nCodeDL 疲劳分析 各种代码 。
综上,我们创建了设置文件 txt2s3t.ats ,脚本文件 txt2s3t.script ,批处理文件 txt2s3t.bat ,工作流文件 txt2s3t.flo。以上各种文件与载荷时序 txt 文件是创建 nCode 求解器能接受的载荷时序文件 .s3t 文件必不可少的文件。
双击 txt2s3t.bat 文件,即可执行 txt 文件转化为 s3t 文件,程序执行完成后,将创建各与 txt 文件相对应的 s3t 文件及 1 个日志文件 txt2s3t.log 文件,日志文件记录着程序的运行情况,如下图所示。
双击任意一个 s3t 文件,即可查看转化后的载荷时序,如下图所示。
六、载荷通道与有限元结果间的匹配/.dcy文件的创建
循环周期/.dcy文件的创建。
实际工作中,载荷通常是多种事件和相应重复的叠加,不能够简单的用常幅值、时序或时间步载荷表示。
循环周期是载荷顺序和重复的叠加,代表复杂载荷的强大的、灵活的工具,可以包括任意常幅值、时序和时间步载荷的叠加,可以包括其他循环周期。
循环周期是用户定义的事件叠加,每一个事件有可定义的重复次数。
事件即载荷,可以是常幅值、时序或时间步载荷,一个循环周期中可以是多种载荷类型的混合。可以是其他的循环周期,嵌套的循环周期。例如,一个循环周期可以包括:一个常幅值载荷重复10次,一个时序载荷重复2次,另外的循环周期重复5次。
Miner 准则用于对所有事件和重复的损伤进行求和。
循环周期可以交互式的创建,编辑求解器中的载荷映射选项。循环周期也可以使用 Schedule Create 创建 *.sch 文件。用文本编辑器创建和修改 *.dcy循环周期文件。
以 GUI 方式创建 .dcy 文件详见博客: nCodeDL 疲劳分析 简明教程 >> 四、载荷映射 Load Mapping >> 4.4 循环周期 。
本文主要介绍以 Python 脚本的方式直接创建 .dcy 文件。
运行如下代码可创建载荷时序与有限元工况间的匹配关系文件 CantileverBeam.dcy 。
path = r"D:\nCodeDL"
txtnames = ["TSLoads-Amp1-1000.txt", "TSLoads-Amp2-2000.txt", "TSLoads-Amp3-3000.txt"]
s3tnames = ["DalNur-" + i[:-4] + ".s3t" for i in txtnames]
counts = [1000, 2000, 3000, ]
num = len(s3tnames)
FELoadCases = [1, 8, 9, 10, 11, 12, 13] # 有限元荷载工况编号
TimeSeriesChans = [1, 2, 3, 4, 5, 6, 7] # s3t中与有限元荷载工况相对应的荷载通道号
DutyCycle = {} # 循环周期字典
for i in range(num):
s3tname, count = s3tnames[i], counts[i]
DutyCycle[s3tname] = [count, FELoadCases, TimeSeriesChans]
dcyname = "CantileverBeam.dcy"
dcypath = path + "\\" + dcyname
create_dcy_file(dcypath, DutyCycle)
完整代码详见: nCodeDL 疲劳分析 各种代码 。
CantileverBeam.dcy 文件中定义的匹配关系可按如下方式查看。
七、作业设置/提交计算
7.1 作业(求解器)设置/.dcl文件的创建
!
! Job
!
SetProperty("Job",Description,)
SetProperty("Job",AuditFilename,)
SetProperty("Job",OverwriteAuditFile,"Append")
SetProperty("Job",ValidateAutoConfigureLoading,"Warn")
SetProperty("Job",IgnoreUnusedArguments,False)
SetProperty("Job",MemoryLogging,False)
SetProperty("Job",NumAnalysisThreads,)
本文主要介绍以 Python 脚本的方式直接创建 .dcl 文件,部分代码如下。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Author: DalNur
Email: liyang@alu.hit.edu.cn
=============================
"""
import os
def create_dcl_file(dclpath, rstpath, matname, dcypath, mxdpath, sncurvename, corenum, sgname,
outfname):
"""创建.dcl文件
:param dclpath: 创建的dcl文件的绝对路径。
:param rstpath: 有限元结果文件的绝对路径。
:param matname: 进行疲劳计算的材料名称/材料组。
:param dcypath: dcy文件的绝对路径。
:param mxdpath: mxd文件的绝对路径。
:param sncurvename: 计算采用的SN曲线名称。
:param corenum: 疲劳计算所调用的核数。
:param sgname: 应力梯度修正文件名称.dat文件/StressGradients。
:param outfname: 疲劳计算完成后输出的结果文件的文件名称,可以为.odb/.rst/.hyp/.csv/.fer格式。
"""
(filename, extension) = os.path.splitext(outfname)
# 获取输出文件的拓展名extension
OutputFormat = {".odb": "ODB", ".rst": "ANS", ".fer": "FER", ".hyp": "HYP", ".csv": "CSV"}
try:
format = OutputFormat[extension]
except:
format = "FER"
blank4, blank8, blank12 = 4 * " ", 8 * " ", 12 * " "
with open(dclpath, "w", encoding='utf-8')as f:
f.write("!" + "\n")
f.write("! Job" + "\n")
f.write("!" + "\n")
......
......
......
f.write('DoCommand("SNEngine", SetAbsMaxStressDom, Output="No")' + "\n")
f.write('DoCommand(job,run)' + "\n")
f.write('' + "\n")
完整代码详见: nCodeDL 疲劳分析 各种代码 。
若有限元结果文件采用 ANSYS 分析结果,即采用 nCodeInput.rst 文件,则运行以下代码可创建相应的作业设置文件,作业设置文件的名称为 AnsysCantileverBeam.dcl 。
path = r"D:\nCodeDL" # 文件夹路径
dclname = "AnsysCantileverBeam.dcl" # dcl文件名称
rstname = "nCodeInput.rst" # 有限元结果文件名称
matname = "MAT_107" # 前梁段所用材料在nCode中的名称
dcyname = "CantileverBeam.dcy" # 循环周期文件.dcy文件名称
mxdname = "Q235MatFatProps.mxd" # 材料疲劳属性数据库文件.mxd名称
sncurvename = "001_Q235_Mean_Curve" # 所采用的材料库中的平均应力SN曲线簇名称
corenum = 10 # 疲劳计算所使用的核数
sgname = "Q235.dat" # 应力梯度修正文件名称
outfname = "AnsysCantileverBeam.csv" # 输出文件的文件名称/OutputFilename
outfname = "AnsysCantileverBeam.hyp" # 输出文件的文件名称/OutputFilename
dclpath = path + "\\" + dclname # dcl文件绝对路径
rstpath = path + "\\" + rstname # 有限元结果文件绝对路径
dcypath = path + "\\" + dcyname # dcy文件绝对路径
mxdpath = path + "\\" + mxdname # mxd文件绝对路径
create_dcl_file(dclpath, rstpath, matname, dcypath, mxdpath, sncurvename, corenum, sgname, outfname)
若有限元结果文件采用 Abaqus 分析结果,即采用 nCodeInput.odb 文件,则运行以下代码可创建相应的作业设置文件,作业设置文件的名称为 AbaqusCantileverBeam.dcl 。
path = r"D:\nCodeDL" # 文件夹路径
dclname = "AbaqusCantileverBeam.dcl" # dcl文件名称
rstname = "nCodeInput.odb" # 有限元结果文件名称
matname = "Q235-MATA-107" # 前梁段所用材料在nCode中的名称
dcyname = "CantileverBeam.dcy" # 循环周期文件.dcy文件名称
mxdname = "Q235MatFatProps.mxd" # 材料疲劳属性数据库文件.mxd名称
sncurvename = "001_Q235_Mean_Curve" # 所采用的材料库中的平均应力SN曲线簇名称
corenum = 10 # 疲劳计算所使用的核数
sgname = "Q235.dat" # 应力梯度修正文件名称
outfname = "AbaqusCantileverBeam.csv" # 疲劳计算完成后损伤结果存储文件名称
outfname = "AbaqusCantileverBeam.hyp" # 疲劳计算完成后损伤结果存储文件名称
dclpath = path + "\\" + dclname # dcl文件绝对路径
rstpath = path + "\\" + rstname # 有限元结果文件绝对路径
dcypath = path + "\\" + dcyname # dcy文件绝对路径
mxdpath = path + "\\" + mxdname # mxd文件绝对路径
create_dcl_file(dclpath, rstpath, matname, dcypath, mxdpath, sncurvename, corenum, sgname, outfname)
特别注意: 虽然,记录损伤结果的输出文件格式可以为 .odb 和 .rst ,但尽量不要采用这两种格式,因为,这两种格式的结果文件与其软件版本依赖严重,很容出错。若查看损伤云图则尽量输出 .hyp 格式的结果文件。若只关心损伤最大值,则输出 .csv 格式的结果文件即可。
7.2 提交计算/.bat文件的创建
至此,以批处理方式执行疲劳计算的全部输入文件已经创建完毕,接下来,只需要创建一个用于提交疲劳计算的.bat 文件即可。其 Python 代码如下。
path = r"D:\nCodeDL" # 文件夹路径
batname = "AnsysFinalRun.bat" # dcl文件名称
dclname = "AnsysCantileverBeam.dcl" # 有限元结果文件名称
dclpath = path + "\\" + dclname # dcl文件绝对路径
batpath = path + "\\" + batname # 有限元结果文件绝对路径
create_bat_file_4_run_job(batpath, dclpath, dtprocpath)
path = r"D:\nCodeDL" # 文件夹路径
batname = "AbaqusFinalRun.bat" # dcl文件名称
dclname = "AbaqusCantileverBeam.dcl" # 有限元结果文件名称
dclpath = path + "\\" + dclname # dcl文件绝对路径
batpath = path + "\\" + batname # 有限元结果文件绝对路径
create_bat_file_4_run_job(batpath, dclpath, dtprocpath)
以上代码分别创建 AnsysFinalRun.bat 和 AbaqusFinalRun.bat 。双击 AnsysFinalRun.bat 文件,nCode 将调用 nCodeInput.rst 文件,执行疲劳计算,最终生成损伤结果文件 AnsysCantileverBeam.hyp 。双击 AbaqusFinalRun.bat 文件,nCode 将调用 nCodeInput.odb 文件,执行疲劳计算,最终生成损伤结果文件 AbaqusCantileverBeam.hyp 。
八、后处理
8.1 损伤云图/.hyp
最终生成的损伤结果文件 AnsysCantileverBeam.hyp 和 AbaqusCantileverBeam.hyp 可通过 HyperView 查看。
- AnsysCantileverBeam.hyp + CantileverBeam.cdb
- AbaqusCantileverBeam.hyp + nCodeInput.inp
- 损伤云图的对比
由上图可以看到,两者计算结果基本一致,至此,以批处理方式执行悬臂梁的高周疲劳分析全部流程基本结束。
8.2 结果报告/.csv
参见官方分析实例: D:\Program Files\nCode\nCode 2018.0 64-bit\GlyphWorks\demo\designlife\13_BatchDesignLife 。
若创建 dcl 文件时,分别将 outfname 设置为 AnsysCantileverBeam.csv 和 AbaqusCantileverBeam.csv ,则损伤结果将记录在这两个 csv 文件中,如下图所示。
九、致谢
特别感谢 CXC 同学提供的无私帮助,使得本文提到的诸多功能得以顺利实现!
十、尾声
以上,便是 nCode 高周疲劳 批处理计算 的简单介绍。
因篇幅有限,某些功能未做详细介绍,如有疑问,欢迎邮件交流。
Email: liyang@alu.hit.edu.cn 。
仅以此文为我断断续续一年多的 nCode 批处理相关工作做一个总结。
与此同时,也希望能够为初学者/有需要的人提供多一点参考。
本文仅用于个人学习,除此之外,无其他任何用途。
因个人水平有限,文中难免有所疏漏,还请各位大神不吝批评指正。
胸藏文墨怀若谷,腹有诗书气自华,希望各位都能在知识的 pāo 子里快乐徜徉。
本文逻辑清楚,内容详实,引例丰富。
欢迎大家点赞、评论及转载,转载请注明出处!
为我打call,不如为我打款!
最后,祝各位攻城狮们,珍爱生命,保护发际线!
十一、参考文献
[01]. DesignLife Theory Guide.
[02]. Batch Operation User Guide.
[03]. DesignLife Worked Examples.
[04]. MaterialsManager User Guide.
[05]. File Formats User Guide.
[06]. GlyphWorks Fatigue Theory Guide.
[07]. ANSYS Mechanical APDL Element Reference.
[08]. ANSYS Mechanical APDL Command Reference.
[09]. Abaqus Scripting Reference Guide.
[10]. DesignLife Programmers Manual