[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