This document describes the steps needed to implement a simple body force propeller model in OpenFOAM. Body forces
are a way to represent objects interfering with a fluid without discretizing said object. Consider a body moving in a fluid.
This body will disturb the surrounding fluid by transferring some of its momentum through viscous and normal stresses.
This can be approximated by introducing a forcing term in the Navier-Stokes momentum equation as shown in
Eq. (1). A body force model of the moving object is a formulation for the distribution of
in the fluid; such that the
generated momentum is accurately represented.
![]() | (1) |
In this case, let’s consider the momentum introduced by a rotating propeller. Approximating this using a body force model presents a major advantage in ship performance calculations. Discretizing a complex rotating geometry behind an already complex geometry (ship’s hull + appendages) is both challenging and computationally intensive.
There are many approaches to describing a propeller using a distribution of . For example, the open source self
propulsion framework SHORTCUt has several formulations implemented, based on Blade Element Momentum theory and
Lifting Line/Surface theory. See Windén (2021a,b) for more information. In this report, a very simple model will be
created to demonstrate the principle of how to modify OpenFOAM solvers for this kind of purpose. These are the goals
that will be addressed in the following sections:
First, let’s create a directory where you will keep the source code of the new solver.
Now, let’s get a copy of simleFoam and call it my_simpleFoam. Note the path to the root installation of OpenFOAM; if yours is different then adjust accordingly.
Remove derivative solvers we don’t need.
Finally, before we start modifying the source code, let’s modify the make files. We need to change the name and location of the target executable to avoid overwriting anything.
Next, we need to have the solver create/read the body force field. In createFields.H, add the following just under the
intitialization of .
The boundary conditions of the volumeForce field are defined by adding a file called volumeForce in the 0-directory in any case that is to use the my_simpleFoam solver. The volumeForce file should contain the following:
which sets the boundary condition of to zeroGradient for all boundaries.
my_simpleFoam.C is the source code for the solver. We need to add an expression for the volume force here. Add the following above #include "Ueqn.H"
Also in my_simpleFoam.C, add the following below #include "initContinuityErrs.H"
Finally, we need to add the body force field to the Navier Stokes momentum equation. In Ueqn.H, Add the volume force to the right hand side of the equation, modifying the definition of tmp<fvVectorMatrix> tUEqn as:
In Section 4, initProp.H was added to the simpleFoam source code to initialize the propeller model. Here, we define how the solver should read propeller properties from a dictionary. Let’s define a new dictionary, it should be called propellerDict and be placed in the system-folder of a case where you would like to use my_simpleFoam. In this example, the propeller thrust and torque will be obtained by curve fit to an experimental open water curve. The dictionary therefore contains 5th order polynomial coefficients that describes the relationship between advance ratio and thrust/torque for a MARIN 7967 propeller. The dictionary can be modified with different coefficients to fit any other available open water curves.
propellerDict should contain the following information:
Now we need to set up the solver to read this dictionary. Create a new file called initProp.H in the same directory as my_simpleFoam.C and initialize the propeller model as follows:
Let be the total velocity
at a probe location
, a distance
upstream of the propeller origin
at a radius of
. Also, let the propeller orientation be defined by the propeller disk normal vector
and the
propeller vertical direction be defined by the vector
. Then
![]() | (2) |
and the propeller inflow velocity can be calculated as
![]() | (3) |
From this, an approximate propeller advance ratio can be calculated as
![]() | (4) |
where is the propeller rotation rate and
is the propeller radius. Using a 5th order polynomial fit to
experimental open water curves, the coefficient of thrust
and torque
can be calculated from this advance ratio
as
![]() | (5) |
![]() | (6) |
Here, the propeller origin , the propeller orientation
, the distance to the probe point
, the propeller
radius
, the rotation rate
as well as the 5th order coefficients
and
are all read from the propeller
dictionary at run-time (as shown in the source code for initProp.H) and do not need to be hard-coded into the
solver.
From Eq. (5) and Eq. (6), the total thrust and torque
of the propeller are given as
![]() | (7) |
![]() | (8) |
This methodology yields an approximation of the total forcing to apply. It does not however, model the distribution of
the force on the propeller disk. To do this, and thereby obtaining the distribution of on the Finite
Volume mesh, a Goldstein (1929) optimal distribution can be used. A non-dimensional radius
is defined
as
![]() | (9) |
where is the propeller hub radius and
is a vector from the propeller origin to the cell center of cell I,
projected onto the propeller plane. Two shape functions,
and
, describe the distribution of thrust and torque
respectively along the blade radius. These are defined, based on
, as:
![]() | (10) |
![]() | (11) |
The distribution of on the Finite Volume mesh can be obtained by applying the shape functions
and
to
each cell of the mesh, with
being applied outside of the propeller radius and inside the hub radius. The shape
functions are based on the cell center location from Eq. (9).
Finally, to ensure consistensy with the calculated thrust and torque from Eq. (7) and Eq. (8), the distribution of
is first normalized by the sum of the forces over all cells inside the propeller disk as:
![]() | (12) |
![]() | (13) |
where is the volume of cell
. Finally, the strength of
in cell
, denoted
, is calculated by
multiplying the normalized force distribution by the thrust, torque and the appropriate directional vectors.
![]() | (14) |
This approach is very crude since only one velocity is probed and no consideration is given to the blade geometry
(Goldstein optimum used instead.) This means that the method is unable to detect variations in both the wake and
propeller geometry and therefore, is not suitable for studying propeller-hull interaction. It is provided here only as a simple
example of how a method like this can be implemented. The normalization done in Eq. (14) is consistent with what would
be done for more advanced models where ,
,
and
are calculated from the propeller geometry rather than
a fixed distribution.
In Section 4, forceEqn.H was added to the simpleFoam source code to calculate the distribution of . Create
a new file called forceEqn.H in the same directory as my_simpleFoam.C and calculate the body force as
follows:
After following the steps in the previous sections, to compile the solver run the following command in the my_simpleFoam-directory
After successful compilation, my_simpleFoam is now available as a solver to use in any OpenFOAM case. Bear in mind
that the case must contain the propellerDict dictionary, in the form shown in Section 5 and the boundary conditions,
in the form shown in Section 3 for the solver to work.
This section shows a very simple usage example for the my_simpleFoam solver that was created in the previous sections.
The propeller is modeled inside a cylindrical domain with a uniform inflow speed of . A shaft extends from
the inlet to the propeller position to mimic the setup of a cavitation tunnel. The dimensions of the domain are shown in
Fig. 1. The propeller radius is
and the rotation rate is
giving an advance ratio of
. The
OpenFOAM case used here is attached to this document.
This example serves only to illustrate that the solver serves its purpose of accelerating the flow and does not go into detail regarding the flow-field accuracy with regards to the target propeller. For more advanced propeller models, such an analysis would be necessary to determine their fitness for purpose. Because the inflow velocity in this solver is probed at a single point upstream, it is unsuitable for studying propeller/hull interaction. It would however be possible to use it for limited propeller/rudder interaction studies by placing a rudder downstream.
The pressure distribution on the tunnel center plane is shown in Fig. 2. The pressure jump stemming from the propeller
blades can clearly be seen. Note that the pressure jump is not explicitly modeled or enforced but is a result of the
pressure-velocity coupling and the applied momentum source (, see Eq. (1)). Three-dimensional streamlines are also
shown to illustrate how the flow is rotated at the propeller plane.
The axial velocity on the tunnel center plane is shown in Fig. 3, with a detailed view near the propeller in Fig. 4. Three-dimensional streamlines are shown in these figures to illustrate how the flow is rotated.
Goldstein, S. (1929). On the vortex theory of screw propellers. Proc. R. Soc. Lond., 123.
Windén, B. (2021a). An open-source framework for ship performance cfd. In Proceedings of the 26th SNAME Offshore Symposium.
Windén, B. (2021b). Predicting the powering performance of different vessel types using an open-source cfd propulsion framework. In Proceedings of the SNAME Maritime Convention 2021.