Nektar++
Loading...
Searching...
No Matches
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/algorithm/string.hpp>
36
38
39using namespace std;
40
42{
43/**
44 * @class AssemblyMap
45 * This class acts as a base class for constructing mappings between
46 * local, global and boundary degrees of freedom. It holds the storage
47 * for the maps and provides the accessors needed to retrieve them.
48 *
49 * There are two derived classes: AssemblyMapCG and
50 * AssemblyMapDG. These perform the actual construction of the
51 * maps within their specific contexts.
52 *
53 */
54
55/// Rounds a double precision number to an integer.
57{
58 return int(x > 0.0 ? x + 0.5 : x - 0.5);
59}
60
61/// Rounds an array of double precision numbers to integers.
63 Array<OneD, int> outarray)
64{
65 int size = inarray.size();
66 ASSERTL1(outarray.size() >= size, "Array sizes not compatible");
67
68 NekDouble x;
69 for (int i = 0; i < size; i++)
70 {
71 x = inarray[i];
72 outarray[i] = int(x > 0.0 ? x + 0.5 : x - 0.5);
73 }
74}
75
76/**
77 * Initialises an empty mapping.
78 */
80 : m_session(), m_comm(), m_hash(0), m_numLocalBndCoeffs(0),
81 m_numGlobalBndCoeffs(0), m_numLocalDirBndCoeffs(0),
82 m_numGlobalDirBndCoeffs(0), m_solnType(eNoSolnType),
83 m_bndSystemBandWidth(0), m_successiveRHS(0),
84 m_linSysIterSolver("ConjugateGradient"), m_gsh(nullptr), m_bndGsh(nullptr)
85{
86}
87
90 const std::string variable)
91 : m_session(pSession), m_comm(comm), m_variable(variable), m_hash(0),
92 m_numLocalBndCoeffs(0), m_numGlobalBndCoeffs(0),
93 m_numLocalDirBndCoeffs(0), m_numGlobalDirBndCoeffs(0),
94 m_bndSystemBandWidth(0), m_successiveRHS(0),
95 m_linSysIterSolver("ConjugateGradient"), m_gsh(nullptr), m_bndGsh(nullptr)
96{
97 // Default value from Solver Info
99 pSession->GetSolverInfoAsEnum<GlobalSysSolnType>("GlobalSysSoln");
100
101 // Override values with data from GlobalSysSolnInfo section
102 if (pSession->DefinesGlobalSysSolnInfo(variable, "GlobalSysSoln"))
103 {
104 std::string sysSoln =
105 pSession->GetGlobalSysSolnInfo(variable, "GlobalSysSoln");
106 m_solnType = pSession->GetValueAsEnum<GlobalSysSolnType>(
107 "GlobalSysSoln", sysSoln);
108 }
109
110 // Set up preconditioner with SysSoln as override then solverinfo otherwise
111 // set a default as diagonal
112 if (pSession->DefinesGlobalSysSolnInfo(variable, "Preconditioner"))
113 {
115 pSession->GetGlobalSysSolnInfo(variable, "Preconditioner");
116 }
117 else if (pSession->DefinesSolverInfo("Preconditioner"))
118 {
119 m_preconType = pSession->GetSolverInfo("Preconditioner");
120 }
121 else
122 { // Possibly preconditioner is default registered in
123 // GlobLinSysIterative.cpp
124 m_preconType = "Diagonal";
125 }
126
127 if (pSession->DefinesGlobalSysSolnInfo(variable, "AbsoluteTolerance"))
128 {
129 std::string abstol =
130 pSession->GetGlobalSysSolnInfo(variable, "AbsoluteTolerance");
132 boost::iequals(boost::to_upper_copy(abstol), "TRUE");
133 }
134 else
135 {
136 m_isAbsoluteTolerance = false;
137 }
138
139 if (pSession->DefinesGlobalSysSolnInfo(variable, "SuccessiveRHS"))
140 {
141 m_successiveRHS = std::stoi(
142 pSession->GetGlobalSysSolnInfo(variable, "SuccessiveRHS").c_str());
143 }
144 else
145 {
146 pSession->LoadParameter("SuccessiveRHS", m_successiveRHS, 0);
147 }
148
149 if (pSession->DefinesGlobalSysSolnInfo(variable, "LinSysIterSolver"))
150 {
152 pSession->GetGlobalSysSolnInfo(variable, "LinSysIterSolver");
153 }
154 else if (pSession->DefinesSolverInfo("LinSysIterSolver"))
155 {
156 m_linSysIterSolver = pSession->GetSolverInfo("LinSysIterSolver");
157 }
158 else
159 {
160 m_linSysIterSolver = "ConjugateGradient";
161 }
162}
163
164/**
165 * Create a new level of mapping using the information in
166 * multiLevelGraph and performing the following steps:
167 */
169 AssemblyMap *oldLevelMap,
170 const BottomUpSubStructuredGraphSharedPtr &multiLevelGraph)
171 : m_session(oldLevelMap->m_session), m_comm(oldLevelMap->GetComm()),
172 m_hash(0), m_solnType(oldLevelMap->m_solnType),
173 m_preconType(oldLevelMap->m_preconType),
174 m_successiveRHS(oldLevelMap->m_successiveRHS),
175 m_linSysIterSolver(oldLevelMap->m_linSysIterSolver),
176 m_gsh(oldLevelMap->m_gsh), m_bndGsh(oldLevelMap->m_bndGsh),
177 m_lowestStaticCondLevel(oldLevelMap->m_lowestStaticCondLevel)
178{
179 int i;
180 int j;
181 int cnt;
182
183 //--------------------------------------------------------------
184 // -- Extract information from the input argument
185 int numGlobalBndCoeffsOld = oldLevelMap->GetNumGlobalBndCoeffs();
186 int numGlobalDirBndCoeffsOld = oldLevelMap->GetNumGlobalDirBndCoeffs();
187 int numLocalBndCoeffsOld = oldLevelMap->GetNumLocalBndCoeffs();
188 int numLocalDirBndCoeffsOld = oldLevelMap->GetNumLocalDirBndCoeffs();
189 bool signChangeOld = oldLevelMap->GetSignChange();
190
191 int staticCondLevelOld = oldLevelMap->GetStaticCondLevel();
192 int numPatchesOld = oldLevelMap->GetNumPatches();
193 GlobalSysSolnType solnTypeOld = oldLevelMap->GetGlobalSysSolnType();
194 const Array<OneD, const unsigned int> &numLocalBndCoeffsPerPatchOld =
195 oldLevelMap->GetNumLocalBndCoeffsPerPatch();
196 //--------------------------------------------------------------
197
198 //--------------------------------------------------------------
199 int newLevel = staticCondLevelOld + 1;
200 /** - STEP 1: setup a mask array to determine to which patch
201 * of the new level every patch of the current
202 * level belongs. To do so we make four arrays,
203 * #gloPatchMask, #globHomPatchMask,
204 * #locPatchMask_NekDouble and #locPatchMask.
205 * These arrays are then used to check which local
206 * dofs of the old level belong to which patch of
207 * the new level
208 */
209 Array<OneD, NekDouble> globPatchMask(numGlobalBndCoeffsOld, -1.0);
210 Array<OneD, NekDouble> globHomPatchMask(globPatchMask +
211 numGlobalDirBndCoeffsOld);
212 Array<OneD, NekDouble> locPatchMask_NekDouble(numLocalBndCoeffsOld, -3.0);
213 Array<OneD, int> locPatchMask(numLocalBndCoeffsOld);
214
215 // Fill the array globPatchMask as follows:
216 // - The first part (i.e. the glob bnd dofs) is filled with the
217 // value -1
218 // - The second part (i.e. the glob interior dofs) is numbered
219 // according to the patch it belongs to (i.e. dofs in first block
220 // all are numbered 0, the second block numbered are 1, etc...)
221 multiLevelGraph->MaskPatches(newLevel, globHomPatchMask);
222
223 // Map from Global Dofs to Local Dofs
224 // As a result, we know for each local dof whether
225 // it is mapped to the boundary of the next level, or to which
226 // patch. Based upon this, we can than later associate every patch
227 // of the current level with a patch in the next level.
228 oldLevelMap->GlobalToLocalBndWithoutSign(globPatchMask,
229 locPatchMask_NekDouble);
230
231 // Convert the result to an array of integers rather than doubles
232 RoundNekDoubleToInt(locPatchMask_NekDouble, locPatchMask);
233
234 /** - STEP 2: We calculate how many local bnd dofs of the
235 * old level belong to the boundaries of each patch at
236 * the new level. We need this information to set up the
237 * mapping between different levels.
238 */
239
240 // Retrieve the number of patches at the next level
241 int numPatchesWithIntNew =
242 multiLevelGraph->GetNpatchesWithInterior(newLevel);
243 int numPatchesNew = numPatchesWithIntNew;
244
245 // Allocate memory to store the number of local dofs associated to
246 // each of elemental boundaries of these patches
247 std::map<int, int> numLocalBndCoeffsPerPatchNew;
248 for (int i = 0; i < numPatchesNew; i++)
249 {
250 numLocalBndCoeffsPerPatchNew[i] = 0;
251 }
252
253 int minval;
254 int maxval;
255 int curPatch;
256 for (i = cnt = 0; i < numPatchesOld; i++)
257 {
258 // For every patch at the current level, the mask array
259 // locPatchMask should be filled with
260 // - the same (positive) number for each entry (which will
261 // correspond to the patch at the next level it belongs to)
262 // - the same (positive) number for each entry, except some
263 // entries that are -1 (the enties correspond to -1, will be
264 // mapped to the local boundary of the next level patch given
265 // by the positive number)
266 // - -1 for all entries. In this case, we will make an
267 // additional patch only consisting of boundaries at the next
268 // level
269 minval =
270 *min_element(&locPatchMask[cnt],
271 &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
272 maxval =
273 *max_element(&locPatchMask[cnt],
274 &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
275 ASSERTL0((minval == maxval) || (minval == -1),
276 "These values should never be the same");
277
278 if (maxval == -1)
279 {
280 curPatch = numPatchesNew;
281 numLocalBndCoeffsPerPatchNew[curPatch] = 0;
282 numPatchesNew++;
283 }
284 else
285 {
286 curPatch = maxval;
287 }
288
289 for (j = 0; j < numLocalBndCoeffsPerPatchOld[i]; j++)
290 {
291 ASSERTL0((locPatchMask[cnt] == maxval) ||
292 (locPatchMask[cnt] == minval),
293 "These values should never be the same");
294 if (locPatchMask[cnt] == -1)
295 {
296 ++numLocalBndCoeffsPerPatchNew[curPatch];
297 }
298 cnt++;
299 }
300 }
301
302 // Count how many local dofs of the old level are mapped
303 // to the local boundary dofs of the new level
306 m_numPatches = numLocalBndCoeffsPerPatchNew.size();
309 multiLevelGraph->GetNintDofsPerPatch(newLevel, m_numLocalIntCoeffsPerPatch);
310
311 for (int i = 0; i < m_numPatches; i++)
312 {
314 (unsigned int)numLocalBndCoeffsPerPatchNew[i];
318 }
319
320 // Also initialise some more data members
321 m_solnType = solnTypeOld;
326 "This method should only be called for in "
327 "case of multi-level static condensation.");
328 m_staticCondLevel = newLevel;
329 m_signChange = signChangeOld;
330 m_numLocalDirBndCoeffs = numLocalDirBndCoeffsOld;
331 m_numGlobalDirBndCoeffs = numGlobalDirBndCoeffsOld;
333 multiLevelGraph->GetInteriorOffset(newLevel) + m_numGlobalDirBndCoeffs;
335 multiLevelGraph->GetNumGlobalDofs(newLevel) + m_numGlobalDirBndCoeffs;
337
341
342 // local to bnd map is just a copy
343 for (int i = 0; i < m_numLocalBndCoeffs; ++i)
344 {
346 }
347
348 // local to int map is just a copy plus offset
349 for (int i = m_numLocalBndCoeffs; i < m_numLocalCoeffs; ++i)
350 {
352 }
353
354 if (m_signChange)
355 {
357 }
358
360 MemoryManager<PatchMap>::AllocateSharedPtr(numLocalBndCoeffsOld);
361
366
367 // Set up an offset array that denotes the offset of the local
368 // boundary degrees of freedom of the next level
369 Array<OneD, int> numLocalBndCoeffsPerPatchOffset(m_numPatches + 1, 0);
370 for (int i = 1; i < m_numPatches + 1; i++)
371 {
372 numLocalBndCoeffsPerPatchOffset[i] +=
373 numLocalBndCoeffsPerPatchOffset[i - 1] +
374 numLocalBndCoeffsPerPatchNew[i - 1];
375 }
376
377 int additionalPatchCnt = numPatchesWithIntNew;
378 int newid;
379 int blockid;
380 bool isBndDof;
382 Array<OneD, int> bndDofPerPatchCnt(m_numPatches, 0);
383
384 for (i = cnt = 0; i < numPatchesOld; i++)
385 {
386 minval =
387 *min_element(&locPatchMask[cnt],
388 &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
389 maxval =
390 *max_element(&locPatchMask[cnt],
391 &locPatchMask[cnt] + numLocalBndCoeffsPerPatchOld[i]);
392 ASSERTL0((minval == maxval) || (minval == -1),
393 "These values should never be the same");
394
395 if (maxval == -1)
396 {
397 curPatch = additionalPatchCnt;
398 additionalPatchCnt++;
399 }
400 else
401 {
402 curPatch = maxval;
403 }
404
405 for (j = 0; j < numLocalBndCoeffsPerPatchOld[i]; j++)
406 {
407 ASSERTL0((locPatchMask[cnt] == maxval) ||
408 (locPatchMask[cnt] == minval),
409 "These values should never be the same");
410
411 sign = oldLevelMap->GetLocalToGlobalBndSign(cnt);
412
413 if (locPatchMask[cnt] == -1)
414 {
415 newid = numLocalBndCoeffsPerPatchOffset[curPatch];
416
417 m_localToGlobalBndMap[newid] =
418 oldLevelMap->GetLocalToGlobalBndMap(cnt);
419
420 if (m_signChange)
421 {
423 }
424
425 blockid = bndDofPerPatchCnt[curPatch];
426 isBndDof = true;
427
428 numLocalBndCoeffsPerPatchOffset[curPatch]++;
429 bndDofPerPatchCnt[curPatch]++;
430 }
431 else
432 {
433 newid = oldLevelMap->GetLocalToGlobalBndMap(cnt) -
435
436 blockid =
437 oldLevelMap->GetLocalToGlobalBndMap(cnt) -
439 multiLevelGraph->GetInteriorOffset(newLevel, curPatch);
440 isBndDof = false;
441 }
442
443 sign = isBndDof ? 1.0 : sign;
444
445 m_patchMapFromPrevLevel->SetPatchMap(cnt, curPatch, blockid,
446 isBndDof, sign);
447 cnt++;
448 }
449 }
450
451 // set up local to local mapping from previous to new level
454
456
457 // Postprocess the computed information - Update the old
458 // level with the mapping to new level
459 // oldLevelMap->SetLocalBndToNextLevelMap(oldLocalBndToNewLevelMap,oldLocalBndToNewLevelSign);
460
461 // - Construct the next level mapping object
462 if (m_staticCondLevel < (multiLevelGraph->GetNlevels() - 1))
463 {
466 multiLevelGraph);
467 }
468}
469
473
474/**
475 * The bandwidth calculated corresponds to what is referred to as
476 * half-bandwidth. If the elements of the matrix are designated as
477 * a_ij, it corresponds to the maximum value of |i-j| for non-zero
478 * a_ij. As a result, the value also corresponds to the number of
479 * sub- or super-diagonals.
480 *
481 * The bandwith can be calculated elementally as it corresponds to the
482 * maximal elemental bandwith (i.e. the maximal difference in global
483 * DOF index for every element).
484 *
485 * We here calculate the bandwith of the global boundary system (as
486 * used for static condensation).
487 */
489{
490 int i, j;
491 int cnt = 0;
492 int locSize;
493 int maxId;
494 int minId;
495 int bwidth = -1;
496 for (i = 0; i < m_numPatches; ++i)
497 {
498 locSize = m_numLocalBndCoeffsPerPatch[i];
499 maxId = -1;
500 minId = m_numLocalBndCoeffs + 1;
501 for (j = 0; j < locSize; j++)
502 {
504 {
505 if (m_localToGlobalBndMap[cnt + j] > maxId)
506 {
507 maxId = m_localToGlobalBndMap[cnt + j];
508 }
509
510 if (m_localToGlobalBndMap[cnt + j] < minId)
511 {
512 minId = m_localToGlobalBndMap[cnt + j];
513 }
514 }
515 }
516 bwidth = (bwidth > (maxId - minId)) ? bwidth : (maxId - minId);
517
518 cnt += locSize;
519 }
520
521 m_bndSystemBandWidth = bwidth;
522}
523
524int AssemblyMap::v_GetLocalToGlobalMap([[maybe_unused]] const int i) const
525{
526 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
527 return 0;
528}
529
530int AssemblyMap::v_GetGlobalToUniversalMap([[maybe_unused]] const int i) const
531{
532 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
533 return 0;
534}
535
537 [[maybe_unused]] const int i) const
538{
539 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
540 return 0;
541}
542
544{
545 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
546 static Array<OneD, const int> result;
547 return result;
548}
549
551{
552 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
553 static Array<OneD, const int> result;
554 return result;
555}
556
558{
559 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
560 static Array<OneD, const int> result;
561 return result;
562}
563
565 [[maybe_unused]] const int i) const
566{
567 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
568 return 0.0;
569}
570
572{
573 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
574 static Array<OneD, NekDouble> result;
575 return result;
576}
577
579 [[maybe_unused]] const Array<OneD, const NekDouble> &loc,
580 [[maybe_unused]] Array<OneD, NekDouble> &global,
581 [[maybe_unused]] bool useComm) const
582{
583 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
584}
585
587 [[maybe_unused]] const Array<OneD, const NekDouble> &loc,
588 [[maybe_unused]] Array<OneD, NekDouble> &global,
589 [[maybe_unused]] bool useComm) const
590{
591 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
592}
593
595 [[maybe_unused]] const Array<OneD, const NekDouble> &global,
596 [[maybe_unused]] Array<OneD, NekDouble> &loc) const
597{
598 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
599}
600
602 [[maybe_unused]] const NekVector<NekDouble> &global,
603 [[maybe_unused]] NekVector<NekDouble> &loc) const
604{
605 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
606}
607
609 [[maybe_unused]] const Array<OneD, const NekDouble> &loc,
610 [[maybe_unused]] Array<OneD, NekDouble> &global) const
611{
612 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
613}
614
616 [[maybe_unused]] const NekVector<NekDouble> &loc,
617 [[maybe_unused]] NekVector<NekDouble> &global) const
618{
619 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
620}
621
623 [[maybe_unused]] Array<OneD, NekDouble> &pGlobal) const
624{
625 // Do nothing here since multi-level static condensation uses a
626 // AssemblyMap and thus will call this routine in serial.
627}
628
630 [[maybe_unused]] Array<OneD, NekDouble> &pGlobal,
631 [[maybe_unused]] int offset) const
632{
633 // Do nothing here since multi-level static condensation uses a
634 // AssemblyMap and thus will call this routine in serial.
635}
636
638{
639 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
640 return 0;
641}
642
644{
645 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
646 return 0;
647}
648
650{
651 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
652 return 0;
653}
654
656{
657 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
658 return 0;
659}
660
662{
663 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
664 return 0;
665}
666
668{
669 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
670 return 0;
671}
672
674{
675 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
676 return 0;
677}
678
680{
681 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
682 return 0;
683}
684
686{
687 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
688 static Array<OneD, const int> result;
689 return result;
690}
691
692std::shared_ptr<AssemblyMap> AssemblyMap::v_LinearSpaceMap(
693 [[maybe_unused]] const ExpList &locexp,
694 [[maybe_unused]] GlobalSysSolnType solnType)
695{
696 NEKERROR(ErrorUtil::efatal, "Not defined for this type of mapping.");
697 static std::shared_ptr<AssemblyMap> result;
698 return result;
699}
700
705
707{
708 return m_variable;
709}
710
712{
713 return m_hash;
714}
715
717{
718 return v_GetLocalToGlobalMap(i);
719}
720
722{
724}
725
730
735
740
745
747{
748 return v_GetLocalToGlobalSign(i);
749}
750
755
758 bool useComm) const
759{
760 v_AvgAssemble(loc, global, useComm);
761}
762
765 bool useComm) const
766{
767 v_LocalToGlobal(loc, global, useComm);
768}
769
771 NekVector<NekDouble> &global,
772 bool useComm) const
773{
774 v_LocalToGlobal(loc.GetPtr(), global.GetPtr(), useComm);
775}
776
778 Array<OneD, NekDouble> &loc) const
779{
780 v_GlobalToLocal(global, loc);
781}
782
784 NekVector<NekDouble> &loc) const
785{
786 v_GlobalToLocal(global, loc);
787}
788
790 Array<OneD, NekDouble> &global) const
791{
792 v_Assemble(loc, global);
793}
794
796 NekVector<NekDouble> &global) const
797{
798 v_Assemble(loc, global);
799}
800
805
810
812 int offset) const
813{
814 v_UniversalAssemble(pGlobal, offset);
815}
816
818 Array<OneD, NekDouble> &global) const
819{
821
822 Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
824
825 if (global.data() == loc.data())
826 {
827 local = Array<OneD, NekDouble>(map.size(), loc.data());
828 }
829 else
830 {
831 local = loc; // create reference
832 }
833
834 Vmath::Scatr(map.size(), sign.data(), local.data(), map.data(),
835 global.data());
836}
837
839 Array<OneD, NekDouble> &loc) const
840{
842
843 Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
845
846 if (global.data() == loc.data())
847 {
848 glo = Array<OneD, NekDouble>(global.size(), global.data());
849 }
850 else
851 {
852 glo = global; // create reference
853 }
854
855 Vmath::Gathr(map.size(), sign.data(), glo.data(), map.data(), loc.data());
856}
857
859 Array<OneD, NekDouble> &global) const
860{
862 Array<OneD, const int> map = m_patchMapFromPrevLevel->GetNewLevelMap();
864
865 if (global.data() == loc.data())
866 {
867 local = Array<OneD, NekDouble>(map.size(), loc.data());
868 }
869 else
870 {
871 local = loc; // create reference
872 }
873
874 // since we are calling mapping from level down from array
875 // the m_numLocaBndCoeffs represents the size of the
876 // boundary elements we need to assemble into
877 Vmath::Zero(m_numLocalCoeffs, global.data(), 1);
878
879 Vmath::Assmb(map.size(), sign.data(), local.data(), map.data(),
880 global.data());
881}
882
887
892
897
902
904{
905 return v_GetNumDirEdges();
906}
907
909{
910 return v_GetNumDirFaces();
911}
912
914{
915 return v_GetNumNonDirEdges();
916}
917
919{
920 return v_GetNumNonDirFaces();
921}
922
927
928std::shared_ptr<AssemblyMap> AssemblyMap::LinearSpaceMap(
929 const ExpList &locexp, GlobalSysSolnType solnType)
930{
931 return v_LinearSpaceMap(locexp, solnType);
932}
933
935{
936 return m_localToGlobalBndMap[i];
937}
938
943
945{
946 return m_signChange;
947}
948
953
958
963
965{
966 if (m_signChange)
967 {
968 return m_localToGlobalBndSign[i];
969 }
970 else
971 {
972 return 1.0;
973 }
974}
975
980
985
990
992{
993 ASSERTL1(i < m_bndCondIDToGlobalTraceID.size(), "Index out of range.");
995}
996
1001
1003{
1004 ASSERTL1(i < m_perbndCondIDToGlobalTraceID.size(), "Index out of range.");
1006}
1007
1012
1017
1022
1024{
1025 return m_numLocalBndCoeffs;
1026}
1027
1032
1034{
1035 return m_numLocalCoeffs;
1036}
1037
1039{
1040 return m_numGlobalCoeffs;
1041}
1042
1044{
1045 return m_systemSingular;
1046}
1047
1049 NekVector<NekDouble> &loc, int offset) const
1050{
1051 GlobalToLocalBnd(global.GetPtr(), loc.GetPtr(), offset);
1052}
1053
1055 NekVector<NekDouble> &loc) const
1056{
1057 GlobalToLocalBnd(global.GetPtr(), loc.GetPtr());
1058}
1059
1062 int offset) const
1063{
1064 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1065 "Local vector is not of correct dimension");
1066 ASSERTL1(global.size() >= m_numGlobalBndCoeffs - offset,
1067 "Global vector is not of correct dimension");
1068
1069 // offset input data by length "offset" for Dirichlet boundary conditions.
1071 Vmath::Vcopy(m_numGlobalBndCoeffs - offset, global.data(), 1,
1072 tmp.data() + offset, 1);
1073
1074 if (m_signChange)
1075 {
1077 tmp.data(), m_localToGlobalBndMap.data(), loc.data());
1078 }
1079 else
1080 {
1082 m_localToGlobalBndMap.data(), loc.data());
1083 }
1084}
1085
1087 Array<OneD, NekDouble> &loc) const
1088{
1089 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1090 "Local vector is not of correct dimension");
1091 ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1092 "Global vector is not of correct dimension");
1093
1095 if (global.data() == loc.data())
1096 {
1097 glo = Array<OneD, NekDouble>(m_numLocalBndCoeffs, global.data());
1098 }
1099 else
1100 {
1101 glo = global; // create reference
1102 }
1103
1104 if (m_signChange)
1105 {
1107 glo.data(), m_localToGlobalBndMap.data(), loc.data());
1108 }
1109 else
1110 {
1112 m_localToGlobalBndMap.data(), loc.data());
1113 }
1114}
1115
1117 Array<OneD, NekDouble> &global, int offset,
1118 bool UseComm) const
1119{
1120 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1121 "Local vector is not of correct dimension");
1122 ASSERTL1(global.size() >= m_numGlobalBndCoeffs - offset,
1123 "Global vector is not of correct dimension");
1124
1125 // offset input data by length "offset" for Dirichlet boundary conditions.
1127
1128 if (m_signChange)
1129 {
1131 loc.data(), m_localToGlobalBndMap.data(), tmp.data());
1132 }
1133 else
1134 {
1136 m_localToGlobalBndMap.data(), tmp.data());
1137 }
1138
1139 // Ensure each processor has unique value with a max gather.
1140 if (UseComm)
1141 {
1143 }
1144 Vmath::Vcopy(m_numGlobalBndCoeffs - offset, tmp.data() + offset, 1,
1145 global.data(), 1);
1146}
1147
1149 Array<OneD, NekDouble> &global,
1150 bool UseComm) const
1151{
1152 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1153 "Local vector is not of correct dimension");
1154 ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1155 "Global vector is not of correct dimension");
1156
1157 if (m_signChange)
1158 {
1160 loc.data(), m_localToGlobalBndMap.data(), global.data());
1161 }
1162 else
1163 {
1165 m_localToGlobalBndMap.data(), global.data());
1166 }
1167 if (UseComm)
1168 {
1169 Gs::Gather(global, Gs::gs_max, m_bndGsh);
1170 }
1171}
1172
1174 Array<OneD, NekDouble> &locbnd) const
1175{
1176 ASSERTL1(locbnd.size() >= m_numLocalBndCoeffs,
1177 "LocBnd vector is not of correct dimension");
1178 ASSERTL1(local.size() >= m_numLocalCoeffs,
1179 "Local vector is not of correct dimension");
1180
1182 locbnd.data());
1183}
1184
1186 Array<OneD, NekDouble> &locint) const
1187{
1189 "Locint vector is not of correct dimension");
1190 ASSERTL1(local.size() >= m_numLocalCoeffs,
1191 "Local vector is not of correct dimension");
1192
1194 m_localToLocalIntMap.data(), locint.data());
1195}
1196
1198 Array<OneD, NekDouble> &local) const
1199{
1200 ASSERTL1(locbnd.size() >= m_numLocalBndCoeffs,
1201 "LocBnd vector is not of correct dimension");
1202 ASSERTL1(local.size() >= m_numLocalCoeffs,
1203 "Local vector is not of correct dimension");
1204
1205 Vmath::Scatr(m_numLocalBndCoeffs, locbnd.data(),
1206 m_localToLocalBndMap.data(), local.data());
1207}
1208
1210 Array<OneD, NekDouble> &local) const
1211{
1213 "LocBnd vector is not of correct dimension");
1214 ASSERTL1(local.size() >= m_numLocalCoeffs,
1215 "Local vector is not of correct dimension");
1216
1218 m_localToLocalIntMap.data(), local.data());
1219}
1220
1222 NekVector<NekDouble> &global, int offset) const
1223{
1224 AssembleBnd(loc.GetPtr(), global.GetPtr(), offset);
1225}
1226
1228 NekVector<NekDouble> &global) const
1229{
1230 AssembleBnd(loc.GetPtr(), global.GetPtr());
1231}
1232
1234 Array<OneD, NekDouble> &global, int offset) const
1235{
1236 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1237 "Local array is not of correct dimension");
1238 ASSERTL1(global.size() >= m_numGlobalBndCoeffs - offset,
1239 "Global array is not of correct dimension");
1241
1242 if (m_signChange)
1243 {
1245 loc.data(), m_localToGlobalBndMap.data(), tmp.data());
1246 }
1247 else
1248 {
1250 m_localToGlobalBndMap.data(), tmp.data());
1251 }
1253 Vmath::Vcopy(m_numGlobalBndCoeffs - offset, tmp.data() + offset, 1,
1254 global.data(), 1);
1255}
1256
1258 Array<OneD, NekDouble> &global) const
1259{
1260 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1261 "Local vector is not of correct dimension");
1262 ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1263 "Global vector is not of correct dimension");
1264
1265 Vmath::Zero(m_numGlobalBndCoeffs, global.data(), 1);
1266
1267 if (m_signChange)
1268 {
1270 loc.data(), m_localToGlobalBndMap.data(), global.data());
1271 }
1272 else
1273 {
1275 m_localToGlobalBndMap.data(), global.data());
1276 }
1277 UniversalAssembleBnd(global);
1278}
1279
1281{
1282 ASSERTL1(pGlobal.size() >= m_numGlobalBndCoeffs, "Wrong size.");
1283 Gs::Gather(pGlobal, Gs::gs_add, m_bndGsh);
1284}
1285
1290
1292 int offset) const
1293{
1294 Array<OneD, NekDouble> tmp(offset);
1295 if (offset > 0)
1296 {
1297 Vmath::Vcopy(offset, pGlobal, 1, tmp, 1);
1298 }
1299 UniversalAssembleBnd(pGlobal);
1300 if (offset > 0)
1301 {
1302 Vmath::Vcopy(offset, tmp, 1, pGlobal, 1);
1303 }
1304}
1305
1310
1315
1317{
1318 return m_staticCondLevel;
1319}
1320
1322{
1323 return m_numPatches;
1324}
1325
1331
1337
1342
1347
1349{
1350 return !(m_nextLevelLocalToGlobalMap.get());
1351}
1352
1357
1359{
1360 return m_preconType;
1361}
1362
1364{
1365 return m_isAbsoluteTolerance;
1366}
1367
1369{
1370 return m_successiveRHS;
1371}
1372
1374{
1375 return m_linSysIterSolver;
1376}
1377
1380{
1381 ASSERTL1(loc.size() >= m_numLocalBndCoeffs,
1382 "Local vector is not of correct dimension");
1383 ASSERTL1(global.size() >= m_numGlobalBndCoeffs,
1384 "Global vector is not of correct dimension");
1385
1386 Vmath::Gathr(m_numLocalBndCoeffs, global.data(),
1387 m_localToGlobalBndMap.data(), loc.data());
1388}
1389
1390void AssemblyMap::PrintStats(std::ostream &out, std::string variable,
1391 bool printHeader) const
1392{
1393 LibUtilities::CommSharedPtr vRowComm = m_session->GetComm()->GetRowComm();
1394 bool isRoot = m_session->GetComm()->IsParallelInTime()
1395 ? m_session->GetComm()->GetRank() == 0
1396 : vRowComm->GetRank() == 0;
1397 int n = vRowComm->GetSize();
1398 int i;
1399
1400 // Determine number of global degrees of freedom.
1401 int globBndCnt = 0, globDirCnt = 0;
1402
1403 for (i = 0; i < m_numGlobalBndCoeffs; ++i)
1404 {
1406 {
1407 globBndCnt++;
1408
1410 {
1411 globDirCnt++;
1412 }
1413 }
1414 }
1415
1416 int globCnt = m_numGlobalCoeffs - m_numGlobalBndCoeffs + globBndCnt;
1417
1418 // Calculate maximum valency
1421
1422 Vmath::Assmb(m_numLocalBndCoeffs, tmpLoc.data(),
1423 m_localToGlobalBndMap.data(), tmpGlob.data());
1424 UniversalAssembleBnd(tmpGlob);
1425
1426 int totGlobDof = globCnt;
1427 int totGlobBndDof = globBndCnt;
1428 int totGlobDirDof = globDirCnt;
1429 int totLocalDof = m_numLocalCoeffs;
1430 int totLocalBndDof = m_numLocalBndCoeffs;
1431 int totLocalDirDof = m_numLocalDirBndCoeffs;
1432
1433 int meanValence = 0;
1434 int maxValence = 0;
1435 int minValence = 10000000;
1436 for (int i = 0; i < m_numGlobalBndCoeffs; ++i)
1437 {
1439 {
1440 continue;
1441 }
1442
1443 if (tmpGlob[i] > maxValence)
1444 {
1445 maxValence = tmpGlob[i];
1446 }
1447 if (tmpGlob[i] < minValence)
1448 {
1449 minValence = tmpGlob[i];
1450 }
1451 meanValence += tmpGlob[i];
1452 }
1453
1454 vRowComm->AllReduce(maxValence, LibUtilities::ReduceMax);
1455 vRowComm->AllReduce(minValence, LibUtilities::ReduceMin);
1456 vRowComm->AllReduce(meanValence, LibUtilities::ReduceSum);
1457 vRowComm->AllReduce(totGlobDof, LibUtilities::ReduceSum);
1458 vRowComm->AllReduce(totGlobBndDof, LibUtilities::ReduceSum);
1459 vRowComm->AllReduce(totGlobDirDof, LibUtilities::ReduceSum);
1460 vRowComm->AllReduce(totLocalDof, LibUtilities::ReduceSum);
1461 vRowComm->AllReduce(totLocalBndDof, LibUtilities::ReduceSum);
1462 vRowComm->AllReduce(totLocalDirDof, LibUtilities::ReduceSum);
1463
1464 meanValence /= totGlobBndDof;
1465
1466 if (isRoot)
1467 {
1468 if (printHeader)
1469 {
1470 out << "Assembly map statistics for field " << variable << ":"
1471 << endl;
1472 }
1473
1474 out << " - Number of local/global dof : " << totLocalDof
1475 << " " << totGlobDof << endl;
1476 out << " - Number of local/global boundary dof : " << totLocalBndDof
1477 << " " << totGlobBndDof << endl;
1478 out << " - Number of local/global Dirichlet dof : " << totLocalDirDof
1479 << " " << totGlobDirDof << endl;
1480 out << " - dof valency (min/max/mean) : " << minValence
1481 << " " << maxValence << " " << meanValence << endl;
1482
1483 if (n > 1)
1484 {
1485 NekDouble mean = m_numLocalCoeffs, mean2 = mean * mean;
1486 NekDouble minval = mean, maxval = mean;
1488
1489 for (i = 1; i < n; ++i)
1490 {
1491 vRowComm->Recv(i, tmp);
1492 mean += tmp[0];
1493 mean2 += tmp[0] * tmp[0];
1494
1495 if (tmp[0] > maxval)
1496 {
1497 maxval = tmp[0];
1498 }
1499 if (tmp[0] < minval)
1500 {
1501 minval = tmp[0];
1502 }
1503 }
1504
1505 if (maxval > 0.1)
1506 {
1507 out << " - Local dof dist. (min/max/mean/dev) : " << minval
1508 << " " << maxval << " " << (mean / n) << " "
1509 << sqrt(mean2 / n - mean * mean / n / n) << endl;
1510 }
1511
1512 vRowComm->Block();
1513
1514 mean = minval = maxval = m_numLocalBndCoeffs;
1515 mean2 = mean * mean;
1516
1517 for (i = 1; i < n; ++i)
1518 {
1519 vRowComm->Recv(i, tmp);
1520 mean += tmp[0];
1521 mean2 += tmp[0] * tmp[0];
1522
1523 if (tmp[0] > maxval)
1524 {
1525 maxval = tmp[0];
1526 }
1527 if (tmp[0] < minval)
1528 {
1529 minval = tmp[0];
1530 }
1531 }
1532
1533 out << " - Local bnd dof dist. (min/max/mean/dev) : " << minval
1534 << " " << maxval << " " << (mean / n) << " "
1535 << sqrt(mean2 / n - mean * mean / n / n) << endl;
1536 }
1537 }
1538 else
1539 {
1541 tmp[0] = m_numLocalCoeffs;
1542 vRowComm->Send(0, tmp);
1543 vRowComm->Block();
1544 tmp[0] = m_numLocalBndCoeffs;
1545 vRowComm->Send(0, tmp);
1546 }
1547
1548 // Either we have no more levels in the static condensation, or we
1549 // are not multi-level.
1551 {
1552 return;
1553 }
1554
1555 int level = 2;
1557 while (tmp->m_nextLevelLocalToGlobalMap)
1558 {
1559 tmp = tmp->m_nextLevelLocalToGlobalMap;
1560 ++level;
1561 }
1562
1563 // Print out multi-level static condensation information.
1564 if (n > 1)
1565 {
1566 if (isRoot)
1567 {
1568 NekDouble mean = level, mean2 = mean * mean;
1569 int minval = level, maxval = level;
1570
1571 Array<OneD, NekDouble> tmpRecv(1);
1572 for (i = 1; i < n; ++i)
1573 {
1574 vRowComm->Recv(i, tmpRecv);
1575 mean += tmpRecv[0];
1576 mean2 += tmpRecv[0] * tmpRecv[0];
1577
1578 if (tmpRecv[0] > maxval)
1579 {
1580 maxval = (int)(tmpRecv[0] + 0.5);
1581 }
1582 if (tmpRecv[0] < minval)
1583 {
1584 minval = (int)(tmpRecv[0] + 0.5);
1585 }
1586 }
1587
1588 out << " - M-level sc. dist. (min/max/mean/dev) : " << minval
1589 << " " << maxval << " " << (mean / n) << " "
1590 << sqrt(mean2 / n - mean * mean / n / n) << endl;
1591 }
1592 else
1593 {
1594 Array<OneD, NekDouble> tmpSend(1);
1595 tmpSend[0] = level;
1596 vRowComm->Send(0, tmpSend);
1597 }
1598 }
1599 else
1600 {
1601 if (isRoot)
1602 {
1603 out << " - Number of static cond. levels : " << level
1604 << endl;
1605 }
1606 }
1607
1608 if (isRoot)
1609 {
1610 out << "Stats at lowest static cond. level:" << endl;
1611 }
1612 tmp->PrintStats(out, variable, false);
1613}
1614} // namespace Nektar::MultiRegions
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define sign(a, b)
return the sign(b)*a
Definition Polylib.cpp:47
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:56
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.
int GetNumPatches() const
Returns the number of patches in this static condensation level.
const Array< OneD, const int > & GetGlobalToUniversalMapUnique()
int GetNumGlobalCoeffs() const
Returns the total number of global coefficients.
int m_numLocalCoeffs
Total number of local coefficients.
void AvgAssemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm=true) const
Array< OneD, int > m_bndCondCoeffsToLocalTraceMap
Integer map of bnd cond coeff to local trace coeff.
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.
virtual const Array< OneD, const int > & v_GetExtraDirEdges()
int GetNumLocalCoeffs() const
Returns the total number of local coefficients.
std::string GetVariable()
Retrieves the variable string.
Array< OneD, int > m_perbndCondIDToGlobalTraceID
Integer map of rotational periodic bnd cond trace number to global trace number.
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.
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
PatchMapSharedPtr m_patchMapFromPrevLevel
Mapping information for previous level in MultiLevel Solver.
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique()
virtual void v_AvgAssemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm) const
int m_numGlobalCoeffs
Total number of global coefficients.
std::string m_linSysIterSolver
Iterative solver: Conjugate Gradient, GMRES.
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.
void PatchAssemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
int m_successiveRHS
sucessive RHS for iterative solver
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.
void UniversalAbsMaxBnd(Array< OneD, NekDouble > &bndvals)
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
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.
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.
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.
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.
int m_bndSystemBandWidth
The bandwith of the global bnd system.
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.
bool GetSingularSystem() const
Retrieves if the system is singular (true) or not (false)
std::string m_variable
Variable string identifier.
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.
LibUtilities::CommSharedPtr GetComm()
Retrieves the communicator.
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
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.
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
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.
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.
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
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.
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.
Array< OneD, NekDouble > m_bndCondCoeffsToLocalCoeffsSign
Integer map of sign of bnd cond coeffs to local coefficients.
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.
const Array< OneD, const int > & GetPerBndCondIDToGlobalTraceID()
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
std::string m_preconType
Type type of preconditioner to use in iterative solver.
int GetNumLocalBndCoeffs() const
Returns the total number of local boundary coefficients.
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Array< OneD, int > m_bndCondIDToGlobalTraceID
Integer map of bnd cond trace number to global trace number.
Base class for all multi-elemental spectral/hp expansions.
Definition ExpList.h:98
Array< OneD, DataType > & GetPtr()
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:278
@ gs_amax
Definition GsLib.hpp:64
@ gs_add
Definition GsLib.hpp:60
@ gs_max
Definition GsLib.hpp:63
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition Comm.h:55
@ eNoSolnType
No Solution type specified.
std::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition AssemblyMap.h:50
std::shared_ptr< PatchMap > PatchMapSharedPtr
int RoundNekDoubleToInt(NekDouble x)
Rounds a double precision number to an integer.
void Gathr(I n, const T *x, const I *y, T *z)
Gather vector z[i] = x[y[i]].
Definition Vmath.hpp:507
void Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
Definition Vmath.hpp:539
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.hpp:577
void Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825
STL namespace.
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290