已知插入顺序时填充 Eigen3 稀疏矩阵的策略

Strategies for filling an Eigen3 sparse matrix when the order of insertion is known

所以在我的非线性有限元求解器中,我使用了 Eigen3 稀疏矩阵和 LDLT 分解。

问题是,这个因式分解在一次动态仿真中需要进行多次,而且很多时间都花在了将系数插入基于三元组的迭代矩阵中(保留存储)。

有什么好的策略可以利用稀疏度不变且插入顺序相同的事实吗?当形成这个矩阵时,循环遍历模型中的元素、耦合等,在模拟过程中的每个时间步的插入顺序都是相同的。

使用 coeffref 将仿真时间增加了大约 10 倍。

我一直在考虑对模型进行单次传递并直接形成指向系数矩阵中相应位置的指针,但这似乎有点危险,尤其是因为 LDLT 因式分解是 运行之间。

如果矩阵的稀疏模式在每个时间步都没有变化,那么您可以直接使用 valuePtr() 更改原始数据数组的值。这非常简单,如果需要可以并行完成。如果你能弄清楚如何以线性方式执行此操作,即

SparseMatrix<double> A;

for(int i = 0; i < n; i++)
   A.valuePtr()[i] = ...

然后它会很快变得愚蠢(与避免缓存未命中和其他黑魔法有关)。至于之前说LDLT分解不会变的评论,从理论上讲是对的。但是,根据 Eigen 文档:

"In factorize(), the factors of the coefficient matrix are computed. This step should be called each time the values of the matrix change. However, the structural pattern of the matrix should not change between multiple calls."

https://eigen.tuxfamily.org/dox/group__TopicSparseSystems.html

我认为这是因为因子存储在求解器对象中,尽管我可能是错的。测试应该很容易以某种方式确认。也就是说,我认为您必须在更改值后调用 factorize() 。尽管如此,您只需调用一次 analyzePattern() 例程即可节省大量时间。