Nektar++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
InterfaceMapDG.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File InterfaceMapDG.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: MPI communication for interfaces
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include "InterfaceMapDG.h"
36 
37 namespace Nektar
38 {
39 namespace MultiRegions
40 {
41 
43  const ExpListSharedPtr &trace,
44  const SpatialDomains::InterfaceShPtr &interfaceShPtr)
45  : m_trace(trace), m_interface(interfaceShPtr)
46 {
47 }
48 
49 // Creates the objects that communicates trace values across the interface in
50 // serial and parallel. Does this by checking all interfaces to see if they
51 // are contained locally (on the current rank), and checks all other ranks for
52 // the same interface ID and if contains the opposite interface side i.e.
53 // 'left' or 'right'
55  const SpatialDomains::MeshGraphSharedPtr &meshGraph,
56  const ExpListSharedPtr &trace)
57  : m_graph(meshGraph), m_movement(meshGraph->GetMovement()), m_trace(trace)
58 {
59  auto comm = m_trace->GetComm();
60  auto interfaceCollection = m_movement->GetInterfaces();
61 
62  // myIndxLR contains the info about what interface edges are present on
63  // current rank with each interface no, i, consisting of:
64  // [i] = indx
65  // [i + 1] = 0 (non), = 1 (left only), = 2 (right only), = 3 (both)
66  std::map<int, int> myIndxLRMap;
67 
68  // localInterfaces contains a map of interface ID to a pair of interface
69  // traces, this pair is 'left' and 'right' interface and is used to
70  // construct and store the traces for interfaces present on the current rank
71  std::map<int, std::pair<InterfaceTraceSharedPtr, InterfaceTraceSharedPtr>>
72  localInterfaces;
73 
74  // Map of m_localInterfaces vector to interface ID
75  Array<OneD, int> indxToInterfaceID(interfaceCollection.size());
76 
77  // Loops over all interfaces and check if either side, 'left' or 'right'
78  // are empty on the current rank, if not empty then populate the local
79  // interface data structures and keep track using myIndxLRMap
80  size_t cnt = 0;
81  for (const auto &interface : interfaceCollection)
82  {
83  indxToInterfaceID[cnt] = interface.first.first;
84  myIndxLRMap[interface.first.first] = 0;
85 
86  if (!interface.second->GetLeftInterface()->IsEmpty())
87  {
88  myIndxLRMap[interface.first.first] += 1;
89 
90  localInterfaces[interface.first.first].first =
92  trace, interface.second->GetLeftInterface());
93  m_localInterfaces.emplace_back(
94  localInterfaces[interface.first.first].first);
95  }
96 
97  if (!interface.second->GetRightInterface()->IsEmpty())
98  {
99  myIndxLRMap[interface.first.first] += 2;
100 
101  localInterfaces[interface.first.first].second =
103  trace, interface.second->GetRightInterface());
104  m_localInterfaces.emplace_back(
105  localInterfaces[interface.first.first].second);
106  }
107 
108  cnt++;
109  }
110 
111  // Send num of interfaces size so all partitions can prepare buffers
112  int nRanks = comm->GetSize();
113 
114  // Send all interface edges present to all partitions
115  Array<OneD, int> interfaceEdges(myIndxLRMap.size());
116  cnt = 0;
117  for (auto pres : myIndxLRMap)
118  {
119  interfaceEdges[cnt++] = pres.second;
120  }
121  Array<OneD, int> rankLocalInterfaceIds(myIndxLRMap.size() * nRanks, 0);
122  comm->AllGather(interfaceEdges, rankLocalInterfaceIds);
123 
124  // Map of rank to vector of interface traces
125  std::map<int, std::vector<InterfaceTraceSharedPtr>> oppRankSharedInterface;
126 
127  // Find what interface Ids match with other ranks, then check if opposite
128  // edge
129  size_t myRank = comm->GetRank();
130  size_t numInterfaces = interfaceCollection.size();
131  for (int i = 0; i < nRanks; ++i)
132  {
133  for (size_t j = 0; j < numInterfaces; ++j)
134  {
135  int otherId = indxToInterfaceID[j];
136 
137  // otherCode represents for a specific interface ID what sides are
138  // present on rank i, 0=non, 1=left, 2=right, 3=both
139  int otherCode = rankLocalInterfaceIds[i * numInterfaces + j];
140 
141  // myCode represents for a specific interface ID what sides are
142  // present on this rank/process 0=non, 1=left, 2=right, 3=both
143  int myCode = myIndxLRMap[otherId];
144 
145  // Special case if checking current rank (this process)
146  if (i == myRank)
147  {
148  // If contains both edges locally then set check local to true
149  if (myCode == 3)
150  {
151  localInterfaces[otherId].first->SetCheckLocal(true);
152  localInterfaces[otherId].second->SetCheckLocal(true);
153  }
154 
155  continue;
156  }
157 
158  // Checks if this ranks 'left' matches any 'right' on other rank
159  if ((myCode == 1 && otherCode == 2) ||
160  (myCode == 1 && otherCode == 3) ||
161  (myCode == 3 && otherCode == 2))
162  {
163  oppRankSharedInterface[i].emplace_back(
164  localInterfaces[otherId].first);
165  }
166  // Checks if this ranks 'right' matches any 'left' on other rank
167  else if ((myCode == 2 && otherCode == 1) ||
168  (myCode == 2 && otherCode == 3) ||
169  (myCode == 3 && otherCode == 1))
170  {
171  oppRankSharedInterface[i].emplace_back(
172  localInterfaces[otherId].second);
173  }
174  // Checks if this ranks 'both' matches any 'both' on other rank
175  else if (myCode == 3 && otherCode == 3)
176  {
177  oppRankSharedInterface[i].emplace_back(
178  localInterfaces[otherId].first);
179  oppRankSharedInterface[i].emplace_back(
180  localInterfaces[otherId].second);
181  }
182  }
183  }
184 
185  // Create individual interface exchange objects (each object is rank ->
186  // rank) and contains a vector of interfaceTrace objects
187  for (auto &rank : oppRankSharedInterface)
188  {
189  m_exchange.emplace_back(
191  m_movement, m_trace, comm, rank));
192  }
193 
194  // Find missing coordinates on interface from other side
195  ExchangeCoords();
196 }
197 
199 {
200  auto comm = m_trace->GetComm();
201  auto zones = m_movement->GetZones();
202 
203  for (auto &interfaceTrace : m_localInterfaces)
204  {
205  interfaceTrace->CalcLocalMissing();
206  }
207 
208  // If parallel communication is needed
209  if (!m_exchange.empty())
210  {
211  auto requestSend = comm->CreateRequest(m_exchange.size());
212  auto requestRecv = comm->CreateRequest(m_exchange.size());
213 
214  for (int i = 0; i < m_exchange.size(); ++i)
215  {
216  m_exchange[i]->RankFillSizes(requestSend, requestRecv, i);
217  }
218  comm->WaitAll(requestSend);
219  comm->WaitAll(requestRecv);
220 
221  for (int i = 0; i < m_exchange.size(); ++i)
222  {
223  m_exchange[i]->SendMissing(requestSend, requestRecv, i);
224  }
225  comm->WaitAll(requestSend);
226  comm->WaitAll(requestRecv);
227 
228  for (auto &i : m_exchange)
229  {
230  i->CalcRankDistances();
231  }
232  }
233 }
234 
235 /**
236  * Calculates what coordinates on the interface are missing; i.e. aren't located
237  * in an edge from the other side of the interface on this partition. These are
238  * stored in the vector #m_missingCoords, and another vector of the same index
239  * layout contains the location of that coordinate in the trace i.e. the
240  * 'offset + i' value. It checks first if the interface is flagged local, which
241  * denotes whether the opposite side is also present on this rank, if not then
242  * all coordinates are missing. If local then the same structure as
243  * CalcRankDistances is used to minimise computational cost.
244  */
246 {
247  auto childEdge = m_interface->GetEdge();
248  // If not flagged 'check local' then all points are missing
249  if (!m_checkLocal)
250  {
251  int cnt = 0;
252  for (auto &childId : childEdge)
253  {
254  auto childElmt = m_trace->GetExpFromGeomId(childId.first);
255  size_t nq = childElmt->GetTotPoints();
256  Array<OneD, NekDouble> xc(nq, 0.0), yc(nq, 0.0), zc(nq, 0.0);
257  childElmt->GetCoords(xc, yc, zc);
258  int offset =
259  m_trace->GetPhys_Offset(m_trace->GetElmtToExpId(childId.first));
260 
261  for (int i = 0; i < nq; ++i, ++cnt)
262  {
264  xs[0] = xc[i];
265  xs[1] = yc[i];
266  xs[2] = zc[i];
267 
268  m_missingCoords.emplace_back(xs);
269  m_mapMissingCoordToTrace.emplace_back(offset + i);
270  }
271  }
272  }
273  // Otherwise we need to check to see what points the other side of the
274  // interface on this rank contains. This is done by looping over each
275  // quadrature point in all the edges on this side of the interface, then
276  // check if this quadrature point is also in any edges on the other side
277  // of the interface. First use MinMaxCheck as a cheap method to eliminate
278  // far away edges. If it passes MinMaxCheck perform the FindDistance search
279  // which numerically searches for the closest local coordinate on the other
280  // interface side edge and returns the cartesian distance from the search
281  // coordinate to the found local coordinate. If determined to be close
282  // enough then add to found local coordinates.
283  else
284  {
285  for (auto &childId : childEdge)
286  {
287  auto childElmt = m_trace->GetExpFromGeomId(childId.first);
288  size_t nq = childElmt->GetTotPoints();
289  Array<OneD, NekDouble> xc(nq, 0.0), yc(nq, 0.0), zc(nq, 0.0);
290  childElmt->GetCoords(xc, yc, zc);
291  int offset =
292  m_trace->GetPhys_Offset(m_trace->GetElmtToExpId(childId.first));
293 
294  for (int i = 0; i < nq; ++i)
295  {
296  bool found = false;
297  Array<OneD, NekDouble> foundLocCoord;
299  xs[0] = xc[i];
300  xs[1] = yc[i];
301  xs[2] = zc[i];
302 
303  auto parentEdge = m_interface->GetOppInterface()->GetEdge();
304  for (auto &edge : parentEdge)
305  {
306  // First check if inside the edge bounding box
307  if (!edge.second->MinMaxCheck(xs))
308  {
309  continue;
310  }
311 
312  NekDouble dist =
313  edge.second->FindDistance(xs, foundLocCoord);
315  {
316  found = true;
317  m_foundLocalCoords[offset + i] = std::make_pair(
318  edge.second->GetGlobalID(), foundLocCoord);
319  break;
320  }
321  }
322 
323  if (!found)
324  {
325  m_missingCoords.emplace_back(xs);
326  m_mapMissingCoordToTrace.emplace_back(offset + i);
327  }
328  }
329  }
330  }
331 
332  // If running in serial there shouldn't be any missing coordinates.
333  if (m_trace->GetComm()->IsSerial())
334  {
335  ASSERTL0(m_missingCoords.empty(),
336  "Missing " + std::to_string(m_missingCoords.size()) +
337  " coordinates on interface ID " +
338  std::to_string(m_interface->GetId()) +
339  " linked to interface ID " +
340  std::to_string(m_interface->GetOppInterface()->GetId()) +
341  ". Check both sides of the interface line up.");
342  }
343 }
344 
345 // This fills m_sendSize and m_recvSize with the correct sizes for the
346 // communication lengths for each rank when communicating the traces. I.e.
347 // however many quadrature points on the opposite side of the interface to
348 // send, and however many on this side to receive.
351  LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum)
352 {
353 
354  // Recalc size is the number of interfaces missing points that need to be
355  // communicated.
356  int recalcSize = 0;
357  for (auto &localInterface : m_interfaceTraces)
358  {
359  recalcSize +=
360  m_zones[localInterface->GetInterface()->GetId()]->GetMoved();
361  }
362 
363  m_sendSize[m_rank] = Array<OneD, int>(recalcSize);
364  m_recvSize[m_rank] = Array<OneD, int>(recalcSize);
365 
366  int cnt = 0;
367  for (auto &interface : m_interfaceTraces)
368  {
369  if (m_zones[interface->GetInterface()->GetId()]->GetMoved())
370  {
371  // Calculates the number of missing coordinates to be communicated
372  // This size is 3 times the number of missing coordinates to allow
373  // for 3D points
374  m_sendSize[m_rank][cnt++] =
375  interface->GetMissingCoords().size() * 3;
376  }
377  }
378 
379  // Uses non-blocking send/recvs to send communication sizes to other ranks
381  requestSend, requestNum);
383  requestRecv, requestNum);
384 }
385 
386 // Uses the calculated send/recv sizes to send all missing coordinates to
387 // other ranks.
390  LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum)
391 {
392  m_totSendSize[m_rank] = std::accumulate(m_sendSize[m_rank].begin(),
393  m_sendSize[m_rank].end(), 0);
394  m_totRecvSize[m_rank] = std::accumulate(m_recvSize[m_rank].begin(),
395  m_recvSize[m_rank].end(), 0);
396 
399 
400  int cnt = 0;
401  for (auto &interface : m_interfaceTraces)
402  {
403  if (m_zones[interface->GetInterface()->GetId()]->GetMoved())
404  {
405  auto missing = interface->GetMissingCoords();
406  for (auto coord : missing)
407  {
408  // Points are organised in blocks of three
409  // x coord, then y coord, then z coord.
410  for (int k = 0; k < 3; ++k, ++cnt)
411  {
412  m_send[cnt] = coord[k];
413  }
414  }
415  }
416  }
417 
418  // Uses non-blocking send/recvs to send missing points to other ranks
419  m_comm->Isend(m_rank, m_send, m_totSendSize[m_rank], requestSend,
420  requestNum);
421  m_comm->Irecv(m_rank, m_recv, m_totRecvSize[m_rank], requestRecv,
422  requestNum);
423 }
424 
425 /**
426  * Performs the trace exchange across interfaces
427  * 1) Calculate and send the Fwd trace to other ranks with pairwise comms
428  * 2) While waiting for the send/recv to complete we fill the local interfaces
429  * Bwd trace
430  * 3) Fill the remaining Bwd trace with the received trace data from other ranks
431  */
434 {
435  auto comm = m_trace->GetComm();
436 
437  // If no parallel exchange needed we only fill the local traces
438  if (m_exchange.empty())
439  {
440  // Fill local interface traces
441  for (auto &m_localInterface : m_localInterfaces)
442  {
443  m_localInterface->FillLocalBwdTrace(Fwd, Bwd);
444  }
445  }
446  else
447  {
448  auto requestSend = comm->CreateRequest(m_exchange.size());
449  auto requestRecv = comm->CreateRequest(m_exchange.size());
450  for (int i = 0; i < m_exchange.size(); ++i)
451  {
452  m_exchange[i]->SendFwdTrace(requestSend, requestRecv, i, Fwd);
453  }
454 
455  // Fill local interface traces
456  for (auto &m_localInterface : m_localInterfaces)
457  {
458  m_localInterface->FillLocalBwdTrace(Fwd, Bwd);
459  }
460 
461  comm->WaitAll(requestSend);
462  comm->WaitAll(requestRecv);
463 
464  // Fill communicated interface traces
465  for (auto &i : m_exchange)
466  {
467  i->FillRankBwdTraceExchange(Bwd);
468  }
469  }
470 }
471 
474 {
475  // If flagged then fill trace from local coords
476  if (m_checkLocal)
477  {
478  for (auto &foundLocCoord : m_foundLocalCoords)
479  {
480  int traceId = m_trace->GetElmtToExpId(foundLocCoord.second.first);
481  Array<OneD, NekDouble> locCoord = foundLocCoord.second.second;
482 
483  Array<OneD, NekDouble> edgePhys =
484  Fwd + m_trace->GetPhys_Offset(traceId);
485 
486  Bwd[foundLocCoord.first] =
487  m_trace->GetExp(traceId)->StdPhysEvaluate(locCoord, edgePhys);
488  }
489  }
490 }
491 
493 {
494  int cnt = 0;
495  for (int i = 0; i < m_interfaceTraces.size(); ++i)
496  {
497  Array<OneD, NekDouble> traceTmp(m_sendSize[m_rank][i] / 3, 0.0);
498  for (int j = 0; j < m_sendSize[m_rank][i] / 3; ++j, ++cnt)
499  {
500  traceTmp[j] = m_recvTrace[cnt];
501  }
502 
503  m_interfaceTraces[i]->FillRankBwdTrace(traceTmp, Bwd);
504  }
505 }
506 
509 {
510  for (int i = 0; i < m_mapMissingCoordToTrace.size(); ++i)
511  {
512  if (!std::isnan(trace[i]))
513  {
514  Bwd[m_mapMissingCoordToTrace[i]] = trace[i];
515  }
516  }
517 }
518 
521  LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum,
523 {
524  m_recvTrace =
525  Array<OneD, NekDouble>(m_totSendSize[m_rank] / 3, std::nan(""));
526  m_sendTrace =
527  Array<OneD, NekDouble>(m_totRecvSize[m_rank] / 3, std::nan(""));
528 
529  for (auto &i : m_foundRankCoords[m_rank])
530  {
531  int traceId = m_trace->GetElmtToExpId(i.second.first);
532  Array<OneD, NekDouble> locCoord = i.second.second;
533 
534  Array<OneD, NekDouble> edgePhys =
535  Fwd + m_trace->GetPhys_Offset(traceId);
536 
537  m_sendTrace[i.first] =
538  m_trace->GetExp(traceId)->StdPhysEvaluate(locCoord, edgePhys);
539  }
540 
541  m_comm->Isend(m_rank, m_sendTrace, m_sendTrace.size(), requestSend,
542  requestNum);
543  m_comm->Irecv(m_rank, m_recvTrace, m_recvTrace.size(), requestRecv,
544  requestNum);
545 }
546 
547 /**
548  * Check coords in m_recv from other rank to see if present on this rank, and
549  * then populates m_foundRankCoords if found.
550  * - Loops over all interface traces present in the exchange, i.e. every
551  * interface needed on this rank-to-rank communication object
552  * - Then loops over all the quadrature points missing from the other side in
553  * that interface using global coordinates
554  * - Loop over each local edge and use MinMaxCheck on the point as a fast
555  * comparison on whether the point lies on the edge
556  * - If true then use the more expensive FindDistance function to find the
557  * closest local coordinate of the global 'missing' point on the local edge
558  * and the distance from the edge that corresponds to
559  * - If distance is less than 5e-5 save found coordinate in m_foundRankCoords
560  */
561 
563 {
564  Array<OneD, int> disp(m_recvSize[m_rank].size() + 1, 0.0);
565  std::partial_sum(m_recvSize[m_rank].begin(), m_recvSize[m_rank].end(),
566  &disp[1]);
567 
568  for (int i = 0; i < m_interfaceTraces.size(); ++i)
569  {
570  auto localEdge = m_interfaceTraces[i]->GetInterface()->GetEdge();
571 
572  for (int j = disp[i]; j < disp[i + 1]; j += 3)
573  {
574  Array<OneD, NekDouble> foundLocCoord;
576  xs[0] = m_recv[j];
577  xs[1] = m_recv[j + 1];
578  xs[2] = m_recv[j + 2];
579 
580  for (auto &edge : localEdge)
581  {
582  // First check if inside the edge bounding box
583  if (!edge.second->MinMaxCheck(xs))
584  {
585  continue;
586  }
587 
588  NekDouble dist = edge.second->FindDistance(xs, foundLocCoord);
589 
591  {
592  m_foundRankCoords[m_rank][j / 3] = std::make_pair(
593  edge.second->GetGlobalID(), foundLocCoord);
594  break;
595  }
596  }
597  }
598  }
599 }
600 
601 } // namespace MultiRegions
602 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::map< int, Array< OneD, int > > m_sendSize
Map of rank to array of size of send buffer for each interface.
void RankFillSizes(LibUtilities::CommRequestSharedPtr &requestSend, LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum)
std::map< int, SpatialDomains::ZoneBaseShPtr > m_zones
Map of zone IDs to zone bases.
const ExpListSharedPtr m_trace
Trace expansion list.
void FillRankBwdTraceExchange(Array< OneD, NekDouble > &Bwd)
const std::vector< InterfaceTraceSharedPtr > m_interfaceTraces
Vector of interface traces i.e. every interface side present on m_rank.
const LibUtilities::CommSharedPtr m_comm
Communicator.
void SendFwdTrace(LibUtilities::CommRequestSharedPtr &requestSend, LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum, Array< OneD, NekDouble > &Fwd)
Array< OneD, NekDouble > m_send
Send buffer for coord exchange.
std::map< int, std::map< int, std::pair< int, Array< OneD, NekDouble > > > > m_foundRankCoords
std::map< int, int > m_totSendSize
Map of rank to total size of send buffer for all interfaces.
void CalcRankDistances()
Populates m_foundRankCoords using the FindDistance function.
std::map< int, int > m_totRecvSize
Map of rank to total size of receive buffer for all interfaces.
std::map< int, Array< OneD, int > > m_recvSize
Map of rank to array of size of receive buffer for each interface.
Array< OneD, NekDouble > m_recv
Receive buffer for coord exchange.
void SendMissing(LibUtilities::CommRequestSharedPtr &requestSend, LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum)
Array< OneD, NekDouble > m_recvTrace
Receive buffer for trace exchange.
Array< OneD, NekDouble > m_sendTrace
Send buffer for trace exchange.
const ExpListSharedPtr m_trace
Trace expansion list.
void ExchangeTrace(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
Perform the trace exchange between processors, given the forwards and backwards spaces.
std::vector< InterfaceExchangeSharedPtr > m_exchange
Vector of interface exchanges, i.e. every rank-to-rank comm needed.
void ExchangeCoords()
Perform the coordinate exchange between processors. This is where the missing coordinates on the inte...
SpatialDomains::MovementSharedPtr m_movement
Movement object associated with the non-conformal interfaces.
InterfaceMapDG(const SpatialDomains::MeshGraphSharedPtr &graph, const ExpListSharedPtr &trace)
std::vector< InterfaceTraceSharedPtr > m_localInterfaces
Interface sides present on current process.
ExpListSharedPtr m_trace
Trace expansion list.
std::map< int, std::pair< int, Array< OneD, NekDouble > > > m_foundLocalCoords
Map of found coordinates present locally.
std::vector< int > m_mapMissingCoordToTrace
Vector of indices corresponding to m_missingCoord locations in trace.
SpatialDomains::InterfaceShPtr m_interface
Local interface object.
std::vector< Array< OneD, NekDouble > > m_missingCoords
Vector of coordinates on interface missing from the other side locally.
InterfaceTrace(const ExpListSharedPtr &trace, const SpatialDomains::InterfaceShPtr &interfaceShPtr)
Constructor.
void FillRankBwdTrace(Array< OneD, NekDouble > &trace, Array< OneD, NekDouble > &Bwd)
Fills the Bwd trace from partitioned trace.
void CalcLocalMissing()
Calculates what coordinates on the interface are missing locally.
void FillLocalBwdTrace(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
Fills the Bwd trace by interpolating from the Fwd for local interfaces.
bool m_checkLocal
Flag whether the opposite side of the interface is present locally.
std::shared_ptr< CommRequest > CommRequestSharedPtr
Definition: Comm.h:86
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
static const NekDouble kFindDistanceMin
std::shared_ptr< Interface > InterfaceShPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:172
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble