60 const bool CheckforSingularSys)
64 size_t cnt = 0, offset = 0;
70 size_t nEdgeInteriorCoeffs;
71 int firstNonDirGraphVertId;
72 size_t nLocBndCondDofs = 0;
73 size_t nLocDirBndCondDofs = 0;
74 int nExtraDirichlet = 0;
81 size_t nvel = fields.size();
85 size_t nel = fields[0]->GetNumElmts();
90 vector<map<int, int>> ReorderedGraphVertId(3);
92 int staticCondLevel = 0;
94 if (CheckforSingularSys)
111 fields[0]->GetPeriodicEntities(periodicVerts, periodicEdges, periodicFaces);
114 fields[0]->GetBndCondExpansions();
117 bndConditionsVec(nvel);
118 for (i = 0; i < nvel; ++i)
120 bndConditionsVec[i] = fields[i]->GetBndConditions();
123 map<int, int> IsDirVertDof;
124 map<int, int> IsDirEdgeDof;
127 for (j = 0; j < bndCondExp.size(); ++j)
129 map<int, int> BndExpVids;
131 for (k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
137 BndExpVids[g->GetVid(0)] = g->GetVid(0);
138 BndExpVids[g->GetVid(1)] = g->GetVid(1);
141 for (i = 0; i < nvel; ++i)
143 if (bndConditionsVec[i][j]->GetBoundaryConditionType() ==
147 for (k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
149 IsDirEdgeDof[bndCondExp[j]
153 ->GetGlobalID()] += 1;
159 for (
auto &mapIt : BndExpVids)
161 id = IsDirVertDof[mapIt.second] + 1;
162 IsDirVertDof[mapIt.second] = (
id > (int)nvel) ? nvel : id;
171 for (k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
179 loc_exp->GetLeftAdjacentElementExp()->GetTraceNormal(
180 loc_exp->GetLeftAdjacentElementTrace());
182 size_t ndir = locnorm.size();
186 for (
size_t l = 0; l < locnorm[0].size(); ++l)
207 size_t edgeId, vertId;
216 for (i = 0; i < bndConditionsVec[0].size(); ++i)
218 if (bndConditionsVec[nvel - 1][i]->GetBoundaryConditionType() ==
230 ASSERTL0(
id != -1,
" Did not find an edge to attach singular pressure "
231 "degree of freedom");
235 for (i = 0; i < nel; ++i)
237 for (j = 0; j < (size_t)locExpVector[i]->GetNverts(); ++j)
239 edgeId = (locExpVector[i]
244 if ((
int)edgeId == id)
246 AddMeanPressureToEdgeId[i] = id;
251 if (AddMeanPressureToEdgeId[i] != -1)
258 for (i = 0; i < nel; ++i)
260 for (j = 0; j < (size_t)locExpVector[i]->GetNverts(); ++j)
265 if (Dofs[0].count(vertId) == 0)
267 Dofs[0][vertId] = nvel * nz_loc;
271 if (IsDirVertDof.count(vertId) != 0)
273 Dofs[0][vertId] -= IsDirVertDof[vertId] * nz_loc;
280 if (Dofs[1].count(edgeId) == 0)
283 nvel * (locExpVector[i]->GetTraceNcoeffs(j) - 2) * nz_loc;
288 if (IsDirEdgeDof.count(edgeId) != 0)
290 Dofs[1][edgeId] -= IsDirEdgeDof[edgeId] * nz_loc *
291 (locExpVector[i]->GetTraceNcoeffs(j) - 2);
296 set<int> extraDirVerts, extraDirEdges;
298 CreateGraph(*fields[0], bndCondExp, bndConditionsVec,
false, periodicVerts,
299 periodicEdges, periodicFaces, ReorderedGraphVertId,
300 bottomUpGraph, extraDirVerts, extraDirEdges,
301 firstNonDirGraphVertId, nExtraDirichlet, 4);
325 edgeId, vertId, firstNonDirGraphVertId,
326 IsDirEdgeDof, bottomUpGraph,
327 AddMeanPressureToEdgeId);
333 for (i = 0; i < nel; ++i)
335 for (j = 0; j < (size_t)locExpVector[i]->GetNverts(); ++j)
341 if (IsDirEdgeDof.count(edgeId) == 0)
345 if (AddMeanPressureToEdgeId[i] == -1)
347 AddMeanPressureToEdgeId[i] = edgeId;
351 ASSERTL0((AddMeanPressureToEdgeId[i] != -1),
353 "an edge to attach mean pressure dof");
355 Dofs[1][AddMeanPressureToEdgeId[i]] += nz_loc;
358 map<int, int> pressureEdgeOffset;
363 for (i = 0; i < bndCondExp.size(); i++)
365 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
368 for (k = 0; k < nvel; ++k)
370 if (bndConditionsVec[k][i]->GetBoundaryConditionType() ==
373 nLocDirBndCondDofs += bndSegExp->
GetNcoeffs() * nz_loc;
376 if (bndConditionsVec[k][i]->GetBoundaryConditionType() !=
379 nLocBndCondDofs += bndSegExp->GetNcoeffs() * nz_loc;
407 (ReorderedGraphVertId[0].size() + ReorderedGraphVertId[1].size()),
409 graphVertOffset[0] = 0;
413 for (i = 0; i < nel; ++i)
417 for (j = 0; j < (size_t)locExpansion->GetNtraces(); ++j)
420 meshEdgeId = (locExpansion->GetGeom2D())->GetEid(j);
421 meshVertId = (locExpansion->GetGeom2D())->GetVid(j);
423 for (k = 0; k < nvel * nz_loc; ++k)
425 graphVertOffset[ReorderedGraphVertId[0][meshVertId] * nvel *
428 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId] * nvel *
430 k] = (nEdgeCoeffs - 2);
433 bType = locExpansion->GetBasisType(0);
443 for (i = 0; i < nel; ++i)
445 graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]] +
458 map<int, int> DirVertChk;
460 for (i = 0; i < bndConditionsVec[0].size(); ++i)
463 for (j = 0; j < nvel; ++j)
465 if (bndConditionsVec[j][i]->GetBoundaryConditionType() ==
473 if ((cnt > 0) && (cnt < nvel))
475 for (j = 0; j < nvel; ++j)
477 if (bndConditionsVec[j][i]->GetBoundaryConditionType() ==
482 for (k = 0; k < bndCondExp[i]->GetNumElmts(); ++k)
490 if (DirVertChk.count(
id * nvel + j) == 0)
492 DirVertChk[
id * nvel + j] = 1;
493 for (n = 0; n < nz_loc; ++n)
495 graphVertOffset[ReorderedGraphVertId[0][id] *
497 j * nz_loc + n] *= -1;
506 if (DirVertChk.count(
id * nvel + j) == 0)
508 DirVertChk[
id * nvel + j] = 1;
509 for (n = 0; n < nz_loc; ++n)
511 graphVertOffset[ReorderedGraphVertId[0][id] *
513 j * nz_loc + n] *= -1;
523 for (n = 0; n < nz_loc; ++n)
525 graphVertOffset[ReorderedGraphVertId[1][id] * nvel *
527 j * nz_loc + n] *= -1;
537 for (i = 0; i < firstNonDirGraphVertId * nvel * nz_loc; ++i)
539 diff =
abs(graphVertOffset[i]);
540 graphVertOffset[i] = cnt;
545 for (i = firstNonDirGraphVertId * nvel * nz_loc; i < graphVertOffset.size();
548 if (graphVertOffset[i] < 0)
550 diff = -graphVertOffset[i];
551 graphVertOffset[i] = -cnt;
560 for (i = firstNonDirGraphVertId * nvel * nz_loc; i < graphVertOffset.size();
563 if (graphVertOffset[i] >= 0)
565 diff = graphVertOffset[i];
566 graphVertOffset[i] = cnt;
573 for (i = firstNonDirGraphVertId * nvel * nz_loc; i < graphVertOffset.size();
576 if (graphVertOffset[i] < 0)
578 graphVertOffset[i] = -graphVertOffset[i];
588 for (i = 0; i < nel; ++i)
591 nz_loc * (nvel * locExpVector[i]->NumBndryCoeffs() + 1);
614 for (i = 0; i < nel; ++i)
617 (
unsigned int)nz_loc *
618 (nvel * locExpVector[i]->NumBndryCoeffs() + 1);
620 (
unsigned int)nz_loc * (
pressure->GetExp(i)->GetNcoeffs() - 1);
631 for (i = 0; i < nel; ++i)
633 for (j = 0; j < nz_loc * (nvel * locExpVector[i]->NumBndryCoeffs());
639 for (n = 0; n < nz_loc; ++n)
642 for (j = 1; j < (size_t)
pressure->GetExp(i)->GetNcoeffs(); ++j)
659 size_t nv, velnbndry;
664 for (i = 0; i < nel; ++i)
673 map<int, int> inv_bmap;
674 locExpansion->GetBoundaryMap(bmap);
675 for (j = 0; j < bmap.size(); ++j)
677 inv_bmap[bmap[j]] = j;
681 for (j = 0; j < (size_t)locExpansion->GetNtraces(); ++j)
683 nEdgeInteriorCoeffs = locExpansion->GetTraceNcoeffs(j) - 2;
684 edgeOrient = (locExpansion->GetGeom())->GetEorient(j);
685 meshEdgeId = (locExpansion->GetGeom())->GetEid(j);
686 meshVertId = (locExpansion->GetGeom())->GetVid(j);
688 auto pIt = periodicEdges.find(meshEdgeId);
693 if (pIt != periodicEdges.end())
695 pair<int, StdRegions::Orientation> idOrient =
698 edgeOrient = idOrient.second;
701 locExpansion->GetTraceInteriorToElementMap(
702 j, edgeInteriorMap, edgeInteriorSign, edgeOrient);
705 for (nv = 0; nv < nvel * nz_loc; ++nv)
708 inv_bmap[locExpansion->GetVertexMap(j)]] =
709 graphVertOffset[ReorderedGraphVertId[0][meshVertId] * nvel *
714 for (k = 0; k < nEdgeInteriorCoeffs; ++k)
717 inv_bmap[edgeInteriorMap[k]]] =
718 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId] *
728 for (nv = 0; nv < nvel * nz_loc; ++nv)
730 for (k = 0; k < nEdgeInteriorCoeffs; ++k)
733 inv_bmap[edgeInteriorMap[k]]] =
742 nEdgeInteriorCoeffs =
743 graphVertOffset[(ReorderedGraphVertId[1]
744 [AddMeanPressureToEdgeId[i]]) *
747 graphVertOffset[(ReorderedGraphVertId[1]
748 [AddMeanPressureToEdgeId[i]]) *
751 size_t psize =
pressure->GetExp(i)->GetNcoeffs();
752 for (n = 0; n < nz_loc; ++n)
756 [(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]] + 1) *
759 nEdgeInteriorCoeffs +
760 pressureEdgeOffset[AddMeanPressureToEdgeId[i]];
762 pressureEdgeOffset[AddMeanPressureToEdgeId[i]] += 1;
765 cnt += (velnbndry * nvel + psize) * nz_loc;
770 for (nv = 0; nv < nvel; ++nv)
772 for (i = 0; i < bndCondExp.size(); i++)
774 if (bndConditionsVec[nv][i]->GetBoundaryConditionType() ==
780 for (n = 0; n < nz_loc; ++n)
783 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
788 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
789 for (k = 0; k < 2; k++)
791 meshVertId = (bndSegExp->GetGeom1D())->GetVid(k);
794 graphVertOffset[ReorderedGraphVertId[0]
800 meshEdgeId = (bndSegExp->GetGeom1D())->GetGlobalID();
802 nEdgeCoeffs = bndSegExp->GetNcoeffs();
803 for (k = 0; k < nEdgeCoeffs; k++)
809 [ReorderedGraphVertId[1][meshEdgeId] *
816 ncoeffcnt += nEdgeCoeffs;
859 firstNonDirGraphVertId);
860 for (i = 0; i < locExpVector.size(); ++i)
863 size_t nVert = locExpansion->
GetNverts();
864 for (j = 0; j < nVert; ++j)
866 meshEdgeId = (locExpansion->GetGeom2D())->GetEid(j);
867 meshVertId = (locExpansion->GetGeom2D())->GetVid(j);
869 if (ReorderedGraphVertId[0][meshVertId] >=
870 firstNonDirGraphVertId)
872 vwgts_perm[ReorderedGraphVertId[0][meshVertId] -
873 firstNonDirGraphVertId] =
877 if (ReorderedGraphVertId[1][meshEdgeId] >=
878 firstNonDirGraphVertId)
880 vwgts_perm[ReorderedGraphVertId[1][meshEdgeId] -
881 firstNonDirGraphVertId] =
887 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
897 vector<map<int, int>> &ReorderedGraphVertId,
size_t &nel,
899 [[maybe_unused]]
size_t &vertId,
int &firstNonDirGraphVertId,
900 map<int, int> &IsDirEdgeDof,
908 map<int, int> HomGraphEdgeIdToEdgeId;
910 for (i = 0; i < nel; ++i)
912 size_t nVert = locExpVector[i]->GetNverts();
913 for (j = 0; j < nVert; ++j)
920 if ((ReorderedGraphVertId[1][edgeId] >= firstNonDirGraphVertId) &&
921 (IsDirEdgeDof.count(edgeId) == 0))
923 HomGraphEdgeIdToEdgeId[ReorderedGraphVertId[1][edgeId] -
924 firstNonDirGraphVertId] = edgeId;
926 if (EdgeIdToElmts[edgeId][0] == -1)
928 EdgeIdToElmts[edgeId][0] = i;
932 EdgeIdToElmts[edgeId][1] = i;
940 size_t nlevels = bottomUpGraph->GetNlevels();
946 vector<MultiRegions::SubGraphSharedPtr> bndgraphs =
947 bottomUpGraph->GetInteriorBlocks(nlevels);
948 for (i = 0; i < bndgraphs.size(); ++i)
950 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
951 size_t nVert = bndgraphs[i]->GetNverts();
953 for (j = 0; j < nVert; ++j)
956 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
958 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
973 for (
size_t n = 1; n < nlevels; ++n)
977 vector<MultiRegions::SubGraphSharedPtr> bndgraphs =
978 bottomUpGraph->GetInteriorBlocks(n + 1);
981 map<int, int> ElmtInBndry;
983 for (i = 0; i < bndgraphs.size(); ++i)
985 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
986 size_t nVert = bndgraphs[i]->GetNverts();
988 for (j = 0; j < nVert; ++j)
991 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
993 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
995 if (EdgeIdToElmts[edgeId][0] != -1)
997 ElmtInBndry[EdgeIdToElmts[edgeId][0]] = i;
999 if (EdgeIdToElmts[edgeId][1] != -1)
1001 ElmtInBndry[EdgeIdToElmts[edgeId][1]] = i;
1010 vector<MultiRegions::SubGraphSharedPtr> intgraphs =
1011 bottomUpGraph->GetInteriorBlocks(n);
1012 for (i = 0; i < intgraphs.size(); ++i)
1014 int GlobIdOffset = intgraphs[i]->GetIdOffset();
1015 bool SetEdge =
false;
1017 size_t nVert = intgraphs[i]->GetNverts();
1018 for (j = 0; j < nVert; ++j)
1021 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
1023 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
1025 for (k = 0; k < 2; ++k)
1028 elmtid = EdgeIdToElmts[edgeId][k];
1032 auto mapIt = ElmtInBndry.find(elmtid);
1034 if (mapIt != ElmtInBndry.end())
1039 bndgraphs[mapIt->second]->GetIdOffset();
1041 l < bndgraphs[mapIt->second]->GetNverts();
1045 if (HomGraphEdgeIdToEdgeId.count(
1046 GlobIdOffset1 + l) != 0)
1048 AddMeanPressureToEdgeId[elmtid] =
1065 if (SetEdge ==
false)
1069 size_t nVert = intgraphs[i]->GetNverts();
1070 for (j = 0; j < nVert; ++j)
1072 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
1074 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
1075 for (k = 0; k < 2; ++k)
1078 elmtid = EdgeIdToElmts[edgeId][k];
1091 if (AddMeanPressureToEdgeId[elmtid] == -1)
1093 AddMeanPressureToEdgeId[elmtid] = defedge;
#define ASSERTL0(condition, msg)
CoupledLocalToGlobalC0ContMap(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph, const SpatialDomains::BoundaryConditionsSharedPtr &boundaryConditions, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const MultiRegions::ExpListSharedPtr &pressure, const size_t nz_loc, const bool CheeckForSingularSys=true)
void FindEdgeIdToAddMeanPressure(std::vector< std::map< int, int > > &ReorderedGraphVertId, size_t &nel, const LocalRegions::ExpansionVector &locExpVector, size_t &edgeId, size_t &vertId, int &firstNonDirGraphVertId, std::map< int, int > &IsDirEdgeDof, MultiRegions::BottomUpSubStructuredGraphSharedPtr &bottomUpGraph, Array< OneD, int > &AddMeanPressureToEdgeId)
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Constructs mappings for the C0 scalar continuous Galerkin formulation.
int CreateGraph(const ExpList &locExp, const BndCondExp &bndCondExp, const Array< OneD, const BndCond > &bndConditions, const bool checkIfSystemSingular, const PeriodicMap &periodicVerts, const PeriodicMap &periodicEdges, const PeriodicMap &periodicFaces, DofGraph &graph, BottomUpSubStructuredGraphSharedPtr &bottomUpGraph, std::set< int > &extraDirVerts, std::set< int > &extraDirEdges, int &firstNonDirGraphVertId, int &nExtraDirichlet, int mdswitch=1)
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
int m_numLocalCoeffs
Total number of local coefficients.
bool m_signChange
Flag indicating if modes require sign reversal.
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
int m_numGlobalCoeffs
Total number of global coefficients.
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
LibUtilities::SessionReaderSharedPtr m_session
Session object.
int m_numLocalBndCoeffs
Number of local boundary coefficients.
AssemblyMapSharedPtr m_nextLevelLocalToGlobalMap
Map from the patches of the previous level to the patches of the current level.
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
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.
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
int m_numPatches
The number of patches (~elements) in the current level.
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.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int NumBndryCoeffs(void) const
int GetVertexMap(const int localVertexId, bool useCoeffPacking=false)
int GetNverts() const
This function returns the number of vertices of the expansion domain.
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ eModified_A
Principle Modified Functions .
std::shared_ptr< SegExp > SegExpSharedPtr
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
std::vector< ExpansionSharedPtr > ExpansionVector
@ eDirectMultiLevelStaticCond
std::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
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::map< int, std::vector< PeriodicEntity > > PeriodicMap
static const NekDouble kNekZeroTol
std::shared_ptr< BoundaryConditions > BoundaryConditionsSharedPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
scalarT< T > abs(scalarT< T > in)