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

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


The following commit has been merged in the upstream branch:
commit d7f1ea538356ee121f4b9719ae325adc3f462229
Author: Stephane Popinet <popinet at users.sf.net>
Date:   Sun Jan 13 19:09:06 2008 +1100

    Deferred GfsFunction compilation
    
    Optionally, GfsFunctions are compiled only when they are used for the first
    time. This greatly improves the speed of GfsView when reading input piped from
    Gerris (when the simulation contains one or several GfsFunctions).
    
    darcs-hash:20080113080906-d4795-2fc1e9c13384bbd7614474a6866280da2137f3da.gz

diff --git a/src/simulation.c b/src/simulation.c
index 6c3f5fc..56d3728 100644
--- a/src/simulation.c
+++ b/src/simulation.c
@@ -66,7 +66,10 @@ static void simulation_write (GtsObject * object, FILE * fp)
   (* GTS_OBJECT_CLASS (gfs_simulation_class ())->parent_class->write)
     (object, fp);
 
-  fputs (" {\n", fp);
+  fputs (" {\n"
+	 "  # when editing this file it is recommended to comment out the following line\n"
+	 "  GfsDeferredCompilation\n",
+	 fp);
 
   i = sim->modules;
   while (i) {
@@ -181,8 +184,14 @@ static void simulation_read (GtsObject ** object, GtsFile * fp)
       return;
     }
 
+    /* ------ Deferred compilation ------*/
+    if (!strcmp (fp->token->str, "GfsDeferredCompilation")) {
+      sim->deferred_compilation = TRUE;
+      gts_file_next_token (fp);
+    }
+
     /* ------------ GModule ------------ */
-    if (!strcmp (fp->token->str, "GModule")) {
+    else if (!strcmp (fp->token->str, "GModule")) {
       gts_file_next_token (fp);
       if (fp->type != GTS_STRING) {
 	gts_file_error (fp, "expecting a string (filename)");
@@ -721,6 +730,8 @@ static void simulation_init (GfsSimulation * object)
 					(GTS_CONTAINER_CLASS
 					 (gts_slist_container_class ())));
   object->modules = NULL;
+
+  object->deferred_compilation = FALSE;
   
   object->tnext = 0.;
 }
diff --git a/src/simulation.h b/src/simulation.h
index 870608e..a1d0cc4 100644
--- a/src/simulation.h
+++ b/src/simulation.h
@@ -75,6 +75,8 @@ struct _GfsSimulation {
   guint thin;
   gboolean output_solid;
 
+  gboolean deferred_compilation;
+
   gdouble tnext;
 };
 
diff --git a/src/source.c b/src/source.c
index bdced85..08fc973 100644
--- a/src/source.c
+++ b/src/source.c
@@ -406,7 +406,7 @@ static void diffusion_destroy (GtsObject * o)
 {
   GfsDiffusion * d = GFS_DIFFUSION (o);
 
-  if (d->mu != gfs_function_get_variable (d->val))
+  if (d->mu && d->mu != gfs_function_get_variable (d->val))
     gts_object_destroy (GTS_OBJECT (d->mu));
   gts_object_destroy (GTS_OBJECT (d->val));
 
@@ -426,10 +426,6 @@ static void diffusion_read (GtsObject ** o, GtsFile * fp)
     if (fp->type == GTS_ERROR)
     return;
   }
-
-  if (gfs_function_get_constant_value (d->val) == G_MAXDOUBLE &&
-      (d->mu = gfs_function_get_variable (d->val)) == NULL)
-    d->mu = gfs_temporary_variable (GFS_DOMAIN (gfs_object_simulation (*o)));
 }
 
 static void diffusion_write (GtsObject * o, FILE * fp)
@@ -448,7 +444,9 @@ static gboolean diffusion_event (GfsEvent * event, GfsSimulation * sim)
 {
   GfsDiffusion * d = GFS_DIFFUSION (event);
 
-  if (d->mu) {
+  if (gfs_function_get_constant_value (d->val) == G_MAXDOUBLE) {
+    if (d->mu == NULL && (d->mu = gfs_function_get_variable (d->val)) == NULL)
+      d->mu = gfs_temporary_variable (GFS_DOMAIN (sim));
     if (d->mu != gfs_function_get_variable (d->val))
       gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
 				(FttCellTraverseFunc) update_mu, event);
@@ -463,14 +461,16 @@ static gboolean diffusion_event (GfsEvent * event, GfsSimulation * sim)
 
 static gdouble diffusion_face (GfsDiffusion * d, FttCellFace * f)
 {
-  return d->mu ? gfs_face_interpolated_value (f, d->mu->i) :
-    gfs_function_get_constant_value (d->val);
+  if (d->mu) return gfs_face_interpolated_value (f, d->mu->i);
+  gdouble val = gfs_function_get_constant_value (d->val);
+  return val < G_MAXDOUBLE ? val : 0.;
 }
 
 static gdouble diffusion_cell (GfsDiffusion * d, FttCell * cell)
 {
-  return d->mu ? GFS_VARIABLE (cell, d->mu->i) :
-    gfs_function_get_constant_value (d->val);
+  if (d->mu) return GFS_VARIABLE (cell, d->mu->i);
+  gdouble val = gfs_function_get_constant_value (d->val);
+  return val < G_MAXDOUBLE ? val : 0.;
 }
 
 static void diffusion_class_init (GfsDiffusionClass * klass)
diff --git a/src/utils.c b/src/utils.c
index 0f44a68..76fb715 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -186,6 +186,7 @@ GtsObjectClass * gfs_global_class (void)
 struct _GfsFunction {
   GtsObject parent;
   GString * expr;
+  gboolean isexpr;
   GModule * module;
   GfsFunctionFunc f;
   gchar * sname;
@@ -196,6 +197,7 @@ struct _GfsFunction {
   GfsDerivedVariable * dv;
   gdouble val;
   gboolean spatial, constant;
+  GtsFile fpd;
 };
 
 static GtsSurface * read_surface (gchar * name, GtsFile * fp)
@@ -310,6 +312,14 @@ static gboolean load_module (GfsFunction * f, GtsFile * fp, gchar * mname)
     g_module_close (f->module);
     return FALSE;
   }
+  if (f->constant) {
+    f->val = (* f->f) (NULL, NULL, NULL);
+    f->f = NULL;
+    g_module_close (f->module);
+    f->module = NULL;
+    if (f->expr) g_string_free (f->expr, TRUE);
+    f->expr = NULL;
+  }
   return TRUE;
 }
 
@@ -523,73 +533,16 @@ static gchar * find_identifier (const gchar * s, const gchar * i)
   return NULL;
 }
 
-static void function_read (GtsObject ** o, GtsFile * fp)
+static void function_compile (GfsFunction * f, GtsFile * fp)
 {
-  GfsFunction * f = GFS_FUNCTION (*o);
-  GfsSimulation * sim;
-  GfsDomain * domain;
-  gboolean isexpr;
-
-  if (GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->read)
-    (* GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->read) (o, fp);
-  if (fp->type == GTS_ERROR)
-    return;
-
-  sim = gfs_object_simulation (*o);
-  domain = GFS_DOMAIN (sim);
-  if (fp->type != GTS_INT && fp->type != GTS_FLOAT && fp->type != GTS_STRING &&
-      fp->type != '(' && fp->type != '{') {
-    gts_file_error (fp, "expecting an expression (val)");
-    return;
-  }
-
-  if ((f->expr = gfs_function_expression (fp, &isexpr)) == NULL)
-    return;
-
-  if (isexpr) {
-    if (fp->type == GTS_INT || fp->type == GTS_FLOAT) {
-      if (!strcmp (fp->token->str, f->expr->str)) {
-	f->val = atof (fp->token->str);
-	gts_file_next_token (fp);
-	return;
-      }
-    }
-    else if (fp->type == GTS_STRING && !f->spatial && !f->constant) {
-      if (strlen (f->expr->str) > 3 &&
-	  !strcmp (&(f->expr->str[strlen (f->expr->str) - 4]), ".gts")) {
-	if ((f->s = read_surface (f->expr->str, fp)) == NULL)
-	  return;
-	f->sname = g_strdup (f->expr->str);
-	gts_file_next_token (fp);
-	return;
-      }
-      else if (strlen (f->expr->str) > 3 &&
-	       !strcmp (&(f->expr->str[strlen (f->expr->str) - 4]), ".cgd")) {
-	if ((f->g = read_cartesian_grid (f->expr->str, fp)) == NULL)
-	  return;
-	if (!fit_index_dimension (f->g, f->index, fp))
-	  return;
-	f->sname = g_strdup (f->expr->str);
-	gts_file_next_token (fp);
-	return;
-      }
-      else if ((f->v = gfs_variable_from_name (domain->variables, f->expr->str))) {
-	gts_file_next_token (fp);
-	return;
-      }
-      else if ((f->dv = lookup_derived_variable (f->expr->str, domain->derived_variables))) {
-	gts_file_next_token (fp);
-	return;
-      }
-    }
-  }
-
   if (!HAVE_PKG_CONFIG) {
     gts_file_error (fp, "expecting a number, variable or GTS surface (val)\n"
 		    "(functions are not supported on this system)");
     return;
   }
   else {
+    GfsSimulation * sim = gfs_object_simulation (f);
+    GfsDomain * domain = GFS_DOMAIN (sim);
     gchar finname[] = "/tmp/gfsXXXXXX";
     gint find, status;
     FILE * fin;
@@ -693,7 +646,7 @@ static void function_read (GtsObject ** o, GtsFile * fp)
     }
     fprintf (fin, "#line %d \"GfsFunction\"\n", fp->line);
 
-    if (isexpr)
+    if (f->isexpr)
       fprintf (fin, "return %s;\n}\n", f->expr->str);
     else {
       gchar * s = f->expr->str;
@@ -712,17 +665,93 @@ static void function_read (GtsObject ** o, GtsFile * fp)
     case SIGQUIT: exit (0);
     case SIGABRT: return;
     }
+  }  
+}
+
+#define DEFERRED_COMPILATION ((GfsFunctionFunc) 0x1)
+
+static void check_for_deferred_compilation (GfsFunction * f)
+{
+  if (f->f == DEFERRED_COMPILATION) {
+    function_compile (f, &f->fpd);
+    if (f->fpd.type == GTS_ERROR) {
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, 
+	     "error in deferred compilation\n%s", 
+	     f->fpd.error);
+      exit (1);
+    }
   }
+}
+
+static void function_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsFunction * f = GFS_FUNCTION (*o);
+  GfsSimulation * sim;
+  GfsDomain * domain;
+
+  if (GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  sim = gfs_object_simulation (*o);
+  domain = GFS_DOMAIN (sim);
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT && fp->type != GTS_STRING &&
+      fp->type != '(' && fp->type != '{') {
+    gts_file_error (fp, "expecting an expression (val)");
+    return;
+  }
+
+  if ((f->expr = gfs_function_expression (fp, &f->isexpr)) == NULL)
+    return;
+
+  if (f->isexpr) {
+    if (fp->type == GTS_INT || fp->type == GTS_FLOAT) {
+      if (!strcmp (fp->token->str, f->expr->str)) {
+	f->val = atof (fp->token->str);
+	gts_file_next_token (fp);
+	return;
+      }
+    }
+    else if (fp->type == GTS_STRING && !f->spatial && !f->constant) {
+      if (strlen (f->expr->str) > 3 &&
+	  !strcmp (&(f->expr->str[strlen (f->expr->str) - 4]), ".gts")) {
+	if ((f->s = read_surface (f->expr->str, fp)) == NULL)
+	  return;
+	f->sname = g_strdup (f->expr->str);
+	gts_file_next_token (fp);
+	return;
+      }
+      else if (strlen (f->expr->str) > 3 &&
+	       !strcmp (&(f->expr->str[strlen (f->expr->str) - 4]), ".cgd")) {
+	if ((f->g = read_cartesian_grid (f->expr->str, fp)) == NULL)
+	  return;
+	if (!fit_index_dimension (f->g, f->index, fp))
+	  return;
+	f->sname = g_strdup (f->expr->str);
+	gts_file_next_token (fp);
+	return;
+      }
+      else if ((f->v = gfs_variable_from_name (domain->variables, f->expr->str))) {
+	gts_file_next_token (fp);
+	return;
+      }
+      else if ((f->dv = lookup_derived_variable (f->expr->str, domain->derived_variables))) {
+	gts_file_next_token (fp);
+	return;
+      }
+    }
+  }
+
+  if (sim->deferred_compilation) {
+    f->f = DEFERRED_COMPILATION;
+    f->fpd = *fp;
+  }
+  else
+    function_compile (f, fp);
+
   if (fp->type == GTS_ERROR)
     return;
-  if (f->constant && f->f) {
-    f->val = (* f->f) (NULL, NULL, NULL);
-    f->f = NULL;
-    if (f->module) g_module_close (f->module);
-    f->module = NULL;
-    if (f->expr) g_string_free (f->expr, TRUE);
-    f->expr = NULL;
-  }    
   gts_file_next_token (fp);
 }
 
@@ -901,8 +930,10 @@ gdouble gfs_function_value (GfsFunction * f, FttCell * cell)
     return (* (GfsFunctionDerivedFunc) f->dv->func) (cell, NULL, 
 						     gfs_object_simulation (f), 
 						     f->dv->data);
-  else if (f->f)
+  else if (f->f) {
+    check_for_deferred_compilation (f);
     return (* f->f) (cell, NULL, gfs_object_simulation (f));
+  }
   else
     return f->val;
 }
@@ -931,8 +962,10 @@ gdouble gfs_function_face_value (GfsFunction * f, FttCellFace * fa)
     return (* (GfsFunctionDerivedFunc) f->dv->func) (NULL, fa,
 						     gfs_object_simulation (f), 
 						     f->dv->data);
-  else if (f->f)
+  else if (f->f) {
+    check_for_deferred_compilation (f);
     return (* f->f) (NULL, fa, gfs_object_simulation (f));
+  }
   else
     return f->val;
 }
@@ -963,6 +996,7 @@ gdouble gfs_function_get_constant_value (GfsFunction * f)
 {
   g_return_val_if_fail (f != NULL, G_MAXDOUBLE);
 
+  check_for_deferred_compilation (f);
   if (f->f || f->s || f->v || f->dv)
     return G_MAXDOUBLE;
   else
@@ -1061,8 +1095,10 @@ gdouble gfs_function_spatial_value (GfsFunction * f, FttVector * p)
   g_return_val_if_fail (GFS_IS_FUNCTION_SPATIAL (f), 0.);
   g_return_val_if_fail (p != NULL, 0.);
 
-  if (f->f)
+  if (f->f) {
+    check_for_deferred_compilation (f);
     return (* (GfsFunctionSpatialFunc) f->f) (p->x, p->y, p->z);
+  }
   else
     return f->val;
 }

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list