[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
popinet at users.sourceforge.net
Fri May 15 02:51:21 UTC 2009
The following commit has been merged in the upstream branch:
commit be058da3b38f54304789e86db18050c40f54275b
Author: Stephane Popinet <popinet at users.sourceforge.net>
Date: Wed Nov 3 13:02:44 2004 +1100
GfsVariable are now events (gerris--mainline--0.7--patch-24)
gerris--mainline--0.7--patch-24
Keywords:
These events are activated at the start of the timestep loop in run()
methods.
This means that the syntax for variables in parameter files has been
changed.
This involved a substantial cleanup and restructuring of the events
and their links with simulations.
The first application of this new mechanism is the new
GfsVariableResidual.
darcs-hash:20041103020244-aabb8-d0f4adaed32c3b3bff083c05419aefbff95a4b0e.gz
diff --git a/src/adaptive.c b/src/adaptive.c
index 0ce3c14..2029459 100644
--- a/src/adaptive.c
+++ b/src/adaptive.c
@@ -843,7 +843,8 @@ void gfs_simulation_adapt (GfsSimulation * simulation,
gfs_domain_timer_start (domain, "adapt");
- gfs_simulation_event (simulation, simulation->adapts->items);
+ gts_container_foreach (GTS_CONTAINER (simulation->adapts), (GtsFunc) gfs_event_do, simulation);
+
i = simulation->adapts->items;
while (i) {
GfsAdapt * a = i->data;
diff --git a/src/event.c b/src/event.c
index c3aea2d..259cc66 100644
--- a/src/event.c
+++ b/src/event.c
@@ -22,6 +22,7 @@
#include <unistd.h>
#include "event.h"
#include "solid.h"
+#include "output.h"
static gboolean gfs_event_event (GfsEvent * event, GfsSimulation * sim)
{
@@ -98,7 +99,7 @@ static void gfs_event_write (GtsObject * object, FILE * fp)
fputc ('}', fp);
}
-static void gfs_event_init (GfsEvent * object)
+static void event_init (GfsEvent * object)
{
object->t = 0.;
object->start = 0.;
@@ -265,7 +266,7 @@ GfsEventClass * gfs_event_class (void)
sizeof (GfsEvent),
sizeof (GfsEventClass),
(GtsObjectClassInitFunc) gfs_event_class_init,
- (GtsObjectInitFunc) gfs_event_init,
+ (GtsObjectInitFunc) event_init,
(GtsArgSetFunc) NULL,
(GtsArgGetFunc) NULL
};
@@ -303,7 +304,7 @@ GfsEvent * gfs_event_new (GfsEventClass * klass)
* If any of the arguments is negative, the corresponding value in @e
* is unchanged.
*/
-void gfs_event_set (GfsEvent * e,
+void gfs_event_set (GfsEvent * e,
gdouble start, gdouble end, gdouble step,
gint istart, gint iend, gint istep)
{
@@ -329,6 +330,78 @@ void gfs_event_set (GfsEvent * e,
e->i = e->istart = G_MAXINT/2;
}
+/**
+ * gfs_event_init:
+ * @event: a #GfsEvent.
+ * @sim: a #GfsSimulation.
+ *
+ * Initalizes @event associated with @sim. In particular, if @event is
+ * an "init" event it is activated by this function.
+ */
+void gfs_event_init (GfsEvent * event,
+ GfsSimulation * sim)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (sim != NULL);
+
+ if (GFS_DOMAIN (sim)->pid > 0 &&
+ GFS_IS_OUTPUT (event) &&
+ (!strcmp (GFS_OUTPUT (event)->format, "stderr") ||
+ !strcmp (GFS_OUTPUT (event)->format, "stdout")))
+ gfs_output_mute (GFS_OUTPUT (event));
+
+ if (event->start < 0.) { /* "init" event */
+ g_assert (GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event);
+ (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event) (event, sim);
+ }
+ else if (event->end_event)
+ event->t = event->start = G_MAXDOUBLE/2.;
+ else {
+ if (event->istep < G_MAXINT)
+ while (event->i < sim->time.i) {
+ event->n++;
+ event->i += event->istep;
+ }
+ else
+ while (event->t < sim->time.t) {
+ event->n++;
+ event->t = event->start + event->n*event->step;
+ }
+ }
+}
+
+/**
+ * gfs_event_do:
+ * @event: a #GfsEvent:
+ * @sim: a #GfsSimulation.
+ *
+ * Realises the event if active.
+ */
+void gfs_event_do (GfsEvent * event, GfsSimulation * sim)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (sim != NULL);
+
+ g_assert (GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event);
+ (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event) (event, sim);
+}
+
+/**
+ * gfs_event_half_do:
+ * @event: a #GfsEvent:
+ * @sim: a #GfsSimulation.
+ *
+ * Realises the half-event if active.
+ */
+void gfs_event_half_do (GfsEvent * event, GfsSimulation * sim)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (sim != NULL);
+
+ if (event->realised && GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event_half)
+ (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event_half) (event, sim);
+}
+
/* GfsGenericInit: Object */
static void gfs_generic_init_init (GfsEvent * event)
diff --git a/src/event.h b/src/event.h
index 690a208..49a19f0 100644
--- a/src/event.h
+++ b/src/event.h
@@ -24,7 +24,7 @@
extern "C" {
#endif /* __cplusplus */
-#include "simulation.h"
+#include <gts.h>
typedef struct _GfsEvent GfsEvent;
typedef struct _GfsEventClass GfsEventClass;
@@ -39,6 +39,8 @@ struct _GfsEvent {
gboolean end_event, realised;
};
+typedef struct _GfsSimulation GfsSimulation;
+
struct _GfsEventClass {
GtsSListContaineeClass parent_class;
@@ -46,6 +48,8 @@ struct _GfsEventClass {
void (* event_half) (GfsEvent * event, GfsSimulation * sim);
};
+#include "simulation.h"
+
#define GFS_EVENT(obj) GTS_OBJECT_CAST (obj,\
GfsEvent,\
gfs_event_class ())
@@ -63,6 +67,12 @@ void gfs_event_set (GfsEvent * e,
gint istart,
gint iend,
gint istep);
+void gfs_event_init (GfsEvent * event,
+ GfsSimulation * sim);
+void gfs_event_do (GfsEvent * event,
+ GfsSimulation * sim);
+void gfs_event_half_do (GfsEvent * event,
+ GfsSimulation * sim);
/* GfsGenericInit: Header */
diff --git a/src/init.c b/src/init.c
index b024249..aae1db5 100644
--- a/src/init.c
+++ b/src/init.c
@@ -217,6 +217,7 @@ void gfs_init (int * argc, char *** argv)
gfs_variable_class ();
gfs_variable_tracer_class ();
+ gfs_variable_residual_class ();
gfs_surface_bc_class ();
diff --git a/src/ocean.c b/src/ocean.c
index 545c410..65392c7 100644
--- a/src/ocean.c
+++ b/src/ocean.c
@@ -345,12 +345,13 @@ static void ocean_run (GfsSimulation * sim)
gfs_simulation_refine (sim);
- gfs_simulation_event_init (sim, sim->events->items);
- gfs_simulation_event_init (sim, sim->adapts->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_init, sim);
+ gts_container_foreach (GTS_CONTAINER (sim->adapts), (GtsFunc) gfs_event_init, sim);
gfs_set_merged (domain);
v = domain->variables;
while (v) {
+ gfs_event_init (GFS_EVENT (v), sim);
gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, v);
v = v->next;
}
@@ -364,10 +365,15 @@ static void ocean_run (GfsSimulation * sim)
gdouble tstart;
gboolean implicit;
+ v = domain->variables;
+ while (v) {
+ gfs_event_do (GFS_EVENT (v), sim);
+ v = v->next;
+ }
gfs_domain_cell_traverse (domain,
FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
(FttCellTraverseFunc) gfs_cell_coarse_init, domain);
- gfs_simulation_event (sim, sim->events->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
tstart = g_timer_elapsed (domain->timer, NULL);
@@ -411,7 +417,7 @@ static void ocean_run (GfsSimulation * sim)
v = v->next;
}
- gfs_simulation_event_half (sim, sim->events->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
gfs_centered_velocity_advection_diffusion (domain, 2,
&sim->advection_params,
@@ -450,7 +456,7 @@ static void ocean_run (GfsSimulation * sim)
gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
gts_range_update (&domain->size);
}
- gfs_simulation_event (sim, sim->events->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
gts_container_foreach (GTS_CONTAINER (sim->events),
(GtsFunc) gts_object_destroy, NULL);
}
diff --git a/src/simulation.c b/src/simulation.c
index 19c5c39..a674614 100644
--- a/src/simulation.c
+++ b/src/simulation.c
@@ -446,7 +446,6 @@ static void simulation_read (GtsObject ** object, GtsFile * fp)
if (klass == NULL ||
(!gts_object_class_is_from_class (klass, gfs_refine_class ()) &&
!gts_object_class_is_from_class (klass, gfs_event_class ()) &&
- !gts_object_class_is_from_class (klass, gfs_variable_class ()) &&
!gts_object_class_is_from_class (klass, gfs_surface_generic_bc_class ()))) {
gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
return;
@@ -468,9 +467,6 @@ static void simulation_read (GtsObject ** object, GtsFile * fp)
else if (GFS_IS_ADAPT (object))
gts_container_add (GTS_CONTAINER (sim->adapts),
GTS_CONTAINEE (object));
- else if (GFS_IS_EVENT (object))
- gts_container_add (GTS_CONTAINER (sim->events),
- GTS_CONTAINEE (object));
else if (GFS_IS_VARIABLE (object)) {
GfsVariable * v = GFS_VARIABLE1 (object);
GfsVariable * old = gfs_variable_from_name (GFS_DOMAIN (sim)->variables, v->name);
@@ -484,6 +480,9 @@ static void simulation_read (GtsObject ** object, GtsFile * fp)
}
sim->variables = g_slist_append (sim->variables, v);
}
+ else if (GFS_IS_EVENT (object))
+ gts_container_add (GTS_CONTAINER (sim->events),
+ GTS_CONTAINEE (object));
else if (GFS_IS_SURFACE_GENERIC_BC (object))
;
else
@@ -521,12 +520,13 @@ static void simulation_run (GfsSimulation * sim)
gfs_simulation_refine (sim);
- gfs_simulation_event_init (sim, sim->events->items);
- gfs_simulation_event_init (sim, sim->adapts->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_init, sim);
+ gts_container_foreach (GTS_CONTAINER (sim->adapts), (GtsFunc) gfs_event_init, sim);
gfs_set_merged (domain);
v = domain->variables;
while (v) {
+ gfs_event_init (GFS_EVENT (v), sim);
gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, v);
v = v->next;
}
@@ -544,10 +544,15 @@ static void simulation_run (GfsSimulation * sim)
sim->time.i < sim->time.iend) {
gdouble tstart;
+ v = domain->variables;
+ while (v) {
+ gfs_event_do (GFS_EVENT (v), sim);
+ v = v->next;
+ }
gfs_domain_cell_traverse (domain,
FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
(FttCellTraverseFunc) gfs_cell_coarse_init, domain);
- gfs_simulation_event (sim, sim->events->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
tstart = g_timer_elapsed (domain->timer, NULL);
@@ -581,7 +586,7 @@ static void simulation_run (GfsSimulation * sim)
v = v->next;
}
- gfs_simulation_event_half (sim, sim->events->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
sim->advection_params.c = ch;
gfs_centered_velocity_advection_diffusion (domain,
@@ -601,7 +606,7 @@ static void simulation_run (GfsSimulation * sim)
gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
gts_range_update (&domain->size);
}
- gfs_simulation_event (sim, sim->events->items);
+ gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
gts_container_foreach (GTS_CONTAINER (sim->events),
(GtsFunc) gts_object_destroy, NULL);
}
@@ -869,99 +874,6 @@ void gfs_simulation_set_timestep (GfsSimulation * sim)
}
/**
- * gfs_simulation_event:
- * @sim: a #GfsSimulation.
- * @events: a list of #GfsEvent.
- *
- * Checks if any event associated with @sim must be activated and
- * activates it if necessary.
- */
-void gfs_simulation_event (GfsSimulation * sim,
- GSList * events)
-{
- g_return_if_fail (sim != NULL);
-
- while (events) {
- GfsEvent * event = events->data;
- GSList * next = events->next;
-
- g_assert (GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event);
- (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event) (event, sim);
-
- events = next;
- }
-}
-
-/**
- * gfs_simulation_event_half:
- * @sim: a #GfsSimulation.
- * @events: a list of #GfsEvent.
- *
- * Checks if any half-timestep event associated with @sim must be
- * activated and activates it if necessary.
- */
-void gfs_simulation_event_half (GfsSimulation * sim,
- GSList * events)
-{
- g_return_if_fail (sim != NULL);
-
- while (events) {
- GfsEvent * event = events->data;
- GSList * next = events->next;
-
- if (event->realised && GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event_half)
- (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event_half) (event, sim);
-
- events = next;
- }
-}
-
-/**
- * gfs_simulation_event_init:
- * @sim: a #GfsSimulation.
- * @events: a list of #GfsEvent.
- *
- * Initalizes the events associated with @sim. In particular, all the
- * "init" events are activated by this function.
- */
-void gfs_simulation_event_init (GfsSimulation * sim,
- GSList * events)
-{
- g_return_if_fail (sim != NULL);
-
- while (events) {
- GfsEvent * event = events->data;
- GSList * next = events->next;
-
- if (GFS_DOMAIN (sim)->pid > 0 &&
- GFS_IS_OUTPUT (event) &&
- (!strcmp (GFS_OUTPUT (event)->format, "stderr") ||
- !strcmp (GFS_OUTPUT (event)->format, "stdout")))
- gfs_output_mute (GFS_OUTPUT (event));
-
- if (event->start < 0.) { /* "init" event */
- g_assert (GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event);
- (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event) (event, sim);
- }
- else if (event->end_event)
- event->t = event->start = G_MAXDOUBLE/2.;
- else {
- if (event->istep < G_MAXINT)
- while (event->i < sim->time.i) {
- event->n++;
- event->i += event->istep;
- }
- else
- while (event->t < sim->time.t) {
- event->n++;
- event->t = event->start + event->n*event->step;
- }
- }
- events = next;
- }
-}
-
-/**
* gfs_time_write:
* @t: the time structure.
* @fp: a file pointer.
diff --git a/src/simulation.h b/src/simulation.h
index b29344d..d048756 100644
--- a/src/simulation.h
+++ b/src/simulation.h
@@ -27,7 +27,9 @@ extern "C" {
#include "domain.h"
#include "timestep.h"
-typedef struct _GfsSimulation GfsSimulation;
+#ifndef __EVENT_H__
+ typedef struct _GfsSimulation GfsSimulation;
+#endif
typedef struct _GfsSimulationClass GfsSimulationClass;
typedef struct _GfsTime GfsTime;
typedef struct _GfsPhysicalParams GfsPhysicalParams;
@@ -103,12 +105,6 @@ void gfs_simulation_write (GfsSimulation * sim,
GfsSimulation * gfs_simulation_read (GtsFile * fp);
void gfs_simulation_refine (GfsSimulation * sim);
void gfs_simulation_set_timestep (GfsSimulation * sim);
-void gfs_simulation_event (GfsSimulation * sim,
- GSList * events);
-void gfs_simulation_event_half (GfsSimulation * sim,
- GSList * events);
-void gfs_simulation_event_init (GfsSimulation * sim,
- GSList * events);
void gfs_time_init (GfsTime * t);
void gfs_time_write (GfsTime * t,
FILE * fp);
diff --git a/src/variable.c b/src/variable.c
index d25223f..8f85f79 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -23,12 +23,18 @@
static void gfs_variable_read (GtsObject ** o, GtsFile * fp)
{
- if (fp->type != GTS_STRING) {
- gts_file_error (fp, "expecting a string (GfsVariableClass)");
+ GfsEvent * e;
+
+ if (GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->read)
+ (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->read) (o, fp);
+ if (fp->type == GTS_ERROR)
return;
- }
- gts_file_next_token (fp);
+ e = GFS_EVENT (*o);
+ if (e->end < G_MAXDOUBLE || e->iend < G_MAXINT || e->end_event) {
+ gts_file_error (fp, "a GfsVariable event cannot end");
+ return;
+ }
if (fp->type != GTS_STRING) {
gts_file_error (fp, "expecting a string (name)");
return;
@@ -39,7 +45,9 @@ static void gfs_variable_read (GtsObject ** o, GtsFile * fp)
static void gfs_variable_write (GtsObject * o, FILE * fp)
{
- fprintf (fp, "%s %s", o->klass->info.name, GFS_VARIABLE1 (o)->name);
+ if (GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->write)
+ (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->write) (o, fp);
+ fprintf (fp, " %s", GFS_VARIABLE1 (o)->name);
}
static void gfs_variable_destroy (GtsObject * object)
@@ -52,8 +60,7 @@ static void gfs_variable_destroy (GtsObject * object)
if (v->surface_bc)
gts_object_destroy (GTS_OBJECT (v->surface_bc));
- (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->destroy)
- (object);
+ (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->destroy) (object);
}
static void gfs_variable_clone (GtsObject * clone, GtsObject * object)
@@ -78,6 +85,7 @@ static void gfs_variable_class_init (GfsVariableClass * klass)
static void gfs_variable_init (GfsVariable * v)
{
+ GFS_EVENT (v)->istep = 1;
v->fine_coarse = (GfsVariableFineCoarseFunc) gfs_get_from_below_intensive;
}
@@ -95,7 +103,7 @@ GfsVariableClass * gfs_variable_class (void)
(GtsArgSetFunc) NULL,
(GtsArgGetFunc) NULL
};
- klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()), &gfs_variable_info);
+ klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()), &gfs_variable_info);
}
return klass;
@@ -263,3 +271,48 @@ GfsVariableClass * gfs_variable_tracer_class (void)
return klass;
}
+
+/* GfsVariableResidual: Object */
+
+static void scale_residual (FttCell * cell, GfsVariable * res)
+{
+ gdouble size = ftt_cell_size (cell);
+ gdouble dt = GFS_SIMULATION (gfs_variable_parent (res))->advection_params.dt;
+ GFS_VARIABLE (cell, res->i) = dt*GFS_STATE (cell)->res/(size*size);
+}
+
+static gboolean variable_residual_event (GfsEvent * event, GfsSimulation * sim)
+{
+ if ((* GFS_EVENT_CLASS (gfs_variable_class ())->event) (event, sim)) {
+ gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+ (FttCellTraverseFunc) scale_residual, event);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void variable_residual_class_init (GfsEventClass * klass)
+{
+ klass->event = variable_residual_event;
+}
+
+GfsVariableClass * gfs_variable_residual_class (void)
+{
+ static GfsVariableClass * klass = NULL;
+
+ if (klass == NULL) {
+ GtsObjectClassInfo gfs_variable_residual_info = {
+ "GfsVariableResidual",
+ sizeof (GfsVariable),
+ sizeof (GfsVariableClass),
+ (GtsObjectClassInitFunc) variable_residual_class_init,
+ (GtsObjectInitFunc) NULL,
+ (GtsArgSetFunc) NULL,
+ (GtsArgGetFunc) NULL
+ };
+ klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()),
+ &gfs_variable_residual_info);
+ }
+
+ return klass;
+}
diff --git a/src/variable.h b/src/variable.h
index 7350291..2432ebf 100644
--- a/src/variable.h
+++ b/src/variable.h
@@ -26,8 +26,8 @@ extern "C" {
typedef struct _GfsSurfaceGenericBc GfsSurfaceGenericBc;
-#include "advection.h"
#include "timestep.h"
+#include "event.h"
/* GfsVariable: Header */
@@ -36,7 +36,7 @@ typedef void (* GfsVariableFineCoarseFunc) (FttCell * cell, GfsVariable * v);
struct _GfsVariable {
/*< private >*/
- GtsObject parent;
+ GfsEvent parent;
/*< public >*/
guint i;
@@ -54,7 +54,7 @@ typedef struct _GfsVariableClass GfsVariableClass;
struct _GfsVariableClass {
/*< private >*/
- GtsObjectClass parent_class;
+ GfsEventClass parent_class;
/*< public >*/
};
@@ -106,6 +106,13 @@ struct _GfsVariableTracer {
GfsVariableClass * gfs_variable_tracer_class (void);
+/* GfsVariableResidual: header */
+
+#define GFS_IS_VARIABLE_RESIDUAL(obj) (gts_object_is_from_class (obj,\
+ gfs_variable_residual_class ()))
+
+GfsVariableClass * gfs_variable_residual_class (void);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list