45 namespace LocalRegions
48 StdExpansion(),
Expansion(pGeom), StdExpansion2D()
59 const Array<OneD, const NekDouble> &Fx,
60 const Array<OneD, const NekDouble> &Fy,
61 Array<OneD, NekDouble> &outarray)
64 "Routine only set up for two-dimensions");
66 const Array<OneD, const Array<OneD, NekDouble> > normals
85 if (edgeExp->GetRightAdjacentElementExp())
87 if (edgeExp->GetRightAdjacentElementExp()->GetGeom2D()
88 ->GetGlobalID() ==
GetGeom2D()->GetGlobalID())
100 int nquad_e = min(EdgeExp->GetNumPoints(0),
101 int(normals[0].num_elements()));
103 int nEdgePts = EdgeExp->GetTotPoints();
104 Array<OneD, NekDouble> edgePhys(nEdgePts);
105 Vmath::Vmul (nquad_e, normals[0], 1, Fx, 1, edgePhys, 1);
106 Vmath::Vvtvp(nquad_e, normals[1], 1, Fy, 1, edgePhys, 1,
115 else if (locExp->GetRightAdjacentElementEdge() != -1)
117 if (locExp->GetRightAdjacentElementExp()->GetGeom2D()->GetGlobalID()
130 const Array<OneD, const NekDouble> &Fn,
131 Array<OneD, NekDouble> &outarray)
151 if (edgeExp->GetRightAdjacentElementExp())
153 if (edgeExp->GetRightAdjacentElementExp()->GetGeom2D()
154 ->GetGlobalID() ==
GetGeom2D()->GetGlobalID())
170 int order_e = map->num_elements();
172 int n_coeffs = EdgeExp->GetNcoeffs();
174 Array<OneD, NekDouble> edgeCoeffs(n_coeffs);
175 if(n_coeffs!=order_e)
177 EdgeExp->FwdTrans(Fn, edgeCoeffs);
185 Array<OneD, NekDouble> coeff(n_coeffs,0.0);
187 LibUtilities::BasisKey bkey_ortho(btype,EdgeExp->GetBasis(0)->GetNumModes(),EdgeExp->GetBasis(0)->GetPointsKey());
188 LibUtilities::BasisKey bkey(EdgeExp->GetBasis(0)->GetBasisType(),EdgeExp->GetBasis(0)->GetNumModes(),EdgeExp->GetBasis(0)->GetPointsKey());
192 for(i = order_e; i < n_coeffs; i++)
200 EdgeExp->MassMatrixOp(edgeCoeffs, edgeCoeffs, masskey);
204 EdgeExp->IProductWRTBase(Fn, edgeCoeffs);
215 if(EdgeExp->GetBasis(0)->GetBasisType() !=
219 for(i = 0; i < order_e; ++i)
221 outarray[(*map)[i].index] +=
222 (*map)[i].sign * edgeCoeffs[i];
227 int nCoeffs0, nCoeffs1;
241 nCoeffs1 =
m_base[1]->GetNumModes();
243 for(i = 0; i < order_e; ++i)
245 for(j = 0; j < nCoeffs1; j++)
247 outarray[(*map)[i].index + j*order_e] +=
248 mat_gauss->GetPtr()[j]*
249 (*map)[i].sign*edgeCoeffs[i];
256 nCoeffs0 =
m_base[0]->GetNumModes();
258 for(i = 0; i < order_e; ++i)
260 for(j = 0; j < nCoeffs0; j++)
262 outarray[(*map)[i].index - j] +=
263 mat_gauss->GetPtr()[order_e - 1 -j]*
264 (*map)[i].sign*edgeCoeffs[i];
271 nCoeffs1 =
m_base[1]->GetNumModes();
273 for(i = 0; i < order_e; ++i)
275 for(j = 0; j < nCoeffs1; j++)
277 outarray[(*map)[i].index - j*order_e] +=
278 mat_gauss->GetPtr()[order_e - 1 - j]*
279 (*map)[i].sign*edgeCoeffs[i];
286 nCoeffs0 =
m_base[0]->GetNumModes();
288 for(i = 0; i < order_e; ++i)
290 for(j = 0; j < nCoeffs0; j++)
292 outarray[(*map)[i].index + j] +=
293 mat_gauss->GetPtr()[j]*
294 (*map)[i].sign*edgeCoeffs[i];
300 ASSERTL0(
false,
"edge value (< 3) is out of range");
307 Array<OneD,StdRegions::StdExpansionSharedPtr> &EdgeExp,
308 Array<OneD, NekDouble> &inout)
312 Array<OneD, NekDouble> e_tmp;
314 for(i = 0; i < nedges; ++i)
316 EdgeExp[i]->SetCoeffsToOrientation(
GetEorient(i),
318 e_tmp = inout + cnt);
329 Array<OneD, const NekDouble> &inarray,
330 Array<OneD, StdRegions::StdExpansionSharedPtr> &EdgeExp,
331 Array<OneD, NekDouble> &outarray,
339 for(e = 0; e < nedges; ++e)
341 order_e = EdgeExp[e]->GetNcoeffs();
342 nquad_e = EdgeExp[e]->GetNumPoints(0);
344 const Array<OneD, const Array<OneD, NekDouble> > &normals
346 Array<OneD, NekDouble> edgeCoeffs(order_e);
347 Array<OneD, NekDouble> edgePhys (nquad_e);
349 for(i = 0; i < order_e; ++i)
351 edgeCoeffs[i] = inarray[i+cnt];
355 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
371 Vmath::Vmul(nquad_e, normals[dir], 1, edgePhys, 1, edgePhys, 1);
384 Array<OneD, StdRegions::StdExpansionSharedPtr> &EdgeExp,
385 Array<
OneD, Array<OneD, NekDouble> > &edgeCoeffs,
386 Array<OneD, NekDouble> &outarray)
392 for(e = 0; e < nedges; ++e)
394 nquad_e = EdgeExp[e]->GetNumPoints(0);
396 Array<OneD, NekDouble> edgePhys(nquad_e);
397 const Array<OneD, const Array<OneD, NekDouble> > &normals
400 EdgeExp[e]->BwdTrans(edgeCoeffs[e], edgePhys);
402 Vmath::Vmul(nquad_e, normals[dir], 1, edgePhys, 1, edgePhys, 1);
420 Array<OneD, NekDouble> &edgePhys,
421 Array<OneD, NekDouble> &outarray,
425 int order_e = EdgeExp->GetNcoeffs();
426 int nquad_e = EdgeExp->GetNumPoints(0);
427 Array<OneD,unsigned int> map;
428 Array<OneD,int>
sign;
429 Array<OneD, NekDouble> coeff(order_e);
436 StdRegions::VarCoeffMap::const_iterator x;
439 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
441 Array<OneD, NekDouble> work(nquad_e);
443 edge, EdgeExp, x->second, work);
444 Vmath::Vmul(nquad_e, work, 1, edgePhys, 1, edgePhys, 1);
447 EdgeExp->IProductWRTBase(edgePhys, coeff);
450 for(i = 0; i < order_e; ++i)
452 outarray[map[i]] += sign[i]*coeff[i];
461 const Array<OneD, const NekDouble> &inarray,
462 Array<OneD,StdRegions::StdExpansionSharedPtr> &EdgeExp,
464 Array<OneD,NekDouble> &outarray)
466 ASSERTL0(&inarray[0] != &outarray[0],
467 "Input and output arrays use the same memory");
469 int e, cnt, order_e, nedges =
GetNedges();
470 Array<OneD, const NekDouble> tmp;
474 for(e = 0; e < nedges; ++e)
476 order_e = EdgeExp[e]->GetNcoeffs();
477 Array<OneD, NekDouble> edgeCoeffs(order_e);
478 Array<OneD, NekDouble> edgePhys (EdgeExp[e]->
GetTotPoints());
480 Vmath::Vcopy(order_e, tmp = inarray + cnt, 1, edgeCoeffs, 1);
481 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
483 tau, e, EdgeExp, edgePhys, dirForcing, outarray);
494 Array<OneD, StdRegions::StdExpansionSharedPtr> &EdgeExp,
495 Array<OneD, NekDouble> &edgePhys,
497 Array<OneD, NekDouble> &outarray)
500 int nquad_e = EdgeExp[edge]->GetNumPoints(0);
501 int order_e = EdgeExp[edge]->GetNcoeffs();
505 Array<OneD, NekDouble> inval (nquad_e);
506 Array<OneD, NekDouble> outcoeff(order_e);
507 Array<OneD, NekDouble> tmpcoeff(ncoeffs);
509 const Array<OneD, const Array<OneD, NekDouble> > &normals
512 Array<OneD,unsigned int> emap;
513 Array<OneD,int>
sign;
532 StdRegions::VarCoeffMap::const_iterator x;
534 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
536 Array<OneD, NekDouble> work(nquad_e);
538 edge, EdgeExp[edge], x->second, work);
539 Vmath::Vmul(nquad_e, work, 1, edgePhys, 1, edgePhys, 1);
545 EdgeExp[edge]->IProductWRTBase(edgePhys, outcoeff);
547 for(i = 0; i < order_e; ++i)
549 outarray[emap[i]] += sign[i] * tau * outcoeff[i];
558 for(n = 0; n < coordim; ++n)
560 Vmath::Vmul(nquad_e, normals[n], 1, edgePhys, 1, inval, 1);
576 EdgeExp[edge]->IProductWRTBase(inval, outcoeff);
579 for(i = 0; i < ncoeffs; ++i)
582 for(j = 0; j < order_e; ++j)
584 tmpcoeff[i] += invMass(i,emap[j])*sign[j]*outcoeff[j];
588 if(varcoeffs.find(VarCoeff[n]) != varcoeffs.end())
592 Coeffs = Coeffs + Dmat*Tmpcoeff;
598 Coeffs = Coeffs + Dmat*Tmpcoeff;
609 const Array<OneD, const NekDouble> &varcoeff,
610 Array<OneD,NekDouble> &outarray)
613 Array<OneD, NekDouble> edgetmp(EdgeExp->GetNcoeffs());
619 Array<OneD,unsigned int> emap;
620 Array<OneD, int>
sign;
624 for (
unsigned int i = 0; i < EdgeExp->GetNcoeffs(); ++i)
626 edgetmp[i] = tmp[emap[i]];
630 EdgeExp->BwdTrans(edgetmp, outarray);
651 "HybridDGHelmholtz matrix not set up "
652 "for non boundary-interior expansions");
660 Array<OneD,unsigned int> emap;
661 Array<OneD,int>
sign;
671 DNekMat LocMat(ncoeffs,ncoeffs);
681 for(i=0; i < coordim; ++i)
690 Mat = Mat + DmatL*invMass*
Transpose(DmatR);
695 Mat = Mat + Dmat*invMass*
Transpose(Dmat);
702 Mat = Mat + lambdaval*Mass;
705 for(i = 0; i < nedges; ++i)
709 order_e = EdgeExp->GetNcoeffs();
710 int nq = EdgeExp->GetNumPoints(0);
717 Array<OneD, NekDouble> mu(nq);
724 for(j = 0; j < order_e; ++j)
726 for(k = 0; k < order_e; ++k)
728 Mat(emap[j],emap[k]) = Mat(emap[j],emap[k]) + tau*sign[j]*sign[k]*
eMass(j,k);
743 Array<OneD,NekDouble> lambda(nbndry);
745 Array<OneD,NekDouble> ulam(ncoeffs);
747 Array<OneD,NekDouble> f(ncoeffs);
750 Array<OneD,StdRegions::StdExpansionSharedPtr> EdgeExp(nedges);
759 Array<OneD,unsigned int> emap;
760 Array<OneD,int>
sign;
762 for(i = 0; i < nedges; ++i)
770 for(j = 0; j < nbndry; ++j)
787 for(k = 0; k < ncoeffs; ++k)
808 Array<OneD,NekDouble> lambda(nbndry);
810 Array<OneD,StdRegions::StdExpansionSharedPtr> EdgeExp(nedges);
812 Array<OneD,NekDouble> ulam(ncoeffs);
814 Array<OneD,NekDouble> f(ncoeffs);
828 for(i = 0; i < nedges; ++i)
850 ASSERTL0(
false,
"Direction not known");
857 for(j = 0; j < nbndry; ++j)
863 for(k = 0; k < ncoeffs; ++k)
865 Ulam[k] = lamToU(k,j);
882 Vmath::Vcopy(ncoeffs,&ulam[0],1,&(Qmat.GetPtr())[0]+j*ncoeffs,1);
890 int order_e, nquad_e;
896 Array<OneD,NekDouble> work, varcoeff_work;
897 Array<OneD,const Array<OneD, NekDouble> > normals;
898 Array<OneD,StdRegions::StdExpansionSharedPtr> EdgeExp(nedges);
899 Array<OneD, NekDouble> lam(nbndry);
901 Array<OneD,unsigned int> emap;
902 Array<OneD, int>
sign;
931 for(i = 0; i < nedges; ++i)
937 for(i = 0; i < nbndry; ++i)
945 for(e = 0; e < nedges; ++e)
947 order_e = EdgeExp[e]->GetNcoeffs();
948 nquad_e = EdgeExp[e]->GetNumPoints(0);
953 work = Array<OneD,NekDouble>(nquad_e);
954 varcoeff_work = Array<OneD, NekDouble>(nquad_e);
963 StdRegions::VarCoeffMap::const_iterator x;
966 Array<OneD, NekDouble> edgeCoeffs(order_e);
967 Array<OneD, NekDouble> edgePhys (nquad_e);
968 for(j = 0; j < order_e; ++j)
970 edgeCoeffs[j] = sign[j]*(*LamToQ[0])(emap[j],i);
973 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
982 Vmath::Vmul(nquad_e, normals[0], 1, edgePhys, 1, work, 1);
985 for(j = 0; j < order_e; ++j)
987 edgeCoeffs[j] = sign[j]*(*LamToQ[1])(emap[j],i);
990 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
1006 for(j = 0; j < order_e; ++j)
1008 edgeCoeffs[j] = sign[j]*(*LamToQ[2])(emap[j],i);
1011 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
1031 for(j = 0; j < order_e; ++j)
1033 edgeCoeffs[j] = sign[j]*LamToU(emap[j],i) - lam[cnt+j];
1036 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
1039 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
1042 Vmath::Vmul(nquad_e,varcoeff_work,1,edgePhys,1,edgePhys,1);
1048 EdgeExp[e]->IProductWRTBase(work, edgeCoeffs);
1050 EdgeExp[e]->SetCoeffsToOrientation(edgeCoeffs, edgedir);
1052 for(j = 0; j < order_e; ++j)
1054 BndMat(cnt+j,i) = edgeCoeffs[j];
1075 Array<OneD, NekDouble> tmp(nq);
1076 Array<OneD, NekDouble> outarray(
m_ncoeffs);
1081 &(lmat->GetPtr())[0],1);
1087 ASSERTL0(
false,
"This matrix type cannot be generated from this class");
1099 const Array<OneD, const NekDouble> &incoeffs,
1100 Array<OneD,StdRegions::StdExpansionSharedPtr> &EdgeExp,
1101 Array<
OneD, Array<OneD, NekDouble> > &edgeCoeffs,
1102 Array<OneD, NekDouble> &out_d)
1113 Array<OneD, NekDouble> coeffs = incoeffs;
1125 Out_d = InvMass*Coeffs;
1138 "Not set up for non boundary-interior expansions");
1139 ASSERTL1(inoutmat->GetRows() == inoutmat->GetColumns(),
1140 "Assuming that input matrix was square");
1144 int order_e = edgeExp->GetNcoeffs();
1146 Array<OneD,unsigned int> map;
1147 Array<OneD,int>
sign;
1153 DNekScalMat &edgemat = *edgeExp->GetLocMatrix(mkey);
1167 int rows = inoutmat->GetRows();
1176 Array<OneD,unsigned int> bmap(nbndry);
1182 for(i = 0; i < order_e; ++i)
1184 for(j = 0; j < nbndry; ++j)
1186 if(map[i] == bmap[j])
1192 ASSERTL1(j != nbndry,
"Did not find number in map");
1199 map = Array<OneD, unsigned int> (order_e);
1200 sign = Array<OneD, int> (order_e,1);
1202 for(i = 0; i < edge; ++i)
1207 for(i = 0; i < order_e; ++i)
1214 switch(edgeExp->GetBasis(0)->GetBasisType())
1217 reverse( map.get() , map.get()+order_e);
1220 reverse( map.get() , map.get()+order_e);
1224 swap(map[0],map[1]);
1225 for(i = 3; i < order_e; i+=2)
1232 ASSERTL0(
false,
"Edge boundary type not valid for this method");
1238 ASSERTL0(
false,
"Could not identify matrix type from dimension");
1241 for(i = 0; i < order_e; ++i)
1244 for(j = 0; j < order_e; ++j)
1247 (*inoutmat)(id1,id2) += edgemat(i,j)*sign[i]*sign[j];
1263 "Not set up for non boundary-interior expansions");
1266 int order_e = edgeExp->GetNcoeffs();
1268 Array<OneD,unsigned int> map;
1269 Array<OneD,int>
sign;
1275 DNekScalMat &edgemat = *edgeExp->GetLocMatrix(mkey);
1281 for (i = 0; i < order_e; ++i)
1283 vEdgeCoeffs[i] = coeffs[map[i]]*sign[i];
1287 vEdgeCoeffs = edgemat * vEdgeCoeffs;
1289 for (i = 0; i < order_e; ++i)
1291 coeffs[map[i]] = vEdgeCoeffs[i]*sign[i];
1301 int nVerts, vid1, vid2, vMap1, vMap2;
1308 nVerts, nVerts, 0.0, storage);
1309 DNekMat &VertexMat = (*m_vertexmatrix);
1311 for (vid1 = 0; vid1 < nVerts; ++vid1)
1315 for (vid2 = 0; vid2 < nVerts; ++vid2)
1318 VertexValue = (*r_bnd)(vMap1, vMap2);
1319 VertexMat.SetValue(vid1, vid2, VertexValue);
1323 return m_vertexmatrix;
1333 Array<OneD, unsigned int> bmap(nBndCoeffs);
1338 map<int, int> invmap;
1339 for (j = 0; j < nBndCoeffs; ++j)
1341 invmap[bmap[j]] = j;
1349 Array<OneD, unsigned int> edgemaparray(nEdgeCoeffs);
1350 Array<OneD, unsigned int> maparray (nEdgeCoeffs);
1351 Array<OneD, int> signarray (nEdgeCoeffs, 1);
1357 for (n = 0; n < nEdgeCoeffs; ++n)
1359 edgemaparray[n] = invmap[maparray[n]];
1362 return edgemaparray;
1372 std::map<int, StdRegions::NormalVector>::const_iterator x;
1375 "Edge normal not computed.");