static void hack_test (mpi_context_t * mpi, p4est_connectivity_t * connectivity) { int i; int8_t cc; p4est_topidx_t tt; p4est_locidx_t lnq, lng, lnc, lnco; p4est_locidx_t li, qtc; p4est_locidx_t co0, co1, coi, cq; p4est_t *p4est; p4est_ghost_t *ghost; p4est_mesh_t *mesh; p4est = p4est_new_ext (mpi->mpicomm, connectivity, 0, refine_level, 1, 0, NULL, NULL); p4est_vtk_write_file (p4est, NULL, "mesh_hack"); ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); mesh = p4est_mesh_new_ext (p4est, ghost, 1, 1, P4EST_CONNECT_FULL); lnq = mesh->local_num_quadrants; lng = mesh->ghost_num_quadrants; lnco = lnq + lng; lnc = mesh->local_num_corners; P4EST_LDEBUGF ("Local quads %lld corners %lld array %lld\n", (long long) lnq, (long long) lnc, (long long) mesh->corner_offset->elem_count); for (li = 0; li < lnq; ++li) { tt = mesh->quad_to_tree[li]; if (tt >= 2) { /* break; */ } for (i = 0; i < P4EST_CHILDREN; ++i) { qtc = mesh->quad_to_corner[P4EST_CHILDREN * li + i]; if (qtc >= lnco) { P4EST_LDEBUGF ("Quad %lld tree %lld Corner %d is %lld\n", (long long) li, (long long) tt, i, (long long) qtc); if (qtc >= lnco) { qtc -= lnco; co0 = *(p4est_locidx_t *) sc_array_index (mesh->corner_offset, qtc); co1 = *(p4est_locidx_t *) sc_array_index (mesh->corner_offset, qtc + 1); for (coi = co0; coi < co1; ++coi) { cq = *(p4est_locidx_t *) sc_array_index (mesh->corner_quad, coi); cc = *(int8_t *) sc_array_index (mesh->corner_corner, coi); P4EST_LDEBUGF (" Part %d quad %lld corner %d\n", (int) (coi - co0), (long long) cq, (int) cc); } } } } } p4est_mesh_destroy (mesh); p4est_ghost_destroy (ghost); p4est_destroy (p4est); }
static void check_all (sc_MPI_Comm mpicomm, p4est_connectivity_t * conn, const char *vtkname, unsigned crc_expected, unsigned gcrc_expected) { int mpiret; unsigned crc_computed, gcrc_computed; long long lsize[3], gsize[3]; size_t size_conn, size_p4est, size_ghost; p4est_t *p4est; p4est_nodes_t *nodes; p4est_ghost_t *ghost; P4EST_GLOBAL_STATISTICSF ("Testing configuration %s\n", vtkname); p4est = p4est_new_ext (mpicomm, conn, 0, 0, 0, 0, NULL, NULL); p4est_refine (p4est, 1, refine_fn, NULL); p4est_coarsen (p4est, 1, coarsen_fn, NULL); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); p4est_partition (p4est, 0, NULL); p4est_vtk_write_file (p4est, NULL, vtkname); crc_computed = p4est_checksum (p4est); P4EST_GLOBAL_STATISTICSF ("Forest checksum 0x%08x\n", crc_computed); if (p4est->mpisize == 2 && p4est->mpirank == 0) { SC_CHECK_ABORT (crc_computed == crc_expected, "Forest checksum mismatch"); } ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); /* compute total size of forest storage */ size_conn = p4est_connectivity_memory_used (conn); size_p4est = p4est_memory_used (p4est); size_ghost = p4est_ghost_memory_used (ghost); lsize[0] = (long long) size_conn; lsize[1] = (long long) size_p4est; lsize[2] = (long long) size_ghost; mpiret = sc_MPI_Reduce (lsize, gsize, 3, sc_MPI_LONG_LONG_INT, sc_MPI_SUM, 0, mpicomm); SC_CHECK_MPI (mpiret); P4EST_GLOBAL_INFOF ("Global byte sizes: %lld %lld %lld\n", gsize[0], gsize[1], gsize[2]); gcrc_computed = p4est_ghost_checksum (p4est, ghost); P4EST_GLOBAL_STATISTICSF ("Ghost checksum 0x%08x\n", gcrc_computed); if (p4est->mpisize == 2 && p4est->mpirank == 0) { SC_CHECK_ABORT (gcrc_computed == gcrc_expected, "Ghost checksum mismatch"); } nodes = p4est_nodes_new (p4est, ghost); p4est_nodes_destroy (nodes); p4est_ghost_destroy (ghost); p4est_destroy (p4est); p4est_connectivity_destroy (conn); }
static void test_the_p4est (p4est_connectivity_t * conn, int N) { p4est_t *p4est; p4est_ghost_t *ghost; p4est_lnodes_t *lnodes; p4est = p4est_new (sc_MPI_COMM_WORLD, conn, 0, NULL, NULL); ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); lnodes = p4est_lnodes_new (p4est, ghost, N); p4est_lnodes_destroy (lnodes); p4est_ghost_destroy (ghost); p4est_destroy (p4est); }
int main (int argc, char **argv) { int mpiret; mpi_context_t mpi_context, *mpi = &mpi_context; p4est_t *p4est; p4est_connectivity_t *connectivity; p4est_ghost_t *ghost; /* initialize MPI and p4est internals */ mpiret = MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpi->mpicomm = MPI_COMM_WORLD; /* your favourite comm here */ mpiret = MPI_Comm_size (mpi->mpicomm, &mpi->mpisize); SC_CHECK_MPI (mpiret); mpiret = MPI_Comm_rank (mpi->mpicomm, &mpi->mpirank); SC_CHECK_MPI (mpiret); /* this should alwaps be MPI_COMM_WORLD (no effect on p4est) */ sc_init (MPI_COMM_WORLD, 0, 0, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); /* create 2D connectivity and forest structures */ connectivity = p4est_connectivity_new_unitsquare (); p4est = p4est_new_ext (mpi->mpicomm, connectivity, 0, 0, 1, 0, NULL, NULL); /* refine and partition */ p4est_refine (p4est, 1, refine_fn, NULL); p4est_partition (p4est, NULL); /* write vtk output */ p4est_vtk_write_file (p4est, NULL, "p4est_ptest2"); /* create and destroy ghost layer */ ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); p4est_ghost_destroy (ghost); /* destroy the p4est and its connectivity structure */ p4est_destroy (p4est); p4est_connectivity_destroy (connectivity); /* clean up and exit */ sc_finalize (); mpiret = MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }
void p4est_wrap_set_hollow (p4est_wrap_t * pp, int hollow) { /* Verify consistency */ if (!pp->hollow) { P4EST_ASSERT (pp->flags != NULL); P4EST_ASSERT (pp->ghost != NULL); P4EST_ASSERT (pp->mesh != NULL); } else { P4EST_ASSERT (pp->flags == NULL); P4EST_ASSERT (pp->ghost == NULL); P4EST_ASSERT (pp->mesh == NULL); } /* Make sure a full wrap is only set to hollow outside of adaptation cycle */ P4EST_ASSERT (!pp->match_aux); P4EST_ASSERT (pp->temp_flags == NULL); P4EST_ASSERT (pp->ghost_aux == NULL); P4EST_ASSERT (pp->mesh_aux == NULL); /* Do nothing if the status is right */ if (hollow == pp->hollow) { return; } if (pp->hollow) { /* Allocate the ghost, mesh, and flag members */ pp->flags = P4EST_ALLOC_ZERO (uint8_t, pp->p4est->local_num_quadrants); pp->ghost = p4est_ghost_new (pp->p4est, pp->btype); pp->mesh = p4est_mesh_new_ext (pp->p4est, pp->ghost, 1, 1, pp->btype); } else { /* Free and nullify the ghost, mesh, and flag members */ p4est_mesh_destroy (pp->mesh); p4est_ghost_destroy (pp->ghost); P4EST_FREE (pp->flags); pp->ghost = NULL; pp->mesh = NULL; pp->flags = NULL; } pp->num_refine_flags = pp->inside_counter = pp->num_replaced = 0; pp->hollow = hollow; }
p4est_wrap_t * p4est_wrap_new_p4est (p4est_t * p4est, int hollow, p4est_connect_type_t btype, p4est_replace_t replace_fn, void *user_pointer) { p4est_wrap_t *pp; P4EST_ASSERT (p4est_is_valid (p4est)); P4EST_ASSERT (p4est->user_pointer == NULL); pp = P4EST_ALLOC_ZERO (p4est_wrap_t, 1); pp->hollow = hollow; sc_refcount_init (&pp->conn_rc, p4est_package_id); pp->conn = p4est->connectivity; pp->conn_owner = NULL; pp->p4est_dim = P4EST_DIM; pp->p4est_half = P4EST_HALF; pp->p4est_faces = P4EST_FACES; pp->p4est_children = P4EST_CHILDREN; pp->btype = btype; pp->replace_fn = replace_fn; pp->p4est = p4est; pp->weight_exponent = 0; /* keep this even though using ALLOC_ZERO */ if (!pp->hollow) { pp->flags = P4EST_ALLOC_ZERO (uint8_t, pp->p4est->local_num_quadrants); pp->ghost = p4est_ghost_new (pp->p4est, pp->btype); pp->mesh = p4est_mesh_new_ext (pp->p4est, pp->ghost, 1, 1, pp->btype); } pp->p4est->user_pointer = pp; pp->user_pointer = user_pointer; return pp; }
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); }
static void mesh_run (mpi_context_t * mpi, p4est_connectivity_t * connectivity, int uniform, int compute_tree_index, int compute_level_lists, p4est_connect_type_t mesh_btype) { int mpiret; unsigned crc; long local_used[4], global_used[4]; p4est_t *p4est; p4est_ghost_t *ghost; p4est_mesh_t *mesh; user_data_t *ghost_data; p4est = p4est_new (mpi->mpicomm, connectivity, sizeof (user_data_t), init_fn, NULL); if (!uniform) p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_new"); /* refinement */ if (uniform) { p4est_refine (p4est, 1, refine_uniform, init_fn); } else { p4est_refine (p4est, 1, refine_normal, init_fn); p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_refined"); } /* balance */ p4est_balance (p4est, P4EST_CONNECT_FULL, init_fn); if (!uniform) p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_balanced"); /* partition */ p4est_partition (p4est, 0, NULL); if (!uniform) { p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_partition"); } crc = p4est_checksum (p4est); /* print and verify forest checksum */ P4EST_GLOBAL_STATISTICSF ("Tree %s checksum 0x%08x\n", uniform ? "uniform" : "adapted", crc); /* create ghost layer and mesh */ ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL); ghost_data = P4EST_ALLOC (user_data_t, ghost->ghosts.elem_count); p4est_ghost_exchange_data (p4est, ghost, ghost_data); mesh = p4est_mesh_new_ext (p4est, ghost, compute_tree_index, compute_level_lists, mesh_btype); test_mesh (p4est, ghost, mesh, compute_tree_index, compute_level_lists, mesh_btype, ghost_data, uniform); /* compute memory used */ local_used[0] = (long) p4est_connectivity_memory_used (p4est->connectivity); local_used[1] = (long) p4est_memory_used (p4est); local_used[2] = (long) p4est_ghost_memory_used (ghost); local_used[3] = (long) p4est_mesh_memory_used (mesh); mpiret = sc_MPI_Allreduce (local_used, global_used, 4, sc_MPI_LONG, sc_MPI_SUM, mpi->mpicomm); SC_CHECK_MPI (mpiret); P4EST_GLOBAL_PRODUCTIONF ("Total %s memory used %ld %ld %ld %ld\n", uniform ? "uniform" : "adapted", global_used[0], global_used[1], global_used[2], global_used[3]); /* destroy ghost layer and mesh */ P4EST_FREE (ghost_data); p4est_mesh_destroy (mesh); p4est_ghost_destroy (ghost); /* destroy the p4est structure */ p4est_destroy (p4est); }
p6est_profile_t * p6est_profile_new_local (p6est_t * p6est, p6est_ghost_t * ghost, p6est_profile_type_t ptype, p8est_connect_type_t btype, int degree) { p6est_profile_t *profile = P4EST_ALLOC (p6est_profile_t, 1); p4est_lnodes_t *lnodes; p4est_locidx_t nln, nle; p4est_topidx_t jt; p4est_t *columns = p6est->columns; p4est_tree_t *tree; sc_array_t *tquadrants; p4est_quadrant_t *col; p4est_qcoord_t diff = P4EST_ROOT_LEN - p6est->root_len; size_t first, last, count, zz, zy; p4est_locidx_t *en, (*lr)[2]; sc_array_t *lc; int i, j; p2est_quadrant_t *layer; sc_array_t *layers = p6est->layers; p4est_locidx_t nidx, enidx; p4est_connect_type_t hbtype; int8_t *c; sc_array_t *thisprof; sc_array_t *selfprof; sc_array_t *faceprof; sc_array_t *cornerprof; sc_array_t *work; sc_array_t oldprof; const int Nrp = degree + 1; P4EST_ASSERT (degree > 1); profile->ptype = ptype; profile->btype = btype; profile->lnode_changed[0] = NULL; profile->lnode_changed[1] = NULL; profile->enode_counts = NULL; profile->diff = diff; if (btype == P8EST_CONNECT_FACE) { hbtype = P4EST_CONNECT_FACE; } else { hbtype = P4EST_CONNECT_FULL; } if (ghost == NULL) { profile->cghost = p4est_ghost_new (p6est->columns, P4EST_CONNECT_FULL); profile->ghost_owned = 1; } else { P4EST_ASSERT (ghost->column_ghost->btype == P4EST_CONNECT_FULL); profile->cghost = ghost->column_ghost; profile->ghost_owned = 0; } if (ptype == P6EST_PROFILE_UNION) { P4EST_ASSERT (degree == 2); } profile->lnodes = lnodes = p4est_lnodes_new (p6est->columns, profile->cghost, degree); en = lnodes->element_nodes; nln = lnodes->num_local_nodes; nle = lnodes->num_local_elements; profile->lnode_ranges = P4EST_ALLOC_ZERO (p4est_locidx_t, 2 * nln); lr = (p4est_locidx_t (*)[2]) profile->lnode_ranges; profile->lnode_columns = lc = sc_array_new (sizeof (int8_t)); selfprof = sc_array_new (sizeof (int8_t)); work = sc_array_new (sizeof (int8_t)); faceprof = sc_array_new (sizeof (int8_t)); cornerprof = sc_array_new (sizeof (int8_t)); if (ptype == P6EST_PROFILE_UNION) { profile->lnode_changed[0] = P4EST_ALLOC (p4est_locidx_t, nln); profile->lnode_changed[1] = P4EST_ALLOC (p4est_locidx_t, nln); profile->enode_counts = P4EST_ALLOC (p4est_locidx_t, P4EST_INSUL * nle); profile->evenodd = 0; memset (profile->lnode_changed[0], -1, nln * sizeof (int)); } /* create the profiles for each node: layers are reduced to just their level * */ for (enidx = 0, jt = columns->first_local_tree; jt <= columns->last_local_tree; ++jt) { tree = p4est_tree_array_index (columns->trees, jt); tquadrants = &tree->quadrants; for (zz = 0; zz < tquadrants->elem_count; ++zz) { col = p4est_quadrant_array_index (tquadrants, zz); P6EST_COLUMN_GET_RANGE (col, &first, &last); count = last - first; sc_array_truncate (selfprof); c = (int8_t *) sc_array_push_count (selfprof, count); for (zy = first; zy < last; zy++) { layer = p2est_quadrant_array_index (layers, zy); *(c++) = layer->level; } if (ptype == P6EST_PROFILE_UNION) { p6est_profile_balance_self (selfprof, work); if (btype == P8EST_CONNECT_FACE) { p6est_profile_balance_face (selfprof, faceprof, work, diff); } else { p6est_profile_balance_full (selfprof, faceprof, work, diff); } if (btype == P8EST_CONNECT_EDGE) { p6est_profile_balance_face (selfprof, cornerprof, work, diff); } else if (btype == P8EST_CONNECT_FULL) { p6est_profile_balance_full (selfprof, cornerprof, work, diff); } } for (j = 0; j < Nrp; j++) { for (i = 0; i < Nrp; i++, enidx++) { nidx = en[enidx]; if (ptype == P6EST_PROFILE_UNION) { thisprof = NULL; if (!(i % degree) && !(j % degree)) { if (hbtype == P4EST_CONNECT_FACE) { /* skip corners if we don't need to balance them */ P4EST_ASSERT (!lr[nidx][0]); P4EST_ASSERT (!lr[nidx][1]); continue; } else { thisprof = cornerprof; } } else if ((i % degree) && (j % degree)) { thisprof = selfprof; } else { thisprof = faceprof; } count = thisprof->elem_count; profile->enode_counts[enidx] = count; if (!lr[nidx][1]) { /* if this node has not yet been initialized, initialize it */ lr[nidx][0] = lc->elem_count; lr[nidx][1] = count; c = (int8_t *) sc_array_push_count (lc, count); memcpy (c, thisprof->array, count * sizeof (int8_t)); } else { /* if this node has been initialized, combine the two profiles, * taking the finer layers from each */ sc_array_init_view (&oldprof, lc, lr[nidx][0], lr[nidx][1]); p6est_profile_union (thisprof, &oldprof, work); if (work->elem_count > oldprof.elem_count) { lr[nidx][0] = lc->elem_count; lr[nidx][1] = work->elem_count; c = (int8_t *) sc_array_push_count (lc, work->elem_count); memcpy (c, work->array, work->elem_count * work->elem_size); } } } else { count = selfprof->elem_count; if (!lr[nidx][1]) { /* if this node has not yet been initialized, initialize it */ lr[nidx][0] = lc->elem_count; lr[nidx][1] = count; c = (int8_t *) sc_array_push_count (lc, count); memcpy (c, selfprof->array, count * sizeof (int8_t)); } else { /* if this node has been initialized, combine the two profiles, * taking the coarser layers from each */ sc_array_init_view (&oldprof, lc, lr[nidx][0], lr[nidx][1]); p6est_profile_intersection (selfprof, &oldprof, work); P4EST_ASSERT (work->elem_count <= oldprof.elem_count); if (work->elem_count < oldprof.elem_count) { lr[nidx][1] = work->elem_count; memcpy (oldprof.array, work->array, work->elem_count * work->elem_size); } } } } } } } p6est_profile_compress (profile); sc_array_destroy (selfprof); sc_array_destroy (faceprof); sc_array_destroy (cornerprof); sc_array_destroy (work); return profile; }
int p4est_wrap_partition (p4est_wrap_t * pp, int weight_exponent, p4est_locidx_t * unchanged_first, p4est_locidx_t * unchanged_length, p4est_locidx_t * unchanged_old_first) { int changed; p4est_gloidx_t pre_me, pre_next; p4est_gloidx_t post_me, post_next; P4EST_ASSERT (!pp->hollow); P4EST_ASSERT (pp->ghost != NULL); P4EST_ASSERT (pp->mesh != NULL); P4EST_ASSERT (pp->ghost_aux != NULL); P4EST_ASSERT (pp->mesh_aux != NULL); P4EST_ASSERT (pp->match_aux == 1); p4est_mesh_destroy (pp->mesh); p4est_ghost_destroy (pp->ghost); pp->match_aux = 0; /* Remember the window onto global quadrant sequence before partition */ pre_me = pp->p4est->global_first_quadrant[pp->p4est->mpirank]; pre_next = pp->p4est->global_first_quadrant[pp->p4est->mpirank + 1]; /* Initialize output for the case that the partition does not change */ if (unchanged_first != NULL) { *unchanged_first = 0; } if (unchanged_length != NULL) { *unchanged_length = pp->p4est->local_num_quadrants; } if (unchanged_old_first != NULL) { *unchanged_old_first = 0; } /* In the future the flags could be used to pass partition weights */ /* We need to lift the restriction on 64 bits for the global weight sum */ P4EST_ASSERT (weight_exponent == 0 || weight_exponent == 1); pp->weight_exponent = weight_exponent; changed = p4est_partition_ext (pp->p4est, 1, weight_exponent ? partition_weight : NULL) > 0; if (changed) { P4EST_FREE (pp->flags); pp->flags = P4EST_ALLOC_ZERO (uint8_t, pp->p4est->local_num_quadrants); pp->ghost = p4est_ghost_new (pp->p4est, pp->btype); pp->mesh = p4est_mesh_new_ext (pp->p4est, pp->ghost, 1, 1, pp->btype); /* Query the window onto global quadrant sequence after partition */ if (unchanged_first != NULL || unchanged_length != NULL || unchanged_old_first != NULL) { /* compute new windof of local quadrants */ post_me = pp->p4est->global_first_quadrant[pp->p4est->mpirank]; post_next = pp->p4est->global_first_quadrant[pp->p4est->mpirank + 1]; /* compute the range of quadrants that have stayed on this processor */ p4est_wrap_partition_unchanged (pre_me, pre_next, post_me, post_next, unchanged_first, unchanged_length, unchanged_old_first); } } else { memset (pp->flags, 0, sizeof (uint8_t) * pp->p4est->local_num_quadrants); pp->ghost = pp->ghost_aux; pp->mesh = pp->mesh_aux; pp->ghost_aux = NULL; pp->mesh_aux = NULL; } return changed; }
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; }
/** 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); }
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; }