예제 #1
0
파일: wave.c 프로젝트: Exteris/Gerris
static void gse_alleviation_diffusion (GfsDomain * domain, GfsVariable * F,
				       FttVector * cg, gdouble dt)
{
  gfs_domain_timer_start (domain, "gse_alleviation");

  gdouble ncg = sqrt (cg->x*cg->x + cg->y*cg->y);
  gdouble dcg = (GFS_WAVE_GAMMA - 1./GFS_WAVE_GAMMA)*ncg/2.;
  gdouble dtheta = 2.*M_PI/GFS_WAVE (domain)->ntheta;
#if 0
  gdouble Ts = 4.*GFS_WAVE (domain)->alpha_s*GFS_WAVE (domain)->alpha_s*dt;
  gdouble dtDss = dt*dcg*dcg*Ts/12.;
  gdouble dtDnn = dt*(ncg*dtheta)*(ncg*dtheta)*Ts/12.;
#else
  gdouble alpha = GFS_WAVE (domain)->alpha_s*dcg*dt;
  gdouble beta = GFS_WAVE (domain)->alpha_s*ncg*dtheta*dt;
  gdouble dtDss = alpha*alpha/3.;
  gdouble dtDnn = beta*beta/3.;
#endif
  GSEData p;
  gdouble cost = cg->x/ncg, sint = cg->y/ncg;
  p.D[0][0] = dtDss*cost*cost + dtDnn*sint*sint;
  p.D[1][1] = dtDss*sint*sint + dtDnn*cost*cost;
  p.D[0][1] = p.D[1][0] = (dtDss - dtDnn)*cost*sint;
  p.F = F;
  p.Fn = gfs_temporary_variable (domain);
  p.dF = gfs_temporary_variable (domain);
  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) copy_F, &p);
  gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
			    (FttCellTraverseFunc) p.Fn->fine_coarse, p.Fn);
  for (p.dF->component = 0; p.dF->component < 2; p.dF->component++) {
    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
			      (FttCellTraverseFunc) compute_gradient, &p);
    gfs_domain_bc (domain, FTT_TRAVERSE_ALL, -1, p.dF);
    gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) diffusion, &p);
  }
  gts_object_destroy (GTS_OBJECT (p.Fn));
  gts_object_destroy (GTS_OBJECT (p.dF));
  gfs_domain_timer_stop (domain, "gse_alleviation");
}
예제 #2
0
파일: porous.c 프로젝트: suhasjains/Gerris
static void gfs_source_darcy_read (GtsObject ** o, GtsFile * fp)
{
    (* GTS_OBJECT_CLASS (gfs_source_darcy_class ())->parent_class->read) (o, fp);
  if (fp->type == GTS_ERROR)
    return;
  
  printf("\ntesting1\n");
  /*Check if source darcy has already been added or not*/
  FttComponent c;
  for (c = 0; c < FTT_DIMENSION; c++) {
    GfsVariable * v = GFS_SOURCE_VELOCITY (*o)->v[c];

    if (v->sources) {
      GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
      
      while (i) {
	if (i->data != *o && GFS_IS_SOURCE_DARCY (i->data)) {
	  gts_file_error (fp, "variable '%s' cannot have multiple Darcy source terms", v->name);
	  return;
	}
	i = i->next;
      }
    }
  }

  printf("\ntesting2\n");
  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
  GfsSourceDarcy * s = GFS_SOURCE_DARCY (*o);
  printf("\ntesting3\n");
  s->darcycoeff = gfs_function_new (gfs_function_class (), 0.);
  gfs_function_read (s->darcycoeff, gfs_object_simulation (s), fp);
  printf("\ntesting4\n");
  
  if (fp->type != '\n') {
    s->forchhicoeff = gfs_function_new (gfs_function_class (), 0.);
    gfs_function_read (s->forchhicoeff, gfs_object_simulation (s), fp);
  }

  if (s->beta < 1.)
    for (c = 0; c <  FTT_DIMENSION; c++)
      s->u[c] = gfs_temporary_variable (domain);
  else {
    GFS_SOURCE_GENERIC (s)->centered_value = NULL;
    GFS_SOURCE_GENERIC (s)->mac_value = NULL;
  }
  printf("\ntesting5\n");
}
예제 #3
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));
}
예제 #4
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]));

}
예제 #5
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]));
  }
}
예제 #6
0
파일: porous.c 프로젝트: suhasjains/Gerris
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);
}