46 namespace MultiRegions
55 "LowEnergy Preconditioning");
65 const boost::shared_ptr<GlobalLinSys> &plinsys,
69 m_locToGloMap(pLocToGloMap)
78 boost::shared_ptr<MultiRegions::ExpList>
79 expList=((
m_linsys.lock())->GetLocMat()).lock();
83 locExpansion = expList->GetExp(0);
85 int nDim = locExpansion->GetShapeDimension();
88 "Preconditioner type only valid in 3D");
120 boost::shared_ptr<MultiRegions::ExpList>
121 expList=((
m_linsys.lock())->GetLocMat()).lock();
126 int nVerts, nEdges,nFaces;
127 int eid, fid, n, cnt, nedgemodes, nfacemodes;
130 int vMap1, vMap2, sign1, sign2;
131 int m, v, eMap1, eMap2, fMap1, fMap2;
132 int offset, globalrow, globalcol, nCoeffs;
138 expList->GetPeriodicEntities(periodicVerts,periodicEdges,periodicFaces);
169 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transmatrixmap;
170 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transposedtransmatrixmap;
182 int n_exp = expList->GetNumElmts();
187 int numBlks = 1+nNonDirEdgeIDs+nNonDirFaceIDs;
189 for(i = 0; i < numBlks; ++i)
193 n_blks[0]=nNonDirVerts;
197 map<int,int> uniqueEdgeMap;
198 map<int,int> uniqueFaceMap;
217 for(i=0; i<extradiredges.num_elements(); ++i)
219 meshEdgeId=extradiredges[i];
220 edgeDirMap.insert(meshEdgeId);
224 for(i = 0; i < bndCondExp.num_elements(); i++)
227 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
229 bndCondFaceExp = boost::dynamic_pointer_cast<
231 if (bndConditions[i]->GetBoundaryConditionType() ==
234 for(k = 0; k < bndCondFaceExp->GetNedges(); k++)
237 if(edgeDirMap.count(meshEdgeId) == 0)
239 edgeDirMap.insert(meshEdgeId);
243 faceDirMap.insert(meshFaceId);
251 int nlocalNonDirEdges=0;
252 int nlocalNonDirFaces=0;
254 int edgematrixlocation=0;
255 int ntotaledgeentries=0;
257 map<int,int> EdgeSize;
258 map<int,int> FaceSize;
261 for(n = 0; n < n_exp; ++n)
263 eid = expList->GetOffset_Elmt_Id(n);
264 locExpansion = expList->GetExp(eid);
266 nEdges = locExpansion->GetNedges();
267 for(j = 0; j < nEdges; ++j)
269 int nEdgeInteriorCoeffs = locExpansion->GetEdgeNcoeffs(j) - 2;
271 EdgeSize[meshEdgeId] = nEdgeInteriorCoeffs;
274 nFaces = locExpansion->GetNfaces();
275 for(j = 0; j < nFaces; ++j)
277 int nFaceInteriorCoeffs = locExpansion->GetFaceIntNcoeffs(j);
279 FaceSize[meshFaceId] = nFaceInteriorCoeffs;
283 m_comm = expList->GetComm();
289 PeriodicMap::const_iterator pIt;
290 for (pIt = periodicEdges.begin(); pIt != periodicEdges.end(); ++pIt)
292 meshEdgeId = pIt->first;
294 if(edgeDirMap.count(meshEdgeId)==0)
296 dof = EdgeSize[meshEdgeId];
297 if(uniqueEdgeMap.count(meshEdgeId)==0 && dof > 0)
299 bool SetUpNewEdge =
true;
302 for (i = 0; i < pIt->second.size(); ++i)
304 if (!pIt->second[i].isLocal)
309 int meshEdgeId2 = pIt->second[i].id;
311 if(edgeDirMap.count(meshEdgeId2)==0)
313 if(uniqueEdgeMap.count(meshEdgeId2)!=0)
316 uniqueEdgeMap[meshEdgeId] =
317 uniqueEdgeMap[meshEdgeId2];
318 SetUpNewEdge =
false;
323 edgeDirMap.insert(meshEdgeId);
324 SetUpNewEdge =
false;
330 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
332 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
334 edgemodeoffset[edgematrixlocation]=dof*dof;
336 ntotaledgeentries+=dof*dof;
338 n_blks[1+edgematrixlocation++]=dof;
346 for(cnt=n=0; n < n_exp; ++n)
348 eid = expList->GetOffset_Elmt_Id(n);
349 locExpansion = expList->GetExp(eid);
351 for (j = 0; j < locExpansion->GetNedges(); ++j)
354 dof = EdgeSize[meshEdgeId];
355 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
357 if(edgeDirMap.count(meshEdgeId)==0)
359 if(uniqueEdgeMap.count(meshEdgeId)==0 && dof > 0)
362 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
364 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
366 edgemodeoffset[edgematrixlocation]=dof*dof;
368 ntotaledgeentries+=dof*dof;
370 n_blks[1+edgematrixlocation++]=dof;
373 nlocalNonDirEdges+=dof*dof;
378 int facematrixlocation=0;
379 int ntotalfaceentries=0;
384 for (pIt = periodicFaces.begin(); pIt != periodicFaces.end(); ++pIt)
386 meshFaceId = pIt->first;
388 if(faceDirMap.count(meshFaceId)==0)
390 dof = FaceSize[meshFaceId];
392 if(uniqueFaceMap.count(meshFaceId) == 0 && dof > 0)
394 bool SetUpNewFace =
true;
396 if(pIt->second[0].isLocal)
398 int meshFaceId2 = pIt->second[0].id;
400 if(faceDirMap.count(meshFaceId2)==0)
402 if(uniqueFaceMap.count(meshFaceId2)!=0)
405 uniqueFaceMap[meshFaceId] =
406 uniqueFaceMap[meshFaceId2];
407 SetUpNewFace =
false;
412 faceDirMap.insert(meshFaceId);
413 SetUpNewFace =
false;
419 uniqueFaceMap[meshFaceId]=facematrixlocation;
421 facemodeoffset[facematrixlocation]=dof*dof;
423 faceglobaloffset[facematrixlocation]+=ntotalfaceentries;
425 ntotalfaceentries+=dof*dof;
427 n_blks[1+nNonDirEdgeIDs+facematrixlocation++]=dof;
434 for(cnt=n=0; n < n_exp; ++n)
436 eid = expList->GetOffset_Elmt_Id(n);
438 locExpansion = expList->GetExp(eid);
440 for (j = 0; j < locExpansion->GetNfaces(); ++j)
444 dof = FaceSize[meshFaceId];
445 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
448 if(faceDirMap.count(meshFaceId)==0)
450 if(uniqueFaceMap.count(meshFaceId)==0 && dof > 0)
452 uniqueFaceMap[meshFaceId]=facematrixlocation;
454 facemodeoffset[facematrixlocation]=dof*dof;
456 faceglobaloffset[facematrixlocation]+=ntotalfaceentries;
458 ntotalfaceentries+=dof*dof;
460 n_blks[1+nNonDirEdgeIDs+facematrixlocation++]=dof;
463 nlocalNonDirFaces+=dof*dof;
482 int edgematrixoffset=0;
483 int facematrixoffset=0;
486 for(n=0; n < n_exp; ++n)
488 eid = expList->GetOffset_Elmt_Id(n);
490 locExpansion = expList->GetExp(eid);
493 for(j = 0; j < locExpansion->GetNedges(); ++j)
500 if(edgeDirMap.count(meshEdgeId)==0)
503 int edgeOffset = edgeglobaloffset[uniqueEdgeMap[meshEdgeId]];
506 int uniOffset = meshEdgeId;
507 pIt = periodicEdges.find(meshEdgeId);
508 if (pIt != periodicEdges.end())
510 for (
int l = 0; l < pIt->second.size(); ++l)
512 uniOffset = min(uniOffset, pIt->second[l].id);
515 uniOffset = uniOffset *maxEdgeDof*maxEdgeDof;
517 for(k=0; k<nedgemodes*nedgemodes; ++k)
519 vGlobal=edgeOffset+k;
520 localEdgeToGlobalMatrixMap[edgematrixoffset+k]=vGlobal;
521 EdgeBlockToUniversalMap[vGlobal] = uniOffset + k + 1;
523 edgematrixoffset+=nedgemodes*nedgemodes;
530 for(j = 0; j < locExpansion->GetNfaces(); ++j)
538 if(faceDirMap.count(meshFaceId)==0)
541 int faceOffset = faceglobaloffset[uniqueFaceMap[meshFaceId]];
544 int uniOffset = meshFaceId;
546 pIt = periodicFaces.find(meshFaceId);
547 if (pIt != periodicFaces.end())
549 uniOffset = min(uniOffset, pIt->second[0].id);
551 uniOffset = uniOffset * maxFaceDof * maxFaceDof;
553 for(k=0; k<nfacemodes*nfacemodes; ++k)
555 vGlobal=faceOffset+k;
557 localFaceToGlobalMatrixMap[facematrixoffset+k]
560 FaceBlockToUniversalMap[vGlobal] = uniOffset + k + 1;
562 facematrixoffset+=nfacemodes*nfacemodes;
585 for(cnt=n=0; n < n_exp; ++n)
587 eid = expList->GetOffset_Elmt_Id(n);
589 locExpansion = expList->GetExp(eid);
590 nCoeffs=locExpansion->NumBndryCoeffs();
594 R=(*(transmatrixmap[eType]));
595 RT=(*(transposedtransmatrixmap[eType]));
598 (nCoeffs, nCoeffs, zero, storage);
602 (nCoeffs, nCoeffs, zero, storage);
605 nVerts=locExpansion->GetGeom()->GetNumVerts();
606 nEdges=locExpansion->GetGeom()->GetNumEdges();
607 nFaces=locExpansion->GetGeom()->GetNumFaces();
610 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
613 bnd_mat=loc_mat->GetBlock(0,0);
616 offset = bnd_mat->GetRows();
628 for (v=0; v<nVerts; ++v)
630 vMap1=locExpansion->GetVertexMap(v);
634 GetLocalToGlobalBndMap(cnt+vMap1)-nDirBnd;
638 for (m=0; m<nVerts; ++m)
640 vMap2=locExpansion->GetVertexMap(m);
645 GetLocalToGlobalBndMap(cnt+vMap2)-nDirBnd;
648 if (globalcol == globalrow)
652 GetLocalToGlobalBndSign(cnt + vMap1);
654 GetLocalToGlobalBndSign(cnt + vMap2);
657 += sign1*sign2*RSRT(vMap1,vMap2);
662 pIt = periodicVerts.find(meshVertId);
663 if (pIt != periodicVerts.end())
665 for (k = 0; k < pIt->second.size(); ++k)
667 meshVertId = min(meshVertId, pIt->second[k].id);
671 VertBlockToUniversalMap[globalrow]
679 for (eid=0; eid<nEdges; ++eid)
681 nedgemodes=locExpansion->GetEdgeNcoeffs(eid)-2;
685 (nedgemodes,nedgemodes,zero,storage);
690 if(edgeDirMap.count(meshEdgeId)==0)
692 for (v=0; v<nedgemodes; ++v)
694 eMap1=edgemodearray[v];
696 for (m=0; m<nedgemodes; ++m)
698 eMap2=edgemodearray[m];
702 GetLocalToGlobalBndSign(cnt + eMap1);
704 GetLocalToGlobalBndSign(cnt + eMap2);
706 NekDouble globalEdgeValue = sign1*sign2*RSRT(eMap1,eMap2);
708 EdgeBlockArray[edgematrixoffset+v*nedgemodes+m]=globalEdgeValue;
711 edgematrixoffset+=nedgemodes*nedgemodes;
716 for (fid=0; fid<nFaces; ++fid)
718 nfacemodes = locExpansion->GetFaceIntNcoeffs(fid);
722 (nfacemodes,nfacemodes,zero,storage);
726 if(faceDirMap.count(meshFaceId)==0)
731 pIt = periodicFaces.find(meshFaceId);
732 if (pIt != periodicFaces.end())
734 if(meshFaceId == min(meshFaceId, pIt->second[0].id))
736 facemodearray = locExpansion->GetFaceInverseBoundaryMap(fid,faceOrient);
741 facemodearray = locExpansion->GetFaceInverseBoundaryMap(fid,faceOrient);
744 for (v=0; v<nfacemodes; ++v)
746 fMap1=facemodearray[v];
748 for (m=0; m<nfacemodes; ++m)
750 fMap2=facemodearray[m];
754 GetLocalToGlobalBndSign(cnt + fMap1);
756 GetLocalToGlobalBndSign(cnt + fMap2);
759 NekDouble globalFaceValue = sign1*sign2*RSRT(fMap1,fMap2);
762 FaceBlockArray[facematrixoffset+v*nfacemodes+m]=globalFaceValue;
765 facematrixoffset+=nfacemodes*nfacemodes;
773 m_RBlk->SetBlock(n,n, transmatrixmap[eType]);
774 m_RTBlk->SetBlock(n,n, transposedtransmatrixmap[eType]);
786 if(ntotaledgeentries)
791 localEdgeToGlobalMatrixMap,
800 if(ntotalfaceentries)
805 localFaceToGlobalMatrixMap,
814 for (
int i = 0; i < nNonDirVerts; ++i)
816 VertBlk->SetValue(i,i,1.0/vertArray[i]);
825 for(
int loc=0; loc<nNonDirEdgeIDs; ++loc)
827 nedgemodes = n_blks[1+loc];
829 (nedgemodes,nedgemodes,zero,storage);
831 for (v=0; v<nedgemodes; ++v)
833 for (m=0; m<nedgemodes; ++m)
835 NekDouble EdgeValue = GlobalEdgeBlock[offset+v*nedgemodes+m];
836 gmat->SetValue(v,m,EdgeValue);
841 m_BlkMat->SetBlock(1+loc,1+loc, gmat);
842 offset+=edgemodeoffset[loc];
849 for(
int loc=0; loc<nNonDirFaceIDs; ++loc)
851 nfacemodes=n_blks[1+nNonDirEdgeIDs+loc];
853 (nfacemodes,nfacemodes,zero,storage);
855 for (v=0; v<nfacemodes; ++v)
857 for (m=0; m<nfacemodes; ++m)
859 NekDouble FaceValue = GlobalFaceBlock[offset+v*nfacemodes+m];
860 gmat->SetValue(v,m,FaceValue);
864 m_BlkMat->SetBlock(1+nNonDirEdgeIDs+loc,1+nNonDirEdgeIDs+loc, gmat);
865 offset+=facemodeoffset[loc];
868 int totblks=
m_BlkMat->GetNumberOfBlockRows();
869 for (i=1; i< totblks; ++i)
871 unsigned int nmodes=
m_BlkMat->GetNumberOfRowsInBlockRow(i);
876 (nmodes,nmodes,zero,storage);
897 int nNonDir = nGlobal-nDir;
914 boost::shared_ptr<MultiRegions::ExpList>
915 expList=((
m_linsys.lock())->GetLocMat()).lock();
923 int n_exp=expList->GetNumElmts();
926 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transmatrixmap;
927 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transposedtransmatrixmap;
928 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> invtransmatrixmap;
929 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> invtransposedtransmatrixmap;
963 for(n=0; n < n_exp; ++n)
965 nel = expList->GetOffset_Elmt_Id(n);
967 locExpansion = expList->GetExp(nel);
971 m_RBlk->SetBlock(n,n, transmatrixmap[eType]);
974 m_RTBlk->SetBlock(n,n, transposedtransmatrixmap[eType]);
977 m_InvRBlk->SetBlock(n,n, invtransmatrixmap[eType]);
980 m_InvRTBlk->SetBlock(n,n, invtransposedtransmatrixmap[eType]);
999 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1015 Vmath::Vcopy(nGlobBndDofs, pInOut.get(), 1, tmp.get(), 1);
1021 F_LocBnd=R*F_LocBnd;
1039 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1040 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1044 ASSERTL1(pInput.num_elements() >= nGlobHomBndDofs,
1045 "Input array is greater than the nGlobHomBndDofs");
1046 ASSERTL1(pOutput.num_elements() >= nGlobHomBndDofs,
1047 "Output array is greater than the nGlobHomBndDofs");
1064 Vmath::Vcopy(nGlobHomBndDofs, pInput.get(), 1, tmp.get() + nDirBndDofs, 1);
1070 F_LocBnd=R*F_LocBnd;
1089 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1090 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1093 ASSERTL1(pInOut.num_elements() >= nGlobBndDofs,
1094 "Output array is greater than the nGlobBndDofs");
1108 m_locToGloMap->GlobalToLocalBnd(V_GlobHomBnd,V_LocBnd, nDirBndDofs);
1111 V_LocBnd=RT*V_LocBnd;
1121 Vmath::Vcopy(nGlobBndDofs-nDirBndDofs, tmp.get() + nDirBndDofs, 1, pInOut.get() + nDirBndDofs, 1);
1132 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1133 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1136 ASSERTL1(pInput.num_elements() >= nGlobHomBndDofs,
1137 "Input array is greater than the nGlobHomBndDofs");
1138 ASSERTL1(pOutput.num_elements() >= nGlobHomBndDofs,
1139 "Output array is greater than the nGlobHomBndDofs");
1156 Vmath::Vcopy(nGlobHomBndDofs, pInput.get(), 1, tmp.get() + nDirBndDofs, 1);
1162 F_LocBnd=invR*F_LocBnd;
1177 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1178 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1181 ASSERTL1(pInput.num_elements() >= nGlobHomBndDofs,
1182 "Input array is greater than the nGlobHomBndDofs");
1183 ASSERTL1(pOutput.num_elements() >= nGlobHomBndDofs,
1184 "Output array is greater than the nGlobHomBndDofs");
1197 m_locToGloMap->GlobalToLocalBnd(pInput,pLocal, nDirBndDofs);
1200 F_LocBnd=invRT*F_LocBnd;
1218 const boost::shared_ptr<DNekScalMat > &loc_mat)
1220 boost::shared_ptr<MultiRegions::ExpList>
1221 expList=((
m_linsys.lock())->GetLocMat()).lock();
1224 locExpansion = expList->GetExp(offset);
1225 unsigned int nbnd=locExpansion->NumBndryCoeffs();
1231 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transmatrixmap;
1232 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transposedtransmatrixmap;
1248 (expList->GetExp(offset))->DetShapeType();
1252 DNekScalMat &RT = (*(transposedtransmatrixmap[eType]));
1273 unsigned int nGlobalBnd =
m_locToGloMap->GetNumGlobalBndCoeffs();
1274 unsigned int nEntries =
m_locToGloMap->GetNumLocalBndCoeffs();
1287 for (i = 0; i < nEntries; ++i)
1289 vCounts[vMap[i]] += 1.0;
1297 for (i = 0; i < nEntries; ++i)
1310 int nGlobHomBnd = nGlobalBnd - nDirBnd;
1335 const int nVerts = 6;
1336 const double point[][3] = {
1337 {-1,-1,0}, {1,-1,0}, {1,1,0},
1338 {-1,1,0}, {0,-1,sqrt(
double(3))}, {0,1,sqrt(
double(3))},
1343 for(
int i=0; i < nVerts; ++i)
1346 ( three, i, point[i][0], point[i][1], point[i][2] );
1348 const int nEdges = 9;
1349 const int vertexConnectivity[][2] = {
1350 {0,1}, {1,2}, {3,2}, {0,3}, {0,4},
1351 {1,4}, {2,5}, {3,5}, {4,5}
1356 for(
int i=0; i < nEdges; ++i){
1358 for(
int j=0; j<2; ++j)
1360 vertsArray[j] = verts[vertexConnectivity[i][j]];
1369 const int nFaces = 5;
1371 const int quadEdgeConnectivity[][4] = { {0,1,2,3}, {1,6,8,5}, {3,7,8,4} };
1372 const bool isQuadEdgeFlipped[][4] = { {0,0,1,1}, {0,0,1,1}, {0,0,1,1} };
1374 const int quadId[] = { 0,-1,1,-1,2 };
1377 const int triEdgeConnectivity[][3] = { {0,5,4}, {2,6,7} };
1378 const bool isTriEdgeFlipped[][3] = { {0,0,1}, {0,0,1} };
1380 const int triId[] = { -1,0,-1,1,-1 };
1384 for(
int f = 0; f < nFaces; ++f){
1385 if(f == 1 || f == 3) {
1389 for(
int j = 0; j < 3; ++j){
1390 edgeArray[j] = edges[triEdgeConnectivity[i][j]];
1399 for(
int j=0; j < 4; ++j){
1400 edgeArray[j] = edges[quadEdgeConnectivity[i][j]];
1426 const int nVerts = 4;
1427 const double point[][3] = {
1428 {-1,-1/sqrt(
double(3)),-1/sqrt(
double(6))},
1429 {1,-1/sqrt(
double(3)),-1/sqrt(
double(6))},
1430 {0,2/sqrt(
double(3)),-1/sqrt(
double(6))},
1431 {0,0,3/sqrt(
double(6))}};
1433 boost::shared_ptr<SpatialDomains::PointGeom> verts[4];
1434 for(i=0; i < nVerts; ++i)
1439 ( three, i, point[i][0], point[i][1], point[i][2] );
1447 const int nEdges = 6;
1448 const int vertexConnectivity[][2] = {
1449 {0,1},{1,2},{0,2},{0,3},{1,3},{2,3}
1454 for(i=0; i < nEdges; ++i)
1456 boost::shared_ptr<SpatialDomains::PointGeom>
1460 vertsArray[j] = verts[vertexConnectivity[i][j]];
1471 const int nFaces = 4;
1472 const int edgeConnectivity[][3] = {
1473 {0,1,2}, {0,4,3}, {1,5,4}, {2,5,3}
1475 const bool isEdgeFlipped[][3] = {
1476 {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
1481 for(i=0; i < nFaces; ++i)
1485 for(j=0; j < 3; ++j)
1487 edgeArray[j] = edges[edgeConnectivity[i][j]];
1488 eorientArray[j] = isEdgeFlipped[i][j] ?
1518 const int nVerts = 8;
1519 const double point[][3] = {
1520 {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0},
1521 {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}
1526 for(
int i = 0; i < nVerts; ++i ) {
1529 point[i][1], point[i][2]);
1537 const int nEdges = 12;
1538 const int vertexConnectivity[][2] = {
1539 {0,1}, {1,2}, {2,3}, {0,3}, {0,4}, {1,5},
1540 {2,6}, {3,7}, {4,5}, {5,6}, {6,7}, {4,7}
1545 for(
int i = 0; i < nEdges; ++i ) {
1547 for(
int j = 0; j < 2; ++j ) {
1548 vertsArray[j] = verts[vertexConnectivity[i][j]];
1558 const int nFaces = 6;
1559 const int edgeConnectivity[][4] = {
1560 {0,1,2,3}, {0,5,8,4}, {1,6,9,5},
1561 {2,7,10,6}, {3,7,11,4}, {8,9,10,11}
1563 const bool isEdgeFlipped[][4] = {
1564 {0,0,0,1}, {0,0,1,1}, {0,0,1,1},
1565 {0,0,1,1}, {0,0,1,1}, {0,0,0,1}
1570 for(
int i = 0; i < nFaces; ++i ) {
1573 for(
int j = 0; j < 4; ++j ) {
1574 edgeArray[j] = edges[edgeConnectivity[i][j]];
1575 eorientArray[j] = isEdgeFlipped[i][j] ?
1602 boost::shared_ptr<MultiRegions::ExpList>
1603 expList=((
m_linsys.lock())->GetLocMat()).lock();
1607 locExpansion = expList->GetExp(0);
1614 DNekMatSharedPtr Rtettmp, RTtettmp, Rhextmp, RThextmp, Rprismtmp, RTprismtmp ;
1630 int nummodes=locExpansion->GetBasisNumModes(0);
1690 StdRegions::VarCoeffMap::const_iterator x;
1691 cnt = expList->GetPhys_Offset(0);
1695 vVarCoeffMap[x->first] = x->second + cnt;
1762 m_Rtet = TetExp->GetLocMatrix(TetR);
1765 m_RTtet = TetExp->GetLocMatrix(TetRT);
1769 Rtettmp=TetExp->BuildInverseTransformationMatrix(m_Rtet);
1772 RTtettmp=TetExp->BuildInverseTransformationMatrix(m_Rtet);
1773 RTtettmp->Transpose();
1785 m_Rhex = HexExp->GetLocMatrix(HexR);
1787 m_RThex = HexExp->GetLocMatrix(HexRT);
1791 Rhextmp=HexExp->BuildInverseTransformationMatrix(
m_Rhex);
1793 RThextmp=HexExp->BuildInverseTransformationMatrix(
m_Rhex);
1794 RThextmp->Transpose();
1806 Rprismoriginal = PrismExp->GetLocMatrix(PrismR);
1808 RTprismoriginal = PrismExp->GetLocMatrix(PrismRT);
1810 unsigned int nRows=Rprismoriginal->GetRows();
1819 for(i=0; i<nRows; ++i)
1821 for(j=0; j<nRows; ++j)
1823 Rvalue=(*Rprismoriginal)(i,j);
1824 RTvalue=(*RTprismoriginal)(i,j);
1825 Rtmpprism->SetValue(i,j,Rvalue);
1826 RTtmpprism->SetValue(i,j,RTvalue);
1842 Rprismtmp=PrismExp->BuildInverseTransformationMatrix(
m_Rprism);
1845 RTprismtmp=PrismExp->BuildInverseTransformationMatrix(
m_Rprism);
1846 RTprismtmp->Transpose();
1883 int TetVertex0=TetExp->GetVertexMap(0);
1884 int TetVertex1=TetExp->GetVertexMap(1);
1885 int TetVertex2=TetExp->GetVertexMap(2);
1886 int TetVertex3=TetExp->GetVertexMap(3);
1903 int PrismVertex0=PrismExp->GetVertexMap(0);
1904 int PrismVertex1=PrismExp->GetVertexMap(1);
1905 int PrismVertex2=PrismExp->GetVertexMap(2);
1906 int PrismVertex3=PrismExp->GetVertexMap(3);
1907 int PrismVertex4=PrismExp->GetVertexMap(4);
1908 int PrismVertex5=PrismExp->GetVertexMap(5);
1912 PrismExp->GetEdgeInverseBoundaryMap(0);
1914 PrismExp->GetEdgeInverseBoundaryMap(1);
1916 PrismExp->GetEdgeInverseBoundaryMap(2);
1918 PrismExp->GetEdgeInverseBoundaryMap(3);
1920 PrismExp->GetEdgeInverseBoundaryMap(4);
1922 PrismExp->GetEdgeInverseBoundaryMap(5);
1924 PrismExp->GetEdgeInverseBoundaryMap(6);
1926 PrismExp->GetEdgeInverseBoundaryMap(7);
1928 PrismExp->GetEdgeInverseBoundaryMap(8);
1932 PrismExp->GetFaceInverseBoundaryMap(1);
1934 PrismExp->GetFaceInverseBoundaryMap(3);
1936 PrismExp->GetFaceInverseBoundaryMap(0);
1938 PrismExp->GetFaceInverseBoundaryMap(2);
1940 PrismExp->GetFaceInverseBoundaryMap(4);
1943 for(i=0; i< PrismEdge0.num_elements(); ++i)
1945 Rvalue=(*m_Rtet)(TetVertex0,TetEdge0[i]);
1946 Rmodprism->SetValue(PrismVertex0,PrismEdge0[i],Rvalue);
1947 Rvalue=(*m_Rtet)(TetVertex0,TetEdge2[i]);
1948 Rmodprism->SetValue(PrismVertex0,PrismEdge3[i],Rvalue);
1949 Rvalue=(*m_Rtet)(TetVertex0,TetEdge3[i]);
1950 Rmodprism->SetValue(PrismVertex0,PrismEdge4[i],Rvalue);
1953 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex0);
1954 RTmodprism->SetValue(PrismEdge0[i],PrismVertex0,RTvalue);
1955 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex0);
1956 RTmodprism->SetValue(PrismEdge3[i],PrismVertex0,RTvalue);
1957 RTvalue=(*m_RTtet)(TetEdge3[i],TetVertex0);
1958 RTmodprism->SetValue(PrismEdge4[i],PrismVertex0,RTvalue);
1962 for(i=0; i< PrismEdge1.num_elements(); ++i)
1964 Rvalue=(*m_Rtet)(TetVertex1,TetEdge0[i]);
1965 Rmodprism->SetValue(PrismVertex1,PrismEdge0[i],Rvalue);
1966 Rvalue=(*m_Rtet)(TetVertex1,TetEdge1[i]);
1967 Rmodprism->SetValue(PrismVertex1,PrismEdge1[i],Rvalue);
1968 Rvalue=(*m_Rtet)(TetVertex1,TetEdge4[i]);
1969 Rmodprism->SetValue(PrismVertex1,PrismEdge5[i],Rvalue);
1972 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex1);
1973 RTmodprism->SetValue(PrismEdge0[i],PrismVertex1,RTvalue);
1974 RTvalue=(*m_RTtet)(TetEdge1[i],TetVertex1);
1975 RTmodprism->SetValue(PrismEdge1[i],PrismVertex1,RTvalue);
1976 RTvalue=(*m_RTtet)(TetEdge4[i],TetVertex1);
1977 RTmodprism->SetValue(PrismEdge5[i],PrismVertex1,RTvalue);
1981 for(i=0; i< PrismEdge2.num_elements(); ++i)
1983 Rvalue=(*m_Rtet)(TetVertex2,TetEdge1[i]);
1984 Rmodprism->SetValue(PrismVertex2,PrismEdge1[i],Rvalue);
1985 Rvalue=(*m_Rtet)(TetVertex1,TetEdge0[i]);
1986 Rmodprism->SetValue(PrismVertex2,PrismEdge2[i],Rvalue);
1987 Rvalue=(*m_Rtet)(TetVertex2,TetEdge5[i]);
1988 Rmodprism->SetValue(PrismVertex2,PrismEdge6[i],Rvalue);
1991 RTvalue=(*m_RTtet)(TetEdge1[i],TetVertex2);
1992 RTmodprism->SetValue(PrismEdge1[i],PrismVertex2,RTvalue);
1993 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex1);
1994 RTmodprism->SetValue(PrismEdge2[i],PrismVertex2,RTvalue);
1995 RTvalue=(*m_RTtet)(TetEdge5[i],TetVertex2);
1996 RTmodprism->SetValue(PrismEdge6[i],PrismVertex2,RTvalue);
2000 for(i=0; i< PrismEdge3.num_elements(); ++i)
2002 Rvalue=(*m_Rtet)(TetVertex2,TetEdge2[i]);
2003 Rmodprism->SetValue(PrismVertex3,PrismEdge3[i],Rvalue);
2004 Rvalue=(*m_Rtet)(TetVertex0,TetEdge0[i]);
2005 Rmodprism->SetValue(PrismVertex3,PrismEdge2[i],Rvalue);
2006 Rvalue=(*m_Rtet)(TetVertex2,TetEdge5[i]);
2007 Rmodprism->SetValue(PrismVertex3,PrismEdge7[i],Rvalue);
2010 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex2);
2011 RTmodprism->SetValue(PrismEdge3[i],PrismVertex3,RTvalue);
2012 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex0);
2013 RTmodprism->SetValue(PrismEdge2[i],PrismVertex3,RTvalue);
2014 RTvalue=(*m_RTtet)(TetEdge5[i],TetVertex2);
2015 RTmodprism->SetValue(PrismEdge7[i],PrismVertex3,RTvalue);
2019 for(i=0; i< PrismEdge4.num_elements(); ++i)
2021 Rvalue=(*m_Rtet)(TetVertex3,TetEdge3[i]);
2022 Rmodprism->SetValue(PrismVertex4,PrismEdge4[i],Rvalue);
2023 Rvalue=(*m_Rtet)(TetVertex3,TetEdge4[i]);
2024 Rmodprism->SetValue(PrismVertex4,PrismEdge5[i],Rvalue);
2025 Rvalue=(*m_Rtet)(TetVertex0,TetEdge2[i]);
2026 Rmodprism->SetValue(PrismVertex4,PrismEdge8[i],Rvalue);
2029 RTvalue=(*m_RTtet)(TetEdge3[i],TetVertex3);
2030 RTmodprism->SetValue(PrismEdge4[i],PrismVertex4,RTvalue);
2031 RTvalue=(*m_RTtet)(TetEdge4[i],TetVertex3);
2032 RTmodprism->SetValue(PrismEdge5[i],PrismVertex4,RTvalue);
2033 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex0);
2034 RTmodprism->SetValue(PrismEdge8[i],PrismVertex4,RTvalue);
2038 for(i=0; i< PrismEdge5.num_elements(); ++i)
2040 Rvalue=(*m_Rtet)(TetVertex3,TetEdge3[i]);
2041 Rmodprism->SetValue(PrismVertex5,PrismEdge6[i],Rvalue);
2042 Rvalue=(*m_Rtet)(TetVertex3,TetEdge4[i]);
2043 Rmodprism->SetValue(PrismVertex5,PrismEdge7[i],Rvalue);
2044 Rvalue=(*m_Rtet)(TetVertex2,TetEdge2[i]);
2045 Rmodprism->SetValue(PrismVertex5,PrismEdge8[i],Rvalue);
2048 RTvalue=(*m_RTtet)(TetEdge3[i],TetVertex3);
2049 RTmodprism->SetValue(PrismEdge6[i],PrismVertex5,RTvalue);
2050 RTvalue=(*m_RTtet)(TetEdge4[i],TetVertex3);
2051 RTmodprism->SetValue(PrismEdge7[i],PrismVertex5,RTvalue);
2052 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex2);
2053 RTmodprism->SetValue(PrismEdge8[i],PrismVertex5,RTvalue);
2057 for(i=0; i< PrismFace1.num_elements(); ++i)
2059 Rvalue=(*m_Rtet)(TetVertex0,TetFace[i]);
2060 Rmodprism->SetValue(PrismVertex0,PrismFace1[i],Rvalue);
2061 Rvalue=(*m_Rtet)(TetVertex1,TetFace[i]);
2062 Rmodprism->SetValue(PrismVertex1,PrismFace1[i],Rvalue);
2063 Rvalue=(*m_Rtet)(TetVertex3,TetFace[i]);
2064 Rmodprism->SetValue(PrismVertex4,PrismFace1[i],Rvalue);
2067 RTvalue=(*m_RTtet)(TetFace[i],TetVertex0);
2068 RTmodprism->SetValue(PrismFace1[i],PrismVertex0,RTvalue);
2069 RTvalue=(*m_RTtet)(TetFace[i],TetVertex1);
2070 RTmodprism->SetValue(PrismFace1[i],PrismVertex1,RTvalue);
2071 RTvalue=(*m_RTtet)(TetFace[i],TetVertex3);
2072 RTmodprism->SetValue(PrismFace1[i],PrismVertex4,RTvalue);
2076 for(i=0; i< PrismFace3.num_elements(); ++i)
2078 Rvalue=(*m_Rtet)(TetVertex1,TetFace[i]);
2079 Rmodprism->SetValue(PrismVertex2,PrismFace3[i],Rvalue);
2080 Rvalue=(*m_Rtet)(TetVertex0,TetFace[i]);
2081 Rmodprism->SetValue(PrismVertex3,PrismFace3[i],Rvalue);
2082 Rvalue=(*m_Rtet)(TetVertex3,TetFace[i]);
2083 Rmodprism->SetValue(PrismVertex5,PrismFace3[i],Rvalue);
2086 RTvalue=(*m_RTtet)(TetFace[i],TetVertex1);
2087 RTmodprism->SetValue(PrismFace3[i],PrismVertex2,RTvalue);
2088 RTvalue=(*m_RTtet)(TetFace[i],TetVertex0);
2089 RTmodprism->SetValue(PrismFace3[i],PrismVertex3,RTvalue);
2090 RTvalue=(*m_RTtet)(TetFace[i],TetVertex3);
2091 RTmodprism->SetValue(PrismFace3[i],PrismVertex5,RTvalue);
2095 for(i=0; i< PrismFace1.num_elements(); ++i)
2097 for(j=0; j<PrismEdge0.num_elements(); ++j)
2099 Rvalue=(*m_Rtet)(TetEdge0[j],TetFace[i]);
2100 Rmodprism->SetValue(PrismEdge0[j],PrismFace1[i],Rvalue);
2101 Rvalue=(*m_Rtet)(TetEdge3[j],TetFace[i]);
2102 Rmodprism->SetValue(PrismEdge4[j],PrismFace1[i],Rvalue);
2103 Rvalue=(*m_Rtet)(TetEdge4[j],TetFace[i]);
2104 Rmodprism->SetValue(PrismEdge5[j],PrismFace1[i],Rvalue);
2107 RTvalue=(*m_RTtet)(TetFace[i],TetEdge0[j]);
2108 RTmodprism->SetValue(PrismFace1[i],PrismEdge0[j],RTvalue);
2109 RTvalue=(*m_RTtet)(TetFace[i],TetEdge3[j]);
2110 RTmodprism->SetValue(PrismFace1[i],PrismEdge4[j],RTvalue);
2111 RTvalue=(*m_RTtet)(TetFace[i],TetEdge4[j]);
2112 RTmodprism->SetValue(PrismFace1[i],PrismEdge5[j],RTvalue);
2117 for(i=0; i< PrismFace3.num_elements(); ++i)
2119 for(j=0; j<PrismEdge2.num_elements(); ++j)
2121 Rvalue=(*m_Rtet)(TetEdge0[j],TetFace[i]);
2122 Rmodprism->SetValue(PrismEdge2[j],PrismFace3[i],Rvalue);
2123 Rvalue=(*m_Rtet)(TetEdge4[j],TetFace[i]);
2124 Rmodprism->SetValue(PrismEdge6[j],PrismFace3[i],Rvalue);
2125 Rvalue=(*m_Rtet)(TetEdge3[j],TetFace[i]);
2126 Rmodprism->SetValue(PrismEdge7[j],PrismFace3[i],Rvalue);
2128 RTvalue=(*m_RTtet)(TetFace[i],TetEdge0[j]);
2129 RTmodprism->SetValue(PrismFace3[i],PrismEdge2[j],RTvalue);
2130 RTvalue=(*m_RTtet)(TetFace[i],TetEdge4[j]);
2131 RTmodprism->SetValue(PrismFace3[i],PrismEdge6[j],RTvalue);
2132 RTvalue=(*m_RTtet)(TetFace[i],TetEdge3[j]);
2133 RTmodprism->SetValue(PrismFace3[i],PrismEdge7[j],RTvalue);
const StdRegions::VarCoeffMap & GetVarCoeffs() const
LibUtilities::CommSharedPtr m_comm
virtual void v_DoPreconditioner(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
PreconditionerLowEnergy(const boost::shared_ptr< GlobalLinSys > &plinsys, const AssemblyMapSharedPtr &pLocToGloMap)
#define ASSERTL0(condition, msg)
Principle Modified Functions .
static void Gather(Nektar::Array< OneD, NekDouble > pU, gs_op pOp, gs_data *pGsh, Nektar::Array< OneD, NekDouble > pBuffer=NullNekDouble1DArray)
Performs a gather-scatter operation of the provided values.
virtual void v_DoMultiplybyInverseTransposedTransformationMatrix(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
Multiply by the block tranposed inverse transformation matrix.
void Gathr(int n, const T *x, const int *y, T *z)
Gather vector z[i] = x[y[i]].
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
std::map< int, vector< PeriodicEntity > > PeriodicMap
#define sign(a, b)
return the sign(b)*a
boost::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
DNekScalMatSharedPtr m_Rprism
Array< OneD, NekDouble > m_multiplicity
Array< OneD, NekDouble > m_locToGloSignMult
DNekScalBlkMatSharedPtr m_RTBlk
DNekScalMatSharedPtr m_RThex
boost::shared_ptr< QuadGeom > QuadGeomSharedPtr
virtual void v_InitObject()
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm)
Initialise Gather-Scatter map.
DNekScalBlkMatSharedPtr m_RBlk
Principle Modified Functions .
PreconFactory & GetPreconFactory()
void Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/y.
boost::shared_ptr< HexExp > HexExpSharedPtr
DNekBlkMatSharedPtr m_BlkMat
const StdRegions::ConstFactorMap & GetConstFactors() const
Returns all the constants.
boost::shared_ptr< HexGeom > HexGeomSharedPtr
int GetEdgeNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th edge.
boost::shared_ptr< DNekMat > DNekMatSharedPtr
DNekScalMatSharedPtr m_RTinvtet
boost::shared_ptr< TetExp > TetExpSharedPtr
DNekScalMatSharedPtr m_Rinvprism
boost::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
DNekScalBlkMatSharedPtr m_InvRTBlk
Gauss Radau pinned at x=-1, .
SpatialDomains::HexGeomSharedPtr CreateRefHexGeom(void)
Sets up the reference hexahedral element needed to construct a low energy basis.
static std::string className
Name of class.
DNekScalMatSharedPtr m_Rhex
DNekScalMatSharedPtr m_RTprism
boost::shared_ptr< StdExpansion2D > StdExpansion2DSharedPtr
virtual DNekScalMatSharedPtr v_TransformedSchurCompl(int offset, const boost::shared_ptr< DNekScalMat > &loc_mat)
Set up the transformed block matrix system.
virtual void v_BuildPreconditioner()
Construct the low energy preconditioner from .
DNekScalMatSharedPtr m_RTinvhex
int GetNVarCoeffs() const
int GetFaceIntNcoeffs(const int i) const
void SetUpReferenceElements(void)
Sets up the reference elements needed by the preconditioner.
static PreconditionerSharedPtr create(const boost::shared_ptr< GlobalLinSys > &plinsys, const boost::shared_ptr< AssemblyMap > &pLocToGloMap)
Creates an instance of this class.
std::map< StdRegions::VarCoeffType, Array< OneD, NekDouble > > VarCoeffMap
boost::shared_ptr< SegGeom > SegGeomSharedPtr
DNekScalBlkMatSharedPtr m_InvRBlk
Principle Modified Functions .
StdRegions::Orientation DeterminePeriodicFaceOrient(StdRegions::Orientation faceOrient, StdRegions::Orientation perFaceOrient)
Determine relative orientation between two faces.
boost::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
virtual void v_DoTransformToLowEnergy(Array< OneD, NekDouble > &pInOut, int offset)
Transform the solution vector vector to low energy.
Defines a specification for a set of points.
void Assmb(int n, const T *x, const int *y, T *z)
Assemble z[y[i]] += x[i]; z should be zero'd first.
boost::shared_ptr< PrismExp > PrismExpSharedPtr
boost::shared_ptr< T > as()
DNekScalMatSharedPtr m_Rinvtet
virtual void v_DoMultiplybyInverseTransformationMatrix(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
Multiply by the block inverse transformation matrix.
Describe a linear system.
virtual void v_DoTransformFromLowEnergy(Array< OneD, NekDouble > &pInOut)
transform the solution vector from low energy back to the original basis.
boost::shared_ptr< AssemblyMap > m_locToGloMap
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
boost::shared_ptr< Geometry2D > Geometry2DSharedPtr
SpatialDomains::TetGeomSharedPtr CreateRefTetGeom(void)
Sets up the reference tretrahedral element needed to construct a low energy basis.
DNekScalMatSharedPtr m_Rinvhex
void ModifyPrismTransformationMatrix(LocalRegions::TetExpSharedPtr TetExp, LocalRegions::PrismExpSharedPtr PrismExp, DNekMatSharedPtr Rmodprism, DNekMatSharedPtr RTmodprism)
Modify the prism transformation matrix to align with the tetrahedral modes.
DNekScalMatSharedPtr m_Rtet
boost::shared_ptr< Expansion > ExpansionSharedPtr
boost::shared_ptr< PrismGeom > PrismGeomSharedPtr
Gauss Radau pinned at x=-1, .
DNekScalMatSharedPtr m_RTtet
void SetupBlockTransformationMatrix(void)
boost::shared_ptr< TetGeom > TetGeomSharedPtr
boost::shared_ptr< TriGeom > TriGeomSharedPtr
SpatialDomains::PrismGeomSharedPtr CreateRefPrismGeom(void)
Sets up the reference prismatic element needed to construct a low energy basis.
const boost::weak_ptr< GlobalLinSys > m_linsys
void CreateMultiplicityMap(void)
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Describes the specification for a Basis.
boost::shared_ptr< PointGeom > PointGeomSharedPtr
1D Gauss-Lobatto-Legendre quadrature points
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
DNekScalMatSharedPtr m_RTinvprism
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.