如何为具有潜在不同非零结构的连续迭代解决方案分配内存?

计算科学 有限差分 宠物 内存管理
2021-12-26 01:05:21

背景

我正在使用交替方向隐式 (ADI) 方法求解 3D 中的不稳定热方程。这意味着我在一个时间步长内求解三个不同的三对角系统(每个笛卡尔轴一次)。这些矩阵的大小约为 10^5 x 10^5。

尽管每个方向的A矩阵沿三个对角线都具有非零值,但在某些情况下,一个方向沿对角线之一将具有零值,而另一个方向则没有。

我最初的计划是建立一个 AIJ 矩阵并为 3 个非零值预分配,并为三个方向中的每一个重用相同的内存分配。这可以很好地解决第一个方向,但是当我击中第二个方向时,PETSc 会抱怨,因为我试图在以前没有的地方添加一个新的非零值(与边界条件的差异有关)。

问题

最有效的方法是什么:

  • 有没有办法以不同的方式分配,让我的值在零和非零之间变化?
  • 或者我应该为每个方向创建一个新矩阵和新分配?(我知道这可行,但我担心为每个解决方案破坏和创建新矩阵的开销。)
  • 其他选择?

在伪代码中,我的程序如下所示:

// Create and preallocate A matrix:
MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,M,M,3,NULL,3,NULL,&Amat);
    
// Create x vector
VecCreate(PETSC_COMM_WORLD,&x);

// Create b vector
VecDuplicate(x,&b);

// Solve for each timestep:
for (each timestep)
{
    for (X,Y,Z)
    {
        MatSetValues(Amat,...,INSERT_VALUES);
        VecSetValues(b,...,INSERT_VALUES);

        MatAssemblyBegin(Amat,MAT_FINAL_ASSEMBLY);
        MatAssemblyEnd(Amat,MAT_FINAL_ASSEMBLY);
        
        VecAssemblyBegin(b);
        VecAssemblyEnd(b);   
     
        KSPSetOperators(ksp, Amat, Amat, DIFFERENT_NONZERO_PATTERN);
        KSPSetUp(ksp);
        KSPSolve(ksp,b,x);

        MatZeroEntries(Amat);
    }
}
1个回答
  1. ADI 不是一个很好的并行算法。您应该认真考虑在 3D 中制定问题并使用多重网格求解。你可以从src/ksp/ksp/examples/tutorials/ex45.c.

  2. 如果你坚持使用ADI,你应该认真考虑分别分配三个矩阵。这是更多的内存,但是您不必在每次迭代时重新组装,因此您可以摊销设置成本。这会使用更多内存。

  3. 如果您坚持使用 ADI 并为每个方向重复使用相同的矩阵,您应该为每行分配三个非零并填充显式零,即使该方向缺少条目也是如此。否则,第一个程序集会压缩未使用的条目,以后就不能廉价地插入它们。

其它你可能感兴趣的问题