Files
OpenFOAM-12/bin/foamInfo
2022-11-23 15:28:51 +00:00

531 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-2022 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 surfaces
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/postProcessing/"
_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"
find "$1" -maxdepth "$_depth" -mindepth "$_depth" -type d
}
modelsInFamily () {
_familyDir="$1"
_family="${_familyDir##*/}"
! [ -d "$_familyDir" ] && return 0
_modelDirs="$(findModelDirs "$_familyDir")"
### special handling of fvModels
[ "$_family" = fvModels ] && \
_modelDirs="\
$(findModelDirs "$_familyDir" 2) \
$(findModelDirs "$FOAM_SRC/lagrangian/parcel/fvModels") \
$(findModelDirs "$FOAM_SRC/surfaceFilmModels/fvModels") \
$(findModelDirs "$FOAM_SRC/radiationModels/fvModels/radiation")"
[ "$_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" ] && \
_file="$(find "$_mDir" -name "*.H" -exec grep -l TypeName {} \;)" && \
TypeName "$_file"
[ "$_hasTypeName" ] && continue
# Model family without TypeName defined
# Exclusions
echo "Make lnInclude" | \
grep -w "$_mName" && continue
echo "$_mName"
done | sort
}
# 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"