ENH: add -case option for foamLog

This commit is contained in:
Mark Olesen
2017-11-17 19:04:13 +01:00
parent 9c3bef5a99
commit 810d090e34

View File

@ -26,7 +26,7 @@
# foamLog # foamLog
# #
# Description # Description
# Script extract data for each time-step from a log file for graphing. # Extract data for each time-step from a log file for graphing.
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
Script=${0##*/} Script=${0##*/}
@ -40,11 +40,12 @@ usage() {
cat <<USAGE cat <<USAGE
Usage: $Script [OPTIONS] <log> Usage: $Script [OPTIONS] <log>
-list lists but does not extract -case <dir> specify alternate case directory, default is the cwd
-n create single column files with the extracted data only -list | -l lists but does not extract
-quiet quiet operation -n create single column files with extracted data only
-localDB only use the local database file -quiet | -q quiet operation
-help print the usage -local | -localDB only use the local database file
-help print the usage
$Script - extracts xy files from OpenFOAM logs. $Script - extracts xy files from OpenFOAM logs.
@ -57,43 +58,42 @@ USAGE
printHelp() { printHelp() {
cat <<HELP cat <<HELP
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
The default is to extract for all the 'Solved for' variables the initial The default is to extract the initial residual, the final residual and
residual, the final residual and the number of iterations. Additionally, a the number of iterations for all 'Solved for' variables.
(user editable) database is used to extract data for standard non-solved for Additionally, a (user editable) database is used to extract data for
variables like Courant number, and execution time. standard non-solved for variables like Courant number, and execution time.
$Script -l lists all the possible variables without extracting them. option -list : lists the possible variables without extracting them.
The program will generate and run an awk script which writes a set of files, The program will generate and run an awk script that writes a set of files,
logs/<var>_<subIter>, for every <var> specified, for every occurrence inside logs/<var>_<subIter>, for every <var> specified, for every occurrence inside
a time step. a time step.
For variables that are 'Solved for', the initial residual name will be For variables that are 'Solved for', the initial residual name will be
<var>, the final residual receive the name <var>FinalRes, <var>, the final residual receive the name <var>FinalRes,
The files are output in a simple xy format with the first column Time (default) The files are output in a simple xy format with the first column Time
and the second the extracted values. Option -n creates single column (default) and the second the extracted values.
files with the extracted data only. 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 by '/' :
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 query database is a simple text format with three entries per line, The database ($Script.db) will taken from these locations:
separated with '/' : .
Column 1 is the name of the variable (cannot contain spaces). $userDir/$WM_PROJECT_VERSION
Column 2 is the extended regular expression (egrep) to select the line. $userDir
Column 3 is the string (fgrep) to select the column inside the line. $siteDir/$WM_PROJECT_VERSION
The value taken will be the first (non-space)word after this column. $siteDir
The database ($Script.db) will taken from these locations: $WM_PROJECT_DIR/etc
$toolsDir
. option -quiet : suppresses the default information and only prints the
$userDir/$WM_PROJECT_VERSION extracted variables.
$userDir
$siteDir/$WM_PROJECT_VERSION
$siteDir
$WM_PROJECT_DIR/etc
$toolsDir
Option -q suppresses the default information and only prints the extracted
variables.
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
HELP HELP
@ -101,8 +101,9 @@ usage
} }
caseDir=.
timeName=Time timeName=Time
unset listOpt quietOpt localDB unset optList optQuiet localDB
# Parse options # Parse options
while [ "$#" -gt 0 ] while [ "$#" -gt 0 ]
@ -112,85 +113,93 @@ do
printHelp printHelp
exit 0 exit 0
;; ;;
-case)
caseDir="$2"
shift
;;
-n) -n)
unset timeName unset timeName
shift
;; ;;
-l | -list) -l | -list)
listOpt=true optList=true
shift
;; ;;
-q | -quiet | -s | -silent) -q | -quiet | -s | -silent)
quietOpt=true optQuiet=true
shift
;; ;;
-localDB) -local | -localDB)
localDB=true localDB=true
shift
;; ;;
-*) -*)
usage "unknown option: '$*'" usage "unknown option: '$1'"
;; ;;
*) *)
break break
;; ;;
esac esac
shift
done done
# Find the database file # Requires a single logFile
DBFILE=$Script.db [ $# -eq 1 ] || usage
[ -f $DBFILE ] || DBFILE=`foamEtcFile $Script.db` || DBFILE=$toolsDir/$Script.db
# Heed the database file logFile=$1
[ -f $DBFILE ] || {
echo "$Script: Cannot read database $DBFILE" # Change to case directory
cd "$caseDir" 2>/dev/null || {
echo "$Script: No such case directory '$caseDir'" 1>&2
exit 1 exit 1
} }
# Single logFile # Find the database file: case-local, from etc dirs, or tools-dir
if [ $# -eq 1 ] DBFILE=$Script.db
then [ -f "$DBFILE" ] || \
LOG=$1 DBFILE=$(foamEtcFile $Script.db) || \
[ -r "$LOG" ] && [ -f "$LOG" ] || usage "Cannot read log $LOG" DBFILE=$toolsDir/$Script.db
else
usage # Need the database file
fi [ -f "$DBFILE" ] || {
echo "$Script: Cannot read database $DBFILE" 1>&2
exit 1
}
# Verify that logFile is readable
[ -r "$logFile" -a -f "$logFile" ] || usage "Cannot read log $logFile"
myEcho() # Say is like echo, but -quiet turns it off
say()
{ {
[ "$quietOpt" = true ] || echo "$*" [ "$optQuiet" = true ] || echo "$*"
} }
# getSolvedVars logFile # getSolvedVars logFile
# Prints names of all 'solved for' variables in the log file. # Prints names of all 'Solving for ...' variables in the log file.
getSolvedVars() getSolvedVars()
{ {
fgrep ' Solving for ' $1 | fgrep ',' | sed -e 's/.* Solving for \([^,]*\)[,:].*/\1/' | sed -e 's/\./_/g' | sort -u [ -f "$1" ] && \
sed -n -e 's/.* Solving for \([^,]*\)[,:].*/\1/p' "$1" | \
sed -e 's/\./_/g' | \
sort -u
} }
# getQueries dbFile queryName # getQueries dbFile queryName
# Gets regular expressions for a certain queryName from the database # Gets regular expressions for a certain queryName from the database
#
# Sets LINEQ, NUMQ
getQueries() getQueries()
{ {
dbFile=$1 local dbFile=$1
queryName=$2 local queryName=$2
[ -f "$dbFile" ] || { [ -f "$dbFile" ] || {
echo "Cannot find dbFile $dbFile" echo "Cannot find dbFile $dbFile" 1>&2
exit 1 exit 1
} }
LINEQ=`grep -v '^#' $dbFile | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $2}'` LINEQ=$(grep -v '^#' $dbFile | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $2}')
NUMQ=`grep -v '^#' $dbFile | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $3}'` NUMQ=$(grep -v '^#' $dbFile | 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
} }
@ -198,7 +207,8 @@ getQueries()
# Echoes list of possible queries # Echoes list of possible queries
getDbQueryList() getDbQueryList()
{ {
grep -v '^#' $1 | grep '[^ \t]' | awk -F '/' '{print $1}' local dbFile=$1
grep -v '^#' $dbFile | grep '[^ \t]' | awk -F '/' '{print $1}'
} }
@ -206,7 +216,7 @@ getDbQueryList()
# Echoes list of queries from "solved for" variables in log file # Echoes list of queries from "solved for" variables in log file
getSolveQueryList() getSolveQueryList()
{ {
solvedVars=`getSolvedVars $1` solvedVars=$(getSolvedVars $1)
for var in $solvedVars for var in $solvedVars
do do
@ -221,31 +231,28 @@ getSolveQueryList()
# Gets all queries from database and from logfile # Gets all queries from database and from logfile
getAllQueries() getAllQueries()
{ {
local db=$1
local log=$2
local q queries
#-- All solved for queries from log file #-- All solved for queries from log file
[ "$localDB" = true ] || queries=`getSolveQueryList $2` [ "$localDB" = true ] || queries=$(getSolveQueryList $log)
#-- Add ones from database, present in log file #-- Add ones from database, present in log file
# Note: just like awk, line selected with regular expression, # Note: just like awk, line selected with regular expression,
# column with string. # column with string.
dbQueries=`getDbQueryList $1` local dbQueries=$(getDbQueryList $db)
for var in $dbQueries for var in $dbQueries
do do
getQueries $1 "$var" getQueries $db "$var"
line=`egrep "$LINEQ" $2` q=$(egrep "$LINEQ" "$log" | fgrep "$NUMQ")
if [ "$line" ] [ -n "$q" ] && queries="$queries $var"
then
column=`echo "$line" | fgrep "$NUMQ"`
if [ "$column" ]
then
queries="$queries $var"
fi
fi
done done
for q in $queries for q in $queries
do do
echo "$q" echo $q
done | sort -u done | sort -u
} }
@ -254,21 +261,14 @@ getAllQueries()
# Main # Main
#----------------------------- #-----------------------------
if [ "$listOpt" = true ] if [ "$optList" = true ]
then then
getAllQueries $DBFILE $LOG getAllQueries $DBFILE $logFile
exit 0 exit 0
fi fi
caseDir=. outputDir=logs
outputDir=$caseDir/logs QUERYNAMES=$(getAllQueries $DBFILE $logFile)
[ -d "$caseDir" ] || {
echo "$Script: Cannot read $caseDir"
exit 1
}
QUERYNAMES=`getAllQueries $DBFILE $LOG`
# #
# Make logs dir in case directory and place awk file there # Make logs dir in case directory and place awk file there
@ -276,12 +276,13 @@ QUERYNAMES=`getAllQueries $DBFILE $LOG`
mkdir -p $outputDir mkdir -p $outputDir
AWKFILE=$outputDir/$Script.awk AWKFILE=$outputDir/$Script.awk
myEcho "Using:" say "Using:"
myEcho " log : $LOG" say " case : $(pwd -L)"
myEcho " database : $DBFILE" say " log : $logFile"
myEcho " awk file : $AWKFILE" say " database : $DBFILE"
myEcho " files to : $outputDir" say " awk file : $AWKFILE"
myEcho "" say " files to : $outputDir"
say
#----------------------------- #-----------------------------
@ -290,33 +291,30 @@ myEcho ""
rm -f $AWKFILE 2> /dev/null rm -f $AWKFILE 2> /dev/null
cat << AWK_CONTENTS > $AWKFILE cat << AWK_CONTENTS > $AWKFILE
# header # Awk script for OpenFOAM log file extraction
BEGIN { BEGIN {
Iteration=0 Iteration=0
resetCounters() resetCounters()
} }
# reset counters used for variable postfix # Reset counters used for variable postfix
function resetCounters() { function resetCounters() {
AWK_CONTENTS AWK_CONTENTS
# ---------- # ----------
for queryName in $QUERYNAMES for queryName in $QUERYNAMES
do do
varName=${queryName}Cnt echo " ${queryName}Cnt=0"
echo " ${varName}=0" >> $AWKFILE done >> $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 << AWK_CONTENTS >> $AWKFILE cat << AWK_CONTENTS >> $AWKFILE
# Reset counters for 'Solving for ...'
for (varName in subIter)
{
subIter[varName]=0
}
}
# Extract value after columnSel # Extract value after columnSel
function extract(inLine,columnSel,outVar,a,b) function extract(inLine,columnSel,outVar,a,b)
{ {
@ -332,7 +330,7 @@ AWK_CONTENTS
# #
# Code for iteration separator (increments 'Iteration') # Code for iteration separator (increments 'Iteration')
# #
getQueries $DBFILE 'Separator' getQueries $DBFILE Separator
cat << AWK_CONTENTS >> $AWKFILE cat << AWK_CONTENTS >> $AWKFILE
# Iteration separator (increments 'Iteration') # Iteration separator (increments 'Iteration')
/$LINEQ/ { /$LINEQ/ {
@ -346,7 +344,7 @@ AWK_CONTENTS
# #
# Code for extracting Time # Code for extracting Time
# #
getQueries $DBFILE 'Time' getQueries $DBFILE Time
cat << AWK_CONTENTS >> $AWKFILE cat << AWK_CONTENTS >> $AWKFILE
# Time extraction (sets 'Time') # Time extraction (sets 'Time')
/$LINEQ/ { /$LINEQ/ {
@ -371,31 +369,30 @@ AWK_CONTENTS
# #
# Code for extracting solved for quantities # Code for extracting solved for quantities
# # - note leading tabs for alignment are intentional
[ "$localDB" = true ] || [ "$localDB" = true ] || cat <<- AWK_CONTENTS >> $AWKFILE
cat << AWK_CONTENTS >> $AWKFILE # Extract: 'Solving for ...'
# Extraction of any solved for variable /Solving for/ {
/Solving for/ { extract(\$0, "Solving for ", varNameVal)
extract(\$0, "Solving for ", varNameVal)
varName=varNameVal[1] varName=varNameVal[1]
file=varName "_" subIter[varName]++ file=varName "_" subIter[varName]++
file="$outputDir/" file file="$outputDir/" file
extract(\$0, "Initial residual = ", val) extract(\$0, "Initial residual = ", val)
print $timeName "\t" val[1] > file print $timeName "\t" val[1] > file
varName=varNameVal[1] "FinalRes" varName=varNameVal[1] "FinalRes"
file=varName "_" subIter[varName]++ file=varName "_" subIter[varName]++
file="$outputDir/" file file="$outputDir/" file
extract(\$0, "Final residual = ", val) extract(\$0, "Final residual = ", val)
print $timeName "\t" val[1] > file print $timeName "\t" val[1] > file
varName=varNameVal[1] "Iters" varName=varNameVal[1] "Iters"
file=varName "_" subIter[varName]++ file=varName "_" subIter[varName]++
file="$outputDir/" file file="$outputDir/" file
extract(\$0, "No Iterations ", val) extract(\$0, "No Iterations ", val)
print $timeName "\t" val[1] > file print $timeName "\t" val[1] > file
} }
AWK_CONTENTS AWK_CONTENTS
# ---------- # ----------
@ -405,38 +402,45 @@ AWK_CONTENTS
# #
for queryName in $QUERYNAMES for queryName in $QUERYNAMES
do do
counter=${queryName}Cnt
getQueries $DBFILE $queryName getQueries $DBFILE $queryName
if [ "$LINEQ" -a "$NUMQ" ]
then
counter=${queryName}Cnt
echo "# Extraction of $queryName" >> $AWKFILE # note leading tabs for alignment are intentional
echo "/$LINEQ/ {" >> $AWKFILE [ -n "$LINEQ" -a -n "$NUMQ" ] && cat<<- AWK_CONTENTS
echo " extract(\$0, \"$NUMQ\", val)" >> $AWKFILE # Extract: '$queryName'
echo " file=\"$outputDir/${queryName}_\" ${counter}" >> $AWKFILE /$LINEQ/ {
echo " print $timeName \"\\t\" val[1] > file" >> $AWKFILE extract(\$0, "$NUMQ", val)
echo " ${counter}++" >> $AWKFILE file="$outputDir/${queryName}_" ${counter}
echo "}" >> $AWKFILE print $timeName "\\t" val[1] > file
echo "" >> $AWKFILE ${counter}++
fi }
done
AWK_CONTENTS
# ----------
done >> $AWKFILE
echo "# End" >> $AWKFILE
#----------------------------- #-----------------------------
# Run awk program on log # Run awk program on log
#----------------------------- #-----------------------------
( say "Executing: awk -f $AWKFILE $logFile"
cmd="awk -f $AWKFILE $LOG" awk -f $AWKFILE $logFile
myEcho "Executing: $cmd" say
$cmd
myEcho ""
)
#----------------------------- #-----------------------------
# Print found # Print found
#----------------------------- #-----------------------------
myEcho "Generated XY files for:" if [ -z "$optQuiet" ]
[ "$quietOpt" = true ] || getAllQueries $DBFILE $LOG then
myEcho "End" echo "Generated XY files for:"
for queryName in $QUERYNAMES
do
echo " ${queryName}"
done
echo "End"
fi
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------