深入理解 OpenFOAM 環境變量與編譯


操作系統選擇

由於 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 腳本中定義了多個變量,按照編譯、運行和第三方函數庫相關可以分為三類。

  1. 與編譯相關的 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 # 編譯設置
  1. 與運行相關的 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
  1. 第三方庫相關變量
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_RULESRULES 為定義的兩個編譯規則變量,可以看出編譯規則名稱由平台 $(WM_ARCH) 和編譯器 $(WM_COMPILER) 組成。
DEFAULT_RULESRULES 變量的區別主要在於,前者中刪除了 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 作為編譯規則配置文件。
在此目錄下 cc++ 兩個文件包含了編譯器的基本設置,在OptDebugProf等后綴的對應文件內,定義了不同優化設置 WM_COMPILE_OPTION 時使用的參數。
為使用 Intel 2019.5.281 版本編譯器,可以修改 cc++ 文件中 CC 變量的值為 icc 和 icpc。為了省去在編譯時指定對應的 MPI 頭文件和動態鏈接庫的位置,也可以直接用 mpiicc 和 mpiicpc 分別作為 C/C++ 程序編譯器。
在對第三方函數庫進行編譯時,使用的編譯器由 WM_CCWM_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 腳本,即可生成按照自定義規則編譯的二進制程序。


  1. https://cfd.direct/openfoam/user-guide/v7-compiling-applications/ ↩︎

  2. https://www.openfoam.com/documentation/guides/latest/api/classFoam_1_1functionEntries_1_1sincludeEntry.html ↩︎


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM