Enhancing OpenFOAM with InsightCAE
In this section, some feature of InsightCAE for improving OpenFOAM usage will be presented. This section is restricted to a user perspective. The API for developing OpenFOAM-based automation solutions is described in a later section.
Building OpenFOAM Cases
An OpenFOAM case comprises mostly of text files which contain the parameters for all required models. Building the set of text files for a new case from scratch is very laborious task. It is common practice to copy files from other cases, e.g. from the tutorials and to modify them as needed. Since a lot of editing might be required, this might be a cumbersome and error prone workflow. InsightCAE thus provides a tool called Case Builder. The aim of this program is to create a set of configuration files for a new OpenFOAM case from scratch. This includes the configuration of numerics, schemes, physical models and the boundary conditions. The latter is regarded especially useful, because the field files containing the boundary conditions usually require a lot of editing.
The Case Builder exposes some of InsightCAEs internal organization of OpenFOAM support to the user. The supported features are organized in so-called case elements. These might be a certain physical model, a numerics setup or a boundary condition for instance. Case elements are not tied to specific single file but might affect any file in the OpenFOAM case. The idea is to combine them as needed to form an OpenFOAM case.
The Case Builder is started by executing
A screenshot is shown below:
The Case Builder GUI has two tabs: "General" for global case settings and "Boundary Conditions" for assigning boundary conditions to patches.
In the "General" tab, there is a list of all available case elements. They are grouped in categories for finding them easier. To add a case element to the case, simply select it from the list of available case elements on the left and assign it to the case by clicking on the button ">>". For some kinds of case elements, it may make sense to add them multiple times (e.g. the "forces" element which creates a function object for force integration. If forces on multiple sets of patches shall be evaluated, multiple instances of it are needed). Others must not be added more than once to a case (e.g. the "simpleFoamNumerics" element).
Once the case elements are assigned, they need to be configured. Therefore select a case element in the list of assigned case elements on the right. The parameters of the selected element are then displayed in the parameter editor below. The parameters can be selected in the left tree window. Once a parameter is selected, the documentation for it is displayed in the right part of the parameter editor along with the controls for its modification.
After all case elements are configured, there is the possibility to save the configuration to a XML file. Click on "Save config..." saving a configuration file. Vice verse, the case configuration can be loaded from a saved file by clicking on "Load config...".
If the configuration in complete, the case can be created by clicking on "Create...". This will create all the OpenFOAM dictionaries in the working directory, from where the Case Builder was started. If multiple versions of OpenFOAM are installed, the version for which the case shall be created is selected from the drop down box labeled "OF version".
The next step is now to create the mesh. Input file for some simple templates for blockMesh (rectangular box and cylinder) can be created by Case Builder. As well as a configuration file for snappyHexMesh. It is then up to the user to execute the appropriate commands to actually create the mesh. After the mesh is in place, it is the next step to assign the boundary conditions. To do this, restart the Case Builder after the mesh has been created.
Boundary conditions are edited in the tab "Boundary Conditions". An exemplary screenshot is shown below:
On the top left, there is a list of available boundary patches in the mesh. If a mesh is present, the list can be populated by clicking on "Parse boundary file". The file "constant/polyMesh/boundary" is then parsed and the result is displayed in the list. If there no mesh yet, it is also possible to add patch names manually by clicking on "Add patch manually...".
To assign a BC, select the patch in the left list and the desired type in the right list. Then click on "< Assign <". Once a patch has got a type assigned, its parameters can be edited. Just select the patch in the left list and its parameters can be modified in the same way as for the case elements on the previous tab. After configuring all the patches, click on "Create..." again to create the appropriate field dictionaries on disk.
Using the Python Interface
After OpenFOAM cases are created and run successfully, the task is to evaluate the results. It is very common to write Python scripts for this task. Since all OpenFOAM files are text files, it is possible to interface everything on a low level without any additional software. But as some tasks are often reoccurring in the work with OpenFOAM, InsightCAE provides some useful functions through its Python API. In the following, this is explained through some examples. The list of examples is not yet complete and will extended successively.
The example reads the output from a forces function object with name "hullForces" and returns it in a numpy array:
from Insight.toolkit import * tab = forces.readForces(OpenFOAMCase(OFEs.get("OFplus")), ".", "hullForces")
This example extracts a number of circumferentially averaged, radial profiles at different axial locations:
from Insight.toolkit import * import numpy as np xs=[0, 0.1, 0.6, 1.1, 2.1, 3.1, 5.1, 7.1] sets= for xd in xds: ps=circumferentialAveragedUniformLine_defaultParameters() ps.setString("name", "radial-x%01.1f"%xd) ps.setVector("start", [xd,0,0]) # start point of base profile ps.setVector("end", [xd,0.5,0]) # end point of base profile ps.setVector("axis", [1,0,0]) # axis of symmetry ps.setInt("np", 100) # number of points on profile ps.setInt("nc", 10) # number of profiles for circumferential averaging sets.append( circumferentialAveragedUniformLine(ps) ) ofc=OpenFOAMCase(OFEs.get("OFplus")) sample( ofc, ".", # OpenFOAM-plus case in the current directory ["p", "U", "UMean", "UPrime2Mean", "F", "FMean", "FPrime2Mean"], # fields to sample sets ) cd=ColumnDescription() profiles=[np.array(st.readSamples(ofc, ".", cd)) for st in sets]