352 bool interiorCellsOnly,
long *
id,
double *distance)
const
356 double tolerance = patch.
getTol();
362 std::size_t rootId = 0;
363 const SkdNode &root = m_nodes[rootId];
364 if (root.isEmpty()) {
365 *distance = std::numeric_limits<double>::max();
370 ClosestCellCandidates *closestCellCandidates =
nullptr;
371 std::unique_ptr<ClosestCellCandidates> privateStorage =
nullptr;
373 privateStorage = std::unique_ptr<ClosestCellCandidates>(
new ClosestCellCandidates());
374 closestCellCandidates = privateStorage.get();
376 closestCellCandidates = &m_closestCellCandidates;
378 closestCellCandidates->maxDistance = *distance;
379 findPointClosestCandidates(point, maxDistance, closestCellCandidates);
382 long nDistanceEvaluations = 0;
383 for (std::size_t k = 0; k < closestCellCandidates->ids.size(); ++k) {
386 if (
utils::DoubleFloatingGreater()(closestCellCandidates->minDistances.at(k), closestCellCandidates->maxDistance, tolerance, tolerance)) {
391 std::size_t nodeId = closestCellCandidates->ids.at(k);
392 const SkdNode &node = m_nodes[nodeId];
395 ++nDistanceEvaluations;
397 *distance = closestCellCandidates->maxDistance;
399 return nDistanceEvaluations;
564 bool interiorCellsOnly, std::vector<long> &ids,
double *distance)
const
568 double tolerance = patch.
getTol();
571 ids.resize(1, Cell::NULL_ID);
574 std::size_t rootId = 0;
575 const SkdNode &root = m_nodes[rootId];
576 if (root.isEmpty()) {
577 *distance = std::numeric_limits<double>::max();
585 ClosestCellCandidates *closestCellCandidates =
nullptr;
586 std::unique_ptr<ClosestCellCandidates> privateStorage =
nullptr;
588 privateStorage = std::unique_ptr<ClosestCellCandidates>(
new ClosestCellCandidates());
589 closestCellCandidates = privateStorage.get();
591 closestCellCandidates = &m_closestCellCandidates;
593 findPointClosestCandidates(point, maxDistance, closestCellCandidates);
596 *distance = closestCellCandidates->maxDistance;
597 long nDistanceEvaluations = 0;
598 for (std::size_t k = 0; k < closestCellCandidates->ids.size(); ++k) {
606 std::size_t nodeId = closestCellCandidates->ids.at(k);
607 const SkdNode &node = m_nodes[nodeId];
610 ++nDistanceEvaluations;
613 return nDistanceEvaluations;
782 long *ids,
int *ranks,
double *distances)
const
784 long nDistanceEvaluations = 0;
789 for (
int i = 0; i < nPoints; ++i) {
791 nDistanceEvaluations +=
findPointClosestCell(points[i], maxDistances[i], ids + i, distances + i);
797 return nDistanceEvaluations;
802 throw std::runtime_error(
"Skd-tree communicator has not been set.");
808 std::vector<int> pointsCount(m_nProcessors);
809 MPI_Allgather(&nPoints, 1, MPI_INT, pointsCount.data(), 1, MPI_INT, communicator);
812 std::vector<int> globalPointsDispls(m_nProcessors, 0);
813 std::vector<int> globalPointsOffsets(m_nProcessors, 0);
814 std::vector<int> globalPointsDataCount(m_nProcessors, 0);
816 globalPointsDataCount[0] = 3 * pointsCount[0];
817 for (
int i = 1; i < m_nProcessors; ++i) {
818 globalPointsDispls[i] = globalPointsDispls[i - 1] + 3 * pointsCount[i - 1];
819 globalPointsOffsets[i] = globalPointsOffsets[i - 1] + pointsCount[i - 1];
820 globalPointsDataCount[i] = 3 * pointsCount[i];
823 int nGlobalPoints = globalPointsDispls.back() + pointsCount.back();
826 std::vector<std::array<double,3>> globalPoints(nGlobalPoints);
827 int pointsDataCount = 3 * nPoints;
828 MPI_Allgatherv(points, pointsDataCount, MPI_DOUBLE, globalPoints.data(),
829 globalPointsDataCount.data(), globalPointsDispls.data(), MPI_DOUBLE, communicator);
832 std::vector<double> globalMaxDistances(nGlobalPoints);
833 MPI_Allgatherv(maxDistances, nPoints, MPI_DOUBLE, globalMaxDistances.data(),
834 pointsCount.data(), globalPointsOffsets.data(), MPI_DOUBLE, communicator);
837 std::vector<SkdGlobalCellDistance> globalCellDistances(nGlobalPoints);
840 for (
int i = 0; i < nGlobalPoints; ++i) {
842 const std::array<double, 3> &point = globalPoints[i];
847 double pointMaxDistance = globalMaxDistances[i];
848 for (
int rank = 0; rank < m_nProcessors; ++rank) {
849 pointMaxDistance = std::min(
getPartitionBox(rank).evalPointMaxDistance(point, std::numeric_limits<double>::max()), pointMaxDistance);
854 int &cellRank = globalCellDistance.
getRank();
855 long &cellId = globalCellDistance.
getId();
856 double &cellDistance = globalCellDistance.
getDistance();
859 bool interiorCellsOnly =
true;
860 nDistanceEvaluations +=
findPointClosestCell(point, pointMaxDistance, interiorCellsOnly, &cellId, &cellDistance);
863 if (cellId != Cell::NULL_ID) {
871 for (
int rank = 0; rank < m_nProcessors; ++rank) {
874 MPI_Reduce(MPI_IN_PLACE, globalCellDistance, pointsCount[rank], globalCellDistanceDatatype, globalCellDistanceMinOp, rank, communicator);
876 MPI_Reduce(globalCellDistance, globalCellDistance, pointsCount[rank], globalCellDistanceDatatype, globalCellDistanceMinOp, rank, communicator);
881 for (
int i = 0; i < nPoints; ++i) {
882 int globalIndex = i + globalPointsOffsets[
m_rank];
884 globalCellDistance.
exportData(ranks + i, ids + i, distances + i);
887 return nDistanceEvaluations;