53 CoupledLocalToGlobalC0ContMap::CoupledLocalToGlobalC0ContMap(
59 const bool CheckforSingularSys)
62 boost::ignore_unused(graph, boundaryConditions);
65 size_t cnt = 0, offset = 0;
71 size_t nEdgeInteriorCoeffs;
72 int firstNonDirGraphVertId;
73 size_t nLocBndCondDofs = 0;
74 size_t nLocDirBndCondDofs = 0;
75 int nExtraDirichlet = 0;
82 size_t nvel = fields.size();
86 size_t nel = fields[0]->GetNumElmts();
91 vector<map<int, int>> ReorderedGraphVertId(3);
93 int staticCondLevel = 0;
95 if (CheckforSingularSys)
112 fields[0]->GetPeriodicEntities(periodicVerts, periodicEdges, periodicFaces);
115 fields[0]->GetBndCondExpansions();
118 bndConditionsVec(nvel);
119 for (i = 0; i < nvel; ++i)
121 bndConditionsVec[i] = fields[i]->GetBndConditions();
124 map<int, int> IsDirVertDof;
125 map<int, int> IsDirEdgeDof;
128 for (j = 0; j < bndCondExp.size(); ++j)
130 map<int, int> BndExpVids;
132 for (k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
138 BndExpVids[g->GetVid(0)] = g->GetVid(0);
139 BndExpVids[g->GetVid(1)] = g->GetVid(1);
142 for (i = 0; i < nvel; ++i)
144 if (bndConditionsVec[i][j]->GetBoundaryConditionType() ==
148 for (k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
150 IsDirEdgeDof[bndCondExp[j]
154 ->GetGlobalID()] += 1;
160 for (
auto &mapIt : BndExpVids)
162 id = IsDirVertDof[mapIt.second] + 1;
163 IsDirVertDof[mapIt.second] = (
id > (int)nvel) ? nvel : id;
172 for (k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
180 loc_exp->GetLeftAdjacentElementExp()->GetTraceNormal(
181 loc_exp->GetLeftAdjacentElementTrace());
183 size_t ndir = locnorm.size();
187 for (
size_t l = 0; l < locnorm[0].size(); ++l)
208 size_t edgeId, vertId;
217 for (i = 0; i < bndConditionsVec[0].size(); ++i)
219 if (bndConditionsVec[nvel - 1][i]->GetBoundaryConditionType() ==
231 ASSERTL0(
id != -1,
" Did not find an edge to attach singular pressure "
232 "degree of freedom");
236 for (i = 0; i < nel; ++i)
238 for (j = 0; j < (size_t)locExpVector[i]->GetNverts(); ++j)
240 edgeId = (locExpVector[i]
245 if ((
int)edgeId == id)
247 AddMeanPressureToEdgeId[i] = id;
252 if (AddMeanPressureToEdgeId[i] != -1)
259 for (i = 0; i < nel; ++i)
261 for (j = 0; j < (size_t)locExpVector[i]->GetNverts(); ++j)
266 if (Dofs[0].count(vertId) == 0)
268 Dofs[0][vertId] = nvel * nz_loc;
272 if (IsDirVertDof.count(vertId) != 0)
274 Dofs[0][vertId] -= IsDirVertDof[vertId] * nz_loc;
281 if (Dofs[1].count(edgeId) == 0)
284 nvel * (locExpVector[i]->GetTraceNcoeffs(j) - 2) * nz_loc;
289 if (IsDirEdgeDof.count(edgeId) != 0)
291 Dofs[1][edgeId] -= IsDirEdgeDof[edgeId] * nz_loc *
292 (locExpVector[i]->GetTraceNcoeffs(j) - 2);
297 set<int> extraDirVerts, extraDirEdges;
299 CreateGraph(*fields[0], bndCondExp, bndConditionsVec,
false, periodicVerts,
300 periodicEdges, periodicFaces, ReorderedGraphVertId,
301 bottomUpGraph, extraDirVerts, extraDirEdges,
302 firstNonDirGraphVertId, nExtraDirichlet, 4);
326 edgeId, vertId, firstNonDirGraphVertId,
327 IsDirEdgeDof, bottomUpGraph,
328 AddMeanPressureToEdgeId);
334 for (i = 0; i < nel; ++i)
336 for (j = 0; j < (size_t)locExpVector[i]->GetNverts(); ++j)
342 if (IsDirEdgeDof.count(edgeId) == 0)
346 if (AddMeanPressureToEdgeId[i] == -1)
348 AddMeanPressureToEdgeId[i] = edgeId;
352 ASSERTL0((AddMeanPressureToEdgeId[i] != -1),
354 "an edge to attach mean pressure dof");
356 Dofs[1][AddMeanPressureToEdgeId[i]] += nz_loc;
359 map<int, int> pressureEdgeOffset;
364 for (i = 0; i < bndCondExp.size(); i++)
366 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
369 for (k = 0; k < nvel; ++k)
371 if (bndConditionsVec[k][i]->GetBoundaryConditionType() ==
374 nLocDirBndCondDofs += bndSegExp->
GetNcoeffs() * nz_loc;
377 if (bndConditionsVec[k][i]->GetBoundaryConditionType() !=
380 nLocBndCondDofs += bndSegExp->GetNcoeffs() * nz_loc;
408 (ReorderedGraphVertId[0].size() + ReorderedGraphVertId[1].size()),
410 graphVertOffset[0] = 0;
414 for (i = 0; i < nel; ++i)
418 for (j = 0; j < (size_t)locExpansion->GetNtraces(); ++j)
421 meshEdgeId = (locExpansion->GetGeom2D())->GetEid(j);
422 meshVertId = (locExpansion->GetGeom2D())->GetVid(j);
424 for (k = 0; k < nvel * nz_loc; ++k)
426 graphVertOffset[ReorderedGraphVertId[0][meshVertId] * nvel *
429 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId] * nvel *
431 k] = (nEdgeCoeffs - 2);
434 bType = locExpansion->GetBasisType(0);
444 for (i = 0; i < nel; ++i)
446 graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]] +
459 map<int, int> DirVertChk;
461 for (i = 0; i < bndConditionsVec[0].size(); ++i)
464 for (j = 0; j < nvel; ++j)
466 if (bndConditionsVec[j][i]->GetBoundaryConditionType() ==
474 if ((cnt > 0) && (cnt < nvel))
476 for (j = 0; j < nvel; ++j)
478 if (bndConditionsVec[j][i]->GetBoundaryConditionType() ==
483 for (k = 0; k < bndCondExp[i]->GetNumElmts(); ++k)
491 if (DirVertChk.count(
id * nvel + j) == 0)
493 DirVertChk[
id * nvel + j] = 1;
494 for (n = 0; n < nz_loc; ++n)
496 graphVertOffset[ReorderedGraphVertId[0][id] *
498 j * nz_loc + n] *= -1;
507 if (DirVertChk.count(
id * nvel + j) == 0)
509 DirVertChk[
id * nvel + j] = 1;
510 for (n = 0; n < nz_loc; ++n)
512 graphVertOffset[ReorderedGraphVertId[0][id] *
514 j * nz_loc + n] *= -1;
524 for (n = 0; n < nz_loc; ++n)
526 graphVertOffset[ReorderedGraphVertId[1][id] * nvel *
528 j * nz_loc + n] *= -1;
538 for (i = 0; i < firstNonDirGraphVertId * nvel * nz_loc; ++i)
540 diff =
abs(graphVertOffset[i]);
541 graphVertOffset[i] = cnt;
546 for (i = firstNonDirGraphVertId * nvel * nz_loc; i < graphVertOffset.size();
549 if (graphVertOffset[i] < 0)
551 diff = -graphVertOffset[i];
552 graphVertOffset[i] = -cnt;
561 for (i = firstNonDirGraphVertId * nvel * nz_loc; i < graphVertOffset.size();
564 if (graphVertOffset[i] >= 0)
566 diff = graphVertOffset[i];
567 graphVertOffset[i] = cnt;
574 for (i = firstNonDirGraphVertId * nvel * nz_loc; i < graphVertOffset.size();
577 if (graphVertOffset[i] < 0)
579 graphVertOffset[i] = -graphVertOffset[i];
589 for (i = 0; i < nel; ++i)
592 nz_loc * (nvel * locExpVector[i]->NumBndryCoeffs() + 1);
615 for (i = 0; i < nel; ++i)
618 (
unsigned int)nz_loc *
619 (nvel * locExpVector[i]->NumBndryCoeffs() + 1);
621 (
unsigned int)nz_loc * (
pressure->GetExp(i)->GetNcoeffs() - 1);
632 for (i = 0; i < nel; ++i)
634 for (j = 0; j < nz_loc * (nvel * locExpVector[i]->NumBndryCoeffs());
640 for (n = 0; n < nz_loc; ++n)
643 for (j = 1; j < (size_t)
pressure->GetExp(i)->GetNcoeffs(); ++j)
660 size_t nv, velnbndry;
665 for (i = 0; i < nel; ++i)
674 map<int, int> inv_bmap;
675 locExpansion->GetBoundaryMap(bmap);
676 for (j = 0; j < bmap.size(); ++j)
678 inv_bmap[bmap[j]] = j;
682 for (j = 0; j < (size_t)locExpansion->GetNtraces(); ++j)
684 nEdgeInteriorCoeffs = locExpansion->GetTraceNcoeffs(j) - 2;
685 edgeOrient = (locExpansion->GetGeom())->GetEorient(j);
686 meshEdgeId = (locExpansion->GetGeom())->GetEid(j);
687 meshVertId = (locExpansion->GetGeom())->GetVid(j);
689 auto pIt = periodicEdges.find(meshEdgeId);
694 if (pIt != periodicEdges.end())
696 pair<int, StdRegions::Orientation> idOrient =
699 edgeOrient = idOrient.second;
702 locExpansion->GetTraceInteriorToElementMap(
703 j, edgeInteriorMap, edgeInteriorSign, edgeOrient);
706 for (nv = 0; nv < nvel * nz_loc; ++nv)
709 inv_bmap[locExpansion->GetVertexMap(j)]] =
710 graphVertOffset[ReorderedGraphVertId[0][meshVertId] * nvel *
715 for (k = 0; k < nEdgeInteriorCoeffs; ++k)
718 inv_bmap[edgeInteriorMap[k]]] =
719 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId] *
729 for (nv = 0; nv < nvel * nz_loc; ++nv)
731 for (k = 0; k < nEdgeInteriorCoeffs; ++k)
734 inv_bmap[edgeInteriorMap[k]]] =
743 nEdgeInteriorCoeffs =
744 graphVertOffset[(ReorderedGraphVertId[1]
745 [AddMeanPressureToEdgeId[i]]) *
748 graphVertOffset[(ReorderedGraphVertId[1]
749 [AddMeanPressureToEdgeId[i]]) *
752 size_t psize =
pressure->GetExp(i)->GetNcoeffs();
753 for (n = 0; n < nz_loc; ++n)
757 [(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]] + 1) *
760 nEdgeInteriorCoeffs +
761 pressureEdgeOffset[AddMeanPressureToEdgeId[i]];
763 pressureEdgeOffset[AddMeanPressureToEdgeId[i]] += 1;
766 cnt += (velnbndry * nvel + psize) * nz_loc;
771 for (nv = 0; nv < nvel; ++nv)
773 for (i = 0; i < bndCondExp.size(); i++)
775 if (bndConditionsVec[nv][i]->GetBoundaryConditionType() ==
781 for (n = 0; n < nz_loc; ++n)
784 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
789 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
790 for (k = 0; k < 2; k++)
792 meshVertId = (bndSegExp->GetGeom1D())->GetVid(k);
795 graphVertOffset[ReorderedGraphVertId[0]
801 meshEdgeId = (bndSegExp->GetGeom1D())->GetGlobalID();
803 nEdgeCoeffs = bndSegExp->GetNcoeffs();
804 for (k = 0; k < nEdgeCoeffs; k++)
810 [ReorderedGraphVertId[1][meshEdgeId] *
817 ncoeffcnt += nEdgeCoeffs;
860 firstNonDirGraphVertId);
861 for (i = 0; i < locExpVector.size(); ++i)
864 size_t nVert = locExpansion->
GetNverts();
865 for (j = 0; j < nVert; ++j)
867 meshEdgeId = (locExpansion->GetGeom2D())->GetEid(j);
868 meshVertId = (locExpansion->GetGeom2D())->GetVid(j);
870 if (ReorderedGraphVertId[0][meshVertId] >=
871 firstNonDirGraphVertId)
873 vwgts_perm[ReorderedGraphVertId[0][meshVertId] -
874 firstNonDirGraphVertId] =
878 if (ReorderedGraphVertId[1][meshEdgeId] >=
879 firstNonDirGraphVertId)
881 vwgts_perm[ReorderedGraphVertId[1][meshEdgeId] -
882 firstNonDirGraphVertId] =
888 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
898 vector<map<int, int>> &ReorderedGraphVertId,
size_t &nel,
900 size_t &vertId,
int &firstNonDirGraphVertId, map<int, int> &IsDirEdgeDof,
904 boost::ignore_unused(vertId);
910 map<int, int> HomGraphEdgeIdToEdgeId;
912 for (i = 0; i < nel; ++i)
914 size_t nVert = locExpVector[i]->GetNverts();
915 for (j = 0; j < nVert; ++j)
922 if ((ReorderedGraphVertId[1][edgeId] >= firstNonDirGraphVertId) &&
923 (IsDirEdgeDof.count(edgeId) == 0))
925 HomGraphEdgeIdToEdgeId[ReorderedGraphVertId[1][edgeId] -
926 firstNonDirGraphVertId] = edgeId;
928 if (EdgeIdToElmts[edgeId][0] == -1)
930 EdgeIdToElmts[edgeId][0] = i;
934 EdgeIdToElmts[edgeId][1] = i;
942 size_t nlevels = bottomUpGraph->GetNlevels();
948 vector<MultiRegions::SubGraphSharedPtr> bndgraphs =
949 bottomUpGraph->GetInteriorBlocks(nlevels);
950 for (i = 0; i < bndgraphs.size(); ++i)
952 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
953 size_t nVert = bndgraphs[i]->GetNverts();
955 for (j = 0; j < nVert; ++j)
958 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
960 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
975 for (
size_t n = 1; n < nlevels; ++n)
979 vector<MultiRegions::SubGraphSharedPtr> bndgraphs =
980 bottomUpGraph->GetInteriorBlocks(n + 1);
983 map<int, int> ElmtInBndry;
985 for (i = 0; i < bndgraphs.size(); ++i)
987 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
988 size_t nVert = bndgraphs[i]->GetNverts();
990 for (j = 0; j < nVert; ++j)
993 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
995 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
997 if (EdgeIdToElmts[edgeId][0] != -1)
999 ElmtInBndry[EdgeIdToElmts[edgeId][0]] = i;
1001 if (EdgeIdToElmts[edgeId][1] != -1)
1003 ElmtInBndry[EdgeIdToElmts[edgeId][1]] = i;
1012 vector<MultiRegions::SubGraphSharedPtr> intgraphs =
1013 bottomUpGraph->GetInteriorBlocks(n);
1014 for (i = 0; i < intgraphs.size(); ++i)
1016 int GlobIdOffset = intgraphs[i]->GetIdOffset();
1017 bool SetEdge =
false;
1019 size_t nVert = intgraphs[i]->GetNverts();
1020 for (j = 0; j < nVert; ++j)
1023 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
1025 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
1027 for (k = 0; k < 2; ++k)
1030 elmtid = EdgeIdToElmts[edgeId][k];
1034 auto mapIt = ElmtInBndry.find(elmtid);
1036 if (mapIt != ElmtInBndry.end())
1041 bndgraphs[mapIt->second]->GetIdOffset();
1043 l < bndgraphs[mapIt->second]->GetNverts();
1047 if (HomGraphEdgeIdToEdgeId.count(
1048 GlobIdOffset1 + l) != 0)
1060 AddMeanPressureToEdgeId[elmtid] =
1078 if (SetEdge ==
false)
1082 size_t nVert = intgraphs[i]->GetNverts();
1083 for (j = 0; j < nVert; ++j)
1085 if (HomGraphEdgeIdToEdgeId.count(GlobIdOffset + j) != 0)
1087 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset + j];
1088 for (k = 0; k < 2; ++k)
1091 elmtid = EdgeIdToElmts[edgeId][k];
1104 if (AddMeanPressureToEdgeId[elmtid] == -1)
1106 AddMeanPressureToEdgeId[elmtid] = defedge;
#define ASSERTL0(condition, msg)
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
The above copyright notice and this permission notice shall be included.
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)