44 namespace LocalRegions
51 Array<OneD, NekDouble> &facePhys,
53 Array<OneD, NekDouble> &outarray)
57 int nquad_f = FaceExp->GetNumPoints(0)*FaceExp->GetNumPoints(1);
58 int order_f = FaceExp->GetNcoeffs();
62 Array<OneD, NekDouble> inval (nquad_f);
63 Array<OneD, NekDouble> outcoeff(order_f);
64 Array<OneD, NekDouble> tmpcoeff(ncoeffs);
66 const Array<OneD, const Array<OneD, NekDouble> > &normals
93 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
95 GetPhysFaceVarCoeffsFromElement(face,FaceExp,x->second,varcoeff_work);
96 Vmath::Vmul(nquad_f,varcoeff_work,1,FaceExp->GetPhys(),1,FaceExp->UpdatePhys(),1);
103 FaceExp->IProductWRTBase(facePhys, outcoeff);
105 for(i = 0; i < order_f; ++i)
107 outarray[(*map)[i].index] += (*map)[i].sign*tau*outcoeff[i];
112 const NekDouble *data = invMass.GetRawPtr();
119 for(n = 0; n < coordim; ++n)
121 Vmath::Vmul(nquad_f, normals[n], 1, facePhys, 1, inval, 1);
139 FaceExp->IProductWRTBase(inval, outcoeff);
142 for(i = 0; i < ncoeffs; ++i)
145 for(j = 0; j < order_f; ++j)
147 tmpcoeff[i] += scale*data[i+(*map)[j].index*ncoeffs]*(*map)[j].sign*outcoeff[j];
152 Coeffs = Coeffs + Dmat*Tmpcoeff;
177 Array<OneD, const NekDouble> &inarray,
178 Array<OneD,StdRegions::StdExpansionSharedPtr> &FaceExp,
179 Array<OneD,NekDouble> &outarray,
187 for(f = 0; f < nfaces; ++f)
189 order_f = FaceExp[f]->GetNcoeffs();
190 nquad_f = FaceExp[f]->GetNumPoints(0)*FaceExp[f]->GetNumPoints(1);
192 const Array<OneD, const Array<OneD, NekDouble> > &normals =
GetFaceNormal(f);
193 Array<OneD, NekDouble> faceCoeffs(order_f);
194 Array<OneD, NekDouble> facePhys (nquad_f);
196 for(i = 0; i < order_f; ++i)
198 faceCoeffs[i] = inarray[i+cnt];
202 FaceExp[f]->BwdTrans(faceCoeffs, facePhys);
218 Vmath::Vmul(nquad_f, normals[dir], 1, facePhys, 1, facePhys, 1);
232 Array<OneD, StdRegions::StdExpansionSharedPtr> &FaceExp,
233 Array<
OneD, Array<OneD, NekDouble> > &faceCoeffs,
234 Array<OneD, NekDouble> &outarray)
237 int order_f, nquad_f;
241 for(f = 0; f < nfaces; ++f)
243 order_f = FaceExp[f]->GetNcoeffs();
244 nquad_f = FaceExp[f]->GetNumPoints(0)*FaceExp[f]->GetNumPoints(1);
246 const Array<OneD, const Array<OneD, NekDouble> > &normals =
GetFaceNormal(f);
247 Array<OneD, NekDouble> facePhys(nquad_f);
251 FaceExp[f]->BwdTrans(faceCoeffs[f], facePhys);
253 Vmath::Vmul(nquad_f, normals[dir], 1, facePhys, 1, facePhys, 1);
270 Array<OneD, NekDouble> &facePhys,
271 Array<OneD, NekDouble> &outarray,
275 int order_f = FaceExp->GetNcoeffs();
276 Array<OneD, NekDouble> coeff(order_f);
298 FaceExp->IProductWRTBase(facePhys, coeff);
301 for(i = 0; i < order_f; ++i)
303 outarray[(*map)[i].index] += (*map)[i].sign*coeff[i];
311 const int face, Array<OneD, NekDouble> &inout)
315 Array<OneD, NekDouble> f_in(nface);
333 ASSERTL1((*map1).num_elements() == (*map2).num_elements(),
334 "There is an error with the GetFaceToElementMap");
336 for(j = 0; j < (*map1).num_elements(); ++j)
339 for(k = 0; k < (*map2).num_elements(); ++k)
342 if((*map1)[j].index == (*map2)[k].index && k != j)
346 if((*map1)[j].sign != (*map2)[k].sign)
362 Array<OneD, NekDouble> f_tmp;
364 for(i = 0; i < nfaces; ++i)
384 "Matrix construction is not implemented for variable "
385 "coefficients at the moment");
396 "HybridDGHelmholtz matrix not set up "
397 "for non boundary-interior expansions");
405 Array<OneD,unsigned int> fmap;
406 Array<OneD,int>
sign;
424 for(i=0; i < coordim; ++i)
427 Mat = Mat + Dmat*invMass*
Transpose(Dmat);
451 Mat = Mat + lambdaval*Mass;
454 for(i = 0; i < nfaces; ++i)
457 order_f = FaceExp->GetNcoeffs();
483 for(j = 0; j < order_f; ++j)
485 for(k = 0; k < order_f; ++k)
487 Mat((*map)[j].index,(*map)[k].index) +=
488 tau*(*map)[j].sign*(*map)[k].sign*
eMass(j,k);
504 Array<OneD,NekDouble> lambda(nbndry);
506 Array<OneD,NekDouble> ulam(ncoeffs);
508 Array<OneD,NekDouble> f(ncoeffs);
520 Array<OneD,unsigned int> fmap;
521 Array<OneD,int>
sign;
525 for(i = 0; i < nfaces; ++i)
529 Array<OneD, NekDouble> face_lambda(nface);
531 const Array<OneD, const Array<OneD, NekDouble> > normals
534 for(j = 0; j < nface; ++j)
538 face_lambda[j] = 1.0;
542 Array<OneD, NekDouble> tmp(FaceExp->GetTotPoints());
543 FaceExp->BwdTrans(face_lambda, tmp);
549 for(k = 0; k < ncoeffs; ++k)
551 Umat(k,bndry_cnt) = Ulam[k];
607 Array<OneD,NekDouble> lambda(nbndry);
609 Array<OneD,StdRegions::StdExpansionSharedPtr> FaceExp(nfaces);
611 Array<OneD,NekDouble> ulam(ncoeffs);
613 Array<OneD,NekDouble> f(ncoeffs);
627 for(i = 0; i < nfaces; ++i)
649 ASSERTL0(
false,
"Direction not known");
656 for(j = 0; j < nbndry; ++j)
662 for(k = 0; k < ncoeffs; ++k)
664 Ulam[k] = lamToU(k,j);
681 Vmath::Vcopy(ncoeffs,&ulam[0],1,&(Qmat.GetPtr())[0]+j*ncoeffs,1);
689 int order_f, nquad_f;
694 Array<OneD,NekDouble> work, varcoeff_work;
695 Array<OneD,const Array<OneD, NekDouble> > normals;
696 Array<OneD,StdRegions::StdExpansionSharedPtr> FaceExp(nfaces);
697 Array<OneD, NekDouble> lam(nbndry);
699 Array<OneD,unsigned int> fmap;
700 Array<OneD, int>
sign;
725 for(i = 0; i < nfaces; ++i)
731 for(i = 0; i < nbndry; ++i)
739 for(f = 0; f < nfaces; ++f)
741 order_f = FaceExp[f]->GetNcoeffs();
742 nquad_f = FaceExp[f]->GetNumPoints(0)*FaceExp[f]->GetNumPoints(1);
745 work = Array<OneD,NekDouble>(nquad_f);
746 varcoeff_work = Array<OneD, NekDouble>(nquad_f);
765 Array<OneD, NekDouble> faceCoeffs(order_f);
766 Array<OneD, NekDouble> facePhys (nquad_f);
767 for(j = 0; j < order_f; ++j)
769 faceCoeffs[j] = (*map)[j].sign*(*LamToQ[0])((*map)[j].index,i);
772 FaceExp[f]->BwdTrans(faceCoeffs, facePhys);
784 Vmath::Vmul(nquad_f, normals[0], 1, facePhys, 1, work, 1);
787 for(j = 0; j < order_f; ++j)
789 faceCoeffs[j] = (*map)[j].sign*(*LamToQ[1])((*map)[j].index,i);
792 FaceExp[f]->BwdTrans(faceCoeffs, facePhys);
804 Vmath::Vvtvp(nquad_f, normals[1], 1, facePhys, 1, work, 1, work, 1);
807 for(j = 0; j < order_f; ++j)
809 faceCoeffs[j] = (*map)[j].sign*(*LamToQ[2])((*map)[j].index,i);
812 FaceExp[f]->BwdTrans(faceCoeffs, facePhys);
834 for(j = 0; j < order_f; ++j)
836 faceCoeffs[j] = (*map)[j].sign*LamToU((*map)[j].index,i) - lam[cnt+j];
839 FaceExp[f]->BwdTrans(faceCoeffs, facePhys);
855 FaceExp[f]->IProductWRTBase(work, faceCoeffs);
859 for(j = 0; j < order_f; ++j)
861 BndMat(cnt+j,i) = faceCoeffs[j];
882 Array<OneD, NekDouble> tmp(nq);
883 Array<OneD, NekDouble> outarray(
m_ncoeffs);
888 &(lmat->GetPtr())[0],1);
895 ASSERTL0(
false,
"This matrix type cannot be generated from this class");
905 ASSERTL1(face < nFaces,
"Face is out of range.");
921 const Array<OneD, const NekDouble> &Fn,
922 Array<OneD, NekDouble> &outarray)
950 if (faceExp->GetRightAdjacentElementExp())
952 if (faceExp->GetRightAdjacentElementExp()->GetGeom3D()
953 ->GetGlobalID() ==
GetGeom3D()->GetGlobalID())
968 int order_e = (*map).num_elements();
969 int n_coeffs = FaceExp->GetNcoeffs();
971 Array<OneD, NekDouble> faceCoeffs(n_coeffs);
973 if (n_coeffs != order_e)
975 Array<OneD, NekDouble> coeff(n_coeffs);
976 Array<OneD, NekDouble> array(n_coeffs);
978 FaceExp->FwdTrans(Fn, faceCoeffs);
980 int NumModesElementMax = FaceExp->GetBasis(0)->GetNumModes();
981 int NumModesElementMin =
m_base[0]->GetNumModes();
983 FaceExp->ReduceOrderCoeffs(NumModesElementMin,
989 FaceExp->MassMatrixOp(
990 faceCoeffs,faceCoeffs,masskey);
993 int offset1 = 0, offset2 = 0;
997 for (i = 0; i < NumModesElementMin; ++i)
999 for (j = 0; j < NumModesElementMin; ++j)
1001 faceCoeffs[offset1+j] =
1002 faceCoeffs[offset2+j];
1004 offset1 += NumModesElementMin;
1005 offset2 += NumModesElementMax;
1009 for (i = NumModesElementMin; i < NumModesElementMax; ++i)
1011 for (j = NumModesElementMin; j < NumModesElementMax; ++j)
1013 faceCoeffs[i*NumModesElementMax+j] = 0.0;
1022 int offset1 = 0, offset2 = 0;
1024 for (i = 0; i < NumModesElementMin; ++i)
1026 for (j = 0; j < NumModesElementMin-i; ++j)
1028 faceCoeffs[offset1+j] =
1029 faceCoeffs[offset2+j];
1031 offset1 += NumModesElementMin-i;
1032 offset2 += NumModesElementMax-i;
1039 FaceExp->IProductWRTBase(Fn, faceCoeffs);
1044 for (i = 0; i < order_e; ++i)
1046 outarray[(*map)[i].index] -= (*map)[i].sign * faceCoeffs[i];
1051 for (i = 0; i < order_e; ++i)
1053 outarray[(*map)[i].index] += (*map)[i].sign * faceCoeffs[i];
1066 const Array<OneD, const NekDouble> &incoeffs,
1067 Array<OneD, StdRegions::StdExpansionSharedPtr> &FaceExp,
1068 Array<
OneD, Array<OneD, NekDouble> > &faceCoeffs,
1069 Array<OneD, NekDouble> &out_d)
1079 Array<OneD, NekDouble> coeffs = incoeffs;
1091 Out_d = InvMass*Coeffs;
1096 const Array<OneD, const NekDouble > &primCoeffs,
1100 "Not set up for non boundary-interior expansions");
1101 ASSERTL1(inoutmat->GetRows() == inoutmat->GetColumns(),
1102 "Assuming that input matrix was square");
1107 int order_f = faceExp->GetNcoeffs();
1109 Array<OneD, unsigned int> map;
1110 Array<OneD, int>
sign;
1116 faceExp->DetShapeType();
1125 DNekScalMat &facemat = *faceExp->GetLocMatrix(mkey);
1139 int rows = inoutmat->GetRows();
1148 Array<OneD,unsigned int> bmap(nbndry);
1153 for(i = 0; i < order_f; ++i)
1155 for(j = 0; j < nbndry; ++j)
1157 if(map[i] == bmap[j])
1163 ASSERTL1(j != nbndry,
"Did not find number in map");
1170 map = Array<OneD, unsigned int> (order_f);
1171 sign = Array<OneD, int> (order_f,1);
1186 ASSERTL1((*map1).num_elements() == (*map2).num_elements(),
1187 "There is an error with the GetFaceToElementMap");
1189 for (i = 0; i < face; ++i)
1194 for(i = 0; i < (*map1).num_elements(); ++i)
1198 for(j = 0; j < (*map2).num_elements(); ++j)
1200 if((*map1)[i].index == (*map2)[j].index)
1207 ASSERTL2(idx >= 0,
"Index not found");
1208 map [i] = idx + cnt;
1209 sign[i] = (*map2)[idx].sign;
1214 ASSERTL0(
false,
"Could not identify matrix type from dimension");
1217 for(i = 0; i < order_f; ++i)
1220 for(j = 0; j < order_f; ++j)
1223 (*inoutmat)(id1,id2) += facemat(i,j)*sign[i]*sign[j];
1234 int nVerts, vid1, vid2, vMap1, vMap2;
1241 nVerts, nVerts, 0.0, storage);
1242 DNekMat &VertexMat = (*m_vertexmatrix);
1244 for (vid1 = 0; vid1 < nVerts; ++vid1)
1248 for (vid2 = 0; vid2 < nVerts; ++vid2)
1251 VertexValue = (*r_bnd)(vMap1, vMap2);
1252 VertexMat.SetValue(vid1, vid2, VertexValue);
1256 return m_vertexmatrix;
1264 int eid, fid, vid, n, i;
1297 int nConnectedEdges = 3;
1298 int nConnectedFaces = 3;
1301 Array<OneD, Array<OneD, unsigned int> >
1302 MatEdgeLocation(nConnectedEdges);
1303 Array<OneD, Array<OneD, unsigned int> >
1304 MatFaceLocation(nConnectedFaces);
1311 m_transformationmatrix =
1313 nBndCoeffs, nBndCoeffs, 0.0, storage);
1314 m_transposedtransformationmatrix =
1316 nBndCoeffs, nBndCoeffs, 0.0, storage);
1318 DNekMat &R = (*m_transformationmatrix);
1319 DNekMat &RT = (*m_transposedtransformationmatrix);
1324 for (vid = 0; vid < nVerts; ++vid)
1335 int nedgemodesconnected =
1339 Array<OneD, unsigned int> edgemodearray(nedgemodesconnected);
1341 int nfacemodesconnected =
1345 Array<OneD, unsigned int> facemodearray(nfacemodesconnected);
1350 for (eid = 0; eid < nConnectedEdges; ++eid)
1353 geom->GetVertexEdgeMap(vid, eid));
1354 nmodes = MatEdgeLocation[eid].num_elements();
1359 1, &edgemodearray[offset], 1);
1368 for (fid = 0; fid < nConnectedFaces; ++fid)
1371 geom->GetVertexFaceMap(vid, fid));
1372 nmodes = MatFaceLocation[fid].num_elements();
1377 1, &facemodearray[offset], 1);
1384 1, efRow, 0.0, storage);
1385 DNekMat &Sveft = (*m_vertexedgefacetransformmatrix);
1389 1, efRow, 0.0, storage);
1390 DNekMat &Svef = (*m_vertexedgefacecoupling);
1393 for (n = 0; n < nedgemodesconnected; ++n)
1400 Svef.SetValue(0, n, VertexEdgeFaceValue);
1404 for (n = 0; n < nfacemodesconnected; ++n)
1411 Svef.SetValue(0, n + nedgemodesconnected, VertexEdgeFaceValue);
1424 efRow, efRow, 0.0, storage);
1425 DNekMat &Sefef = (*m_edgefacecoupling);
1430 for (m = 0; m < nedgemodesconnected; ++m)
1432 for (n = 0; n < nedgemodesconnected; ++n)
1435 EdgeEdgeValue = (*r_bnd)(edgemodearray[n],
1439 Sefef.SetValue(n, m, EdgeEdgeValue);
1444 for (n = 0; n < nfacemodesconnected; ++n)
1446 for (m = 0; m < nfacemodesconnected; ++m)
1449 FaceFaceValue = (*r_bnd)(facemodearray[n],
1452 Sefef.SetValue(nedgemodesconnected + n,
1453 nedgemodesconnected + m, FaceFaceValue);
1458 for (n = 0; n < nedgemodesconnected; ++n)
1460 for (m = 0; m < nfacemodesconnected; ++m)
1463 FaceFaceValue = (*r_bnd)(edgemodearray[n],
1468 n, nedgemodesconnected + m, FaceFaceValue);
1472 nedgemodesconnected + m, n, FaceFaceValue);
1483 Sveft = -Svef * Sefef;
1487 for (n = 0; n < edgemodearray.num_elements(); ++n)
1496 for (n = 0; n < facemodearray.num_elements(); ++n)
1499 Sveft(0, n + nedgemodesconnected));
1501 Sveft(0, n + nedgemodesconnected));
1524 int efCol, efRow, nedgemodes;
1527 nConnectedFaces = 2;
1530 MatEdgeLocation = Array<OneD, Array<OneD, unsigned int> >
1532 MatFaceLocation = Array<OneD, Array<OneD, unsigned int> >
1538 for (eid = 0; eid < nEdges; ++eid)
1548 efRow, efCol, 0.0, storage);
1549 DNekMat &Mef = (*m_efedgefacecoupling);
1554 efCol, efCol, 0.0, storage);
1555 DNekMat &Meff = (*m_effacefacecoupling);
1560 efRow, efCol, 0.0, storage);
1561 DNekMat &Meft = (*m_edgefacetransformmatrix);
1563 int nfacemodesconnected =
1566 Array<OneD, unsigned int>
1567 facemodearray(nfacemodesconnected);
1570 Array<OneD, unsigned int> inedgearray
1573 Array<OneD, unsigned int> edgemodearray(nedgemodes);
1578 1, &edgemodearray[0], 1);
1584 for (fid = 0; fid < nConnectedFaces; ++fid)
1587 geom->GetEdgeFaceMap(eid, fid));
1588 nmodes = MatFaceLocation[fid].num_elements();
1593 1, &facemodearray[offset], 1);
1599 for (n = 0; n < nedgemodes; ++n)
1601 for (m = 0; m < nfacemodesconnected; ++m)
1604 EdgeFaceValue = (*r_bnd)(edgemodearray[n],
1608 Mef.SetValue(n, m, EdgeFaceValue);
1613 for (n = 0; n < nfacemodesconnected; ++n)
1615 for (m = 0; m < nfacemodesconnected; ++m)
1618 FaceFaceValue = (*r_bnd)(facemodearray[n],
1622 Meff.SetValue(n, m, FaceFaceValue);
1636 for (n = 0; n < Meft.GetRows(); ++n)
1638 for (m = 0; m < Meft.GetColumns(); ++m)
1640 R.SetValue(edgemodearray[n], facemodearray[m],
1642 RT.SetValue(facemodearray[m], edgemodearray[n],
1648 for (i = 0; i < R.GetRows(); ++i)
1650 R.SetValue(i, i, 1.0);
1651 RT.SetValue(i, i, 1.0);
1657 return m_transformationmatrix;
1662 return m_transposedtransformationmatrix;
1683 int i, j, n, eid = 0, fid = 0;
1694 nCoeffs, nCoeffs, 0.0, storage);
1695 DNekMat &InvR = (*m_inversetransformationmatrix);
1703 int nedgemodestotal = 0;
1704 int nfacemodestotal = 0;
1706 for (eid = 0; eid < nEdges; ++eid)
1709 nedgemodestotal += nedgemodes;
1712 for (fid = 0; fid < nFaces; ++fid)
1715 nfacemodestotal += nfacemodes;
1718 Array<OneD, unsigned int>
1719 edgemodearray(nedgemodestotal);
1720 Array<OneD, unsigned int>
1721 facemodearray(nfacemodestotal);
1726 for (eid = 0; eid < nEdges; ++eid)
1728 Array<OneD, unsigned int> edgearray
1736 &edgemodearray[offset], 1);
1739 offset += nedgemodes;
1745 for (fid = 0; fid < nFaces; ++fid)
1747 Array<OneD, unsigned int> facearray
1755 &facemodearray[offset], 1);
1758 offset += nfacemodes;
1762 for (i = 0; i < nVerts; ++i)
1764 for (j = 0; j < nedgemodestotal; ++j)
1770 for (j = 0; j < nfacemodestotal; ++j)
1775 for (n = 0; n < nedgemodestotal; ++n)
1777 MatrixValue = InvR.GetValue(
1780 * R(edgemodearray[n], facemodearray[j]);
1788 for (i = 0; i < nedgemodestotal; ++i)
1790 for (j = 0; j < nfacemodestotal; ++j)
1793 edgemodearray[i], facemodearray[j],
1794 -R(edgemodearray[i], facemodearray[j]));
1798 for (i = 0; i < nCoeffs; ++i)
1800 InvR.SetValue(i, i, 1.0);
1803 return m_inversetransformationmatrix;
1813 Array<OneD, unsigned int> bmap(nBndCoeffs);
1818 map<int, int> invmap;
1819 for (j = 0; j < nBndCoeffs; ++j)
1821 invmap[bmap[j]] = j;
1829 Array<OneD, unsigned int> edgemaparray(nEdgeCoeffs);
1831 geom->GetEorient(eid);
1832 Array<OneD, unsigned int> maparray =
1833 Array<OneD, unsigned int>(nEdgeCoeffs);
1834 Array<OneD, int> signarray =
1835 Array<OneD, int>(nEdgeCoeffs, 1);
1840 for (n = 0; n < nEdgeCoeffs; ++n)
1842 edgemaparray[n] = invmap[maparray[n]];
1845 return edgemaparray;
1848 Array<OneD, unsigned int>
1856 Array<OneD, unsigned int> bmap(nBndCoeffs);
1861 map<int, int> reversemap;
1862 for (j = 0; j < bmap.num_elements(); ++j)
1864 reversemap[bmap[j]] = j;
1870 Array<OneD, unsigned int> facemaparray(nFaceCoeffs);
1872 Array<OneD, unsigned int> maparray =
1873 Array<OneD, unsigned int>(nFaceCoeffs);
1874 Array<OneD, int> signarray =
1875 Array<OneD, int>(nFaceCoeffs, 1);
1883 fOrient = faceOrient;
1889 for (n = 0; n < nFaceCoeffs; ++n)
1891 facemaparray[n] = reversemap[maparray[n]];
1894 return facemaparray;
1898 const Array<OneD, const NekDouble>& inarray)
1901 "This function is not implemented here. It is shape "