for consistency with fvModels and fvConstraints, to simplify code and case maintenance and to avoid the potentially complex functions entries being unnecessarily parsed by utilities for which functionObject evaluation is disabled. The functions entry in controlDict is still read if the functions file is not present for backward-compatibility, but it is advisable to migrate cases to use the new functions file.
547 lines
14 KiB
Bash
Executable File
547 lines
14 KiB
Bash
Executable File
#!/bin/sh
|
|
#------------------------------------------------------------------------------
|
|
# ========= |
|
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
# \\ / O peration | Website: https://openfoam.org
|
|
# \\ / A nd | Copyright (C) 2018-2024 OpenFOAM Foundation
|
|
# \\/ M anipulation |
|
|
#------------------------------------------------------------------------------
|
|
# 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
|
|
# foamInfo
|
|
#
|
|
# Description
|
|
# Prints description and usage of an application, a script, or a model
|
|
# (including boundary conditions, function objects and fvModels).
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
usage() {
|
|
cat<<USAGE
|
|
|
|
Usage: ${0##*/} [OPTIONS] <name>
|
|
options:
|
|
-all | -a list all tutorials that use <name> (otherwise maximum 10)
|
|
and all models of the same family (otherwise maximum 25)
|
|
-browser | -b <name> output C++ source guide web page with specified browser,
|
|
e.g. foamInfo -browser "firefox"
|
|
-help | -h print the usage
|
|
-keyword | -k uses <name> as a keyword, rather than an exact match
|
|
-web | -w output C++ source guide web page with the browser
|
|
specified in the global controlDict file
|
|
|
|
Prints the following for an application, a script, or a model
|
|
(including boundary conditions, function objects and fvModels).
|
|
- File: the location of the relevant source code header file.
|
|
- Description details from the header file.
|
|
- Usage details from the header file.
|
|
- Models: lists other models belonging to the same family, where applicable.
|
|
- Examples: a list of relevant cases from the tutorials directory.
|
|
|
|
By default, finds an exact match with <name> or something beginning with <name>,
|
|
which is case-insensitive on the first character.
|
|
|
|
Otherwise the user can try a broader keyword match with "-keyword | -k" option.
|
|
|
|
Examples
|
|
foamInfo incompressibleFluid
|
|
foamInfo interFoam
|
|
foamInfo fixedValue
|
|
foamInfo -k fixedValue
|
|
foamInfo -a turbulentIntensityKineticEnergyInlet
|
|
foamInfo symmetry
|
|
foamInfo -k wallFunction
|
|
foamInfo kEpsilon
|
|
foamInfo -k kEpsilon
|
|
foamInfo RAS
|
|
foamInfo hPolynomial
|
|
foamInfo -k contactAngle
|
|
foamInfo Function1
|
|
foamInfo square
|
|
foamInfo fixedTemperatureConstraint
|
|
foamInfo foamNewBC
|
|
|
|
USAGE
|
|
}
|
|
|
|
error() {
|
|
exec 1>&2
|
|
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
|
|
usage
|
|
exit 1
|
|
}
|
|
|
|
capitaliseWord () {
|
|
echo "$1" | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1'
|
|
}
|
|
|
|
# (1) case-sensitive match; (2) case-insensitive match; (3) keyword match
|
|
findModelFiles() {
|
|
find "$FOAM_SRC" "$FOAM_APP" \
|
|
-name "$1" \
|
|
-iname "$2" \
|
|
! -iname "$3" \
|
|
! -name "*Fwd.H" \
|
|
! -name "*Fields.H" \
|
|
! -name "*I.H" -type f
|
|
}
|
|
|
|
findFiles() {
|
|
_pre="$1"
|
|
|
|
# Application
|
|
_out="$(find "$FOAM_APP" -name "${_pre}.C" -type f)"
|
|
# If same file with .H extension exists, then .C is not an application
|
|
[ "$_out" ] && \
|
|
[ "$(find "$FOAM_APP" -name "${_pre}.H" -type f | wc -c)" -ne 0 ] && unset _out
|
|
|
|
# Script
|
|
_out="$(find "$FOAM_APP/../bin" -name "${_pre}" -type f | \
|
|
sed 's@applications/../@@g' ) $_out"
|
|
|
|
# Model
|
|
# case-sensitive match
|
|
_models="$(findModelFiles "${_pre}*.H" "*" "") \
|
|
$(findModelFiles "$(capitaliseWord "$_pre")*.H" "*" "")"
|
|
|
|
# case-insensitive match
|
|
[ "$_models" ] || \
|
|
_models="$(findModelFiles "*" "${_pre}*.H" "")"
|
|
|
|
# keyword match
|
|
[ "$_models" ] && ! [ "$KEYWORD" ] || \
|
|
_models="$_models $(findModelFiles "*" "*${_pre}*.H" "${_pre}*.H")"
|
|
|
|
_out="$_models $_out"
|
|
|
|
for _t in scalar vector tensor
|
|
do
|
|
echo "$_pre" | grep -oq "$_t" && \
|
|
_mod="$(echo "$_pre" | sed "s/${_t}//g")" && \
|
|
_out="$(find "$FOAM_SRC" -name "${_mod}*.H" -type f) $_out"
|
|
done
|
|
|
|
# Function
|
|
_out="$(find "$FOAM_ETC" -name "${_pre}" -type f) $_out"
|
|
|
|
# Remove whitespace
|
|
echo "$_out" | xargs -n 1 | sort -u | awk 'NF'
|
|
}
|
|
|
|
nArgs() {
|
|
! [ "$1" ] && echo 0 && return 0
|
|
echo "$1" | xargs -n 1 | wc -l
|
|
|
|
return 0
|
|
}
|
|
|
|
listArgs() {
|
|
_i=0
|
|
_suggest=""
|
|
_pri=100
|
|
|
|
for _a in $1
|
|
do
|
|
_i=$(( _i + 1))
|
|
echo "${_i}) $_a" >&2
|
|
|
|
# Prioritise suggestion locations
|
|
_tests="\
|
|
fields/fvPatchFields/ \
|
|
fvMesh/fvPatches/ \
|
|
caseDicts/functions/"
|
|
|
|
_n=0
|
|
for _t in $_tests
|
|
do
|
|
_n=$(( _n + 1))
|
|
[ "$_n" -lt "$_pri" ] && \
|
|
echo "$_a" | grep -q "$_t" && _suggest="$_i" && _pri="$_n"
|
|
done
|
|
done
|
|
|
|
echo "$_suggest"
|
|
}
|
|
|
|
setFile() {
|
|
_files="$1"
|
|
_n="$2"
|
|
echo "$_files" | xargs -n 1 | awk -v n="${_n}" 'NR==n'
|
|
}
|
|
|
|
# (1) model family directory (2) depth (optional, default 1)
|
|
findModelDirs () {
|
|
_familyDir="$1"
|
|
_depth=1
|
|
[ "$2" ] && _depth="$2"
|
|
_dirs=""
|
|
|
|
while [ "$_depth" -ge 1 ]
|
|
do
|
|
_dirs="$(find "$1" -maxdepth "$_depth" -mindepth "$_depth" -type d | \
|
|
sed 's/\/Make//g' | sed 's/\/lnInclude//g')"
|
|
|
|
[ "$_dirs" ] && break
|
|
_depth=$((_depth - 1))
|
|
done
|
|
|
|
echo "$_dirs" | sort -u
|
|
}
|
|
|
|
fvModelDirs () {
|
|
for d in \
|
|
$(find "$FOAM_APP" -name fvModels) \
|
|
$(find "$FOAM_SRC" -name fvModels)
|
|
do
|
|
findModelDirs "$d" 2
|
|
done
|
|
}
|
|
|
|
modelsInFamily () {
|
|
_familyDir="$1"
|
|
_family="${_familyDir##*/}"
|
|
|
|
! [ -d "$_familyDir" ] && return 0
|
|
|
|
_modelDirs="$(findModelDirs "$_familyDir")"
|
|
|
|
### special handling of fvModels
|
|
[ "$_family" = fvModels ] && _modelDirs="$(fvModelDirs)"
|
|
|
|
[ "$_modelDirs" ] || return 0
|
|
|
|
_hasTypeName=""
|
|
grep -rqw TypeName "$_familyDir" && _hasTypeName="yes"
|
|
|
|
for _mDir in $_modelDirs
|
|
do
|
|
# Exclude base class
|
|
_mName="${_mDir##*/}"
|
|
echo "$_family" | grep -q "$_mName" && continue
|
|
|
|
# Model family with TypeName defined
|
|
[ "$_hasTypeName" ] && \
|
|
_files="$(find "$_mDir" -maxdepth 1 -name "*.H" -exec \
|
|
grep -l TypeName {} \;)" && \
|
|
for _f in $_files ; do TypeName "$_f" ; done
|
|
|
|
[ "$_hasTypeName" ] && continue
|
|
|
|
# Model family without TypeName defined
|
|
# Exclusions
|
|
echo "Make lnInclude" | \
|
|
grep -w "$_mName" && continue
|
|
|
|
echo "$_mName"
|
|
|
|
# Remove model names ending "Base" as they are base classes
|
|
done | sort -u | sed '/Base$/d'
|
|
}
|
|
|
|
# Argument: .H file
|
|
TypeName () {
|
|
# First sed captures FvPatch, PolyPatch, PointPatch
|
|
_model="$(grep -Es "TypeName\(\"*[[:alnum:]:_()]*\"*\);" "$1" | \
|
|
sed 's@[FP][[:lower:]]*Patch::typeName_()@@g' | \
|
|
sed 's@[\t ]*TypeName("*\([[:alnum:]:]*\)"*);@\1@')"
|
|
|
|
[ "$_model" ] && echo "$_model" && return 0
|
|
|
|
return 1
|
|
}
|
|
|
|
modelName () {
|
|
_file="$1"
|
|
|
|
# Get model from TypeName in file
|
|
TypeName "$_file" && return 0
|
|
|
|
# Otherwise use the directory name
|
|
_modelDir="${_file%/*}"
|
|
echo "${_modelDir##*/}"
|
|
|
|
return 0
|
|
}
|
|
|
|
printInfo() {
|
|
_file="$1"
|
|
_all="$2"
|
|
|
|
echo "File"
|
|
printf " %s\n\n" "$_file"
|
|
|
|
# Description
|
|
sed -e "s/^#.//g" -e "s/^#$//g" "$_file" | \
|
|
sed -n '/^Description/,/^[^ ]/p' | sed \$d
|
|
|
|
# Usage
|
|
sed -n '/^Usage/,/^[^ ]/p' "$_file" | sed \$d
|
|
|
|
# Model
|
|
echo "$_file" | grep -q "$FOAM_SRC" || return 0
|
|
|
|
_model="$(modelName "$_file")" || return 0
|
|
_familyDir="$(dirname "$(dirname "$_file")")"
|
|
|
|
### special handling of fvModels
|
|
echo "$_familyDir" | grep -q fvModels && \
|
|
_familyDir="$FOAM_SRC/fvModels"
|
|
|
|
### special handling of fvConstraints
|
|
echo "$_familyDir" | grep -q fvConstraints && \
|
|
_familyDir="$FOAM_SRC/fvConstraints"
|
|
|
|
_family="${_familyDir##*/}"
|
|
|
|
_models="$(modelsInFamily "$_familyDir")"
|
|
_nMo="$(nArgs "$_models")"
|
|
|
|
[ "$_nMo" -eq 0 ] && return 0
|
|
|
|
printf "Model\n"
|
|
echo "$_family" | grep -q "$_model" && \
|
|
printf " This appears to be the '%s' family of models.\n" \
|
|
"$_family" || \
|
|
printf " This appears to be the '%s' model of the '%s' family.\n" \
|
|
"$_model" "$_family"
|
|
|
|
printf " The models in the '%s' family are:\n" "$_family"
|
|
|
|
_nMoD=25
|
|
[ "$_all" = "yes" ] && _nMoD=1000
|
|
|
|
[ "$_nMo" -gt "$_nMoD" ] && [ "$_all" = "no" ] && \
|
|
echo " *** Listing $_nMoD out of $_nMo;" \
|
|
"run with \"-a\" option to list all ***"
|
|
echo "$_models" | awk -v nMoD="$_nMoD" 'FNR <= nMoD {print " + " $1}'
|
|
|
|
printf "\n"
|
|
|
|
return 0
|
|
}
|
|
|
|
webInfo() {
|
|
# basename of file
|
|
_file="$(basename "$1")"
|
|
|
|
echo "$_file" | grep -q ".[CH]" ||
|
|
error "No web documentation for file \"$_file\""
|
|
|
|
_pre="$(echo "$_file" | sed 's/\./_8/g')"
|
|
_url="https://cpp.openfoam.org/${VER}/${_pre}.html"
|
|
|
|
echo "Running \"$BROWSER $_url\""
|
|
$BROWSER "$_url"
|
|
|
|
return 0
|
|
}
|
|
|
|
showInfo() {
|
|
_file="$1"
|
|
_all="$2"
|
|
_web="$3"
|
|
|
|
# Return 1 for web so examples are not printed
|
|
[ -n "$_web" ] && webInfo "$_file" && return 1
|
|
printInfo "$_file" "$_all"
|
|
}
|
|
|
|
findSolverExamples() {
|
|
_pre="$1"
|
|
_out=""
|
|
|
|
# Solvers
|
|
_app="$(find "$FOAM_TUTORIALS" -name "$_pre")"
|
|
_dirs="$(find "$_app" -name "system" -type d)"
|
|
for _d in $_dirs
|
|
do
|
|
_out="${_d%/*} $_out"
|
|
done
|
|
|
|
# Remove whitespace
|
|
echo "$_out" | xargs -n 1
|
|
}
|
|
|
|
findUtilityExamples() {
|
|
_pre="$1"
|
|
_out=""
|
|
|
|
# Applications
|
|
_scripts="$(find "$FOAM_TUTORIALS" -type f -name "All*")"
|
|
for _f in $_scripts
|
|
do
|
|
grep -rq "$_pre" "$_f" && _out="${_f%/*} $_out"
|
|
done
|
|
|
|
# Remove whitespace
|
|
echo "$_out" | xargs -n 1 | sort -u
|
|
}
|
|
|
|
findModelExamples() {
|
|
_pre="$1"
|
|
_out=""
|
|
|
|
# Field files
|
|
_dirs="$(find "$FOAM_TUTORIALS" \
|
|
-type d -name "0*" -o -name "constant" -o -name "system")"
|
|
for _d in $_dirs
|
|
do
|
|
# Space and semicolon pick up exact matches
|
|
grep -rq " ${_pre};" "$_d" && _out="${_d%/*} $_out"
|
|
done
|
|
|
|
# Remove whitespace
|
|
echo "$_out" | xargs -n 1 | sort -u
|
|
}
|
|
|
|
findAllExamples() {
|
|
_pre="$1"
|
|
_type="$2"
|
|
|
|
case "$_type" in
|
|
model) findModelExamples "$_pre" ;;
|
|
utility|script) findUtilityExamples "$_pre" ;;
|
|
solver) findSolverExamples "$_pre" ;;
|
|
esac
|
|
}
|
|
|
|
showTypeExamples() {
|
|
_pre="$1"
|
|
_type="$2"
|
|
_all="$3"
|
|
_examples=""
|
|
|
|
[ -z "$_pre" ] && echo "Examples: none found" && return 1
|
|
|
|
_nExD=10
|
|
[ "$_all" = "yes" ] && _nExD=1000
|
|
|
|
_examples="$(findAllExamples "$_pre" "$_type")"
|
|
|
|
[ -z "$_examples" ] && \
|
|
echo "Examples: cannot find any tutorials using \"$_pre\"" && \
|
|
return 1
|
|
|
|
_nEx="$(nArgs "$_examples")"
|
|
|
|
echo "Examples using \"$_pre\""
|
|
[ "$_nEx" -gt "$_nExD" ] && ! [ "$_all" = "yes" ] && \
|
|
echo " *** Listing $_nExD out of $_nEx;" \
|
|
"run with \"-a\" option to list all ***"
|
|
echo "$_examples" | awk -v nExD="$_nExD" 'FNR <= nExD {print " " $1}'
|
|
}
|
|
|
|
showExamples() {
|
|
_pre="$1"
|
|
_file="$2"
|
|
_all="$3"
|
|
|
|
echo "$_file" | grep -q ".H" && _type=model && \
|
|
_pre="$(basename "${file%/*}")" && \
|
|
echo "$_pre" | grep -iq include && _pre=""
|
|
! [ "$_type" ] && echo "$_file" | grep -q "$FOAM_SRC/../bin" && _type=script
|
|
! [ "$_type" ] && echo "$_file" | grep -q "$FOAM_UTILITIES" && _type=utility
|
|
! [ "$_type" ] && echo "$_file" | grep -q "$FOAM_SOLVERS" && _type=solver
|
|
|
|
[ -n "$_type" ] && showTypeExamples "$_pre" "$_type" "$_all" && return 0
|
|
return 0
|
|
}
|
|
|
|
web=""
|
|
all="no"
|
|
# Global controlDict file
|
|
controlDict="$(foamEtcFile controlDict 2> /dev/null)"
|
|
BROWSER="$(grep docBrowser "$controlDict" 2> /dev/null | cut -d "\"" -f2)"
|
|
KEYWORD=""
|
|
|
|
while [ "$#" -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-a | -all)
|
|
all="yes"
|
|
shift
|
|
;;
|
|
-b | -browser)
|
|
[ "$#" -ge 2 ] || error "'$1' option requires an argument"
|
|
BROWSER="$2"
|
|
web="yes"
|
|
shift 2
|
|
;;
|
|
-h | -help)
|
|
usage && exit 0
|
|
;;
|
|
-k | -keyword)
|
|
KEYWORD="yes"
|
|
shift
|
|
;;
|
|
-w | -web)
|
|
web="yes"
|
|
shift
|
|
;;
|
|
-*)
|
|
error "invalid option '$1'"
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Check if browsing is possible
|
|
VER="${WM_PROJECT_VERSION%%.*}"
|
|
|
|
[ -n "$web" ] && \
|
|
! command -v "$BROWSER" >/dev/null 2>&1 && \
|
|
error "Cannot run browser application: $BROWSER"
|
|
[ -n "$web" ] && [ -z "$VER" ] && \
|
|
error "Cannot establish OpenFOAM version: \$WM_PROJECT_VERSION not set"
|
|
|
|
[ "$VER" = "dev" ] || VER="v${VER}"
|
|
|
|
[ $# -gt 1 ] && error "$# arguments \"$*\" specified: only 1 permitted"
|
|
[ $# -eq 1 ] || error "Missing argument: no application, model, script, etc provided"
|
|
prefix="$1"
|
|
|
|
files="$(findFiles "$prefix")"
|
|
[ -z "$files" ] && error "Nothing found with \"$prefix\" in the name"
|
|
|
|
nFiles="$(nArgs "$files")"
|
|
nFile=""
|
|
if [ "$nFiles" -eq 1 ]
|
|
then
|
|
nFile=1
|
|
else
|
|
echo "Multiple items with \"$prefix\" found:"
|
|
suggest="$(listArgs "$files")"
|
|
|
|
printf "\n%s" "Enter file number (1-$nFiles) to obtain description "
|
|
[ -n "$suggest" ] && printf "%s" "(suggest $suggest) "
|
|
printf "%s" ": "
|
|
|
|
read -r nFile
|
|
[ -z "$nFile" ] && [ -n "$suggest" ] && nFile="$suggest"
|
|
[ -z "$nFile" ] && \
|
|
echo "Cannot specify nothing; re-run and enter a file number" && exit 1
|
|
! [ "$nFile" -eq "$nFile" ] 2>/dev/null && \
|
|
echo "\"$nFile\" is not a number between 1 and $nFiles" && exit 1
|
|
{ [ "$nFile" -lt 1 ] || [ "$nFile" -gt "$nFiles" ] ; } && \
|
|
echo "\"$nFile\" is not a number between 1 and $nFiles" && exit 1
|
|
fi
|
|
|
|
file="$(setFile "$files" "$nFile")"
|
|
showInfo "$file" "$all" "$web" && showExamples "$prefix" "$file" "$all"
|