47 namespace MultiRegions
56 "Block Diagonal Preconditioning");
65 const boost::shared_ptr<GlobalLinSys> &plinsys,
69 m_preconType(pLocToGloMap->GetPreconType()),
70 m_locToGloMap(pLocToGloMap)
84 boost::shared_ptr<MultiRegions::ExpList>
85 expList=((
m_linsys.lock())->GetLocMat()).lock();
87 locExpansion = expList->GetExp(0);
88 int nDim = locExpansion->GetShapeDimension();
92 ASSERTL0(0,
"Unknown preconditioner");
118 boost::shared_ptr<MultiRegions::ExpList>
119 expList=((
m_linsys.lock())->GetLocMat()).lock();
125 int eid, n, cnt, nedgemodes;
128 int vMap1, vMap2, sign1, sign2;
129 int m, v, eMap1, eMap2;
130 int offset, globalrow, globalcol;
150 Array<OneD, NekDouble> vertArray(nNonDirVerts,0.0);
151 Array<OneD, long> VertBlockToUniversalMap(nNonDirVerts,-1);
153 int n_exp = expList->GetNumElmts();
157 Array<OneD,unsigned int> n_blks(1+nNonDirEdgeIDs);
158 n_blks[0]=nNonDirVerts;
160 map<int,int> edgeDirMap;
161 map<int,int> uniqueEdgeMap;
164 Array<OneD, int> edgemodeoffset(nNonDirEdgeIDs,0);
165 Array<OneD, int> edgeglobaloffset(nNonDirEdgeIDs,0);
167 const Array<OneD, const ExpListSharedPtr>& bndCondExp = expList->GetBndCondExpansions();
170 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr>&
171 bndConditions = expList->GetBndConditions();
177 for(i = 0; i < bndCondExp.num_elements(); i++)
180 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
182 bndSegExp = bndCondExp[i]->GetExp(j)
184 if (bndConditions[i]->GetBoundaryConditionType() ==
187 meshEdgeId = (bndSegExp->GetGeom1D())->GetEid();
188 edgeDirMap[meshEdgeId] = 1;
195 int nlocalNonDirEdges=0;
197 int edgematrixlocation=0;
198 int ntotaledgeentries=0;
202 for(cnt=n=0; n < n_exp; ++n)
204 nel = expList->GetOffset_Elmt_Id(n);
206 locExpansion = expList->GetExp(nel);
208 for (j = 0; j < locExpansion->GetNedges(); ++j)
210 dof = locExpansion->GetEdgeNcoeffs(j)-2;
211 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
213 ->GetGeom2D()->GetEid(j);
215 if(edgeDirMap.count(meshEdgeId)==0)
217 if(uniqueEdgeMap.count(meshEdgeId)==0)
219 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
221 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
223 edgemodeoffset[edgematrixlocation]=dof*dof;
225 ntotaledgeentries+=dof*dof;
227 n_blks[1+edgematrixlocation++]=dof;
231 nlocalNonDirEdges+=dof*dof;
236 m_comm = expList->GetComm()->GetRowComm();
240 Array<OneD, long> EdgeBlockToUniversalMap(ntotaledgeentries,-1);
242 Array<OneD, int> localEdgeToGlobalMatrixMap(nlocalNonDirEdges,-1);
245 Array<OneD, NekDouble> EdgeBlockArray(nlocalNonDirEdges,-1);
247 int edgematrixoffset=0;
250 for(n=0; n < n_exp; ++n)
252 nel = expList->GetOffset_Elmt_Id(n);
254 locExpansion = expList->GetExp(nel);
257 for(j = 0; j < locExpansion->GetNedges(); ++j)
261 ->GetGeom2D()->GetEid(j);
265 if(edgeDirMap.count(meshEdgeId)==0)
267 for(k=0; k<nedgemodes*nedgemodes; ++k)
269 vGlobal=edgeglobaloffset[uniqueEdgeMap[meshEdgeId]]+k;
272 localEdgeToGlobalMatrixMap[edgematrixoffset+k]=vGlobal;
274 EdgeBlockToUniversalMap[vGlobal]
275 = meshEdgeId * maxEdgeDof * maxEdgeDof + k + 1;
277 edgematrixoffset+=nedgemodes*nedgemodes;
290 for(cnt=n=0; n < n_exp; ++n)
292 nel = expList->GetOffset_Elmt_Id(n);
294 locExpansion = expList->GetExp(nel);
296 nVerts=locExpansion->GetGeom()->GetNumVerts();
297 nEdges=locExpansion->GetGeom()->GetNumEdges();
300 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
303 bnd_mat=loc_mat->GetBlock(0,0);
306 offset = bnd_mat->GetRows();
312 for (v=0; v<nVerts; ++v)
314 vMap1=locExpansion->GetVertexMap(v);
318 GetLocalToGlobalBndMap(cnt+vMap1)-nDirBnd;
322 for (m=0; m<nVerts; ++m)
324 vMap2=locExpansion->GetVertexMap(m);
329 GetLocalToGlobalBndMap(cnt+vMap2)-nDirBnd;
332 if (globalcol == globalrow)
338 GetLocalToGlobalBndSign(cnt + vMap1);
340 GetLocalToGlobalBndSign(cnt + vMap2);
343 += sign1*sign2*S(vMap1,vMap2);
345 VertBlockToUniversalMap[globalrow]
346 = meshVertId * maxEdgeDof * maxEdgeDof + 1;
353 for (eid=0; eid<nEdges; ++eid)
355 nedgemodes=locExpansion->GetEdgeNcoeffs(eid)-2;
359 (nedgemodes,nedgemodes,zero,storage);
362 Array<OneD, unsigned int> edgemodearray =
365 if(edgeDirMap.count(meshEdgeId)==0)
367 for (v=0; v<nedgemodes; ++v)
369 eMap1=edgemodearray[v];
371 for (m=0; m<nedgemodes; ++m)
373 eMap2=edgemodearray[m];
377 GetLocalToGlobalBndSign(cnt + eMap1);
379 GetLocalToGlobalBndSign(cnt + eMap2);
382 sign1*sign2*S(eMap1,eMap2);
384 EdgeBlockArray[edgematrixoffset+v*nedgemodes+m]=
388 edgematrixoffset+=nedgemodes*nedgemodes;
397 Array<OneD, NekDouble> GlobalEdgeBlock(ntotaledgeentries);
398 Vmath::Zero(ntotaledgeentries, GlobalEdgeBlock.get(), 1);
400 EdgeBlockArray.get(),
401 localEdgeToGlobalMatrixMap.get(),
402 GlobalEdgeBlock.get());
416 for (
int i = 0; i < nNonDirVerts; ++i)
418 VertBlk->SetValue(i,i,1.0/vertArray[i]);
426 for(
int loc=0; loc<nNonDirEdgeIDs; ++loc)
430 (nedgemodes,nedgemodes,zero,storage);
432 for (v=0; v<nedgemodes; ++v)
434 for (m=0; m<nedgemodes; ++m)
436 NekDouble EdgeValue = GlobalEdgeBlock[offset+v*nedgemodes+m];
437 gmat->SetValue(v,m,EdgeValue);
441 m_blkMat->SetBlock(1+loc,1+loc, gmat);
443 offset+=edgemodeoffset[loc];
446 int totblks=
m_blkMat->GetNumberOfBlockRows();
447 for (i=1; i< totblks; ++i)
449 unsigned int nmodes=
m_blkMat->GetNumberOfRowsInBlockRow(i);
452 (nmodes,nmodes,zero,storage);
465 boost::shared_ptr<MultiRegions::ExpList>
466 expList=((
m_linsys.lock())->GetLocMat()).lock();
471 int nVerts, nEdges,nFaces;
472 int eid, fid, n, cnt, nedgemodes, nfacemodes;
475 int vMap1, vMap2, sign1, sign2;
476 int m, v, eMap1, eMap2, fMap1, fMap2;
477 int offset, globalrow, globalcol;
497 Array<OneD, NekDouble> vertArray(nNonDirVerts,0.0);
498 Array<OneD, long> VertBlockToUniversalMap(nNonDirVerts,-1);
500 int n_exp = expList->GetNumElmts();
505 Array<OneD,unsigned int> n_blks(1+nNonDirEdgeIDs+nNonDirFaceIDs);
506 n_blks[0]=nNonDirVerts;
508 map<int,int> edgeDirMap;
509 map<int,int> faceDirMap;
510 map<int,int> uniqueEdgeMap;
511 map<int,int> uniqueFaceMap;
514 Array<OneD, int> edgemodeoffset(nNonDirEdgeIDs,0);
515 Array<OneD, int> facemodeoffset(nNonDirFaceIDs,0);
517 Array<OneD, int> edgeglobaloffset(nNonDirEdgeIDs,0);
518 Array<OneD, int> faceglobaloffset(nNonDirFaceIDs,0);
520 const Array<OneD, const ExpListSharedPtr>& bndCondExp = expList->GetBndCondExpansions();
522 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr>& bndConditions = expList->GetBndConditions();
528 const Array<OneD, const int> &extradiredges
530 for(i=0; i<extradiredges.num_elements(); ++i)
532 meshEdgeId=extradiredges[i];
533 edgeDirMap[meshEdgeId] = 1;
537 for(i = 0; i < bndCondExp.num_elements(); i++)
540 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
543 if (bndConditions[i]->GetBoundaryConditionType() ==
546 for(k = 0; k < bndCondFaceExp->GetNedges(); k++)
549 if(edgeDirMap.count(meshEdgeId) == 0)
551 edgeDirMap[meshEdgeId] = 1;
555 faceDirMap[meshFaceId] = 1;
563 int nlocalNonDirEdges=0;
564 int nlocalNonDirFaces=0;
566 int edgematrixlocation=0;
567 int ntotaledgeentries=0;
571 for(cnt=n=0; n < n_exp; ++n)
573 nel = expList->GetOffset_Elmt_Id(n);
575 locExpansion = expList->GetExp(nel);
577 for (j = 0; j < locExpansion->GetNedges(); ++j)
579 dof = locExpansion->GetEdgeNcoeffs(j)-2;
580 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
583 if(edgeDirMap.count(meshEdgeId)==0)
585 if(uniqueEdgeMap.count(meshEdgeId)==0 && dof > 0)
587 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
589 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
591 edgemodeoffset[edgematrixlocation]=dof*dof;
593 ntotaledgeentries+=dof*dof;
595 n_blks[1+edgematrixlocation++]=dof;
598 nlocalNonDirEdges+=dof*dof;
603 int facematrixlocation=0;
604 int ntotalfaceentries=0;
608 for(cnt=n=0; n < n_exp; ++n)
610 nel = expList->GetOffset_Elmt_Id(n);
612 locExpansion = expList->GetExp(nel);
614 for (j = 0; j < locExpansion->GetNfaces(); ++j)
616 dof = locExpansion->GetFaceIntNcoeffs(j);
617 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
621 if(faceDirMap.count(meshFaceId)==0)
623 if(uniqueFaceMap.count(meshFaceId)==0 && dof > 0)
625 uniqueFaceMap[meshFaceId]=facematrixlocation;
627 facemodeoffset[facematrixlocation]=dof*dof;
629 faceglobaloffset[facematrixlocation]+=ntotalfaceentries;
631 ntotalfaceentries+=dof*dof;
633 n_blks[1+nNonDirEdgeIDs+facematrixlocation++]=dof;
635 nlocalNonDirFaces+=dof*dof;
641 m_comm = expList->GetComm();
646 Array<OneD, long> EdgeBlockToUniversalMap(ntotaledgeentries,-1);
647 Array<OneD, long> FaceBlockToUniversalMap(ntotalfaceentries,-1);
649 Array<OneD, int> localEdgeToGlobalMatrixMap(nlocalNonDirEdges,-1);
650 Array<OneD, int> localFaceToGlobalMatrixMap(nlocalNonDirFaces,-1);
653 Array<OneD, NekDouble> EdgeBlockArray(nlocalNonDirEdges,-1);
654 Array<OneD, NekDouble> FaceBlockArray(nlocalNonDirFaces,-1);
656 int edgematrixoffset=0;
657 int facematrixoffset=0;
660 for(n=0; n < n_exp; ++n)
662 nel = expList->GetOffset_Elmt_Id(n);
664 locExpansion = expList->GetExp(nel);
667 for(j = 0; j < locExpansion->GetNedges(); ++j)
674 if(edgeDirMap.count(meshEdgeId)==0)
676 for(k=0; k<nedgemodes*nedgemodes; ++k)
678 vGlobal=edgeglobaloffset[uniqueEdgeMap[meshEdgeId]]+k;
681 localEdgeToGlobalMatrixMap[edgematrixoffset+k]=vGlobal;
683 EdgeBlockToUniversalMap[vGlobal]
684 = meshEdgeId * maxEdgeDof * maxEdgeDof + k + 1;
686 edgematrixoffset+=nedgemodes*nedgemodes;
691 for(j = 0; j < locExpansion->GetNfaces(); ++j)
699 if(faceDirMap.count(meshFaceId)==0)
701 for(k=0; k<nfacemodes*nfacemodes; ++k)
703 vGlobal=faceglobaloffset[uniqueFaceMap[meshFaceId]]+k;
705 localFaceToGlobalMatrixMap[facematrixoffset+k]
708 FaceBlockToUniversalMap[vGlobal]
709 = meshFaceId * maxFaceDof * maxFaceDof + k + 1;
711 facematrixoffset+=nfacemodes*nfacemodes;
725 for(cnt=n=0; n < n_exp; ++n)
727 nel = expList->GetOffset_Elmt_Id(n);
729 locExpansion = expList->GetExp(nel);
731 nVerts=locExpansion->GetGeom()->GetNumVerts();
732 nEdges=locExpansion->GetGeom()->GetNumEdges();
733 nFaces=locExpansion->GetGeom()->GetNumFaces();
736 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
739 bnd_mat=loc_mat->GetBlock(0,0);
742 offset = bnd_mat->GetRows();
748 for (v=0; v<nVerts; ++v)
750 vMap1=locExpansion->GetVertexMap(v);
754 GetLocalToGlobalBndMap(cnt+vMap1)-nDirBnd;
758 for (m=0; m<nVerts; ++m)
760 vMap2=locExpansion->GetVertexMap(m);
765 GetLocalToGlobalBndMap(cnt+vMap2)-nDirBnd;
768 if (globalcol == globalrow)
774 GetLocalToGlobalBndSign(cnt + vMap1);
776 GetLocalToGlobalBndSign(cnt + vMap2);
779 += sign1*sign2*S(vMap1,vMap2);
781 VertBlockToUniversalMap[globalrow]
782 = meshVertId * maxEdgeDof * maxEdgeDof + 1;
789 for (eid=0; eid<nEdges; ++eid)
791 nedgemodes=locExpansion->GetEdgeNcoeffs(eid)-2;
795 (nedgemodes,nedgemodes,zero,storage);
800 if(edgeDirMap.count(meshEdgeId)==0)
802 for (v=0; v<nedgemodes; ++v)
804 eMap1=edgemodearray[v];
806 for (m=0; m<nedgemodes; ++m)
808 eMap2=edgemodearray[m];
812 GetLocalToGlobalBndSign(cnt + eMap1);
814 GetLocalToGlobalBndSign(cnt + eMap2);
816 NekDouble globalEdgeValue = sign1*sign2*S(eMap1,eMap2);
818 EdgeBlockArray[edgematrixoffset+v*nedgemodes+m]=globalEdgeValue;
821 edgematrixoffset+=nedgemodes*nedgemodes;
826 for (fid=0; fid<nFaces; ++fid)
828 nfacemodes = locExpansion->GetFaceIntNcoeffs(fid);
832 (nfacemodes,nfacemodes,zero,storage);
838 if(faceDirMap.count(meshFaceId)==0)
840 for (v=0; v<nfacemodes; ++v)
842 fMap1=facemodearray[v];
844 for (m=0; m<nfacemodes; ++m)
846 fMap2=facemodearray[m];
850 GetLocalToGlobalBndSign(cnt + fMap1);
852 GetLocalToGlobalBndSign(cnt + fMap2);
855 NekDouble globalFaceValue = sign1*sign2*S(fMap1,fMap2);
858 FaceBlockArray[facematrixoffset+v*nfacemodes+m]=globalFaceValue;
861 facematrixoffset+=nfacemodes*nfacemodes;
870 Array<OneD, NekDouble> GlobalEdgeBlock(ntotaledgeentries);
871 Vmath::Zero(ntotaledgeentries, GlobalEdgeBlock.get(), 1);
873 EdgeBlockArray.get(),
874 localEdgeToGlobalMatrixMap.get(),
875 GlobalEdgeBlock.get());
878 Array<OneD, NekDouble> GlobalFaceBlock(ntotalfaceentries);
879 Vmath::Zero(ntotalfaceentries, GlobalFaceBlock.get(), 1);
881 FaceBlockArray.get(),
882 localFaceToGlobalMatrixMap.get(),
883 GlobalFaceBlock.get());
901 for (
int i = 0; i < nNonDirVerts; ++i)
903 VertBlk->SetValue(i,i,1.0/vertArray[i]);
911 for(
int loc=0; loc<nNonDirEdgeIDs; ++loc)
915 (nedgemodes,nedgemodes,zero,storage);
917 for (v=0; v<nedgemodes; ++v)
919 for (m=0; m<nedgemodes; ++m)
921 NekDouble EdgeValue = GlobalEdgeBlock[offset+v*nedgemodes+m];
922 gmat->SetValue(v,m,EdgeValue);
926 m_blkMat->SetBlock(1+loc,1+loc, gmat);
928 offset+=edgemodeoffset[loc];
933 for(
int loc=0; loc<nNonDirFaceIDs; ++loc)
935 nfacemodes=n_blks[1+nNonDirEdgeIDs+loc];
939 (nfacemodes,nfacemodes,zero,storage);
941 for (v=0; v<nfacemodes; ++v)
943 for (m=0; m<nfacemodes; ++m)
945 NekDouble FaceValue = GlobalFaceBlock[offset+v*nfacemodes+m];
946 gmat->SetValue(v,m,FaceValue);
950 m_blkMat->SetBlock(1+nNonDirEdgeIDs+loc,1+nNonDirEdgeIDs+loc, gmat);
952 offset+=facemodeoffset[loc];
956 int totblks=
m_blkMat->GetNumberOfBlockRows();
957 for (i=1; i< totblks; ++i)
959 unsigned int nmodes=
m_blkMat->GetNumberOfRowsInBlockRow(i);
962 (nmodes,nmodes,zero,storage);
975 const Array<OneD, NekDouble>& pInput,
976 Array<OneD, NekDouble>& pOutput)
980 int nNonDir = nGlobal-nDir;