View Issue Details

IDProjectCategoryView StatusLast Update
0003427OpenFOAMContributionpublic2020-01-16 11:05
Reportermichael.mueller-wrd Assigned Tohenry  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionsuspended 
PlatformUnixOScentOSOS Version(please specify)
Summary0003427: foamMonitor output to png file
DescriptionI am using the foamMonitor utility to automate the reporting process.
In order to generate plot files using the gnuplot terminal pngcairo, I added a new option...
-output | -o "filename.png"
... to the foamMonitor utility. See attached script.
Maybe you can adopt this functionality in future releases as this might be helpful for others as well.
TagsNo tags attached.

Activities

michael.mueller-wrd

2020-01-13 11:52

reporter  

foamMonitor (5,963 bytes)   
#!/bin/sh
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     | Website:  https://openfoam.org
#   \\  /    A nd           | Copyright (C) 2015-2019 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
#     foamMonitor
#
# Description
#     Monitor data with Gnuplot from time-value(s) graphs written by OpenFOAM
#     e.g. by functionObjects
#     - requires gnuplot
#
#------------------------------------------------------------------------------
usage() {
    cat<<USAGE

Usage: ${0##*/} [OPTION] <file>
options:
  -help     | -h         print the usage
  -idle     | -i <time>  stops if <file> unchanging for <time> sec (default 60s)
  -title    | -t <title> set the graph title (default "Data Monitoring")
  -logscale | -l         plots data (y-axis) on log scale, e.g. for residuals
  -refresh  | -r <time>  refreshes display every <time> sec (default 10s)
  -yrange   | -y <range> sets data (y-axis) range, format "[0:1]"
  -size     | -s <size>  set the size of the output plot, format "640,480"
  -ascii    | -a         show the graph by printing ascii in the terminal
  -output   | -o <file>  plots data to png file 

Monitor data with Gnuplot from time-value(s) graphs written by OpenFOAM
e.g. by functionObjects
- requires gnuplot

Example:
  foamMonitor -l postProcessing/residuals/0/residuals.dat

USAGE
}

error() {
    exec 1>&2
    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
    usage
    exit 1
}

plotFileHeader() {
    cat<<EOF
set term $gpterminal $size
$png
$logscale
$yrange
set ytics format "$yticFormat"
set title "$title"
set xlabel "$xlabel"
plot \\
EOF
}

plotFileFooter() {
    cat<<EOF

pause $refresh
reread
EOF
}

howMany() ( echo "$1" | awk '{ print NF }' )
#howMany() ( echo "$1" | set -f; set -- $1; echo $# )

isInteger() {
    [ ! -z "${1##*[!0-9]*}" ] && echo "$1" && return 0
}

idle=60
refresh=10
logscale=""
yrange=""
yticFormat="%g"
title="Data Monitoring"
size=""
gpterminal='x11 1 font "helvetica,17" linewidth 1.5 persist noraise'
png=""

command -v gnuplot >/dev/null 2>&1 || error "Gnuplot not installed"

# parse options
while [ "$#" -gt 0 ]
do
    case "$1" in
    -h | -help)
        usage && exit 0
        ;;
    -i | -idle)
        [ "$#" -ge 2 ] || error "'$1' option requires an argument"
        idle=$(isInteger "$2") || error "Argument of '$1' is not an integer: '$2'"
        shift 2
        ;;
    -l | -logscale)
        logscale="set logscale y"
        yticFormat="%1.e"
        shift 1
        ;;
    -t | -title)
        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
        title=$2
        shift 2
        ;;
    -r | -refresh)
        [ "$#" -ge 2 ] || error "'$1' option requires an argument"
        refresh=$(isInteger "$2") || error "Argument of '$1' is not an integer: '$2'"
        shift 2
        ;;
    -y | -yrange)
        [ "$#" -ge 2 ] || error "'$1' option requires an argument"
        yrange="set yrange $2"
        shift 2
        ;;
    -s | -size)
        [ "$#" -ge 2 ] || error "'$1' option requires an argument"
        size="size $2"
        shift 2
        ;;
    -o | -output)
        [ "$#" -ge 2 ] || error "'$1' option requires an argument"
        gpterminal="pngcairo enhanced solid font 'Arial,16'"
        size="size 800,600"  # default
        png="set output '$2'"
        shift 2
        ;;
    -a | -ascii)
        gpterminal="dumb"
        shift 1
        ;;
    -*)
        error "unknown option: '$*'"
        ;;
    *)
        break
        ;;
    esac
done

[ $# -eq 1 ] || error "Incorrect arguments specified"
[ -f "$1" ]  || error "File $1 does not exit"
file=$1

# Get keys from header
keys=$(grep -E '^#' "$file" | tail -1)

[ "x$keys" = "x" ] && keys="# Step"
n_keys=$(howMany "$keys")
n_cols=$(tail -1 "$file" | awk '{ print NF }')

# With full column labels, n_keys = n_cols + 1, since it includes "#"

# If n_keys > n_cols + 1, REMOVE EXCESS keys
n_cols_pone=$(( n_cols + 1 ))
[ "$n_keys" -gt "$n_cols_pone" ] && \
    keys=$(echo "$keys" | cut -d" " -f1-$n_cols_pone)
n_keys=$(howMany "$keys")

i=0
while [ "$n_keys" -le "$n_cols" ]
do
    i=$(( i + 1 ))
    keys="$keys data$i"
    n_keys=$(howMany "$keys")
done

# Remove # and Time keys
xlabel=$(echo "$keys" | cut -d " " -f2)
keys=$(echo "$keys" | cut -d " " -f3-)

gp_file=$(mktemp /tmp/tmp.XXXXXX)
plotFileHeader > "$gp_file"
i=1
for field in $keys
do
    i=$(( i + 1 ))
    plot_line="\"$file\" using 1:${i} with lines title \"$field\""
    if [ $i -lt "$n_cols" ]
    then
       plot_line="$plot_line, \\"
    fi
    echo "$plot_line" >> "$gp_file"
done

if [ -z "$png" ]; then
    plotFileFooter >> "$gp_file"

    touch "$file"
    gnuplot "$gp_file" &
    pid=$!
    
    while true
    do
        mod_time=$(stat --format=%Y "$file")
        idle_ago=$(( $(date +%s) - idle ))
        test "$mod_time" -gt "$idle_ago" || break
        sleep "$refresh"
    done
    
    kill -9 $pid
else
    gnuplot "$gp_file"
fi
rm "$gp_file"

#------------------------------------------------------------------------------
foamMonitor (5,963 bytes)   

openfoam_ran

2020-01-14 19:41

reporter   ~0011067

Yes. It is helpful.

henry

2020-01-15 15:28

manager   ~0011069

foamMonitor is designed for monitoring residuals during a run, rather than adding a specialized output function to generate a graph in a particular format wouldn't it be better to write a more general graphing tool which could generate graphs from any of the OpenFOAM post-processing files?

michael.mueller-wrd

2020-01-16 10:18

reporter   ~0011070

Of course, you are right, it would be better to have it in a more general way.
But I think, this requires lots more effort -- especially in case you have a multiRegion case... it can get quite complicated to get useful graphs from the postProcessing data.

Nonetheless, if someone comes up with a more general graphing tool, I would really appreciate it.

henry

2020-01-16 11:05

manager   ~0011071

Pending a more general solution.

Issue History

Date Modified Username Field Change
2020-01-13 11:52 michael.mueller-wrd New Issue
2020-01-13 11:52 michael.mueller-wrd File Added: foamMonitor
2020-01-14 19:41 openfoam_ran Note Added: 0011067
2020-01-15 15:28 henry Note Added: 0011069
2020-01-16 10:18 michael.mueller-wrd Note Added: 0011070
2020-01-16 11:05 henry Assigned To => henry
2020-01-16 11:05 henry Status new => closed
2020-01-16 11:05 henry Resolution open => suspended
2020-01-16 11:05 henry Note Added: 0011071