工程师平台

Ansys 材料库 XML 怎么读

Ansys Engineering Data 的材料库是一种叫 MatML 的 XML。第一次打开它的人 基本都会卡在同一个地方:属性名不在数值旁边,数值的单位也不在数值旁边,还有一个反复出现的 7.88860905221012e-31 完全看不出是什么。这三件事都有确定的答案, 这一页把它们讲完,并给出换算到 Abaqus tonne-mm-s 的系数表。

pr0 不是「第一个属性」
它是 id,不是序号。pr0 在通用库里是 材料的显示颜色,不是密度。而且 <Metadata> 里这些 id 的排列顺序是乱的,不能按位置索引。
7.888e-31 = 2⁻¹⁰⁰,是哨兵
意思是「这个自变量没有真实取值」。真值在同一段里的 Default Data 上。当成 0 或当成温度用,整条温度曲线就废了。
单位一律 SI 基本单位
应力是 Pa 不是 MPa,密度是 kg·m⁻³。 搬进 Abaqus 的 tonne-mm-s 要分别 ×1e-6 和 ×1e-12 —— 这两个错求解器都不会报。
这一页不含材料性能数值
正文里出现的所有数字都是**结构示意**:第 03 节那组 132 / 139 / 179 是材料在界面里的 显示颜色 RGB,第 05 节的曲线数字是编的整数。为什么不搬真实数值,见 第 10 节

01库文件长什么样:15 个 XML,805 条材料

一套完整的样例库是 15 个 XML 文件加一个 .h5, XML 里一共 805 条材料。它们不是一次做出来的 —— 文件头的 <EngineeringData version="…"> 14.0.0.207 一直排到 23.1.0.230,跨了九个大版本。 写解析器时别只认一个版本号。

文件名条数大致内容
Explicit_Materials.xml211显式动力学(LS-DYNA / Autodyn 口味),Johnson-Cook、状态方程一类
Mixtures.xml161混合物定义
Fluid_Materials.xml108流体单质,CFD 用
Fluid_Mixtures.xml108流体混合物
Thermal_Materials.xml61热分析专用,温度相关表最多的一份
Granta_Design_Typical_Materials.xml39Granta 商业数据集**样本**(见第 10 节)
Magnetic_B-H_curves_Soft_Materials.xml33软磁材料 B-H 曲线
Composite_Materials.xml28复合材料,正交异性属性集中在这里
General_Materials.xml12通用线弹性,Structural Steel 就在这份里
Piezoelectric_Materials.xml10压电,含耦合矩阵
General Materials Non-linear.xml9通用非线性(注意:文件名里是空格,不是下划线)
GeoMechanical_Materials.xml8岩土(Drucker-Prager、Mohr-Coulomb 一类)
Additive_Manufacturing_Materials.xml8增材制造
Hyperelastic_Materials.xml5超弹(Mooney-Rivlin、Ogden 系数)
AIM_Samples.xml4AIM 示例
有一个文件名用的是空格
General Materials Non-linear.xml —— 别的都是下划线,只有这一个是空格。 脚本里拼路径不加引号,在这一个文件上会断。

02文件骨架:五层嵌套

外面两层是 Ansys 的壳,从 <MatML_Doc> 往里才是 MatML 本身。 每条材料由两块组成:<BulkDetails> 放这条材料的数据, 而解释这些数据的「字典」在文件末尾单独一块 <Metadata> 里。 这个分离就是所有困惑的来源。

<EngineeringData version="19.4.0.79" versiondate="6/9/2017 …">
  <Notes> … </Notes>
  <Materials>
    <MatML_Doc>
      <Material>
        <BulkDetails>
          <Name>Structural Steel</Name>
          <Description>…</Description>
          <Class><Name>Alloy</Name></Class>
          <PropertyData property="pr0">      ← 数据在这里,但只有 id
            <ParameterValue parameter="pa0" format="float">
              <Data>132</Data>
            </ParameterValue>
          </PropertyData>
          …
        </BulkDetails>
      </Material>
      …更多 <Material>…
      <Metadata>                            ← 字典在这里
        <PropertyDetails id="pr0"><Name>Color</Name></PropertyDetails>
        <ParameterDetails id="pa0"><Name>Red</Name><Unitless /></ParameterDetails>
        …
      </Metadata>
    </MatML_Doc>
  </Materials>
</EngineeringData>

注意 <Metadata>整个文件共用一份, 不是每条材料一份。所以一个文件里的 pa17 对所有材料都指同一个物理量; 但换一个文件,pa17 就可能是别的东西。

03核心:pr0 / pa0 三层寻址

这是读懂这类文件唯一必须掌握的机制。一个数值要经过三跳才能确定它是什么:

属性层 · <PropertyData property="pr0">
拿到属性 id。去 Metadata 查 <PropertyDetails id="pr0"> 的 Name,得到「Color」。
参数层 · <ParameterValue parameter="pa0">
拿到参数 id。去查 <ParameterDetails id="pa0">,得到 Name「Red」和它的单位。
数值层 · <Data>132</Data>
到这里才是数。含义 =「Color 属性的 Red 参数 = 132,无量纲」。

为什么拿颜色当例子

因为它正好戳破最常见的那个误会。通用库里第一条材料的第一个属性块就是 pr0,很多人想当然以为「第一个属性总是密度」,于是把 132 / 139 / 179 当成了材料性能 —— 其实那是这条材料在 Workbench 树里显示的 RGB 颜色(pa0=Red、pa1=Green、pa2=Blue)。

Metadata 里的 id 顺序是乱的,绝对不能按位置索引
通用库里 <ParameterDetails> 的实际出现顺序是 pa1, pa2, pa3, pa40, pa41, pa42, pa47, …, pa9, pa4, pa34, pa44, pa0pa0 排在倒数几个,pa4 排在 pa51 后面。 用「第 n 个 ParameterDetails 就是 paN」这种写法读文件,拿到的属性名会整片错位, 而且错得很隐蔽 —— 值都是合法浮点数,跑得通,只是每个数都挂在别人的名下。
唯一正确的做法:先把整个 <Metadata> 读成 {id: {name, units}} 映射表,再回头遍历材料。

04单位:power 幂次相乘

单位不在数值旁边,只在 <ParameterDetails> 里。 形式是若干个 <Unit> 相乘,power 属性是幂次, 省略就是 1。分母写成负幂。

<ParameterDetails id="pa6">
  <Name>Density</Name>
  <Units name="Density">
    <Unit><Name>kg</Name></Unit>
    <Unit power="-3"><Name>m</Name></Unit>     →  kg·m⁻³
  </Units>
</ParameterDetails>

<ParameterDetails id="pa17">
  <Name>Thermal Conductivity</Name>
  <Units name="Thermal Conductivity">
    <Unit><Name>W</Name></Unit>
    <Unit power="-1"><Name>m</Name></Unit>
    <Unit power="-1"><Name>C</Name></Unit>     →  W·m⁻¹·C⁻¹
  </Units>
</ParameterDetails>

<ParameterDetails id="pa47">
  <Name>Strength Exponent</Name>
  <Unitless />                                 →  无量纲
</ParameterDetails>

两个细节值得记住。一是 <Units name="…"> 上那个 name 是量的种类(Stress、Density、Thermal Conductivity), 不是单位符号,可以拿它做量纲校验。二是温度用的符号是 C 而不是 K:对导热系数、比热这种「每温度」的量, 摄氏度和开尔文的温差相同,数值不用换;但遇到绝对温度 (熔点、参考温度)就必须分清,那里差 273.15。

属性层永远是 Unitless,别在那里找单位
<PropertyDetails> 里清一色写着 <Unitless />,包括 Density、Compressive Ultimate Strength 这些明显有单位的。 这不是数据缺失 —— 单位属于参数,不属于属性。往 ParameterDetails 里找。

05多点曲线:逗号分隔 + 同序配对

硬化曲线、B-H 曲线这类多点数据不用嵌套结构,而是把整条曲线塞进一个 <Data> 里逗号分隔,连 Qualifier 也跟着逗号分隔,两边靠下标一一对应。属性块上会有 <Qualifier name="Definition">Piecewise</Qualifier> 做标记。

<PropertyData property="pr2">
  <Qualifier name="Definition">Piecewise</Qualifier>
  <ParameterValue parameter="pa4" format="float">
    <Data>0,1e7,4e7,4.4e7</Data>                      ← 纵轴(示意值,非真实材料数据)
    <Qualifier name="Variable Type">Dependent,Dependent,Dependent,Dependent</Qualifier>
  </ParameterValue>
  <ParameterValue parameter="pa5" format="float">
    <Data>-4e6,0,1.5e7,5e7</Data>                     ← 横轴
    <Qualifier name="Variable Type">Independent,Independent,Independent,Independent</Qualifier>
  </ParameterValue>
</PropertyData>

Dependent 是因变量(纵轴),Independent 是自变量(横轴)。 哪个是哪个只能靠这个 Qualifier 判断,不能靠出现顺序 —— 上例里因变量反而排在前面。 两个数组的第 i 项配成一个点。

三件必查
  • 两个数组长度必须相等。不等说明文件被手改过或导出中断,不要猜着补。
  • Variable Type 的逗号项数要和 Data 的项数一致; 只有一项而 Data 有多项时,按那一项对整条曲线生效。
  • 分隔符是逗号,没有空格。按空白切分会得到一个整串,float() 抛异常还算好事 —— 更糟的是某些语言会静默解析出第一个数。

062⁻¹⁰⁰:那个看不懂的 7.888e-31

7.88860905221012e-31 在这些文件里到处出现,它不是测量值, 是 2⁻¹⁰⁰2**-100 = 7.888609052210118e-31), Ansys 拿它当「此处自变量无真实取值」的哨兵。它出现的位置很固定:一个 Variable Type = Independent 的参数上,旁边一定跟着 Default Data

<ParameterValue parameter="pa2" format="float">
  <Data>7.88860905221012e-31</Data>              ← 哨兵:不是温度
  <Qualifier name="Variable Type">Independent</Qualifier>
  <Qualifier name="Field Variable">Temperature</Qualifier>
  <Qualifier name="Default Data">22</Qualifier>  ← 真正的温度在这里:22 °C
  <Qualifier name="Field Units">C</Qualifier>
  <Qualifier name="Upper Limit">Program Controlled</Qualifier>
  <Qualifier name="Lower Limit">Program Controlled</Qualifier>
</ParameterValue>

含义是:这条属性只有一个数据点,它对应的温度没有单独存,用默认的 22 °C。 读的时候规则很简单 —— 看见这个数,就去取 Default Data

把它当 0 或当温度用会发生什么
7.9e-31 °C 实际上就是 0 °C 附近,而真值是 22 °C。单点数据被标到错误的温度上, 一旦这条属性后来和别的温度点合成一张表,插值就会围绕一个假的锚点展开。 比这更常见的错法是把它当成属性值本身(比如导热系数 = 7.9e-31), 那会让传热计算变成绝热 —— 求解器照样收敛,只是结果全错。
判断方式建议用区间而不是等值比较:abs(v) < 1e-30 就当哨兵处理, 免得被文件里不同精度的写法绕过(同一个数在不同版本的文件里位数不完全一样)。

07各向异性,以及两套并存的命名

材料的方向性由属性块上的 <Qualifier name="Behavior"> 声明。整套库里数出来是:Isotropic 598 处、Orthotropic 85 处、Anisotropic 21 处。正交异性和各向异性的属性名带方向后缀, 集中在复合材料那一份里。

Young's Modulus X direction / Y direction / Z direction
Shear Modulus XY / XZ / YZ
Poisson's Ratio XY / XZ / YZ
Coefficient of Thermal Expansion X direction / Y direction / Z direction
同一个文件里混着两套方向命名
复合材料库里既有 Poisson's Ratio XY, 又有 Poisson's Ratio in the AB direction。 也就是说属性名不能做精确字符串匹配, 尤其不能用一张写死的名字表去认属性。稳一点的做法是先按关键词 (poisson / modulus / expansion)粗分,再从名字里正则抽方向标记 (X|Y|Z|XY|XZ|YZ|AB|AC|BC)。 顺带一提,撇号也是坑:Young's 里那个是 ASCII 单引号, 但别的文件里出现过排版撇号,比较之前先归一化。

导到 Abaqus 时,等向材料可以直接搬;正交异性的数值能搬,方向不能想当然 —— Abaqus 的工程常数必须配一个材料方向 (*ORIENTATION),而 XML 里的 X/Y/Z 是相对谁定义的, 文件本身没说。这一步建议手工确认,不要让脚本替你决定。

08换算到 Abaqus tonne-mm-s

Ansys 库存的是 SI 基本单位,Abaqus 里最常用的是 tonne-mm-s(长度 mm、力 N、应力 MPa、密度 t/mm³)。 下表是逐项系数,标红的三行是真正会毁掉结果的。

物理量Ansys 库(SI)Abaqus tonne-mm-s乘以
长度mmm×1e3
NN×1(相同)
应力 / 弹性模量必查PaMPa×1e-6
密度必查kg·m⁻³t·mm⁻³×1e-12
能量JmJ×1e3
导热系数W·m⁻¹·C⁻¹mW·mm⁻¹·C⁻¹×1(数值相同)
比热容必查J·kg⁻¹·C⁻¹mJ·t⁻¹·C⁻¹×1e6
热膨胀系数C⁻¹C⁻¹×1(相同)
温度°C°C×1(相同)
电阻率ohm·m按模型自定看单元类型
密度那个 10¹² 是最容易出事的一个
钢在 Ansys 库里是 7850(kg·m⁻³),在 Abaqus tonne-mm-s 里应该是 7.85e-09。直接把 7850 填进去,静力学看不出问题, 但一做模态或者显式动力学,结果会离谱到不像同一个模型 —— 而且不报错。 本站的 单位对照表 里有完整的一份,插件会自动做这个换算。

09解析思路:先建映射,再读值

顺序很关键:整份 Metadata 读完,再碰材料。 前面所有的坑归结起来就是这一句。下面是骨架,标准库就够,不需要第三方依赖。

import xml.etree.ElementTree as ET

SENTINEL = 1e-30          # 2**-100 ≈ 7.89e-31,见第 06 节

def load(path):
    root = ET.parse(path).getroot()

    # ① 先建字典。注意是整个文件共用一份,且 id 顺序无意义。
    props, params = {}, {}
    for md in root.iter('Metadata'):
        for pd in md.findall('PropertyDetails'):
            props[pd.get('id')] = pd.findtext('Name')
        for pd in md.findall('ParameterDetails'):
            units = []
            for u in pd.findall('./Units/Unit'):
                units.append((u.findtext('Name'), int(u.get('power', 1))))
            params[pd.get('id')] = {'name': pd.findtext('Name'), 'units': units}

    # ② 再遍历材料,靠 id 回查
    for mat in root.iter('BulkDetails'):
        out = {'name': mat.findtext('Name'), 'props': []}
        for pdata in mat.findall('PropertyData'):
            pname = props.get(pdata.get('property'), '?')
            behavior = None
            for q in pdata.findall('Qualifier'):
                if q.get('name') == 'Behavior':
                    behavior = q.text
            for pv in pdata.findall('ParameterValue'):
                meta = params.get(pv.get('parameter'), {})
                raw = (pv.findtext('Data') or '').strip()
                quals = {q.get('name'): q.text for q in pv.findall('Qualifier')}

                if pv.get('format') != 'float':
                    continue                     # 字符串项('-'、'Interpolation Options')跳过

                # ③ 逗号分隔 = 多点曲线;Variable Type 也是逗号列表,同序对应
                vals = [float(x) for x in raw.split(',') if x]
                kinds = (quals.get('Variable Type') or '').split(',')

                # ④ 哨兵:真值在 Default Data 里
                if len(vals) == 1 and abs(vals[0]) < SENTINEL:
                    d = quals.get('Default Data')
                    vals = [float(d)] if d else []

                out['props'].append({
                    'property': pname,
                    'parameter': meta.get('name'),
                    'units': meta.get('units'),
                    'behavior': behavior,
                    'values': vals,
                    'kinds': kinds,
                })
        yield out
跑之前先自查三件事
  • 映射表非空。如果 propsparams 是空的,说明 Metadata 没找到(有些文件里它的层级和你以为的不同), 此时所有属性名都会是 ?,但程序不会报错。
  • 随机抽一条比对界面。把解析结果和 Workbench 里同一条材料的 Engineering Data 面板对一眼,特别是量级 —— 界面显示 MPa,你手上的应该是 Pa。
  • 数一下哨兵命中次数。如果一份文件里一次都没命中, 多半是判断写成了等值比较;如果几乎每条都命中,检查是不是把阈值写太大了。

10为什么本站不转载这些数值

有人问过能不能把这 805 条直接补进本站材料表。没有做,两个理由。

一、这些数字达不到入库标准

库里的条目普遍没有牌号、没有试验标准、没有热处理状态; 复合材料没给纤维体积含量和铺层,而这两项不写清楚,一个「碳纤维环氧」的抗拉强度 可以在几百到一千几百 MPa 之间随便落。Ansys 自己也没把它当权威数据 —— Granta 那份库里每条材料的 <Description> 结尾都写着:

Data compiled by Ansys Granta, incorporating various sources
including JAHM and MagWeb.
ANSYS, Inc. provides no warranty for this data.

本站材料表的每一项都要能追到牌号或厂家数据表,这条线不能为了凑条数破掉。 真需要这些值的人应该直接在 Ansys 里用它们 —— 它们在那个语境下是合适的 (演示、入门、量级估算),只是不适合被当成查询库转载出去。

二、其中一份是商业数据集

Granta_Design_Typical_Materials.xml 是 Ansys Granta 的 商业数据集样本,文件头写明聚合了 JAHM、MagWeb 等来源。 整份搬运是再发布,不是引用,这不是本站该替别人做的决定。

那这一页留下了什么
格式知识。它不属于任何人的数据集,讲清楚了能让人自己把手上的库读明白 —— 包括你公司内部那份带牌号、带试验报告的私有材料库, 导出来也是同一套 MatML 结构。

读完之后,大概率你要做的下一件事

把材料参数搬进求解器。本站材料表公开可查, 每条都带出处;另有一个 Abaqus/CAE 插件,可以把选中的材料直接建成 *MATERIAL 关键字块,单位换算(含上面那个 10¹² 倍)由它做。 安装包可以直接下载,激活需有效会员。

常见问题 FAQ

Ansys 材料库 XML 在哪个目录?

文件名是固定的(见第 01 节那张表),跟着 Ansys 安装包分发,随版本走。最稳的办法是拿文件名去安装盘搜 —— 比如搜 General_Materials.xml —— 而不是记路径:Engineering Data 的样例库目录在不同大版本里挪过位置,同一台机器上装了两个版本时更容易搜错。另一条路是在 Workbench 的 Engineering Data 里直接「Export」,导出的就是同一套 MatML 结构。

MatML 和 Ansys 的 XML 是一回事吗?

MatML 是材料数据交换的公开标记语言(ASTM 那边推的),Ansys 的库文件是它的一种实现:最外层套了一个 Ansys 自己的 <EngineeringData> 壳,里面才是 <MatML_Doc>。也就是说 <MatML_Doc> 以内的结构相对通用,而 <EngineeringData> 这一层、以及各种 <Qualifier> 的取值(Behavior、Definition、Field Variable Compatible 这些)是 Ansys 的方言。写解析器时要按后者来。

为什么 <Data> 里的值那么大,比如应力是 4 后面一串零?

库文件一律用 SI 基本单位存,应力的 SI 基本单位是 Pa,所以 40 MPa 在文件里就是 40000000。Ansys 界面上显示 MPa 是显示层换算,XML 里没有换算过。这一点对导到 Abaqus 的人尤其要紧:tonne-mm-s 单位制的应力是 MPa,直接搬 Pa 会让模量偏大 10⁶ 倍 —— 而这种错误求解器不会报错,它会算出一个「特别硬」的结果。

7.88860905221012e-31 是什么意思,能不能当 0 处理?

它是 2⁻¹⁰⁰,Ansys 用它当「这个自变量在这里没有真实取值」的哨兵。不能当 0,更不能当温度用:真值在同一个 <ParameterValue> 里的 <Qualifier name="Default Data"> 上。当 0 处理会把一条常温数据变成接近绝对零度的数据,后面所有温度插值都跟着废。详见第 06 节。

同一个属性名在不同文件里的 pa 编号一样吗?

不一样,而且不能假设一样。paN / prN 只在**它所在的那一个文件**里有效,是文件内的局部 id。换个文件,同一个 pa17 可能是完全不同的物理量。所以解析必须逐文件重建映射表,不能把某个文件里数出来的编号写死进代码。

这些材料数据可以直接拿来做设计吗?

不建议,Ansys 自己也没有这么承诺 —— Granta 那份库里每条材料的 <Description> 结尾写着「ANSYS, Inc. provides no warranty for this data.」,官方定位是演示和入门。这些条目普遍没有牌号、没有试验标准、没有热处理状态,复合材料也没给纤维体积含量和铺层。做正式设计要回到材料供应商的牌号数据表。这也是本站没有把它们收进材料表的原因,见第 10 节。

正交异性材料导到 Abaqus 里要注意什么?

库里用 <Qualifier name="Behavior">Orthotropic</Qualifier> 标出来,属性名带方向后缀(Young's Modulus X direction、Shear Modulus XY、Poisson's Ratio XY…)。搬到 Abaqus 时最容易出事的不是数值而是**方向定义**:Abaqus 的工程常数要求配一个材料方向(Orientation / *ORIENTATION),XML 里的 X/Y/Z 是谁定的坐标系并没有随文件说清楚。等向材料可以照搬,正交异性建议手工核对一遍方向再用。

本站的材料表能直接导进 Abaqus 吗?

能。材料表公开可查,另外有一个 Abaqus/CAE 插件可以把选中的材料直接建成 *MATERIAL 关键字块,单位换算(含密度那个 10¹² 倍)由插件做。插件安装包可以直接下载,激活需要有效会员。