Exemplo n.º 1
0
void gfs_post_projection (GfsDomain *domain, GfsPorous *por, guint dimension)
{
GfsVariable **v;
FttComponent c;
gpointer data[3];

g_return_if_fail (domain != NULL);
data[0] = v = gfs_domain_velocity (domain);
data[1] = &dimension;
data[2] = por;
    
gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) correct_por_undo, data);

for (c = 0; c < dimension; c++)
gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, v[c]);
printf("\nvelocity correction undo !!!\n");

}
Exemplo n.º 2
0
static gboolean gfs_init_stokes_wave_event (GfsEvent * event, GfsSimulation * sim)
{
  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_init_stokes_wave_class ())->parent_class)->event) 
      (event, sim)) {
    GfsVariable ** velocity = gfs_domain_velocity (GFS_DOMAIN (sim));
    GfsVariable * t = gfs_variable_from_name (GFS_DOMAIN (sim)->variables, "T");
    g_assert (velocity);
    g_assert (t);
    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) init_velocity, velocity);
    GfsSurface * surface = GFS_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
    surface->f = gfs_function_spatial_new (gfs_function_spatial_class (), stokes_height);
    gfs_object_simulation_set (surface->f, sim);
    gfs_domain_init_fraction (GFS_DOMAIN (sim), GFS_GENERIC_SURFACE (surface), t);
    gts_object_destroy (GTS_OBJECT (surface));
    return TRUE;
  }
  return FALSE;
}
Exemplo n.º 3
0
void gfs_update_gradients_por (GfsDomain * domain,
                               GfsPorous * por,
                               GfsVariable * p,  
                               GfsFunction * alpha,
                               GfsVariable ** g)
{        
  g_return_if_fail (domain != NULL);
  g_return_if_fail (p != NULL);
  g_return_if_fail (g != NULL);
  
  /* Add face sources */
  gfs_reset_gradients (domain, FTT_DIMENSION, g);
  gfs_velocity_face_sources (domain, gfs_domain_velocity (domain), 0., alpha, g);
  /* Initialize face coefficients */
  gfs_poisson_coefficients_por (domain, por, alpha, TRUE, TRUE, TRUE);
  /* Add pressure gradient */
  gfs_correct_normal_velocities (domain, FTT_DIMENSION, p, g, 0.); 
  gfs_scale_gradients (domain, FTT_DIMENSION, g);
}                               
Exemplo n.º 4
0
void gfs_approximate_projection_por (GfsDomain * domain,
                                     GfsPorous * por,
                                     GfsMultilevelParams * par,
                                     gdouble dt,
                                     GfsVariable * p,
                                     GfsFunction * alpha,
                                     GfsVariable * res,
                                     GfsVariable ** g,
                                     void (* divergence_hook) (GfsDomain * domain, 
                                                           gdouble dt,
                                                           GfsVariable * div)
                                     )
{
  g_return_if_fail (domain != NULL);
  g_return_if_fail (par != NULL);
  g_return_if_fail (p != NULL);
  g_return_if_fail (g != NULL);

  gfs_domain_timer_start (domain, "approximate_projection");
  
  gfs_pre_projection (domain, por, FTT_DIMENSION);

  /* compute MAC velocities from centered velocities */
  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, 
                            gfs_domain_velocity (domain));
  
  mac_projection_por (domain, por, par, dt, p, alpha, res, g, divergence_hook);
  
  gfs_correct_centered_velocities (domain, FTT_DIMENSION, g, dt);

  gfs_post_projection (domain, por, FTT_DIMENSION);

  gfs_domain_timer_stop (domain, "approximate_projection");

  if (par->residual.infty > par->tolerance)
    g_warning ("approx projection: max residual %g > %g", par->residual.infty, par->tolerance);
}
Exemplo n.º 5
0
static void darcy_coefficients (GfsSourceDarcy * sd, FttCell * cell, GfsVariable ** u, FttComponent c1, gdouble f[2])
{
    GfsPorous * por = GFS_POROUS (gfs_object_simulation (sd));
    GfsDomain * domain = GFS_DOMAIN(por);
    GfsFunction * porosity = por->porosity;
    GfsFunction * K = por->K;
    gdouble viscosity = 0.001;
    GfsVariable ** U = gfs_domain_velocity (domain);
    GfsSourceVelocity * sv = GFS_SOURCE_VELOCITY (domain);
    GfsSourceDiffusion * d = source_diffusion_viscosity (U[0]); 

    if (d)
    viscosity = gfs_diffusion_cell (d->D, cell);
       
    f[0] = (viscosity * gfs_function_value (porosity,cell))/gfs_function_value (K,cell);
    
    gdouble modu;
    modu = fabs(sqrt(GFS_VALUE (cell, sv->v[0])*GFS_VALUE (cell, sv->v[0]) + 
		   GFS_VALUE (cell, sv->v[1])*GFS_VALUE (cell, sv->v[1])));

    f[1] = (gfs_function_value (porosity,cell))/sqrt(gfs_function_value (K,cell))*modu;
    
  
}
Exemplo n.º 6
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]));

}
Exemplo n.º 7
0
static void mac_projection_por (GfsDomain * domain,
                                GfsPorous * por,
                                GfsMultilevelParams * par,
                                gdouble dt,
                                GfsVariable * p,
                                GfsFunction * alpha,
                                GfsVariable * res,
                                GfsVariable ** g,
                                void (* divergence_hook) (GfsDomain * domain,
                                                      gdouble dt,
                                                      GfsVariable * div)
                            )
{
  /* Add face sources */
  gfs_reset_gradients (domain, FTT_DIMENSION, g);
  gfs_velocity_face_sources (domain, gfs_domain_velocity (domain), dt, alpha, g);
    
  GfsVariable * dia = gfs_temporary_variable (domain);
  GfsVariable * div = gfs_temporary_variable (domain);
  GfsVariable * res1 = res ? res : gfs_temporary_variable (domain);
  
  /* Initialize face coefficients */
  gfs_poisson_coefficients_por (domain, por, alpha, TRUE, TRUE, TRUE);
  
  /* hydrostatic pressure */ 
  GSList * i = domain->variables;
  while (i) {
    if (GFS_IS_HYDROSTATIC_PRESSURE (i->data))
      gfs_correct_normal_velocities (domain, FTT_DIMENSION, i->data, g, dt);
    i = i->next;
  }
  
  /* Initialize diagonal coefficient */
  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
                            (FttCellTraverseFunc) gfs_cell_reset, dia);

  /* compute MAC divergence */
  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
                            (FttCellTraverseFunc) gfs_normal_divergence, div);

  /* Divergence hook */
  if (divergence_hook)
    (* divergence_hook) (domain, dt, div);

  /* add volume sources (if any) */
  if (p->sources)
    volume_sources (domain, p, div);

  /* Scale divergence */
  gpointer data[2];
  data[0] = div;
  data[1] = &dt;
  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
                            (FttCellTraverseFunc) scale_divergence, data);

#if 0
  {
    FILE * fp = fopen ("/tmp/mac", "wt");
    GfsNorm norm;

    gfs_write_mac_velocity (domain, 0.9, FTT_TRAVERSE_LEAFS, -1, NULL, fp);
    fclose (fp);
    norm = gfs_domain_norm_variable (domain, div, FTT_TRAVERSE_LEAFS, -1);
    fprintf (stderr, "mac div before: %g %g %g\n",
             norm.first, norm.second, norm.infty);
  }
#endif

par->poisson_solve (domain, par, p, div, res1, dia, dt);

  gts_object_destroy (GTS_OBJECT (dia));
  gts_object_destroy (GTS_OBJECT (div));
  if (!res)
    gts_object_destroy (GTS_OBJECT (res1));

  gfs_correct_normal_velocities (domain, FTT_DIMENSION, p, g, dt);
  gfs_scale_gradients (domain, FTT_DIMENSION, g);
}