处理全部,
感谢您抽出宝贵时间阅读我的问题。
我正在使用Eigen3.3.4(http://eigen.tuxfamily.org/index.php?title=Main_Page)编写一些FEM代码。

我阅读了Eigen3.3.4文档,并在此网站(http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html)中说
我们应该使用Ref<MatrixBase>来避免重复复制并获得高性能。

因此,在我的FEM代码中,对于稀疏矩阵组装部分,假设函数为:

FormFE(const Ref<VectorXd> &U,const Ref<VectorXd> &V,
Ref<SparseMatrix<double> > AMATRIX,Ref<VectorXd> RHS)

其中U代表位移,V代表速度项。 AMATRIX是我的稀疏矩阵,RHS是残差项。

然后我尝试在组装之前先初始化AMATRIX(我有一个包含所有非零元素及其值的TripletList(我将值设置为零进行初始化))
所以我尝试了:
AMATRIX.setFromTriplets(ZeroTripList.begin(),ZeroTripList.end());
但是我有一个错误:
class Eigen::Ref<Eigen::SparseMatrix<double, 0, int> >’ has no member named ‘setFromTriplets

那么我该如何解决这个问题呢?

我的解决方案之一是使用:
FormFE(const Ref<VectorXd> &U,const Ref<VectorXd> &V,
SparseMatrix<double> &AMATRIX,Ref<VectorXd> RHS)

这工作得很好,但是我不确定它是否有效。
我不太擅长cpp:P

实际上,我的问题是:
  • 如何有效地使用Eigen(尤其是用于FEM计算),我在每个与FEM相关的功能中几乎都在使用Eigen的VectorXd和MatrixXd。
  • 如何有效地组装SparseMatrix?
  • 是否可以为FEM组装做一些OpenMP并行化?
  • 欢迎任何有关基于C++的FEM编码的有用建议(库建议或任何有用的想法)!

  • 谢谢。
    最好的祝福。

    最佳答案

    是的,在这里传递SparseMatrix<double> &是正确的事情。 Ref<SparseMatrix>的目的是传递组装成SparseMatrix的组装对象,例如次稀疏矩阵,Map<SparseMatrix> ...

    使用setFromTriplets也是正确的做法,以确保获得良好的性能。如果您正确执行mat.insert(i,j) = val;,则直接插入元素的速度可能会提高x2倍(即正确调用保留方法和正确的插入顺序)。但是,如果您弄错了,它也可能会慢100倍...请参阅文档。使用SparseMatrix::insert,也可以使用OpenMP填充矩阵,但这需要更加小心和严格,这是一个典型的模式:

    int n_cols = ??, n_rows = ??;
    std::vector<int> nnz_per_col(n_cols);
    // set each nnz_per_col[j] to the exact number
    // of non-zero entries in the j-th column (or more, but NOT less)
    SparseMatrix<double> mat(n_rows, n_cols);
    #pragma omp parallel for
    for(int j=0; j<cols; ++j) {
      for each non zero entry i in the j-th column {
        // preferably with increasing i
        double val_i_j = ...;
        mat.insert(i,j) = val_i_j;
      }
    }
    

    当然,如果您更方便,也可以按行工作。在这种情况下,请使用SparseMatrix<double,RowMajor>。当然,您可以调整此模式以处理列/行等块。

    如果对于装配体,您需要使用一些密集的矩阵/ vector ,那么我相信它们在固定尺寸下非常小。然后,最好使用静态分配的Matrix<double,N,M>Matrix<double,N,1>类型,而不是使用MatrixXd / VectorXd。这将防止大量内存分配/取消分配。

    最后,是最重要的建议:如果您关心性能,请不要忘记对代码进行配置,然后再调查时间和精力,以优化代码。另外,始终在启用编译器优化的情况下进行基准测试。

    关于c++ - 如何有效地组装FEM稀疏矩阵,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47093836/

    10-08 22:04