-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce populate functionality according to cmesh borders #998
base: main
Are you sure you want to change the base?
Conversation
t8code is a C library to manage a collection (a forest) of multiple | ||
connected adaptive space-trees of general element classes in parallel. | ||
|
||
Copyright (C) 2015 the developers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe change the date to 2024?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I already have the template for VScode that creates the header for new files, but this file was still created via copy paste before, so I will change it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you create a template for these things in VS Code (I'm curious because I use that editor too)?
Here are two additional tests with three quadratic quads. The TEST (t8_forest_new_from_partition, one_two_quad)
{
/* Current process */
int rank, size;
sc_MPI_Comm_size (sc_MPI_COMM_WORLD, &size);
sc_MPI_Comm_rank (sc_MPI_COMM_WORLD, &rank);
/* Geometry */
int degree = 2;
std::vector<std::vector<double>> cells;
cells.push_back (std::vector<double> { -1, 1.2, 0, 0, 1.2, 0, -1, 3, 0, 0, 3, 0, -1, 2.1,
0, 0, 2.1, 0, -0.5, 1.2, 0, -0.5, 3, 0, -0.5, 2.1, 0 });
cells.push_back (std::vector<double> { 0, 1.2, 0, 2, 1.5, 0, 0, 3, 0, 2, 3, 0, 0, 2.1,
0, 1.7, 2.1, 0, 1, 1.55, 0, 1, 3, 0, 0.9, 2.1, 0 });
cells.push_back (
std::vector<double> { 2, 1.5, 0, 4, 0, 0, 2, 3, 0, 4, 3, 0, 1.7, 2.1, 0, 4, 1.5, 0, 3, 1, 0, 3, 3, 0, 3, 2, 0 });
/* Create a partitioned cmesh */
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);
if (size != 2)
SC_ABORT ("Program must be run on two MPI processes.\n");
else {
if (rank == 0) {
t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD);
t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_QUAD);
t8_cmesh_set_tree_vertices (cmesh, 0, cells[0].data (), cells[0].size ());
t8_cmesh_set_tree_vertices (cmesh, 1, cells[1].data (), cells[1].size ());
t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree, sizeof (int), 1);
t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree, sizeof (int), 1);
t8_cmesh_set_join (cmesh, 0, 1, 1, 0, 0);
t8_cmesh_set_partition_range (cmesh, 3, 0, 0);
}
else if (rank == 1) {
for (size_t itree = 0; itree < 3; ++itree) {
t8_cmesh_set_tree_class (cmesh, itree, T8_ECLASS_QUAD);
t8_cmesh_set_tree_vertices (cmesh, itree, cells[itree].data (), cells[itree].size ());
t8_cmesh_set_attribute (cmesh, itree, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree,
sizeof (int), 1);
}
t8_cmesh_set_join (cmesh, 0, 1, 1, 0, 0);
t8_cmesh_set_join (cmesh, 1, 2, 1, 0, 0);
t8_cmesh_set_partition_range (cmesh, 3, 1, 2);
}
}
t8_cmesh_register_geometry<t8_geometry_lagrange> (cmesh, 2);
t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD);
t8_cmesh_vtk_write_file (cmesh, "cmesh");
t8_forest_t forest
= t8_forest_new_uniform_with_cmesh_partition (cmesh, t8_scheme_new_default_cxx (), 0, 0, sc_MPI_COMM_WORLD);
// t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), 0, 1, sc_MPI_COMM_WORLD);
t8_forest_write_vtk (forest, "forest");
t8_cmesh_destroy (&cmesh);
}
TEST (t8_forest_new_from_partition, two_one_quad)
{
/* Current process */
int rank, size;
sc_MPI_Comm_size (sc_MPI_COMM_WORLD, &size);
sc_MPI_Comm_rank (sc_MPI_COMM_WORLD, &rank);
/* Geometry */
int degree = 2;
std::vector<std::vector<double>> cells;
cells.push_back (std::vector<double> { -1, 1.2, 0, 0, 1.2, 0, -1, 3, 0, 0, 3, 0, -1, 2.1,
0, 0, 2.1, 0, -0.5, 1.2, 0, -0.5, 3, 0, -0.5, 2.1, 0 });
cells.push_back (std::vector<double> { 0, 1.2, 0, 2, 1.5, 0, 0, 3, 0, 2, 3, 0, 0, 2.1,
0, 1.7, 2.1, 0, 1, 1.55, 0, 1, 3, 0, 0.9, 2.1, 0 });
cells.push_back (
std::vector<double> { 2, 1.5, 0, 4, 0, 0, 2, 3, 0, 4, 3, 0, 1.7, 2.1, 0, 4, 1.5, 0, 3, 1, 0, 3, 3, 0, 3, 2, 0 });
/* Create a partitioned cmesh */
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);
if (size != 2)
SC_ABORT ("Program must be run on two MPI processes.\n");
else {
if (rank == 0) {
for (size_t itree = 0; itree < 3; ++itree) {
t8_cmesh_set_tree_class (cmesh, itree, T8_ECLASS_QUAD);
t8_cmesh_set_tree_vertices (cmesh, itree, cells[itree].data (), cells[itree].size ());
t8_cmesh_set_attribute (cmesh, itree, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree,
sizeof (int), 1);
}
t8_cmesh_set_join (cmesh, 0, 1, 1, 0, 0);
t8_cmesh_set_join (cmesh, 1, 2, 1, 0, 0);
t8_cmesh_set_partition_range (cmesh, 3, 0, 1);
}
else if (rank == 1) {
t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_QUAD);
t8_cmesh_set_tree_class (cmesh, 2, T8_ECLASS_QUAD);
t8_cmesh_set_tree_vertices (cmesh, 1, cells[1].data (), cells[1].size ());
t8_cmesh_set_tree_vertices (cmesh, 2, cells[2].data (), cells[2].size ());
t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree, sizeof (int), 1);
t8_cmesh_set_attribute (cmesh, 2, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree, sizeof (int), 1);
t8_cmesh_set_join (cmesh, 1, 2, 1, 0, 0);
t8_cmesh_set_partition_range (cmesh, 3, 2, 2);
}
}
t8_cmesh_register_geometry<t8_geometry_lagrange> (cmesh, 2);
t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD);
t8_cmesh_vtk_write_file (cmesh, "cmesh");
t8_forest_t forest
= t8_forest_new_uniform_with_cmesh_partition (cmesh, t8_scheme_new_default_cxx (), 0, 0, sc_MPI_COMM_WORLD);
// t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), 0, 1, sc_MPI_COMM_WORLD);
t8_forest_write_vtk (forest, "forest");
t8_cmesh_destroy (&cmesh);
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A first batch of comments for your code.
I need to review the changes in the t8_forest_populate function, but I need a clear mind for that. Probably will do it tomorrow.
/* create a line cmesh */ | ||
int mpirank, mpisize; | ||
sc_MPI_Comm comm = sc_MPI_COMM_WORLD; | ||
sc_MPI_Comm_size (comm, &mpisize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check the return values after calling this function.
sc_MPI_Comm comm = sc_MPI_COMM_WORLD; | ||
sc_MPI_Comm_size (comm, &mpisize); | ||
sc_MPI_Comm_rank (comm, &mpirank); | ||
int face_knowledge = 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int face_knowledge = 3; | |
const int face_knowledge = 3; |
sc_MPI_Comm_size (comm, &mpisize); | ||
sc_MPI_Comm_rank (comm, &mpirank); | ||
int face_knowledge = 3; | ||
int num_trees = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int num_trees = 2; | |
const t8_gloidx_t num_trees = 2; |
t8_cmesh_set_tree_class (cmesh, second, T8_ECLASS_LINE); | ||
t8_cmesh_set_tree_vertices (cmesh, first, vertices, 2); | ||
t8_cmesh_set_tree_vertices (cmesh, second, vertices + 3, 2); | ||
// t8_cmesh_set_join (cmesh, first, second, 1, 0, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// t8_cmesh_set_join (cmesh, first, second, 1, 0, 0); |
t8_cmesh_set_partition_range (cmesh, face_knowledge, 0, 1); | ||
} | ||
else { | ||
t8_cmesh_set_dimension (cmesh, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dimension is not set in the first case. It should be set in both cases, I think you can move it out of the if/else part
/* Allocate elements for this processor. */ | ||
t8_element_array_init_size (telements, eclass_scheme, end - start); | ||
t8_element_t *element = t8_element_array_index_locidx_mutable (telements, 0); | ||
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, start); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, start); | |
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, 0); |
t8_element_t *element = t8_element_array_index_locidx_mutable (telements, 0); | ||
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, start); | ||
count_elements++; | ||
for (t8_locidx_t et = start + 1; et < end; et++, count_elements++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (t8_locidx_t et = start + 1; et < end; et++, count_elements++) { | |
for (t8_locidx_t et = 1; et < end; et++, count_elements++) { |
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, start); | ||
count_elements++; | ||
for (t8_locidx_t et = start + 1; et < end; et++, count_elements++) { | ||
t8_element_t *element_succ = t8_element_array_index_locidx_mutable (telements, et - start); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t8_element_t *element_succ = t8_element_array_index_locidx_mutable (telements, et - start); | |
t8_element_t *element_succ = t8_element_array_index_locidx_mutable (telements, et); |
t8_element_t *element = t8_element_array_index_locidx_mutable (telements, 0); | ||
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, start); | ||
count_elements++; | ||
for (t8_locidx_t et = start + 1; et < end; et++, count_elements++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
et is not a good name for a variable
T8_ASSERT (forest->set_level <= forest->maxlevel); | ||
/* populate a new forest with tree and quadrant objects */ | ||
if (t8_forest_refines_irregular (forest) && forest->set_level > 0) { | ||
/* On root level we will also use the normal algorithm */ | ||
t8_forest_populate_irregular (forest); | ||
t8_forest_populate_irregular (forest, 1); | ||
// t8_forest_populate_irregular (forest, !forest->set_initial_partition_according_to_cmesh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// t8_forest_populate_irregular (forest, !forest->set_initial_partition_according_to_cmesh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: investigate further, because it looks like the second argument is not even used in t8_forest_populate_irregular
cc579aa
to
f93958f
Compare
/* True if the forest has no elements */ | ||
is_empty = forest->first_local_tree > forest->last_local_tree | ||
|| (forest->first_local_tree == forest->last_local_tree && child_in_tree_begin >= child_in_tree_end); | ||
t8_gloidx_t cmesh_first_tree = t8_cmesh_get_first_treeid (forest->cmesh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t8_gloidx_t cmesh_first_tree = t8_cmesh_get_first_treeid (forest->cmesh); | |
const t8_gloidx_t cmesh_first_tree = t8_cmesh_get_first_treeid (forest->cmesh); |
is_empty = forest->first_local_tree > forest->last_local_tree | ||
|| (forest->first_local_tree == forest->last_local_tree && child_in_tree_begin >= child_in_tree_end); | ||
t8_gloidx_t cmesh_first_tree = t8_cmesh_get_first_treeid (forest->cmesh); | ||
t8_gloidx_t cmesh_last_tree = cmesh_first_tree + t8_cmesh_get_num_local_trees (forest->cmesh) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t8_gloidx_t cmesh_last_tree = cmesh_first_tree + t8_cmesh_get_num_local_trees (forest->cmesh) - 1; | |
const t8_gloidx_t cmesh_last_tree = cmesh_first_tree + t8_cmesh_get_num_local_trees (forest->cmesh) - 1; |
|
||
if (!is_empty) { | ||
/* True if the forest has no elements */ | ||
int is_empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int is_empty | |
const bool is_empty |
tree_class = tree->eclass = t8_cmesh_get_tree_class (forest->cmesh, jt - first_ctree); | ||
t8_gloidx_t first_ctree = t8_cmesh_get_first_treeid (forest->cmesh); | ||
t8_locidx_t count_elements = 0; | ||
for (t8_gloidx_t jt = forest->first_local_tree; jt <= forest->last_local_tree; jt++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jt is not a good name for a variable.
for (jt = forest->first_local_tree, count_elements = 0; jt <= forest->last_local_tree; jt++) { | ||
tree = (t8_tree_t) t8_sc_array_index_locidx (forest->trees, jt - forest->first_local_tree); | ||
tree_class = tree->eclass = t8_cmesh_get_tree_class (forest->cmesh, jt - first_ctree); | ||
t8_gloidx_t first_ctree = t8_cmesh_get_first_treeid (forest->cmesh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t8_gloidx_t first_ctree = t8_cmesh_get_first_treeid (forest->cmesh); | |
const t8_gloidx_t first_ctree = t8_cmesh_get_first_treeid (forest->cmesh); |
eclass_scheme->t8_element_set_linear_id (element, forest->set_level, start); | ||
count_elements++; | ||
for (et = start + 1; et < end; et++, count_elements++) { | ||
element_succ = t8_element_array_index_locidx_mutable (telements, et - start); | ||
for (t8_locidx_t et = start + 1; et < end; et++, count_elements++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change the name of the variable.
Describe your changes here:
Unclean version of creating a forest according to the partitioned cmesh boundaries (cmesh elements are not allowed to be shared).
For discussions with @CsatiZoltan about whether this satisfies his requirements.
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 Makefiles
The code is well documented
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
Github action
The code compiles without warning in debugging and release mode, with and without MPI (this should be executed automatically in a github action)
All tests pass (in various configurations, this should be executed automatically in a github action)
If the Pull request introduces code that is not covered by the github action (for example coupling with a new library):
Scripts and Wiki
script/find_all_source_files.scp
to check the indentation of these files.Licence
doc/
(or already has one)