41 #include "DTK_ParallelSearch.hpp" 44 #include <Tpetra_Distributor.hpp> 51 const Teuchos::RCP<
const Teuchos::Comm<int>> &comm,
52 const int physical_dimension,
const EntityIterator &domain_iterator,
53 const Teuchos::RCP<EntityLocalMap> &domain_local_map,
54 const Teuchos::ParameterList ¶meters )
56 , d_physical_dim( physical_dimension )
57 , d_track_missed_range_entities( false )
58 , d_missed_range_entity_ids( 0 )
61 domain_local_map->setParameters( parameters );
64 if ( parameters.isParameter(
"Track Missed Range Entities" ) )
66 d_track_missed_range_entities =
67 parameters.get<
bool>(
"Track Missed Range Entities" );
73 d_comm, physical_dimension, domain_iterator, parameters ) );
76 d_empty_domain = ( 0 == domain_iterator.size() );
77 if ( !d_empty_domain )
80 domain_iterator, domain_local_map, parameters ) );
89 void ParallelSearch::search(
91 const Teuchos::RCP<EntityLocalMap> &range_local_map,
92 const Teuchos::ParameterList ¶meters )
95 range_local_map->setParameters( parameters );
98 d_empty_range = ( 0 == range_iterator.size() );
101 d_range_owner_ranks.clear();
102 d_domain_to_range_map.clear();
103 d_range_to_domain_map.clear();
104 d_parametric_coords.clear();
107 Teuchos::Array<EntityId> range_entity_ids;
108 Teuchos::Array<int> range_owner_ranks;
109 Teuchos::Array<double> range_centroids;
110 d_coarse_global_search->search( range_iterator, range_local_map, parameters,
111 range_entity_ids, range_owner_ranks,
116 Teuchos::Array<EntityId> found_range_entity_ids;
117 Teuchos::Array<int> found_range_ranks;
118 Teuchos::Array<EntityId> missed_range_entity_ids;
119 Teuchos::Array<int> missed_range_ranks;
120 if ( d_track_missed_range_entities )
122 missed_range_entity_ids = Teuchos::Array<EntityId>(
123 d_coarse_global_search->getMissedRangeEntityIds() );
124 missed_range_ranks.assign( missed_range_entity_ids.size(),
129 Teuchos::Array<int> export_range_ranks;
130 Teuchos::Array<EntityId> export_data;
131 if ( !d_empty_domain )
134 int num_range = range_entity_ids.size();
135 Teuchos::Array<Entity> domain_neighbors;
136 Teuchos::Array<Entity> domain_parents;
137 Teuchos::Array<double> reference_coordinates;
138 Teuchos::Array<double> local_coords( d_physical_dim );
140 for (
int n = 0; n < num_range; ++n )
144 d_coarse_local_search->search(
145 range_centroids( d_physical_dim * n, d_physical_dim ),
146 parameters, domain_neighbors );
150 d_fine_local_search->search(
152 range_centroids( d_physical_dim * n, d_physical_dim ),
153 parameters, domain_parents, reference_coordinates );
157 std::unordered_map<EntityId, Teuchos::Array<double>> ref_map;
158 num_parents = domain_parents.size();
159 for (
int p = 0; p < num_parents; ++p )
162 local_coords().assign( reference_coordinates(
163 d_physical_dim * p, d_physical_dim ) );
164 d_range_owner_ranks.emplace( range_entity_ids[n],
165 range_owner_ranks[n] );
166 d_domain_to_range_map.emplace( domain_parents[p].
id(),
167 range_entity_ids[n] );
168 ref_map.emplace( domain_parents[p].
id(), local_coords );
172 export_range_ranks.push_back( range_owner_ranks[n] );
173 export_data.push_back( range_entity_ids[n] );
174 export_data.push_back( domain_parents[p].
id() );
175 export_data.push_back(
176 Teuchos::as<EntityId>( d_comm->getRank() ) );
180 if ( num_parents > 0 )
182 d_parametric_coords.emplace( range_entity_ids[n], ref_map );
187 if ( d_track_missed_range_entities )
189 found_range_entity_ids.push_back( range_entity_ids[n] );
190 found_range_ranks.push_back( range_owner_ranks[n] );
195 else if ( d_track_missed_range_entities )
197 missed_range_entity_ids.push_back( range_entity_ids[n] );
198 missed_range_ranks.push_back( range_owner_ranks[n] );
205 Tpetra::Distributor domain_to_range_dist( d_comm );
207 domain_to_range_dist.createFromSends( export_range_ranks() );
208 Teuchos::Array<EntityId> domain_data( 3 * num_import );
209 Teuchos::ArrayView<const EntityId> export_data_view = export_data();
210 domain_to_range_dist.doPostsAndWaits( export_data_view, 3, domain_data() );
213 for (
int i = 0; i < num_import; ++i )
215 d_domain_owner_ranks.emplace( domain_data[3 * i + 1],
216 domain_data[3 * i + 2] );
217 d_range_to_domain_map.emplace( domain_data[3 * i],
218 domain_data[3 * i + 1] );
223 if ( d_track_missed_range_entities )
226 Tpetra::Distributor missed_range_dist( d_comm );
227 int num_import_missed =
228 missed_range_dist.createFromSends( missed_range_ranks() );
229 Teuchos::Array<EntityId> import_missed( num_import_missed );
230 Teuchos::ArrayView<const EntityId> missed_view =
231 missed_range_entity_ids();
232 missed_range_dist.doPostsAndWaits( missed_view, 1, import_missed() );
235 Tpetra::Distributor found_range_dist( d_comm );
236 int num_import_found =
237 found_range_dist.createFromSends( found_range_ranks() );
238 Teuchos::Array<EntityId> import_found( num_import_found );
239 Teuchos::ArrayView<const EntityId> found_view =
240 found_range_entity_ids();
241 found_range_dist.doPostsAndWaits( found_view, 1, import_found() );
244 std::sort( import_missed.begin(), import_missed.end() );
245 auto import_missed_unique_end =
246 std::unique( import_missed.begin(), import_missed.end() );
247 import_missed.resize(
248 std::distance( import_missed.begin(), import_missed_unique_end ) );
251 std::sort( import_found.begin(), import_found.end() );
252 auto import_found_unique_end =
253 std::unique( import_found.begin(), import_found.end() );
255 std::distance( import_found.begin(), import_found_unique_end ) );
259 Teuchos::Array<EntityId> false_positive_missed( import_missed.size() );
260 auto false_positive_end = std::set_intersection(
261 import_missed.begin(), import_missed.end(), import_found.begin(),
262 import_found.end(), false_positive_missed.begin() );
265 d_missed_range_entity_ids.resize( num_import_missed );
266 auto missed_range_end = std::set_difference(
267 import_missed.begin(), import_missed.end(),
268 false_positive_missed.begin(), false_positive_end,
269 d_missed_range_entity_ids.begin() );
270 d_missed_range_entity_ids.resize( std::distance(
271 d_missed_range_entity_ids.begin(), missed_range_end ) );
274 unsigned long long int n_entities =
275 d_missed_range_entity_ids.size() + import_found.size();
276 DTK_REQUIRE( n_entities == range_iterator.size() );
285 const EntityId domain_id, Teuchos::Array<EntityId> &range_ids )
const 287 DTK_REQUIRE( !d_empty_domain );
288 auto domain_pair = d_domain_to_range_map.equal_range( domain_id );
289 range_ids.resize( std::distance( domain_pair.first, domain_pair.second ) );
290 auto range_it = range_ids.begin();
291 for (
auto domain_it = domain_pair.first; domain_it != domain_pair.second;
292 ++domain_it, ++range_it )
294 *range_it = domain_it->second;
302 const EntityId range_id, Teuchos::Array<EntityId> &domain_ids )
const 304 DTK_REQUIRE( !d_empty_range );
305 auto range_pair = d_range_to_domain_map.equal_range( range_id );
306 domain_ids.resize( std::distance( range_pair.first, range_pair.second ) );
307 auto domain_it = domain_ids.begin();
308 for (
auto range_it = range_pair.first; range_it != range_pair.second;
309 ++range_it, ++domain_it )
311 *domain_it = range_it->second;
319 DTK_REQUIRE( !d_empty_domain );
320 DTK_REQUIRE( d_range_owner_ranks.count( range_id ) );
321 return d_range_owner_ranks.find( range_id )->second;
328 DTK_REQUIRE( !d_empty_range );
329 DTK_REQUIRE( d_domain_owner_ranks.count( domain_id ) );
330 return d_domain_owner_ranks.find( domain_id )->second;
337 Teuchos::ArrayView<const double> ¶metric_coords )
const 339 DTK_REQUIRE( !d_empty_domain );
340 DTK_REQUIRE( d_parametric_coords.count( range_id ) );
342 d_parametric_coords.find( range_id )->second.count( domain_id ) );
344 d_parametric_coords.find( range_id )->second.find( domain_id )->second;
351 Teuchos::ArrayView<const EntityId>
354 return d_missed_range_entity_ids();
A CoarseLocalSearch data structure for local entity coarse search.
void getRangeEntitiesFromDomain(const EntityId domain_id, Teuchos::Array< EntityId > &range_ids) const
Given a domain entity id on a domain process, get the ids of the range entities that mapped to it...
int rangeEntityOwnerRank(const EntityId range_id) const
Get the owner rank of a given range entity on a domain process.
Entity iterator interface.
int domainEntityOwnerRank(const EntityId domain_id) const
Get the owner rank of a given domain entity on a rank process.
void rangeParametricCoordinatesInDomain(const EntityId domain_id, const EntityId range_id, Teuchos::ArrayView< const double > ¶metric_coords) const
Get the parametric coordinates of the range entities in the domain entities on a domain process...
A FineLocalSearch data structure for local entity fine search.
Assertions and Design-by-Contract for error handling.
A CoarseGlobalSearch data structure for global entity coarse search.
unsigned long int EntityId
Entity id type.
void getDomainEntitiesFromRange(const EntityId range_id, Teuchos::Array< EntityId > &domain_ids) const
Given a range entity id on a range process, get the ids of the domain entities that it mapped to...
ParallelSearch(const Teuchos::RCP< const Teuchos::Comm< int >> &comm, const int physical_dimension, const EntityIterator &domain_iterator, const Teuchos::RCP< EntityLocalMap > &domain_local_map, const Teuchos::ParameterList ¶meters)
Constructor.
Teuchos::ArrayView< const EntityId > getMissedRangeEntityIds() const
Return the ids of the range entities that were not during the last search (i.e. those that are guaran...