48 namespace MultiRegions
57 "Block Diagonal Preconditioning");
66 const boost::shared_ptr<GlobalLinSys> &plinsys,
70 m_preconType(pLocToGloMap->GetPreconType()),
71 m_locToGloMap(pLocToGloMap)
92 boost::shared_ptr<MultiRegions::ExpList>
93 expList=((
m_linsys.lock())->GetLocMat()).lock();
95 locExpansion = expList->GetExp(0);
96 int nDim = locExpansion->GetShapeDimension();
100 ASSERTL0(0,
"Unknown preconditioner");
125 boost::shared_ptr<MultiRegions::ExpList>
126 expList=((
m_linsys.lock())->GetLocMat()).lock();
132 int eid, n, cnt, nedgemodes;
135 int vMap1, vMap2, sign1, sign2;
136 int m, v, eMap1, eMap2;
137 int offset, globalrow, globalcol;
157 Array<OneD, NekDouble> vertArray(nNonDirVerts,0.0);
158 Array<OneD, long> VertBlockToUniversalMap(nNonDirVerts,-1);
160 int n_exp = expList->GetNumElmts();
164 Array<OneD,unsigned int> n_blks(1+nNonDirEdgeIDs);
165 n_blks[0]=nNonDirVerts;
167 map<int,int> edgeDirMap;
168 map<int,int> uniqueEdgeMap;
171 Array<OneD, int> edgemodeoffset(nNonDirEdgeIDs,0);
172 Array<OneD, int> edgeglobaloffset(nNonDirEdgeIDs,0);
174 const Array<OneD, const ExpListSharedPtr>& bndCondExp = expList->GetBndCondExpansions();
177 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr>&
178 bndConditions = expList->GetBndConditions();
184 for(i = 0; i < bndCondExp.num_elements(); i++)
187 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
189 bndSegExp = bndCondExp[i]->GetExp(j)
191 if (bndConditions[i]->GetBoundaryConditionType() ==
194 meshEdgeId = (bndSegExp->GetGeom1D())->GetEid();
195 edgeDirMap[meshEdgeId] = 1;
202 int nlocalNonDirEdges=0;
204 int edgematrixlocation=0;
205 int ntotaledgeentries=0;
209 for(cnt=n=0; n < n_exp; ++n)
211 nel = expList->GetOffset_Elmt_Id(n);
213 locExpansion = expList->GetExp(nel);
215 for (j = 0; j < locExpansion->GetNedges(); ++j)
217 dof = locExpansion->GetEdgeNcoeffs(j)-2;
218 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
220 ->GetGeom2D()->GetEid(j);
222 if(edgeDirMap.count(meshEdgeId)==0)
224 if(uniqueEdgeMap.count(meshEdgeId)==0)
226 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
228 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
230 edgemodeoffset[edgematrixlocation]=dof*dof;
232 ntotaledgeentries+=dof*dof;
234 n_blks[1+edgematrixlocation++]=dof;
238 nlocalNonDirEdges+=dof*dof;
243 m_comm = expList->GetComm()->GetRowComm();
247 Array<OneD, long> EdgeBlockToUniversalMap(ntotaledgeentries,-1);
249 Array<OneD, int> localEdgeToGlobalMatrixMap(nlocalNonDirEdges,-1);
252 Array<OneD, NekDouble> EdgeBlockArray(nlocalNonDirEdges,-1);
254 int edgematrixoffset=0;
257 for(n=0; n < n_exp; ++n)
259 nel = expList->GetOffset_Elmt_Id(n);
261 locExpansion = expList->GetExp(nel);
264 for(j = 0; j < locExpansion->GetNedges(); ++j)
268 ->GetGeom2D()->GetEid(j);
272 if(edgeDirMap.count(meshEdgeId)==0)
274 for(k=0; k<nedgemodes*nedgemodes; ++k)
276 vGlobal=edgeglobaloffset[uniqueEdgeMap[meshEdgeId]]+k;
279 localEdgeToGlobalMatrixMap[edgematrixoffset+k]=vGlobal;
281 EdgeBlockToUniversalMap[vGlobal]
282 = meshEdgeId * maxEdgeDof * maxEdgeDof + k + 1;
284 edgematrixoffset+=nedgemodes*nedgemodes;
297 for(cnt=n=0; n < n_exp; ++n)
299 nel = expList->GetOffset_Elmt_Id(n);
301 locExpansion = expList->GetExp(nel);
303 nVerts=locExpansion->GetGeom()->GetNumVerts();
304 nEdges=locExpansion->GetGeom()->GetNumEdges();
307 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
310 bnd_mat=loc_mat->GetBlock(0,0);
313 offset = bnd_mat->GetRows();
319 for (v=0; v<nVerts; ++v)
321 vMap1=locExpansion->GetVertexMap(v);
325 GetLocalToGlobalBndMap(cnt+vMap1)-nDirBnd;
329 for (m=0; m<nVerts; ++m)
331 vMap2=locExpansion->GetVertexMap(m);
336 GetLocalToGlobalBndMap(cnt+vMap2)-nDirBnd;
339 if (globalcol == globalrow)
345 GetLocalToGlobalBndSign(cnt + vMap1);
347 GetLocalToGlobalBndSign(cnt + vMap2);
350 += sign1*sign2*S(vMap1,vMap2);
352 VertBlockToUniversalMap[globalrow]
353 = meshVertId * maxEdgeDof * maxEdgeDof + 1;
360 for (eid=0; eid<nEdges; ++eid)
362 nedgemodes=locExpansion->GetEdgeNcoeffs(eid)-2;
366 (nedgemodes,nedgemodes,zero,storage);
369 Array<OneD, unsigned int> edgemodearray =
372 if(edgeDirMap.count(meshEdgeId)==0)
374 for (v=0; v<nedgemodes; ++v)
376 eMap1=edgemodearray[v];
378 for (m=0; m<nedgemodes; ++m)
380 eMap2=edgemodearray[m];
384 GetLocalToGlobalBndSign(cnt + eMap1);
386 GetLocalToGlobalBndSign(cnt + eMap2);
389 sign1*sign2*S(eMap1,eMap2);
391 EdgeBlockArray[edgematrixoffset+v*nedgemodes+m]=
395 edgematrixoffset+=nedgemodes*nedgemodes;
404 Array<OneD, NekDouble> GlobalEdgeBlock(ntotaledgeentries);
405 Vmath::Zero(ntotaledgeentries, GlobalEdgeBlock.get(), 1);
407 EdgeBlockArray.get(),
408 localEdgeToGlobalMatrixMap.get(),
409 GlobalEdgeBlock.get());
423 for (
int i = 0; i < nNonDirVerts; ++i)
425 VertBlk->SetValue(i,i,1.0/vertArray[i]);
433 for(
int loc=0; loc<nNonDirEdgeIDs; ++loc)
437 (nedgemodes,nedgemodes,zero,storage);
439 for (v=0; v<nedgemodes; ++v)
441 for (m=0; m<nedgemodes; ++m)
443 NekDouble EdgeValue = GlobalEdgeBlock[offset+v*nedgemodes+m];
444 gmat->SetValue(v,m,EdgeValue);
448 m_blkMat->SetBlock(1+loc,1+loc, gmat);
450 offset+=edgemodeoffset[loc];
453 int totblks=
m_blkMat->GetNumberOfBlockRows();
454 for (i=1; i< totblks; ++i)
456 unsigned int nmodes=
m_blkMat->GetNumberOfRowsInBlockRow(i);
459 (nmodes,nmodes,zero,storage);
472 boost::shared_ptr<MultiRegions::ExpList>
473 expList=((
m_linsys.lock())->GetLocMat()).lock();
478 int nVerts, nEdges,nFaces;
479 int eid, fid, n, cnt, nedgemodes, nfacemodes;
482 int vMap1, vMap2, sign1, sign2;
483 int m, v, eMap1, eMap2, fMap1, fMap2;
484 int offset, globalrow, globalcol;
504 Array<OneD, NekDouble> vertArray(nNonDirVerts,0.0);
505 Array<OneD, long> VertBlockToUniversalMap(nNonDirVerts,-1);
507 int n_exp = expList->GetNumElmts();
512 Array<OneD,unsigned int> n_blks(1+nNonDirEdgeIDs+nNonDirFaceIDs);
513 n_blks[0]=nNonDirVerts;
515 map<int,int> edgeDirMap;
516 map<int,int> faceDirMap;
517 map<int,int> uniqueEdgeMap;
518 map<int,int> uniqueFaceMap;
521 Array<OneD, int> edgemodeoffset(nNonDirEdgeIDs,0);
522 Array<OneD, int> facemodeoffset(nNonDirFaceIDs,0);
524 Array<OneD, int> edgeglobaloffset(nNonDirEdgeIDs,0);
525 Array<OneD, int> faceglobaloffset(nNonDirFaceIDs,0);
527 const Array<OneD, const ExpListSharedPtr>& bndCondExp = expList->GetBndCondExpansions();
529 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr>& bndConditions = expList->GetBndConditions();
535 const Array<OneD, const int> &extradiredges
537 for(i=0; i<extradiredges.num_elements(); ++i)
539 meshEdgeId=extradiredges[i];
540 edgeDirMap[meshEdgeId] = 1;
544 for(i = 0; i < bndCondExp.num_elements(); i++)
547 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
550 if (bndConditions[i]->GetBoundaryConditionType() ==
553 for(k = 0; k < bndCondFaceExp->GetNedges(); k++)
556 if(edgeDirMap.count(meshEdgeId) == 0)
558 edgeDirMap[meshEdgeId] = 1;
562 faceDirMap[meshFaceId] = 1;
570 int nlocalNonDirEdges=0;
571 int nlocalNonDirFaces=0;
573 int edgematrixlocation=0;
574 int ntotaledgeentries=0;
578 for(cnt=n=0; n < n_exp; ++n)
580 nel = expList->GetOffset_Elmt_Id(n);
582 locExpansion = expList->GetExp(nel);
584 for (j = 0; j < locExpansion->GetNedges(); ++j)
586 dof = locExpansion->GetEdgeNcoeffs(j)-2;
587 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
590 if(edgeDirMap.count(meshEdgeId)==0)
592 if(uniqueEdgeMap.count(meshEdgeId)==0 && dof > 0)
594 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
596 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
598 edgemodeoffset[edgematrixlocation]=dof*dof;
600 ntotaledgeentries+=dof*dof;
602 n_blks[1+edgematrixlocation++]=dof;
605 nlocalNonDirEdges+=dof*dof;
610 int facematrixlocation=0;
611 int ntotalfaceentries=0;
615 for(cnt=n=0; n < n_exp; ++n)
617 nel = expList->GetOffset_Elmt_Id(n);
619 locExpansion = expList->GetExp(nel);
621 for (j = 0; j < locExpansion->GetNfaces(); ++j)
623 dof = locExpansion->GetFaceIntNcoeffs(j);
624 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
628 if(faceDirMap.count(meshFaceId)==0)
630 if(uniqueFaceMap.count(meshFaceId)==0 && dof > 0)
632 uniqueFaceMap[meshFaceId]=facematrixlocation;
634 facemodeoffset[facematrixlocation]=dof*dof;
636 faceglobaloffset[facematrixlocation]+=ntotalfaceentries;
638 ntotalfaceentries+=dof*dof;
640 n_blks[1+nNonDirEdgeIDs+facematrixlocation++]=dof;
642 nlocalNonDirFaces+=dof*dof;
648 m_comm = expList->GetComm();
653 Array<OneD, long> EdgeBlockToUniversalMap(ntotaledgeentries,-1);
654 Array<OneD, long> FaceBlockToUniversalMap(ntotalfaceentries,-1);
656 Array<OneD, int> localEdgeToGlobalMatrixMap(nlocalNonDirEdges,-1);
657 Array<OneD, int> localFaceToGlobalMatrixMap(nlocalNonDirFaces,-1);
660 Array<OneD, NekDouble> EdgeBlockArray(nlocalNonDirEdges,-1);
661 Array<OneD, NekDouble> FaceBlockArray(nlocalNonDirFaces,-1);
663 int edgematrixoffset=0;
664 int facematrixoffset=0;
667 for(n=0; n < n_exp; ++n)
669 nel = expList->GetOffset_Elmt_Id(n);
671 locExpansion = expList->GetExp(nel);
674 for(j = 0; j < locExpansion->GetNedges(); ++j)
681 if(edgeDirMap.count(meshEdgeId)==0)
683 for(k=0; k<nedgemodes*nedgemodes; ++k)
685 vGlobal=edgeglobaloffset[uniqueEdgeMap[meshEdgeId]]+k;
688 localEdgeToGlobalMatrixMap[edgematrixoffset+k]=vGlobal;
690 EdgeBlockToUniversalMap[vGlobal]
691 = meshEdgeId * maxEdgeDof * maxEdgeDof + k + 1;
693 edgematrixoffset+=nedgemodes*nedgemodes;
698 for(j = 0; j < locExpansion->GetNfaces(); ++j)
706 if(faceDirMap.count(meshFaceId)==0)
708 for(k=0; k<nfacemodes*nfacemodes; ++k)
710 vGlobal=faceglobaloffset[uniqueFaceMap[meshFaceId]]+k;
712 localFaceToGlobalMatrixMap[facematrixoffset+k]
715 FaceBlockToUniversalMap[vGlobal]
716 = meshFaceId * maxFaceDof * maxFaceDof + k + 1;
718 facematrixoffset+=nfacemodes*nfacemodes;
732 for(cnt=n=0; n < n_exp; ++n)
734 nel = expList->GetOffset_Elmt_Id(n);
736 locExpansion = expList->GetExp(nel);
738 nVerts=locExpansion->GetGeom()->GetNumVerts();
739 nEdges=locExpansion->GetGeom()->GetNumEdges();
740 nFaces=locExpansion->GetGeom()->GetNumFaces();
743 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
746 bnd_mat=loc_mat->GetBlock(0,0);
749 offset = bnd_mat->GetRows();
755 for (v=0; v<nVerts; ++v)
757 vMap1=locExpansion->GetVertexMap(v);
761 GetLocalToGlobalBndMap(cnt+vMap1)-nDirBnd;
765 for (m=0; m<nVerts; ++m)
767 vMap2=locExpansion->GetVertexMap(m);
772 GetLocalToGlobalBndMap(cnt+vMap2)-nDirBnd;
775 if (globalcol == globalrow)
781 GetLocalToGlobalBndSign(cnt + vMap1);
783 GetLocalToGlobalBndSign(cnt + vMap2);
786 += sign1*sign2*S(vMap1,vMap2);
788 VertBlockToUniversalMap[globalrow]
789 = meshVertId * maxEdgeDof * maxEdgeDof + 1;
796 for (eid=0; eid<nEdges; ++eid)
798 nedgemodes=locExpansion->GetEdgeNcoeffs(eid)-2;
802 (nedgemodes,nedgemodes,zero,storage);
807 if(edgeDirMap.count(meshEdgeId)==0)
809 for (v=0; v<nedgemodes; ++v)
811 eMap1=edgemodearray[v];
813 for (m=0; m<nedgemodes; ++m)
815 eMap2=edgemodearray[m];
819 GetLocalToGlobalBndSign(cnt + eMap1);
821 GetLocalToGlobalBndSign(cnt + eMap2);
823 NekDouble globalEdgeValue = sign1*sign2*S(eMap1,eMap2);
825 EdgeBlockArray[edgematrixoffset+v*nedgemodes+m]=globalEdgeValue;
828 edgematrixoffset+=nedgemodes*nedgemodes;
833 for (fid=0; fid<nFaces; ++fid)
835 nfacemodes = locExpansion->GetFaceIntNcoeffs(fid);
839 (nfacemodes,nfacemodes,zero,storage);
845 if(faceDirMap.count(meshFaceId)==0)
847 for (v=0; v<nfacemodes; ++v)
849 fMap1=facemodearray[v];
851 for (m=0; m<nfacemodes; ++m)
853 fMap2=facemodearray[m];
857 GetLocalToGlobalBndSign(cnt + fMap1);
859 GetLocalToGlobalBndSign(cnt + fMap2);
862 NekDouble globalFaceValue = sign1*sign2*S(fMap1,fMap2);
865 FaceBlockArray[facematrixoffset+v*nfacemodes+m]=globalFaceValue;
868 facematrixoffset+=nfacemodes*nfacemodes;
877 Array<OneD, NekDouble> GlobalEdgeBlock(ntotaledgeentries);
878 Vmath::Zero(ntotaledgeentries, GlobalEdgeBlock.get(), 1);
880 EdgeBlockArray.get(),
881 localEdgeToGlobalMatrixMap.get(),
882 GlobalEdgeBlock.get());
885 Array<OneD, NekDouble> GlobalFaceBlock(ntotalfaceentries);
886 Vmath::Zero(ntotalfaceentries, GlobalFaceBlock.get(), 1);
888 FaceBlockArray.get(),
889 localFaceToGlobalMatrixMap.get(),
890 GlobalFaceBlock.get());
908 for (
int i = 0; i < nNonDirVerts; ++i)
910 VertBlk->SetValue(i,i,1.0/vertArray[i]);
918 for(
int loc=0; loc<nNonDirEdgeIDs; ++loc)
922 (nedgemodes,nedgemodes,zero,storage);
924 for (v=0; v<nedgemodes; ++v)
926 for (m=0; m<nedgemodes; ++m)
928 NekDouble EdgeValue = GlobalEdgeBlock[offset+v*nedgemodes+m];
929 gmat->SetValue(v,m,EdgeValue);
933 m_blkMat->SetBlock(1+loc,1+loc, gmat);
935 offset+=edgemodeoffset[loc];
940 for(
int loc=0; loc<nNonDirFaceIDs; ++loc)
942 nfacemodes=n_blks[1+nNonDirEdgeIDs+loc];
946 (nfacemodes,nfacemodes,zero,storage);
948 for (v=0; v<nfacemodes; ++v)
950 for (m=0; m<nfacemodes; ++m)
952 NekDouble FaceValue = GlobalFaceBlock[offset+v*nfacemodes+m];
953 gmat->SetValue(v,m,FaceValue);
957 m_blkMat->SetBlock(1+nNonDirEdgeIDs+loc,1+nNonDirEdgeIDs+loc, gmat);
959 offset+=facemodeoffset[loc];
963 int totblks=
m_blkMat->GetNumberOfBlockRows();
964 for (i=1; i< totblks; ++i)
966 unsigned int nmodes=
m_blkMat->GetNumberOfRowsInBlockRow(i);
969 (nmodes,nmodes,zero,storage);
980 boost::shared_ptr<MultiRegions::ExpList>
981 expList=((
m_linsys.lock())->GetLocMat()).lock();
982 boost::shared_ptr<MultiRegions::ExpList> trace = expList->GetTrace();
990 int i, j, k, n, cnt, cnt2;
993 int nTrace = expList->GetTrace()->GetExpSize();
996 for (cnt = n = 0; n < nTrace; ++n)
1003 cnt += trace->GetExp(n)->GetNcoeffs();
1010 int maxTraceSize = -1;
1011 map<int, int> arrayOffsets;
1013 for (cnt = 0, n = nDir; n < nTrace; ++n)
1015 int nCoeffs = trace->GetExp(n)->GetNcoeffs();
1016 int nCoeffs2 = nCoeffs * nCoeffs;
1018 arrayOffsets[n] = cnt;
1021 if (maxTraceSize < nCoeffs2)
1023 maxTraceSize = nCoeffs2;
1029 expList->GetSession()->GetComm()->GetRowComm();
1033 Array<OneD, NekDouble> tmpStore(cnt, 0.0);
1036 for (cnt = n = 0; n < expList->GetExpSize(); ++n)
1038 int elmt = expList->GetOffset_Elmt_Id(n);
1039 locExpansion = expList->GetExp(elmt);
1041 Array<OneD, LocalRegions::ExpansionSharedPtr> &elmtToTraceMap =
1042 asmMap->GetElmtToTrace()[elmt];
1045 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
1046 bnd_mat = loc_mat->GetBlock(0,0);
1048 int nFacets = locExpansion->GetNumBases() == 2 ?
1049 locExpansion->GetNedges() : locExpansion->GetNfaces();
1051 for (cnt2 = i = 0; i < nFacets; ++i)
1053 int nCoeffs = elmtToTraceMap[i]->GetNcoeffs();
1054 int elmtId = elmtToTraceMap[i]->GetElmtId ();
1064 NekDouble *off = &tmpStore[arrayOffsets[elmtId]];
1066 for (j = 0; j < nCoeffs; ++j)
1068 NekDouble sign1 = asmMap->GetLocalToGlobalBndSign(
1070 for (k = 0; k < nCoeffs; ++k)
1072 NekDouble sign2 = asmMap->GetLocalToGlobalBndSign(
1074 off[j*nCoeffs + k] +=
1075 (*bnd_mat)(cnt2+j, cnt2+k) * sign1 * sign2;
1085 Array<OneD, long> uniIds(tmpStore.num_elements());
1086 for (cnt = 0, n = nDir; n < nTrace; ++n)
1089 int nCoeffs = traceExp->GetNcoeffs();
1090 int geomId = traceExp->GetGeom()->GetGlobalID();
1092 for (i = 0; i < nCoeffs*nCoeffs; ++i)
1094 uniIds[cnt++] = geomId * maxTraceSize + i + 1;
1103 Array<OneD, unsigned int> n_blks(nTrace - nDir);
1104 for (n = 0; n < nTrace - nDir; ++n)
1106 n_blks[n] = trace->GetExp(n + nDir)->GetNcoeffs();
1112 for (n = 0; n < nTrace - nDir; ++n)
1114 int nCoeffs = trace->GetExp(n + nDir)->GetNcoeffs();
1117 NekDouble *off = &tmpStore[arrayOffsets[n+nDir]];
1119 for (i = 0; i < nCoeffs; ++i)
1121 for (j = 0; j < nCoeffs; ++j)
1123 (*tmp)(i,j) = off[i*nCoeffs + j];
1136 const Array<OneD, NekDouble>& pInput,
1137 Array<OneD, NekDouble>& pOutput)
1141 int nNonDir = nGlobal-nDir;