64 const std::shared_ptr<GlobalLinSys> &plinsys,
78 "Solver type not valid");
132 int i, j, k, n, cnt, gId;
133 int meshVertId, meshEdgeId, meshFaceId;
137 const int nExp = expList->GetExpSize();
138 const int nDirBnd = asmMap->GetNumGlobalDirBndCoeffs();
141 PeriodicMap periodicVerts, periodicEdges, periodicFaces;
142 expList->GetPeriodicEntities(periodicVerts, periodicEdges, periodicFaces);
152 vector<map<int, vector<NekDouble>>> idMats(nStorage);
156 vector<map<int, int>> gidMeshIds(3);
160 vector<map<int, int>> gidDofs(nStorage);
172 for (cnt = n = 0; n < nExp; ++n)
174 exp = expList->GetExp(n);
184 auto tmpMat =
m_linsys.lock()->GetBlock(n);
187 int nBndDofs = exp->NumBndryCoeffs();
188 int nIntDofs = exp->GetNcoeffs() - nBndDofs;
192 exp->GetBoundaryMap(bndMap);
193 exp->GetInteriorMap(intMap);
201 for (
int i = 0; i < nBndDofs; ++i)
203 for (
int j = 0; j < nBndDofs; ++j)
205 (*bndryMat)(i, j) = (*tmpMat)(bndMap[i], bndMap[j]);
213 vector<NekDouble> tmpStore(nIntDofs * nIntDofs);
214 for (
int i = 0; i < nIntDofs; ++i)
216 for (
int j = 0; j < nIntDofs; ++j)
218 tmpStore[j + i * nIntDofs] =
219 (*tmpMat)(intMap[i], intMap[j]);
224 idMats[3][n] = tmpStore;
225 gidDofs[3][n] = nIntDofs;
233 schurMat =
m_linsys.lock()->GetStaticCondBlock(n)->GetBlock(0, 0);
238 for (i = 0; i < exp->GetNverts(); ++i)
240 meshVertId = exp->GetGeom()->GetVid(i);
241 int locId = exp->GetVertexMap(i);
244 gId = asmMap->GetLocalToGlobalMap(cnt + locId) - nDirBnd;
255 NekDouble vertVal = (*schurMat)(locId, locId);
259 auto gIt = idMats[0].find(gId);
261 if (gIt == idMats[0].end())
264 idMats[0][gId] = vector<NekDouble>(1, vertVal);
270 gIt->second[0] += vertVal;
277 auto pIt = periodicVerts.find(meshVertId);
278 if (pIt != periodicVerts.end())
280 for (j = 0; j < pIt->second.size(); ++j)
282 meshVertId = min(meshVertId, pIt->second[j].id);
288 gidMeshIds[0][gId] = meshVertId;
289 maxVertIds[0] = max(maxVertIds[0], meshVertId);
295 for (i = 0; i < exp->GetGeom()->GetNumEdges(); ++i)
297 meshEdgeId = exp->GetGeom()->GetEid(i);
305 auto pIt = periodicEdges.find(meshEdgeId);
306 if (pIt != periodicEdges.end())
308 pair<int, StdRegions::Orientation> idOrient =
311 meshEdgeId = idOrient.first;
312 edgeOrient = idOrient.second;
318 if (exp->GetGeom()->GetNumFaces())
321 ->GetEdgeInteriorToElementMap(i, bmap,
sign, edgeOrient);
323 ->GetEdgeInverseBoundaryMap(i);
327 exp->GetTraceInteriorToElementMap(i, bmap,
sign, edgeOrient);
329 ->GetTraceInverseBoundaryMap(i);
333 const int nEdgeCoeffs = bmap.size();
334 vector<NekDouble> tmpStore(nEdgeCoeffs * nEdgeCoeffs);
336 gId = asmMap->GetLocalToGlobalMap(cnt + bmap[0]);
338 for (j = 0; j < nEdgeCoeffs; ++j)
346 asmMap->GetLocalToGlobalMap(cnt + bmap[j]) - nDirBnd);
358 for (k = 0; k < nEdgeCoeffs; ++k)
360 tmpStore[k + j * nEdgeCoeffs] =
361 sign1 *
sign[k] * (*schurMat)(bmap2[j], bmap2[k]);
370 gidDofs[1][gId] = nEdgeCoeffs;
373 auto gIt = idMats[1].find(gId);
374 if (gIt == idMats[1].end())
376 idMats[1][gId] = tmpStore;
380 ASSERTL1(tmpStore.size() == gIt->second.size(),
381 "Number of modes mismatch");
382 Vmath::Vadd(nEdgeCoeffs * nEdgeCoeffs, &gIt->second[0], 1,
383 &tmpStore[0], 1, &gIt->second[0], 1);
386 gidMeshIds[1][gId] = meshEdgeId;
387 maxVertIds[2] = max(maxVertIds[2], meshEdgeId);
388 maxVertIds[3] = max(maxVertIds[3], nEdgeCoeffs);
393 for (i = 0; i < exp->GetGeom()->GetNumFaces(); ++i)
395 meshFaceId = exp->GetGeom()->GetFid(i);
403 auto pIt = periodicFaces.find(meshFaceId);
404 if (pIt != periodicFaces.end())
406 meshFaceId = min(meshFaceId, pIt->second[0].id);
408 pIt->second[0].orient);
411 exp->GetTraceInteriorToElementMap(i, bmap,
sign, faceOrient);
413 ->GetTraceInverseBoundaryMap(i);
416 const int nFaceCoeffs = bmap.size();
417 vector<NekDouble> tmpStore(nFaceCoeffs * nFaceCoeffs);
419 gId = asmMap->GetLocalToGlobalMap(cnt + bmap[0]);
421 for (j = 0; j < nFaceCoeffs; ++j)
424 asmMap->GetLocalToGlobalMap(cnt + bmap[j]) - nDirBnd);
436 for (k = 0; k < nFaceCoeffs; ++k)
438 tmpStore[k + j * nFaceCoeffs] =
439 sign1 *
sign[k] * (*schurMat)(bmap2[j], bmap2[k]);
448 gidDofs[2][gId] = nFaceCoeffs;
451 auto gIt = idMats[2].find(gId);
452 if (gIt == idMats[2].end())
454 idMats[2][gId] = tmpStore;
458 ASSERTL1(tmpStore.size() == gIt->second.size(),
459 "Number of modes mismatch");
460 Vmath::Vadd(nFaceCoeffs * nFaceCoeffs, &gIt->second[0], 1,
461 &tmpStore[0], 1, &gIt->second[0], 1);
464 gidMeshIds[2][gId] = meshFaceId;
465 maxVertIds[4] = max(maxVertIds[4], meshFaceId);
466 maxVertIds[5] = max(maxVertIds[5], nFaceCoeffs);
469 cnt += exp->GetNcoeffs();
474 m_comm = expList->GetSession()->GetComm()->GetRowComm();
479 vector<NekDouble> storageBuf;
480 vector<long> globalToUniversal;
482 for (i = 0, cnt = 1; i < 3; ++i)
484 const int maxDofs = maxVertIds[2 * i + 1];
489 for (
auto &gIt : idMats[i])
492 storageBuf.insert(storageBuf.end(), gIt.second.begin(),
496 ASSERTL1(gidMeshIds[i].count(gIt.first) > 0,
497 "Unable to find global ID " +
498 boost::lexical_cast<string>(gIt.first) +
500 meshVertId = gidMeshIds[i][gIt.first];
502 for (j = 0; j < gIt.second.size(); ++j)
504 globalToUniversal.push_back(cnt +
505 meshVertId * maxDofs * maxDofs + j);
512 cnt += (maxVertIds[2 * i] + 1) * maxDofs * maxDofs;
515 ASSERTL1(storageBuf.size() == globalToUniversal.size(),
516 "Storage buffer and global to universal map size does "
521 &globalToUniversal[0]);
526 expList->GetSession()->DefinesCmdLineArgument(
"verbose"));
530 int nblksSize = 1 + idMats[1].size() + idMats[2].size();
533 nblksSize += idMats[3].size();
538 n_blks[0] = idMats[0].size();
543 for (i = 1; i < nStorage; ++i)
545 for (
auto &gIt : idMats[i])
547 ASSERTL1(gidDofs[i].count(gIt.first) > 0,
548 "Unable to find number of degrees of freedom for "
550 boost::lexical_cast<string>(gIt.first));
552 n_blks[cnt++] = gidDofs[i][gIt.first];
567 for (
auto gIt = idMats[0].begin(); gIt != idMats[0].end(); ++gIt, ++cnt)
569 (*vertMat)(cnt, cnt) = 1.0 / storageData[cnt];
578 for (i = 1; i < nStorage; ++i)
580 for (
auto &gIt : idMats[i])
582 int nDofs = gidDofs[i][gIt.first];
587 for (j = 0; j < nDofs; ++j)
589 for (k = 0; k < nDofs; ++k)
595 (*tmp)(j, k) = gIt.second[k + j * nDofs];
600 (*tmp)(j, k) = storageData[k + j * nDofs + cnt];
605 cnt += nDofs * nDofs;
608 m_blkMat->SetBlock(cnt2, cnt2, tmp);
629 std::shared_ptr<MultiRegions::ExpList> expList =
630 ((
m_linsys.lock())->GetLocMat()).lock();
631 std::shared_ptr<MultiRegions::ExpList> trace = expList->GetTrace();
637 std::dynamic_pointer_cast<AssemblyMapDG>(
m_locToGloMap.lock());
639 int i, j, k, n, cnt, cnt2;
642 int nTrace = expList->GetTrace()->GetExpSize();
643 int nDir = asmMap->GetNumGlobalDirBndCoeffs();
645 for (cnt = n = 0; n < nTrace; ++n)
652 cnt += trace->GetExp(n)->GetNcoeffs();
659 int maxTraceSize = -1;
660 map<int, int> arrayOffsets;
662 for (cnt = 0, n = nDir; n < nTrace; ++n)
664 int nCoeffs = trace->GetExp(n)->GetNcoeffs();
665 int nCoeffs2 = nCoeffs * nCoeffs;
667 arrayOffsets[n] = cnt;
670 if (maxTraceSize < nCoeffs2)
672 maxTraceSize = nCoeffs2;
677 m_comm = expList->GetSession()->GetComm()->GetRowComm();
684 for (cnt = n = 0; n < expList->GetExpSize(); ++n)
687 locExpansion = expList->GetExp(elmt);
690 asmMap->GetElmtToTrace()[elmt];
693 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
694 bnd_mat = loc_mat->GetBlock(0, 0);
696 int nFacets = locExpansion->GetNtraces();
698 for (cnt2 = i = 0; i < nFacets; ++i)
700 int nCoeffs = elmtToTraceMap[i]->GetNcoeffs();
701 int elmtId = elmtToTraceMap[i]->GetElmtId();
711 NekDouble *off = &tmpStore[arrayOffsets[elmtId]];
713 for (j = 0; j < nCoeffs; ++j)
715 NekDouble sign1 = asmMap->GetLocalToGlobalBndSign(cnt + j);
716 for (k = 0; k < nCoeffs; ++k)
718 NekDouble sign2 = asmMap->GetLocalToGlobalBndSign(cnt + k);
719 off[j * nCoeffs + k] +=
720 (*bnd_mat)(cnt2 + j, cnt2 + k) * sign1 * sign2;
731 for (cnt = 0, n = nDir; n < nTrace; ++n)
734 int nCoeffs = traceExp->GetNcoeffs();
735 int geomId = traceExp->GetGeom()->GetGlobalID();
737 for (i = 0; i < nCoeffs * nCoeffs; ++i)
739 uniIds[cnt++] = geomId * maxTraceSize + i + 1;
746 expList->GetSession()->DefinesCmdLineArgument(
"verbose"));
751 for (n = 0; n < nTrace - nDir; ++n)
753 n_blks[n] = trace->GetExp(n + nDir)->GetNcoeffs();
759 for (n = 0; n < nTrace - nDir; ++n)
761 int nCoeffs = trace->GetExp(n + nDir)->GetNcoeffs();
764 NekDouble *off = &tmpStore[arrayOffsets[n + nDir]];
766 for (i = 0; i < nCoeffs; ++i)
768 for (j = 0; j < nCoeffs; ++j)
770 (*tmp)(i, j) = off[i * nCoeffs + j];
791 int nGlobal =
m_isFull ? asmMap->GetNumGlobalCoeffs()
792 : asmMap->GetNumGlobalBndCoeffs();
793 int nDir = asmMap->GetNumGlobalDirBndCoeffs();
794 int nNonDir = nGlobal - nDir;
803 asmMap->Assemble(pInput, wk);
811 asmMap->GlobalToLocal(wk1, pOutput);
#define ASSERTL0(condition, msg)
#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
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Describe a linear system.
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
void BlockPreconditionerCG(void)
Construct a block preconditioner from for the continuous Galerkin system.
static PreconditionerSharedPtr create(const std::shared_ptr< GlobalLinSys > &plinsys, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Creates an instance of this class.
virtual void v_DoPreconditioner(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &isLocal=false) override
Apply preconditioner to pInput and store the result in pOutput.
void BlockPreconditionerHDG(void)
Construct a block preconditioner for the hybridized discontinuous Galerkin system.
PreconditionerBlock(const std::shared_ptr< GlobalLinSys > &plinsys, const AssemblyMapSharedPtr &pLocToGloMap)
virtual void v_InitObject() override
static std::string className
Name of class.
DNekBlkMatSharedPtr m_blkMat
virtual void v_BuildPreconditioner() override
LibUtilities::CommSharedPtr m_comm
const std::weak_ptr< GlobalLinSys > m_linsys
std::weak_ptr< AssemblyMap > m_locToGloMap
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.
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
std::shared_ptr< Expansion > ExpansionSharedPtr
std::shared_ptr< AssemblyMapDG > AssemblyMapDGSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
PreconFactory & GetPreconFactory()
pair< int, StdRegions::Orientation > DeterminePeriodicEdgeOrientId(int meshEdgeId, StdRegions::Orientation edgeOrient, const vector< PeriodicEntity > &periodicEdges)
Determine orientation of an edge to its periodic equivalents, as well as the ID of the representative...
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
StdRegions::Orientation DeterminePeriodicFaceOrient(StdRegions::Orientation faceOrient, StdRegions::Orientation perFaceOrient)
Determine relative orientation between two faces.
std::vector< double > z(NPUPPER)
The above copyright notice and this permission notice shall be included.
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
std::shared_ptr< DNekMat > DNekMatSharedPtr
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
void Zero(int n, T *x, const int incx)
Zero vector.