在 CentOS 上安装 OpenFOAM

本篇记录我在 CentOS 上编译安装 OpenFOAM 的过程。我需要在不能联网且没有 root 权限的集群上使用OpenFOAM ,最早的时候,我使用的是 centFOAM project 提供的 64bit CentOS 安装包,这个很方便,把压缩包下载,解压,然后配置一下环境变量就可以了。但是后来 centFOAM 好像不再更新了,所以我只好尝试着自己编译。

由于集群上缺少一些 OpenFOAM 依赖的包,要是一个一个去下载源码编译以补齐那些依赖的包,实在很费劲,所以我采取了另一种尝试:在虚拟机里安装跟集群上一样的系统,然后在虚拟机里编译好 OpenFOAM ,再拷贝到集群上去用(据信 cenoFOAM project 提供的安装包也是在虚拟机编译好的,而且在 cfd-online 论坛上也见有人推荐这么做)。我尝试过在 CentOS 5.4 ,CentOS 6.3 以及 Scientific Linux 6.5 上安装过 OpenFOAM-2.3.x,都成功了,过程大同小异。下面是我的安装过程的一个简要记录。

1 CentOS 6.3

首先,你需要一个虚拟机软件,我使用的是 VirtualBox,然后在虚拟机里安装一个64 bit 的CentOS 6.3(镜像可以去官网下载)。注意,要想在 VirtualBox安装 64 bit的虚拟机,你的主系统也必须是 64 bit,而且,还要求你的 CPU 支持并开启了虚拟化技术,见这个链接。然后,安装虚拟机的过程中,CentOS 6.3 会让你选择以哪种方式安装系统,我选择的是 “Software Development Workstation”,因为这种方式安装的包最全。以下是我在虚拟机里编译安装 OpenFOAM-2.3.x 的过程。

1.0 补充一些依赖包

确保你的虚拟机可以联网,然后运行以下命令补充一些包:

1
2
3
4
5
6
yum groupinstall 'Development Tools'

yum install glibc-devel.i686

yum install zlib.x86_64
yum install zlib-devel.x86_64

1.1 下载需要的源码包。

需要的源码包包括:OpenFOAM-2.3.x ,ThirdParty-2.3.x,这两个可以在OpenFOAM的官网找到,其中 OpenFOAM-2.3.x 可以用 git 从这里克隆一份;gcc-4.8.2, mpfr-3.1.2, gmp-5.1.2, mpc-1.0.1, boost-1.55.0, 这些可以OpenFOAM的 github 仓库里找到链接。因为有移植到集群上的需要,所以我这里需要自己编译gcc 和openmpi,这样,就不需要依赖集群系统上的 gcc 和 openmpi 了。

1.2 将源码包解压到合适的位置

建议在虚拟里,创建一个普通用户(假设为 user),不要用root用户来编译,以下操作都假定是以user用户的身份在进行。在 $HOME 下创建一个目录 OpenFOAM,然后将OpenFOAM-2.3.x 以及 ThirdParty-2.3.x 拷贝到该目录下(如果需要的话,先解压)。然后,解压 gcc-4.8.2,mpfr-3.1.2, gmp-5.1.2, mpc-1.0.1, boost-1.55.0, 并拷贝到 $HOME/ThirdParty-2.3.x 下,并将 boost-1.55.0 重命名为 boost-system。

1.3 编译前的配置和检查

打开$HOME/OpenFOAM/OpenFOAM-2.3.x/etc/config/settings.sh 文件,跳到

1
2
3
4
5
6
7
8
9
case "${foamCompiler}" in
OpenFOAM | ThirdParty)
case "$WM_COMPILER" in
Gcc | Gcc++0x | Gcc48 | Gcc48++0x)
gcc_version=gcc-4.8.2
gmp_version=gmp-5.1.2
mpfr_version=mpfr-3.1.2
mpc_version=mpc-1.0.1
;;

检查一下你下载的软件包版本跟这里的设置是否一样,如果不一致,可以直接修改这个文件以使这里的设置和你下载的版本一致。
此外,还需要跳到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
OPENMPI)
export FOAM_MPI=openmpi-1.6.5
# optional configuration tweaks:
_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config/openmpi.sh`

export MPI_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$FOAM_MPI

# Tell OpenMPI where to find its install directory
export OPAL_PREFIX=$MPI_ARCH_PATH

_foamAddPath $MPI_ARCH_PATH/bin

# 64-bit on OpenSuSE 12.1 uses lib64 others use lib
_foamAddLib $MPI_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH
_foamAddLib $MPI_ARCH_PATH/lib

_foamAddMan $MPI_ARCH_PATH/share/man
;;

看看你的 ThirdParty-2.3.x 下的 openmpi 的版本是否跟这里的一样(上面的设置是 openmpi-1.6.5),如果不一样,也需要修改这个文件。

然后,打开$HOME/OpenFOAM/OpenFOAM-2.3.x/etc/bashrc 文件,设置

1
2
foamCompiler=ThirdParty
export WM_MPLIB=OPENMPI

接着,打开~/.bashrc 文件,在最后一行输入”source $HOME/OpenFOAM/OpenFOAM-2.3.x/etc/bashrc”,保存后,在终端里运行一下

1
source ~/.bashrc

来加载跟OpenFOAM相关的环境变量。

最后,还需要检查一下 ThirdParty-2.3.x 目录下的那些编译辅助脚本,看看设置是否正确。需要检查的脚本有 makeGccmakeCGALmakeCmake,主要的检查项目仍然是看脚本里设置的软件包版本和实际下载的是否一致。比如,打开脚本 makeGcc ,有这么一段配置

1
2
3
4
gmpPACKAGE=gmp-5.1.2
mpfrPACKAGE=mpfr-3.1.2
mpcPACKAGE=mpc-1.0.1
gccPACKAGE=gcc-4.8.2

需要保证这里的设置与 ThirdParty-2.3.x 目录下实际的源码包的版本一致。

1.4 编译过程

上面的配置完成以后,就可以开始编译了。按如下顺序进行编译:

  • gcc
    运行 ThirdParty-2.3.x 下的脚本 makeGcc 即可。
    这一步完成以后,在终端里输入 gcc -v ,看看返回的版本是否是下载的那个版本。如若不然,重新运行一下 source ~/.bashrc ,再看看 gcc 的版本是否正常。要是不对的话,那就得检查一下 gcc 的编译过程是否出错了。gcc 的编译成功是前提,要是这一步没有成功,下面的也就无法进行了。
  • CGAL
    运行 makeCGAL 即可,boost 和 CGAL 的编译包括在这一步。
    完成以后,也同样需要检查一下是否编译成功。检查的办法是,看看 ThirdParty-2.3.x/platforms/linux64Gcc 下是否有 CGAL-4.3boost-system,然后看看这两个目录下是否都有 libbin 目录。如果没有,那就是编译出问题了,需要检查一下。
  • Cmake
    运行 makeCmake
    同样的,编译完以后需要检查是否成功。
  • ThirdParty的其他包
    运行 ThirdParty-2.3.x 下面的 Allwmake ,这一步包括了openmpi 以及 Scotch 的编译。
    正常的话,这一步编译完以后,应该就可以有 mpirun 以及 mpicc 等命令了。请运行 which mpirun 来检查编译是否成功。
  • 编译OpenFOAM-2.3.x
    $HOME/OpenFOAM/OpenFOAM-2.3.x 下去运行 Allwmake,进行 OpenFOAM 的编译。

建议将编译过程的输出保留下来,万一编译失败,可以根据编译过程的报错来找原因。比如,上面说的 “运行 makeGcc” ,在终端里可以这样操作

1
./makeGcc > log_gcc 2>&1 &

这样,便会将编译 gcc 过程中的正常输出信息和报错信息都输出到文件 “log_gcc” 里面。此外,后来我发现,其实运行 ThirdParty-2.3.x 下面的 Allwmake 时,其实也包括了”CGAL”的编译,所以其实 makeCGAL 不需要单独拿出来作为一步。

1.5 测试

编译结束以后,需要测试一下编译是否成功。建议至少运行一个串行算例,一个并行算例来检验 OpenFOAM 编译是否成功。最简单的是将 interFoam 求解器的 dambreak 算例串行运行一次,并行运行一次。

1.6 移植到集群

如果上述编译一切正常,那就可以考虑将编译好的OpenFOAM移植到集群了。移植之前,为了减少需要拷贝的文件的数量,可以将一些不需要的源码和编译过程产生的中间文件删除。比如,ThirdParty-2.3.x 目录下的 gcc, mpfr,gmp,mpc以及 boost 的源码包都删除(openmpi-1.6.5 的源码建议保留),因为有用的是文件其实都在 platforms 目录下,只要保证这个目录完好就可以了。然后,建议将 $HOME/OpenFOAM 整个目录打包,再拷贝到集群上去。打包的目的有两个,一是减小文件的空间占用,另外一个更重要的原因是,OpenFOAM 的编译过程中会产生很多重要的软链接,如果不打包,这些软链接容易在拷贝的过程中损坏(比如,假如你用U盘拷贝 OpenFOAM 这个目录,那软链接几乎肯定会损坏)。

将压缩包拷贝到集群,在你的 $HOME 下解压。建议你在集群上也创建跟在虚拟上一样的目录结构,即在$HOME下创建目录 OpenFOAM,然后将 OpenFOAM-2.3.x 和 ThirdParty-2.3.x 拷贝到OpenFOAM目录下,这样,就不再需要去修改OpenFOAM的安装路径这个环境变量了。万一你没法做到这一点,那么,你需要修改 OpenFOAM-2.3.x/etc/bashrc 文件,将 foamInstall=$HOME/$WM_PROJECT 修改成你的实际路径(这里 $HOME/$WM_PROJECT=$HOME/OpenFOAM)。

然后,类似的,打开~/.bashrc 文件,在最后一行输入”source $HOME/OpenFOAM/OpenFOAM-2.3.x/etc/bashrc”,保存后,在终端里运行一下

1
source ~/.bashrc

一切正常的话,移植工作就完成了。

当然,也需要测试一下移植是否成功,同样可以通过运行 dambreak算例来测试。我曾经遇到的问题是,串行可以运行,但是并行出问题了。对于这种情况,解决办法是,到 OpenFOAM/OpenFOAM-2.3.x/src/Pstream 目录下, dummympi 下运行 wclean,然后,运行 Pstream 下面的 Allwmake ,重新编译 dummympi 。如果这样编译了仍然不能并行,那么还可以再试试重新编译openmpi,具体做法是,删除 ThirdParty-2.3.x/platforms/linux64GccDPOpt/lib/openmpi-1.6.5 以及 ThirdParty-2.3.x/platforms/linux64Gcc/openmpi-1.6.5,然后重新运行ThirdParty-2.3.x 下的 Allwmake,编译完以后在重新编译一下 dummympi。一般情况下,可以编译成功,因为编译需要的东西其实都在 ThirdParty-2.3.x 下面包含了,不需要依赖系统的什么包,这也是自己上面自己手动编译 gcc 等这些包带来的好处。这样处理以后,就可以正常并行运行了。

2. CentOS 5.4

CentOS 5.4 上的编译和移植过程几乎和上面是一样的,只有几个细节不同,比如,安装依赖包的时候,

1
yum install glibc-devel.i686

应该是

1
yum install glibc-devel.i386

其他的差别,在我印象中是没有了。

最后,有必要提一下一个诡异的失败经历,这个问题我至今也不知道是什么原因导致的。
有一次在移植到集群的时候,重新编以 openmpi 的过程中遇到如下报错:

1
CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/sh /storage02.mnt/home/lmu/OpenFOAM/ThirdParty-2.3.x/openmpi-1.6.5/config/missing --run aclocal-1.11 -I config

导致 openmpi 无法编译。
但是,将OpenFOAM拷贝到另一个目录(不再是 $HOME/OpenFOAM ),再重新尝试,却成功了。

另一次,是在 Scientific Linux 上,也是重新编译 openmpi 的时候遇到了一样的报错,后来解决的办法是,弃用ThirdParty下的 openmpi,改启用系统的openmpi(虽然版本老一点),具体设置是将” export WM_MPLIB=OPENMPI” 改为 “ export WM_MPLIB=SYSTEMOPENMPI”,改完以后也能成功并行运行。

本篇博文,由于是写在我编译 OpenFOAM 好几个月之后,当时也没有详细记录编译过程,所以肯定有细节遗漏或者错误的地方。而且,在不同的系统上,也可能遇到我这里没有提到的问题,本篇博文仅仅是给有需要的人做一个参考。要是你编译过程中遇到某个问题在看了本文后得到了解决,那我的目的就达到了。有问题 ,欢迎来OpenFOAM开源计算千人群讨论交流。

2016.05.22 补充
最近编译了 OpenFOAM-v3.0+,使用 gcc-4.9.3 和 openMPI-1.10.0,在编译过程中,流程跟上面是一样的,但是有些额外的步骤。

  1. 编译 gcc 的时候,报错说找不到 lgcc_s,提示可能是缺少32位的库,经过 “ yum install libgcc “ 和 “ yum install libgcc.i686 “ 后,问题解决。
  2. 编译 openmpi-1.10.0 时,遇到提示 autoconf 和 aclocal 版本不对,经过源码编译安装 autoconf-2.69 和 automake-1.12 后,问题解决。