-
-
Notifications
You must be signed in to change notification settings - Fork 182
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
base: main
Are you sure you want to change the base?
Changes from all commits
9f2597a
434aa5e
5855796
881434c
5b6726f
b06ab5a
aa7d47e
06c9928
7be7013
75a3bc5
05c609a
5baf1c2
6fda65d
5e1246d
9420238
74b9a22
a969271
3e481f0
ec3f179
5313809
de68fc9
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 |
---|---|---|
|
@@ -663,41 +663,41 @@ graph::AdjacencyList<std::int32_t> compute_colliding_cells( | |
/// @param[in] mesh The mesh | ||
/// @param[in] points Points to check for collision (`shape=(num_points, | ||
/// 3)`). Storage is row-major. | ||
/// @param[in] cells Cells to check for ownership | ||
jhale marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// @param[in] padding Amount of absolute padding of bounding boxes of the mesh. | ||
/// Each bounding box of the mesh is padded with this amount, to increase | ||
/// the number of candidates, avoiding rounding errors in determining the owner | ||
/// of a point if the point is on the surface of a cell in the mesh. | ||
/// @return Tuple `(src_owner, dest_owner, dest_points, dest_cells)`, | ||
/// 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 | ||
/// corresponding cell for each entry in dest_points. | ||
/// @return Point ownership data. | ||
/// | ||
/// @note `dest_owner` is sorted | ||
/// @note Returns -1 if no colliding process is found | ||
/// @note `src_owner` is -1 if no colliding process is found | ||
/// @note dest_points is flattened row-major, shape `(dest_owner.size(), | ||
/// 3)` | ||
/// @note Only looks through cells owned by the process | ||
/// @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) | ||
T padding, | ||
std::span<const std::int32_t> cells = {}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
{ | ||
MPI_Comm comm = mesh.comm(); | ||
|
||
const int tdim = mesh.topology()->dim(); | ||
|
||
std::vector<std::int32_t> local_cells; | ||
if (cells.empty()) { | ||
auto cell_map = mesh.topology()->index_map(tdim); | ||
local_cells.resize(cell_map->size_local()); | ||
std::iota(local_cells.begin(), local_cells.end(), 0); | ||
cells = std::span<const std::int32_t>(local_cells.data(), local_cells.size()); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jhale I made There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still an issue? |
||
// Create a global bounding-box tree to find candidate processes with | ||
// cells that could collide with the points | ||
const int tdim = mesh.topology()->dim(); | ||
auto cell_map = mesh.topology()->index_map(tdim); | ||
const std::int32_t num_cells = cell_map->size_local(); | ||
// NOTE: Should we send the cells in as input? | ||
std::vector<std::int32_t> cells(num_cells, 0); | ||
std::iota(cells.begin(), cells.end(), 0); | ||
BoundingBoxTree bb(mesh, tdim, cells, padding); | ||
BoundingBoxTree bb(mesh, tdim, padding, cells); | ||
BoundingBoxTree global_bbtree = bb.create_global_tree(comm); | ||
|
||
// Compute collisions: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,8 +103,8 @@ def create_global_tree(self, comm) -> BoundingBoxTree: | |
def bb_tree( | ||
mesh: Mesh, | ||
dim: int, | ||
padding: float, | ||
entities: typing.Optional[npt.NDArray[np.int32]] = None, | ||
padding: float = 0.0, | ||
) -> BoundingBoxTree: | ||
"""Create a bounding box tree for use in collision detection. | ||
|
||
|
@@ -128,11 +128,11 @@ def bb_tree( | |
dtype = mesh.geometry.x.dtype | ||
if np.issubdtype(dtype, np.float32): | ||
return BoundingBoxTree( | ||
_cpp.geometry.BoundingBoxTree_float32(mesh._cpp_object, dim, entities, padding) | ||
_cpp.geometry.BoundingBoxTree_float32(mesh._cpp_object, dim, padding, entities) | ||
) | ||
elif np.issubdtype(dtype, np.float64): | ||
return BoundingBoxTree( | ||
_cpp.geometry.BoundingBoxTree_float64(mesh._cpp_object, dim, entities, padding) | ||
_cpp.geometry.BoundingBoxTree_float64(mesh._cpp_object, dim, padding, entities) | ||
) | ||
else: | ||
raise NotImplementedError(f"Type {dtype} not supported.") | ||
|
@@ -270,3 +270,45 @@ def compute_distance_gjk( | |
|
||
""" | ||
return _cpp.geometry.compute_distance_gjk(p, q) | ||
|
||
|
||
def determine_point_ownership( | ||
mesh: Mesh, | ||
points: npt.NDArray[np.floating], | ||
padding: float, | ||
cells: typing.Optional[npt.NDArray[np.int32]] = None, | ||
) -> PointOwnershipData: | ||
"""Build point ownership data for a mesh-points pair. | ||
|
||
First, potential collisions are found by computing intersections | ||
between the bounding boxes of the cells and the set of points. | ||
Then, actual containment pairs are determined using the GJK algorithm. | ||
|
||
Args: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting needs fixing - second and subsequent lines of docstring for an argument must be indented. |
||
mesh: The mesh | ||
points: Points to check for collision (``shape=(num_points, gdim)``) | ||
padding: Amount of absolute padding of bounding boxes of the mesh. | ||
Each bounding box of the mesh is padded with this amount, to increase | ||
the number of candidates, avoiding rounding errors in determining the owner | ||
of a point if the point is on the surface of a cell in the mesh. | ||
cells: Cells to check for ownership | ||
If ``None`` then all cells are considered. | ||
|
||
Returns: | ||
Point ownership data | ||
jhale marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Note: | ||
``dest_owner`` is sorted | ||
|
||
``src_owner`` is -1 if no colliding process is found | ||
|
||
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. | ||
""" | ||
if cells is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you switch the C++ interface to |
||
map = mesh.topology.index_map(mesh.topology.dim) | ||
cells = np.arange(map.size_local, dtype=np.int32) | ||
return PointOwnershipData( | ||
_cpp.geometry.determine_point_ownership(mesh._cpp_object, points, cells, padding) | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,17 +34,16 @@ void declare_bbtree(nb::module_& m, std::string type) | |
"__init__", | ||
[](dolfinx::geometry::BoundingBoxTree<T>* bbt, | ||
const dolfinx::mesh::Mesh<T>& mesh, int dim, | ||
double padding, | ||
nb::ndarray<const std::int32_t, nb::ndim<1>, nb::c_contig> | ||
entities, | ||
double padding) | ||
entities) | ||
{ | ||
new (bbt) dolfinx::geometry::BoundingBoxTree<T>( | ||
mesh, dim, | ||
std::span<const std::int32_t>(entities.data(), entities.size()), | ||
padding); | ||
padding, | ||
std::span<const std::int32_t>(entities.data(), entities.size())); | ||
}, | ||
nb::arg("mesh"), nb::arg("dim"), nb::arg("entities"), | ||
nb::arg("padding") = 0.0) | ||
nb::arg("mesh"), nb::arg("dim"), nb::arg("padding"), nb::arg("entities")) | ||
.def_prop_ro("num_bboxes", | ||
&dolfinx::geometry::BoundingBoxTree<T>::num_bboxes) | ||
.def( | ||
|
@@ -182,13 +181,18 @@ void declare_bbtree(nb::module_& m, std::string type) | |
nb::arg("mesh"), nb::arg("dim"), nb::arg("indices"), nb::arg("points")); | ||
m.def("determine_point_ownership", | ||
[](const dolfinx::mesh::Mesh<T>& mesh, | ||
nb::ndarray<const T, nb::c_contig> points, const T padding) | ||
nb::ndarray<const T, nb::c_contig> points, | ||
nb::ndarray<const std::int32_t, nb::ndim<1>, nb::c_contig> cells, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
const T padding) | ||
{ | ||
std::size_t p_s0 = points.ndim() == 1 ? 1 : points.shape(0); | ||
std::span<const T> _p(points.data(), 3 * p_s0); | ||
return dolfinx::geometry::determine_point_ownership<T>(mesh, _p, | ||
padding); | ||
}); | ||
padding, | ||
std::span(cells.data(), cells.size())); | ||
}, | ||
nb::arg("mesh"), nb::arg("points"), nb::arg("padding"), nb::arg("cells"), | ||
"Compute point ownership data for mesh-points pair."); | ||
|
||
std::string pod_pyclass_name = "PointOwnershipData_" + type; | ||
nb::class_<dolfinx::geometry::PointOwnershipData<T>>(m, | ||
|
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.
Could you switch this literal 0 to 0.0 so it's 100% clear T is a floating point type.