PETSc 真的能让 OpenFOAM 如虎添翼吗?

PETSc 是美国阿贡国家实验室开发的轻便式可拓展科学计算工具箱(Portable Extensible Toolkit for Scientific computing),读作 pet-see。将 PETSc 植入 OpenFOAM 替换其原生线性求解器的研究早已有之,但实际效果比较有争议,有研究认为 PETSc 远胜于 OpenFOAM 的原生求解器,也有研究认为 PETSc 在很多情况下远逊于 OpenFOAM 的原生求解器,甚至会花费数倍时间。

这些争议引起了小编的关注,小编决定把玩一下这个大名鼎鼎的工具箱。OpenFOAM® v2006 将 PETSc 作为外部求解器整合进了 ThirdParty 包[1],写好了现成的编译脚本,还带有教程。

OpenFOAM® v2006 的编译过程非常容易,如果要使用 PETSc,可以先编译 PETSc,再编译 OpenFOAM。如果你已经有了编译好的 OpenFOAM® v2006,也不用清除,编译好 PETSc,再运行 OpenFOAM 的 Allwmake 脚本就可以更新相应的组件。编译 PETSc 时,容易遇到的问题是网络不好,导致一些源码下载失败。这种情况可以开代理服务器,手动下载,并相应地修改脚本。PETSc 的编译过程参见[1]的最后一节,OpenFOAM 的编译过程参见 OpenFOAM® Quick Build Guide[2]

编译好 PETSc 后,运行 PETSc 的示例,位置是 OpenFOAM-v2006/modules/external-solver/tutorials,涉及到 laplacianFoam 和 simpleFoam 两个求解器,但 PETSc 是通用的,也可以在其他求解器中调用。

我们重点研究下 simpleFoam/pitzDaily 这个算例,无脑跑一下 PETSc,再和原生的对比,计算结果非常惊人。PETSc 只用了 1 s,而原生的 pitzDaily 居然用了 10 s。 PETSc 的 log 文件大概是这样的

Time = 1

Initializing PETSc
PETSc-bicg:  Solving for Ux, Initial residual = 0, Final residual = 0, No Iterations 1
PETSc-bicg:  Solving for Uy, Initial residual = 0, Final residual = 0, No Iterations 1
PETSc-cg:  Solving for p, Initial residual = 0, Final residual = 0, No Iterations 154
time step continuity errors : sum local = 1.71696, global = -0.010057, cumulative = -0.010057
PETSc-bicg:  Solving for epsilon, Initial residual = 0, Final residual = 0, No Iterations 2
bounding epsilon, min: -1.45735 max: 1080.25 average: 48.855
PETSc-bicg:  Solving for k, Initial residual = 0, Final residual = 0, No Iterations 3
ExecutionTime = 0.57 s  ClockTime = 1 s
Code language: PHP (php)

自带的算例毕竟是海专精的结果,如果把类似的配置无脑迁移到其他算例,是否还能有如此惊人的效果呢?

接下来,我们看一下两种求解器的配置参数,然后迁移到 compressibleInterFoam/depthCharge3D 这个算例。

配置有 PETSc 的 simpleFoam 的 fvSolution 中的 solvers 字段如下

solvers
{
    p
    {
        solver petsc;

        petsc
        {
            options
            {
                ksp_type  cg;
                ksp_cg_single_reduction  true;
                ksp_norm_type none;

// With or without hypre
#if 0
                pc_type  hypre;
                pc_hypre_type boomeramg;
                pc_hypre_boomeramg_max_iter "1";
                pc_hypre_boomeramg_strong_threshold "0.25";
                pc_hypre_boomeramg_grid_sweeps_up "1";
                pc_hypre_boomeramg_grid_sweeps_down "1";
                pc_hypre_boomeramg_agg_nl "1";
                pc_hypre_boomeramg_agg_num_paths "1";
                pc_hypre_boomeramg_max_levels "25";
                pc_hypre_boomeramg_coarsen_type HMIS;
                pc_hypre_boomeramg_interp_type ext+i;
                pc_hypre_boomeramg_P_max "1";
                pc_hypre_boomeramg_truncfactor "0.3";
#else
                pc_type bjacobi;
                sub_pc_type ilu;
#endif
            }

            caching
            {
                matrix
                {
                    update always;
                }

                preconditioner
                {
                    update always;
                }
            }
        }

        tolerance       1e-06;
        relTol          0.1;
    }

    "(U|k|epsilon|omega|f|v2)"
    {
        solver petsc;

        petsc
        {
            options
            {
                ksp_type bicg;
                pc_type bjacobi;
                sub_pc_type ilu;
            }

            caching
            {
                matrix
                {
                    update always;
                }

                preconditioner
                {
                    update always;
                }
            }
        }

        tolerance       1e-05;
        relTol          0.1;
    }
}Code language: PHP (php)

而 OpenFOAM 原生的 fvSolution 中的 solvers 字段如下

solvers
{
    p
    {
        solver          GAMG;
        tolerance       1e-06;
        relTol          0.1;
        smoother        GaussSeidel;
    }

    "(U|k|epsilon|omega|f|v2)"
    {
        solver          smoothSolver;
        smoother        symGaussSeidel;
        tolerance       1e-05;
        relTol          0.1;
    }
}Code language: JavaScript (javascript)

可见,PETSc 使用 cg 方法、OpenFOAM 默认使用 GAMG 方法来求解压强场。PETSc 提供了非常丰富的求解控制参数。字典中提到的 hypre 是另一个适用于大规模并行的求解器,常常和 PETSc 配合使用,贫民窟男孩并没有大规模并行的实验条件,所以没有编译 hypre。

我将上述配置迁移到 compressibleInterFoam/depthCharge3D,统一了 tolerance。结果真的反转了,PETSc 用的时间更多,用了 7325 s,原生 OpenFOAM 用了 5294 s。可能是我的使用经验不足,没能发挥出 PETSc 的性能,我再调调参数,有了新进展向大家报告。

欢迎有经验的朋友在评论区聊聊心得,也可加微信拍砖(微信号:goodbountyhunter);不推荐新手入坑 PETSc,这并不是一个可以无脑硬上的算法。

参考

  1. ^OpenFOAM® v2006: New and improved numerics https://www.openfoam.com/releases/openfoam-v2006/numerics.php
  2. ^OpenFOAM® Quick Build Guide https://develop.openfoam.com/Development/openfoam/blob/develop/doc/Build.md

常恭

作者: 常恭

略懂 OpenFOAM

发表评论