[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
popinet at users.sourceforge.net
Fri May 15 02:51:14 UTC 2009
The following commit has been merged in the upstream branch:
commit 2bcae611752441943880c55658e2f143416a6e6e
Author: Stephane Popinet <popinet at users.sourceforge.net>
Date: Thu Oct 14 08:12:50 2004 +1000
Support for binary simulation files (gerris--mainline--0.5--patch-5)
gerris--mainline--0.5--patch-5
Keywords:
Binary files speed up reading time by a factor of ~5 for big simulations.
There is no consideration of endianess at this point.
darcs-hash:20041013221250-aabb8-a90871bc9a5f5a6d95ffa7194ddd3acfb3e5a466.gz
diff --git a/src/boundary.c b/src/boundary.c
index 3144016..ae18d5d 100644
--- a/src/boundary.c
+++ b/src/boundary.c
@@ -1019,9 +1019,12 @@ static void gfs_box_write (GtsObject * object, FILE * fp)
fputs (" }", fp);
if (domain != NULL && domain->max_depth_write > -2) {
fputs (" {\n", fp);
- ftt_cell_write (box->root, domain->max_depth_write, fp,
- (FttCellWriteFunc) gfs_cell_write,
- domain->variables_io);
+ if (domain->binary)
+ ftt_cell_write_binary (box->root, domain->max_depth_write, fp,
+ (FttCellWriteFunc) gfs_cell_write_binary, domain->variables_io);
+ else
+ ftt_cell_write (box->root, domain->max_depth_write, fp,
+ (FttCellWriteFunc) gfs_cell_write, domain->variables_io);
fputc ('}', fp);
}
}
@@ -1110,8 +1113,20 @@ static void gfs_box_read (GtsObject ** o, GtsFile * fp)
ftt_cell_destroy (b->root, (FttCellCleanupFunc) gfs_cell_cleanup, NULL);
fp->scope_max++;
- gts_file_first_token_after (fp, '\n');
- b->root = ftt_cell_read (fp, (FttCellReadFunc) gfs_cell_read, domain);
+ if (domain->binary) {
+ if (gts_file_getc (fp) != '\n') {
+ gts_file_error (fp, "expecting a newline");
+ return;
+ }
+ b->root = ftt_cell_read_binary (fp, (FttCellReadFunc) gfs_cell_read_binary, domain);
+ if (fp->type == GTS_ERROR)
+ return;
+ gts_file_next_token (fp);
+ }
+ else {
+ gts_file_first_token_after (fp, '\n');
+ b->root = ftt_cell_read (fp, (FttCellReadFunc) gfs_cell_read, domain);
+ }
fp->scope_max--;
if (fp->type == GTS_ERROR)
return;
diff --git a/src/domain.c b/src/domain.c
index f53b6ee..a17d1ce 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1865,6 +1865,42 @@ void gfs_cell_copy (const FttCell * from,
}
/**
+ * gfs_cell_write:
+ * @cell: a #FttCell.
+ * @fp: a file pointer.
+ * @variables: the #GfsVariable to be written.
+ *
+ * Writes in @fp the fluid data associated with @cell and described by
+ * @variables. This function is generally used in association with
+ * ftt_cell_write().
+ */
+void gfs_cell_write (const FttCell * cell, FILE * fp,
+ GfsVariable * variables)
+{
+ g_return_if_fail (cell != NULL);
+ g_return_if_fail (fp != NULL);
+
+ if (GFS_IS_MIXED (cell)) {
+ GfsStateVector * s = GFS_STATE (cell);
+ guint i;
+
+ for (i = 0; i < FTT_NEIGHBORS; i++)
+ fprintf (fp, " %g", s->solid->s[i]);
+ fprintf (fp, " %g", s->solid->a);
+ for (i = 0; i < FTT_DIMENSION; i++)
+ fprintf (fp, " %g", (&s->solid->cm.x)[i]);
+ }
+ else
+ fputs (" -1", fp);
+
+ while (variables) {
+ if (variables->name)
+ fprintf (fp, " %g", GFS_VARIABLE (cell, variables->i));
+ variables = variables->next;
+ }
+}
+
+/**
* gfs_cell_read:
* @cell: a #FttCell.
* @fp: a #GtsFile.
@@ -1936,6 +1972,103 @@ void gfs_cell_read (FttCell * cell, GtsFile * fp, GfsDomain * domain)
}
/**
+ * gfs_cell_write_binary:
+ * @cell: a #FttCell.
+ * @fp: a file pointer.
+ * @variables: the #GfsVariable to be written.
+ *
+ * Writes in @fp the fluid data associated with @cell and described by
+ * @variables. This function is generally used in association with
+ * ftt_cell_write_binary().
+ */
+void gfs_cell_write_binary (const FttCell * cell, FILE * fp,
+ GfsVariable * variables)
+{
+ g_return_if_fail (cell != NULL);
+ g_return_if_fail (fp != NULL);
+
+ if (GFS_IS_MIXED (cell)) {
+ GfsStateVector * s = GFS_STATE (cell);
+
+ fwrite (s->solid->s, sizeof (gdouble), FTT_NEIGHBORS, fp);
+ fwrite (&s->solid->a, sizeof (gdouble), 1, fp);
+ fwrite (&s->solid->cm.x, sizeof (gdouble), FTT_DIMENSION, fp);
+ }
+ else {
+ gdouble a = -1.;
+ fwrite (&a, sizeof (gdouble), 1, fp);
+ }
+
+ while (variables) {
+ if (variables->name) {
+ gdouble a = GFS_VARIABLE (cell, variables->i);
+ fwrite (&a, sizeof (gdouble), 1, fp);
+ }
+ variables = variables->next;
+ }
+}
+
+/**
+ * gfs_cell_read_binary:
+ * @cell: a #FttCell.
+ * @fp: a #GtsFile.
+ * @domain: the #GfsDomain containing @cell.
+ *
+ * Reads from @fp the fluid data associated with @cell and described
+ * by @domain->variables_io. This function is generally used in
+ * association with ftt_cell_read_binary().
+ */
+void gfs_cell_read_binary (FttCell * cell, GtsFile * fp, GfsDomain * domain)
+{
+ gdouble s0;
+ GfsStateVector * s;
+ GfsVariable * v;
+
+ g_return_if_fail (cell != NULL);
+ g_return_if_fail (fp != NULL);
+ g_return_if_fail (domain != NULL);
+
+ if (gts_file_read (fp, &s0, sizeof (gdouble), 1) != 1) {
+ gts_file_error (fp, "expecting a number (solid->s[0])");
+ return;
+ }
+
+ gfs_cell_init (cell, domain);
+ s = cell->data;
+ if (s0 >= 0.) {
+ guint i;
+
+ s->solid = g_malloc0 (sizeof (GfsSolidVector));
+ s->solid->s[0] = s0;
+
+ if (gts_file_read (fp, &s->solid->s[1], sizeof (gdouble), FTT_NEIGHBORS - 1) != FTT_NEIGHBORS - 1) {
+ gts_file_error (fp, "expecting numbers (solid->s[1..%d])", FTT_NEIGHBORS - 1);
+ return;
+ }
+ if (gts_file_read (fp, &s->solid->a, sizeof (gdouble), 1) != 1) {
+ gts_file_error (fp, "expecting a number (solid->a)");
+ return;
+ }
+ if (gts_file_read (fp, &s->solid->cm.x, sizeof (gdouble), FTT_DIMENSION) != FTT_DIMENSION) {
+ gts_file_error (fp, "expecting numbers (solid->cm[0..%d])", FTT_DIMENSION - 1);
+ return;
+ }
+ }
+
+ v = domain->variables_io;
+ while (v) {
+ gdouble a;
+
+ if (gts_file_read (fp, &a, sizeof (gdouble), 1) != 1) {
+ gts_file_error (fp, "expecting a number (%s)", v->name);
+ return;
+ }
+ GFS_VARIABLE (cell, v->i) = a;
+ v = v->next;
+ }
+}
+
+/**
* gfs_domain_replace_variable:
* @domain: a #GfsDomain.
* @v: the #GfsVariable to replace.
diff --git a/src/domain.h b/src/domain.h
index c61b070..f99c0a0 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -176,6 +176,15 @@ void gfs_cell_copy (const FttCell * from,
void gfs_cell_read (FttCell * cell,
GtsFile * fp,
GfsDomain * domain);
+void gfs_cell_write (const FttCell * cell,
+ FILE * fp,
+ GfsVariable * variables);
+void gfs_cell_read_binary (FttCell * cell,
+ GtsFile * fp,
+ GfsDomain * domain);
+void gfs_cell_write_binary (const FttCell * cell,
+ FILE * fp,
+ GfsVariable * variables);
void gfs_domain_replace_variable (GfsDomain * domain,
GfsVariable * v,
GfsVariable * with);
diff --git a/src/fluid.c b/src/fluid.c
index 703d4c4..b164be3 100644
--- a/src/fluid.c
+++ b/src/fluid.c
@@ -819,7 +819,7 @@ static gboolean face_bilinear (const FttCellFace * face,
(*cell_pos) (n[i + 1], &cm);
cm.x = (cm.x - o->x)/size;
cm.y = (cm.y - o->y)/size;
- g_assert (fabs (cm.x) <= 5./2. && fabs (cm.y) <= 5./2.);
+ g_assert (fabs (cm.x) <= 4. && fabs (cm.y) <= 4.);
m[i][0] = cm.x;
m[i][1] = cm.y;
m[i][2] = cm.x*cm.y;
@@ -1793,42 +1793,6 @@ void gfs_cell_traverse_mixed (FttCell * root,
}
/**
- * gfs_cell_write:
- * @cell: a #FttCell.
- * @fp: a file pointer.
- * @variables: the #GfsVariable to be written.
- *
- * Writes in @fp the fluid data associated with @cell and described by
- * @variables. This function is generally used in association with
- * ftt_cell_write().
- */
-void gfs_cell_write (const FttCell * cell, FILE * fp,
- GfsVariable * variables)
-{
- g_return_if_fail (cell != NULL);
- g_return_if_fail (fp != NULL);
-
- if (GFS_IS_MIXED (cell)) {
- GfsStateVector * s = GFS_STATE (cell);
- guint i;
-
- for (i = 0; i < FTT_NEIGHBORS; i++)
- fprintf (fp, " %g", s->solid->s[i]);
- fprintf (fp, " %g", s->solid->a);
- for (i = 0; i < FTT_DIMENSION; i++)
- fprintf (fp, " %g", (&s->solid->cm.x)[i]);
- }
- else
- fputs (" -1", fp);
-
- while (variables) {
- if (variables->name)
- fprintf (fp, " %g", GFS_VARIABLE (cell, variables->i));
- variables = variables->next;
- }
-}
-
-/**
* gfs_interpolate:
* @cell: a #FttCell containing location @p.
* @p: the location at which to interpolate.
diff --git a/src/fluid.h b/src/fluid.h
index a46ecc2..010de42 100644
--- a/src/fluid.h
+++ b/src/fluid.h
@@ -183,9 +183,6 @@ GTS_C_VAR GfsVariable * gfs_derived_first, * gfs_derived_last;
void gfs_cell_cleanup (FttCell * cell);
void gfs_cell_reset (FttCell * cell,
GfsVariable * v);
-void gfs_cell_write (const FttCell * cell,
- FILE * fp,
- GfsVariable * variables);
void gfs_get_from_above (FttCell * cell,
const GfsVariable * v);
void gfs_get_from_below_intensive (FttCell * cell,
diff --git a/src/ftt.c b/src/ftt.c
index f5cfe68..de4d844 100644
--- a/src/ftt.c
+++ b/src/ftt.c
@@ -1698,13 +1698,8 @@ void ftt_cell_destroy (FttCell * cell,
g_assert (opneighbor == cell);
FTT_ROOT_CELL (neighbor.c[i])->neighbors.c[od] = NULL;
}
- if (!FTT_CELL_IS_LEAF (neighbor.c[i])) {
- FttOct * children = neighbor.c[i]->children;
- FttCell * opneighbor = children->neighbors.c[od];
-
- /* g_assert (opneighbor == NULL || opneighbor == cell); */
- children->neighbors.c[od] = NULL;
- }
+ if (!FTT_CELL_IS_LEAF (neighbor.c[i]))
+ neighbor.c[i]->children->neighbors.c[od] = NULL;
}
if (FTT_CELL_IS_ROOT (cell))
@@ -1984,6 +1979,48 @@ void ftt_cell_write (const FttCell * root,
}
}
+/**
+ * ftt_cell_write_binary:
+ * @root: a #FttCell.
+ * @max_depth: the maximum depth at which to stop writing (-1 means no limit).
+ * @fp: a file pointer.
+ * @write: a #FttCellWriteFunc function or %NULL.
+ * @data: user data to pass to @write.
+ *
+ * Writes in the file pointed to by @fp a binary representation of the
+ * cell tree starting at @root. If not %NULL, the user-defined
+ * function @write is used to write the extra user data associated
+ * with each cell.
+ */
+void ftt_cell_write_binary (const FttCell * root,
+ gint max_depth,
+ FILE * fp,
+ FttCellWriteFunc write,
+ gpointer data)
+{
+ guint flags;
+
+ g_return_if_fail (root != NULL);
+ g_return_if_fail (fp != NULL);
+
+ flags = root->flags;
+ if (FTT_CELL_IS_LEAF (root) || ftt_cell_level (root) == max_depth)
+ flags |= FTT_FLAG_LEAF;
+
+ fwrite (&flags, sizeof (guint), 1, fp);
+ if (write && !FTT_CELL_IS_DESTROYED (root))
+ (* write) (root, fp, data);
+
+ if ((flags & FTT_FLAG_LEAF) == 0) {
+ FttOct * oct;
+ guint i;
+
+ oct = root->children;
+ for (i = 0; i < FTT_CELLS; i++)
+ ftt_cell_write_binary (&(oct->cell[i]), max_depth, fp, write, data);
+ }
+}
+
#define FTT_CELL_IS_FLAGGED_LEAF(cell) (((cell)->flags & FTT_FLAG_LEAF) != 0)
static gboolean oct_read (FttCell * parent,
@@ -2093,6 +2130,105 @@ FttCell * ftt_cell_read (GtsFile * fp,
return root;
}
+static gboolean oct_read_binary (FttCell * parent,
+ GtsFile * fp,
+ FttCellReadFunc read,
+ gpointer data);
+
+static gboolean cell_read_binary (FttCell * cell,
+ GtsFile * fp,
+ FttCellReadFunc read,
+ gpointer data)
+{
+ guint flags;
+
+ if (gts_file_read (fp, &flags, sizeof (guint), 1) != 1) {
+ gts_file_error (fp, "expecting an integer (flags)");
+ return FALSE;
+ }
+ if (FTT_CELL_ID (cell) != (flags & FTT_FLAG_ID)) {
+ gts_file_error (fp, "flags `%d' != (flags & FTT_FLAG_ID) `%d'",
+ flags, (flags & FTT_FLAG_ID));
+ return FALSE;
+ }
+ cell->flags = flags;
+
+ if (read && !FTT_CELL_IS_DESTROYED (cell))
+ (* read) (cell, fp, data);
+ if (fp->type == GTS_ERROR)
+ return FALSE;
+
+ if (!FTT_CELL_IS_DESTROYED (cell) && !FTT_CELL_IS_FLAGGED_LEAF (cell))
+ return oct_read_binary (cell, fp, read, data);
+
+ cell->flags &= ~FTT_FLAG_LEAF;
+ return TRUE;
+}
+
+static gboolean oct_read_binary (FttCell * parent,
+ GtsFile * fp,
+ FttCellReadFunc read,
+ gpointer data)
+{
+ FttOct * oct;
+ guint n;
+
+ oct = g_malloc0 (sizeof (FttOct));
+ oct->level = ftt_cell_level (parent);
+ oct->parent = parent;
+#ifdef FTT_2D3
+ oct->dz = ftt_cell_dz (parent);
+#endif
+ parent->children = oct;
+ ftt_cell_pos (parent, &(oct->pos));
+
+ for (n = 0; n < FTT_CELLS; n++) {
+ oct->cell[n].parent = oct;
+ oct->cell[n].flags = n;
+ }
+
+ for (n = 0; n < FTT_CELLS; n++)
+ if (!cell_read_binary (&(oct->cell[n]), fp, read, data))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * ftt_cell_read_binary:
+ * @fp: a #GtsFile.
+ * @read: a #FttCellReadFunc function or %NULL.
+ * @data: user data to pass to @read.
+ *
+ * If an error occurs (i.e. corrupted file or file format incorrect),
+ * the @error field of @fp is set. A possibly incomplete tree is then
+ * returned.
+ *
+ * Returns: the root cell of the tree contained in the file pointed to
+ * by @fp. If not %NULL, the user-defined function @read is used to
+ * read the extra user data associated with each cell.
+ */
+FttCell * ftt_cell_read_binary (GtsFile * fp,
+ FttCellReadFunc read,
+ gpointer data)
+{
+ FttCell * root;
+ guint l, depth;
+
+ g_return_val_if_fail (fp != NULL, NULL);
+
+ root = ftt_cell_new (NULL, NULL);
+ cell_read_binary (root, fp, read, data);
+
+ depth = ftt_cell_depth (root);
+ for (l = 0; l < depth; l++)
+ ftt_cell_traverse (root, FTT_PRE_ORDER,
+ FTT_TRAVERSE_LEVEL|FTT_TRAVERSE_NON_LEAFS, l,
+ (FttCellTraverseFunc) set_neighbors, NULL);
+
+ return root;
+}
+
/**
* ftt_refine_corner:
* @cell: a #FttCell.
diff --git a/src/ftt.h b/src/ftt.h
index 2b7dea9..31c3715 100644
--- a/src/ftt.h
+++ b/src/ftt.h
@@ -711,12 +711,20 @@ void ftt_cell_write (const FttCell * root,
FILE * fp,
FttCellWriteFunc write,
gpointer data);
+void ftt_cell_write_binary (const FttCell * root,
+ gint max_depth,
+ FILE * fp,
+ FttCellWriteFunc write,
+ gpointer data);
typedef void (* FttCellReadFunc) (FttCell * cell,
GtsFile * fp,
gpointer data);
FttCell * ftt_cell_read (GtsFile * fp,
FttCellReadFunc read,
gpointer data);
+FttCell * ftt_cell_read_binary (GtsFile * fp,
+ FttCellReadFunc read,
+ gpointer data);
typedef void (* FttCellCleanupFunc) (FttCell * cell,
gpointer data);
void ftt_cell_destroy (FttCell * cell,
diff --git a/src/gerris.c b/src/gerris.c
index 80e829f..f02ce24 100644
--- a/src/gerris.c
+++ b/src/gerris.c
@@ -120,7 +120,7 @@ int main (int argc, char * argv[])
return 1; /* failure */
}
- fptr = fopen (argv[optind], "rt");
+ fptr = fopen (argv[optind], "r");
if (fptr == NULL) {
fprintf (stderr, "gerris: unable to open file `%s'\n", argv[optind]);
return 1;
diff --git a/src/output.c b/src/output.c
index a73c607..d076cfe 100644
--- a/src/output.c
+++ b/src/output.c
@@ -1162,12 +1162,15 @@ static gboolean output_simulation_event (GfsEvent * event, GfsSimulation * sim)
if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
GfsDomain * domain = GFS_DOMAIN (sim);
GfsVariable * var = domain->variables_io;
+ gboolean binary = domain->binary;
domain->variables_io = GFS_OUTPUT_SIMULATION (event)->var;
- gfs_simulation_write (sim,
- GFS_OUTPUT_SIMULATION (event)->max_depth,
- GFS_OUTPUT (event)->file->fp);
+ domain->binary = GFS_OUTPUT_SIMULATION (event)->binary;
+ gfs_simulation_write (sim,
+ GFS_OUTPUT_SIMULATION (event)->max_depth,
+ GFS_OUTPUT (event)->file->fp);
domain->variables_io = var;
+ domain->binary = binary;
fflush (GFS_OUTPUT (event)->file->fp);
return TRUE;
}
@@ -1179,8 +1182,7 @@ static void output_simulation_write (GtsObject * o, FILE * fp)
GfsOutputSimulation * output = GFS_OUTPUT_SIMULATION (o);
GfsVariable * v = output->var;
- (* GTS_OBJECT_CLASS (gfs_output_simulation_class ())->parent_class->write)
- (o, fp);
+ (* GTS_OBJECT_CLASS (gfs_output_simulation_class ())->parent_class->write) (o, fp);
fputs (" {", fp);
if (output->max_depth != -1)
@@ -1194,14 +1196,17 @@ static void output_simulation_write (GtsObject * o, FILE * fp)
v = v->next;
}
}
+ if (output->binary)
+ fputs (" binary = 1", fp);
fputs (" }", fp);
}
static void output_simulation_read (GtsObject ** o, GtsFile * fp)
{
GtsFileVariable var[] = {
- {GTS_INT, "depth", TRUE},
+ {GTS_INT, "depth", TRUE},
{GTS_STRING, "variables", TRUE},
+ {GTS_INT, "binary", TRUE},
{GTS_NONE}
};
gchar * variables = NULL;
@@ -1215,6 +1220,7 @@ static void output_simulation_read (GtsObject ** o, GtsFile * fp)
var[0].data = &output->max_depth;
var[1].data = &variables;
+ var[2].data = &output->binary;
gts_file_assign_variables (fp, var);
if (fp->type == GTS_ERROR) {
g_free (variables);
diff --git a/src/output.h b/src/output.h
index d7527cf..e4072b0 100644
--- a/src/output.h
+++ b/src/output.h
@@ -132,6 +132,7 @@ struct _GfsOutputSimulation {
gint max_depth;
GfsVariable * var;
+ gboolean binary;
};
#define GFS_OUTPUT_SIMULATION(obj) GTS_OBJECT_CAST (obj,\
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list