OpenFOAM-script:RunFunctions

description: Miscellaneous functions for running tutorial cases.

该脚本中包含了运行tutorial算例所涉及到的各种函数。实际调用中最常见的是runApplicationrunParallel,另外两个函数服务于这两个函数:getApplicationgetNumberOfProcessors

串行应用

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory

# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions

# 划分网格
runApplication blockMesh
# 运行求解
application=$(getApplication)
runApplication $application

并行应用

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
cd ${0%/*} || exit 1

# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions

runApplication blockMesh
runApplication decomposePar
runParallel $(getApplication)
runApplication reconstructPar

下面分函数来分开解释该脚本。

isTest()

功能:检查参数中是否包含 -test 选项:包含则返回0;否则返回1。

1
2
3
4
5
6
7
8
9
10
isTest()
{
for i in "$@"; do # 遍历每个参数,分辨检查是否等于"-test"
if [ "$i" = "-test" ]
then
return 0
fi
done
return 1
}

getNumberOfProcessors()

功能:获取decomposeParDict中设置的进程数。

1
2
3
4
getNumberOfProcessors()  # 基于foamDictionary工具
{
foamDictionary -entry numberOfSubdomains -value system/decomposeParDict
}

getApplication()

功能:获取controlDict中设置的求解器application。

1
2
3
4
getApplication()  # 基于foamDictionary工具
{
foamDictionary -entry application -value system/controlDict
}

应用举例:

1
2
# 获取application的名称
application=$(getApplication)

runApplication()

功能:串行运行求解。调用方式:

1
runApplication [own_options] app [app_options]

其中own_options用于表示该函数可用的选项,包括:-append|-a-overwrite|-o-suffix|-s。这三个选项分别表示处理日志文件(即log.xxx文件)的方式:-a表示以追加的方式记录日志到已存在的日志文件上;-o表示覆盖已存在的日志文件;-s用于指定日志文件的后缀。
app用于指定求解器,通常由getApplication函数获得。app后面的参数都会直接传递给求解器。

runParallel函数用法类似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
runApplication() 
{
APP_RUN=
LOG_IGNORE=false
LOG_APPEND=false
LOG_SUFFIX=

# Parse options and executable
while [ $# -gt 0 ] && [ -z "$APP_RUN" ]; do # 参数数目>1并且APP_RUN的值为空
key="$1" # 取第一个参数
case "$key" in
-append|-a)
LOG_IGNORE=true
LOG_APPEND=true
;;
-overwrite|-o)
LOG_IGNORE=true
;;
-suffix|-s)
LOG_SUFFIX=".$2"
shift
;;
*)
APP_RUN="$key"
APP_NAME="${key##*/}"
LOG_SUFFIX="${APP_NAME}${LOG_SUFFIX}"
;;
esac

shift # 注意这里的shift,用于移动位置参数
done

# 已经存在log文件,且不忽略已存在的log文件
if [ -f log.$LOG_SUFFIX ] && [ "$LOG_IGNORE" = "false" ]
then
echo "$APP_NAME already run on $PWD:" \
"remove log file 'log.$LOG_SUFFIX' to re-run"
else
echo "Running $APP_RUN on $PWD"
if [ "$LOG_APPEND" = "true" ]; then
# 追加log内容;将所有参数传递给第一个参数,即求解器
$APP_RUN "$@" >> log.$LOG_SUFFIX 2>&1
else
# 不追加log内容
$APP_RUN "$@" > log.$LOG_SUFFIX 2>&1
fi
fi
}

应用举例:

1
2
3
4
...
runApplication $(getApplication)
# 其中getApplicaiton的值通过getApplication函数获取
...

runParallel()

功能:并行运行求解。相比于runApplication,该函数多了一步从decomposedParDict文件中获取numberOfSubdomains值,从而可以在调用mpirun的时候指定正确的进程数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
runParallel() 
{
APP_RUN=
LOG_IGNORE=false
LOG_APPEND=false
LOG_SUFFIX=
nProcs=$(getNumberOfProcessors)

# Parse options and executable
while [ $# -gt 0 ] && [ -z "$APP_RUN" ]; do
key="$1"
case "$key" in
-append|-a)
LOG_IGNORE=true
LOG_APPEND=true
;;
-overwrite|-o)
LOG_IGNORE=true
;;
-suffix|-s)
LOG_SUFFIX=".$2"
shift
;;
-np|-n)
nProcs="$2"
shift
;;
*)
APP_RUN="$key"
APP_NAME="${key##*/}"
LOG_SUFFIX="${APP_NAME}${LOG_SUFFIX}"
;;
esac

shift
done

if [ -f log.$LOG_SUFFIX ] && [ "$LOG_IGNORE" = "false" ]
then
echo "$APP_NAME already run on $PWD:" \
"remove log file 'log.$LOG_SUFFIX' to re-run"
else
echo "Running $APP_RUN in parallel on $PWD using $nProcs processes"
if [ "$LOG_APPEND" = "true" ]; then
( mpirun -np $nProcs $APP_RUN -parallel "$@" < /dev/null >> log.$LOG_SUFFIX 2>&1 )
else
( mpirun -np $nProcs $APP_RUN -parallel "$@" < /dev/null > log.$LOG_SUFFIX 2>&1 )
fi
fi
}

compileApplication()

功能:调用wmake编译求解器。

1
2
3
4
5
compileApplication() 
{
echo "Compiling $1 application"
wmake $1
}

cloneCase()

功能: 拷贝算例,即拷贝其中的0systemconstant文件夹。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cloneCase() 
{
from=$1
to=$2

if [ ! -d $from ]
then
echo "Case $from does not exist"
return 1
elif [ -d $to ]
then
echo "Case already cloned: remove case directory $to to clone"
return 1
else
echo "Cloning $to case from $from"
mkdir -p $to
for f in 0 system constant
do
cp -r $from/$f $to
done
return 0
fi
}

cloneMesh()

功能:拷贝网格,即算例目录下的constant/polyMesh文件夹。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cloneMesh() 
{
from=$1/constant/polyMesh
to=$2/constant/polyMesh

if [ ! -d $from ]
then
echo "Mesh $from does not exist"
return 1
elif [ -d $to ]
then
echo "Mesh already cloned: remove mesh directory $to to clone"
return 1
else
echo "Cloning $to mesh from $from"
cp -pr $from $to
return 0
fi
}