예제 #1
0
파일: refine.c 프로젝트: Exteris/Gerris
static void gfs_refine_refine (GfsRefine * refine, GfsSimulation * sim)
{
  gfs_catch_floating_point_exceptions ();
  gts_container_foreach (GTS_CONTAINER (sim),
			 (GtsFunc) refine_box, refine->maxlevel);
  gfs_restore_fpe_for_function (refine->maxlevel);
}
예제 #2
0
파일: moving2.c 프로젝트: Exteris/Gerris
static void swap_face_fractions (GfsSimulation * sim)
{
  GfsDomain * domain = GFS_DOMAIN (sim);
  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
			    (FttCellTraverseFunc) swap_fractions, 
			    GFS_SIMULATION_MOVING (sim)->old_solid);
  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) foreach_box, NULL);
}
예제 #3
0
파일: partition.c 프로젝트: ClavinSBU/gts
/**
 * gts_graph_bisection_check:
 * @bg: a #GtsGraphBisection.
 *
 * Checks that the boundary of @bg is correctly defined (used for
 * debugging purposes).
 *
 * Returns: %TRUE if @bg is ok, %FALSE otherwise.  
 */
gboolean gts_graph_bisection_check (GtsGraphBisection * bg)
{
  gboolean ok = TRUE;
  guint nb;
  gpointer data[4];

  g_return_val_if_fail (bg != NULL, FALSE);

  nb = 0;
  data[0] = bg->bg1;
  data[1] = bg->g2;
  data[2] = &ok;
  data[3] = &nb;
  gts_container_foreach (GTS_CONTAINER (bg->g1), (GtsFunc) check_bg, data);
  g_return_val_if_fail (g_hash_table_size (bg->bg1) == nb, FALSE);

  nb = 0;
  data[0] = bg->bg2;
  data[1] = bg->g1;
  gts_container_foreach (GTS_CONTAINER (bg->g2), (GtsFunc) check_bg, data);
  g_return_val_if_fail (g_hash_table_size (bg->bg2) == nb, FALSE);

  return ok;
}
예제 #4
0
파일: partition.c 프로젝트: ClavinSBU/gts
/**
 * gts_graph_bisection_bkl_refine:
 * @bg: a #GtsGraphBisection.
 * @mmax: the maximum number of unsuccessful successive moves.
 * @imbalance: the maximum relative imbalance allowed between the
 * weights of both halves of the partition.
 *
 * An implementation of the simplified boundary Kernighan-Lin
 * algorithm for graph bisection refinement as described in Karypis
 * and Kumar (1997).
 *
 * The algorithm stops if @mmax consecutive modes do not lead to a
 * decrease in the number of edges cut. This last @mmax moves are
 * undone.
 *
 * Returns: the decrease in the weight of the edges cut by the bisection.  
 */
gdouble gts_graph_bisection_bkl_refine (GtsGraphBisection * bg,
					guint mmax,
					gfloat imbalance)
{
  GtsEHeap * h1, * h2;
  GtsGNode * n;
  guint nm = 0, i;
  GtsGNode ** moves;
  gdouble bestcost = 0., totalcost = 0., best_balance;
  gboolean balanced = FALSE;

  g_return_val_if_fail (bg != NULL, 0.);
  g_return_val_if_fail (mmax > 0, 0.);
  g_return_val_if_fail (imbalance >= 0. && imbalance <= 1., 0.);

  h1 = gts_eheap_new ((GtsKeyFunc) node_move_cost1, bg);
  gts_eheap_freeze (h1);
  g_hash_table_foreach (bg->bg1, (GHFunc) build_bheap, h1);
  gts_eheap_thaw (h1);

  h2 = gts_eheap_new ((GtsKeyFunc) node_move_cost2, bg);
  gts_eheap_freeze (h2);
  g_hash_table_foreach (bg->bg2, (GHFunc) build_bheap, h2);
  gts_eheap_thaw (h2);

  moves = g_malloc (sizeof (GtsGNode *)*mmax);
  imbalance *= gts_graph_weight (bg->g);
  best_balance = fabs (gts_graph_weight (bg->g1) - gts_graph_weight (bg->g2));
  if (best_balance <= imbalance)
    balanced = TRUE;

  do {
    GtsGraph * g1, * g2;
    GHashTable * bg1, * bg2;
    gdouble cost;

    if (gts_graph_weight (bg->g1) > gts_graph_weight (bg->g2)) {
      n = gts_eheap_remove_top (h1, &cost);
      g1 = bg->g1;
      g2 = bg->g2;
      bg1 = bg->bg1;
      bg2 = bg->bg2;
    }
    else {
      n = gts_eheap_remove_top (h2, &cost);
      g1 = bg->g2;
      g2 = bg->g1;
      bg1 = bg->bg2;
      bg2 = bg->bg1;
    }
    if (n) {
      gdouble balance;
	
      GTS_OBJECT (n)->reserved = n;
      gts_container_add (GTS_CONTAINER (g2), GTS_CONTAINEE (n));
      gts_container_remove (GTS_CONTAINER (g1), GTS_CONTAINEE (n));
      g_hash_table_remove (bg1, n);
      if (gts_gnode_degree (n, g1))
	g_hash_table_insert (bg2, n, n);

      update_neighbors (n, bg, h1, h2);

      totalcost += cost;
      balance = fabs (gts_graph_weight (g1) - gts_graph_weight (g2));
      
      if (!balanced && balance <= imbalance) {
	bestcost = totalcost;
	best_balance = balance;
	balanced = TRUE;
	nm = 0;
      }
      else if (totalcost < bestcost && 
	       (balance < best_balance || balance <= imbalance)) {
	bestcost = totalcost;
	best_balance = balance;
	nm = 0;
      }
      else if (totalcost == bestcost && balance < best_balance) {
	best_balance = balance;
	nm = 0;
      }
      else
	moves[nm++] = n;
    }
  } while (n && nm < mmax);

  gts_container_foreach (GTS_CONTAINER (bg->g), 
			 (GtsFunc) gts_object_reset_reserved, NULL);
  gts_eheap_destroy (h1);
  gts_eheap_destroy (h2);

  /* undo last nm moves */
  for (i = 0; i < nm; i++) {
    GtsGNode * n = moves[i];
    GtsGraph * g1, * g2;
    GHashTable * bg1, * bg2;

    if (gts_containee_is_contained (GTS_CONTAINEE (n),
				    GTS_CONTAINER (bg->g1))) {
      g1 = bg->g1;
      g2 = bg->g2;
      bg1 = bg->bg1;
      bg2 = bg->bg2;
    }
    else {
      g1 = bg->g2;
      g2 = bg->g1;
      bg1 = bg->bg2;
      bg2 = bg->bg1;
    }
    
    gts_container_add (GTS_CONTAINER (g2), GTS_CONTAINEE (n));
    gts_container_remove (GTS_CONTAINER (g1), GTS_CONTAINEE (n));
    g_hash_table_remove (bg1, n);
    if (gts_gnode_degree (n, g1))
      g_hash_table_insert (bg2, n, n);

    update_neighbors (n, bg, NULL, NULL);
  }
  g_free (moves);

  return bestcost;
}
예제 #5
0
파일: partition.c 프로젝트: ClavinSBU/gts
/**
 * gts_graph_bisection_kl_refine:
 * @bg: a #GtsGraphBisection.
 * @mmax: the maximum number of unsuccessful successive moves.
 *
 * An implementation of the simplified Kernighan-Lin algorithm for
 * graph bisection refinement as described in Karypis and Kumar
 * (1997).
 *
 * The algorithm stops if @mmax consecutive modes do not lead to a
 * decrease in the number of edges cut. This last @mmax moves are
 * undone.
 *
 * Returns: the decrease in the weight of the edges cut by the bisection.  
 */
gdouble gts_graph_bisection_kl_refine (GtsGraphBisection * bg,
				       guint mmax)
{
  GtsEHeap * h1, * h2;
  GtsGNode * n;
  guint nm = 0, i;
  GtsGNode ** moves;
  gdouble bestcost = 0., totalcost = 0., best_balance;

  g_return_val_if_fail (bg != NULL, 0.);
  g_return_val_if_fail (mmax > 0, 0.);

  h1 = gts_eheap_new ((GtsKeyFunc) node_move_cost1, bg);
  gts_eheap_freeze (h1);
  gts_container_foreach (GTS_CONTAINER (bg->g1), (GtsFunc) build_heap, h1);
  gts_eheap_thaw (h1);

  h2 = gts_eheap_new ((GtsKeyFunc) node_move_cost2, bg);
  gts_eheap_freeze (h2);
  gts_container_foreach (GTS_CONTAINER (bg->g2), (GtsFunc) build_heap, h2);
  gts_eheap_thaw (h2);

  moves = g_malloc (sizeof (GtsGNode *)*mmax);
  best_balance = fabs (gts_graph_weight (bg->g1) - gts_graph_weight (bg->g2));

  do {
    GtsGraph * g1, * g2;
    gdouble cost;

    if (gts_graph_weight (bg->g1) > gts_graph_weight (bg->g2)) {
      n = gts_eheap_remove_top (h1, &cost);
      g1 = bg->g1;
      g2 = bg->g2;
    }
    else {
      n = gts_eheap_remove_top (h2, &cost);
      g1 = bg->g2;
      g2 = bg->g1;
    }
    if (n) {
      GSList * i;

      GTS_OBJECT (n)->reserved = NULL;
      gts_container_add (GTS_CONTAINER (g2), GTS_CONTAINEE (n));
      gts_container_remove (GTS_CONTAINER (g1), GTS_CONTAINEE (n));

      totalcost += cost;
      if (totalcost < bestcost) {
	bestcost = totalcost;
	nm = 0;
      }
      else if (totalcost == bestcost) {
	gdouble balance = fabs (gts_graph_weight (g1) - gts_graph_weight (g2));

	if (balance < best_balance) {
	  best_balance = balance;
	  nm = 0;
	}
      }	       
      else
	moves[nm++] = n;

      i = GTS_SLIST_CONTAINER (n)->items;
      while (i) {
	GtsGNode * n1 = GTS_GNODE_NEIGHBOR (n, i->data);
	if (GTS_OBJECT (n1)->reserved && 
	    gts_containee_is_contained (GTS_CONTAINEE (n1), 
					GTS_CONTAINER (bg->g))) {
	  GtsEHeap * h = 
	    gts_containee_is_contained (GTS_CONTAINEE (n1), 
					GTS_CONTAINER (bg->g1)) ? h1 : h2;
	  gts_eheap_remove (h, GTS_OBJECT (n1)->reserved);
	  GTS_OBJECT (n1)->reserved = gts_eheap_insert (h, n1);
	}
	i = i->next;
      }
    }
  } while (n && nm < mmax);

  gts_eheap_foreach (h1, (GFunc) gts_object_reset_reserved, NULL);
  gts_eheap_foreach (h2, (GFunc) gts_object_reset_reserved, NULL);
  gts_eheap_destroy (h1);
  gts_eheap_destroy (h2);

  /* undo last nm moves */
  for (i = 0; i < nm; i++) {
    GtsGNode * n = moves[i];
    GtsGraph * g1 = 
      gts_containee_is_contained (GTS_CONTAINEE (n),
				  GTS_CONTAINER (bg->g1)) ? bg->g1 : bg->g2;
    GtsGraph * g2 = g1 == bg->g1 ? bg->g2 : bg->g1;
    
    gts_container_add (GTS_CONTAINER (g2), GTS_CONTAINEE (n));
    gts_container_remove (GTS_CONTAINER (g1), GTS_CONTAINEE (n));
  }
  g_free (moves);

  return bestcost;
}
예제 #6
0
파일: partition.c 프로젝트: ClavinSBU/gts
/**
 * gts_graph_bfgg_bisection:
 * @g: a #GtsGraph.
 * @ntry: the number of randomly selected initial seeds.
 *
 * An implementation of a "Breadth-First Graph Growing" algorithm.
 *
 * @ntry randomly chosen seeds are used and the best partition is retained.
 *
 * Returns: a new #GtsGraphBisection of @g.
 */
GtsGraphBisection * gts_graph_bfgg_bisection (GtsGraph * g, guint ntry)
{
  gfloat size, bestcost = G_MAXFLOAT, smin;
  GtsGraph * bestg1 = NULL, * bestg2 = NULL;
  GtsEHeap * degree_heap;
  GtsGNode * seed;
  GtsGraphBisection * bg;

  g_return_val_if_fail (g != NULL, NULL);

  bg = g_malloc (sizeof (GtsGraphBisection));
  bg->g = g;

  size = gts_graph_weight (g)/2.;
  smin = 0.9*size;

  degree_heap = gts_eheap_new ((GtsKeyFunc) degree_cost, g);
  gts_eheap_freeze (degree_heap);
  gts_container_foreach (GTS_CONTAINER (g), (GtsFunc) add_seed, degree_heap);
  gts_eheap_thaw (degree_heap);

  while (ntry && ((seed = gts_eheap_remove_top (degree_heap, NULL)))) {
    GtsGraph * g1, * g2;
    GtsGNode * n;
    gdouble cost;
    GtsGraphTraverse * t = gts_graph_traverse_new (g, seed, 
						   GTS_BREADTH_FIRST, TRUE);
    
    g1 = gts_graph_new (GTS_GRAPH_CLASS (GTS_OBJECT (g)->klass),
			g->node_class, g->edge_class);
    g2 = gts_graph_new (GTS_GRAPH_CLASS (GTS_OBJECT (g)->klass),
			g->node_class, g->edge_class);

    while ((n = gts_graph_traverse_next (t)))
      if (gts_graph_weight (g1) + gts_gnode_weight (n) <= size) {
	gts_container_add (GTS_CONTAINER (g1), GTS_CONTAINEE (n));
	GTS_OBJECT (n)->reserved = n;
      }
    gts_graph_traverse_destroy (t);
    
    gts_container_foreach (GTS_CONTAINER (g), (GtsFunc) add_unused, g2);

    cost = gts_graph_edges_cut_weight (g1);
    if (!bestg1 || (cost < bestcost && gts_graph_weight (g1) >= smin)) {
      if (bestg1)
	bestcost = cost;
      if (bestg1)
	gts_object_destroy (GTS_OBJECT (bestg1));
      if (bestg2)
	gts_object_destroy (GTS_OBJECT (bestg2));
      bestg1 = g1;
      bestg2 = g2;
    }
    else {
      gts_object_destroy (GTS_OBJECT (g1));
      gts_object_destroy (GTS_OBJECT (g2));
    }

    ntry--;
  }
  gts_eheap_destroy (degree_heap);

#ifdef DEBUG
  fprintf (stderr, "bestcost: %5g g1: %5g|%5d g2: %5g|%5d\n",
	   bestcost, 
	   gts_graph_weight (bestg1), 
	   gts_container_size (GTS_CONTAINER (bestg1)),
	   gts_graph_weight (bestg2), 
	   gts_container_size (GTS_CONTAINER (bestg2)));
#endif

  bg->g1 = bestg1;
  bg->g2 = bestg2;
  
  /* boundary nodes */
  bg->bg1 = g_hash_table_new (NULL, NULL);
  gts_container_foreach (GTS_CONTAINER (bg->g1), (GtsFunc) boundary_node1, bg);
  bg->bg2 = g_hash_table_new (NULL, NULL);
  gts_container_foreach (GTS_CONTAINER (bg->g2), (GtsFunc) boundary_node2, bg);

  return bg;
}
예제 #7
0
파일: partition.c 프로젝트: ClavinSBU/gts
/**
 * gts_graph_ggg_bisection:
 * @g: a #GtsGraph.
 * @ntry: the number of randomly selected initial seeds.
 *
 * An implementation of the "Greedy Graph Growing" algorithm of
 * Karypis and Kumar (1997).  
 *
 * @ntry randomly chosen seeds are used and the best partition is retained.
 *
 * Returns: a new #GtsGraphBisection of @g.
 */
GtsGraphBisection * gts_graph_ggg_bisection (GtsGraph * g, guint ntry)
{
  gfloat size, bestcost = G_MAXFLOAT, smin;
  GtsGraph * bestg1 = NULL, * bestg2 = NULL;
  gboolean balanced = FALSE;
  GtsEHeap * degree_heap;
  GtsGNode * seed;
  GtsGraphBisection * bg;

  g_return_val_if_fail (g != NULL, NULL);

  bg = g_malloc (sizeof (GtsGraphBisection));
  bg->g = g;

  size = gts_graph_weight (g)/2.;
  smin = 0.9*size;

  degree_heap = gts_eheap_new ((GtsKeyFunc) degree_cost, g);
  gts_eheap_freeze (degree_heap);
  gts_container_foreach (GTS_CONTAINER (g), (GtsFunc) add_seed, degree_heap);
  gts_eheap_thaw (degree_heap);

  while (ntry && ((seed = gts_eheap_remove_top (degree_heap, NULL)))) {
    GtsGraph * g1, * g2;
    GtsGNode * n;
    gdouble cost;
    gpointer data[2];
    GtsEHeap * heap;
  
    g1 = gts_graph_new (GTS_GRAPH_CLASS (GTS_OBJECT (g)->klass),
			g->node_class, g->edge_class);
    g2 = gts_graph_new (GTS_GRAPH_CLASS (GTS_OBJECT (g)->klass),
			g->node_class, g->edge_class);
    
    data[0] = g;
    data[1] = g1;
    heap = gts_eheap_new ((GtsKeyFunc) node_cost, data);

    gts_container_add (GTS_CONTAINER (g1), GTS_CONTAINEE (seed));
    GTS_OBJECT (seed)->reserved = seed;
    gts_gnode_foreach_neighbor (seed, g, (GtsFunc) add_neighbor, heap);

    while ((n = gts_eheap_remove_top (heap, &cost)))
      if (gts_graph_weight (g1) + gts_gnode_weight (n) <= size) {
	gts_container_add (GTS_CONTAINER (g1), GTS_CONTAINEE (n));
	GTS_OBJECT (n)->reserved = n;
	gts_gnode_foreach_neighbor (n, g, (GtsFunc) add_neighbor, heap);
      }
      else
	GTS_OBJECT (n)->reserved = NULL;
    gts_eheap_destroy (heap);
    
    gts_container_foreach (GTS_CONTAINER (g), (GtsFunc) add_unused, g2);

    cost = gts_graph_edges_cut_weight (g1);
    if (!bestg1 || 
	(!balanced && gts_graph_weight (g1) >= smin) ||
	(cost < bestcost && gts_graph_weight (g1) >= smin)) {
      if (bestg1)
	bestcost = cost;
      if (bestg1)
	gts_object_destroy (GTS_OBJECT (bestg1));
      if (bestg2)
	gts_object_destroy (GTS_OBJECT (bestg2));
      bestg1 = g1;
      bestg2 = g2;
      if (gts_graph_weight (g1) >= smin)
	balanced = TRUE;
    }
    else {
      gts_object_destroy (GTS_OBJECT (g1));
      gts_object_destroy (GTS_OBJECT (g2));
    }

    ntry--;
  }
  gts_eheap_destroy (degree_heap);

#ifdef DEBUG
  fprintf (stderr, "bestcost: %5g g1: %5g|%5d g2: %5g|%5d\n",
	   bestcost, 
	   gts_graph_weight (bestg1), 
	   gts_container_size (GTS_CONTAINER (bestg1)),
	   gts_graph_weight (bestg2), 
	   gts_container_size (GTS_CONTAINER (bestg2)));
#endif

  g_assert (bestg1 != NULL);
  bg->g1 = bestg1;
  g_assert (bestg2 != NULL);
  bg->g2 = bestg2;
  
  /* boundary nodes */
  bg->bg1 = g_hash_table_new (NULL, NULL);
  gts_container_foreach (GTS_CONTAINER (bg->g1), (GtsFunc) boundary_node1, bg);
  bg->bg2 = g_hash_table_new (NULL, NULL);
  gts_container_foreach (GTS_CONTAINER (bg->g2), (GtsFunc) boundary_node2, bg);

  return bg;
}
예제 #8
0
파일: partition.c 프로젝트: ClavinSBU/gts
/**
 * gts_graph_bubble_partition:
 * @g: a #GtsGraph.
 * @np: number of partitions.
 * @niter: the maximum number of iterations.
 * @step_info: a #GtsFunc or %NULL.
 * @data: user data to pass to @step_info.
 *
 * An implementation of the "bubble partitioning algorithm" of
 * Diekmann, Preis, Schlimbach and Walshaw (2000). The maximum number
 * of iteration on the positions of the graph growing seeds is
 * controlled by @niter.
 *
 * If not %NULL @step_info is called after each iteration on the seeds
 * positions passing the partition (a GSList) as argument.
 *
 * Returns: a list of @np new #GtsGraph representing the partition.  
 */
GSList * gts_graph_bubble_partition (GtsGraph * g, 
				     guint np, 
				     guint niter,
				     GtsFunc step_info,
				     gpointer data)
{
  GSList * list = NULL, * seeds = NULL;
  GtsGNode * seed = NULL;
  guint min = G_MAXINT/2 - 1;
  gpointer info[3];
  GtsGraph * g1;
  gboolean changed = TRUE;

  g_return_val_if_fail (g != NULL, NULL);
  g_return_val_if_fail (np > 0, NULL);

  info[0] = &seed;
  info[1] = g;
  info[2] = &min;
  gts_container_foreach (GTS_CONTAINER (g), 
			 (GtsFunc) find_smallest_degree,
			 info);
  if (seed == NULL)
    return NULL;

  g1 = GTS_GRAPH (gts_object_new (GTS_OBJECT (g)->klass));
  gts_container_add (GTS_CONTAINER (g1), GTS_CONTAINEE (seed));
  list = g_slist_prepend (list, g1);
  GTS_OBJECT (g1)->reserved = seed;
  seeds = g_slist_prepend (seeds, seed);

  while (--np && seed)
    if ((seed = gts_graph_farthest (g, seeds))) {
      g1 = GTS_GRAPH (gts_object_new (GTS_OBJECT (g)->klass));
      gts_container_add (GTS_CONTAINER (g1), GTS_CONTAINEE (seed));
      list = g_slist_prepend (list, g1);
      GTS_OBJECT (g1)->reserved = seed;
      seeds = g_slist_prepend (seeds, seed);
    }
  g_slist_free (seeds);
  
  partition_update (list, g);

  while (changed && niter--) {
    GSList * i;

    changed = FALSE;
    i = list;
    while (i) {
      GtsGraph * g1 = i->data;
      GtsGNode * seed = GTS_OBJECT (g1)->reserved;
      GtsGNode * new_seed = graph_new_seed (g1, seed);
      if (new_seed != seed) {
	changed = TRUE;
	GTS_OBJECT (g1)->reserved = new_seed;
      }
      i = i->next;
    }

    if (changed) {
      i = list;
      while (i) {
	GtsGraph * g1 = i->data;
	GtsGNode * seed = GTS_OBJECT (g1)->reserved;

	gts_object_destroy (GTS_OBJECT (g1));
	i->data = g1 = GTS_GRAPH (gts_object_new (GTS_OBJECT (g)->klass));
	gts_container_add (GTS_CONTAINER (g1), GTS_CONTAINEE (seed));
	GTS_OBJECT (g1)->reserved = seed;
	i = i->next;
      }
      partition_update (list, g);
      if (step_info)
	(* step_info) (list, data);
    }
  }
  g_slist_foreach (list, (GFunc) gts_object_reset_reserved, NULL);
  return list;
}
예제 #9
0
파일: wave.c 프로젝트: Exteris/Gerris
static void wave_run (GfsSimulation * sim)
{
  GfsDomain * domain = GFS_DOMAIN (sim);
  GfsWave * wave = GFS_WAVE (sim);

  SolidFluxParams par;
  par.div = gfs_variable_from_name (domain->variables, "P");
  g_assert (par.div);
  par.p = &sim->advection_params;
  par.fv = gfs_temporary_variable (domain);

  gfs_simulation_refine (sim);
  gfs_simulation_init (sim);

  while (sim->time.t < sim->time.end &&
	 sim->time.i < sim->time.iend) {
    gdouble tstart = gfs_clock_elapsed (domain->timer);

    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);

    /* get global timestep */
    gfs_domain_face_traverse (domain, FTT_XYZ,
			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
    gfs_simulation_set_timestep (sim);
    gdouble dt = sim->advection_params.dt;
    gdouble g = sim->physical_params.g/sim->physical_params.L;
    gdouble tnext = sim->tnext;
    
    /* spatial advection */
    guint ik, ith;
    for (ik = 0; ik < wave->nk; ik++) {
      FttVector cg;
      group_velocity (ik, 0, &cg, wave->ntheta, g);
      gfs_domain_face_traverse (domain, FTT_XYZ,
				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
				(FttFaceTraverseFunc) set_group_velocity, &cg);
      if (wave->alpha_s > 0.) {
	/* stability criterion for GSE diffusion */
	gdouble cfl = sim->advection_params.cfl;
	sim->advection_params.cfl = MIN (cfl, 2./(4.*wave->alpha_s*M_PI/wave->ntheta));
	/* fixme: this should be:
	   sim->advection_params.cfl = MIN (cfl, sqrt(3.)/(wave->alpha_s*2.*M_PI/wave->ntheta));
	*/
	gfs_simulation_set_timestep (sim);
	sim->advection_params.cfl = cfl;
      }
      else
	gfs_simulation_set_timestep (sim);
      /* subcycling */
      guint n = rint (dt/sim->advection_params.dt);
      g_assert (fabs (sim->time.t + sim->advection_params.dt*n - tnext) < 1e-12);
      while (n--) {
	for (ith = 0; ith < wave->ntheta; ith++) {
	  FttVector cg;
	  group_velocity (ik, ith, &cg, wave->ntheta, g);
	  gfs_domain_face_traverse (domain, FTT_XYZ,
				    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
				    (FttFaceTraverseFunc) set_group_velocity, &cg);
	  GfsVariable * t = GFS_WAVE (sim)->F[ik][ith];
	  sim->advection_params.v = t;
	  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) solid_flux, &par);
	  gfs_tracer_advection_diffusion (domain, &sim->advection_params, NULL);
	  sim->advection_params.fv = par.fv;
	  gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, 
	  			      &sim->advection_params);
	  if (wave->alpha_s > 0.)
	    gse_alleviation_diffusion (domain, t, &cg, sim->advection_params.dt);
	  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, t);
	  gfs_domain_cell_traverse (domain,
				    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
				    (FttCellTraverseFunc) t->fine_coarse, t);
	}
	gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) redo_some_events, sim);
	gfs_simulation_adapt (sim);
      }
    }

    sim->advection_params.dt = dt;

    /* source terms */
    if (wave->source)
      (* wave->source) (wave);

    sim->time.t = sim->tnext = tnext;
    sim->time.i++;

    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
    gts_range_update (&domain->timestep);
    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
    gts_range_update (&domain->size);
  }
  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
  gts_object_destroy (GTS_OBJECT (par.fv));
}
예제 #10
0
static void gfs_skew_symmetric_run (GfsSimulation * sim)
{
  GfsVariable * p,  * res = NULL, * gmac[FTT_DIMENSION]; 
  GfsDomain * domain;
  GSList * i;

  domain = GFS_DOMAIN (sim);

  p = gfs_variable_from_name (domain->variables, "P");

  g_assert (p);
  FttComponent c;
  for (c = 0; c < FTT_DIMENSION; c++) 
    gmac[c] = gfs_temporary_variable (domain);

  gfs_variable_set_vector (gmac, FTT_DIMENSION);

  gfs_simulation_refine (sim);
  gfs_simulation_init (sim);

  i = domain->variables;
  while (i) {
    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
      res = i->data;
    i = i->next;
  }

  gfs_simulation_set_timestep (sim);

  GfsVariable ** u = gfs_domain_velocity (domain);
  GfsVariable ** velfaces = GFS_SKEW_SYMMETRIC(sim)->velfaces;
  GfsVariable ** velold   = GFS_SKEW_SYMMETRIC(sim)->velold;

  FaceData fd = { velfaces, velold, u, p, &sim->advection_params.dt, GFS_SKEW_SYMMETRIC(sim)->beta};

  if (sim->time.i == 0) {

    gfs_domain_cell_traverse (domain, 
                              FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) reset_unold, &fd);
    
    


    gfs_domain_cell_traverse (domain, 
        FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
        (FttCellTraverseFunc) get_face_values, &fd);
  
    gfs_mac_projection (domain,
			&sim->projection_params, 
			sim->advection_params.dt/2.,
			p, sim->physical_params.alpha, gmac, NULL);
 
    gfs_domain_cell_traverse (domain, 
			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) get_velfaces, &fd);

    gfs_domain_cell_traverse (domain, 
                              FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) initialize_unold, &fd);
  
  }

  while (sim->time.t < sim->time.end && sim->time.i < sim->time.iend) {
    
    gdouble tstart = gfs_clock_elapsed (domain->timer);

    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);

    gfs_skew_symmetric_momentum (sim, &fd, gmac);

    gfs_mac_projection (domain,
			&sim->projection_params, 
			sim->advection_params.dt/2.,
			p, sim->physical_params.alpha, gmac, NULL);

    gfs_domain_cell_traverse (domain, 
                              FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, 
                              (FttCellTraverseFunc) correct_face_velocity, NULL);

    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim); 
    gfs_domain_cell_traverse (domain, 
			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) get_velfaces, &fd);

    gfs_domain_cell_traverse (domain, 
			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) get_cell_values, &fd);

    gfs_domain_cell_traverse (domain,
			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
    gfs_simulation_adapt (sim);

    sim->time.t = sim->tnext;
    sim->time.i++;

    gfs_simulation_set_timestep (sim);
    gfs_advance_tracers (sim, sim->advection_params.dt);

    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
    gts_range_update (&domain->timestep);
    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
    gts_range_update (&domain->size);
  }
  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);

  for (c = 0; c < FTT_DIMENSION; c++) 
    gts_object_destroy (GTS_OBJECT (gmac[c]));

}
예제 #11
0
파일: porous.c 프로젝트: suhasjains/Gerris
static void gfs_porous_run (GfsSimulation * sim)
{
  GfsVariable * p, * pmac, * res = NULL, * g[FTT_DIMENSION], * gmac[FTT_DIMENSION];
  GfsVariable ** gc = sim->advection_params.gc ? g : NULL;
  GfsDomain * domain;
  GfsPorous *por;
  GSList * i;
    
  domain = GFS_DOMAIN (sim);
  por = GFS_POROUS (sim);

  p = gfs_variable_from_name (domain->variables, "P");
  g_assert (p);
  pmac = gfs_variable_from_name (domain->variables, "Pmac");
  g_assert (pmac);
  FttComponent c;
  for (c = 0; c < FTT_DIMENSION; c++) {
    gmac[c] = gfs_temporary_variable (domain);
    if (sim->advection_params.gc)
      g[c] = gfs_temporary_variable (domain);
    else
      g[c] = gmac[c];
  }
  gfs_variable_set_vector (gmac, FTT_DIMENSION);
  gfs_variable_set_vector (g, FTT_DIMENSION);

  gfs_simulation_refine (sim);
  gfs_simulation_init (sim);

  i = domain->variables;
  while (i) {
    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
      res = i->data;
    i = i->next;
  }

  gfs_simulation_set_timestep (sim);
  if (sim->time.i == 0) {

    /*inserted changes inside this function*/
    gfs_approximate_projection_por (domain, por,
				&sim->approx_projection_params,
				sim->advection_params.dt,
				p, sim->physical_params.alpha, res, g, NULL);


    gfs_simulation_set_timestep (sim);
    gfs_advance_tracers (sim, sim->advection_params.dt/2.);
  }
  else if (sim->advection_params.gc)
    gfs_update_gradients_por (domain, por, p, sim->physical_params.alpha, g);


  while (sim->time.t < sim->time.end &&
	 sim->time.i < sim->time.iend) {
    gdouble tstart = gfs_clock_elapsed (domain->timer);

    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
    
    /*inserted changes */
      gfs_pre_projection (domain, por, FTT_DIMENSION);
      
    if (sim->advection_params.linear) {
      /* linearised advection */

      gfs_domain_face_traverse (domain, FTT_XYZ,
				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
				(FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
      gfs_domain_face_traverse (domain, FTT_XYZ,
				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
				(FttFaceTraverseFunc) gfs_face_interpolated_normal_velocity,
				sim->u0);
    }

    else
      gfs_predicted_face_velocities (domain, FTT_DIMENSION, &sim->advection_params);
      
    gfs_variables_swap (p, pmac);


    gfs_mac_projection_por (domain, por,
    			&sim->projection_params, 
    			sim->advection_params.dt/2.,
			p, sim->physical_params.alpha, gmac, NULL);


    gfs_variables_swap (p, pmac);

    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);

    gfs_centered_velocity_advection_diffusion (domain,
					       FTT_DIMENSION,
					       &sim->advection_params,
					       gmac,
					       sim->time.i > 0 || !gc ? gc : gmac,
					       sim->physical_params.alpha);
    if (gc) {
      gfs_source_darcy_implicit (domain, sim->advection_params.dt);
      gfs_correct_centered_velocities (domain, FTT_DIMENSION, sim->time.i > 0 ? gc : gmac, 
				       -sim->advection_params.dt);
      /*inserted changes*/
      gfs_post_projection (domain, por, FTT_DIMENSION);
}
    else if (gfs_has_source_coriolis (domain)) {
      gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, sim->advection_params.dt);
      gfs_source_darcy_implicit (domain, sim->advection_params.dt);
      gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, -sim->advection_params.dt);
      /*inserted changes*/
      gfs_post_projection (domain, por, FTT_DIMENSION);
   
 }

    gfs_domain_cell_traverse (domain,
			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
    gfs_simulation_adapt (sim);

    /*inserted changes */

    gfs_approximate_projection_por (domain, por,
   				&sim->approx_projection_params, 
    				sim->advection_params.dt, 
				p, sim->physical_params.alpha, res, g, NULL);

    /*inserted changes */

    sim->time.t = sim->tnext;
    sim->time.i++;

    gfs_simulation_set_timestep (sim);
    gfs_advance_tracers (sim, sim->advection_params.dt);

    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
    gts_range_update (&domain->timestep);
    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
    gts_range_update (&domain->size);
  }
  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);

  for (c = 0; c < FTT_DIMENSION; c++) {
    gts_object_destroy (GTS_OBJECT (gmac[c]));
    if (sim->advection_params.gc)
      gts_object_destroy (GTS_OBJECT (g[c]));
  }
}