int main (int argc, char **argv) { int i, i1, i2, i3, i3last, i4, i4last, temp, count; size_t s, swaps1, swaps2, swaps3, total1, total2, total3; ssize_t searched; int *pi; sc_array_t *a1, *a2, *a3, *a4; int mpiret; double start, elapsed_pqueue, elapsed_qsort; mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_DEFAULT); a1 = sc_array_new (sizeof (int)); a2 = sc_array_new (sizeof (int)); a3 = sc_array_new (sizeof (int)); a4 = sc_array_new (sizeof (int)); #ifdef THEBIGTEST count = 325323; #else count = 3251; #endif SC_INFOF ("Test pqueue with count %d\n", count); start = -sc_MPI_Wtime (); swaps1 = swaps2 = swaps3 = 0; total1 = total2 = total3 = 0; for (i = 0; i < count; ++i) { *(int *) sc_array_push (a1) = i; s = sc_array_pqueue_add (a1, &temp, compar); swaps1 += ((s > 0) ? 1 : 0); total1 += s; *(int *) sc_array_push (a2) = count - i - 1; s = sc_array_pqueue_add (a2, &temp, compar); swaps2 += ((s > 0) ? 1 : 0); total2 += s; *(int *) sc_array_push (a3) = (15 * i) % 172; s = sc_array_pqueue_add (a3, &temp, compar); swaps3 += ((s > 0) ? 1 : 0); total3 += s; } SC_CHECK_ABORT (swaps1 == 0 && total1 == 0, "pqueue_add"); SC_VERBOSEF (" Swaps %lld %lld %lld Total %lld %lld %lld\n", (long long) swaps1, (long long) swaps2, (long long) swaps3, (long long) total1, (long long) total2, (long long) total3); temp = 52; searched = sc_array_bsearch (a1, &temp, compar); SC_CHECK_ABORT (searched != -1, "array_bsearch_index"); pi = (int *) sc_array_index_ssize_t (a1, searched); SC_CHECK_ABORT (*pi == temp, "array_bsearch"); i3last = -1; swaps1 = swaps2 = swaps3 = 0; total1 = total2 = total3 = 0; for (i = 0; i < count; ++i) { s = sc_array_pqueue_pop (a1, &i1, compar); swaps1 += ((s > 0) ? 1 : 0); total1 += s; s = sc_array_pqueue_pop (a2, &i2, compar); swaps2 += ((s > 0) ? 1 : 0); total2 += s; s = sc_array_pqueue_pop (a3, &i3, compar); swaps3 += ((s > 0) ? 1 : 0); total3 += s; SC_CHECK_ABORT (i == i1 && i == i2, "pqueue_pop"); SC_CHECK_ABORT (i3 >= i3last, "pqueue_pop"); i3last = i3; } SC_VERBOSEF (" Swaps %lld %lld %lld Total %lld %lld %lld\n", (long long) swaps1, (long long) swaps2, (long long) swaps3, (long long) total1, (long long) total2, (long long) total3); elapsed_pqueue = start + sc_MPI_Wtime (); sc_array_destroy (a1); sc_array_destroy (a2); sc_array_destroy (a3); SC_INFOF ("Test array sort with count %d\n", count); start = -sc_MPI_Wtime (); /* the resize is done to be comparable with the above procedure */ for (i = 0; i < count; ++i) { *(int *) sc_array_push (a4) = (15 * i) % 172; } sc_array_sort (a4, compar); i4last = -1; for (i = 0; i < count; ++i) { i4 = *(int *) sc_array_index_int (a4, i); SC_CHECK_ABORT (i4 >= i4last, "array_sort"); i4last = i4; } sc_array_resize (a4, 0); elapsed_qsort = start + sc_MPI_Wtime (); SC_STATISTICSF ("Test timings pqueue %g qsort %g\n", elapsed_pqueue, 3. * elapsed_qsort); sc_array_destroy (a4); sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
static void test_loadsave (p4est_connectivity_t * connectivity, const char *prefix, MPI_Comm mpicomm, int mpirank) { int mpiret; double elapsed, wtime; p4est_connectivity_t *conn2; p4est_t *p4est, *p4est2; sc_statinfo_t stats[STATS_COUNT]; char conn_name[BUFSIZ]; char p4est_name[BUFSIZ]; snprintf (conn_name, BUFSIZ, "%s.%s", prefix, P4EST_CONN_SUFFIX); snprintf (p4est_name, BUFSIZ, "%s.%s", prefix, P4EST_FOREST_SUFFIX); P4EST_GLOBAL_INFOF ("Using file names %s and %s\n", conn_name, p4est_name); p4est = p4est_new_ext (mpicomm, connectivity, 0, 0, 0, sizeof (int), init_fn, NULL); p4est_refine (p4est, 1, refine_fn, init_fn); /* save, synchronize, load connectivity and compare */ if (mpirank == 0) { p4est_connectivity_save (conn_name, connectivity); } mpiret = MPI_Barrier (mpicomm); SC_CHECK_MPI (mpiret); wtime = MPI_Wtime (); conn2 = p4est_connectivity_load (conn_name, NULL); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_CONN_LOAD, elapsed, "conn load"); SC_CHECK_ABORT (p4est_connectivity_is_equal (connectivity, conn2), "load/save connectivity mismatch A"); p4est_connectivity_destroy (conn2); /* save, synchronize, load p4est and compare */ wtime = MPI_Wtime (); p4est_save (p4est_name, p4est, 1); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_SAVE1, elapsed, "p4est save 1"); wtime = MPI_Wtime (); p4est2 = p4est_load (p4est_name, mpicomm, sizeof (int), 1, NULL, &conn2); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_LOAD1a, elapsed, "p4est load 1a"); SC_CHECK_ABORT (p4est_connectivity_is_equal (connectivity, conn2), "load/save connectivity mismatch Ba"); SC_CHECK_ABORT (p4est_is_equal (p4est, p4est2, 1), "load/save p4est mismatch Ba"); p4est_destroy (p4est2); p4est_connectivity_destroy (conn2); wtime = MPI_Wtime (); p4est2 = p4est_load (p4est_name, mpicomm, sizeof (char), 0, NULL, &conn2); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_LOAD1b, elapsed, "p4est load 1b"); SC_CHECK_ABORT (p4est_connectivity_is_equal (connectivity, conn2), "load/save connectivity mismatch Bb"); SC_CHECK_ABORT (p4est_is_equal (p4est, p4est2, 0), "load/save p4est mismatch Bb"); p4est_destroy (p4est2); p4est_connectivity_destroy (conn2); /* partition and balance */ p4est_partition (p4est, NULL); p4est_balance (p4est, P4EST_CONNECT_FULL, init_fn); sc_stats_set1 (stats + STATS_P4EST_ELEMS, (double) p4est->local_num_quadrants, "p4est elements"); /* save, synchronize, load p4est and compare */ wtime = MPI_Wtime (); p4est_save (p4est_name, p4est, 0); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_SAVE2, elapsed, "p4est save 2"); wtime = MPI_Wtime (); p4est2 = p4est_load (p4est_name, mpicomm, sizeof (int), 0, NULL, &conn2); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_LOAD2, elapsed, "p4est load 2"); SC_CHECK_ABORT (p4est_connectivity_is_equal (connectivity, conn2), "load/save connectivity mismatch C"); SC_CHECK_ABORT (p4est_is_equal (p4est, p4est2, 0), "load/save p4est mismatch C"); p4est_destroy (p4est2); p4est_connectivity_destroy (conn2); /* save, synchronize, load p4est and compare */ wtime = MPI_Wtime (); p4est_save (p4est_name, p4est, 1); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_SAVE3, elapsed, "p4est save 3"); wtime = MPI_Wtime (); p4est2 = p4est_load (p4est_name, mpicomm, sizeof (int), 0, NULL, &conn2); elapsed = MPI_Wtime () - wtime; sc_stats_set1 (stats + STATS_P4EST_LOAD3, elapsed, "p4est load 3"); SC_CHECK_ABORT (p4est_connectivity_is_equal (connectivity, conn2), "load/save connectivity mismatch D"); SC_CHECK_ABORT (p4est_is_equal (p4est, p4est2, 0), "load/save p4est mismatch D"); p4est_destroy (p4est2); p4est_connectivity_destroy (conn2); /* destroy data structures */ p4est_destroy (p4est); /* compute and print timings */ sc_stats_compute (mpicomm, STATS_COUNT, stats); sc_stats_print (p4est_package_id, SC_LP_STATISTICS, STATS_COUNT, stats, 0, 1); }
int main (int argc, char **argv) { MPI_Comm mpicomm; int mpiret; int mpirank; int first_arg; const char *prefix; p4est_connectivity_t *connectivity; sc_options_t *opt; /* initialize MPI */ mpiret = MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpicomm = MPI_COMM_WORLD; mpiret = MPI_Comm_rank (mpicomm, &mpirank); SC_CHECK_MPI (mpiret); /* initialize libsc and p4est */ sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); /* handle command line options */ opt = sc_options_new (argv[0]); sc_options_add_int (opt, 'l', "level", &refine_level, default_refine_level, "Refinement level"); sc_options_add_string (opt, 'o', "oprefix", &prefix, P4EST_STRING, "Output prefix"); first_arg = sc_options_parse (p4est_package_id, SC_LP_INFO, opt, argc, argv); SC_CHECK_ABORT (first_arg >= 0, "Option error"); /* create connectivity */ #ifndef P4_TO_P8 connectivity = p4est_connectivity_new_star (); #else connectivity = p8est_connectivity_new_rotcubes (); #endif /* test with vertex information */ test_loadsave (connectivity, prefix, mpicomm, mpirank); /* test without vertex information */ connectivity->num_vertices = 0; P4EST_FREE (connectivity->vertices); connectivity->vertices = NULL; P4EST_FREE (connectivity->tree_to_vertex); connectivity->tree_to_vertex = NULL; p4est_connectivity_set_attr (connectivity, 1); memset (connectivity->tree_to_attr, 0, connectivity->num_trees * sizeof (int8_t)); test_loadsave (connectivity, prefix, mpicomm, mpirank); /* clean up and exit */ p4est_connectivity_destroy (connectivity); sc_options_destroy (opt); sc_finalize (); mpiret = MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
int main (int argc, char **argv) { int rank; int num_procs; int mpiret; sc_MPI_Comm mpicomm; p4est_t *p4est, *copy; p4est_connectivity_t *connectivity; int i; p4est_topidx_t t; size_t qz; p4est_locidx_t num_quadrants_on_last; p4est_locidx_t *num_quadrants_in_proc; p4est_gloidx_t *pertree1, *pertree2; p4est_quadrant_t *quad; p4est_tree_t *tree; user_data_t *user_data; int64_t sum; unsigned crc; mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpicomm = sc_MPI_COMM_WORLD; mpiret = sc_MPI_Comm_rank (mpicomm, &rank); SC_CHECK_MPI (mpiret); sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT); /* create connectivity and forest structures */ #ifdef P4_TO_P8 connectivity = p8est_connectivity_new_twocubes (); #else connectivity = p4est_connectivity_new_corner (); #endif p4est = p4est_new_ext (mpicomm, connectivity, 15, 0, 0, sizeof (user_data_t), init_fn, NULL); pertree1 = P4EST_ALLOC (p4est_gloidx_t, p4est->connectivity->num_trees + 1); pertree2 = P4EST_ALLOC (p4est_gloidx_t, p4est->connectivity->num_trees + 1); num_procs = p4est->mpisize; num_quadrants_in_proc = P4EST_ALLOC (p4est_locidx_t, num_procs); /* refine and balance to make the number of elements interesting */ test_pertree (p4est, NULL, pertree1); p4est_refine (p4est, 1, refine_fn, init_fn); test_pertree (p4est, NULL, pertree1); /* Set an arbitrary partition. * * Since this is just a test we assume the global number of * quadrants will fit in an int32_t */ num_quadrants_on_last = (p4est_locidx_t) p4est->global_num_quadrants; for (i = 0; i < num_procs - 1; ++i) { num_quadrants_in_proc[i] = (p4est_locidx_t) i + 1; /* type ok */ num_quadrants_on_last -= (p4est_locidx_t) i + 1; /* type ok */ } num_quadrants_in_proc[num_procs - 1] = num_quadrants_on_last; SC_CHECK_ABORT (num_quadrants_on_last > 0, "Negative number of quadrants on the last processor"); /* Save a checksum of the original forest */ crc = p4est_checksum (p4est); /* partition the forest */ (void) p4est_partition_given (p4est, num_quadrants_in_proc); test_pertree (p4est, pertree1, pertree2); /* Double check that we didn't loose any quads */ SC_CHECK_ABORT (crc == p4est_checksum (p4est), "bad checksum, missing a quad"); /* count the actual number of quadrants per proc */ SC_CHECK_ABORT (num_quadrants_in_proc[rank] == p4est->local_num_quadrants, "partition failed, wrong number of quadrants"); /* check user data content */ for (t = p4est->first_local_tree; t <= p4est->last_local_tree; ++t) { tree = p4est_tree_array_index (p4est->trees, t); for (qz = 0; qz < tree->quadrants.elem_count; ++qz) { quad = p4est_quadrant_array_index (&tree->quadrants, qz); user_data = (user_data_t *) quad->p.user_data; sum = quad->x + quad->y + quad->level; SC_CHECK_ABORT (user_data->a == t, "bad user_data, a"); SC_CHECK_ABORT (user_data->sum == sum, "bad user_data, sum"); } } /* do a weighted partition with uniform weights */ p4est_partition (p4est, 0, weight_one); test_pertree (p4est, pertree1, pertree2); SC_CHECK_ABORT (crc == p4est_checksum (p4est), "bad checksum after uniformly weighted partition"); /* copy the p4est */ copy = p4est_copy (p4est, 1); SC_CHECK_ABORT (crc == p4est_checksum (copy), "bad checksum after copy"); /* do a weighted partition with many zero weights */ weight_counter = 0; weight_index = (rank == 1) ? 1342 : 0; p4est_partition (copy, 0, weight_once); test_pertree (copy, pertree1, pertree2); SC_CHECK_ABORT (crc == p4est_checksum (copy), "bad checksum after unevenly weighted partition 1"); /* do a weighted partition with many zero weights */ weight_counter = 0; weight_index = 0; p4est_partition (copy, 0, weight_once); test_pertree (copy, pertree1, pertree2); SC_CHECK_ABORT (crc == p4est_checksum (copy), "bad checksum after unevenly weighted partition 2"); /* do a weighted partition with many zero weights * * Since this is just a test we assume the local number of * quadrants will fit in an int */ weight_counter = 0; weight_index = (rank == num_procs - 1) ? ((int) copy->local_num_quadrants - 1) : 0; p4est_partition (copy, 0, weight_once); test_pertree (copy, pertree1, pertree2); SC_CHECK_ABORT (crc == p4est_checksum (copy), "bad checksum after unevenly weighted partition 3"); /* check user data content */ for (t = copy->first_local_tree; t <= copy->last_local_tree; ++t) { tree = p4est_tree_array_index (copy->trees, t); for (qz = 0; qz < tree->quadrants.elem_count; ++qz) { quad = p4est_quadrant_array_index (&tree->quadrants, qz); user_data = (user_data_t *) quad->p.user_data; sum = quad->x + quad->y + quad->level; SC_CHECK_ABORT (user_data->a == t, "bad user_data, a"); SC_CHECK_ABORT (user_data->sum == sum, "bad user_data, sum"); } } /* Add another test. Overwrites pertree1, pertree2 */ test_partition_circle (mpicomm, connectivity, pertree1, pertree2); /* clean up and exit */ P4EST_FREE (pertree1); P4EST_FREE (pertree2); P4EST_FREE (num_quadrants_in_proc); p4est_destroy (p4est); p4est_destroy (copy); p4est_connectivity_destroy (connectivity); sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
static void test_partition_circle (sc_MPI_Comm mpicomm, p4est_connectivity_t * connectivity, p4est_gloidx_t * pertree1, p4est_gloidx_t * pertree2) { int i, j; int num_procs; int empty_proc1, empty_proc2; unsigned crc1, crc2; p4est_gloidx_t global_num; p4est_locidx_t *new_counts; p4est_t *p4est, *copy; /* Create a forest and make a copy */ circle_count = 0; p4est = p4est_new_ext (mpicomm, connectivity, 0, 3, 1, sizeof (int), circle_init, NULL); num_procs = p4est->mpisize; test_pertree (p4est, NULL, pertree1); global_num = p4est->global_num_quadrants; crc1 = p4est_checksum (p4est); copy = p4est_copy (p4est, 1); P4EST_ASSERT (p4est_checksum (copy) == crc1); new_counts = P4EST_ALLOC (p4est_locidx_t, num_procs); /* Partition with one empty processor */ if (num_procs > 1) { P4EST_GLOBAL_INFO ("First circle partition\n"); empty_proc1 = num_procs / 3; j = 0; for (i = 0; i < num_procs; ++i) { if (i == empty_proc1) { new_counts[i] = 0; } else { new_counts[i] = p4est_partition_cut_gloidx (global_num, j + 1, num_procs - 1) - p4est_partition_cut_gloidx (global_num, j, num_procs - 1); P4EST_ASSERT (new_counts[i] >= 0); ++j; } } P4EST_ASSERT (j == num_procs - 1); p4est_partition_given (p4est, new_counts); test_pertree (p4est, pertree1, pertree2); crc2 = p4est_checksum (p4est); SC_CHECK_ABORT (crc1 == crc2, "First checksum mismatch"); } /* Partition with two empty processors */ if (num_procs > 2) { P4EST_GLOBAL_INFO ("Second circle partition\n"); empty_proc1 = (2 * num_procs) / 3 - 2; empty_proc2 = (2 * num_procs) / 3; j = 0; for (i = 0; i < num_procs; ++i) { if (i == empty_proc1 || i == empty_proc2) { new_counts[i] = 0; } else { new_counts[i] = p4est_partition_cut_gloidx (global_num, j + 1, num_procs - 2) - p4est_partition_cut_gloidx (global_num, j, num_procs - 2); P4EST_ASSERT (new_counts[i] >= 0); ++j; } } P4EST_ASSERT (j == num_procs - 2); p4est_partition_given (p4est, new_counts); test_pertree (p4est, pertree1, pertree2); crc2 = p4est_checksum (p4est); SC_CHECK_ABORT (crc1 == crc2, "Second checksum mismatch"); } /* Uniform partition */ P4EST_GLOBAL_INFO ("Third circle partition\n"); p4est_partition (p4est, 0, NULL); test_pertree (p4est, pertree1, pertree2); crc2 = p4est_checksum (p4est); SC_CHECK_ABORT (crc1 == crc2, "Third checksum mismatch"); SC_CHECK_ABORT (p4est_is_equal (p4est, copy, 1), "Forest mismatch"); P4EST_FREE (new_counts); p4est_destroy (copy); p4est_destroy (p4est); }
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, c4, c5, c6, c7; 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; const int indices[27] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 9, 11, 13, 18, 19, 22, 23, 27, 31, 36, 37, 38, 39, 45, 47, 54, 55, 63 }; /* initialize MPI */ mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); /* create connectivity and forest structures */ connectivity = p8est_connectivity_new_unitcube (); 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 */ p8est_quadrant_children (q1, &c0, &c1, &c2, &c3, &c4, &c5, &c6, &c7); SC_CHECK_ABORT (p8est_quadrant_is_family (&c0, &c1, &c2, &c3, &c4, &c5, &c6, &c7), "is_family"); SC_CHECK_ABORT (!p8est_quadrant_is_family (&c1, &c0, &c2, &c3, &c4, &c5, &c6, &c7), "is_family"); SC_CHECK_ABORT (!p8est_quadrant_is_family (&c0, &c1, &c2, &c3, &c4, &c5, &c5, &c7), "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_equal (&c4, &cv[4]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c5, &cv[5]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c6, &cv[6]), "is_family"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c7, &cv[7]), "is_family"); SC_CHECK_ABORT (p8est_quadrant_is_family (&cv[0], &cv[1], &cv[2], &cv[3], &cv[4], &cv[5], &cv[6], &cv[7]), "is_family"); cp[0] = &cv[0]; cp[1] = &cv[1]; cp[2] = &cv[2]; cp[3] = &cv[3]; cp[4] = &cv[4]; cp[5] = &cv[5]; cp[6] = &cv[6]; cp[7] = &cv[7]; 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[6] = &c7; SC_CHECK_ABORT (!p4est_quadrant_is_familypv (cp), "is_family"); /* test the sibling function */ mid = p4est_quadrant_child_id (q1); for (cid = 0; cid < P4EST_CHILDREN; ++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, 4); q1 = p4est_quadrant_array_index (&tree.quadrants, 0); p4est_quadrant_set_morton (q1, 3, 191); q1 = p4est_quadrant_array_index (&tree.quadrants, 1); p4est_quadrant_set_morton (q1, 1, 3); q1 = p4est_quadrant_array_index (&tree.quadrants, 2); p4est_quadrant_set_morton (q1, 2, 32); q1 = p4est_quadrant_array_index (&tree.quadrants, 3); p4est_quadrant_set_morton (q1, 2, 33); 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.quadrants_per_level[3] = 1; tree.maxlevel = 3; 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, 2); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 2"); p4est_quadrant_set_morton (&A, 1, 3); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 3"); p4est_quadrant_set_morton (&A, 1, 4); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 4"); p4est_quadrant_set_morton (&A, 1, 5); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 5"); p4est_quadrant_set_morton (&B, 3, 13); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 6"); p4est_quadrant_set_morton (&B, 3, 191); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 7"); p4est_quadrant_set_morton (&B, 3, 271); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 8"); p4est_quadrant_set_morton (&B, 3, 272); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 9"); p4est_quadrant_set_morton (&C, 4, 2175); SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &C), "overlaps 10"); p4est_quadrant_set_morton (&C, 4, 2176); SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &C), "overlaps 11"); 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.z = 0; A.level = 0; B.x = qone << P4EST_MAXLEVEL; B.y = -qone << P4EST_MAXLEVEL; B.z = 0; B.level = 0; C.x = -qone << P4EST_MAXLEVEL; C.y = qone << P4EST_MAXLEVEL; C.z = 0; C.level = 0; D.x = qone << P4EST_MAXLEVEL; D.y = qone << P4EST_MAXLEVEL; D.z = 0; D.level = 0; /* this one is outside the 3x3 box */ E.x = -qone << (P4EST_MAXLEVEL + 1); E.y = -qone; E.z = -qone; E.level = 0; F.x = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh); F.y = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh); F.z = -qone << P4EST_MAXLEVEL; F.level = P4EST_QMAXLEVEL; G.x = -mh; G.y = -mh; G.z = -mh; G.level = P4EST_QMAXLEVEL; H.x = -qone << (P4EST_MAXLEVEL - 1); H.y = -qone << (P4EST_MAXLEVEL - 1); H.z = qone << (P4EST_MAXLEVEL - 1); H.level = 1; I.x = -qone << P4EST_MAXLEVEL; I.y = -qone << (P4EST_MAXLEVEL - 1); I.z = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh); I.level = P4EST_QMAXLEVEL; P.x = -qone << P4EST_MAXLEVEL; P.y = -qone << (P4EST_MAXLEVEL - 1); P.z = qone << (P4EST_MAXLEVEL - 1); P.level = 1; Q.x = -2 * mh; Q.y = -2 * mh; Q.z = (qone << P4EST_MAXLEVEL) - 2 * mh; Q.level = P4EST_QMAXLEVEL - 1; SC_CHECK_ABORT (p4est_quadrant_compare (&B, &F) < 0, "Comp 1"); SC_CHECK_ABORT (p4est_quadrant_compare (&A, &G) < 0, "Comp 2"); SC_CHECK_ABORT (p4est_quadrant_compare (&F, &G) < 0, "Comp 3"); SC_CHECK_ABORT (p4est_quadrant_compare (&A, &I) < 0, "Comp 4"); SC_CHECK_ABORT (p4est_quadrant_compare (&D, &C) < 0, "Comp 5"); SC_CHECK_ABORT (p4est_quadrant_compare (&B, &G) < 0, "Comp 6"); SC_CHECK_ABORT (p4est_quadrant_compare (&G, &G) == 0, "Comp 7"); 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); check_linear_id (&P, &F); check_linear_id (&P, &G); check_linear_id (&P, &H); check_linear_id (&P, &Q); check_linear_id (&Q, &F); check_linear_id (&Q, &B); check_linear_id (&Q, &H); check_linear_id (&Q, &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.piggy1.which_tree = 0; B.p.piggy2.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.which_tree = 0; G.p.piggy1.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.piggy2.which_tree = (p4est_topidx_t) P4EST_TOPIDX_MAX - 3; G.p.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"); SC_CHECK_ABORT (p4est_quadrant_is_sibling (&P, &H) == 1, "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_sibling (&A, &H) == 0, "is_sibling"); SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&P, &H) == 1, "is_sibling_D"); SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&A, &H) == 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, &Q) == 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, &Q) == 1, "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor (&A, &A) == 0, "is_ancestor"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (&A, &P) == 1, "is_ancestor_D"); SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (&G, &G) == 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 (&P, &h, 7); SC_CHECK_ABORT (p4est_quadrant_is_equal (&H, &h) == 1, "sibling"); p8est_quadrant_children (&A, &c0, &c1, &c2, &c3, &c4, &c5, &c6, &c7); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c6, &P) == 1, "children"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c7, &H) == 1, "children"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&c7, &Q) == 0, "children"); SC_CHECK_ABORT (p8est_quadrant_is_family (&c0, &c1, &c2, &c3, &c4, &c5, &c6, &c7) == 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 (&c6); SC_CHECK_ABORT (id0 == 0 && id1 == 1 && id2 == 2 && id3 == 6, "child_id"); SC_CHECK_ABORT (p4est_quadrant_child_id (&G) == 7, "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 - 1); SC_CHECK_ABORT (p4est_quadrant_is_equal (&Q, &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 == 27, "linear_id"); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "set_morton/linear_id"); p4est_nearest_common_ancestor (&P, &H, &a); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "ancestor"); p4est_nearest_common_ancestor_D (&P, &Q, &a); SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "ancestor_D"); for (k = 0; k < 27; ++k) { p4est_quadrant_set_morton (&E, 0, (uint64_t) indices[k]); } p4est_quadrant_set_morton (&P, 0, 54); p4est_quadrant_set_morton (&Q, 0, 55); 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; }
int main (int argc, char *argv[]) { MPI_Comm comm = MPI_COMM_WORLD; p4est_t *p4est; p4est_connectivity_t *conn; p4est_ghost_t *ghost_layer; p4est_lnodes_t *lnodes; int rank; const int degree = 1; BFAM_MPI_CHECK(MPI_Init(&argc,&argv)); BFAM_MPI_CHECK(MPI_Comm_rank(comm, &rank)); bfam_log_init(rank, stdout, BFAM_LL_DEFAULT); bfam_signal_handler_set(); sc_init(comm, 0, 0, NULL, SC_LP_DEFAULT); p4est_init(NULL, SC_LP_DEFAULT); conn = p4est_connectivity_new_corner(); p4est = p4est_new_ext(comm, conn, 0, 0, 0, 0, NULL, NULL); refine_level = 1; p4est_refine(p4est, 1, refine_fn, NULL); p4est_balance(p4est, P4EST_CONNECT_FACE, NULL); p4est_partition(p4est, 1, NULL); p4est_vtk_write_file(p4est, NULL, "mesh"); ghost_layer = p4est_ghost_new(p4est, P4EST_CONNECT_FULL); lnodes = p4est_lnodes_new(p4est, ghost_layer, degree); /* * Output the mesh. It can be read using something like following command: * * mpirun -np 3 ./bfam_exam_p4est | grep MESH | sort -n -k 2 | sort -n -k 5 | gvim - */ fflush(stdout); BFAM_MPI_CHECK(MPI_Barrier(comm)); BFAM_ROOT_INFO("MESH 0 ------------ Mesh Begin ------------"); BFAM_ROOT_INFO("MESH 1 degree = %d", lnodes->degree); BFAM_ROOT_INFO("MESH 2 vnodes = %d", lnodes->vnodes); BFAM_INFO("MESH 3 num_local_elements = %jd", (intmax_t)lnodes->num_local_elements); BFAM_INFO("MESH 4 num_local_nodes = %jd", (intmax_t)lnodes->num_local_nodes); BFAM_INFO("MESH 5 owned_count = %jd", (intmax_t)lnodes->owned_count); BFAM_INFO("MESH 6 global_offset = %jd", (intmax_t)lnodes->global_offset); sc_array_t *global_nodes = sc_array_new(sizeof (p4est_gloidx_t)); sc_array_resize(global_nodes, lnodes->num_local_nodes); for(size_t zz = 0; zz < global_nodes->elem_count; ++zz) { *((p4est_gloidx_t *) sc_array_index(global_nodes, zz)) = p4est_lnodes_global_index(lnodes, zz); } p4est_lnodes_share_owned(global_nodes, lnodes); for(size_t zz = 0; zz < global_nodes->elem_count; ++zz) { const p4est_gloidx_t gn = *((p4est_gloidx_t *)sc_array_index(global_nodes, zz)); SC_CHECK_ABORT (gn == p4est_lnodes_global_index(lnodes, zz), "Lnodes: bad global index across procesors"); BFAM_INFO("MESH 7 global_nodes[%zu] = %jd", zz, (intmax_t)gn); } sc_array_destroy(global_nodes); p4est_topidx_t flt = p4est->first_local_tree; p4est_topidx_t llt = p4est->last_local_tree; p4est_locidx_t elid, elnid; p4est_topidx_t t; const double *v = conn->vertices; const p4est_topidx_t *tree_to_vertex = conn->tree_to_vertex; for(elid = 0, elnid = 0, t = flt; t <= llt; ++t) { p4est_tree_t *tree = p4est_tree_array_index(p4est->trees, t); const size_t count = tree->quadrants.elem_count; p4est_topidx_t vt[P4EST_CHILDREN]; for (int c = 0; c < P4EST_CHILDREN; ++c) { vt[c] = tree_to_vertex[t * P4EST_CHILDREN + c]; } for (size_t zz = 0; zz < count; ++zz, ++elid) { p4est_quadrant_t *q = p4est_quadrant_array_index(&tree->quadrants, zz); for(int jind = 0; jind < degree + 1; ++jind) { for(int iind = 0; iind < degree + 1; ++iind, ++elnid) { double xyz[3]; for (int j = 0; j < 3; ++j) { const p4est_qcoord_t len = P4EST_QUADRANT_LEN(q->level); const double rlen = (double) P4EST_ROOT_LEN; const double deg = (double) degree; const double qlen = ((double) len) / rlen; const double eta_x = ((double) q->x) / rlen + (((double) iind) / deg) * qlen; const double eta_y = ((double) q->y) / rlen + (((double) jind) / deg) * qlen; xyz[j] = ((1. - eta_y) * ((1. - eta_x) * v[3 * vt[0] + j] + eta_x * v[3 * vt[1] + j]) + eta_y * ((1. - eta_x) * v[3 * vt[2] + j] + eta_x * v[3 * vt[3] + j])); } const p4est_locidx_t nid = lnodes->element_nodes[elnid]; BFAM_INFO( "MESH 8 local_node[%03jd] = %03jd ( %25.16e %25.16e %25.16e )", (intmax_t)elnid, (intmax_t)nid, xyz[0], xyz[1], xyz[2]); } } } } BFAM_ROOT_INFO("MESH 9 ------------ Mesh End ------------"); p4est_lnodes_destroy(lnodes); p4est_ghost_destroy(ghost_layer); p4est_destroy(p4est); p4est_connectivity_destroy(conn); sc_finalize(); BFAM_MPI_CHECK(MPI_Finalize()); return EXIT_SUCCESS; }
/* main */ int main (int argc, char **argv) { int rank, num_procs, mpiret, i; sc_MPI_Comm mpicomm = sc_MPI_COMM_WORLD; p4est_t *p4est_1tree, *p4est_ntrees; p4est_connectivity_t *connectivity_1tree, *connectivity_ntrees; /* initialize MPI and p4est internals */ mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpiret = sc_MPI_Comm_size (mpicomm, &num_procs); SC_CHECK_MPI (mpiret); mpiret = sc_MPI_Comm_rank (mpicomm, &rank); SC_CHECK_MPI (mpiret); sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); /* create connectivity */ #ifdef P4_TO_P8 connectivity_1tree = p8est_connectivity_new_unitcube (); connectivity_ntrees = p8est_connectivity_new_twocubes (); #else connectivity_1tree = p4est_connectivity_new_unitsquare (); connectivity_ntrees = p4est_connectivity_new_corner (); #endif /* create p4est structure */ p4est_1tree = p4est_new_ext (mpicomm, connectivity_1tree, 15, 0, 0, sizeof (user_data_t), init_fn, NULL); p4est_ntrees = p4est_new_ext (mpicomm, connectivity_ntrees, 15, 0, 0, sizeof (user_data_t), init_fn, NULL); /* write output: new */ p4est_vtk_write_file (p4est_1tree, NULL, P4EST_STRING "_partition_corr_1tree_new"); p4est_vtk_write_file (p4est_ntrees, NULL, P4EST_STRING "_partition_corr_ntrees_new"); /* refine */ p4est_refine (p4est_1tree, 1, refine_fn, init_fn); p4est_refine (p4est_ntrees, 1, refine_fn, init_fn); /* write output: refined */ p4est_vtk_write_file (p4est_1tree, NULL, P4EST_STRING "_partition_corr_1tree_refined"); p4est_vtk_write_file (p4est_ntrees, NULL, P4EST_STRING "_partition_corr_ntrees_refined"); /* run partition and coarsen till one quadrant per tree remains */ i = 0; while (p4est_1tree->global_num_quadrants > 1 && i <= P4EST_MAXLEVEL) { (void) p4est_partition_ext (p4est_1tree, 1, NULL); p4est_coarsen (p4est_1tree, 0, coarsen_fn, init_fn); i++; } SC_CHECK_ABORT (p4est_1tree->global_num_quadrants == 1, "coarsest forest with one tree was not achieved"); i = 0; while (p4est_ntrees->global_num_quadrants > connectivity_ntrees->num_trees && i <= P4EST_MAXLEVEL) { (void) p4est_partition_ext (p4est_ntrees, 1, NULL); p4est_coarsen (p4est_ntrees, 0, coarsen_fn, init_fn); i++; } SC_CHECK_ABORT (p4est_ntrees->global_num_quadrants == connectivity_ntrees->num_trees, "coarsest forest with multiple trees was not achieved"); /* run partition on coarse forest (one quadrant per tree) once again */ (void) p4est_partition_ext (p4est_1tree, 1, NULL); (void) p4est_partition_ext (p4est_ntrees, 1, NULL); /* write output: coarsened */ p4est_vtk_write_file (p4est_1tree, NULL, P4EST_STRING "_partition_corr_1tree_coarsened"); p4est_vtk_write_file (p4est_ntrees, NULL, P4EST_STRING "_partition_corr_ntrees_coarsened"); /* destroy the p4est and its connectivity structure */ p4est_destroy (p4est_1tree); p4est_destroy (p4est_ntrees); p4est_connectivity_destroy (connectivity_1tree); p4est_connectivity_destroy (connectivity_ntrees); /* clean up and exit */ sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }