int main (int argc, char **argv) { sc_MPI_Comm mpicomm; int mpiret; int mpisize, mpirank; unsigned crc; #ifndef P4_TO_P8 size_t kz; int8_t l; p4est_quadrant_t *q; p4est_tree_t stree, *tree = &stree; #endif p4est_t *p4est; p4est_connectivity_t *connectivity; /* initialize MPI */ mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpicomm = sc_MPI_COMM_WORLD; mpiret = sc_MPI_Comm_size (mpicomm, &mpisize); SC_CHECK_MPI (mpiret); mpiret = sc_MPI_Comm_rank (mpicomm, &mpirank); SC_CHECK_MPI (mpiret); sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); #ifndef P4_TO_P8 connectivity = p4est_connectivity_new_star (); #else connectivity = p8est_connectivity_new_rotcubes (); #endif p4est = p4est_new_ext (mpicomm, connectivity, 0, 0, 0, 4, NULL, NULL); #ifndef P4_TO_P8 /* build empty tree */ sc_array_init (&tree->quadrants, sizeof (p4est_quadrant_t)); for (l = 0; l <= P4EST_MAXLEVEL; ++l) { tree->quadrants_per_level[l] = 0; } tree->maxlevel = 0; /* insert two quadrants */ sc_array_resize (&tree->quadrants, 4); q = p4est_quadrant_array_index (&tree->quadrants, 0); p4est_quadrant_set_morton (q, 3, 13); q = p4est_quadrant_array_index (&tree->quadrants, 1); p4est_quadrant_set_morton (q, 1, 1); q = p4est_quadrant_array_index (&tree->quadrants, 2); p4est_quadrant_set_morton (q, 1, 2); q = p4est_quadrant_array_index (&tree->quadrants, 3); p4est_quadrant_set_morton (q, 1, 3); for (kz = 0; kz < tree->quadrants.elem_count; ++kz) { q = p4est_quadrant_array_index (&tree->quadrants, kz); q->p.user_data = sc_mempool_alloc (p4est->user_data_pool); ++tree->quadrants_per_level[q->level]; tree->maxlevel = (int8_t) SC_MAX (tree->maxlevel, q->level); } /* balance the tree, print and destroy */ #if 0 p4est_balance_subtree (p4est, P4EST_CONNECT_FULL, 0, NULL); p4est_tree_print (SC_LP_INFO, tree); #endif for (kz = 0; kz < tree->quadrants.elem_count; ++kz) { q = p4est_quadrant_array_index (&tree->quadrants, kz); sc_mempool_free (p4est->user_data_pool, q->p.user_data); } sc_array_reset (&tree->quadrants); #endif /* !P4_TO_P8 */ /* check reset data function */ p4est_reset_data (p4est, 0, init_fn, NULL); p4est_reset_data (p4est, 0, NULL, NULL); /* refine and balance the forest */ SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 1"); p4est_refine (p4est, 1, refine_fn, NULL); SC_CHECK_ABORT (!p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 2"); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 3"); /* check reset data function */ p4est_reset_data (p4est, 17, NULL, NULL); p4est_reset_data (p4est, 8, init_fn, NULL); /* checksum and partition */ crc = p4est_checksum (p4est); p4est_partition (p4est, 0, NULL); SC_CHECK_ABORT (p4est_checksum (p4est) == crc, "Partition"); SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 4"); /* check reset data function */ p4est_reset_data (p4est, 3, NULL, NULL); p4est_reset_data (p4est, 3, NULL, NULL); /* checksum and rebalance */ crc = p4est_checksum (p4est); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); SC_CHECK_ABORT (p4est_checksum (p4est) == crc, "Rebalance"); /* clean up and exit */ P4EST_ASSERT (p4est->user_data_pool->elem_count == (size_t) p4est->local_num_quadrants); p4est_destroy (p4est); p4est_connectivity_destroy (connectivity); sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
p4est_mesh_t * p4est_mesh_new_ext (p4est_t * p4est, p4est_ghost_t * ghost, int compute_tree_index, int compute_level_lists, p4est_connect_type_t btype) { int do_corner = 0; int do_volume = 0; int rank; p4est_locidx_t lq, ng; p4est_locidx_t jl; p4est_mesh_t *mesh; P4EST_ASSERT (p4est_is_balanced (p4est, btype)); mesh = P4EST_ALLOC_ZERO (p4est_mesh_t, 1); lq = mesh->local_num_quadrants = p4est->local_num_quadrants; ng = mesh->ghost_num_quadrants = (p4est_locidx_t) ghost->ghosts.elem_count; if (btype == P4EST_CONNECT_FULL) { do_corner = 1; } do_volume = (compute_tree_index || compute_level_lists ? 1 : 0); /* Optional map of tree index for each quadrant */ if (compute_tree_index) { mesh->quad_to_tree = P4EST_ALLOC (p4est_topidx_t, lq); } mesh->ghost_to_proc = P4EST_ALLOC (int, ng); mesh->quad_to_quad = P4EST_ALLOC (p4est_locidx_t, P4EST_FACES * lq); mesh->quad_to_face = P4EST_ALLOC (int8_t, P4EST_FACES * lq); mesh->quad_to_half = sc_array_new (P4EST_HALF * sizeof (p4est_locidx_t)); /* Optional per-level lists of quadrants */ if (compute_level_lists) { mesh->quad_level = P4EST_ALLOC (sc_array_t, P4EST_QMAXLEVEL + 1); for (jl = 0; jl <= P4EST_QMAXLEVEL; ++jl) { sc_array_init (mesh->quad_level + jl, sizeof (p4est_locidx_t)); } } /* Populate ghost information */ rank = 0; for (jl = 0; jl < ng; ++jl) { while (ghost->proc_offsets[rank + 1] <= jl) { ++rank; P4EST_ASSERT (rank < p4est->mpisize); } mesh->ghost_to_proc[jl] = rank; } /* Fill face arrays with default values */ memset (mesh->quad_to_quad, -1, P4EST_FACES * lq * sizeof (p4est_locidx_t)); memset (mesh->quad_to_face, -25, P4EST_FACES * lq * sizeof (int8_t)); if (do_corner) { /* Initialize corner information to a consistent state */ mesh->quad_to_corner = P4EST_ALLOC (p4est_locidx_t, P4EST_CHILDREN * lq); memset (mesh->quad_to_corner, -1, P4EST_CHILDREN * lq * sizeof (p4est_locidx_t)); mesh->corner_offset = sc_array_new (sizeof (p4est_locidx_t)); *(p4est_locidx_t *) sc_array_push (mesh->corner_offset) = 0; mesh->corner_quad = sc_array_new (sizeof (p4est_locidx_t)); mesh->corner_corner = sc_array_new (sizeof (int8_t)); } /* Call the forest iterator to collect face connectivity */ p4est_iterate (p4est, ghost, mesh, (do_volume ? mesh_iter_volume : NULL), mesh_iter_face, #ifdef P4_TO_P8 NULL, #endif do_corner ? mesh_iter_corner : NULL); return mesh; }