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:
objectMain entry point for accessing OpenFOAM
postProcessingdata.If the function object dictionary is not provided as an argument, the class will attempt to infer the functions activated in
controlDictfile.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.ABCMetaCreate 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_propertiesthat 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.DictMetaSpecialization for Function objects
-
class
caelus.post.funcobj.funcobj.FunctionObject(name, obj_dict, *, casedir=None)[source]¶ Bases:
objectBase 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:
objectBase 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.SampledDataA concrete
setinstance.Currently only
raw,vtk, andcsvformats are supported forsetFormatif 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
axisisxyzthen 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.SamplingA
setsfunctionObjects 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.SampledDataA concrete
surfaceinstance.Currently only
vtkoutput format is supported for reading data. Apyvista.Meshinstance is returned and can be interacted usingvtk.vtkPolyDatamethods.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.SamplingA
surfacesfunctionObjects 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.FunctionObjectThe class retrieves data from
coefficient.datfile 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.FunctionObjectThe class retrives data from
force.datandmoment.datfiles 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:
objectProcess 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
SolverLogclass.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. SeeLogWatcherfor 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:
objectCaelus solver log file interface.
SolverLogextracts information from solver outputs and allows interaction with the log data asnumpy.ndarrayorpandas.Dataframeobjects.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:
objectCaelus 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:
objectReal-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:
typeProvide interactive and non-interactive versions of plot methods.
This metaclass automatically wraps methods starting with
_plotsuch 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.