Nektar++
AssemblyMap.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: AssemblyMap.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: Assembly (e.g. local to global) base mapping routines
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
38 
39 using namespace std;
40 
41 namespace Nektar
42 {
43 namespace MultiRegions
44 {
45 /**
46  * @class AssemblyMap
47  * This class acts as a base class for constructing mappings between
48  * local, global and boundary degrees of freedom. It holds the storage
49  * for the maps and provides the accessors needed to retrieve them.
50  *
51  * There are two derived classes: AssemblyMapCG and
52  * AssemblyMapDG. These perform the actual construction of the
53  * maps within their specific contexts.
54  *
55  */
56 
57 /// Rounds a double precision number to an integer.
59 {
60  return int(x > 0.0 ? x + 0.5 : x - 0.5);
61 }
62 
63 /// Rounds an array of double precision numbers to integers.
65  Array<OneD, int> outarray)
66 {
67  int size = inarray.size();
68  ASSERTL1(outarray.size() >= size, "Array sizes not compatible");
69 
70  NekDouble x;
71  for (int i = 0; i < size; i++)
72  {
73  x = inarray[i];
74  outarray[i] = int(x > 0.0 ? x + 0.5 : x - 0.5);
75  }
76 }
77 
78 /**
79  * Initialises an empty mapping.
80  */
81 AssemblyMap::AssemblyMap()
82  : m_session(), m_comm(), m_hash(0), m_numLocalBndCoeffs(0),
83  m_numGlobalBndCoeffs(0), m_numLocalDirBndCoeffs(0),
84  m_numGlobalDirBndCoeffs(0), m_solnType(eNoSolnType),
85  m_bndSystemBandWidth(0), m_successiveRHS(0),
86  m_linSysIterSolver("ConjugateGradient"), m_gsh(0), m_bndGsh(0)
87 {
88 }
89 
91  const LibUtilities::CommSharedPtr &comm,
92  const std::string variable)
93  : m_session(pSession), m_comm(comm), m_hash(0), m_numLocalBndCoeffs(0),
94  m_numGlobalBndCoeffs(0), m_numLocalDirBndCoeffs(0),
95  m_numGlobalDirBndCoeffs(0), m_bndSystemBandWidth(0), m_successiveRHS(0),
96  m_linSysIterSolver("ConjugateGradient"), m_gsh(0), m_bndGsh(0)
97 {
98  // Default value from Solver Info
99  m_solnType =
100  pSession->GetSolverInfoAsEnum<GlobalSysSolnType>("GlobalSysSoln");
101  m_preconType =
102  pSession->GetSolverInfoAsEnum<PreconditionerType>("Preconditioner");
103 
104  // Override values with data from GlobalSysSolnInfo section
105  if (pSession->DefinesGlobalSysSolnInfo(variable, "GlobalSysSoln"))
106  {
107  std::string sysSoln =
108  pSession->GetGlobalSysSolnInfo(variable, "GlobalSysSoln");
109  m_solnType = pSession->GetValueAsEnum<GlobalSysSolnType>(
110  "GlobalSysSoln", sysSoln);
111  }
112 
113  if (pSession->DefinesGlobalSysSolnInfo(variable, "Preconditioner"))
114  {
115  std::string precon =
116  pSession->GetGlobalSysSolnInfo(variable, "Preconditioner");
117  m_preconType = pSession->GetValueAsEnum<PreconditionerType>(
118  "Preconditioner", precon);
119  }
120 
121  if (pSession->DefinesGlobalSysSolnInfo(variable,
122  "IterativeSolverTolerance"))
123  {
124  m_iterativeTolerance = boost::lexical_cast<NekDouble>(
125  pSession->GetGlobalSysSolnInfo(variable, "IterativeSolverTolerance")
126  .c_str());
127  }
128  else
129  {
130  pSession->LoadParameter("IterativeSolverTolerance",
133  }
134 
135  if (pSession->DefinesGlobalSysSolnInfo(variable, "MaxIterations"))
136  {
137  m_maxIterations = boost::lexical_cast<int>(
138  pSession->GetGlobalSysSolnInfo(variable, "MaxIterations").c_str());
139  }
140  else
141  {
142  pSession->LoadParameter("MaxIterations", m_maxIterations, 5000);
143  }
144 
145  if (pSession->DefinesGlobalSysSolnInfo(variable, "SuccessiveRHS"))
146  {
147  m_successiveRHS = boost::lexical_cast<int>(
148  pSession->GetGlobalSysSolnInfo(variable, "SuccessiveRHS").c_str());
149  }
150  else
151  {
152  pSession->LoadParameter("SuccessiveRHS", m_successiveRHS, 0);
153  }
154 
155  if (pSession->DefinesGlobalSysSolnInfo(variable, "LinSysIterSolver"))
156  {
158  pSession->GetGlobalSysSolnInfo(variable, "LinSysIterSolver");
159  }
160  else if (pSession->DefinesSolverInfo("LinSysIterSolver"))
161  {
162  m_linSysIterSolver = pSession->GetSolverInfo("LinSysIterSolver");
163  }
164  else
165  {
166  m_linSysIterSolver = "ConjugateGradient";
167  }
168 }
169 
170 /**
171  * Create a new level of mapping using the information in
172  * multiLevelGraph and performing the following steps:
173  */
175  AssemblyMap *oldLevelMap,
176  const BottomUpSubStructuredGraphSharedPtr &multiLevelGraph)
177  : m_session(oldLevelMap->m_session), m_comm(oldLevelMap->GetComm()),
178  m_hash(0), m_solnType(oldLevelMap->m_solnType),
179  m_preconType(oldLevelMap->m_preconType),
180  m_maxIterations(oldLevelMap->m_maxIterations),
181  m_iterativeTolerance(oldLevelMap->m_iterativeTolerance),
182  m_successiveRHS(oldLevelMap->m_successiveRHS),
183  m_linSysIterSolver(oldLevelMap->m_linSysIterSolver),
184  m_gsh(oldLevelMap->m_gsh), m_bndGsh(oldLevelMap->m_bndGsh),
185  m_lowestStaticCondLevel(oldLevelMap->m_lowestStaticCondLevel)
186 {
187  int i;
188  int j;
189  int cnt;
190 
191  //--------------------------------------------------------------
192  // -- Extract information from the input argument
193  int numGlobalBndCoeffsOld = oldLevelMap->GetNumGlobalBndCoeffs();
194  int numGlobalDirBndCoeffsOld = oldLevelMap->GetNumGlobalDirBndCoeffs();
195  int numLocalBndCoeffsOld = oldLevelMap->GetNumLocalBndCoeffs();
196  int numLocalDirBndCoeffsOld = oldLevelMap->GetNumLocalDirBndCoeffs();
197  bool signChangeOld = oldLevelMap->GetSignChange();
198 
199  int staticCondLevelOld = oldLevelMap->GetStaticCondLevel();
200  int numPatchesOld = oldLevelMap->GetNumPatches();
201  GlobalSysSolnType solnTypeOld = oldLevelMap->GetGlobalSysSolnType();
202  const Array<OneD, const unsigned int> &numLocalBndCoeffsPerPatchOld =
203  oldLevelMap->GetNumLocalBndCoeffsPerPatch();
204  //--------------------------------------------------------------
205 
206  //--------------------------------------------------------------
207  int newLevel = staticCondLevelOld + 1;
208  /** - STEP 1: setup a mask array to determine to which patch
209  * of the new level every patch of the current
210  * level belongs. To do so we make four arrays,
211  * #gloPatchMask, #globHomPatchMask,
212  * #locPatchMask_NekDouble and #locPatchMask.
213  * These arrays are then used to check which local
214  * dofs of the old level belong to which patch of
215  * the new level
216  */
217  Array<OneD, NekDouble> globPatchMask(numGlobalBndCoeffsOld, -1.0);
218  Array<OneD, NekDouble> globHomPatchMask(globPatchMask +
219  numGlobalDirBndCoeffsOld);
220  Array<OneD, NekDouble> locPatchMask_NekDouble(numLocalBndCoeffsOld, -3.0);
221  Array<OneD, int> locPatchMask(numLocalBndCoeffsOld);
222 
223  // Fill the array globPatchMask as follows:
224  // - The first part (i.e. the glob bnd dofs) is filled with the
225  // value -1
226  // - The second part (i.e. the glob interior dofs) is numbered
227  // according to the patch it belongs to (i.e. dofs in first block
228  // all are numbered 0, the second block numbered are 1, etc...)
229  multiLevelGraph->MaskPatches(newLevel, globHomPatchMask);
230 
231  // Map from Global Dofs to Local Dofs
232  // As a result, we know for each local dof whether
233  // it is mapped to the boundary of the next level, or to which
234  // patch. Based upon this, we can than later associate every patch
235  // of the current level with a patch in the next level.
236  oldLevelMap->GlobalToLocalBndWithoutSign(globPatchMask,
237  locPatchMask_NekDouble);
238 
239  // Convert the result to an array of integers rather than doubles
240  RoundNekDoubleToInt(locPatchMask_NekDouble, locPatchMask);
241 
242  /** - STEP 2: We calculate how many local bnd dofs of the
243  * old level belong to the boundaries of each patch at
244  * the new level. We need this information to set up the
245  * mapping between different levels.
246  */
247 
248  // Retrieve the number of patches at the next level
249  int numPatchesWithIntNew =
250  multiLevelGraph->GetNpatchesWithInterior(newLevel);
251  int numPatchesNew = numPatchesWithIntNew;
252 
253  // Allocate memory to store the number of local dofs associated to
254  // each of elemental boundaries of these patches
255  std::map<int, int> numLocalBndCoeffsPerPatchNew;
256  for (int i = 0; i < numPatchesNew; i++)
257  {
258  numLocalBndCoeffsPerPatchNew[i] = 0;
259  }
260 
261  int minval;
262  int maxval;
263  int curPatch;
264  for (i = cnt = 0; i < numPatchesOld; i++)
265  {
266  // For every patch at the current level, the mask array
267  // locPatchMask should be filled with
268  // - the same (positive) number for each entry (which will
269  // correspond to the patch at the next level it belongs to)
270  // - the same (positive) number for each entry, except some
271  // entries that are -1 (the enties correspond to -1, will be
272  // mapped to the local boundary of the next level patch given
273  // by the positive number)
274  // - -1 for all entries. In this case, we will make an
275  // additional patch only consisting of boundaries at the next
276  // level
277  minval =
278  *min_element(&locPatchMask[cnt],
279  &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
280  maxval =
281  *max_element(&locPatchMask[cnt],
282  &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
283  ASSERTL0((minval == maxval) || (minval == -1),
284  "These values should never be the same");
285 
286  if (maxval == -1)
287  {
288  curPatch = numPatchesNew;
289  numLocalBndCoeffsPerPatchNew[curPatch] = 0;
290  numPatchesNew++;
291  }
292  else
293  {
294  curPatch = maxval;
295  }
296 
297  for (j = 0; j < numLocalBndCoeffsPerPatchOld[i]; j++)
298  {
299  ASSERTL0((locPatchMask[cnt] == maxval) ||
300  (locPatchMask[cnt] == minval),
301  "These values should never be the same");
302  if (locPatchMask[cnt] == -1)
303  {
304  ++numLocalBndCoeffsPerPatchNew[curPatch];
305  }
306  cnt++;
307  }
308  }
309 
310  // Count how many local dofs of the old level are mapped
311  // to the local boundary dofs of the new level
312  m_numLocalCoeffs = 0;
314  m_numPatches = numLocalBndCoeffsPerPatchNew.size();
317  multiLevelGraph->GetNintDofsPerPatch(newLevel, m_numLocalIntCoeffsPerPatch);
318 
319  for (int i = 0; i < m_numPatches; i++)
320  {
322  (unsigned int)numLocalBndCoeffsPerPatchNew[i];
326  }
327 
328  // Also initialise some more data members
329  m_solnType = solnTypeOld;
334  "This method should only be called for in "
335  "case of multi-level static condensation.");
336  m_staticCondLevel = newLevel;
337  m_signChange = signChangeOld;
338  m_numLocalDirBndCoeffs = numLocalDirBndCoeffsOld;
339  m_numGlobalDirBndCoeffs = numGlobalDirBndCoeffsOld;
341  multiLevelGraph->GetInteriorOffset(newLevel) + m_numGlobalDirBndCoeffs;
343  multiLevelGraph->GetNumGlobalDofs(newLevel) + m_numGlobalDirBndCoeffs;
345 
349 
350  // local to bnd map is just a copy
351  for (int i = 0; i < m_numLocalBndCoeffs; ++i)
352  {
353  m_localToLocalBndMap[i] = i;
354  }
355 
356  // local to int map is just a copy plus offset
357  for (int i = m_numLocalBndCoeffs; i < m_numLocalCoeffs; ++i)
358  {
360  }
361 
362  if (m_signChange)
363  {
365  }
366 
368  MemoryManager<PatchMap>::AllocateSharedPtr(numLocalBndCoeffsOld);
369 
374 
375  // Set up an offset array that denotes the offset of the local
376  // boundary degrees of freedom of the next level
377  Array<OneD, int> numLocalBndCoeffsPerPatchOffset(m_numPatches + 1, 0);
378  for (int i = 1; i < m_numPatches + 1; i++)
379  {
380  numLocalBndCoeffsPerPatchOffset[i] +=
381  numLocalBndCoeffsPerPatchOffset[i - 1] +
382  numLocalBndCoeffsPerPatchNew[i - 1];
383  }
384 
385  int additionalPatchCnt = numPatchesWithIntNew;
386  int newid;
387  int blockid;
388  bool isBndDof;
389  NekDouble sign;
390  Array<OneD, int> bndDofPerPatchCnt(m_numPatches, 0);
391 
392  for (i = cnt = 0; i < numPatchesOld; i++)
393  {
394  minval =
395  *min_element(&locPatchMask[cnt],
396  &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
397  maxval =
398  *max_element(&locPatchMask[cnt],
399  &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
400  ASSERTL0((minval == maxval) || (minval == -1),
401  "These values should never be the same");
402 
403  if (maxval == -1)
404  {
405  curPatch = additionalPatchCnt;
406  additionalPatchCnt++;
407  }
408  else
409  {
410  curPatch = maxval;
411  }
412 
413  for (j = 0; j < numLocalBndCoeffsPerPatchOld[i]; j++)
414  {
415  ASSERTL0((locPatchMask[cnt] == maxval) ||
416  (locPatchMask[cnt] == minval),
417  "These values should never be the same");
418 
419  sign = oldLevelMap->GetLocalToGlobalBndSign(cnt);
420 
421  if (locPatchMask[cnt] == -1)
422  {
423  newid = numLocalBndCoeffsPerPatchOffset[curPatch];
424 
425  m_localToGlobalBndMap[newid] =
426  oldLevelMap->GetLocalToGlobalBndMap(cnt);
427 
428  if (m_signChange)
429  {
430  m_localToGlobalBndSign[newid] = sign;
431  }
432 
433  blockid = bndDofPerPatchCnt[curPatch];
434  isBndDof = true;
435 
436  numLocalBndCoeffsPerPatchOffset[curPatch]++;
437  bndDofPerPatchCnt[curPatch]++;
438  }
439  else
440  {
441  newid = oldLevelMap->GetLocalToGlobalBndMap(cnt) -
443 
444  blockid =
445  oldLevelMap->GetLocalToGlobalBndMap(cnt) -
447  multiLevelGraph->GetInteriorOffset(newLevel, curPatch);
448  isBndDof = false;
449  }
450 
451  sign = isBndDof ? 1.0 : sign;
452 
453  m_patchMapFromPrevLevel->SetPatchMap(cnt, curPatch, blockid,
454  isBndDof, sign);
455  cnt++;
456  }
457  }
458 
459  // set up local to local mapping from previous to new level
462 
464 
465  // Postprocess the computed information - Update the old
466  // level with the mapping to new level
467  // oldLevelMap->SetLocalBndToNextLevelMap(oldLocalBndToNewLevelMap,oldLocalBndToNewLevelSign);
468 
469  // - Construct the next level mapping object
470  if (m_staticCondLevel < (multiLevelGraph->GetNlevels() - 1))
471  {
474  multiLevelGraph);
475  }
476 }
477 
479 {
480 }
481 
482 /**
483  * The bandwidth calculated corresponds to what is referred to as
484  * half-bandwidth. If the elements of the matrix are designated as
485  * a_ij, it corresponds to the maximum value of |i-j| for non-zero
486  * a_ij. As a result, the value also corresponds to the number of
487  * sub- or super-diagonals.
488  *
489  * The bandwith can be calculated elementally as it corresponds to the
490  * maximal elemental bandwith (i.e. the maximal difference in global
491  * DOF index for every element).
492  *
493  * We here calculate the bandwith of the global boundary system (as
494  * used for static condensation).
495  */
497 {
498  int i, j;
499  int cnt = 0;
500  int locSize;
501  int maxId;
502  int minId;
503  int bwidth = -1;
504  for (i = 0; i < m_numPatches; ++i)
505  {
506  locSize = m_numLocalBndCoeffsPerPatch[i];
507  maxId = -1;
508  minId = m_numLocalBndCoeffs + 1;
509  for (j = 0; j < locSize; j++)
510  {
512  {
513  if (m_localToGlobalBndMap[cnt + j] > maxId)
514  {
515  maxId = m_localToGlobalBndMap[cnt + j];
516  }
517 
518  if (m_localToGlobalBndMap[cnt + j] < minId)
519  {
520  minId = m_localToGlobalBndMap[cnt + j];
521  }
522  }
523  }
524  bwidth = (bwidth > (maxId - minId)) ? bwidth : (maxId - minId);
525 
526  cnt += locSize;
527  }
528 
529  m_bndSystemBandWidth = bwidth;
530 }
531 
533 {
534  boost::ignore_unused(i);
535  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
536  return 0;
537 }
538 
540 {
541  boost::ignore_unused(i);
542  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
543  return 0;
544 }
545 
547 {
548  boost::ignore_unused(i);
549  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
550  return 0;
551 }
552 
554 {
555  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
556  static Array<OneD, const int> result;
557  return result;
558 }
559 
561 {
562  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
563  static Array<OneD, const int> result;
564  return result;
565 }
566 
568 {
569  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
570  static Array<OneD, const int> result;
571  return result;
572 }
573 
575 {
576  boost::ignore_unused(i);
577  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
578  return 0.0;
579 }
580 
582 {
583  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
584  static Array<OneD, NekDouble> result;
585  return result;
586 }
587 
589  Array<OneD, NekDouble> &global,
590  bool useComm) const
591 {
592  boost::ignore_unused(loc, global, useComm);
593  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
594 }
595 
597  NekVector<NekDouble> &global,
598  bool useComm) const
599 {
600  boost::ignore_unused(loc, global, useComm);
601  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
602 }
603 
606 {
607  boost::ignore_unused(loc, global);
608  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
609 }
610 
612  NekVector<NekDouble> &loc) const
613 {
614  boost::ignore_unused(loc, global);
615  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
616 }
617 
619  Array<OneD, NekDouble> &global) const
620 {
621  boost::ignore_unused(loc, global);
622  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
623 }
624 
626  NekVector<NekDouble> &global) const
627 {
628  boost::ignore_unused(loc, global);
629  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
630 }
631 
633 {
634  boost::ignore_unused(pGlobal);
635  // Do nothing here since multi-level static condensation uses a
636  // AssemblyMap and thus will call this routine in serial.
637 }
638 
640 {
641  boost::ignore_unused(pGlobal);
642  // Do nothing here since multi-level static condensation uses a
643  // AssemblyMap and thus will call this routine in serial.
644 }
645 
647  int offset) const
648 {
649  boost::ignore_unused(pGlobal, offset);
650  // Do nothing here since multi-level static condensation uses a
651  // AssemblyMap and thus will call this routine in serial.
652 }
653 
655 {
656  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
657  return 0;
658 }
659 
661 {
662  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
663  return 0;
664 }
665 
667 {
668  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
669  return 0;
670 }
671 
673 {
674  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
675  return 0;
676 }
677 
679 {
680  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
681  return 0;
682 }
683 
685 {
686  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
687  return 0;
688 }
689 
691 {
692  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
693  return 0;
694 }
695 
697 {
698  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
699  return 0;
700 }
701 
703 {
704  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
705  static Array<OneD, const int> result;
706  return result;
707 }
708 
709 std::shared_ptr<AssemblyMap> AssemblyMap::v_LinearSpaceMap(
710  const ExpList &locexp, GlobalSysSolnType solnType)
711 {
712  boost::ignore_unused(locexp, solnType);
713  NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
714  static std::shared_ptr<AssemblyMap> result;
715  return result;
716 }
717 
719 {
720  return m_comm;
721 }
722 
723 size_t AssemblyMap::GetHash() const
724 {
725  return m_hash;
726 }
727 
728 int AssemblyMap::GetLocalToGlobalMap(const int i) const
729 {
730  return v_GetLocalToGlobalMap(i);
731 }
732 
734 {
735  return v_GetGlobalToUniversalMap(i);
736 }
737 
739 {
741 }
742 
744 {
745  return v_GetLocalToGlobalMap();
746 }
747 
749 {
750  return v_GetGlobalToUniversalMap();
751 }
752 
754 {
756 }
757 
759 {
760  return v_GetLocalToGlobalSign(i);
761 }
762 
764 {
765  return v_GetLocalToGlobalSign();
766 }
767 
769  Array<OneD, NekDouble> &global,
770  bool useComm) const
771 {
772  v_LocalToGlobal(loc, global, useComm);
773 }
774 
776  NekVector<NekDouble> &global,
777  bool useComm) const
778 {
779  v_LocalToGlobal(loc, global, useComm);
780 }
781 
784 {
785  v_GlobalToLocal(global, loc);
786 }
787 
789  NekVector<NekDouble> &loc) const
790 {
791  v_GlobalToLocal(global, loc);
792 }
793 
795  Array<OneD, NekDouble> &global) const
796 {
797  v_Assemble(loc, global);
798 }
799 
801  NekVector<NekDouble> &global) const
802 {
803  v_Assemble(loc, global);
804 }
805 
807 {
808  v_UniversalAssemble(pGlobal);
809 }
810 
812 {
813  v_UniversalAssemble(pGlobal);
814 }
815 
817  int offset) const
818 {
819  v_UniversalAssemble(pGlobal, offset);
820 }
821 
823  Array<OneD, NekDouble> &global) const
824 {
826 
827  Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
829 
830  if (global.data() == loc.data())
831  {
832  local = Array<OneD, NekDouble>(map.size(), loc.data());
833  }
834  else
835  {
836  local = loc; // create reference
837  }
838 
839  Vmath::Scatr(map.size(), sign.get(), local.get(), map.get(), global.get());
840 }
841 
844 {
846 
847  Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
849 
850  if (global.data() == loc.data())
851  {
852  glo = Array<OneD, NekDouble>(global.size(), global.data());
853  }
854  else
855  {
856  glo = global; // create reference
857  }
858 
859  Vmath::Gathr(map.size(), sign.get(), glo.get(), map.get(), loc.get());
860 }
861 
863  Array<OneD, NekDouble> &global) const
864 {
866  Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
868 
869  if (global.data() == loc.data())
870  {
871  local = Array<OneD, NekDouble>(map.size(), loc.data());
872  }
873  else
874  {
875  local = loc; // create reference
876  }
877 
878  // since we are calling mapping from level down from array
879  // the m_numLocaBndCoeffs represents the size of the
880  // boundary elements we need to assemble into
881  Vmath::Zero(m_numLocalCoeffs, global.get(), 1);
882 
883  Vmath::Assmb(map.size(), sign.get(), local.get(), map.get(), global.get());
884 }
885 
887 {
888  return v_GetFullSystemBandWidth();
889 }
890 
892 {
893  return v_GetNumNonDirVertexModes();
894 }
895 
897 {
898  return v_GetNumNonDirEdgeModes();
899 }
900 
902 {
903  return v_GetNumNonDirFaceModes();
904 }
905 
907 {
908  return v_GetNumDirEdges();
909 }
910 
912 {
913  return v_GetNumDirFaces();
914 }
915 
917 {
918  return v_GetNumNonDirEdges();
919 }
920 
922 {
923  return v_GetNumNonDirFaces();
924 }
925 
927 {
928  return v_GetExtraDirEdges();
929 }
930 
931 std::shared_ptr<AssemblyMap> AssemblyMap::LinearSpaceMap(
932  const ExpList &locexp, GlobalSysSolnType solnType)
933 {
934  return v_LinearSpaceMap(locexp, solnType);
935 }
936 
938 {
939  return m_localToGlobalBndMap[i];
940 }
941 
943 {
944  return m_localToGlobalBndMap;
945 }
946 
948 {
949  return m_signChange;
950 }
951 
953 {
954  return m_localToGlobalBndSign;
955 }
956 
958 {
960 }
961 
963 {
965 }
966 
968 {
969  if (m_signChange)
970  {
971  return m_localToGlobalBndSign[i];
972  }
973  else
974  {
975  return 1.0;
976  }
977 }
978 
980 {
982 }
983 
985 {
987 }
988 
990 {
992 }
993 
995 {
996  ASSERTL1(i < m_bndCondIDToGlobalTraceID.size(), "Index out of range.");
997  return m_bndCondIDToGlobalTraceID[i];
998 }
999 
1001 {
1003 }
1004 
1006 {
1007  return m_numGlobalDirBndCoeffs;
1008 }
1009 
1011 {
1012  return m_numLocalDirBndCoeffs;
1013 }
1014 
1016 {
1017  return m_numLocalBndCoeffs;
1018 }
1019 
1021 {
1022  return m_numGlobalBndCoeffs;
1023 }
1024 
1026 {
1027  return m_numLocalCoeffs;
1028 }
1029 
1031 {
1032  return m_numGlobalCoeffs;
1033 }
1034 
1036 {
1037  return m_systemSingular;
1038 }
1039 
1041  NekVector<NekDouble> &loc, int offset) const
1042 {
1043  GlobalToLocalBnd(global.GetPtr(), loc.GetPtr(), offset);
1044 }
1045 
1047  NekVector<NekDouble> &loc) const
1048 {
1049  GlobalToLocalBnd(global.GetPtr(), loc.GetPtr());
1050 }
1051 
1054  int offset) const
1055 {
1056  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1057  "Local vector is not of correct dimension");
1058  ASSERTL1(global.size() >= m_numGlobalBndCoeffs - offset,
1059  "Global vector is not of correct dimension");
1060 
1061  // offset input data by length "offset" for Dirichlet boundary conditions.
1063  Vmath::Vcopy(m_numGlobalBndCoeffs - offset, global.get(), 1,
1064  tmp.get() + offset, 1);
1065 
1066  if (m_signChange)
1067  {
1069  tmp.get(), m_localToGlobalBndMap.get(), loc.get());
1070  }
1071  else
1072  {
1073  Vmath::Gathr(m_numLocalBndCoeffs, tmp.get(),
1074  m_localToGlobalBndMap.get(), loc.get());
1075  }
1076 }
1077 
1079  Array<OneD, NekDouble> &loc) const
1080 {
1081  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1082  "Local vector is not of correct dimension");
1083  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1084  "Global vector is not of correct dimension");
1085 
1086  if (m_signChange)
1087  {
1089  global.get(), m_localToGlobalBndMap.get(), loc.get());
1090  }
1091  else
1092  {
1093  Vmath::Gathr(m_numLocalBndCoeffs, global.get(),
1094  m_localToGlobalBndMap.get(), loc.get());
1095  }
1096 }
1097 
1099  Array<OneD, NekDouble> &global, int offset,
1100  bool UseComm) const
1101 {
1102  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1103  "Local vector is not of correct dimension");
1104  ASSERTL1(global.size() >= m_numGlobalBndCoeffs - offset,
1105  "Global vector is not of correct dimension");
1106 
1107  // offset input data by length "offset" for Dirichlet boundary conditions.
1109 
1110  if (m_signChange)
1111  {
1113  loc.get(), m_localToGlobalBndMap.get(), tmp.get());
1114  }
1115  else
1116  {
1118  m_localToGlobalBndMap.get(), tmp.get());
1119  }
1120 
1121  // Ensure each processor has unique value with a max gather.
1122  if (UseComm)
1123  {
1125  }
1126  Vmath::Vcopy(m_numGlobalBndCoeffs - offset, tmp.get() + offset, 1,
1127  global.get(), 1);
1128 }
1129 
1131  Array<OneD, NekDouble> &global,
1132  bool UseComm) const
1133 {
1134  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1135  "Local vector is not of correct dimension");
1136  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1137  "Global vector is not of correct dimension");
1138 
1139  if (m_signChange)
1140  {
1142  loc.get(), m_localToGlobalBndMap.get(), global.get());
1143  }
1144  else
1145  {
1147  m_localToGlobalBndMap.get(), global.get());
1148  }
1149  if (UseComm)
1150  {
1151  Gs::Gather(global, Gs::gs_max, m_bndGsh);
1152  }
1153 }
1154 
1156  Array<OneD, NekDouble> &locbnd) const
1157 {
1158  ASSERTL1(locbnd.size() >= m_numLocalBndCoeffs,
1159  "LocBnd vector is not of correct dimension");
1160  ASSERTL1(local.size() >= m_numLocalCoeffs,
1161  "Local vector is not of correct dimension");
1162 
1164  locbnd.get());
1165 }
1166 
1168  Array<OneD, NekDouble> &locint) const
1169 {
1170  ASSERTL1(locint.size() >= m_numLocalCoeffs - m_numLocalBndCoeffs,
1171  "Locint vector is not of correct dimension");
1172  ASSERTL1(local.size() >= m_numLocalCoeffs,
1173  "Local vector is not of correct dimension");
1174 
1176  m_localToLocalIntMap.get(), locint.get());
1177 }
1178 
1180  Array<OneD, NekDouble> &local) const
1181 {
1182  ASSERTL1(locbnd.size() >= m_numLocalBndCoeffs,
1183  "LocBnd vector is not of correct dimension");
1184  ASSERTL1(local.size() >= m_numLocalCoeffs,
1185  "Local vector is not of correct dimension");
1186 
1188  local.get());
1189 }
1190 
1192  Array<OneD, NekDouble> &local) const
1193 {
1194  ASSERTL1(locint.size() >= m_numLocalCoeffs - m_numLocalBndCoeffs,
1195  "LocBnd vector is not of correct dimension");
1196  ASSERTL1(local.size() >= m_numLocalCoeffs,
1197  "Local vector is not of correct dimension");
1198 
1200  m_localToLocalIntMap.get(), local.get());
1201 }
1202 
1204  NekVector<NekDouble> &global, int offset) const
1205 {
1206  AssembleBnd(loc.GetPtr(), global.GetPtr(), offset);
1207 }
1208 
1210  NekVector<NekDouble> &global) const
1211 {
1212  AssembleBnd(loc.GetPtr(), global.GetPtr());
1213 }
1214 
1216  Array<OneD, NekDouble> &global, int offset) const
1217 {
1218  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1219  "Local array is not of correct dimension");
1220  ASSERTL1(global.size() >= m_numGlobalBndCoeffs - offset,
1221  "Global array is not of correct dimension");
1223 
1224  if (m_signChange)
1225  {
1227  loc.get(), m_localToGlobalBndMap.get(), tmp.get());
1228  }
1229  else
1230  {
1232  m_localToGlobalBndMap.get(), tmp.get());
1233  }
1234  UniversalAssembleBnd(tmp);
1235  Vmath::Vcopy(m_numGlobalBndCoeffs - offset, tmp.get() + offset, 1,
1236  global.get(), 1);
1237 }
1238 
1240  Array<OneD, NekDouble> &global) const
1241 {
1242  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1243  "Local vector is not of correct dimension");
1244  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1245  "Global vector is not of correct dimension");
1246 
1247  Vmath::Zero(m_numGlobalBndCoeffs, global.get(), 1);
1248 
1249  if (m_signChange)
1250  {
1252  loc.get(), m_localToGlobalBndMap.get(), global.get());
1253  }
1254  else
1255  {
1257  m_localToGlobalBndMap.get(), global.get());
1258  }
1259  UniversalAssembleBnd(global);
1260 }
1261 
1263 {
1264  ASSERTL1(pGlobal.size() >= m_numGlobalBndCoeffs, "Wrong size.");
1265  Gs::Gather(pGlobal, Gs::gs_add, m_bndGsh);
1266 }
1267 
1269 {
1270  UniversalAssembleBnd(pGlobal.GetPtr());
1271 }
1272 
1274  int offset) const
1275 {
1276  Array<OneD, NekDouble> tmp(offset);
1277  if (offset > 0)
1278  Vmath::Vcopy(offset, pGlobal, 1, tmp, 1);
1279  UniversalAssembleBnd(pGlobal);
1280  if (offset > 0)
1281  Vmath::Vcopy(offset, tmp, 1, pGlobal, 1);
1282 }
1283 
1285 {
1286  Gs::Gather(bndvals, Gs::gs_amax, m_dirBndGsh);
1287 }
1288 
1290 {
1291  return m_bndSystemBandWidth;
1292 }
1293 
1295 {
1296  return m_staticCondLevel;
1297 }
1298 
1300 {
1301  return m_numPatches;
1302 }
1303 
1306 {
1308 }
1309 
1312 {
1314 }
1315 
1317 {
1319 }
1320 
1322 {
1323  return m_patchMapFromPrevLevel;
1324 }
1325 
1327 {
1328  return !(m_nextLevelLocalToGlobalMap.get());
1329 }
1330 
1332 {
1333  return m_solnType;
1334 }
1335 
1337 {
1338  return m_preconType;
1339 }
1340 
1342 {
1343  return m_iterativeTolerance;
1344 }
1345 
1347 {
1348  return m_maxIterations;
1349 }
1350 
1352 {
1353  return m_successiveRHS;
1354 }
1355 
1357 {
1358  return m_linSysIterSolver;
1359 }
1360 
1363 {
1364  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1365  "Local vector is not of correct dimension");
1366  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1367  "Global vector is not of correct dimension");
1368 
1370  loc.get());
1371 }
1372 
1373 void AssemblyMap::PrintStats(std::ostream &out, std::string variable,
1374  bool printHeader) const
1375 {
1376  LibUtilities::CommSharedPtr vRowComm = m_session->GetComm()->GetRowComm();
1377  bool isRoot = vRowComm->GetRank() == 0;
1378  int n = vRowComm->GetSize();
1379  int i;
1380 
1381  // Determine number of global degrees of freedom.
1382  int globBndCnt = 0, globDirCnt = 0;
1383 
1384  for (i = 0; i < m_numGlobalBndCoeffs; ++i)
1385  {
1387  {
1388  globBndCnt++;
1389 
1390  if (i < m_numGlobalDirBndCoeffs)
1391  {
1392  globDirCnt++;
1393  }
1394  }
1395  }
1396 
1397  int globCnt = m_numGlobalCoeffs - m_numGlobalBndCoeffs + globBndCnt;
1398 
1399  // Calculate maximum valency
1402 
1404  tmpGlob.get());
1405  UniversalAssembleBnd(tmpGlob);
1406 
1407  int totGlobDof = globCnt;
1408  int totGlobBndDof = globBndCnt;
1409  int totGlobDirDof = globDirCnt;
1410  int totLocalDof = m_numLocalCoeffs;
1411  int totLocalBndDof = m_numLocalBndCoeffs;
1412  int totLocalDirDof = m_numLocalDirBndCoeffs;
1413 
1414  int meanValence = 0;
1415  int maxValence = 0;
1416  int minValence = 10000000;
1417  for (int i = 0; i < m_numGlobalBndCoeffs; ++i)
1418  {
1420  {
1421  continue;
1422  }
1423 
1424  if (tmpGlob[i] > maxValence)
1425  {
1426  maxValence = tmpGlob[i];
1427  }
1428  if (tmpGlob[i] < minValence)
1429  {
1430  minValence = tmpGlob[i];
1431  }
1432  meanValence += tmpGlob[i];
1433  }
1434 
1435  vRowComm->AllReduce(maxValence, LibUtilities::ReduceMax);
1436  vRowComm->AllReduce(minValence, LibUtilities::ReduceMin);
1437  vRowComm->AllReduce(meanValence, LibUtilities::ReduceSum);
1438  vRowComm->AllReduce(totGlobDof, LibUtilities::ReduceSum);
1439  vRowComm->AllReduce(totGlobBndDof, LibUtilities::ReduceSum);
1440  vRowComm->AllReduce(totGlobDirDof, LibUtilities::ReduceSum);
1441  vRowComm->AllReduce(totLocalDof, LibUtilities::ReduceSum);
1442  vRowComm->AllReduce(totLocalBndDof, LibUtilities::ReduceSum);
1443  vRowComm->AllReduce(totLocalDirDof, LibUtilities::ReduceSum);
1444 
1445  meanValence /= totGlobBndDof;
1446 
1447  if (isRoot)
1448  {
1449  if (printHeader)
1450  {
1451  out << "Assembly map statistics for field " << variable << ":"
1452  << endl;
1453  }
1454 
1455  out << " - Number of local/global dof : " << totLocalDof
1456  << " " << totGlobDof << endl;
1457  out << " - Number of local/global boundary dof : " << totLocalBndDof
1458  << " " << totGlobBndDof << endl;
1459  out << " - Number of local/global Dirichlet dof : " << totLocalDirDof
1460  << " " << totGlobDirDof << endl;
1461  out << " - dof valency (min/max/mean) : " << minValence
1462  << " " << maxValence << " " << meanValence << endl;
1463 
1464  if (n > 1)
1465  {
1466  NekDouble mean = m_numLocalCoeffs, mean2 = mean * mean;
1467  NekDouble minval = mean, maxval = mean;
1468  Array<OneD, NekDouble> tmp(1);
1469 
1470  for (i = 1; i < n; ++i)
1471  {
1472  vRowComm->Recv(i, tmp);
1473  mean += tmp[0];
1474  mean2 += tmp[0] * tmp[0];
1475 
1476  if (tmp[0] > maxval)
1477  {
1478  maxval = tmp[0];
1479  }
1480  if (tmp[0] < minval)
1481  {
1482  minval = tmp[0];
1483  }
1484  }
1485 
1486  if (maxval > 0.1)
1487  {
1488  out << " - Local dof dist. (min/max/mean/dev) : " << minval
1489  << " " << maxval << " " << (mean / n) << " "
1490  << sqrt(mean2 / n - mean * mean / n / n) << endl;
1491  }
1492 
1493  vRowComm->Block();
1494 
1495  mean = minval = maxval = m_numLocalBndCoeffs;
1496  mean2 = mean * mean;
1497 
1498  for (i = 1; i < n; ++i)
1499  {
1500  vRowComm->Recv(i, tmp);
1501  mean += tmp[0];
1502  mean2 += tmp[0] * tmp[0];
1503 
1504  if (tmp[0] > maxval)
1505  {
1506  maxval = tmp[0];
1507  }
1508  if (tmp[0] < minval)
1509  {
1510  minval = tmp[0];
1511  }
1512  }
1513 
1514  out << " - Local bnd dof dist. (min/max/mean/dev) : " << minval
1515  << " " << maxval << " " << (mean / n) << " "
1516  << sqrt(mean2 / n - mean * mean / n / n) << endl;
1517  }
1518  }
1519  else
1520  {
1521  Array<OneD, NekDouble> tmp(1);
1522  tmp[0] = m_numLocalCoeffs;
1523  vRowComm->Send(0, tmp);
1524  vRowComm->Block();
1525  tmp[0] = m_numLocalBndCoeffs;
1526  vRowComm->Send(0, tmp);
1527  }
1528 
1529  // Either we have no more levels in the static condensation, or we
1530  // are not multi-level.
1532  {
1533  return;
1534  }
1535 
1536  int level = 2;
1538  while (tmp->m_nextLevelLocalToGlobalMap)
1539  {
1540  tmp = tmp->m_nextLevelLocalToGlobalMap;
1541  ++level;
1542  }
1543 
1544  // Print out multi-level static condensation information.
1545  if (n > 1)
1546  {
1547  if (isRoot)
1548  {
1549  NekDouble mean = level, mean2 = mean * mean;
1550  int minval = level, maxval = level;
1551 
1552  Array<OneD, NekDouble> tmpRecv(1);
1553  for (i = 1; i < n; ++i)
1554  {
1555  vRowComm->Recv(i, tmpRecv);
1556  mean += tmpRecv[0];
1557  mean2 += tmpRecv[0] * tmpRecv[0];
1558 
1559  if (tmpRecv[0] > maxval)
1560  {
1561  maxval = (int)(tmpRecv[0] + 0.5);
1562  }
1563  if (tmpRecv[0] < minval)
1564  {
1565  minval = (int)(tmpRecv[0] + 0.5);
1566  }
1567  }
1568 
1569  out << " - M-level sc. dist. (min/max/mean/dev) : " << minval
1570  << " " << maxval << " " << (mean / n) << " "
1571  << sqrt(mean2 / n - mean * mean / n / n) << endl;
1572  }
1573  else
1574  {
1575  Array<OneD, NekDouble> tmpSend(1);
1576  tmpSend[0] = level;
1577  vRowComm->Send(0, tmpSend);
1578  }
1579  }
1580  else
1581  {
1582  out << " - Number of static cond. levels : " << level << endl;
1583  }
1584 
1585  if (isRoot)
1586  {
1587  out << "Stats at lowest static cond. level:" << endl;
1588  }
1589  tmp->PrintStats(out, variable, false);
1590 }
1591 } // namespace MultiRegions
1592 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:49
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Base class for constructing local to global mapping of degrees of freedom.
Definition: AssemblyMap.h:58
void PatchLocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
const Array< OneD, const int > & GetExtraDirEdges()
GlobalSysSolnType m_solnType
The solution type of the global system.
Definition: AssemblyMap.h:398
int GetNumPatches() const
Returns the number of patches in this static condensation level.
PreconditionerType m_preconType
Type type of preconditioner to use in iterative solver.
Definition: AssemblyMap.h:403
const Array< OneD, const int > & GetGlobalToUniversalMapUnique()
int GetNumGlobalCoeffs() const
Returns the total number of global coefficients.
int m_numLocalCoeffs
Total number of local coefficients.
Definition: AssemblyMap.h:360
Array< OneD, int > m_bndCondCoeffsToLocalTraceMap
Integer map of bnd cond coeff to local trace coeff.
Definition: AssemblyMap.h:389
const Array< OneD, const unsigned int > & GetNumLocalBndCoeffsPerPatch()
Returns the number of local boundary coefficients in each patch.
Array< OneD, int > m_bndCondCoeffsToLocalCoeffsMap
Integer map of bnd cond coeffs to local coefficients.
Definition: AssemblyMap.h:385
virtual const Array< OneD, const int > & v_GetExtraDirEdges()
int GetNumLocalCoeffs() const
Returns the total number of local coefficients.
const Array< OneD, const unsigned int > & GetNumLocalIntCoeffsPerPatch()
Returns the number of local interior coefficients in each patch.
virtual void v_Assemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
bool m_signChange
Flag indicating if modes require sign reversal.
Definition: AssemblyMap.h:374
void Assemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
NekDouble GetLocalToGlobalBndSign(const int i) const
Retrieve the sign change of a given local boundary mode.
virtual std::shared_ptr< AssemblyMap > v_LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType)
Generate a linear space mapping from existing mapping.
void AssembleBnd(const NekVector< NekDouble > &loc, NekVector< NekDouble > &global, int offset) const
virtual void v_LocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm) const
PreconditionerType GetPreconType() const
PatchMapSharedPtr m_patchMapFromPrevLevel
Mapping information for previous level in MultiLevel Solver.
Definition: AssemblyMap.h:512
int m_maxIterations
Maximum iterations for iterative solver.
Definition: AssemblyMap.h:406
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
Definition: AssemblyMap.h:383
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique()
NekDouble m_iterativeTolerance
Tolerance for iterative solver.
Definition: AssemblyMap.h:409
NekDouble GetIterativeTolerance() const
int m_numGlobalCoeffs
Total number of global coefficients.
Definition: AssemblyMap.h:371
std::string m_linSysIterSolver
Iterative solver: Conjugate Gradient, GMRES.
Definition: AssemblyMap.h:415
bool AtLastLevel() const
Returns true if this is the last level in the multi-level static condensation.
void UniversalAssembleBnd(Array< OneD, NekDouble > &pGlobal) const
const Array< OneD, const int > & GetLocalToGlobalMap()
const Array< OneD, const int > & GetBndCondCoeffsToLocalTraceMap()
Retrieves the local indices corresponding to the boundary expansion modes to global trace.
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMap()
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
Definition: AssemblyMap.h:393
void PatchAssemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
int m_successiveRHS
sucessive RHS for iterative solver
Definition: AssemblyMap.h:412
std::shared_ptr< AssemblyMap > LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType)
virtual int v_GetNumNonDirVertexModes() const
void CalculateBndSystemBandWidth()
Calculates the bandwidth of the boundary system.
void LocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm=true) const
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Definition: AssemblyMap.h:379
void UniversalAbsMaxBnd(Array< OneD, NekDouble > &bndvals)
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
Definition: AssemblyMap.h:428
virtual const Array< OneD, const int > & v_GetLocalToGlobalMap()
const Array< OneD, const int > & GetGlobalToUniversalMap()
std::string GetLinSysIterSolver() const
virtual int v_GetNumNonDirEdgeModes() const
virtual int v_GetNumDirFaces() const
LibUtilities::SessionReaderSharedPtr m_session
Session object.
Definition: AssemblyMap.h:332
virtual const Array< OneD, NekDouble > & v_GetLocalToGlobalSign() const
int GetNumGlobalDirBndCoeffs() const
Returns the number of global Dirichlet boundary coefficients.
const Array< OneD, NekDouble > & GetBndCondCoeffsToLocalCoeffsSign()
Returns the modal sign associated with a given boundary expansion mode.
int m_numLocalBndCoeffs
Number of local boundary coefficients.
Definition: AssemblyMap.h:341
void LocalToLocalBnd(const Array< OneD, const NekDouble > &local, Array< OneD, NekDouble > &locbnd) const
const Array< OneD, const int > & GetBndCondCoeffsToLocalCoeffsMap()
Retrieves the local indices corresponding to the boundary expansion modes.
void PrintStats(std::ostream &out, std::string variable, bool printHeader=true) const
AssemblyMapSharedPtr m_nextLevelLocalToGlobalMap
Map from the patches of the previous level to the patches of the current level.
Definition: AssemblyMap.h:435
const Array< OneD, const int > & GetLocalToGlobalBndMap()
Retrieve the global indices of the local boundary modes.
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Definition: AssemblyMap.h:424
int m_bndSystemBandWidth
The bandwith of the global bnd system.
Definition: AssemblyMap.h:400
const Array< OneD, const int > & GetGlobalToUniversalBndMapUnique()
void GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const
GlobalSysSolnType GetGlobalSysSolnType() const
Returns the method of solving global systems.
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:345
bool GetSingularSystem() const
Retrieves if the system is singular (true) or not (false)
virtual int v_GetNumNonDirFaceModes() const
void PatchGlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const
virtual int v_GetFullSystemBandWidth() const
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:347
LibUtilities::CommSharedPtr GetComm()
Retrieves the communicator.
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Definition: AssemblyMap.h:430
const AssemblyMapSharedPtr GetNextLevelLocalToGlobalMap() const
Returns the local to global mapping for the next level in the multi-level static condensation.
int GetBndSystemBandWidth() const
Returns the bandwidth of the boundary system.
virtual void v_UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const
int GetStaticCondLevel() const
Returns the level of static condensation for this map.
void GlobalToLocalBndWithoutSign(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc)
bool m_systemSingular
Flag indicating if the system is singular or not.
Definition: AssemblyMap.h:349
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
Definition: AssemblyMap.h:377
size_t GetHash() const
Retrieves the hash of this map.
int GetLocalToGlobalBndMap(const int i) const
Retrieve the global index of a given local boundary mode.
virtual ~AssemblyMap()
Destructor.
Gs::gs_data * m_dirBndGsh
gs gather communication to impose Dirhichlet BCs.
Definition: AssemblyMap.h:420
virtual void v_GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const
const Array< OneD, NekDouble > & GetLocalToGlobalSign() const
int GetNumLocalDirBndCoeffs() const
Returns the number of local Dirichlet boundary coefficients.
Array< OneD, const NekDouble > GetLocalToGlobalBndSign() const
Retrieve the sign change for all local boundary modes.
void LocalBndToLocal(const Array< OneD, const NekDouble > &locbnd, Array< OneD, NekDouble > &local) const
AssemblyMap()
Default constructor.
Definition: AssemblyMap.cpp:81
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
Definition: AssemblyMap.h:395
virtual int v_GetNumNonDirEdges() const
virtual int v_GetNumDirEdges() const
const PatchMapSharedPtr & GetPatchMapFromPrevLevel(void) const
Returns the patch map from the previous level of the multi-level static condensation.
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: AssemblyMap.h:335
int GetNumGlobalBndCoeffs() const
Returns the total number of global boundary coefficients.
const Array< OneD, const int > & GetGlobalToUniversalBndMap()
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
Definition: AssemblyMap.h:381
Array< OneD, NekDouble > m_bndCondCoeffsToLocalCoeffsSign
Integer map of sign of bnd cond coeffs to local coefficients.
Definition: AssemblyMap.h:387
const Array< OneD, const int > & GetBndCondIDToGlobalTraceID()
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:426
void LocalToLocalInt(const Array< OneD, const NekDouble > &local, Array< OneD, NekDouble > &locint) const
virtual int v_GetNumNonDirFaces() const
bool GetSignChange()
Returns true if using a modal expansion requiring a change of sign of some modes.
void LocalIntToLocal(const Array< OneD, const NekDouble > &locbnd, Array< OneD, NekDouble > &local) const
void GlobalToLocalBnd(const NekVector< NekDouble > &global, NekVector< NekDouble > &loc, int offset) const
int GetNumLocalBndCoeffs() const
Returns the total number of local boundary coefficients.
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Definition: AssemblyMap.h:343
Array< OneD, int > m_bndCondIDToGlobalTraceID
Integer map of bnd cond trace number to global trace number.
Definition: AssemblyMap.h:391
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:103
Array< OneD, DataType > & GetPtr()
Definition: NekVector.cpp:217
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:270
@ gs_amax
Definition: GsLib.hpp:66
@ gs_add
Definition: GsLib.hpp:62
@ gs_max
Definition: GsLib.hpp:65
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
@ eNoSolnType
No Solution type specified.
std::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
void RoundNekDoubleToInt(const Array< OneD, const NekDouble > inarray, Array< OneD, int > outarray)
Rounds an array of double precision numbers to integers.
Definition: AssemblyMap.cpp:64
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:51
std::shared_ptr< PatchMap > PatchMapSharedPtr
int RoundNekDoubleToInt(NekDouble x)
Rounds a double precision number to an integer.
Definition: AssemblyMap.cpp:58
static const NekDouble kNekIterativeTol
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
void Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
Definition: Vmath.cpp:822
void Gathr(int n, const T *sign, const T *x, const int *y, T *z)
Gather vector z[i] = sign[i]*x[y[i]].
Definition: Vmath.cpp:805
void Assmb(int n, const T *x, const int *y, T *z)
Assemble z[y[i]] += x[i]; z should be zero'd first.
Definition: Vmath.cpp:862
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294