diff --git a/src/p4est_communication.c b/src/p4est_communication.c index e0f7955a8..a0466714d 100644 --- a/src/p4est_communication.c +++ b/src/p4est_communication.c @@ -574,6 +574,53 @@ p4est_comm_is_empty (p4est_t * p4est, int p) return gfq[p] == gfq[p + 1]; } +int +p4est_comm_is_contained (p4est_t * p4est, p4est_locidx_t which_tree, + const p4est_quadrant_t * q, int rank) +{ + p4est_topidx_t ctree; + p4est_quadrant_t qlast; + const p4est_quadrant_t *cur; + + P4EST_ASSERT (p4est != NULL && p4est->connectivity != NULL); + P4EST_ASSERT (p4est->global_first_position != NULL); + P4EST_ASSERT (0 <= which_tree && + which_tree < p4est->connectivity->num_trees); + P4EST_ASSERT (q != NULL); + P4EST_ASSERT (0 <= rank && rank < p4est->mpisize); + P4EST_ASSERT (p4est_quadrant_is_node (q, 1) || p4est_quadrant_is_valid (q)); + + /* check whether q begins on a lower processor than rank */ + cur = &p4est->global_first_position[rank]; + P4EST_ASSERT (cur->level == P4EST_QMAXLEVEL); + ctree = cur->p.which_tree; + if (which_tree < ctree || + (which_tree == ctree && + (p4est_quadrant_compare (q, cur) < 0 && + (q->x != cur->x || q->y != cur->y +#ifdef P4_TO_P8 + || q->z != cur->z +#endif + )))) { + return 0; + } + + /* check whether q ends on a higher processor than rank */ + ++cur; + P4EST_ASSERT (cur == &p4est->global_first_position[rank + 1]); + P4EST_ASSERT (cur->level == P4EST_QMAXLEVEL); + ctree = cur->p.which_tree; + if (which_tree > ctree || + (which_tree == ctree && + (p4est_quadrant_last_descendant (q, &qlast, P4EST_QMAXLEVEL), + p4est_quadrant_compare (cur, &qlast) <= 0))) { + return 0; + } + + /* the quadrant lies fully in the ownership region of rank */ + return 1; +} + int p4est_comm_is_owner (p4est_t * p4est, p4est_locidx_t which_tree, const p4est_quadrant_t * q, int rank) diff --git a/src/p4est_communication.h b/src/p4est_communication.h index 3d25157d1..adc7f3d43 100644 --- a/src/p4est_communication.h +++ b/src/p4est_communication.h @@ -136,6 +136,17 @@ void p4est_comm_count_pertree (p4est_t * p4est, */ int p4est_comm_is_empty (p4est_t * p4est, int p); +/** Test whether a quadrant is fully contained in a rank's owned regien. + * This function may return false when \ref p4est_comm_is_owner returns true. + * \param [in] rank Rank whose ownership is tested. + * Assumes a forest with no overlaps. + * \return true if rank is the owner of the whole area of the quadrant. + */ +int p4est_comm_is_contained (p4est_t * p4est, + p4est_locidx_t which_tree, + const p4est_quadrant_t * q, + int rank); + /** Test ownershop of a quadrant via p4est->global_first_position. * The quadrant is considered owned if its first descendant is owned. * This, a positive result occurs even if its last descendant overlaps diff --git a/src/p4est_to_p8est.h b/src/p4est_to_p8est.h index e038a43b9..78b7139cf 100644 --- a/src/p4est_to_p8est.h +++ b/src/p4est_to_p8est.h @@ -314,6 +314,7 @@ #define p4est_comm_global_partition p8est_comm_global_partition #define p4est_comm_count_pertree p8est_comm_count_pertree #define p4est_comm_is_empty p8est_comm_is_empty +#define p4est_comm_is_contained p8est_comm_is_contained #define p4est_comm_is_owner p8est_comm_is_owner #define p4est_comm_find_owner p8est_comm_find_owner #define p4est_comm_tree_info p8est_comm_tree_info diff --git a/src/p8est_communication.h b/src/p8est_communication.h index 8c83f49bd..68d488d3a 100644 --- a/src/p8est_communication.h +++ b/src/p8est_communication.h @@ -136,6 +136,17 @@ void p8est_comm_count_pertree (p8est_t * p8est, */ int p8est_comm_is_empty (p8est_t * p8est, int p); +/** Test whether a quadrant is fully contained in a rank's owned regien. + * This function may return false when \ref p8est_comm_is_owner returns true. + * \param [in] rank Rank whose ownership is tested. + * Assumes a forest with no overlaps. + * \return true if rank is the owner of the whole area of the quadrant. + */ +int p8est_comm_is_contained (p8est_t * p8est, + p4est_locidx_t which_tree, + const p8est_quadrant_t * q, + int rank); + /** Test ownershop of a quadrant via p8est->global_first_position. * The quadrant is considered owned if its first descendant is owned. * This, a positive result occurs even if its last descendant overlaps