420 lines
9.9 KiB
Text
420 lines
9.9 KiB
Text
|
#!/bin/sh
|
||
|
#------------------------------------------------------------------------------
|
||
|
# ========= |
|
||
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||
|
# \\ / O peration |
|
||
|
# \\ / A nd | Copyright held by original author
|
||
|
# \\/ 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 2 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, write to the Free Software Foundation,
|
||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
#
|
||
|
# Script
|
||
|
# foamLog
|
||
|
#
|
||
|
# Description
|
||
|
# extracts info from log file
|
||
|
#
|
||
|
# Bugs
|
||
|
# -solution singularity not handled
|
||
|
#------------------------------------------------------------------------------
|
||
|
|
||
|
PROGDIR=`dirname $0`
|
||
|
PROGNAME=`basename $0`
|
||
|
|
||
|
if [ -r $HOME/.${PROGNAME}.db ]; then
|
||
|
DBFILE=$HOME/.${PROGNAME}.db
|
||
|
else
|
||
|
DBFILE=$PROGDIR/$PROGNAME.db
|
||
|
fi
|
||
|
|
||
|
|
||
|
printUsage() {
|
||
|
cat <<LABUSAGE
|
||
|
$PROGNAME - extracts xy files from Foam logs.
|
||
|
|
||
|
Usage: $PROGNAME [-n][-s] <log>
|
||
|
extracts xy files from log
|
||
|
$PROGNAME -l <log>
|
||
|
lists but does not extract
|
||
|
$PROGNAME -h
|
||
|
for a help message
|
||
|
|
||
|
LABUSAGE
|
||
|
}
|
||
|
|
||
|
|
||
|
printHelp() {
|
||
|
printUsage
|
||
|
cat <<LABHELP
|
||
|
The default is to extract for all the 'Solved for' variables the
|
||
|
initial residual, the final residual and the number of iterations. On
|
||
|
top of this a (user editable) database of standard non-solved for
|
||
|
variables is used to extract data like Courant number, execution time.
|
||
|
|
||
|
$PROGNAME -l shows all the possible variables but does not extract them.
|
||
|
|
||
|
The program will generate and run an awk script which writes a set of
|
||
|
files, logs/<var>_<subIter>, for every <var> specified, for every
|
||
|
occurrence inside a time step.
|
||
|
|
||
|
For variables that are 'Solved for' the initial residual name will
|
||
|
be <var>, the final residual will get name <var>FinalRes,
|
||
|
|
||
|
The files are a simple xy format with the first column Time (default)
|
||
|
and the second the extracted values. Option -n creates single column
|
||
|
files with the extracted data only.
|
||
|
|
||
|
|
||
|
The query database is a simple text format with three entries per line,
|
||
|
separated with '/'. Column 1 is the name of the variable (cannot contain
|
||
|
spaces), column 2 is the extended regular expression (egrep) to select
|
||
|
the line and column 3 is the string (fgrep) to select the column inside the
|
||
|
line. The value taken will be the first (non-space)word after this
|
||
|
column. The database will either be \$HOME/.${PROGNAME}.db or if not
|
||
|
found $PROGDIR/${PROGNAME}.db.
|
||
|
|
||
|
Option -s suppresses the default information and only prints the extracted
|
||
|
variables.
|
||
|
|
||
|
LABHELP
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
myEcho() {
|
||
|
if [ "$VERBOSE" ]; then
|
||
|
echo "$*"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# getSolvedVars logFile
|
||
|
# Prints names of all 'solved for' variables in the log file.
|
||
|
getSolvedVars() {
|
||
|
fgrep ' Solving for ' $1 | fgrep ',' | sed -e 's/.* Solving for \([^,]*\)[,:].*/\1/' | sort -u
|
||
|
}
|
||
|
|
||
|
|
||
|
# getQueries dbFile queryName
|
||
|
# Gets regular expressions for a certain queryName from the database
|
||
|
getQueries() {
|
||
|
if [ ! -f "$1" ]; then
|
||
|
echo "Cannot find dbFile $1"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
queryName=$2
|
||
|
|
||
|
LINEQ=`grep -v '^#' $1 | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $2}'`
|
||
|
NUMQ=`grep -v '^#' $1 | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $3}'`
|
||
|
|
||
|
#echo "For $queryName found line selection /$LINEQ/ , column selection /$NUMQ/" 1>&2
|
||
|
#if [ ! "$LINEQ" -o ! "$NUMQ" ]; then
|
||
|
# echo "Did not find query for $2 in database $1" 1>&2
|
||
|
#fi
|
||
|
}
|
||
|
|
||
|
|
||
|
# getDbQueryList dbFile
|
||
|
# Echoes list of possible queries
|
||
|
getDbQueryList() {
|
||
|
grep -v '^#' $1 | grep '[^ \t]' | awk -F '/' '{print $1}'
|
||
|
}
|
||
|
|
||
|
|
||
|
# getSolveQueryList logFile
|
||
|
# Echoes list of queries from "solved for" variables in log file
|
||
|
getSolveQueryList() {
|
||
|
solvedVars=`getSolvedVars $1`
|
||
|
|
||
|
for var in $solvedVars
|
||
|
do
|
||
|
echo "${var}"
|
||
|
echo "${var}FinalRes"
|
||
|
echo "${var}Iters"
|
||
|
done
|
||
|
}
|
||
|
|
||
|
# getAllQueries dbFile logFile
|
||
|
# Gets all queries from database and from logfile
|
||
|
getAllQueries() {
|
||
|
#-- All solved for queries from log file
|
||
|
queries=`getSolveQueryList $2`
|
||
|
|
||
|
#-- Add ones from database, present in log file
|
||
|
# Note: just like awk, line selected with regular expression,
|
||
|
# column with string.
|
||
|
dbQueries=`getDbQueryList $1`
|
||
|
|
||
|
for var in $dbQueries
|
||
|
do
|
||
|
getQueries $1 "$var"
|
||
|
line=`egrep "$LINEQ" $2`
|
||
|
if [ "$line" ]; then
|
||
|
column=`echo "$line" | fgrep "$NUMQ"`
|
||
|
if [ "$column" ]; then
|
||
|
queries="$queries $var"
|
||
|
fi
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
for q in $queries
|
||
|
do
|
||
|
echo "$q"
|
||
|
done | sort -u
|
||
|
}
|
||
|
|
||
|
#-----------------------------
|
||
|
# Main
|
||
|
#-----------------------------
|
||
|
|
||
|
# sort arguments
|
||
|
TIMENAME='Time'
|
||
|
VERBOSE='yes'
|
||
|
LISTONLY=''
|
||
|
|
||
|
while getopts nslh flags
|
||
|
do
|
||
|
case $flags in
|
||
|
n) TIMENAME=""
|
||
|
;;
|
||
|
h) printHelp
|
||
|
exit 0
|
||
|
;;
|
||
|
s) VERBOSE=""
|
||
|
;;
|
||
|
l) LISTONLY='yes'
|
||
|
;;
|
||
|
\?) printUsage
|
||
|
exit 1
|
||
|
;;
|
||
|
esac
|
||
|
done
|
||
|
|
||
|
|
||
|
# Shift options
|
||
|
shift `expr $OPTIND - 1`
|
||
|
|
||
|
if [ ! -f $DBFILE ]; then
|
||
|
echo "$PROGNAME: Cannot read database $DBFILE"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
if [ "$LISTONLY" ]; then
|
||
|
if [ $# -ne 1 ]; then
|
||
|
printUsage
|
||
|
exit 1
|
||
|
fi
|
||
|
LOG=$1;
|
||
|
if [ ! -r $LOG ]; then
|
||
|
echo "$PROGNAME: Cannot read log $LOG"
|
||
|
exit 1
|
||
|
fi
|
||
|
getAllQueries $DBFILE $LOG
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
if [ $# -ne 1 ]; then
|
||
|
printUsage
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
CASEDIR=.
|
||
|
LOG=$1
|
||
|
if [ ! -r $LOG ]; then
|
||
|
echo "$PROGNAME: Cannot read log $LOG"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
QUERYNAMES=`getAllQueries $DBFILE $LOG`
|
||
|
|
||
|
|
||
|
if [ ! "$CASEDIR" ]; then
|
||
|
printUsage
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
if [ ! -d "$CASEDIR" ]; then
|
||
|
echo "$PROGNAME: Cannot read $CASEDIR"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
if [ ! -f "$LOG" ]; then
|
||
|
echo "$PROGNAME: Cannot read log file $LOG"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
|
||
|
#-- Make logs dir in case directory and put awk file there.
|
||
|
|
||
|
mkdir -p $CASEDIR/logs
|
||
|
AWKFILE=$CASEDIR/logs/$PROGNAME.awk
|
||
|
|
||
|
myEcho "Using:"
|
||
|
myEcho " log : $LOG"
|
||
|
myEcho " database : $DBFILE"
|
||
|
myEcho " awk file : $AWKFILE"
|
||
|
myEcho " files to : $CASEDIR/logs"
|
||
|
myEcho ""
|
||
|
|
||
|
|
||
|
#-----------------------------
|
||
|
# Generate Awk program
|
||
|
#-----------------------------
|
||
|
|
||
|
|
||
|
|
||
|
#-- header
|
||
|
|
||
|
rm -f $AWKFILE; touch $AWKFILE
|
||
|
echo "BEGIN {" >> $AWKFILE
|
||
|
echo " Iteration=0" >> $AWKFILE
|
||
|
echo " resetCounters()" >> $AWKFILE
|
||
|
echo "}" >> $AWKFILE
|
||
|
|
||
|
echo "" >> $AWKFILE
|
||
|
echo "# reset counters used for variable postfix" >> $AWKFILE
|
||
|
echo "function resetCounters() {" >> $AWKFILE
|
||
|
for queryName in $QUERYNAMES
|
||
|
do
|
||
|
varName=${queryName}Cnt
|
||
|
echo " ${varName}=0" >> $AWKFILE
|
||
|
done
|
||
|
echo " # Reset counters for general Solving for extraction" >> $AWKFILE
|
||
|
echo " for (varName in subIter)" >> $AWKFILE
|
||
|
echo " {" >> $AWKFILE
|
||
|
echo " subIter[varName]=0" >> $AWKFILE
|
||
|
echo " }" >> $AWKFILE
|
||
|
echo "}" >> $AWKFILE
|
||
|
echo "" >> $AWKFILE
|
||
|
|
||
|
|
||
|
cat <<LABEL >> $AWKFILE
|
||
|
# Extract value after columnSel
|
||
|
function extract(inLine,columnSel,outVar,
|
||
|
a,b)
|
||
|
{
|
||
|
a=index(inLine, columnSel)
|
||
|
b=length(columnSel)
|
||
|
split(substr(inLine, a+b),outVar)
|
||
|
gsub("[,:]","",outVar[1])
|
||
|
}
|
||
|
|
||
|
LABEL
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#-- Generate code for iteration separator (increments 'Iteration')
|
||
|
getQueries $DBFILE 'Separator'
|
||
|
cat <<LABSEP >> $AWKFILE
|
||
|
#-- Iteration separator (increments 'Iteration')
|
||
|
/$LINEQ/ {
|
||
|
Iteration++
|
||
|
resetCounters()
|
||
|
}
|
||
|
|
||
|
LABSEP
|
||
|
|
||
|
|
||
|
#-- Generate code for extracting Time
|
||
|
getQueries $DBFILE 'Time'
|
||
|
cat <<LABTIME >> $AWKFILE
|
||
|
#-- Time extraction (sets 'Time')
|
||
|
/$LINEQ/ {
|
||
|
extract(\$0, "$NUMQ", val)
|
||
|
Time=val[1]
|
||
|
}
|
||
|
|
||
|
LABTIME
|
||
|
|
||
|
|
||
|
#-- Generate code for singularity handling.
|
||
|
cat <<LABSING >> $AWKFILE
|
||
|
#-- Skip whole line with singularity variable
|
||
|
/solution singularity/ {
|
||
|
next;
|
||
|
}
|
||
|
LABSING
|
||
|
|
||
|
|
||
|
#-- Generate code for extracting solved for quantities
|
||
|
cat <<LABSOLVE >> $AWKFILE
|
||
|
#-- Extraction of any solved for variable
|
||
|
/Solving for/ {
|
||
|
extract(\$0, "Solving for ", varNameVal)
|
||
|
|
||
|
varName=varNameVal[1]
|
||
|
file=varName "_" subIter[varName]++
|
||
|
file="$CASEDIR/logs/" file
|
||
|
extract(\$0, "Initial residual = ", val)
|
||
|
print $TIMENAME "\t" val[1] > file
|
||
|
|
||
|
varName=varNameVal[1] "FinalRes"
|
||
|
file=varName "_" subIter[varName]++
|
||
|
file="$CASEDIR/logs/" file
|
||
|
extract(\$0, "Final residual = ", val)
|
||
|
print $TIMENAME "\t" val[1] > file
|
||
|
|
||
|
varName=varNameVal[1] "Iters"
|
||
|
file=varName "_" subIter[varName]++
|
||
|
file="$CASEDIR/logs/" file
|
||
|
extract(\$0, "No Iterations ", val)
|
||
|
print $TIMENAME "\t" val[1] > file
|
||
|
}
|
||
|
|
||
|
LABSOLVE
|
||
|
|
||
|
#-- generate code to process queries
|
||
|
for queryName in $QUERYNAMES
|
||
|
do
|
||
|
getQueries $DBFILE $queryName
|
||
|
if [ "$LINEQ" -a "$NUMQ" ]; then
|
||
|
counter=${queryName}Cnt
|
||
|
|
||
|
echo "#-- Extraction of $queryName" >> $AWKFILE
|
||
|
echo "/$LINEQ/ {" >> $AWKFILE
|
||
|
echo " extract(\$0, \"$NUMQ\", val)" >> $AWKFILE
|
||
|
echo " file=\"$CASEDIR/logs/${queryName}_\" ${counter}" >> $AWKFILE
|
||
|
echo " print $TIMENAME \"\\t\" val[1] > file" >> $AWKFILE
|
||
|
echo " ${counter}++" >> $AWKFILE
|
||
|
echo "}" >> $AWKFILE
|
||
|
echo "" >> $AWKFILE
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
|
||
|
|
||
|
#-----------------------------
|
||
|
# Run awk program on log
|
||
|
#-----------------------------
|
||
|
(
|
||
|
cmd="awk -f $AWKFILE $LOG"
|
||
|
myEcho "Executing: $cmd"
|
||
|
$cmd
|
||
|
myEcho ""
|
||
|
)
|
||
|
|
||
|
#-----------------------------
|
||
|
# Print found
|
||
|
#-----------------------------
|
||
|
myEcho "Generated XY files for:"
|
||
|
getAllQueries $DBFILE $LOG
|
||
|
|
||
|
#------------------------------------------------------------------------------
|