Exemple #1
0
static void get_face_values (FttCell * cell, FaceData * fd)
{
  GfsStateVector * s = GFS_STATE (cell);

  FttDirection d;
  for (d = 0; d < FTT_NEIGHBORS; d++) {
    FttComponent c = d/2;
    s->f[d].un = GFS_VALUE (cell, fd->u[c])/2.;
    if (ftt_cell_neighbor (cell, d))
      s->f[d].un += GFS_VALUE (ftt_cell_neighbor (cell, d), fd->u[c])/2.;
    else
      s->f[d].un  = 0;
  }
}
Exemple #2
0
static void face_coeff_from_below_por (FttCell * cell)
{
  FttDirection d;
  GfsFaceStateVector * f = GFS_STATE (cell)->f;
  guint neighbors = 0;

  for (d = 0; d < FTT_NEIGHBORS; d++) {
    FttCellChildren child;
    guint i, n;

    f[d].v = 0.;
    n = ftt_cell_children_direction (cell, d, &child);
    for (i = 0; i < n; i++)
      if (child.c[i])
        f[d].v += GFS_STATE (child.c[i])->f[d].v;
    f[d].v /= n;
    /* fixme: this stuff may not be necessary anymore? The 'dumbell'
       test case seems to work fine without this */
    FttCell * neighbor;
    if (f[d].v != 0. &&
        (neighbor = ftt_cell_neighbor (cell, d)) && !GFS_CELL_IS_BOUNDARY (neighbor))
      neighbors++;
  }

  if (neighbors == 1)
    for (d = 0; d < FTT_NEIGHBORS; d++)
      f[d].v = 0.;
}
Exemple #3
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;
}
Exemple #4
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.;
}
Exemple #5
0
static void traverse_face (FttCell * cell, gpointer * datum)
{
  FttDirection * d = datum[0];
  gint max_depth = *((gint *) datum[1]);
  FttFaceTraverseFunc func = (FttFaceTraverseFunc) datum[2];
  gpointer data = datum[3];
  gboolean check = *((gboolean *) datum[4]);
  gboolean boundary_faces = *((gboolean *) datum[5]);  
  FttCellFace face;
  
  face.d = *d;
  face.cell = cell;
  face.neighbor = ftt_cell_neighbor (cell, face.d);
  if (face.neighbor) {
    if (!check || (face.neighbor->flags & FTT_FLAG_TRAVERSED) == 0) {
      if (FTT_CELL_IS_LEAF (cell) && 
	  !FTT_CELL_IS_LEAF (face.neighbor) && 
	  (max_depth < 0 || ftt_cell_level (face.neighbor) < max_depth)) {
	/* coarse -> fine */
	FttCellChildren children;
	guint i, n;
	
	face.d = FTT_OPPOSITE_DIRECTION (face.d);
	n = ftt_cell_children_direction (face.neighbor, face.d, &children);
	face.neighbor = face.cell;
	for (i = 0; i < n; i++)
	  if ((face.cell = children.c[i]) && 
	      (!check || (face.cell->flags & FTT_FLAG_TRAVERSED) == 0))
	    (* func) (&face, data);
      }
      else
	(* func) (&face, data);
    }
  }
  else if (boundary_faces)
    (* func) (&face, data);
}
Exemple #6
0
static void obtain_face_fluxes (const FttCell * cell)
{                               
  FttCellChildren child;
  GfsStateVector * s = GFS_STATE (cell);

  FttDirection d;
  for (d = 0; d < FTT_NEIGHBORS; d++) {
    FttCell * neighbor = ftt_cell_neighbor (cell, d);
    if (neighbor) {
      if (!FTT_CELL_IS_LEAF (neighbor)) {
        gint i, n = ftt_cell_children_direction (neighbor, FTT_OPPOSITE_DIRECTION(d), &child);
        s->f[d].v = 0;
        for (i = 0; i < n; i++)
          if (child.c[i])  
            s->f[d].v += GFS_STATE (child.c[i])->f[FTT_OPPOSITE_DIRECTION(d)].v;
        s->f[d].v /= n;
      }
      else if ((d % 2) > 0 && ftt_cell_level(cell) == ftt_cell_level(neighbor))
        s->f[d].v = GFS_STATE (neighbor)->f[FTT_OPPOSITE_DIRECTION(d)].v;
    }
    else
      s->f[d].v = 0;
  }
}
Exemple #7
0
/* d2: cell direction with respect to cellref */
static gdouble interpolate_value_skew (FttCell * cellref,
				       FttDirection d, 
				       FttDirection * d2, 
				       FaceData * fd)
{
  FttCell * cell;
  FttComponent c = d/2;
  if (d2)
    cell = ftt_cell_neighbor (cellref, *d2);
  else
    cell = cellref;

  if (!cell) {
    /* Symmetric BC */
    if ( d == (*d2) ) 
      return -GFS_VALUE (cellref,fd->velfaces[FTT_OPPOSITE_DIRECTION(d)]);
    else
      return GFS_VALUE (cellref,fd->velfaces[d]);
  } 

  if (!FTT_CELL_IS_LEAF (cell)) { 
    FttDirection corner[FTT_DIMENSION];
    FttCell * cell2;
    gdouble val;
#if FTT_2D
    if ( d == (*d2) ) {
      FttComponent c1 = FTT_ORTHOGONAL_COMPONENT (c);
      corner[0]=2*c1;
      corner[1]=FTT_OPPOSITE_DIRECTION(*d2);
      cell2 = ftt_cell_child_corner(cell, corner);  
      val = GFS_VALUE (cell2,fd->velfaces[d]);
      corner[0]=2*c1+1;
      cell2 = ftt_cell_child_corner(cell, corner);
      return ( val + GFS_VALUE (cell2,fd->velfaces[d]) ) / 2. ;
    }   
    else {
      corner[0]=d;
      corner[1]=FTT_OPPOSITE_DIRECTION(*d2);
      cell2 = ftt_cell_child_corner(cell, corner);
      return GFS_VALUE (cell2,fd->velfaces[d]);
    }
#else
  static FttComponent orthogonal[FTT_DIMENSION][2] = {
    {FTT_Y, FTT_Z}, {FTT_X, FTT_Z}, {FTT_X, FTT_Y}
  };
    val = 0.;
    gint i,j;
    if ( d == (*d2) ) {
      FttVector pc;
      ftt_cell_pos (cell, &pc);
      corner[0]=FTT_OPPOSITE_DIRECTION(*d2);
      for ( i = 0; i < 2; i++ ) {
        for ( j = 0; i < 2; i++ ) {
          corner[1]=2*orthogonal[c][0]+i;     
          corner[2]=2*orthogonal[c][1]+j;     
          cell2 = ftt_cell_child_corner(cell, corner);
          val += GFS_VALUE (cell2,fd->velfaces[d]);
        }
      }
      return val / 4.;
    }
    else {
      corner[0]=FTT_OPPOSITE_DIRECTION(*d2);
      corner[1]=d;
      FttComponent c2 = (*d2) / 2;
      if ( c != orthogonal[c2][0] )
        c2 = orthogonal[c2][0];
      else
        c2 = orthogonal[c2][1];
      for ( i = 0; i < 2; i++ ) {
        corner[2]=2*c2+i;
        cell2 = ftt_cell_child_corner(cell, corner);
        val += GFS_VALUE (cell2,fd->velfaces[d]);
      }
      return val / 2.;
    }
#endif 
  }
  else {
    if ( ftt_cell_level(cell) == ftt_cell_level(cellref) || d == (*d2) )
      return GFS_VALUE (cell,fd->velfaces[d]);
    else {
      FttVector pos_next, pos_ref;
      ftt_cell_pos (cellref, &pos_ref);
      ftt_cell_pos (cell, &pos_next);
      if ( ( (&(pos_ref.x))[c] < (&(pos_next.x))[c] && (d % 2) != 0 ) || 
           ( (&(pos_ref.x))[c] > (&(pos_next.x))[c] && (d % 2) == 0 )  )
        return GFS_VALUE (cell,fd->velfaces[d]);
      else 
        return ( GFS_VALUE (cell,fd->velfaces[d]) + GFS_VALUE (cell,fd->velfaces[FTT_OPPOSITE_DIRECTION(d)]) ) / 2;
    }
  }
}