[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
popinet at users.sf.net
Fri May 15 02:55:09 UTC 2009
The following commit has been merged in the upstream branch:
commit 52582c4b28d5ada0c7556510a8162528e03ff43f
Author: Stephane Popinet <popinet at users.sf.net>
Date: Tue Mar 25 14:57:21 2008 +1100
Support for geometric "mapping" of domain coordinates
darcs-hash:20080325035721-d4795-a00cb17be98079cc16aa1136213f31114e1740ae.gz
diff --git a/src/Makefile.am b/src/Makefile.am
index c7b5ad6..ade3276 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,7 @@ GFS_HDS = \
cartesian.h \
surface.h \
unstructured.h \
+ map.h \
version.h \
$(MPI_HDS)
@@ -100,6 +101,7 @@ SRC = \
cartesian.c \
surface.c \
unstructured.c \
+ map.c \
$(GFS_HDS)
simulation.c: version.h
diff --git a/src/gfs.h b/src/gfs.h
index 3bdb2ff..2b956da 100644
--- a/src/gfs.h
+++ b/src/gfs.h
@@ -39,6 +39,8 @@
#include <gerris/vof.h>
#include <gerris/cartesian.h>
#include <gerris/surface.h>
+#include <gerris/unstructured.h>
+#include <gerris/map.h>
#include <gerris/version.h>
#endif /* GFS_H */
diff --git a/src/map.c b/src/map.c
new file mode 100644
index 0000000..1b46d1d
--- /dev/null
+++ b/src/map.c
@@ -0,0 +1,90 @@
+/* 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 "map.h"
+#include "variable.h"
+#include "utils.h"
+
+/* GfsMap: Object */
+
+static void gfs_map_read (GtsObject ** o, GtsFile * fp)
+{
+ GfsMap * map = GFS_MAP (*o);
+ GtsObjectClass * klass;
+ gboolean class_changed = FALSE;
+
+ if (fp->type != GTS_STRING) {
+ gts_file_error (fp, "expecting a string (GfsMapClass)");
+ return;
+ }
+ klass = gfs_object_class_from_name (fp->token->str);
+ if (klass == NULL) {
+ gts_file_error (fp, "unknown class `%s'", fp->token->str);
+ return;
+ }
+ if (!gts_object_class_is_from_class (klass, gfs_map_class ())) {
+ gts_file_error (fp, "`%s' is not a GfsMap", fp->token->str);
+ return;
+ }
+ if (klass != (*o)->klass) {
+ *o = gts_object_new (klass);
+ gts_object_destroy (GTS_OBJECT (map));
+ map = GFS_MAP (*o);
+ class_changed = TRUE;
+ }
+ gts_file_next_token (fp);
+}
+
+static void gfs_map_write (GtsObject * o, FILE * fp)
+{
+ fprintf (fp, "%s", o->klass->info.name);
+}
+
+static void identity (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+ *dest = *src;
+}
+
+static void gfs_map_class_init (GfsMapClass * klass)
+{
+ GTS_OBJECT_CLASS (klass)->read = gfs_map_read;
+ GTS_OBJECT_CLASS (klass)->write = gfs_map_write;
+ GFS_MAP_CLASS (klass)->transform = GFS_MAP_CLASS (klass)->inverse = identity;
+}
+
+GfsMapClass * gfs_map_class (void)
+{
+ static GfsMapClass * klass = NULL;
+
+ if (klass == NULL) {
+ GtsObjectClassInfo gfs_map_info = {
+ "GfsMap",
+ sizeof (GfsMap),
+ sizeof (GfsMapClass),
+ (GtsObjectClassInitFunc) gfs_map_class_init,
+ (GtsObjectInitFunc) NULL,
+ (GtsArgSetFunc) NULL,
+ (GtsArgGetFunc) NULL
+ };
+ klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()),
+ &gfs_map_info);
+ }
+
+ return klass;
+}
diff --git a/src/levelset.h b/src/map.h
similarity index 50%
copy from src/levelset.h
copy to src/map.h
index 2e8fede..2184b86 100644
--- a/src/levelset.h
+++ b/src/map.h
@@ -1,5 +1,5 @@
/* Gerris - The GNU Flow Solver
- * Copyright (C) 2001-2006 National Institute of Water and Atmospheric Research
+ * Copyright (C) 2001 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,38 +17,50 @@
* 02111-1307, USA.
*/
-#ifndef __LEVELSET_H__
-#define __LEVELSET_H__
+#ifndef __MAP_H__
+#define __MAP_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include "variable.h"
+#include "ftt.h"
-/* GfsVariableDistance: header */
+/* GfsMap: Header */
-typedef struct _GfsVariableDistance GfsVariableDistance;
+typedef struct _GfsMap GfsMap;
-struct _GfsVariableDistance {
+struct _GfsMap {
/*< private >*/
- GfsVariable parent;
- gboolean first_done;
+ GtsSListContainee parent;
/*< public >*/
- GfsVariable * v;
};
-#define GFS_VARIABLE_DISTANCE(obj) GTS_OBJECT_CAST (obj,\
- GfsVariableDistance,\
- gfs_variable_distance_class ())
-#define GFS_IS_VARIABLE_DISTANCE(obj) (gts_object_is_from_class (obj,\
- gfs_variable_distance_class ()))
+typedef struct _GfsMapClass GfsMapClass;
-GfsVariableClass * gfs_variable_distance_class (void);
+struct _GfsMapClass {
+ /*< private >*/
+ GtsSListContaineeClass parent_class;
+
+ /*< public >*/
+ void (* transform) (GfsMap * map, const FttVector * src, FttVector * dest);
+ void (* inverse) (GfsMap * map, const FttVector * src, FttVector * dest);
+};
+
+#define GFS_MAP(obj) GTS_OBJECT_CAST (obj,\
+ GfsMap,\
+ gfs_map_class ())
+#define GFS_MAP_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass,\
+ GfsMapClass,\
+ gfs_map_class())
+#define GFS_IS_MAP(obj) (gts_object_is_from_class (obj,\
+ gfs_map_class ()))
+
+GfsMapClass * gfs_map_class (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* __LEVELSET_H__ */
+#endif /* __MAP_H__ */
diff --git a/src/output.c b/src/output.c
index b2c7df0..983fba9 100644
--- a/src/output.c
+++ b/src/output.c
@@ -1122,8 +1122,9 @@ static gboolean gfs_output_location_event (GfsEvent * event,
fputc ('\n', fp);
}
for (i = 0; i < location->p->len; i++) {
- FttVector p = g_array_index (location->p, FttVector, i);
- FttCell * cell = gfs_domain_locate (domain, p, -1);
+ FttVector p = g_array_index (location->p, FttVector, i), pm = p;
+ gfs_simulation_map (sim, &pm);
+ FttCell * cell = gfs_domain_locate (domain, pm, -1);
if (cell != NULL) {
GSList * i = domain->variables;
@@ -1131,7 +1132,7 @@ static gboolean gfs_output_location_event (GfsEvent * event,
fprintf (fp, "%g %g %g %g", sim->time.t, p.x, p.y, p.z);
while (i) {
if (GFS_VARIABLE1 (i->data)->name)
- fprintf (fp, " %g", gfs_interpolate (cell, p, i->data));
+ fprintf (fp, " %g", gfs_interpolate (cell, pm, i->data));
i = i->next;
}
fputc ('\n', fp);
@@ -1195,6 +1196,7 @@ static void write_text (FttCell * cell, GfsOutputSimulation * output)
FttVector p;
gfs_cell_cm (cell, &p);
+ gfs_simulation_map_inverse (gfs_object_simulation (output), &p);
fprintf (fp, "%g %g %g", p.x, p.y, p.z);
while (i) {
if (GFS_VARIABLE1 (i->data)->name)
@@ -1962,6 +1964,7 @@ static void maxima (FttCell * cell, GfsOutputScalarMaxima * m)
FttVector p;
gfs_cell_cm (cell, &p);
+ gfs_simulation_map_inverse (gfs_object_simulation (m), &p);
m->m[0][i] = p.x; m->m[1][i] = p.y; m->m[2][i] = p.z;
m->m[3][i] = v;
return;
@@ -2772,9 +2775,11 @@ static gboolean gfs_output_streamline_event (GfsEvent * event,
{
if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_streamline_class ())->parent_class)->event)
(event,sim)) {
+ FttVector p = GFS_OUTPUT_STREAMLINE (event)->p;
+ gfs_simulation_map (sim, &p);
GList * stream = gfs_streamline_new (GFS_DOMAIN (sim),
gfs_domain_velocity (GFS_DOMAIN (sim)),
- GFS_OUTPUT_STREAMLINE (event)->p,
+ p,
GFS_OUTPUT_SCALAR (event)->v,
0., 0.,
TRUE,
@@ -2877,8 +2882,10 @@ static gboolean gfs_output_particle_event (GfsEvent * event,
if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_particle_class ())->parent_class)->event)
(event,sim)) {
FILE * fp = GFS_OUTPUT (event)->file->fp;
-
- fprintf (fp, "%g %g %g %g\n", sim->time.t, l->p->x, l->p->y, l->p->z);
+ FttVector pm;
+ pm.x = l->p->x; pm.y = l->p->y; pm.z = l->p->z;
+ gfs_simulation_map_inverse (sim, &pm);
+ fprintf (fp, "%g %g %g %g\n", sim->time.t, pm.x, pm.y, pm.z);
ret = TRUE;
}
gfs_domain_advect_point (GFS_DOMAIN (sim), l->p, sim->advection_params.dt);
diff --git a/src/simulation.c b/src/simulation.c
index 75aa8ed..63c6feb 100644
--- a/src/simulation.c
+++ b/src/simulation.c
@@ -30,6 +30,7 @@
#include "source.h"
#include "vof.h"
#include "tension.h"
+#include "map.h"
#include "version.h"
#ifdef HAVE_MPI
# include "mpi_boundary.h"
@@ -41,13 +42,15 @@ static void simulation_destroy (GtsObject * object)
{
GfsSimulation * sim = GFS_SIMULATION (object);
- gts_container_foreach (GTS_CONTAINER (sim->refines),
- (GtsFunc) gts_object_destroy, NULL);
+ gts_container_foreach (GTS_CONTAINER (sim->refines), (GtsFunc) gts_object_destroy, NULL);
gts_object_destroy (GTS_OBJECT (sim->refines));
- gts_container_foreach (GTS_CONTAINER (sim->events),
- (GtsFunc) gts_object_destroy, NULL);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
gts_object_destroy (GTS_OBJECT (sim->events));
+
+ gts_container_foreach (GTS_CONTAINER (sim->maps), (GtsFunc) gts_object_destroy, NULL);
+ gts_object_destroy (GTS_OBJECT (sim->maps));
+
gts_object_destroy (GTS_OBJECT (sim->adapts));
gts_object_destroy (GTS_OBJECT (sim->solids));
@@ -138,6 +141,15 @@ static void simulation_write (GtsObject * object, FILE * fp)
gfs_multilevel_params_write (&sim->projection_params, fp);
fputc ('\n', fp);
+ i = sim->maps->items;
+ while (i) {
+ GtsObject * object = i->data;
+ g_assert (object->klass->write);
+ (* object->klass->write) (object, fp);
+ fputc ('\n', fp);
+ i = i->next;
+ }
+
fputc ('}', fp);
}
@@ -194,16 +206,16 @@ static void simulation_read (GtsObject ** object, GtsFile * fp)
if (!g_module_supported ())
g_warning ("modules are not supported on this system");
else {
- gchar * name, * path;
GModule * module;
- name = g_strconcat (fp->token->str, FTT_DIMENSION == 2 ? "2D" : "3D", NULL);
- path = g_module_build_path (GFS_MODULES_DIR, name);
- g_free (name);
- module = g_module_open (path, 0);
- g_free (path);
- if (module == NULL)
- module = g_module_open (fp->token->str, 0);
+ module = g_module_open (fp->token->str, 0);
+ if (module == NULL) {
+ gchar * name = g_strconcat (fp->token->str, FTT_DIMENSION == 2 ? "2D" : "3D", NULL);
+ gchar * path = g_module_build_path (GFS_MODULES_DIR, name);
+ g_free (name);
+ module = g_module_open (path, 0);
+ g_free (path);
+ }
if (module == NULL) {
gts_file_error (fp, "cannot load module: %s", g_module_error ());
return;
@@ -292,6 +304,8 @@ static void simulation_read (GtsObject ** object, GtsFile * fp)
}
else if (GFS_IS_EVENT (object))
gts_container_add (GTS_CONTAINER (sim->events), GTS_CONTAINEE (object));
+ else if (GFS_IS_MAP (object))
+ gts_container_add (GTS_CONTAINER (sim->maps), GTS_CONTAINEE (object));
else if (GFS_IS_SURFACE_GENERIC_BC (object))
;
else
@@ -459,7 +473,7 @@ static void gfs_simulation_class_init (GfsSimulationClass * klass)
/* Derived variables */
-static gdouble cell_x (FttCell * cell, FttCellFace * face)
+static gdouble cell_x (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
FttVector p;
@@ -469,10 +483,11 @@ static gdouble cell_x (FttCell * cell, FttCellFace * face)
gfs_face_ca (face, &p);
else
gfs_cell_cm (cell, &p);
+ gfs_simulation_map_inverse (sim, &p);
return p.x;
}
-static gdouble cell_y (FttCell * cell, FttCellFace * face)
+static gdouble cell_y (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
FttVector p;
@@ -482,10 +497,11 @@ static gdouble cell_y (FttCell * cell, FttCellFace * face)
gfs_face_ca (face, &p);
else
gfs_cell_cm (cell, &p);
+ gfs_simulation_map_inverse (sim, &p);
return p.y;
}
-static gdouble cell_z (FttCell * cell, FttCellFace * face)
+static gdouble cell_z (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
FttVector p;
@@ -495,31 +511,47 @@ static gdouble cell_z (FttCell * cell, FttCellFace * face)
gfs_face_ca (face, &p);
else
gfs_cell_cm (cell, &p);
+ gfs_simulation_map_inverse (sim, &p);
return p.z;
}
-static gdouble cell_ax (FttCell * cell)
+static gdouble cell_ax (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
g_return_val_if_fail (cell != NULL, 0.);
-
- return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->ca.x : 0.;
+ if (!GFS_IS_MIXED (cell))
+ return 0.;
+ else {
+ FttVector p = GFS_STATE (cell)->solid->ca;
+ gfs_simulation_map_inverse (sim, &p);
+ return p.x;
+ }
}
-static gdouble cell_ay (FttCell * cell)
+static gdouble cell_ay (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
g_return_val_if_fail (cell != NULL, 0.);
-
- return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->ca.y : 0.;
+ if (!GFS_IS_MIXED (cell))
+ return 0.;
+ else {
+ FttVector p = GFS_STATE (cell)->solid->ca;
+ gfs_simulation_map_inverse (sim, &p);
+ return p.y;
+ }
}
-static gdouble cell_az (FttCell * cell)
+static gdouble cell_az (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
g_return_val_if_fail (cell != NULL, 0.);
-
- return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->ca.z : 0.;
+ if (!GFS_IS_MIXED (cell))
+ return 0.;
+ else {
+ FttVector p = GFS_STATE (cell)->solid->ca;
+ gfs_simulation_map_inverse (sim, &p);
+ return p.z;
+ }
}
-static gdouble cell_cx (FttCell * cell, FttCellFace * face)
+static gdouble cell_cx (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
FttVector p;
@@ -529,10 +561,11 @@ static gdouble cell_cx (FttCell * cell, FttCellFace * face)
ftt_face_pos (face, &p);
else
ftt_cell_pos (cell, &p);
+ gfs_simulation_map_inverse (sim, &p);
return p.x;
}
-static gdouble cell_cy (FttCell * cell, FttCellFace * face)
+static gdouble cell_cy (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
FttVector p;
@@ -542,10 +575,11 @@ static gdouble cell_cy (FttCell * cell, FttCellFace * face)
ftt_face_pos (face, &p);
else
ftt_cell_pos (cell, &p);
+ gfs_simulation_map_inverse (sim, &p);
return p.y;
}
-static gdouble cell_cz (FttCell * cell, FttCellFace * face)
+static gdouble cell_cz (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
{
FttVector p;
@@ -555,6 +589,7 @@ static gdouble cell_cz (FttCell * cell, FttCellFace * face)
ftt_face_pos (face, &p);
else
ftt_cell_pos (cell, &p);
+ gfs_simulation_map_inverse (sim, &p);
return p.z;
}
@@ -750,6 +785,9 @@ static void simulation_init (GfsSimulation * object)
object->refines = GTS_SLIST_CONTAINER (gts_container_new
(GTS_CONTAINER_CLASS
(gts_slist_container_class ())));
+ object->maps = GTS_SLIST_CONTAINER (gts_container_new
+ (GTS_CONTAINER_CLASS
+ (gts_slist_container_class ())));
object->adapts = GTS_SLIST_CONTAINER (gts_container_new
(GTS_CONTAINER_CLASS
(gts_slist_container_class ())));
@@ -1334,6 +1372,48 @@ void gfs_simulation_run (GfsSimulation * sim)
g_log_remove_handler ("Gfs", id);
}
+/**
+ * gfs_simulation_map:
+ * @sim: a #GfsSimulation.
+ * @p: a #FttVector.
+ *
+ * Applies the mapping transformations associated with @sim to
+ * coordinates @p.
+ */
+void gfs_simulation_map (GfsSimulation * sim, FttVector * p)
+{
+ g_return_if_fail (sim != NULL);
+ g_return_if_fail (p != NULL);
+
+ GSList * i = sim->maps->items;
+ while (i) {
+ GtsObject * o = i->data;
+ (* GFS_MAP_CLASS (o->klass)->transform) (i->data, p, p);
+ i = i->next;
+ }
+}
+
+/**
+ * gfs_simulation_map_inverse:
+ * @sim: a #GfsSimulation.
+ * @p: a #FttVector.
+ *
+ * Applies the inverse mapping transformations associated with @sim to
+ * coordinates @p.
+ */
+void gfs_simulation_map_inverse (GfsSimulation * sim, FttVector * p)
+{
+ g_return_if_fail (sim != NULL);
+ g_return_if_fail (p != NULL);
+
+ GSList * i = sim->maps->items;
+ while (i) {
+ GtsObject * o = i->data;
+ (* GFS_MAP_CLASS (o->klass)->inverse) (i->data, p, p);
+ i = i->next;
+ }
+}
+
/* GfsAdvection: Object */
static void advection_run (GfsSimulation * sim)
diff --git a/src/simulation.h b/src/simulation.h
index 2ae8b72..3bd8c00 100644
--- a/src/simulation.h
+++ b/src/simulation.h
@@ -68,7 +68,7 @@ struct _GfsSimulation {
GtsSListContainer * adapts;
GfsAdaptStats adapts_stats;
- GtsSListContainer * events;
+ GtsSListContainer * events, * maps;
GSList * modules, * globals;
GtsSListContainer * solids;
@@ -105,6 +105,10 @@ GfsSimulation * gfs_simulation_read (GtsFile * fp);
GSList * gfs_simulation_get_solids (GfsSimulation * sim);
void gfs_simulation_refine (GfsSimulation * sim);
void gfs_simulation_set_timestep (GfsSimulation * sim);
+void gfs_simulation_map (GfsSimulation * sim,
+ FttVector * p);
+void gfs_simulation_map_inverse (GfsSimulation * sim,
+ FttVector * p);
void gfs_time_init (GfsTime * t);
void gfs_time_write (GfsTime * t,
FILE * fp);
diff --git a/src/unstructured.c b/src/unstructured.c
index b74f1b1..ab32317 100644
--- a/src/unstructured.c
+++ b/src/unstructured.c
@@ -49,9 +49,10 @@ static FttDirection d[NV][FTT_DIMENSION] = {
#endif /* 3D */
};
-static void vertex_pos (Vertex * v, FttVector * p)
+static void vertex_pos (Vertex * v, FttVector * p, GfsSimulation * sim)
{
ftt_corner_pos (v->cell, d[v->i], p);
+ gfs_simulation_map_inverse (sim, p);
}
static float vertex_value (Vertex * vertex, GfsVariable * v, gint max_depth)
@@ -153,13 +154,6 @@ static void print_pos (Vertex * v)
}
#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)
{
@@ -226,7 +220,13 @@ void gfs_domain_write_vtk (GfsDomain * domain, gint max_depth, GSList * variable
/* vertices */
guint nv = g_slist_length (vertices);
fprintf (fp, "POINTS %d float\n", nv);
- g_slist_foreach (vertices, (GFunc) write_pos, fp);
+ GSList * j = vertices;
+ while (j) {
+ FttVector p;
+ vertex_pos (j->data, &p, GFS_SIMULATION (domain));
+ fprintf (fp, "%g %g %g\n", p.x, p.y, p.z);
+ j = j->next;
+ }
fputc ('\n', fp);
/* elements */
@@ -344,7 +344,7 @@ void gfs_domain_write_tecplot (GfsDomain * domain, gint max_depth, GSList * vari
while (j) {
Vertex * vertex = j->data;
FttVector p;
- vertex_pos (vertex, &p);
+ vertex_pos (vertex, &p, GFS_SIMULATION (domain));
#if FTT_2D
fprintf (fp, "%g %g", p.x, p.y);
#else
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list