操作系統選擇
由於 OpenFOAM 在 Linux 平台開發和測試,在非 Linux 平台無法直接對軟件進行編譯和安裝,所以在非 Linux 平台上最簡便方法是使用 docker 容器運行 OpenFOAM。下面主要介紹在 Linux 平台上 OpenFOAM 源程序編譯安裝過程。
環境變量
在 OpenFOAM 編譯和運行時,需要設置多個環境變量。在源程序路徑 ${FOAM_DIR}/etc
下,腳本文件 bashrc
包含了軟件編譯和運行所需的所有環境變量的設置,可以直接通過 source
命令加載。
為什么要用 source 命令?
在 OpenFOAM 中,bashrc 其實是一個 shell 腳本,這個腳本里定義了所需的環境變量。在 Linux 環境中,執行 shell 腳本有多種形式。以 bash 腳本為例,首先可以通過新開啟一個 shell 並在新的環境中運行腳本,這種方式可以用
bash
命令執行此腳本,或者在腳本第一行添加#!/bin/bash
說明執行腳本的程序,隨后添加執行權限后直接執行此腳本。$ bash ${FOAM_DIR}/etc/bashrc # bash 命令執行 $ ${FOAM_DIR}/etc/bashrc # 直接執行
這兩種方法執行效果是相同的,當新的 shell 運行腳本完畢后再返回當前環境,此時當前 shell 的工作環境是未變的,也就是說執行完畢后是無法看到
bashrc
腳本內定義的環境變量。另外一種方式就是在當前 shell 環境中執行此腳本,這時在腳本名前使用
.
或者source
命令,如下所示。$ . ${FOAM_DIR}/etc/bashrc # 使用 . 執行 $ source ${FOAM_DIR}/etc/bashrc # 使用 source 命令執行
此時腳本內定義的變量或所做的修改都會直接添加到當前 shell 環境內,這種方式才是正確加載 OpenFOAM 環境變量方法。
在 bashrc
腳本中定義了多個變量,按照編譯、運行和第三方函數庫相關可以分為三類。
- 與編譯相關的
WM_XXX
變量
WM_THIRD_PARTY_DIR=$HOME/OpenFOAM/ThirdParty-1.6.x # 第三方函數庫路徑
WM_PROJECT_INST_DIR=$HOME/OpenFOAM
WM_PROJECT_DIR=$HOME/OpenFOAM/OpenFOAM-1.6.x # 源程序路徑
WM_DIR=$HOME/OpenFOAM/OpenFOAM-1.6.x/wmake #
WM_PROJECT_USER_DIR=$HOME/OpenFOAM/$USER-1.6.x # 用戶路徑
WM_PRECISION_OPTION=DP # 精度設置
WM_ARCH_OPTION=64 #
WM_LINK_LANGUAGE=c++ # 鏈接器
WM_ARCH=linux64 # 平台架構
WM_CXXFLAGS=-m64 -fPIC # c++ 編譯器參數
WM_CFLAGS=-m64 -fPIC # c 編譯器參數
WM_PROJECT_VERSION=1.6.x # 版本
WM_COMPILER_LIB_ARCH=64 #
WM_CXX=g++ # c++ 編譯器
WM_COMPILER_ARCH=
WM_PROJECT=OpenFOAM # 工程名
WM_LDFLAGS=-m64 # 鏈接器參數
WM_COMPILER=Gcc # 編譯器
WM_MPLIB=OPENMPI # MPI 函數庫
WM_CC=gcc # C 編譯器
WM_COMPILE_OPTION=Opt # 編譯選項
WM_OPTIONS=linux64GccDPOpt # 編譯設置
- 與運行相關的
FOAM_XXX
變量
FOAM_SOLVERS=$HOME/OpenFOAM/OpenFOAM-1.6.x/applications/solvers
FOAM_APPBIN=$HOME/OpenFOAM/OpenFOAM-1.6.x/applications/bin/linux64GccDPOpt
FOAM_TUTORIALS=$HOME/OpenFOAM/OpenFOAM-1.6.x/tutorials
FOAM_JOB_DIR=$HOME/OpenFOAM/jobControl
FOAM_LIB=$HOME/OpenFOAM/OpenFOAM-1.6.x/lib
FOAM_SITE_APPBIN=$HOME/OpenFOAM/site/1.6.x/bin/linux64GccDPOpt
FOAM_MPI_LIBBIN=$HOME/OpenFOAM/OpenFOAM-1.6.x/lib/linux64GccDPOpt/openmpi-1.3.3
FOAM_APP=$HOME/OpenFOAM/OpenFOAM-1.6.x/applications
FOAM_SITE_LIBBIN=$HOME/OpenFOAM/site/1.6.x/lib/linux64GccDPOpt
FOAM_SRC=$HOME/OpenFOAM/OpenFOAM-1.6.x/src
FOAM_SIGFPE=
FOAM_UTILITIES=$HOME/OpenFOAM/OpenFOAM-1.6.x/applications/utilities
FOAM_USER_LIBBIN=$WM_PROJECT_USER_DIR/lib/linux64GccDPOpt
FOAM_INST_DIR=$HOME/OpenFOAM
FOAM_LIBBIN=$HOME/OpenFOAM/OpenFOAM-1.6.x/lib/linux64GccDPOpt
FOAM_RUN=$WM_PROJECT_USER_DIR/run
FOAM_USER_APPBIN=$WM_PROJECT_USER_DIR/applications/bin/linux64GccDPOpt
- 第三方庫相關變量
MPI_ARCH_PATH=$HOME/OpenFOAM/ThirdParty-1.6.x/openmpi-1.3.3/platforms/linux64GccDPOpt
ParaView_INST_DIR=$HOME/OpenFOAM/ThirdParty-1.6.x/paraview-3.6.1
OPAL_PREFIX=$HOME/OpenFOAM/ThirdParty-1.6.x/openmpi-1.3.3/platforms/linux64GccDPOpt
ParaView_DIR=$HOME/OpenFOAM/ThirdParty-1.6.x/paraview-3.6.1/platforms/linux64Gcc
PARAVIEW_DIR=/opt/packages/Paraview3
ParaView_VERSION=3.6.1
MPI_HOME=$HOME/OpenFOAM/ThirdParty-1.6.x/openmpi-1.3.3
在正確設置上述環境變量后,即可對 OpenFOAM 源程序進行編譯,並運行對應的求解器和工具。
編譯系統
在大型程序編譯與安裝過程中,通常使用 make 和 cmake 等工具構建。在 OpenFOAM 中,使用的是 wmake 腳本進行編譯,所在位置為 ${FOAM_DIR}/wmake/wmake
。
查看此腳本可以發現,其編譯是基於 make 修改,但是提供了針對 OpenFOAM 不同模塊更靈活的特性,具體可參考網站[1]。
wmake 編譯
在 Linux 平台編譯軟件時,通常需要給定一些編譯和優化參數。在使用 wmake 編譯時,編譯腳本會則根據環境變量會加載對應的參數設置腳本進行編譯。
在 OpenFOAM 中,編譯參數設置文件所在路徑為 ${FOAM_DIR}/wmake/rules/<Rules>
,其中 <Rules>
成為編譯規則,與環境變量中定義的編譯平台、架構、編譯器設置有關。
編譯規則的定義在腳本 ${FOAM_DIR}/wmake/rules/General/general
中,查看腳本最后幾行
$ tail -n 20 ${FOAM_DIR}/wmake/rules/General/general
COMPILER_TYPE = $(shell echo $(WM_COMPILER) | tr -d [:digit:])
DEFAULT_RULES = $(WM_DIR)/rules/$(WM_ARCH)$(COMPILER_TYPE)
RULES = $(WM_DIR)/rules/$(WM_ARCH)$(WM_COMPILER)
WMAKE_BIN = $(WM_DIR)/platforms/$(WM_ARCH)$(WM_COMPILER)
......
include $(DEFAULT_RULES)/general
include $(DEFAULT_RULES)/c++
sinclude $(RULES)/general
sinclude $(RULES)/c++
include $(GENERAL_RULES)/transform
其中 DEFAULT_RULES
和 RULES
為定義的兩個編譯規則變量,可以看出編譯規則名稱由平台 $(WM_ARCH)
和編譯器 $(WM_COMPILER)
組成。
DEFAULT_RULES
和 RULES
變量的區別主要在於,前者中刪除了 WM_COMPILER
中包含的所有數字,而默認加載的是 DEFAULT_RULES
路徑下編譯設置文件。
為了保證在定義規則時能夠添加數字,可以修改 DEFAULT_RULES
,使其與 RULES
定義完全相同。
在加載腳本指令中,#sinclude
為 OpenFOAM 自定義的宏指令。與 #include
主要區別在於,當加載文件不存在時不會報錯並退出[2]。
當使用某個編譯規則編譯完成后,生成中間文件 *.o
的路徑為 ${FOAM}/build/$(DEFAULT_RULES)
,而可執行程序的路徑為 ${FOAM}/platforam/<makeRule>
。
這些路徑的定義都包含在了環境配置文件 ${FOAM}/etc/bashrc
中 ,並且還將可執行程序路徑自動添加到 PATH
變量內,從而可以直接運行 OpenFOAM 工具和求解器。
由於 wmake 是基於 make 命令實現的,因此其也具有自動推導功能。當對某個特定源程序文件進行修改后,wmake 只會重新編譯包含與此文件相關的模塊。
wmake 使用
1. 編譯文件結構
在使用 make 編譯源程序時,需要在 makefile 中指定編譯指令,並提供引用的頭文件和動態鏈接庫位置。當使用 wmake 腳本時,則僅按照一定規則配置說明文件即可。
在 OpenFOAM 每個模塊內,源程序文件后綴為 .C
,頭文件后綴為 .H
。為了提供編譯所需的信息,在文件夾內必須同時包含 Make 文件夾,內含 files 和 options 兩個設置文件。以 icoFoam 求解器為例,其編譯文件結構為
icoFoam
├── createFields.H
├── icoFoam.C
└── Make
├── files
└── options
在 files
文件內,包含了進行編譯程序全路徑和名字(EXE
變量)。關於安裝路徑可以提供兩種形式,一個是標准路徑,編譯好的求解器儲存在 $FOAM_APPBIN
,也可以保存在用戶自己的路徑 $FOAM_USER_APPBIN
中。在 icoFoam
求解器中,配置文件files
內容如下所示,其中 EXE
變量說明了需編譯生成可執行程序,當目標為動態鏈接庫時使用 LIB
變量。
$ cat icoFoam/Make/files
icoFoam.C
EXE = $(FOAM_APPBIN)/icoFoam
options
文件內指定了模塊需要連接的頭文件和鏈接庫,其中頭文件使用 EXE_INC
和 -I
關鍵字進行指定,而連接庫則需要用 EXE_LIBS
和 -L/-l
等指定。在 icoFoam 求解器中 options
文件的內容為
$ cat icoFoam/Make/options
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools
2. 模塊編譯
在 OpenFOAM 中,對特定模塊編譯時,需要進入模塊上一層目錄下,使用 wmake
+ <模塊名>
進行編譯。在 wmake
命令運行時,可以通過增加 -j
參數可以啟用並行編譯指令。當需要對 OpenFOAM 全部代碼進行編譯時,可以直接運行源程序目錄下 Allwmake
腳本。
當需要刪除特定求解器和動態庫時運行 wclean
命令,若需將全部求解器和動態庫,加 -all
參數。
自定義編譯規則:Intel-2019
在本節中,將定義一個新的編譯規則,設置采用 intel 2019.5.281 版本編譯器和 MPI 函數庫進行編譯,並對編譯設置文件進行相應修改。
為了在編譯后,能夠通過加載單獨的 bashrc
腳本來使用不同的 OpenFOAM 可執行程序,可以復制一份 bashrc
文件的拷貝 bashrc-intel-19
,並在此文件中修改 WM_COMPILER=Intel-19
。此時自定義編譯規則名為 linux64Intel-19
。
在使用默認參數對 OpenFOAM 編譯后,生成可執行程序使用的是 SSE 指令集。隨着新一代 CPU 開始提供浮點性能更高的 AVX 系列指令集,可以通過修改編譯參數,使求解器使用 AVX 指令集。
這時,需要在新的編譯配置文件中進行修改。為此,復制目錄 ${FOAM_DIR}/wmake/rules/linux64Icc
,並將目錄名稱修改為 ${FOAM_DIR}/wmake/rules/linux64Intel-19
作為編譯規則配置文件。
在此目錄下 c
和 c++
兩個文件包含了編譯器的基本設置,在Opt
、Debug
、Prof
等后綴的對應文件內,定義了不同優化設置 WM_COMPILE_OPTION
時使用的參數。
為使用 Intel 2019.5.281 版本編譯器,可以修改 c
和 c++
文件中 CC 變量的值為 icc 和 icpc。為了省去在編譯時指定對應的 MPI 頭文件和動態鏈接庫的位置,也可以直接用 mpiicc 和 mpiicpc 分別作為 C/C++ 程序編譯器。
在對第三方函數庫進行編譯時,使用的編譯器由 WM_CC
和 WM_CXX
變量提供,因此還需要在配置文件 bashrc-intel-19
中,添加這兩個變量的定義。
$ echo 'export WM_CC=icc' >> ${FOAM_DIR}/etc/bashrc-intel-19
$ echo 'export WM_CC=icpc' >> ${FOAM_DIR}/etc/bashrc-intel-19
設置完畢后,加載新的環境配置文件 ${FOAM_DIR}/etc/bashrc-intel-19
,再運行Allwmake
腳本,即可生成按照自定義規則編譯的二進制程序。