我正在使用Visual Studio Community 2015,我正在尝试使用c ++中的Eigen库来解决大型稀疏线性系统。我把所有东西都包装在我的类 Domain2D 中,具有定义的刚度矩阵和荷载向量,荷载向量是我自己的长双精度类型:
typedef Eigen::Matrix<long double, Eigen::Dynamic, 1> VectorXld; // somewhere way up in the code
class Domain2D {
private:
...
Eigen::SparseMatrix<long double, Eigen::ColMajor> constant_stiffness;
Eigen::SparseMatrix<long double, Eigen::ColMajor> convection_stiffness;
...
VectorXld load;
...
public:
...
void load_constant_stiffness() {
...
resize, reserve, fill up with elements
}
...
void load_convection_stiffness() {
...
}
void load_RHS() {
...
}
}
最后,在课堂上的某个地方,我有以下例程:
void advance_step(const int &step) {
...
Eigen::SparseLU<Eigen::SparseMatrix<long double, Eigen::ColMajor>, Eigen::COLAMDOrdering<int>> solver;
Eigen::SparseMatrix<long double, Eigen::ColMajor> M;
VectorXld res, res_new;
res.resize(2 * N + n);
...
while (d > 1e-5) {
d = 0;
load_convection_stiffness();
load_RHS();
M = constant_stiffness + convection_stiffness;
M.makeCompressed();
solver.analyzePattern(M);
solver.factorize(M);
res_new = solver.solve(load);
...
}
Save("output\results\", step);
t += dt;
}
程序在最后提到的行失败:res_new = solver.solve(M);
它向我展示了一个名为"SparseLU_SupermodalMatrix.h"的文件,它失败的例程是void MappedSuperNodalMatrix<Scalar,Index_>::solveInPlace( MatrixBase<Dest>&X) const
,行Index fsupc = supToCol()[k];
,它显示的错误是
Unhandled exception thrown: read access violation.
this->m_sup_to_col was 0x111011101110112.
If there is a handler for this exception, the program may be safely continued.
我搜索了一下,发现如果我在课堂上使用特征对象,我应该在公共部分添加行EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
,我这样做了,但无济于事。所有矩阵的大小都合适,以及长双精度的向量。我已经解决了这些系统一段时间,它奏效了,但突然间,这发生了。可能是什么原因?
PS:我将矩阵和加载向量加载到数学中,即使使用标准精度,我也得到了一个看起来绝对没问题的解决方案,所以它不像系统状况不佳。
一些提示:
- 您需要通过在调用
factorize()
后检查该solver.info()==Eigen::Success
来检查因式分解是否顺利。 - 尝试在此处与 3.3 分支的负责人联系,看看此问题是否已解决。
- 确保您尝试未定义
NDEBUG
(也称为可视化中的调试模式),以查看 Eigen 是否触发了一些有见地的断言。 - 使用
double
而不是long double
进行检查可能有助于隔离问题。为此,您可以使用本地M
进行转换并使用.cast<double>()
进行load
。 - 在内存调试器中运行程序也可能有所帮助。
- 在尝试了所有这些之后,与 Eigen 的团队分享您的矩阵
M
,让他们(即我自己;))重现问题。