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)[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
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 = None

Absolute path to the case directory

data = None

Input dictionary for this function object

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, cdict, **kwargs)[source]

Bases: abc.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, cdict, **kwargs)[source]

Bases: caelus.post.funcobj.funcobj.DictMeta

Specialization for Function objects

class caelus.post.funcobj.funcobj.FunctionObject(name, obj_dict, *, casedir=None)[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.

enabled
executeControl
executeInterval
latest_time

Return the latest time available

libs
log
region
root

Root path to the function object in postProcessing

timeEnd
timeStart
times

Return the list of time directories available

writeControl
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 = None

Input dictionary containing data for this instance

fields

Return the names of fields requested by user

name = None

User-defined name for this sampling instance

parent = None

The parent sets/surfaces group instance

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

Bases: caelus.post.funcobj.sampling.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
axis
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.

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.

points
type
class caelus.post.funcobj.sampling.SampledSets(name, obj_dict, *, casedir=None)[source]

Bases: caelus.post.funcobj.sampling.Sampling

A sets functionObjects entry.

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

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

Bases: caelus.post.funcobj.sampling.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
type
class caelus.post.funcobj.sampling.SampledSurfaces(name, obj_dict, *, casedir=None)[source]

Bases: caelus.post.funcobj.sampling.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.

surfaceFormat
class caelus.post.funcobj.sampling.Sampling(name, obj_dict, *, casedir=None)[source]

Bases: caelus.post.funcobj.funcobj.FunctionObject

Base class for sets and surfaces sampling groups.

keys()[source]

Return the names of the sampling entries

fields
interpolationScheme
samples = None

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(name, obj_dict, *, casedir=None)[source]

Bases: caelus.post.funcobj.funcobj.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)
Aref
dragDir
lRef
liftDir
magUInf
patches
pitchAxis
class caelus.post.funcobj.forces.Forces(name, obj_dict, *, casedir=None)[source]

Bases: caelus.post.funcobj.funcobj.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)

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 = None

Open file handles for bounding outputs

case_dir = None

Absolute path to the case directory

converged = None

Flag indicating convergence message in logs

converged_time = None

Timestep when the steady state solver converged

current_state

Return the current state of the logs processor

failed = None

Flag indicating whether the solver failed

logfile = None

User-supplied log file (relative to case directory)

logs_dir = None

Absolute path to the directory containing processed logs

res_files = None

Open file handles for the residual outputs

solve_completed = None

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

subiter_map = None

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

time = None

Track the latest time that was processed by the utility

time_str = None

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

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 = None

Path to the case directory

plot_continuity_errors = None

Flag indicating whether continuity errors are plotted along with residuals

plotdir = None

Path to plots output directory

solver_log = None

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 = None

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

skip_fields = None

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

time_array = None

Time array used for plotting data

class caelus.post.plots.PlotsMeta[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