Skip to content
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

Improve python exposure of determine_point_ownership #3344

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

ordinary-slim
Copy link

Python wrapper around nanobind exposure of determine_point_ownership and extra optional arguments cells so that the search is performed only for cells.

Copy link
Sponsor Member

@jorgensd jorgensd left a 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. Could you add a test for this?:)

python/dolfinx/geometry.py Outdated Show resolved Hide resolved
python/dolfinx/geometry.py Outdated Show resolved Hide resolved
python/dolfinx/geometry.py Outdated Show resolved Hide resolved
python/dolfinx/geometry.py Outdated Show resolved Hide resolved
python/dolfinx/geometry.py Outdated Show resolved Hide resolved
python/dolfinx/geometry.py Outdated Show resolved Hide resolved
@ordinary-slim
Copy link
Author

Looks good to me. Could you add a test for this?:)

I added a test comparing bounding box tree results to determine_point_ownership. Another possibility would be to look at post files and hardcode rank-cell data into a test.

Comment on lines 516 to 520
def test_po_against_bb_tree(mesh,points,cells):
cells = np.array([cell for cell in cells if cell < cell_map.size_local])
num_points = points.shape[0]
po = determine_point_ownership(mesh,points,cells)
tree = bb_tree(mesh, mesh.topology.dim, cells)
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Run ruff format and ruff check --fix on the Python files to assure appropriate formatting.

@ordinary-slim
Copy link
Author

ordinary-slim commented Aug 21, 2024

Sorry, I made a mess with my branches in my fork and closed the pull request by mistake. Is it possible to reopen it pointing to https://github.com/ordinary-slim/dolfinx/tree/main ?

@jorgensd @jhale

@jorgensd
Copy link
Sponsor Member

Sorry, I made a mess with my branches in my fork and closed the pull request by mistake. Is it possible to reopen it pointing to https://github.com/ordinary-slim/dolfinx/tree/main ?

@jorgensd @jhale

I think you have to reopen it from your repository. See: https://gist.github.com/Farhan-Haseeb/fd4cbb476de4e2931c322d7bacb75e5f

@ordinary-slim
Copy link
Author

Sorry, I made a mess with my branches in my fork and closed the pull request by mistake. Is it possible to reopen it pointing to https://github.com/ordinary-slim/dolfinx/tree/main ?
@jorgensd @jhale

I think you have to reopen it from your repository. See: https://gist.github.com/Farhan-Haseeb/fd4cbb476de4e2931c322d7bacb75e5f

I can't see the PR from my repository. I deleted the original branch of the PR and it automatically closed it. The reopen button is greyed out:
Screenshot

The link you provided says:

If you changed the branch name or deleted the branch, the reopen pull request button will be disabled so first you need to click the restore branch button in the right section of your commit ( change branch name / delete branch commit) inside your pull request then the reopen button will be enabled

But I can't find this restore branch button. Could you look for it on your side? Else I think I have to open a new PR. Sorry for the inconvenience!

@jorgensd
Copy link
Sponsor Member

I cannot reopen. Please open a new PR:)

@ordinary-slim
Copy link
Author

ordinary-slim commented Aug 22, 2024

Ok, I had to recover the deleted branch with the same name then I could reopen, as per this stackoverflow comment. Sorry for the inconvenience!

@ordinary-slim ordinary-slim reopened this Aug 22, 2024
* Python wrapper around nanobind exposed function
* Extra optional arguments `cells`
Copy link
Sponsor Member

@jorgensd jorgensd left a comment

Choose a reason for hiding this comment

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

I am happy with these changes.
What do you think @jhale ?:)

@jorgensd
Copy link
Sponsor Member

@ordinary-slim could you run
ruff format and ruff check --fix on the ./python/dolfinx folder to ensure that we follow ruff/black standards, ref: https://github.com/FEniCS/dolfinx/actions/runs/10579774006/job/29313029757?pr=3344

@mscroggs mscroggs added this to the 0.9.0 milestone Sep 3, 2024
h = dtype(1.0 / num_cells_side)
if tdim == 2:
mesh = create_unit_square(
MPI.COMM_WORLD, num_cells_side, num_cells_side, CellType.quadrilateral, dtype=dtype
Copy link
Member

Choose a reason for hiding this comment

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

Can it be. parameterised across the mesh? (triangle, quad, tet, hex)?

Copy link
Author

Choose a reason for hiding this comment

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

No, as the test is now it needs the elements to coincide with their bounding boxes. I'll commit a version that covers triangles and tet elements.

Copy link
Member

Choose a reason for hiding this comment

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

That would be great, thank you.

A large padding value will increase the run-time of the code by orders
of magnitude. General advice is to use a padding on the scale of the
cell size.

Copy link
Member

Choose a reason for hiding this comment

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

Remove new line?

/// where src_owner is a list of ranks corresponding to the input
/// points. dest_owner is a list of ranks corresponding to dest_points,
/// the points that this process owns. dest_cells contains the
/// @return Point ownership data with fields `src_owner`, `dest_owner`, `dest_points`, `dest_cells`,
Copy link
Member

Choose a reason for hiding this comment

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

I think this documentation should be moved out to the struct itself.

mesh: Mesh,
points: npt.NDArray[np.floating],
cells: typing.Optional[npt.NDArray[np.int32]] = None,
padding: float = 0.0,
Copy link
Member

Choose a reason for hiding this comment

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

As this argument is critical to the behaviour of the function it is best to leave it as a non-default. Then user's need to engage with it, rather than not realise it exists.

Copy link
Author

Choose a reason for hiding this comment

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

I am bit reluctant to do this change since if cells is left as default then the argument order mesh, points, padding, cells feels a bit awkward to me. Moreover bb_tree also has a default value for padding.

Copy link
Member

Choose a reason for hiding this comment

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

@jorgensd @garth-wells What do you think about this padding argument? My view is that as it's critical to the operation of the bounding box and we cannot provide a sensible default, it's better not to have it hidden as a default parameter.

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

I think it is a crucial parameter. We have already rewritten the API for non-matching interpolation since 0.7, so I think it is fine to make it required.

Copy link
Member

Choose a reason for hiding this comment

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

@ordinary-slim Please make it non-default argument in both bounding box tree and here.

/// @note A large padding value can increase the runtime of the function by
/// orders of magnitude, because for non-colliding cells
/// one has to determine the closest cell among all processes with an
/// intersecting bounding box, which is an expensive operation to perform.
template <std::floating_point T>
PointOwnershipData<T> determine_point_ownership(const mesh::Mesh<T>& mesh,
std::span<const T> points,
T padding)
std::span<const std::int32_t> cells,
T padding = 0.0)
Copy link
Member

Choose a reason for hiding this comment

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

As this argument is critical to the behaviour of the function it is best to leave it as a non-default. Then user's need to engage with it, rather than not realise it exists.

Copy link
Author

Choose a reason for hiding this comment

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

padding is forwarded to BoundingBoxTree constructor where it is also default.

Copy link
Member

Choose a reason for hiding this comment

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

@ordinary-slim Please make it non-default argument in both bounding box tree and here.

/// @note A large padding value can increase the runtime of the function by
/// orders of magnitude, because for non-colliding cells
/// one has to determine the closest cell among all processes with an
/// intersecting bounding box, which is an expensive operation to perform.
template <std::floating_point T>
PointOwnershipData<T> determine_point_ownership(const mesh::Mesh<T>& mesh,
std::span<const T> points,
T padding)
std::span<const std::int32_t> cells,
Copy link
Member

Choose a reason for hiding this comment

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

This argument could be converted to std::optional - can be done on later patch.

of a point if the point is on the surface of a cell in the mesh.

Returns:
Point ownership data
Copy link
Member

Choose a reason for hiding this comment

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

Are the fields of PointOwnershipData documented in the Python wrapped class?

Copy link
Author

Choose a reason for hiding this comment

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

def src_owner(self) -> npt.NDArray[np.int32]:
"""Ranks owning each point sent into ownership determination for current process"""
return self._cpp_object.src_owner
def dest_owner(self) -> npt.NDArray[np.int32]:
"""Ranks that sent `dest_points` to current process"""
return self._cpp_object.dest_owners
def dest_points(self) -> npt.NDArray[np.floating]:
"""Points owned by current rank"""
return self._cpp_object.dest_points
def dest_cells(self) -> npt.NDArray[np.int32]:
"""Cell indices (local to process) where each entry of `dest_points` is located"""
return self._cpp_object.dest_cells

The doc is the same as on the c++ side.

Copy link
Member

Choose a reason for hiding this comment

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

Looks good, thanks for pointing it out to me.

The C++ documentation for the return argument describing PointOwnershipData looks over-specified given the struct is now properly documented.

cpp/dolfinx/geometry/utils.h Show resolved Hide resolved
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.

5 participants