Optimizing Outputs with OpenFOAM’s writeObjects
Published:
Efficient data handling is a cornerstone of successful computational fluid dynamics simulations, and OpenFOAM provides powerful tools to achieve this. Among them, the writeObjects
function object stands out for its ability to specify different writing frequencies for various objects registered in the simulation database. This capability allows users to tailor output schedules for volume fields and other entities, optimizing disk usage and post-processing workflows. In this blog, we will explore how configuring and utilizing writeObjects can enhance simulation efficiency. Whether you’re optimizing a large-scale simulation or managing limited resources, this guide will help you make the most of OpenFOAM’s functionality.

In computational fluid dynamics, managing simulation data efficiently is as critical as running the simulation itself. OpenFOAM offers a robust feature set to help users optimize their workflows. Among these features, the writeObjects
function object provides a simple yet powerful way to control the writing frequency of various objects registered in the simulation database. Whether you’re working with scalar fields, vector fields, or surface data, this functionality enables you to reduce redundant outputs and streamline post-processing without compromising on the data you need.
In this blog, we’ll explore how the writeObjects
function object works, why it’s an essential tool for any OpenFOAM user, and how to configure it effectively for your simulations. By the end of this article, you’ll have a clear understanding of how to leverage writeObjects
to balance simulation output precision with resource efficiency.
For this tutorial, I will again use the simulation of three-dimensional flow around a square cylinder at Reynolds number of 260. You can find a reference case setup here.
Lets Begin!!!
OpenFOAM Object Registry
Before diving into the writeObjects
function, it’s crucial to understand the OpenFOAM object registry, as this is the source from which we will extract our fields of interest. The objectRegistry serves as a hierarchical database that OpenFOAM uses to organize case-related data. This structured database is maintained by OpenFOAM solvers at various levels:
- Primary Registry: This is the Time object or the
runTime
database, which acts as the root of the objectRegistry. - Second-Tier Database: This level consists of mesh regions and global properties defined in the
controlDict
. - Lower Levels: Sub-objects are registered here, such as individual mesh regions with their respective fvSchemes, fvSolution, mesh data, and fields created in files like createFields.H.
The objectRegistry is built around two main components:
- IOobject: This class standardizes input/output operations and provides access to
runTime
, the root of the objectRegistry. - regIOobject: This class automates the registration and deregistration of objects within the objectRegistry.
By understanding the objectRegistry, we can better grasp how writeObjects interacts with these components to selectively output data from a simulation. For instance, in a standard solver, the objectRegistry might look like this:
* runTime # objectRegistry
|--> controlDict # regIOobject (can't have sub-entries attached to it)
|--> mesh1 # objectRegistry (a database)
|--> points, owner, neighbour, cellZones ...
|--> fvSchemes, fvSolution
|--> U, p
|--> mesh2
|--> points, owner, neighbour, cellZones ...
|--> fvSchemes, fvSolution
|--> U, p
For instance, let’s explore the objectRegistry or check the available objects in the database for a sample simulation. You can do this by running the following command in a terminal where OpenFOAM is sourced:
pimpleFoam -postProcess -func "writeObjects(banana)" -latestTime
In this example, since banana
is not a valid object in the OpenFOAM simulation database, the executable will output a list of available objects that you can choose from. For example, the output in my case looks like this:
writeObjects writeObjects(banana) write:
--> FOAM Warning :
From virtual bool Foam::functionObjects::writeObjects::write()
in file writeObjects/writeObjects.C at line 162
No corresponding selection for (banana)
Available objects in database:
20
(
MRFProperties
U
boundary
cellZones
data
faceZones
faces
fvOptions
fvSchemes
fvSolution
neighbour
nu
owner
p
phi
pointZones
points
solutionControl
transportProperties
turbulenceProperties
)
This approach is a straightforward way to inspect the objectRegistry and identify objects available for post-processing or output customization. The output reveals that there are 20 objects available in my simulation that can be written out. For example, velocity and pressure fields are commonly available for this purpose. Let’s use the same command as before but this time attempt to write the phi
field:
pimpleFoam -postProcess -func "writeObjects(phi)" -latestTime
This command should create a phi
field in your latestTime
folder. If the phi
field already exists in the folder, you can delete it and run the command again to ensure it’s correctly written out. This demonstrates how writeObjects
can be used to selectively output specific fields from the simulation database.
Extracting fields using writeObjects
Imagine a scenario where you are running a simulation on an HPC system with limited storage. To conserve space, you might use the purgeWrite
setting to retain only the last three time steps. However, what if you need full-domain velocity and pressure snapshots from the simulation? This is where the writeObjects
function object becomes incredibly useful.
The writeObjects
function object operates similarly to the writeControl
setting in your controlDict
. It allows you to write out specific fields of interest at a defined frequency. Let’s see how to configure it. Add the following lines of code to the <case>/controlDict/functions
section:
fieldofinterest
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
objects (U p);
writeControl timeStep;
writeInterval 25;
purgeWrite 0;
writeFormat ascii;
writePrecision 8;
writeCompression uncompressed;
timeFormat general;
timePrecision 8;
writeOption autoWrite;
}
This configuration saves velocity (U) and pressure (p) fields every 25 time steps, which is significantly more frequent than the full simulation write interval. This allows you to collect detailed snapshots of the fields while keeping the size of your simulation directory manageable.
For instance, let’s compare the size of two time directories: one containing only the fields of interest and the other with the full simulation data:
du -sh 1996.85/ 1997.05/
## OUTPUT
## 21M 1996.85/
## 67M 1997.05/
The results clearly show that the directory containing only the fields of interest is significantly smaller, demonstrating the effectiveness of the writeObjects
function in managing disk space without sacrificing data granularity.
Extended usage
The writeObjects
function object can be further extended for more advanced use cases. Imagine a scenario where you want to exclude certain variables from being written to files while specifying others to be saved. This is particularly useful in multiphase simulations, where you might deal with multiple fields and want precise control over what gets written.
To achieve this, you can define multiple writeObjects
function objects in your controlDict
, specifying which fields to omit and which to write. Ensure that the controlDict/writeInterval
is set appropriately to control the overall output frequency. For example:
functions
{
writeObjects1
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
objects (rho nut alphat alphaPhi0.water phi T.air T.water);
writeOption noWrite;
}
writeObjects2
{
type writeObjects;
libs ("libutilityFunctionObjects.so");
objects (U p T alpha.water);
writeOption autoWrite;
}
}
In this setup:
- The first function object,
writeObjects1
, excludes fields likerho
,nut
, andalphat
using thenoWrite
option, ensuring they are not written to disk. - The second function object,
writeObjects2
, uses theautoWrite
option for fields such asU
,p
,T
, andalpha.water
, following the output frequency specified incontrolDict/writeInterval
.
This flexibility allows you to optimize both storage usage and post-processing requirements by precisely managing what data is written out during your simulations.