Esempio n. 1
0
static double new_solid_old_solid (FttCell * cell, FttDirection d1,
				   GfsVariable * old_solid,
				   GfsVariable ** sold2)
{
  FttDirection d;
  FttCellNeighbors neighbors;
  double s1, s2;

  g_assert(cell);

  s1 = GFS_STATE (cell)->solid->s[d1];
  ftt_cell_neighbors (cell,&neighbors);
  for  (d = 0; d < 2*FTT_DIMENSION;d++)
    if (d != 2*(d1/2) && d != 2*(d1/2)+1)
      if (neighbors.c[d] &&
	  !cell_is_corner(neighbors.c[d]) && 
	  !cell_was_corner(neighbors.c[d], old_solid, sold2)) {
	if ((GFS_IS_MIXED(neighbors.c[d]) && GFS_STATE(neighbors.c[d])->solid->s[d1] == 1.) ||
	    !GFS_IS_MIXED(neighbors.c[d])) {
	  if (SOLD2 (neighbors.c[d], d1) != 1.){
	    s2 = 1.-SOLD2 (neighbors.c[d], d1);
	    return s1/(s1+s2);
	  }
	}
	else if ((GFS_STATE(cell)->solid->s[d1] == 0. && GFS_IS_MIXED(neighbors.c[d])) ) {
	  s1 = SOLD2 (cell, d1);
	  s2 = 1.-GFS_STATE(neighbors.c[d])->solid->s[d1];
	  return s2/(s1+s2);
	}
      }
  return -1.;
}
Esempio n. 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);
    }
  }
}
Esempio n. 3
0
static void reset_coeff_por (FttCell * cell, PoissonCoeff_por * p)
{
  FttDirection d;
  GfsFaceStateVector * f = GFS_STATE (cell)->f;
  if (GFS_IS_MIXED (cell)) {
    FttVector v = {0.,0.,0.};
    GFS_STATE (cell)->solid->v = v;
  }
  for (d = 0; d < FTT_NEIGHBORS; d++)
    f[d].v = 0.;
}
Esempio n. 4
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;
  }
}
Esempio n. 5
0
static void second_order_face_fractions (FttCell * cell, GfsSimulationMoving * sim)
{
#ifndef FTT_2D /* 3D */
  g_assert_not_implemented ();
#endif

  GfsVariable * old_solid_v = sim->old_solid;
  GfsVariable ** sold2 = sim->sold2;
  gdouble dt1, dt2, dto1, dto2, s1, s2;
  gint d1, d2, d, do1, do2;
  FttCellNeighbors neighbors;

  dt1 = dt2 = dto1 = dto2 = -2;
  d1 = d2 = do1 = do2 = -1;
  s1 = s2 = -1;

  g_assert(cell);
      
  ftt_cell_neighbors (cell,&neighbors);

  if (!OLD_SOLID (cell) && !GFS_IS_MIXED(cell))
    return;

  if (!OLD_SOLID (cell)) {
    FttDirection c;
    OLD_SOLID (cell) = g_malloc0 (sizeof (GfsSolidVector));

    OLD_SOLID (cell)->a = 1.;
    for (c = 0; c < FTT_NEIGHBORS; c++)
      OLD_SOLID (cell)->s[c] = 1.;
  }

  /* Find directions of intersection */
  if (GFS_IS_MIXED(cell))
    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 (); 
    }
  
  for (d = 0; d < FTT_NEIGHBORS; d ++) {
    if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0. && do1 == -1 && do2 == -1)
      do1 = d;
    else if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0 && do2 == -1)
      do2 = d;
    else if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0.)
      g_assert_not_reached (); 
  }

  /* Treats easy cases */
  if (d1 != -1 && d1 == do1)
    OLD_SOLID (cell)->s[d1] = SOLD2 (cell, d1);
  if (d2 != -1 && d2 == do2)
    OLD_SOLID (cell)->s[d2] = SOLD2 (cell, d2);

  if (d1 == do1 && d2 == do2)
    return;
    
  /* Finds timescale for d1/do1 */
  if (d1 != -1) {
    if (SOLD2 (cell, d1) == 1.) {
      dt1 = new_solid_old_fluid (cell, d1, old_solid_v, sold2);
      if (dt1 == -1)
	if (neighbors.c[d1]){
	  FttDirection dop = ftt_opposite_direction[d1];
	  dt1 = new_solid_old_fluid (neighbors.c[d1], dop, old_solid_v, sold2);
	}
    }   
    else if (SOLD2 (cell, d1) == 0.){
      dt1 = new_solid_old_solid (cell, d1, old_solid_v, sold2);
    }  
  }
  
  if (do1 != -1 && do1 != d1 && do1 != d2) {
    if (GFS_IS_MIXED(cell) && GFS_STATE(cell)->solid->s[do1] == 0.)
      dto1 = new_solid_old_solid (cell, do1, old_solid_v, sold2);
    else
      dto1 = new_fluid_old_solid (cell, do1, old_solid_v, sold2);
  }

  /* Finds timescale for d2/do2 */

  if (d2 != -1) {
    if (SOLD2 (cell, d2) == 1.) {
      dt2 = new_solid_old_fluid (cell, d2, old_solid_v, sold2);
      if (dt2 == -1 && neighbors.c[d2]) {
	FttDirection dop = ftt_opposite_direction[d2];
	dt2 = new_solid_old_fluid (neighbors.c[d2], dop, old_solid_v, sold2);
      }
    }
    else if (SOLD2 (cell, d2) == 0.)
      dt2 = new_solid_old_solid (cell, d2, old_solid_v, sold2);
  }
 
  if (do2 != -1 && do2 != d1 && do2 != d2) {
    if (GFS_IS_MIXED(cell) && GFS_STATE(cell)->solid->s[do2] == 0.)
      dto2 = new_solid_old_solid (cell, do2, old_solid_v, sold2);
    else
      dto2 = new_fluid_old_solid (cell, do2, old_solid_v, sold2);
  }
 
  /* Uses time-scale from other faces if one is missing */
  if (dt1 == -1) {
    if (dto1 != -2)
      dt1 = dto1;
    else if (dt2 != -2)
      dt1 = dt2;
    else if (dto2 != -2)
      dt1 = dto2;
  }

  if (dt2 == -1) {
    if (dt1 != -2)
      dt2 = dt1;
    else if (dto2 != -2)
      dt2 = dto2;
    else if (dto1 != -2)
      dt2 = dto1;
  }

  if (dto1 == -1) {
    if (dt1 != -2)
      dto1 = dt1;
    else if (dt2 != -2)
      dto1 = dt2;
    else if (dto2 != -2)
      dto1 = dto2;
  }

  if (dto2 == -1) {
    if (dt1 != -2)
      dto2 = dt1;
    else if (dt2 != -2)
      dto2 = dt2;
    else if (dto1 != -2)
      dto2 = dto1;
  }

  /* Treats cell is corner */
  if (dt1 != -2 && dt2 != -2) {
    if (dt1 != dt2 && d1/2 != d2/2) {
      if (cell_is_corner (cell)) {
	if (dt1 < dt2)
	  dt2 = dt1;
	else
	  dt1 = dt2;
      }}}

  /* Treats cell was corner */
  if (dto1 != -2 && dto2 != -2 && 
      dto1 != dto2 && do1/2 != do2/2 &&
      cell_was_corner (cell, old_solid_v, sold2)) {
    if (dto1 < dto2)
      dto2 = dto1;
    else
      dto1 = dto2;
  }
  
  /* Compute the t^n+1/2 contribution of the face */
  if (do1 > -1)
    if (do1 != d1 && do1 != d2) {
      OLD_SOLID (cell)->s[do1]=SOLD2 (cell, do1)*(1-dto1)+dto1;
      if (neighbors.c[do1])
	if (!OLD_SOLID (neighbors.c[do1]) || !GFS_IS_MIXED(neighbors.c[do1])) {
	  if (!OLD_SOLID (neighbors.c[do1])) {
	    FttDirection c;
	    OLD_SOLID (neighbors.c[do1]) = g_malloc0 (sizeof (GfsSolidVector));
	    OLD_SOLID (neighbors.c[do1])->a = 1.;
	    for (c = 0; c < FTT_NEIGHBORS; c++)
	      OLD_SOLID (neighbors.c[do1])->s[c] = 1.;
	  }	  
	  OLD_SOLID (neighbors.c[do1])->s[ftt_opposite_direction[do1]] = 
	    SOLD2 (cell, do1)*(1-dto1)+dto1;
	}
    }

  if (do2 > -1)
    if (do2 != d1 && do2 != d2) {
      OLD_SOLID (cell)->s[do2]=SOLD2 (cell, do2)*(1-dto2)+dto2;
      if (neighbors.c[do2])
	if (!OLD_SOLID (neighbors.c[do2]) || !GFS_IS_MIXED(neighbors.c[do2])) {
	  if (!OLD_SOLID (neighbors.c[do2])) {
	    FttDirection c;
	    OLD_SOLID (neighbors.c[do2]) = g_malloc0 (sizeof (GfsSolidVector));
	    OLD_SOLID (neighbors.c[do2])->a = 1.;
	    for (c = 0; c < FTT_NEIGHBORS; c++)
	      OLD_SOLID (neighbors.c[do2])->s[c] = 1.;
	  }	  
	  OLD_SOLID (neighbors.c[do2])->s[ftt_opposite_direction[do2]] = 
	    SOLD2 (cell, do2)*(1-dto2)+dto2;
	}
    }


  if (d1 > -1) {
    if (SOLD2 (cell, d1) == 0.)
      OLD_SOLID (cell)->s[d1] = GFS_STATE(cell)->solid->s[d1]*(dt1-1.); 
    else if (SOLD2 (cell, d1) == 1.)
      OLD_SOLID (cell)->s[d1] = (dt1-1.)*GFS_STATE(cell)->solid->s[d1]+2.-dt1;
  }

  if (d2 > -1) {
    if (SOLD2 (cell, d2) == 0.)
      OLD_SOLID (cell)->s[d2] = GFS_STATE(cell)->solid->s[d2]*(dt2-1.); 
    else if (SOLD2 (cell, d2) == 1.)
      OLD_SOLID (cell)->s[d2] = (dt2-1.)*GFS_STATE(cell)->solid->s[d2]+2.-dt2;
  }

  if (d1/2 == d2/2 && do1 == -1 && do2 == -1)  /* third face has to be treated for 
						  the timescale determined on the other faces */  
    for (d = 0; d < FTT_NEIGHBORS; d ++)
      if (d/2 != d1/2 && SOLD2 (cell, d) == 0.)
	OLD_SOLID (cell)->s[d] = -1.+dt1+dt2;
    

  if (do1/2 == do2/2 && d1 == -1 && d2 == -1)
    for (d = 0; d < FTT_NEIGHBORS; d++)
      if (d/2 != do1/2 && SOLD2 (cell, d) == 0.)
	OLD_SOLID (cell)->s[d] = -1.+dto1+dto2;
}