ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

EBSD到Abaqus全流程:MTEX晶粒重构与网格生成

EBSD到Abaqus全流程:MTEX晶粒重构与网格生成 简介晶体塑性有限元模拟需要将真实微观组织转化为可计算的有限元模型。电子背散射衍射EBSD技术能够获取材料内部的晶粒形貌与晶体取向信息而Abaqus作为通用有限元平台其求解精度高度依赖初始网格和取向数据的准确性。本文介绍如何借助MTEX工具箱在MATLAB环境中完成EBSD数据预处理、晶粒重构、多边形网格剖分以及Bunge欧拉角的正确导出最终生成可无缝导入Abaqus的inp文件。该流程有效解决了真实组织形貌与有限元模型脱节的痛点为晶界应力、织构演化、微裂纹扩展等工程模拟提供了可靠的前处理路径适合正在开展晶体塑性研究的工程师与科研人员参考。 我最早干这件事的时候还是手动在MATLAB里把EBSD的每个晶粒抠出来再一笔一笔写Abaqus的inp文件。后来换了MTEX这套工具箱整个流程从“想放弃”变成“顺滑”。今天就把这条从EBSD到Abaqus网格和晶粒取向的完整链路梳理一遍核心工具是MTEX MATLAB最后落点是Abaqus。这个过程适合正在做晶体塑性有限元、晶界应力、微裂纹扩展或者织构演化模拟的朋友尤其是被“怎么把真实组织变成可算模型”卡住的人。之所以强调“真实组织”是因为很多人一开始用的是Voronoi随机生成晶粒那个模型虽然好画但缺少真实的晶粒尺寸分布、晶界形貌和初始织构。而EBSD数据能把你热处理、轧制、焊接之后得到的真实微观组织直接搬进有限元里。这篇文章不打算铺垫太多理论只讲怎么落地从读取原始数据到MTEX里重构晶粒再到生成网格、写取向最后进Abaqus能算。1. 从EBSD彩图到Abaqus模型为什么要绕这么一圈1.1 真实组织形貌的价值不是玄学是物理EBSD电子背散射衍射采集出来的是每个像素点的晶体取向MTEX把这些像素点按取向差聚合成晶粒再输给Abaqus做晶体塑性模拟。这套流程的核心目的是把“真实的晶粒形貌”和“真实的初始取向”同时带到有限元网格里。普通的多晶模型可以用Voronoi图生成但它有几个硬伤晶粒尺寸分布是人为设定的、晶界是数学直线、晶粒形状过于规整最重要的是没有真实的取向数据。对于做单晶或者简单双晶验证来说Voronoi够用但一旦涉及多晶织构演化、晶界滑移、应力集中位置预测真实EBSD组织带来的晶粒形态和取向分布差异会直接影响计算结果。另一个容易被忽略的点是EBSD还能带出相分布。比如双相钢里的铁素体和马氏体、钛合金里的α和β相这些相信息在MTEX里可以保留到最后的单元集合中。也就是说通过一条链路不仅能把几何弄进Abaqus还能把相、晶粒ID、取向全部带进去后面的子程序就不需要再猜每个单元是什么组织了。1.2 三条路径对比为什么选MTEX自己做网格从EBSD到Abaqus模型目前主流路径有三条我列个表方便对比路径网格来源优点缺点路径A像素直转单元每个EBSD像素生成一个单元流程最简单不改原数据单元数量爆炸计算效率低路径BMTEX重构晶粒多边形剖分晶粒边界多边形网格化单元数量适中保留晶界形貌可控性最高需要处理共享边界和节点合并路径CDREAM.3D/Neper等软件体素化或PFC网格功能完善适合三维重构多学一套软件格式转换麻烦定制不灵活我最终选择路径B不是因为路径C不好而是因为很多EBSD扫描本来就是二维截面用MTEX直接在MATLAB里处理完数据之后紧接着生成网格和inp文件变量全在同一个工作空间排查问题快得多。而且遇到特殊需求比如只保留某几个特定取向的晶粒、按晶粒直径筛掉小晶粒、把晶界单独提取出来做界面单元路径B都能非常灵活地改。2. 预处理与晶粒重构这步没做对后面全是废网格2.1 数据加载与晶体对称性检查MTEX加载EBSD数据的核心命令很简单% 老版本写法 % ebsd loadEBSD(sample.ctf); % 新版本MTEX 5.10推荐写法 ebsd EBSD.load(sample.ctf);CTF是牛津仪器Channel 5的格式.ang是EDAX/OIM的格式.crc是常见第三方格式MTEX大部分都支持。加载之后第一件事不是急着画图而是先确认一件事晶体对称性crystal symmetry是否从文件里正确读出来了。% 查看相位与对称性信息 ebsd.CSList如果这里显示为空的或者跟你的材料明显不符需要手动指定。比如体心立方铁CS crystalSymmetry(m-3m, [2.866 2.866 2.866], mineral, Ferrite); ebsd EBSD.load(sample.ctf, CS, CS);这一步很多人忽略结果后面算取向差、算晶粒、输出欧拉角全部乱了。晶体对称性一旦设错晶粒重构的阈值角度会凭空多出很多对称等价的取向差直接导致同一颗晶粒被切成好几块。另外一个容易翻车的是坐标方向。EBSD采集的坐标和MTEX默认绘图坐标经常存在镜像或旋转关系尤其是从扫描电镜里导出的图像有时候Y轴是向下的。你打印一张图plot(ebsd, coordinates, on);然后把这张图跟原始EBSD软件里的IPF图对比看晶粒形貌是不是左右或者上下反了。如果反了可以在MTEX里做翻转或旋转处理% 以Y轴为镜像轴翻转 ebsd flip(ebsd, y);坐标不一致的问题在你把网格导进Abaqus后会暴露得很明显晶界形貌对不上、显微硬度和模拟区域错位、微裂纹位置完全对不上。所以这个过程一定要在早期就检查。2.2 清洗噪点与未索引点EBSD扫描很难做到100%索引尤其在晶界附近、析出相处、变形严重区域会有大量未索引点或者错误索引点。如果不处理晶粒重构时会出现一堆像素级的“假晶粒”。我的标准预处理流程是这样% 只保留已索引点 ebsd ebsd(indexed); % 可选对未索引区域做邻域填充数据质量不太差时用 % 注意这会让坏点“继承”邻居取向属于人为修饰谨慎使用 % ebsd fill(ebsd);ebsd(indexed)这条命令会把所有未索引点直接剔除。如果未索引点比例很低比如低于5%直接剔除对后续影响不大。如果未索引点比例高比如某些变形试样超过20%就得评估一下是不是整个区域都要剔除还是用更保守的填充策略。噪点的破坏力在于它会产生大量面积只有1~2个像素的细小晶粒。这些小晶粒在后续网格剖分阶段会让剖分算法生成极度细长或者极小面积的单元。Abaqus里这些单元极易发生畸变和收敛问题。2.3 晶粒重构参数阈值角、最小尺寸、晶界平滑MTEX重构晶粒的核心是calcGrains需要定两个关键参数% 取向差阈值10度低于该角度的相邻像素合并为同一晶粒 grains calcGrains(ebsd, angle, 10*degree); % 剔除面积过小的“晶粒”这里按像素数门槛 grains grains(grains.grainSize 10);取向差阈值的选取取决于材料本身。冷变形金属亚晶多晶界取向差分布宽阈值可以取到10~15度再结晶材料或者铸态组织阈值取5~10度比较合适。最常见是10度这也是很多文献默认值。grains.grainSize 10会剔除掉所有像素数小于10的细碎区域效果非常明显。我一般建议从10开始试如果发现晶粒边界变得支离破碎、出现大量锯齿就往上加比如20或30如果发现细小晶粒被误删了就往下调。晶界平滑是很有争议的一步我自己的经验是轻度使用可以重度过分修饰不可取。% 平滑1次保留原本晶界走势 grains smooth(grains, 1);smooth会改变晶粒边界坐标相当于给晶界做了一次滤波。原始EBSD晶界是逐像素的锯齿状直接用来剖网格会产生很多小尖角严重影响单元质量。但平滑次数过多晶粒面积会明显变化晶界曲率也会失真。所以一般我只平滑1到2次并且每次平滑后都检查一下面积损失。面积损失超过2%就不建议继续平滑了。3. 网格生成像素直转还是晶粒多边形剖分3.1 像素直转的适用范围与单元写法最简单粗暴的网格生成办法是把每个EBSD像素点直接变成一个单元像素中心作为节点或单元积分点。比如一张500×400的扫描图大概20万个点生成20万个平面单元Abaqus完全扛得住。但这种做法的问题也很明显单元数量大求解慢特别是UMAT/VUMAT每一步要算晶体塑性本构的时候像素本身就是正方形生成的四边形单元长宽比固定但晶界处因为像素取舍会出现锯齿扫描区域越大单元数量增长越不可控。像素直转用在验证阶段很有价值。比如你刚写好一个晶体塑性UMAT想快速跑通流程直接用像素单元可以跳过网格剖分先验证子程序是否正常。它不适合作为正式计算模型的方案原因就是计算效率。如果你想用像素直转思路是把EBSD点云按规则的x、y排布重新组织成网格节点每个像素格作为一个CPE4单元。需要注意MTEX中的EBSD数据是以“点列表”存储的虽然排列规则但你需要根据ebsd.x和ebsd.y复原出矩阵索引才能正确生成单元连接。3.2 晶粒多边形三角剖分的实施建议正式计算我推荐用晶粒多边形剖分。因为calcGrains之后MTEX已经把所有晶粒边界提取成了多边形我们可以从这些多边形出发生成一套“保留晶界形貌、单元数量可控”的网格。关键数据有两个V grains.V; % 所有多边形顶点的坐标 poly grains.poly; % 每个晶粒的多边形poly{i}是顶点索引列表有了这两个变量就能拿到每个晶粒边界的坐标序列。接下来就是对这个多边形集合做三角剖分。这一步有很多种做法MATLAB File Exchange上的distmesh2d适合做有约束的三角形网格Neper软件如果你不介意多学一个工具它对多晶多边形网格化很专业自己写基于Delaunay的带约束剖分灵活但工程量不小。我的建议是晶粒数量不多几百个以内时直接用distmesh2d对每个晶粒逐一剖分然后合并节点晶粒数量很多时考虑用Neper或者先对晶粒边界做一次整体背景网格剖分再映射晶粒ID。逐一剖分最麻烦的点是共享边界的节点合并。相邻两个晶粒分别剖分边界上的节点位置往往不一致直接拼接会形成裂缝。解决办法是先提取所有晶粒边界的公共边把这些公共边上的节点统一强制对齐然后再做内部剖分。实际操作中一个简单有效的方式是把所有晶粒边界点放到一个集合里对坐标做近似去重让共享边界点是同一批节点然后对每个晶粒内部用Delaunay生成内部节点和单元最后把边界节点、内部节点、单元连接信息合并成一套模型。这个流程用MATLAB写代码量不短但都是常规操作一次调通后面换任何EBSD数据都能复用。3.3 网格检查三步面积、边界、单元质量网格剖分完千万别急着写inp。先做三个检查第一面积对比。对比每个晶粒的网格总面积和MTEX计算的晶粒面积误差应该控制在1%以内。如果偏差大说明剖分过程中多边形丢了边或内部挖了洞。areaEBSD area(grains); areaMesh zeros(length(grains), 1); % 根据单元节点坐标用叉积公式计算每个晶粒面积 % 这里需要你按单元-晶粒编号映射逐个累加第二边界闭合。检查每条晶粒公共边界两侧的节点是否完全对应。如果一侧有节点另一侧没有说明共享边没有焊好Abaqus里会出现单元分离。第三单元质量。简单看两点最小内角是否大于20度最长边与最短边之比是否过大。出现极端细长单元的位置几乎都在小晶粒和晶界交汇处。我的经验是在网格剖分之前就把过于细小的晶粒剔除掉能省掉后面好多网格优化工作。4. 取向数据写入Abaqus欧拉角约定与两种落地方案4.1 MTEX输出的欧拉角到底是什么EBSD的取向通常用Bunge约定的欧拉角(φ1, Φ, φ2)表示单位是弧度。MTEX中也非常自然地用这套约定。ori grains.meanOrientation; % 每个晶粒的平均取向 phi1 ori.phi1 ./ degree; Phi ori.Phi ./ degree; phi2 ori.phi2 ./ degree;这里有个细节grains.meanOrientation给出的是晶粒平均取向它是对晶粒内所有像素取向求平均后的结果。如果晶粒内部取向梯度很大变形金属里常见平均取向会“平滑”掉一部分信息。如果你做的是初始织构对力学性能的影响平均取向够了如果你要精细模拟晶粒内部取向梯度那就不能用平均取向而要用每个像素的取向分别赋给对应单元。这个选择会直接影响后续模拟的精度和计算成本。欧拉角从MTEX到Abaqus还有一个隐藏的“转置坑”。MTEX的orientation.matrix给出的旋转矩阵和Abaqus里*ORIENTATION期望的局部坐标方向余弦行和列经常是反的。我踩过一次之后凡是写进inp之前都要用一个已知晶粒做手算验证。4.2 方案一每个晶粒一个ORIENTATION如果你的模型里晶粒数量不超过几百个我推荐用Abaqus原生*ORIENTATION方式每个晶粒各自定义一组局部坐标方向然后在*SOLID SECTION里指定。在inp里大概长这样*ORIENTATION, NAMEORI-001, SYSTEMRECTANGULAR 0.982, 0.002, 0.018, -0.012, 0.994, -0.013, -0.015, 0.014, 0.999 *ELSET, ELSETGrain001, GENERATE 101, 200, 1 *SOLID SECTION, ELSETGrain001, MATERIALMAT-1, ORIENTATIONORI-001注意*ORIENTATION后面那一行是3×3的方向余弦矩阵代表局部坐标系三个轴在全局坐标系下的分量。这个矩阵需要由Bunge欧拉角转出来。MTEX里通常是rot orientation.byEuler(phi1*degree, Phi*degree, phi2*degree, Bunge, CS, CS); R matrix(rot); % 3x3旋转矩阵然后在写inp时按Abaqus期望的格式输出。这里一定要做一次已知方向的验证比如一个立方晶粒欧拉角全为零时*ORIENTATION应该是单位矩阵Abaqus Visualization里画出来应该看到三个坐标轴与全局坐标完全重合。这个方案的优点是可视化直观、Abaqus原生支持好、不需要写额外的子程序代码。缺点是每个晶粒都要生成一个Section和Orientation晶粒数量一多inp体积急剧膨胀而且后续如果晶粒数上千Abaqus对Section数量的处理也会变得麻烦。4.3 方案二把欧拉角写进状态变量如果晶粒数量很大或者你用的是自己写的UMAT/VUMAT我更推荐把欧拉角作为初始状态变量传给单元而不是依赖*ORIENTATION。比如你的UMAT里规定SVARS(1)、SVARS(2)、SVARS(3)分别存phi1、Phi、phi2那么在inp里可以这样初始化*INITIAL CONDITIONS, TYPESOLUTION 101, 0.024, 0.531, 0.017 102, 0.331, 0.208, 0.002 ...这种做法的本质是让“取向”成为一个随单元变化的初始场子程序在第一步开始时读入这些值之后完全由本构更新。它绕开了Abaqus本地坐标系的定义问题尤其适合那些在UMAT里已经有自己旋转逻辑的晶体塑性模型。我在实际中使用这种方案比较多原因有三个不需要为每个晶粒生成独立的Section和Orientation一个Elset、一个Material就搞定晶粒数量和单元数量再大也只是一行一行的数据写盘而已后续想在某个特定晶粒或者特定区域内改初始取向只需要改那一行数据不用动网格。缺点是*INITIAL CONDITIONS, TYPESOLUTION按单元写入单元多的时候inp文件会很大而且如果不小心把单元编号弄错位整个模型的取向分布会整体错乱。后面我会专门说这个坑。5. 生成inp文件的代码骨架与关键细节5.1 节点、单元、set、section的组织整个流程的终极目标是生成一个可被Abaqus正确导入的inp文件。一个基本的结构是这样*NODE 1, 0.0000, 0.0000, 0.0000 2, 0.0230, 0.0000, 0.0000 ... *ELEMENT, TYPECPE3, ELSETALL_ELEM 1, 1, 2, 3 2, 1, 3, 4 ... *ELSET, ELSETGrain001 1, 2, 3, 4, 5, 6 ... *SOLID SECTION, ELSETGrain001, MATERIALMAT-1MATLAB里用fprintf写文件的骨架大概是这样fid fopen(ebsd_model.inp, w); fprintf(fid, *NODE\n); for i 1:size(nodes, 1) fprintf(fid, %d, %.6f, %.6f, 0.0\n, ... i, nodes(i, 1), nodes(i, 2)); end fprintf(fid, *ELEMENT, TYPECPE3, ELSETALL_ELEM\n); for e 1:size(elems, 1) fprintf(fid, %d, %d, %d, %d\n, ... e, elems(e, 1), elems(e, 2), elems(e, 3)); end fprintf(fid, *ELSET, ELSETGrain001\n); ... fclose(fid);这里有几个容易踩的细节一是坐标单位。EBSD原点坐标通常以微米为单位比如x坐标是从0到500微米。如果你在Abaqus里用微米制那材料参数弹性模量、硬化参数也需要全部统一到微米制。如果你习惯用毫米或米就需要对坐标做缩放。我一般直接用微米因为EBSD天然就是这个量纲省得换算但一定要确定材料参数的单位制也一致否则应力应变差几个数量级。二是单元类型。二维EBSD截面我一般用CPE3平面应变三节点三角形或CPS3平面应力。如果你生成的是四边形可以用CPE4。如果做三维柱状晶假定的模型可以把二维三角形网格沿厚度方向拉伸成C3D6棱柱单元。这个拉伸在MATLAB里做也不复杂只是节点和单元编号要按层规律排列。三是*ELSET每行最多建议放16个单元编号超过后换行不然Abaqus导入时容易出现格式解析问题。虽然现代Abaqus对一行放多少数据比以前宽容很多但保险起见还是多换几行。5.2 单元编号和晶粒归属的错位陷阱单元编号和晶粒归属错位是这类项目最危险的bug。发生原因往往是你在MATLAB里对晶粒做了筛选或者排序但写*ELSET时没有同步更新单元对应的晶粒编号。最后表现出来就是Abaqus里看晶粒分布形貌边界是对的但一查某个单元的取向和该晶粒实际平均取向完全对不上。我的规避办法是网格生成过程中始终维护一个elemGrainID数组长度等于单元总数值为每个单元所属的晶粒编号。整个写inp阶段所有fprintf都从同一个索引出发绝不单独写for循环。% elemGrainID 必须与 elems 一一对应 for g 1:numGrains idx find(elemGrainID g); % 如果该晶粒没有单元极小晶粒被剔除跳过 if isempty(idx), continue; end fprintf(fid, *ELSET, ELSETGrain%03d\n, g); fprintf(fid, %d, , idx); fprintf(fid, \n); end顺便说一句如果某个晶粒在网格剖分阶段因为面积太小没有生成合格单元它就会在elemGrainID里缺失。这种情况如果不处理Abaqus里会少一段材料区域变成空洞。所以我在剔除小晶粒时会把晶粒面积阈值和网格剖分的最小单元边长关联起来避免出现“被保留但没被剖出来”的尴尬状态。6. 实测复盘最容易翻车的三个环节6.1 EBSD图与Abaqus模型图左右镜像我在本文还有配套的精品资源点击获取
返回列表