-
-
Notifications
You must be signed in to change notification settings - Fork 174
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
Simplify integration domain packing #3215
Conversation
Co-authored-by: Joe Dean <jpd62@cam.ac.uk>
@jpdean Thanks for your comments. I've addressed them by simplifying |
Is there anything specific holding this PR back? |
Wait for @jpdean to return and add approval. |
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 think letting compute_integration_domains
just deal with turning a list of mesh entities into data needed for the assembler (instead of worrying about meshtag values) is a good idea. It fits the DOLFINx design philosophy better than the function in main. One downside is that it basically does nothing for cells now, but that's not a big issue. It might make user C++ code a bit more complex though, because they'll have to loop over integration domains and call this function manually. Overall, I prefer the approach in this PR to the one in main.
As I've seen no C++ example where this function is actually used, I don't think we should worry to much. |
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.
Looks good to me! One thing I'd like to do is simplify this logic if possible:
dolfinx/python/dolfinx/fem/forms.py
Lines 203 to 242 in 159cb1c
# Make map from integral_type to subdomain id | |
subdomain_ids = {type: [] for type in sd.get(domain).keys()} | |
for integral in form.integrals(): | |
if integral.subdomain_data() is not None: | |
subdomain_ids[integral.integral_type()].append(integral.subdomain_id()) | |
# Chain and sort subdomain ids | |
for itg_type, marker_ids in subdomain_ids.items(): | |
flattened_ids = list(chain(marker_ids)) | |
flattened_ids.sort() | |
subdomain_ids[itg_type] = flattened_ids | |
def get_integration_domains(integral_type, subdomain, subdomain_ids): | |
"""Get integration domains from subdomain data""" | |
if subdomain is None: | |
return [] | |
else: | |
domains = [] | |
try: | |
if integral_type in (IntegralType.exterior_facet, IntegralType.interior_facet): | |
tdim = subdomain.topology.dim | |
subdomain._cpp_object.topology.create_connectivity(tdim - 1, tdim) | |
subdomain._cpp_object.topology.create_connectivity(tdim, tdim - 1) | |
# Compute integration domains only for each subdomain id in the integrals | |
# If a process has no integral entities, insert an empty array | |
for id in subdomain_ids: | |
try: | |
integration_entities = _cpp.fem.compute_integration_domains( | |
integral_type, | |
subdomain._cpp_object.topology, | |
subdomain.find(id), | |
subdomain.dim, | |
) | |
domains.append((id, integration_entities)) | |
except TypeError: | |
pass # If subdomain id is "everywhere" | |
return [(s[0], np.array(s[1])) for s in domains] | |
except AttributeError: | |
return [(s[0], np.array(s[1])) for s in subdomain] |
It was already complicated in main, and this PR adds more complexity. Happy to look at this in a separate PR though; maybe we should make an issue?
We would have to change how ufl exposes integrals to touch upon this (I think). |
Resolve #3214 and #3213.
This PR changes the packing such that we only pack integral entities for those subdomain id's that exist in the integrals.
For processors with no entities for a given tag, we return the tuple (id, []) indicating that there is an integral of this type on the process, but that it has no entities.
This simplifies the packing of integration entities massively, as we only pack those specified by the form data, not for every value in the meshtags. It also returns a cleaner data-structure that can be used directly by users.