diff --git a/bin/foamGetDict b/bin/foamGetDict new file mode 100755 index 0000000000000000000000000000000000000000..35ded94201d883fe0bc3dc0cffdb9ebc5d901126 --- /dev/null +++ b/bin/foamGetDict @@ -0,0 +1,354 @@ +#!/bin/bash +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. +# \\/ M anipulation | +#------------------------------------------------------------------------------ +# | Copyright (C) 2018 OpenFOAM Foundation +#------------------------------------------------------------------------------ +# License +# This file is part of OpenFOAM. +# +# OpenFOAM is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. +# +# Script +# foamGetDict +# +# Description +# Find an OpenFOAM dictionary file from OpenFOAM/etc/caseDicts/ +# or {user,site} locations and copy it into the case directory. +# +# Environment +# FOAM_API +# WM_PROJECT_DIR +# WM_PROJECT_SITE +# +#------------------------------------------------------------------------------ +printHelp() { + cat<<USAGE + +Usage: ${0##*/} [OPTIONS] <file> +options: + -case <dir> Alternative case directory, default is the cwd + -ext <ext> File extension + -cfg Same as '-e cfg' for '.cfg' files + -no-ext Files without extension + -target <dir> Target directory (default: system, or auto-detected) + -with-api=NUM Alternative api value for searching + -help Display short help and exit + +Find an OpenFOAM dictionary file from etc/caseDicts/ or {user,site} locations +and copy it into the case directory. For example, + + foamGetDict decomposeParDict + foamGetDict extrudeMeshDict + foamGetDict createPatchDict + foamGetDict surfaces + +USAGE + exit 0 # A clean exit +} + + +# Report error and exit +die() +{ + exec 1>&2 + echo + echo "Error encountered:" + while [ "$#" -ge 1 ]; do echo " $1"; shift; done + echo + echo "See '${0##*/} -help' for usage" + echo + exit 1 +} + + +#------------------------------------------------------------------------------- +projectDir="$WM_PROJECT_DIR" # Project dir +userDir="$HOME/.OpenFOAM" # As per foamVersion.H +groupDir="${WM_PROJECT_SITE:-$projectDir/site}" # As per foamVersion.H +projectApi="$FOAM_API" + +#------------------------------------------------------------------------------- + +searchExt="<any>" +unset targetDir + +while [ "$#" -gt 0 ] +do + case "$1" in + -h | -help*) + printHelp + ;; + -case) + [ "$#" -ge 2 ] || die "'$1' option requires an argument" + cd "$2" 2>/dev/null || die "directory does not exist: '$2'" + shift + ;; + -with-api=*) + projectApi="${1#*=}" + ;; + -ext) + [ "$#" -ge 2 ] || die "'$1' option requires an argument" + searchExt="$2" + shift + ;; + -no-ext) + unset searchExt + ;; + -cfg) + searchExt="cfg" + ;; + -target) + [ "$#" -ge 2 ] || die "'$1' option requires an argument" + targetDir="$2" + shift + ;; + -target=*) + targetDir="${1#*=}" + ;; + --) + shift + break # Stop here + ;; + -*) + die "invalid option '$1'" + ;; + *) + break + ;; + esac + shift +done + +[ "$#" -eq 1 ] || die "Incorrect number of arguments" + +filePrefix="$1" + +# The target (time-dir) directory as one of (. | constant | system | 0) +if [ -z "$targetDir" ] +then + targetDir="system" + + case "$filePrefix" in + All*) + targetDir="." + ;; + *Properties | *Cloud) + targetDir="constant" + ;; + s) + targetDir="0" + ;; + esac +fi + + +# No api specified -with-api= or from environment (FOAM_API) +if [ -z "$projectApi" ] +then + projectApi="$(foamEtcFile -show-api 2>/dev/null)" +fi + + +# Define the various places to be searched. +# Similar to foamEtcFile, but with etc/caseDicts/ for the projectDir +# Filter out nonexistent directories later + +searchDirs="${projectApi:+$userDir/$projectApi} $userDir \ +${projectApi:+$groupDir/$projectApi/etc} $groupDir/etc \ +$projectDir/etc/caseDicts"; + +## echo "Using <$searchDirs>" 1>&2 + +# ------------------------------------------------------------------------------ + +# Search directories (searchDirs) for file +# $1 = file-name +# +# Globals: searchDirs +findFilesInDirs() +{ + local fileName="$1" + local dir + + for dir in $searchDirs + do + if [ -d "$dir" ] + then + find "$dir" -name "$fileName" -type f | sort + fi + done +} + + +# Search directories (searchDirs) for file-prefix with extension (searchExt) +# +# $1 = file-prefix +# +# Globals: searchDirs, searchExt +findFiles() +{ + local prefix="$1" + + if [ -z "$searchExt" ] + then + # No extension + findFilesInDirs "$prefix" + elif [ "$searchExt" = "<any>" ] + then + # No extension or any extension + findFilesInDirs "$prefix" + findFilesInDirs "${prefix}.*" + else + # With specific extension + findFilesInDirs "${prefix}.$searchExt" + fi +} + + +# Slightly dressed up version of 'cp -v' +copyFile() +{ + echo 1>&2 + echo "Copying $1 to $2" 1>&2 + \cp "$1" "$2" + echo 1>&2 +} + + +# Priority locations for suggestion +priorityLocations="\ + caseDicts/postProcessing/ \ + caseDicts/preProcessing/ \ + caseDicts/general/ \ + caseDicts/mesh/ \ + caseDicts/surface/ \ + caseDicts/solvers/" + +# Create an indexed list of suggestions +listArgs() +{ + local arg loc n suggest + local i=0 pri=100 + + for arg in $1 + do + i=$((i + 1)) + echo "${i}) $arg" >&2 + + n=0 + for loc in $priorityLocations + do + n=$((n + 1)) + if [ "$n" -lt "$pri" ] && echo "$arg" | grep -q "$loc" + then + suggest="$i" + pri="$n" + fi + done + done + + echo "$suggest" +} + + +# Select specified file by index from list +selectFile() +{ + local files="$1" + local index="$2" + echo "$files" | tr -s '\n' ' ' | awk -v n="$index" '{print $n}' +} + + +# ------------------------------------------------------------------------------ + +[ -s "system/controlDict" ] || \ + echo "Warning: no OpenFOAM system/controlDict file" 1>&2 + +[ -d "$targetDir" ] || \ + die "target directory does not exist: '$targetDir'" + +# Begin search +filesFound="$(findFiles "$filePrefix")" +nFilesFound=0 + +if [ -z "$filesFound" ] +then + message="No file $filePrefix found" + + if [ "$searchExt" = "<any>" ] + then + message="$message with/without file extensions" + elif [ -n "$searchExt" ] + then + message="$message with file extension '$searchExt'" + fi + + die "$message" +else + nFilesFound="$(echo "$filesFound" | xargs -n 1 | wc -l)" +fi + +# Exactly one file found - we are done +if [ "$nFilesFound" -eq 1 ] +then + copyFile "$filesFound" "$targetDir" + exit 0 +fi + +# ------------------------------------------------------------------------------ + +# Multiple files found - offer simple selection + +echo "Multiple files with \"$filePrefix\" prefix found:" +echo + +suggest="$(listArgs "$filesFound")" + +if echo "$filesFound" | grep -q "annotated/" +then + echo + echo "** Note: it may be easier not to use 'annotated/' files" +fi + +echo +echo "Choose file number [1-$nFilesFound]${suggest:+ (suggest $suggest)} :" +read -r nFile + +# Nothing specified? Use default suggestion +: "${nFile:=$suggest}" + +if [ -z "$nFile" ] +then + echo "Nothing specify - re-run and enter a file number" 1>&2 + exit 1 +elif [ "$nFile" -lt 1 ] || [ "$nFile" -gt "$nFilesFound" ] +then + echo "\"$nFile\" is not a number between 1 and $nFilesFound" 1>&2 + exit 1 +fi + +# Appears to have been successful. Select the file from the list + +file="$(selectFile "$filesFound" "$nFile")" + +copyFile "$file" "$targetDir" + + +#------------------------------------------------------------------------------