void p8est_quadrant_edge_neighbor (const p4est_quadrant_t * q, int edge, p4est_quadrant_t * r) { const p4est_qcoord_t qh = P4EST_QUADRANT_LEN (q->level); P4EST_ASSERT (0 <= edge && edge < 12); P4EST_ASSERT (p4est_quadrant_is_valid (q)); switch (edge / 4) { case 0: r->x = q->x; r->y = q->y + (2 * (edge & 0x01) - 1) * qh; r->z = q->z + ((edge & 0x02) - 1) * qh; break; case 1: r->x = q->x + (2 * (edge & 0x01) - 1) * qh; r->y = q->y; r->z = q->z + ((edge & 0x02) - 1) * qh; break; case 2: r->x = q->x + (2 * (edge & 0x01) - 1) * qh; r->y = q->y + ((edge & 0x02) - 1) * qh; r->z = q->z; break; default: SC_ABORT_NOT_REACHED (); break; } r->level = q->level; P4EST_ASSERT (p4est_quadrant_is_extended (r)); }
int p8est_quadrant_touches_edge (const p4est_quadrant_t * q, int edge, int inside) { int quad_contact[P4EST_FACES]; int axis, side, incount; p4est_qcoord_t lower, upper; P4EST_ASSERT (0 <= edge && edge < 12); axis = edge / 4; if (q->level == P4EST_MAXLEVEL) { P4EST_ASSERT (p4est_quadrant_is_node (q, inside)); lower = 0; upper = P4EST_ROOT_LEN - (int) inside; } else { if (!inside) { P4EST_ASSERT (p4est_quadrant_is_extended (q)); lower = -P4EST_QUADRANT_LEN (q->level); upper = P4EST_ROOT_LEN; } else { P4EST_ASSERT (p4est_quadrant_is_valid (q)); lower = 0; upper = P4EST_LAST_OFFSET (q->level); } } quad_contact[0] = (q->x == lower); quad_contact[1] = (q->x == upper); quad_contact[2] = (q->y == lower); quad_contact[3] = (q->y == upper); quad_contact[4] = (q->z == lower); quad_contact[5] = (q->z == upper); incount = 0; if (axis != 0) { side = edge & 1; incount += quad_contact[side]; } if (axis != 1) { side = (axis == 0) ? (edge & 1) : ((edge >> 1) & 1); incount += quad_contact[2 + side]; }
int p4est_quadrant_is_family (const p4est_quadrant_t * q0, const p4est_quadrant_t * q1, const p4est_quadrant_t * q2, const p4est_quadrant_t * q3, const p4est_quadrant_t * q4, const p4est_quadrant_t * q5, const p4est_quadrant_t * q6, const p4est_quadrant_t * q7) { const int8_t level = q0->level; p4est_qcoord_t inc; P4EST_ASSERT (p4est_quadrant_is_extended (q0)); P4EST_ASSERT (p4est_quadrant_is_extended (q1)); P4EST_ASSERT (p4est_quadrant_is_extended (q2)); P4EST_ASSERT (p4est_quadrant_is_extended (q3)); P4EST_ASSERT (p4est_quadrant_is_extended (q4)); P4EST_ASSERT (p4est_quadrant_is_extended (q5)); P4EST_ASSERT (p4est_quadrant_is_extended (q6)); P4EST_ASSERT (p4est_quadrant_is_extended (q7)); if (level == 0 || level != q1->level || level != q2->level || level != q3->level || level != q4->level || level != q5->level || level != q6->level || level != q7->level) { return 0; } inc = P4EST_QUADRANT_LEN (level); return ((q0->x + inc == q1->x && q0->y == q1->y && q0->z == q1->z) && (q0->x == q2->x && q0->y + inc == q2->y && q0->z == q2->z) && (q1->x == q3->x && q2->y == q3->y && q0->z == q3->z) && (q0->x == q4->x && q0->y == q4->y && q0->z + inc == q4->z) && (q1->x == q5->x && q1->y == q5->y && q4->z == q5->z) && (q2->x == q6->x && q2->y == q6->y && q4->z == q6->z) && (q3->x == q7->x && q3->y == q7->y && q4->z == q7->z)); }
int main (int argc, char **argv) { const p4est_qcoord_t qone = 1; int mpiret; int k; int level, mid, cid; int id0, id1, id2, id3; int64_t index1, index2; size_t iz, jz, incount; p4est_qcoord_t mh = P4EST_QUADRANT_LEN (P4EST_QMAXLEVEL); p4est_connectivity_t *connectivity; p4est_t *p4est1; p4est_t *p4est2; p4est_tree_t *t1, *t2, tree; p4est_quadrant_t *p, *q1, *q2; p4est_quadrant_t r, s; p4est_quadrant_t c0, c1, c2, c3; p4est_quadrant_t cv[P4EST_CHILDREN], *cp[P4EST_CHILDREN]; p4est_quadrant_t A, B, C, D, E, F, G, H, I, P, Q; p4est_quadrant_t a, f, g, h; uint64_t Aid, Fid; /* initialize MPI */ mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); /* create connectivity and forest structures */ connectivity = p4est_connectivity_new_unitsquare (); p4est1 = p4est_new_ext (sc_MPI_COMM_SELF, connectivity, 15, 0, 0, 0, NULL, NULL); p4est2 = p4est_new_ext (sc_MPI_COMM_SELF, connectivity, 15, 0, 0, 8, NULL, NULL); /* refine the second tree to a uniform level */ p4est_refine (p4est1, 1, refine_none, NULL); p4est_refine (p4est2, 1, refine_some, NULL); t1 = p4est_tree_array_index (p4est1->trees, 0); t2 = p4est_tree_array_index (p4est2->trees, 0); SC_CHECK_ABORT (p4est_tree_is_sorted (t1), "is_sorted"); SC_CHECK_ABORT (p4est_tree_is_sorted (t2), "is_sorted"); /* run a bunch of cross-tests */ p = NULL; for (iz = 0; iz < t1->quadrants.elem_count; ++iz) { q1 = p4est_quadrant_array_index (&t1->quadrants, iz); /* test the index conversion */ index1 = p4est_quadrant_linear_id (q1, (int) q1->level); p4est_quadrant_set_morton (&r, (int) q1->level, index1); index2 = p4est_quadrant_linear_id (&r, (int) r.level); SC_CHECK_ABORT (index1 == index2, "index conversion"); level = (int) q1->level - 1; if (level >= 0) { index1 = p4est_quadrant_linear_id (q1, level); p4est_quadrant_set_morton (&r, level, index1); index2 = p4est_quadrant_linear_id (&r, level); SC_CHECK_ABORT (index1 == index2, "index conversion"); } /* test the is_next function */ if (p != NULL) { SC_CHECK_ABORT (p4est_quadrant_is_next (p, q1), "is_next"); } p = q1; /* test the is_family function */ p4est_quadrant_children (q1, &c0, &c1, &c2, &c3); SC_CHECK_ABORT (p4est_quadrant_is_family (&c0, &c1, &c2, &c3), "is_family"); SC_CHECK_ABORT (!p4est_quadrant_is_family (&c1, &c0, &c2, &c3), "is_family"); SC_CHECK_ABORT (!p4est_quadrant_is_family (&c0, &c0, &c1, &c2), "is_family"); p4est_quadrant_childrenv (q1, cv); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c0, &cv[0]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c1, &cv[1]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c2, &cv[2]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c3, &cv[3]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_family (&cv[0], &cv[1], &cv[2], &cv[3]), "is_family"); cp[0] = &cv[0]; cp[1] = &cv[1]; cp[2] = &cv[2]; cp[3] = &cv[3]; SC_CHECK_ABORT (p4est_quadrant_is_familypv (cp), "is_family"); cv[1] = cv[0]; SC_CHECK_ABORT (!p4est_quadrant_is_familyv (cv), "is_family"); cp[1] = &c1; SC_CHECK_ABORT (p4est_quadrant_is_familypv (cp), "is_family"); cp[2] = &c3; SC_CHECK_ABORT (!p4est_quadrant_is_familypv (cp), "is_family"); /* test the sibling function */ mid = p4est_quadrant_child_id (q1); for (cid = 0; cid < 4; ++cid) { p4est_quadrant_sibling (q1, &r, cid); if (cid != mid) { SC_CHECK_ABORT (p4est_quadrant_is_sibling (q1, &r), "sibling"); } else { SC_CHECK_ABORT (p4est_quadrant_is_equal (q1, &r), "sibling"); } } /* test t1 against itself */ for (jz = 0; jz < t1->quadrants.elem_count; ++jz) { q2 = p4est_quadrant_array_index (&t1->quadrants, jz); /* test the comparison function */ SC_CHECK_ABORT (p4est_quadrant_compare (q1, q2) == -p4est_quadrant_compare (q2, q1), "compare"); SC_CHECK_ABORT ((p4est_quadrant_compare (q1, q2) == 0) == p4est_quadrant_is_equal (q1, q2), "is_equal"); /* test the descriptive versions of functions */ SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (q1, q2) == p4est_quadrant_is_sibling (q1, q2), "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q1, q2) == p4est_quadrant_is_parent (q1, q2), "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q2, q1) == p4est_quadrant_is_parent (q2, q1), "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q1, q2) == p4est_quadrant_is_ancestor (q1, q2), "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q2, q1) == p4est_quadrant_is_ancestor (q2, q1), "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_next_D (q1, q2) == p4est_quadrant_is_next (q1, q2), "is_next"); SC_CHECK_ABORT (p4est_quadrant_is_next_D (q2, q1) == p4est_quadrant_is_next (q2, q1), "is_next"); p4est_nearest_common_ancestor_D (q1, q2, &r); p4est_nearest_common_ancestor (q1, q2, &s); SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor"); p4est_nearest_common_ancestor_D (q2, q1, &r); p4est_nearest_common_ancestor (q2, q1, &s); SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor"); } /* test t1 against t2 */ for (jz = 0; jz < t2->quadrants.elem_count; ++jz) { q2 = p4est_quadrant_array_index (&t2->quadrants, jz); /* test the comparison function */ SC_CHECK_ABORT (p4est_quadrant_compare (q1, q2) == -p4est_quadrant_compare (q2, q1), "compare"); SC_CHECK_ABORT ((p4est_quadrant_compare (q1, q2) == 0) == p4est_quadrant_is_equal (q1, q2), "is_equal"); /* test the descriptive versions of functions */ SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (q1, q2) == p4est_quadrant_is_sibling (q1, q2), "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q1, q2) == p4est_quadrant_is_parent (q1, q2), "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q2, q1) == p4est_quadrant_is_parent (q2, q1), "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q1, q2) == p4est_quadrant_is_ancestor (q1, q2), "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q2, q1) == p4est_quadrant_is_ancestor (q2, q1), "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_next_D (q1, q2) == p4est_quadrant_is_next (q1, q2), "is_next"); SC_CHECK_ABORT (p4est_quadrant_is_next_D (q2, q1) == p4est_quadrant_is_next (q2, q1), "is_next"); p4est_nearest_common_ancestor_D (q1, q2, &r); p4est_nearest_common_ancestor (q1, q2, &s); SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor"); p4est_nearest_common_ancestor_D (q2, q1, &r); p4est_nearest_common_ancestor (q2, q1, &s); SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor"); } } p = NULL; for (iz = 0; iz < t2->quadrants.elem_count; ++iz) { q1 = p4est_quadrant_array_index (&t2->quadrants, iz); /* test the is_next function */ if (p != NULL) { SC_CHECK_ABORT (p4est_quadrant_is_next (p, q1), "is_next"); } p = q1; } /* test the coarsen function */ p4est_coarsen (p4est1, 1, coarsen_none, NULL); p4est_coarsen (p4est1, 1, coarsen_all, NULL); p4est_coarsen (p4est2, 1, coarsen_some, NULL); /* test the linearize algorithm */ incount = t2->quadrants.elem_count; (void) p4est_linearize_tree (p4est2, t2); SC_CHECK_ABORT (incount == t2->quadrants.elem_count, "linearize"); /* this is user_data neutral only when p4est1->data_size == 0 */ sc_array_init (&tree.quadrants, sizeof (p4est_quadrant_t)); sc_array_resize (&tree.quadrants, 18); q1 = p4est_quadrant_array_index (&tree.quadrants, 0); q2 = p4est_quadrant_array_index (&t2->quadrants, 0); *q1 = *q2; q2 = p4est_quadrant_array_index (&t2->quadrants, 1); for (k = 0; k < 3; ++k) { q1 = p4est_quadrant_array_index (&tree.quadrants, (size_t) (k + 1)); *q1 = *q2; q1->level = (int8_t) (q1->level + k); } for (k = 0; k < 10; ++k) { q1 = p4est_quadrant_array_index (&tree.quadrants, (size_t) (k + 4)); q2 = p4est_quadrant_array_index (&t2->quadrants, (size_t) (k + 3)); *q1 = *q2; q1->level = (int8_t) (q1->level + k); } for (k = 0; k < 4; ++k) { q1 = p4est_quadrant_array_index (&tree.quadrants, (size_t) (k + 14)); q2 = p4est_quadrant_array_index (&t2->quadrants, (size_t) (k + 12)); *q1 = *q2; q1->level = (int8_t) (q1->level + 10 + k); } tree.maxlevel = 0; for (k = 0; k <= P4EST_QMAXLEVEL; ++k) { tree.quadrants_per_level[k] = 0; } for (; k <= P4EST_MAXLEVEL; ++k) { tree.quadrants_per_level[k] = -1; } incount = tree.quadrants.elem_count; for (iz = 0; iz < incount; ++iz) { q1 = p4est_quadrant_array_index (&tree.quadrants, iz); ++tree.quadrants_per_level[q1->level]; tree.maxlevel = (int8_t) SC_MAX (tree.maxlevel, q1->level); } SC_CHECK_ABORT (!p4est_tree_is_linear (&tree), "is_linear"); (void) p4est_linearize_tree (p4est1, &tree); SC_CHECK_ABORT (incount - 3 == tree.quadrants.elem_count, "linearize"); sc_array_reset (&tree.quadrants); /* create a partial tree and check overlap */ sc_array_resize (&tree.quadrants, 3); q1 = p4est_quadrant_array_index (&tree.quadrants, 0); p4est_quadrant_set_morton (q1, 1, 1); q1 = p4est_quadrant_array_index (&tree.quadrants, 1); p4est_quadrant_set_morton (q1, 2, 8); q1 = p4est_quadrant_array_index (&tree.quadrants, 2); p4est_quadrant_set_morton (q1, 2, 9); for (k = 0; k <= P4EST_QMAXLEVEL; ++k) { tree.quadrants_per_level[k] = 0; } for (; k <= P4EST_MAXLEVEL; ++k) { tree.quadrants_per_level[k] = -1; } tree.quadrants_per_level[1] = 1; tree.quadrants_per_level[2] = 2; tree.maxlevel = 2; p4est_quadrant_first_descendant (p4est_quadrant_array_index (&tree.quadrants, 0), &tree.first_desc, P4EST_QMAXLEVEL); p4est_quadrant_last_descendant (p4est_quadrant_array_index (&tree.quadrants, tree.quadrants.elem_count - 1), &tree.last_desc, P4EST_QMAXLEVEL); SC_CHECK_ABORT (p4est_tree_is_complete (&tree), "is_complete"); p4est_quadrant_set_morton (&D, 0, 0); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &D), "overlaps 0"); p4est_quadrant_set_morton (&A, 1, 0); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 1"); p4est_quadrant_set_morton (&A, 1, 1); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 2"); p4est_quadrant_set_morton (&A, 1, 2); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 3"); p4est_quadrant_set_morton (&A, 1, 3); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 4"); p4est_quadrant_set_morton (&B, 3, 13); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 5"); p4est_quadrant_set_morton (&B, 3, 25); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 6"); p4est_quadrant_set_morton (&B, 3, 39); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 7"); p4est_quadrant_set_morton (&B, 3, 40); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 8"); p4est_quadrant_set_morton (&C, 4, 219); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &C), "overlaps 9"); sc_array_reset (&tree.quadrants); /* destroy the p4est and its connectivity structure */ p4est_destroy (p4est1); p4est_destroy (p4est2); p4est_connectivity_destroy (connectivity); /* This will test the ability to address negative quadrants */ P4EST_QUADRANT_INIT (&A); P4EST_QUADRANT_INIT (&B); P4EST_QUADRANT_INIT (&C); P4EST_QUADRANT_INIT (&D); P4EST_QUADRANT_INIT (&E); P4EST_QUADRANT_INIT (&F); P4EST_QUADRANT_INIT (&G); P4EST_QUADRANT_INIT (&H); P4EST_QUADRANT_INIT (&I); P4EST_QUADRANT_INIT (&P); P4EST_QUADRANT_INIT (&Q); A.x = -qone << P4EST_MAXLEVEL; A.y = -qone << P4EST_MAXLEVEL; A.level = 0; B.x = qone << P4EST_MAXLEVEL; B.y = -qone << P4EST_MAXLEVEL; B.level = 0; C.x = -qone << P4EST_MAXLEVEL; C.y = qone << P4EST_MAXLEVEL; C.level = 0; D.x = qone << P4EST_MAXLEVEL; D.y = qone << P4EST_MAXLEVEL; D.level = 0; /* this one is outside the 3x3 box */ E.x = -qone << (P4EST_MAXLEVEL + 1); E.y = -qone; E.level = 0; F.x = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh); F.y = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh); F.level = P4EST_QMAXLEVEL; G.x = -mh; G.y = -mh; G.level = P4EST_QMAXLEVEL; H.x = -qone << (P4EST_MAXLEVEL - 1); H.y = -qone << (P4EST_MAXLEVEL - 1); H.level = 1; I.x = -qone << P4EST_MAXLEVEL; I.y = -qone << (P4EST_MAXLEVEL - 1); I.level = 1; check_linear_id (&A, &A); check_linear_id (&A, &B); check_linear_id (&A, &C); check_linear_id (&A, &D); /* check_linear_id (&A, &E); */ check_linear_id (&A, &F); check_linear_id (&A, &G); check_linear_id (&A, &H); check_linear_id (&A, &I); check_linear_id (&B, &A); check_linear_id (&B, &B); check_linear_id (&B, &C); check_linear_id (&B, &D); /* check_linear_id (&B, &E); */ check_linear_id (&B, &F); check_linear_id (&B, &G); check_linear_id (&B, &H); check_linear_id (&B, &I); check_linear_id (&D, &A); check_linear_id (&D, &B); check_linear_id (&D, &C); check_linear_id (&D, &D); /* check_linear_id (&D, &E); */ check_linear_id (&D, &F); check_linear_id (&D, &G); check_linear_id (&D, &H); check_linear_id (&D, &I); check_linear_id (&G, &A); check_linear_id (&G, &B); check_linear_id (&G, &C); check_linear_id (&G, &D); /* check_linear_id (&G, &E); */ check_linear_id (&G, &F); check_linear_id (&G, &G); check_linear_id (&G, &H); check_linear_id (&G, &I); check_linear_id (&I, &A); check_linear_id (&I, &B); check_linear_id (&I, &C); check_linear_id (&I, &D); /* check_linear_id (&I, &E); */ check_linear_id (&I, &F); check_linear_id (&I, &G); check_linear_id (&I, &H); check_linear_id (&I, &I); SC_CHECK_ABORT (p4est_quadrant_is_extended (&A) == 1, "is_extended A"); SC_CHECK_ABORT (p4est_quadrant_is_extended (&B) == 1, "is_extended B"); SC_CHECK_ABORT (p4est_quadrant_is_extended (&C) == 1, "is_extended C"); SC_CHECK_ABORT (p4est_quadrant_is_extended (&D) == 1, "is_extended D"); SC_CHECK_ABORT (!p4est_quadrant_is_extended (&E) == 1, "!is_extended E"); SC_CHECK_ABORT (p4est_quadrant_is_extended (&F) == 1, "is_extended F"); SC_CHECK_ABORT (p4est_quadrant_is_extended (&G) == 1, "is_extended G"); SC_CHECK_ABORT (p4est_quadrant_compare (&A, &A) == 0, "compare"); SC_CHECK_ABORT (p4est_quadrant_compare (&A, &B) > 0, "compare"); SC_CHECK_ABORT (p4est_quadrant_compare (&B, &A) < 0, "compare"); SC_CHECK_ABORT (p4est_quadrant_compare (&F, &F) == 0, "compare"); SC_CHECK_ABORT (p4est_quadrant_compare (&G, &F) > 0, "compare"); SC_CHECK_ABORT (p4est_quadrant_compare (&F, &G) < 0, "compare"); A.p.which_tree = 0; B.p.piggy1.which_tree = 0; SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&A, &A) == 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&A, &B) > 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&B, &A) < 0, "compare_piggy"); F.p.piggy2.which_tree = 0; G.p.which_tree = 0; SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &F) == 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&G, &F) > 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &G) < 0, "compare_piggy"); F.p.piggy1.which_tree = (p4est_topidx_t) P4EST_TOPIDX_MAX - 3; G.p.piggy2.which_tree = (p4est_topidx_t) P4EST_TOPIDX_MAX / 2; SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &F) == 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&G, &F) < 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &G) > 0, "compare_piggy"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &A) == 1, "is_equal"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&F, &F) == 1, "is_equal"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&G, &G) == 1, "is_equal"); /* Not sure if these make sense because D, O and A are all level 0 */ #if 0 SC_CHECK_ABORT (p4est_quadrant_is_sibling (&D, &O) == 1, "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_sibling (&D, &A) == 0, "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&D, &O) == 1, "is_sibling_D"); SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&D, &A) == 0, "is_sibling_D"); #endif SC_CHECK_ABORT (p4est_quadrant_is_sibling (&I, &H) == 1, "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_sibling (&I, &G) == 0, "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&I, &H) == 1, "is_sibling_D"); SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&I, &G) == 0, "is_sibling_D"); SC_CHECK_ABORT (p4est_quadrant_is_parent (&A, &H) == 1, "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_parent (&H, &A) == 0, "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_parent (&A, &D) == 0, "is_parent"); SC_CHECK_ABORT (p4est_quadrant_is_parent_D (&A, &H) == 1, "is_parent_D"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor (&A, &G) == 1, "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor (&G, &A) == 0, "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (&A, &G) == 1, "is_ancestor_D"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (&G, &A) == 0, "is_ancestor_D"); /* SC_CHECK_ABORT (p4est_quadrant_is_next (&F, &E) == 1, "is_next"); */ SC_CHECK_ABORT (p4est_quadrant_is_next (&A, &H) == 0, "is_next"); /* SC_CHECK_ABORT (p4est_quadrant_is_next_D (&F, &E) == 1, "is_next_D"); */ SC_CHECK_ABORT (p4est_quadrant_is_next_D (&A, &H) == 0, "is_next_D"); p4est_quadrant_parent (&H, &a); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "parent"); p4est_quadrant_sibling (&I, &h, 3); SC_CHECK_ABORT (p4est_quadrant_is_equal (&H, &h) == 1, "sibling"); p4est_quadrant_children (&A, &c0, &c1, &c2, &c3); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c2, &I) == 1, "children"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c3, &H) == 1, "children"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c3, &G) == 0, "children"); SC_CHECK_ABORT (p4est_quadrant_is_family (&c0, &c1, &c2, &c3) == 1, "is_family"); id0 = p4est_quadrant_child_id (&c0); id1 = p4est_quadrant_child_id (&c1); id2 = p4est_quadrant_child_id (&c2); id3 = p4est_quadrant_child_id (&c3); SC_CHECK_ABORT (id0 == 0 && id1 == 1 && id2 == 2 && id3 == 3, "child_id"); SC_CHECK_ABORT (p4est_quadrant_child_id (&G) == 3, "child_id"); p4est_quadrant_first_descendant (&A, &c1, 1); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c0, &c1) == 1, "first_descendant"); p4est_quadrant_last_descendant (&A, &g, P4EST_QMAXLEVEL); SC_CHECK_ABORT (p4est_quadrant_is_equal (&G, &g) == 1, "last_descendant"); Fid = p4est_quadrant_linear_id (&F, P4EST_QMAXLEVEL); p4est_quadrant_set_morton (&f, P4EST_QMAXLEVEL, Fid); SC_CHECK_ABORT (p4est_quadrant_is_equal (&F, &f) == 1, "set_morton/linear_id"); Aid = p4est_quadrant_linear_id (&A, 0); p4est_quadrant_set_morton (&a, 0, Aid); SC_CHECK_ABORT (Aid == 15, "linear_id"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "set_morton/linear_id"); p4est_nearest_common_ancestor (&I, &H, &a); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "ancestor"); p4est_nearest_common_ancestor_D (&I, &H, &a); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "ancestor_D"); for (k = 0; k < 16; ++k) { if (k != 4 && k != 6 && k != 8 && k != 9 && k != 12 && k != 13 && k != 14) { p4est_quadrant_set_morton (&E, 0, (uint64_t) k); } } p4est_quadrant_set_morton (&P, 0, 10); p4est_quadrant_set_morton (&Q, 0, 11); SC_CHECK_ABORT (p4est_quadrant_is_next (&P, &Q), "is_next"); SC_CHECK_ABORT (!p4est_quadrant_is_next (&A, &Q), "is_next"); sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
static void p8est_bal_edge_con_internal (p4est_quadrant_t const *q, p4est_quadrant_t * p, int edge, int balance, int *consistent, p4est_quadrant_t * add) { int plevel = p->level; int qlevel = q->level; int blevel; int child; int recon; p4est_quadrant_t porig; p4est_quadrant_t temp; p4est_quadrant_t a; p4est_qcoord_t dx, dy; p4est_qcoord_t dist; p4est_qcoord_t qlen, plen, mask; p4est_qcoord_t b1len, pmask; int i; P4EST_ASSERT (p4est_quadrant_is_extended (q)); P4EST_ASSERT (p4est_quadrant_is_extended (p)); if (qlevel <= plevel) { if (consistent != NULL) { *consistent = 1; } return; } qlen = P4EST_QUADRANT_LEN (qlevel); plen = P4EST_QUADRANT_LEN (plevel); switch (edge / 4) { case 0: dx = (edge & 1) ? (q->y + qlen) - (p->y + plen) : p->y - q->y; dy = (edge & 2) ? (q->z + qlen) - (p->z + plen) : p->z - q->z; break; case 1: dx = (edge & 1) ? (q->x + qlen) - (p->x + plen) : p->x - q->x; dy = (edge & 2) ? (q->z + qlen) - (p->z + plen) : p->z - q->z; break; case 2: dx = (edge & 1) ? (q->x + qlen) - (p->x + plen) : p->x - q->x; dy = (edge & 2) ? (q->y + qlen) - (p->y + plen) : p->y - q->y; break; default: SC_ABORT_NOT_REACHED (); } P4EST_ASSERT (dx >= 0); P4EST_ASSERT (dy >= 0); if (balance) { dist = SC_MAX (dx, dy); blevel = p4est_balance_kernel_1d (dist, qlevel); } else { blevel = p4est_balance_kernel_2d (dx, dy, qlevel); } if (blevel <= plevel) { if (consistent != NULL) { *consistent = 1; } return; } if (consistent != NULL) { *consistent = 0; } porig = *p; *p = *q; switch (edge / 4) { case 0: p->y += (edge & 1) ? -dx : dx; p->z += (edge & 2) ? -dy : dy; break; case 1: p->x += (edge & 1) ? -dx : dx; p->z += (edge & 2) ? -dy : dy; break; case 2: p->x += (edge & 1) ? -dx : dx; p->y += (edge & 2) ? -dy : dy; break; default: SC_ABORT_NOT_REACHED (); } mask = -1 << (P4EST_MAXLEVEL - blevel); p->x &= mask; p->y &= mask; p->z &= mask; p->level = blevel; P4EST_ASSERT (p4est_quadrant_is_extended (p)); if (add != NULL) { add[1] = *p; /* this is the only quad needed if it is only one level smaller than the * original quadrant */ if (blevel == plevel - 1) { return; } mask = -1 << (P4EST_MAXLEVEL - (blevel - 1)); pmask = -1 << (P4EST_MAXLEVEL - (plevel)); a = *p; a.x &= mask; a.y &= mask; a.z &= mask; a.level = blevel - 1; b1len = P4EST_QUADRANT_LEN (blevel - 1); for (i = -1; i <= 1; i += 2) { temp = a; /* temp is in a family group one family group over from temp */ switch (edge / 4) { case 0: temp.x += i * b1len; break; case 1: temp.y += i * b1len; break; case 2: temp.z += i * b1len; break; default: SC_ABORT_NOT_REACHED (); } if ((temp.x & pmask) != porig.x || (temp.y & pmask) != porig.y || (temp.z & pmask) != porig.z) { /* only test other descendents of p */ continue; } child = p8est_edge_corners[edge][(1 - i) / 2]; p4est_bal_corner_con_internal (q, &temp, child, balance, &recon); if (!recon) { add[1 + i] = temp; } } } }
static void p4est_bal_face_con_internal (p4est_quadrant_t const *q, p4est_quadrant_t * p, int face, int balance, int *consistent, p4est_quadrant_t * add) { int qlevel = q->level; int plevel = p->level; int blevel; int child; #ifdef P4_TO_P8 int edge; int dual; int achild = -1; #endif int recon; p4est_quadrant_t porig; p4est_quadrant_t temp; p4est_quadrant_t a; int i; #ifndef P4_TO_P8 int nconextra = 3; #else int nconextra = 9; int j; p4est_qcoord_t b2mask; #endif p4est_qcoord_t distance; p4est_qcoord_t qlen, plen, mask, pmask; p4est_qcoord_t b1len; P4EST_ASSERT (p4est_quadrant_is_extended (q)); P4EST_ASSERT (p4est_quadrant_is_extended (p)); if (qlevel <= plevel) { if (consistent != NULL) { *consistent = 1; } return; } qlen = P4EST_QUADRANT_LEN (qlevel); plen = P4EST_QUADRANT_LEN (plevel); switch (face) { case 0: distance = p->x - q->x; break; case 1: distance = (q->x + qlen) - (p->x + plen); break; case 2: distance = p->y - q->y; break; case 3: distance = (q->y + qlen) - (p->y + plen); break; #ifdef P4_TO_P8 case 4: distance = p->z - q->z; break; case 5: distance = (q->z + qlen) - (p->z + plen); break; #endif default: SC_ABORT_NOT_REACHED (); } P4EST_ASSERT (distance >= 0); blevel = p4est_balance_kernel_1d (distance, q->level); if (blevel <= plevel) { if (consistent != NULL) { *consistent = 1; } return; } if (consistent != NULL) { *consistent = 0; } porig = *p; *p = *q; /* shift a until it is inside p */ switch (face) { case 0: p->x += distance; break; case 1: p->x -= distance; break; case 2: p->y += distance; break; case 3: p->y -= distance; break; #ifdef P4_TO_P8 case 4: p->z += distance; break; case 5: p->z -= distance; break; #endif default: SC_ABORT_NOT_REACHED (); } mask = -1 << (P4EST_MAXLEVEL - blevel); p->x &= mask; p->y &= mask; #ifdef P4_TO_P8 p->z &= mask; #endif p->level = blevel; P4EST_ASSERT (p4est_quadrant_is_extended (p)); if (add != NULL) { add[nconextra / 2] = *p; /* this is the only quad needed if it is only one level smaller than the * original quadrant */ if (blevel == plevel - 1) { return; } mask = -1 << (P4EST_MAXLEVEL - (blevel - 1)); pmask = -1 << (P4EST_MAXLEVEL - (plevel)); a = *p; a.x &= mask; a.y &= mask; #ifdef P4_TO_P8 a.z &= mask; #endif a.level = blevel - 1; b1len = P4EST_QUADRANT_LEN (blevel - 1); #ifndef P4_TO_P8 for (i = -1; i <= 1; i += 2) { temp = a; /* temp is in a family group one family group over from temp */ if (face / 2 == 0) { temp.y += i * b1len; } else { temp.x += i * b1len; } if ((temp.x & pmask) != porig.x || (temp.y & pmask) != porig.y) { /* only test other descendents of p */ continue; } child = p4est_face_corners[face][(1 - i) / 2]; p4est_bal_corner_con_internal (q, &temp, child, balance, &recon); if (!recon) { add[1 + i] = temp; } } #else b2mask = -1 << (P4EST_MAXLEVEL - (blevel - 2)); if (!balance) { achild = p8est_quadrant_child_id (&a); } for (j = -1; j <= 1; j++) { for (i = -1; i <= 1; i++) { if (!i & !j) { continue; } temp = a; switch (face / 2) { case 0: temp.y += i * b1len; temp.z += j * b1len; break; case 1: temp.x += i * b1len; temp.z += j * b1len; break; case 2: temp.x += i * b1len; temp.y += j * b1len; break; default: SC_ABORT_NOT_REACHED (); } if ((temp.x & pmask) != porig.x || (temp.y & pmask) != porig.y || (temp.z & pmask) != porig.z) { /* only test other descendents of p */ continue; } if (i && j) { child = p8est_face_corners[face][(1 - j) + (1 - i) / 2]; /* for face only balance, we need to check a larger neighbor in one * instance */ if (!balance) { dual = p8est_face_corners[face][(1 + j) + (1 + i) / 2]; if (achild == dual) { temp.x &= b2mask; temp.y &= b2mask; temp.z &= b2mask; temp.level = blevel - 2; } } p4est_bal_corner_con_internal (q, &temp, child, balance, &recon); if (!recon) { add[4 + 3 * j + i] = temp; } } else { if (!i) { edge = p8est_face_edges[face][(1 - j) / 2]; } else { edge = p8est_face_edges[face][2 + (1 - i) / 2]; } p8est_bal_edge_con_internal (q, &temp, edge, balance, &recon, NULL); if (!recon) { add[4 + 3 * j + i] = temp; } } } } if (!balance) { for (j = -1; j <= 1; j += 2) { for (i = -1; i <= 1; i += 2) { if (add[4 + 3 * j + i].level != -1 && add[4 + 3 * j + i].level < blevel) { if (add[4 + 3 * j].level != -1 || add[4 + i].level != -1) { memset (&(add[4 + 3 * j + i]), -1, sizeof (p4est_quadrant_t)); } } } } } #endif } }
/* \a corner is the corner of \a p closest to \a q: the corner of \a q closest * to \a p is the dual of \a corner */ static void p4est_bal_corner_con_internal (p4est_quadrant_t const *q, p4est_quadrant_t * p, int corner, int balance, int *consistent) { int qlevel = q->level; int plevel = p->level; int blevel; p4est_qcoord_t qlen, plen, mask; p4est_qcoord_t dx, dy, dist; #ifdef P4_TO_P8 p4est_qcoord_t dz; #endif P4EST_ASSERT (p4est_quadrant_is_extended (q)); P4EST_ASSERT (p4est_quadrant_is_extended (p)); if (qlevel <= plevel) { if (consistent != NULL) { *consistent = 1; } return; } qlen = P4EST_QUADRANT_LEN (qlevel); plen = P4EST_QUADRANT_LEN (plevel); dx = (corner & 1) ? ((q->x + qlen) - (p->x + plen)) : p->x - q->x; P4EST_ASSERT (dx >= 0); dy = (corner & 2) ? ((q->y + qlen) - (p->y + plen)) : p->y - q->y; P4EST_ASSERT (dy >= 0); #ifdef P4_TO_P8 dz = (corner & 4) ? ((q->z + qlen) - (p->z + plen)) : p->z - q->z; P4EST_ASSERT (dz >= 0); #endif #ifndef P4_TO_P8 if (balance) { dist = SC_MAX (dx, dy); blevel = p4est_balance_kernel_1d (dist, qlevel); } else { blevel = p4est_balance_kernel_2d (dx, dy, qlevel); } #else switch (balance) { case 0: blevel = p8est_balance_kernel_3d_face (dx, dy, dz, qlevel); break; case 1: blevel = p8est_balance_kernel_3d_edge (dx, dy, dz, qlevel); break; case 2: dist = SC_MAX (dx, dy); dist = SC_MAX (dist, dz); blevel = p4est_balance_kernel_1d (dist, qlevel); break; default: SC_ABORT_NOT_REACHED (); } #endif if (blevel <= plevel) { if (consistent != NULL) { *consistent = 1; } return; } if (consistent != NULL) { *consistent = 0; } mask = -1 << (P4EST_MAXLEVEL - blevel); p->x = q->x + ((corner & 1) ? -dx : dx); p->x &= mask; p->y = q->y + ((corner & 2) ? -dy : dy); p->y &= mask; #ifdef P4_TO_P8 p->z = q->z + ((corner & 4) ? -dz : dz); p->z &= mask; #endif p->level = blevel; P4EST_ASSERT (p4est_quadrant_is_extended (p)); }