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.size();
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.size(); ++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()->
172 GetTraceNormal(loc_exp->GetLeftAdjacentElementTrace());
174 int ndir = locnorm.size();
177 for(
int l = 0; l < locnorm[0].size(); ++l)
208 for(i = 0; i < bndConditionsVec[0].size(); ++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]->
267 GetTraceNcoeffs(j)-2)*nz_loc;
271 if(IsDirEdgeDof.count(edgeId) != 0)
273 Dofs[1][edgeId] -= IsDirEdgeDof[edgeId]*nz_loc*(locExpVector[i]->
274 GetTraceNcoeffs(j)-2);
279 set<int> extraDirVerts, extraDirEdges;
281 CreateGraph(*fields[0], bndCondExp, bndConditionsVec,
false,
282 periodicVerts, periodicEdges, periodicFaces,
283 ReorderedGraphVertId, bottomUpGraph, extraDirVerts,
284 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, 4);
309 edgeId, vertId, firstNonDirGraphVertId, IsDirEdgeDof,
311 AddMeanPressureToEdgeId);
317 for(i = 0; i < nel; ++i)
319 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
322 ->GetGeom2D())->GetEid(j);
324 if(IsDirEdgeDof.count(edgeId) == 0)
328 if(AddMeanPressureToEdgeId[i] == -1)
330 AddMeanPressureToEdgeId[i] = edgeId;
334 ASSERTL0((AddMeanPressureToEdgeId[i] != -1),
"Did not determine "
335 "an edge to attach mean pressure dof");
337 Dofs[1][AddMeanPressureToEdgeId[i]] += nz_loc;
340 map<int,int> pressureEdgeOffset;
345 for(i = 0; i < bndCondExp.size(); i++)
347 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
349 bndSegExp = bndCondExp[i]->GetExp(j)
351 for(k = 0; k < nvel; ++k)
355 nLocDirBndCondDofs += bndSegExp->
GetNcoeffs()*nz_loc;
360 nLocBndCondDofs += bndSegExp->GetNcoeffs()*nz_loc;
386 Array<OneD, int> graphVertOffset(nvel*nz_loc*(ReorderedGraphVertId[0].size() + ReorderedGraphVertId[1].size()),0);
387 graphVertOffset[0] = 0;
391 for(i = 0; i < nel; ++i)
395 for(j = 0; j < locExpansion->GetNtraces(); ++j)
398 meshEdgeId = (locExpansion->GetGeom2D())->GetEid(j);
399 meshVertId = (locExpansion->GetGeom2D())->GetVid(j);
401 for(k = 0; k < nvel*nz_loc; ++k)
403 graphVertOffset[ReorderedGraphVertId[0]
404 [meshVertId]*nvel*nz_loc+k] = 1;
405 graphVertOffset[ReorderedGraphVertId[1]
406 [meshEdgeId]*nvel*nz_loc+k] = (nEdgeCoeffs-2);
409 bType = locExpansion->GetBasisType(0);
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].size(); ++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.size(); ++i)
506 if(graphVertOffset[i] < 0)
508 diff = -graphVertOffset[i];
509 graphVertOffset[i] = -cnt;
518 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.size(); ++i)
520 if(graphVertOffset[i] >= 0)
522 diff = graphVertOffset[i];
523 graphVertOffset[i] = cnt;
530 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.size(); ++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)
586 for(i = 0; i < nel; ++i)
588 for(j = 0; j < nz_loc*(nvel*locExpVector[i]->NumBndryCoeffs()); ++j)
593 for(n = 0; n < nz_loc; ++n)
596 for(j = 1; j <
pressure->GetExp(i)->GetNcoeffs(); ++j)
620 for(i = 0; i < nel; ++i)
629 map<int,int> inv_bmap;
630 locExpansion->GetBoundaryMap(bmap);
631 for(j = 0; j < bmap.size(); ++j)
633 inv_bmap[bmap[j]] = j;
637 for(j = 0; j < locExpansion->GetNtraces(); ++j)
639 nEdgeInteriorCoeffs = locExpansion->GetTraceNcoeffs(j)-2;
640 edgeOrient = (locExpansion->GetGeom())->GetEorient(j);
641 meshEdgeId = (locExpansion->GetGeom())->GetEid(j);
642 meshVertId = (locExpansion->GetGeom())->GetVid(j);
644 auto pIt = periodicEdges.find(meshEdgeId);
649 if (pIt != periodicEdges.end())
651 pair<int, StdRegions::Orientation> idOrient =
653 meshEdgeId, edgeOrient, pIt->second);
654 edgeOrient = idOrient.second;
657 locExpansion->GetTraceInteriorToElementMap(j,edgeInteriorMap,
658 edgeInteriorSign,edgeOrient);
661 for(nv = 0; nv < nvel*nz_loc; ++nv)
664 inv_bmap[locExpansion->GetVertexMap(j)]]
665 = graphVertOffset[ReorderedGraphVertId[0]
666 [meshVertId]*nvel*nz_loc+ nv];
669 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
672 inv_bmap[edgeInteriorMap[k]]] =
673 graphVertOffset[ReorderedGraphVertId[1]
674 [meshEdgeId]*nvel*nz_loc+nv]+k;
681 for(nv = 0; nv < nvel*nz_loc; ++nv)
683 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
686 inv_bmap[edgeInteriorMap[k]]]
695 nEdgeInteriorCoeffs = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]])*nvel*nz_loc+1] - graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]])*nvel*nz_loc];
697 int psize =
pressure->GetExp(i)->GetNcoeffs();
698 for(n = 0; n < nz_loc; ++n)
701 graphVertOffset[(ReorderedGraphVertId[1]
702 [AddMeanPressureToEdgeId[i]]+1)*nvel*nz_loc-1]+
703 nEdgeInteriorCoeffs +
704 pressureEdgeOffset[AddMeanPressureToEdgeId[i]];
706 pressureEdgeOffset[AddMeanPressureToEdgeId[i]] += 1;
709 cnt += (velnbndry*nvel+ psize)*nz_loc;
714 for(nv = 0; nv < nvel; ++nv)
716 for(i = 0; i < bndCondExp.size(); i++)
718 if (bndConditionsVec[nv][i]->GetBoundaryConditionType()==
724 for(n = 0; n < nz_loc; ++n)
727 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
729 bndSegExp = bndCondExp[i]->GetExp(j)
732 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
733 for(k = 0; k < 2; k++)
735 meshVertId = (bndSegExp->GetGeom1D())->GetVid(k);
738 graphVertOffset[ReorderedGraphVertId[0]
739 [meshVertId]*nvel*nz_loc+nv*nz_loc+n];
742 meshEdgeId = (bndSegExp->GetGeom1D())->GetGlobalID();
744 nEdgeCoeffs = bndSegExp->GetNcoeffs();
745 for(k = 0; k < nEdgeCoeffs; k++)
750 graphVertOffset[ReorderedGraphVertId[1]
751 [meshEdgeId]*nvel*nz_loc+nv*nz_loc+n]+bndEdgeCnt;
755 ncoeffcnt += nEdgeCoeffs;
797 Dofs[0].size()+Dofs[1].size()-firstNonDirGraphVertId);
798 for(i = 0; i < locExpVector.size(); ++i)
801 for(j = 0; j < locExpansion->GetNverts(); ++j)
803 meshEdgeId = (locExpansion->GetGeom2D())->GetEid(j);
804 meshVertId = (locExpansion->GetGeom2D())->GetVid(j);
806 if(ReorderedGraphVertId[0][meshVertId] >=
807 firstNonDirGraphVertId)
809 vwgts_perm[ReorderedGraphVertId[0][meshVertId]-
810 firstNonDirGraphVertId] =
814 if(ReorderedGraphVertId[1][meshEdgeId] >=
815 firstNonDirGraphVertId)
817 vwgts_perm[ReorderedGraphVertId[1][meshEdgeId]-
818 firstNonDirGraphVertId] =
824 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
836 int &edgeId,
int &vertId,
int &firstNonDirGraphVertId, map<int,int> &IsDirEdgeDof,
845 map<int,int> HomGraphEdgeIdToEdgeId;
847 for(i = 0; i < nel; ++i)
849 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
852 ->GetGeom2D())->GetEid(j);
855 if((ReorderedGraphVertId[1][edgeId] >= firstNonDirGraphVertId)
856 && (IsDirEdgeDof.count(edgeId) == 0))
858 HomGraphEdgeIdToEdgeId[ReorderedGraphVertId[1][edgeId]-firstNonDirGraphVertId] = edgeId;
860 if(EdgeIdToElmts[edgeId][0] == -1)
862 EdgeIdToElmts[edgeId][0] = i;
866 EdgeIdToElmts[edgeId][1] = i;
874 int nlevels = bottomUpGraph->GetNlevels();
880 vector<MultiRegions::SubGraphSharedPtr> bndgraphs = bottomUpGraph->GetInteriorBlocks(nlevels);
881 for(i = 0; i < bndgraphs.size(); ++i)
883 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
885 for(j = 0; j < bndgraphs[i]->GetNverts(); ++j)
888 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
890 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
905 for(
int n = 1; n < nlevels; ++n)
909 vector<MultiRegions::SubGraphSharedPtr> bndgraphs = bottomUpGraph->GetInteriorBlocks(n+1);
912 map<int,int> ElmtInBndry;
914 for(i = 0; i < bndgraphs.size(); ++i)
916 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
918 for(j = 0; j < bndgraphs[i]->GetNverts(); ++j)
921 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
923 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
925 if(EdgeIdToElmts[edgeId][0] != -1)
927 ElmtInBndry[EdgeIdToElmts[edgeId][0]] = i;
929 if(EdgeIdToElmts[edgeId][1] != -1)
931 ElmtInBndry[EdgeIdToElmts[edgeId][1]] = i;
940 vector<MultiRegions::SubGraphSharedPtr> intgraphs = bottomUpGraph->GetInteriorBlocks(n);
941 for(i = 0; i < intgraphs.size(); ++i)
943 int GlobIdOffset = intgraphs[i]->GetIdOffset();
944 bool SetEdge =
false;
946 for(j = 0; j < intgraphs[i]->GetNverts(); ++j)
949 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
951 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
953 for(k = 0; k < 2; ++k)
956 elmtid = EdgeIdToElmts[edgeId][k];
960 auto mapIt = ElmtInBndry.find(elmtid);
962 if(mapIt != ElmtInBndry.end())
965 int GlobIdOffset1 = bndgraphs[mapIt->second]->GetIdOffset();
966 for(
int l = 0; l < bndgraphs[mapIt->second]->GetNverts(); ++l)
969 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset1+l) != 0)
978 AddMeanPressureToEdgeId[elmtid] = defedge;
1000 for(j = 0; j < intgraphs[i]->GetNverts(); ++j)
1002 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
1004 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
1005 for(k = 0; k < 2; ++k)
1008 elmtid = EdgeIdToElmts[edgeId][k];
1021 if(AddMeanPressureToEdgeId[elmtid] == -1)
1023 AddMeanPressureToEdgeId[elmtid] = defedge;
#define ASSERTL0(condition, msg)
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)
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, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
int m_numLocalCoeffs
Total number of local coefficients.
bool m_signChange
Flag indicating if modes require sign reversal.
int m_numGlobalCoeffs
Total number of global coefficients.
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
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.
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
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_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
int m_numPatches
The number of patches (~elements) in the current level.
Array< OneD, int > m_bndCondIDToGlobalTraceID
Integer map of bnd cond trace number to global trace number.
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
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 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::vector< ExpansionSharedPtr > ExpansionVector
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
@ 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)