从我的 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