Ejemplo n.º 1
0
static gdouble get_size_next ( FttCell * cell, FttDirection d )
{
  FttCell * cellnext = ftt_cell_neighbor (cell, d);
  if (!cellnext) return ftt_cell_size (cell);
  gdouble size;

  if (!FTT_CELL_IS_LEAF (cellnext))
    size = ftt_cell_size (cell) / 2.;
  else 
    size = ftt_cell_size (cellnext);

  return size;
}
Ejemplo n.º 2
0
static void diffusion_term (FttCell * cell, DataDif * data)
{
  /* fixme: I need to account for the metric */
  gdouble size, sizenext, size_ratio;
  gdouble un, unext, unprev;

  FttDirection d0;
  for (d0 = 0; d0 < FTT_NEIGHBORS; d0++) {

  FttCellFace face = gfs_cell_face(cell, d0);
  gdouble flux = 0.;  
  gdouble invdens = data->alpha ? gfs_function_face_value (data->alpha, &face) : 1.;
  gdouble visc = gfs_diffusion_cell (data->d->D, cell);

  GfsStateVector * s = GFS_STATE (cell);

  FttDirection od = FTT_OPPOSITE_DIRECTION(d0);

  un = interpolate_value_skew (cell, d0, NULL, data->fd);

  if ((d0 % 2) != 0) {
    unext    = interpolate_value_skew (cell, od , NULL, data->fd);
    unprev   = interpolate_value_skew (cell, d0 , &(d0) , data->fd); 
    sizenext = ftt_cell_size (cell); 
    size     = get_size_next (cell, d0);
  }
  else {
    unext    = interpolate_value_skew (cell, d0, &(d0), data->fd);
    unprev   = interpolate_value_skew (cell, od,      NULL,    data->fd);
    size     = ftt_cell_size (cell); 
    sizenext = get_size_next (cell, d0);
  } 
  size_ratio = ( 1. + sizenext / size ) / 2;
  flux = ( (unext - un)/sizenext - (un - unprev)/size );

  FttComponent c = d0/2;
#if FTT_2D
  FttComponent oc = FTT_ORTHOGONAL_COMPONENT (c);
  flux += size_ratio * transverse_diffusion(cell, oc, d0, un, data->fd);
#else
  static FttComponent orthogonal[FTT_DIMENSION][2] = {
    {FTT_Y, FTT_Z}, {FTT_X, FTT_Z}, {FTT_X, FTT_Y}
  };
  flux += size_ratio * transverse_diffusion(cell, orthogonal[c][0], d0, un, data->fd);
  flux += size_ratio * transverse_diffusion(cell, orthogonal[c][1], d0, un, data->fd);
#endif 

  s->f[d0].v -= invdens*visc*flux;
  }
}
Ejemplo n.º 3
0
/* see gfs_face_velocity_advection_flux() for the initial implementation with static boundaries */
static void moving_face_velocity_advection_flux (const FttCellFace * face,
						 const GfsAdvectionParams * par)
{
  gdouble flux;
  FttComponent c = par->v->component;

  g_return_if_fail (c >= 0 && c < FTT_DIMENSION);

  /* fixme: what's up with face mapping? */
  flux = face_fraction_half (face, par)*GFS_FACE_NORMAL_VELOCITY (face)*
    par->dt/ftt_cell_size (face->cell);
#if 0
  if (c == face->d/2) /* normal component */
    flux *= GFS_FACE_NORMAL_VELOCITY (face);
  else /* tangential component */
#else
    flux *= gfs_face_upwinded_value (face, par->upwinding, par->u)
      /* pressure correction */
      - gfs_face_interpolated_value (face, par->g[c]->i)*par->dt/2.;
#endif
  if (!FTT_FACE_DIRECT (face))
    flux = - flux;
  GFS_VALUE (face->cell, par->fv) -= flux;

  switch (ftt_face_type (face)) {
  case FTT_FINE_FINE:
    GFS_VALUE (face->neighbor, par->fv) += flux;
    break;
  case FTT_FINE_COARSE:
    GFS_VALUE (face->neighbor, par->fv) += flux/FTT_CELLS;
    break;
  default:
    g_assert_not_reached ();
  }
}
Ejemplo n.º 4
0
static void ftt_bbox(FttCell *cell, gpointer data)
{
  FttVector p;
  ftt_cell_pos(cell,&p);

  double size = ftt_cell_size(cell)/2.0;

  bbox_t bb, *pbb = *(bbox_t**)data; 

  bb.x.min = p.x - size;
  bb.x.max = p.x + size;
  bb.y.min = p.y - size;
  bb.y.max = p.y + size;

  if (pbb)
    {
      bbox_t bbx = bbox_join(bb,*pbb);

      *pbb = bbx;
    }
  else
    {
      pbb = malloc(sizeof(bbox_t));

      *pbb  = bb;
      *(bbox_t**)data = pbb;
    }
}
Ejemplo n.º 5
0
static gdouble solid_curvature (FttCell * cell, FttCellFace * face, 
				GfsDomain * domain, GfsGenericSurface * s)
{
  KappaData d;
  d.kappa = gfs_solid_is_thin (cell, s) ? 1./ftt_cell_size (cell) : 0.;
  d.s = GFS_SURFACE (s)->s;
  gts_surface_foreach_vertex (d.s, (GtsFunc) max_kappa, &d);
  return d.kappa;
}
Ejemplo n.º 6
0
/* b Adaptative boolean */
static gdouble transverse_advection (FttCell * cell, 
				     FttComponent oc,
				     FttDirection d,
				     gdouble un,
				     FaceData * fd,
				     gboolean b)
{
  gdouble uauxbot, uauxtop,size_ratio;
  gdouble vn, vntop, vnbot, vndiag;
  FttDirection daux;
  FttCell * cellnext = ftt_cell_neighbor (cell, d);
  if (!cellnext) cellnext = cell;
  size_ratio = ftt_cell_size (cell);

  if (!b) {
    size_ratio = ftt_cell_size (cellnext)/size_ratio;
    if (!FTT_CELL_IS_LEAF (cellnext))
      size_ratio /= 2.;
    vn      = interpolate_value_skew (cell,2*oc,NULL,fd);
    vntop   = interpolate_value_skew (cell,2*oc,&d  ,fd);
    vndiag  = interpolate_value_skew (cell,2*oc+1,&d ,fd);
    vnbot   = interpolate_value_skew (cell,2*oc+1,NULL,fd);
    daux    = 2*oc;
    uauxtop = interpolate_value_skew (cell, d, &daux, fd);
    daux    = 2*oc+1;
    uauxbot = interpolate_value_skew (cell, d, &daux, fd);
  } else {
    size_ratio = size_ratio/ftt_cell_size (cellnext);
    if (!FTT_CELL_IS_LEAF (cellnext))
      size_ratio *= 2.;
    daux    = FTT_OPPOSITE_DIRECTION(d);
    vn      = interpolate_value_skew (cell,2*oc,&daux, fd);
    vntop   = interpolate_value_skew (cell,2*oc,&daux, fd);
    vndiag  = interpolate_value_skew (cell,2*oc+1,NULL,fd);
    vnbot   = interpolate_value_skew (cell,2*oc,&daux ,fd);
    daux    = 2*oc;
    uauxtop = interpolate_value_skew (cell, FTT_OPPOSITE_DIRECTION(d), &daux, fd);
    daux    = 2*oc+1;
    uauxbot = interpolate_value_skew (cell, FTT_OPPOSITE_DIRECTION(d), &daux, fd);
  }

  return (uauxtop*(vn + vntop*size_ratio) - uauxbot*(vnbot + vndiag*size_ratio)) / 4.;
}
Ejemplo n.º 7
0
static void solid_flux (FttCell * cell, SolidFluxParams * par)
{
  gfs_normal_divergence (cell, par->div);
  if (GFS_VALUE (cell, par->div) < 0.) {
    gdouble h = ftt_cell_size (cell);
    GFS_VALUE (cell, par->fv) = GFS_VALUE (cell, par->div)*par->p->dt*
      GFS_VALUE (cell, par->p->v)/(h*h);
  }
  else
    GFS_VALUE (cell, par->fv) = 0.;
}
Ejemplo n.º 8
0
static gdouble cell_distance (FttCell * cell, 
			      FttCellFace * face, 
			      GfsSimulation * sim,
			      GfsRefineDistance * refine)
{
  FttVector pos;
  gdouble h = GFS_DIAGONAL*ftt_cell_size (cell), d;
  GtsPoint p;

  ftt_cell_pos (cell, &pos);
  p.x = pos.x; p.y = pos.y; p.z = pos.z;
  d = gts_bb_tree_point_distance (refine->stree, &p,
				  (GtsBBoxDistFunc) gts_point_triangle_distance, NULL);
  return d > h ? d - h : 0.;
}
Ejemplo n.º 9
0
static void diffusion (FttCell * cell, GSEData * p)
{
  gdouble h2 = ftt_cell_size (cell);
  h2 *= h2;
  /* off-diagonal */
  FttComponent j;
  for (j = 0; j < 2; j++)
    if (j != p->dF->component)
      GFS_VALUE (cell, p->F) += 
	p->D[j][p->dF->component]*gfs_center_regular_gradient (cell, j, p->dF)/h2;
  /* diagonal */
  GFS_VALUE (cell, p->F) += 
    p->D[p->dF->component][p->dF->component]*
    gfs_center_regular_2nd_derivative (cell, p->dF->component, p->Fn)/h2;
}
Ejemplo n.º 10
0
static void update_vel (FttCell * cell, FaceData * fd)
{
  GfsStateVector * s = GFS_STATE (cell);
  gdouble size;

  FttDirection d;
  for (d = 0; d < FTT_NEIGHBORS; d++) {
    size = ( ftt_cell_size (cell) + get_size_next (cell, d) ) / 2;
    GFS_VALUE (cell, fd->velfaces[d]) = (GFS_VALUE (cell, fd->velfaces[d]) + 
					 fd->beta*GFS_VALUE (cell, fd->velold[d]))/(1.+fd->beta); 
    s->f[d].un = (2*fd->beta*GFS_VALUE (cell, fd->velfaces[d]) + 
		  (0.5-fd->beta)*GFS_VALUE (cell, fd->velold[d]) - 
		  s->f[d].v*(*fd->dt)/size)/(0.5+fd->beta);
    GFS_VALUE (cell, fd->velold[d]) = GFS_VALUE (cell, fd->velfaces[d]);
    s->f[d].v = s->f[d].un;
  }
}
Ejemplo n.º 11
0
static gdouble transverse_diffusion (FttCell * cell, 
				     FttComponent oc,
				     FttDirection d,
				     gdouble un,
				     FaceData * fd)
{
  gdouble uaux, size, flux = 0;
  gint i;  

  for ( i = 0; i < 2; i++ ) {
    FttDirection daux = 2*oc + i;
    uaux = interpolate_value_skew (cell, d, &daux, fd);
    size = ( ftt_cell_size (cell) + get_size_next (cell, daux) ) / 2;
    flux += (uaux - un) / size;
  }

  return flux;
}
Ejemplo n.º 12
0
/* see gfs_face_advection_flux() for the initial implementation with static boundaries */
static void moving_face_advection_flux (const FttCellFace * face,
					const GfsAdvectionParams * par)
{
  gdouble flux;
  
  /* fixme: what's up with face mapping? */
  flux = face_fraction_half (face, par)*GFS_FACE_NORMAL_VELOCITY (face)*par->dt*
    gfs_face_upwinded_value (face, GFS_FACE_UPWINDING, NULL)/ftt_cell_size (face->cell);
  if (!FTT_FACE_DIRECT (face))
    flux = - flux;
  GFS_VALUE (face->cell, par->fv) -= flux;

  switch (ftt_face_type (face)) {
  case FTT_FINE_FINE:
    GFS_VALUE (face->neighbor, par->fv) += flux;
    break;
  case FTT_FINE_COARSE:
    GFS_VALUE (face->neighbor, par->fv) += flux/FTT_CELLS;
    break;
  default:
    g_assert_not_reached ();
  }
}
Ejemplo n.º 13
0
static void ftt_sample(FttCell *cell, gpointer data)
{
  ftts_t ftts = *((ftts_t*)data);
  int level   = ftt_cell_level(cell);
  double size = ftt_cell_size(cell);
  bbox_t bb   = bilinear_bbox(ftts.B[0]);

  FttVector p;
  ftt_cell_pos(cell,&p);

  /* the number in each directon we will sample */

  int n = POW2(ftts.depth-level);
  
  /* cell coordinates at this level */

  int ic = (p.x - bb.x.min)/size;
  int jc = (p.y - bb.y.min)/size;

  /* subgrid extent */

  double xmin = p.x - size/2.0;
  double ymin = p.y - size/2.0;
  double d = size/n;

#ifdef FFTS_DEBUG
  printf("%f %f (%i %i %i %i)\n",p.x,p.y,level,n,ic,jc);
#endif 

  int i,j;

  for (i=0 ; i<n ; i++)
    {
      double x = xmin + (i+0.5)*d;
      int ig = ic*n + i;

      for (j=0 ; j<n ; j++)
	{
	  double y = ymin + (j+0.5)*d;
	  int jg = jc*n + j;

	  /* 
	     ig, jg are the global indicies, so give a sample
	     point for the bilinear struct. Note that (x,y) and
	     (x0,y0) shoule be the same, else the bilinear and
	     octree grids are not aligned.
	  */

#ifdef FFTS_DEBUG
	  double x0, y0;
	  bilinear_getxy(ig, jg, ftts.B[0], &x0, &y0);
#endif

	  FttVector p;

	  p.x = x;
	  p.y = y;

	  double 
	    u = gfs_interpolate(cell,p,ftts.u),
	    v = gfs_interpolate(cell,p,ftts.v);

	  bilinear_setz(ig,jg,u,ftts.B[0]);
	  bilinear_setz(ig,jg,v,ftts.B[1]);

#ifdef FFTS_DEBUG
	  printf("  (%f %f) (%f %f) (%i %i) %f %f (%f %f)\n",
		 x, y, x0, y0, ig, jg, u, v, x-x0, y-y0);
#endif
	}
    }
}