46 namespace MultiRegions
55 "LowEnergy Preconditioning");
65 const boost::shared_ptr<GlobalLinSys> &plinsys,
69 m_locToGloMap(pLocToGloMap)
79 boost::shared_ptr<MultiRegions::ExpList>
80 expList=((
m_linsys.lock())->GetLocMat()).lock();
84 locExpansion = expList->GetExp(0);
86 int nDim = locExpansion->GetShapeDimension();
89 "Preconditioner type only valid in 3D");
121 boost::shared_ptr<MultiRegions::ExpList>
122 expList=((
m_linsys.lock())->GetLocMat()).lock();
127 int nVerts, nEdges,nFaces;
128 int eid, fid, n, cnt, nedgemodes, nfacemodes;
131 int vMap1, vMap2, sign1, sign2;
132 int m, v, eMap1, eMap2, fMap1, fMap2;
133 int offset, globalrow, globalcol, nCoeffs;
139 expList->GetPeriodicEntities(periodicVerts,periodicEdges,periodicFaces);
170 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transmatrixmap;
171 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transposedtransmatrixmap;
183 int n_exp = expList->GetNumElmts();
188 int numBlks = 1+nNonDirEdgeIDs+nNonDirFaceIDs;
190 for(i = 0; i < numBlks; ++i)
194 n_blks[0]=nNonDirVerts;
198 map<int,int> uniqueEdgeMap;
199 map<int,int> uniqueFaceMap;
218 for(i=0; i<extradiredges.num_elements(); ++i)
220 meshEdgeId=extradiredges[i];
221 edgeDirMap.insert(meshEdgeId);
225 for(i = 0; i < bndCondExp.num_elements(); i++)
228 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
230 bndCondFaceExp = boost::dynamic_pointer_cast<
232 if (bndConditions[i]->GetBoundaryConditionType() ==
235 for(k = 0; k < bndCondFaceExp->GetNedges(); k++)
238 if(edgeDirMap.count(meshEdgeId) == 0)
240 edgeDirMap.insert(meshEdgeId);
244 faceDirMap.insert(meshFaceId);
252 int nlocalNonDirEdges=0;
253 int nlocalNonDirFaces=0;
255 int edgematrixlocation=0;
256 int ntotaledgeentries=0;
258 map<int,int> EdgeSize;
259 map<int,int> FaceSize;
262 for(n = 0; n < n_exp; ++n)
264 eid = expList->GetOffset_Elmt_Id(n);
265 locExpansion = expList->GetExp(eid);
267 nEdges = locExpansion->GetNedges();
268 for(j = 0; j < nEdges; ++j)
270 int nEdgeInteriorCoeffs = locExpansion->GetEdgeNcoeffs(j) - 2;
272 EdgeSize[meshEdgeId] = nEdgeInteriorCoeffs;
275 nFaces = locExpansion->GetNfaces();
276 for(j = 0; j < nFaces; ++j)
278 int nFaceInteriorCoeffs = locExpansion->GetFaceIntNcoeffs(j);
280 FaceSize[meshFaceId] = nFaceInteriorCoeffs;
284 m_comm = expList->GetComm();
290 PeriodicMap::const_iterator pIt;
291 for (pIt = periodicEdges.begin(); pIt != periodicEdges.end(); ++pIt)
293 meshEdgeId = pIt->first;
295 if(edgeDirMap.count(meshEdgeId)==0)
297 dof = EdgeSize[meshEdgeId];
298 if(uniqueEdgeMap.count(meshEdgeId)==0 && dof > 0)
300 bool SetUpNewEdge =
true;
303 for (i = 0; i < pIt->second.size(); ++i)
305 if (!pIt->second[i].isLocal)
310 int meshEdgeId2 = pIt->second[i].id;
312 if(edgeDirMap.count(meshEdgeId2)==0)
314 if(uniqueEdgeMap.count(meshEdgeId2)!=0)
317 uniqueEdgeMap[meshEdgeId] =
318 uniqueEdgeMap[meshEdgeId2];
319 SetUpNewEdge =
false;
324 edgeDirMap.insert(meshEdgeId);
325 SetUpNewEdge =
false;
331 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
333 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
335 edgemodeoffset[edgematrixlocation]=dof*dof;
337 ntotaledgeentries+=dof*dof;
339 n_blks[1+edgematrixlocation++]=dof;
347 for(cnt=n=0; n < n_exp; ++n)
349 eid = expList->GetOffset_Elmt_Id(n);
350 locExpansion = expList->GetExp(eid);
352 for (j = 0; j < locExpansion->GetNedges(); ++j)
355 dof = EdgeSize[meshEdgeId];
356 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
358 if(edgeDirMap.count(meshEdgeId)==0)
360 if(uniqueEdgeMap.count(meshEdgeId)==0 && dof > 0)
363 uniqueEdgeMap[meshEdgeId]=edgematrixlocation;
365 edgeglobaloffset[edgematrixlocation]+=ntotaledgeentries;
367 edgemodeoffset[edgematrixlocation]=dof*dof;
369 ntotaledgeentries+=dof*dof;
371 n_blks[1+edgematrixlocation++]=dof;
374 nlocalNonDirEdges+=dof*dof;
379 int facematrixlocation=0;
380 int ntotalfaceentries=0;
385 for (pIt = periodicFaces.begin(); pIt != periodicFaces.end(); ++pIt)
387 meshFaceId = pIt->first;
389 if(faceDirMap.count(meshFaceId)==0)
391 dof = FaceSize[meshFaceId];
393 if(uniqueFaceMap.count(meshFaceId) == 0 && dof > 0)
395 bool SetUpNewFace =
true;
397 if(pIt->second[0].isLocal)
399 int meshFaceId2 = pIt->second[0].id;
401 if(faceDirMap.count(meshFaceId2)==0)
403 if(uniqueFaceMap.count(meshFaceId2)!=0)
406 uniqueFaceMap[meshFaceId] =
407 uniqueFaceMap[meshFaceId2];
408 SetUpNewFace =
false;
413 faceDirMap.insert(meshFaceId);
414 SetUpNewFace =
false;
420 uniqueFaceMap[meshFaceId]=facematrixlocation;
422 facemodeoffset[facematrixlocation]=dof*dof;
424 faceglobaloffset[facematrixlocation]+=ntotalfaceentries;
426 ntotalfaceentries+=dof*dof;
428 n_blks[1+nNonDirEdgeIDs+facematrixlocation++]=dof;
435 for(cnt=n=0; n < n_exp; ++n)
437 eid = expList->GetOffset_Elmt_Id(n);
439 locExpansion = expList->GetExp(eid);
441 for (j = 0; j < locExpansion->GetNfaces(); ++j)
445 dof = FaceSize[meshFaceId];
446 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
449 if(faceDirMap.count(meshFaceId)==0)
451 if(uniqueFaceMap.count(meshFaceId)==0 && dof > 0)
453 uniqueFaceMap[meshFaceId]=facematrixlocation;
455 facemodeoffset[facematrixlocation]=dof*dof;
457 faceglobaloffset[facematrixlocation]+=ntotalfaceentries;
459 ntotalfaceentries+=dof*dof;
461 n_blks[1+nNonDirEdgeIDs+facematrixlocation++]=dof;
464 nlocalNonDirFaces+=dof*dof;
483 int edgematrixoffset=0;
484 int facematrixoffset=0;
487 for(n=0; n < n_exp; ++n)
489 eid = expList->GetOffset_Elmt_Id(n);
491 locExpansion = expList->GetExp(eid);
494 for(j = 0; j < locExpansion->GetNedges(); ++j)
501 if(edgeDirMap.count(meshEdgeId)==0)
504 int edgeOffset = edgeglobaloffset[uniqueEdgeMap[meshEdgeId]];
507 int uniOffset = meshEdgeId;
508 pIt = periodicEdges.find(meshEdgeId);
509 if (pIt != periodicEdges.end())
511 for (
int l = 0; l < pIt->second.size(); ++l)
513 uniOffset = min(uniOffset, pIt->second[l].id);
516 uniOffset = uniOffset *maxEdgeDof*maxEdgeDof;
518 for(k=0; k<nedgemodes*nedgemodes; ++k)
520 vGlobal=edgeOffset+k;
521 localEdgeToGlobalMatrixMap[edgematrixoffset+k]=vGlobal;
522 EdgeBlockToUniversalMap[vGlobal] = uniOffset + k + 1;
524 edgematrixoffset+=nedgemodes*nedgemodes;
531 for(j = 0; j < locExpansion->GetNfaces(); ++j)
539 if(faceDirMap.count(meshFaceId)==0)
542 int faceOffset = faceglobaloffset[uniqueFaceMap[meshFaceId]];
545 int uniOffset = meshFaceId;
547 pIt = periodicFaces.find(meshFaceId);
548 if (pIt != periodicFaces.end())
550 uniOffset = min(uniOffset, pIt->second[0].id);
552 uniOffset = uniOffset * maxFaceDof * maxFaceDof;
554 for(k=0; k<nfacemodes*nfacemodes; ++k)
556 vGlobal=faceOffset+k;
558 localFaceToGlobalMatrixMap[facematrixoffset+k]
561 FaceBlockToUniversalMap[vGlobal] = uniOffset + k + 1;
563 facematrixoffset+=nfacemodes*nfacemodes;
586 for(cnt=n=0; n < n_exp; ++n)
588 eid = expList->GetOffset_Elmt_Id(n);
590 locExpansion = expList->GetExp(eid);
591 nCoeffs=locExpansion->NumBndryCoeffs();
595 R=(*(transmatrixmap[eType]));
596 RT=(*(transposedtransmatrixmap[eType]));
599 (nCoeffs, nCoeffs, zero, storage);
603 (nCoeffs, nCoeffs, zero, storage);
606 nVerts=locExpansion->GetGeom()->GetNumVerts();
607 nEdges=locExpansion->GetGeom()->GetNumEdges();
608 nFaces=locExpansion->GetGeom()->GetNumFaces();
611 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
614 bnd_mat=loc_mat->GetBlock(0,0);
617 offset = bnd_mat->GetRows();
629 for (v=0; v<nVerts; ++v)
631 vMap1=locExpansion->GetVertexMap(v);
635 GetLocalToGlobalBndMap(cnt+vMap1)-nDirBnd;
639 for (m=0; m<nVerts; ++m)
641 vMap2=locExpansion->GetVertexMap(m);
646 GetLocalToGlobalBndMap(cnt+vMap2)-nDirBnd;
649 if (globalcol == globalrow)
653 GetLocalToGlobalBndSign(cnt + vMap1);
655 GetLocalToGlobalBndSign(cnt + vMap2);
658 += sign1*sign2*RSRT(vMap1,vMap2);
663 pIt = periodicVerts.find(meshVertId);
664 if (pIt != periodicVerts.end())
666 for (k = 0; k < pIt->second.size(); ++k)
668 meshVertId = min(meshVertId, pIt->second[k].id);
672 VertBlockToUniversalMap[globalrow]
680 for (eid=0; eid<nEdges; ++eid)
682 nedgemodes=locExpansion->GetEdgeNcoeffs(eid)-2;
686 (nedgemodes,nedgemodes,zero,storage);
691 if(edgeDirMap.count(meshEdgeId)==0)
693 for (v=0; v<nedgemodes; ++v)
695 eMap1=edgemodearray[v];
697 for (m=0; m<nedgemodes; ++m)
699 eMap2=edgemodearray[m];
703 GetLocalToGlobalBndSign(cnt + eMap1);
705 GetLocalToGlobalBndSign(cnt + eMap2);
707 NekDouble globalEdgeValue = sign1*sign2*RSRT(eMap1,eMap2);
709 EdgeBlockArray[edgematrixoffset+v*nedgemodes+m]=globalEdgeValue;
712 edgematrixoffset+=nedgemodes*nedgemodes;
717 for (fid=0; fid<nFaces; ++fid)
719 nfacemodes = locExpansion->GetFaceIntNcoeffs(fid);
723 (nfacemodes,nfacemodes,zero,storage);
727 if(faceDirMap.count(meshFaceId)==0)
732 pIt = periodicFaces.find(meshFaceId);
733 if (pIt != periodicFaces.end())
735 if(meshFaceId == min(meshFaceId, pIt->second[0].id))
737 facemodearray = locExpansion->GetFaceInverseBoundaryMap(fid,faceOrient);
742 facemodearray = locExpansion->GetFaceInverseBoundaryMap(fid,faceOrient);
745 for (v=0; v<nfacemodes; ++v)
747 fMap1=facemodearray[v];
749 for (m=0; m<nfacemodes; ++m)
751 fMap2=facemodearray[m];
755 GetLocalToGlobalBndSign(cnt + fMap1);
757 GetLocalToGlobalBndSign(cnt + fMap2);
760 NekDouble globalFaceValue = sign1*sign2*RSRT(fMap1,fMap2);
763 FaceBlockArray[facematrixoffset+v*nfacemodes+m]=globalFaceValue;
766 facematrixoffset+=nfacemodes*nfacemodes;
774 m_RBlk->SetBlock(n,n, transmatrixmap[eType]);
775 m_RTBlk->SetBlock(n,n, transposedtransmatrixmap[eType]);
787 if(ntotaledgeentries)
792 localEdgeToGlobalMatrixMap,
801 if(ntotalfaceentries)
806 localFaceToGlobalMatrixMap,
815 for (
int i = 0; i < nNonDirVerts; ++i)
817 VertBlk->SetValue(i,i,1.0/vertArray[i]);
826 for(
int loc=0; loc<nNonDirEdgeIDs; ++loc)
828 nedgemodes = n_blks[1+loc];
830 (nedgemodes,nedgemodes,zero,storage);
832 for (v=0; v<nedgemodes; ++v)
834 for (m=0; m<nedgemodes; ++m)
836 NekDouble EdgeValue = GlobalEdgeBlock[offset+v*nedgemodes+m];
837 gmat->SetValue(v,m,EdgeValue);
842 m_BlkMat->SetBlock(1+loc,1+loc, gmat);
843 offset+=edgemodeoffset[loc];
850 for(
int loc=0; loc<nNonDirFaceIDs; ++loc)
852 nfacemodes=n_blks[1+nNonDirEdgeIDs+loc];
854 (nfacemodes,nfacemodes,zero,storage);
856 for (v=0; v<nfacemodes; ++v)
858 for (m=0; m<nfacemodes; ++m)
860 NekDouble FaceValue = GlobalFaceBlock[offset+v*nfacemodes+m];
861 gmat->SetValue(v,m,FaceValue);
865 m_BlkMat->SetBlock(1+nNonDirEdgeIDs+loc,1+nNonDirEdgeIDs+loc, gmat);
866 offset+=facemodeoffset[loc];
869 int totblks=
m_BlkMat->GetNumberOfBlockRows();
870 for (i=1; i< totblks; ++i)
872 unsigned int nmodes=
m_BlkMat->GetNumberOfRowsInBlockRow(i);
877 (nmodes,nmodes,zero,storage);
898 int nNonDir = nGlobal-nDir;
915 boost::shared_ptr<MultiRegions::ExpList>
916 expList=((
m_linsys.lock())->GetLocMat()).lock();
924 int n_exp=expList->GetNumElmts();
927 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transmatrixmap;
928 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transposedtransmatrixmap;
929 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> invtransmatrixmap;
930 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> invtransposedtransmatrixmap;
964 for(n=0; n < n_exp; ++n)
966 nel = expList->GetOffset_Elmt_Id(n);
968 locExpansion = expList->GetExp(nel);
972 m_RBlk->SetBlock(n,n, transmatrixmap[eType]);
975 m_RTBlk->SetBlock(n,n, transposedtransmatrixmap[eType]);
978 m_InvRBlk->SetBlock(n,n, invtransmatrixmap[eType]);
981 m_InvRTBlk->SetBlock(n,n, invtransposedtransmatrixmap[eType]);
1000 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1016 Vmath::Vcopy(nGlobBndDofs, pInOut.get(), 1, tmp.get(), 1);
1022 F_LocBnd=R*F_LocBnd;
1040 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1041 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1045 ASSERTL1(pInput.num_elements() >= nGlobHomBndDofs,
1046 "Input array is greater than the nGlobHomBndDofs");
1047 ASSERTL1(pOutput.num_elements() >= nGlobHomBndDofs,
1048 "Output array is greater than the nGlobHomBndDofs");
1065 Vmath::Vcopy(nGlobHomBndDofs, pInput.get(), 1, tmp.get() + nDirBndDofs, 1);
1071 F_LocBnd=R*F_LocBnd;
1090 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1091 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1094 ASSERTL1(pInOut.num_elements() >= nGlobBndDofs,
1095 "Output array is greater than the nGlobBndDofs");
1109 m_locToGloMap->GlobalToLocalBnd(V_GlobHomBnd,V_LocBnd, nDirBndDofs);
1112 V_LocBnd=RT*V_LocBnd;
1122 Vmath::Vcopy(nGlobBndDofs-nDirBndDofs, tmp.get() + nDirBndDofs, 1, pInOut.get() + nDirBndDofs, 1);
1133 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1134 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1137 ASSERTL1(pInput.num_elements() >= nGlobHomBndDofs,
1138 "Input array is greater than the nGlobHomBndDofs");
1139 ASSERTL1(pOutput.num_elements() >= nGlobHomBndDofs,
1140 "Output array is greater than the nGlobHomBndDofs");
1157 Vmath::Vcopy(nGlobHomBndDofs, pInput.get(), 1, tmp.get() + nDirBndDofs, 1);
1163 F_LocBnd=invR*F_LocBnd;
1178 int nDirBndDofs =
m_locToGloMap->GetNumGlobalDirBndCoeffs();
1179 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
1182 ASSERTL1(pInput.num_elements() >= nGlobHomBndDofs,
1183 "Input array is greater than the nGlobHomBndDofs");
1184 ASSERTL1(pOutput.num_elements() >= nGlobHomBndDofs,
1185 "Output array is greater than the nGlobHomBndDofs");
1198 m_locToGloMap->GlobalToLocalBnd(pInput,pLocal, nDirBndDofs);
1201 F_LocBnd=invRT*F_LocBnd;
1219 const boost::shared_ptr<DNekScalMat > &loc_mat)
1221 boost::shared_ptr<MultiRegions::ExpList>
1222 expList=((
m_linsys.lock())->GetLocMat()).lock();
1225 locExpansion = expList->GetExp(offset);
1226 unsigned int nbnd=locExpansion->NumBndryCoeffs();
1232 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transmatrixmap;
1233 map<LibUtilities::ShapeType,DNekScalMatSharedPtr> transposedtransmatrixmap;
1249 (expList->GetExp(offset))->DetShapeType();
1253 DNekScalMat &RT = (*(transposedtransmatrixmap[eType]));
1274 unsigned int nGlobalBnd =
m_locToGloMap->GetNumGlobalBndCoeffs();
1275 unsigned int nEntries =
m_locToGloMap->GetNumLocalBndCoeffs();
1288 for (i = 0; i < nEntries; ++i)
1290 vCounts[vMap[i]] += 1.0;
1298 for (i = 0; i < nEntries; ++i)
1311 int nGlobHomBnd = nGlobalBnd - nDirBnd;
1336 const int nVerts = 6;
1337 const double point[][3] = {
1338 {-1,-1,0}, {1,-1,0}, {1,1,0},
1339 {-1,1,0}, {0,-1,sqrt(
double(3))}, {0,1,sqrt(
double(3))},
1344 for(
int i=0; i < nVerts; ++i)
1347 ( three, i, point[i][0], point[i][1], point[i][2] );
1349 const int nEdges = 9;
1350 const int vertexConnectivity[][2] = {
1351 {0,1}, {1,2}, {3,2}, {0,3}, {0,4},
1352 {1,4}, {2,5}, {3,5}, {4,5}
1357 for(
int i=0; i < nEdges; ++i){
1359 for(
int j=0; j<2; ++j)
1361 vertsArray[j] = verts[vertexConnectivity[i][j]];
1370 const int nFaces = 5;
1372 const int quadEdgeConnectivity[][4] = { {0,1,2,3}, {1,6,8,5}, {3,7,8,4} };
1373 const bool isQuadEdgeFlipped[][4] = { {0,0,1,1}, {0,0,1,1}, {0,0,1,1} };
1375 const int quadId[] = { 0,-1,1,-1,2 };
1378 const int triEdgeConnectivity[][3] = { {0,5,4}, {2,6,7} };
1379 const bool isTriEdgeFlipped[][3] = { {0,0,1}, {0,0,1} };
1381 const int triId[] = { -1,0,-1,1,-1 };
1385 for(
int f = 0; f < nFaces; ++f){
1386 if(f == 1 || f == 3) {
1390 for(
int j = 0; j < 3; ++j){
1391 edgeArray[j] = edges[triEdgeConnectivity[i][j]];
1400 for(
int j=0; j < 4; ++j){
1401 edgeArray[j] = edges[quadEdgeConnectivity[i][j]];
1427 const int nVerts = 4;
1428 const double point[][3] = {
1429 {-1,-1/sqrt(
double(3)),-1/sqrt(
double(6))},
1430 {1,-1/sqrt(
double(3)),-1/sqrt(
double(6))},
1431 {0,2/sqrt(
double(3)),-1/sqrt(
double(6))},
1432 {0,0,3/sqrt(
double(6))}};
1434 boost::shared_ptr<SpatialDomains::PointGeom> verts[4];
1435 for(i=0; i < nVerts; ++i)
1440 ( three, i, point[i][0], point[i][1], point[i][2] );
1448 const int nEdges = 6;
1449 const int vertexConnectivity[][2] = {
1450 {0,1},{1,2},{0,2},{0,3},{1,3},{2,3}
1455 for(i=0; i < nEdges; ++i)
1457 boost::shared_ptr<SpatialDomains::PointGeom>
1461 vertsArray[j] = verts[vertexConnectivity[i][j]];
1472 const int nFaces = 4;
1473 const int edgeConnectivity[][3] = {
1474 {0,1,2}, {0,4,3}, {1,5,4}, {2,5,3}
1476 const bool isEdgeFlipped[][3] = {
1477 {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
1482 for(i=0; i < nFaces; ++i)
1486 for(j=0; j < 3; ++j)
1488 edgeArray[j] = edges[edgeConnectivity[i][j]];
1489 eorientArray[j] = isEdgeFlipped[i][j] ?
1519 const int nVerts = 8;
1520 const double point[][3] = {
1521 {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0},
1522 {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}
1527 for(
int i = 0; i < nVerts; ++i ) {
1530 point[i][1], point[i][2]);
1538 const int nEdges = 12;
1539 const int vertexConnectivity[][2] = {
1540 {0,1}, {1,2}, {2,3}, {0,3}, {0,4}, {1,5},
1541 {2,6}, {3,7}, {4,5}, {5,6}, {6,7}, {4,7}
1546 for(
int i = 0; i < nEdges; ++i ) {
1548 for(
int j = 0; j < 2; ++j ) {
1549 vertsArray[j] = verts[vertexConnectivity[i][j]];
1559 const int nFaces = 6;
1560 const int edgeConnectivity[][4] = {
1561 {0,1,2,3}, {0,5,8,4}, {1,6,9,5},
1562 {2,7,10,6}, {3,7,11,4}, {8,9,10,11}
1564 const bool isEdgeFlipped[][4] = {
1565 {0,0,0,1}, {0,0,1,1}, {0,0,1,1},
1566 {0,0,1,1}, {0,0,1,1}, {0,0,0,1}
1571 for(
int i = 0; i < nFaces; ++i ) {
1574 for(
int j = 0; j < 4; ++j ) {
1575 edgeArray[j] = edges[edgeConnectivity[i][j]];
1576 eorientArray[j] = isEdgeFlipped[i][j] ?
1603 boost::shared_ptr<MultiRegions::ExpList>
1604 expList=((
m_linsys.lock())->GetLocMat()).lock();
1608 locExpansion = expList->GetExp(0);
1615 DNekMatSharedPtr Rtettmp, RTtettmp, Rhextmp, RThextmp, Rprismtmp, RTprismtmp ;
1631 int nummodes=locExpansion->GetBasisNumModes(0);
1691 StdRegions::VarCoeffMap::const_iterator x;
1692 cnt = expList->GetPhys_Offset(0);
1696 vVarCoeffMap[x->first] = x->second + cnt;
1763 m_Rtet = TetExp->GetLocMatrix(TetR);
1766 m_RTtet = TetExp->GetLocMatrix(TetRT);
1770 Rtettmp=TetExp->BuildInverseTransformationMatrix(m_Rtet);
1773 RTtettmp=TetExp->BuildInverseTransformationMatrix(m_Rtet);
1774 RTtettmp->Transpose();
1786 m_Rhex = HexExp->GetLocMatrix(HexR);
1788 m_RThex = HexExp->GetLocMatrix(HexRT);
1792 Rhextmp=HexExp->BuildInverseTransformationMatrix(
m_Rhex);
1794 RThextmp=HexExp->BuildInverseTransformationMatrix(
m_Rhex);
1795 RThextmp->Transpose();
1807 Rprismoriginal = PrismExp->GetLocMatrix(PrismR);
1809 RTprismoriginal = PrismExp->GetLocMatrix(PrismRT);
1811 unsigned int nRows=Rprismoriginal->GetRows();
1820 for(i=0; i<nRows; ++i)
1822 for(j=0; j<nRows; ++j)
1824 Rvalue=(*Rprismoriginal)(i,j);
1825 RTvalue=(*RTprismoriginal)(i,j);
1826 Rtmpprism->SetValue(i,j,Rvalue);
1827 RTtmpprism->SetValue(i,j,RTvalue);
1843 Rprismtmp=PrismExp->BuildInverseTransformationMatrix(
m_Rprism);
1846 RTprismtmp=PrismExp->BuildInverseTransformationMatrix(
m_Rprism);
1847 RTprismtmp->Transpose();
1884 int TetVertex0=TetExp->GetVertexMap(0);
1885 int TetVertex1=TetExp->GetVertexMap(1);
1886 int TetVertex2=TetExp->GetVertexMap(2);
1887 int TetVertex3=TetExp->GetVertexMap(3);
1904 int PrismVertex0=PrismExp->GetVertexMap(0);
1905 int PrismVertex1=PrismExp->GetVertexMap(1);
1906 int PrismVertex2=PrismExp->GetVertexMap(2);
1907 int PrismVertex3=PrismExp->GetVertexMap(3);
1908 int PrismVertex4=PrismExp->GetVertexMap(4);
1909 int PrismVertex5=PrismExp->GetVertexMap(5);
1913 PrismExp->GetEdgeInverseBoundaryMap(0);
1915 PrismExp->GetEdgeInverseBoundaryMap(1);
1917 PrismExp->GetEdgeInverseBoundaryMap(2);
1919 PrismExp->GetEdgeInverseBoundaryMap(3);
1921 PrismExp->GetEdgeInverseBoundaryMap(4);
1923 PrismExp->GetEdgeInverseBoundaryMap(5);
1925 PrismExp->GetEdgeInverseBoundaryMap(6);
1927 PrismExp->GetEdgeInverseBoundaryMap(7);
1929 PrismExp->GetEdgeInverseBoundaryMap(8);
1933 PrismExp->GetFaceInverseBoundaryMap(1);
1935 PrismExp->GetFaceInverseBoundaryMap(3);
1937 PrismExp->GetFaceInverseBoundaryMap(0);
1939 PrismExp->GetFaceInverseBoundaryMap(2);
1941 PrismExp->GetFaceInverseBoundaryMap(4);
1944 for(i=0; i< PrismEdge0.num_elements(); ++i)
1946 Rvalue=(*m_Rtet)(TetVertex0,TetEdge0[i]);
1947 Rmodprism->SetValue(PrismVertex0,PrismEdge0[i],Rvalue);
1948 Rvalue=(*m_Rtet)(TetVertex0,TetEdge2[i]);
1949 Rmodprism->SetValue(PrismVertex0,PrismEdge3[i],Rvalue);
1950 Rvalue=(*m_Rtet)(TetVertex0,TetEdge3[i]);
1951 Rmodprism->SetValue(PrismVertex0,PrismEdge4[i],Rvalue);
1954 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex0);
1955 RTmodprism->SetValue(PrismEdge0[i],PrismVertex0,RTvalue);
1956 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex0);
1957 RTmodprism->SetValue(PrismEdge3[i],PrismVertex0,RTvalue);
1958 RTvalue=(*m_RTtet)(TetEdge3[i],TetVertex0);
1959 RTmodprism->SetValue(PrismEdge4[i],PrismVertex0,RTvalue);
1963 for(i=0; i< PrismEdge1.num_elements(); ++i)
1965 Rvalue=(*m_Rtet)(TetVertex1,TetEdge0[i]);
1966 Rmodprism->SetValue(PrismVertex1,PrismEdge0[i],Rvalue);
1967 Rvalue=(*m_Rtet)(TetVertex1,TetEdge1[i]);
1968 Rmodprism->SetValue(PrismVertex1,PrismEdge1[i],Rvalue);
1969 Rvalue=(*m_Rtet)(TetVertex1,TetEdge4[i]);
1970 Rmodprism->SetValue(PrismVertex1,PrismEdge5[i],Rvalue);
1973 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex1);
1974 RTmodprism->SetValue(PrismEdge0[i],PrismVertex1,RTvalue);
1975 RTvalue=(*m_RTtet)(TetEdge1[i],TetVertex1);
1976 RTmodprism->SetValue(PrismEdge1[i],PrismVertex1,RTvalue);
1977 RTvalue=(*m_RTtet)(TetEdge4[i],TetVertex1);
1978 RTmodprism->SetValue(PrismEdge5[i],PrismVertex1,RTvalue);
1982 for(i=0; i< PrismEdge2.num_elements(); ++i)
1984 Rvalue=(*m_Rtet)(TetVertex2,TetEdge1[i]);
1985 Rmodprism->SetValue(PrismVertex2,PrismEdge1[i],Rvalue);
1986 Rvalue=(*m_Rtet)(TetVertex1,TetEdge0[i]);
1987 Rmodprism->SetValue(PrismVertex2,PrismEdge2[i],Rvalue);
1988 Rvalue=(*m_Rtet)(TetVertex2,TetEdge5[i]);
1989 Rmodprism->SetValue(PrismVertex2,PrismEdge6[i],Rvalue);
1992 RTvalue=(*m_RTtet)(TetEdge1[i],TetVertex2);
1993 RTmodprism->SetValue(PrismEdge1[i],PrismVertex2,RTvalue);
1994 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex1);
1995 RTmodprism->SetValue(PrismEdge2[i],PrismVertex2,RTvalue);
1996 RTvalue=(*m_RTtet)(TetEdge5[i],TetVertex2);
1997 RTmodprism->SetValue(PrismEdge6[i],PrismVertex2,RTvalue);
2001 for(i=0; i< PrismEdge3.num_elements(); ++i)
2003 Rvalue=(*m_Rtet)(TetVertex2,TetEdge2[i]);
2004 Rmodprism->SetValue(PrismVertex3,PrismEdge3[i],Rvalue);
2005 Rvalue=(*m_Rtet)(TetVertex0,TetEdge0[i]);
2006 Rmodprism->SetValue(PrismVertex3,PrismEdge2[i],Rvalue);
2007 Rvalue=(*m_Rtet)(TetVertex2,TetEdge5[i]);
2008 Rmodprism->SetValue(PrismVertex3,PrismEdge7[i],Rvalue);
2011 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex2);
2012 RTmodprism->SetValue(PrismEdge3[i],PrismVertex3,RTvalue);
2013 RTvalue=(*m_RTtet)(TetEdge0[i],TetVertex0);
2014 RTmodprism->SetValue(PrismEdge2[i],PrismVertex3,RTvalue);
2015 RTvalue=(*m_RTtet)(TetEdge5[i],TetVertex2);
2016 RTmodprism->SetValue(PrismEdge7[i],PrismVertex3,RTvalue);
2020 for(i=0; i< PrismEdge4.num_elements(); ++i)
2022 Rvalue=(*m_Rtet)(TetVertex3,TetEdge3[i]);
2023 Rmodprism->SetValue(PrismVertex4,PrismEdge4[i],Rvalue);
2024 Rvalue=(*m_Rtet)(TetVertex3,TetEdge4[i]);
2025 Rmodprism->SetValue(PrismVertex4,PrismEdge5[i],Rvalue);
2026 Rvalue=(*m_Rtet)(TetVertex0,TetEdge2[i]);
2027 Rmodprism->SetValue(PrismVertex4,PrismEdge8[i],Rvalue);
2030 RTvalue=(*m_RTtet)(TetEdge3[i],TetVertex3);
2031 RTmodprism->SetValue(PrismEdge4[i],PrismVertex4,RTvalue);
2032 RTvalue=(*m_RTtet)(TetEdge4[i],TetVertex3);
2033 RTmodprism->SetValue(PrismEdge5[i],PrismVertex4,RTvalue);
2034 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex0);
2035 RTmodprism->SetValue(PrismEdge8[i],PrismVertex4,RTvalue);
2039 for(i=0; i< PrismEdge5.num_elements(); ++i)
2041 Rvalue=(*m_Rtet)(TetVertex3,TetEdge3[i]);
2042 Rmodprism->SetValue(PrismVertex5,PrismEdge6[i],Rvalue);
2043 Rvalue=(*m_Rtet)(TetVertex3,TetEdge4[i]);
2044 Rmodprism->SetValue(PrismVertex5,PrismEdge7[i],Rvalue);
2045 Rvalue=(*m_Rtet)(TetVertex2,TetEdge2[i]);
2046 Rmodprism->SetValue(PrismVertex5,PrismEdge8[i],Rvalue);
2049 RTvalue=(*m_RTtet)(TetEdge3[i],TetVertex3);
2050 RTmodprism->SetValue(PrismEdge6[i],PrismVertex5,RTvalue);
2051 RTvalue=(*m_RTtet)(TetEdge4[i],TetVertex3);
2052 RTmodprism->SetValue(PrismEdge7[i],PrismVertex5,RTvalue);
2053 RTvalue=(*m_RTtet)(TetEdge2[i],TetVertex2);
2054 RTmodprism->SetValue(PrismEdge8[i],PrismVertex5,RTvalue);
2058 for(i=0; i< PrismFace1.num_elements(); ++i)
2060 Rvalue=(*m_Rtet)(TetVertex0,TetFace[i]);
2061 Rmodprism->SetValue(PrismVertex0,PrismFace1[i],Rvalue);
2062 Rvalue=(*m_Rtet)(TetVertex1,TetFace[i]);
2063 Rmodprism->SetValue(PrismVertex1,PrismFace1[i],Rvalue);
2064 Rvalue=(*m_Rtet)(TetVertex3,TetFace[i]);
2065 Rmodprism->SetValue(PrismVertex4,PrismFace1[i],Rvalue);
2068 RTvalue=(*m_RTtet)(TetFace[i],TetVertex0);
2069 RTmodprism->SetValue(PrismFace1[i],PrismVertex0,RTvalue);
2070 RTvalue=(*m_RTtet)(TetFace[i],TetVertex1);
2071 RTmodprism->SetValue(PrismFace1[i],PrismVertex1,RTvalue);
2072 RTvalue=(*m_RTtet)(TetFace[i],TetVertex3);
2073 RTmodprism->SetValue(PrismFace1[i],PrismVertex4,RTvalue);
2077 for(i=0; i< PrismFace3.num_elements(); ++i)
2079 Rvalue=(*m_Rtet)(TetVertex1,TetFace[i]);
2080 Rmodprism->SetValue(PrismVertex2,PrismFace3[i],Rvalue);
2081 Rvalue=(*m_Rtet)(TetVertex0,TetFace[i]);
2082 Rmodprism->SetValue(PrismVertex3,PrismFace3[i],Rvalue);
2083 Rvalue=(*m_Rtet)(TetVertex3,TetFace[i]);
2084 Rmodprism->SetValue(PrismVertex5,PrismFace3[i],Rvalue);
2087 RTvalue=(*m_RTtet)(TetFace[i],TetVertex1);
2088 RTmodprism->SetValue(PrismFace3[i],PrismVertex2,RTvalue);
2089 RTvalue=(*m_RTtet)(TetFace[i],TetVertex0);
2090 RTmodprism->SetValue(PrismFace3[i],PrismVertex3,RTvalue);
2091 RTvalue=(*m_RTtet)(TetFace[i],TetVertex3);
2092 RTmodprism->SetValue(PrismFace3[i],PrismVertex5,RTvalue);
2096 for(i=0; i< PrismFace1.num_elements(); ++i)
2098 for(j=0; j<PrismEdge0.num_elements(); ++j)
2100 Rvalue=(*m_Rtet)(TetEdge0[j],TetFace[i]);
2101 Rmodprism->SetValue(PrismEdge0[j],PrismFace1[i],Rvalue);
2102 Rvalue=(*m_Rtet)(TetEdge3[j],TetFace[i]);
2103 Rmodprism->SetValue(PrismEdge4[j],PrismFace1[i],Rvalue);
2104 Rvalue=(*m_Rtet)(TetEdge4[j],TetFace[i]);
2105 Rmodprism->SetValue(PrismEdge5[j],PrismFace1[i],Rvalue);
2108 RTvalue=(*m_RTtet)(TetFace[i],TetEdge0[j]);
2109 RTmodprism->SetValue(PrismFace1[i],PrismEdge0[j],RTvalue);
2110 RTvalue=(*m_RTtet)(TetFace[i],TetEdge3[j]);
2111 RTmodprism->SetValue(PrismFace1[i],PrismEdge4[j],RTvalue);
2112 RTvalue=(*m_RTtet)(TetFace[i],TetEdge4[j]);
2113 RTmodprism->SetValue(PrismFace1[i],PrismEdge5[j],RTvalue);
2118 for(i=0; i< PrismFace3.num_elements(); ++i)
2120 for(j=0; j<PrismEdge2.num_elements(); ++j)
2122 Rvalue=(*m_Rtet)(TetEdge0[j],TetFace[i]);
2123 Rmodprism->SetValue(PrismEdge2[j],PrismFace3[i],Rvalue);
2124 Rvalue=(*m_Rtet)(TetEdge4[j],TetFace[i]);
2125 Rmodprism->SetValue(PrismEdge6[j],PrismFace3[i],Rvalue);
2126 Rvalue=(*m_Rtet)(TetEdge3[j],TetFace[i]);
2127 Rmodprism->SetValue(PrismEdge7[j],PrismFace3[i],Rvalue);
2129 RTvalue=(*m_RTtet)(TetFace[i],TetEdge0[j]);
2130 RTmodprism->SetValue(PrismFace3[i],PrismEdge2[j],RTvalue);
2131 RTvalue=(*m_RTtet)(TetFace[i],TetEdge4[j]);
2132 RTmodprism->SetValue(PrismFace3[i],PrismEdge6[j],RTvalue);
2133 RTvalue=(*m_RTtet)(TetFace[i],TetEdge3[j]);
2134 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< Expansion > ExpansionSharedPtr
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< 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.