Coupled Motion of Two Floating Objects
Coupled Motion of Two Floating Objects
Project work:
Disclaimer: This is a student project work, done as part of a course where OpenFOAM and some
other OpenSource software are introduced to the students. Any reader should be aware that it
might not be free of errors. Still, it might be useful for someone who would like learn some details
similar to the ones presented in the report and in the accompanying files. The material has gone
through a review process. The role of the reviewer is to go through the tutorial and make sure that
it works, that it is possible to follow, and to some extent correct the writing. The reviewer has no
responsibility for the contents.
February 5, 2016
Learning outcomes
How to add the member data and functions in the sixDoFRigidBodyMotion library
1
Chapter 1
Introduction
The coupling motions of the floating structures are often concerned in the ocean engineering hy-
drodynamics analysis. This project work focuses on the implementation of simulating the motions
of two coupled floating objects. Two main tasks in this project are be completed. The first is to
implement the six-degree-of-freedom (6DOF) motions of two uncoupled floating objects. The other
is to simulate the 6DOF motions of them with a linear spring in between.
The work is performed on the platform of OpenFOAM 2.4.x. The solver interDyMFoam is used
in the two cases. The cases are modified from the floatingObject tutorial. The uncoupled case is
achieved by introducing two floating object patches and using the displacementLaplacian mesh
motion solver. The coupled case is done by developing a new class of couplingLinearSpring re-
straint type based on the existed linearSpring restraint class.
In order to better illustrate these cases, the size of each floating body is slightly reduced com-
pared with the object size in the tutorial floatingObject case. The mass of each object in the
presented cases is decreased to 4kg while the mass is 15kg in the tutorial case. The original dimen-
sion of the object introduced in tutorial case is 0.3m × 0.2m × 0.5m. In this report, the dimension
of each object is shrinked to 0.2m × 0.2m × 0.2m and the distance between the two objects is 0.4m.
The length of the pool is doubled compared with the tutorial case in order to store the two floating
objects. The width and the depth are not changed.
The tutorials and instructions of some other 6DOF single body motion cases with interDyMFoam
and potentialFreeSurfaceDyMFoam can be traced from [1],[2] and [3].
2
Chapter 2
The OpenFOAM 2.4.x has provided a floating object tutorial within the multiphase flow examples.
This case can be modified through the following steps to implement the independent motion of two
floating objects.
2.2 blockMeshDict
Find the blockMeshDict dictionary with the following command.
vi constant/polyMesh/blockMeshDict
The original case uses the box blockMesh with length, width and depth of 1m × 1m × 1m. In this
case, the length of the blockmesh box is extended to 2 meters while the mesh size is not changed.
One more boundary is added for the the additional object. The blockMeshDict is modified as the
following.
vertices
(
(-1 0 0)
(1 0 0)
(1 1 0)
(-1 1 0)
(-1 0 1)
(1 0 1)
(1 1 1)
(-1 1 1)
); // Extend x-dir length
3
2.3. TOPOSETDICT CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
blocks
(
hex (0 1 2 3 4 5 6 7) (40 20 30) simpleGrading(1 1 1)
) // Meshes increases in x-dir
edges
(); // unchanged
boundary
(
.... //stationaryWalls and atmosphere are not changed
//Add one more object
floatingObject1
{
type wall;
faces ();
} //Renamed
floatingObject2
{
type wall;
faces ();
} //Added
);
mergePatchPairs
(); // unchanged
The floating object patches do not contain any of the faces in this blockMesh dictionary because the
topoSet utility will be used to define the patch faces.
2.3 topoSetDict
In OpenFOAM 2.4.x, the topoSet dictionary topoSetDict is used for the selection cells or facets
in simple geometries. The floating box is defined by the boxToCell function. In order to involve
one additional floating box, two toposet dictionaries should be used alternatively. The topoSet
application and subsetMesh application are run twice regarding to the different patches. Here, the
subsetMesh is used to mesh on the selected sub-part done by topoSet. During this process, the
topoSet names, c1 and c2, are replaced with floatingObject1 and floatingObject2. They will become
the names of the patches.
cd $FOAM_RUN/uncoupledFloatingObjects/system
cp topoSetDict object1topoSet
mv topoSetDict object2topoSet
Here, object1topoSet is the topoSet information for floating object 1 and object2topoSet defines
topoSet for floating object2.
4
2.4. DYNAMICMESHDICT
CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
source boxToCell;
sourceInfo
{
box (-0.3 0.4 0.4) (-0.1 0.6 0.6);
} // Redefined
}
{
name c1; //Renamed
type cellSet;
action invert;
}
);
For floating object 2,
actions
(
{
name c2; //Renamed
type cellSet;
action new;
source boxToCell;
sourceInfo
{
box (0.1 0.4 0.4) (0.3 0.6 0.6);
} // Redefined
}
{
name c2; //Renamed
type cellSet;
action invert;
}
);
Thus, the floating object 1 is located in negative x-direction and the floating object 2 is located in
positive x-direction. The following commands can visulize the location of the two floating objects
and the mesh sets, as shown in Figure 2.1.
cd $FOAM_RUN/uncoupledFloatingObjects/
blockMesh
topoSet -dict system/object1topoSet
subsetMesh -overwrite c1 -patch floatingObject1
topoSet -dict system/object2topoSet
subsetMesh -overwrite c2 -patch floatingObject2
paraFoam
This process can also be done automatically by modifying an Allrun file.
2.4 dynamicMeshDict
The dynamicMeshDict file is the dictionary that defines the dynamic mesh solver along with the
libraries and coefficients to be used. It can be read by the following command.
cd $FOAM_RUN/uncoupledFloatingObjects/constant
vi dynamicMeshDict
5
2.4. DYNAMICMESHDICT
CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
The tutorial case applies the sixDoFRigidBodyMotion solver to solver single object motion. The
dynamicMeshDict also contains the sixDoFRigidBodyMotionCoeffs including the centre of mass,
mass, moment of inertia and constraints. In the tutorial, the CodeStream is applied to calculate
mass and moment of inertia.
The parameters innerDistance and outerDistance are the point distances away from the object
patches. These are used to calculate the scaling factor in the field where the scaling is 1 up to the
inner distance and decreasing linearly to 0 at the outer distance. The definitions can be found in
sixDoFRigidBodyMotionSolver.C with the following command.
vi $FOAM_SRC/sixDoFRigidBodyMotion/sixDoFRigidBodyMotionSolver\
/sixDoFRigidBodyMotionSolver.C
However, the sixDoFRigidBodyMotion does not support the multi-body motion. The following code
shows the mechanism of point displacement update in sixDoFRigidBodyMotionSolver.C.
// Update the displacements
pointDisplacement_.internalField() =
motion_.transform(points0(), scale_) - points0();
In this way, the point displacement in the field is changed only based on the coordinate transforma-
tion of one rigid system. Instead, the displacement Laplacian motion solver can be used to simulate
the multi and independent floating object motions. The displacementLaplacianFvMotionSolver
is a dynamic mesh motion solver which solves the Laplace’s equation for cell displacement. The code
of this fvMotionSolver can be read with the commands as below.
vi $FOAM_SRC/fvMotionSolver/fvMotionSolvers/displacement/\
laplacian/displacementLaplacianFvMotionSolver.C
The following code is the core of the mesh motion solver.
void Foam::displacementLaplacianFvMotionSolver::solve()
{
// The points have moved so before interpolation update
// the motionSolver accordingly
movePoints(fvMesh_.points());
diffusivity().correct();
pointDisplacement_.boundaryField().updateCoeffs();
Foam::solve
6
2.4. DYNAMICMESHDICT
CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
(
fvm::laplacian
(
diffusivity().operator()(),
cellDisplacement_,
"laplacian(diffusivity,cellDisplacement)"
)
);
}
It can be seen that the mesh motion is not limited on one object patch. But the diffusivity is the a
key factor to determine the cell displacement. The available diffusivity models are
directional
exponential
file
inverseDistance
inverseFaceDistance
inversePointDistance
inverseVolume
motionDirectional
quadratic
uniform
Here in this report, the inverseDistance diffusivity model is adopted. According to [4] and [5],
the inverseDistance model calculates the diffusivity of the internal field based on the inverse
of the distance from the boundary. The user can specify one or more boundaries in this step.
Thus, the two floating objects boundaries are chosen in this case to calculate the diffusivity for the
displacementLaplacian solver.
Since the sixDoFRigidBodyMotion library is compiled separately in version 2.4.x and the fvMotionSolver
doesn’t include this library to compute 6DOF body motion, it is necessary to add both the libfvMotionSolvers
and libsixDoFRigidBodyMotion to motionSolverLibs.
More alternatives in mesh motion solvers can be traced from Andreu[4].
Turn to the dynamicMeshDict again.
cd $FOAM_RUN/uncoupledFloatingObjects/constant
vi dynamicMeshDict
The dynamicMeshDict is written as the following lines.
dynamicFvMesh dynamicMotionSolverFvMesh; //Changed
motionSolverLibs
(
"libsixDoFRigidBodyMotion.so"
"libfvMotionSolvers.so" //Added
);
solver displacementLaplacian; //Changed
displacementLaplacianCoeffs
{
diffusivity inverseDistance (floatingObject1 floatingObject2);
} //Changed
//end of file
7
2.5. 0.ORG DIRECTORY
CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
The first sed command change the patch name floatingObject to floatingObject1. Then the
following sed commands copy the corresponding lines in each file and paste to the right positions. For
example, the 34-37th line in alpha.water file is copied and pasted after the 37th line. Since now there
are two floatingObject1 in each file, the last sed command change the second floatingObject1
to floatingObject2. Take the k file as an example, after running the commands, the boundary
conditions for the floating object patches look as
2.6 pointDisplacement
In order to use the displacementLaplacian mesh motion solver, an initial pointDisplacement shall
be defined along with the object patch movement rules. Get access to this file by
cd $FOAM_RUN/uncoupledFloatingObjects/0.org
vi 0.org/pointDisplacement
The floating object boundary field is defined as a calculated type. This is a primitive type which
means the boundary field is derived from the other fields. As the sixDoFRigidBodyMotionSolver
is not used in dynamicMeshDict, the derived 6DOF motion boundary conditions should be used in
the modified case. Here, the sixDoFRigidBodyDisplacement type is used for the floating objects,
which will align the point patch on boundary according to the sixDoFRigidBodyMotion algorithm.
The source files of this derived point patch boundary type can be reached by typing
vi $FOAM_SRC/sixDoFRigidBodyMotion/pointPatchFields/derived/\
sixDoFRigidBodyDisplacement/sixDoFRigidBodyDisplacementPointPatchVectorField.C
8
2.6. POINTDISPLACEMENT
CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
To apply this sixDoFRigidBodyMotion type, the mass, moment of inertia, center of mass, constraints
and restraints properties of the floating objects should be defined. The constraints limit some degrees
of freedom of motion, such as limiting rotation around points and limiting motion on specific axis
or plane. The restraints do not limit the degree of freedom of the body motion, but will impose a
restraint force to limit the motion amplitude or velocity. In this case, only the constraint of rotation
around a fixed point is applied. Open 0.org/pointDisplacement file and modify it as below.
//Do not change dimensions and internalField
dimensions [0 1 0 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
//Do not change stationaryWalls and atmosphere
stationaryWalls
{
type fixedValue;
value uniform (0 0 0);
}
atmosphere
{
type fixedValue;
value uniform (0 0 0);
}
// Remove the floatingObject patch and copy-paste the following lines
floatingObject1
{
type sixDoFRigidBodyDisplacement; //derived type
mass 4;
centreOfMass (-0.2 0.5 0.43);
momentOfInertia (0.0255 0.0255 0.0255);
rhoName rhoInf;
rhoInf 1;
report on;
value uniform (0 0 0);
constraints
{
fixedpoint1
{
sixDoFRigidBodyMotionConstraint point;
centreOfRotation (-0.2 0.5 0.43);
}
} //Fixed point constraint
}
floatingObject2
{
type sixDoFRigidBodyDisplacement; //derived type
mass 4;
centreOfMass (0.2 0.5 0.43);
momentOfInertia (0.0255 0.0255 0.0255);
rhoName rhoInf;
rhoInf 1;
report on;
value uniform (0 0 0);
constraints
{
9
2.7. FVSOLUTION CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
fixedpoint2
{
sixDoFRigidBodyMotionConstraint point;
centreOfRotation (0.2 0.5 0.43);
}
} //Fixed point constraint
}
}
2.7 fvSolution
The fvSolution file defines the specification of the linear equation solvers and tolerances and other
algorithm controls. Get access to this file by
vi $FOAM_RUN/uncoupledFloatingObjects/system/fvSolution
Since the cellDisplacement is to be calculated during the iteration, in the fvSolution file, the
solver for the cellDisplacement is added with the following lines.
solvers
{
// Add this before "alpha.water.*"
"cellDisplacement.*"
{
solver GAMG;
tolerance 1e-8;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration true;
nCellInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
}
"alpha.water.*"
// The following part is not changed
}
2.8 setFieldsDict
The setFieldsDict is used to define the configuration of setFields utility. In this case, the
setFields sets the initial field information about the distribution of water and air. Use the follow-
ing command to have a look at this dictionary.
vi $FOAM_RUN/uncoupledFloatingObjects/system/setFieldsDict
defaultFieldValues
(
volScalarFieldValue alpha.water 0
);
regions
(
boxToCell
{
box ( -100 -100 -100 ) ( 100 100 0.5 );
fieldValues ( volScalarFieldValue alpha.water 1 );
}
10
2.9. ALLRUN CHAPTER 2. UNCOUPLED MOTION OF TWO FLOATING OBJECTS
boxToCell
{
box ( 0.9 0 -100 ) ( 100 100 0.6 ); //This part is changed
fieldValues ( volScalarFieldValue alpha.water 1 );
}
);
// ************************************************************************* //
The first boxToCell command sets the water depth to 0.5m. The second boxToCell command sets
a dambreak water volume at one side of the tank with water height of 0.6m.
2.9 Allrun
As two topoSet dictionaries, the topoSet and subsetMesh utilities are used twice. Here two forms
of running applications are shown, one is with ”runApplication” in front, the other is without. If
the runApplication is used in Allrun file, it is necessary to remove the log-file before executing,
otherwise the system will complain about this. Edit the Allrun by substituting the lines after
application=`getApplication`. with the following words.
runApplication blockMesh
#run toposet for object1
#use runApplication
runApplication topoSet -dict system/object1topoSet
runApplication subsetMesh -overwrite c1 -patch floatingObject1
#Cleaning logs when runApplication is used
rm log.topoSet
rm log.subsetMesh
#run toposet for object2
#without runApplication
topoSet -dict system/object2topoSet
runApplication subsetMesh -overwrite c2 -patch floatingObject2
cp -r 0.org 0 > /dev/null 2>&1
runApplication setFields
runApplication $application
11
Chapter 3
12
3.2. START A NEW LIBRARY
CHAPTER
AND3.A NEW
COUPLED
CLASS
MOTION OF TWO FLOATING OBJECTS
modify on the basis of existed restraint types in OpenFOAM, the new classes have to be invented.
This report will focus on the how to modify a linearSpring class to support the multi-body motion
with the linear spring connection in between.
All the restraints classes in OpenFOAM-2.4.x can be traced with the following command.
cd $FOAM_SRC/sixDoFRigidBodyMotion/sixDoFRigidBodyMotion/restraints
The linearSpring directory contains the source file of the linear spring connection type. The
restraints force are calculated with the following lines.
r = restraintPosition - anchor_;
magR = mag(r);
r /= (magR + VSMALL);
restraintForce = -stiffness_*(magR-restLength_)*r-damping_*(r & v)*r;
The force induced by stiffness is related to the stretched length of the spring while the damping
force is related to the velocity of the object. The two member data stiffness_ and damping in
the linearSpring class are scalars. The stationary anchor position (anchor_) and the attachment
point on object (refAttachmentPt_) are two point member data. The scalar restLength_ member
data is the equilibrium length of the spring. The referenced attachment point refAttachmentPt
will be transformed to global coordinate system as a restrainPosition in every loop according to
the position of the floating body.
To couple the two objects together, the anchor point of one object is updated in every loop. This
point is the same as the restrainPosition from the other object. Hence, the information is to be
exchanged between the patches. This is the key point of solving this problem.
13
3.3. IDENTIFICATION OF
CHAPTER
THE OBJECTS
3. COUPLED MOTION OF TWO FLOATING OBJECTS
rm -r linear*
rm -r spher*
rm -r t*
Use the following command to get access to the Make/files file.
cd $WM_PROJECT_USER_DIR/src/mysixDoFRigidBodyMotion
vi Make/files
In the files file, remove the unnecessary restraints classes source file and add the new class to
file list. Then set the library to user’s directory. Note that only the restraints part and the library
path is changed, the rest of the file is not changed.
restraints = sixDoFRigidBodyMotion/restraints
$(restraints)/sixDoFRigidBodyMotionRestraint/sixDoFRigidBodyMotionRestraint.C
$(restraints)/sixDoFRigidBodyMotionRestraint/sixDoFRigidBodyMotionRestraintNew.C
$(restraints)/couplingLinearSpring/couplingLinearSpring.C
LIB = $(FOAM_USER_LIBBIN)/libmysixDoFRigidBodyMotion
Then use wclean to prepare for further steps.
3.3.1 sixDoFRigidBodyMotion.H
The modification can be started with sixDoFRigidBodyMotion.H. Use the following line to find this
file.
cd $WM_PROJECT_USER_DIR/src/mysixDoFRigidBodyMotion/sixDoFRigidBodyMotion
vi sixDoFRigidBodyMotion.H
Modify the private data with adding the two names.
class sixDoFRigidBodyMotion
{
// Private data
....
Switch report_; // All private data to this line are not changed
// Add the two data after Switch report_;
//- Name of the rigid body
word rigidBodyName_;
14
3.3. IDENTIFICATION OF
CHAPTER
THE OBJECTS
3. COUPLED MOTION OF TWO FLOATING OBJECTS
....
inline bool report() const; //All lines to here are not changed
// Add the following lines here
//- Return the Name
inline word rigidBodyName() const;
3.3.2 sixDoFRigidBodyMotionI.H
Go to sixDoFRigidBodyMotionI.H with
cd $WM_PROJECT_USER_DIR/src/mysixDoFRigidBodyMotion/sixDoFRigidBodyMotion
vi sixDoFRigidBodyMotionI.H
and add the information of the body names.
....
// * * * * * * * * * Member Functions * * * * * * * * * //
// It is possible to put following two inline functions everywhere in the list
// In this report, they are put in the beginning of the member function list
inline Foam::word Foam::sixDoFRigidBodyMotion::rigidBodyName() const
{
return rigidBodyName_;
}
3.3.3 sixDoFRigidBodyMotion.C
Type vi sixDoFRigidBodyMtion.C to modify the sixDoFRigidBodyMotion.C file. The constructors
of sixDoFRigidBodyMotion.C should contain the the attributives of the body names.
// * * * * * * * * * * Constructors * * * * * * * * * //
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion()
:
....
report_(false), // All lines to here are not changed
rigidBodyName_(), //Added
coupledBodyName_() //Added
{}
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion
(
const dictionary& dict,
const dictionary& stateDict
)
:
....
report_(dict.lookupOrDefault<Switch>("report", false)),
// All lines to here are not changed
15
3.4. COUPLINGLINEARSPRING
CHAPTERCLASS
3. COUPLED MOTION OF TWO FLOATING OBJECTS
rigidBodyName_(dict.lookupOrDefault<word>("rigidBodyName","rigidbody1")), //Added
coupledBodyName_(dict.lookupOrDefault<word>("coupledBodyName","None")) //Added
{
// Contents in this pair of braces are not changed
}
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion
(
const sixDoFRigidBodyMotion& sDoFRBM
)
:
....
report_(sDoFRBM.report_), //All lines to here are not changed
rigidBodyName_(sDoFRBM.rigidBodyName_), //Added
coupledBodyName_(sDoFRBM.coupledBodyName_) //Added
{}
The status() member function of the sixDoFRigidBodyMotion class requires a small update to
output the rigidBodyName. This helps to identify the rigid body information in the log files.
void Foam::sixDoFRigidBodyMotion::status() const
{
// Add the name of the rigid body
Info<< "6-DoF rigid body motion" << nl
<< " Name of rigid body: " << rigidBodyName() << nl
<< " Centre of rotation: " << centreOfRotation() << nl
<< " Centre of mass: " << centreOfMass() << nl
<< " Orientation: " << orientation() << nl
<< " Linear velocity: " << v() << nl
<< " Angular velocity: " << omega()
<< endl;
}
3.3.4 sixDoFRigidBodyMotionIO.C
The coupling information shall be added to the write() function of sixDoFRigidBodyMotionIO.C
to enable the refreshing of dictionaries in each time loop. Use vi sixDoFRigidBodyMotionIO.C to
edit the file.
void Foam::sixDoFRigidBodyMotion::write(Ostream& os) const
{ motionState_.write(os);
// Add the following lines after here
os.writeKeyword("rigidBodyName")
<< rigidBodyName_ << token::END_STATEMENT << nl;
os.writeKeyword("coupledBodyName")
<< coupledBodyName_ << token::END_STATEMENT << nl;
// The rest part are not changed
16
3.4. COUPLINGLINEARSPRING
CHAPTERCLASS
3. COUPLED MOTION OF TWO FLOATING OBJECTS
For this case, the anchor of the first object comes from the restraint position of the second object,
the restraint position of the first object will become the anchor of the second object. The data needs
to be exchanged between the two patches. The OFstream and IFstream can be applied to solve the
problem.
It should be noted that, OFstream and IFstream is not the best way to solve the problem. There
should be ways to exchange information between patches in the dictionary file of restraints. Due
to the limited couse time, the OFstream and IFstream is only an alternative. There are many
limitations regarding to this method.
3.4.2 couplingLinearSpring.C
Turn to the pre-established class couplingLinearSpring.C by command
cd $WM_PROJECT_USER_DIR/src/mysixDoFRigidBodyMotion\
/sixDoFRigidBodyMotion/restraints/couplingLinearSpring
vi couplingLinearSpring.C
Some Foam classes and standard classes should be included at the header.
17
3.4. COUPLINGLINEARSPRING
CHAPTERCLASS
3. COUPLED MOTION OF TWO FLOATING OBJECTS
\*---------------------------------------*/
// The other included files are not changed
// Add the following files which are to be included
// Foam classes
#include "OFstream.H"
#include "IFstream.H"
#include "Vector.H"
// std classes
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <string.h>
#include <stdlib.h>
In the restrain() member function, add the following lines before restraintPosition=motion.transform(refAttachment
void Foam::sixDoFRigidBodyMotionRestraints::couplingLinearSpring::restrain
(
// parameters are not changed inside this pair of parentheses
)
(
//Add the following lines from here
OFstream restrainPositionOutputX(motion.rigidBodyName()+"X");
OFstream restrainPositionOutputY(motion.rigidBodyName()+"Y");
OFstream restrainPositionOutputZ(motion.rigidBodyName()+"Z");
IFstream AnchorInputX(motion.coupledBodyName()+"X");
IFstream AnchorInputY(motion.coupledBodyName()+"Y");
IFstream AnchorInputZ(motion.coupledBodyName()+"Z");
double AX,AY,AZ;
char temp[100];
AnchorInputX.stdStream().getline(temp, 100);
AX=(double)strtod(temp,NULL);
AnchorInputY.stdStream().getline(temp, 100);
AY=(double)strtod(temp,NULL);
AnchorInputZ.stdStream().getline(temp, 100);
AZ=(double)strtod(temp,NULL);
After restraintMoment = vector::zero; where the restraint force computation is finished, the
three components of restraint position are outputted to the restrainPositionOutput* files. In
the motion report, the anchor position information can be written to check whether the anchor is
moving.
restraintMoment=vector::zero //not changed
//Add the following lines
restrainPositionOutputX << restraintPosition.x()<< nl
<< endl;
restrainPositionOutputY << restraintPosition.y()<< nl
<< endl;
restrainPositionOutputZ << restraintPosition.z()<< nl
18
3.5. COMPILE THE NEW
CHAPTER
CLASS 3. COUPLED MOTION OF TWO FLOATING OBJECTS
<< endl;
// Small modification to this if command
if (motion.report())
{
Info << " attachmentPt-anchor " << r*magR
<< " spring length " << magR
<< " force" << restraintForce
<< endl; // not changed
Info << " anchor position" << anchor_ << endl; //Added
}
} // end of the restrain function
The anchor position information can be checked by using
Info<< " anchor position " << anchor_<< endl;
The idea behind using three files to store the restraint position is to avoid complex data conversion
behind. The point type, which is derived from a vector type, can be easily exported, but difficult
to built when reading with a string type. The common way to construct a vector type is to assemble
the three elements from standard types such as float and double or from Foam scalar type. The
strtod function is used to get a float number from a string.
When read the anchor data, the AnchorInput* files will find information given by the coupled
body of the patch. Thus, the values which are imported from sDoFRBMRCoeffs_ dictionary will be
overwritten with the outside anchor information.
19
3.6. RUN THE CASE CHAPTER 3. COUPLED MOTION OF TWO FLOATING OBJECTS
20
3.6. RUN THE CASE CHAPTER 3. COUPLED MOTION OF TWO FLOATING OBJECTS
21
Chapter 4
Figure 4.1: Uncoupled case t=0s Figure 4.2: Uncoupled case t=0.5s
Figure 4.3: Uncoupled case t=1.0s Figure 4.4: Uncoupled case t=1.5s
22
4.2. COUPLED CASE CHAPTER 4. RESULTS AND DISCUSSION
Figure 4.5: Coupled case t=0s Figure 4.6: Coupled case t=0.5s
Figure 4.7: Coupled case t=1.0s Figure 4.8: Coupled case t=1.5s
Compared with the uncoupled case at t=1.0s and 1.5s, it can be seen that the restraints limits the
motion amplitude. Take a look at the log file of interDyMFoam, the anchor information is changed
during the iterations.
23
4.3. SUGGESTIONS FOR BALANCING SPRINGCHAPTER
FORCE 4. RESULTS AND DISCUSSION
Another factor which may cause the unbalanced force is the damping. Since the modification in
this report does not include the input/output of the velocity information, the damping force part
will be definitely different from each object. It is suggested to use damping factor as 0.
Howeve, if it is assumed that the spring force is slowly varying and this force is approximately
equal in current and previous time steps, it is possible to calculate apply the restrain force from last
time step. Since the motion transformation in last time step will never change in current time and
current PIMPLE loop, the spring force can be balanced for each object. Under this assumption,
the time step should be relatively very small if the stiffness of the spring is high, since high stiffness
means high frequency and short period.
24
4.3. SUGGESTIONS FOR BALANCING SPRINGCHAPTER
FORCE 4. RESULTS AND DISCUSSION
//- Transform the given initial state point by the current motion
// state
inline point transform(const point& initialPoints) const;
Then, use vi sixDoFRigidBodyMotionI.H to define the inline function transform0 at the end
of the file.
inline Foam::point Foam::sixDoFRigidBodyMotion::transform
(
const point& initialPoint
) const
{
return
(
centreOfRotation()
+ (Q() & initialQ_.T() & (initialPoint - initialCentreOfRotation_))
);
}
// This tranform function is not changed
// Add the following code here
inline Foam::point Foam::sixDoFRigidBodyMotion::transform0
(
const point& initialPoint
) const
{
return
(
centreOfRotation()
+ (Q0() & initialQ_.T() & (initialPoint - initialCentreOfRotation_))
);
}
// ************************************************************************* //
Where the Q0() is the orientation in previous time step. Then recompile the library by
cd $WM_PROJECT_USER_DIR/src/mysixDoFRigidBodyMotion
wclean libso
wmake libso
25
4.4. DISCUSSION AND FUTURE WORK CHAPTER 4. RESULTS AND DISCUSSION
First, since IFstream function is very limited, it is more suitable to use dictionary input and output
system in OpenFOAM. This will make the data exchange more reliable and fast. The discrepencies
between the restraint forces for coupling objects case can also be avoided if the dictionary I/O is
adopted.
Second, the method can be extended to more floating objects linked by multiple restraints. This
requires that the system is able to identify more linked body names and different restraints between
each other.
26
4.4. DISCUSSION AND FUTURE WORK CHAPTER 4. RESULTS AND DISCUSSION
Third, the restraints are defined with a sub dictionary method which limits the restraints only
belonging to one body. If more objects are linked, the more appropriate way is to share one re-
straints between the objects. Thus, the restraints dictionary should have the same level with the
patch dictionary. But some more modifications of adding restraints member function need to be
done.
27
References
[1] Erik Ekedahl, 6-DOF VOF-solver without Damping in OpenFOAM, PhD course in CFD with
OpenSource software, 2009
[2] Johannes Palm, Connecting OpenFOAM with MATLAB, PhD course in CFD with OpenSource
software, 2012
[3] Guilherme Moura Paredes, Application of dynamic meshes to potentialFreeSurfaceFoam to solve
for 6DOF floating body motions, PhD course in CFD with OpenSource software, 2012.
[4] Andreu Oliver González, Mesh motion alternatives in OpenFOAM, PhD course in CFD with
OpenSource software, 2009.
[5] Hrvoje Jasak and Henrik Rusche, Dynamic Mesh Handling in OpenFOAM, Advanced Training
at the OpenFOAM Workshop, 2010.
http://web.student.chalmers.se/groups/ofw5/Advanced Training/DynamicMesh.pdf
[6] http://www.cplusplus.com/reference/istream/istream/
28
Study questions
4. Why are the hinged and catenary connection types harder to develop?
5. Why is it difficult to exchange restraint information in between two patches?
6. When running the coupled case, why does the result diverge when the stiffness is high?
7. In the coupled case, why are there three output files for one object, eg. floatingObject1X,
floatingObject1Y, floatingObject1Z? Why not use one file?
29