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

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


The following commit has been merged in the upstream branch:
commit 3dc1fe470745da266a06b8f4609b5c29cc48d803
Author: Stephane Popinet <popinet at users.sf.net>
Date:   Mon Feb 11 16:36:08 2008 +1100

    VTK/Tecplot export
    
    darcs-hash:20080211053608-d4795-dcd73c8da6092e78b5eedb6d0b86ebc855699bf7.gz

diff --git a/AUTHORS b/AUTHORS
index 06ae08a..e763d99 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,3 +9,4 @@ Ruben Scardovelli: - author of the Fortran version of gfs_plane_alpha()
       		   - Mixed Youngs-Centered VOF normal calculation
 Ivan Adam Vari: RPM packages.
 Daniel Fuster: gfsjoin script
+Rohallah Tavakoli: initial implementation of VTK and Tecplot output
diff --git a/src/Makefile.am b/src/Makefile.am
index 65d2df9..c7b5ad6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,7 @@ GFS_HDS = \
 	isocube.h \
 	cartesian.h \
 	surface.h \
+	unstructured.h \
 	version.h \
 	$(MPI_HDS)
 
@@ -98,6 +99,7 @@ SRC = \
 	myc2d.h \
 	cartesian.c \
 	surface.c \
+	unstructured.c \
 	$(GFS_HDS)
 
 simulation.c: version.h
diff --git a/src/output.c b/src/output.c
index bee532d..4f08f2a 100644
--- a/src/output.c
+++ b/src/output.c
@@ -29,6 +29,7 @@
 #include "adaptive.h"
 #include "solid.h"
 #include "ocean.h"
+#include "unstructured.h"
 
 /* GfsOutput: object */
 
@@ -1230,6 +1231,16 @@ static gboolean output_simulation_event (GfsEvent * event, GfsSimulation * sim)
 				(FttCellTraverseFunc) write_text, event);
       break;
     }
+    case GFS_VTK: {
+      gfs_domain_write_vtk (domain, output->max_depth, domain->variables_io,
+			    GFS_OUTPUT (event)->file->fp);
+      break;
+    }
+    case GFS_TECPLOT: {
+      gfs_domain_write_tecplot (domain, output->max_depth, domain->variables_io,
+				GFS_OUTPUT (event)->file->fp);
+      break;
+    }
     default:
       g_assert_not_reached ();
     }
@@ -1264,8 +1275,12 @@ static void output_simulation_write (GtsObject * o, FILE * fp)
     fputs (" binary = 0", fp);
   if (!output->solid)
     fputs (" solid = 0", fp);
-  if (output->format == GFS_TEXT)
-    fputs (" format = text", fp);
+  switch (output->format) {
+  case GFS_TEXT:    fputs (" format = text", fp);    break;
+  case GFS_VTK:     fputs (" format = VTK", fp);     break;
+  case GFS_TECPLOT: fputs (" format = Tecplot", fp); break;
+  default: break;
+  }
   fputs (" }", fp);
 }
 
@@ -1330,6 +1345,10 @@ static void output_simulation_read (GtsObject ** o, GtsFile * fp)
 	output->format = GFS;
       else if (!strcmp (format, "text"))
 	output->format = GFS_TEXT;
+      else if (!strcmp (format, "VTK"))
+	output->format = GFS_VTK;
+      else if (!strcmp (format, "Tecplot"))
+	output->format = GFS_TECPLOT;
       else {
 	gts_file_variable_error (fp, var, "format",
 				 "unknown format `%s'", format);
diff --git a/src/output.h b/src/output.h
index 8daef8f..5385f2b 100644
--- a/src/output.h
+++ b/src/output.h
@@ -144,7 +144,10 @@ GfsOutputClass * gfs_output_location_class  (void);
 /* GfsOutputSimulation: Header */
 
 typedef struct _GfsOutputSimulation         GfsOutputSimulation;
-typedef enum   { GFS, GFS_TEXT }            GfsOutputSimulationFormat;
+typedef enum   { GFS, 
+		 GFS_TEXT, 
+		 GFS_VTK, 
+		 GFS_TECPLOT }              GfsOutputSimulationFormat;
 
 struct _GfsOutputSimulation {
   GfsOutput parent;
diff --git a/src/unstructured.c b/src/unstructured.c
new file mode 100644
index 0000000..1cfbcfa
--- /dev/null
+++ b/src/unstructured.c
@@ -0,0 +1,370 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2008 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 "unstructured.h"
+#include "variable.h"
+#include "config.h"
+#include "version.h"
+
+#define NV (4*(FTT_DIMENSION - 1))
+
+static void reset_pointers (FttCell * cell, GfsVariable ** v)
+{
+  guint i;
+  for (i = 0; i < NV; i++)
+    GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, v[i])) = NULL;
+}
+
+typedef struct {
+  FttCell * cell;
+  guint i, index;
+} Vertex;
+
+/* Using VTK convention */
+static FttDirection d[NV][FTT_DIMENSION] = {
+#if FTT_2D
+  {FTT_LEFT,FTT_BOTTOM}, {FTT_RIGHT,FTT_BOTTOM}, {FTT_LEFT,FTT_TOP}, {FTT_RIGHT,FTT_TOP},
+#else /* 3D */
+  {FTT_LEFT,FTT_BOTTOM,FTT_BACK}, {FTT_RIGHT,FTT_BOTTOM,FTT_BACK}, 
+  {FTT_LEFT,FTT_TOP,FTT_BACK}, {FTT_RIGHT,FTT_TOP,FTT_BACK},
+  {FTT_LEFT,FTT_BOTTOM,FTT_FRONT}, {FTT_RIGHT,FTT_BOTTOM,FTT_FRONT}, 
+  {FTT_LEFT,FTT_TOP,FTT_FRONT}, {FTT_RIGHT,FTT_TOP,FTT_FRONT}
+#endif /* 3D */
+};
+
+static void vertex_pos (Vertex * v, FttVector * p)
+{
+  ftt_corner_pos (v->cell, d[v->i], p);
+}
+
+static gdouble vertex_value (Vertex * vertex, GfsVariable * v, gint max_depth)
+{
+  return gfs_cell_corner_value (vertex->cell, d[vertex->i], v, max_depth);
+}
+
+typedef struct {
+  GfsVariable ** v;
+  GfsDomain * domain;
+  GSList * vertices;
+  gint max_depth;
+  guint size, index;
+} AllocParams;
+
+static void allocate_vertices (FttCell * cell, AllocParams * par)
+{
+  static gint dx[NV][FTT_DIMENSION] = {
+#if FTT_2D
+    {-1,-1}, {1,-1}, {-1,1}, {1,1},
+#else /* 3D */
+    {-1,-1,-1}, {1,-1,-1}, {-1,1,-1}, {1,1,-1},
+    {-1,-1,1},  {1,-1,1},  {-1,1,1},  {1,1,1}
+#endif /* 3D */
+  };
+
+  gdouble h = ftt_cell_size (cell)/128.;
+  guint i;
+  for (i = 0; i < NV; i++)
+    if (GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[i])) == NULL) {
+      Vertex * vertex = g_malloc (par->size);
+      vertex->i = i;
+      vertex->cell = cell;
+      vertex->index = par->index++;
+      GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[i])) = vertex;
+      par->vertices = g_slist_prepend (par->vertices, vertex);
+      
+      FttVector p;
+      ftt_corner_pos (cell, d[i], &p);
+      FttCell * neighbor[NV];
+      guint j;
+      for (j = 0; j < NV; j++)
+	if (i != j) {
+	  FttVector q;
+	  FttComponent c;
+	  for (c = 0; c < FTT_DIMENSION; c++)
+	    (&q.x)[c] = (&p.x)[c] - dx[j][c]*h;
+	  FttCell * n = gfs_domain_locate (par->domain, q, par->max_depth);
+	  if (n) {
+	    guint k;
+	    for (k = 0; k < j && n; k++)
+	      if (n == neighbor[k]) {
+		/* T-junction */
+#if DEBUG
+		fprintf (stderr, "tj: %g %g %g %g %g %g\n", p.x, p.y, p.z, q.x, q.y, q.z);
+#endif
+		neighbor[k] = n = NULL;
+	      }
+	  }
+	  neighbor[j] = n;
+	}
+	else
+	  neighbor[j] = NULL;
+      for (j = 0; j < NV; j++)
+	if (neighbor[j]) {
+	  g_assert (GFS_DOUBLE_TO_POINTER (GFS_VALUE (neighbor[j], par->v[j])) == NULL);
+	  GFS_DOUBLE_TO_POINTER (GFS_VALUE (neighbor[j], par->v[j])) = vertex;
+	}
+    }
+}
+
+static GSList * allocate_domain_vertices (GfsDomain * domain, 
+					  gint max_depth, 
+					  GfsVariable * v[NV],
+					  guint size)
+{
+  g_return_val_if_fail (size >= sizeof (Vertex), NULL);
+
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) reset_pointers, v);
+  AllocParams par;
+  par.v = v;
+  par.domain = domain;
+  par.max_depth = max_depth;
+  par.size = size;  
+  par.vertices = NULL;
+  par.index = 0;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) allocate_vertices, &par);
+  return g_slist_reverse (par.vertices);
+}
+
+#if DEBUG
+static void print_pos (Vertex * v)
+{
+  FttVector p;
+  ftt_corner_pos (v->cell, d[v->i], &p);
+  fprintf (stderr, "v: %g %g %g\n", p.x, p.y, p.z);
+}
+#endif /* DEBUG */
+
+static void write_pos (Vertex * v, FILE * fp)
+{
+  FttVector p;
+  vertex_pos (v, &p);
+  fprintf (fp, "%g %g %g\n", p.x, p.y, p.z);
+}
+
+#if DEBUG
+static void draw_vertices (FttCell * cell, GfsVariable ** v)
+{
+  guint i;
+  FttVector c;
+  ftt_cell_pos (cell, &c);
+  for (i = 0; i < NV; i++) {
+    Vertex * vertex = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, v[i]));
+    FttVector p;
+    ftt_corner_pos (vertex->cell, d[vertex->i], &p);
+    fprintf (stderr, "vp: %g %g\nvp: %g %g\nvp: \n", c.x, c.y, p.x, p.y);
+  }    
+}
+#endif /* DEBUG */
+
+typedef struct {
+  FILE * fp;
+  GfsVariable ** v;
+} WriteParams;
+
+static void write_element (FttCell * cell, WriteParams * par)
+{
+  fprintf (par->fp, "%d", NV);
+  guint i;
+  for (i = 0; i < NV; i++) {
+    Vertex * v = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[i]));
+    fprintf (par->fp, " %d", v->index);
+  }
+  fputc ('\n', par->fp);
+}
+
+/**
+ * gfs_domain_write_vtk:
+ * @domain: a #GfsDomain.
+ * @max_depth: the maximum depth to consider.
+ * @variables: a list of #GfsVariable to output.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a VTK-formatted representation of @domain and of the
+ * corresponding variables in the given list.
+ */
+void gfs_domain_write_vtk (GfsDomain * domain, gint max_depth, GSList * variables, FILE * fp)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GfsVariable * v[NV];
+  guint i;
+  for (i = 0; i < NV; i++)
+    v[i] = gfs_temporary_variable (domain);
+
+  GSList * vertices = allocate_domain_vertices (domain, max_depth, v, sizeof (Vertex));
+
+  /* header */
+  fprintf (fp, 
+	   "# vtk DataFile Version 2.0\n"
+	   "Gerris simulation version %s (%s)\n"
+	   "ASCII\n"
+	   "DATASET UNSTRUCTURED_GRID\n"
+	   "\n", 
+	   GFS_VERSION,
+	   GFS_BUILD_VERSION);
+  
+  /* vertices */
+  guint nv = g_slist_length (vertices);
+  fprintf (fp, "POINTS %d float\n", nv);
+  g_slist_foreach (vertices, (GFunc) write_pos, fp);
+  fputc ('\n', fp);
+
+  /* elements */
+  guint n_cells = gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, max_depth);
+  fprintf (fp, "CELLS %d %d\n", n_cells, n_cells*(NV + 1));
+  WriteParams par;
+  par.v = v;
+  par.fp = fp;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) write_element, &par);
+  fprintf (fp, "\nCELL_TYPES %d\n",n_cells);
+  for (i = 0; i < n_cells; i++) {
+#if FTT_2D
+    fputs ("8\n", fp);
+#else
+    fputs ("11\n", fp);
+#endif
+  }
+  fputc ('\n', fp);
+
+#if DEBUG
+  fprintf (stderr, "vertices: %d\n", g_slist_length (vertices));
+  g_slist_foreach (vertices, (GFunc) print_pos, NULL);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) draw_vertices, v);
+#endif /* DEBUG */
+  
+  /* write scalar fields */
+  if (variables) {
+    fprintf (fp, "POINT_DATA %d\n", nv);
+    GSList * i = variables;
+    while (i) {
+      GfsVariable * v = i->data;
+      fprintf (fp, "SCALARS %s float\nLOOKUP_TABLE default\n", v->name);
+      GSList * j = vertices;
+      while (j) {
+	Vertex * vertex = j->data;
+	fprintf (fp, "%g\n", vertex_value (vertex, v, max_depth));
+	j = j->next;
+      }
+      fputc ('\n', fp);
+      i = i->next;
+    }
+  }
+
+  /* cleanup */
+  g_slist_foreach (vertices, (GFunc) g_free, NULL);
+  g_slist_free (vertices);
+  for (i = 0; i < NV; i++)
+    gts_object_destroy (GTS_OBJECT (v[i]));
+}
+
+static void write_tecplot_element (FttCell * cell, WriteParams * par)
+{
+  static guint tecplot_index[NV] = {
+#if FTT_2D
+    0, 1, 3, 2
+#else /* 3D */
+    0, 1, 3, 2,
+    4, 5, 7, 6
+#endif /* 3D */
+  };
+  guint i;
+  for (i = 0; i < NV; i++) {
+    Vertex * v = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[tecplot_index[i]]));
+    fprintf (par->fp, "%d ", v->index + 1);
+  }
+  fputc ('\n', par->fp);
+}
+
+/**
+ * gfs_domain_write_tecplot:
+ * @domain: a #GfsDomain.
+ * @max_depth: the maximum depth to consider.
+ * @variables: a list of #GfsVariable to output.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a Tecplot-formatted representation of @domain and of the
+ * corresponding variables in the given list.
+ */
+void gfs_domain_write_tecplot (GfsDomain * domain, gint max_depth, GSList * variables, FILE * fp)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GfsVariable * v[NV];
+  guint i;
+  for (i = 0; i < NV; i++)
+    v[i] = gfs_temporary_variable (domain);
+
+  GSList * vertices = allocate_domain_vertices (domain, max_depth, v, sizeof (Vertex));
+
+  /* header */
+  fprintf (fp,
+	   " TITLE = 'Gerris simulation version %s (%s)'\n",
+	   GFS_VERSION,
+	   GFS_BUILD_VERSION);
+
+  fputs (FTT_DIMENSION == 2 ? " VARIABLES = 'X', 'Y'" : " VARIABLES = 'X', 'Y', 'Z'", fp);
+  GSList * j = variables;
+  while (j) {
+    GfsVariable * v = j->data;
+    fprintf (fp, ", '%s'", v->name);
+    j = j->next;
+  }
+  fputc ('\n', fp);
+
+  guint nv = g_slist_length (vertices);
+  guint n_cells = gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, max_depth);
+  fprintf (fp, " ZONE N=%i, E=%i, F=FEPOINT, ", nv, n_cells);
+  fputs (FTT_DIMENSION == 2 ? "ET=QUADRILATERAL\n" : "ET=BRICK\n", fp);
+  
+  /* vertices and scalar data */
+  j = vertices;
+  while (j) {
+    Vertex * vertex = j->data;
+    FttVector p;
+    vertex_pos (vertex, &p);
+    fprintf (fp, "%g %g %g", p.x, p.y, p.z);
+    GSList * k = variables;
+    while (k) {
+      fprintf (fp, " %g", vertex_value (vertex, k->data, max_depth));
+      k = k->next;
+    }
+    fputc ('\n', fp);
+    j = j->next;
+  }
+
+  /* elements */
+  WriteParams par;
+  par.v = v;
+  par.fp = fp;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) write_tecplot_element, &par);
+
+  /* cleanup */
+  g_slist_foreach (vertices, (GFunc) g_free, NULL);
+  g_slist_free (vertices);
+  for (i = 0; i < NV; i++)
+    gts_object_destroy (GTS_OBJECT (v[i]));
+}
diff --git a/src/init.h b/src/unstructured.h
similarity index 65%
copy from src/init.h
copy to src/unstructured.h
index 425b2a2..67f4520 100644
--- a/src/init.h
+++ b/src/unstructured.h
@@ -1,5 +1,6 @@
 /* Gerris - The GNU Flow Solver
- * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ * Copyright (C) 2001-2008 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
@@ -17,21 +18,26 @@
  * 02111-1307, USA.  
  */
 
-#ifndef __INIT_H__
-#define __INIT_H__
+#ifndef __UNSTRUCTURED_H__
+#define __UNSTRUCTURED_H__
 
-#include <gts.h>
+#include "domain.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-GtsObjectClass ** gfs_classes             (void);
-void              gfs_init                (int * argc, 
-					   char *** argv);
+void gfs_domain_write_vtk     (GfsDomain * domain, 
+			       gint max_depth, 
+			       GSList * variables, 
+			       FILE * fp);
+void gfs_domain_write_tecplot (GfsDomain * domain, 
+			       gint max_depth, 
+			       GSList * variables, 
+			       FILE * fp);
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* __INIT_H__ */
+#endif /* __UNSTRUCTURED_H__ */

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list