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.; }
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); } } }
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 (); } }
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.; }
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.; }
static void get_velfaces (FttCell * cell, FaceData * fd) { GfsStateVector * s = GFS_STATE (cell); FttDirection d; for (d = 0; d < FTT_NEIGHBORS; d++) { GFS_VALUE (cell, fd->velfaces[d]) = s->f[d].un; s->f[d].un = ( fd->beta + 0.5 ) * s->f[d].un - ( fd->beta - 0.5 ) * GFS_VALUE (cell, fd->velold[d]); } }
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 (); } } } }
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; } }
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; } }
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; } }
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; } }
static void swap_fractions_back (FttCell * cell, GfsVariable * old_solid_v) { if (OLD_SOLID (cell)) if (GFS_STATE(cell)->solid) { GfsSolidVector * tmp = OLD_SOLID (cell); OLD_SOLID (cell) = GFS_STATE(cell)->solid; GFS_STATE(cell)->solid = tmp; tmp = NULL; } else { GFS_STATE(cell)->solid = OLD_SOLID (cell); OLD_SOLID (cell) = NULL; } else if (GFS_STATE(cell)->solid) { OLD_SOLID (cell) = GFS_STATE(cell)->solid; GFS_STATE(cell)->solid = NULL; } }
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 } }
static void swap_fractions (FttCell * cell, GfsVariable * old_solid_v) { FttDirection c; g_assert (cell); if (FTT_CELL_IS_LEAF(cell)) { if (OLD_SOLID (cell)) { GfsSolidVector * solid_old = OLD_SOLID (cell); if (GFS_STATE (cell)->solid) { GfsSolidVector * solid = GFS_STATE (cell)->solid; OLD_SOLID (cell)->merged = GFS_STATE (cell)->solid->merged; for (c = 0; c < 2*FTT_DIMENSION; c++) if (solid->s[c] == 0.) solid_old->s[c] = 0; else solid_old->s[c] = (solid_old->s[c]+solid->s[c])/2. ; } else { OLD_SOLID (cell)->merged = NULL; for (c = 0; c < 2*FTT_DIMENSION; c++) solid_old->s[c] = (solid_old->s[c]+1.)/2. ; } } else if (GFS_STATE (cell)->solid) { GfsSolidVector * solid = GFS_STATE (cell)->solid; GfsSolidVector * solid_old = OLD_SOLID (cell) = g_malloc0 (sizeof (GfsSolidVector)); OLD_SOLID (cell)->a= 1.; OLD_SOLID (cell)->merged = GFS_STATE (cell)->solid->merged; for (c = 0; c < 2*FTT_DIMENSION; c++) solid_old->s[c] = 1.; for (c = 0; c < 2*FTT_DIMENSION; c++) if (solid->s[c] == 0.) solid_old->s[c] = 0; else solid_old->s[c] = (solid_old->s[c]+solid->s[c])/2. ; } } if (OLD_SOLID (cell)) { if (GFS_STATE(cell)->solid) { GfsSolidVector * tmp = OLD_SOLID (cell); OLD_SOLID (cell)->merged = GFS_STATE (cell)->solid->merged; OLD_SOLID (cell) = GFS_STATE(cell)->solid; GFS_STATE(cell)->solid = tmp; tmp = NULL; } else { OLD_SOLID (cell)->merged = NULL; GFS_STATE(cell)->solid = OLD_SOLID (cell); OLD_SOLID (cell) = NULL; } } else if (GFS_STATE(cell)->solid) { OLD_SOLID (cell) = GFS_STATE(cell)->solid; GFS_STATE(cell)->solid = NULL; } /* Check for negative fractions and fix */ if (GFS_STATE(cell)->solid) for (c = 0; c < 2*FTT_DIMENSION; c++) if (GFS_STATE(cell)->solid->s[c] < 0.) { if (OLD_SOLID (cell)) if (OLD_SOLID (cell)->s[c] >= 0.) GFS_STATE(cell)->solid->s[c] = OLD_SOLID (cell)->s[c]; else GFS_STATE(cell)->solid->s[c] = 1.; else GFS_STATE(cell)->solid->s[c] = 0.; } if (OLD_SOLID (cell)) for (c = 0; c < 2*FTT_DIMENSION; c++) if (OLD_SOLID (cell)->s[c] < 0.){ if (GFS_STATE(cell)->solid) if (GFS_STATE(cell)->solid->s[c] >= 0.) OLD_SOLID (cell)->s[c] = GFS_STATE(cell)->solid->s[c]; else OLD_SOLID (cell)->s[c] = 1.; else OLD_SOLID (cell)->s[c] = 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; } }
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; }