58 const bool CheckforSingularSys):
59 AssemblyMapCG(pSession)
68 int nEdgeInteriorCoeffs;
69 int firstNonDirGraphVertId;
70 int nLocBndCondDofs = 0;
71 int nLocDirBndCondDofs = 0;
72 int nExtraDirichlet = 0;
79 int nvel = fields.num_elements();
80 MultiRegions::PeriodicMap::const_iterator pIt;
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;
126 for(j = 0; j < bndCondExp.num_elements(); ++j)
128 map<int,int> BndExpVids;
130 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
134 BndExpVids[g->GetVid(0)] = g->GetVid(0);
135 BndExpVids[g->GetVid(1)] = g->GetVid(1);
138 for(i = 0; i < nvel; ++i)
143 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
145 IsDirEdgeDof[bndCondExp[j]->GetExp(k)
147 ->GetGeom1D()->GetEid()] += 1;
154 for(mapIt = BndExpVids.begin(); mapIt != BndExpVids.end(); mapIt++)
156 id = IsDirVertDof[mapIt->second]+1;
157 IsDirVertDof[mapIt->second] = (
id > nvel)?nvel:
id;
166 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
170 = bndCondExp[j]->GetExp(k)
172 locnorm = loc_exp->GetLeftAdjacentElementExp()->GetEdgeNormal(loc_exp->GetLeftAdjacentElementEdge());
175 int ndir = locnorm.num_elements();
178 for(
int l = 0; l < locnorm[0].num_elements(); ++l)
209 for(i = 0; i < bndConditionsVec[0].num_elements(); ++i)
213 id = bndCondExp[i]->GetExp(0)
220 ASSERTL0(
id != -1,
" Did not find an edge to attach singular pressure degree of freedom");
224 for(i = 0; i < nel; ++i)
226 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
229 ->GetGeom2D())->GetEid(j);
233 AddMeanPressureToEdgeId[i] = id;
238 if(AddMeanPressureToEdgeId[i] != -1)
246 for(i = 0; i < nel; ++i)
248 eid = fields[0]->GetOffset_Elmt_Id(i);
249 for(j = 0; j < locExpVector[eid]->GetNverts(); ++j)
252 ->GetGeom2D())->GetVid(j);
253 if(Dofs[0].count(vertId) == 0)
255 Dofs[0][vertId] = nvel*nz_loc;
258 if(IsDirVertDof.count(vertId) != 0)
260 Dofs[0][vertId] -= IsDirVertDof[vertId]*nz_loc;
265 ->GetGeom2D())->GetEid(j);
266 if(Dofs[1].count(edgeId) == 0)
268 Dofs[1][edgeId] = nvel*(locExpVector[eid]->GetEdgeNcoeffs(j)-2)*nz_loc;
272 if(IsDirEdgeDof.count(edgeId) != 0)
274 Dofs[1][edgeId] -= IsDirEdgeDof[edgeId]*nz_loc*(locExpVector[eid]->GetEdgeNcoeffs(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 eid = fields[0]->GetOffset_Elmt_Id(i);
320 for(j = 0; j < locExpVector[eid]->GetNverts(); ++j)
323 ->GetGeom2D())->GetEid(j);
325 if(IsDirEdgeDof.count(edgeId) == 0)
329 if(AddMeanPressureToEdgeId[eid] == -1)
331 AddMeanPressureToEdgeId[eid] = edgeId;
335 ASSERTL0((AddMeanPressureToEdgeId[eid] != -1),
"Did not determine "
336 "an edge to attach mean pressure dof");
338 Dofs[1][AddMeanPressureToEdgeId[eid]] += nz_loc;
341 map<int,int> pressureEdgeOffset;
346 for(i = 0; i < bndCondExp.num_elements(); i++)
348 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
350 bndSegExp = bndCondExp[i]->GetExp(j)
352 for(k = 0; k < nvel; ++k)
356 nLocDirBndCondDofs += bndSegExp->
GetNcoeffs()*nz_loc;
358 nLocBndCondDofs += bndSegExp->GetNcoeffs()*nz_loc;
383 Array<OneD, int> graphVertOffset(nvel*nz_loc*(ReorderedGraphVertId[0].size() + ReorderedGraphVertId[1].size()),0);
384 graphVertOffset[0] = 0;
388 for(i = 0; i < nel; ++i)
390 eid = fields[0]->GetOffset_Elmt_Id(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()->GetEid();
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)
596 eid = fields[0]->GetOffset_Elmt_Id(i);
605 map<int,int> inv_bmap;
606 locExpansion->GetBoundaryMap(bmap);
607 for(j = 0; j < bmap.num_elements(); ++j)
609 inv_bmap[bmap[j]] = j;
613 for(j = 0; j < locExpansion->GetNedges(); ++j)
615 nEdgeInteriorCoeffs = locExpansion->GetEdgeNcoeffs(j)-2;
617 ->GetGeom2D())->GetEorient(j);
619 ->GetGeom2D())->GetEid(j);
621 ->GetGeom2D())->GetVid(j);
623 pIt = periodicEdges.find(meshEdgeId);
628 if (pIt != periodicEdges.end())
630 pair<int, StdRegions::Orientation> idOrient =
632 meshEdgeId, edgeOrient, pIt->second);
633 edgeOrient = idOrient.second;
636 locExpansion->GetEdgeInteriorMap(j,edgeOrient,edgeInteriorMap,edgeInteriorSign);
639 for(nv = 0; nv < nvel*nz_loc; ++nv)
641 m_localToGlobalMap[cnt+nv*velnbndry+inv_bmap[locExpansion->GetVertexMap(j)]] = graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+ nv];
643 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
645 m_localToGlobalMap[cnt+nv*velnbndry+inv_bmap[edgeInteriorMap[k]]] = graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+nv]+k;
652 for(nv = 0; nv < nvel*nz_loc; ++nv)
654 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
656 m_localToGlobalSign[cnt+nv*velnbndry + inv_bmap[edgeInteriorMap[k]]] = (
NekDouble) edgeInteriorSign[k];
663 nEdgeInteriorCoeffs = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[eid]])*nvel*nz_loc+1] - graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[eid]])*nvel*nz_loc];
665 int psize = pressure->GetExp(eid)->GetNcoeffs();
666 for(n = 0; n < nz_loc; ++n)
668 m_localToGlobalMap[cnt + nz_loc*nvel*velnbndry + n*psize] = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[eid]]+1)*nvel*nz_loc-1]+nEdgeInteriorCoeffs + pressureEdgeOffset[AddMeanPressureToEdgeId[eid]];
670 pressureEdgeOffset[AddMeanPressureToEdgeId[eid]] += 1;
673 cnt += (velnbndry*nvel+ psize)*nz_loc;
678 for(nv = 0; nv < nvel; ++nv)
680 for(i = 0; i < bndCondExp.num_elements(); i++)
682 for(n = 0; n < nz_loc; ++n)
685 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
687 bndSegExp = bndCondExp[i]->GetExp(j)
690 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
691 for(k = 0; k < 2; k++)
693 meshVertId = (bndSegExp->GetGeom1D())->GetVid(k);
694 m_bndCondCoeffsToGlobalCoeffsMap[cnt+bndSegExp->
GetVertexMap(k)] = graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+nv*nz_loc+n];
697 meshEdgeId = (bndSegExp->GetGeom1D())->GetEid();
699 nEdgeCoeffs = bndSegExp->GetNcoeffs();
700 for(k = 0; k < nEdgeCoeffs; k++)
702 if(m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] == -1)
704 m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] =
705 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+nv*nz_loc+n]+bndEdgeCnt;
709 ncoeffcnt += nEdgeCoeffs;
751 Dofs[0].size()+Dofs[1].size()-firstNonDirGraphVertId);
752 for(i = 0; i < locExpVector.size(); ++i)
754 eid = fields[0]->GetOffset_Elmt_Id(i);
755 locExpansion = locExpVector[eid]
757 for(j = 0; j < locExpansion->GetNverts(); ++j)
759 meshEdgeId = (locExpansion
761 ->GetGeom2D())->GetEid(j);
762 meshVertId = (locExpansion
764 ->GetGeom2D())->GetVid(j);
766 if(ReorderedGraphVertId[0][meshVertId] >=
767 firstNonDirGraphVertId)
769 vwgts_perm[ReorderedGraphVertId[0][meshVertId]-
770 firstNonDirGraphVertId] =
774 if(ReorderedGraphVertId[1][meshEdgeId] >=
775 firstNonDirGraphVertId)
777 vwgts_perm[ReorderedGraphVertId[1][meshEdgeId]-
778 firstNonDirGraphVertId] =
784 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
794 void CoupledLocalToGlobalC0ContMap::FindEdgeIdToAddMeanPressure(vector<map<int,int> > &ReorderedGraphVertId,
796 int &edgeId,
int &vertId,
int &firstNonDirGraphVertId, map<int,int> &IsDirEdgeDof,
805 map<int,int> HomGraphEdgeIdToEdgeId;
807 for(i = 0; i < nel; ++i)
809 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
812 ->GetGeom2D())->GetEid(j);
815 if((ReorderedGraphVertId[1][edgeId] >= firstNonDirGraphVertId)
816 && (IsDirEdgeDof.count(edgeId) == 0))
818 HomGraphEdgeIdToEdgeId[ReorderedGraphVertId[1][edgeId]-firstNonDirGraphVertId] = edgeId;
820 if(EdgeIdToElmts[edgeId][0] == -1)
822 EdgeIdToElmts[edgeId][0] = i;
826 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 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)
bool m_systemSingular
Flag indicating if the system is singular or not.
bool m_signChange
Flag indicating if modes require sign reversal.
CoupledLocalToGlobalC0ContMap(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph, const SpatialDomains::BoundaryConditionsSharedPtr &boundaryConditions, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const MultiRegions::ExpListSharedPtr &pressure, const int nz_loc, const bool CheeckForSingularSys=true)
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
std::map< int, vector< PeriodicEntity > > PeriodicMap
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
void FindEdgeIdToAddMeanPressure(vector< map< int, int > > &ReorderedGraphVertId, int &nel, const LocalRegions::ExpansionVector &locExpVector, int &edgeId, int &vertId, int &firstNonDirGraphVertId, map< int, int > &IsDirEdgeDof, MultiRegions::BottomUpSubStructuredGraphSharedPtr &bottomUpGraph, Array< OneD, int > &AddMeanPressureToEdgeId)
Principle Modified Functions .
boost::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
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, set< int > &extraDirVerts, set< int > &extraDirEdges, int &firstNonDirGraphVertId, int &nExtraDirichlet, int mdswitch=1)
int m_numLocalCoeffs
Total number of local coefficients.
int GetEdgeNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th edge.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
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 NumBndryCoeffs(void) const
boost::shared_ptr< StdExpansion2D > StdExpansion2DSharedPtr
boost::shared_ptr< SegExp > SegExpSharedPtr
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 .
boost::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...
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Array< OneD, int > m_localToGlobalBndMap
Integer map of local boundary coeffs to global space.
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
Array< OneD, int > m_bndCondCoeffsToGlobalCoeffsMap
Integer map of bnd cond coeffs to global coefficients.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
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.
boost::shared_ptr< BoundaryConditions > BoundaryConditionsSharedPtr
boost::shared_ptr< Geometry1D > Geometry1DSharedPtr
LibUtilities::SessionReaderSharedPtr m_session
Session object.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int m_numGlobalCoeffs
Total number of global coefficients.
boost::shared_ptr< MeshGraph > MeshGraphSharedPtr
boost::shared_ptr< Expansion1D > Expansion1DSharedPtr
int m_numPatches
The number of patches (~elements) in the current level.