# Gerris Flow Solver Programming Course for Dummies

(Difference between revisions)
+
-                                                                                                                                     % cd src                                                                                                                                                                                                                                                                                       +
-                                                                                                                                     % make tags                                                                                                                                                                                                                                                                                    +
-
+ - + - # In emacs: + - ## open any *.c or *.h file with emacs. + - ## Position the cursor on a function or variable. + - ## do ESC . to find its definition. (or M-. using the emacs Meta key convention ) + - ## do ESC * to return to the previous location (s) . + - # In vim: + - ## to be written ... + - + - + - ==== No order in which to read the code ==== + - + - 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 ==== + - + - + - + - struct Point { + - char name; + - double x, y; + - }; + - + - + - An example of usage + - + - + - ﻿main() + - { + - struct Point my_point; /* declaration */ + - + - my_point.x = 0. ; + - my_point.y = 1.; + - my_point.name = ‘A’; + - } + - + - + - 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 ==== + - + - + - struct _GfsNorm { + - gdouble bias, first, second, infty, w; + - }; + - typedef struct _GfsNorm GfsNorm + - + - + - From ''domain.h''. + - + - + - ﻿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; + - } + - + - + - 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 gpointer + - + -
typedef void* gpointer;                                                                                                                                                                                                                                                                   +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     An untyped pointer. gpointer looks better and is easier to use than void*.                                                                                                                                                                                                                     +
-
+
-                                                                                                                                     % gtstemplate                                                                                                                                                                                                                                                                                  +
-                                                                                                                                     Usage: gtstemplate [OPTIONS] Class ParentClass                                                                                                                                                                                                                                                 +
-                                                                                                                                     Options:                                                                                                                                                                                                                                                                                       +
-                                                                                                                                     [--no-extra-data]                                                                                                                                                                                                                                                                              +
-                                                                                                                                     [--no-extra-method]                                                                                                                                                                                                                                                                            +
-                                                                                                                                     % gtstemplate Square Quadrangle                                                                                                                                                                                                                                                                +
-
+
-                                                                                                                                     /* Daniel: Header */                                                                                                                                                                                                                                                                           +
-                                                                                                                                     #include                                                                                                                                                                                                                                                                               +
-                                                                                                                                     #include                                                                                                                                                                                                                                                                             +
-                                                                                                                                     #include                                                                                                                                                                                                                                                                                +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     typedef struct _Daniel         Daniel;                                                                                                                                                                                                                                                         +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     struct _Daniel {                                                                                                                                                                                                                                                                               +
-                                                                                                                                     /*< private >*/                                                                                                                                                                                                                                                                                +
-                                                                                                                                     GfsGenericInit parent;                                                                                                                                                                                                                                                                         +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     /*< public >*/                                                                                                                                                                                                                                                                                 +
-                                                                                                                                     gdouble m;                                                                                                                                                                                                                                                                                     +
-                                                                                                                                     };                                                                                                                                                                                                                                                                                             +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     typedef struct _DanielClass    DanielClass;                                                                                                                                                                                                                                                    +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     struct _DanielClass {                                                                                                                                                                                                                                                                          +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     GfsGenericInitClass parent_class;                                                                                                                                                                                                                                                              +
-                                                                                                                                     /*< public >*/                                                                                                                                                                                                                                                                                 +
-                                                                                                                                     /* add extra methods here */                                                                                                                                                                                                                                                                   +
-                                                                                                                                     };                                                                                                                                                                                                                                                                                             +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     #define DANIEL(obj)            GTS_OBJECT_CAST (obj,\                                                                                                                                                                                                                                          +
-                                                                                                                                     Daniel,\                                                                                                                                                                                                                                                                                       +
-                                                                                                                                     daniel_class ())                                                                                                                                                                                                                                                                               +
-                                                                                                                                     #define DANIEL_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\                                                                                                                                                                                                                                  +
-                                                                                                                                     DanielClass,\                                                                                                                                                                                                                                                                                  +
-                                                                                                                                     daniel_class())                                                                                                                                                                                                                                                                                +
-                                                                                                                                     #define IS_DANIEL(obj)         (gts_object_is_from_class (obj,\                                                                                                                                                                                                                                +
-                                                                                                                                     daniel_class ()))                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     DanielClass * daniel_class  (void);                                                                                                                                                                                                                                                            +
-
+ - Did you notice the change ? We are using GfsGenericInit as the parent class of Daniel, not GfsInit. + - Can you explain why ? + - Now we define the read, write etc.. functions + -
+
-                                                                                                                                     /* Daniel: Object */                                                                                                                                                                                                                                                                           +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     static void daniel_read (GtsObject ** o, GtsFile * fp)                                                                                                                                                                                                                                         +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     /* call read method of parent */                                                                                                                                                                                                                                                               +
-                                                                                                                                     if (GTS_OBJECT_CLASS (daniel_class ())->parent_class->read)                                                                                                                                                                                                                                    +
-                                                                                                                                     (* GTS_OBJECT_CLASS (daniel_class ())->parent_class->read)                                                                                                                                                                                                                                     +
-                                                                                                                                     (o, fp);                                                                                                                                                                                                                                                                                       +
-                                                                                                                                     if (fp->type == GTS_ERROR)                                                                                                                                                                                                                                                                     +
-                                                                                                                                     return;                                                                                                                                                                                                                                                                                        +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {                                                                                                                                                                                                                                            +
-                                                                                                                                     gts_file_error (fp, "expecting a number (m)");                                                                                                                                                                                                                                                 +
-                                                                                                                                     return;                                                                                                                                                                                                                                                                                        +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     DANIEL (*o)->m = atof (fp->token->str);                                                                                                                                                                                                                                                        +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     /* do not forget to prepare for next read */                                                                                                                                                                                                                                                   +
-                                                                                                                                     gts_file_next_token (fp);                                                                                                                                                                                                                                                                      +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     static void daniel_write (GtsObject * o, FILE * fp)                                                                                                                                                                                                                                            +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     /* call write method of parent */                                                                                                                                                                                                                                                              +
-                                                                                                                                     if (GTS_OBJECT_CLASS (daniel_class ())->parent_class->write)                                                                                                                                                                                                                                   +
-                                                                                                                                     (* GTS_OBJECT_CLASS (daniel_class ())->parent_class->write)                                                                                                                                                                                                                                    +
-                                                                                                                                     (o, fp);                                                                                                                                                                                                                                                                                       +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     fprintf (fp, " %g", DANIEL (o)->m);                                                                                                                                                                                                                                                            +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     /* do object specific write here */                                                                                                                                                                                                                                                            +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-
+ - + - Now we have a problem following the tutorial. The tutorial says: + -
+
-                                                                                                                                     static void init_velocity (FttCell * cell,                                                                                                                                                                                                                                                     +
-                                                                                                                                     InitPeriodic * init)                                                                                                                                                                                                                                                                           +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     FttVector pos;                                                                                                                                                                                                                                                                                 +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     ftt_cell_pos (cell, &pos);                                                                                                                                                                                                                                                                     +
-                                                                                                                                     GFS_STATE (cell)->u =                                                                                                                                                                                                                                                                          +
-                                                                                                                                     - cos (2.*init->m*M_PI*pos.x)*sin (2.*init->m*M_PI*pos.y);                                                                                                                                                                                                                                     +
-                                                                                                                                     GFS_STATE (cell)->v =                                                                                                                                                                                                                                                                          +
-                                                                                                                                     sin (2.*init->m*M_PI*pos.x)*cos (2.*init->m*M_PI*pos.y);                                                                                                                                                                                                                                       +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     static gboolean init_periodic_event (GfsEvent * event, GfsSimulation * sim)                                                                                                                                                                                                                    +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (init_periodic_class ())\                                                                                                                                                                                                                             +
-                                                                                                                                     ->parent_class)->event) (event, sim)) {                                                                                                                                                                                                                                                        +
-                                                                                                                                     gfs_domain_cell_traverse (GFS_DOMAIN (sim),                                                                                                                                                                                                                                                    +
-                                                                                                                                     FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,                                                                                                                                                                                                                                                         +
-                                                                                                                                     (FttCellTraverseFunc) init_velocity,                                                                                                                                                                                                                                                           +
-                                                                                                                                     event);                                                                                                                                                                                                                                                                                        +
-                                                                                                                                     return TRUE;                                                                                                                                                                                                                                                                                   +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     return FALSE;                                                                                                                                                                                                                                                                                  +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-
+ - but when we try to do something similar it does not work. The problem is with passing the event object to the init_velocity function. Daniel fixed it as follows: + -
+
-                                                                                                                                     static void init_velocity (FttCell * cell,                                                                                                                                                                                                                                                     +
-                                                                                                                                     gpointer * data )                                                                                                                                                                                                                                                                              +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     FttVector pos;                                                                                                                                                                                                                                                                                 +
-                                                                                                                                     GfsVariable * v;                                                                                                                                                                                                                                                                               +
-                                                                                                                                     gdouble * m = data[0];                                                                                                                                                                                                                                                                         +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     ftt_cell_pos (cell, &pos);                                                                                                                                                                                                                                                                     +
-                                                                                                                                     v = data[1];                                                                                                                                                                                                                                                                                   +
-                                                                                                                                     GFS_VARIABLE (cell, v->i) = sin (2.*(*m)*M_PI*pos.x)*cos (2.*(*m)*M_PI*pos.y);                                                                                                                                                                                                                 +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     static gboolean daniel_event (GfsEvent * event, GfsSimulation * sim)                                                                                                                                                                                                                           +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     gpointer data[2];                                                                                                                                                                                                                                                                              +
-                                                                                                                                     Daniel * inputdata = DANIEL (event);                                                                                                                                                                                                                                                           +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (daniel_class ())->parent_class)->event) (event, sim)) {                                                                                                                                                                                              +
-                                                                                                                                     /* do object-specific event here */                                                                                                                                                                                                                                                            +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     GfsDomain * domain = GFS_DOMAIN (sim);                                                                                                                                                                                                                                                         +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     data[0] = &(inputdata->m);                                                                                                                                                                                                                                                                     +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     data[1] = gfs_variable_from_name (domain->variables, "U");                                                                                                                                                                                                                                     +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     gfs_domain_cell_traverse (GFS_DOMAIN (sim),                                                                                                                                                                                                                                                    +
-                                                                                                                                     FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,                                                                                                                                                                                                                                                         +
-                                                                                                                                     (FttCellTraverseFunc) init_velocity,                                                                                                                                                                                                                                                           +
-                                                                                                                                     data);                                                                                                                                                                                                                                                                                         +
-                                                                                                                                     return TRUE;                                                                                                                                                                                                                                                                                   +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     return FALSE;                                                                                                                                                                                                                                                                                  +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-
+ - This works, and is the way things are usually written in Gerris. + - + -
+
-                                                                                                                                     static void daniel_class_init (DanielClass * klass)                                                                                                                                                                                                                                            +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     /* define new methods and overload inherited methods here */                                                                                                                                                                                                                                   +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     GFS_EVENT_CLASS (klass)->event = daniel_event;                                                                                                                                                                                                                                                 +
-                                                                                                                                     GTS_OBJECT_CLASS (klass)->write = daniel_write;                                                                                                                                                                                                                                                +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     static void daniel_init (Daniel * object)                                                                                                                                                                                                                                                      +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     /* initialize object here */                                                                                                                                                                                                                                                                   +
-                                                                                                                                     object->m = 1.;                                                                                                                                                                                                                                                                                +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     DanielClass * daniel_class (void)                                                                                                                                                                                                                                                              +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     static DanielClass * klass = NULL;                                                                                                                                                                                                                                                             +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     if (klass == NULL) {                                                                                                                                                                                                                                                                           +
-                                                                                                                                     GtsObjectClassInfo daniel_info = {                                                                                                                                                                                                                                                             +
-                                                                                                                                     "Daniel",                                                                                                                                                                                                                                                                                      +
-                                                                                                                                     sizeof (Daniel),                                                                                                                                                                                                                                                                               +
-                                                                                                                                     sizeof (DanielClass),                                                                                                                                                                                                                                                                          +
-                                                                                                                                     (GtsObjectClassInitFunc) daniel_class_init,                                                                                                                                                                                                                                                    +
-                                                                                                                                     (GtsObjectInitFunc) daniel_init,                                                                                                                                                                                                                                                               +
-                                                                                                                                     (GtsArgSetFunc) NULL,                                                                                                                                                                                                                                                                          +
-                                                                                                                                     (GtsArgGetFunc) NULL                                                                                                                                                                                                                                                                           +
-                                                                                                                                     };                                                                                                                                                                                                                                                                                             +
-                                                                                                                                     klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_init_class ()),                                                                                                                                                                                                                            +
-                                                                                                                                     &daniel_info);                                                                                                                                                                                                                                                                                 +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     return klass;                                                                                                                                                                                                                                                                                  +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     /* Initialize module */                                                                                                                                                                                                                                                                        +
-                                                                                                                                                                                                                                                                                                                                                                                                                                    +
-                                                                                                                                     const gchar * g_module_check_init (void)                                                                                                                                                                                                                                                       +
-                                                                                                                                     {                                                                                                                                                                                                                                                                                              +
-                                                                                                                                     daniel_class ();                                                                                                                                                                                                                                                                               +
-                                                                                                                                     return NULL;                                                                                                                                                                                                                                                                                   +
-                                                                                                                                     }                                                                                                                                                                                                                                                                                              +
-
+ - + - To be written. +

## 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.