01三条路,先看代价
「材料复用」听起来是一件事,实际上取决于你手里有什么、要搬到哪里去。 先把三条路和各自的代价摆出来:
| 路子 | 适合的场合 | 代价 |
|---|---|---|
| 复制整个 model | 新模型和旧模型是同一个项目的变体,几何也要接着用 | 材料不能单独走,跟着几何、装配、分析步、载荷一起过去;只要材料就要删剩下的 |
| 导出成 JSON 再导入 | 只要材料,且要跨文件、跨机器、跨同事传 | 只覆盖插件读得出来的块,读不出来的会被点名列出;导出这一项要求授权在有效期内 |
| 写 Python 脚本重建 | 材料要按参数批量生成,或者要嵌进已有的建模脚本里 | 每一个参数名、每一个常量都要自己写对,写错的那部分没人替你拦 |
这三条不是互斥的。实际项目里常见的组合是: 用导出把已有的材料落成一个文件, 再用脚本对这个文件做批量改动(比如整体换单位制、按温度插几个点), 然后导回去。文件在中间那一步是可读可 diff 的纯文本, 这是它比另外两条都强的地方。
02路 A:复制整个 model
最快的一条,也是最容易留下后患的一条。 它的问题不在「不好用」,而在粒度: Abaqus 里材料是挂在 model 下面的, 复制 model 就是把这个 model 下的全部内容复制一份, 材料没法单独拎出来走。
于是新模型里会多出这些你并不想要的东西:
- 旧的几何和网格 —— 通常要整个删掉重建
- 旧的 Section 和 Section Assignment —— 指向旧几何,删几何时会一并断掉
- 旧的分析步、载荷、边界条件、接触对
- 旧的作业输出请求,包括你上个项目临时加的那几个变量
还有一件事这条路做不到:它不产生任何能给别人的东西。 同事问「你那个不锈钢的参数发我一下」, 答案不能是「我把整个 cae 发你」—— 那是几百 MB,而且带着你不一定想给的几何。
所以路 A 只在一种场合是最优的:新模型确实是旧模型的变体, 几何、分析设置本来就要接着用,材料只是顺便跟过来的。 剩下的场合都该看路 B。
03路 B:导出成 JSON 再导回来
1.4 起插件多了一个反方向的功能: 把模型里已有的材料写回标准 JSON,再导回任何一个模型。 这条路只搬材料,产物是一个几 KB 的纯文本文件, 能发微信、能进 git、能用记事本改。
导出对话框里有什么
对话框分三块:导出路径、要导出的材料、来源模型。 材料列表默认全选, 上面有一个筛选框,输入的词按空格分开、全部命中才显示,不区分大小写 —— 输 steel plate 会留下名字里同时含这两个词的材料。 列表下方有一行状态,随勾选实时变:
共 12 种材料 —— 已勾选 12 种。
筛选后显示 3 / 12 —— 已勾选 5 种(含未显示的)。第二行那个括号是有意写的:筛选只影响显示,不影响勾选。 筛掉的材料如果之前勾着,导出时还是会出去。 这一点在「只想导那三种」的时候要注意 —— 先按清空、再筛、再全选,才是干净的做法。
请至少勾选一种要导出的材料。;路径没填则是请选择导出路径。这两条都在提交前拦,不会写出半个文件。导出的文件长什么样
顶层是一个数组,不带 materials 外壳 —— 这两种写法导入侧都收,所以往返成立。 中文描述按原字符写,不会变成 \u4e2d\u6587 那种转义, 缩进两格,可以直接读。
比较值得注意的是它的形态归一规则, 因为导出来的文件和你手写的可能长得不一样,但意思完全相同:
| 情况 | 写成什么 |
|---|---|
| 只有一行、列数刚好、不带温度依赖 | 命名键,例如 elastic 写成 youngsModulus 加 poissonsRatio |
| 只有一列、单行 | 一个裸数字,例如 density 直接是 7.85e-9 |
| 多行,或带温度列 | 显式 table,并把 temperatureDependency 明写成 true |
| damage 下的四个模型 | 一律显式 table,即使只有一行 |
另一类归一是默认值被省略。 损伤演化的软化方式是线性、退化方式取最大、热膨胀的零应变温度是 0、 塑性硬化是等向、弹性是等向 —— 这些等于 Abaqus 默认值的项不会写进文件。 省略之后导回来还是同一个值,所以省得起。 反过来说,文件里没写不等于没有, 别看到少了一行就以为丢了东西。
真正会丢的,有一份清单
这是这一节最要紧的一段。 导出不保证每个材料都能整个写下来 —— 碰到读不出来的块,它不猜、不填默认值、也不因此放弃整次导出, 而是把这个材料的问题单独记下来。三类:
- 这个版本导不出的行为。材料身上有插件不认识的属性块, 提示会明说「这个版本不导出某某,所以它不在文件里」。 这一条最常出现在你在 CAE 里手工加过什么冷门属性的材料上。
- 阻尼系数全是零。提示是
damping is defined but every factor is zero。 为什么不写出去:写出去的文件导回来会被拒(阻尼块要求至少有一个系数), 而编一个非零系数进去就是在编阻尼。 - 超弹说要用试验数据,身上却没有曲线。提示是
hyperelastic is set to use test data but carries none。 这种材料写出去会变成一个「导得进、什么都不描述」的空壳。
还有一件必须说清楚的:导出不区分材料是哪来的。 在线库取的和自己手工建的,在模型里长得一样,导出文件里也一样。 正因为分不出来,1.5.0 起导出整体要求授权在有效期内 —— 过期之后连自己手工建的材料也导不出来,续期立刻恢复, 模型里的材料一个都不会动。这条口径在产品页的授权说明里写着,JSON 字段的完整清单在帮助文档的格式一节。
04路 C:写脚本重建
第三条路是不要文件,直接用 Abaqus 的 Python 接口把材料建出来。 它在两种场合无可替代:
- 材料要按参数生成。同一种钢在八个温度点上各取一组值、或者要做一批系数扫描 —— 这种「材料本身是算出来的」的情况,手工填和文件都不合适。
- 要嵌进已有的建模脚本。建几何、划网格、建材料、建 Section、提交作业一气呵成, 中间不能停下来点对话框。
代价也很实在:参数名和常量全要自己写对。 插件内核里那张各向异性弹性的常数个数表就是为这件事存在的 —— LAMINA 要正好六个常数,写七个就会被 Abaqus 当成六个常数加一个温度,而且不报错。这类坑在用 Python 批量建材料那篇里有最小可用例和一份必须显式写清的参数清单。
05复用里最危险的一步:覆盖同名材料
复用的第二次、第三次,几乎必然遇上同名。 默认行为是跳过不覆盖,报告里会明写:
skipped, already present (2): Steel_Q345, Al_6061_T6 [tick "Overwrite" to replace]这个默认值救过很多人,代价是「我明明重新导了一遍怎么没变」。 勾上覆盖之后,接下来发生的事值得知道, 因为它决定了失败时你会不会丢东西。
覆盖不是「先删了再建」
直觉的做法是删掉旧的、按同名建新的。 这个做法有一个很贵的失败模式:新数据要是有问题,旧的已经没了。 你手工调了半天的材料,换来一行报错。
所以插件走的是另一条:
- 先在一个暂存名下把新材料整个建出来(名字是
zzMaterialImporterScratch,撞了就在后面加数字)。 这一步失败,旧材料一个字没动。 - 建成了,才删掉旧的那个。
- 把暂存名改成正式名。
第二步和第三步各有各的失败方式,处理得也不一样:
| 失败在哪 | 结果 | 报告里说什么 |
|---|---|---|
| 第一步:新数据有问题 | 半成品被清掉,旧材料完好 | FAILED 加上具体的数据问题 |
| 第二步:旧材料删不掉 | 旧材料原样保留,什么都没换 | could not replace the existing material, so it was left as it was (is a section still using it?) |
| 第三步:改名失败 | 新材料留在模型里,名字是暂存名 | rebuilt but could not be renamed, so it is in the model as ... rename it by hand |
这个模式值得抄进自己的脚本。 如果你在路 C 里写覆盖逻辑,不要直接删旧的再建同名的 —— 建暂存名、成功了再换,多写四行,换来「失败不丢数据」。
覆盖会替换整个材料定义
最后一个容易误会的点:覆盖不是「更新你改的那几个字段」, 是把整个材料定义换成新的。 旧材料上你在 CAE 里手工加过的东西,覆盖之后就没了。 稳妥的做法是先改个名字导进去,对比确认再决定要不要覆盖。
06跨模型复用的头号事故:单位制不一致
前面五节讲的都是「怎么搬」。这一节讲搬过去之后最贵的那个错。
Abaqus 不记录单位制。 同一个数字 7850,它不知道是 kg/m³ 还是 tonne/mm³, 两种都能算完、都不报错。 所以从一个 SI 制的老模型往一个 mm 制的新模型搬材料, 是复用场景里唯一一个静力结果看着还挺正常、一做模态就全错的错法。
插件在导入前会做一件事:把模型里已有材料的数值和待导入数值各采一遍样,判断两边像不像同一个单位制。 对不上就整批拒绝,一个材料都不写。 提示的第一句是:
这个模型里已有的材料和要导入的数据不是同一个单位制,已停止导入。后面会分别列出两边「看起来是哪个制」, 并从你自己的数据里引三个具体数值当依据 —— 不是一句泛泛的警告。 如果是文件自己前后不一致(一半材料用一套、一半用另一套), 提示换成另一句,跟模型无关:
这个材料库自己的单位制就不一致,无法导入。它拿什么当依据
只有三个量在两套单位制下数值差得足够远,能当证据。 而且每个量中间都留了一条很宽的「说不准」带,落在带里的一律不算证据:
| 量 | 判为 mm 制 | 判为 SI 或其它大数值制 | 中间地带 |
|---|---|---|---|
| 密度 | 不大于 1e-06 | 不小于 0.05 | 两者之间一律不算证据 |
| 比热 | 不小于 1e+07 | 不大于 1e+05 | 注意方向是反的:mm 制的是大数 |
| 弹性模量 | 不大于 1e+07 | 不小于 1e+09 | 软橡胶在两制下确实分不出来 |
也有三个量故意不用,知道为什么有用:
- 导热系数 —— mm 制和 SI 下数值完全一样, 45 在两套里都对,所以它什么也说明不了。这件事本身在导热系数与比热那篇里推过一遍。
- 热膨胀系数 —— 两制都是 1/°C,同理。
- 屈服应力 —— 355 MPa 换成 Pa 是 3.55e8, 正好落在应力的说不准带里。
07怎么选:三个问题
按顺序问自己三句话,答案就定了。
- 新模型的几何要不要接着用?要 —— 复制整个 model,然后把 Section 重新过一遍。 不要 —— 往下走。
- 材料的数值是已经定好的,还是要算出来的?定好的 —— 导出成 JSON 再导入,把「没进去」清单确认是空的。 要算出来的 —— 往下走。
- 要算的部分能不能只做纯数据变换?能 —— 先导出成 JSON,脚本改文件,再导回去; 这样容易写错的建材料那一半不用自己写。 不能 —— 写完整的建材料脚本,参数名和常量逐个核。
三条路走完之后,别忘了材料到单元中间还隔着 Section 和指派两步 —— 材料搬过去了不等于新模型用上了它。 那两步和它们的排查顺序在材料建了却不生效里。