OpenFOAM-script:RunFunctions

创建时间: 2021-01-14 21:21:35
摘要: RunFunctions脚本分析。

脚本描述:

description: Miscellaneous functions for running tutorial cases.

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

串行应用

#!/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 

并行应用

#!/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。

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

getNumberOfProcessors()

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

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

getApplication()

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

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

应用举例:

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

runApplication()

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

runApplication [own_options] app [app_options]

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

runParallel函数用法类似。

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
}

应用举例:

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

runParallel()

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

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编译求解器。

compileApplication() 
{
    echo "Compiling $1 application"
    wmake $1
}

cloneCase()

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

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文件夹。

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
}