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
-
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)
-
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)
-
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
, andcsv
formats are supported forsetFormat
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
isxyz
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. Apyvista.Mesh
instance is returned and can be interacted usingvtk.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
¶
-
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
andmoment.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
-
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:
-
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. SeeLogWatcher
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 asnumpy.ndarray
orpandas.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.
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
-
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)
-
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.