[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
popinet at users.sf.net
Fri May 15 02:54:42 UTC 2009
The following commit has been merged in the upstream branch:
commit a2c8a0a7dd8417fbbb1f5fd2c1dc77dc1c1bb348
Author: Stephane Popinet <popinet at users.sf.net>
Date: Fri Sep 14 09:07:59 2007 +1000
Fix for domain splitting with periodic boundary conditions
darcs-hash:20070913230759-d4795-6f2633be9c6b541d57b3377fad5fda117afa2af2.gz
diff --git a/src/boundary.c b/src/boundary.c
index 2875f94..1534bd6 100644
--- a/src/boundary.c
+++ b/src/boundary.c
@@ -1043,6 +1043,7 @@ static void periodic_match (GfsBoundary * boundary)
static void send (GfsBoundary * bb)
{
GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
+ g_assert (boundary->matching);
GfsBoundaryPeriodic * matching = GFS_BOUNDARY_PERIODIC (boundary->matching->neighbor[bb->d]);
g_assert (GFS_IS_BOUNDARY_PERIODIC (matching));
diff --git a/src/domain.c b/src/domain.c
index c74fe72..5ef244c 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1675,20 +1675,24 @@ GfsDomain * gfs_domain_read (GtsFile * fp)
return domain;
}
-static void box_split (GfsBox * box, gpointer * data)
+typedef struct {
+ GSList * boxlist;
+ guint bid;
+ gboolean one_box_per_pe;
+ gint pid;
+ GfsVariable * newboxp;
+ GfsDomain * domain;
+} SplitPar;
+
+static void box_split (GfsBox * box, SplitPar * p)
{
- GSList ** boxlist = data[0];
- guint * bid = data[1];
- gboolean * one_box_per_pe = data[2];
- gint * pid = data[3];
- GfsVariable * newboxp = data[4];
guint refid = FTT_DIMENSION == 2 ? 2 : 6;
FttCellChildren child;
FttDirection d;
guint i;
GfsDomain * domain = gfs_box_domain (box);
- *boxlist = g_slist_prepend (*boxlist, box);
+ p->boxlist = g_slist_prepend (p->boxlist, box);
if (FTT_CELL_IS_LEAF (box->root))
ftt_cell_refine_single (box->root, (FttCellInitFunc) gfs_cell_init, domain);
@@ -1699,16 +1703,16 @@ static void box_split (GfsBox * box, gpointer * data)
GfsBox * newbox = GFS_BOX (gts_object_new (GTS_OBJECT (box)->klass));
GTS_OBJECT (newbox)->reserved = domain;
- if (*one_box_per_pe)
- newbox->pid = (*pid)++;
+ if (p->one_box_per_pe)
+ newbox->pid = (p->pid)++;
else
newbox->pid = box->pid;
if (box->id == 1 && i == refid)
newbox->id = 1;
else
- newbox->id = (*bid)++;
+ newbox->id = (p->bid)++;
- GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], newboxp->i)) = newbox;
+ GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], p->newboxp->i)) = newbox;
if (FTT_CELL_IS_LEAF (child.c[i]))
ftt_cell_refine_single (child.c[i], (FttCellInitFunc) gfs_cell_init, domain);
@@ -1732,25 +1736,30 @@ static void box_split (GfsBox * box, gpointer * data)
for (i = 0; i < FTT_CELLS/2; i++)
if (child.c[i]) {
FttCell * neighbor = ftt_cell_neighbor (child.c[i], d);
- GfsBox * newbox = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], newboxp->i));
+ GfsBox * newbox = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], p->newboxp->i));
GfsBoundaryClass * klass = GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass);
GtsObject * newboundary = GTS_OBJECT (gfs_boundary_new (klass, newbox, d));
- gchar fname[] = "/tmp/XXXXXX";
- gint fd = mkstemp (fname);
- FILE * fp = fdopen (fd, "w");
- GtsFile * gfp;
-
- (* GTS_OBJECT_CLASS (klass)->write) (GTS_OBJECT (boundary), fp);
- fclose (fp);
- close (fd);
- fp = fopen (fname, "r");
- unlink (fname);
- gfp = gts_file_new (fp);
- (* GTS_OBJECT_CLASS (klass)->read) (&newboundary, gfp);
- g_assert (gfp->type != GTS_ERROR);
- gts_file_destroy (gfp);
- fclose (fp);
+ if (GFS_IS_BOUNDARY_PERIODIC (newboundary))
+ GFS_BOUNDARY_PERIODIC (newboundary)->matching =
+ GFS_BOUNDARY_PERIODIC (boundary)->matching;
+ else {
+ gchar fname[] = "/tmp/XXXXXX";
+ gint fd = mkstemp (fname);
+ FILE * fp = fdopen (fd, "w");
+ GtsFile * gfp;
+
+ (* GTS_OBJECT_CLASS (klass)->write) (GTS_OBJECT (boundary), fp);
+ fclose (fp);
+ close (fd);
+ fp = fopen (fname, "r");
+ unlink (fname);
+ gfp = gts_file_new (fp);
+ (* GTS_OBJECT_CLASS (klass)->read) (&newboundary, gfp);
+ g_assert (gfp->type != GTS_ERROR);
+ gts_file_destroy (gfp);
+ fclose (fp);
+ }
g_assert (neighbor);
GFS_BOUNDARY (newboundary)->root = neighbor;
}
@@ -1758,27 +1767,63 @@ static void box_split (GfsBox * box, gpointer * data)
}
}
-static void box_link (GfsBox * box, gpointer * data)
+static GtsGEdge * node_is_linked (GtsGNode * n1, GtsGNode * n2, FttDirection d)
+{
+ GSList * i = GTS_SLIST_CONTAINER (n1)->items;
+ while (i) {
+ if (GTS_GNODE_NEIGHBOR (n1, i->data) == n2 &&
+ GFS_GEDGE (i->data)->d == d)
+ return i->data;
+ i = i->next;
+ }
+ return NULL;
+}
+
+static void box_link (GfsBox * box, SplitPar * p)
{
- GfsVariable * newboxp = data[4];
- GfsDomain * domain = data[5];
FttCellChildren child;
guint i;
ftt_cell_children (box->root, &child);
for (i = 0; i < FTT_CELLS; i++)
if (child.c[i]) {
- GfsBox * newbox = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], newboxp->i));
+ GfsBox * newbox = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], p->newboxp->i));
FttDirection d;
g_assert (newbox);
- gts_container_add (GTS_CONTAINER (domain), GTS_CONTAINEE (newbox));
+ gts_container_add (GTS_CONTAINER (p->domain), GTS_CONTAINEE (newbox));
+
for (d = 0; d < FTT_NEIGHBORS; d++)
- if (newbox->neighbor[d] == NULL) {
+ if (newbox->neighbor[d] != NULL && GFS_IS_BOUNDARY_PERIODIC (newbox->neighbor[d])) {
+ GfsBox * matching = GFS_BOUNDARY_PERIODIC (newbox->neighbor[d])->matching;
+ static FttDirection match[FTT_CELLS][FTT_DIMENSION] = {
+#if FTT_2D
+ {0,2}, {1,2}, {0,3}, {1,3}
+#elif FTT_2D3
+#else /* 3D */
+ {0,2,4}, {1,2,4}, {0,3,4}, {1,3,4},
+ {0,2,5}, {1,2,5}, {0,3,5}, {1,3,5}
+#endif /* 3D */
+ };
+ FttCell * neighbor = ftt_cell_child_corner (matching->root,
+ match[FTT_CELL_ID (child.c[i])]);
+ g_assert (neighbor);
+ GfsBox * newbox1 = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (neighbor, p->newboxp->i));
+ g_assert (newbox1);
+ GFS_BOUNDARY_PERIODIC (newbox->neighbor[d])->matching = newbox1;
+ if (!node_is_linked (GTS_GNODE (newbox1), GTS_GNODE (newbox),
+ FTT_OPPOSITE_DIRECTION (d))) {
+ GfsGEdge * edge = GFS_GEDGE (gts_gedge_new (GTS_GRAPH (p->domain)->edge_class,
+ GTS_GNODE (newbox),
+ GTS_GNODE (newbox1)));
+ edge->d = d;
+ }
+ }
+ else if (newbox->neighbor[d] == NULL) {
FttCell * neighbor = ftt_cell_neighbor (child.c[i], d);
if (neighbor) {
- GfsBox * newbox1 = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (neighbor, newboxp->i));
+ GfsBox * newbox1 = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (neighbor, p->newboxp->i));
FttDirection od = FTT_OPPOSITE_DIRECTION (d);
GfsGEdge * edge;
@@ -1786,7 +1831,7 @@ static void box_link (GfsBox * box, gpointer * data)
newbox->neighbor[d] = GTS_OBJECT (newbox1);
g_assert (newbox1->neighbor[od] == NULL);
newbox1->neighbor[od] = GTS_OBJECT (newbox);
- edge = GFS_GEDGE (gts_gedge_new (GTS_GRAPH (domain)->edge_class,
+ edge = GFS_GEDGE (gts_gedge_new (GTS_GRAPH (p->domain)->edge_class,
GTS_GNODE (newbox),
GTS_GNODE (newbox1)));
edge->d = d;
@@ -1838,28 +1883,23 @@ static void get_ref_pos (GfsBox * box, FttVector * pos)
*/
void gfs_domain_split (GfsDomain * domain, gboolean one_box_per_pe)
{
- GSList * list = NULL;
- guint bid = 2;
- gint pid = 0;
- gpointer data[6];
- GfsVariable * newboxp;
+ SplitPar p;
g_return_if_fail (domain != NULL);
- newboxp = gfs_temporary_variable (domain);
+ p.newboxp = gfs_temporary_variable (domain);
gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, 1,
- (FttCellTraverseFunc) gfs_cell_reset, newboxp);
- data[0] = &list;
- data[1] = &bid;
- data[2] = &one_box_per_pe;
- data[3] = &pid;
- data[4] = newboxp;
- data[5] = domain;
- gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_split, data);
- g_slist_foreach (list, (GFunc) box_link, data);
- g_slist_foreach (list, (GFunc) box_destroy, newboxp);
- g_slist_free (list);
- gts_object_destroy (GTS_OBJECT (newboxp));
+ (FttCellTraverseFunc) gfs_cell_reset, p.newboxp);
+ p.boxlist = NULL;
+ p.bid = 2;
+ p.pid = 0;
+ p.one_box_per_pe = one_box_per_pe;
+ p.domain = domain;
+ gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_split, &p);
+ g_slist_foreach (p.boxlist, (GFunc) box_link, &p);
+ g_slist_foreach (p.boxlist, (GFunc) box_destroy, p.newboxp);
+ g_slist_free (p.boxlist);
+ gts_object_destroy (GTS_OBJECT (p.newboxp));
gfs_domain_match (domain);
domain->rootlevel++;
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list