Generate coordinate tuples for quadrants, uniquify and hash them.Please see the page on The p4est coordinate system for further details.
#ifndef P4_TO_P8
#else
#endif
typedef struct coordinates_hash_key
{
}
coordinates_hash_key_t;
typedef struct coordinates_hash_data
{
sc_mempool_t *ckeys;
sc_hash_t *chash;
}
coordinates_hash_data_t;
static unsigned
coordinates_hash_fn (const void *v, const void *u)
{
const coordinates_hash_key_t *k = (coordinates_hash_key_t *) v;
uint32_t a, b, c;
P4EST_ASSERT (k != NULL);
a = (uint32_t) k->coords[0];
b = (uint32_t) k->coords[1];
#ifndef P4_TO_P8
c = (uint32_t) k->which_tree;
#else
c = (uint32_t) k->coords[2];
sc_hash_mix (a, b, c);
a += (uint32_t) k->which_tree;
#endif
sc_hash_final (a, b, c);
return (unsigned) c;
}
static int
coordinates_equal_fn (const void *v1, const void *v2, const void *u)
{
const coordinates_hash_key_t *k1 = (coordinates_hash_key_t *) v1;
const coordinates_hash_key_t *k2 = (coordinates_hash_key_t *) v2;
P4EST_ASSERT (k1 != NULL);
P4EST_ASSERT (k2 != NULL);
return k1->which_tree == k2->which_tree &&
}
static int
{
P4EST_ASSERT (r != NULL);
P4EST_ASSERT (coords != NULL);
return (r->
x == coords[0] && r->
y == coords[1] &&
#ifdef P4_TO_P8
r->z == coords[2] &&
#endif
1);
}
static void
test_hash (coordinates_hash_data_t *hdata,
{
void **found;
coordinates_hash_key_t *k;
k = (coordinates_hash_key_t *) sc_mempool_alloc (hdata->ckeys);
k->which_tree = tt;
k->coords[0] = coords[0];
k->coords[1] = coords[1];
#ifdef P4_TO_P8
k->coords[2] = coords[2];
#endif
if (sc_hash_insert_unique (hdata->chash, k, &found)) {
P4EST_ASSERT (*found == k);
#ifndef P4_TO_P8
P4EST_INFOF ("First time adding tree %ld, coordinates %lx %lx\n",
(long) tt, (long) coords[0], (long) coords[1]);
#else
P4EST_INFOF ("First time adding tree %ld, coordinates %lx %lx %lx\n",
(long) tt, (long) coords[0], (long) coords[1],
(long) coords[2]);
#endif
++hdata->added;
}
else {
P4EST_ASSERT (*found != k);
sc_mempool_free (hdata->ckeys, k);
++hdata->duped;
}
}
static void
{
int mpiret;
int size, rank;
int face, corner;
#ifdef P4_TO_P8
int edge;
#endif
coordinates_hash_data_t shdata, *hdata = &shdata;
mpiret = sc_MPI_Comm_size (mpicomm, &size);
SC_CHECK_MPI (mpiret);
mpiret = sc_MPI_Comm_rank (mpicomm, &rank);
SC_CHECK_MPI (mpiret);
if (rank != 0) {
return;
}
hdata->ckeys = sc_mempool_new (sizeof (coordinates_hash_key_t));
hdata->chash = sc_hash_new (coordinates_hash_fn, coordinates_equal_fn,
hdata, NULL);
hdata->added = hdata->duped = 0;
r = &node;
for (tt = 0; tt < num_trees; ++tt) {
P4EST_INFOF ("Going through tree %ld\n", (long) tt);
(conn, tt, coords, &nt, coords_out);
SC_CHECK_ABORT (nt == tt, "Mysterious volume tree");
"Mysterious volume coordinates");
test_hash (hdata, nt, coords_out);
(conn, tt, coords, &nt, coords_out);
SC_CHECK_ABORT (nt <= tt, "Mysterious face tree");
SC_CHECK_ABORT (nt < tt ||
"Mysterious face coordinates");
test_hash (hdata, nt, coords_out);
}
#ifdef P4_TO_P8
(conn, tt, coords, &nt, coords_out);
SC_CHECK_ABORT (nt <= tt, "Mysterious edge tree");
SC_CHECK_ABORT (nt < tt ||
"Mysterious edge coordinates");
test_hash (hdata, nt, coords_out);
}
#endif
SC_CHECK_ABORT (test_node_coordinates (r, coords), "Node coordinates");
(conn, tt, coords, &nt, coords_out);
SC_CHECK_ABORT (nt <= tt, "Mysterious corner tree");
SC_CHECK_ABORT (nt < tt ||
"Mysterious corner coordinates");
test_hash (hdata, nt, coords_out);
}
}
sc_hash_destroy (hdata->chash);
sc_mempool_destroy (hdata->ckeys);
P4EST_PRODUCTIONF ("Added %ld coordinates, duplicates %ld\n",
(long) hdata->added, (long) hdata->duped);
}
static void
test_coordinates (sc_MPI_Comm mpicomm)
{
#ifndef P4_TO_P8
#else
#endif
test_connectivity (mpicomm, conn);
}
int
main (int argc, char **argv)
{
sc_MPI_Comm mpicomm;
int mpiret;
mpiret = sc_MPI_Init (&argc, &argv);
SC_CHECK_MPI (mpiret);
mpicomm = sc_MPI_COMM_WORLD;
sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
test_coordinates (mpicomm);
sc_finalize ();
mpiret = sc_MPI_Finalize ();
SC_CHECK_MPI (mpiret);
return EXIT_SUCCESS;
}
int32_t p4est_qcoord_t
Typedef for quadrant coordinates.
Definition: p4est_base.h:81
int32_t p4est_topidx_t
Typedef for counting topological entities (trees, tree vertices).
Definition: p4est_base.h:93
int32_t p4est_locidx_t
Typedef for processor-local indexing of quadrants and nodes.
Definition: p4est_base.h:106
void p4est_init(sc_log_handler_t log_handler, int log_threshold)
Registers p4est with the SC Library and sets the logging behavior.
Routines for manipulating quadrants (neighbors, parents, children, etc.)
int p4est_coordinates_compare(const p4est_qcoord_t v1[], const p4est_qcoord_t v2[])
Compare two sets of coordinates in their Morton ordering.
int p4est_quadrant_is_node(const p4est_quadrant_t *q, int inside)
Test if a quadrant is used to represent a mesh node.
void p4est_quadrant_volume_coordinates(const p4est_quadrant_t *q, p4est_qcoord_t coords[])
Compute the coordinates of a quadrant's midpoint.
void p4est_quadrant_face_coordinates(const p4est_quadrant_t *q, int face, p4est_qcoord_t coords[])
Compute the coordinates of a specific quadrant face's midpoint.
void p4est_quadrant_root(p4est_quadrant_t *root)
Generate the root quadrant of any tree.
void p4est_quadrant_corner_coordinates(const p4est_quadrant_t *q, int corner, p4est_qcoord_t coords[])
Compute the coordinates of a specific quadrant corner.
void p4est_quadrant_corner_node(const p4est_quadrant_t *q, int corner, p4est_quadrant_t *r)
Compute a corner node of a quadrant.
The connectivity defines the coarse topology of the forest.
void p4est_connectivity_destroy(p4est_connectivity_t *connectivity)
Destroy a connectivity structure.
#define P4EST_DIM
The spatial dimension.
Definition: p4est_connectivity.h:71
void p4est_connectivity_coordinates_canonicalize(p4est_connectivity_t *conn, p4est_topidx_t treeid, const p4est_qcoord_t coords[], p4est_topidx_t *treeid_out, p4est_qcoord_t coords_out[])
Determine the owning tree for a coordinate and transform it there.
int p4est_connectivity_is_valid(p4est_connectivity_t *connectivity)
Examine a connectivity structure.
#define P4EST_FACES
The number of faces of a quadrant.
Definition: p4est_connectivity.h:73
#define P4EST_CHILDREN
The number of children of a quadrant, also the number of corners.
Definition: p4est_connectivity.h:75
p4est_connectivity_t * p4est_connectivity_new_corner(void)
Create a connectivity structure for a three-tree mesh around a corner.
Routines for manipulating quadrants (neighbors, parents, children, etc.)
void p8est_quadrant_edge_coordinates(const p8est_quadrant_t *q, int edge, p4est_qcoord_t coords[])
Compute the coordinates of a specific quadrant edge's midpoint.
The connectivity defines the coarse topology of the forest.
p8est_connectivity_t * p8est_connectivity_new_rotcubes(void)
Create a connectivity structure that contains a few cubes.
#define P8EST_EDGES
The number of edges around an octant.
Definition: p8est_connectivity.h:83
This structure holds the 2D inter-tree connectivity information.
Definition: p4est_connectivity.h:190
p4est_topidx_t num_trees
the number of trees
Definition: p4est_connectivity.h:194
The 2D quadrant datatype.
Definition: p4est.h:76
p4est_qcoord_t y
coordinates
Definition: p4est.h:78