[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
popinet at users.sf.net
Fri May 15 02:53:10 UTC 2009
The following commit has been merged in the upstream branch:
commit 16533780f580a230957f9d4de6717d43c90fd1ca
Author: Stephane Popinet <popinet at users.sf.net>
Date: Wed Mar 15 15:20:29 2006 +1100
Thin cells are removed
"Thin" cells are topologically complex cut cells which lead to
inaccurate volume-of-fluid representation of solid surfaces. In some
cases the presence of these cells could lead to instabilities in the
projection. In all cases they would lead to inaccurate velocities.
darcs-hash:20060315042029-d4795-fb87c2f1dc1d923c96e2798029b15eeca37d28f3.gz
diff --git a/src/output.c b/src/output.c
index 4048177..33da9fb 100644
--- a/src/output.c
+++ b/src/output.c
@@ -749,10 +749,12 @@ static gboolean gfs_output_solid_stats_event (GfsEvent * event,
"Total merged solid volume fraction\n"
" min: %10.3e avg: %10.3e | %10.3e max: %10.3e n: %10d\n"
"Number of cells merged per merged cell\n"
- " min: %10.0f avg: %10.3f | %10.3f max: %10.0f n: %10d\n",
+ " min: %10.0f avg: %10.3f | %10.3f max: %10.0f n: %10d\n"
+ "Number of \"thin\" cells removed: %10d\n",
stats.min, stats.mean, stats.stddev, stats.max, stats.n,
ma.min, ma.mean, ma.stddev, ma.max, ma.n,
- mn.min, mn.mean, mn.stddev, mn.max, mn.n);
+ mn.min, mn.mean, mn.stddev, mn.max, mn.n,
+ sim->thin);
return TRUE;
}
return FALSE;
diff --git a/src/simulation.c b/src/simulation.c
index fd9ea6c..c6282f2 100644
--- a/src/simulation.c
+++ b/src/simulation.c
@@ -873,9 +873,9 @@ void gfs_simulation_refine (GfsSimulation * sim)
if (sim->surface) {
gfs_domain_timer_start (domain, "solid_fractions");
- gfs_domain_init_solid_fractions (domain, sim->surface, TRUE,
- (FttCellCleanupFunc) gfs_cell_cleanup, NULL,
- NULL);
+ sim->thin = gfs_domain_init_solid_fractions (domain, sim->surface, TRUE,
+ (FttCellCleanupFunc) gfs_cell_cleanup, NULL,
+ NULL);
gfs_domain_match (domain);
gfs_domain_timer_stop (domain, "solid_fractions");
}
diff --git a/src/simulation.h b/src/simulation.h
index cfd172f..9cfd50e 100644
--- a/src/simulation.h
+++ b/src/simulation.h
@@ -65,6 +65,7 @@ struct _GfsSimulation {
GfsAdvectionParams advection_params;
GtsSurface * surface;
+ guint thin;
gboolean output_surface;
GtsSListContainer * refines;
diff --git a/src/solid.c b/src/solid.c
index b1726f7..40ec980 100644
--- a/src/solid.c
+++ b/src/solid.c
@@ -263,17 +263,20 @@ static gboolean solid_face_is_thin (CellFace * f)
* @s: a #GtsSurface.
*
* Sets the 2D volume fractions of @cell cut by @s.
+ *
+ * Returns: %TRUE if the cell is thin, %FALSE otherwise;
*/
-void gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
- GtsSurface * s)
+gboolean gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
+ GtsSurface * s)
{
GfsSolidVector * solid;
FttVector h;
CellFace f;
guint i, n1 = 0;
+ gboolean thin = FALSE;
- g_return_if_fail (cell != NULL);
- g_return_if_fail (s != NULL);
+ g_return_val_if_fail (cell != NULL, FALSE);
+ g_return_val_if_fail (s != NULL, FALSE);
h.x = h.y = ftt_cell_size (cell);
face_new (&f, cell, s, &h);
@@ -294,7 +297,10 @@ void gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
GFS_STATE (cell)->solid = NULL;
}
break;
- case 2: case 4: {
+ case 4:
+ thin = TRUE;
+ /* fall through */
+ case 2: {
if (!solid)
GFS_STATE (cell)->solid = solid = g_malloc (sizeof (GfsSolidVector));
face_fractions (&f, solid, &h);
@@ -304,11 +310,28 @@ void gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
"the surface is probably not closed (n1 = %d)", n1);
}
+ return thin;
}
+typedef struct {
+ gboolean destroy_solid;
+ FttCellCleanupFunc cleanup;
+ gpointer data;
+ GfsVariable * status;
+ guint thin;
+} InitSolidParams;
+
#if FTT_2D /* 2D */
-# define set_solid_fractions_from_surface gfs_set_2D_solid_fractions_from_surface
+static void set_solid_fractions_from_surface (FttCell * cell,
+ GtsSurface * s,
+ InitSolidParams * p)
+{
+ if (gfs_set_2D_solid_fractions_from_surface (cell, s)) {
+ GFS_VARIABLE (cell, p->status->i) = 1.;
+ p->thin++;
+ }
+}
/**
* gfs_solid_is_thin:
@@ -446,7 +469,7 @@ static void cube_new (CellCube * cube, FttCell * cell, GtsSurface * s, FttVector
gts_surface_foreach_face (s, (GtsFunc) triangle_cube_intersection, cube);
}
-static void set_solid_fractions_from_surface3D (FttCell * cell, GtsSurface * s)
+static void set_solid_fractions_from_surface (FttCell * cell, GtsSurface * s, InitSolidParams * p)
{
GfsSolidVector * solid = GFS_STATE (cell)->solid;
CellCube cube;
@@ -581,13 +604,8 @@ static void set_solid_fractions_from_surface3D (FttCell * cell, GtsSurface * s)
else {
solid->cm = solid->ca;
solid->a = 0.;
- for (i = 0; i < FTT_NEIGHBORS; i++)
- solid->a += solid->s[i];
- solid->a /= FTT_NEIGHBORS;
- if (solid->a == 0. || solid->a == 1.) {
- g_free (solid);
- GFS_STATE (cell)->solid = NULL;
- }
+ GFS_VARIABLE (cell, p->status->i) = 1.;
+ p->thin++;
}
}
@@ -626,8 +644,6 @@ gboolean gfs_solid_is_thin (FttCell * cell, GtsSurface * s)
return (topology (&cube) > 1);
}
-# define set_solid_fractions_from_surface set_solid_fractions_from_surface3D
-
#endif /* 2D3 or 3D */
static gdouble solid_sa (GfsSolidVector * s)
@@ -752,7 +768,7 @@ static void push_leaf (GtsFifo * fifo, FttCell * cell, FttDirection d, gdouble a
GFS_VARIABLE (child.c[i], status->i) = a;
gts_fifo_push (fifo, child.c[i]);
}
- }
+ }
}
static void paint_leaf (GtsFifo * fifo, gdouble a, GfsVariable * status)
@@ -803,13 +819,6 @@ static void paint_mixed_leaf (FttCell * cell, GfsVariable * status)
}
}
-typedef struct {
- gboolean destroy_solid;
- FttCellCleanupFunc cleanup;
- gpointer data;
- GfsVariable * status;
-} InitSolidParams;
-
static void solid_fractions_from_children (FttCell * cell, InitSolidParams * p)
{
if (!FTT_CELL_IS_LEAF (cell)) {
@@ -856,28 +865,33 @@ static void match_fractions (FttCell * cell, GfsVariable * status)
if (GFS_IS_MIXED (cell)) {
FttCellNeighbors neighbor;
guint level = ftt_cell_level (cell);
+ GfsSolidVector * solid = GFS_STATE (cell)->solid;
FttDirection d;
ftt_cell_neighbors (cell, &neighbor);
for (d = 0; d < FTT_NEIGHBORS; d++)
if (neighbor.c[d] &&
- !GFS_CELL_IS_BOUNDARY (neighbor.c[d]) &&
- GFS_VARIABLE (neighbor.c[d], status->i) != 1.) {
+ !GFS_CELL_IS_BOUNDARY (neighbor.c[d])) {
if (!FTT_CELL_IS_LEAF (neighbor.c[d])) {
FttCellChildren child;
FttDirection od = FTT_OPPOSITE_DIRECTION (d);
guint i, n = ftt_cell_children_direction (neighbor.c[d], od, &child);
gdouble s = 0.;
+ g_assert (GFS_VARIABLE (neighbor.c[d], status->i) != 1.);
for (i = 0; i < n; i++)
if (child.c[i] && GFS_VARIABLE (child.c[i], status->i) != 1.)
s += GFS_IS_MIXED (child.c[i]) ? GFS_STATE (child.c[i])->solid->s[od] : 1.;
- GFS_STATE (cell)->solid->s[d] = s/n;
+ solid->s[d] = s/n;
}
- else if (!GFS_IS_MIXED (neighbor.c[d]) && GFS_STATE (cell)->solid->s[d] < 1.) {
- g_assert (ftt_cell_level (neighbor.c[d]) == level - 1);
- GFS_STATE (cell)->solid->s[d] = 1.;
+ else if (GFS_VARIABLE (neighbor.c[d], status->i) != 1.) {
+ if (!GFS_IS_MIXED (neighbor.c[d]) && solid->s[d] < 1.) {
+ g_assert (ftt_cell_level (neighbor.c[d]) == level - 1);
+ solid->s[d] = 1.;
+ }
}
+ else if (GFS_IS_MIXED (neighbor.c[d])) /* this is a thin cell */
+ solid->s[d] = 0.;
}
}
}
@@ -895,27 +909,30 @@ static void match_fractions (FttCell * cell, GfsVariable * status)
*
* If @destroy_solid is set to %TRUE, the cells entirely contained in
* the solid are destroyed using @cleanup as cleanup function.
+ *
+ * Returns: the number of thin cells.
*/
-void gfs_domain_init_solid_fractions (GfsDomain * domain,
- GtsSurface * s,
- gboolean destroy_solid,
- FttCellCleanupFunc cleanup,
- gpointer data,
- GfsVariable * status)
+guint gfs_domain_init_solid_fractions (GfsDomain * domain,
+ GtsSurface * s,
+ gboolean destroy_solid,
+ FttCellCleanupFunc cleanup,
+ gpointer data,
+ GfsVariable * status)
{
InitSolidParams p;
- g_return_if_fail (domain != NULL);
- g_return_if_fail (s != NULL);
+ g_return_val_if_fail (domain != NULL, 0);
+ g_return_val_if_fail (s != NULL, 0);
p.destroy_solid = destroy_solid;
p.cleanup = cleanup;
p.data = data;
p.status = status ? status : gfs_temporary_variable (domain);
- gfs_domain_traverse_cut (domain, s, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
- (FttCellTraverseCutFunc) set_solid_fractions_from_surface, NULL);
+ p.thin = 0;
gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
(FttCellTraverseFunc) gfs_cell_reset, p.status);
+ gfs_domain_traverse_cut (domain, s, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+ (FttCellTraverseCutFunc) set_solid_fractions_from_surface, &p);
gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
(FttCellTraverseFunc) paint_mixed_leaf, p.status);
gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
@@ -923,6 +940,8 @@ void gfs_domain_init_solid_fractions (GfsDomain * domain,
gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) foreach_box, &p);
if (status == NULL)
gts_object_destroy (GTS_OBJECT (p.status));
+
+ return p.thin;
}
static gboolean check_area_fractions (const FttCell * root)
diff --git a/src/solid.h b/src/solid.h
index d1648ec..1cfda72 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,
GtsSurface * s);
-void gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
+gboolean gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
GtsSurface * s);
-void gfs_domain_init_solid_fractions (GfsDomain * domain,
+guint gfs_domain_init_solid_fractions (GfsDomain * domain,
GtsSurface * s,
gboolean destroy_solid,
FttCellCleanupFunc cleanup,
diff --git a/src/timestep.c b/src/timestep.c
index f786179..ce0e4fa 100644
--- a/src/timestep.c
+++ b/src/timestep.c
@@ -80,10 +80,11 @@ static void scale_gradients (FttCell * cell, gpointer * data)
if (GFS_IS_MIXED (cell)) {
GfsSolidVector * s = GFS_STATE (cell)->solid;
- for (c = 0; c < *dimension; c++) {
- g_assert (s->s[2*c] + s->s[2*c + 1] > 0.);
- GFS_VARIABLE (cell, g[c]->i) /= s->s[2*c] + s->s[2*c + 1];
- }
+ for (c = 0; c < *dimension; c++)
+ if (s->s[2*c] + s->s[2*c + 1] > 0.)
+ GFS_VARIABLE (cell, g[c]->i) /= s->s[2*c] + s->s[2*c + 1];
+ else
+ g_assert (GFS_VARIABLE (cell, g[c]->i) == 0.);
}
else {
FttCellNeighbors n;
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list