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 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 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; }
/* 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.; }
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); }
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; } }
/* 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; } } }