Skip to content
Snippets Groups Projects
foamMonitor 7.09 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/bin/sh
    #------------------------------------------------------------------------------
    # =========                 |
    # \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    #  \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
    #   \\  /    A nd           | www.openfoam.com
    
    #    \\/     M anipulation  |
    #-------------------------------------------------------------------------------
    
    #    Copyright (C) 2015 OpenFOAM Foundation
    
    #    Copyright (C) 2019-2023 OpenCFD Ltd.
    
    #------------------------------------------------------------------------------
    
    #     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
    
    #
    # Script
    #     foamMonitor
    #
    # Description
    #     Monitor data with Gnuplot from time-value(s) graphs written by OpenFOAM
    #     e.g. by functionObjects
    
    #     - requires gnuplot, gnuplot_x11, sed, awk
    
    #
    #------------------------------------------------------------------------------
    
    Usage: ${0##*/} [OPTIONS] <file>
    Options:
      -g | -grid            Draw grid lines
      -i | -idle <time>     Stop if <file> unchanging for <time> sec (default = 60)
      -l | -logscale        Plot y-axis data on log scale
      -r | -refresh <time>  Refresh display every <time> sec (default = 10)
      -x | -xrange <range>  Set <range> of x-axis data, format "[0:1]"
      -y | -yrange <range>  Set <range> of y-axis data, format "[0:1]"
      -h | -help            Display short help and exit
    
    
    Monitor data with Gnuplot from time-value(s) graphs written by OpenFOAM
    
    e.g. by functionObjects. For example,
    
        foamMonitor -l postProcessing/residuals/0/residuals.dat
    
        exit 0  # A clean exit
    }
    
    
    # Report error and exit
    die()
    {
        exec 1>&2
        echo
        echo "Error encountered:"
        while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
        echo
        echo "See '${0##*/} -help' for usage"
        echo
    
    # Count the number of scalars between ( and ) to deduce the field dimensions
    count_components() {
        _text="$1"
    
        # Extract text between the first ( and )
        _matches="$(echo "$_text" | sed -n 's/^[^(]*(\([^)]*\)).*$/\1/p')"
    
        # Use grep to find numbers (doubles and 0) between ( and ), then count them
        _count="$(echo "$_matches" | grep -Eo '\b[0-9]+\.?[0-9]*[eE]?[-+]?[0-9]+\b|\b0\b' | wc -l)"
    
        echo "$_count"
    }
    
    
    
    set term x11 1 font "helvetica,17" linewidth 1.5 persist noraise size $SIZE
    
    set key outside
    set linetype cycle "$NCOLOURS"
    
    # Count number of tokens in a variable
    howMany() {
        ( set -f; set -- $1; echo $# )
    }
    
    
    #-------------------------------------------------------------------------------
    
    [ ! "$GNUPLOT" = "" ] || die "foamMonitor requires Gnuplot installed"
    
    command -v sed >/dev/null || die "foamMonitor requires sed installed"
    command -v awk >/dev/null || die "foamMonitor requires awk installed"
    
    #-------------------------------------------------------------------------------
    
    # Parse options
    
            [ "$#" -ge 2 ] || die "'$1' option requires an argument"
            if [ -n "${2##*[!0-9]*}" ]
            then
                IDLE=$2
            else
                die "Argument of '$1' is not an integer: '$2'"
            fi
    
            shift 2
            ;;
        -l | -logscale)
            LOGSCALE="set logscale y"
            shift 1
            ;;
        -r | -refresh)
    
            [ "$#" -ge 2 ] || die "'$1' option requires an argument"
            if [ -n "${2##*[!0-9]*}" ]
            then
                REFRESH=$2
            else
                die "Argument of '$1' is not an integer: '$2'"
            fi
            shift 2
            ;;
        -x | -xrange)
            [ "$#" -ge 2 ] || die "'$1' option requires an argument"
            XRANGE="set xrange $2"
    
            [ "$#" -ge 2 ] || die "'$1' option requires an argument"
    
        -g | -grid)
            GRID="set grid"
            shift 1
            ;;
    
    [ "$#" -eq 1 ] || die "Incorrect arguments specified"
    [ -f "$1" ]    || die "File $1 does not exit"
    FILE="$1"
    
    KEYS=$(grep -E '^#' "$FILE" | tail -1)
    
    NCOLS=$(grep -m 1 '^[^#]' "$FILE" | awk '{ print NF }')
    
    NCOMPS=$(count_components "$(grep -m 1 '^[^#]' "$FILE")")
    
    
    # With full column labels, NKEYS = NCOLS + 1, since it includes "#"
    
    # If NKEYS > NCOLS + 1, REMOVE EXCESS KEYS
    
    [ "$NKEYS" -gt "$NCOLSPONE" ] && KEYS=$(echo "$KEYS" | cut -d" " -f1-$NCOLSPONE)
    
    # Remove # and Time keys
    XLABEL=$(echo "$KEYS" | cut -d " " -f2)
    KEYS=$(echo "$KEYS" | cut -d " " -f3-)
    
        case "$NCOMPS" in
            0)  # scalar
                TEMPKEYS="$TEMPKEYS $i"
                ;;
            3)  # vector
                for j in x y z
                do
                    TEMPKEYS="$TEMPKEYS ${i}_${j}"
                done
                ;;
            6)  # symmetric tensor
                for j in xx xy xz yy yz zz
                do
                    TEMPKEYS="$TEMPKEYS ${i}_${j}"
                done
                ;;
            9)  # tensor
                for j in xx xy xz yx yy yz zx zy zz
                do
                    TEMPKEYS="$TEMPKEYS ${i}_${j}"
                done
                ;;
            *)  # handle other cases if needed
                echo "Unsupported number of components: $NCOMPS"
                exit 1
                ;;
        esac
    
    PLOT_TITLE="$(echo "$FILE" | awk -F'/' '{print $(NF-2) "/" $NF}')"
    NUM_ELEMENTS="$((NKEYS * NCOMPS))"
    
    plotFileHeader "$PLOT_TITLE" "$NUM_ELEMENTS" > "$GPFILE"
    
    
    
        # Reject any keys consisting of 'iter|converged|solver' words
        case "$field" in
            *"iter"*|*"converged"*|*"solver"*)
                continue
                ;;
        esac
    
        # Reject any parentheses, and configure gnuplot for the underscore character
        PLOTLINE="\"< sed 's/[()]//g' $FILE\" u 1:${i} w l dt ${j} t \"$(echo "$field" | sed 's/_/\\\\_/g')\""
        if [ "$i" -lt "$NCOLS" ]
    
        echo "$PLOTLINE" >> "$GPFILE"
    
        # Change the dash type after every 5 non-rejected lines
        [ $(((i-1) % 5)) -eq 0 ] && j=$((j+1))
    
    
    # Scrap ', \' characters from the tail of plot command, if necessary
    if tail -n 1 "$GPFILE" | grep -q ', \\$'; then
        { head -n -1 "$GPFILE"; tail -n 1 "$GPFILE" | sed 's/, \\$//'; } > tmp.gp
        mv -f -- tmp.gp "$GPFILE"
    fi
    
    
        MODTIME="$(stat --format=%Y "$FILE")"
    
        test "$MODTIME" -gt "$IDLEAGO" || break
    
    
    #------------------------------------------------------------------------------