$$\det(A) = (-1)^{s}\prod_i U_{ii}, \qquad r = \|A\,x - b\|_2$$
分解代价为 O(n³),但对同一 A 的每个新右端项仅需 O(n²),正是 FEM 多荷载工况中的关键优势。
什么是LU分解模拟器
🙋
解线性方程组就是中学学过的消元法吧?计算机做的事情和我们一样吗?
🎓
本质上是同样的「高斯消去」。但在工程实务中,会把消去过程的中间结果保留为两个矩阵 L 和 U——这就是 LU 分解。看上面的第二张画布:绿色的 L 记录了「消去时每行所乘的倍率」,蓝色的 U 是「整理为上三角后的形态」。两者相乘就能还原 A。
🙋
特意做分解有什么好处?解一次不就够了吗?
🎓
这正是关键所在。例如 FEM 的线性静力分析中,常常要对同一个刚度矩阵 K 解 10 个、100 个荷载工况。只要先做一次 LU 分解,每个工况只需「前向代入和回代」即可完成。分解本身是 O(n³),比较重;但其后每次求解仅为 O(n²)。1000 元的方程,做一次分解的代价就能解约 1000 个右端项。
对。把求得的 x 代回原矩阵 A 乘一次,再和 b 相减取范数就是残差。理论上为 0,在双精度浮点下通常也只到 10⁻¹⁰ 量级。如果出现 1 或 10,要么矩阵几乎奇异(条件数极大),要么实现里有 bug。检查残差,是数值解的「自我体检」,实务中必养成习惯。
常见问题
两者都是 LU 分解的实现方式:Doolittle 把 L 的对角设为 1(主元保留在 U 中),Crout 把 U 的对角设为 1。本工具采用 Doolittle 法,这也是教科书中最常见的约定。数值结果本质等价,差异主要体现在内存布局与计算顺序上。
条件数定义为 cond(A)=‖A‖·‖A⁻¹‖,衡量输入误差被放大到解的程度。粗略估计,条件数为 10ᵏ 时,双精度浮点(约 16 位精度)下大约会损失 k 位有效数字。当条件数超过 10¹⁶,有效精度全部消失,解不可信。实务中通过迭代精化、缩放或更换问题表述来控制条件数。
大型 FEM 与 CFD 矩阵超过 99% 的元素为 0,是「稀疏矩阵」。直接做 LU 分解会在原本为零的位置产生「填充(fill-in)」,导致内存爆炸。实务中先用 AMD、METIS 等排序算法重排行列以最小化填充,再用 SuperLU、PARDISO、MUMPS 等稀疏 LU 库完成分解。规模超大时则改用共轭梯度法(CG)、GMRES 或代数多重网格等迭代解法。
线性弹性分析的刚度矩阵 K 多为对称正定,此时首选 Cholesky 分解(K=L·Lᵀ),其内存与运算量约为一般 LU 的一半。接触分析、塑性分析或非对称表述(如流固耦合)中使用一般 LU。无论何种情况,直接法的真正优势都体现在「分解一次、便宜地求解多个右端项」,特别适合多荷载工况。
实际应用
FEM 线性静力分析:结构分析求解器(NASTRAN、Abaqus、ANSYS、Marc 等)的核心是对刚度矩阵的直接解法。对称正定时用 Cholesky,一般情况下用 LU。当同一 K 需要对多个荷载工况(自重、风载、地震、热载等)求解时,分解的可重用性带来巨大收益。稀疏实现(SuperLU、PARDISO、MUMPS)是行业标准,可处理数千万自由度的模型。
电路分析(SPICE):电子电路的节点方程 G·v=i 中,节点导纳矩阵 G 是稀疏对称矩阵,常用 LU 求解。SPICE 类仿真器在每个时间积分步求解线性化方程,对于矩阵结构不变的区段,重用 LU 因子可极大加速。