36 #include "DistanceMapCalculator.hpp"
37 #include "DistributedTetrahedralMesh.hpp"
39 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
43 mWorkOnEntireMesh(true),
44 mNumHalosPerProcess(nullptr),
47 mTargetNodeIndex(UINT_MAX),
63 mLo =
mrMesh.GetDistributedVectorFactory()->GetLow();
64 mHi =
mrMesh.GetDistributedVectorFactory()->GetHigh();
72 MPI_Allgather(&my_size, 1, MPI_UNSIGNED,
mNumHalosPerProcess, 1, MPI_UNSIGNED, PETSC_COMM_WORLD);
76 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
78 const std::vector<unsigned>& rSourceNodeIndices,
79 std::vector<double>& rNodeDistances)
81 rNodeDistances.resize(mNumNodes);
82 for (
unsigned index=0; index<mNumNodes; index++)
84 rNodeDistances[index] = DBL_MAX;
86 assert(mActivePriorityNodeIndexQueue.empty());
90 assert(rSourceNodeIndices.size() == 1);
91 unsigned source_node_index = rSourceNodeIndices[0];
94 if (mLo<=source_node_index && source_node_index<mHi)
96 double heuristic_correction = norm_2(mrMesh.GetNode(source_node_index)->rGetLocation()-mTargetNodePoint);
97 PushLocal(heuristic_correction, source_node_index);
98 rNodeDistances[source_node_index] = heuristic_correction;
103 for (
unsigned source_index=0; source_index<rSourceNodeIndices.size(); source_index++)
105 unsigned source_node_index = rSourceNodeIndices[source_index];
106 PushLocal(0.0, source_node_index);
107 rNodeDistances[source_node_index] = 0.0;
111 bool non_empty_queue =
true;
114 while (non_empty_queue)
116 bool termination = WorkOnLocalQueue(rNodeDistances);
129 non_empty_queue = UpdateQueueFromRemote(rNodeDistances);
132 if (mWorkOnEntireMesh ==
false)
136 std::vector<double> local_distances = rNodeDistances;
139 MPI_Allreduce( &local_distances[0], &rNodeDistances[0], mNumNodes, MPI_DOUBLE, MPI_MIN, PETSC_COMM_WORLD);
143 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
146 if (mWorkOnEntireMesh)
149 return !mActivePriorityNodeIndexQueue.empty();
154 double* dist_exchange =
new double[ mNumHalosPerProcess[bcast_process] ];
155 unsigned* index_exchange =
new unsigned[ mNumHalosPerProcess[bcast_process] ];
159 for (
unsigned index=0; index<mHaloNodeIndices.size();index++)
161 dist_exchange[index] = rNodeDistances[mHaloNodeIndices[index]];
162 index_exchange[index] = mHaloNodeIndices[index];
171 MPI_Bcast(dist_exchange, mNumHalosPerProcess[bcast_process], MPI_DOUBLE,
172 bcast_process, PETSC_COMM_WORLD);
173 MPI_Bcast(index_exchange, mNumHalosPerProcess[bcast_process], MPI_UNSIGNED,
174 bcast_process, PETSC_COMM_WORLD);
178 for (
unsigned index=0; index<mNumHalosPerProcess[bcast_process];index++)
180 unsigned global_index=index_exchange[index];
182 if (dist_exchange[index] < rNodeDistances[global_index]*(1.0-2*DBL_EPSILON) )
185 rNodeDistances[global_index] = dist_exchange[index];
186 PushLocal(rNodeDistances[global_index], global_index);
190 delete [] dist_exchange;
191 delete [] index_exchange;
195 return(non_empty_queue);
198 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
202 while (!mActivePriorityNodeIndexQueue.empty())
205 unsigned current_node_index = mActivePriorityNodeIndexQueue.top().second;
206 double distance_when_queued = -mActivePriorityNodeIndexQueue.top().first;
207 mActivePriorityNodeIndexQueue.pop();
211 if (distance_when_queued == rNodeDistances[current_node_index])
215 double current_heuristic = 0.0;
218 current_heuristic=norm_2(p_current_node->
rGetLocation()-mTargetNodePoint);
230 for (
unsigned node_local_index=0;
231 node_local_index<p_containing_element->
GetNumNodes();
235 unsigned neighbour_node_index = p_neighbour_node->
GetIndex();
238 if (neighbour_node_index != current_node_index)
241 double neighbour_heuristic=0.0;
244 neighbour_heuristic=norm_2(p_neighbour_node->
rGetLocation()-mTargetNodePoint);
247 double updated_distance = rNodeDistances[current_node_index] +
249 - current_heuristic + neighbour_heuristic;
250 if (updated_distance < rNodeDistances[neighbour_node_index] * (1.0-2*DBL_EPSILON))
252 rNodeDistances[neighbour_node_index] = updated_distance;
253 PushLocal(updated_distance, neighbour_node_index);
260 if (current_node_index == mTargetNodeIndex)
265 if (mPopCounter%pop_stop == 0)
276 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
279 std::vector<unsigned> source_node_index_vector;
280 source_node_index_vector.push_back(sourceNodeIndex);
283 mTargetNodeIndex = targetNodeIndex;
284 mSingleTarget =
true;
287 c_vector<double, SPACE_DIM> target_point = zero_vector<double>(SPACE_DIM);
288 if (mrMesh.GetDistributedVectorFactory()->IsGlobalIndexLocal(mTargetNodeIndex))
291 target_point = mrMesh.GetNode(mTargetNodeIndex)->rGetLocation();
295 MPI_Allreduce(&target_point[0], &mTargetNodePoint[0], SPACE_DIM, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD);
298 std::vector<double> distances;
299 ComputeDistanceMap(source_node_index_vector, distances);
304 mSingleTarget =
false;
307 if (!mActivePriorityNodeIndexQueue.empty())
309 mActivePriorityNodeIndexQueue = std::priority_queue<std::pair<double, unsigned> >();
312 return distances[targetNodeIndex];
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
std::vector< unsigned > mHaloNodeIndices
unsigned * mNumHalosPerProcess
void GetHaloNodeIndices(std::vector< unsigned > &rHaloIndices) const
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
ContainingElementIterator ContainingElementsBegin() const
unsigned GetNumNodes() const
bool UpdateQueueFromRemote(std::vector< double > &rNodeDistances)
const c_vector< double, SPACE_DIM > & rGetLocation() const
bool WorkOnLocalQueue(std::vector< double > &rNodeDistances)
unsigned GetIndex() const
void ComputeDistanceMap(const std::vector< unsigned > &rSourceNodeIndices, std::vector< double > &rNodeDistances)
DistanceMapCalculator(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
ContainingElementIterator ContainingElementsEnd() const
double SingleDistance(unsigned sourceNodeIndex, unsigned destinationNodeIndex)