网格生成 03:质量、误差与有效性

“质量”至少有五种

质量典型量失败时的后果
几何逼近Hausdorff 距离、法向误差边界条件施加在错误几何上
单元形状最小角、长宽比、scaled Jacobian插值误差和条件数恶化
拓扑结构奇异点/奇异边数量、块数样条结构复杂、方向传播困难
尺寸与方向度量边长、alignment自由度花在错误区域
求解器表现误差、迭代数、时间、内存“漂亮网格”在仿真中无收益

因此报告一个平均角度不等于完成评测。至少应同时给最坏值、分位数、无效单元数、几何误差和求解器指标。

三角形质量

三角形边长为a,b,ca,b,c,面积为AA,一个常用无量纲质量是

q△=43Aa2+b2+c2∈(0,1].q_{\triangle}=\frac{4\sqrt3 A}{a^2+b^2+c^2}\in(0,1].

等边三角形取 1,退化三角形趋近 0。它适合各向同性欧氏网格,但会错误惩罚按MM 度量设计的细长单元;各向异性时应先用M1/2M^{1/2} 把单元变换到度量空间再评价。

四面体的 sliver

四面体可以所有边都不极端,却四点几乎共面,体积接近 0。这类 sliver 说明仅看边长不够。可同时检查:

qvol=62V∑e∈Eℓe3,ρ=Rℓmin⁡,q_{\mathrm{vol}}=\frac{6\sqrt2 V}{\sum_{e\in E}\ell_e^3}, \qquad \rho=\frac{R}{\ell_{\min}},

其中VV 是体积、RR 是外接球半径。不同软件的归一化不同,比较前必须核对定义。

四边形与六面体的 Jacobian

参考单元坐标ξ\xi 映到物理单元x(ξ)x(\xi):

J(ξ)=∂x∂ξ.J(\xi)=\frac{\partial x}{\partial \xi}.

  • det⁡J>0\det J>0:局部保定向;
  • det⁡J=0\det J=0:局部压扁;
  • det⁡J<0\det J<0:局部翻转,单元无效。

只在顶点采样det⁡J\det J 不总能证明高阶单元内部有效。对曲边高阶映射,需要更密采样、Bernstein/Bézier 系数界或专门的严格认证方法。

scaled Jacobian 把三个局部边向量归一化:

qJ=det⁡[e1,e2,e3]∥e1∥ ∥e2∥ ∥e3∥∈[−1,1].q_J=\frac{\det[e_1,e_2,e_3]} {\|e_1\|\,\|e_2\|\,\|e_3\|}\in[-1,1].

它反映局部夹角和翻转,却不反映绝对尺寸。

误差为何需要 Hessian

线性有限元插值误差与解的二阶变化相关。二维中把 Hessian 对角化:

∣H(u)∣=R diag⁡(∣λ1∣,∣λ2∣)RT.|H(u)|=R\,\operatorname{diag}(|\lambda_1|,|\lambda_2|)R^T.

网格应沿∣λi∣|\lambda_i| 大的方向更密。一个典型目标度量形如

M(x)=c det⁡(∣H∣+εI)−α(∣H∣+εI),M(x)=c\,\det(|H|+\varepsilon I)^{-\alpha}(|H|+\varepsilon I),

常数cc 控制总复杂度,指数α\alpha 取决于维数、范数和误差模型。这说明“自适应网格”不是按曲率随意加点,而是把误差模型转成度量。

可运行的最小质量检查

import numpy as np

def triangle_quality(p0, p1, p2):
    p0, p1, p2 = map(np.asarray, (p0, p1, p2))
    a = np.linalg.norm(p1 - p2)
    b = np.linalg.norm(p2 - p0)
    c = np.linalg.norm(p0 - p1)
    e1, e2 = p1 - p0, p2 - p0
    twice_area = abs(e1[0]*e2[1] - e1[1]*e2[0])
    area = 0.5 * twice_area
    denom = a*a + b*b + c*c
    return 0.0 if denom == 0 else 4*np.sqrt(3)*area/denom

def signed_tet_volume(p0, p1, p2, p3):
    A = np.column_stack((np.asarray(p1)-p0,
                         np.asarray(p2)-p0,
                         np.asarray(p3)-p0))
    return np.linalg.det(A) / 6.0

assert np.isclose(triangle_quality([0, 0], [1, 0],
                                   [0.5, np.sqrt(3)/2]), 1.0)
assert signed_tet_volume(np.zeros(3), np.eye(3)[0],
                         np.eye(3)[1], np.eye(3)[2]) > 0

真实项目还要统一顶点顺序、容差和长度单位,并报告完整分布,而非只断言一个单元。

最小评测协议

  1. 同一几何、同一目标尺寸/自由度预算;
  2. 记录失败模型,不能只统计成功样例;
  3. 分开报告生成、优化和求解时间;
  4. 报告最坏 1%、中位数和无效单元数;
  5. 用至少一个 PDE 做误差—自由度曲线;
  6. 保存软件版本、参数、随机种子与硬件。

自测

  1. scaled Jacobian 为正是否足以说明网格适合某个 PDE?
  2. 为什么最小角对各向异性网格可能误导?
  3. 高阶单元为什么不能只检查角点 Jacobian?

答案:不够,它不含尺寸、方向和误差信息;细长可能是度量空间中的等边单元;高阶 Jacobian 是单元内部变化的多项式,角点为正时内部仍可能为负。

文献深读

本章的质量指标、鲁棒谓词与四面体有效性可继续沿单纯形生成、鲁棒性与质量文献谱系阅读;高阶全域 Jacobian 的问题见高阶曲边网格文献谱系。