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

Stephane Popinet popinet at users.sf.net
Tue Nov 24 12:24:08 UTC 2009


The following commit has been merged in the upstream branch:
commit 17a7ca17ecb8e4a98d8f2e491b8c3e53f08236da
Author: Stephane Popinet <popinet at users.sf.net>
Date:   Thu Jun 18 18:14:25 2009 +1000

    New gfsjoin2D, gfsjoin3D tools
    
    These are replacing the gfsjoin script. Note however that they can only be used
    to join parallel files created using this and later versions of Gerris. Older
    parallel simulation files should still use the gfsjoin script.
    
    darcs-hash:20090618081425-d4795-5451510c6e3cee16c6890077ff47774cd13fff48.gz

diff --git a/src/domain.c b/src/domain.c
index 084b971..29e3ec3 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -196,16 +196,10 @@ static void mpi_links (GfsBox * box, GfsDomain * domain)
 
   for (d = 0; d < FTT_NEIGHBORS; d++)
     if (neighbor[d])
-#ifndef DUMMY_MPI
       gfs_boundary_mpi_new (gfs_boundary_mpi_class (),
 			    GFS_BOX (neighbor[d]), 
 			    FTT_OPPOSITE_DIRECTION (d), 
 			    pid, id);
-#else  /* DUMMY_MPI */
-      gfs_boundary_new (GFS_BOUNDARY_CLASS (gfs_boundary_outflow_class ()),
-			GFS_BOX (neighbor[d]), 
-			FTT_OPPOSITE_DIRECTION (d));
-#endif /* DUMMY_MPI */
 }
 #endif /* HAVE_MPI */
 
diff --git a/src/mpi_boundary.c b/src/mpi_boundary.c
index 1c5919f..0bf07c2 100644
--- a/src/mpi_boundary.c
+++ b/src/mpi_boundary.c
@@ -17,12 +17,35 @@
  * 02111-1307, USA.  
  */
 
+#include <stdlib.h>
 #include "domain.h"
 #include "mpi_boundary.h"
 #include "adaptive.h"
 
 /* #define DEBUG mpi_debug */
 
+static void boundary_mpi_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_boundary_mpi_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %d %d", GFS_BOUNDARY_MPI (o)->process, GFS_BOUNDARY_MPI (o)->id);
+}
+
+static void boundary_mpi_read (GtsObject ** o, GtsFile * fp)
+{
+  if (fp->type == GTS_INT) {
+    GFS_BOUNDARY_MPI (*o)->process = atoi (fp->token->str);
+    gts_file_next_token (fp);
+    if (fp->type != GTS_INT) {
+      gts_file_error (fp, "expecting an integer (id)");
+      return;
+    }
+    GFS_BOUNDARY_MPI (*o)->id = atoi (fp->token->str);
+    gts_file_next_token (fp);
+  }
+  else
+    GFS_BOUNDARY_MPI (*o)->process = GFS_BOUNDARY_MPI (*o)->id = -1;
+}
+
 #ifdef DEBUG
 FILE * mpi_debug = NULL;
 #endif
@@ -39,6 +62,9 @@ static void send (GfsBoundary * bb)
   GfsBoundaryMpi * mpi = GFS_BOUNDARY_MPI (bb);
   GfsDomain * domain = gfs_box_domain (bb->box);
 
+  if (domain->pid < 0)
+    return;
+
   g_assert (boundary->sndcount <= boundary->sndbuf->len);
   if (GFS_BOUNDARY (boundary)->type == GFS_BOUNDARY_MATCH_VARIABLE) {
 #ifdef DEBUG
@@ -76,8 +102,13 @@ static void receive (GfsBoundary * bb,
 {
   GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
   GfsBoundaryMpi * mpi = GFS_BOUNDARY_MPI (bb);
+  GfsDomain * domain = gfs_box_domain (bb->box);
   MPI_Status status;
   gint count;
+
+  if (domain->pid < 0)
+    return;
+
 #ifdef PROFILE_MPI
   GfsDomain * domain = gfs_box_domain (bb->box);
   gdouble start, end;
@@ -180,6 +211,8 @@ static void synchronize (GfsBoundary * bb)
 
 static void gfs_boundary_mpi_class_init (GfsBoundaryClass * klass)
 {
+  GTS_OBJECT_CLASS (klass)->read = boundary_mpi_read;
+  GTS_OBJECT_CLASS (klass)->write = boundary_mpi_write;
   klass->send        = send;
   klass->receive     = receive;
   klass->synchronize = synchronize;
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 71dd459..a28b37a 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -12,6 +12,8 @@ bin_PROGRAMS = \
 	gfscompare2D \
 	gfscompare2D3 \
 	gfscompare3D \
+	gfsjoin2D \
+	gfsjoin3D \
 	shapes
 
 bin_SCRIPTS = \
@@ -31,6 +33,8 @@ gfs2oogl3D_SOURCES = gfs2oogl.c
 gfscompare2D_SOURCES = gfscompare.c
 gfscompare2D3_SOURCES = gfscompare.c
 gfscompare3D_SOURCES = gfscompare.c
+gfsjoin2D_SOURCES = gfsjoin2.c
+gfsjoin3D_SOURCES = gfsjoin2.c
 
 gfs2oogl2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
 gfs2oogl2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
@@ -42,6 +46,9 @@ gfscompare2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
 gfscompare2D_LDADD = $(GFS2D_LIBS)
 gfscompare2D3_LDADD = $(GFS2D3_LIBS)
 gfscompare3D_LDADD = $(GFS3D_LIBS)
+gfsjoin2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfsjoin2D_LDADD = $(GFS2D_LIBS)
+gfsjoin3D_LDADD = $(GFS3D_LIBS)
 
 ppmcombine_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
 ppmcombine_LDADD = $(GFS2D_LIBS)
diff --git a/tools/gfsjoin2.c b/tools/gfsjoin2.c
new file mode 100644
index 0000000..230dfc3
--- /dev/null
+++ b/tools/gfsjoin2.c
@@ -0,0 +1,179 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2009 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 "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+
+#include "init.h"
+#include "simulation.h"
+
+#ifdef HAVE_MPI
+# include <mpi.h>
+# include "mpi_boundary.h"
+#endif /* HAVE_MPI */
+
+static void add_box (GfsBox * box, GfsSimulation * sim)
+{
+  gts_container_add (GTS_CONTAINER (sim), GTS_CONTAINEE (box));
+}
+
+static void hash_id (GfsBox * box, GHashTable * hash)
+{
+  g_hash_table_insert (hash, &box->id, box);
+}
+
+static void convert_boundary_mpi_into_edges (GfsBox * box, GHashTable * hash)
+{
+#ifdef HAVE_MPI
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      GfsBoundaryMpi * b = GFS_BOUNDARY_MPI (box->neighbor[d]);
+      if (b->id < 0) {
+	fprintf (stderr, 
+		 "gfsjoin: id < 0, you maybe trying to join old parallel simulation files\n");
+	exit (1);
+      }
+      GfsBox * nbox = g_hash_table_lookup (hash, &b->id);
+      if (!nbox) {
+	fprintf (stderr, "gfsjoin: inconsistent MPI boundary: pid = %d, id = %d\n",
+		 b->process, b->id);
+	exit (1);
+      }
+      if (nbox->pid != b->process) {
+	fprintf (stderr, "gfsjoin: inconsistent MPI boundary: pid = %d, nbox->pid = %d\n",
+		 b->process, nbox->pid);
+	exit (1);
+      }
+      if (!GFS_IS_BOUNDARY_MPI (nbox->neighbor[FTT_OPPOSITE_DIRECTION (d)])) {
+	fprintf (stderr, "gfsjoin: inconsistent MPI boundary: nbox[%d] is not an MPI boundary\n",
+		 FTT_OPPOSITE_DIRECTION (d));
+	exit (1);
+      }
+      GfsBoundaryMpi * nb = GFS_BOUNDARY_MPI (nbox->neighbor[FTT_OPPOSITE_DIRECTION (d)]);
+      if (box->pid != nb->process || box->id != nb->id) {
+	fprintf (stderr, "gfsjoin: inconsistent MPI boundary\n"
+		 "box->pid != nb->process || box->id != nb->id\n");
+	exit (1);
+      }
+      gts_object_destroy (GTS_OBJECT (b));
+      gts_object_destroy (GTS_OBJECT (nb));
+      gfs_gedge_new (gfs_gedge_class (), box, nbox, d);
+    }
+#endif /* HAVE_MPI */
+}
+
+int main (int argc, char * argv[])
+{
+  int c = 0;
+  gboolean verbose = FALSE;
+
+  gfs_init (&argc, &argv);
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, 
+			      "hv",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, 
+			 "hv"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+	       "Usage: gfsjoin [OPTION] NAME1 NAME2... > JOINED\n"
+	       "Joins several parallel Gerris simulation files\n"
+	       "\n"
+	       "  -v      --verbose     display statistics and other info\n"
+	       "  -h      --help        display this help and exit\n"
+	       "\n"
+	       "Reports bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `gfsjoin --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+#ifndef HAVE_MPI
+  fprintf (stderr, 
+	   "gfsjoin: only works for MPI version of Gerris\n"
+	   "Try `gfsjoin --help' for more information.\n");
+  return 1; /* failure */
+#endif
+
+  if (optind >= argc) { /* missing NAME */
+    fprintf (stderr, 
+	     "gfsjoin: missing NAME\n"
+	     "Try `gfsjoin --help' for more information.\n");
+    return 1; /* failure */
+  }
+
+  GfsSimulation ** sim = g_malloc (sizeof (GfsSimulation *)*(argc - optind));
+  for (c = optind; c < argc; c++) {
+    FILE * fptr = fopen (argv[c], "r");
+    if (fptr == NULL) {
+      fprintf (stderr, "gfsjoin: cannot open file `%s'\n", argv[c]);
+      return 1; /* failure */
+    }
+    GtsFile * fp = gts_file_new (fptr);    
+    if (!(sim[c - optind] = gfs_simulation_read (fp))) {
+      fprintf (stderr, 
+	       "gfsjoin: file `%s' is not a valid simulation file\n"
+	       "%s:%d:%d: %s\n",
+	       argv[c], argv[c], fp->line, fp->pos, fp->error);
+      return 1;
+    }
+    if (verbose)
+      fprintf (stderr, "%s: %d box(es), %d cells\n", argv[c],
+	       gts_container_size (GTS_CONTAINER (sim[c - optind])),
+	       gfs_domain_size (GFS_DOMAIN (sim[c - optind]), FTT_TRAVERSE_LEAFS, -1));
+  }
+
+  /* Add all boxes to first simulation */
+  for (c = 1; c < argc - optind; c++)
+    gts_container_foreach (GTS_CONTAINER (sim[c]), (GtsFunc) add_box, sim[0]);
+
+  /* Create hash table for fast linking of ids to GfsBox pointers */
+  GHashTable * hash = g_hash_table_new (g_int_hash, g_int_equal);
+  gts_container_foreach (GTS_CONTAINER (sim[0]), (GtsFunc) hash_id, hash);
+
+  /* Convert GfsBoundaryMpi into graph edges */
+  gts_container_foreach (GTS_CONTAINER (sim[0]), (GtsFunc) convert_boundary_mpi_into_edges, hash);
+
+  gfs_simulation_write (sim[0], -1, stdout);
+
+  return 0;
+}

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list