[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203

Stephane Popinet popinet at users.sf.net
Fri May 15 02:55:17 UTC 2009


The following commit has been merged in the upstream branch:
commit 6a486d79d4be78d6df123d4ff9e4ed32dfdb1ef2
Author: Stephane Popinet <popinet at users.sf.net>
Date:   Thu Apr 24 15:02:49 2008 +1000

    New abstract class GfsGenericSurface
    
    darcs-hash:20080424050249-d4795-3c1355ff1b545ce699973da706df6f3c3e6f5081.gz

diff --git a/src/domain.c b/src/domain.c
index f97731b..6caa042 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -955,7 +955,7 @@ typedef struct {
   gpointer data;
   FttTraverseType order;
   FttTraverseFlags flags;
-  GfsSurface * s;
+  GfsGenericSurface * s;
 } TraverseCut;
 
 static void traverse_cut (GfsBox * box, TraverseCut * p)
@@ -966,7 +966,7 @@ static void traverse_cut (GfsBox * box, TraverseCut * p)
 /**
  * gfs_domain_traverse_cut:
  * @domain: a #GfsDomain.
- * @s: a #GfsSurface.
+ * @s: a #GfsGenericSurface.
  * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
  * %FTT_POST_ORDER. 
  * @flags: which types of children are to be visited.
@@ -976,7 +976,7 @@ static void traverse_cut (GfsBox * box, TraverseCut * p)
  * Calls @func for each cell of @domain cut by @s.
  */
 void gfs_domain_traverse_cut (GfsDomain * domain,
-			      GfsSurface * s,
+			      GfsGenericSurface * s,
 			      FttTraverseType order,
 			      FttTraverseFlags flags,
 			      FttCellTraverseCutFunc func,
@@ -1005,7 +1005,7 @@ static void traverse_cut_2D (GfsBox * box, TraverseCut * p)
 /**
  * gfs_domain_traverse_cut_2D:
  * @domain: a #GfsDomain.
- * @s: a #GfsSurface.
+ * @s: a #GfsGenericSurface.
  * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
  * %FTT_POST_ORDER. 
  * @flags: which types of children are to be visited.
@@ -1017,7 +1017,7 @@ static void traverse_cut_2D (GfsBox * box, TraverseCut * p)
  * The cells are flattened in the z-direction.
  */
 void gfs_domain_traverse_cut_2D (GfsDomain * domain,
-				 GfsSurface * s,
+				 GfsGenericSurface * s,
 				 FttTraverseType order,
 				 FttTraverseFlags flags,
 				 FttCellTraverseCutFunc func,
diff --git a/src/domain.h b/src/domain.h
index 14e080f..b0862d5 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -123,13 +123,13 @@ void         gfs_domain_traverse_mixed        (GfsDomain * domain,
 					       FttCellTraverseFunc func,
 					       gpointer data);
 void         gfs_domain_traverse_cut          (GfsDomain * domain,
-					       GfsSurface * s,
+					       GfsGenericSurface * s,
 					       FttTraverseType order,
 					       FttTraverseFlags flags,
 					       FttCellTraverseCutFunc func,
 					       gpointer data);
 void         gfs_domain_traverse_cut_2D       (GfsDomain * domain,
-					       GfsSurface * s,
+					       GfsGenericSurface * s,
 					       FttTraverseType order,
 					       FttTraverseFlags flags,
 					       FttCellTraverseCutFunc func,
diff --git a/src/event.c b/src/event.c
index a24d240..96da9e2 100644
--- a/src/event.c
+++ b/src/event.c
@@ -1692,7 +1692,7 @@ static void gfs_init_fraction_read (GtsObject ** o, GtsFile * fp)
   }
   gts_file_next_token (fp);
 
-  gfs_surface_read (init->surface, gfs_object_simulation (*o), fp);
+  gfs_generic_surface_read (init->surface, gfs_object_simulation (*o), fp);
 }
 
 static void gfs_init_fraction_write (GtsObject * o, FILE * fp)
@@ -1702,7 +1702,7 @@ static void gfs_init_fraction_write (GtsObject * o, FILE * fp)
 
   (* GTS_OBJECT_CLASS (gfs_init_fraction_class ())->parent_class->write) (o, fp);
   fprintf (fp, " %s", init->c->name);
-  gfs_surface_write (init->surface, gfs_object_simulation (o), fp);
+  gfs_generic_surface_write (init->surface, gfs_object_simulation (o), fp);
 }
 
 static gboolean gfs_init_fraction_event (GfsEvent * event, GfsSimulation * sim)
@@ -1727,7 +1727,7 @@ static void gfs_init_fraction_class_init (GfsInitFractionClass * klass)
 
 static void gfs_init_fraction_init (GfsInitFraction * object)
 {
-  object->surface = GFS_SURFACE (gts_object_new (gfs_surface_class ()));
+  object->surface = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
 }
 
 GfsInitFractionClass * gfs_init_fraction_class (void)
diff --git a/src/event.h b/src/event.h
index e85424c..a07eabc 100644
--- a/src/event.h
+++ b/src/event.h
@@ -258,7 +258,7 @@ struct _GfsInitFraction {
   GfsGenericInit parent;
 
   GfsVariable * c;
-  GfsSurface * surface;
+  GfsGenericSurface * surface;
 };
 
 typedef struct _GfsInitFractionClass    GfsInitFractionClass;
diff --git a/src/refine.c b/src/refine.c
index 8862312..c9e74a4 100644
--- a/src/refine.c
+++ b/src/refine.c
@@ -173,11 +173,11 @@ static void max_kappa (GtsVertex * v, KappaData * d)
 }
 
 static gdouble solid_curvature (FttCell * cell, FttCellFace * face, 
-				GfsDomain * domain, GfsSurface * s)
+				GfsDomain * domain, GfsGenericSurface * s)
 {
   KappaData d;
   d.kappa = gfs_solid_is_thin (cell, s) ? 1./ftt_cell_size (cell) : 0.;
-  d.s = s->s;
+  d.s = GFS_SURFACE (s)->s;
   gts_surface_foreach_vertex (d.s, (GtsFunc) max_kappa, &d);
   return d.kappa;
 }
@@ -199,10 +199,10 @@ static void refine_solid_read (GtsObject ** o, GtsFile * fp)
 typedef struct {
   GfsRefine * refine;
   GfsDomain * domain;
-  GfsSurface * surface;
+  GfsGenericSurface * surface;
 } RefineCut;
 
-static void refine_cut_cell (FttCell * cell, GfsSurface * s, RefineCut * p)
+static void refine_cut_cell (FttCell * cell, GfsGenericSurface * s, RefineCut * p)
 {
   GTS_OBJECT (s)->reserved = p->surface;
   GFS_REFINE_SOLID (p->refine)->v->data = s;
@@ -227,7 +227,7 @@ static void gfs_refine_solid_refine (GfsRefine * refine, GfsSimulation * sim)
     GSList * i = sim->solids->items;
     while (i) {
       p.surface = GFS_SOLID (i->data)->s;
-      if (p.surface->s)
+      if (GFS_SURFACE (p.surface)->s)
 	gfs_domain_traverse_cut (GFS_DOMAIN (sim), p.surface,
 				 FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
 				 (FttCellTraverseCutFunc) refine_cut_cell, &p);
@@ -282,7 +282,7 @@ static void refine_surface_destroy (GtsObject * object)
 static void refine_surface_write (GtsObject * o, FILE * fp)
 {
   (* GTS_OBJECT_CLASS (gfs_refine_surface_class ())->parent_class->write) (o, fp);
-  gfs_surface_write (GFS_REFINE_SURFACE (o)->surface, gfs_object_simulation (o), fp);
+  gfs_generic_surface_write (GFS_REFINE_SURFACE (o)->surface, gfs_object_simulation (o), fp);
 }
 
 static void refine_surface_read (GtsObject ** o, GtsFile * fp)
@@ -291,7 +291,7 @@ static void refine_surface_read (GtsObject ** o, GtsFile * fp)
   if (fp->type == GTS_ERROR)
     return;
 
-  gfs_surface_read (GFS_REFINE_SURFACE (*o)->surface, gfs_object_simulation (*o), fp);
+  gfs_generic_surface_read (GFS_REFINE_SURFACE (*o)->surface, gfs_object_simulation (*o), fp);
 }
 
 static void gfs_refine_surface_refine (GfsRefine * refine, GfsSimulation * sim)
@@ -301,8 +301,8 @@ static void gfs_refine_surface_refine (GfsRefine * refine, GfsSimulation * sim)
   p.refine = refine;
   p.domain = GFS_DOMAIN (sim);
   p.surface = GFS_REFINE_SURFACE (refine)->surface;
-  if (p.surface->twod) {
-    if (p.surface->s)
+  if (GFS_SURFACE (p.surface)->twod) {
+    if (GFS_SURFACE (p.surface)->s)
       gfs_domain_traverse_cut_2D (GFS_DOMAIN (sim), GFS_REFINE_SURFACE (refine)->surface,
 				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
 				  (FttCellTraverseCutFunc) refine_cut_cell, &p);
@@ -310,7 +310,7 @@ static void gfs_refine_surface_refine (GfsRefine * refine, GfsSimulation * sim)
       g_assert_not_implemented ();
   }
   else {
-    if (p.surface->s)
+    if (GFS_SURFACE (p.surface)->s)
       gfs_domain_traverse_cut (GFS_DOMAIN (sim), GFS_REFINE_SURFACE (refine)->surface,
 			       FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
 			       (FttCellTraverseCutFunc) refine_cut_cell, &p);
@@ -332,7 +332,7 @@ static void gfs_refine_surface_class_init (GfsRefineClass * klass)
 
 static void refine_surface_init (GfsRefineSurface * r)
 {
-  r->surface = GFS_SURFACE (gts_object_new (gfs_surface_class ()));
+  r->surface = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
 }
 
 GfsRefineClass * gfs_refine_surface_class (void)
@@ -399,13 +399,14 @@ static void refine_distance_read (GtsObject ** o, GtsFile * fp)
   (* GTS_OBJECT_CLASS (gfs_refine_distance_class ())->parent_class->read) (o, fp);
   if (fp->type == GTS_ERROR)
     return;
-  
-  if (!GFS_REFINE_SURFACE (*o)->surface->s) {
+
+  GtsSurface * s = GFS_SURFACE (GFS_REFINE_SURFACE (*o)->surface)->s;
+  if (!s) {
     gts_file_error (fp, "RefineDistance only works with GTS surfaces");
     return;
   }
 
-  GFS_REFINE_DISTANCE (*o)->stree = gts_bb_tree_surface (GFS_REFINE_SURFACE (*o)->surface->s);
+  GFS_REFINE_DISTANCE (*o)->stree = gts_bb_tree_surface (s);
 }
 
 static void gfs_refine_distance_class_init (GfsRefineClass * klass)
@@ -468,7 +469,7 @@ static gdouble cell_height (FttCell * cell,
 {
   FttVector pos;
   ftt_cell_pos (cell, &pos);
-  return interpolated_value (refine->surface->s, &pos);
+  return interpolated_value (GFS_SURFACE (refine->surface)->s, &pos);
 }
 
 static void refine_height_read (GtsObject ** o, GtsFile * fp)
@@ -486,7 +487,7 @@ static void refine_height_read (GtsObject ** o, GtsFile * fp)
   if (fp->type == GTS_ERROR)
     return;
 
-  if (!GFS_REFINE_SURFACE (*o)->surface->s) {
+  if (!GFS_SURFACE (GFS_REFINE_SURFACE (*o)->surface)->s) {
     gts_file_error (fp, "RefineDistance only works with GTS surfaces");
     return;
   }
diff --git a/src/refine.h b/src/refine.h
index b33d82d..a5f9cfe 100644
--- a/src/refine.h
+++ b/src/refine.h
@@ -75,7 +75,7 @@ typedef struct _GfsRefineSurface         GfsRefineSurface;
 struct _GfsRefineSurface {
   GfsRefine parent;
 
-  GfsSurface * surface;
+  GfsGenericSurface * surface;
 };
 
 #define GFS_REFINE_SURFACE(obj)            GTS_OBJECT_CAST (obj,\
diff --git a/src/simulation.c b/src/simulation.c
index e2bfb33..af610d4 100644
--- a/src/simulation.c
+++ b/src/simulation.c
@@ -976,6 +976,7 @@ void gfs_simulation_refine (GfsSimulation * sim)
 			     FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
 			     (FttCellTraverseFunc) refine_cell_corner, 
 			      domain);
+
   gfs_domain_match (domain);
   gfs_domain_timer_stop (domain, "simulation_refine");
 
diff --git a/src/solid.c b/src/solid.c
index ee38648..72e461a 100644
--- a/src/solid.c
+++ b/src/solid.c
@@ -160,7 +160,7 @@ static void face_fractions (CellFace * f, GfsSolidVector * solid, FttVector * h)
   solid->a = a;
 }
 
-static void face_new (CellFace * f, FttCell * cell, GfsSurface * s, FttVector * h)
+static void face_new (CellFace * f, FttCell * cell, GfsGenericSurface * s, FttVector * h)
 {
   FttVector p;
   guint i;
@@ -174,7 +174,7 @@ static void face_new (CellFace * f, FttCell * cell, GfsSurface * s, FttVector *
   for (i = 0; i < 4; i++) {
     f->s[i].E = &f->p[i];
     f->s[i].D = &f->p[(i + 1) % 4];
-    gfs_surface_segment_intersection (s, &f->s[i]);
+    gfs_surface_segment_intersection (s, cell, &f->s[i]);
   }
 }
 
@@ -201,14 +201,14 @@ static gboolean solid_face_is_thin (CellFace * f)
 /**
  * gfs_set_2D_solid_fractions_from_surface:
  * @cell: a #FttCell.
- * @s: a #GfsSurface.
+ * @s: a #GfsGenericSurface.
  *
  * Sets the 2D volume fractions of @cell cut by @s.
  *
  * Returns: %TRUE if the cell is thin, %FALSE otherwise;
  */
 gboolean gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
-						  GfsSurface * s)
+						  GfsGenericSurface * s)
 {
   GfsSolidVector * solid;
   FttVector h;
@@ -295,7 +295,7 @@ static void deal_with_thin_cell (FttCell * cell, InitSolidParams * p)
 #if FTT_2D /* 2D */
 
 static void set_solid_fractions_from_surface (FttCell * cell,
-					      GfsSurface * s,
+					      GfsGenericSurface * s,
 					      InitSolidParams * p)
 {
   if (gfs_set_2D_solid_fractions_from_surface (cell, s)) {
@@ -309,7 +309,7 @@ static void set_solid_fractions_from_surface (FttCell * cell,
 /**
  * gfs_solid_is_thin:
  * @cell: a #FttCell.
- * @s: a #GfsSurface.
+ * @s: a #GfsGenericSurface.
  *
  * @s is "thin" relative to @cell if the miminum distance between
  * non-connected faces of @s cutting @cell is smaller than the size of
@@ -317,7 +317,7 @@ static void set_solid_fractions_from_surface (FttCell * cell,
  *
  * Returns: %TRUE if @s is a thin surface, %FALSE otherwise.
  */
-gboolean gfs_solid_is_thin (FttCell * cell, GfsSurface * s)
+gboolean gfs_solid_is_thin (FttCell * cell, GfsGenericSurface * s)
 {
   CellFace f;
   FttVector h;
@@ -407,7 +407,7 @@ static guint topology (CellCube * cube)
   return nl;
 }
 
-static void cube_new (CellCube * cube, FttCell * cell, GfsSurface * s, FttVector * o, FttVector * h)
+static void cube_new (CellCube * cube, FttCell * cell, GfsGenericSurface * s, FttVector * o, FttVector * h)
 {
   guint i;
 
@@ -422,12 +422,12 @@ static void cube_new (CellCube * cube, FttCell * cell, GfsSurface * s, FttVector
   for (i = 0; i < 12; i++) {
     cube->s[i].E = &cube->p[edge1[i][0]];
     cube->s[i].D = &cube->p[edge1[i][1]];
-    gfs_surface_segment_intersection (s, &cube->s[i]);
+    gfs_surface_segment_intersection (s, cell, &cube->s[i]);
   }
 }
 
 static void set_solid_fractions_from_surface (FttCell * cell, 
-					      GfsSurface * surface, 
+					      GfsGenericSurface * surface, 
 					      InitSolidParams * p)
 {
   GfsSolidVector * solid = GFS_STATE (cell)->solid;
@@ -586,7 +586,7 @@ static void set_solid_fractions_from_surface (FttCell * cell,
 /**
  * gfs_solid_is_thin:
  * @cell: a #FttCell.
- * @s: a #GfsSurface.
+ * @s: a #GfsGenericSurface.
  *
  * @s is "thin" relative to @cell if the miminum distance between
  * non-connected faces of @s cutting @cell is smaller than the size of
@@ -594,7 +594,7 @@ static void set_solid_fractions_from_surface (FttCell * cell,
  *
  * Returns: %TRUE if @s is a thin surface, %FALSE otherwise.
  */
-gboolean gfs_solid_is_thin (FttCell * cell, GfsSurface * s)
+gboolean gfs_solid_is_thin (FttCell * cell, GfsGenericSurface * s)
 {
   CellCube cube;
   FttVector o, h;
@@ -843,8 +843,7 @@ static void match_fractions (FttCell * cell, GfsVariable * status)
 
     ftt_cell_neighbors (cell, &neighbor);
     for (d = 0; d < FTT_NEIGHBORS; d++)
-      if (neighbor.c[d] &&
-	  !GFS_CELL_IS_BOUNDARY (neighbor.c[d])) {
+      if (neighbor.c[d] && !GFS_CELL_IS_BOUNDARY (neighbor.c[d])) {
 	if (!FTT_CELL_IS_LEAF (neighbor.c[d])) {
 	  FttCellChildren child;
 	  FttDirection od = FTT_OPPOSITE_DIRECTION (d);
@@ -872,7 +871,7 @@ static void match_fractions (FttCell * cell, GfsVariable * status)
 /**
  * gfs_domain_init_solid_fractions:
  * @domain: a #GfsDomain.
- * @i: a list of #GfsSurfaces.
+ * @i: a list of #GfsGenericSurfaces.
  * @destroy_solid: controls what to do with solid cells.
  * @cleanup: a #FttCellCleanupFunc or %NULL.
  * @data: user data to pass to @cleanup.
@@ -1116,7 +1115,7 @@ static void restore_solid (FttCell * cell, gpointer * data)
  * the cells of @domain.
  */
 void gfs_domain_init_fraction (GfsDomain * domain,
-			       GfsSurface * s,
+			       GfsGenericSurface * s,
 			       GfsVariable * c)
 {
   gboolean not_cut = TRUE;
@@ -1414,7 +1413,7 @@ static void gfs_solid_read (GtsObject ** o, GtsFile * fp)
   if (fp->type == GTS_ERROR)
     return;
 
-  gfs_surface_read (GFS_SOLID (*o)->s, gfs_object_simulation (*o), fp);
+  gfs_generic_surface_read (GFS_SOLID (*o)->s, gfs_object_simulation (*o), fp);
 }
 
 static void gfs_solid_write (GtsObject * o, FILE * fp)
@@ -1422,7 +1421,7 @@ static void gfs_solid_write (GtsObject * o, FILE * fp)
   GfsSimulation * sim = gfs_object_simulation (o);
   if (sim->output_solid) {
     (* GTS_OBJECT_CLASS (gfs_solid_class ())->parent_class->write) (o, fp);
-    gfs_surface_write (GFS_SOLID (o)->s, sim, fp);
+    gfs_generic_surface_write (GFS_SOLID (o)->s, sim, fp);
   }
 }
 
@@ -1442,7 +1441,7 @@ static void gfs_solid_class_init (GtsObjectClass * klass)
 
 static void gfs_solid_init (GfsSolid * object)
 {
-  object->s = GFS_SURFACE (gts_object_new (gfs_surface_class ()));
+  object->s = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
   GFS_EVENT (object)->istep = G_MAXINT/2;
 }
 
diff --git a/src/solid.h b/src/solid.h
index bb992e6..80128b4 100644
--- a/src/solid.h
+++ b/src/solid.h
@@ -31,9 +31,9 @@ extern "C" {
 
 void         gfs_cell_fluid                              (FttCell * cell);
 gboolean     gfs_solid_is_thin                           (FttCell * cell, 
-							  GfsSurface * s);
+							  GfsGenericSurface * s);
 gboolean     gfs_set_2D_solid_fractions_from_surface     (FttCell * cell,
-							  GfsSurface * s);
+							  GfsGenericSurface * s);
 guint        gfs_domain_init_solid_fractions             (GfsDomain * domain,
 							  GSList * i,
 							  gboolean destroy_solid,
@@ -43,7 +43,7 @@ guint        gfs_domain_init_solid_fractions             (GfsDomain * domain,
 void         gfs_cell_init_solid_fractions_from_children (FttCell * cell);
 gboolean     gfs_cell_check_solid_fractions              (FttCell * root);
 void         gfs_domain_init_fraction                    (GfsDomain * domain,
-							  GfsSurface * s,
+							  GfsGenericSurface * s,
 							  GfsVariable * c);
 void         gfs_cell_cm                                 (const FttCell * cell, 
 							  FttVector * cm);
@@ -62,7 +62,7 @@ struct _GfsSolid {
   GfsEvent parent;
 
   /*< public >*/
-  GfsSurface * s;
+  GfsGenericSurface * s;
 };
 
 #define GFS_SOLID(obj)            GTS_OBJECT_CAST (obj,\
diff --git a/src/surface.c b/src/surface.c
index 808047a..f9dc81d 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -21,6 +21,225 @@
 #include "simulation.h"
 #include "surface.h"
 
+/* GfsGenericSurface: Object */
+
+GfsGenericSurfaceClass * gfs_generic_surface_class (void)
+{
+  static GfsGenericSurfaceClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_generic_surface_info = {
+      "GfsGenericSurface",
+      sizeof (GtsObject),
+      sizeof (GfsGenericSurfaceClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+				  &gfs_generic_surface_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_cell_is_cut:
+ * @cell: a #FttCell.
+ * @s: a #GfsGenericSurface.
+ * @flatten: if set to %TRUE, @cell is flattened in the z direction.
+ * @maxlevel: the maximum (virtual) cell level to consider.
+ *
+ * Returns: a (possibly new) #GfsGenericSurface containing a subset of @s which may
+ * intersect @cell or %NULL if @s does not intersect @cell.
+ */
+GfsGenericSurface * gfs_cell_is_cut (FttCell * cell, GfsGenericSurface * s, 
+				     gboolean flatten, gint maxlevel)
+{
+  g_return_val_if_fail (cell != NULL, NULL);
+  g_return_val_if_fail (s != NULL, NULL);
+  
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->cell_is_cut);
+  return (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->cell_is_cut) 
+    (cell, s, flatten, maxlevel);
+}
+
+static void cell_traverse_cut (FttCell * cell,
+			       GfsGenericSurface * s,
+			       FttTraverseType order,
+			       FttTraverseFlags flags,
+			       FttCellTraverseCutFunc func,
+			       gpointer data,
+			       gboolean flatten)
+{
+  GfsGenericSurface * s1 = gfs_cell_is_cut (cell, s, flatten && FTT_CELL_IS_LEAF (cell), -1);
+
+  if (s1 == NULL)
+    return;
+  if (order == FTT_PRE_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
+    (* func) (cell, s1, data);
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    struct _FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_cut (c, s1, order, flags, func, data, flatten);
+    }
+  }
+  if (order == FTT_POST_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
+    (* func) (cell, s1, data);
+  if (s1 != s)
+    gts_object_destroy (GTS_OBJECT (s1));
+}
+
+/**
+ * gfs_cell_traverse_cut:
+ * @root: the root #FttCell of the tree to traverse.
+ * @s: a #GfsGenericSurface.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * 
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell cut by @s.
+ */
+void gfs_cell_traverse_cut (FttCell * root,
+			    GfsGenericSurface * s,
+			    FttTraverseType order,
+			    FttTraverseFlags flags,
+			    FttCellTraverseCutFunc func,
+			    gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (func != NULL);
+
+  cell_traverse_cut (root, s, order, flags, func, data, FALSE);
+}
+
+/**
+ * gfs_cell_traverse_cut_2D:
+ * @root: the root #FttCell of the tree to traverse.
+ * @s: a #GfsGenericSurface.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * 
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell cut by @s.
+ *
+ * The cells are "flattened" in the z-direction.
+ */
+void gfs_cell_traverse_cut_2D (FttCell * root,
+			       GfsGenericSurface * s,
+			       FttTraverseType order,
+			       FttTraverseFlags flags,
+			       FttCellTraverseCutFunc func,
+			       gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (func != NULL);
+
+  cell_traverse_cut (root, s, order, flags, func, data, TRUE);
+}
+
+/**
+ * gfs_generic_surface_read:
+ * @s: a #GfsGenericSurface.
+ * @sim: a #GfsSimulation.
+ * @fp: a #GtsFile.
+ * 
+ * Calls the read() method of @s.
+ */
+void gfs_generic_surface_read (GfsGenericSurface * s, gpointer sim, GtsFile * fp)
+{
+  GtsObject * o = (GtsObject *) s;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (fp != NULL);
+
+  o->reserved = sim;
+  (* GTS_OBJECT (s)->klass->read) (&o, fp);
+}
+
+/**
+ * gfs_generic_surface_write:
+ * @s: a #GfsGenericSurface.
+ * @sim: a #GfsSimulation.
+ * @fp: a file pointer.
+ * 
+ * Calls the write() method of @s.
+ */
+void gfs_generic_surface_write (GfsGenericSurface * s, gpointer sim, FILE * fp)
+{
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GTS_OBJECT (s)->reserved = sim;
+  (* GTS_OBJECT (s)->klass->write) (GTS_OBJECT (s), fp);
+}
+
+/**
+ * gfs_surface_segment_intersection:
+ * @s: a #GfsGenericSurface.
+ * @cell: a #FttCell containing @I.
+ * @I: a GfsSegment.
+ *
+ * Fills @I with the intersection of @s and @I.
+ *
+ * Returns: the number of times @s intersects @I.
+ */
+guint gfs_surface_segment_intersection (GfsGenericSurface * s,
+					FttCell * cell,
+					GfsSegment * I)
+{
+  g_return_val_if_fail (s != NULL, 0);
+  g_return_val_if_fail (cell != NULL, 0);
+  g_return_val_if_fail (I != NULL, 0);
+
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_intersection);
+  return (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_intersection) (s, cell, I);
+}
+
+/**
+ * gfs_surface_segment_normal:
+ * @s: a #GfsGenericSurface.
+ * @cell: a #FttCell containing @I.
+ * @I: a GfsSegment.
+ * @n: a #GtsVector.
+ *
+ * Fills @n with the normal to @s at the intersection of @s and @I.
+ */
+void gfs_surface_segment_normal (GfsGenericSurface * s,
+				 FttCell * cell,
+				 GfsSegment * I,
+				 GtsVector n)
+{
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (I != NULL);
+  g_return_if_fail (I->n > 0);
+  g_return_if_fail (n != NULL);
+
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_normal);
+  (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_normal) (s, cell, I, n);
+}
+
 /* GfsSurface: Object */
 
 static void check_solid_surface (GtsSurface * s, 
@@ -246,90 +465,70 @@ static void surface_destroy (GtsObject * object)
   (* GTS_OBJECT_CLASS (gfs_surface_class ())->parent_class->destroy) (object);
 }
 
-static void gfs_surface_class_init (GtsObjectClass * klass)
-{
-  klass->read = surface_read;
-  klass->write = surface_write;
-  klass->destroy = surface_destroy;
-}
-
-static void gfs_surface_init (GfsSurface * s)
-{
-  s->scale[0] = 1.; s->scale[1] = 1.; s->scale[2] = 1.;
-  s->flip = FALSE;
-}
 
-GtsObjectClass * gfs_surface_class (void)
+static void face_overlaps_box (GtsTriangle * t, gpointer * data)
 {
-  static GtsObjectClass * klass = NULL;
+  GtsBBox * bb = data[0];
+  GtsSurface ** s1 = data[1];
 
-  if (klass == NULL) {
-    GtsObjectClassInfo gfs_surface_info = {
-      "GfsSurface",
-      sizeof (GfsSurface),
-      sizeof (GtsObjectClass),
-      (GtsObjectClassInitFunc) gfs_surface_class_init,
-      (GtsObjectInitFunc) gfs_surface_init,
-      (GtsArgSetFunc) NULL,
-      (GtsArgGetFunc) NULL
-    };
-    klass = gts_object_class_new (gts_object_class (), &gfs_surface_info);
+  if (gts_bbox_overlaps_triangle (bb, t)) {
+    if (*s1 == NULL)
+      *s1 = gts_surface_new (gts_surface_class (),
+			     gts_face_class (),
+			     gts_edge_class (),
+			     gts_vertex_class ());
+    gts_surface_add_face (*s1, GTS_FACE (t));
   }
-
-  return klass;
 }
 
-/**
- * gfs_surface_read:
- * @s: a #GfsSurface.
- * @sim: a #GfsSimulation.
- * @fp: a #GtsFile.
- * 
- * Calls the read() method of @s.
- */
-void gfs_surface_read (GfsSurface * s, gpointer sim, GtsFile * fp)
-{
-  GtsObject * o = (GtsObject *) s;
-
-  g_return_if_fail (s != NULL);
-  g_return_if_fail (fp != NULL);
-
-  o->reserved = sim;
-  (* GTS_OBJECT (s)->klass->read) (&o, fp);
-}
-
-/**
- * gfs_surface_write:
- * @s: a #GfsSurface.
- * @sim: a #GfsSimulation.
- * @fp: a file pointer.
- * 
- * Calls the write() method of @s.
- */
-void gfs_surface_write (GfsSurface * s, gpointer sim, FILE * fp)
-{
-  g_return_if_fail (s != NULL);
-  g_return_if_fail (fp != NULL);
-
-  GTS_OBJECT (s)->reserved = sim;
-  (* GTS_OBJECT (s)->klass->write) (GTS_OBJECT (s), fp);
-}
+#define SIGN(v) ((v) > 0. ? 1 : (v) < 0. ? -1 : 0)
 
-/**
- * gfs_surface_implicit_value:
- * @s: an (implicit) #GfsSurface.
- * @p: a #GtsPoint.
- *
- * Returns: the value of the implicit surface a location @p.
- */
-gdouble gfs_surface_implicit_value (GfsSurface * s, GtsPoint p)
+static GfsGenericSurface * cell_is_cut (FttCell * cell, GfsGenericSurface * s1, 
+					gboolean flatten, gint maxlevel)
 {
-  g_return_val_if_fail (s != NULL, 0.);
-  g_return_val_if_fail (s->f != NULL, 0.);
-
-  if (s->m)
-    gts_point_transform (&p, s->m);
-  return (s->flip ? -1. : 1.)*gfs_function_spatial_value (s->f, (FttVector *)&p.x);
+  GfsSurface * s = GFS_SURFACE (s1);
+  if (s->s) {
+    GtsSurface * s1 = NULL;
+    gpointer data[2];
+    GtsBBox bb;
+    ftt_cell_bbox (cell, &bb);
+    if (flatten)
+      bb.z1 = bb.z2 = 0.;
+    data[0] = &bb;
+    data[1] = &s1;
+    gts_surface_foreach_face (s->s, (GtsFunc) face_overlaps_box, data);
+    if (s1 == NULL)
+      return NULL;
+    GfsSurface * s2 = GFS_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
+    s2->s = s1;
+    return GFS_GENERIC_SURFACE (s2);
+  }
+  else if (s->f) {
+    if (!FTT_CELL_IS_LEAF (cell))
+      return GFS_GENERIC_SURFACE (s);
+    FttVector p;
+    gdouble h = ftt_cell_size (cell)/2.;
+    ftt_cell_pos (cell, &p);
+    gint i, j, k = 0, sign = 0, n = 1;
+    i = maxlevel - ftt_cell_level (cell);
+    while (i-- > 0)
+      n *= 2;
+#if !FTT_2D
+    for (k = - n; k <= n; k += 2)
+#endif
+      for (i = - n; i <= n; i += 2)
+	for (j = - n; j <= n; j += 2) {
+	  GtsPoint o;
+	  o.x = p.x + i*h/n; o.y = p.y + j*h/n; o.z = p.z + k*h/n;
+	  gdouble v = gfs_surface_implicit_value (s, o);
+	  if (sign && sign*SIGN(v) <= 0)
+	    return GFS_GENERIC_SURFACE (s);
+	  sign = SIGN(v);
+	}
+    return NULL;
+  }
+  g_assert_not_reached ();
+  return NULL;
 }
 
 static gdouble segment_triangle_intersection (GtsPoint * E, GtsPoint * D,
@@ -395,23 +594,18 @@ static GtsPoint segment_intersection (GfsSegment * I)
   p.x = I->E->x + I->x*(I->D->x - I->E->x);
   p.y = I->E->y + I->x*(I->D->y - I->E->y);
   p.z = I->E->z + I->x*(I->D->z - I->E->z);
+  /* lines below just to prevent compiler warnings about uninitialised fields */
+  p.object.flags = 0;
+  p.object.reserved = NULL;
+  p.object.klass = NULL;
   return p;
 }
 
-/**
- * gfs_surface_segment_intersection:
- * @s: a #GfsSurface.
- * @I: a GfsSegment.
- *
- * Fills @I with the intersection of @s and @I.
- *
- * Returns: the number of times @s intersects @I.
- */
-guint gfs_surface_segment_intersection (GfsSurface * s,
-					GfsSegment * I)
+static guint surface_segment_intersection (GfsGenericSurface * s1,
+					   FttCell * cell,
+					   GfsSegment * I)
 {
-  g_return_val_if_fail (s != NULL, 0);
-  g_return_val_if_fail (I != NULL, 0);
+  GfsSurface * s = GFS_SURFACE (s1);
 
   I->n = 0;
   I->x = 0.;
@@ -475,23 +669,12 @@ static void surface_normal (GtsTriangle * t, GtsVector n)
   n[2] -= m[2];
 }
 
-/**
- * gfs_surface_segment_normal:
- * @s: a #GfsSurface.
- * @I: a GfsSegment.
- * @n: a #GtsVector.
- *
- * Fills @n with the normal to @s at the intersection of @s and @I.
- */
-void gfs_surface_segment_normal (GfsSurface * s,
-				 GfsSegment * I,
-				 GtsVector n)
+static void surface_segment_normal (GfsGenericSurface * s1,
+				    FttCell * cell,
+				    GfsSegment * I,
+				    GtsVector n)
 {
-  g_return_if_fail (s != NULL);
-  g_return_if_fail (I != NULL);
-  g_return_if_fail (I->n > 0);
-  g_return_if_fail (n != NULL);
-  
+  GfsSurface * s = GFS_SURFACE (s1);
   if (s->s) {
     n[0] = n[1] = n[2] = 0.;
     gts_surface_foreach_face (s->s, (GtsFunc) surface_normal, n);
@@ -510,171 +693,57 @@ void gfs_surface_segment_normal (GfsSurface * s,
   }
 }
 
-static void face_overlaps_box (GtsTriangle * t, gpointer * data)
+static void gfs_surface_class_init (GtsObjectClass * klass)
 {
-  GtsBBox * bb = data[0];
-  GtsSurface ** s1 = data[1];
+  klass->read = surface_read;
+  klass->write = surface_write;
+  klass->destroy = surface_destroy;
 
-  if (gts_bbox_overlaps_triangle (bb, t)) {
-    if (*s1 == NULL)
-      *s1 = gts_surface_new (gts_surface_class (),
-			     gts_face_class (),
-			     gts_edge_class (),
-			     gts_vertex_class ());
-    gts_surface_add_face (*s1, GTS_FACE (t));
-  }
+  GFS_GENERIC_SURFACE_CLASS (klass)->cell_is_cut = cell_is_cut;
+  GFS_GENERIC_SURFACE_CLASS (klass)->segment_intersection = surface_segment_intersection;
+  GFS_GENERIC_SURFACE_CLASS (klass)->segment_normal = surface_segment_normal;
 }
 
-#define SIGN(v) ((v) > 0. ? 1 : (v) < 0. ? -1 : 0)
-
-/**
- * gfs_cell_is_cut:
- * @cell: a #FttCell.
- * @s: a #GfsSurface.
- * @flatten: if set to %TRUE, @cell is flattened in the z direction.
- * @maxlevel: the maximum (virtual) cell level to consider.
- *
- * Returns: a (possibly new) #GfsSurface containing a subset of @s which may
- * intersect @cell or %NULL if @s does not intersect @cell.
- */
-GfsSurface * gfs_cell_is_cut (FttCell * cell, GfsSurface * s, gboolean flatten, gint maxlevel)
+static void gfs_surface_init (GfsSurface * s)
 {
-  g_return_val_if_fail (cell != NULL, NULL);
-  g_return_val_if_fail (s != NULL, NULL);
-
-  if (s->s) {
-    GtsSurface * s1 = NULL;
-    gpointer data[2];
-    GtsBBox bb;
-    ftt_cell_bbox (cell, &bb);
-    if (flatten)
-      bb.z1 = bb.z2 = 0.;
-    data[0] = &bb;
-    data[1] = &s1;
-    gts_surface_foreach_face (s->s, (GtsFunc) face_overlaps_box, data);
-    if (s1 == NULL)
-      return NULL;
-    GfsSurface * s2 = GFS_SURFACE (gts_object_new (gfs_surface_class ()));
-    s2->s = s1;
-    return s2;
-  }
-  else if (s->f) {
-    if (!FTT_CELL_IS_LEAF (cell))
-      return s;
-    FttVector p;
-    gdouble h = ftt_cell_size (cell)/2.;
-    ftt_cell_pos (cell, &p);
-    gint i, j, k = 0, sign = 0, n = 1;
-    i = maxlevel - ftt_cell_level (cell);
-    while (i-- > 0)
-      n *= 2;
-#if !FTT_2D
-    for (k = - n; k <= n; k += 2)
-#endif
-      for (i = - n; i <= n; i += 2)
-	for (j = - n; j <= n; j += 2) {
-	  GtsPoint o;
-	  o.x = p.x + i*h/n; o.y = p.y + j*h/n; o.z = p.z + k*h/n;
-	  gdouble v = gfs_surface_implicit_value (s, o);
-	  if (sign && sign*SIGN(v) <= 0)
-	    return s;
-	  sign = SIGN(v);
-	}
-    return NULL;
-  }
-  g_assert_not_reached ();
-  return NULL;
+  s->scale[0] = 1.; s->scale[1] = 1.; s->scale[2] = 1.;
+  s->flip = FALSE;
 }
 
-static void cell_traverse_cut (FttCell * cell,
-			       GfsSurface * s,
-			       FttTraverseType order,
-			       FttTraverseFlags flags,
-			       FttCellTraverseCutFunc func,
-			       gpointer data,
-			       gboolean flatten)
+GfsGenericSurfaceClass * gfs_surface_class (void)
 {
-  GfsSurface * s1 = gfs_cell_is_cut (cell, s, flatten && FTT_CELL_IS_LEAF (cell), -1);
-
-  if (s1 == NULL)
-    return;
-  if (order == FTT_PRE_ORDER &&
-      (flags == FTT_TRAVERSE_ALL ||
-       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
-       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
-    (* func) (cell, s1, data);
-  if (!FTT_CELL_IS_LEAF (cell)) {
-    struct _FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
+  static GfsGenericSurfaceClass * klass = NULL;
 
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_cut (c, s1, order, flags, func, data, flatten);
-    }
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_surface_info = {
+      "GfsSurface",
+      sizeof (GfsSurface),
+      sizeof (GfsGenericSurfaceClass),
+      (GtsObjectClassInitFunc) gfs_surface_class_init,
+      (GtsObjectInitFunc) gfs_surface_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_surface_class ()), 
+				  &gfs_surface_info);
   }
-  if (order == FTT_POST_ORDER &&
-      (flags == FTT_TRAVERSE_ALL ||
-       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
-       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
-    (* func) (cell, s1, data);
-  if (s1 != s)
-    gts_object_destroy (GTS_OBJECT (s1));
-}
-
-/**
- * gfs_cell_traverse_cut:
- * @root: the root #FttCell of the tree to traverse.
- * @s: a #GfsSurface.
- * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
- * %FTT_POST_ORDER. 
- * @flags: which types of children are to be visited.
- * @func: the function to call for each visited #FttCell.
- * @data: user data to pass to @func.
- * 
- * Traverses a cell tree starting at the given root #FttCell. Calls
- * the given function for each cell cut by @s.
- */
-void gfs_cell_traverse_cut (FttCell * root,
-			    GfsSurface * s,
-			    FttTraverseType order,
-			    FttTraverseFlags flags,
-			    FttCellTraverseCutFunc func,
-			    gpointer data)
-{
-  g_return_if_fail (root != NULL);
-  g_return_if_fail (s != NULL);
-  g_return_if_fail (func != NULL);
 
-  cell_traverse_cut (root, s, order, flags, func, data, FALSE);
+  return klass;
 }
 
 /**
- * gfs_cell_traverse_cut_2D:
- * @root: the root #FttCell of the tree to traverse.
- * @s: a #GfsSurface.
- * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
- * %FTT_POST_ORDER. 
- * @flags: which types of children are to be visited.
- * @func: the function to call for each visited #FttCell.
- * @data: user data to pass to @func.
- * 
- * Traverses a cell tree starting at the given root #FttCell. Calls
- * the given function for each cell cut by @s.
+ * gfs_surface_implicit_value:
+ * @s: an (implicit) #GfsSurface.
+ * @p: a #GtsPoint.
  *
- * The cells are "flattened" in the z-direction.
+ * Returns: the value of the implicit surface a location @p.
  */
-void gfs_cell_traverse_cut_2D (FttCell * root,
-			       GfsSurface * s,
-			       FttTraverseType order,
-			       FttTraverseFlags flags,
-			       FttCellTraverseCutFunc func,
-			       gpointer data)
+gdouble gfs_surface_implicit_value (GfsSurface * s, GtsPoint p)
 {
-  g_return_if_fail (root != NULL);
-  g_return_if_fail (s != NULL);
-  g_return_if_fail (func != NULL);
+  g_return_val_if_fail (s != NULL, 0.);
+  g_return_val_if_fail (s->f != NULL, 0.);
 
-  cell_traverse_cut (root, s, order, flags, func, data, TRUE);
+  if (s->m)
+    gts_point_transform (&p, s->m);
+  return (s->flip ? -1. : 1.)*gfs_function_spatial_value (s->f, (FttVector *)&p.x);
 }
diff --git a/src/surface.h b/src/surface.h
index 214f0e5..f0e5307 100644
--- a/src/surface.h
+++ b/src/surface.h
@@ -23,6 +23,80 @@
 #include <gts.h>
 #include "ftt.h"
 
+/* GfsGenericSurface: Header */
+
+typedef GtsObject GfsGenericSurface;
+
+typedef struct {
+  GtsPoint * E, * D;
+  gdouble x;
+  guint n;
+  gint inside;
+} GfsSegment;
+
+typedef struct _GfsGenericSurfaceClass    GfsGenericSurfaceClass;
+
+struct _GfsGenericSurfaceClass {
+  /*< private >*/
+  GtsObjectClass parent_class;
+
+  /*< public >*/
+  GfsGenericSurface * (* cell_is_cut)          (FttCell * cell,
+						GfsGenericSurface * s,
+						gboolean flatten,
+						gint maxlevel);
+  guint               (* segment_intersection) (GfsGenericSurface * s,
+						FttCell * cell,
+						GfsSegment * I);
+  void                (* segment_normal)       (GfsGenericSurface * s,
+						FttCell * cell,
+						GfsSegment * I,
+						GtsVector n);
+};
+
+#define GFS_GENERIC_SURFACE(obj)            GTS_OBJECT_CAST (obj,\
+					         GtsObject,\
+					         gfs_generic_surface_class ())
+#define GFS_GENERIC_SURFACE_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsGenericSurfaceClass,\
+						 gfs_generic_surface_class())
+#define GFS_IS_GENERIC_SURFACE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_generic_surface_class ()))
+
+GfsGenericSurfaceClass * gfs_generic_surface_class  (void);
+guint              gfs_surface_segment_intersection (GfsGenericSurface * s,
+						     FttCell * cell,
+						     GfsSegment * I);
+void               gfs_surface_segment_normal       (GfsGenericSurface * s,
+						     FttCell * cell,
+						     GfsSegment * I,
+						     GtsVector n);
+GfsGenericSurface *      gfs_cell_is_cut (FttCell * cell,
+					  GfsGenericSurface * s,
+					  gboolean flatten,
+					  gint maxlevel);
+typedef void       (* FttCellTraverseCutFunc) (FttCell * cell,
+					       GfsGenericSurface * s,
+					       gpointer data);
+void               gfs_cell_traverse_cut       (FttCell * root,
+						GfsGenericSurface * s,
+						FttTraverseType order,
+						FttTraverseFlags flags,
+						FttCellTraverseCutFunc func,
+						gpointer data);
+void               gfs_cell_traverse_cut_2D    (FttCell * root,
+						GfsGenericSurface * s,
+						FttTraverseType order,
+						FttTraverseFlags flags,
+						FttCellTraverseCutFunc func,
+						gpointer data);
+void               gfs_generic_surface_read    (GfsGenericSurface * s, 
+						gpointer sim,
+						GtsFile * fp);
+void               gfs_generic_surface_write   (GfsGenericSurface * s,
+						gpointer sim,
+						FILE * fp);
+
 /* GfsSurface: Header */
 
 typedef struct _GfsSurface         GfsSurface;
@@ -40,52 +114,15 @@ struct _GfsSurface {
   gboolean twod;
 };
 
-typedef struct {
-  GtsPoint * E, * D;
-  gdouble x;
-  guint n;
-  gint inside;
-} GfsSegment;
-
 #define GFS_SURFACE(obj)            GTS_OBJECT_CAST (obj,\
 					         GfsSurface,\
 					         gfs_surface_class ())
 #define GFS_IS_SURFACE(obj)         (gts_object_is_from_class (obj,\
 						 gfs_surface_class ()))
 
-GtsObjectClass *   gfs_surface_class          (void);
-void               gfs_surface_read           (GfsSurface * s, 
-					       gpointer sim,
-					       GtsFile * fp);
-void               gfs_surface_write          (GfsSurface * s,
-					       gpointer sim,
-					       FILE * fp);
+GfsGenericSurfaceClass *   gfs_surface_class          (void);
 gdouble            gfs_surface_implicit_value (GfsSurface * s, 
 					       GtsPoint p);
-guint              gfs_surface_segment_intersection (GfsSurface * s,
-						     GfsSegment * I);
-void               gfs_surface_segment_normal (GfsSurface * s,
-					       GfsSegment * I,
-					       GtsVector n);
-GfsSurface *       gfs_cell_is_cut            (FttCell * cell,
-					       GfsSurface * s,
-					       gboolean flatten,
-					       gint maxlevel);
-typedef void       (* FttCellTraverseCutFunc) (FttCell * cell,
-					       GfsSurface * s,
-					       gpointer data);
-void               gfs_cell_traverse_cut       (FttCell * root,
-						GfsSurface * s,
-						FttTraverseType order,
-						FttTraverseFlags flags,
-						FttCellTraverseCutFunc func,
-						gpointer data);
-void               gfs_cell_traverse_cut_2D    (FttCell * root,
-						GfsSurface * s,
-						FttTraverseType order,
-						FttTraverseFlags flags,
-						FttCellTraverseCutFunc func,
-						gpointer data);
 
 #ifdef __cplusplus
 }

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list