openfoam/bin/foamLog

458 lines
10 KiB
Bash
Executable File

#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
# \\/ 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`
DBFILE=${PROGNAME}.db
printUsage() {
cat <<USAGE
$PROGNAME - extracts xy files from OpenFOAM 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
USAGE
}
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. Additionally, a
(user editable) database is used to extract data for standard non-solved for
variables like Courant number, and execution time.
$PROGNAME -l lists all the possible variables without extracting 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 receive the name <var>FinalRes,
The files are output in 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.
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 ($PROGNAME.db) will taken from these locations:
.
$HOME/.OpenFOAM/$WM_PROJECT_VERSION
$HOME/.OpenFOAM
$WM_PROJECT_INST_DIR/site/$WM_PROJECT_VERSION
$WM_PROJECT_INST_DIR/site
$WM_PROJECT_DIR/etc
$PROGDIR/tools
Option -s suppresses the default information and only prints the extracted
variables.
LABHELP
}
# The various places to be searched:
for i in \
. \
$HOME/.OpenFOAM/$WM_PROJECT_VERSION \
$HOME/.OpenFOAM \
$WM_PROJECT_INST_DIR/site/$WM_PROJECT_VERSION \
$WM_PROJECT_INST_DIR/site \
$WM_PROJECT_DIR/etc \
$PROGDIR/tools \
;
do
if [ -r $i/$DBFILE ]
then
DBFILE="$i/$DBFILE"
break
fi
done
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
myEcho "End"
#------------------------------------------------------------------------------