-
Notifications
You must be signed in to change notification settings - Fork 301
[WIP] Debugging check that variables of discontinuous family live on just one elem->dim() #4345
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
Changes from 5 commits
1e949f5
cdcae75
ddbbb0c
51dee79
315f6eb
138e739
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3139,6 +3139,47 @@ void DofMap::reinit_static_condensation() | |
| _sc->reinit(); | ||
| } | ||
|
|
||
| #ifdef DEBUG | ||
| namespace | ||
| { | ||
| unsigned char determine_elem_dims(const MeshBase & mesh, | ||
| const std::set<subdomain_id_type> & subdomains) | ||
| { | ||
| unsigned char elem_dims = 0; | ||
| for (const auto * const elem : mesh.active_subdomain_set_element_ptr_range(subdomains)) | ||
| elem_dims |= static_cast<unsigned char>(1u << cast_int<unsigned char>(elem->dim())); | ||
| mesh.comm().bitwise_or(elem_dims); | ||
| return elem_dims; | ||
| } | ||
|
|
||
| void discontinuity_sanity_check(const System & sys, | ||
| const FEType & fe_type, | ||
| const std::set<subdomain_id_type> * const active_subdomains) | ||
| { | ||
| const auto continuity = FEInterface::get_continuity(fe_type); | ||
| if (continuity != DISCONTINUOUS && continuity != SIDE_DISCONTINUOUS) | ||
| return; | ||
|
|
||
| const auto & mesh = sys.get_mesh(); | ||
| // This check won't be meaninful if the mesh isn't prepared | ||
| if (!mesh.is_prepared()) | ||
| return; | ||
|
|
||
| const auto & var_subdomains = (active_subdomains && !active_subdomains->empty()) | ||
| ? *active_subdomains | ||
| : mesh.get_mesh_subdomains(); | ||
| const auto var_elem_dims = determine_elem_dims(mesh, var_subdomains); | ||
| // Power of two trick. Note that unsigned char automatically promoted to int for arithmetic and bitwise operations | ||
| const bool more_than_one_bit_set = (var_elem_dims & (var_elem_dims - 1)) != 0; | ||
| libmesh_assert_msg( | ||
| !more_than_one_bit_set, | ||
| "Discontinuous finite element families are typically associated with discontinuous Galerkin " | ||
| "methods. If degrees of freedom are associated with different values of element dimension, " | ||
| "then generally this will result in a singular system after application of the DG method."); | ||
|
||
| } | ||
| } | ||
| #endif | ||
|
|
||
| unsigned int DofMap::add_variable(System & sys, | ||
| std::string_view var, | ||
| const FEType & type, | ||
|
|
@@ -3153,6 +3194,10 @@ unsigned int DofMap::add_variable(System & sys, | |
| if (active_subdomains) | ||
| libmesh_assert(this->comm().verify(active_subdomains->size())); | ||
|
|
||
| #ifdef DEBUG | ||
| discontinuity_sanity_check(sys, type, active_subdomains); | ||
| #endif | ||
|
|
||
| // Make sure the variable isn't there already | ||
| // or if it is, that it's the type we want | ||
| for (auto v : make_range(this->n_vars())) | ||
|
|
@@ -3262,6 +3307,10 @@ unsigned int DofMap::add_variables(System & sys, | |
| if (active_subdomains) | ||
| libmesh_assert(this->comm().verify(active_subdomains->size())); | ||
|
|
||
| #ifdef DEBUG | ||
| discontinuity_sanity_check(sys, type, active_subdomains); | ||
| #endif | ||
|
|
||
| // Make sure the variable isn't there already | ||
| // or if it is, that it's the type we want | ||
| for (auto ovar : vars) | ||
|
|
||
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.
is this chatgpt or does this make sense to you?
like the << and |= on chars
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.
well copilot explained it to me! Pretty creative
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.
I believe this is the sort of thing that's more clearly written with
std::bitsetin C++ code? But this was the standard idiom for bit sets in C code; I'm old enough that until I saw your comment it didn't even occur to me that the code here might be confusing.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.
I really like it for being extremely lightweight compared to a
std::set