首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何有效地组合有限元稀疏矩阵

如何有效地组合有限元稀疏矩阵
EN

Stack Overflow用户
提问于 2017-11-03 10:43:38
回答 1查看 1.4K关注 0票数 3

好了,谢谢你抽出时间阅读我的问题。我正在使用Eigen3.3.4(Page)编写一些有限元程序。

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

所以在我的有限元程序中,对于稀疏矩阵组装部分,假设函数是:

代码语言:javascript
运行
复制
FormFE(const Ref<VectorXd> &U,const Ref<VectorXd> &V,
Ref<SparseMatrix<double> > AMATRIX,Ref<VectorXd> RHS)

其中U代表位移,V代表速度项。A矩阵是我的稀疏矩阵,RHS是剩余项。

然后,我尝试在组装之前先初始化我的矩阵(我有一个tripletList,它包含所有的非零元素及其值(我将值设置为零,用于初始化),所以我尝试:

AMATRIX.setFromTriplets(ZeroTripList.begin(),ZeroTripList.end());

但我有个错误:

代码语言:javascript
运行
复制
class Eigen::Ref<Eigen::SparseMatrix<double, 0, int> >’ has no member named ‘setFromTriplets

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

我的解决方案之一是使用:

代码语言:javascript
运行
复制
FormFE(const Ref<VectorXd> &U,const Ref<VectorXd> &V,
SparseMatrix<double> &AMATRIX,Ref<VectorXd> RHS)

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

事实上,我的问题是:

  1. 如何有效地使用特征元(特别是有限元计算),我几乎在我的有限元相关函数中几乎无处不在地使用了特征元的VectorXd和MatrixXd。
  2. 如何有效地组装SparseMatrix?
  3. 有限元装配可以进行OpenMP并行化吗?
  4. 欢迎对基于C++的有限元编码的任何有用的建议(库推荐或任何有用的想法)!

谢谢。诚挚的问候。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-03 21:35:15

是的,在这里传递SparseMatrix<double> &是正确的。Ref<SparseMatrix>的目的是将组装好的对象传递给SparseMatrix,如子稀疏矩阵,Map<SparseMatrix>.

使用setFromTriplets也是正确的做法,以确保得到良好的性能。如果正确地插入元素,直接使用mat.insert(i,j) = val;插入元素的速度可能会更快(例如,正确调用预订和正确的插入顺序)。但如果你搞错了,它也可能是x100倍慢.去看医生。使用SparseMatrix::insert,也可以使用OpenMP填充矩阵,但这需要更加小心和严格,下面是一个典型的模式:

代码语言:javascript
运行
复制
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>。当然,您可以调整这个模式来处理列/行等块。

如果对于程序集来说,你需要处理一些密集的矩阵/向量,那么我认为它们在固定大小的情况下非常小。然后,最好使用静态分配的Matrix<double,N,M>Matrix<double,N,1>类型,而不是使用MatrixXd/VectorXd。这将防止大量内存分配/取消分配。

最后,最重要的建议:如果您关心性能,在研究优化代码的时间和精力之前,不要忘记对代码进行分析。此外,始终支持编译器优化的工作台/概要文件。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47093836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档