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  {
66  int size = inarray.size();
67  ASSERTL1(outarray.size()>=size,"Array sizes not compatible");
68 
69  NekDouble x;
70  for(int i = 0; i < size; i++)
71  {
72  x = inarray[i];
73  outarray[i] = int(x > 0.0 ? x + 0.5 : x - 0.5);
74  }
75  }
76 
77  /**
78  * Initialises an empty mapping.
79  */
80  AssemblyMap::AssemblyMap():
81  m_session(),
82  m_comm(),
83  m_hash(0),
84  m_numLocalBndCoeffs(0),
85  m_numGlobalBndCoeffs(0),
86  m_numLocalDirBndCoeffs(0),
87  m_numGlobalDirBndCoeffs(0),
88  m_solnType(eNoSolnType),
89  m_bndSystemBandWidth(0),
90  m_successiveRHS(0),
91  m_linSysIterSolver("ConjugateGradient"),
92  m_gsh(0),
93  m_bndGsh(0)
94  {
95  }
96 
99  const std::string variable):
100  m_session(pSession),
101  m_comm(pSession->GetComm()),
102  m_hash(0),
103  m_numLocalBndCoeffs(0),
104  m_numGlobalBndCoeffs(0),
105  m_numLocalDirBndCoeffs(0),
106  m_numGlobalDirBndCoeffs(0),
107  m_bndSystemBandWidth(0),
108  m_successiveRHS(0),
109  m_linSysIterSolver("ConjugateGradient"),
110  m_gsh(0),
111  m_bndGsh(0)
112  {
113  // Default value from Solver Info
114  m_solnType = pSession->GetSolverInfoAsEnum<GlobalSysSolnType>(
115  "GlobalSysSoln");
116  m_preconType = pSession->GetSolverInfoAsEnum<PreconditionerType>(
117  "Preconditioner");
118 
119  // Override values with data from GlobalSysSolnInfo section
120  if(pSession->DefinesGlobalSysSolnInfo(variable, "GlobalSysSoln"))
121  {
122  std::string sysSoln = pSession->GetGlobalSysSolnInfo(variable,
123  "GlobalSysSoln");
124  m_solnType = pSession->GetValueAsEnum<GlobalSysSolnType>(
125  "GlobalSysSoln", sysSoln);
126  }
127 
128  if(pSession->DefinesGlobalSysSolnInfo(variable, "Preconditioner"))
129  {
130  std::string precon = pSession->GetGlobalSysSolnInfo(variable,
131  "Preconditioner");
132  m_preconType = pSession->GetValueAsEnum<PreconditionerType>(
133  "Preconditioner", precon);
134  }
135 
136  if(pSession->DefinesGlobalSysSolnInfo(variable,
137  "IterativeSolverTolerance"))
138  {
139  m_iterativeTolerance = boost::lexical_cast<NekDouble>(
140  pSession->GetGlobalSysSolnInfo(variable,
141  "IterativeSolverTolerance").c_str());
142  }
143  else
144  {
145  pSession->LoadParameter("IterativeSolverTolerance",
148  }
149 
150 
151  if(pSession->DefinesGlobalSysSolnInfo(variable,
152  "MaxIterations"))
153  {
154  m_maxIterations = boost::lexical_cast<int>(
155  pSession->GetGlobalSysSolnInfo(variable,
156  "MaxIterations").c_str());
157  }
158  else
159  {
160  pSession->LoadParameter("MaxIterations",
162  5000);
163  }
164 
165 
166  if(pSession->DefinesGlobalSysSolnInfo(variable,"SuccessiveRHS"))
167  {
168  m_successiveRHS = boost::lexical_cast<int>(
169  pSession->GetGlobalSysSolnInfo(variable,
170  "SuccessiveRHS").c_str());
171  }
172  else
173  {
174  pSession->LoadParameter("SuccessiveRHS",
175  m_successiveRHS,0);
176  }
177 
178  if (pSession->DefinesGlobalSysSolnInfo(variable, "LinSysIterSolver"))
179  {
180  m_linSysIterSolver = pSession->GetGlobalSysSolnInfo(
181  variable,"LinSysIterSolver");
182  }
183  else if (pSession->DefinesSolverInfo("LinSysIterSolver"))
184  {
185  m_linSysIterSolver = pSession->GetSolverInfo("LinSysIterSolver");
186  }
187  else
188  {
189  m_linSysIterSolver = "ConjugateGradient";
190  }
191  }
192 
193  /**
194  * Create a new level of mapping using the information in
195  * multiLevelGraph and performing the following steps:
196  */
198  AssemblyMap* oldLevelMap,
199  const BottomUpSubStructuredGraphSharedPtr& multiLevelGraph):
200  m_session(oldLevelMap->m_session),
201  m_comm(oldLevelMap->GetComm()),
202  m_hash(0),
203  m_solnType(oldLevelMap->m_solnType),
204  m_preconType(oldLevelMap->m_preconType),
205  m_maxIterations(oldLevelMap->m_maxIterations),
206  m_iterativeTolerance(oldLevelMap->m_iterativeTolerance),
207  m_successiveRHS(oldLevelMap->m_successiveRHS),
208  m_linSysIterSolver(oldLevelMap->m_linSysIterSolver),
209  m_gsh(oldLevelMap->m_gsh),
210  m_bndGsh(oldLevelMap->m_bndGsh),
211  m_lowestStaticCondLevel(oldLevelMap->m_lowestStaticCondLevel)
212  {
213  int i;
214  int j;
215  int cnt;
216 
217  //--------------------------------------------------------------
218  // -- Extract information from the input argument
219  int numGlobalBndCoeffsOld = oldLevelMap->GetNumGlobalBndCoeffs();
220  int numGlobalDirBndCoeffsOld = oldLevelMap->GetNumGlobalDirBndCoeffs();
221  int numLocalBndCoeffsOld = oldLevelMap->GetNumLocalBndCoeffs();
222  int numLocalDirBndCoeffsOld = oldLevelMap->GetNumLocalDirBndCoeffs();
223  bool signChangeOld = oldLevelMap->GetSignChange();
224 
225  int staticCondLevelOld = oldLevelMap->GetStaticCondLevel();
226  int numPatchesOld = oldLevelMap->GetNumPatches();
227  GlobalSysSolnType solnTypeOld = oldLevelMap->GetGlobalSysSolnType();
228  const Array<OneD, const unsigned int>& numLocalBndCoeffsPerPatchOld = oldLevelMap->GetNumLocalBndCoeffsPerPatch();
229  //--------------------------------------------------------------
230 
231  //--------------------------------------------------------------
232  int newLevel = staticCondLevelOld+1;
233  /** - STEP 1: setup a mask array to determine to which patch
234  * of the new level every patch of the current
235  * level belongs. To do so we make four arrays,
236  * #gloPatchMask, #globHomPatchMask,
237  * #locPatchMask_NekDouble and #locPatchMask.
238  * These arrays are then used to check which local
239  * dofs of the old level belong to which patch of
240  * the new level
241  */
242  Array<OneD, NekDouble> globPatchMask (numGlobalBndCoeffsOld,-1.0);
243  Array<OneD, NekDouble> globHomPatchMask (globPatchMask+numGlobalDirBndCoeffsOld);
244  Array<OneD, NekDouble> locPatchMask_NekDouble(numLocalBndCoeffsOld,-3.0);
245  Array<OneD, int> locPatchMask (numLocalBndCoeffsOld);
246 
247  // Fill the array globPatchMask as follows:
248  // - The first part (i.e. the glob bnd dofs) is filled with the
249  // value -1
250  // - The second part (i.e. the glob interior dofs) is numbered
251  // according to the patch it belongs to (i.e. dofs in first block
252  // all are numbered 0, the second block numbered are 1, etc...)
253  multiLevelGraph->MaskPatches(newLevel,globHomPatchMask);
254 
255  // Map from Global Dofs to Local Dofs
256  // As a result, we know for each local dof whether
257  // it is mapped to the boundary of the next level, or to which
258  // patch. Based upon this, we can than later associate every patch
259  // of the current level with a patch in the next level.
260  oldLevelMap->GlobalToLocalBndWithoutSign(globPatchMask,
261  locPatchMask_NekDouble);
262 
263  // Convert the result to an array of integers rather than doubles
264  RoundNekDoubleToInt(locPatchMask_NekDouble,locPatchMask);
265 
266  /** - STEP 2: We calculate how many local bnd dofs of the
267  * old level belong to the boundaries of each patch at
268  * the new level. We need this information to set up the
269  * mapping between different levels.
270  */
271 
272  // Retrieve the number of patches at the next level
273  int numPatchesWithIntNew = multiLevelGraph->GetNpatchesWithInterior(newLevel);
274  int numPatchesNew = numPatchesWithIntNew;
275 
276  // Allocate memory to store the number of local dofs associated to
277  // each of elemental boundaries of these patches
278  std::map<int, int> numLocalBndCoeffsPerPatchNew;
279  for(int i = 0; i < numPatchesNew; i++)
280  {
281  numLocalBndCoeffsPerPatchNew[i] = 0;
282  }
283 
284  int minval;
285  int maxval;
286  int curPatch;
287  for(i = cnt = 0; i < numPatchesOld; i++)
288  {
289  // For every patch at the current level, the mask array
290  // locPatchMask should be filled with
291  // - the same (positive) number for each entry (which will
292  // correspond to the patch at the next level it belongs to)
293  // - the same (positive) number for each entry, except some
294  // entries that are -1 (the enties correspond to -1, will be
295  // mapped to the local boundary of the next level patch given
296  // by the positive number)
297  // - -1 for all entries. In this case, we will make an
298  // additional patch only consisting of boundaries at the next
299  // level
300  minval = *min_element(&locPatchMask[cnt],
301  &locPatchMask[cnt]+numLocalBndCoeffsPerPatchOld[i]);
302  maxval = *max_element(&locPatchMask[cnt],
303  &locPatchMask[cnt]+numLocalBndCoeffsPerPatchOld[i]);
304  ASSERTL0((minval==maxval)||(minval==-1),"These values should never be the same");
305 
306  if(maxval == -1)
307  {
308  curPatch = numPatchesNew;
309  numLocalBndCoeffsPerPatchNew[curPatch] = 0;
310  numPatchesNew++;
311  }
312  else
313  {
314  curPatch = maxval;
315  }
316 
317  for(j = 0; j < numLocalBndCoeffsPerPatchOld[i]; j++ )
318  {
319  ASSERTL0((locPatchMask[cnt]==maxval)||(locPatchMask[cnt]==minval),
320  "These values should never be the same");
321  if(locPatchMask[cnt] == -1)
322  {
323  ++numLocalBndCoeffsPerPatchNew[curPatch];
324  }
325  cnt++;
326  }
327  }
328 
329  // Count how many local dofs of the old level are mapped
330  // to the local boundary dofs of the new level
331  m_numLocalCoeffs = 0;
333  m_numPatches = numLocalBndCoeffsPerPatchNew.size();
336  multiLevelGraph->GetNintDofsPerPatch(newLevel,m_numLocalIntCoeffsPerPatch);
337 
338  for(int i = 0; i < m_numPatches; i++)
339  {
340  m_numLocalBndCoeffsPerPatch[i] = (unsigned int) numLocalBndCoeffsPerPatchNew[i];
344  }
345 
346  // Also initialise some more data members
347  m_solnType = solnTypeOld;
352  "This method should only be called for in "
353  "case of multi-level static condensation.");
354  m_staticCondLevel = newLevel;
355  m_signChange = signChangeOld;
356  m_numLocalDirBndCoeffs = numLocalDirBndCoeffsOld;
357  m_numGlobalDirBndCoeffs = numGlobalDirBndCoeffsOld;
358  m_numGlobalBndCoeffs = multiLevelGraph->GetInteriorOffset(newLevel) +
360  m_numGlobalCoeffs = multiLevelGraph->GetNumGlobalDofs(newLevel) +
363 
366 
367  //local to bnd map is just a copy
368  for(int i = 0; i < m_numLocalBndCoeffs; ++i)
369  {
370  m_localToLocalBndMap[i] = i;
371  }
372 
373  // local to int map is just a copy plus offset
374  for(int i = m_numLocalBndCoeffs; i < m_numLocalCoeffs; ++i)
375  {
377  }
378 
379  if(m_signChange)
380  {
382  }
383 
385 
390 
391  // Set up an offset array that denotes the offset of the local
392  // boundary degrees of freedom of the next level
393  Array<OneD, int> numLocalBndCoeffsPerPatchOffset(m_numPatches+1,0);
394  for(int i = 1; i < m_numPatches+1; i++)
395  {
396  numLocalBndCoeffsPerPatchOffset[i] +=
397  numLocalBndCoeffsPerPatchOffset[i-1] +
398  numLocalBndCoeffsPerPatchNew[i-1];
399  }
400 
401  int additionalPatchCnt = numPatchesWithIntNew;
402  int newid;
403  int blockid;
404  bool isBndDof;
405  NekDouble sign;
406  Array<OneD, int> bndDofPerPatchCnt(m_numPatches,0);
407 
408  for(i = cnt = 0; i < numPatchesOld; i++)
409  {
410  minval = *min_element(&locPatchMask[cnt],
411  &locPatchMask[cnt]+numLocalBndCoeffsPerPatchOld[i]);
412  maxval = *max_element(&locPatchMask[cnt],
413  &locPatchMask[cnt]+numLocalBndCoeffsPerPatchOld[i]);
414  ASSERTL0((minval==maxval)||(minval==-1),
415  "These values should never be the same");
416 
417  if(maxval == -1)
418  {
419  curPatch = additionalPatchCnt;
420  additionalPatchCnt++;
421  }
422  else
423  {
424  curPatch = maxval;
425  }
426 
427  for(j = 0; j < numLocalBndCoeffsPerPatchOld[i]; j++ )
428  {
429  ASSERTL0((locPatchMask[cnt]==maxval)||
430  (locPatchMask[cnt]==minval),
431  "These values should never be the same");
432 
433  sign = oldLevelMap->GetLocalToGlobalBndSign(cnt);
434 
435  if(locPatchMask[cnt] == -1)
436  {
437  newid = numLocalBndCoeffsPerPatchOffset[curPatch];
438 
439  m_localToGlobalBndMap[newid] = oldLevelMap->
441 
442  if(m_signChange)
443  {
444  m_localToGlobalBndSign[ newid ] = sign;
445  }
446 
447  blockid = bndDofPerPatchCnt[curPatch];
448  isBndDof = true;
449 
450  numLocalBndCoeffsPerPatchOffset[curPatch]++;
451  bndDofPerPatchCnt[curPatch]++;
452  }
453  else
454  {
455  newid = oldLevelMap->GetLocalToGlobalBndMap(cnt) -
457 
458  blockid = oldLevelMap->GetLocalToGlobalBndMap(cnt)-
460  multiLevelGraph->GetInteriorOffset(newLevel,curPatch);
461  isBndDof = false;
462  }
463 
464  sign = isBndDof?1.0:sign;
465 
466  m_patchMapFromPrevLevel->SetPatchMap(cnt,curPatch,blockid,isBndDof,sign);
467  cnt++;
468  }
469  }
470 
471 
472  // set up local to local mapping from previous to new level
475 
476 
478 
479  // Postprocess the computed information - Update the old
480  // level with the mapping to new level
481  // oldLevelMap->SetLocalBndToNextLevelMap(oldLocalBndToNewLevelMap,oldLocalBndToNewLevelSign);
482 
483  // - Construct the next level mapping object
484  if(m_staticCondLevel < (multiLevelGraph->GetNlevels()-1))
485  {
487  }
488 
489  }
490 
492  {
493  }
494 
495 
496  /**
497  * The bandwidth calculated corresponds to what is referred to as
498  * half-bandwidth. If the elements of the matrix are designated as
499  * a_ij, it corresponds to the maximum value of |i-j| for non-zero
500  * a_ij. As a result, the value also corresponds to the number of
501  * sub- or super-diagonals.
502  *
503  * The bandwith can be calculated elementally as it corresponds to the
504  * maximal elemental bandwith (i.e. the maximal difference in global
505  * DOF index for every element).
506  *
507  * We here calculate the bandwith of the global boundary system (as
508  * used for static condensation).
509  */
511  {
512  int i,j;
513  int cnt = 0;
514  int locSize;
515  int maxId;
516  int minId;
517  int bwidth = -1;
518  for(i = 0; i < m_numPatches; ++i)
519  {
520  locSize = m_numLocalBndCoeffsPerPatch[i];
521  maxId = -1;
522  minId = m_numLocalBndCoeffs+1;
523  for(j = 0; j < locSize; j++)
524  {
526  {
527  if(m_localToGlobalBndMap[cnt+j] > maxId)
528  {
529  maxId = m_localToGlobalBndMap[cnt+j];
530  }
531 
532  if(m_localToGlobalBndMap[cnt+j] < minId)
533  {
534  minId = m_localToGlobalBndMap[cnt+j];
535  }
536  }
537  }
538  bwidth = (bwidth>(maxId-minId))?bwidth:(maxId-minId);
539 
540  cnt+=locSize;
541  }
542 
543  m_bndSystemBandWidth = bwidth;
544  }
545 
546 
547  int AssemblyMap::v_GetLocalToGlobalMap(const int i) const
548  {
549  boost::ignore_unused(i);
551  "Not defined for this type of mapping.");
552  return 0;
553  }
554 
556  {
557  boost::ignore_unused(i);
559  "Not defined for this type of mapping.");
560  return 0;
561  }
562 
564  {
565  boost::ignore_unused(i);
567  "Not defined for this type of mapping.");
568  return 0;
569  }
570 
572  {
574  "Not defined for this type of mapping.");
575  static Array<OneD,const int> result;
576  return result;
577  }
578 
580  {
582  "Not defined for this type of mapping.");
583  static Array<OneD, const int> result;
584  return result;
585  }
586 
588  {
590  "Not defined for this type of mapping.");
591  static Array<OneD, const int> result;
592  return result;
593  }
594 
596  {
597  boost::ignore_unused(i);
599  "Not defined for this type of mapping.");
600  return 0.0;
601  }
602 
604  {
606  "Not defined for this type of mapping.");
607  static Array<OneD, NekDouble> result;
608  return result;
609  }
610 
613  Array<OneD, NekDouble>& global,
614  bool useComm) const
615  {
616  boost::ignore_unused(loc, global, useComm);
618  "Not defined for this type of mapping.");
619  }
620 
622  const NekVector<NekDouble>& loc,
623  NekVector< NekDouble>& global,
624  bool useComm) const
625  {
626  boost::ignore_unused(loc, global, useComm);
628  "Not defined for this type of mapping.");
629  }
630 
631 
633  const Array<OneD, const NekDouble>& global,
635  {
636  boost::ignore_unused(loc, global);
638  "Not defined for this type of mapping.");
639  }
640 
642  const NekVector<NekDouble>& global,
643  NekVector< NekDouble>& loc) const
644  {
645  boost::ignore_unused(loc, global);
647  "Not defined for this type of mapping.");
648  }
649 
652  Array<OneD, NekDouble> &global) const
653  {
654  boost::ignore_unused(loc, global);
656  "Not defined for this type of mapping.");
657  }
658 
660  const NekVector<NekDouble>& loc,
661  NekVector< NekDouble>& global) const
662  {
663  boost::ignore_unused(loc, global);
665  "Not defined for this type of mapping.");
666  }
667 
669  Array<OneD, NekDouble>& pGlobal) const
670  {
671  boost::ignore_unused(pGlobal);
672  // Do nothing here since multi-level static condensation uses a
673  // AssemblyMap and thus will call this routine in serial.
674  }
675 
677  NekVector< NekDouble>& pGlobal) const
678  {
679  boost::ignore_unused(pGlobal);
680  // Do nothing here since multi-level static condensation uses a
681  // AssemblyMap and thus will call this routine in serial.
682  }
683 
685  Array<OneD, NekDouble>& pGlobal,
686  int offset) const
687  {
688  boost::ignore_unused(pGlobal, offset);
689  // Do nothing here since multi-level static condensation uses a
690  // AssemblyMap and thus will call this routine in serial.
691  }
692 
694  {
696  "Not defined for this type of mapping.");
697  return 0;
698  }
699 
701  {
703  "Not defined for this type of mapping.");
704  return 0;
705  }
706 
708  {
710  "Not defined for this type of mapping.");
711  return 0;
712  }
713 
715  {
717  "Not defined for this type of mapping.");
718  return 0;
719  }
720 
722  {
724  "Not defined for this type of mapping.");
725  return 0;
726  }
727 
729  {
731  "Not defined for this type of mapping.");
732  return 0;
733  }
734 
736  {
738  "Not defined for this type of mapping.");
739  return 0;
740  }
741 
743  {
745  "Not defined for this type of mapping.");
746  return 0;
747  }
748 
750  {
752  "Not defined for this type of mapping.");
753  static Array<OneD, const int> result;
754  return result;
755  }
756 
757  std::shared_ptr<AssemblyMap> AssemblyMap::v_LinearSpaceMap(
758  const ExpList &locexp, GlobalSysSolnType solnType)
759  {
760  boost::ignore_unused(locexp, solnType);
762  "Not defined for this type of mapping.");
763  static std::shared_ptr<AssemblyMap> result;
764  return result;
765  }
766 
768  {
769  return m_comm;
770  }
771 
772  size_t AssemblyMap::GetHash() const
773  {
774  return m_hash;
775  }
776 
777  int AssemblyMap::GetLocalToGlobalMap(const int i) const
778  {
779  return v_GetLocalToGlobalMap(i);
780  }
781 
783  {
784  return v_GetGlobalToUniversalMap(i);
785  }
786 
788  {
790  }
791 
793  {
794  return v_GetLocalToGlobalMap();
795  }
796 
798  {
799  return v_GetGlobalToUniversalMap();
800  }
801 
803  {
805  }
806 
808  {
809  return v_GetLocalToGlobalSign(i);
810  }
811 
813  {
814  return v_GetLocalToGlobalSign();
815  }
816 
817 
820  Array<OneD, NekDouble>& global,
821  bool useComm) const
822  {
823  v_LocalToGlobal(loc,global,useComm);
824  }
825 
827  const NekVector<NekDouble>& loc,
828  NekVector< NekDouble>& global,
829  bool useComm) const
830  {
831  v_LocalToGlobal(loc,global,useComm);
832  }
833 
835  const Array<OneD, const NekDouble>& global,
837  {
838  v_GlobalToLocal(global,loc);
839  }
840 
842  const NekVector<NekDouble>& global,
843  NekVector< NekDouble>& loc) const
844  {
845  v_GlobalToLocal(global,loc);
846  }
847 
850  Array<OneD, NekDouble> &global) const
851  {
852  v_Assemble(loc,global);
853  }
854 
856  const NekVector<NekDouble>& loc,
857  NekVector< NekDouble>& global) const
858  {
859  v_Assemble(loc,global);
860  }
861 
863  Array<OneD, NekDouble>& pGlobal) const
864  {
865  v_UniversalAssemble(pGlobal);
866  }
867 
869  NekVector< NekDouble>& pGlobal) const
870  {
871  v_UniversalAssemble(pGlobal);
872  }
873 
875  Array<OneD, NekDouble>& pGlobal,
876  int offset) const
877  {
878  v_UniversalAssemble(pGlobal, offset);
879  }
880 
883  Array<OneD, NekDouble>& global) const
884  {
886 
887  Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
889 
890  if(global.data() == loc.data())
891  {
892  local = Array<OneD, NekDouble>(map.size(),loc.data());
893  }
894  else
895  {
896  local = loc; // create reference
897  }
898 
899 
900  Vmath::Scatr(map.size(), sign.get(),
901  local.get(), map.get(), global.get());
902  }
903 
904 
906  const Array<OneD, const NekDouble>& global,
908  {
910 
911  Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
913 
914  if(global.data() == loc.data())
915  {
916  glo = Array<OneD, NekDouble>(global.size(),global.data());
917  }
918  else
919  {
920  glo = global; // create reference
921  }
922 
923  Vmath::Gathr(map.size(),sign.get(),glo.get(),map.get(),loc.get());
924  }
925 
928  Array<OneD, NekDouble> &global) const
929  {
931  Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
933 
934  if(global.data() == loc.data())
935  {
936  local = Array<OneD, NekDouble>(map.size(),loc.data());
937  }
938  else
939  {
940  local = loc; // create reference
941  }
942 
943  // since we are calling mapping from level down from array
944  // the m_numLocaBndCoeffs represents the size of the
945  // boundary elements we need to assemble into
946  Vmath::Zero(m_numLocalCoeffs,global.get(), 1);
947 
948  Vmath::Assmb(map.size(), sign.get(), local.get(),
949  map.get(), global.get());
950  }
951 
953  {
954  return v_GetFullSystemBandWidth();
955  }
956 
958  {
959  return v_GetNumNonDirVertexModes();
960  }
961 
963  {
964  return v_GetNumNonDirEdgeModes();
965  }
966 
968  {
969  return v_GetNumNonDirFaceModes();
970  }
971 
973  {
974  return v_GetNumDirEdges();
975  }
976 
978  {
979  return v_GetNumDirFaces();
980  }
981 
983  {
984  return v_GetNumNonDirEdges();
985  }
986 
988  {
989  return v_GetNumNonDirFaces();
990  }
991 
993  {
994  return v_GetExtraDirEdges();
995  }
996 
997  std::shared_ptr<AssemblyMap> AssemblyMap::LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType)
998  {
999  return v_LinearSpaceMap(locexp, solnType);
1000  }
1001 
1003  {
1004  return m_localToGlobalBndMap[i];
1005  }
1006 
1007  const Array<OneD,const int>&
1009  {
1010  return m_localToGlobalBndMap;
1011  }
1012 
1014  {
1015  return m_signChange;
1016  }
1017 
1018 
1021  {
1022  return m_localToGlobalBndSign;
1023  }
1024 
1026  {
1028  }
1029 
1031  {
1033  }
1034 
1036  {
1037  if(m_signChange)
1038  {
1039  return m_localToGlobalBndSign[i];
1040  }
1041  else
1042  {
1043  return 1.0;
1044  }
1045  }
1046 
1047 
1048  const Array<OneD,const int>&
1050  {
1052  }
1053 
1055  {
1057  }
1058 
1059  const Array<OneD,const int>&
1061  {
1063  }
1064 
1065 
1067  const int i)
1068  {
1070  "Index out of range.");
1071  return m_bndCondIDToGlobalTraceID[i];
1072  }
1073 
1075  {
1077  }
1078 
1079 
1081  {
1082  return m_numGlobalDirBndCoeffs;
1083  }
1084 
1085 
1087  {
1088  return m_numLocalDirBndCoeffs;
1089  }
1090 
1092  {
1093  return m_numLocalBndCoeffs;
1094  }
1095 
1097  {
1098  return m_numGlobalBndCoeffs;
1099  }
1100 
1102  {
1103  return m_numLocalCoeffs;
1104  }
1105 
1107  {
1108  return m_numGlobalCoeffs;
1109  }
1110 
1112  {
1113  return m_systemSingular;
1114  }
1115 
1117  const NekVector<NekDouble>& global,
1119  int offset) const
1120  {
1121  GlobalToLocalBnd(global.GetPtr(), loc.GetPtr(), offset);
1122  }
1123 
1124 
1126  const NekVector<NekDouble>& global,
1127  NekVector<NekDouble>& loc) const
1128  {
1129  GlobalToLocalBnd(global.GetPtr(), loc.GetPtr());
1130  }
1131 
1132 
1134  const Array<OneD, const NekDouble>& global,
1135  Array<OneD,NekDouble>& loc, int offset) const
1136  {
1137  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local vector is not of correct dimension");
1138  ASSERTL1(global.size() >= m_numGlobalBndCoeffs-offset,"Global vector is not of correct dimension");
1139 
1140  // offset input data by length "offset" for Dirichlet boundary conditions.
1142  Vmath::Vcopy(m_numGlobalBndCoeffs-offset, global.get(), 1, tmp.get() + offset, 1);
1143 
1144  if(m_signChange)
1145  {
1147  }
1148  else
1149  {
1150  Vmath::Gathr(m_numLocalBndCoeffs, tmp.get(), m_localToGlobalBndMap.get(), loc.get());
1151  }
1152  }
1153 
1154 
1156  const Array<OneD, const NekDouble>& global,
1157  Array<OneD,NekDouble>& loc) const
1158  {
1159  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local vector is not of correct dimension");
1160  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,"Global vector is not of correct dimension");
1161 
1162  if(m_signChange)
1163  {
1165  }
1166  else
1167  {
1168  Vmath::Gathr(m_numLocalBndCoeffs, global.get(), m_localToGlobalBndMap.get(), loc.get());
1169  }
1170  }
1171 
1174  Array<OneD,NekDouble>& global,
1175  int offset, bool UseComm) const
1176  {
1177  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local vector is not of correct dimension");
1178  ASSERTL1(global.size() >= m_numGlobalBndCoeffs-offset,"Global vector is not of correct dimension");
1179 
1180  // offset input data by length "offset" for Dirichlet boundary conditions.
1182 
1183  if(m_signChange)
1184  {
1186  }
1187  else
1188  {
1189  Vmath::Scatr(m_numLocalBndCoeffs, loc.get(), m_localToGlobalBndMap.get(), tmp.get());
1190  }
1191 
1192  // Ensure each processor has unique value with a max gather.
1193  if(UseComm)
1194  {
1196  }
1197  Vmath::Vcopy(m_numGlobalBndCoeffs-offset, tmp.get()+offset, 1, global.get(), 1);
1198  }
1199 
1202  Array<OneD,NekDouble>& global, bool UseComm) const
1203  {
1204  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local vector is not of correct dimension");
1205  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,"Global vector is not of correct dimension");
1206 
1207  if(m_signChange)
1208  {
1210  }
1211  else
1212  {
1213  Vmath::Scatr(m_numLocalBndCoeffs, loc.get(), m_localToGlobalBndMap.get(), global.get());
1214  }
1215  if(UseComm)
1216  {
1217  Gs::Gather(global, Gs::gs_max, m_bndGsh);
1218  }
1219  }
1220 
1221 
1223  const Array<OneD, const NekDouble>& local,
1224  Array<OneD,NekDouble>& locbnd) const
1225  {
1226  ASSERTL1(locbnd.size() >= m_numLocalBndCoeffs,"LocBnd vector is not of correct dimension");
1227  ASSERTL1(local.size() >= m_numLocalCoeffs,"Local vector is not of correct dimension");
1228 
1229  Vmath::Gathr(m_numLocalBndCoeffs, local.get(), m_localToLocalBndMap.get(), locbnd.get());
1230  }
1231 
1233  const Array<OneD, const NekDouble>& local,
1234  Array<OneD,NekDouble>& locint) const
1235  {
1236  ASSERTL1(locint.size() >= m_numLocalCoeffs-m_numLocalBndCoeffs,"Locint vector is not of correct dimension");
1237  ASSERTL1(local.size() >= m_numLocalCoeffs,"Local vector is not of correct dimension");
1238 
1239  Vmath::Gathr(m_numLocalCoeffs-m_numLocalBndCoeffs, local.get(), m_localToLocalIntMap.get(), locint.get());
1240  }
1241 
1242 
1244  const Array<OneD, const NekDouble>& locbnd,
1245  Array<OneD,NekDouble>& local) const
1246  {
1247  ASSERTL1(locbnd.size() >= m_numLocalBndCoeffs,"LocBnd vector is not of correct dimension");
1248  ASSERTL1(local.size() >= m_numLocalCoeffs,"Local vector is not of correct dimension");
1249 
1250  Vmath::Scatr(m_numLocalBndCoeffs, locbnd.get(), m_localToLocalBndMap.get(), local.get());
1251  }
1252 
1254  const Array<OneD, const NekDouble>& locint,
1255  Array<OneD,NekDouble>& local) const
1256  {
1257  ASSERTL1(locint.size() >= m_numLocalCoeffs-m_numLocalBndCoeffs,"LocBnd vector is not of correct dimension");
1258  ASSERTL1(local.size() >= m_numLocalCoeffs,"Local vector is not of correct dimension");
1259 
1260  Vmath::Scatr(m_numLocalCoeffs-m_numLocalBndCoeffs, locint.get(), m_localToLocalIntMap.get(), local.get());
1261  }
1262 
1263 
1265  const NekVector<NekDouble>& loc,
1266  NekVector<NekDouble>& global, int offset) const
1267  {
1268  AssembleBnd(loc.GetPtr(), global.GetPtr(), offset);
1269  }
1270 
1271 
1273  const NekVector<NekDouble>& loc,
1274  NekVector<NekDouble>& global) const
1275  {
1276  AssembleBnd(loc.GetPtr(), global.GetPtr());
1277  }
1278 
1279 
1282  Array<OneD, NekDouble>& global, int offset) const
1283  {
1284  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local array is not of correct dimension");
1285  ASSERTL1(global.size() >= m_numGlobalBndCoeffs-offset,"Global array is not of correct dimension");
1287 
1288  if(m_signChange)
1289  {
1291  }
1292  else
1293  {
1294  Vmath::Assmb(m_numLocalBndCoeffs,loc.get(), m_localToGlobalBndMap.get(), tmp.get());
1295  }
1296  UniversalAssembleBnd(tmp);
1297  Vmath::Vcopy(m_numGlobalBndCoeffs-offset, tmp.get() + offset, 1, global.get(), 1);
1298  }
1299 
1300 
1303  Array<OneD, NekDouble>& global) const
1304  {
1305  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local vector is not of correct dimension");
1306  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,"Global vector is not of correct dimension");
1307 
1308  Vmath::Zero(m_numGlobalBndCoeffs, global.get(), 1);
1309 
1310  if(m_signChange)
1311  {
1313  loc.get(), m_localToGlobalBndMap.get(), global.get());
1314  }
1315  else
1316  {
1317  Vmath::Assmb(m_numLocalBndCoeffs,loc.get(), m_localToGlobalBndMap.get(), global.get());
1318  }
1319  UniversalAssembleBnd(global);
1320  }
1321 
1323  Array<OneD, NekDouble>& pGlobal) const
1324  {
1325  ASSERTL1(pGlobal.size() >= m_numGlobalBndCoeffs,
1326  "Wrong size.");
1327  Gs::Gather(pGlobal, Gs::gs_add, m_bndGsh);
1328  }
1329 
1331  NekVector< NekDouble>& pGlobal) const
1332  {
1333  UniversalAssembleBnd(pGlobal.GetPtr());
1334  }
1335 
1337  Array<OneD, NekDouble>& pGlobal,
1338  int offset) const
1339  {
1340  Array<OneD, NekDouble> tmp(offset);
1341  if (offset > 0) Vmath::Vcopy(offset, pGlobal, 1, tmp, 1);
1342  UniversalAssembleBnd(pGlobal);
1343  if (offset > 0) Vmath::Vcopy(offset, tmp, 1, pGlobal, 1);
1344  }
1345 
1347  {
1348  Gs::Gather(bndvals, Gs::gs_amax, m_dirBndGsh);
1349  }
1350 
1352  {
1353  return m_bndSystemBandWidth;
1354  }
1355 
1357  {
1358  return m_staticCondLevel;
1359  }
1360 
1362  {
1363  return m_numPatches;
1364  }
1365 
1368  {
1370  }
1371 
1372 
1375  {
1377  }
1378 
1379  const AssemblyMapSharedPtr
1381  {
1383  }
1384 
1385  const PatchMapSharedPtr&
1387  const
1388  {
1389  return m_patchMapFromPrevLevel;
1390  }
1391 
1393  {
1394  return !( m_nextLevelLocalToGlobalMap.get() );
1395  }
1396 
1397 
1399  {
1400  return m_solnType;
1401  }
1402 
1404  {
1405  return m_preconType;
1406  }
1407 
1409  {
1410  return m_iterativeTolerance;
1411  }
1412 
1414  {
1415  return m_maxIterations;
1416  }
1417 
1419  {
1420  return m_successiveRHS;
1421  }
1422 
1424  {
1425  return m_linSysIterSolver;
1426  }
1427 
1429  const Array<OneD, const NekDouble>& global,
1431  {
1432  ASSERTL1(loc.size() >= m_numLocalBndCoeffs,"Local vector is not of correct dimension");
1433  ASSERTL1(global.size() >= m_numGlobalBndCoeffs,"Global vector is not of correct dimension");
1434 
1435  Vmath::Gathr(m_numLocalBndCoeffs, global.get(), m_localToGlobalBndMap.get(), loc.get());
1436  }
1437 
1439  std::ostream &out, std::string variable, bool printHeader) const
1440  {
1442  = m_session->GetComm()->GetRowComm();
1443  bool isRoot = vRowComm->GetRank() == 0;
1444  int n = vRowComm->GetSize();
1445  int i;
1446 
1447  // Determine number of global degrees of freedom.
1448  int globBndCnt = 0, globDirCnt = 0;
1449 
1450  for (i = 0; i < m_numGlobalBndCoeffs; ++i)
1451  {
1453  {
1454  globBndCnt++;
1455 
1456  if (i < m_numGlobalDirBndCoeffs)
1457  {
1458  globDirCnt++;
1459  }
1460  }
1461  }
1462 
1463  int globCnt = m_numGlobalCoeffs - m_numGlobalBndCoeffs + globBndCnt;
1464 
1465  // Calculate maximum valency
1468 
1469  Vmath::Assmb(
1470  m_numLocalBndCoeffs, tmpLoc.get(),
1471  m_localToGlobalBndMap.get(), tmpGlob.get());
1472  UniversalAssembleBnd(tmpGlob);
1473 
1474  int totGlobDof = globCnt;
1475  int totGlobBndDof = globBndCnt;
1476  int totGlobDirDof = globDirCnt;
1477  int totLocalDof = m_numLocalCoeffs;
1478  int totLocalBndDof = m_numLocalBndCoeffs;
1479  int totLocalDirDof = m_numLocalDirBndCoeffs;
1480 
1481  int meanValence = 0;
1482  int maxValence = 0;
1483  int minValence = 10000000;
1484  for (int i = 0; i < m_numGlobalBndCoeffs; ++i)
1485  {
1487  {
1488  continue;
1489  }
1490 
1491  if (tmpGlob[i] > maxValence)
1492  {
1493  maxValence = tmpGlob[i];
1494  }
1495  if (tmpGlob[i] < minValence)
1496  {
1497  minValence = tmpGlob[i];
1498  }
1499  meanValence += tmpGlob[i];
1500  }
1501 
1502  vRowComm->AllReduce(maxValence, LibUtilities::ReduceMax);
1503  vRowComm->AllReduce(minValence, LibUtilities::ReduceMin);
1504  vRowComm->AllReduce(meanValence, LibUtilities::ReduceSum);
1505  vRowComm->AllReduce(totGlobDof, LibUtilities::ReduceSum);
1506  vRowComm->AllReduce(totGlobBndDof, LibUtilities::ReduceSum);
1507  vRowComm->AllReduce(totGlobDirDof, LibUtilities::ReduceSum);
1508  vRowComm->AllReduce(totLocalDof, LibUtilities::ReduceSum);
1509  vRowComm->AllReduce(totLocalBndDof, LibUtilities::ReduceSum);
1510  vRowComm->AllReduce(totLocalDirDof, LibUtilities::ReduceSum);
1511 
1512  meanValence /= totGlobBndDof;
1513 
1514  if (isRoot)
1515  {
1516  if (printHeader)
1517  {
1518  out << "Assembly map statistics for field " << variable
1519  << ":" << endl;
1520  }
1521 
1522  out << " - Number of local/global dof : "
1523  << totLocalDof << " " << totGlobDof << endl;
1524  out << " - Number of local/global boundary dof : "
1525  << totLocalBndDof << " " << totGlobBndDof << endl;
1526  out << " - Number of local/global Dirichlet dof : "
1527  << totLocalDirDof << " " << totGlobDirDof << endl;
1528  out << " - dof valency (min/max/mean) : "
1529  << minValence << " " << maxValence << " " << meanValence
1530  << endl;
1531 
1532  if (n > 1)
1533  {
1534  NekDouble mean = m_numLocalCoeffs, mean2 = mean * mean;
1535  NekDouble minval = mean, maxval = mean;
1536  Array<OneD, NekDouble> tmp(1);
1537 
1538  for (i = 1; i < n; ++i)
1539  {
1540  vRowComm->Recv(i, tmp);
1541  mean += tmp[0];
1542  mean2 += tmp[0]*tmp[0];
1543 
1544  if (tmp[0] > maxval)
1545  {
1546  maxval = tmp[0];
1547  }
1548  if (tmp[0] < minval)
1549  {
1550  minval = tmp[0];
1551  }
1552  }
1553 
1554  if (maxval > 0.1)
1555  {
1556  out << " - Local dof dist. (min/max/mean/dev) : "
1557  << minval << " " << maxval << " " << (mean / n)
1558  << " " << sqrt(mean2/n - mean*mean/n/n) << endl;
1559  }
1560 
1561  vRowComm->Block();
1562 
1563  mean = minval = maxval = m_numLocalBndCoeffs;
1564  mean2 = mean * mean;
1565 
1566  for (i = 1; i < n; ++i)
1567  {
1568  vRowComm->Recv(i, tmp);
1569  mean += tmp[0];
1570  mean2 += tmp[0]*tmp[0];
1571 
1572  if (tmp[0] > maxval)
1573  {
1574  maxval = tmp[0];
1575  }
1576  if (tmp[0] < minval)
1577  {
1578  minval = tmp[0];
1579  }
1580  }
1581 
1582  out << " - Local bnd dof dist. (min/max/mean/dev) : "
1583  << minval << " " << maxval << " " << (mean / n) << " "
1584  << sqrt(mean2/n - mean*mean/n/n) << endl;
1585  }
1586  }
1587  else
1588  {
1589  Array<OneD, NekDouble> tmp(1);
1590  tmp[0] = m_numLocalCoeffs;
1591  vRowComm->Send(0, tmp);
1592  vRowComm->Block();
1593  tmp[0] = m_numLocalBndCoeffs;
1594  vRowComm->Send(0, tmp);
1595  }
1596 
1597  // Either we have no more levels in the static condensation, or we
1598  // are not multi-level.
1600  {
1601  return;
1602  }
1603 
1604  int level = 2;
1606  while (tmp->m_nextLevelLocalToGlobalMap)
1607  {
1608  tmp = tmp->m_nextLevelLocalToGlobalMap;
1609  ++level;
1610  }
1611 
1612  // Print out multi-level static condensation information.
1613  if (n > 1)
1614  {
1615  if (isRoot)
1616  {
1617  NekDouble mean = level, mean2 = mean * mean;
1618  int minval = level, maxval = level;
1619 
1620  Array<OneD, NekDouble> tmpRecv(1);
1621  for (i = 1; i < n; ++i)
1622  {
1623  vRowComm->Recv(i, tmpRecv);
1624  mean += tmpRecv[0];
1625  mean2 += tmpRecv[0]*tmpRecv[0];
1626 
1627  if (tmpRecv[0] > maxval)
1628  {
1629  maxval = (int)(tmpRecv[0] + 0.5);
1630  }
1631  if (tmpRecv[0] < minval)
1632  {
1633  minval = (int)(tmpRecv[0] + 0.5);
1634  }
1635  }
1636 
1637  out << " - M-level sc. dist. (min/max/mean/dev) : "
1638  << minval << " " << maxval << " " << (mean / n) << " "
1639  << sqrt(mean2/n - mean*mean/n/n) << endl;
1640  }
1641  else
1642  {
1643  Array<OneD, NekDouble> tmpSend(1);
1644  tmpSend[0] = level;
1645  vRowComm->Send(0, tmpSend);
1646  }
1647  }
1648  else
1649  {
1650  out << " - Number of static cond. levels : "
1651  << level << endl;
1652  }
1653 
1654  if (isRoot)
1655  {
1656  out << "Stats at lowest static cond. level:" << endl;
1657  }
1658  tmp->PrintStats(out, variable, false);
1659  }
1660  } // namespace
1661 } // namespace
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#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:250
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:15
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:59
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:395
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:400
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:357
const Array< OneD, const unsigned int > & GetNumLocalBndCoeffsPerPatch()
Returns the number of local boundary coefficients in each patch.
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
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 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
Array< OneD, int > m_bndCondCoeffsToLocalCoeffsMap
Integer map of bnd cond coeffs to local coefficients.
Definition: AssemblyMap.h:382
PatchMapSharedPtr m_patchMapFromPrevLevel
Mapping information for previous level in MultiLevel Solver.
Definition: AssemblyMap.h:445
int m_maxIterations
Maximum iterations for iterative solver.
Definition: AssemblyMap.h:403
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique()
NekDouble m_iterativeTolerance
Tolerance for iterative solver.
Definition: AssemblyMap.h:406
NekDouble GetIterativeTolerance() const
int m_numGlobalCoeffs
Total number of global coefficients.
Definition: AssemblyMap.h:368
std::string m_linSysIterSolver
Iterative solver: Conjugate Gradient, GMRES.
Definition: AssemblyMap.h:412
bool AtLastLevel() const
Returns true if this is the last level in the multi-level static condensation.
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
Definition: AssemblyMap.h:374
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()
void PatchAssemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
int m_successiveRHS
sucessive RHS for iterative solver
Definition: AssemblyMap.h:409
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
void UniversalAbsMaxBnd(Array< OneD, NekDouble > &bndvals)
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
Definition: AssemblyMap.h:425
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:329
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:338
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:432
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:421
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Definition: AssemblyMap.h:376
int m_bndSystemBandWidth
The bandwith of the global bnd system.
Definition: AssemblyMap.h:397
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
Definition: AssemblyMap.h:380
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:342
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:344
LibUtilities::CommSharedPtr GetComm()
Retrieves the communicator.
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Definition: AssemblyMap.h:427
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:346
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:417
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:80
Array< OneD, NekDouble > m_bndCondCoeffsToLocalCoeffsSign
Integer map of sign of bnd cond coeffs to local coefficients.
Definition: AssemblyMap.h:384
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:332
int GetNumGlobalBndCoeffs() const
Returns the total number of global boundary coefficients.
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
const Array< OneD, const int > & GetGlobalToUniversalBndMap()
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:423
void LocalToLocalInt(const Array< OneD, const NekDouble > &local, Array< OneD, NekDouble > &locint) const
Array< OneD, int > m_bndCondIDToGlobalTraceID
Integer map of bnd cond trace number to global trace number.
Definition: AssemblyMap.h:388
virtual int v_GetNumNonDirFaces() const
bool GetSignChange()
Returns true if using a modal expansion requiring a change of sign of some modes.
Array< OneD, int > m_bndCondCoeffsToLocalTraceMap
Integer map of bnd cond coeff to local trace coeff.
Definition: AssemblyMap.h:386
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:340
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:107
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_amax
Definition: GsLib.hpp:53
@ gs_add
Definition: GsLib.hpp:53
@ gs_max
Definition: GsLib.hpp:53
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:52
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:1
double NekDouble
void Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
Definition: Vmath.cpp:772
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:756
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:813
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:436
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267