55 const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
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;
77 Array<OneD, unsigned int> edgeInteriorMap;
78 Array<OneD, int> edgeInteriorSign;
79 int nvel = fields.num_elements();
83 int nel = fields[0]->GetNumElmts();
88 vector<map<int,int> > ReorderedGraphVertId(3);
90 int staticCondLevel = 0;
92 if(CheckforSingularSys)
109 fields[0]->GetPeriodicEntities(periodicVerts,periodicEdges,periodicFaces);
112 const Array<OneD, const MultiRegions::ExpListSharedPtr> bndCondExp = fields[0]->GetBndCondExpansions();
114 Array<OneD, Array<OneD, const SpatialDomains::BoundaryConditionShPtr> > bndConditionsVec(nvel);
115 for(i = 0; i < nvel; ++i)
117 bndConditionsVec[i] = fields[i]->GetBndConditions();
120 map<int,int> IsDirVertDof;
121 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()->GetEid()] += 1;
153 for(mapIt = BndExpVids.begin(); mapIt != BndExpVids.end(); mapIt++)
155 id = IsDirVertDof[mapIt->second]+1;
156 IsDirVertDof[mapIt->second] = (
id > nvel)?nvel:
id;
165 for(k = 0; k < bndCondExp[j]->GetNumElmts(); ++k)
167 Array<OneD,Array<OneD,NekDouble> > locnorm;
169 = bndCondExp[j]->GetExp(k)
174 int ndir = locnorm.num_elements();
177 for(
int l = 0; l < locnorm[0].num_elements(); ++l)
195 Array<OneD, map<int,int> >Dofs(2);
197 Array<OneD, int> AddMeanPressureToEdgeId(nel,-1);
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 eid = fields[0]->GetOffset_Elmt_Id(i);
248 for(j = 0; j < locExpVector[eid]->GetNverts(); ++j)
251 ->GetGeom2D())->GetVid(j);
252 if(Dofs[0].count(vertId) == 0)
254 Dofs[0][vertId] = nvel*nz_loc;
257 if(IsDirVertDof.count(vertId) != 0)
259 Dofs[0][vertId] -= IsDirVertDof[vertId]*nz_loc;
264 ->GetGeom2D())->GetEid(j);
265 if(Dofs[1].count(edgeId) == 0)
267 Dofs[1][edgeId] = nvel*(locExpVector[eid]->GetEdgeNcoeffs(j)-2)*nz_loc;
271 if(IsDirEdgeDof.count(edgeId) != 0)
273 Dofs[1][edgeId] -= IsDirEdgeDof[edgeId]*nz_loc*(locExpVector[eid]->GetEdgeNcoeffs(j)-2);
278 set<int> extraDirVerts, extraDirEdges;
280 CreateGraph(*fields[0], bndCondExp, bndConditionsVec,
false,
281 periodicVerts, periodicEdges, periodicFaces,
282 ReorderedGraphVertId, bottomUpGraph, extraDirVerts,
283 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, 4);
308 edgeId, vertId, firstNonDirGraphVertId, IsDirEdgeDof,
310 AddMeanPressureToEdgeId);
316 for(i = 0; i < nel; ++i)
318 eid = fields[0]->GetOffset_Elmt_Id(i);
319 for(j = 0; j < locExpVector[eid]->GetNverts(); ++j)
322 ->GetGeom2D())->GetEid(j);
324 if(IsDirEdgeDof.count(edgeId) == 0)
328 if(AddMeanPressureToEdgeId[eid] == -1)
330 AddMeanPressureToEdgeId[eid] = edgeId;
334 ASSERTL0((AddMeanPressureToEdgeId[eid] != -1),
"Did not determine "
335 "an edge to attach mean pressure dof");
337 Dofs[1][AddMeanPressureToEdgeId[eid]] += nz_loc;
340 map<int,int> pressureEdgeOffset;
345 for(i = 0; i < bndCondExp.num_elements(); 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;
357 nLocBndCondDofs += bndSegExp->GetNcoeffs()*nz_loc;
382 Array<OneD, int> graphVertOffset(nvel*nz_loc*(ReorderedGraphVertId[0].size() + ReorderedGraphVertId[1].size()),0);
383 graphVertOffset[0] = 0;
387 for(i = 0; i < nel; ++i)
389 eid = fields[0]->GetOffset_Elmt_Id(i);
392 for(j = 0; j < locExpansion->GetNedges(); ++j)
396 ->GetGeom2D())->GetEid(j);
398 ->GetGeom2D())->GetVid(j);
400 for(k = 0; k < nvel*nz_loc; ++k)
402 graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+k] = 1;
403 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+k] = (nEdgeCoeffs-2);
406 bType = locExpansion->GetEdgeBasisType(j);
408 if( (nEdgeCoeffs >= 4)&&
418 for(i = 0; i < nel; ++i)
420 graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[i]]+1)*nvel*nz_loc-1] += nz_loc;
429 map<int,int> DirVertChk;
431 for(i = 0; i < bndConditionsVec[0].num_elements(); ++i)
434 for(j = 0; j < nvel; ++j)
443 if((cnt > 0)&&(cnt < nvel))
445 for(j = 0; j < nvel; ++j)
451 for(k = 0; k < bndCondExp[i]->GetNumElmts(); ++k)
454 id = bndCondExp[i]->GetExp(k)
456 ->GetGeom1D()->GetVid(0);
457 if(DirVertChk.count(
id*nvel+j) == 0)
459 DirVertChk[
id*nvel+j] = 1;
460 for(n = 0; n < nz_loc; ++n)
462 graphVertOffset[ReorderedGraphVertId[0][id]*nvel*nz_loc+j*nz_loc + n] *= -1;
466 id = bndCondExp[i]->GetExp(k)
468 ->GetGeom1D()->GetVid(1);
469 if(DirVertChk.count(
id*nvel+j) == 0)
471 DirVertChk[
id*nvel+j] = 1;
472 for(n = 0; n < nz_loc; ++n)
474 graphVertOffset[ReorderedGraphVertId[0][id]*nvel*nz_loc+j*nz_loc+n] *= -1;
479 id = bndCondExp[i]->GetExp(k)
481 ->GetGeom1D()->GetEid();
482 for(n = 0; n < nz_loc; ++n)
484 graphVertOffset[ReorderedGraphVertId[1][id]*nvel*nz_loc+j*nz_loc +n] *= -1;
495 for(i = 0; i < firstNonDirGraphVertId*nvel*nz_loc; ++i)
497 diff = abs(graphVertOffset[i]);
498 graphVertOffset[i] = cnt;
503 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.num_elements(); ++i)
505 if(graphVertOffset[i] < 0)
507 diff = -graphVertOffset[i];
508 graphVertOffset[i] = -cnt;
517 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.num_elements(); ++i)
519 if(graphVertOffset[i] >= 0)
521 diff = graphVertOffset[i];
522 graphVertOffset[i] = cnt;
529 for(i = firstNonDirGraphVertId*nvel*nz_loc; i < graphVertOffset.num_elements(); ++i)
531 if(graphVertOffset[i] < 0)
533 graphVertOffset[i] = -graphVertOffset[i];
544 for(i = 0; i < nel; ++i)
571 for(i = 0; i < nel; ++i)
574 m_numLocalIntCoeffsPerPatch[i] = (
unsigned int) nz_loc*(pressure->GetExp(i)->GetNcoeffs()-1);
588 Array<OneD, unsigned int> bmap;
593 for(i = 0; i < nel; ++i)
595 eid = fields[0]->GetOffset_Elmt_Id(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 locExpansion->GetEdgeInteriorMap(j,edgeOrient,edgeInteriorMap,edgeInteriorSign);
625 for(nv = 0; nv < nvel*nz_loc; ++nv)
627 m_localToGlobalMap[cnt+nv*velnbndry+inv_bmap[locExpansion->GetVertexMap(j)]] = graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+ nv];
629 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
631 m_localToGlobalMap[cnt+nv*velnbndry+inv_bmap[edgeInteriorMap[k]]] = graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+nv]+k;
638 for(nv = 0; nv < nvel*nz_loc; ++nv)
640 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
642 m_localToGlobalSign[cnt+nv*velnbndry + inv_bmap[edgeInteriorMap[k]]] = (
NekDouble) edgeInteriorSign[k];
649 nEdgeInteriorCoeffs = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[eid]])*nvel*nz_loc+1] - graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[eid]])*nvel*nz_loc];
651 int psize = pressure->GetExp(eid)->GetNcoeffs();
652 for(n = 0; n < nz_loc; ++n)
654 m_localToGlobalMap[cnt + nz_loc*nvel*velnbndry + n*psize] = graphVertOffset[(ReorderedGraphVertId[1][AddMeanPressureToEdgeId[eid]]+1)*nvel*nz_loc-1]+nEdgeInteriorCoeffs + pressureEdgeOffset[AddMeanPressureToEdgeId[eid]];
656 pressureEdgeOffset[AddMeanPressureToEdgeId[eid]] += 1;
659 cnt += (velnbndry*nvel+ psize)*nz_loc;
664 for(nv = 0; nv < nvel; ++nv)
666 for(i = 0; i < bndCondExp.num_elements(); i++)
668 for(n = 0; n < nz_loc; ++n)
671 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
673 bndSegExp = bndCondExp[i]->GetExp(j)
676 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
677 for(k = 0; k < 2; k++)
679 meshVertId = (bndSegExp->GetGeom1D())->GetVid(k);
680 m_bndCondCoeffsToGlobalCoeffsMap[cnt+bndSegExp->
GetVertexMap(k)] = graphVertOffset[ReorderedGraphVertId[0][meshVertId]*nvel*nz_loc+nv*nz_loc+n];
683 meshEdgeId = (bndSegExp->GetGeom1D())->GetEid();
686 for(k = 0; k < nEdgeCoeffs; k++)
688 if(m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] == -1)
690 m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] =
691 graphVertOffset[ReorderedGraphVertId[1][meshEdgeId]*nvel*nz_loc+nv*nz_loc+n]+bndEdgeCnt;
695 ncoeffcnt += nEdgeCoeffs;
736 Array<OneD, int> vwgts_perm(
737 Dofs[0].size()+Dofs[1].size()-firstNonDirGraphVertId);
738 for(i = 0; i < locExpVector.size(); ++i)
740 eid = fields[0]->GetOffset_Elmt_Id(i);
741 locExpansion = locExpVector[eid]
743 for(j = 0; j < locExpansion->GetNverts(); ++j)
745 meshEdgeId = (locExpansion
747 ->GetGeom2D())->GetEid(j);
748 meshVertId = (locExpansion
750 ->GetGeom2D())->GetVid(j);
752 if(ReorderedGraphVertId[0][meshVertId] >=
753 firstNonDirGraphVertId)
755 vwgts_perm[ReorderedGraphVertId[0][meshVertId]-
756 firstNonDirGraphVertId] =
760 if(ReorderedGraphVertId[1][meshEdgeId] >=
761 firstNonDirGraphVertId)
763 vwgts_perm[ReorderedGraphVertId[1][meshEdgeId]-
764 firstNonDirGraphVertId] =
770 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
780 void CoupledLocalToGlobalC0ContMap::FindEdgeIdToAddMeanPressure(vector<map<int,int> > &ReorderedGraphVertId,
782 int &edgeId,
int &vertId,
int &firstNonDirGraphVertId, map<int,int> &IsDirEdgeDof,
784 Array<OneD, int> &AddMeanPressureToEdgeId)
790 Array<TwoD, int> EdgeIdToElmts(ReorderedGraphVertId[1].size(),2,-1);
791 map<int,int> HomGraphEdgeIdToEdgeId;
793 for(i = 0; i < nel; ++i)
795 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
798 ->GetGeom2D())->GetEid(j);
801 if((ReorderedGraphVertId[1][edgeId] >= firstNonDirGraphVertId)
802 && (IsDirEdgeDof.count(edgeId) == 0))
804 HomGraphEdgeIdToEdgeId[ReorderedGraphVertId[1][edgeId]-firstNonDirGraphVertId] = edgeId;
806 if(EdgeIdToElmts[edgeId][0] == -1)
808 EdgeIdToElmts[edgeId][0] = i;
812 EdgeIdToElmts[edgeId][1] = i;
823 int nlevels = bottomUpGraph->GetNlevels();
829 vector<MultiRegions::SubGraphSharedPtr> bndgraphs = bottomUpGraph->GetInteriorBlocks(nlevels);
830 for(i = 0; i < bndgraphs.size(); ++i)
832 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
834 for(j = 0; j < bndgraphs[i]->GetNverts(); ++j)
837 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
839 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
854 for(
int n = 1; n < nlevels; ++n)
858 vector<MultiRegions::SubGraphSharedPtr> bndgraphs = bottomUpGraph->GetInteriorBlocks(n+1);
861 map<int,int> ElmtInBndry;
863 for(i = 0; i < bndgraphs.size(); ++i)
865 int GlobIdOffset = bndgraphs[i]->GetIdOffset();
867 for(j = 0; j < bndgraphs[i]->GetNverts(); ++j)
870 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
872 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
874 if(EdgeIdToElmts[edgeId][0] != -1)
876 ElmtInBndry[EdgeIdToElmts[edgeId][0]] = i;
878 if(EdgeIdToElmts[edgeId][1] != -1)
880 ElmtInBndry[EdgeIdToElmts[edgeId][1]] = i;
889 vector<MultiRegions::SubGraphSharedPtr> intgraphs = bottomUpGraph->GetInteriorBlocks(n);
890 for(i = 0; i < intgraphs.size(); ++i)
892 int GlobIdOffset = intgraphs[i]->GetIdOffset();
893 bool SetEdge =
false;
895 for(j = 0; j < intgraphs[i]->GetNverts(); ++j)
898 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
900 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
902 for(k = 0; k < 2; ++k)
905 elmtid = EdgeIdToElmts[edgeId][k];
909 mapIt = ElmtInBndry.find(elmtid);
911 if(mapIt != ElmtInBndry.end())
914 int GlobIdOffset1 = bndgraphs[mapIt->second]->GetIdOffset();
915 for(
int l = 0; l < bndgraphs[mapIt->second]->GetNverts(); ++l)
918 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset1+l) != 0)
927 AddMeanPressureToEdgeId[elmtid] = defedge;
949 for(j = 0; j < intgraphs[i]->GetNverts(); ++j)
951 if(HomGraphEdgeIdToEdgeId.count(GlobIdOffset+j) != 0)
953 edgeId = HomGraphEdgeIdToEdgeId[GlobIdOffset+j];
954 for(k = 0; k < 2; ++k)
957 elmtid = EdgeIdToElmts[edgeId][k];
970 if(AddMeanPressureToEdgeId[elmtid] == -1)
972 AddMeanPressureToEdgeId[elmtid] = defedge;