[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
popinet at users.sf.net
Fri May 15 02:54:55 UTC 2009
The following commit has been merged in the upstream branch:
commit 166cea036ac6478ab83f0cbde9442c6437f96789
Author: Stephane Popinet <popinet at users.sf.net>
Date: Fri Jan 11 11:48:15 2008 +1100
New function gfs_domain_tag_droplets()
Used by GfsRemoveDroplets. This is more generic than the previous
implementation.
darcs-hash:20080111004815-d4795-bc5b7577688850f187810360a404609966f8a7a6.gz
diff --git a/src/domain.c b/src/domain.c
index 7bde91d..2f5e396 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -2820,16 +2820,12 @@ void gfs_domain_solid_force (GfsDomain * domain,
}
}
-typedef struct {
- GfsVariable * v, * c;
- GArray * sizes;
- guint min;
-} RemoveDropletsPar;
+#define THRESHOLD 1e-4
static void tag_cell_fraction (GtsFifo * fifo,
FttCell * cell,
GfsVariable * c, GfsVariable * v,
- guint tag, guint * size)
+ guint tag)
{
FttDirection d;
FttCellNeighbors n;
@@ -2837,10 +2833,9 @@ static void tag_cell_fraction (GtsFifo * fifo,
g_assert (FTT_CELL_IS_LEAF (cell));
ftt_cell_neighbors (cell, &n);
for (d = 0; d < FTT_NEIGHBORS; d++)
- if (n.c[d] && GFS_VARIABLE (n.c[d], v->i) == 0. && GFS_VARIABLE (n.c[d], c->i) > 1e-4) {
+ if (n.c[d] && GFS_VARIABLE (n.c[d], v->i) == 0. && GFS_VARIABLE (n.c[d], c->i) > THRESHOLD) {
if (FTT_CELL_IS_LEAF (n.c[d])) {
GFS_VARIABLE (n.c[d], v->i) = tag;
- (*size)++;
gts_fifo_push (fifo, n.c[d]);
}
else {
@@ -2854,38 +2849,81 @@ static void tag_cell_fraction (GtsFifo * fifo,
ftt_cell_children_direction (n.c[d], od, &child);
for (i = 0; i < FTT_CELLS/2; i++)
if (child.c[i] && GFS_VARIABLE (child.c[i], v->i) == 0. &&
- GFS_VARIABLE (child.c[i], c->i) > 1e-4) {
+ GFS_VARIABLE (child.c[i], c->i) > THRESHOLD) {
GFS_VARIABLE (child.c[i], v->i) = tag;
- (*size)++;
gts_fifo_push (fifo, child.c[i]);
}
}
}
}
-static void tag_new_fraction_region (FttCell * cell, RemoveDropletsPar * p)
+typedef struct {
+ GfsVariable * v, * c;
+ guint tag;
+} TagPar;
+
+static void tag_new_fraction_region (FttCell * cell, TagPar * p)
{
- if (GFS_VARIABLE (cell, p->v->i) == 0. && GFS_VARIABLE (cell, p->c->i) > 1e-4) {
- guint size = 1;
+ if (GFS_VARIABLE (cell, p->v->i) == 0. && GFS_VARIABLE (cell, p->c->i) > THRESHOLD) {
GtsFifo * fifo = gts_fifo_new ();
- GFS_VARIABLE (cell, p->v->i) = p->sizes->len + 1;
+ GFS_VARIABLE (cell, p->v->i) = ++p->tag;
gts_fifo_push (fifo, cell);
while ((cell = gts_fifo_pop (fifo)))
- tag_cell_fraction (fifo, cell, p->c, p->v, p->sizes->len + 1, &size);
+ tag_cell_fraction (fifo, cell, p->c, p->v, p->tag);
gts_fifo_destroy (fifo);
- g_array_append_val (p->sizes, size);
}
}
-static void reset_small_fraction (FttCell * cell, RemoveDropletsPar * p)
+/**
+ * gfs_domain_tag_droplets:
+ * @domain: a #GfsDomain.
+ * @c: the volume fraction.
+ * @tag: a #GfsVariable.
+ *
+ * Fills the @tag variable of the cells of @domain with the (strictly
+ * positive) index of the droplet they belong to. The cells belonging
+ * to the background phase have an index of zero.
+ *
+ * Returns: the number of droplets.
+ */
+guint gfs_domain_tag_droplets (GfsDomain * domain,
+ GfsVariable * c,
+ GfsVariable * tag)
{
- if (GFS_VARIABLE (cell, p->v->i) > 0.) {
- guint i = GFS_VARIABLE (cell, p->v->i) - 1.;
+ g_return_val_if_fail (domain != NULL, 0);
+ g_return_val_if_fail (c != NULL, 0);
+ g_return_val_if_fail (tag != NULL, 0);
- if (g_array_index (p->sizes, guint, i) < p->min)
- GFS_VARIABLE (cell, p->c->i) = 0.;
- }
+ TagPar p;
+ p.c = c;
+ p.v = tag;
+ p.tag = 0;
+ gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+ (FttCellTraverseFunc) gfs_cell_reset, tag);
+ gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+ (FttCellTraverseFunc) tag_new_fraction_region, &p);
+ return p.tag;
+}
+
+typedef struct {
+ GfsVariable * tag, * c;
+ guint * sizes;
+ guint n, min;
+} RemoveDropletsPar;
+
+static void compute_droplet_size (FttCell * cell, RemoveDropletsPar * p)
+{
+ guint i = GFS_VARIABLE (cell, p->tag->i);
+ if (i > 0)
+ p->sizes[i - 1]++;
+}
+
+static void reset_small_fraction (FttCell * cell, RemoveDropletsPar * p)
+{
+ guint i = GFS_VARIABLE (cell, p->tag->i);
+ if (i > 0 && p->sizes[i - 1] < p->min)
+ GFS_VARIABLE (cell, p->c->i) = 0.;
}
static int greater (const void * a, const void * b)
@@ -2913,29 +2951,26 @@ void gfs_domain_remove_droplets (GfsDomain * domain,
g_return_if_fail (c != NULL);
p.c = c;
- p.v = gfs_temporary_variable (domain);
- p.sizes = g_array_new (FALSE, FALSE, sizeof (guint));
- gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
- (FttCellTraverseFunc) gfs_cell_reset, p.v);
- gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
- (FttCellTraverseFunc) tag_new_fraction_region, &p);
- if (p.sizes->len > 0) {
+ p.tag = gfs_temporary_variable (domain);
+ p.n = gfs_domain_tag_droplets (domain, c, p.tag);
+ if (p.n > 0 && -min < p.n) {
+ p.sizes = g_malloc0 (p.n*sizeof (guint));
+ gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+ (FttCellTraverseFunc) compute_droplet_size, &p);
if (min >= 0)
p.min = min;
- else if (-min >= p.sizes->len)
- p.min = 0;
else {
- guint * tmp = g_malloc (p.sizes->len*sizeof (guint));
- memcpy (tmp, p.sizes->data, p.sizes->len*sizeof (guint));
- qsort (tmp, p.sizes->len, sizeof (guint), greater);
+ guint * tmp = g_malloc (p.n*sizeof (guint));
+ memcpy (tmp, p.sizes, p.n*sizeof (guint));
+ qsort (tmp, p.n, sizeof (guint), greater);
p.min = tmp[-1 - min];
g_free (tmp);
}
gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
(FttCellTraverseFunc) reset_small_fraction, &p);
+ g_free (p.sizes);
}
- g_array_free (p.sizes, TRUE);
- gts_object_destroy (GTS_OBJECT (p.v));
+ gts_object_destroy (GTS_OBJECT (p.tag));
}
static void tag_cell (FttCell * cell, GfsVariable * v, guint tag, guint * size)
diff --git a/src/domain.h b/src/domain.h
index 67e754f..07e7dbe 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -245,6 +245,9 @@ void gfs_domain_solid_force (GfsDomain * domain,
FttVector * vf,
FttVector * pm,
FttVector * vm);
+guint gfs_domain_tag_droplets (GfsDomain * domain,
+ GfsVariable * c,
+ GfsVariable * tag);
void gfs_domain_remove_droplets (GfsDomain * domain,
GfsVariable * c,
gint min);
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list