52 CoupledLocalToGlobalC0ContMap::CoupledLocalToGlobalC0ContMap(
59 const bool CheckforSingularSys):
69 int nEdgeInteriorCoeffs;
70 int firstNonDirGraphVertId;
71 int nLocBndCondDofs = 0;
72 int nLocDirBndCondDofs = 0;
73 int nExtraDirichlet = 0;
80 int nvel = fields.num_elements();
84 int nel = fields[0]->GetNumElmts();
89 vector<map<int,int> > ReorderedGraphVertId(3);
91 int staticCondLevel = 0;
93 if(CheckforSingularSys)
110 fields[0]->GetPeriodicEntities(periodicVerts,periodicEdges,periodicFaces);
116 for(i = 0; i < nvel; ++i)
118 bndConditionsVec[i] = fields[i]->GetBndConditions();
121 map<int,int> IsDirVertDof;
122 map<int,int> IsDirEdgeDof;
125 for(j = 0; j < bndCondExp.num_elements(); ++j)
127 map<int,int> BndExpVids;
129 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
133 BndExpVids[g->GetVid(0)] = g->GetVid(0);
134 BndExpVids[g->GetVid(1)] = g->GetVid(1);
137 for(i = 0; i < nvel; ++i)
142 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
144 IsDirEdgeDof[bndCondExp[j]->GetExp(k)
146 ->GetGeom1D()->GetGlobalID()] += 1;
153 for(
auto &mapIt : BndExpVids)
155 id = IsDirVertDof[mapIt.second]+1;
156 IsDirVertDof[mapIt.second] = (
id > nvel)?nvel:
id;
165 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
169 = bndCondExp[j]->GetExp(k)
171 locnorm = loc_exp->GetLeftAdjacentElementExp()->GetEdgeNormal(loc_exp->GetLeftAdjacentElementEdge());
174 int ndir = locnorm.num_elements();
177 for(
int l = 0; l < locnorm[0].num_elements(); ++l)
208 for(i = 0; i < bndConditionsVec[0].num_elements(); ++i)
212 id = bndCondExp[i]->GetExp(0)
219 ASSERTL0(
id != -1,
" Did not find an edge to attach singular pressure degree of freedom");
223 for(i = 0; i < nel; ++i)
225 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
228 ->GetGeom2D())->GetEid(j);
232 AddMeanPressureToEdgeId[i] = id;
237 if(AddMeanPressureToEdgeId[i] != -1)
245 for(i = 0; i < nel; ++i)
247 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
250 ->GetGeom2D())->GetVid(j);
251 if(Dofs[0].count(vertId) == 0)
253 Dofs[0][vertId] = nvel*nz_loc;
256 if(IsDirVertDof.count(vertId) != 0)
258 Dofs[0][vertId] -= IsDirVertDof[vertId]*nz_loc;
263 ->GetGeom2D())->GetEid(j);
264 if(Dofs[1].count(edgeId) == 0)
266 Dofs[1][edgeId] = nvel*(locExpVector[i]->GetEdgeNcoeffs(j)-2)*nz_loc;
270 if(IsDirEdgeDof.count(edgeId) != 0)
272 Dofs[1][edgeId] -= IsDirEdgeDof[edgeId]*nz_loc*(locExpVector[i]->GetEdgeNcoeffs(j)-2);
277 set<int> extraDirVerts, extraDirEdges;
279 CreateGraph(*fields[0], bndCondExp, bndConditionsVec,
false,
280 periodicVerts, periodicEdges, periodicFaces,
281 ReorderedGraphVertId, bottomUpGraph, extraDirVerts,
282 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, 4);
307 edgeId, vertId, firstNonDirGraphVertId, IsDirEdgeDof,
309 AddMeanPressureToEdgeId);
315 for(i = 0; i < nel; ++i)
317 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
320 ->GetGeom2D())->GetEid(j);
322 if(IsDirEdgeDof.count(edgeId) == 0)
326 if(AddMeanPressureToEdgeId[i] == -1)
328 AddMeanPressureToEdgeId[i] = edgeId;
332 ASSERTL0((AddMeanPressureToEdgeId[i] != -1),
"Did not determine " 333 "an edge to attach mean pressure dof");
335 Dofs[1][AddMeanPressureToEdgeId[i]] += nz_loc;
338 map<int,int> pressureEdgeOffset;
343 for(i = 0; i < bndCondExp.num_elements(); i++)
345 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
347 bndSegExp = bndCondExp[i]->GetExp(j)
349 for(k = 0; k < nvel; ++k)
353 nLocDirBndCondDofs += bndSegExp->
GetNcoeffs()*nz_loc;
358 nLocBndCondDofs += bndSegExp->GetNcoeffs()*nz_loc;
384 Array<OneD, int> graphVertOffset(nvel*nz_loc*(ReorderedGraphVertId[0].size() + ReorderedGraphVertId[1].size()),0);
385 graphVertOffset[0] = 0;
389 for(i = 0; i < nel; ++i)
393 for(j = 0; j < locExpansion->GetNedges(); ++j)
397 ->GetGeom2D())->GetEid(j);
399 ->GetGeom2D())->GetVid(j);
401 for(k = 0; k < nvel*nz_loc; ++k)
403 graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+k] = 1;
404 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+k] = (nEdgeCoeffs-2);
407 bType = locExpansion->GetEdgeBasisType(j);
409 if( (nEdgeCoeffs >= 4)&&
419 for(i = 0; i < nel; ++i)
421 graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]]+1)*nvel*nz_loc-1] += nz_loc;
430 map<int,int> DirVertChk;
432 for(i = 0; i < bndConditionsVec[0].num_elements(); ++i)
435 for(j = 0; j < nvel; ++j)
444 if((cnt > 0)&&(cnt < nvel))
446 for(j = 0; j < nvel; ++j)
452 for(k = 0; k < bndCondExp[i]->GetNumElmts(); ++k)
455 id = bndCondExp[i]->GetExp(k)
457 ->GetGeom1D()->GetVid(0);
458 if(DirVertChk.count(
id*nvel+j) == 0)
460 DirVertChk[
id*nvel+j] = 1;
461 for(n = 0; n < nz_loc; ++n)
463 graphVertOffset[ReorderedGraphVertId[0][id]*nvel*nz_loc+j*nz_loc + n] *= -1;
467 id = bndCondExp[i]->GetExp(k)
469 ->GetGeom1D()->GetVid(1);
470 if(DirVertChk.count(
id*nvel+j) == 0)
472 DirVertChk[
id*nvel+j] = 1;
473 for(n = 0; n < nz_loc; ++n)
475 graphVertOffset[ReorderedGraphVertId[0][id]*nvel*nz_loc+j*nz_loc+n] *= -1;
480 id = bndCondExp[i]->GetExp(k)
482 ->GetGeom1D()->GetGlobalID();
483 for(n = 0; n < nz_loc; ++n)
485 graphVertOffset[ReorderedGraphVertId[1][id]*nvel*nz_loc+j*nz_loc +n] *= -1;
496 for(i = 0; i < firstNonDirGraphVertId*nvel*nz_loc; ++i)
498 diff = abs(graphVertOffset[i]);
499 graphVertOffset[i] = cnt;
504 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.num_elements(); ++i)
506 if(graphVertOffset[i] < 0)
508 diff = -graphVertOffset[i];
509 graphVertOffset[i] = -cnt;
518 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.num_elements(); ++i)
520 if(graphVertOffset[i] >= 0)
522 diff = graphVertOffset[i];
523 graphVertOffset[i] = cnt;
530 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.num_elements(); ++i)
532 if(graphVertOffset[i] < 0)
534 graphVertOffset[i] = -graphVertOffset[i];
545 for(i = 0; i < nel; ++i)
572 for(i = 0; i < nel; ++i)
575 m_numLocalIntCoeffsPerPatch[i] = (
unsigned int) nz_loc*(pressure->GetExp(i)->GetNcoeffs()-1);
594 for(i = 0; i < nel; ++i)
604 map<int,int> inv_bmap;
605 locExpansion->GetBoundaryMap(bmap);
606 for(j = 0; j < bmap.num_elements(); ++j)
608 inv_bmap[bmap[j]] = j;
612 for(j = 0; j < locExpansion->GetNedges(); ++j)
614 nEdgeInteriorCoeffs = locExpansion->GetEdgeNcoeffs(j)-2;
616 ->GetGeom2D())->GetEorient(j);
618 ->GetGeom2D())->GetEid(j);
620 ->GetGeom2D())->GetVid(j);
622 auto pIt = periodicEdges.find(meshEdgeId);
627 if (pIt != periodicEdges.end())
629 pair<int, StdRegions::Orientation> idOrient =
631 meshEdgeId, edgeOrient, pIt->second);
632 edgeOrient = idOrient.second;
635 locExpansion->GetEdgeInteriorMap(j,edgeOrient,edgeInteriorMap,edgeInteriorSign);
638 for(nv = 0; nv < nvel*nz_loc; ++nv)
640 m_localToGlobalMap[cnt+nv*velnbndry+inv_bmap[locExpansion->GetVertexMap(j)]] = graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+ nv];
642 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
644 m_localToGlobalMap[cnt+nv*velnbndry+inv_bmap[edgeInteriorMap[k]]] = graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+nv]+k;
651 for(nv = 0; nv < nvel*nz_loc; ++nv)
653 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
655 m_localToGlobalSign[cnt+nv*velnbndry + inv_bmap[edgeInteriorMap[k]]] = (
NekDouble) edgeInteriorSign[k];
662 nEdgeInteriorCoeffs = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]])*nvel*nz_loc+1] - graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]])*nvel*nz_loc];
664 int psize = pressure->GetExp(i)->GetNcoeffs();
665 for(n = 0; n < nz_loc; ++n)
667 m_localToGlobalMap[cnt + nz_loc*nvel*velnbndry + n*psize] = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]]+1)*nvel*nz_loc-1]+nEdgeInteriorCoeffs + pressureEdgeOffset[AddMeanPressureToEdgeId[i]];
669 pressureEdgeOffset[AddMeanPressureToEdgeId[i]] += 1;
672 cnt += (velnbndry*nvel+ psize)*nz_loc;
677 for(nv = 0; nv < nvel; ++nv)
679 for(i = 0; i < bndCondExp.num_elements(); i++)
686 for(n = 0; n < nz_loc; ++n)
689 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
691 bndSegExp = bndCondExp[i]->GetExp(j)
694 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
695 for(k = 0; k < 2; k++)
697 meshVertId = (bndSegExp->GetGeom1D())->GetVid(k);
698 m_bndCondCoeffsToGlobalCoeffsMap[cnt+bndSegExp->
GetVertexMap(k)] = graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+nv*nz_loc+n];
701 meshEdgeId = (bndSegExp->GetGeom1D())->GetGlobalID();
703 nEdgeCoeffs = bndSegExp->GetNcoeffs();
704 for(k = 0; k < nEdgeCoeffs; k++)
706 if(m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] == -1)
708 m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] =
709 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+nv*nz_loc+n]+bndEdgeCnt;
713 ncoeffcnt += nEdgeCoeffs;
755 Dofs[0].size()+Dofs[1].size()-firstNonDirGraphVertId);
756 for(i = 0; i < locExpVector.size(); ++i)
758 locExpansion = locExpVector[i]
760 for(j = 0; j < locExpansion->GetNverts(); ++j)
762 meshEdgeId = (locExpansion
764 ->GetGeom2D())->GetEid(j);
765 meshVertId = (locExpansion
767 ->GetGeom2D())->GetVid(j);
769 if(ReorderedGraphVertId[0][meshVertId] >=
770 firstNonDirGraphVertId)
772 vwgts_perm[ReorderedGraphVertId[0][meshVertId]-
773 firstNonDirGraphVertId] =
777 if(ReorderedGraphVertId[1][meshEdgeId] >=
778 firstNonDirGraphVertId)
780 vwgts_perm[ReorderedGraphVertId[1][meshEdgeId]-
781 firstNonDirGraphVertId] =
787 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
799 int &edgeId,
int &vertId,
int &firstNonDirGraphVertId, map<int,int> &IsDirEdgeDof,
808 map<int,int> HomGraphEdgeIdToEdgeId;
810 for(i = 0; i < nel; ++i)
812 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
815 ->GetGeom2D())->GetEid(j);
818 if((ReorderedGraphVertId[1][edgeId] >= firstNonDirGraphVertId)
819 && (IsDirEdgeDof.count(edgeId) == 0))
821 HomGraphEdgeIdToEdgeId[ReorderedGraphVertId[1][edgeId]-firstNonDirGraphVertId] = edgeId;
823 if(EdgeIdToElmts[edgeId][0] == -1)
825 EdgeIdToElmts[edgeId][0] = i;
829 EdgeIdToElmts[edgeId][1] = i;
837 int nlevels = bottomUpGraph->GetNlevels();
843 vector<MultiRegions::SubGraphSharedPtr> bndgraphs = bottomUpGraph->GetInteriorBlocks(nlevels);
844 for(i = 0; i < bndgraphs.size(); ++i)
846 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
848 for(j = 0; j < bndgraphs[i]->GetNverts(); ++j)
851 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
853 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
868 for(
int n = 1; n < nlevels; ++n)
872 vector<MultiRegions::SubGraphSharedPtr> bndgraphs = bottomUpGraph->GetInteriorBlocks(n+1);
875 map<int,int> ElmtInBndry;
877 for(i = 0; i < bndgraphs.size(); ++i)
879 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
881 for(j = 0; j < bndgraphs[i]->GetNverts(); ++j)
884 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
886 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
888 if(EdgeIdToElmts[edgeId][0] != -1)
890 ElmtInBndry[EdgeIdToElmts[edgeId][0]] = i;
892 if(EdgeIdToElmts[edgeId][1] != -1)
894 ElmtInBndry[EdgeIdToElmts[edgeId][1]] = i;
903 vector<MultiRegions::SubGraphSharedPtr> intgraphs = bottomUpGraph->GetInteriorBlocks(n);
904 for(i = 0; i < intgraphs.size(); ++i)
906 int GlobIdOffset = intgraphs[i]->GetIdOffset();
907 bool SetEdge =
false;
909 for(j = 0; j < intgraphs[i]->GetNverts(); ++j)
912 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
914 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
916 for(k = 0; k < 2; ++k)
919 elmtid = EdgeIdToElmts[edgeId][k];
923 auto mapIt = ElmtInBndry.find(elmtid);
925 if(mapIt != ElmtInBndry.end())
928 int GlobIdOffset1 = bndgraphs[mapIt->second]->GetIdOffset();
929 for(
int l = 0; l < bndgraphs[mapIt->second]->GetNverts(); ++l)
932 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset1+l) != 0)
941 AddMeanPressureToEdgeId[elmtid] = defedge;
963 for(j = 0; j < intgraphs[i]->GetNverts(); ++j)
965 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
967 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
968 for(k = 0; k < 2; ++k)
971 elmtid = EdgeIdToElmts[edgeId][k];
984 if(AddMeanPressureToEdgeId[elmtid] == -1)
986 AddMeanPressureToEdgeId[elmtid] = defedge;
#define ASSERTL0(condition, msg)
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
bool m_systemSingular
Flag indicating if the system is singular or not.
bool m_signChange
Flag indicating if modes require sign reversal.
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
int NumBndryCoeffs(void) const
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
std::shared_ptr< BoundaryConditions > BoundaryConditionsSharedPtr
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)
Principle Modified Functions .
int m_numLocalCoeffs
Total number of local coefficients.
std::shared_ptr< StdExpansion2D > StdExpansion2DSharedPtr
std::vector< ExpansionSharedPtr > ExpansionVector
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
AssemblyMapSharedPtr m_nextLevelLocalToGlobalMap
Map from the patches of the previous level to the patches of the current level.
int GetEdgeNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th edge.
static const NekDouble kNekZeroTol
int GetVertexMap(const int localVertexId, bool useCoeffPacking=false)
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Principle Modified Functions .
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
Array< OneD, int > m_localToGlobalBndMap
Integer map of local boundary coeffs to global space.
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
Array< OneD, int > m_bndCondCoeffsToGlobalCoeffsMap
Integer map of bnd cond coeffs to global coefficients.
int m_numLocalBndCoeffs
Number of local boundary coefficients.
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
std::shared_ptr< SegExp > SegExpSharedPtr
LibUtilities::SessionReaderSharedPtr m_session
Session object.
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
void FindEdgeIdToAddMeanPressure(std::vector< std::map< int, int > > &ReorderedGraphVertId, int &nel, const LocalRegions::ExpansionVector &locExpVector, int &edgeId, int &vertId, int &firstNonDirGraphVertId, std::map< int, int > &IsDirEdgeDof, MultiRegions::BottomUpSubStructuredGraphSharedPtr &bottomUpGraph, Array< OneD, int > &AddMeanPressureToEdgeId)
Constructs mappings for the C0 scalar continuous Galerkin formulation.
int m_numGlobalCoeffs
Total number of global coefficients.
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< Expansion1D > Expansion1DSharedPtr
std::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
std::shared_ptr< SessionReader > SessionReaderSharedPtr
int m_numPatches
The number of patches (~elements) in the current level.