@@ -171,117 +171,110 @@ void CInterpolator::ReconstructBoundary(unsigned long val_zone, int val_marker){
171171
172172 CGeometry *geom = Geometry[val_zone][INST_0][MESH_0];
173173
174- unsigned long iVertex, kVertex ;
174+ unsigned long iVertex, jVertex, kVertex ;
175175
176- unsigned long *uptr, nVertex, nElems , iDim, nDim, iPoint;
176+ unsigned long count, iTmp, *uptr, dPoint, EdgeIndex, jEdge, nEdges, nNodes, nVertex , iDim, nDim, iPoint;
177177
178178 unsigned long nGlobalLinkedNodes, nLocalVertex, nLocalLinkedNodes;
179179
180180 nDim = geom->GetnDim ();
181181
182- /* --- If this zone has no parts of the marker, it will not participate
183- * in the first part of this function (collection). ---*/
184- if ( val_marker != -1 ){
182+ if ( val_marker != -1 )
185183 nVertex = geom->GetnVertex ( val_marker );
186- nElems = geom->GetnElem_Bound (val_marker);
187- } else {
184+ else
188185 nVertex = 0 ;
189- nElems = 0 ;
190- }
191186
192- /* --- Get the number of domain vertices on the marker, and a mapping
193- * (iVertex) -> (iLocalVertex, non-domain points being ignored). ---*/
194- unsigned long * iVertex_to_iLocalVertex = new unsigned long [ nVertex ];
195- nLocalVertex = 0 ;
196- for (iVertex = 0 ; iVertex < nVertex; iVertex++) {
197- iPoint = geom->vertex [val_marker][iVertex]->GetNode ();
198- if (geom->nodes ->GetDomain (iPoint)){
199- iVertex_to_iLocalVertex[iVertex] = nLocalVertex;
200- nLocalVertex++;
201- } else {
202- iVertex_to_iLocalVertex[iVertex] = numeric_limits<unsigned long >::max ();
203- }
204- }
205187
206- // coordinates of all domain vertices on the marker
207- su2double *Buffer_Send_Coord = new su2double [ nLocalVertex * nDim ];
208- // global point IDs of all domain vertices on the marker
209- long *Buffer_Send_GlobalPoint = new long [ nVertex ];
188+ su2double *Buffer_Send_Coord = new su2double [ nVertex * nDim ];
189+ unsigned long *Buffer_Send_GlobalPoint = new unsigned long [ nVertex ];
190+
191+ unsigned long *Buffer_Send_nLinkedNodes = new unsigned long [ nVertex ];
192+ unsigned long *Buffer_Send_StartLinkedNodes = new unsigned long [ nVertex ];
193+ unsigned long **Aux_Send_Map = new unsigned long *[ nVertex ];
194+
195+ #ifdef HAVE_MPI
196+ int nProcessor = size, iRank;
197+ unsigned long iTmp2, tmp_index, tmp_index_2;
198+ #endif
199+
200+ /* --- Copy coordinates and point to the auxiliar vector ---*/
210201
211- // Assign to each domain vertex on the marker, identified by local point ID,
212- // a set of surface-neighbor vertices on the marker, identified by global point ID.
213- map< unsigned long , forward_list< unsigned long >*> neighbors ;
202+ nGlobalVertex = 0 ;
203+ nLocalVertex = 0 ;
204+ nLocalLinkedNodes = 0 ;
214205
215- /* --- Define or initialize them. ---*/
216206 for (iVertex = 0 ; iVertex < nVertex; iVertex++) {
207+
208+ Buffer_Send_nLinkedNodes[iVertex] = 0 ;
209+ Aux_Send_Map[iVertex] = nullptr ;
210+
217211 iPoint = geom->vertex [val_marker][iVertex]->GetNode ();
212+
218213 if (geom->nodes ->GetDomain (iPoint)) {
219- unsigned long iLocalVertex = iVertex_to_iLocalVertex[iVertex] ;
220- Buffer_Send_GlobalPoint[iLocalVertex] = ( long ) geom-> nodes -> GetGlobalIndex (iPoint);
214+ Buffer_Send_GlobalPoint[nLocalVertex] = geom-> nodes -> GetGlobalIndex (iPoint) ;
215+
221216 for (iDim = 0 ; iDim < nDim; iDim++)
222- Buffer_Send_Coord[iLocalVertex*nDim+iDim] = geom->nodes ->GetCoord (iPoint, iDim);
223- neighbors.insert (pair<unsigned long , forward_list<unsigned long >*>(iPoint, new forward_list<unsigned long >));
224- }
225- }
217+ Buffer_Send_Coord[nLocalVertex*nDim+iDim] = geom->nodes ->GetCoord (iPoint, iDim);
226218
227- /* --- Define the neighbors map. ---*/
228- for (unsigned long iElem=0 ; iElem < nElems; iElem++){
229- CPrimalGrid* elem = geom->bound [val_marker][iElem];
230- for (unsigned short iNode=0 ; iNode<elem->GetnNodes (); iNode++){
231- iPoint = elem->GetNode (iNode);
232- if (geom->nodes ->GetDomain (iPoint)) {
233- forward_list<unsigned long >* neighb = neighbors.at (iPoint);
234- for (unsigned short iNeighbor=0 ; iNeighbor<elem->GetnNeighbor_Nodes (iNode); iNeighbor++){
235- unsigned long jPoint = elem->GetNode ( elem->GetNeighbor_Nodes (iNode,iNeighbor) );
236- unsigned long jPoint_global = geom->nodes ->GetGlobalIndex (jPoint);
237- if ( std::find (std::begin (*neighb), std::end (*neighb), jPoint_global) == std::end (*neighb) ){
238- neighb->emplace_front ( jPoint_global );
239- }
219+ nNodes = 0 ;
220+ nEdges = geom->nodes ->GetnPoint (iPoint);
221+
222+ for (jEdge = 0 ; jEdge < nEdges; jEdge++){
223+ EdgeIndex = geom->nodes ->GetEdge (iPoint, jEdge);
224+
225+ if ( iPoint == geom->edges ->GetNode (EdgeIndex,0 ) )
226+ dPoint = geom->edges ->GetNode (EdgeIndex,1 );
227+ else
228+ dPoint = geom->edges ->GetNode (EdgeIndex,0 );
229+
230+ if ( geom->nodes ->GetVertex (dPoint, val_marker) != -1 )
231+ nNodes++;
232+ }
233+
234+ Buffer_Send_StartLinkedNodes[nLocalVertex] = nLocalLinkedNodes;
235+ Buffer_Send_nLinkedNodes[nLocalVertex] = nNodes;
236+
237+ nLocalLinkedNodes += nNodes;
238+
239+ Aux_Send_Map[nLocalVertex] = new unsigned long [ nNodes ];
240+ nNodes = 0 ;
241+
242+ for (jEdge = 0 ; jEdge < nEdges; jEdge++){
243+ EdgeIndex = geom->nodes ->GetEdge (iPoint, jEdge);
244+
245+ if ( iPoint == geom->edges ->GetNode (EdgeIndex,0 ) )
246+ dPoint = geom->edges ->GetNode (EdgeIndex,1 );
247+ else
248+ dPoint = geom->edges ->GetNode (EdgeIndex,0 );
249+
250+ if ( geom->nodes ->GetVertex (dPoint, val_marker) != -1 ){
251+ Aux_Send_Map[nLocalVertex][nNodes] = geom->nodes ->GetGlobalIndex (dPoint);
252+ nNodes++;
240253 }
241254 }
255+ nLocalVertex++;
242256 }
243257 }
244258
245- // numbers of surface-neighbors of all domain vertices on the marker
246- unsigned long *Buffer_Send_nLinkedNodes = new unsigned long [ nLocalVertex ];
247- // cumsum of Buffer_Send_nLinkedNodes
248- unsigned long *Buffer_Send_StartLinkedNodes = new unsigned long [ nLocalVertex ];
259+ unsigned long *Buffer_Send_LinkedNodes = new unsigned long [ nLocalLinkedNodes ];
260+
249261 nLocalLinkedNodes = 0 ;
250- for (iVertex = 0 ; iVertex < nVertex; iVertex++) {
251- iPoint = geom->vertex [val_marker][iVertex]->GetNode ();
252- if (geom->nodes ->GetDomain (iPoint)) {
253- unsigned long iLocalVertex = iVertex_to_iLocalVertex[iVertex];
254- Buffer_Send_nLinkedNodes[iLocalVertex] = std::count_if (
255- std::begin (*neighbors[iPoint]), std::end (*neighbors[iPoint]),
256- [](unsigned long i){return true ;} );
257- Buffer_Send_StartLinkedNodes[iLocalVertex] = nLocalLinkedNodes;
258- nLocalLinkedNodes += Buffer_Send_nLinkedNodes[iLocalVertex];
259- }
260- }
261- // global point IDs of surface-neighbors of all domain vertices on the marker
262- unsigned long *Buffer_Send_LinkedNodes = new unsigned long [ nLocalLinkedNodes ];
263- unsigned long index = 0 ;
264- for (iVertex = 0 ; iVertex < nVertex; iVertex++) {
265- iPoint = geom->vertex [val_marker][iVertex]->GetNode ();
266- if (geom->nodes ->GetDomain (iPoint)) {
267- for (unsigned long jPoint_global : *(neighbors[iPoint])){
268- Buffer_Send_LinkedNodes[index] = jPoint_global;
269- index++;
270- }
271- delete neighbors[iPoint];
272- neighbors[iPoint]=nullptr ;
262+
263+ for (iVertex = 0 ; iVertex < nLocalVertex; iVertex++){
264+ for (jEdge = 0 ; jEdge < Buffer_Send_nLinkedNodes[iVertex]; jEdge++){
265+ Buffer_Send_LinkedNodes[nLocalLinkedNodes] = Aux_Send_Map[iVertex][jEdge];
266+ nLocalLinkedNodes++;
273267 }
274268 }
275269
276- delete[] iVertex_to_iLocalVertex;
277-
270+ for (iVertex = 0 ; iVertex < nVertex; iVertex++){
271+ if ( Aux_Send_Map[iVertex] != nullptr )
272+ delete [] Aux_Send_Map[iVertex];
273+ }
274+ delete [] Aux_Send_Map; Aux_Send_Map = nullptr ;
278275
279- /* --- Now these arrays of all processes must be joined to a single/global arrays. For this,
280- * the entries of StartLinkedNodes must be shifted.
281- * Furthermore, the global point IDs in LinkedNodes are replaced by global vertex IDs.
282- * For this, the master process collects the data from all processes, joins them and broadcasts them again. ---*/
276+ /* --- Reconstruct boundary by gathering data from all ranks ---*/
283277
284- /* --- Allocate global arrays. ---*/
285278 SU2_MPI::Allreduce ( &nLocalVertex, &nGlobalVertex, 1 , MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm ());
286279 SU2_MPI::Allreduce (&nLocalLinkedNodes, &nGlobalLinkedNodes, 1 , MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm ());
287280
@@ -293,13 +286,9 @@ void CInterpolator::ReconstructBoundary(unsigned long val_zone, int val_marker){
293286 Buffer_Receive_LinkedNodes = new unsigned long [ nGlobalLinkedNodes ];
294287 Buffer_Receive_StartLinkedNodes = new unsigned long [ nGlobalVertex ];
295288
296- /* --- Master process gathers data from all ranks ---*/
297289#ifdef HAVE_MPI
298- int nProcessor = size, iRank;
299- unsigned long received_nLocalLinkedNodes, received_nLocalVertex, received_nLocalLinkedNodes_sum;
300-
301290 if (rank == MASTER_NODE){
302- /* --- "Receive" from master process, i.e. copy. --- */
291+
303292 for (iVertex = 0 ; iVertex < nDim*nLocalVertex; iVertex++)
304293 Buffer_Receive_Coord[iVertex] = Buffer_Send_Coord[iVertex];
305294
@@ -313,29 +302,28 @@ void CInterpolator::ReconstructBoundary(unsigned long val_zone, int val_marker){
313302 for (iVertex = 0 ; iVertex < nLocalLinkedNodes; iVertex++)
314303 Buffer_Receive_LinkedNodes[iVertex] = Buffer_Send_LinkedNodes[iVertex];
315304
316- unsigned long received_nLocalVertex_sum = nLocalVertex;
317- unsigned long received_nLocalLinkedNodes_sum = nLocalLinkedNodes;
305+ tmp_index = nLocalVertex;
306+ tmp_index_2 = nLocalLinkedNodes;
318307
319- /* --- Receive from other processes to the appropriate position in the buffers and shift StartLinkedNodes indices. ---*/
320308 for (iRank = 1 ; iRank < nProcessor; iRank++){
321309
322- SU2_MPI::Recv (&received_nLocalLinkedNodes, 1 , MPI_UNSIGNED_LONG, iRank, 0 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
323- SU2_MPI::Recv (&Buffer_Receive_LinkedNodes[received_nLocalLinkedNodes_sum ], received_nLocalLinkedNodes , MPI_UNSIGNED_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
310+ SU2_MPI::Recv ( &iTmp2, 1 , MPI_UNSIGNED_LONG, iRank, 0 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
311+ SU2_MPI::Recv (&Buffer_Receive_LinkedNodes[tmp_index_2 ], iTmp2 , MPI_UNSIGNED_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
324312
325- SU2_MPI::Recv (&received_nLocalVertex, 1 , MPI_UNSIGNED_LONG, iRank, 0 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
326- SU2_MPI::Recv (&Buffer_Receive_Coord[received_nLocalVertex_sum *nDim], nDim*received_nLocalVertex , MPI_DOUBLE, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
313+ SU2_MPI::Recv ( &iTmp, 1 , MPI_UNSIGNED_LONG, iRank, 0 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
314+ SU2_MPI::Recv (&Buffer_Receive_Coord[tmp_index *nDim], nDim*iTmp , MPI_DOUBLE, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
327315
328- SU2_MPI::Recv ( &Buffer_Receive_GlobalPoint[received_nLocalVertex_sum ], received_nLocalVertex , MPI_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
329- SU2_MPI::Recv ( &Buffer_Receive_nLinkedNodes[received_nLocalVertex_sum ], received_nLocalVertex , MPI_UNSIGNED_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
330- SU2_MPI::Recv (&Buffer_Receive_StartLinkedNodes[received_nLocalVertex_sum ], received_nLocalVertex , MPI_UNSIGNED_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
316+ SU2_MPI::Recv ( &Buffer_Receive_GlobalPoint[tmp_index ], iTmp , MPI_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
317+ SU2_MPI::Recv ( &Buffer_Receive_nLinkedNodes[tmp_index ], iTmp , MPI_UNSIGNED_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
318+ SU2_MPI::Recv (&Buffer_Receive_StartLinkedNodes[tmp_index ], iTmp , MPI_UNSIGNED_LONG, iRank, 1 , SU2_MPI::GetComm (), MPI_STATUS_IGNORE);
331319
332- for (iVertex = 0 ; iVertex < received_nLocalVertex ; iVertex++){
333- Buffer_Receive_Proc[ received_nLocalVertex_sum + iVertex ] = iRank;
334- Buffer_Receive_StartLinkedNodes[ received_nLocalVertex_sum + iVertex ] += received_nLocalLinkedNodes_sum ;
320+ for (iVertex = 0 ; iVertex < iTmp ; iVertex++){
321+ Buffer_Receive_Proc[ tmp_index + iVertex ] = iRank;
322+ Buffer_Receive_StartLinkedNodes[ tmp_index + iVertex ] += tmp_index_2 ;
335323 }
336324
337- received_nLocalVertex_sum += received_nLocalVertex ;
338- received_nLocalLinkedNodes_sum += received_nLocalLinkedNodes ;
325+ tmp_index += iTmp ;
326+ tmp_index_2 += iTmp2 ;
339327 }
340328 }
341329 else {
@@ -345,7 +333,7 @@ void CInterpolator::ReconstructBoundary(unsigned long val_zone, int val_marker){
345333 SU2_MPI::Send ( &nLocalVertex, 1 , MPI_UNSIGNED_LONG, 0 , 0 , SU2_MPI::GetComm ());
346334 SU2_MPI::Send (Buffer_Send_Coord, nDim * nLocalVertex, MPI_DOUBLE, 0 , 1 , SU2_MPI::GetComm ());
347335
348- SU2_MPI::Send ( Buffer_Send_GlobalPoint, nLocalVertex, MPI_LONG , 0 , 1 , SU2_MPI::GetComm ());
336+ SU2_MPI::Send ( Buffer_Send_GlobalPoint, nLocalVertex, MPI_UNSIGNED_LONG , 0 , 1 , SU2_MPI::GetComm ());
349337 SU2_MPI::Send ( Buffer_Send_nLinkedNodes, nLocalVertex, MPI_UNSIGNED_LONG, 0 , 1 , SU2_MPI::GetComm ());
350338 SU2_MPI::Send (Buffer_Send_StartLinkedNodes, nLocalVertex, MPI_UNSIGNED_LONG, 0 , 1 , SU2_MPI::GetComm ());
351339 }
@@ -364,29 +352,27 @@ void CInterpolator::ReconstructBoundary(unsigned long val_zone, int val_marker){
364352 Buffer_Receive_LinkedNodes[iVertex] = Buffer_Send_LinkedNodes[iVertex];
365353#endif
366354
367- /* --- Master process replaced global point indices in Buffer_Receive_LinkedNodes by their indices in
368- * Buffer_Receive_GlobalPoint, Buffer_Receive_nLinkedNodes etc. ---*/
369355 if (rank == MASTER_NODE){
370356 for (iVertex = 0 ; iVertex < nGlobalVertex; iVertex++){
357+ count = 0 ;
371358 uptr = &Buffer_Receive_LinkedNodes[ Buffer_Receive_StartLinkedNodes[iVertex] ];
372359
373- for (unsigned long jLinkedNode = 0 ; jLinkedNode < Buffer_Receive_nLinkedNodes[iVertex]; jLinkedNode++){
374- unsigned long jPoint = uptr[ jLinkedNode ];
375- bool found = false ; // Global point index has been found
360+ for (jVertex = 0 ; jVertex < Buffer_Receive_nLinkedNodes[iVertex]; jVertex++){
361+ iTmp = uptr[ jVertex ];
376362 for (kVertex = 0 ; kVertex < nGlobalVertex; kVertex ++){
377- if ( Buffer_Receive_GlobalPoint[kVertex ] == long (jPoint ) ){
378- uptr[ jLinkedNode ] = kVertex ;
379- found = true ;
363+ if ( Buffer_Receive_GlobalPoint[kVertex ] == long (iTmp ) ){
364+ uptr[ jVertex ] = kVertex ;
365+ count++ ;
380366 break ;
381367 }
382368 }
383369
384- if ( !found ){ // remove from list
385- for (kVertex = jLinkedNode ; kVertex < Buffer_Receive_nLinkedNodes[iVertex]-1 ; kVertex ++){
370+ if ( count != (jVertex+ 1 ) ){
371+ for (kVertex = jVertex ; kVertex < Buffer_Receive_nLinkedNodes[iVertex]-1 ; kVertex ++){
386372 uptr[ kVertex ] = uptr[ kVertex + 1 ];
387373 }
388374 Buffer_Receive_nLinkedNodes[iVertex]--;
389- jLinkedNode --;
375+ jVertex --;
390376 }
391377 }
392378 }
0 commit comments