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

Stephane Popinet popinet at users.sf.net
Fri May 15 02:54:30 UTC 2009


The following commit has been merged in the upstream branch:
commit 177f83437328d9ca5744d9dde935df16ae619875
Author: Stephane Popinet <popinet at users.sf.net>
Date:   Thu May 24 13:10:02 2007 +1000

    Refines cells which are too coarse for VOF advection
    
    Cells are too coarse when one of their neighboring cells is finer and
    contains and interface which will be advected in them at the next
    timestep.
    
    darcs-hash:20070524031002-d4795-4b8dacfc0d455c667f9fec06325f9a1af9e5955d.gz

diff --git a/src/adaptive.c b/src/adaptive.c
index 7b9e627..facceb6 100644
--- a/src/adaptive.c
+++ b/src/adaptive.c
@@ -590,17 +590,44 @@ GfsEventClass * gfs_adapt_curvature_class (void)
   return klass;
 }
 
-#define CELL_COST(cell) (GFS_VARIABLE (cell, p->costv->i))
-#define CELL_HCOARSE(c) (GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (c, p->hcoarsev->i)))
-#define CELL_HFINE(c)   (GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (c, p->hfinev->i)))
-
 static void refine_cell_corner (FttCell * cell, GfsDomain * domain)
 {
   if (ftt_refine_corner (cell))
-    ftt_cell_refine_single (cell, (FttCellInitFunc) gfs_cell_fine_init, 
-			    domain);
+    ftt_cell_refine_single (cell, (FttCellInitFunc) gfs_cell_fine_init, domain);
+}
+
+/**
+ * @domain: a #GfsDomain.
+ * @depth: the depth of @domain.
+ *
+ * Force the grading of the tree hierarchy of domain, matches the
+ * boundaries, recomputes merged cells and applies the boundary
+ * conditions for all variables.
+ */
+void gfs_domain_reshape (GfsDomain * domain, guint depth)
+{
+  gint l;
+
+  g_return_if_fail (domain != NULL);
+
+  for (l = depth - 2; l >= 0; l--)
+    gfs_domain_cell_traverse (domain,
+			     FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+			     (FttCellTraverseFunc) refine_cell_corner, 
+			      domain);
+  gfs_domain_match (domain);
+  gfs_set_merged (domain);
+  GSList * i = domain->variables;
+  while (i) {
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, i->data);
+    i = i->next;
+  }
 }
 
+#define CELL_COST(cell) (GFS_VARIABLE (cell, p->costv->i))
+#define CELL_HCOARSE(c) (GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (c, p->hcoarsev->i)))
+#define CELL_HFINE(c)   (GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (c, p->hfinev->i)))
+
 static FttCell * remove_top_coarse (GtsEHeap * h, gdouble * cost, GfsVariable * hcoarse)
 {
   FttCell * cell = gts_eheap_remove_top (h, cost);
@@ -1008,18 +1035,7 @@ void gfs_simulation_adapt (GfsSimulation * simulation)
     else
       adapt_local (simulation, &depth, &simulation->adapts_stats);
 
-    gint l;
-    for (l = depth - 2; l >= 0; l--)
-      gfs_domain_cell_traverse (domain, 
-				FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
-				(FttCellTraverseFunc) refine_cell_corner, domain);
-    gfs_domain_match (domain);
-    gfs_set_merged (domain);
-    i = domain->variables;
-    while (i) {
-      gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, i->data);
-      i = i->next;
-    }
+    gfs_domain_reshape (domain, depth);
   }
 
   gfs_domain_timer_stop (domain, "adapt");
diff --git a/src/adaptive.h b/src/adaptive.h
index e42b6c7..09768a9 100644
--- a/src/adaptive.h
+++ b/src/adaptive.h
@@ -34,6 +34,8 @@ void          gfs_cell_fine_init            (FttCell * cell,
 void          gfs_adapt_stats_init          (GfsAdaptStats * s);
 void          gfs_adapt_stats_update        (GfsAdaptStats * s);
 void          gfs_simulation_adapt          (GfsSimulation * simulation);
+void          gfs_domain_reshape            (GfsDomain * domain, 
+					     guint depth);
 
 /* GfsAdapt: Header */
 
diff --git a/src/vof.c b/src/vof.c
index 1370b60..a4bab09 100644
--- a/src/vof.c
+++ b/src/vof.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include "vof.h"
 #include "variable.h"
+#include "adaptive.h"
 #include "graphic.h"
 
 #define THRESHOLD(c) {if ((c) < 0.) c = 0.; else if ((c) > 1.) c = 1.;}
@@ -1084,6 +1085,8 @@ GfsVariableClass * gfs_variable_tracer_vof_class (void)
 typedef struct {
   GfsAdvectionParams * par;
   FttComponent c;
+  GfsDomain * domain;
+  guint depth, too_coarse;
 } VofParms;
 
 static gdouble plane_volume_shifted (FttVector m, gdouble alpha, FttVector p[2])
@@ -1153,6 +1156,40 @@ static gdouble coarse_fraction (FttCellFace * face, VofParms * p, gdouble un)
   }
 }
 
+#define TOO_COARSE(cell) (GFS_VARIABLE (cell, p->par->fv->i))
+
+/* Marks coarse cells which should be refined because an interface in
+   a neighboring finer cell will be advected into them */
+static void face_too_coarse (FttCellFace * face, VofParms * p)
+{
+  if (ftt_face_type (face) == FTT_FINE_COARSE) {
+    gdouble un = GFS_FACE_NORMAL_VELOCITY (face);
+    if (!FTT_FACE_DIRECT (face))
+      un = - un;
+    if (un > 0.) {
+      gdouble f = GFS_VARIABLE (face->neighbor, p->par->v->i);
+      if (GFS_IS_FULL (f) &&
+	  fine_fraction (face, p, un*p->par->dt/ftt_cell_size (face->cell)) != f) {
+	p->too_coarse++;
+	TOO_COARSE (face->neighbor) = TRUE;
+      }
+    }
+  }
+}
+
+static void refine_too_coarse (FttCell * cell, VofParms * p)
+{
+  if (TOO_COARSE (cell)) {
+    guint level = ftt_cell_level (cell);
+
+    TOO_COARSE (cell) = FALSE;
+    ftt_cell_refine_corners (cell, (FttCellInitFunc) gfs_cell_fine_init, p->domain);
+    ftt_cell_refine_single (cell, (FttCellInitFunc) gfs_cell_fine_init, p->domain);
+    if (level + 1 > p->depth)
+      p->depth = level + 1;
+  }
+}
+
 static void vof_face_value (FttCellFace * face, VofParms * p)
 {
   gdouble un = GFS_FACE_NORMAL_VELOCITY (face)*p->par->dt/ftt_cell_size (face->cell);
@@ -1246,12 +1283,24 @@ void gfs_tracer_vof_advection (GfsDomain * domain,
   par->fv = gfs_temporary_variable (domain);
   for (c = 0; c < FTT_DIMENSION; c++) {
     p.c = (cstart + c) % FTT_DIMENSION;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_reset, par->fv);
+    p.too_coarse = 0;
+    gfs_domain_face_traverse (domain, p.c,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) face_too_coarse, &p);
+    if (p.too_coarse > 0) {
+      p.depth = 0;
+      p.domain = domain;
+      gfs_domain_cell_traverse (domain,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) refine_too_coarse, &p);
+      gfs_domain_reshape (domain, p.depth);
+    }
     gfs_domain_face_traverse (domain, p.c,
 			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
 			      (FttFaceTraverseFunc) vof_face_value, &p);
     gfs_domain_face_bc (domain, p.c, par->v);
-    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
-			      (FttCellTraverseFunc) gfs_cell_reset, par->fv);
     gfs_domain_face_traverse (domain, p.c,
 			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
 			      (FttFaceTraverseFunc) vof_flux, &p);

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list