Nektar++
AssemblyMapDG.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File AssemblyMapDG.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: Local to Global Base Class mapping routines
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
38 #include <MultiRegions/ExpList.h>
39 #include <LocalRegions/SegExp.h>
40 #include <LocalRegions/PointExp.h>
43 
44 #include <boost/core/ignore_unused.hpp>
45 #include <boost/config.hpp>
46 #include <boost/graph/adjacency_list.hpp>
47 
48 using namespace std;
49 
50 namespace Nektar
51 {
52  namespace MultiRegions
53  {
54  AssemblyMapDG::AssemblyMapDG():
55  m_numDirichletBndPhys(0)
56  {
57  }
58 
60  {
61  }
62 
66  const ExpListSharedPtr &trace,
67  const ExpList &locExp,
70  const PeriodicMap &periodicTrace,
71  const std::string variable):
72  AssemblyMap(pSession,variable)
73  {
74  boost::ignore_unused(graph);
75 
76  int i, j, k, cnt, id, id1, gid;
77  int order_e = 0;
78  int nTraceExp = trace->GetExpSize();
79  int nbnd = bndCondExp.size();
80 
84 
85  const LocalRegions::ExpansionVector expList = *(locExp.GetExp());
86  int nel = expList.size();
87 
88  map<int, int> meshTraceId;
89 
90  m_signChange = true;
91 
92  // determine mapping from geometry edges to trace
93  for(i = 0; i < nTraceExp; ++i)
94  {
95  meshTraceId[trace->GetExp(i)->GetGeom()->GetGlobalID()] = i;
96  }
97 
98  // Count total number of trace elements
99  cnt = 0;
100  for(i = 0; i < nel; ++i)
101  {
102  cnt += expList[i]->GetNtraces();
103  }
104 
108 
109  // set up trace expansions links;
110  for(cnt = i = 0; i < nel; ++i)
111  {
112  m_elmtToTrace[i] = tracemap + cnt;
113  exp = expList[i];
114 
115  for(j = 0; j < exp->GetNtraces(); ++j)
116  {
117  id = exp->GetGeom()->GetTid(j);
118 
119  if(meshTraceId.count(id) > 0)
120  {
121  m_elmtToTrace[i][j] =
122  trace->GetExp(meshTraceId.find(id)->second);
123  }
124  else
125  {
126  ASSERTL0(false, "Failed to find trace map");
127  }
128  }
129 
130  cnt += exp->GetNtraces();
131  }
132 
133  // Set up boundary mapping
134  cnt = 0;
135  for(i = 0; i < nbnd; ++i)
136  {
137  if (bndCond[i]->GetBoundaryConditionType() ==
139  {
140  continue;
141  }
142  cnt += bndCondExp[i]->GetExpSize();
143  }
144 
145  set<int> dirTrace;
146 
149 
150  for(i = 0; i < bndCondExp.size(); ++i)
151  {
152  for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
153  {
154  bndExp = bndCondExp[i]->GetExp(j);
155  traceGeom = bndExp->GetGeom();
156  id = traceGeom->GetGlobalID();
157 
158  if(bndCond[i]->GetBoundaryConditionType() ==
160  {
161  m_numLocalDirBndCoeffs += bndExp->GetNcoeffs();
162  m_numDirichletBndPhys += bndExp->GetTotPoints();
163  dirTrace.insert(id);
164  }
165  }
166  }
167 
168  // Set up integer mapping array and sign change for each degree of
169  // freedom + initialise some more data members.
170  m_staticCondLevel = 0;
172  m_numPatches = nel;
175 
176  int nbndry = 0;
177  for(i = 0; i < nel; ++i) // count number of elements in array
178  {
179  int BndCoeffs = expList[i]->NumDGBndryCoeffs();
180  nbndry += BndCoeffs;
182  m_numLocalBndCoeffsPerPatch[i] = (unsigned int) BndCoeffs;
183  }
184 
186  m_numLocalBndCoeffs = nbndry;
187  m_numLocalCoeffs = nbndry;
190 
191  // Set up array for potential mesh optimsation
192  Array<OneD,int> traceElmtGid(nTraceExp, -1);
193  int nDir = 0;
194  cnt = 0;
195 
196  // We are now going to construct a graph of the mesh which can be
197  // reordered depending on the type of solver we would like to use.
198  typedef boost::adjacency_list<
199  boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
200 
201  BoostGraph boostGraphObj;
202  int trace_id, trace_id1;
203  int dirOffset = 0;
204 
205  // make trace renumbering map where first solved trace starts
206  // at 0 so we can set up graph.
207  for(i = 0; i < nTraceExp; ++i)
208  {
209  id = trace->GetExp(i)->GetGeom()->GetGlobalID();
210 
211  if (dirTrace.count(id) == 0)
212  {
213  // Initial put in element ordering (starting from zero) into
214  // traceElmtGid
215  boost::add_vertex(boostGraphObj);
216  traceElmtGid[i] = cnt++;
217  }
218  else
219  {
220  // Use existing offset for Dirichlet edges
221  traceElmtGid[i] = dirOffset;
222  dirOffset += trace->GetExp(i)->GetNcoeffs();
223  nDir++;
224  }
225  }
226 
227  // Set up boost Graph
228  for(i = 0; i < nel; ++i)
229  {
230  exp = expList[i];
231 
232  for(j = 0; j < exp->GetNtraces(); ++j)
233  {
234  // Add trace to boost graph for non-Dirichlet Boundary
235  traceGeom = m_elmtToTrace[i][j]->GetGeom();
236  id = traceGeom->GetGlobalID();
237  trace_id = meshTraceId.find(id)->second;
238 
239  if(dirTrace.count(id) == 0)
240  {
241  for(k = j+1; k < exp->GetNtraces(); ++k)
242  {
243  traceGeom = m_elmtToTrace[i][k]->GetGeom();
244  id1 = traceGeom->GetGlobalID();
245  trace_id1 = meshTraceId.find(id1)->second;
246 
247  if(dirTrace.count(id1) == 0)
248  {
249  boost::add_edge((size_t)traceElmtGid[trace_id],
250  (size_t)traceElmtGid[trace_id1],
251  boostGraphObj);
252  }
253  }
254  }
255  }
256  }
257 
258  int nGraphVerts = nTraceExp - nDir;
259  Array<OneD, int> perm (nGraphVerts);
260  Array<OneD, int> iperm(nGraphVerts);
261  Array<OneD, int> vwgts(nGraphVerts);
263 
264  for(i = 0; i < nGraphVerts; ++i)
265  {
266  vwgts[i] = trace->GetExp(i+nDir)->GetNcoeffs();
267  }
268 
269  if(nGraphVerts)
270  {
271  switch(m_solnType)
272  {
273  case eDirectFullMatrix:
274  case eIterativeFull:
276  case eXxtFullMatrix:
277  case eXxtStaticCond:
278  case ePETScFullMatrix:
279  case ePETScStaticCond:
280  {
281  NoReordering(boostGraphObj,perm,iperm);
282  break;
283  }
284  case eDirectStaticCond:
285  {
286  CuthillMckeeReordering(boostGraphObj,perm,iperm);
287  break;
288  }
293  {
294  MultiLevelBisectionReordering(boostGraphObj,perm,iperm,
295  bottomUpGraph);
296  break;
297  }
298  default:
299  {
300  ASSERTL0(false,"Unrecognised solution type");
301  }
302  }
303  }
304 
305  // Recast the permutation so that it can be used as a map from old
306  // trace ID to new trace ID
308  for(i = 0; i < nTraceExp - nDir; ++i)
309  {
310  traceElmtGid[perm[i]+nDir] = cnt;
311  cnt += trace->GetExp(perm[i]+nDir)->GetNcoeffs();
312  }
313 
314  // Now have trace edges Gid position
315  cnt = 0;
316  for(i = 0; i < nel; ++i)
317  {
318  exp = expList[i];
319 
320  for(j = 0; j < exp->GetNtraces(); ++j)
321  {
322  traceGeom = m_elmtToTrace[i][j]->GetGeom();
323  id = traceGeom->GetGlobalID();
324  gid = traceElmtGid[meshTraceId.find(id)->second];
325 
326  const int nDim = exp->GetNumBases();
327 
328  if (nDim == 1)
329  {
330  order_e = 1;
331  m_localToGlobalBndMap[cnt] = gid;
332  }
333  else if (nDim == 2)
334  {
335  order_e = exp->GetTraceNcoeffs(j);
336 
337  if(exp->GetTraceOrient(j) == StdRegions::eForwards)
338  {
339  for(k = 0; k < order_e; ++k)
340  {
341  m_localToGlobalBndMap[k+cnt] = gid + k;
342  }
343  }
344  else
345  {
346  switch(m_elmtToTrace[i][j]->GetBasisType(0))
347  {
349  {
350  // reverse vertex order
351  m_localToGlobalBndMap[cnt] = gid + 1;
352  m_localToGlobalBndMap[cnt+1] = gid;
353  for (k = 2; k < order_e; ++k)
354  {
355  m_localToGlobalBndMap[k+cnt] = gid + k;
356  }
357 
358  // negate odd modes
359  for(k = 3; k < order_e; k+=2)
360  {
361  m_localToGlobalBndSign[cnt+k] = -1.0;
362  }
363  break;
364  }
366  {
367  // reverse order
368  for(k = 0; k < order_e; ++k)
369  {
370  m_localToGlobalBndMap[cnt+order_e-k-1] = gid + k;
371  }
372  break;
373  }
375  {
376  // reverse order
377  for(k = 0; k < order_e; ++k)
378  {
379  m_localToGlobalBndMap[cnt+order_e-k-1] = gid + k;
380  }
381  break;
382  }
383  default:
384  {
385  ASSERTL0(false,"Boundary type not permitted");
386  }
387  }
388  }
389  }
390  else if (nDim == 3)
391  {
392  order_e = exp->GetTraceNcoeffs(j);
393 
394  std::map<int, int> orientMap;
395 
396  Array<OneD, unsigned int> elmMap1 (order_e);
397  Array<OneD, int> elmSign1(order_e);
398  Array<OneD, unsigned int> elmMap2 (order_e);
399  Array<OneD, int> elmSign2(order_e);
400 
401  StdRegions::Orientation fo = exp->GetTraceOrient(j);
402 
403  // Construct mapping which will permute global IDs
404  // according to face orientations.
405  exp->GetTraceToElementMap(j,elmMap1,elmSign1,fo);
406  exp->GetTraceToElementMap(j,elmMap2,elmSign2,
408 
409  for (k = 0; k < elmMap1.size(); ++k)
410  {
411  // Find the elemental co-efficient in the original
412  // mapping.
413  int idx = -1;
414  for (int l = 0; l < elmMap2.size(); ++l)
415  {
416  if (elmMap1[k] == elmMap2[l])
417  {
418  idx = l;
419  break;
420  }
421  }
422 
423  ASSERTL2(idx != -1, "Problem with face to element map!");
424  orientMap[k] = idx;
425  }
426 
427  for(k = 0; k < order_e; ++k)
428  {
429  m_localToGlobalBndMap [k+cnt] = gid + orientMap[k];
430  m_localToGlobalBndSign[k+cnt] = elmSign2[orientMap[k]];
431  }
432  }
433 
434  cnt += order_e;
435  }
436  }
437 
438  // set up identify map for lcoal to lcoal
440 
441  //local to bnd map is just a copy
442  for(i = 0; i < m_numLocalBndCoeffs; ++i)
443  {
444  m_localToLocalBndMap[i] = i;
445  }
446 
447 
448  m_numGlobalBndCoeffs = trace->GetNcoeffs();
450 
452 
453  // set up m_bndCondCoeffsToLocalTraceMap
454  // Number of boundary expansions
455  int nbndexp = 0;
456  int bndTotal = 0;
457  int bndOffset;
458  int traceOffset;
459 
460  cnt = 0;
461  for(i = 0; i < nbnd; ++i)
462  {
463  if (bndCond[i]->GetBoundaryConditionType() ==
465  {
466  continue;
467  }
468  cnt += bndCondExp[i]->GetNcoeffs();
469  nbndexp += bndCondExp[i]->GetExpSize();
470  }
471 
474 
475  cnt = 0;
476  for(i = 0; i < bndCondExp.size(); ++i)
477  {
478  if (bndCond[i]->GetBoundaryConditionType() ==
480  {
481  continue;
482  }
483 
484  for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
485  {
486  bndExp = bndCondExp[i]->GetExp(j);
487  id = bndExp->GetGeom()->GetGlobalID();
488 
489  int meshId = meshTraceId.find(id)->second;
490  m_bndCondIDToGlobalTraceID[cnt++] = meshId;
491 
492  // initialy set up map with global bnd location
493  // and then use the localToGlobalBndMap to invert
494  // since this is a one to one mapping on boundaries
495  traceOffset = traceElmtGid[meshId];
496  bndOffset = bndCondExp[i]->GetCoeff_Offset(j) + bndTotal;
497 
498 
499  for(k = 0; k < bndExp->GetNcoeffs(); ++k)
500  {
501  m_bndCondCoeffsToLocalTraceMap[bndOffset+k] =
502  traceOffset + k;
503  }
504  }
505  bndTotal += bndCondExp[i]->GetNcoeffs();
506  }
507 
508  // generate an inverse local to global bnd map;
509  map<int,int> invLocToGloMap;
510  for(i = 0; i < nbndry; ++i)
511  {
512  invLocToGloMap[m_localToGlobalBndMap[i]] = i;
513  }
514 
515  // reset bndCondCoeffToLocalTraceMap to hold local rather
516  // than global reference
517  for(i = 0; i < m_bndCondCoeffsToLocalTraceMap.size(); ++i)
518  {
520  invLocToGloMap[m_bndCondCoeffsToLocalTraceMap[i]];
521  }
522 
523  // Now set up mapping from global coefficients to universal.
524  ExpListSharedPtr tr = std::dynamic_pointer_cast<ExpList>(trace);
525  SetUpUniversalDGMap (locExp);
526 
529  locExp, tr, m_elmtToTrace, bndCondExp, bndCond, periodicTrace));
530 
535  && nGraphVerts)
536  {
537  if (m_staticCondLevel < (bottomUpGraph->GetNlevels() - 1))
538  {
539  Array<OneD, int> vwgts_perm(nGraphVerts);
540 
541  for (int i = 0; i < nGraphVerts; i++)
542  {
543  vwgts_perm[i] = vwgts[perm[i]];
544  }
545 
546  bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
548  AllocateSharedPtr(this, bottomUpGraph);
549  }
550  }
551 
553  m_localToGlobalBndMap.end());
554  }
555 
556  /**
557  * Constructs a mapping between the process-local global numbering and
558  * a universal numbering of the trace space expansion. The universal
559  * numbering is defined by the mesh edge IDs to enforce consistency
560  * across processes.
561  *
562  * @param locExp List of local elemental expansions.
563  */
565  {
567  int cnt = 0;
568  int id = 0;
569  int order_e = 0;
570  int vGlobalId = 0;
571  int maxDof = 0;
572  int dof = 0;
573  int nDim = 0;
574  int i,j,k;
575 
576  const LocalRegions::ExpansionVector &locExpVector = *(locExp.GetExp());
577 
578  // Initialise the global to universal maps.
581 
582  // Loop over all the elements in the domain and compute max
583  // DOF. Reduce across all processes to get universal maximum.
584  for(i = 0; i < locExpVector.size(); ++i)
585  {
586  locExpansion = locExpVector[i];
587  nDim = locExpansion->GetShapeDimension();
588 
589  // Loop over all edges of element i
590  if (nDim == 1)
591  {
592  maxDof = (1 > maxDof ? 1 : maxDof);
593  }
594  else
595  {
596  for (j = 0; j < locExpansion->GetNtraces(); ++j)
597  {
598  dof = locExpansion->GetTraceNcoeffs(j);
599  maxDof = (dof > maxDof ? dof : maxDof);
600  }
601  }
602  }
603  m_comm->GetRowComm()->AllReduce(maxDof, LibUtilities::ReduceMax);
604 
605  // Now have trace edges Gid position
606  cnt = 0;
607  for(i = 0; i < locExpVector.size(); ++i)
608  {
609  locExpansion = locExpVector[i];
610  nDim = locExpansion->GetShapeDimension();
611 
612  // Populate mapping for each edge of the element.
613  if (nDim == 1)
614  {
615  int nverts = locExpansion->GetNverts();
616  for(j = 0; j < nverts; ++j)
617  {
618  LocalRegions::PointExpSharedPtr locPointExp =
620  id = locPointExp->GetGeom()->GetGlobalID();
621  vGlobalId = m_localToGlobalBndMap[cnt+j];
622  m_globalToUniversalBndMap[vGlobalId]
623  = id * maxDof + j + 1;
624  }
625  cnt += nverts;
626  }
627  else if (nDim == 2)
628  {
629  for(j = 0; j < locExpansion->GetNtraces(); ++j)
630  {
632  m_elmtToTrace[i][j]->as<LocalRegions::SegExp>();
633 
634  id = locSegExp->GetGeom()->GetGlobalID();
635  order_e = locExpansion->GetTraceNcoeffs(j);
636 
637  map<int,int> orientMap;
638  Array<OneD, unsigned int> map1(order_e), map2(order_e);
639  Array<OneD, int> sign1(order_e), sign2(order_e);
640 
641  locExpansion->GetTraceToElementMap(j, map1, sign1,
643  locExpansion->GetTraceToElementMap(j, map2, sign2,
644  locExpansion->GetTraceOrient(j));
645 
646  for (k = 0; k < map1.size(); ++k)
647  {
648  // Find the elemental co-efficient in the original
649  // mapping.
650  int idx = -1;
651  for (int l = 0; l < map2.size(); ++l)
652  {
653  if (map1[k] == map2[l])
654  {
655  idx = l;
656  break;
657  }
658  }
659 
660  ASSERTL2(idx != -1, "Problem with face to"
661  " element map!");
662  orientMap[k] = idx;
663  }
664 
665  for(k = 0; k < order_e; ++k)
666  {
667  vGlobalId = m_localToGlobalBndMap[k+cnt];
668  m_globalToUniversalBndMap[vGlobalId]
669  = id * maxDof + orientMap[k] + 1;
670  }
671  cnt += order_e;
672  }
673  }
674  else if (nDim == 3) //This could likely be combined with nDim == 2
675  {
676  for(j = 0; j < locExpansion->GetNtraces(); ++j)
677  {
679  m_elmtToTrace[i][j]
681 
682  id = locFaceExp->GetGeom()->GetGlobalID();
683  order_e = locExpansion->GetTraceNcoeffs(j);
684 
685  map<int,int> orientMap;
686  Array<OneD, unsigned int> map1(order_e), map2(order_e);
687  Array<OneD, int> sign1(order_e), sign2(order_e);
688 
689  locExpansion->GetTraceToElementMap(j, map1, sign1,
691  locExpansion->GetTraceToElementMap(j, map2, sign2,
692  locExpansion->GetTraceOrient(j));
693 
694  for (k = 0; k < map1.size(); ++k)
695  {
696  // Find the elemental co-efficient in the original
697  // mapping.
698  int idx = -1;
699  for (int l = 0; l < map2.size(); ++l)
700  {
701  if (map1[k] == map2[l])
702  {
703  idx = l;
704  break;
705  }
706  }
707 
708  ASSERTL2(idx != -1, "Problem with face to "
709  "element map!");
710  orientMap[k] = idx;
711  }
712 
713  for(k = 0; k < order_e; ++k)
714  {
715  vGlobalId = m_localToGlobalBndMap[k+cnt];
716  m_globalToUniversalBndMap[vGlobalId]
717  = id * maxDof + orientMap[k] + 1;
718  }
719  cnt += order_e;
720  }
721  }
722  }
723 
724  // Initialise GSlib and populate the unique map.
726  for (i = 0; i < m_globalToUniversalBndMap.size(); ++i)
727  {
728  tmp[i] = m_globalToUniversalBndMap[i];
729  }
730  m_bndGsh = m_gsh = Gs::Init(tmp, m_comm->GetRowComm());
731  Gs::Unique(tmp, m_comm->GetRowComm());
732  for (i = 0; i < m_globalToUniversalBndMap.size(); ++i)
733  {
734  m_globalToUniversalBndMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
735  }
736  }
737 
739  Array<OneD, int> &toAlign,
741  int nquad1,
742  int nquad2)
743  {
744  if (orient == StdRegions::eBackwards)
745  {
746  ASSERTL1(nquad2 == 0, "nquad2 != 0 for reorienation");
747  for (int i = 0; i < nquad1/2; ++i)
748  {
749  swap(toAlign[i], toAlign[nquad1-1-i]);
750  }
751  }
752  else if (orient != StdRegions::eForwards)
753  {
754  ASSERTL1(nquad2 != 0, "nquad2 == 0 for reorienation");
755 
756  Array<OneD, int> tmp(nquad1*nquad2);
757 
758  // Copy transpose.
759  if (orient == StdRegions::eDir1FwdDir2_Dir2FwdDir1 ||
763  {
764  for (int i = 0; i < nquad2; ++i)
765  {
766  for (int j = 0; j < nquad1; ++j)
767  {
768  tmp[i*nquad1 + j] = toAlign[j*nquad2 + i];
769  }
770  }
771  }
772  else
773  {
774  for (int i = 0; i < nquad2; ++i)
775  {
776  for (int j = 0; j < nquad1; ++j)
777  {
778  tmp[i*nquad1 + j] = toAlign[i*nquad1 + j];
779  }
780  }
781  }
782 
783  if (orient == StdRegions::eDir1BwdDir1_Dir2FwdDir2 ||
787  {
788  // Reverse x direction
789  for (int i = 0; i < nquad2; ++i)
790  {
791  for (int j = 0; j < nquad1/2; ++j)
792  {
793  swap(tmp[i*nquad1 + j],
794  tmp[i*nquad1 + nquad1-j-1]);
795  }
796  }
797  }
798 
799  if (orient == StdRegions::eDir1FwdDir1_Dir2BwdDir2 ||
803  {
804  // Reverse y direction
805  for (int j = 0; j < nquad1; ++j)
806  {
807  for (int i = 0; i < nquad2/2; ++i)
808  {
809  swap(tmp[i*nquad1 + j],
810  tmp[(nquad2-i-1)*nquad1 + j]);
811  }
812  }
813  }
814  Vmath::Vcopy(nquad1*nquad2, tmp, 1, toAlign, 1);
815  }
816  }
817 
819  {
820  return m_localToGlobalBndMap[i];
821  }
822 
824  {
825  return m_globalToUniversalBndMap[i];
826  }
827 
829  {
831  }
832 
834  {
835  return m_localToGlobalBndMap;
836  }
837 
839  {
841  }
842 
844  {
846  }
847 
849  const int i) const
850  {
851  return GetLocalToGlobalBndSign(i);
852  }
853 
856  Array<OneD, NekDouble>& global,
857  bool useComm ) const
858  {
859  LocalBndToGlobal(loc,global,useComm);
860  }
861 
863  const Array<OneD, const NekDouble>& global,
865  {
866  GlobalToLocalBnd(global,loc);
867  }
868 
870  const NekVector<NekDouble>& global,
871  NekVector< NekDouble>& loc) const
872  {
873  GlobalToLocalBnd(global,loc);
874  }
875 
878  Array<OneD, NekDouble> &global) const
879  {
880  AssembleBnd(loc,global);
881  }
882 
884  const NekVector<NekDouble>& loc,
885  NekVector< NekDouble>& global) const
886  {
887  AssembleBnd(loc,global);
888  }
889 
891  Array<OneD, NekDouble>& pGlobal) const
892  {
893  Gs::Gather(pGlobal, Gs::gs_add, m_gsh);
894  }
895 
897  NekVector< NekDouble>& pGlobal) const
898  {
899  UniversalAssemble(pGlobal.GetPtr());
900  }
901 
903  {
904  return GetBndSystemBandWidth();
905  }
906 
908  {
909  return m_numDirichletBndPhys;
910  }
911 
914  {
915  ASSERTL1(i >= 0 && i < m_elmtToTrace.size(),
916  "i is out of range");
917  return m_elmtToTrace[i];
918  }
919 
922  {
923  return m_elmtToTrace;
924  }
925 
927  {
928  return m_assemblyComm;
929  }
930 
931  } //namespace
932 } // namespace
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:274
SpatialDomains::GeometrySharedPtr GetGeom() const
Definition: Expansion.cpp:172
const SpatialDomains::PointGeomSharedPtr GetGeom() const
Definition: PointExp.h:110
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.
Array< OneD, Array< OneD, LocalRegions::ExpansionSharedPtr > > m_elmtToTrace
list of edge expansions for a given element
virtual void v_GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique()
static void RealignTraceElement(Array< OneD, int > &toAlign, StdRegions::Orientation orient, int nquad1, int nquad2=0)
AssemblyCommDGSharedPtr m_assemblyComm
Array< OneD, Array< OneD, LocalRegions::ExpansionSharedPtr > > & GetElmtToTrace()
virtual int v_GetFullSystemBandWidth() const
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMap()
AssemblyCommDGSharedPtr GetAssemblyCommDG()
int GetNumDirichletBndPhys()
Return the number of boundary segments on which Dirichlet boundary conditions are imposed.
virtual void v_LocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm=false) const
virtual void v_Assemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
void SetUpUniversalDGMap(const ExpList &locExp)
int m_numDirichletBndPhys
Number of physical dirichlet boundary values in trace.
virtual void v_UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const
AssemblyMapDG()
Default constructor.
virtual const Array< OneD, const int > & v_GetLocalToGlobalMap()
Base class for constructing local to global mapping of degrees of freedom.
Definition: AssemblyMap.h:59
int m_lowestStaticCondLevel
Lowest static condensation level.
Definition: AssemblyMap.h:434
GlobalSysSolnType m_solnType
The solution type of the global system.
Definition: AssemblyMap.h:395
int m_numLocalCoeffs
Total number of local coefficients.
Definition: AssemblyMap.h:357
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
Definition: AssemblyMap.h:390
bool m_signChange
Flag indicating if modes require sign reversal.
Definition: AssemblyMap.h:371
void AssembleBnd(const NekVector< NekDouble > &loc, NekVector< NekDouble > &global, int offset) const
int m_numGlobalCoeffs
Total number of global coefficients.
Definition: AssemblyMap.h:368
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
Definition: AssemblyMap.h:374
void CalculateBndSystemBandWidth()
Calculates the bandwidth of the boundary system.
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
Definition: AssemblyMap.h:425
virtual const Array< OneD, NekDouble > & v_GetLocalToGlobalSign() const
int m_numLocalBndCoeffs
Number of local boundary coefficients.
Definition: AssemblyMap.h:338
AssemblyMapSharedPtr m_nextLevelLocalToGlobalMap
Map from the patches of the previous level to the patches of the current level.
Definition: AssemblyMap.h:432
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Definition: AssemblyMap.h:421
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Definition: AssemblyMap.h:376
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:342
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:344
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Definition: AssemblyMap.h:427
int GetBndSystemBandWidth() const
Returns the bandwidth of the boundary system.
Array< OneD, const NekDouble > GetLocalToGlobalBndSign() const
Retrieve the sign change for all local boundary modes.
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: AssemblyMap.h:332
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
Definition: AssemblyMap.h:378
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
Definition: AssemblyMap.h:392
void LocalBndToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, int offset, bool UseComm=true) const
void UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const
int m_numPatches
The number of patches (~elements) in the current level.
Definition: AssemblyMap.h:423
Array< OneD, int > m_bndCondIDToGlobalTraceID
Integer map of bnd cond trace number to global trace number.
Definition: AssemblyMap.h:388
Array< OneD, int > m_bndCondCoeffsToLocalTraceMap
Integer map of bnd cond coeff to local trace coeff.
Definition: AssemblyMap.h:386
void GlobalToLocalBnd(const NekVector< NekDouble > &global, NekVector< NekDouble > &loc, int offset) const
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Definition: AssemblyMap.h:340
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:107
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
Definition: ExpList.h:2422
Array< OneD, DataType > & GetPtr()
Definition: NekVector.cpp:227
static void Gather(Nektar::Array< OneD, NekDouble > pU, gs_op pOp, gs_data *pGsh, Nektar::Array< OneD, NekDouble > pBuffer=NullNekDouble1DArray)
Performs a gather-scatter operation of the provided values.
Definition: GsLib.hpp:245
@ gs_add
Definition: GsLib.hpp:53
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
Definition: GsLib.hpp:167
static void Unique(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm)
Updates pId to negate all-but-one references to each universal ID.
Definition: GsLib.hpp:202
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ eGauss_Lagrange
Lagrange Polynomials using the Gauss points .
Definition: BasisType.h:55
@ eGLL_Lagrange
Lagrange for SEM basis .
Definition: BasisType.h:54
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:48
std::shared_ptr< SegExp > SegExpSharedPtr
Definition: SegExp.h:272
std::shared_ptr< PointExp > PointExpSharedPtr
Definition: PointExp.h:129
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:68
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
Definition: Expansion1D.h:47
std::vector< ExpansionSharedPtr > ExpansionVector
Definition: Expansion.h:70
void NoReordering(const BoostGraph &graph, Array< OneD, int > &perm, Array< OneD, int > &iperm)
std::shared_ptr< AssemblyCommDG > AssemblyCommDGSharedPtr
void CuthillMckeeReordering(const BoostGraph &graph, Array< OneD, int > &perm, Array< OneD, int > &iperm)
void MultiLevelBisectionReordering(const BoostGraph &graph, Array< OneD, int > &perm, Array< OneD, int > &iperm, BottomUpSubStructuredGraphSharedPtr &substructgraph, std::set< int > partVerts, int mdswitch)
std::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:53
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
std::size_t hash_range(Iter first, Iter last)
Definition: HashUtils.hpp:69
double NekDouble
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199