深入理解 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
脚本中定义了多个变量,按照编译、运行和第三方函数库相关可以分为三类。
- 与编译相关的
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
脚本,即可生成按照自定义规则编译的二进制程序。
深入理解 OpenFOAM 环境变量与编译的更多相关文章
- Nodejs第一天-{Nodejs基础 深刻理解浏览器 环境变量 基础语法}
Nodejs第一天 1.什么是Nodejs Nodejs是一个可以运行(解析)ECMAScript的环境; ECMAScript是规定了一些列的语法 ,这些语法想要解析的执行就需要放在某个环境 ...
- window环境变量
首先Window中有很多乱七八糟的路径变量之类的,归类下来有几类,主要是为了我们分清楚概念,以免搞的糊涂了. 1. Window系统的环境变量:顾名思义,就是系统级别的变量,或者利用我们编程的角度来讲 ...
- 一文彻底搞懂Java中的环境变量
一文搞懂Java环境变量 记得刚接触Java,第一件事就是配环境变量,作为一个初学者,只知道环境变量怎样配,在加上各种IDE使我们能方便的开发,而忽略了其本质的东西,只知其然不知其所以然,随着不断的深 ...
- 【转】windows7 修改环境变量 和 用不用重启电脑的讨论
原文:http://www.cnblogs.com/zhenmingliu/archive/2013/02/21/2921396.html 先到我的电脑>属性>高级>环境变量 ...
- GCC相关的环境变量
介绍GCC在编译阶段和程序运行阶段用到的环境变量. GCC编译时用到的环境变量 GCC编译时用到的变量. C_INCLUDE_PATH GCC编译时查找头文件的目录列表.比如: echo $C_INC ...
- Shell 全局变量、环境变量和局部变量
Shell 变量的作用域(Scope),就是 Shell 变量的有效范围(可以使用的范围). 在不同的作用域中,同名的变量不会相互干涉,就好像 A 班有个叫小明的同学,B 班也有个叫小明的同学,虽然他 ...
- 延迟环境变量扩展(bat)
延迟环境变量扩展(bat) 之前遇到一些环境变量的问题,简单记录下 From:http://www.cnblogs.com/dongzhiquan/archive/2012/09/05/2671218 ...
- Linux学习总结(十)-文件复制及查看, 环境变量
一 文件复制及移动 1.命令 cp --------copy 的意思格式 cp 选项 源文件 目标文件a: 对于文件我们直接cp 文件 目标文件假定我们在普通用户家目录下/home/lv新建两个普通文 ...
- [小记]Windows下配置环境变量和需不需要重启问题
经常看到一些软件的安装说明上写着,修改Windows的环境变量,然后重新启动计算机.这让人不禁产生疑问,修改环境变量之后真的要重启吗? 其实只要理解了环境变量的原理就可以做出正确的判断.环境变量是一些 ...
随机推荐
- 【Spring】重新认识 IoC
前言 IoC (Inversion of control) 并不是Spring特有的概念. IoC 维基百科的解释: In software engineering, inversion of con ...
- 天脉2(ACoreOS653)操作系统学习02
天脉2(ACoreOS653)操作系统学习02 一.分区内通信方法 分区内通信指同一分区内进程之间的通信.ARINC 653定义的分区内进程通信机制,包括:缓存队列(Buffers-Queue).黑板 ...
- 【UE4 C++ 基础知识】<6> 容器——TMap
概述 TMap主要由两个类型定义(一个键类型和一个值类型),以关联对的形式存储在映射中. 将数据存储为键值对(TPair<KeyType, ValueType>),只将键用于存储和获取 映 ...
- js判断移动端浏览器类型,微信浏览器、支付宝小程序、微信小程序等
起因 现在市场上各种跨平台开发方案百家争鸣各有千秋,个人认为最成熟的还是hybird方案,简单的说就是写H5各种嵌入,当然作为前端工程师最希望的也就是公司采用hybird方案当作技术路线. 所谓的hy ...
- 欧姆龙PLC HostLink协议整理
欧姆龙PLC HostLink协议整理 1.常用的存储器功能区 CIO: 输入继电器 272 点(17 CH) 0.00-16.15 输出继电器 272 点(17 CH) 100.00-116.1 ...
- mybatis自定义分页拦截器
最近看了一下项目中代码,发现系统中使用的mybatis分页使用的是mybatis自带的分页,即使用RowBounds来进行分页,而这种分页是基于内存分页,即一次查出所有的数据,然后再返回分页需要的数据 ...
- Noip模拟51 2021.9.12
T1 茅山道术 考场上卡在了一个恶心的地方, 当时以为每次施法都会产生新的可以施法的区间,然后想都没细想, 认为不可做,甚至$dfs$也无法打,考后一问发现是自己想多了.. 新产生的区间对答案根本没有 ...
- Noip模拟49 2021.9.7
T1 reverse 又一道板子打假的挂分题,直接挂到倒二.. 考场上思路神奇,居然想到用$bfs$建边然后跑最短路, 其实当时也想到了直接$bfs$,但是不知道为啥觉得$dij$屌就没直接打$bfs ...
- PCB电路板元器件布局的一般原则*(转)
PCB电路板元器件布局的一般原则: 设计人员在PCB电路板布局过程中需要遵循的一般原则如下. (1)元器件最好单面放置.如果需要双面放置元器件,在底层(Bottom Layer)放置插针式元器件, ) ...
- numpy中的nan和常用方法
1.数组的拼接 import numpy as np t1 = np.array([[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]) t2 = np.array([ ...