从我的 Fortran 代码到 PETSc 获取复杂稀疏矩阵的最有效方法是什么?我知道这取决于问题,所以我试图在下面提供尽可能多的相关细节。
我一直在使用 FEAST 特征值求解器 [1] 来解决此类问题, 矩阵的维数和是, 几乎所有的时间都花在解决问题上M0 右手边的复线性系统。N 很大(FE 基函数的数量,在 3D 中),M0 很小(在我的情况下,我对 M0 ~ 20 感兴趣)。矩阵和是真实的、对称的和稀疏的,需要解决的复杂问题是, 在哪里是一个复数。FEAST 的作者似乎建议,为了获得高精度的特征值和特征向量,该线性系统的解的精度不必非常高,因此一些快速迭代求解器可能是一个很好的解决方案。
到目前为止,我一直只是将 Lapack 用于复杂系统,这对在我的电脑上。对于较大的,我还不知道最好的求解器是什么,所以我只想使用 PETSc 并在那里使用迭代求解器。
我编写了一个简单的 C 驱动程序,并从 Fortran 调用它,所有代码请参见 [2],但问题仅在于这部分(更新:我已将所有行都放在此处以创建矩阵,正如我刚刚意识到的那样这是相关的):
ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr);
ierr = MatSetFromOptions(A);CHKERRQ(ierr);
ierr = MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr);
ierr = MatSetUp(A);CHKERRQ(ierr);
for (i=0; i<n; i++) col[i] = i;
ierr = MatSetValues(A,n,col,n,col,A_,INSERT_VALUES);CHKERRQ(ierr);
这非常慢(即对于 N~1500,这可能需要 2 秒,而实际上解决它是立即的),实际上这MatSetValues
条线几乎花费了整个特征值计算的 100% 时间......矩阵 A_ 是来自 Fortran 的二维矩阵。我试图禁用它,MAT_IGNORE_ZERO_ENTRIES
但它没有任何区别。所以我认为问题很简单,即使对于像 1500 这样的中等 N,我也需要使用一些稀疏矩阵格式,对吗?
所以我在我的 Fortran 代码中实现了 CSR 格式和矩阵(或对于) 现在我正试图弄清楚如何有效地将其提供给 PETSc。现在,我只想让一些东西按顺序工作,这比 Lapack 好。我应该MatCreateSeqAIJWithArrays
为此使用该功能吗?
这是最有效的方法吗?由于矩阵和不要改变,只有复数FEAST 算法和 FE 计算中的变化,我认为两者和具有相同的稀疏结构,可以通过预先分配稀疏结构然后快速评估来进一步改进在每次 FEAST 迭代中(,是 CSR 格式的值数组),我可以在 Fortran 中轻松做到这一点,但可能总是调用很慢MatCreateSeqAIJWithArrays
,所以一旦矩阵在 PETSc 中完成所有这些可能会更快和被转移过来。
我想知道这种 CSR 解决这个问题的方法是否正确,或者我做错了(显然我最初的方法MatSetValues
不是最优的)。感谢您的任何提示。
[1] http://www.ecs.umass.edu/~polizzi/feast/
[2] https://github.com/certik/hfsolver/pull/14
[3] http://www.mcs.anl.gov/petsc/petsc-3.1/docs/manualpages/Mat/MatCreateSeqAIJWithArrays.html