Skip to content

Conversation

@hannesbrandt
Copy link
Contributor

Partition search for the replicated coarse mesh and tutorial
This PR adds the partition search for forests with replicated coarse mesh using the interface defined in #1286.

Additionally, the search is exercised in a new tutorial t8_tutorial_search_partition.cxx. In the tutorial, a forest is defined on the unit cube and refined adaptively. The coarse mesh can be either a 2x2x2 brick or the hybrid hypercube example cmesh. A set of random query points is created on rank 0 and broadcasted to all processes. The replicated queries are first searched in the local part of the forest using the already existing local search routines. Subsequently, they are searched in the partition of the forest and thereby assigned to processes. The results of the partition search are checked for consistency with the results of the local search across all processes.

This PR is currently just a draft for the following reasons

  • The geometric routines required to check for element-query intersections like t8_forest_element_points_inside all expect a local tree id as input. For the partition search it would be convenient to call the same routines for global tree ids as well. As a temporary solution we adapted the required geometric functions to accept a global tree id and use the replicated cmesh instead of the forest to obtain the tree class. A future partition search for distributed cmeshes may even benefit from similar geometric functionalities using the tree class directly as input.
  • The refinement method in the tutorial uses some geometric routines like t8_forest_element_centroid, which are not allowed to be called during adaptation, as the forest is temporarily not committed. We temporarily disabled the respective assertions.

All these boxes must be checked by the AUTHOR before requesting review:

  • The PR is small enough to be reviewed easily. If not, consider splitting up the changes in multiple PRs.
  • The title starts with one of the following prefixes: Documentation:, Bugfix:, Feature:, Improvement: or Other:.
  • If the PR is related to an issue, make sure to link it.
  • The author made sure that, as a reviewer, he/she would check all boxes below.

All these boxes must be checked by the REVIEWERS before merging the pull request:

As a reviewer please read through all the code lines and make sure that the code is fully understood, bug free, well-documented and well-structured.

General

  • The reviewer executed the new code features at least once and checked the results manually.
  • The code follows the t8code coding guidelines.
  • New source/header files are properly added to the CMake files.
  • The code is well documented. In particular, all function declarations, structs/classes and their members have a proper doxygen documentation.
  • All new algorithms and data structures are sufficiently optimal in terms of memory and runtime (If this should be merged, but there is still potential for optimization, create a new issue).

Tests

  • The code is covered in an existing or new test case using Google Test.
  • The code coverage of the project (reported in the CI) should not decrease. If coverage is decreased, make sure that this is reasonable and acceptable.
  • Valgrind doesn't find any bugs in the new code. This script can be used to check for errors; see also this wiki article.

If the Pull request introduces code that is not covered by the github action (for example coupling with a new library):

  • Should this use case be added to the github action?
  • If not, does the specific use case compile and all tests pass (check manually).

Scripts and Wiki

  • If a new directory with source files is added, it must be covered by the script/find_all_source_files.scp to check the indentation of these files.
  • If this PR introduces a new feature, it must be covered in an example or tutorial and a Wiki article.

License

  • The author added a BSD statement to doc/ (or already has one).

@Davknapp
Copy link
Collaborator

Hey @hannesbrandt ,

thank you for this Draft-PR. What do you need to progress further, to convert it into a PR and to merge it into main eventually?

Thank you & have a nice week,
David

@hannesbrandt
Copy link
Contributor Author

Hey @Davknapp, the implementation of the partition search itself is ready to be merged. However, the example/test program currently relies on some workarounds I implemented in t8_forest.cxx. For example, I changed some functions to use the coarse mesh instead of the forest to retrieve geometry information for all trees during the partition search. I would appreciate your input on if/how to implement these changes in a consistent manner, as I think it would increase the usability of the partition search, if the geometry functions in t8code are able to deal with arbitrary trees in a replicated coarse mesh.

@Davknapp
Copy link
Collaborator

I just had a look at it:
I think your work around in the adaptation-criterium is not necessary. As far as I understand you want to evaluate the elements in the "old" non-adapted forest. This can be done by calling the routine with forest_from, which is the already committed forest.

For the global-id part: You can use the function "t8_forest_get_local_id " to get the local-id. That way all the other functions don't need to be changed.

const int num_points, int *is_inside,
const double tolerance) const
{
const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltreeid);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change necessary?

T8_ASSERT (forest != NULL);
T8_ASSERT (forest->scheme != NULL);
/* Get the tree's class and scheme */
const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltree_id);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you ensure the execution of these functions on commited forests, all of the changes here can be reverted, I think

* This function performs a search operation on a tree identified by the given local tree ID.
* It uses the \a search_recursion function to perform the search.
*
* \param[in] ltreeid The local tree ID of the tree to be searched.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please document all parameters

* \param[in] plast The last processor that owns part of \a element. Guaranteed to be non-empty.
*/
void
search_recursion (const t8_locidx_t ltreeid, t8_element_t *element, const t8_scheme *ts, int pfirst, int plast);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
search_recursion (const t8_locidx_t ltreeid, t8_element_t *element, const t8_scheme *ts, int pfirst, int plast);
search_recursion (const t8_locidx_t ltreeid, const t8_element_t *element, const t8_scheme *ts, int pfirst, int plast);

* \param[in] ltreeid The local tree ID of the tree to be searched.
*/
void
search_tree (const t8_locidx_t ltreeid, int pfirst, int plast);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to pass a reference here. As far as I understand it you want to change the values of pfirst & plast in this functions, or pass it further down to let it be changed. So int &pfirst should do the trick .


/* compute sum of local number of queries across all processes */
gnq = 0;
for (il = 0; il < g->global_nlq->elem_count; il++) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (il = 0; il < g->global_nlq->elem_count; il++) {
for (size_t il = 0; il < g->global_nlq->elem_count; il++) {

static bool
t8_tutorial_search_partition_partition_element_fn (const t8_forest_t forest, const t8_locidx_t ltreeid,
const t8_element_t *element, int pfirst, int plast,
t8_tutorial_search_partition_global_t *g)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use a better name than g.

static bool
t8_tutorial_search_partition_partition_query_fn (const t8_forest_t forest, const t8_locidx_t ltreeid,
const t8_element_t *element, int pfirst, int plast,
const t8_point_t &query, t8_tutorial_search_partition_global_t *g)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use a better name than g.

const std::vector<t8_point_t> &queries,
const std::vector<size_t> &active_query_indices,
std::vector<bool> &query_matches,
t8_tutorial_search_partition_global_t *g)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use a better name than g.

static void
t8_tutorial_search_partition_search_partition (t8_tutorial_search_partition_global_t *g)
{
size_t iz, lenz, buffer_size;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please declare the variables when they are needed, not always at the beginning, especially for variables used as indices in loops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants