int main (int argc, char **argv) { int mpirank, mpisize; int mpiret; sc_MPI_Comm mpicomm; p4est_t *p4est; p4est_connectivity_t *connectivity; 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); /* create connectivity and forest structures */ #ifdef P4_TO_P8 connectivity = p8est_connectivity_new_rotcubes (); #else connectivity = p4est_connectivity_new_star (); #endif p4est = p4est_new_ext (mpicomm, connectivity, 15, 0, 0, 1, NULL, NULL); p4est_refine_ext (p4est, 1, P4EST_QMAXLEVEL, refine_fn, NULL, replace_fn); p4est_coarsen_ext (p4est, 1, 0, coarsen_fn, NULL, replace_fn); p4est_balance_ext (p4est, P4EST_CONNECT_FULL, NULL, replace_fn); p4est_destroy (p4est); p4est_connectivity_destroy (connectivity); sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
int main (int argc, char **argv) { int mpiret; sc_MPI_Comm mpicomm; p4est_t *p4est; p4est_connectivity_t *connectivity; p4est_locidx_t save_local_count; p4est_geometry_t *geom; mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpicomm = sc_MPI_COMM_WORLD; sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); /* create connectivity and forest structures */ #ifdef P4_TO_P8 connectivity = p8est_connectivity_new_rotcubes (); geom = NULL; #else connectivity = p4est_connectivity_new_star (); geom = p4est_geometry_new_connectivity (connectivity); #endif p4est = p4est_new_ext (mpicomm, connectivity, 15, 0, 0, 0, NULL, NULL); save_local_count = p4est->local_num_quadrants; refine_callback_count = 0; p4est_refine_ext (p4est, 0, 2, test_refine, NULL, NULL); SC_CHECK_ABORT (refine_callback_count == save_local_count, "Refine count"); refine_callback_count = 0; p4est_refine (p4est, 1, test_refine, NULL); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); coarsen_all = 1; p4est_coarsen_both (p4est, 0, test_coarsen, NULL); coarsen_all = 0; p4est_coarsen_both (p4est, 1, test_coarsen, NULL); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); coarsen_all = 1; p4est_coarsen_both (p4est, 1, test_coarsen, NULL); p4est_vtk_write_file (p4est, geom, P4EST_STRING "_endcoarsen"); if (p4est->mpisize == 1) { SC_CHECK_ABORT (p4est->global_num_quadrants == (p4est_gloidx_t) connectivity->num_trees, "Coarsen all"); } p4est_destroy (p4est); if (geom != NULL) { p4est_geometry_destroy (geom); } 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; }
int main(int argc, char *argv[]) { int mpiret; sc_MPI_Comm mpicomm; int proc_size; p4est_connectivity_t *conn; p4est_geometry_t *geom; p4est_t* p4est; int seed = time(NULL); srand(seed); /* MPI init */ mpiret = sc_MPI_Init(&argc, &argv); SC_CHECK_MPI(mpiret); mpicomm = sc_MPI_COMM_WORLD; sc_init (mpicomm, 1, 1, NULL, SC_LP_ESSENTIAL); mpiret = MPI_Comm_size(mpicomm, &proc_size); SC_CHECK_MPI (mpiret); /* pXest init */ p4est_init(NULL, SC_LP_PRODUCTION); conn = p4est_connectivity_new_disk(); /* geom = p4est_geometry_new_connectivity(conn); */ geom = p4est_geometry_new_disk(conn,1.,2.); p4est = p4est_new_ext (mpicomm, conn, -1, 0, 1, sizeof(curved_element_data_t), NULL, NULL); int world_rank,world_size; sc_MPI_Comm_rank(sc_MPI_COMM_WORLD, &world_rank); sc_MPI_Comm_size(sc_MPI_COMM_WORLD, &world_size); /* start just-in-time dg-math */ dgmath_jit_dbase_t* dgmath_jit_dbase = dgmath_jit_dbase_init(); geometric_factors_t* geometric_factors = geometric_factors_init(p4est); curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, 4); /* int local_nodes = curved_element_data_get_local_nodes(p4est); */ /* double* u = P4EST_ALLOC(double, local_nodes); */ /* for (int i = 0; i < local_nodes; i++){ */ /* /\* u = x *\/ */ /* u[i] = geometric_factors->xyz[i]; */ /* } */ int num_of_refinements = 2; /* p4est_vtk_write_all */ /* (p4est, */ /* geom, */ /* 0.99, */ /* 1, */ /* 1, */ /* 1, */ /* 0, */ /* 0, */ /* 0, */ /* "disk0" */ /* ); */ for (int i = 0; i < num_of_refinements; i++){ p4est_refine_ext (p4est, 0, -1, random_h_refine, NULL, refine_uniform_replace_callback); p4est_balance_ext(p4est, P4EST_CONNECT_FACE, NULL, refine_uniform_replace_callback); /* p4est_vtk_write_all */ /* (p4est, */ /* geom, */ /* 0.99, */ /* 1, */ /* 1, */ /* 1, */ /* 0, */ /* 0, */ /* 0, */ /* "disk" */ /* ); */ } curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, -1); int local_nodes = curved_element_data_get_local_nodes(p4est); double* u = P4EST_ALLOC(double, local_nodes); for (int i = 0; i < local_nodes; i++){ /* u = x */ u[i] = geometric_factors->xyz[i]; } /* curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, -1); */ /* store vector */ curved_element_data_copy_from_vec_to_storage ( p4est, u ); test_curved_data_t test_curved_data; test_curved_data.mortar_err = 0.; test_curved_data.hanging_proj_err = 0.; test_curved_data.full_proj_err = 0.; test_curved_data.print_data = 1; test_curved_data.no_reorient = 0; test_curved_data.geom = geom; p4est_ghost_t* ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FACE); /* create space for storing the ghost data */ curved_element_data_t* ghost_data = P4EST_ALLOC (curved_element_data_t, ghost->ghosts.elem_count); p4est_ghost_exchange_data (p4est, ghost, ghost_data); curved_compute_flux_user_data_t curved_compute_flux_user_data; curved_compute_flux_user_data.dgmath_jit_dbase = dgmath_jit_dbase; curved_flux_fcn_ptrs_t flux_fcns = (test_curved_data_fetch_fcns(&test_curved_data)); curved_compute_flux_user_data.flux_fcn_ptrs = &flux_fcns; p4est->user_pointer = &curved_compute_flux_user_data; p4est_iterate (p4est, ghost, (void *) ghost_data, NULL, curved_compute_flux_on_local_elements, #if (P4EST_DIM)==3 NULL, #endif NULL); test_curved_data.mortar_err = 0.; if (world_rank == 0) printf("mortar_err = %.20f\n", test_curved_data.mortar_err ); p4est_ghost_destroy (ghost); P4EST_FREE (ghost_data); ghost = NULL; ghost_data = NULL; /* curved_hp_amr(p4est, */ /* &u, */ /* test_nonconform_random_hp, */ /* NULL, */ /* NULL, */ /* NULL, */ /* dgmath_jit_dbase */ /* ); */ /* curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, -1); */ /* double* u_vertex = P4EST_ALLOC(double, p4est->local_num_quadrants*(P4EST_CHILDREN)); */ /* element_data_store_nodal_vec_in_vertex_array */ /* ( */ /* p4est, */ /* u, */ /* u_vertex */ /* ); */ /* char sol_save_as [500]; */ /* sprintf(sol_save_as, "%s_test_nonconform_sym_level_%d_u", P4EST_STRING, i); */ /* curved_hacked_p4est_vtk_write_all */ /* (p4est, */ /* NULL, */ /* 0.99, */ /* 0, */ /* 1, */ /* 1, */ /* 0, */ /* 1, */ /* 0, */ /* sol_save_as, */ /* "u", */ /* u_vertex */ /* ); */ /* P4EST_FREE(u_vertex); */ /* ip_flux_params_t ip_flux_params; */ /* ip_flux_params.ip_flux_penalty_prefactor = atoi(argv[6]); */ /* ip_flux_params.ip_flux_penalty_calculate_fcn = sipg_flux_vector_calc_penalty_maxp2_over_minh; */ /* problem_data_t vecs; */ /* vecs.u = u; */ /* vecs.local_nodes = element_data_get_local_nodes(p4est); */ /* vecs.vector_flux_fcn_data = sipg_flux_vector_dirichlet_fetch_fcns */ /* ( */ /* zero_fcn, */ /* &ip_flux_params */ /* ); */ /* vecs.scalar_flux_fcn_data = sipg_flux_scalar_dirichlet_fetch_fcns(zero_fcn); */ /* weakeqn_ptrs_t fcns; */ /* fcns.apply_lhs = poisson_apply_aij; */ /* matrix_sym_tester */ /* ( */ /* p4est, */ /* &vecs, /\* only needed for # of nodes *\/ */ /* &fcns, */ /* .000000000000001, */ /* dgmath_jit_dbase, */ /* 0, */ /* 0 */ /* ); */ /* } */ P4EST_FREE(u); geometric_factors_destroy(geometric_factors); /* free pointers */ dgmath_jit_dbase_destroy(dgmath_jit_dbase); /* free pXest */ p4est_destroy(p4est); /* p4est_destroy(p4est); */ if (geom != NULL) { p4est_geometry_destroy (geom); } p4est_connectivity_destroy(conn); /* finalize mpi stuff */ sc_finalize(); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI(mpiret); }
int p4est_wrap_adapt (p4est_wrap_t * pp) { int changed; #ifdef P4EST_ENABLE_DEBUG p4est_locidx_t jl, local_num; #endif p4est_gloidx_t global_num; p4est_t *p4est = pp->p4est; P4EST_ASSERT (!pp->hollow); P4EST_ASSERT (pp->coarsen_delay >= 0); P4EST_ASSERT (pp->mesh != NULL); P4EST_ASSERT (pp->ghost != NULL); P4EST_ASSERT (pp->mesh_aux == NULL); P4EST_ASSERT (pp->ghost_aux == NULL); P4EST_ASSERT (pp->match_aux == 0); P4EST_ASSERT (pp->temp_flags == NULL); P4EST_ASSERT (pp->num_refine_flags >= 0 && pp->num_refine_flags <= p4est->local_num_quadrants); /* This allocation is optimistic when not all refine requests are honored */ pp->temp_flags = P4EST_ALLOC_ZERO (uint8_t, p4est->local_num_quadrants + (P4EST_CHILDREN - 1) * pp->num_refine_flags); /* Execute refinement */ pp->inside_counter = pp->num_replaced = 0; #ifdef P4EST_ENABLE_DEBUG local_num = p4est->local_num_quadrants; #endif global_num = p4est->global_num_quadrants; p4est_refine_ext (p4est, 0, -1, refine_callback, NULL, replace_on_refine); P4EST_ASSERT (pp->inside_counter == local_num); P4EST_ASSERT (p4est->local_num_quadrants - local_num == pp->num_replaced * (P4EST_CHILDREN - 1)); changed = global_num != p4est->global_num_quadrants; /* Execute coarsening */ pp->inside_counter = pp->num_replaced = 0; #ifdef P4EST_ENABLE_DEBUG local_num = p4est->local_num_quadrants; #endif global_num = p4est->global_num_quadrants; p4est_coarsen_ext (p4est, 0, 1, coarsen_callback, NULL, pp->coarsen_delay ? replace_on_coarsen : pp->replace_fn); P4EST_ASSERT (pp->inside_counter == local_num); P4EST_ASSERT (local_num - p4est->local_num_quadrants == pp->num_replaced * (P4EST_CHILDREN - 1)); changed = changed || global_num != p4est->global_num_quadrants; /* Free temporary flags */ P4EST_FREE (pp->temp_flags); pp->temp_flags = NULL; /* Only if refinement and/or coarsening happened do we need to balance */ if (changed) { P4EST_FREE (pp->flags); p4est_balance_ext (p4est, pp->btype, NULL, pp->coarsen_delay ? replace_on_balance : pp->replace_fn); pp->flags = P4EST_ALLOC_ZERO (uint8_t, p4est->local_num_quadrants); pp->ghost_aux = p4est_ghost_new (p4est, pp->btype); pp->mesh_aux = p4est_mesh_new_ext (p4est, pp->ghost_aux, 1, 1, pp->btype); pp->match_aux = 1; } #ifdef P4EST_ENABLE_DEBUG else { for (jl = 0; jl < p4est->local_num_quadrants; ++jl) { P4EST_ASSERT (pp->flags[jl] == 0); } } #endif pp->num_refine_flags = 0; return changed; }
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); }
/** Timestep the advection problem. * * Update the state, refine, repartition, and write the solution to file. * * \param [in,out] p4est the forest, whose state is updated * \param [in] time the end time */ static void step3_timestep (p4est_t * p4est, double time) { double t = 0.; double dt = 0.; int i; step3_data_t *ghost_data; step3_ctx_t *ctx = (step3_ctx_t *) p4est->user_pointer; int refine_period = ctx->refine_period; int repartition_period = ctx->repartition_period; int write_period = ctx->write_period; int recursive = 0; int allowed_level = P4EST_QMAXLEVEL; int allowcoarsening = 1; int callbackorphans = 0; int mpiret; double orig_max_err = ctx->max_err; double umax, global_umax; p4est_ghost_t *ghost; /* create the ghost quadrants */ ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); /* create space for storing the ghost data */ ghost_data = P4EST_ALLOC (step3_data_t, ghost->ghosts.elem_count); /* synchronize the ghost data */ p4est_ghost_exchange_data (p4est, ghost, ghost_data); /* initialize du/dx estimates */ p4est_iterate (p4est, ghost, (void *) ghost_data, /* pass in ghost data that we just exchanged */ step3_reset_derivatives, /* blank the previously calculated derivatives */ step3_minmod_estimate, /* compute the minmod estimate of each cell's derivative */ #ifdef P4_TO_P8 NULL, /* there is no callback for the edges between quadrants */ #endif NULL); /* there is no callback for the corners between quadrants */ for (t = 0., i = 0; t < time; t += dt, i++) { P4EST_GLOBAL_PRODUCTIONF ("time %f\n", t); /* refine */ if (!(i % refine_period)) { if (i) { /* compute umax */ umax = 0.; /* initialize derivative estimates */ p4est_iterate (p4est, NULL, (void *) &umax, /* pass in ghost data that we just exchanged */ step3_compute_max, /* blank the previously calculated derivatives */ NULL, /* there is no callback for the faces between quadrants */ #ifdef P4_TO_P8 NULL, /* there is no callback for the edges between quadrants */ #endif NULL); /* there is no callback for the corners between quadrants */ mpiret = sc_MPI_Allreduce (&umax, &global_umax, 1, sc_MPI_DOUBLE, sc_MPI_MAX, p4est->mpicomm); SC_CHECK_MPI (mpiret); ctx->max_err = orig_max_err * global_umax; P4EST_GLOBAL_PRODUCTIONF ("u_max %f\n", global_umax); /* adapt */ p4est_refine_ext (p4est, recursive, allowed_level, step3_refine_err_estimate, NULL, step3_replace_quads); p4est_coarsen_ext (p4est, recursive, callbackorphans, step3_coarsen_err_estimate, NULL, step3_replace_quads); p4est_balance_ext (p4est, P4EST_CONNECT_FACE, NULL, step3_replace_quads); p4est_ghost_destroy (ghost); P4EST_FREE (ghost_data); ghost = NULL; ghost_data = NULL; } dt = step3_get_timestep (p4est); } /* repartition */ if (i && !(i % repartition_period)) { p4est_partition (p4est, allowcoarsening, NULL); if (ghost) { p4est_ghost_destroy (ghost); P4EST_FREE (ghost_data); ghost = NULL; ghost_data = NULL; } } /* write out solution */ if (!(i % write_period)) { step3_write_solution (p4est, i); } /* synchronize the ghost data */ if (!ghost) { ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); ghost_data = P4EST_ALLOC (step3_data_t, ghost->ghosts.elem_count); p4est_ghost_exchange_data (p4est, ghost, ghost_data); } /* compute du/dt */ /* *INDENT-OFF* */ p4est_iterate (p4est, /* the forest */ ghost, /* the ghost layer */ (void *) ghost_data, /* the synchronized ghost data */ step3_quad_divergence, /* callback to compute each quad's interior contribution to du/dt */ step3_upwind_flux, /* callback to compute each quads' faces' contributions to du/du */ #ifdef P4_TO_P8 NULL, /* there is no callback for the edges between quadrants */ #endif NULL); /* there is no callback for the corners between quadrants */ /* *INDENT-ON* */ /* update u */ p4est_iterate (p4est, NULL, /* ghosts are not needed for this loop */ (void *) &dt, /* pass in dt */ step3_timestep_update, /* update each cell */ NULL, /* there is no callback for the faces between quadrants */ #ifdef P4_TO_P8 NULL, /* there is no callback for the edges between quadrants */ #endif NULL); /* there is no callback for the corners between quadrants */ /* synchronize the ghost data */ p4est_ghost_exchange_data (p4est, ghost, ghost_data); /* update du/dx estimate */ p4est_iterate (p4est, ghost, (void *) ghost_data, /* pass in ghost data that we just exchanged */ step3_reset_derivatives, /* blank the previously calculated derivatives */ step3_minmod_estimate, /* compute the minmod estimate of each cell's derivative */ #ifdef P4_TO_P8 NULL, /* there is no callback for the edges between quadrants */ #endif NULL); /* there is no callback for the corners between quadrants */ } P4EST_FREE (ghost_data); p4est_ghost_destroy (ghost); }
void problem_init ( int argc, char* argv [], p4est_t* p4est, p4est_geometry_t* p4est_geom, dgmath_jit_dbase_t* dgmath_jit_dbase, int proc_size, sc_MPI_Comm mpicomm, int load_from_checkpoint ) { mpi_assert((P4EST_DIM) == 2 || (P4EST_DIM) == 3); int world_rank, world_size; sc_MPI_Comm_rank(sc_MPI_COMM_WORLD, &world_rank); sc_MPI_Comm_size(sc_MPI_COMM_WORLD, &world_size); double* Au = P4EST_ALLOC_ZERO(double, 1); double* rhs = P4EST_ALLOC_ZERO(double, 1); double* u = P4EST_ALLOC_ZERO(double, 1); double* f = P4EST_ALLOC_ZERO(double, 1); double* u_analytic = P4EST_ALLOC_ZERO(double, 1); int local_nodes = 1; problem_input_t input = problem_input("options.input"); int endlevel = input.endlevel; int degree = input.degree; ip_flux_params_t ip_flux_params; ip_flux_params.ip_flux_penalty_prefactor = input.ip_flux_penalty; ip_flux_params.ip_flux_penalty_calculate_fcn = sipg_flux_vector_calc_penalty_maxp2_over_minh; p4est_ghost_t* ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FACE); /* create space for storing the ghost data */ element_data_t* ghost_data = P4EST_ALLOC (element_data_t, ghost->ghosts.elem_count); p4est_partition(p4est, 0, NULL); p4est_balance (p4est, P4EST_CONNECT_FACE, NULL); grid_fcn_t boundary_flux_fcn = zero_fcn; problem_data_t prob_vecs; prob_vecs.rhs = rhs; prob_vecs.Au = Au; prob_vecs.u = u; prob_vecs.f = f; prob_vecs.local_nodes = local_nodes; for (int level = 0; level < endlevel; ++level){ if (level != 0){ p4est_refine_ext(p4est, 0, -1, refine_function, NULL, NULL ); p4est_balance_ext ( p4est, P4EST_CONNECT_FACE, NULL, NULL ); p4est_ghost_destroy(ghost); P4EST_FREE(ghost_data); ghost = p4est_ghost_new(p4est, P4EST_CONNECT_FACE); ghost_data = P4EST_ALLOC(element_data_t, ghost->ghosts.elem_count); } } p4est_partition(p4est, 1, NULL); p4est_balance_ext ( p4est, P4EST_CONNECT_FACE, NULL, NULL ); p4est_ghost_destroy(ghost); P4EST_FREE(ghost_data); ghost = p4est_ghost_new(p4est, P4EST_CONNECT_FACE); ghost_data = P4EST_ALLOC(element_data_t, ghost->ghosts.elem_count); weakeqn_ptrs_t prob_fcns; prob_fcns.apply_lhs = problem_apply_aij; element_data_init(p4est, degree); local_nodes = element_data_get_local_nodes(p4est); printf("RANK %d: Nodes = %d\n", world_rank, local_nodes); Au = P4EST_REALLOC(Au, double, local_nodes); u = P4EST_REALLOC(u, double, local_nodes); f = P4EST_REALLOC(f, double, local_nodes); rhs = P4EST_REALLOC(rhs, double, local_nodes); u_analytic = P4EST_REALLOC(u_analytic, double, local_nodes); prob_vecs.Au = Au; prob_vecs.u = u; prob_vecs.f = f; prob_vecs.rhs = rhs; prob_vecs.local_nodes = local_nodes; linalg_fill_vec(u, 0., local_nodes); element_data_init_node_vec(p4est,f,f_fcn,dgmath_jit_dbase); prob_vecs.vector_flux_fcn_data = sipg_flux_vector_dirichlet_fetch_fcns ( boundary_fcn, &ip_flux_params ); prob_vecs.scalar_flux_fcn_data = sipg_flux_scalar_dirichlet_fetch_fcns ( boundary_flux_fcn ); problem_build_rhs ( p4est, &prob_vecs, &prob_fcns, ghost, ghost_data, dgmath_jit_dbase ); clock_t begin = 0; clock_t end = -1; if (world_rank == 0){ begin = clock(); } int vcycle_iter = 3; double vcycle_rtol = 1e-3; double vcycle_atol = 0.; int smooth_iter = 8; int cg_eigs_iter = 10; double max_eig_factor = 1.1; int max_eig_reuse = 1; double lmax_lmin_rat = 30.; int coarse_iter = 100; double coarse_rtol = 1e-8; int save_vtk_snapshot = 0; int perform_checksum = 0; multigrid_data_t* mg_data = multigrid_data_init ( world_rank, endlevel, vcycle_iter, vcycle_rtol, vcycle_atol, smooth_iter, cg_eigs_iter, max_eig_factor, max_eig_reuse, lmax_lmin_rat, CG, coarse_iter, coarse_rtol, save_vtk_snapshot, perform_checksum, RES_AND_EIG_LOG, dgmath_jit_dbase ); multigrid_solve ( p4est, &prob_vecs, &prob_fcns, mg_data, &ghost, &ghost_data ); multigrid_data_destroy(mg_data); element_data_init_node_vec(p4est, u_analytic, analytic_solution_fcn, dgmath_jit_dbase); linalg_vec_axpy(-1., u, u_analytic, local_nodes); double local_l2_norm_sqr = element_data_compute_l2_norm_sqr_no_local ( p4est, u_analytic, dgmath_jit_dbase ); double local_nodes_dbl = (double)local_nodes; double local_reduce [2]; local_reduce[0] = local_nodes_dbl; local_reduce[1] = local_l2_norm_sqr; double global_reduce [2]; sc_reduce ( &local_reduce[0], &global_reduce[0], 2, sc_MPI_DOUBLE, sc_MPI_SUM, 0, sc_MPI_COMM_WORLD ); double global_nodes_dbl = global_reduce[0]; double global_l2_norm_sqr = global_reduce[1]; if (world_rank == 0){ end = clock(); double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf ( "\n\n[HP_AMR]: %d %d %d %.25f %f \n\n", degree, (int)p4est->global_num_quadrants, (int)global_nodes_dbl, sqrt(global_l2_norm_sqr), /* info.iterations, */ /* info.residual_norm, */ time_spent ); } if (ghost) { p4est_ghost_destroy (ghost); P4EST_FREE (ghost_data); ghost = NULL; ghost_data = NULL; } P4EST_FREE(f); P4EST_FREE(Au); P4EST_FREE(rhs); P4EST_FREE(u_analytic); P4EST_FREE(u); }