caelus.post – Post-processing utilities

Provides log analysis and plotting utilities

PostProcessing

Main entry point for accessing OpenFOAM postProcessing data.

SolverLog

Caelus solver log file interface.

CaelusPlot

Caelus Data Plotting Interface

Post-processing interface

This module contains the implementation of PostProcessing the main entry point for accessing OpenFOAM’s postProcessing outputs.

Example

>>> post = PostProcessing() # In case directory
>>> print("Available objects: ", post.keys())
Available objects:  ['samples', 'samplePlanes', 'forceCoeffs1']
>>> fcoeffs = post['forceCoeffs1']
>>> #print details
... print(fcoeffs.magUInf, fcoeffs.liftDir, fcoeffs.dragDir)
...
20 [0 0 1] [1 0 0]
>>> # Get dataframe corresponding to `coefficient.dat`
... df = fcoeffs()
... print(df[['Cl', 'Cd']].head())
...
         Cl        Cd
0  0.031805  0.003195
1  0.078845  0.001883
2  0.106916  0.001444
3  0.106786  0.001842
4  0.079757  0.002850
>>> df.columns # show available columns
Index(['Time', 'Cd', 'Cs', 'Cl', 'CmRoll', 'CmPitch', 'CmYaw', 'Cd(f)',
       'Cd(r)', 'Cs(f)', 'Cs(r)', 'Cl(f)', 'Cl(r)'],
      dtype='object')
>>>
class caelus.post.funcobj.functions.PostProcessing(casedir=None, func_dict=None, raise_on_error: bool = False)[source]

Bases: object

Main entry point for accessing OpenFOAM postProcessing data.

If the function object dictionary is not provided as an argument, the class will attempt to infer the functions activated in controlDict file.

Parameters:
  • casedir (path) – Path to the case directory (default: cwd)

  • func_dict (CaelusDict) – Function objects dictionary

  • raise_on_error (bool) – Raise exception if some objects fail to process

filter(func_type)[source]

Retrieve function obects of a particular type.

The filter method is used to select function objects of a certain type. This is useful when the custom user-defined names might not correspond to the exact type of object.

Currently supported: sets, surfaces, forces, forceCoeffs.

Example

>>> fig = plt.figure()
>>> for fcoeff in post.filter('forceCoeffs'):
...    df = fcoeff('0')
...    plt.plot(df['Time'], df['Cl'])
Parameters:

func_type (str) – Type of function object

Yields:

FunctionObject – Function object instances

keys()[source]

Return the names of the function objects

casedir

Absolute path to the case directory

data

Input dictionary for this function object

property root

Return path to the postProcessing directory.

Core function object utilities

Implements the base classes upon with the concrete function object interfaces are built on. FunctionObject implements common methods used by all the subclasses.

class caelus.post.funcobj.funcobj.DictMeta(name, bases, namespace, **kwargs)[source]

Bases: ABCMeta

Create property methods and add validation for properties.

This metaclass implements the boilerplate code necessary to add getter/setters for various entries found in a Caelus input file. It expects a class variable _dict_properties that contains tuples for the various entries in the input file. The tuple can be of two forms:

  • (name, default_value)

  • (name, default_value, valid_values)

process_properties(proplist)[source]

Create getters/setters for properties

process_property(plist)[source]

Process a property

class caelus.post.funcobj.funcobj.FuncObjMeta(name, bases, namespace, **kwargs)[source]

Bases: DictMeta

Specialization for Function objects

class caelus.post.funcobj.funcobj.FunctionObject(*args, **kwargs)[source]

Bases: object

Base class representing an OpenFOAM function object

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

classmethod create(*, name, casedir=None, **kwargs)[source]

Create a function object from scratch

classmethod funcobj_type()[source]

Return the string representing this functionObject type.

property enabled
property executeControl
property executeInterval
property latest_time

Return the latest time available

property libs
property log
property region
property root

Root path to the function object in postProcessing

property timeEnd
property timeStart
property times

Return the list of time directories available

property writeControl
property writeInterval

Sets and surfaces sampling

This module implements the python interface to OpenFOAM’s sets and surfaces sampling objects.

SampledSets

A sets functionObjects entry.

SampledSurfaces

A surfaces functionObjects entry.

SampledSet

A concrete set instance.

SampledSurface

A concrete surface instance.

The different classes are illustrated using this example functionObject entry in motorBike tutorial example:

cuttingPlane
{
    type            surfaces;
    libs            (sampling);
    writeControl    writeTime;

    surfaceFormat   vtk;
    fields          ( p U );

    interpolationScheme cellPoint;

    surfaces
    {
        yNormal
        {
            type            cuttingPlane;
            planeType       pointAndNormal;
            pointAndNormalDict
            {
                point   (0 0 0);
                normal  (0 1 0);
            }
            interpolate     true;
        }
    }
}

When the above object is accessed via PostProcessing class, the cuttingPlane object is represented by SampledSurfaces, and the yNormal object is represented by SampledSurface instance. Similar relationship exists between SampledSets and SampledSet.

class caelus.post.funcobj.sampling.SampledData(name, fobj_dict, parent)[source]

Bases: object

Base class for a single sampling object.

Initialize data from input dictionary.

Parameters:
  • name (str) – User-defined name for this sampling instance

  • fobj_dict (CaelusDict) – Input parameter dictionary

  • parent (Sampling) – Parent collection instance

data

Input dictionary containing data for this instance

property fields

Return the names of fields requested by user

name

User-defined name for this sampling instance

parent

The parent sets/surfaces group instance

class caelus.post.funcobj.sampling.SampledSet(name, fobj_dict, parent)[source]

Bases: SampledData

A concrete set instance.

Currently only raw, vtk, and csv formats are supported for setFormat if the user intends to load the dataset through this class.

Example

>>> post = PostProcessing()      # Access post-processing instance
>>> sets = post['sampledSets1']  # Get the sets group
>>> probes = sets['probe1']      # Access line probe data
>>> df = probes()                # Get dataframe for latest time
>>> df1 = probes('10')           # Get dataframe for different time

Initialize data from input dictionary.

Parameters:
  • name (str) – User-defined name for this sampling instance

  • fobj_dict (CaelusDict) – Input parameter dictionary

  • parent (Sampling) – Parent collection instance

property axis
property coord_cols

Return names of the coordinates column.

If axis == "xyz" then returns a list of 3 columns, else returns the column name defined by axis.

property num_coord_cols

Return the number of expected columns for coordinates.

If the axis is xyz then returns 3, else returns 1 for all other axis options.

property points
property type
class caelus.post.funcobj.sampling.SampledSets(*args, **kwargs)[source]

Bases: Sampling

A sets functionObjects entry.

This class provides an interface to a group of sampled set instances. The instances are of type SampledSet.

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

property setFormat
class caelus.post.funcobj.sampling.SampledSurface(name, fobj_dict, parent)[source]

Bases: SampledData

A concrete surface instance.

Currently only vtk output format is supported for reading data. A pyvista.Mesh instance is returned and can be interacted using vtk.vtkPolyData methods.

Example

>>> post = PostProcessing()          # Access post-processing instance
>>> surfaces = post['cuttingPlane']  # Get the surfaces group
>>> plane = surfaces['yNormal']      # Access plane data
>>> patch = plane()                  # Get dataframe for latest time
>>> patch1 = plane('10')             # Get dataframe for different time

Initialize data from input dictionary.

Parameters:
  • name (str) – User-defined name for this sampling instance

  • fobj_dict (CaelusDict) – Input parameter dictionary

  • parent (Sampling) – Parent collection instance

property type
class caelus.post.funcobj.sampling.SampledSurfaces(*args, **kwargs)[source]

Bases: Sampling

A surfaces functionObjects entry.

This class provides an interface to a group of sampled surface (planes or patches) instances. The instances are of type SampledSurface.

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

property surfaceFormat
class caelus.post.funcobj.sampling.Sampling(*args, **kwargs)[source]

Bases: FunctionObject

Base class for sets and surfaces sampling groups.

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

keys()[source]

Return the names of the sampling entries

property fields
property interpolationScheme
samples

Mapping of sampling instances to their names.

Force and Force coefficients interface

Provides pythonic interface to OpenFOAM’s Forces function objects.

class caelus.post.funcobj.forces.ForceCoeffs(*args, **kwargs)[source]

Bases: FunctionObject

The class retrieves data from coefficient.dat file generated during a run.

Example

>>> post = PostProcessing()         # Get the post processing instance
>>> fcoeffs = post['forceCoeffs1']  # Retrieve force coefficients object
>>> df = fcoeffs()                  # Dataframe for latest time instance
>>> print(df.columns)               # Examine columns

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

property Aref
property dragDir
property lRef
property liftDir
property magUInf
property patches
property pitchAxis
class caelus.post.funcobj.forces.Forces(*args, **kwargs)[source]

Bases: FunctionObject

The class retrives data from force.dat and moment.dat files generated during a run and returns a single Pandas DataFrame containing the following columns.

Column

Value

Fx

Total force (x-direction)

Fy

Total force (y-direction)

Fz

Total force (z-direction)

Fpx

Pressure force (x-direction)

Fpy

Pressure force (y-direction)

Fpz

Pressure force (z-direction)

Fvx

Viscous force (x-direction)

Fvy

Viscous force (y-direction)

Fvz

Viscous force (z-direction)

Mx

Total moment (x-direction)

My

Total moment (y-direction)

Mz

Total moment (z-direction)

Mpx

Pressure moment (x-direction)

Mpy

Pressure moment (y-direction)

Mpz

Pressure moment (z-direction)

Mvx

Viscous moment (x-direction)

Mvy

Viscous moment (y-direction)

Mvz

Viscous moment (z-direction)

Example

>>> post = PostProcessing()   # Get the post processing instance
>>> forces = post['forces1']  # Retrieve force coefficients object
>>> df = forces()             # Dataframe for latest time instance
>>> print(df.columns)         # Examine columns

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

class caelus.post.funcobj.forces.LiftDrag(*args, **kwargs)[source]

Bases: FunctionObject

A variation of ForceCoeffs that calculates lift/drag for specific use case.

Initialize object from input dictionary.

Parameters:
  • name (str) – User-defined name for this object (in functions)

  • obj_dict (CaelusDict) – Input dictionary for this functionObject

  • casedir (path) – Path to the case directory (default: cwd)

property Uinf
property dragDirection
property liftDirection
property maxCp
property minCp
property nAveragingSteps
property outputRegionData
property patches
property pitchAxis
property porosity
property referenceArea
property referenceLength
property rhoInfo
property runOnLastIterOnly
property wheelbase
property writeFields

Caelus Log Analyzer

This module provides utilities to parse and extract information from solver outputs (log files) that can be used to monitor and analyze the convergence of runs. It implements the SolverLog class that can be used to access time histories of residuals for various fields of interest.

Example

>>> logs = SolverLog()
>>> print ("Available fields: ", logs.fields)
>>> ux_residuals = logs.residual("Ux")

The actual extraction of the logs is performed by LogProcessor which uses regular expressions to match lines of interest and convert them into tabular files suitable for loading with numpy.loadtxt or pandas.read_table.

class caelus.post.logs.LogProcessor(logfile, case_dir=None, logs_dir='logs')[source]

Bases: object

Process the log file and extract information for analysis.

This is a low-level utility to parse log files and extract information using regular expressions from the log file. Users should interact with solver output using the SolverLog class.

Parameters:
  • logfile (str) – Name of the Caelus log file

  • casedir (path) – Path to the case directory (default: cwd)

  • logs_dir (path) – Relative path to the directory where logs are written

add_rule(regexp, actions)[source]

Add a user-defined rule for processing

Parameters:
  • regexp (str) – A string that can be compiled into a regexp

  • action (func) – A coroutine that can consume matching patterns

bounding_processor()[source]

Process the bounding lines

completion_processor()[source]

Process End line indicating solver completion

continuity_processor()[source]

Process continuity error lines from log file

convergence_processor()[source]

Process convergence information (steady solvers only)

courant_processor()[source]

Process Courant Number lines

exec_time_processor()[source]

Process execution/clock time lines

exiting_processor()[source]

Process exiting option

extend_rule(line_type, actions)[source]

Extend a pre-defined regexp with extra functions

The default action for LogProcessor is to output processed lines into files. Additional actions on pre-defined lines (e.g., “time”) can be hooked via this method.

Parameters:
  • line_type (str) – Pre-defined line type

  • actions (list) – A list of coroutines that receive the matching lines

fatal_error_processor()[source]

Process CAELUS FATAL ERROR line

residual_processor()[source]

Process a residual line and output data to the relevant file.

time_processor()[source]

Processor for the Time line in log files

watch_file(target=None, wait_time=0.1)[source]

Process a log file for an in-progress run.

This method takes one parameter, target, a coroutine that is called at the end of every timestep. See LogWatcher for an example of using target to plot residuals for monitoring the run.

Parameters:
  • target (coroutine) – A consumer acting on the data

  • wait_time (seconds) – Wait time between checking the log file for updates

bound_files

Open file handles for bounding outputs

case_dir

Absolute path to the case directory

converged

Flag indicating convergence message in logs

converged_time

Timestep when the steady state solver converged

property current_state

Return the current state of the logs processor

failed

Flag indicating whether the solver failed

logfile

User-supplied log file (relative to case directory)

logs_dir

Absolute path to the directory containing processed logs

res_files

Open file handles for the residual outputs

solve_completed

Flag indicating solver completion in logs (if End is found)

subiter_map

(variable, subIteration) pairs tracking the number of predictor subIterations for each flow variable

time

Track the latest time that was processed by the utility

time_str

Time as a string (for output)

class caelus.post.logs.SolverLog(case_dir=None, logs_dir='logs', force_reload=False, logfile=None)[source]

Bases: object

Caelus solver log file interface.

SolverLog extracts information from solver outputs and allows interaction with the log data as numpy.ndarray or pandas.Dataframe objects.

Parameters:
  • case_dir (path) – Absolute path to case directory

  • logs_dir (path) – Path to logs directory relative to case_dir

  • force_reload (bool) – If True, force reread of the log file even if the logs were processed previously.

  • logfile (file) – If force_reload, then log file to process

Raises:

RuntimeError – An error is raised if no logs directory is available and the user has not provided a logfile that can be processed on the fly during initialization.

bounding_var(field)[source]

Return the bounding information for a field

clock_time()[source]

Return the clock time table

continuity_errors()[source]

Return the time history of continuity errors

residual(field, all_cols=False)[source]

Return the residual time-history for a field

Caelus Plotting Utilities

This module provides the capability to plot various quantities of interest using matplotlib through CaelusPlot.

class caelus.post.plots.CaelusPlot(casedir=None, plotdir='results')[source]

Bases: object

Caelus Data Plotting Interface

Currently implemented:
  • Plot residual time history

  • Plot convergence of forces and force coeffcients

Parameters:
  • casedir (path) – Path to the case directory

  • plotdir (path) – Directory where figures are saved

plot_force_coeffs_hist(plotfile=None, dpi=300, **kwargs)

Plot force coefficients

Parameters:

func_object (str) – The function object used in controlDict

plotfile: File to save plot (e.g., residuals.png) dpi: Resolution for saving plots (default=300)

plot_forces_hist(plotfile=None, dpi=300, **kwargs)

Plot forces

Parameters:

func_object (str) – The function object used in controlDict

plotfile: File to save plot (e.g., residuals.png) dpi: Resolution for saving plots (default=300)

plot_residuals_hist(plotfile=None, dpi=300, **kwargs)

Plot time-history of residuals for a Caelus run

Parameters:

fields (list) – Plot residuals only for the fields in this list

plotfile: File to save plot (e.g., residuals.png) dpi: Resolution for saving plots (default=300)

casedir

Path to the case directory

plot_continuity_errors

Flag indicating whether continuity errors are plotted along with residuals

plotdir

Path to plots output directory

solver_log

Instance of SolverLog

class caelus.post.plots.LogWatcher(logfile, case_dir=None)[source]

Bases: object

Real-time log monitoring utility

Parameters:
  • logfile (str) – Name of the Caelus log file

  • casedir (path) – Path to the case directory (default: cwd)

continuity_processor()[source]

Capture continuity errors for plot updates

plot_residuals()[source]

Update plot for residuals

residual_processor()[source]

Capture residuals for plot updates

skip_field(field)[source]

Helper function to determine if field must be processed

time_processor()[source]

Capture time array

plot_fields

List of fields to plot. If None, plots all available fields

skip_fields

List of fields to skip. If None, plots all available fields

time_array

Time array used for plotting data

class caelus.post.plots.PlotsMeta(name, bases, cdict)[source]

Bases: type

Provide interactive and non-interactive versions of plot methods.

This metaclass automatically wraps methods starting with _plot such that these methods can be used in both interactive and non-interactive modes. Non-interactive modes are automatically enabled if the user provides a file name to save the resulting figure.

caelus.post.plots.make_plot_method(func)[source]

Make a wrapper plot method

caelus.post.plots.mpl_settings(backend='agg')[source]

Temporarily switch matplotlib settings for a plot