01库文件长什么样:15 个 XML,805 条材料
一套完整的样例库是 15 个 XML 文件加一个 .h5, XML 里一共 805 条材料。它们不是一次做出来的 —— 文件头的 <EngineeringData version="…"> 从 14.0.0.207 一直排到 23.1.0.230,跨了九个大版本。 写解析器时别只认一个版本号。
| 文件名 | 条数 | 大致内容 |
|---|---|---|
| Explicit_Materials.xml | 211 | 显式动力学(LS-DYNA / Autodyn 口味),Johnson-Cook、状态方程一类 |
| Mixtures.xml | 161 | 混合物定义 |
| Fluid_Materials.xml | 108 | 流体单质,CFD 用 |
| Fluid_Mixtures.xml | 108 | 流体混合物 |
| Thermal_Materials.xml | 61 | 热分析专用,温度相关表最多的一份 |
| Granta_Design_Typical_Materials.xml | 39 | Granta 商业数据集**样本**(见第 10 节) |
| Magnetic_B-H_curves_Soft_Materials.xml | 33 | 软磁材料 B-H 曲线 |
| Composite_Materials.xml | 28 | 复合材料,正交异性属性集中在这里 |
| General_Materials.xml | 12 | 通用线弹性,Structural Steel 就在这份里 |
| Piezoelectric_Materials.xml | 10 | 压电,含耦合矩阵 |
| General Materials Non-linear.xml | 9 | 通用非线性(注意:文件名里是空格,不是下划线) |
| GeoMechanical_Materials.xml | 8 | 岩土(Drucker-Prager、Mohr-Coulomb 一类) |
| Additive_Manufacturing_Materials.xml | 8 | 增材制造 |
| Hyperelastic_Materials.xml | 5 | 超弹(Mooney-Rivlin、Ogden 系数) |
| AIM_Samples.xml | 4 | AIM 示例 |
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"><PropertyDetails id="pr0"> 的 Name,得到「Color」。<ParameterValue parameter="pa0"><ParameterDetails id="pa0">,得到 Name「Red」和它的单位。<Data>132</Data>为什么拿颜色当例子
因为它正好戳破最常见的那个误会。通用库里第一条材料的第一个属性块就是 pr0,很多人想当然以为「第一个属性总是密度」,于是把 132 / 139 / 179 当成了材料性能 —— 其实那是这条材料在 Workbench 树里显示的 RGB 颜色(pa0=Red、pa1=Green、pa2=Blue)。
<ParameterDetails> 的实际出现顺序是 pa1, pa2, pa3, pa40, pa41, pa42, pa47, …, pa9, pa4, pa34, pa44, pa0。pa0 排在倒数几个,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。
<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。
判断方式建议用区间而不是等值比较:
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 directionPoisson'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 | 乘以 |
|---|---|---|---|
| 长度 | m | mm | ×1e3 |
| 力 | N | N | ×1(相同) |
| 应力 / 弹性模量必查 | Pa | MPa | ×1e-6 |
| 密度必查 | kg·m⁻³ | t·mm⁻³ | ×1e-12 |
| 能量 | J | mJ | ×1e3 |
| 导热系数 | W·m⁻¹·C⁻¹ | mW·mm⁻¹·C⁻¹ | ×1(数值相同) |
| 比热容必查 | J·kg⁻¹·C⁻¹ | mJ·t⁻¹·C⁻¹ | ×1e6 |
| 热膨胀系数 | C⁻¹ | C⁻¹ | ×1(相同) |
| 温度 | °C | °C | ×1(相同) |
| 电阻率 | ohm·m | 按模型自定 | 看单元类型 |
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- 映射表非空。如果
props或params是空的,说明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 等来源。 整份搬运是再发布,不是引用,这不是本站该替别人做的决定。
读完之后,大概率你要做的下一件事
把材料参数搬进求解器。本站材料表公开可查, 每条都带出处;另有一个 Abaqus/CAE 插件,可以把选中的材料直接建成 *MATERIAL 关键字块,单位换算(含上面那个 10¹² 倍)由它做。 安装包可以直接下载,激活需有效会员。