p4est_wrap_t * p4est_wrap_new_copy (p4est_wrap_t * source, size_t data_size, p4est_replace_t replace_fn, void *user_pointer) { p4est_wrap_t *pp; P4EST_ASSERT (source != NULL); pp = P4EST_ALLOC_ZERO (p4est_wrap_t, 1); pp->hollow = 1; sc_refcount_init_invalid (&pp->conn_rc); pp->conn_owner = (source->conn_owner != NULL ? source->conn_owner : source); pp->conn = pp->conn_owner->conn; sc_refcount_ref (&pp->conn_owner->conn_rc); pp->p4est_dim = P4EST_DIM; pp->p4est_half = P4EST_HALF; pp->p4est_faces = P4EST_FACES; pp->p4est_children = P4EST_CHILDREN; pp->btype = source->btype; pp->replace_fn = replace_fn; pp->p4est = p4est_copy (source->p4est, 0); if (data_size > 0) { p4est_reset_data (pp->p4est, data_size, NULL, NULL); } pp->weight_exponent = 0; /* keep this even though using ALLOC_ZERO */ pp->p4est->user_pointer = pp; pp->user_pointer = user_pointer; return pp; }
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_t * p4est_new_points (sc_MPI_Comm mpicomm, p4est_connectivity_t * connectivity, int maxlevel, p4est_quadrant_t * points, p4est_locidx_t num_points, p4est_locidx_t max_points, size_t data_size, p4est_init_t init_fn, void *user_pointer) { int mpiret; int num_procs, rank; int i, isizet; size_t lcount; size_t *nmemb; #ifdef P4EST_ENABLE_DEBUG size_t zz; #endif p4est_topidx_t jt, num_trees; p4est_topidx_t first_tree, last_tree, next_tree; p4est_quadrant_t *first_quad, *next_quad, *quad; p4est_quadrant_t a, b, c, f, l, n; p4est_tree_t *tree; p4est_t *p4est; p4est_points_state_t ppstate; P4EST_GLOBAL_PRODUCTIONF ("Into " P4EST_STRING "_new_points with max level %d max points %lld\n", maxlevel, (long long) max_points); p4est_log_indent_push (); P4EST_ASSERT (p4est_connectivity_is_valid (connectivity)); P4EST_ASSERT (max_points >= -1); /* retrieve MPI information */ mpiret = sc_MPI_Comm_size (mpicomm, &num_procs); SC_CHECK_MPI (mpiret); mpiret = sc_MPI_Comm_rank (mpicomm, &rank); SC_CHECK_MPI (mpiret); /* This implementation runs in O(P/p * maxlevel) * with P the total number of points, p the number of processors. * Two optimizations are possible: * 1. At startup remove points that lead to duplicate quadrants. * 2. Use complete_region between successive points instead of * the call to refine. This should give O(N/p) * maxlevel * with N the total number of quadrants. */ /* parallel sort the incoming points */ lcount = (size_t) num_points; nmemb = P4EST_ALLOC_ZERO (size_t, num_procs); isizet = (int) sizeof (size_t); mpiret = sc_MPI_Allgather (&lcount, isizet, sc_MPI_BYTE, nmemb, isizet, sc_MPI_BYTE, mpicomm); SC_CHECK_MPI (mpiret); sc_psort (mpicomm, points, nmemb, sizeof (p4est_quadrant_t), p4est_quadrant_compare_piggy); P4EST_FREE (nmemb); #ifdef P4EST_ENABLE_DEBUG first_quad = points; for (zz = 1; zz < lcount; ++zz) { next_quad = points + zz; P4EST_ASSERT (p4est_quadrant_compare_piggy (first_quad, next_quad) <= 0); first_quad = next_quad; } #endif /* create the p4est */ p4est = P4EST_ALLOC_ZERO (p4est_t, 1); ppstate.points = points; ppstate.num_points = num_points; ppstate.max_points = max_points; ppstate.current = 0; ppstate.maxlevel = maxlevel; /* assign some data members */ p4est->data_size = 2 * sizeof (p4est_locidx_t); /* temporary */ p4est->user_pointer = &ppstate; p4est->connectivity = connectivity; num_trees = connectivity->num_trees; /* create parallel environment */ p4est_comm_parallel_env_create (p4est, mpicomm); /* allocate memory pools */ p4est->user_data_pool = sc_mempool_new (p4est->data_size); p4est->quadrant_pool = sc_mempool_new (sizeof (p4est_quadrant_t)); P4EST_GLOBAL_PRODUCTIONF ("New " P4EST_STRING " with %lld trees on %d processors\n", (long long) num_trees, num_procs); /* allocate trees */ p4est->trees = sc_array_new (sizeof (p4est_tree_t)); sc_array_resize (p4est->trees, num_trees); for (jt = 0; jt < num_trees; ++jt) { tree = p4est_tree_array_index (p4est->trees, jt); sc_array_init (&tree->quadrants, sizeof (p4est_quadrant_t)); P4EST_QUADRANT_INIT (&tree->first_desc); P4EST_QUADRANT_INIT (&tree->last_desc); tree->quadrants_offset = 0; for (i = 0; i <= P4EST_QMAXLEVEL; ++i) { tree->quadrants_per_level[i] = 0; } for (; i <= P4EST_MAXLEVEL; ++i) { tree->quadrants_per_level[i] = -1; } tree->maxlevel = 0; } p4est->local_num_quadrants = 0; p4est->global_num_quadrants = 0; /* create point based partition */ P4EST_QUADRANT_INIT (&f); p4est->global_first_position = P4EST_ALLOC_ZERO (p4est_quadrant_t, num_procs + 1); if (num_points == 0) { P4EST_VERBOSE ("Empty processor"); first_tree = p4est->first_local_tree = -1; first_quad = NULL; } else { /* we are probably not empty */ if (rank == 0) { first_tree = p4est->first_local_tree = 0; p4est_quadrant_set_morton (&f, maxlevel, 0); } else { first_tree = p4est->first_local_tree = points->p.which_tree; p4est_node_to_quadrant (points, maxlevel, &f); } first_quad = &f; } last_tree = p4est->last_local_tree = -2; p4est_comm_global_partition (p4est, first_quad); first_quad = p4est->global_first_position + rank; next_quad = p4est->global_first_position + (rank + 1); next_tree = next_quad->p.which_tree; if (first_tree >= 0 && p4est_quadrant_is_equal (first_quad, next_quad) && first_quad->p.which_tree == next_quad->p.which_tree) { /* if all our points are consumed by the next processor we are empty */ first_tree = p4est->first_local_tree = -1; } if (first_tree >= 0) { /* we are definitely not empty */ if (next_quad->x == 0 && next_quad->y == 0 #ifdef P4_TO_P8 && next_quad->z == 0 #endif ) { last_tree = p4est->last_local_tree = next_tree - 1; } else { last_tree = p4est->last_local_tree = next_tree; } P4EST_ASSERT (first_tree <= last_tree); } /* fill the local trees */ P4EST_QUADRANT_INIT (&a); P4EST_QUADRANT_INIT (&b); P4EST_QUADRANT_INIT (&c); P4EST_QUADRANT_INIT (&l); n = *next_quad; n.level = (int8_t) maxlevel; for (jt = first_tree; jt <= last_tree; ++jt) { int onlyone = 0; int includeb = 0; tree = p4est_tree_array_index (p4est->trees, jt); /* determine first local quadrant of this tree */ if (jt == first_tree) { a = *first_quad; a.level = (int8_t) maxlevel; first_quad = next_quad = NULL; /* free to use further down */ P4EST_ASSERT (p4est_quadrant_is_valid (&a)); } else { p4est_quadrant_set_morton (&a, maxlevel, 0); P4EST_ASSERT (jt < next_tree || p4est_quadrant_compare (&a, &n) < 0); } /* enlarge first local quadrant if possible */ if (jt < next_tree) { while (p4est_quadrant_child_id (&a) == 0 && a.level > 0) { p4est_quadrant_parent (&a, &a); } P4EST_ASSERT (jt == first_tree || a.level == 0); } else { for (c = a; p4est_quadrant_child_id (&c) == 0; a = c) { p4est_quadrant_parent (&c, &c); p4est_quadrant_last_descendant (&c, &l, maxlevel); if (p4est_quadrant_compare (&l, &n) >= 0) { break; } } P4EST_ASSERT (a.level > 0); P4EST_ASSERT ((p4est_quadrant_last_descendant (&a, &l, maxlevel), p4est_quadrant_compare (&l, &n) < 0)); } p4est_quadrant_first_descendant (&a, &tree->first_desc, P4EST_QMAXLEVEL); /* determine largest possible last quadrant of this tree */ if (jt < next_tree) { p4est_quadrant_last_descendant (&a, &l, maxlevel); p4est_quadrant_set_morton (&b, 0, 0); p4est_quadrant_last_descendant (&b, &b, maxlevel); if (p4est_quadrant_is_equal (&l, &b)) { onlyone = 1; } else { includeb = 1; for (c = b; p4est_quadrant_child_id (&c) == P4EST_CHILDREN - 1; b = c) { p4est_quadrant_parent (&c, &c); p4est_quadrant_first_descendant (&c, &f, maxlevel); if (p4est_quadrant_compare (&l, &f) >= 0) { break; } } } } else { b = n; } /* create a complete tree */ if (onlyone) { quad = p4est_quadrant_array_push (&tree->quadrants); *quad = a; p4est_quadrant_init_data (p4est, jt, quad, p4est_points_init); tree->maxlevel = a.level; ++tree->quadrants_per_level[a.level]; } else { p4est_complete_region (p4est, &a, 1, &b, includeb, tree, jt, p4est_points_init); quad = p4est_quadrant_array_index (&tree->quadrants, tree->quadrants.elem_count - 1); } tree->quadrants_offset = p4est->local_num_quadrants; p4est->local_num_quadrants += tree->quadrants.elem_count; p4est_quadrant_last_descendant (quad, &tree->last_desc, P4EST_QMAXLEVEL); /* verification */ #ifdef P4EST_ENABLE_DEBUG first_quad = p4est_quadrant_array_index (&tree->quadrants, 0); for (zz = 1; zz < tree->quadrants.elem_count; ++zz) { next_quad = p4est_quadrant_array_index (&tree->quadrants, zz); P4EST_ASSERT (((p4est_locidx_t *) first_quad->p.user_data)[1] == ((p4est_locidx_t *) next_quad->p.user_data)[0]); first_quad = next_quad; } #endif } if (last_tree >= 0) { for (; jt < num_trees; ++jt) { tree = p4est_tree_array_index (p4est->trees, jt); tree->quadrants_offset = p4est->local_num_quadrants; } } /* compute some member variables */ p4est->global_first_quadrant = P4EST_ALLOC (p4est_gloidx_t, num_procs + 1); p4est_comm_count_quadrants (p4est); /* print more statistics */ P4EST_VERBOSEF ("total local quadrants %lld\n", (long long) p4est->local_num_quadrants); P4EST_ASSERT (p4est_is_valid (p4est)); p4est_log_indent_pop (); P4EST_GLOBAL_PRODUCTIONF ("Done " P4EST_STRING "_new_points with %lld total quadrants\n", (long long) p4est->global_num_quadrants); /* refine to have one point per quadrant */ if (max_points >= 0) { p4est_refine_ext (p4est, 1, maxlevel, p4est_points_refine, p4est_points_init, NULL); #ifdef P4EST_ENABLE_DEBUG for (jt = first_tree; jt <= last_tree; ++jt) { tree = p4est_tree_array_index (p4est->trees, jt); first_quad = p4est_quadrant_array_index (&tree->quadrants, 0); for (zz = 1; zz < tree->quadrants.elem_count; ++zz) { next_quad = p4est_quadrant_array_index (&tree->quadrants, zz); P4EST_ASSERT (((p4est_locidx_t *) first_quad->p.user_data)[1] == ((p4est_locidx_t *) next_quad->p.user_data)[0]); first_quad = next_quad; } } #endif } /* initialize user pointer and data size */ p4est_reset_data (p4est, data_size, init_fn, user_pointer); return p4est; }
END_TEST START_TEST(test_surface_plot) { int test_check = 1; int startlevel = 0; int endlevel = 2; int degree = 3; int level; p4est_reset_data(global_p4est_pointer, sizeof(element_data_t), NULL, NULL); element_data_init(global_p4est_pointer,degree); for (level = startlevel; level < endlevel; ++level){ /* p4est_refine(global_p4est_pointer, 0, refine_h, NULL); */ p4est_refine_ext(global_p4est_pointer, 0, -1, refine_uni, NULL, NULL); } p4est_balance_ext (global_p4est_pointer, P4EST_CONNECT_FACE, NULL, NULL); element_data_init(global_p4est_pointer,degree); /* element_data_print(global_p4est_pointer); */ p4est_t* p4est = global_p4est_pointer; int local_nodes = element_data_get_local_nodes(global_p4est_pointer); double* u = P4EST_ALLOC(double, local_nodes); element_data_init_node_vec(p4est, u, sin_wave); double* xyz [(P4EST_DIM)]; int i; for (i = 0; i < (P4EST_DIM); i++) xyz[i] = P4EST_ALLOC(double, local_nodes); element_data_get_xyz(p4est, xyz); plot_data x_data; x_data.N = local_nodes; x_data.data = xyz[0]; plot_data y_data; y_data.N = local_nodes; y_data.data = xyz[1]; plot_data z_data; z_data.N = local_nodes; z_data.data = u; plot_features features_surface; features_surface.saveas = "test_plot_surface.png"; features_surface.save = 1; plot_features features_contour; features_contour.saveas = "test_plot_contour.png"; features_contour.save = 1; /* matplotlib_wrapper_init(); */ matplotlib_wrapper_surfaceplot(&x_data,&y_data,&z_data,NULL,&features_surface); matplotlib_wrapper_contourplot(&x_data,&y_data,&z_data,NULL,&features_contour); matplotlib_wrapper_exit(); for (i = 0; i < (P4EST_DIM); i++) P4EST_FREE(xyz[i]); P4EST_FREE(u); ck_assert_int_eq(test_check,1); }