int main (int argc, char **argv) { int mpiret; int wrongusage; unsigned crc; const char *usage; mpi_context_t mpi_context, *mpi = &mpi_context; p8est_t *p8est; p8est_connectivity_t *connectivity; p8est_geometry_t *geom; p8est_refine_t refine_fn; p8est_coarsen_t coarsen_fn; simple_config_t config; const simple_regression_t *r; /* initialize MPI and p4est internals */ mpiret = MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpi->mpicomm = MPI_COMM_WORLD; mpiret = MPI_Comm_size (mpi->mpicomm, &mpi->mpisize); SC_CHECK_MPI (mpiret); mpiret = MPI_Comm_rank (mpi->mpicomm, &mpi->mpirank); SC_CHECK_MPI (mpiret); sc_init (mpi->mpicomm, 1, 1, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); /* process command line arguments */ usage = "Arguments: <configuration> <level>\n" " Configuration can be any of\n" " unit|periodic|rotwrap|twocubes|twowrap|rotcubes|shell|sphere\n" " Level controls the maximum depth of refinement\n"; wrongusage = 0; config = P8EST_CONFIG_NULL; if (!wrongusage && argc != 3) { wrongusage = 1; } if (!wrongusage) { if (!strcmp (argv[1], "unit")) { config = P8EST_CONFIG_UNIT; } else if (!strcmp (argv[1], "periodic")) { config = P8EST_CONFIG_PERIODIC; } else if (!strcmp (argv[1], "rotwrap")) { config = P8EST_CONFIG_ROTWRAP; } else if (!strcmp (argv[1], "twocubes")) { config = P8EST_CONFIG_TWOCUBES; } else if (!strcmp (argv[1], "twowrap")) { config = P8EST_CONFIG_TWOWRAP; } else if (!strcmp (argv[1], "rotcubes")) { config = P8EST_CONFIG_ROTCUBES; } else if (!strcmp (argv[1], "shell")) { config = P8EST_CONFIG_SHELL; } else if (!strcmp (argv[1], "sphere")) { config = P8EST_CONFIG_SPHERE; } else { wrongusage = 1; } } if (wrongusage) { P4EST_GLOBAL_LERROR (usage); sc_abort_collective ("Usage error"); } /* assign variables based on configuration */ refine_level = atoi (argv[2]); refine_fn = refine_normal_fn; coarsen_fn = NULL; /* create connectivity and forest structures */ geom = NULL; if (config == P8EST_CONFIG_PERIODIC) { connectivity = p8est_connectivity_new_periodic (); } else if (config == P8EST_CONFIG_ROTWRAP) { connectivity = p8est_connectivity_new_rotwrap (); } else if (config == P8EST_CONFIG_TWOCUBES) { connectivity = p8est_connectivity_new_twocubes (); refine_fn = refine_sparse_fn; } else if (config == P8EST_CONFIG_TWOWRAP) { connectivity = p8est_connectivity_new_twowrap (); refine_fn = refine_sparse_fn; } else if (config == P8EST_CONFIG_ROTCUBES) { connectivity = p8est_connectivity_new_rotcubes (); } else if (config == P8EST_CONFIG_SHELL) { connectivity = p8est_connectivity_new_shell (); geom = p8est_geometry_new_shell (1., .55); } else if (config == P8EST_CONFIG_SPHERE) { connectivity = p8est_connectivity_new_sphere (); geom = p8est_geometry_new_sphere (1., 0.191728, 0.039856); } else { connectivity = p8est_connectivity_new_unitcube (); } p8est = p8est_new_ext (mpi->mpicomm, connectivity, 1, 0, 0, sizeof (user_data_t), init_fn, NULL); #ifdef VTK_OUTPUT p8est_vtk_write_file (p8est, geom, "simple3_new"); #endif /* refinement and coarsening */ p8est_refine (p8est, 1, refine_fn, init_fn); if (coarsen_fn != NULL) { p8est_coarsen (p8est, 1, coarsen_fn, init_fn); } #ifdef VTK_OUTPUT p8est_vtk_write_file (p8est, geom, "simple3_refined"); #endif /* balance */ p8est_balance (p8est, P8EST_CONNECT_FULL, init_fn); #ifdef VTK_OUTPUT p8est_vtk_write_file (p8est, geom, "simple3_balanced"); #endif crc = p8est_checksum (p8est); /* partition */ p8est_partition (p8est, NULL); #ifdef VTK_OUTPUT p8est_vtk_write_file (p8est, geom, "simple3_partition"); #endif #ifdef P4EST_DEBUG /* rebalance should not change checksum */ p8est_balance (p8est, P8EST_CONNECT_FULL, init_fn); P4EST_ASSERT (p8est_checksum (p8est) == crc); #endif /* print and verify forest checksum */ P4EST_GLOBAL_STATISTICSF ("Tree checksum 0x%08x\n", crc); if (mpi->mpirank == 0) { for (r = regression; r->config != P8EST_CONFIG_NULL; ++r) { if (r->config != config || r->mpisize != mpi->mpisize || r->level != refine_level) continue; SC_CHECK_ABORT (crc == r->checksum, "Checksum mismatch"); P4EST_GLOBAL_INFO ("Checksum regression OK\n"); break; } } /* destroy the p8est and its connectivity structure */ p8est_destroy (p8est); P4EST_FREE (geom); p8est_connectivity_destroy (connectivity); /* clean up and exit */ sc_finalize (); mpiret = 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); }