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

Stephane Popinet popinet at users.sf.net
Fri May 15 02:53:32 UTC 2009


The following commit has been merged in the upstream branch:
commit 23f416358113471f61342d23231d6b43f348fb23
Author: Stephane Popinet <popinet at users.sf.net>
Date:   Mon Jan 30 07:07:20 2006 +1100

    VariableLevelSet computes the levelset function
    
    darcs-hash:20060129200720-d4795-6f47ffc8d439784fbd63f9abcfbf25a130332871.gz

diff --git a/src/Makefile.am b/src/Makefile.am
index 2d90dc2..0977427 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,6 +51,7 @@ GFS_HDS = \
 	vof.h \
 	utils.h \
 	ocean.h \
+	levelset.h \
 	$(MPI_HDS)
 
 pkginclude_HEADERS = \
@@ -83,6 +84,7 @@ SRC = \
 	vof.c \
 	utils.c \
 	ocean.c \
+	levelset.c \
 	$(GFS_HDS)
 
 libgfs3D_la_LDFLAGS = $(NO_UNDEFINED)\
diff --git a/src/domain.c b/src/domain.c
index 2aec9a2..c2fea66 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1907,7 +1907,7 @@ static void bubble_sort (GPtrArray * a, gdouble * d)
  * For non-leafs cells @distance2 must return a lower-bound for the
  * minimum distance (using for example ftt_cell_point_distance2_min()).
  *
- * Returns: square of the minimum distance measured according to
+ * Returns: the square of the minimum distance measured according to
  * @distance2 between @p and a leaf cell of @domain.
  */
 gdouble gfs_domain_cell_point_distance2 (GfsDomain * domain,
diff --git a/src/init.c b/src/init.c
index 3836c90..d28234c 100644
--- a/src/init.c
+++ b/src/init.c
@@ -36,6 +36,7 @@
 #include "source.h"
 #include "tension.h"
 #include "ocean.h"
+#include "levelset.h"
 
 #include "modules.h"
 
diff --git a/src/levelset.c b/src/levelset.c
new file mode 100644
index 0000000..3460725
--- /dev/null
+++ b/src/levelset.c
@@ -0,0 +1,220 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2006 National Institute of Water and Atmospheric Research
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "levelset.h"
+
+/* GfsVariableLevelSet: object */
+
+static void variable_levelset_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain;
+
+  (* GTS_OBJECT_CLASS (gfs_variable_levelset_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (c)");
+    return;
+  }
+  domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (!(GFS_VARIABLE_LEVELSET (*o)->v = 
+	gfs_variable_from_name (domain->variables, fp->token->str))) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (level)");
+    return;
+  }
+  GFS_VARIABLE_LEVELSET (*o)->level = atof (fp->token->str);
+  gts_file_next_token (fp);
+}
+
+static void variable_levelset_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_levelset_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s %g", GFS_VARIABLE_LEVELSET (o)->v->name, GFS_VARIABLE_LEVELSET (o)->level);
+}
+
+static FttDirection corner[4][2] = {
+  {FTT_LEFT, FTT_BOTTOM}, {FTT_RIGHT, FTT_BOTTOM}, 
+  {FTT_RIGHT, FTT_TOP}, {FTT_LEFT, FTT_TOP}
+};
+
+static void min_max (FttCell * cell, GfsVariableLevelSet * v)
+{
+  gdouble min = G_MAXDOUBLE, max = -G_MAXDOUBLE;
+  guint i;
+
+  if (FTT_CELL_IS_LEAF (cell)) {
+    GfsVariable * c = v->v;
+
+    for (i = 0; i < 4; i++) {
+      gdouble val = gfs_cell_corner_value (cell, corner[i], c, -1);
+      if (val < min) min = val;
+      if (val > max) max = val;
+    }
+  }
+  else {
+    FttCellChildren child;
+
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i]) {
+	gdouble vmin = GFS_VARIABLE (child.c[i], v->min->i);
+	gdouble vmax = GFS_VARIABLE (child.c[i], v->max->i);
+	if (vmin < min) min = vmin;
+	if (vmax > max) max = vmax;
+      }
+  }
+  GFS_VARIABLE (cell, v->min->i) = min;
+  GFS_VARIABLE (cell, v->max->i) = max;
+}
+
+static guint inter (FttVector * p1, FttVector * p2, GtsPoint * m, gdouble z)
+{
+  if ((p1->z > z && p2->z <= z) || (p1->z <= z && p2->z > z)) {
+    gdouble a = (z - p1->z)/(p2->z - p1->z);
+    m->x = p1->x + a*(p2->x - p1->x);
+    m->y = p1->y + a*(p2->y - p1->y);
+    m->z = 0.;
+    return 1;
+  }
+  return 0;
+}
+
+static gdouble isoline_distance2 (FttCell * cell, GtsPoint * t, gpointer v1)
+{
+  GfsVariableLevelSet * v = GFS_VARIABLE_LEVELSET (v1);
+  GfsVariable * c = v->v;
+  gdouble z = v->level;
+
+  if (GFS_VARIABLE (cell, v->min->i) > z || GFS_VARIABLE (cell, v->max->i) < z)
+    return G_MAXDOUBLE;
+  if (!FTT_CELL_IS_LEAF (cell))
+    return ftt_cell_point_distance2_min (cell, t);
+  else {
+    FttVector p[4];
+    GtsPoint m[4];
+    guint n = 0, i;
+    gdouble d2 = G_MAXDOUBLE;
+
+    for (i = 0; i < 4; i++) {
+      ftt_corner_pos (cell, corner[i], &p[i]);
+      p[i].z = gfs_cell_corner_value (cell, corner[i], c, -1);
+    }
+
+    n += inter (&p[0], &p[1], &m[n], z);
+    n += inter (&p[1], &p[2], &m[n], z);
+    n += inter (&p[2], &p[3], &m[n], z);
+    n += inter (&p[3], &p[0], &m[n], z);
+    g_assert (n % 2 == 0);
+
+    for (i = 0; i < n; i += 2) {
+      GtsSegment s;
+      gdouble d3;
+
+      s.v1 = (GtsVertex *) &m[i];
+      s.v2 = (GtsVertex *) &m[i + 1];
+      d3 = gts_point_segment_distance2 (t, &s);
+      if (d3 < d2)
+	d2 = d3;
+    }
+    return d2;
+  }
+}
+
+static void levelset (FttCell * cell, GfsVariable * v)
+{
+  GfsVariableLevelSet * l = GFS_VARIABLE_LEVELSET (v);
+  GtsPoint p;
+  gdouble d2;
+  
+  ftt_cell_pos (cell, (FttVector *) &p.x);
+  d2 = gfs_domain_cell_point_distance2 (v->domain, &p, isoline_distance2, v, NULL);
+  GFS_VARIABLE (cell, v->i) = GFS_VARIABLE (cell, l->v->i) > l->level ? sqrt (d2) : -sqrt (d2);
+}
+
+static void variable_levelset_event_half (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariableLevelSet * v = GFS_VARIABLE_LEVELSET (event);
+
+#if FTT_3D
+  g_assert_not_implemented ();
+#endif
+
+  gfs_domain_timer_start (domain, "levelset");
+
+  v->min = gfs_temporary_variable (domain);
+  v->max = gfs_temporary_variable (domain);
+  gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_ALL, -1,
+  			    (FttCellTraverseFunc) min_max, v);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) levelset, event);
+  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, GFS_VARIABLE1 (event));
+  gts_object_destroy (GTS_OBJECT (v->min));
+  gts_object_destroy (GTS_OBJECT (v->max));
+
+  gfs_domain_timer_stop (domain, "levelset");
+}
+
+static gboolean variable_levelset_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_levelset_class ())->parent_class)->event)
+      (event, sim)) {
+    variable_levelset_event_half (event, sim);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_levelset_class_init (GtsObjectClass * klass)
+{
+  klass->read = variable_levelset_read;
+  klass->write = variable_levelset_write;
+  GFS_EVENT_CLASS (klass)->event = variable_levelset_event;
+  GFS_EVENT_CLASS (klass)->event_half = variable_levelset_event_half;
+}
+
+GfsVariableClass * gfs_variable_levelset_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_levelset_info = {
+      "GfsVariableLevelSet",
+      sizeof (GfsVariableLevelSet),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_levelset_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_levelset_info);
+  }
+
+  return klass;
+}
diff --git a/src/init.h b/src/levelset.h
similarity index 52%
copy from src/init.h
copy to src/levelset.h
index 425b2a2..c330acc 100644
--- a/src/init.h
+++ b/src/levelset.h
@@ -1,5 +1,5 @@
 /* Gerris - The GNU Flow Solver
- * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ * Copyright (C) 2001-2006 National Institute of Water and Atmospheric Research
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -17,21 +17,39 @@
  * 02111-1307, USA.  
  */
 
-#ifndef __INIT_H__
-#define __INIT_H__
-
-#include <gts.h>
+#ifndef __LEVELSET_H__
+#define __LEVELSET_H__
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-GtsObjectClass ** gfs_classes             (void);
-void              gfs_init                (int * argc, 
-					   char *** argv);
+#include "variable.h"
+
+/* GfsVariableLevelSet: header */
+
+typedef struct _GfsVariableLevelSet                GfsVariableLevelSet;
+
+struct _GfsVariableLevelSet {
+  /*< private >*/
+  GfsVariable parent;
+  GfsVariable * min, * max;
+
+  /*< public >*/
+  GfsVariable * v;
+  gdouble level;
+};
+
+#define GFS_VARIABLE_LEVELSET(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableLevelSet,\
+					           gfs_variable_levelset_class ())
+#define GFS_IS_VARIABLE_LEVELSET(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_levelset_class ()))
+
+GfsVariableClass * gfs_variable_levelset_class  (void);
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* __INIT_H__ */
+#endif /* __LEVELSET_H__ */
diff --git a/src/tension.c b/src/tension.c
index bc19466..5c541f5 100644
--- a/src/tension.c
+++ b/src/tension.c
@@ -99,7 +99,7 @@ static void foreach_cell_tension_css (FttCell * cell, GfsSourceTensionCSS * s)
 }
 
 static void gfs_source_tension_css_event (GfsEvent * event, 
-				      GfsSimulation * sim)
+					  GfsSimulation * sim)
 {
   GfsSourceTensionCSS * s = GFS_SOURCE_TENSION_CSS (event);
   guint i;
@@ -123,8 +123,8 @@ static void gfs_source_tension_css_event (GfsEvent * event,
 }
 
 static gdouble gfs_source_tension_css_value (GfsSourceGeneric * s, 
-					 FttCell * cell,
-					 GfsVariable * v)
+					     FttCell * cell,
+					     GfsVariable * v)
 {
   return GFS_VARIABLE (cell, GFS_SOURCE_TENSION_CSS (s)->t[v->component]->i);
 }

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list