Пример #1
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;
    }
}
Пример #2
0
static void poisson_mixed_coeff_por (FttCell * cell, PoissonCoeff_por * p)
{
  if (GFS_IS_MIXED (cell)) {
    gdouble alpha = p->alpha ? (gfs_function_value (p->alpha, cell)*gfs_function_value (p->phi , cell)) : gfs_function_value (p->phi, cell);
    if (((cell)->flags & GFS_FLAG_DIRICHLET) == 0)
      /* Neumann condition (prescribed flux) */
      GFS_STATE (cell)->solid->v.x += alpha;
    else {
      /* Dirichlet */
      GfsSolidVector * s = GFS_STATE (cell)->solid;
      FttVector m = {1.,1.,1.};
      gfs_domain_solid_metric (p->domain, cell, &m);
      FttComponent c;
      for (c = 0; c < FTT_DIMENSION; c++)
        (&s->v.x)[c] += alpha*(&m.x)[c]*(s->s[2*c + 1] - s->s[2*c]);
    }

    if (alpha <= 0. && p->positive) {
      FttVector p;
      ftt_cell_pos (cell, &p);
      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
             "alpha is negative (%g) at cell (%g,%g,%g).\n"
             "Please check your definition.",
             alpha, p.x, p.y, p.z);
    }
  }
}
Пример #3
0
static gdouble cell_height (FttCell * cell, 
			    FttCellFace * face, 
			    GfsSimulation * sim,
			    GfsRefineSurface * refine)
{
  FttVector pos;
  ftt_cell_pos (cell, &pos);
  return interpolated_value (GFS_SURFACE (refine->surface)->s, &pos);
}
Пример #4
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.;
}
Пример #5
0
static void redistribute_old_face_in_merged (FttCell * cell, 
					     FttCell * merged, FttDirection d, 
					     GfsVariable * old_solid_v)
{  
  gint i;
  gdouble sc, sm;
  
  g_assert (cell != NULL);
  g_assert (merged != NULL);

  sc = ftt_cell_volume(cell);
  sm = ftt_cell_volume(merged);
  
  if (sc != sm)
    printf("Face redistribution not implemented yet for adaptive grid \n");
  g_assert (sc == sm);
  
  for (i = 0; i < FTT_DIMENSION;i++)
    if (i != d/2) {
      FttCellNeighbors neighbors;
      FttVector pos;
      
      ftt_cell_pos(cell,&pos);
      ftt_cell_neighbors (merged,&neighbors);

      GfsSolidVector * old_solid_merged = OLD_SOLID (merged);
      if (!old_solid_merged) {
	FttDirection c;
	OLD_SOLID (merged) = old_solid_merged = g_malloc0 (sizeof (GfsSolidVector));
	old_solid_merged->a = 1.;
	for (c = 0; c < FTT_NEIGHBORS; c++)
	  old_solid_merged->s[c] = 1.;
      }
          
      old_solid_merged->s[2*i] += OLD_SOLID (cell)->s[2*i];

      if (neighbors.c[2*i]) {
	GfsSolidVector * old_solid = OLD_SOLID (neighbors.c[2*i]);
	if (!old_solid) {
	  FttDirection c;
	  OLD_SOLID (neighbors.c[2*i]) = old_solid = g_malloc0 (sizeof (GfsSolidVector));
	  old_solid->a = 1.;
	  for (c = 0; c < FTT_NEIGHBORS; c++)
	    old_solid->s[c] = 1.;
	}
	old_solid->s[ftt_opposite_direction[2*i]] += OLD_SOLID (cell)->s[2*i];
      }
      
      old_solid_merged->s[2*i+1] += OLD_SOLID (cell)->s[2*i+1];
      
      if (neighbors.c[2*i+1]) {
	GfsSolidVector * old_solid = OLD_SOLID (neighbors.c[2*i+1]);
	if (!old_solid) {
	  FttDirection c;
	  OLD_SOLID (neighbors.c[2*i+1]) = old_solid = g_malloc0 (sizeof (GfsSolidVector));
	  old_solid->a = 1.;
	  for (c = 0; c < FTT_NEIGHBORS; c++)
	    old_solid->s[c] = 1.;
	}
	old_solid->s[ftt_opposite_direction[2*i+1]] += OLD_SOLID (cell)->s[2*i+1];	
      }
    }
}
Пример #6
0
static int cell_is_corner (FttCell * cell)
{
  FttDirection d, d1, d2;
  gdouble  norm;
  FttCellNeighbors neighbors;
  FttVector n1, n2;


  g_assert (cell);

  ftt_cell_neighbors (cell,&neighbors);

  d1 = d2 = -1;

  if (!GFS_IS_MIXED(cell))
    return 0;

  for (d = 0; d < FTT_NEIGHBORS; d ++)
    if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0. && d1 == -1 && d2 == -1)
      d1 = d;
    else if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0 && d2 == -1)
      d2 = d;
    else if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0.)
      g_assert_not_reached ();

  if ( d1 == -1 || d2 == -1) {
    FttVector pos;
    ftt_cell_pos (cell,&pos);
    
    g_warning ("REA: %f, %f \n", pos.x, pos.y);
    g_warning ("d1: %i d2: %i  \n", d1,d2);
    
    g_assert_not_reached ();
  }

 


  gfs_solid_normal (neighbors.c[d1], &n1);
  norm = sqrt (n1.x*n1.x + n1.y*n1.y);
  if (norm != 0.) {
    n1.x /= norm;
    n1.y /= norm;
  }
  gfs_solid_normal (neighbors.c[d2], &n2);
  norm = sqrt (n2.x*n2.x + n2.y*n2.y);
  if (norm != 0.) {
    n2.x /= norm;
    n2.y /= norm;
  }

  if (d1/2 == d2/2)
    return 0;
  else {
    if (neighbors.c[d2])
      if ( neighbors.c[d1])
	if (GFS_IS_MIXED (neighbors.c[d2]) && GFS_IS_MIXED (neighbors.c[d1]))
	  if (fabs(n1.x*n2.x+n1.y*n2.y) < 0.70) {
	    if (GFS_STATE(neighbors.c[d1])->solid->s[d1] > 0 && GFS_STATE(neighbors.c[d1])->solid->s[d1] < 1)
	      return 1;
	    if (GFS_STATE(neighbors.c[d2])->solid->s[d2] > 0 && GFS_STATE(neighbors.c[d2])->solid->s[d2] < 1)
	      return 1;
	  }
    return 0;
  }
}
Пример #7
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
	}
    }
}
Пример #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;
    }
  }
}