@@ -48,6 +48,9 @@ std::vector<T> shortest_vector(const mesh::Mesh<T>& mesh, int dim,
48
48
{
49
49
for (std::size_t e = 0 ; e < entities.size (); e++)
50
50
{
51
+ // Check that we have sent in valid entities, i.e. that they exist in the
52
+ // local dofmap. One gets a cryptical memory segfault if entities is -1
53
+ assert (entities[e] >= 0 );
51
54
auto dofs
52
55
= MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
53
56
submdspan (x_dofmap, entities[e],
@@ -674,6 +677,7 @@ determine_point_ownership(const mesh::Mesh<T>& mesh, std::span<const T> points)
674
677
std::vector<std::int32_t > cells (num_cells, 0 );
675
678
std::iota (cells.begin (), cells.end (), 0 );
676
679
BoundingBoxTree bb (mesh, tdim, cells, padding);
680
+ BoundingBoxTree midpoint_tree = create_midpoint_tree (mesh, tdim, cells);
677
681
BoundingBoxTree global_bbtree = bb.create_global_tree (comm);
678
682
679
683
// Compute collisions:
@@ -751,20 +755,15 @@ determine_point_ownership(const mesh::Mesh<T>& mesh, std::span<const T> points)
751
755
dolfinx::MPI::mpi_type<T>(), received_points.data (), recv_sizes.data (),
752
756
recv_offsets.data (), dolfinx::MPI::mpi_type<T>(), forward_comm);
753
757
754
- // Each process checks which points collides with a cell on the process
758
+ // Each process checks which local cell is closest and computes the squared
759
+ // distance to the cell
755
760
const int rank = dolfinx::MPI::rank (comm);
756
- std::vector<std::int32_t > cell_indicator (received_points.size () / 3 );
757
- std::vector<std::int32_t > colliding_cells (received_points.size () / 3 );
758
- for (std::size_t p = 0 ; p < received_points.size (); p += 3 )
759
- {
760
- std::array<T, 3 > point;
761
- std::copy (std::next (received_points.begin (), p),
762
- std::next (received_points.begin (), p + 3 ), point.begin ());
763
- const int colliding_cell
764
- = geometry::compute_first_colliding_cell (mesh, bb, point);
765
- cell_indicator[p / 3 ] = (colliding_cell >= 0 ) ? rank : -1 ;
766
- colliding_cells[p / 3 ] = colliding_cell;
767
- }
761
+ const std::vector<std::int32_t > closest_cells = compute_closest_entity (
762
+ bb, midpoint_tree, mesh,
763
+ std::span<const T>(received_points.data (), received_points.size ()));
764
+ const std::vector<T> squared_distances = squared_distance (
765
+ mesh, tdim, closest_cells,
766
+ std::span<const T>(received_points.data (), received_points.size ()));
768
767
769
768
// Create neighborhood communicator in the reverse direction: send
770
769
// back col to requesting processes
@@ -791,20 +790,28 @@ determine_point_ownership(const mesh::Mesh<T>& mesh, std::span<const T> points)
791
790
std::swap (recv_offsets, send_offsets);
792
791
}
793
792
794
- std::vector<std::int32_t > recv_ranks (recv_offsets.back ());
793
+ // Get distances from closest entity of points that were on the other process
794
+ std::vector<T> recv_distances (recv_offsets.back ());
795
795
MPI_Neighbor_alltoallv (
796
- cell_indicator.data (), send_sizes.data (), send_offsets.data (),
797
- dolfinx::MPI::mpi_type<std::int32_t >(), recv_ranks.data (),
798
- recv_sizes.data (), recv_offsets.data (),
799
- dolfinx::MPI::mpi_type<std::int32_t >(), reverse_comm);
796
+ squared_distances.data (), send_sizes.data (), send_offsets.data (),
797
+ dolfinx::MPI::mpi_type<T>(), recv_distances.data (), recv_sizes.data (),
798
+ recv_offsets.data (), dolfinx::MPI::mpi_type<T>(), reverse_comm);
800
799
801
800
std::vector<std::int32_t > point_owners (points.size () / 3 , -1 );
802
- for (std::size_t i = 0 ; i < unpack_map.size (); i++)
801
+ std::vector<T> closest_distance (points.size () / 3 , -1 );
802
+ for (std::size_t i = 0 ; i < out_ranks.size (); i++)
803
803
{
804
- const std::int32_t pos = unpack_map[i];
805
- // Only insert new owner if no owner has previously been found
806
- if ((recv_ranks[i] >= 0 ) && (point_owners[pos] == -1 ))
807
- point_owners[pos] = recv_ranks[i];
804
+ for (std::int32_t j = recv_offsets[i]; j < recv_offsets[i + 1 ]; j++)
805
+ {
806
+ const std::int32_t pos = unpack_map[j];
807
+ // If point has not been found yet distance is negative
808
+ // If new received distance smaller than current distance choose owner
809
+ if (auto d = closest_distance[pos]; d < 0 or d > recv_distances[j])
810
+ {
811
+ point_owners[pos] = out_ranks[i];
812
+ closest_distance[pos] = recv_distances[j];
813
+ }
814
+ }
808
815
}
809
816
810
817
// Communication is reversed again to send dest ranks to all processes
@@ -847,7 +854,7 @@ determine_point_ownership(const mesh::Mesh<T>& mesh, std::span<const T> points)
847
854
owned_recv_points.insert (
848
855
owned_recv_points.end (), std::next (received_points.cbegin (), 3 * j),
849
856
std::next (received_points.cbegin (), 3 * (j + 1 )));
850
- owned_recv_cells.push_back (colliding_cells [j]);
857
+ owned_recv_cells.push_back (closest_cells [j]);
851
858
}
852
859
}
853
860
}
0 commit comments