Пример #1
0
static void gfs_skew_symmetric_momentum (GfsSimulation * sim, FaceData * fd, GfsVariable **gmac)
{
  GfsDomain * domain = GFS_DOMAIN (sim);
  FttComponent c;
  FttDirection d;
  /* it is used for implementation of viscosity (improve?) */
  GfsSourceDiffusion * dif = source_diffusion_viscosity (fd->u[0]);

  gfs_domain_cell_traverse (domain,
			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			    (FttCellTraverseFunc) advance_face_values, fd);
  
  /* boundary conditions */
  for (d = 0; d <  FTT_NEIGHBORS; d++)
    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, fd->velfaces[d]);

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

  if (dif) { 
    DataDif dd = { dif , sim->physical_params.alpha, fd };
    gfs_domain_cell_traverse (domain, 
			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
			      (FttCellTraverseFunc) diffusion_term, &dd); 
  }

  /* regularize flux at faces */
  for (c = 0; c <  FTT_DIMENSION; c++)
    gfs_domain_face_bc (domain, c, fd->u[c]);

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

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

  gfs_velocity_face_sources (domain, fd->u, (*fd->dt), sim->physical_params.alpha, gmac);

  gfs_domain_cell_traverse (domain, 
                            FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, 
                            (FttCellTraverseFunc) correct_face_velocity, NULL);
}
Пример #2
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);
}                               
Пример #3
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);
}