[Thesis]on MpCCI as a Coupling Library for FSI With CFX
Transcript of [Thesis]on MpCCI as a Coupling Library for FSI With CFX
Lehrstuhl fur Bauinformatik
Technische Universitat Munchen
Master Thesis
On MpCCI as a coupling library for
Fluid-Structure Interaction with CFX
Ozgur Gurses∗
Matr. Nr.: 2628532
Supervisior: Dipl.-Ing. S. Kollmannsberger
Acknowledgements
I would like wholeheartedly and genuinely thank to Univ. Prof. Dr. K.Uwe Blet-
zinger and Prof.Dr.rer.nat.Ernst Rank for their guidance and kindness throughout
this work. Their patience as advisors, their limitless energy while teaching and pas-
sion kept in deep for research are to be commended.
I am indebt to Dipl-Ing. S. Kollmannsberger for enhancing my knowledge by his
questions and rationalistic advices despite his busy schedule.
A special thank goes to the staff of Lehrstuhle fur Statik und Bauinformatik which
helped me to enter the exciting harmony of computations and computers.
I would like to thank all those friends who have gave me their support during the
completion of this work.
Most importantly, I would like to thank my family for their boundless support and
love. Their encouragement makes everything easier to achieve.
i
ii
Abstract
On MPCCI as a coupling library for Fluid-Structure Interaction with CFX
One major simplification made when calculating physical behaviour is to take one
field into account. While this may often be sufficient, some engineering problems
require to consider two or more fields. For a flexible structure submerged in a fluid,
the interaction of the fluid with the structure may be the driving mechanism char-
acterising its behaviour. For the individual disciplines sophisticated solvers exists.
Different solution methods for various flow problems have been developed. Various
numerical methods and code implementations have been used to increase the quality
of the results.
In order to find a common basis of comparison, a set of benchmark problems have
been defined. In view of the results of previous numerical tests a commercial robust
fluid solver ANSYS-CFX was chosen. MpCCI is a communication library to which
ANSYS-CFX provides an interface. Goal of this thesis was to assess this interface such
that a structural solver could be connected to this interface. Therefore, the major
steps had to be followed. First to assess the fluid solver by calculating a cylinder
submerged in a fluid benchmark. Second to write a dummy structural code providing
an interface to MpCCI and finally to couple the both codes such that an algorithmic
coupling was possible.
iii
Contents
List of Figures vi
1. Introduction 1
1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3. Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Definition of the Test Cases 3
2.1. Test Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2. Test Case 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.1. Geometry and Boundary Conditions . . . . . . . . . . . . . . 3
2.2.2. Computational Grid . . . . . . . . . . . . . . . . . . . . . . . 5
2.3. Test Case 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3.1. Geometry and Boundary Conditions . . . . . . . . . . . . . . 8
2.3.2. Computational Grid . . . . . . . . . . . . . . . . . . . . . . . 8
2.4. Mesh Quality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.1. Determinant . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4.2. Warpage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4.3. Angle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5. Error Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5.1. Modelling Error . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5.2. Iteration Error . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5.3. Discretisation Error . . . . . . . . . . . . . . . . . . . . . . . . 11
iv
Contents
3. MpCCI 12
3.1. Coupling Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2. MpCCI:Mesh-Based Parallel Code Coupling Interface . . . . . . . . . 12
3.3. MpCCI Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3.1. Naming Conventions and Descriptions . . . . . . . . . . . . . 15
3.3.2. Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3.3. Coupling Definition . . . . . . . . . . . . . . . . . . . . . . . . 16
3.4. MpCCI Input File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.4.1. Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4. Moving Boundaries 30
4.1. Outline of achieveing a Bi-Directional coupling via MpCCI . . . . . . 30
4.1.1. AdhoC Dummy Code . . . . . . . . . . . . . . . . . . . . . . 30
4.1.2. Implementation of MpCCI on a written Dummy Structure Code
and CFX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.1.3. CFX Expression Language (CEL) . . . . . . . . . . . . . . . . 33
4.1.4. Monitor Points . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5. Discussion of the Results 36
5.1. Discussion of the Results of the Test Case 1 . . . . . . . . . . . . . . 36
5.1.1. Comparision of Coarse Meshes . . . . . . . . . . . . . . . . . . 37
5.2. Discussion of the Results of the Test Case 2 . . . . . . . . . . . . . . 38
5.2.1. Effect of Velocity Change . . . . . . . . . . . . . . . . . . . . 38
5.2.2. Effect of Grid Type . . . . . . . . . . . . . . . . . . . . . . . . 38
6. Concluding Remarks and Recommendations 53
References 54
A. THE DUMMY CODE 55
B. PYTHON SCRIPT 76
v
List of Figures
2.1. Dimensions of the Test Case 1 . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Hexahedral mesh. An example of a structured mesh. . . . . . . . . . 5
2.3. Hexahedral mesh detail around the cylinder. . . . . . . . . . . . . . . 5
2.4. Coarse mesh with prismatic elements. An example of an unstructured
mesh. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5. Fine mesh. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6. Very fine mesh. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.7. Optimal mesh. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.8. Dimensions of the Test Case 2 . . . . . . . . . . . . . . . . . . . . . . 8
3.1. Coupling Scheme [1] . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.1. Parts of Adhoc Dummy . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1. lift and drag forces [0-20 s.] (Test Case 1) . . . . . . . . . . . . . . . 40
5.2. lift and drag forces [0-5 s.] (Test Case 1) . . . . . . . . . . . . . . . . 41
5.3. lift and drag forces [10-15 s.] (Test Case 1) . . . . . . . . . . . . . . . 42
5.4. Comparision of coarse meshes that have different thickness [0-20 s.]
(Test Case 1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.5. Comparision of coarse meshes that have different thickness [0-5 s.]
(Test Case 1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.6. Comparision of coarse meshes that have different thickness [10-15 s.]
(Test Case 1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.7. Values for lift and drag forces. The results shown are calculated for
the last 5 seconds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
vi
LIST OF FIGURES
5.8. lift and drag forces around the cylinder and flag (CFD1,M1 ) . . . . . 46
5.9. lift and drag forces around the cylinder and flag (CFD2,M1 ) . . . . . 47
5.10. lift and drag forces around the cylinder and flag (CFD2,M2 ) . . . . . 48
5.11. lift and drag forces around the cylinder and flag (CFD2,M3 ) . . . . . 49
5.12. lift and drag forces around the cylinder and flag (CFD3,M1 ) . . . . . 50
5.13. lift and drag forces around the cylinder and flag (CFD3,M2 ) . . . . . 51
5.14. lift and drag forces around the cylinder and flag (CFD3,M3 ) . . . . . 52
vii
1. Introduction
1.1. Motivation
The Finite Element Method (FEM) is a widely used technique to solve all sorts of
differential equations. It is an approximation method for engineering problems which
usually cannot be solved analytically.
There are different FE implementations each adjusted to the discipline and degree
of complexity of the problems. Generally, major FE-based analysis codes have spe-
cialized in and restricted themselves to a single analysis discipline like, structural,
fluid, thermal etc. However, scientists and engineers are sometimes interested in
handling problems concerning the interaction of these fields. These multidisciplinary
approaches are known as coupled problems and require significant effort to be solved.
There are two ways to solve a coupled problem.
� Internally Coupled Analysis- coupling through internal data structures. (MSC.Dytran,
ADINA)
� Externally Coupled Analysis- coupled through boundary data exchanged be-
tween separate solvers. (MpCCI -coupling library) [8]
Internal coupling provides better compatibility between the exchanging variables
and values of the participating disciplines. External coupling provides the combina-
tion of the powerful solvers.
1.2. Objectives
This thesis emerges from a research project worked on at the Chair of Bauinformatik
at the Technical University of Munich. The primary objective of this thesis is to
1
1. Introduction
perform a series of numerical simulations and to check the suitability of ANSYS-CFX
with MpCCI library by means of coupling with a self written dummy code [7]. Besides,
as a major task, in order to reduce computational costs while being economical in
terms of calculation time, optimal mesh studies were performed. Structured and
unstructured meshes were constructed with ICEM-CFD and Domesh, respectively.
The results obtained were compared.
The name of the communication library MpCCI drifts the readers into the expec-
tation of that a speed-up of an analysis by a parallel computation research is a part
of work. Although it would be an interesting task for a future study, this research
does not attempt to perform parallel computations. Furthermore, it is an application-
based study. Hence, presentation of theoretical knowledge or formulations is out of
scope.
1.3. Outline
In Chapter 2, definitions of the study cases are given. Some comments about the
grids formation and their quality checks as well as an outlook over error analysis can
also be found here.
Chapter 3 describes in detail the parts of the required MpCCI input file. Besides,
definitions of the basic functions that are used in coupling are given.
Moving boundary concept is studied in detail in Chapter 4.
Chapter 5 is dedicated to the discussion of the results. Several graphical and
tabulated results are presented.
Finally, in Chapter 6, conclusions to this work are drawn and suggestions for further
research are recommended.
2
2. Definition of the Test Cases
This chapter starts with the definition of the test cases, then continues with the
computational grids and parameters that are required for the numerical computations.
Besides, error analysis will be covered.
2.1. Test Cases
In the scope of this thesis, two different test cases are studied. The first one is based
on the classical DFG laminar flow around cylinder benchmark test for Re=100 [9].
It is simulated to check the numerical computation capability of CFX, as well as to
generate optimum meshes which provide efficient simulations in relation to time and
memory. The optimum mesh will later be used as a template for the meshes of the
second test case.
The second test [7]is the fluid part of a fluid part interaction test case defined in
section2.3.
For the sake of easiness, the names test case 1 and test case 2 are used to refer to
the both benchmarks, respectively.
2.2. Test Case 1
2.2.1. Geometry and Boundary Conditions
The configuration of the test case 1 is depicted in figure 2.1. A 2-dimensional channel
with a length of 2.2 m, a height of 0.41 m is defined as a domain. The radius of
the circular hole inside the domain is 0.1 m and the centre of it is located at B
(0.2, 0.2). The cylinder is mounted slightly off the symmetry axis in order to trigger
the von Karman vortex shedding as soon as possible. In future it is planned to
3
2. Definition of the Test Cases
calculate 3D fluid-structure interaction and the structure code ([6]) is especially suited
to investigate 3D structures. In order to change the setup as little as possible it was
decided to calculate this 2D benchmark with a 3D setup. To simulate 2D behaviour
with a 3D calculation, the third dimension z was discretised with one element only
and symmetrical boundary conditions were applied in z direction in the x-y plane.
The depth is varied in a study (section 5.1.1) to study the effect of the chosen depth
and resulting unfavourable element ratio.
Figure 2.1.: Dimensions of the Test Case 1
On the upper and the lower walls and around the cylinder boundary condition is
defined as no-slip condition. That is, the velocity of the fluid on the wall and the
velocity on the walls are the same. All the surfaces with no-slip boundary condition
have zero velocity. The inlet part (figure 2.1) has a parabolic velocity distribution
with its maximum velocity in the center of the domain at y=0.205 m. To have a
smoother start without numeric instabilities and to trigger the vortex shedding, the
parabolic inflow velocity is blended in within one second by a cosine function and
remains constant afterwards. The outlet has a do nothing boundary condition.
4
2. Definition of the Test Cases
2.2.2. Computational Grid
The domain of the test case is divided into number of elements to get a discrete
representation. This procedure is called discretization. Through discretization, a set
of algebraic equations are obtained from the differential equations. These algebraic
equations are solved and related values are extracted from the results.
Basically, there are two types of grid structure used for the computations, struc-
tured and unstructured grids. In a structured grid the elements edges are mainly
oriented along the coordinate axis of the domain whereas in an unstrucured grid the
elements are created randomly. Unstructured meshes are easier to create, however
structured ones lead to more accurate results with the same amount of elements.
Figure 2.2.: Hexahedral mesh. An example of a structured mesh.
Figure 2.3.: Hexahedral mesh detail around the cylinder.
Five meshes are tested in the numerical simulation. A structured mesh with hex-
ahedral elements and four more with unstructured prismatic elements. They are
5
2. Definition of the Test Cases
Figure 2.4.: Coarse mesh with prismatic elements. An example of an unstructured
mesh.
Figure 2.5.: Fine mesh.
named Hexa, DoMeshCoarse, DoMeshFine, DoMeshVeryFine and DoMeshOptimal.
The unstructured grids are investigated first since it is an easy and a fast way of
meshing the geometries with curved edges. A programme called Domesh 1 which is
developed at the chair of Bauinformatik (TUM) is used to obtain unstructured grids.
The difference between DoMeshCoarse (figure 2.4) and DoMeshFine (figure 2.5) is
the element size around the cylinder region. As the given names imply the latter one
has smaller elements. DoMeshVeryFine (figure 2.6) has considerably finer elements
not only around the cylinder part but also anywhere in the domain. The number
of elements is almost five times larger than DomesFine’s. After the analysis of the
results of the first four meshes an optimized mesh is chosen. Hexahedral elements,
for the structured grid, are created with a commercial programme called ANSYS-
ICEM-CFD-5.0. Blocking strategy is utilized to divide the domain into smaller parts.
These blocks are then meshed with a macro from the assigned number of elements
at its boundaries. O-grid is a robust technique to improve the mesh quality. This
technique is facilitated when it is desired to mesh a circular or ”O-type” mesh around
1Interfacing DO MESH, Lehrstuhl fur Bauinformatik, TU Muenchen, 2000
6
2. Definition of the Test Cases
Figure 2.6.: Very fine mesh.
Figure 2.7.: Optimal mesh.
an object (figure). Roughly speaking a big block (sometimes blocks) is transformd
to 5 sub blocks. Elements are kept fine around the cylinder. In the rest of the
domain relatively coarser elements are preferred to reduce the computation effort.
The thickness is chosen to be the maximum element size (0.04 m.) so that the
element ratio stays within reasonable bounds. (Table 2.1 )
Mesh Name Number of nodes Number of elements Maximum Element Ratio
Hexa 13700 6636 7.526
DoMeshCoarse 5442 4996 16.243
DoMeshFine 8720 7568 37.197
DoMeshVeryFine 43682 42608 39.894
DoMeshOptimal 25568 24932 11.841
Table 2.1.: Mesh properties
7
2. Definition of the Test Cases
2.3. Test Case 2
2.3.1. Geometry and Boundary Conditions
Test case 2 has the same geometric dimensions as the test case 1. Additionally, a flag
part is attached to the right side to the cylindrical hole (2.8). The tip of the tail is
located 0.6 m away from the origin. Like the cylinder, the flag is assigned a no-slip
boundary condition. The AdhoC Dummy code creates a structure composed of three
plates which surrounds the tail part and forces tail to move up and down. For the
details it is referred to section 4.1.4
Figure 2.8.: Dimensions of the Test Case 2
Three different inlet velocities are used (Table 2.2). CFD1, CFD2, and CFD3
differ only in the average velocities 0.3m/s, 1.0m/s, and 2.0m/s, respectively while
the geometry stays fixed as depicted in figure 2.8
2.3.2. Computational Grid
Three different hexahedral meshes are investigated for this test case 2. They are
labelled as M1, M2 and M3. Table 2.3 shows the numbers of elements of each grid.
CFD1 is tested only with mesh M1 since the flow develops to a steady-state and
8
2. Definition of the Test Cases
CFD1 Uave = 0.3 m/s
CFD2 Uave = 1.0 m/s
CFD3 Uave = 2.0 m/s
Table 2.2.: Average Velocity
the mesh is fine enough to simulate the flow with the required accuracy. CFD2 and
CFD3 are tested applying all of the mesh samples (Table 2.3).
Mesh Name M1 M2 M3
Number of hexa elements 11.984 136.308 269.328
Table 2.3.: Mesh information of the Test Case 2
2.4. Mesh Quality
The solution phase is the most time-consuming part of the FE analysis. The time
needed is directly affected by the mesh used. A mesh of good quality should fulfill
certain conditions. The size of the elements should be chosen properly. Coarse meshes
usually don’t provide good results since a too coarse discretization of the domain is
not expensive but leads to poor results. On the other hand, the finer the mesh, the
more time required. Hence, a mesh providing an optimal solution between the two
extremes has to be found. The biggest problem of meshing in the test cases is to assign
a good quality mesh by putting rectangular elements around the cylinder and/or flag
section. A grid is consists of blocks and blocks have four edges (note we only regard
the 2D case here, for the 3D-Mesh is obtained by extrusion). The lines opposite to
the each other have to have the same sampling. Additionally, these edges bounding
the blocks are at the same time bounding the neighbour blocks such that this effect
carries over until the boundaries of the domain. Although good quality local meshes
are possible, the global mesh might be spoiled by this carry-over effect.
At this point some remarks can be made about the quality of the grids. There are
three criteria used to check the mesh quality.
9
2. Definition of the Test Cases
2.4.1. Determinant
Determinant takes a value between 0 and 1. 1 represents a perfect hexahedral cube
whereas 0 represents a cube that has one or more degenerated edges. Determinants
value above the 0.3 is acceptable.
2.4.2. Warpage
Maximum internal angle deviation from 90 degrees is checked with this quality cri-
terion. Different solvers have different tolerance values. Therefore, for the tolerance
limits solvers should be checked. Internal angles are small if the cells are distorted.
2.4.3. Angle
The level of cell distortion is determined with the warpage check. Degree of the
warpage is increased if the nodes that make elements are distorted in plane direction.
Minimum value is 0 and maximum is 90.
2.5. Error Analysis
Without any study of errors and uncertainties a CFD simulation cannot be assessed
properly. There are possible error sources. Some these errors can be classified as
modelling error, discretisation error, iteration error, etc.
2.5.1. Modelling Error
The modelling error emerges from the simplifications. That is, the real physical prob-
lem is reduced to a mathematical problem through modelling. This is a crucial part
of the simulation, since the modelling assumptions decide how close the simulation
results are to your engineering problem. Fluid models are simplified by reducing some
terms of governing equations to only the terms having the biggest influence on the
problem to be calculated.
10
2. Definition of the Test Cases
2.5.2. Iteration Error
Numerical methods inevitably produce iteration errors. There are some techniques
to judge how accurate the computation is. One of them is to make a convergence
study of the method. If the difference between the results of the successive iteration
steps gets smaller, the result is getting closer to the answer. This is certified for the
methods used here. In other words, the result is converging to the solution.
Computers are prone to round off errors. Sincethe floating numbers get discrete
values, they have to be truncated up to certain precision level. These errors are
accumulated and magnified with the increasing numbers of iteration loops necessary
and might accumulate and affect the results. For CFX there is an option to limit the
cut off error up to e-20 level. Hence, arrangement of the cut off error is not a problem
for the computation.
2.5.3. Discretisation Error
The modelling error stems from simplification. However, this simplification phase is
not enough to reach a solution. A decision has to be made about the method which
will be used. Simplified problems can be solved analytically or numerically. Most
engineering tasks need numerical computation. To make a numerical simulation the
domain often has to be discretized to get a finite number of degrees of freedom. If
the number of degrees of freedom is increased the solution is expected to improve.
This error may be evaluated by comparison of two succesive discretizations (When it
is done hierarchically, it is also possible to assess the order of this error ).
11
3. MpCCI
3.1. Coupling Concept
The exchange of variables defined on an interface may have to be done only in one
direction. One code then exports the variables which in turn are imported by the
other code. Depending on the application, a two-way coupling might be required
in which both code have to send and receive. Furthermore, data exchange may be
required at every time step or at certain time steps only.
MpCCI is a library which offers the functionality needed for this data exchange. It
also provides a framework with which the coupling algorithm of calculation may be
progressed.
3.2. MpCCI:Mesh-Based Parallel Code Coupling
Interface
MpCCI [2] is an application independent code coupling interface for multidisciplinary
applications. The library has been developed at the Fraunhofer-Institute for Algo-
rithms and Scientific Computing (SCAI). The main goal of this software is to enable
users to combine different stand-alone simulation codes. Different solvers for the so-
lution of coupled problems may be integrated without much effort. MpCCI provides
an exchange of mesh based quantities between two or more simulation codes in the
coupling area. Since different simulation codes generally possess incompatible nu-
merical grids, MpCCI performs an interpolation or several methods of conservative
mapping of the quantities defined thereon. In other words, the meshes of the codes
do not have to match at the coupling region (Figure 3.1). This mapping (and the
necessary neighbourhood search) is done even if the coupling region is distributed
12
3. MpCCI
over different processes. By using the MpCCI coupling library for coupled solutions
the functionality of every simulation code is preserved. There is no need to repro-
gram the new simulation packages for specific applications. It is very flexible and can
be applied to various problems such as fluid-structure, fluid-fluid, structure-thermo,
fluid-acoustic-interaction, etc. MpCCI can be adjusted by the user to demand the
specific needs and therefore is applicable to almost every kind of multidisciplinary
problems. As mentioned before, the necessity for this library came from the demand
Figure 3.1.: Coupling Scheme [1]
for generating a general environment for coupling of any simulation code to another.
The basic notions of MpCCI are loose couplings between codes, minimal source code
changes, minimal knowledge requirement of the other codes, facility of sequential,
distributed, parallel execution and portability.
It is possible to use different coupling areas like lines, surfaces, and volumes. For
parallel simulation codes MpCCI distinguishes the separation of code internal and ex-
ternal communication. Although the source code is completely written in C++, lan-
guage interfaces for both FORTRAN and C are also available. Additionally, MpCCI
enables users to control facilities like convergence checks, monitoring and debugging.
MpCCI is available on the following platforms[3]:
13
3. MpCCI
� SUN (Solaris)
� SGI (IRIX)
� IBM (AIX)
� Hitachi
� Fujitsu VPP
� CRAY T3E (UNICOSmk)
� PC (WINDOWS NT)
� PC (Linux)
3.3. MpCCI Functions
The general structure of the application interface of MpCCI depends on the coupling
algorithm, but generally can be assigned to three major steps:
� Initialisation: Definition of partitions, nodes, elements, grids, parameters, etc.
� Coupling: Sending and receiving MpCCI messages.
� Termination: Closing the coupling phase.
The section 3.3.3 gives a short and basic information about the subroutines used for
the coupling. Definition and the explanation of these subroutines are inspired from
the MpCCI manual.[2]
� Function name:
Definition of the variables used:
Function call for C and FORTRAN:
Data type of variables used for FORTRAN:
Short remarks about the function:
Example:
14
3. MpCCI
pArgc INOUT pointer to pass the argument count to MPI Init
pArgv INOUT pointer to pass the arguments to MPI Init
int CCI Init ( int* pArgc, char*** pArgv ) for C
subroutine CCI INIT ( ierror ) for FORTRAN
integer ierror
� CCI Init
pArgc and pArgv are the parameters required for this function. INOUT
means that these parameters can be input or output of the call. Some parame-
ters can be used only as an input(IN ) or an output (OUT ).
3.3.1. Naming Conventions and Descriptions
As indicated before, there are FORTRAN and C interfaces of MpCCI. The
naming convention and description of subroutines are similar for these two ver-
sions. For the C version, subroutine names of MpCCI start with CCI (Code
Coupling Interface) and are followed by a list of words separated by the under-
score symbol ” ”. The first letter of the word after CCI is written in capital, e.g.
CCI Recv. Unlike the C interface, capital letters are used for the subroutine
nomenclature of the FORTRAN interface, e.g. CCI RECV. A maximum length
of 30 characters is allowed to account for portability. I is used as the first letter
of the first word after CCI if a non-blocking routine is chosen (CCI I followed
by lowercase letters). For instance, a name for non-blocking C is CCI Irecv
and for non-blocking FORTRAN is CCI IRECV. The naming convention for
MpCCI and MPI are quite similar.
3.3.2. Data Types
MpCCI data types are introduced to solve platform-dependent data types clash
problems. Data types are required for some of the routines. They are listed in
(Table 3.1 Table 3.2) for C and FORTRAN, respectively.
15
3. MpCCI
C Type MpCCI type
int CCI INT
float CCI FLOAT
double CCI DOUBLE
long double CCI LONG DOUBLE
char [] CCI STRING
bool CCI BOOL
Table 3.1.: MpCCI data types for C
FORTRAN Type MpCCI type
integer CCI INTEGER
real CCI REAL
real*4 CCI REAL4
real*8 CCI REAL8
double precision CCI DOUBLE PRECISION
Character*(*) CCI STRING
logical CCI LOGICAL
Table 3.2.: MpCCI data types for FORTRAN
3.3.3. Coupling Definition
Different codes are connected to each other in the initialisation phase. MPI
communicators are determined by the codes and some constants are computed
in this start up phase. These constants, MpCCI definitions and the data types
are attained by adding an appropriate library file (#include ”cci.h” (for C ),
#include ”ccif.h” (for FORTRAN )) to the related codes.
16
3. MpCCI
In the coupling phase, each code introduces its coupling area to MpCCI. Nodes
and elements are generated then a neighborhood search is performed.
� CCI Init
pArgc INOUT pointer to pass the argument count to MPI Init
pArgv INOUT pointer to pass the arguments to MPI Init
int CCI Init ( int* pArgc, char*** pArgv ) for C
subroutine CCI INIT ( ierror ) for FORTRAN
integer ierror
CCI Init is the first MpCCI call which passes the array of command line argu-
ments argv[] to the communication library and initialises MpCCI. The working
directory, environment variables, etc. are set as defined in the MpCCI input
file 3.4. MpCCI is based on MPI communication. Hence, MPI Init is initialised
inside CCI Init automatically.
� CCI Def partition
meshId IN grid identifier within each code
partId IN partition identifier of each code
int CCI Def partition ( int meshId, int partId )
subroutine CCI DEF PARTITION ( meshId, partId, ierror )
integer meshId, partId, ierror
Partitions of meshes which will be considered in the coupling computation are
specified by using CCI Def partition. Grids are identified by meshId and for
the partitions on each meshId, partId ’s are set. Partitions can be thought of
being a subdivision of a grid.
17
3. MpCCI
meshId IN grid identifier within each code
partId IN partition identifier of each code
globalDim IN dimension of the global coordinate system
nNodes IN number of nodes
nNodeIds IN switch node numbering, dimension of array nodes
nodeIds IN node identifier
realType IN data type of elements of coords
coords IN address of coordinate array
int CCI Def nodes ( int meshId, int partId, int globalDim, int nNodes,
int nNodeIds, const int nodeIds[], int realType, const void* coords )
subroutine CCI DEF NODES ( meshId, partId, globalDim, nNodes,nNodeIds,
nodeIds,realType, coords, ierror )
integer meshId, partId, globalDim, nNodes, nNodeIds,nodeIds(nNodeIds),
realType,coords, ierror)
<real type> coords (globalDim*nNodes)
� CCI Def nodes
Nodes which participate in coupling are specified with this call. With nNodeIds,
the numbering scheme of the nodes is set. realType (Table 3.1 Table 3.2) is for
the data type of the nodes that are created. CCI Def nodes have to be called
for every partition and only once. That means, the CCI Def partition has to
be called before this subroutine. The coords array has a maximum of globalDim
dimensions. For instance, if globalDim = 2 then coords array will be stored as,
Ax, Ay, Bx, By, where A and B denote the name of nodal arrays, x and y are
the axes.
� CCI Def elems
After the nodes are created, elements are formed. Element types, sequence of
nodes in elements and number of elements are defined. Different types of ele-
ments can be chosen for different dimensional space coupling. A wide range of
element types from line to pyramid are provided. nElems make the definition
18
3. MpCCI
meshId IN grid identifier within each code
partId IN partition identifier of each code
nElems IN number of elements
nElemIds IN switch for element numbering, dimension of array elemIds
elemIds IN element identifier
nElemTypes IN length of array elemTypes
elemTypes IN element type of the specified elements
nNodesPerElem IN number of nodes needed to describe one specific element
elemNodes IN indices of the nodes which define the elements
int CCI Def elems ( int meshId, int partId, int nElems, int nElemIds,
const int elemIds[], int nElemTypes, const int elemTypes[],
const int nNodesPerElem[], const int elemNodes[] )
subroutine CCI DEF ELEMS ( meshId, partId, nElems, nElemIds, elemIds,
nElemTypes, elemTypes, nNodesPerElem, elemNodes, ierror )
integer meshId, partId, nElems, nElemIds, elemIds(nElemIds),
nElemTypes, elemTypes(nElemTypes), NodesPerElem( ),
elemNodes( ), ierror
of different element types possible in a partition.
� CCI Def comm
localCommId IN communicator of local code
remoteCodeId IN id of the remote code
remoteCommId IN communicator of remote code
nQuantityIds IN length of array quantityIds
quantityIds IN ids as defined in the input file
nLocalMeshIds IN length of array localMeshIds
localMeshIds IN id of local meshes
Communicators are created with the CCI Def comm subroutine. It collects
required information of the parameters that are needed. Another way to spec-
19
3. MpCCI
int CCI Def comm( int localCommId, int remoteCodeId,
int remoteCommId, int nQuantityIds, const int quantityIds[],
int nLocalMeshIds,const int localMeshIds[] )
subroutine CCI DEF COMM( localCommId, remoteCodeId, remoteCommId,
nQuantityIds, quantityIds, nLocalMeshIds, localMeshIds, ierror )
integer localCommId, remoteCodeId, remoteCommId, nQuantityIds,
quantityIds (nQuantityIds), nLocalMeshIds,
localMeshIds (nLocalMeshIds), ierror
ify the communicator parameters is through the MpCCI input file. However,
to attain those parameters CCI Comm info has to be called before calling
CCI Def comm. localCommId is a variable that is only known to every pro-
cess within the local code. On the remote side it searches its counterpart in the
variable remoteCommId. nQuantityIds keeps the number of quantities which
are stored in quantityIds. Both id’s (localCommId and remoteCodeId) should
be greater than zero.
� CCI Def sync point
syncPointId IN identifier of the synchronization point
nQuantitiesToSend IN number of quantities to be sent
quantitiesToSend IN array of quantity identifiers, length nQuantitiesToSend
nMeshIdsToSend IN length of the array meshIdsToSend,
either 1 or nQuantitiesToSend
meshIdsToSend IN array of mesh identifiers, length nMeshIdsToSend
nQuantitiesToRecv IN number of quantities to be received
quantitiesToRecv IN array of quantity identifiers, length nQuantitiesToRecv
nMeshIdsToRecv IN length of the array meshIdsToRecv,
either 1 or nQuantitiesToRecv
meshIdsToRecv IN array of mesh identifiers, length nMeshIdsToRecv
Synchronisation points are the places where send and receive operations are es-
tablished. They have to be generated at the initialization phase. CCI Reach sync point
and the input file are the two complementary parts of CCI Def sync point.
20
3. MpCCI
int CCI Def sync point ( int syncPointId, int nQuantitiesToSend,
const int quantitiesToSend[], int nMeshIdsToSend,
const int meshIdsToSend[], int nQuantitiesToRecv,
const int quantitiesToRecv[], int nMeshIdsToRecv,
const int meshIdsToRecv[] )
subroutine CCI DEF SYNC POINT (syncPointId, nQuantitiesToSend,
quantitiesToSend, MeshIdsToSend, meshIdsToSend, nQuantitiesToRecv,
quantitiesToRecv, nMeshIdsToRecv, meshIdsToRecv, ierror )
integer syncPointId, nQuantitiesToSend, quantitiesToSend (nQuantitiesToSend),
nMeshIdsToSend, meshIdsToSend (nMeshIdsToSend), nQuantitiesToRecv,
quantitiesToRecv (nQuantitiesToRecv), nMeshIdsToRecv,
meshIdsToRecv( nMeshIdsToRecv ), ierror
CCI Sync point info should be called to get the required data from the input
file. The identifier for synchronisation points can be different in various codes.
There is no need to match the codes since matching is done by the input file.
� CCI Close setup
cciProcess IN flag for MpCCI process
int CCI Close setup ( int cciProcess )
subroutine CCI CLOSE SETUP( cciProcess, ierror )
integer cciProcess, ierror
This routine terminates the definition phase. It has to be called by every pro-
cess which also called the CCI Init.
� CCI Put nodes
CCI Put nodes is used to specify the coupling quantities at the nodes to MpCCI.
The values with the identifier quantityId must be defined in the relevant code
21
3. MpCCI
meshId IN grid identifier within each code
partId IN partition identifier of each code
quantityId IN identifier specified in the input file
quantityDim IN dimension of quantity
nNodes IN number of nodes
nNodeIds IN switch node numbering, dimension of array nodeIds
nodeIds IN node identifier
valuesDataType IN identifier of input data
values IN returned data values´
int CCI Put nodes( int meshId, int partId, int quantityId,
int quantityDim, int nNodes, int nNodeIds, const int nodeIds[],
int valuesDataType, const void* values )
subroutine CCI PUT NODES( meshId, partId, quantityId, quantityDim,
nNodes, nNodeIds, nodeIds, valuesDataType, values, ierror )
integer meshId, partId, quantityId, quantityDim, nNodes, nNodeIds,
nodeIds(nNodeIds), valuesDataType, ierror
<real type> values(quantityDim*nNodes)
block of the MpCCI input file. The location specification in the input file de-
cides which call is used for the coupling. (Since loc = nodes is chosen the
CCI Put nodes subroutine is used. If loc = elem was chosen CCI Put elems
would have to be used.) If scalar is chosen as a quantity, quantityDim has to be
set to 1. If vector is chosen, quantityDim must be equal the dimension of the
vector.
� CCI Reach sync point
syncPointId IN identifier of a synchronization point
status OUT status object
CCI Reach sync point performs the communication between the codes which
are specified in the match syncpt statement of the coupling block of the input
file. The send and receive operations are determined by the synchronisation
22
3. MpCCI
int CCI Reach sync point ( int syncPointId, CCI Status* status )
subroutine CCI REACH SYNC POINT( syncPointId, status, ierror )
integer syncPointId, status( CCI STATUS SIZE ), ierror
point definition of the codes. The communication at the synchronisation point
with the identifier syncPointId is carried out.
� CCI Get nodes
meshId IN grid identifier within each code
partId IN partition identifier of each code
quantityId IN identifier specified in the input file
quantityDim IN dimension of quantity
nNodes IN number of nodes
nNodeIds IN switch node numbering, dimension of array nodeIds
nodeIds IN node identifier
valuesDataType IN identifier of input data
values OUT returned data values´
maxnEmptyNodes IN maximum number of nodes without data
emptyNodes OUT returned nodes containing no data
nEmptyNodes OUT length of array emptyNodes
int CCI Get nodes( int meshId, int partId, int quantityId,
int quantityDim, int nNodes, int nNodeIds, const int nodeIds[],
int valuesDataType, const void* values,int maxnEmptyNodes,
int emptyNodes[], int* nEmptyNodes )
subroutine CCI GET NODES( meshId, partId, quantityId, quantityDim,
nNodes, nNodeIds, nodeIds, valuesDataType, values,
maxnEmptyNodes, emptyNodes, nEmptyNodes, ierror )
integer meshId, partId, quantityId, quantityDim, nNodes, nNodeIds,
maxnEmptyNodes, emptyNodes (maxnEmptyNodes),
nEmptyNodes, nodeIds(nNodeIds), valuesDataType, ierror
<real type> values(quantityDim*nNodes)
23
3. MpCCI
CCI Get nodes are used to obtain coupling values received from the other code.
valuesDataType must be chosen according to the quantities transferred (Ta-
ble 3.1 Table 3.2). nNodes are the number of nodes specified by the call of
CCI Def nodes. The array emptyNodes determines the nodes where no new
values are obtained.
� CCI Check convergence
myConvergence IN code of local convergence state
globalConvergence OUT global convergence state
comm IN MpCCI communicator
int CCI Check convergence( int myConvergence, int *globalConvergence,
int comm )
subroutine CCI CHECK CONVERGENCE( myConvergence, globalConvergence,
comm, ierror )
integer myConvergence, globalConvergence, comm, ierror
CCI Check convergence must be called by all codes and exchanges the conver-
gence states. Each code specifies its local convergence state myConvergence by
an integer. These integers are exchanged between the codes and the maximum
of all integers is returned to each code in globalConvergence. MpCCI defines
four constants for the local convergence state with the following meaning:
CCI CONVERGED ( = 0 ) converged and could stop here,
but I can also do a further coupling step.
CCI CONVERGED ( = 1 ) not yet converged and would like to
do a further coupling step.
CCI CONVERGED ( = 2 ) converged and must stop here.
No further coupling step is possible.
CCI CONVERGED ( = 3 ) diverged and must stop here.
24
3. MpCCI
Another important meaning of this subroutine is the creation of coupling steps
when writing a MpCCI tracefile. CCI Check convergence introduces a new
coupling step in the tracefile. With a suitable visualisation tool for MpCCI
tracefiles the user can observe the data sent and received in the different steps
in an animation.
� CCI Finalize
int CCI Finalize()
subroutine CCI FINALIZE( ierror )
integer ierror
Subroutine CCI Finalize terminates the coupling. It has to be called by the processes
which called CCI Init. The coupled computation is finished after this subroutine
MpCCI terminates. After the termination messages all processes do a clean-up and
write their output files.
3.4. MpCCI Input File
The MpCCI input file has to provide information regarding the following questions.
� Which codes should be run?
� Where should they be located?
� How should they be started?
� What are the environmental variables to be specified?
� What are the quantities to be mapped and how are they recognised by the
codes?
The input file is an important part of the definition of coupling process. Part of
the flexibility when using MpCCI to couple the codes is due to this input file.
MpCCI library contains some values by default. These default values can be altered
via input file. Moreover, it contains the coupling algorithms itself, quality checks and
level of debugging, etc. It is important to note that the input file is a case-sensitive
file.
25
3. MpCCI
3.4.1. Structure
The file comprises of several blocks. Some of them have to be specified whereas some
of them are optional and only change default values. The ordering structure listed
below is important and must not be changed. Each block starts with its name (code
block, quantities block, etc.) and finishes with the word ’end’.
� code block(s)
� quantities block(s)
� control block
� contact block
� switches block
� jobs block
� parameters block
� coupling block
� additional block
Code Block
This block is mandatory in the input file. The numbers of codes which participate
in the coupling determine the number of code blocks. For each code there must be
a code block. The quantities to be exchanged (received and sent) are named here.
Their type, dimension and location in the grid are also specified.
name of the quantity ( number, location, dimension, type )
force ( no=1, loc=elem, dim=vector, type=flux )
Number is given to label the name of the quantity in a code block. Different
numbers must be chosen for different quantities. Negative numbering is allowed. [4]
Location indicates whether it is an elemental or nodal quantity. Dimension can be a
26
3. MpCCI
vector or a scalar. Besides, user defined extended dimension can be created. Finally,
the type is generally described as ’flux’ or ’field’. Field is used for scalar type values
like heat and flux is a vector type like force.
Quantity Block
This mandatory part clarifies how the quantities of the different codes defined in the
code block are related to each other. The matching of two quantities is valid if they
have the same type and dimension set in their code blocks. However, it is independent
of their location.
Example:
code1.quantity = code2.quantity
ansys.force = cfx.force
Control Block
This part specifies parameters related with the control of algorithms used by MpCCI.
It is an optional block. To visualise the coupled computation a tracefile section should
be established in this block. If no name is specified then there will not be any tracefile
written. There are numbers of on/off switches with which the quality of the meshes
can be checked.
Contact Block
This optional block is for the attributes of the grids. It defines the contact detection
algorithm and matching criterion.
Switches Block
Switches block is the place where the debugging level is decided. There are different
possibilities ranging between no output and maximum output choices. It is also
possible to define a group. A group is a section used to define in which part of
MpCCI the switch command is applied. For the group part there is a hierarchy to
27
3. MpCCI
obey. For the list of hierarchy, please check the appendix. This block is another
optional block in the input file. [5]
Jobs Block
This section describes the coupling codes which participate in the coupling. Paths for
the executables of the individual codes are define here. Arrangements related with
the parallisation is done under jobs block. Number of processes and environmental
variables are set in a group name. In the following example, a group named struct1
is created with a keyword struct, number of processes are decided to be 4 and the
environmental variable ’STRUCT JOB’ is set to ’part’. Pwd specifies the working
directory and exec sets the command to start the process.
Example:
jobs
struct1 = struct (
pwd = C:
exec = ”binary1”
nprocs = 4
env (STRUC JOB) = ”part”
);
end
Parameters Block
This block is optional. It helps users to introduce some string, float or integer values.
Coupling Block
This is one of the crucial parts of an input file although it is an optional block. Com-
municators and synchronisation points are described in this block. Synchronisation
points are the points where the send and receive operations are performed. They are
combined with the ’match syncpt’ command. If match syncpt is not defined then the
synchronisation is performed between the points which have the same identifier.
28
3. MpCCI
Example:
In this example, the generation of synchronisation points and their relation to each
syncpt jobname1 (syncPt1) = send (quantityId1/meshId1, quantityId2/meshId2, )
recv (quantityId1/meshId1, quantityId2/meshId2, )
syncpt jobname2 (syncPt2) = send (quantityId1/meshId1, quantityId2/meshId2, )
recv (quantityId1/meshId1, quantityId2/meshId2, )
match syncpt jobname1 (syncPt1, syncPt2, )
= jobname2 (syncPt1, syncPt2, )
other are illustrated.
A synchronisation point definition starts with the job name defined in the code
block. Then, quantities that are sent and received which are specified together with
its grid id. If one of the operations is not needed (send or recv) then it is omitted
from the definition. The equality in the specification of match syncpt depicts that the
synchronisation point 1 (syncPt1) of job1 is matched with the synchronisation point
1 (syncPt1) of job2. Similarly, synchronisation point 2 (syncPt2) of job1 is related
with the synchronisation point 2 (syncPt2) of job 2.
Additional Block
This block is optional. Some additional features are placed in this block such as
coordinate transformation or intersection points.
29
4. Moving Boundaries
Moving boundaries were implemented on a third trial example derived from test case
2. Here, the tail of test case 2 was moved with a sinusoidal movement in time and
with a parabolic displacement in space. The following describes how this movement
was implemented in CFX via coupling to a pseudo-code. This code received forces at
the tail shaped boundary only to discharge them and return a fixed displacement in
form of 4.1.
4.1. Outline of achieveing a Bi-Directional coupling
via MpCCI
The long term goal is to couple the high-order structure code AdhoC to the fluid code
CFX. In order to achieve this goal it was decided to take three major intermediate
steps using MpCCI.
1. Couple a dummy fluid code to a dummy AdhoC code
2. Replace the dummy fluid code with CFX
3. Replace the dummy AdhoC code with AdhoC
Step one (section 4.1.1) and step two (section 4.1.2) are described in this thesis. Step
three has yet to be taken. The necessary dummy codes were written in C.
4.1.1. AdhoC Dummy Code
In step 1, the dummy codes received either forces (AdhoC Dummy) or displacements
(Fluid Dummy) and vice versa, sent displacemets (AdhoC Dummy) or sent forces
30
4. Moving Boundaries
(Fluid Dummy). This dummy code first is used solely both as a solid dummy and
fluid dummy but with different settings.
Three planes are created and they are connected together to obtain the shape of
tail. Definition of a plane is based on the specification of the coordinates of the three
corners. Number of the nodes should be set in both transverse and longitudinal di-
rections to generate quadratic local meshes. Meshes are combined with each other
and a global mesh is obtained. Since two partitions are on a line, nodes on the line of
combination must have the same values. The subroutine Associate Partitions (Ap-
pendix A)is generated to take care of this problem. The basic idea of the subroutine
is to delete one set of common nodes (there are two sets of nodes with different mesh
identities but the same geometric properties) and to assign the remaining nodes to
the other mesh.
Figure 4.1.: Parts of Adhoc Dummy
The dummy forces and displacements to be exchanged are defined using some
indices that are a function of position and time by calling the AdhoC Dummy routine
in the code. During mesh generation, geometric information of the nodes and elements
are kept in matrices.
One-way data transfer is applied first. Then, program is extended for the quantity
exchange. Please refer to appendix for the AdhoC Dummy code.
4.1.2. Implementation of MpCCI on a written Dummy Structure
Code and CFX
ANSYS-CFX
ANSYS-CFX is a program package for modelling general fluid flow in complex geome-
tries. CFX is composed of the preprocessor, the flow solver, and the postprocessor.
CFX offers a wide area of physical models and numerical solution algorithms for
31
4. Moving Boundaries
steady or transient, incompressible or compressible, laminar or turbulent, free surface
flows and etc. In this thesis, CFX 5.7 version is used.
CFX-Pre
There are two steps to set up a CFD problem, mesh generation and physical problem
set-up.
In the new version of the program mesh geometry and meshes can be generated by
CFX. However, in version 5.7 there is no option to generete a geometry or a mesh
and therefore these data have to be imported. CFX-Pre can import meshes from lots
of programs using a variety of formats like ACIS and IGES. ANSYS-ICEM-CFD and
Domesh (reference) are chosen to create the required geometries and meshes.
Once meshes have been imported, the user assigns meshes to domains. Depending
on the demands of the problem multiple meshes can be combined to form a single
domain or a single mesh can be split into several of domains.
It is easy to set and access the details of the physical problem through an interactive
control panel. Any changes made in the definition of the problem can be displayed
simultaneously. Errors in definitions can be detected via colorful descriptive messages
in interactive panels.
After the problem definition is complete, a definition file for the CFX solver is
written.
CFX-Solve
The solver manager enables users to monitor the convergence progress of the calcu-
lations through graphs while the calculation is running. Residuals, forces, monitor
points, and expressions can be displayed during the process.
CFX-Post
Post-processing is an important step in the CFD analysis. Data obtained from the
solver manager should be clearly presented in order to make reasonable comments
on the application. Not only is the visualization important but the calculation data
should be assessed carefully by analysing the output files of the monitor points an
res-files.
32
4. Moving Boundaries
CFX-Post has powerful tools to extract valuable information from ANSYS-CFX.
CFX-Post provides users with all the graphical features. Streamlines, planes, vectors,
isosurfaces and charts are available to display the flows within the specified domain.
Animation of the applications is also available. However, it was foud to be useful
to create monitor points and analyse the monitor files by a script written in python.
Please, check the python scripts in appendix B.
CFX Expression Language(CEL) is available in the postprocessor. Specific func-
tions such as area integral and averages of some quantities can be obtained. Expres-
sions can be used to define new user defined variables.
When the fluid code was replaced by CFX, the forces sent by CFX were received
by the AdhoC Dummy code (See, appendix A) and discharged. A fixed displacement
according to
(i− 1.0) ∗ (i− 1.0)
((n− 1.0) ∗ (n− 1.0))∗maxEndDisplZ ∗ sin(3.14159265 ∗ insT ime)
Formula was then returned by the AhoC Dummy to CFX and this displacement
was imposed on the boundary at test case 2.
4.1.3. CFX Expression Language (CEL)
CEL is a declarative language that is used to define relationship that depends on
other variables and complex boundary condition profiles. Some values or expressions
are generated by using CEL. Values can be defined either dimensionless or with the
dimensions in terms of time, length, mass, temperature, etc. Arithmetic operations
like addition or subtraction are possible. Any name can be chosen as an expression
name except the names of some predefined expressions, mathematical functions, sys-
tem variables or other user defined functions .The value of a CEL expression can also
be monitored during the solution process.
To call the required function a certain syntax has to be followed. The general syn-
tax is as follows:
<function> (<variable>) @ <location>
<function> is used for the CEL function specification.
<variable> is the variable to be applied. If there is no need an empty brackets must
be leaved.
33
4. Moving Boundaries
<location> is the region or boundary that of interest.
For the calculation of the lift and drag forces around the cylinder and the flag some
functions are defined. Boundary conditions are different for the each test case, hence
different expressions are specified. Definition of the parabolic velocity profile at the
inlet is also experienced with CEL functions. CEL expressions that are used during
the test case computations are given below.
ForceX = force x()@cylinder
ForceY = force y()@cylinder
ForceX = force x()@cylinder + force x()@tail
ForceY = force y()@cylinder + force y()@tail
InflowVelicity = 1.5 [m s-1]
StartSlow = (cos(t * 3.141[rad s-1]-3.141)*1/2 + 0.5)
ParabolicInflow = InflowVelicity*y*(0.41 [m]-y)/((0.41 [m]/2)2)*StartSlow*
step(1-t*1[s-1])+InflowVelicity*y*(0.41 [m]-y)/((0.41 [m]/2)2)*step(t*1[s-1]-1)
The first thing that can be deduced from the examples is that an expression can be
used to define another one. To define parabolic inflow boundary condition expressions
like StartSlow or InflowVelicity are defined in order to run to simulations with different
velocity settings spending much effort. The CEL function force is already defined
internally. The force function which is separated by an underscore from the direction
to be projected on (x or y) is then followed by an ”@”operator to specify the domain,
sub-domain or boundary of interest. Since arithmetic operations are available to
calculate the total drag and lift forces around the cylinder and flag, their domains are
added to each other. All the variables are dimensionalised by assigning values with
dimensions.
4.1.4. Monitor Points
Specification of the expressions is not enough to attain the pressure values, drag or
lift forces. Monitor objects which are the points at which certain quantities are ob-
served, are also needed to extract the required quantities from the output data. For
the extraction following command needs to be run from the command line.
34
4. Moving Boundaries
cfx5dfile <file> -read-monitor > output.txt
<file> is the result file that contains the monitor points data. Output data (out-
put.txt is referred as ”output data” from now on.) contains a list of variable names
followed by a list of values. A line of data for every iteration in the order of the
variable names is written to the file. They all are separated from each other with a
comma.
Output data is parsed with the help of a python (Appendix B) script into the for-
mat required for the gnuplot. Python is an interactive, object-oriented programming
language and gnuplot is an interactive plotting programme. With the python script,
quantities that are needed can easily be extracted from the output data with a simple
run.
35
5. Discussion of the Results
5.1. Discussion of the Results of the Test Case 1
All tests are calculated with CFX 5.7. To get an idea about the effect of the spatial
discretization the time step is kept constant. In other words, it is intended to depict
only the spatial error of computations (reference). The time step is set to 0.01[s].
The velocity profile introduced at the inlet boundary is increased with a sinusoidal
function so that the full velocity is reached after one second.
Fluid force exerted on the cylinder can be separated and analyzed as lift and drag
forces. Drag forces are the forces exerted on the submerged cylinder in x-direction
whereas lift forces are perpendicular to it. Related to lift and drag forces, two im-
portant dimensionless parameters are defined, CD and CL, to ensure the comparison
criteria free from any dimensions.
CD =Fx
12ρν2
0dLCL =
Fy
12ρν2
0dL
where,
� CD, CL: Lift and drag coefficients,
� Fx and Fy: Resultant forces tangential and perpendicular to the velocity vector,
respectively,
Fx =
∫s
σ~nxdS Fy =
∫s
σ~nydS
� ρ : Flow is density,
� ν : Bulk velocity,
� D : Diameter of the cylinder,
36
5. Discussion of the Results
� L : Lenght of the channel.
Following diagrams present change of lift and drag forces with different time periods.
If the graphs are examined, it is observed that Hexa mesh is not shown in any graphs.
It is because, the results obtained are too far from our references. Hence, Only the
results of unstructured meshes are compared to each other.
Starting from rest, the flow develops and finally reaches a periodic stage. Vortex
shedding causes the lift and drag forces to oscillate. They oscillate at different fre-
quencies. Figures (5.1a and 5.1b) show that the lift has half the frequency of the
drag.
After certain transition period all the lift forces show similar pattern in period but
not in amplitude and phase angle.(Figures 5.1a, 5.2a and 5.3a). The best results are
obtained form DoMeshVeryFine and DoMeshOptimal. (Figures 5.1b, 5.2b and 5.3b)
All drag forces overshoot before they oscillate around their mean value. As it is the
case in lift good results are obtained from DoMeshVeryFine and DoMeshOptimal.
To conclude, DoMeshOptimal leads to sufficiently accurate results and is used as a
template for the second test case.
5.1.1. Comparision of Coarse Meshes
In this part was to test the effect of the element ratio in connection with symmetry
boundary conditions. In the graphs 0.005, 0.01 and 0.02 show the length of the
thicknesses, respectively. Table 5.1 shows the maximum edge length ratio for different
the thicknesses.
Thickness(m) M1 M2 M3
Max. Edge Length Ratio 13.692 11.828 74.391
Table 5.1.: Comparison of Max. Edge Length Ratios
Figures 5.4 5.5 5.6 show the drag and lift force for different time steps. If the overall
pattern of the lift forces ([0-20s]) is considered it is observed that there is almost no
difference between the lift forces. They have almost the same frequency and amplitude
over the entire analysis time. However, in the beginning of the simulation([0-5s]) there
37
5. Discussion of the Results
is slight deviation of lift and drag of the thickness 0.005 in amplitude and phase.
As time passes([10-15s]) the amplitude difference vanishes although phase difference
continues until the end of the simulation.
Normally, the forces should be the same since we do not change any boundary
conditions. But, still the error between the values are very small and can be neglected.
5.2. Discussion of the Results of the Test Case 2
The results of test case 2 are shown in the following graphs.
5.2.1. Effect of Velocity Change
A chosen mesh is tested with the average inflow velocities 0.3, 1.0 and 2,0 (in m/s).
All the velocities are applied to the mesh type M1. However, M2 and M3 are tested
without the velocity value 0,3 m/s. The reason is that M1 is fine enough to simulate
an inflow velocity 0,3 m/s. The flow shows a steady-state situation and the results
are close to the other benchmark test results. [7]
For the grid M1, as the velocity is incresed from 0,3 m/s to 1, 0 m/s there is no
change in the pattern of the drag forces. The value increases about 10 times. If the lift
forces are considered not only the values increase but also the graph changes. Increase
in velocity results in a signifcant peak in the graph. (Figures 5.8a and 5.9a) Further
increase in velocity maintain the increase in drag and lift values. Additionally, the
steady state situation is disturbed and periodic behavior is observed.(Figures 5.12a
and 5.12b). Negative and positive lift forces are formed and drag forces fluctuates
with small amplitudes.
For the meshes M2 and M3 the increase in velocity results in periodic forces with
higher lift and drag values as mentioned above for the mesh M1. This time drag
forces show macroscopic alteration.
5.2.2. Effect of Grid Type
For CFD1, only one mesh was investigated since the benchmark tests are reproduced
with sufficient accuracy with the coarsest grid. (Figures 5.8b and 5.8a)
38
5. Discussion of the Results
For CFD2 (Figures 5.9a, 5.10a and 5.11a), in other words for the average inflow
velocity 1,0 m/s, refinement of the mesh causes reduction in lift and drag forces,
respectively. After certain transition period forces stabilize themselves and reach
constant values. Refinement does not change the graphical pattern.
For CFD3 (Figures 5.12a, 5.13a and 5.14a) where the flow is 2,0 m/s, refinement
results in increase in amplitude of the periodic motion of the drag forces. Besides,
fluctuations start earlier as the number of elements increases. Similar observations
can be made for the lift forces, as well.
39
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.1.: lift and drag forces [0-20 s.] (Test Case 1)
40
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.2.: lift and drag forces [0-5 s.] (Test Case 1)
41
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.3.: lift and drag forces [10-15 s.] (Test Case 1)
42
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.4.: Comparision of coarse meshes that have different thickness [0-20 s.]
(Test Case 1)
43
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.5.: Comparision of coarse meshes that have different thickness [0-5 s.] (Test
Case 1)
44
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.6.: Comparision of coarse meshes that have different thickness [10-15 s.]
(Test Case 1)
45
5. Discussion of the Results
Figure 5.7.: Values for lift and drag forces. The results shown are calculated for the
last 5 seconds
(a) lift
(b) drag
Figure 5.8.: lift and drag forces around the cylinder and flag (CFD1,M1)
46
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.9.: lift and drag forces around the cylinder and flag (CFD2,M1)
47
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.10.: lift and drag forces around the cylinder and flag (CFD2,M2)
48
5. Discussion of the Results
(a) lift
(b) drag
Figure 5.11.: lift and drag forces around the cylinder and flag (CFD2,M3)
49
5. Discussion of the Results
(a) lift
(b) drag
(c) Fourier
Figure 5.12.: lift and drag forces around the cylinder and flag (CFD3,M1)50
5. Discussion of the Results
(a) lift
(b) drag
(c) Fourier
Figure 5.13.: lift and drag forces around the cylinder and flag (CFD3,M2)
51
5. Discussion of the Results
(a) lift
(b) drag
(c) Fourier
Figure 5.14.: lift and drag forces around the cylinder and flag (CFD3,M3)
52
6. Concluding Remarks and
Recommendations
In this study, coupling analysis of the two benchmark tests are successfully performed.
First, computation of the DFG-Benchmark 1995/6: Channel flow around a circle for
laminar flow is carried out. MpCCI library and AdhoC-Dummy are used for external
coupling. An optimal mesh is needed to reduce the computation time and memory
requirements. With the help of optimal mesh, new grids are created for he second
test case, interaction between fluid and an elastic structure.
Finally, the second test case is numerically studied. Different average inflow veloc-
ities are tested using different grids. Results are compared to the studies of the other
numerical benchmark calculations. For this goal, forces are splitted as drag and lift
forces.
In the near future, further research is in progress to test AdhoC, p- version of finite
element code written at the Chair of Bauinformatik, for fluid-structure interaction
problems of different settings such as laminar flow-elastic structure or laminar flow
inelastic-solid structure interaction, etc. Testing process can be enlarged to compare
the responses of p and h -versions of finite element codes. Another research study can
be related to the efficiency investigation of time and memory of AdhoC for different
FSI problems.
53
References
[1] Frauenhofer Institute for Algorithms and Scientific Computating SCAI. Mpcci
3.0.4 manuals. page 9, 2005.
[2] Frauenhofer Institute for Algorithms and Scientific Computating SCAI. Mpcci
3.0.4 manuals. 2005.
[3] Frauenhofer Institute for Algorithms and Scientific Computating SCAI. Mpcci
3.0.4 manuals. page 2, 2005.
[4] Frauenhofer Institute for Algorithms and Scientific Computating SCAI. Mpcci
3.0.4 manuals. page 78, 2005.
[5] Frauenhofer Institute for Algorithms and Scientific Computating SCAI. Mpcci
3.0.4 manuals. page 86, 2005.
[6] Lehrstuhl fur Bauinformatik (Technische Universitat Munchen). Adhoc users’
guide. 30 March 2004.
[7] J. Hron and S. Turek. Proposal for numerical benchmarking of fluid-structure
interaction between elastic object and laminar incompressible flow. Journal of
Process Control, 10(2-3):209–218, 25 July 2005.
[8] D.Dennis Parsons. Methods and applications in coupled engineering simulations.
7th US National Congress on Computational Mehanics. http://usnccm.sandia.
gov/mslist/msDetail.lasso?RecID=il960.32.
[9] M. Schafer and S. Turek. Benchmark computations of laminar flow around cylin-
der. Numerical Fluid Mechanics, 52(1):547–566, 1996.
54
A. THE DUMMY CODE
This program is a small benchmark example for coupling algorithm betweenfluid and a solid structure. Solid code is aimed to be written (definedand computed) in C while fluid part is defined and solved with CFX. Bothcodes specify a simple mesh to MpCCI. Code ’SOLID’ sends some vectorialvalues (displacements) to the ’FLUID’ code and gets some vectorial data(forces) from it. Each code has only one process i.e. runs sequentially.
Compile/link/run benchmark example
# # # # # Solid # # # # #
make clean # Do some cleanup and remove all non-source files
If you prefer to do it ’by hand’ instead of typing ’make’,you can use the compile, link and run scripts of the MpCCI distribution.The compile and link scripts print to stdout the full command which theyare going to perform (all include or lib flags).
## Compilation of structureCode.c:#
ccicc -c structureCode.c # Compile the C versioncciCC -c structureCode.c # Alternatively: Compile the C version
# using the C++ compilerccilink structureCode.o -o structureCodeBinary # Link
# the 1st code (C version) with MpCCIccilink structureCode.o -o structureCodeBinary # Link
# the 2nd code (C version) with MpCCI# NOTE: MpCCI input file ’benchmark.cci’# expects the name of the binary to be# ’structureCodeBinary’
## Start the coupled computation:#ccirun -log structureCode.c # Start the coupled computation.
# You can also try out the -xterm# option of the ccirun script.
55
A. THE DUMMY CODE
The resulting output files of the coupled computation are’ccirun.out<r>’ where <r> is the global rank process.These files should be in the form of ’ccirun.out.*’.
# # # # # Fluid # # # # #
For fluid to make the CFX program ready for coupling job COMMANDshould be run.
/*This file is the structure part of the coupling. The code providesusers to define three planes and then to mesh them as it is shownin the following figure. Users should provide to the function’createPlane’ three corners of a plane and number of nodes in bothdirections (longitudinal and transverse) required for quadraticmesh generation.
Planes should be joined together in order to get a mesh with threepartitions. For this goal a function ’Associate_partitions’ is usedto volatile the duplication of nodes that lie on the commonboundaries of the partition.
MpCCI library is used to transfer the force and displacement databetween structure code and fluid code. Structure code gets forcedata whereas fluid part needs to get the displacement from thestructure. The displacement is a parabolic function of position.(please, check the ’AdhoC_Dummy’ function !) It also changessinosidually with time.
---Plane 1-------|| Plane 3
---Plane 2-------|
*/
/*--- Header files ---*/#include<cci.h>#include<stdio.h>#include<stdlib.h>#include<math.h>
/*--- Create a vector (namely a point) ---*/typedef struct{
int id;double x;double y;double z;
} Node;
56
A. THE DUMMY CODE
/*--- Vector addititon ---*/void addVectors(Node *v1, Node *v2, Node *res){
res->x = v1->x + v2->x;res->y = v1->y + v2->y;res->z = v1->z + v2->z;
}
/*--- Vector subtraction ---*/void subVectors(Node *v1, Node *v2, Node *res){
res->x = v1->x - v2->x;res->y = v1->y - v2->y;res->z = v1->z - v2->z;
}
/*--- Multiplication of a vector by a constant ---*/void multConstant(Node *v1, Node *res, double n){
res->x = n* v1->x;res->y = n* v1->y;res->z = n* v1->z;
}
/*--- Division of a vector by a constant ---*/void divConstant(Node *v1, Node *res, double n){
res->x = v1->x / n;res->y = v1->y / n;res->z = v1->z / n;
}
/*--- Creates a plane ---*/Node ***createPlane(Node RefKo, Node P_00, Node P_n0, Node P_0m
int elem_u, int elem_v){/* RefKo is the origin in the plate system *//*
P_0melem_v o--o--o--o--o
| | | | |o--o--o--o--o sample plane| | | | |o--o--o--o--o elem_uP_00 P_n0
elem_u and elem_v are both the maximum node numbers in bothdirections successively.*/
57
A. THE DUMMY CODE
Node ***P;Node u,v,du,dv;du.x=0.0; du.y=0.0; du.z=0.0; /* u and v are both vectors*/dv.x=0.0; dv.y=0.0; dv.z=0.0;int i,j,inc=0;
P= (Node***)calloc(elem_u, sizeof(Node**)); /* allocatememory for the nodes of a plane
for (i=0; i<elem_u; i++){P[i]=(Node**)calloc(elem_v, sizeof(Node*));
for (j=0; j<elem_v; j++)P[i][j]=(Node*)calloc(1, sizeof(Node));
}subVectors(&P_n0, &P_00, &u); /* vector in u direction
(non-normalized) */subVectors(&P_0m, &P_00, &v); /* vector in v direction
(non-normalized) */divConstant(&u, &du, (double)(elem_u-1));divConstant(&v, &dv, (double)(elem_v-1));
for (j=0; j<elem_v; j++){
inc=elem_u*j;for (i=0; i<elem_u; i++){/*--- in pseudo code: n[i][j]= P_00 + du*i + dv*j ---*/P[i][j]->id = inc + i + 1 + RefKo.id;P[i][j]->x = i*du.x + j*dv.x + RefKo.x;P[i][j]->y = i*du.y + j*dv.y + RefKo.y;P[i][j]->z = i*du.z + j*dv.z + RefKo.z;}
}return P;}
/*--- Free the memory ---*/destructPlane(Node ***P, int elem_u, int elem_v){
int i,j;for(j=0; elem_v; j++){for(i=0; i<elem_u; i++){cfree(P[i][j]);
}cfree(P[j]);
}cfree(P);
}
/*--- This function will return to the displacement vector ---*/
58
A. THE DUMMY CODE
void AdhoC_Dummy(int n, int m, int change, double* displacementfloat insTime)
/*--- AdhoC_Dummy(node number in u direction, node number inv direction, change, displacement, instantaneous time)---*/
{int index=1;int i,j;float maxEndDisplZ=0.01;if(change==1) /*--- parabolic displacement for all nodes ---*/{for(j=1; j<=m; j++){index= (j-1)*n+1;for (i=0; i<=n; i++, index++){displacement[3*index-3]=0.0;displacement[3*index-2]=((i-1.0)*(i-1.0)/((n-1.0)*(n-1.0))*
maxEndDisplZ*sin(3.14159265*insTime));displacement[3*index-1]=0.0;
}}
}if(change==2) /*--- constant displacement for all nodes ---*/{for(index=1; index<=m*n; index++){
displacement[3*index-3]=0.0;displacement[3*index-2]=maxEndDisplZ*sin(3.14159265*insTime);displacement[3*index-1]=0.0;
}}
return;}
/*--- Combines different partitions of the same mesh ---*/void Associate_partitions(Node ***partition1, Node ***partition2
int n1, int m1, int n2, int m1)
/*--- void Associate_partitions(1st partition, 2nd partition,(1st partition)number of nodes in u direction,(1st partition)number of nodes in v direction,(2nd partition)number of nodes in u direction,(2nd partition)number of nodes in v direction) ---*/
{int i,j,k,l;double eps;eps=0.0001;
for (i=0; i<n1; i++){
59
A. THE DUMMY CODE
for (j=0; j<n1; j++){for (k=0; k<n1; k++){for (l=0; l<m2; l++){If((fabs(partition[i][j]->x - partition[i][j]->x) <=eps) &&(fabs(partition[i][j]->y - partition[i][j]->y) <=eps) &&(fabs(partition[i][j]->z - partition[i][j]->z) <=eps)){cfree(partition[i][j]); /*--- delete one of the objects
that are created on the boundariesof the different partitions ---*/
partition[i][j] = partition[k][l];}
}}
}}
}/*--- Created for debugging purpose ---*/void debug(Node ***partition, int n, int m){int i,j;double eps;eps=1E-6;
for (j=0; j<m; j++){for(i=0; i<n; i++){printf("i=%d, j=%d, i,j");printf("id1 %d, x% lf, y% lf, z% lf \n", partition[i][j]->id,
partition[i][j]->x, partition[i][j]->y, partition[i][j]->z);}
}}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%** ** introduce some variables: ** **%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*--- for the definition of the Partitions: CCI_Def_partitions ---*/int meshId;
/* grid IDs */int partId1, partId3, partId3;
/* partition IDs *//*--- for the definition of the Nodes: CCI_Def_nodes ---*/
60
A. THE DUMMY CODE
int globalDim = 3;/* dimension of the system */
int nNodes1, nNodes2, nNodes3;/* number of nodes (for each partition) */
int nNodesIds1, nNodesIds2, nNodesIds3;/* switch node numbering ; dimension of array of nodeIds*/
int nodeIds1[2000], nodeIds2[2000], nodeIds3[2000];/* actual node IDs*/
int realType = CCI_DOUBLE;/* type of elements of coords */
double coords1[3*2000], coords2[3*2000], coords3[3*2000];/* address of coordinate array */
/*--- for the definition of the Elements: CCI_Def_elements ---*/int nElements1, nElements2, nElements3;
/* number of elements in the mesh */int nElemIds1, nElemIds2, nElemIds3;
/* switch node numbering; dimension of array of nElemIds*/int elemIds1[2000], elemIds2[2000], elemIds3[2000];
/* number of elements in the mesh */int elemTypes1[] = {CCI_ELEM_QUAD}, elemTypes2[] = {CCI_ELEM_QUAD},
elemTypes3[] = {CCI_ELEM_QUAD};/* element type*/
int nNodesPerElem1[] = {4}, nNodesPerElem2[] = {4}, nNodesPerElem3[] = {4};int elemNodes1[nNodesPerElem1[0]*2000], elemNodes2[nNodesPerElem2[0]*2000],
elemNodes3[nNodesPerElem3[0]*2000];
/*--- for the definition of communication with the remote code ---*//* CCI_Get_Nodes */ /* CCI_Put_Nodes */int quantityId;int quantityDim;int valuesDataType;double displacement1[2000*3], displacement2[2000*3], displacement3[2000*3];double force1[2000*3], force2[2000*3], force3[2000*3], fx1, fy1, fz1,
fx2, fy2, fz2, fx3, fy3, fz3;int maxnEmptyNodes;int* EmptyNodes;int nEmptyNodes;
/*--- for the definition of syncronization point: CCI_Def_Sync_point ---*/
int sycnPointId;/* identifier of the syncronization points */
int maxnQuantToSend;int nQuantitiesToSend;
/* number of quantities to be sent */int quantitiesToSend[CCI_MAX_NQUANTITIES];
/* array of quantity-identifiers,length of nQuantitiesToSend */
int nMeshIdsToSend;/* length of meshIdsToSend, either 1 or
61
A. THE DUMMY CODE
nQuantitiesToSend */int meshIdsToSend[CCI_MAX_NQUANTITIES];
/* array of mesh-identifiers,length of MeshIdsToSend */
int maxnQuantToRecv;int nQuantitiesToRecv;
/* number of quantities to be received */int quantitiesToRecv[CCI_MAX_NQUANTITIES];
/* array of quantity-identifiers,length of nQuantitiesToRecv */
int nMeshIdsToRecv;/* length of meshIdsToRecv, either 1 ornQuantitiesToRecv */
int meshIdsToRecv[CCI_MAX_NQUANTITIES];/* array of mesh-identifiers,length of MeshIdsToRecv */
/*--- convergence check ---*/int remoteCodeId;int myConvergenceState;int globalConvergenceState;int error, cont = 1;int comm, Iteration = 0;
/*--- general variables ---*/int i_am_a_cci_process;int change = 1;int index,i,j;double inc;int ix,iy,iNode,nNodex,nNodey,el_id_n,m,n1,n2,n3,m1,m2,m3;double dx,dy,x,y,z;int ElmIndexShift;double deltax = 0,deltay = 0,deltaz = 0;float insTime = 0.0, maxTime = 5.0, deltaTime= 0.1;float eps = 0.0001;
/*--- this part is from plane123.c filedecleration of the plates’ variables ---*/
Node point1, point2, point3;Node ***nodeMatrix_Plane1, ***nodeMatrix_Plane2, ***nodeMatrix_Plane3;Node RefKo1, RefKo2, RefKo3;
/**********************************************************************************************************************************************/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%** ** initialization phase: ** **%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
62
A. THE DUMMY CODE
CCI_Init (&argc, &argv);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%** ** mesh definition phase: ** **%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/***** ----- Define partitions ----- *****/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~** CCI_Def_partition 1 : **~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
meshId = 1;partId1 = 1;CCI_Def_partition(meshId, partId1);printf("... returned from CCI_Def_partition. \n"); fflush(stdout);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~** CCI_Def_partition 2 : **~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
meshId = 1;partId2 = 2;CCI_Def_partition(meshId, partId2);printf("... returned from CCI_Def_partition. \n"); fflush(stdout);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~** CCI_Def_partition 3 : **~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
meshId = 1;partId1 = 3;CCI_Def_partition(meshId, partId3);printf("... returned from CCI_Def_partition. \n"); fflush(stdout);
deltax = 0.25 - 0.001046717167;deltay = 0.21;deltaz = 0.0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Nodes for partition 1 (nodeMatrix_Plane1) **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/n1 = 36, m1 = 42 ;
/* n1 is the node number along the longitudinal(u) direction,m1 is the node number along the transverse(v) direction,respectively */
63
A. THE DUMMY CODE
RefKo1.x = 0.0 + deltax;RefKo1.y = 0.0 + deltay;RefKo1.z = 0.0 + deltaz;RefKo1.id = 0;
/* three points are needed in order to create a planein the global coordinate system */
point1.x = 0.0; point1.y = 0.0; point1.z = 0.0;point2.x = 0.35 + 0.001046717167; point2.y = 0.0; point2.z = 0.0;point3.x = 0.0; point3.y = 0.0; point3.z = 0.41;
nodeMatrix_Plane1 = createPlane(Refko, point1, point2, point3, n1, m1);/* nodeMatrix_Plane1=createPlane(Refko,1st point,2nd point,3rd point,n1,m1) */
nNodes1 = m1 * n1;/* number of nodes */
nNodesIds1 = nNodes1;/* switch node numbering */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Nodes for partition 2 (nodeMatrix_Plane2) **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
n2 = 36, m2 = 42 ;
RefKo2.x = 0.0 + deltax;RefKo2.y = -0.02 + deltay;RefKo2.z = 0.0 + deltaz;RefKo2.id = 1512;
point1.x = 0.0; point1.y = 0.0; point1.z = 0.0;point2.x = 0.35 + 0.001046717167; point2.y = 0.0; point2.z = 0.0;point3.x = 0.0; point3.y = 0.0; point3.z = 0.41;
nodeMatrix_Plane2 = createPlane(Refko, point1, point2, point3, n2, m2);/* nodeMatrix_Plane2=createPlane(Refko,1st point,2nd point,3rd point,n2,m2) */
nNodes2 = m2 * n2;/* number of nodes */
nNodesIds2 = nNodes2;/* switch node numbering */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Nodes for partition 3 (nodeMatrix_Plane3) **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
n1 = 3, m1 = 42 ;
RefKo1.x = 0.0 + deltax;RefKo1.y = 0.0 + deltay;
64
A. THE DUMMY CODE
RefKo1.z = 0.0 + deltaz;RefKo1.id = 0;
point1.x = 0.35 + 0.001046717167; point1.y = 0.0; point1.z = 0.0;point2.x = 0.35 + 0.001046717167; point2.y = 0.02; point2.z = 0.0;point3.x = 0.35 + 0.001046717167; point3.y = 0.0; point3.z = 0.41;
nodeMatrix_Plane3 = createPlane(Refko, point1, point2, point3, n3, m3);/* nodeMatrix_Plane3=createPlane(Refko,1st point,2nd point,3rd point,n3,m3) */
nNodes3 = m3 * n3;/* number of nodes */
nNodesIds3 = nNodes3;/* switch node numbering */
/***** ----- Associate node partitions ----- *****/
printf("... begin associating nodes. \n"); fflush(stdout);Associate_partitions (nodeMatrix_Plane1, nodeMatrix_Plane3,n1,m1,n3,m3);
Associate_partitions (nodeMatrix_Plane2, nodeMatrix_Plane3,n2,m2,n3,m3);printf("... returned Associate_partitions. \n"); fflush(stdout);
/***** ----- for debugging ----- *****/printf("********* Plane1 *********\n");debug (nodeMatrix_Plane1, 36, 42);
printf("********* Plane2 *********\n");debug (nodeMatrix_Plane2, 36, 42);
printf("********* Plane3 *********\n");debug (nodeMatrix_Plane3, 3, 42);
/***** ----- Create node matrices ----- *****/
for (j=0; iNode=1; j<m1, j++){for (i=0; i<n1; i++, ++iNode){nodeIds1[iNode-1] = nodeMatrix_Plane1[i][j] -> id;coodrs1[(iNode-1)*globalDim + 0] = nodeMatrix_Plane1[i][j] -> x;coodrs1[(iNode-1)*globalDim + 1] = nodeMatrix_Plane1[i][j] -> y;coodrs1[(iNode-1)*globalDim + 0] = nodeMatrix_Plane1[i][j] -> z;
}}
for (j=0; iNode=1; j<m2, j++){for (i=0; i<n2; i++, ++iNode){nodeIds2[iNode-1] = nodeMatrix_Plane2[i][j] -> id;
65
A. THE DUMMY CODE
coodrs2[(iNode-1)*globalDim + 0] = nodeMatrix_Plane2[i][j] -> x;coodrs2[(iNode-1)*globalDim + 1] = nodeMatrix_Plane2[i][j] -> y;coodrs2[(iNode-1)*globalDim + 0] = nodeMatrix_Plane2[i][j] -> z;
}}
for (j=0; iNode=1; j<m3, j++){for (i=0; i<n3; i++, ++iNode){nodeIds3[iNode-1] = nodeMatrix_Plane3[i][j] -> id;coodrs3[(iNode-1)*globalDim + 0] = nodeMatrix_Plane3[i][j] -> x;coodrs3[(iNode-1)*globalDim + 1] = nodeMatrix_Plane3[i][j] -> y;coodrs3[(iNode-1)*globalDim + 0] = nodeMatrix_Plane3[i][j] -> z;
}}
/***** ----- Define CCI_Def_nodes ----- *****/
printf("... calling CCI_Def_nodes ... \n"); fflush(stdout);/* to observe the progress */
CCI_Def_nodes ( meshId, partId1,globalDim, nNodes1,nNodesIds1, nodeIds1,realType, coords1);
CCI_Def_nodes ( meshId, partId2,globalDim, nNodes2,nNodesIds2, nodeIds2,realType, coords2);
CCI_Def_nodes ( meshId, partId3,globalDim, nNodes3,nNodesIds3, nodeIds3,realType, coords3);
printf("... returned from CCI_Def_nodes ... \n"); fflush(stdout);/* to observe the progress */
/***** ----- Create node matrices ----- *****/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~** CCI_Def_elems 1 : **~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
nElements1 = (m1-1)*(n1-1);/* n1 and m1 are the numbers of the nodes in 2D */
nElemIds1 = nElements1;nElemTypes1 = 1;
for(index=0; index<nElements1; ++index) elemIds1[index]=index+1;/* create elements and assign a number each of them */
/* m_el = m-1; n_el =n-1; for (i=1; i<m_el;i++)... */
66
A. THE DUMMY CODE
for (j=1; j<m1, j++){for (i=1; i<n1; i++){el_id = (j-1)*(n1-1) + i;
/* printf("Element ID %d, i:%d, j:%d\n", el_id, i,j); */
/* printf("elemNode1 %d,\n", nodeMatrix_Plane1[i-1][j-1] ->id); */elemNodes1[4*(el_id-1) + 0] = nodeMatrix_Plane1[i-1][j-1]->id;
/* printf("elemNode2 %d,\n", nodeMatrix_Plane1[i][j-1] ->id); */elemNodes1[4*(el_id-1) + 1] = nodeMatrix_Plane1[i][j-1]->id;
/* printf("elemNode4 %d,\n", nodeMatrix_Plane1[i][j] ->id); */elemNodes1[4*(el_id-1) + 2] = nodeMatrix_Plane1[i][j]->id;
/* printf("elemNode3 %d,\n", nodeMatrix_Plane1[i-1][j] ->id); */elemNodes1[4*(el_id-1) + 3] = nodeMatrix_Plane1[i-1][j]->id;
}}
printf("... calling CCI_Def_elements. Part 1. \n"); fflush(stdout);
CCI_Def_elems ( meshId, partId1,nElements1, nElemIds1,elemIds1, nElemTypes1,elemTypes1, nNodesPerElem1,elemNodes1);
printf("... returned from CCI_Def_elements. Part 1. \n"); fflush(stdout);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** CCI_Def_elems 3 : !!!!! MUST BE BEFORE CCI_Def_elems 2 !!!!! **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
nElements3 = (m3-1)*(n3-1);/* n3 and m3 are the numbers of the nodes in 2D */
nElemIds3 = nElements3;nElemTypes3 = 1;
ElmIndexShift = nElements1 ;
for(index=0 + ElmIndexShift ; index<nElements3 + ElmIndexShift; ++index){elemIds3[index - ElmIndexShift]=index+1;
/* printf("%d\n", elemIds3[index - ElmIndexShift]); */}
/* m_el = m-1; n_el =n-1; for (i=1; i<m_el;i++)... */
67
A. THE DUMMY CODE
for (j=1; j<m3, j++){for (i=1; i<n3; i++){el_id = (j-1)*(n3-1) + i;
/* printf("Element ID %d, i:%d, j:%d\n", el_id, i,j); */
/* printf("elemNode1 %d,\n", nodeMatrix_Plane3[i-1][j-1] ->id); */elemNodes3[4*(el_id-1) + 0] = nodeMatrix_Plane3[i-1][j-1]->id;
/* printf("elemNode2 %d,\n", nodeMatrix_Plane3[i][j-1] ->id); */elemNodes3[4*(el_id-1) + 1] = nodeMatrix_Plane3[i][j-1]->id;
/* printf("elemNode4 %d,\n", nodeMatrix_Plane3[i][j] ->id); */elemNodes3[4*(el_id-1) + 2] = nodeMatrix_Plane3[i][j]->id;
/* printf("elemNode3 %d,\n", nodeMatrix_Plane3[i-1][j] ->id); */elemNodes3[4*(el_id-1) + 3] = nodeMatrix_Plane3[i-1][j]->id;
}}
printf("... calling CCI_Def_elements. Part 3. \n"); fflush(stdout);
CCI_Def_elems ( meshId, partId3,nElements3, nElemIds3,elemIds3, nElemTypes3,elemTypes3, nNodesPerElem3,elemNodes3);
printf("... returned from CCI_Def_elements. Part 3. \n"); fflush(stdout);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~** CCI_Def_elems 2 : **~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
nElements1 = (m2-1)*(n2-1);/* n2 and m2 are the numbers of the nodes in 2D */
nElemIds2 = nElements2;nElemTypes2 = 1;
ElmIndexShift = nElements1 + nElements3;
for(index=0 + ElmIndexShift ; index<nElements2 + ElmIndexShift; ++index){elemIds2[index - ElmIndexShift]=index+1;
/* printf("%d\n", elemIds3[index - ElmIndexShift]); */}
/* m_el = m-1; n_el =n-1; for (i=1; i<m_el;i++)... */
for (j=1; j<m2, j++)
68
A. THE DUMMY CODE
{for (i=1; i<n2; i++){el_id = (j-1)*(n2-1) + i;
/* printf("Element ID %d, i:%d, j:%d\n", el_id, i,j); */
/* printf("elemNode2 %d,\n", nodeMatrix_Plane1[i-1][j-1] ->id); */elemNodes2[4*(el_id-1) + 0] = nodeMatrix_Plane2[i-1][j-1]->id;
/* printf("elemNode2 %d,\n", nodeMatrix_Plane2[i][j-1] ->id); */elemNodes2[4*(el_id-1) + 1] = nodeMatrix_Plane2[i][j-1]->id;
/* printf("elemNode4 %d,\n", nodeMatrix_Plane2[i][j] ->id); */elemNodes2[4*(el_id-1) + 2] = nodeMatrix_Plane2[i][j]->id;
/* printf("elemNode3 %d,\n", nodeMatrix_Plane2[i-1][j] ->id); */elemNodes2[4*(el_id-1) + 3] = nodeMatrix_Plane2[i-1][j]->id;
}}
printf("... calling CCI_Def_elements. Part 2. \n"); fflush(stdout);
CCI_Def_elems ( meshId, partId2,nElements2, nElemIds2,elemIds2, nElemTypes2,elemTypes2, nNodesPerElem2,elemNodes2);
printf("... returned from CCI_Def_elements. Part 2. \n"); fflush(stdout);
/**********************************************************************************************************************************************/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Syncronization Point 1 : CCI_Def_Sync_point **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
syncPointId=1;maxnQuantToSend = CCI_MAX_NQUANTITIES;maxnQuantToRecv = CCI_MAX_NQUANTITIES;
printf("... calling CCI_Sync_point_info ... \n"); fflush(stdout);
CCI_Sync_point_info ( syncPointId,CCI_MAX_NQUANTITIES,quantitiesToSend,meshIdsToSend,&nQuantitiesToSend,CCI_MAX_NQUANTITIES,quantitiesToSend,meshIdsToRecv,
69
A. THE DUMMY CODE
&nQuantitiesToRecv);
printf("... returned from CCI_Sync_point_info ... \n"); fflush(stdout);
nMeshIdsToSend = nQuantitiesToSend;/* to send each quantities we need a mesh */
nMeshIdsToRecv = nQuantitiesToRecv;
printf("... calling CCI_Def_sync_point ... \n"); fflush(stdout);
CCI_Def_sync_point ( syncPointId,nQuantitiesToSend,quantitiesToSend,nMeshIdsToSend,meshIdsToSend,nQuantitiesToRecv,quantitiesToRecv,nMeshIdsToRecv,meshIdsToRecv);
printf("... returned from CCI_Def_sync_point ... \n"); fflush(stdout);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Syncronization Point 2 : ** for sending displacements to CFX **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
syncPointId=2;maxnQuantToSend = CCI_MAX_NQUANTITIES;maxnQuantToRecv = CCI_MAX_NQUANTITIES;
CCI_Sync_point_info ( syncPointId,CCI_MAX_NQUANTITIES,quantitiesToSend,meshIdsToSend,&nQuantitiesToSend,CCI_MAX_NQUANTITIES,quantitiesToSend,meshIdsToRecv,&nQuantitiesToRecv);
nMeshIdsToSend = nQuantitiesToSend;/* to send each quantities we need a mesh */
nMeshIdsToRecv = nQuantitiesToRecv;
CCI_Def_sync_point ( syncPointId,nQuantitiesToSend,quantitiesToSend,nMeshIdsToSend,meshIdsToSend,nQuantitiesToRecv,
70
A. THE DUMMY CODE
quantitiesToRecv,nMeshIdsToRecv,meshIdsToRecv);
i_am_a_cci_process = 1;/* Close definition phase */
CCI_Close_setup(i_am_a_cci_process);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%** ** coupled computation phase: ** **%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
do{insTime = insTime + deltaTime;printf("Inst.time = %lf \n", insTime);printf("Max.time = %lf \n", maxTime);
/***** ----- Get the values from the MpCCI ----- *****/
for(index=1; index<=3*nNodes1; index++){force1[index] = 0.0;
}for(index=1; index<=3*nNodes2; index++){force2[index] = 0.0;
}for(index=1; index<=3*nNodes3; index++){force3[index] = 0.0;
}fx1 = 0.0; fy1 = 0.0; fz1 = 0.0;fx2 = 0.0; fy2 = 0.0; fz2 = 0.0;fx3 = 0.0; fy3 = 0.0; fz3 = 0.0;
printf("before Sync. point ID 1 \n", insTime);/* for debugging */
syncPointId = 1;quantityId = 2;
/* forces have ID 2 */quantityDim = 3;valuesDataType = CCI_DOUBLE_PRECISION;maxnEmptyNodes = 0;
CCI_Status status;printf("before CCI_Reach_sync_point 1 \n");
/* for debugging */CCI_Reach_sync_point (syncPointId, &status);
71
A. THE DUMMY CODE
/*~~~~~~~~~~~~~~~~~~~~~~** Partition 1 : **~~~~~~~~~~~~~~~~~~~~~~*/
printf("before CCI_Get_nodes Part 1 \n");
CCI_Get_nodes(meshId,partId1,quantityId,quantityDim,nNodes1,nNodesIds1,nodeIds1,valuesDataType,force1, /* the force vector */maxnEmptyNodes,EmptyNodes,&nEmptyNodes);
/*~~~~~~~~~~~~~~~~~~~~~~** Partition 2 : **~~~~~~~~~~~~~~~~~~~~~~*/
printf("before CCI_Get_nodes Part 2 \n");
CCI_Get_nodes(meshId,partId2,quantityId,quantityDim,nNodes2,nNodesIds2,nodeIds2,valuesDataType,force2, /* the force vector */maxnEmptyNodes,EmptyNodes,&nEmptyNodes);
/*~~~~~~~~~~~~~~~~~~~~~~** Partition 3 : **~~~~~~~~~~~~~~~~~~~~~~*/
printf("before CCI_Get_nodes Part 3 \n");
CCI_Get_nodes(meshId,partId3,quantityId,quantityDim,nNodes3,nNodesIds3,nodeIds3,valuesDataType,force3, /* the force vector */maxnEmptyNodes,
72
A. THE DUMMY CODE
EmptyNodes,&nEmptyNodes);
/***** ----- Check sum of the incoming forces ----- *****/
for(index=1; index<=nNodes1; index++){fx1 = fx1 + force1[3*index - 2];fy1 = fy1 + force1[3*index - 1];fz1 = fz1 + force1[3*index];
}for(index=1; index<=nNodes2; index++){fx2 = fx2 + force2[3*index - 2];fy2 = fy2 + force2[3*index - 1];fz2 = fz2 + force2[3*index];
}for(index=1; index<=nNodes3; index++){fx3 = fx3 + force3[3*index - 2];fy3 = fy3 + force3[3*index - 1];fz3 = fz3 + force3[3*index];
}
printf(sum of the forces (partition 1) received by AdhoC_Dummy =%4.2f", sqrt(fx1*fx1 + fy1*fy1 + fz1*fz1));
printf(sum of the forces (partition 2) received by AdhoC_Dummy =%4.2f", sqrt(fx2*fx2 + fy2*fy2 + fz2*fz2));
printf(sum of the forces (partition 3) received by AdhoC_Dummy =%4.2f", sqrt(fx3*fx3 + fy3*fy3 + fz3*fz3));
/***** ----- Calculation of the displacements ----- *****/
printf("before calling AdhoC_Dummy \n");change = 1;
/* parabolic displacement of the nodes of the firstand second plane */
AdhoC_Dummy (n1,m1,change,displacement1,insTime);/* returns to the displacement vector */
AdhoC_Dummy (n2,m2,change,displacement2,insTime);/* returns to the displacement vector */
change = 1;/* constant displacement for all nodes of the third plane */
AdhoC_Dummy (n3,m3,change,displacement3,insTime);/* returns to the displacement vector */
printf("before Sync. point 2 \n");
73
A. THE DUMMY CODE
/* Put the displacements into MpCCI */syncPointId = 2;quantityId = 1;
/* forces have ID 1 */quantityDim = 3;valuesDataType = CCI_DOUBLE_PRECISION;
/***** ----- Send the values to the MpCCI ----- *****/
/*~~~~~~~~~~~~~~~~~~~~~~** Partition 1 : **~~~~~~~~~~~~~~~~~~~~~~*/
CCI_Put_nodes(meshId,partId1,quantityId,quantityDim,nNodes1,nNodesIds1,nodeIds1,valuesDataType,displacement1); /* the displacement vector */
/*~~~~~~~~~~~~~~~~~~~~~~** Partition 2 : **~~~~~~~~~~~~~~~~~~~~~~*/
CCI_Put_nodes(meshId,partId2,quantityId,quantityDim,nNodes2,nNodesIds2,nodeIds2,valuesDataType,displacement2); /* the displacement vector */
/*~~~~~~~~~~~~~~~~~~~~~~** Partition 3 : **~~~~~~~~~~~~~~~~~~~~~~*/
CCI_Put_nodes(meshId,partId3,quantityId,quantityDim,nNodes3,nNodesIds3,nodeIds3,valuesDataType,displacement3); /* the displacement vector */
74
A. THE DUMMY CODE
CCI_Reach_sync_point (syncPointId, &status);
/***** ----- Iteration Control ----- *****/
myConvergenceState = CCI_CONTINUE;remoteCode = 2;comm = CCI_COMM_RCODE[remoteCodeId];error = CCI_Check_convergence(myConvergenceState,
&globalConvergenceState, comm);printf("error = %d\n", error);switch(globalConvergenceState){case CCI_CONVERGED:cont = 1;printf("case CCI_CONVERGED, cont = %d\n", cont);break;
case CCI_CONTINUE:cont = 1;printf("case CCI_CONTINUE, cont = %d\n", cont);break;
case CCI_STOP:cont = 0;printf("case CCI_STOP, cont = %d\n", cont);break;
case CCI_DIVERGED:cont = 0;printf("case CCI_DIVERGED, cont = %d\n", cont);break;
}
Iteration++;printf("iteration number = %d\n", Iteration);If(Iteration == 50) cont =0;
}while (cont);/* fabs(maxTime - insTime)<=eps */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%** ** termination phase: ** **%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
CCI_Finalize();printf("CCI_Finalize\n");return 0;
}
75
B. PYTHON SCRIPT
#!/usr/bin/env python
# This script reads a MonitorPointFile and filters it# using given data in order to obtain suitable format for gnuplot
import sysfrom Numeric import *
resultList = [] # for global result listscale = 200 #scaling for depth
def readHeader( fileIn, iterationCounterName, colNames ):# it will be the column number of iterationCounters
iterationCounter=0# list of column numbers of the result of interest
cols=[]# aktuel column number
colPos = 0for line in fileIn:
if line.find("@END@") > -1:return (iterationCounter,cols)
if line.find(iterationCounterName) == 0:iterationCounter = colPos
for n in colNames:if line.find(n) == 0:
cols.append(colPos)# rows with "@" will not be accepted as column name
if line.find("@") == -1:colPos += 1
def processData( fileIn, fileOut, iterationCounter, cols):prevLine=[]fileIn.seek(0)while fileIn.readline().find("@END@") == -1:
pass
# local definition, result will be writtendef writeResultLine():
res=[]# c is an index of prevLine
76
B. PYTHON SCRIPT
for c in cols:res.append(prevLine[c])
# res is a list of the row of the filtered resultsfileOut.write(" ".join(res))fileOut.write("\n") # "\n\r" fur windows
# global result list for calculation of mean valueresultList.append(res[0])
# print #float(res[0])
for l in fileIn:# print l
line = l.strip().split(",")# print line[5]
if prevLine == []:prevLine = linecontinue
if prevLine[iterationCounter] >= line[iterationCounter]:writeResultLine()
prevLine = linewriteResultLine()
################# main program ##############################
if len(sys.argv) < 5:print "usage : %s inFile outFile iteratorColName
resultColName_1 [... resultColName_n]"%sys.argv[0]sys.exit(0)
# open filesfileIn = open(sys.argv[1],"r")fileOut = open(sys.argv[2],"w")# read Header(iterationCounter,cols) = readHeader(fileIn, sys.argv[3], sys.argv[4:])processData(fileIn,fileOut,iterationCounter,cols)fileIn.close()fileOut.close()# setting things to 0sum = 0.0vonwo = 1500biswo = 2000mean = 0.0plus = 0.0minus = 0.0# consider the last results onlyresultList = resultList[vonwo:biswo]# convert contents of list into floatsresultList = map(float,resultList)
for n in resultList:sum = sum + float(n)
77
B. PYTHON SCRIPT
summax = 0.0summin =0.0min = [] # list of minimumsmax = [] # list of maximumsmean = (sum/len(resultList))for n in resultList:n = n - mean
for i in range(len(resultList)-2):if ((resultList[i+1]<=resultList[i]) and
(resultList[i+1]<= resultList[i+2])):min.append(resultList[i+1])summin = summin + resultList[i+1]
if ((resultList[i+1]>=resultList[i]) and(resultList[i+1]>= resultList[i+2])):
max.append(resultList[i+1])summax = summax + resultList[i+1]
meanmax = (summax/len(max))*scalemeanmin = (summin/len(min))*scale
resultList = asarray (resultList) # convert list into array
max = asarray (max)min = asarray (min)plusminus = abs(meanmax-meanmin)print meanmaxprint meanminprint plusminus/2#print resultList*scaleprint mean*scaleprint ’end’}
78