Beispiel #1
0
static void poisson_coeff_por (FttCellFace * face,
                           PoissonCoeff_por * p)
{
  gdouble alpha = p->alpha ? (gfs_function_face_value (p->alpha, face)*gfs_function_face_value (p->phi, face)) : gfs_function_face_value (p->phi, face);
  gdouble v = p->lambda2[face->d/2]*alpha*gfs_domain_face_fraction (p->domain, face)/
    gfs_domain_face_scale_metric (p->domain, face, face->d/2);

  if (alpha <= 0. && p->positive) {
    FttVector p;
    ftt_face_pos (face, &p);
    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
           "alpha is negative (%g) at face (%g,%g,%g).\n"
           "Please check your definition.",
           alpha, p.x, p.y, p.z);
  }
  GFS_STATE (face->cell)->f[face->d].v += v;

  switch (ftt_face_type (face)) {
  case FTT_FINE_FINE:
    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v += v;
    break;
  case FTT_FINE_COARSE:
    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v +=
      v/FTT_CELLS_DIRECTION (face->d);
    break;
  default:
    g_assert_not_reached ();
  }
}
Beispiel #2
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.;
}
Beispiel #3
0
static void correct_face_velocity (FttCell * cell)
{                               
  FttDirection d;
  for (d = 0; d < FTT_NEIGHBORS; d++) {
    FttCellFace face = gfs_cell_face(cell, d);
    if (GFS_FACE_FRACTION_RIGHT (&face) != 0. && face.neighbor) {

    switch (ftt_face_type (&face)) {
      case FTT_FINE_FINE:
        GFS_STATE (face.neighbor)->f[FTT_OPPOSITE_DIRECTION(face.d)].un = GFS_STATE (cell)->f[face.d].un;
        break;
      case FTT_FINE_COARSE:
        GFS_STATE (cell)->f[face.d].un = GFS_STATE (face.neighbor)->f[FTT_OPPOSITE_DIRECTION(face.d)].un;
        break;
      default:
        g_assert_not_reached ();
    }
    }
  }
}
Beispiel #4
0
static void advection_term (FttCell * cell, FaceData * fd)
{
  gdouble un, unext, unprev;

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

  GfsStateVector * s = GFS_STATE (cell);
  FttComponent c = d0/2;
  FttDirection d;
  gboolean cond;

  un = GFS_VALUE (cell,fd->velfaces[d0]);
  if ((d0 % 2 ) != 0 ) {
    cond = TRUE;
    d = FTT_OPPOSITE_DIRECTION (d0);
    unext     = interpolate_value_skew (cell, d,    NULL , fd);
    unprev    = interpolate_value_skew (cell, d0, &d0, fd); 
  }
  else { 
    cond = FALSE;
    d = d0;
    unext     = interpolate_value_skew (cell, d, &d, fd);
    unprev    = interpolate_value_skew (cell, FTT_OPPOSITE_DIRECTION(d), NULL, fd);
  }

  s->f[d0].v = ((un + unext)*unext - (un + unprev)*unprev) / 4.;
#if FTT_2D
  s->f[d0].v += transverse_advection (cell, 
				      FTT_ORTHOGONAL_COMPONENT (c), d, un, fd, cond);
#else  /* FTT_3D */
  static FttComponent orthogonal[FTT_DIMENSION][2] = {
    {FTT_Y, FTT_Z}, {FTT_X, FTT_Z}, {FTT_X, FTT_Y}
  };
  s->f[d0].v += transverse_advection (cell, orthogonal[c][0], d, un, fd, cond);
  s->f[d0].v += transverse_advection (cell, orthogonal[c][1], d, un, fd, cond); 
#endif
  }
}
Beispiel #5
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;
  }
}
Beispiel #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;
  }
}
Beispiel #7
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);
}
Beispiel #8
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;
    }
  }
}