Merge commit 'b5be6201e00421a59e574a07b3d28cde5defff84'
[foam-extend-4.0.git] / bin / foamLog
blob0024ddb65503e635c4e6d72f1892bfee8ad10346
1 #!/bin/sh
2 #------------------------------------------------------------------------------
3 # ========= |
4 # \\ / F ield | foam-extend: Open Source CFD
5 # \\ / O peration | Version: 4.0
6 # \\ / A nd | Web: http://www.foam-extend.org
7 # \\/ M anipulation | For copyright notice see file Copyright
8 #------------------------------------------------------------------------------
9 # License
10 # This file is part of foam-extend.
12 # foam-extend is free software: you can redistribute it and/or modify it
13 # under the terms of the GNU General Public License as published by the
14 # Free Software Foundation, either version 3 of the License, or (at your
15 # option) any later version.
17 # foam-extend is distributed in the hope that it will be useful, but
18 # WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 # General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 # Script
26 # foamLog
28 # Description
29 # extracts info from log file
31 # Bugs
32 # -solution singularity not handled
33 #------------------------------------------------------------------------------
35 PROGDIR=`dirname $0`
36 PROGNAME=`basename $0`
38 if [ -r $HOME/.${PROGNAME}.db ]; then
39 DBFILE=$HOME/.${PROGNAME}.db
40 else
41 DBFILE=$PROGDIR/$PROGNAME.db
45 printUsage() {
46 cat <<LABUSAGE
47 $PROGNAME - extracts xy files from Foam logs.
49 Usage: $PROGNAME [-n][-s] <log>
50 extracts xy files from log
51 $PROGNAME -l <log>
52 lists but does not extract
53 $PROGNAME -h
54 for a help message
56 LABUSAGE
60 printHelp() {
61 printUsage
62 cat <<LABHELP
63 The default is to extract for all the 'Solved for' variables the
64 initial residual, the final residual and the number of iterations. On
65 top of this a (user editable) database of standard non-solved for
66 variables is used to extract data like Courant number, execution time.
68 $PROGNAME -l shows all the possible variables but does not extract them.
70 The program will generate and run an awk script which writes a set of
71 files, logs/<var>_<subIter>, for every <var> specified, for every
72 occurrence inside a time step.
74 For variables that are 'Solved for' the initial residual name will
75 be <var>, the final residual will get name <var>FinalRes,
77 The files are a simple xy format with the first column Time (default)
78 and the second the extracted values. Option -n creates single column
79 files with the extracted data only.
82 The query database is a simple text format with three entries per line,
83 separated with '/'. Column 1 is the name of the variable (cannot contain
84 spaces), column 2 is the extended regular expression (egrep) to select
85 the line and column 3 is the string (fgrep) to select the column inside the
86 line. The value taken will be the first (non-space)word after this
87 column. The database will either be \$HOME/.${PROGNAME}.db or if not
88 found $PROGDIR/${PROGNAME}.db.
90 Option -s suppresses the default information and only prints the extracted
91 variables.
93 LABHELP
98 myEcho() {
99 if [ "$VERBOSE" ]; then
100 echo "$*"
104 # getSolvedVars logFile
105 # Prints names of all 'solved for' variables in the log file.
106 getSolvedVars() {
107 fgrep ' Solving for ' $1 | fgrep ',' | sed -e 's/.* Solving for \([^,]*\)[,:].*/\1/' | sort -u
111 # getQueries dbFile queryName
112 # Gets regular expressions for a certain queryName from the database
113 getQueries() {
114 if [ ! -f "$1" ]; then
115 echo "Cannot find dbFile $1"
116 exit 1
119 queryName=$2
121 LINEQ=`grep -v '^#' $1 | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $2}'`
122 NUMQ=`grep -v '^#' $1 | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $3}'`
124 #echo "For $queryName found line selection /$LINEQ/ , column selection /$NUMQ/" 1>&2
125 #if [ ! "$LINEQ" -o ! "$NUMQ" ]; then
126 # echo "Did not find query for $2 in database $1" 1>&2
131 # getDbQueryList dbFile
132 # Echoes list of possible queries
133 getDbQueryList() {
134 grep -v '^#' $1 | grep '[^ \t]' | awk -F '/' '{print $1}'
138 # getSolveQueryList logFile
139 # Echoes list of queries from "solved for" variables in log file
140 getSolveQueryList() {
141 solvedVars=`getSolvedVars $1`
143 for var in $solvedVars
145 echo "${var}"
146 echo "${var}FinalRes"
147 echo "${var}Iters"
148 done
151 # getAllQueries dbFile logFile
152 # Gets all queries from database and from logfile
153 getAllQueries() {
154 #-- All solved for queries from log file
155 queries=`getSolveQueryList $2`
157 #-- Add ones from database, present in log file
158 # Note: just like awk, line selected with regular expression,
159 # column with string.
160 dbQueries=`getDbQueryList $1`
162 for var in $dbQueries
164 getQueries $1 "$var"
165 line=`egrep "$LINEQ" $2`
166 if [ "$line" ]; then
167 column=`echo "$line" | fgrep "$NUMQ"`
168 if [ "$column" ]; then
169 queries="$queries $var"
172 done
174 for q in $queries
176 echo "$q"
177 done | sort -u
180 #-----------------------------
181 # Main
182 #-----------------------------
184 # sort arguments
185 TIMENAME='Time'
186 VERBOSE='yes'
187 LISTONLY=''
189 while getopts nslh flags
191 case $flags in
192 n) TIMENAME=""
194 h) printHelp
195 exit 0
197 s) VERBOSE=""
199 l) LISTONLY='yes'
201 \?) printUsage
202 exit 1
204 esac
205 done
208 # Shift options
209 shift `expr $OPTIND - 1`
211 if [ ! -f $DBFILE ]; then
212 echo "$PROGNAME: Cannot read database $DBFILE"
213 exit 1
216 if [ "$LISTONLY" ]; then
217 if [ $# -ne 1 ]; then
218 printUsage
219 exit 1
221 LOG=$1;
222 if [ ! -r $LOG ]; then
223 echo "$PROGNAME: Cannot read log $LOG"
224 exit 1
226 getAllQueries $DBFILE $LOG
227 exit 0
230 if [ $# -ne 1 ]; then
231 printUsage
232 exit 1
235 CASEDIR=.
236 LOG=$1
237 if [ ! -r $LOG ]; then
238 echo "$PROGNAME: Cannot read log $LOG"
239 exit 1
242 QUERYNAMES=`getAllQueries $DBFILE $LOG`
245 if [ ! "$CASEDIR" ]; then
246 printUsage
247 exit 1
250 if [ ! -d "$CASEDIR" ]; then
251 echo "$PROGNAME: Cannot read $CASEDIR"
252 exit 1
255 if [ ! -f "$LOG" ]; then
256 echo "$PROGNAME: Cannot read log file $LOG"
257 exit 1
261 #-- Make logs dir in case directory and put awk file there.
263 mkdir -p $CASEDIR/logs
264 AWKFILE=$CASEDIR/logs/$PROGNAME.awk
266 myEcho "Using:"
267 myEcho " log : $LOG"
268 myEcho " database : $DBFILE"
269 myEcho " awk file : $AWKFILE"
270 myEcho " files to : $CASEDIR/logs"
271 myEcho ""
274 #-----------------------------
275 # Generate Awk program
276 #-----------------------------
280 #-- header
282 rm -f $AWKFILE; touch $AWKFILE
283 echo "BEGIN {" >> $AWKFILE
284 echo " Iteration=0" >> $AWKFILE
285 echo " resetCounters()" >> $AWKFILE
286 echo "}" >> $AWKFILE
288 echo "" >> $AWKFILE
289 echo "# reset counters used for variable postfix" >> $AWKFILE
290 echo "function resetCounters() {" >> $AWKFILE
291 for queryName in $QUERYNAMES
293 varName=${queryName}Cnt
294 echo " ${varName}=0" >> $AWKFILE
295 done
296 echo " # Reset counters for general Solving for extraction" >> $AWKFILE
297 echo " for (varName in subIter)" >> $AWKFILE
298 echo " {" >> $AWKFILE
299 echo " subIter[varName]=0" >> $AWKFILE
300 echo " }" >> $AWKFILE
301 echo "}" >> $AWKFILE
302 echo "" >> $AWKFILE
305 cat <<LABEL >> $AWKFILE
306 # Extract value after columnSel
307 function extract(inLine,columnSel,outVar,
308 a,b)
310 a=index(inLine, columnSel)
311 b=length(columnSel)
312 split(substr(inLine, a+b),outVar)
313 gsub("[,:]","",outVar[1])
316 LABEL
322 #-- Generate code for iteration separator (increments 'Iteration')
323 getQueries $DBFILE 'Separator'
324 cat <<LABSEP >> $AWKFILE
325 #-- Iteration separator (increments 'Iteration')
326 /$LINEQ/ {
327 Iteration++
328 resetCounters()
331 LABSEP
334 #-- Generate code for extracting Time
335 getQueries $DBFILE 'Time'
336 cat <<LABTIME >> $AWKFILE
337 #-- Time extraction (sets 'Time')
338 /$LINEQ/ {
339 extract(\$0, "$NUMQ", val)
340 Time=val[1]
343 LABTIME
346 #-- Generate code for singularity handling.
347 cat <<LABSING >> $AWKFILE
348 #-- Skip whole line with singularity variable
349 /solution singularity/ {
350 next;
352 LABSING
355 #-- Generate code for extracting solved for quantities
356 cat <<LABSOLVE >> $AWKFILE
357 #-- Extraction of any solved for variable
358 /Solving for/ {
359 extract(\$0, "Solving for ", varNameVal)
361 varName=varNameVal[1]
362 file=varName "_" subIter[varName]++
363 file="$CASEDIR/logs/" file
364 extract(\$0, "Initial residual = ", val)
365 print $TIMENAME "\t" val[1] > file
367 varName=varNameVal[1] "FinalRes"
368 file=varName "_" subIter[varName]++
369 file="$CASEDIR/logs/" file
370 extract(\$0, "Final residual = ", val)
371 print $TIMENAME "\t" val[1] > file
373 varName=varNameVal[1] "Iters"
374 file=varName "_" subIter[varName]++
375 file="$CASEDIR/logs/" file
376 extract(\$0, "No Iterations ", val)
377 print $TIMENAME "\t" val[1] > file
380 LABSOLVE
382 #-- generate code to process queries
383 for queryName in $QUERYNAMES
385 getQueries $DBFILE $queryName
386 if [ "$LINEQ" -a "$NUMQ" ]; then
387 counter=${queryName}Cnt
389 echo "#-- Extraction of $queryName" >> $AWKFILE
390 echo "/$LINEQ/ {" >> $AWKFILE
391 echo " extract(\$0, \"$NUMQ\", val)" >> $AWKFILE
392 echo " file=\"$CASEDIR/logs/${queryName}_\" ${counter}" >> $AWKFILE
393 echo " print $TIMENAME \"\\t\" val[1] > file" >> $AWKFILE
394 echo " ${counter}++" >> $AWKFILE
395 echo "}" >> $AWKFILE
396 echo "" >> $AWKFILE
398 done
402 #-----------------------------
403 # Run awk program on log
404 #-----------------------------
406 cmd="awk -f $AWKFILE $LOG"
407 myEcho "Executing: $cmd"
408 $cmd
409 myEcho ""
412 #-----------------------------
413 # Print found
414 #-----------------------------
415 myEcho "Generated XY files for:"
416 getAllQueries $DBFILE $LOG
418 #------------------------------------------------------------------------------