45 namespace LocalRegions
48 StdExpansion(),
Expansion(pGeom), StdExpansion2D()
57 const Array<OneD, const NekDouble> &Fx,
58 const Array<OneD, const NekDouble> &Fy,
59 Array<OneD, NekDouble> &outarray)
62 "Routine only set up for two-dimensions");
64 const Array<OneD, const Array<OneD, NekDouble> > normals
83 if (edgeExp->GetRightAdjacentElementExp())
85 if (edgeExp->GetRightAdjacentElementExp()->GetGeom2D()
86 ->GetGlobalID() ==
GetGeom2D()->GetGlobalID())
98 int nquad_e = min(EdgeExp->GetNumPoints(0),
99 int(normals[0].num_elements()));
101 int nEdgePts = EdgeExp->GetTotPoints();
102 Array<OneD, NekDouble> edgePhys(nEdgePts);
103 Vmath::Vmul (nquad_e, normals[0], 1, Fx, 1, edgePhys, 1);
104 Vmath::Vvtvp(nquad_e, normals[1], 1, Fy, 1, edgePhys, 1,
113 else if (locExp->GetRightAdjacentElementEdge() != -1)
115 if (locExp->GetRightAdjacentElementExp()->GetGeom2D()->GetGlobalID()
128 const Array<OneD, const NekDouble> &Fn,
129 Array<OneD, NekDouble> &outarray)
149 if (edgeExp->GetRightAdjacentElementExp())
151 if (edgeExp->GetRightAdjacentElementExp()->GetGeom2D()
152 ->GetGlobalID() ==
GetGeom2D()->GetGlobalID())
168 int order_e = map->num_elements();
170 int n_coeffs = EdgeExp->GetNcoeffs();
172 Array<OneD, NekDouble> edgeCoeffs(n_coeffs);
173 if(n_coeffs!=order_e)
175 EdgeExp->FwdTrans(Fn, edgeCoeffs);
183 Array<OneD, NekDouble> coeff(n_coeffs,0.0);
185 LibUtilities::BasisKey bkey_ortho(btype,EdgeExp->GetBasis(0)->GetNumModes(),EdgeExp->GetBasis(0)->GetPointsKey());
186 LibUtilities::BasisKey bkey(EdgeExp->GetBasis(0)->GetBasisType(),EdgeExp->GetBasis(0)->GetNumModes(),EdgeExp->GetBasis(0)->GetPointsKey());
190 for(i = order_e; i < n_coeffs; i++)
198 EdgeExp->MassMatrixOp(edgeCoeffs, edgeCoeffs, masskey);
202 EdgeExp->IProductWRTBase(Fn, edgeCoeffs);
213 if(EdgeExp->GetBasis(0)->GetBasisType() !=
217 for(i = 0; i < order_e; ++i)
219 outarray[(*map)[i].index] +=
220 (*map)[i].sign * edgeCoeffs[i];
225 int nCoeffs0, nCoeffs1;
239 nCoeffs1 =
m_base[1]->GetNumModes();
241 for(i = 0; i < order_e; ++i)
243 for(j = 0; j < nCoeffs1; j++)
245 outarray[(*map)[i].index + j*order_e] +=
246 mat_gauss->GetPtr()[j]*
247 (*map)[i].sign*edgeCoeffs[i];
254 nCoeffs0 =
m_base[0]->GetNumModes();
256 for(i = 0; i < order_e; ++i)
258 for(j = 0; j < nCoeffs0; j++)
260 outarray[(*map)[i].index - j] +=
261 mat_gauss->GetPtr()[order_e - 1 -j]*
262 (*map)[i].sign*edgeCoeffs[i];
269 nCoeffs1 =
m_base[1]->GetNumModes();
271 for(i = 0; i < order_e; ++i)
273 for(j = 0; j < nCoeffs1; j++)
275 outarray[(*map)[i].index - j*order_e] +=
276 mat_gauss->GetPtr()[order_e - 1 - j]*
277 (*map)[i].sign*edgeCoeffs[i];
284 nCoeffs0 =
m_base[0]->GetNumModes();
286 for(i = 0; i < order_e; ++i)
288 for(j = 0; j < nCoeffs0; j++)
290 outarray[(*map)[i].index + j] +=
291 mat_gauss->GetPtr()[j]*
292 (*map)[i].sign*edgeCoeffs[i];
298 ASSERTL0(
false,
"edge value (< 3) is out of range");
305 Array<OneD, ExpansionSharedPtr> &EdgeExp,
306 Array<OneD, NekDouble> &inout)
310 Array<OneD, NekDouble> e_tmp;
312 for(i = 0; i < nedges; ++i)
314 EdgeExp[i]->SetCoeffsToOrientation(
GetEorient(i),
316 e_tmp = inout + cnt);
327 Array<OneD, const NekDouble> &inarray,
328 Array<OneD, ExpansionSharedPtr> &EdgeExp,
329 Array<OneD, NekDouble> &outarray,
337 for(e = 0; e < nedges; ++e)
339 order_e = EdgeExp[e]->GetNcoeffs();
340 nquad_e = EdgeExp[e]->GetNumPoints(0);
342 const Array<OneD, const Array<OneD, NekDouble> > &normals
344 Array<OneD, NekDouble> edgeCoeffs(order_e);
345 Array<OneD, NekDouble> edgePhys (nquad_e);
347 for(i = 0; i < order_e; ++i)
349 edgeCoeffs[i] = inarray[i+cnt];
353 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
369 Vmath::Vmul(nquad_e, normals[dir], 1, edgePhys, 1, edgePhys, 1);
382 Array<OneD, ExpansionSharedPtr> &EdgeExp,
383 Array<
OneD, Array<OneD, NekDouble> > &edgeCoeffs,
384 Array<OneD, NekDouble> &outarray)
390 for(e = 0; e < nedges; ++e)
392 nquad_e = EdgeExp[e]->GetNumPoints(0);
394 Array<OneD, NekDouble> edgePhys(nquad_e);
395 const Array<OneD, const Array<OneD, NekDouble> > &normals
398 EdgeExp[e]->BwdTrans(edgeCoeffs[e], edgePhys);
400 Vmath::Vmul(nquad_e, normals[dir], 1, edgePhys, 1, edgePhys, 1);
418 Array<OneD, NekDouble> &edgePhys,
419 Array<OneD, NekDouble> &outarray,
423 int order_e = EdgeExp->GetNcoeffs();
424 int nquad_e = EdgeExp->GetNumPoints(0);
425 Array<OneD,unsigned int> map;
426 Array<OneD,int>
sign;
427 Array<OneD, NekDouble> coeff(order_e);
434 StdRegions::VarCoeffMap::const_iterator x;
437 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
439 Array<OneD, NekDouble> work(nquad_e);
441 edge, EdgeExp, x->second, work);
442 Vmath::Vmul(nquad_e, work, 1, edgePhys, 1, edgePhys, 1);
445 EdgeExp->IProductWRTBase(edgePhys, coeff);
448 for(i = 0; i < order_e; ++i)
450 outarray[map[i]] += sign[i]*coeff[i];
459 const Array<OneD, const NekDouble> &inarray,
460 Array<OneD, ExpansionSharedPtr> &EdgeExp,
462 Array<OneD,NekDouble> &outarray)
464 ASSERTL0(&inarray[0] != &outarray[0],
465 "Input and output arrays use the same memory");
467 int e, cnt, order_e, nedges =
GetNedges();
468 Array<OneD, const NekDouble> tmp;
472 for(e = 0; e < nedges; ++e)
474 order_e = EdgeExp[e]->GetNcoeffs();
475 Array<OneD, NekDouble> edgeCoeffs(order_e);
476 Array<OneD, NekDouble> edgePhys (EdgeExp[e]->
GetTotPoints());
478 Vmath::Vcopy(order_e, tmp = inarray + cnt, 1, edgeCoeffs, 1);
479 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
481 tau, e, EdgeExp, edgePhys, dirForcing, outarray);
492 Array<OneD, ExpansionSharedPtr> &EdgeExp,
493 Array<OneD, NekDouble> &edgePhys,
495 Array<OneD, NekDouble> &outarray)
498 int nquad_e = EdgeExp[edge]->GetNumPoints(0);
499 int order_e = EdgeExp[edge]->GetNcoeffs();
503 Array<OneD, NekDouble> inval (nquad_e);
504 Array<OneD, NekDouble> outcoeff(order_e);
505 Array<OneD, NekDouble> tmpcoeff(ncoeffs);
507 const Array<OneD, const Array<OneD, NekDouble> > &normals
510 Array<OneD,unsigned int> emap;
511 Array<OneD,int>
sign;
530 StdRegions::VarCoeffMap::const_iterator x;
532 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
534 Array<OneD, NekDouble> work(nquad_e);
536 edge, EdgeExp[edge], x->second, work);
537 Vmath::Vmul(nquad_e, work, 1, edgePhys, 1, edgePhys, 1);
543 EdgeExp[edge]->IProductWRTBase(edgePhys, outcoeff);
545 for(i = 0; i < order_e; ++i)
547 outarray[emap[i]] += sign[i] * tau * outcoeff[i];
556 for(n = 0; n < coordim; ++n)
558 Vmath::Vmul(nquad_e, normals[n], 1, edgePhys, 1, inval, 1);
574 EdgeExp[edge]->IProductWRTBase(inval, outcoeff);
577 for(i = 0; i < ncoeffs; ++i)
580 for(j = 0; j < order_e; ++j)
582 tmpcoeff[i] += invMass(i,emap[j])*sign[j]*outcoeff[j];
586 if(varcoeffs.find(VarCoeff[n]) != varcoeffs.end())
590 Coeffs = Coeffs + Dmat*Tmpcoeff;
596 Coeffs = Coeffs + Dmat*Tmpcoeff;
607 const Array<OneD, const NekDouble> &varcoeff,
608 Array<OneD,NekDouble> &outarray)
611 Array<OneD, NekDouble> edgetmp(EdgeExp->GetNcoeffs());
617 Array<OneD,unsigned int> emap;
618 Array<OneD, int>
sign;
622 for (
unsigned int i = 0; i < EdgeExp->GetNcoeffs(); ++i)
624 edgetmp[i] = tmp[emap[i]];
628 EdgeExp->BwdTrans(edgetmp, outarray);
649 "HybridDGHelmholtz matrix not set up "
650 "for non boundary-interior expansions");
658 Array<OneD,unsigned int> emap;
659 Array<OneD,int>
sign;
669 DNekMat LocMat(ncoeffs,ncoeffs);
679 for(i=0; i < coordim; ++i)
688 Mat = Mat + DmatL*invMass*
Transpose(DmatR);
693 Mat = Mat + Dmat*invMass*
Transpose(Dmat);
700 Mat = Mat + lambdaval*Mass;
703 for(i = 0; i < nedges; ++i)
707 order_e = EdgeExp->GetNcoeffs();
708 int nq = EdgeExp->GetNumPoints(0);
715 Array<OneD, NekDouble> mu(nq);
722 for(j = 0; j < order_e; ++j)
724 for(k = 0; k < order_e; ++k)
726 Mat(emap[j],emap[k]) = Mat(emap[j],emap[k]) + tau*sign[j]*sign[k]*
eMass(j,k);
741 Array<OneD,NekDouble> lambda(nbndry);
743 Array<OneD,NekDouble> ulam(ncoeffs);
745 Array<OneD,NekDouble> f(ncoeffs);
748 Array<OneD, ExpansionSharedPtr> EdgeExp(nedges);
757 Array<OneD,unsigned int> emap;
758 Array<OneD,int>
sign;
760 for(i = 0; i < nedges; ++i)
768 for(j = 0; j < nbndry; ++j)
785 for(k = 0; k < ncoeffs; ++k)
806 Array<OneD,NekDouble> lambda(nbndry);
808 Array<OneD, ExpansionSharedPtr> EdgeExp(nedges);
810 Array<OneD,NekDouble> ulam(ncoeffs);
812 Array<OneD,NekDouble> f(ncoeffs);
826 for(i = 0; i < nedges; ++i)
848 ASSERTL0(
false,
"Direction not known");
855 for(j = 0; j < nbndry; ++j)
861 for(k = 0; k < ncoeffs; ++k)
863 Ulam[k] = lamToU(k,j);
880 Vmath::Vcopy(ncoeffs,&ulam[0],1,&(Qmat.GetPtr())[0]+j*ncoeffs,1);
888 int order_e, nquad_e;
894 Array<OneD,NekDouble> work, varcoeff_work;
895 Array<OneD,const Array<OneD, NekDouble> > normals;
896 Array<OneD, ExpansionSharedPtr> EdgeExp(nedges);
897 Array<OneD, NekDouble> lam(nbndry);
899 Array<OneD,unsigned int> emap;
900 Array<OneD, int>
sign;
929 for(i = 0; i < nedges; ++i)
935 for(i = 0; i < nbndry; ++i)
943 for(e = 0; e < nedges; ++e)
945 order_e = EdgeExp[e]->GetNcoeffs();
946 nquad_e = EdgeExp[e]->GetNumPoints(0);
951 work = Array<OneD,NekDouble>(nquad_e);
952 varcoeff_work = Array<OneD, NekDouble>(nquad_e);
961 StdRegions::VarCoeffMap::const_iterator x;
964 Array<OneD, NekDouble> edgeCoeffs(order_e);
965 Array<OneD, NekDouble> edgePhys (nquad_e);
966 for(j = 0; j < order_e; ++j)
968 edgeCoeffs[j] = sign[j]*(*LamToQ[0])(emap[j],i);
971 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
980 Vmath::Vmul(nquad_e, normals[0], 1, edgePhys, 1, work, 1);
983 for(j = 0; j < order_e; ++j)
985 edgeCoeffs[j] = sign[j]*(*LamToQ[1])(emap[j],i);
988 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
1004 for(j = 0; j < order_e; ++j)
1006 edgeCoeffs[j] = sign[j]*(*LamToQ[2])(emap[j],i);
1009 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
1029 for(j = 0; j < order_e; ++j)
1031 edgeCoeffs[j] = sign[j]*LamToU(emap[j],i) - lam[cnt+j];
1034 EdgeExp[e]->BwdTrans(edgeCoeffs, edgePhys);
1037 if ((x = varcoeffs.find(VarCoeff[0])) != varcoeffs.end())
1040 Vmath::Vmul(nquad_e,varcoeff_work,1,edgePhys,1,edgePhys,1);
1046 EdgeExp[e]->IProductWRTBase(work, edgeCoeffs);
1048 EdgeExp[e]->SetCoeffsToOrientation(edgeCoeffs, edgedir);
1050 for(j = 0; j < order_e; ++j)
1052 BndMat(cnt+j,i) = edgeCoeffs[j];
1073 Array<OneD, NekDouble> tmp(nq);
1074 Array<OneD, NekDouble> outarray(
m_ncoeffs);
1079 &(lmat->GetPtr())[0],1);
1085 ASSERTL0(
false,
"This matrix type cannot be generated from this class");
1097 const Array<OneD, const NekDouble> &incoeffs,
1098 Array<OneD, ExpansionSharedPtr> &EdgeExp,
1099 Array<
OneD, Array<OneD, NekDouble> > &edgeCoeffs,
1100 Array<OneD, NekDouble> &out_d)
1111 Array<OneD, NekDouble> coeffs = incoeffs;
1123 Out_d = InvMass*Coeffs;
1136 "Not set up for non boundary-interior expansions");
1137 ASSERTL1(inoutmat->GetRows() == inoutmat->GetColumns(),
1138 "Assuming that input matrix was square");
1142 int order_e = edgeExp->GetNcoeffs();
1144 Array<OneD,unsigned int> map;
1145 Array<OneD,int>
sign;
1151 DNekScalMat &edgemat = *edgeExp->GetLocMatrix(mkey);
1165 int rows = inoutmat->GetRows();
1174 Array<OneD,unsigned int> bmap(nbndry);
1180 for(i = 0; i < order_e; ++i)
1182 for(j = 0; j < nbndry; ++j)
1184 if(map[i] == bmap[j])
1190 ASSERTL1(j != nbndry,
"Did not find number in map");
1197 map = Array<OneD, unsigned int> (order_e);
1198 sign = Array<OneD, int> (order_e,1);
1200 for(i = 0; i < edge; ++i)
1205 for(i = 0; i < order_e; ++i)
1212 switch(edgeExp->GetBasis(0)->GetBasisType())
1215 reverse( map.get() , map.get()+order_e);
1218 reverse( map.get() , map.get()+order_e);
1222 swap(map[0],map[1]);
1223 for(i = 3; i < order_e; i+=2)
1230 ASSERTL0(
false,
"Edge boundary type not valid for this method");
1236 ASSERTL0(
false,
"Could not identify matrix type from dimension");
1239 for(i = 0; i < order_e; ++i)
1242 for(j = 0; j < order_e; ++j)
1245 (*inoutmat)(id1,id2) += edgemat(i,j)*sign[i]*sign[j];
1261 "Not set up for non boundary-interior expansions");
1264 int order_e = edgeExp->GetNcoeffs();
1266 Array<OneD,unsigned int> map;
1267 Array<OneD,int>
sign;
1273 DNekScalMat &edgemat = *edgeExp->GetLocMatrix(mkey);
1279 for (i = 0; i < order_e; ++i)
1281 vEdgeCoeffs[i] = coeffs[map[i]]*sign[i];
1285 vEdgeCoeffs = edgemat * vEdgeCoeffs;
1287 for (i = 0; i < order_e; ++i)
1289 coeffs[map[i]] = vEdgeCoeffs[i]*sign[i];
1299 int nVerts, vid1, vid2, vMap1, vMap2;
1306 nVerts, nVerts, 0.0, storage);
1307 DNekMat &VertexMat = (*m_vertexmatrix);
1309 for (vid1 = 0; vid1 < nVerts; ++vid1)
1313 for (vid2 = 0; vid2 < nVerts; ++vid2)
1316 VertexValue = (*r_bnd)(vMap1, vMap2);
1317 VertexMat.SetValue(vid1, vid2, VertexValue);
1321 return m_vertexmatrix;
1331 Array<OneD, unsigned int> bmap(nBndCoeffs);
1336 map<int, int> invmap;
1337 for (j = 0; j < nBndCoeffs; ++j)
1339 invmap[bmap[j]] = j;
1347 Array<OneD, unsigned int> edgemaparray(nEdgeCoeffs);
1348 Array<OneD, unsigned int> maparray (nEdgeCoeffs);
1349 Array<OneD, int> signarray (nEdgeCoeffs, 1);
1355 for (n = 0; n < nEdgeCoeffs; ++n)
1357 edgemaparray[n] = invmap[maparray[n]];
1360 return edgemaparray;
1370 std::map<int, StdRegions::NormalVector>::const_iterator x;
1373 "Edge normal not computed.");