This course material is about Gerris, a general-purpose fluid mechanics code developped by Stephane Popinet at NIWA, Wellington, New Zealand. Gerris is a free, GPL-licensed, open source code available at [[http://gfs.sf.net http://gfs.sf.net]] .

+

This course material is about Gerris, a general-purpose fluid mechanics code developed by [[User:Popinet|St&eacute;phane Popinet]] at NIWA, Wellington, New Zealand. Gerris is a free, GPL-licensed, open source code available at [http://gfs.sf.net http://gfs.sf.net].

-

The intended audience is typical first-year science or engineering graduate students with either very little experience of C or with some Fortran knowledge, but willing to work hard and learn. The student should know simple C data types, pointers and functions but not structures.

+

The intended audience is typical first-year science or engineering graduate students with either very little experience of C or with some Fortran knowledge, but willing to work hard and learn. The student should know simple C data types, pointers and functions but not structures.

-

The course is being taught as of writing (october 2007) in Paris. In the actual course a lot of talking is done in addition to the material here. Each session is 30 minutes + 15 minutes of questions.

+

[[User:Zaleski|S. Zaleski]] has taught the course several times in Paris. In the actual course a lot of talking is done in addition to the material here. Each session is 30 minutes + 15 minutes of questions.

-

== Session 1 ==

-

+

#[[Introduction to Gerris Programming]]

-

=== Introduction ===

+

#[[The Fully Threaded Tree]]

-

+

#[[The Fluid Domain]]

-

+

#[[Programming the Advection Scheme]]

-

+

#[[The Gerris Object System]]

-

This course is about how Gerris ([[http://gfs.sf.net]] ) is programmed. It is intended to help in understanding the Gerris source code and learning how to modify it usefully.

+

#[[An Example of Use of the Gerris Object System]]

-

+

#[[GfsView]]

-

This course is not about the numerical methods in Gerris (however it would be good for students of this course to learn about them, for instance in the J. Comput. Phys. article) .

+

#[[Values, macros and structures in Gerris]]

-

+

-

Gerris is closely linked to Gts, the GNU triangulated surface library, also written by Stephane Popinet

+

-

+

-

Gerris and Gts are programmed in a style analogous to that of Glib, Gnome and GTK . It is a style of C programming that offers several advantages:

+

-

+

-

* Most aspects of Object-Oriented Programming (OOP) , such as the existence of classes with their own methods and inheritance.

+

-

+

-

* The ability to interface to other programming languages. (As far as I know, this feature is not used in Gerris/Gts)

+

-

+

-

To implement Object-Oriented Programming, Gerris/Gts uses its own “Object system”. This system is analogous to the Glib object system (Gobject), but not identical to it. Learning more about Gobject can be very useful.

+

-

+

-

=== References and reading material ===

+

-

+

-

* Introduction and in-depth discussion of the Gobject system (in order of decreasing ease of reading):

There is no good order in which to read the code (I have not found it yet).

+

-

+

-

+

-

==== Keep a C precedence and associativity table nearby ====

+

-

+

-

A lot of macros and functions such g_assert come from the Glib.

+

-

Keep a bookmark to the Glib documentation: [[http://library.gnome.org/devel/glib/unstable/index.html]]

+

-

+

-

+

-

=== C basics ===

+

-

+

-

==== Introduction to Structures ====

+

-

+

-

+

-

<source c>

+

-

struct Point {

+

-

char name;

+

-

double x, y;

+

-

};

+

-

</source>

+

-

+

-

An example of usage

+

-

+

-

<source c>

+

-

﻿main()

+

-

{

+

-

struct Point my_point; /* declaration */

+

-

+

-

my_point.x = 0. ;

+

-

my_point.y = 1.;

+

-

my_point.name = ‘A’;

+

-

}

+

-

</source>

+

-

+

-

name, x and y are members of the structure of type “Point” called my_point. We also give it a name that can be exported (printed, passed to other functions) as a character. This example shows why it is useful to use structures to store several relevant informations or data together.

+

-

+

-

==== An example: the structure GfsNorm in Gerris ====

+

-

+

-

<source c>

+

-

struct _GfsNorm {

+

-

gdouble bias, first, second, infty, w;

+

-

};

+

-

typedef struct _GfsNorm GfsNorm

+

-

</source>

+

-

+

-

From ''domain.h''.

+

-

+

-

<source c>

+

-

﻿GfsNorm gfs_domain_norm_residual (GfsDomain * domain,

+

-

FttTraverseFlags flags,

+

-

gint max_depth,

+

-

gdouble dt,

+

-

GfsVariable * res)

+

-

{

+

-

GfsNorm n;

+

-

gpointer data[2];

+

-

+

-

g_return_val_if_fail (domain != NULL, n);

+

-

g_return_val_if_fail (res != NULL, n);

+

-

+

-

gfs_norm_init (&n);

+

-

data[0] = res;

+

-

data[1] = &n;

+

-

gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth,

+

-

(FttCellTraverseFunc) add_norm_residual, data);

+

-

#ifdef HAVE_MPI

+

-

domain_norm_reduce (domain, &n);

+

-

#endif /* HAVE_MPI */

+

-

gfs_norm_update (&n);

+

-

+

-

dt *= dt;

+

-

n.bias *= dt;

+

-

n.first *= dt;

+

-

n.second *= dt;

+

-

n.infty *= dt;

+

-

return n;

+

-

}

+

-

</source>

+

-

+

-

From ''domain.c''

+

-

+

-

Notice the use of

+

-

+

-

* glib basic types ''gdouble, gpointer''

+

-

+

-

* glib functions ''g_return_val_if_fail''

+

-

+

-

+

-

===== Note =====

+

-

+

-

This is what the [[http://library.gnome.org/devel/glib/unstable/index.html glib documentation]] says about <code>gpointer</code>

+

-

+

-

<pre>typedef void* gpointer;

+

-

+

-

An untyped pointer. gpointer looks better and is easier to use than void*.

+

-

</pre>

+

-

+

-

==== Structures that are related to other structures ====

+

-

+

-

More complex relationships between structures create the need for ''inheritance''.

+

-

+

-

Below one defines two structures which have some similarities.

+

-

The ''Square'' is a kind of ''Quadrangle''.

+

-

+

-

<source c>

+

-

struct _Quadrangle {

+

-

Point A, B, C, D;

+

-

};

+

-

+

-

typedef struct _Quadrangle Quadrangle

+

-

</source>

+

-

+

-

Notice that we use typedef: this creates an "alias" for the structure name and will

+

-

make it able to refer to itself in its list of member names.

+

-

+

-

<source c>

+

-

﻿/* Related structure */

+

-

+

-

struct _Square {

+

-

Point A, B, C, D;

+

-

};

+

-

+

-

typedef struct _Square Square

+

-

</source>

+

-

+

-

In the following ''pseudo-code'' we use the structures, for instance we define

+

-

a function that computes the area.

+

-

+

-

<source c>

+

-

area_Quadrangle (Quadrangle X )

+

-

{

+

-

Triangle ABC;

+

-

ABC = create_triangle(X.A,X.B,X.C);

+

-

…

+

-

return area_Triangle (ABC) + area_Triangle (CDA) ;

+

-

}

+

-

</source>

+

-

+

-

If we use squares, we may need a very similar function to compute the area of

+

-

squares.

+

-

<source c>

+

-

area_Square ( Square Y )

+

-

{

+

-

…

+

-

return area_Triangle (ABC) + area_Triangle (CDA) ;

+

-

}

+

-

</source>

+

-

+

-

+

-

=== Elementary classes ===

+

-

+

-

* We want to avoid such repetitions.

+

-

+

-

* Notion of parent structure: Quadrangle is the parent of Square.

+

-

One shall from now on use the “class” terminology. A class is a structure with some

+

-

functions attached to it, the functions are called methods. This should become clearer in

+

-

what follows.

+

-

+

-

==== Simple example : structures with inheritance ====

+

-

+

-

<source c>

+

-

struct _Square {

+

-

Quadrangle parent;

+

-

double longueur_du_cote;

+

-

};

+

-

+

-

typedef struct _Square Square

+

-

+

-

main()

+

-

{

+

-

Square MySquare ; /* Déclaration of Square */

+

-

double area;

+

-

+

-

Initialize_Square(&MySquare) ; /*Initialisation */

+

-

area = area_Square ( MySquare ) ;

+

-

}

+

-

</source>

+

-

+

-

Problem: for each class we need a new function giving the area

+

-

<code> area_Square, area_Quadrangle, </code> etc…

+

-

So we will define the function "area_square" quite simply from "area_quadrangle".

* In the "magical" approach we just now that <code>GFS_VARIABLE(somecell,somevariable->i)</code>allows us to write to the variable <code>somevariable</code>in the cell <code>somecell</code>. For us ''dummies'' a question may arise: what value should the index ''i'' have ? Is it the cell number ? Well ''i'' is not an index: it is a member of ''each'' GfsVariable. We do not have to set it: it is already there in the variable.

+

-

+

-

* In the rational approach, we would like to read the code and understand the definition of <code>GFS_VARIABLE</code>. However the definition of the <code>GFS_VARIABLE</code> macro is a bit baffling. It can be found in <code>fluid.h</code>. (It is a good idea to try the following: find any place in the code where the <code>GFS_VARIABLE</code> macro is used ---that should be easy--- and then click on it. Type M-. in emacs ---or the equivalent in vim--- and get to the definition.)

* In the "magical" approach we just now that <code>GFS_VARIABLE(somecell,somevariable->i)</code>allows us to write to the variable <code>somevariable</code>in the cell <code>somecell</code>. For us ''dummies'' a question may arise: what value should the index ''i'' have ? Is it the cell number ? Well ''i'' is not an index: it is a member of ''each'' GfsVariable. We do not have to set it: it is already there in the variable.

+

-

+

-

* In the rational approach, we would like to read the code and understand the definition of <code>GFS_VARIABLE</code>. However the definition of the <code>GFS_VARIABLE</code> macro is a bit baffling. It can be found in <code>fluid.h</code>. (It is a good idea to try the following: find any place in the code where the <code>GFS_VARIABLE</code> macro is used ---that should be easy--- and then click on it. Type M-. in emacs ---or the equivalent in vim--- and get to the definition.)

Current revision

Preamble

This course material is about Gerris, a general-purpose fluid mechanics code developed by Stéphane Popinet at NIWA, Wellington, New Zealand. Gerris is a free, GPL-licensed, open source code available at http://gfs.sf.net.

The intended audience is typical first-year science or engineering graduate students with either very little experience of C or with some Fortran knowledge, but willing to work hard and learn. The student should know simple C data types, pointers and functions but not structures.

S. Zaleski has taught the course several times in Paris. In the actual course a lot of talking is done in addition to the material here. Each session is 30 minutes + 15 minutes of questions.