static void p6est_profile_balance_self (sc_array_t * a, sc_array_t * work) { P4EST_ASSERT (SC_ARRAY_IS_OWNER (a)); P4EST_ASSERT (SC_ARRAY_IS_OWNER (work)); P4EST_ASSERT (a->elem_size == sizeof (int8_t)); P4EST_ASSERT (work->elem_size == sizeof (int8_t)); p6est_profile_balance_self_one_pass (a, work); p6est_profile_balance_self_one_pass (work, a); }
/* assumes a is already self balanced */ static void p6est_profile_balance_full (sc_array_t * a, sc_array_t * b, sc_array_t * work, p4est_qcoord_t diff) { P4EST_ASSERT (SC_ARRAY_IS_OWNER (b)); P4EST_ASSERT (SC_ARRAY_IS_OWNER (work)); P4EST_ASSERT (a->elem_size == sizeof (int8_t)); P4EST_ASSERT (b->elem_size == sizeof (int8_t)); P4EST_ASSERT (work->elem_size == sizeof (int8_t)); p6est_profile_balance_full_one_pass (a, work, diff); p6est_profile_balance_self_one_pass (work, b); }
static void p6est_profile_balance_self_one_pass (sc_array_t * read, sc_array_t * write) { int stackcount; int8_t n, newn, p, l; int8_t *wc; size_t count = read->elem_count; size_t zy; P4EST_ASSERT (SC_ARRAY_IS_OWNER (write)); P4EST_ASSERT (read->elem_size == sizeof (int8_t)); P4EST_ASSERT (write->elem_size == sizeof (int8_t)); sc_array_truncate (write); wc = (int8_t *) sc_array_push (write); n = *((int8_t *) sc_array_index (read, count - 1)); *wc = l = n; for (zy = 1; zy < count; zy++) { n = *((int8_t *) sc_array_index (read, count - 1 - zy)); p = l - 1; newn = SC_MAX (p, n); stackcount = newn - n; wc = (int8_t *) sc_array_push_count (write, 1 + stackcount); *wc = l = newn; while (stackcount--) { *(++wc) = l = newn--; } } }
/* given two profiles (layers that have been reduced to just their levels), * take the union, i.e. combine them, taking the finer layers */ static void p6est_profile_union (sc_array_t * a, sc_array_t * b, sc_array_t * c) { size_t az, bz, na; P4EST_ASSERT (SC_ARRAY_IS_OWNER (c)); P4EST_ASSERT (a->elem_size == sizeof (int8_t)); P4EST_ASSERT (b->elem_size == sizeof (int8_t)); P4EST_ASSERT (c->elem_size == sizeof (int8_t)); int8_t al, bl, finel, *cc; p4est_qcoord_t finesize, coarsesize; sc_array_t *finer; size_t *fineincr; sc_array_truncate (c); az = 0; bz = 0; na = a->elem_count; while (az < na) { P4EST_ASSERT (bz < b->elem_count); cc = (int8_t *) sc_array_push (c); al = *((int8_t *) sc_array_index (a, az++)); bl = *((int8_t *) sc_array_index (b, bz++)); if (al == bl) { *cc = al; continue; } else if (al > bl) { finer = a; finesize = P4EST_QUADRANT_LEN (al); fineincr = &az; finel = al; coarsesize = P4EST_QUADRANT_LEN (bl); } else { finer = b; finesize = P4EST_QUADRANT_LEN (bl); fineincr = &bz; finel = bl; coarsesize = P4EST_QUADRANT_LEN (al); } P4EST_ASSERT (finesize < coarsesize); do { *cc = finel; cc = (int8_t *) sc_array_push (c); finel = *((int8_t *) sc_array_index (finer, (*fineincr)++)); finesize += P4EST_QUADRANT_LEN (finel); } while (finesize < coarsesize); P4EST_ASSERT (finesize == coarsesize); *cc = finel; } }
static void p6est_profile_balance_full_one_pass (sc_array_t * read, sc_array_t * write, p4est_qcoord_t readh) { int8_t *wc; size_t count; int stackcount; int8_t n, nn, newn, p, l, prevl, nextl; size_t zy; P4EST_ASSERT (SC_ARRAY_IS_OWNER (write)); P4EST_ASSERT (read->elem_size == sizeof (int8_t)); P4EST_ASSERT (write->elem_size == sizeof (int8_t)); count = read->elem_count; sc_array_truncate (write); l = 0; zy = 0; while (zy < count) { n = *((int8_t *) sc_array_index (read, count - 1 - zy++)); if (n && !(readh & P4EST_QUADRANT_LEN (n))) { P4EST_ASSERT (zy < count); nn = *((int8_t *) sc_array_index (read, count - 1 - zy)); if (n == nn) { if (zy > 1) { prevl = *((int8_t *) sc_array_index (read, count - 1 - (zy - 2))); } else { prevl = -1; } if (zy < count - 1) { nextl = *((int8_t *) sc_array_index (read, count - 1 - (zy + 1))); } else { nextl = -1; } if (n >= SC_MAX (nextl, prevl) - 1) { zy++; n--; } } } readh += P4EST_QUADRANT_LEN (n); p = l - 1; newn = SC_MAX (p, n); stackcount = newn - n; wc = (int8_t *) sc_array_push_count (write, 1 + stackcount); *wc = l = newn; while (stackcount--) { *(++wc) = l = newn--; } } }
void p8est_quadrant_edge_neighbor_extra (const p4est_quadrant_t * q, p4est_topidx_t t, int edge, sc_array_t * quads, sc_array_t * treeids, p4est_connectivity_t * conn) { p4est_quadrant_t temp; p4est_quadrant_t *qp; p4est_topidx_t *tp; int face; p8est_edge_info_t ei; p8est_edge_transform_t *et; sc_array_t *eta; size_t etree; eta = &ei.edge_transforms; P4EST_ASSERT (SC_ARRAY_IS_OWNER (quads)); P4EST_ASSERT (quads->elem_count == 0); P4EST_ASSERT (quads->elem_size == sizeof (p4est_quadrant_t)); P4EST_ASSERT (SC_ARRAY_IS_OWNER (treeids)); P4EST_ASSERT (treeids->elem_count == 0); P4EST_ASSERT (treeids->elem_size == sizeof (p4est_topidx_t)); p8est_quadrant_edge_neighbor (q, edge, &temp); if (p4est_quadrant_is_inside_root (&temp)) { qp = p4est_quadrant_array_push (quads); *qp = temp; tp = (p4est_topidx_t *) sc_array_push (treeids); *tp = t; return; } if (!p8est_quadrant_is_outside_edge (&temp)) { qp = p4est_quadrant_array_push (quads); tp = (p4est_topidx_t *) sc_array_push (treeids); face = p8est_edge_faces[edge][0]; p4est_quadrant_face_neighbor (q, face, &temp); if (p4est_quadrant_is_inside_root (&temp)) { face = p8est_edge_faces[edge][1]; *tp = p8est_quadrant_face_neighbor_extra (&temp, t, face, qp, conn); if (*tp == -1) { qp = (p4est_quadrant_t *) sc_array_pop (quads); tp = (p4est_topidx_t *) sc_array_pop (treeids); } return; } face = p8est_edge_faces[edge][1]; p4est_quadrant_face_neighbor (q, face, &temp); P4EST_ASSERT (p4est_quadrant_is_inside_root (&temp)); face = p8est_edge_faces[edge][0]; *tp = p8est_quadrant_face_neighbor_extra (&temp, t, face, qp, conn); if (*tp == -1) { qp = (p4est_quadrant_t *) sc_array_pop (quads); tp = (p4est_topidx_t *) sc_array_pop (treeids); } return; } sc_array_init (eta, sizeof (p8est_edge_transform_t)); p8est_find_edge_transform (conn, t, edge, &ei); sc_array_resize (quads, eta->elem_count); sc_array_resize (treeids, eta->elem_count); for (etree = 0; etree < eta->elem_count; etree++) { qp = p4est_quadrant_array_index (quads, etree); tp = (p4est_topidx_t *) sc_array_index (treeids, etree); et = p8est_edge_array_index (eta, etree); p8est_quadrant_transform_edge (&temp, qp, &ei, et, 1); *tp = et->ntree; } sc_array_reset (eta); }