Nektar++
Expansion1D.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: Expansion1D.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: File for Expansion1D routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <boost/core/ignore_unused.hpp>
36
39
40using namespace std;
41
42namespace Nektar
43{
44namespace LocalRegions
45{
46
48{
49 DNekMatSharedPtr returnval;
50
51 switch (mkey.GetMatrixType())
52 {
54 {
56 "HybridDGHelmholtz matrix not set up "
57 "for non boundary-interior expansions");
58 int i;
59 NekDouble lambdaval =
62 int ncoeffs = GetNcoeffs();
63
64 int coordim = GetCoordim();
65
70 DNekMat LocMat(ncoeffs, ncoeffs);
71
72 returnval =
74 DNekMat &Mat = *returnval;
75
76 Vmath::Zero(ncoeffs * ncoeffs, Mat.GetPtr(), 1);
77
78 for (i = 0; i < coordim; ++i)
79 {
80 DNekScalMat &Dmat = *GetLocMatrix(DerivType[i]);
81
82 Mat = Mat + Dmat * invMass * Transpose(Dmat);
83 }
84
85 // Add end Mass Matrix Contribution
87 Mat = Mat + lambdaval * Mass;
88
90 GetBoundaryMap(bmap);
91
92 // Add tau*F_e using elemental mass matrices
93 for (i = 0; i < 2; ++i)
94 {
95 Mat(bmap[i], bmap[i]) = Mat(bmap[i], bmap[i]) + tau;
96 }
97 }
98 break;
100 {
101 int j, k;
102 int nbndry = NumDGBndryCoeffs();
103 int ncoeffs = GetNcoeffs();
109
110 Array<OneD, NekDouble> lambda(nbndry);
111 DNekVec Lambda(nbndry, lambda, eWrapper);
112 Array<OneD, NekDouble> ulam(ncoeffs);
113 DNekVec Ulam(ncoeffs, ulam, eWrapper);
114 Array<OneD, NekDouble> f(ncoeffs);
115 DNekVec F(ncoeffs, f, eWrapper);
116
117 // declare matrix space
118 returnval =
120 DNekMat &Umat = *returnval;
121
122 // Helmholtz matrix
123 DNekScalMat &invHmat =
125
126 // for each degree of freedom of the lambda space
127 // calculate Umat entry
128 // Generate Lambda to U_lambda matrix
129 for (j = 0; j < nbndry; ++j)
130 {
131 Vmath::Zero(nbndry, &lambda[0], 1);
132 Vmath::Zero(ncoeffs, &f[0], 1);
133 lambda[j] = 1.0;
134
136 lambda, f);
137
138 Ulam = invHmat * F; // generate Ulam from lambda
139
140 // fill column of matrix
141 for (k = 0; k < ncoeffs; ++k)
142 {
143 Umat(k, j) = Ulam[k];
144 }
145 }
146 }
147 break;
151 {
152 int j = 0;
153 int k = 0;
154 int dir = 0;
155 int nbndry = NumDGBndryCoeffs();
156 int ncoeffs = GetNcoeffs();
157
158 Array<OneD, NekDouble> lambda(nbndry);
159 DNekVec Lambda(nbndry, lambda, eWrapper);
160
161 Array<OneD, NekDouble> ulam(ncoeffs);
162 DNekVec Ulam(ncoeffs, ulam, eWrapper);
163 Array<OneD, NekDouble> f(ncoeffs);
164 DNekVec F(ncoeffs, f, eWrapper);
170
171 // declare matrix space
172 returnval =
174 DNekMat &Qmat = *returnval;
175
176 // Lambda to U matrix
177 DNekScalMat &lamToU =
179
180 // Inverse mass matrix
182
183 // Weak Derivative matrix
185 switch (mkey.GetMatrixType())
186 {
188 dir = 0;
190 break;
192 dir = 1;
194 break;
196 dir = 2;
198 break;
199 default:
200 ASSERTL0(false, "Direction not known");
201 break;
202 }
203
204 // for each degree of freedom of the lambda space
205 // calculate Qmat entry
206 // Generate Lambda to Q_lambda matrix
207 for (j = 0; j < nbndry; ++j)
208 {
209 Vmath::Zero(nbndry, &lambda[0], 1);
210 lambda[j] = 1.0;
211
212 // for lambda[j] = 1 this is the solution to ulam
213 for (k = 0; k < ncoeffs; ++k)
214 {
215 Ulam[k] = lamToU(k, j);
216 }
217
218 // -D^T ulam
219 Vmath::Neg(ncoeffs, &ulam[0], 1);
220 F = Transpose(*Dmat) * Ulam;
221
222 // + \tilde{G} \lambda
223 AddNormTraceInt(dir, lambda, f);
224
225 // multiply by inverse mass matrix
226 Ulam = invMass * F;
227
228 // fill column of matrix (Qmat is in column major format)
229 Vmath::Vcopy(ncoeffs, &ulam[0], 1,
230 &(Qmat.GetPtr())[0] + j * ncoeffs, 1);
231 }
232 }
233 break;
235 {
236 int j;
237 int nbndry = NumBndryCoeffs();
238
244
247 GetBoundaryMap(bmap);
248
249 // declare matrix space
250 returnval =
252 DNekMat &BndMat = *returnval;
253
254 // Matrix to map Lambda to U
255 DNekScalMat &LamToU =
257
258 // Matrix to map Lambda to Q
259 DNekScalMat &LamToQ =
261
262 lam[0] = 1.0;
263 lam[1] = 0.0;
264 for (j = 0; j < nbndry; ++j)
265 {
266 BndMat(0, j) =
267 -LamToQ(bmap[0], j) - factors[StdRegions::eFactorTau] *
268 (LamToU(bmap[0], j) - lam[j]);
269 }
270
271 lam[0] = 0.0;
272 lam[1] = 1.0;
273 for (j = 0; j < nbndry; ++j)
274 {
275 BndMat(1, j) =
276 LamToQ(bmap[1], j) - factors[StdRegions::eFactorTau] *
277 (LamToU(bmap[1], j) - lam[j]);
278 }
279 }
280 break;
281 default:
282 ASSERTL0(false,
283 "This matrix type cannot be generated from this class");
284 break;
285 }
286
287 return returnval;
288}
289
292 Array<OneD, NekDouble> &outarray)
293{
294 boost::ignore_unused(dir);
295
296 int k;
297 int nbndry = NumBndryCoeffs();
298 int nquad = GetNumPoints(0);
299 const Array<OneD, const NekDouble> &Basis = GetBasis(0)->GetBdata();
301
302 GetBoundaryMap(vmap);
303
304 // add G \lambda term (can assume G is diagonal since one
305 // of the basis is zero at boundary otherwise)
306 for (k = 0; k < nbndry; ++k)
307 {
308 outarray[vmap[k]] += (Basis[(vmap[k] + 1) * nquad - 1] *
309 Basis[(vmap[k] + 1) * nquad - 1] -
310 Basis[vmap[k] * nquad] * Basis[vmap[k] * nquad]) *
311 inarray[vmap[k]];
312 }
313}
314
316 const NekDouble tau, const Array<OneD, const NekDouble> &inarray,
317 Array<OneD, NekDouble> &outarray)
318{
319 int i, n;
320 int nbndry = NumBndryCoeffs();
321 int nquad = GetNumPoints(0);
322 int ncoeffs = GetNcoeffs();
323 int coordim = GetCoordim();
325
326 ASSERTL0(&inarray[0] != &outarray[0],
327 "Input and output arrays use the same memory");
328
329 const Array<OneD, const NekDouble> &Basis = GetBasis(0)->GetBdata();
331
332 GetBoundaryMap(vmap);
333
334 // Add F = \tau <phi_i,phi_j> (note phi_i is zero if phi_j is non-zero)
335 for (i = 0; i < nbndry; ++i)
336 {
337 outarray[vmap[i]] += tau * Basis[(vmap[i] + 1) * nquad - 1] *
338 Basis[(vmap[i] + 1) * nquad - 1] *
339 inarray[vmap[i]];
340 outarray[vmap[i]] += tau * Basis[vmap[i] * nquad] *
341 Basis[vmap[i] * nquad] * inarray[vmap[i]];
342 }
343
344 //===============================================================
345 // Add -\sum_i D_i^T M^{-1} G_i + E_i M^{-1} G_i =
346 // \sum_i D_i M^{-1} G_i term
347
351 Array<OneD, NekDouble> tmpcoeff(ncoeffs, 0.0);
352 DNekVec Coeffs(ncoeffs, outarray, eWrapper);
353 DNekVec Tmpcoeff(ncoeffs, tmpcoeff, eWrapper);
354
355 for (n = 0; n < coordim; ++n)
356 {
357 // evaluate M^{-1} G
358 for (i = 0; i < ncoeffs; ++i)
359 {
360 // lower boundary (negative normal)
361 tmpcoeff[i] -= invMass(i, vmap[0]) * Basis[vmap[0] * nquad] *
362 Basis[vmap[0] * nquad] * inarray[vmap[0]];
363
364 // upper boundary (positive normal)
365 tmpcoeff[i] += invMass(i, vmap[1]) *
366 Basis[(vmap[1] + 1) * nquad - 1] *
367 Basis[(vmap[1] + 1) * nquad - 1] * inarray[vmap[1]];
368 }
369
370 DNekScalMat &Dmat = *GetLocMatrix(DerivType[n]);
371 Coeffs = Coeffs + Dmat * Tmpcoeff;
372 }
373}
374
376 const int vert, const Array<OneD, const NekDouble> &primCoeffs,
377 DNekMatSharedPtr &inoutmat)
378{
380 "Robin boundary conditions are only implemented for "
381 "boundary-interior expanisons");
382 ASSERTL1(inoutmat->GetRows() == inoutmat->GetColumns(),
383 "Assuming that input matrix was square");
384
385 // Get local Element mapping for vertex point
386 int map = GetVertexMap(vert);
387
388 // Now need to identify a map which takes the local edge
389 // mass matrix to the matrix stored in inoutmat;
390 // This can currently be deduced from the size of the matrix
391 // - if inoutmat.m_rows() == v_NCoeffs() it is a full
392 // matrix system
393 // - if inoutmat.m_rows() == v_NumBndCoeffs() it is a
394 // boundary CG system
395
396 int rows = inoutmat->GetRows();
397
398 if (rows == GetNcoeffs())
399 {
400 // no need to do anything
401 }
402 else if (rows == NumBndryCoeffs()) // same as NumDGBndryCoeffs()
403 {
404 int i;
406 GetBoundaryMap(bmap);
407
408 for (i = 0; i < 2; ++i)
409 {
410 if (map == bmap[i])
411 {
412 map = i;
413 break;
414 }
415 }
416 ASSERTL1(i != 2, "Did not find number in map");
417 }
418
419 // assumes end points have unit magnitude
420 (*inoutmat)(map, map) += primCoeffs[0];
421}
422
423/**
424 * Given an edge and vector of element coefficients:
425 * - maps those elemental coefficients corresponding to the trace into
426 * an vector.
427 * - update the element coefficients
428 * - multiplies the edge vector by the edge mass matrix
429 * - maps the edge coefficients back onto the elemental coefficients
430 */
432 const int vert, const Array<OneD, const NekDouble> &primCoeffs,
433 const Array<OneD, NekDouble> &incoeffs, Array<OneD, NekDouble> &coeffs)
434{
436 "Not set up for non boundary-interior expansions");
437
438 int map = GetVertexMap(vert);
439 coeffs[map] += primCoeffs[0] * incoeffs[map];
440}
441
443 const Array<OneD, Array<OneD, NekDouble>> &vec)
444{
446 GetLeftAdjacentElementExp()->GetTraceNormal(
448
449 int nq = m_base[0]->GetNumPoints();
451 Vmath::Vmul(nq, &vec[0][0], 1, &normals[0][0], 1, &Fn[0], 1);
452 Vmath::Vvtvp(nq, &vec[1][0], 1, &normals[1][0], 1, &Fn[0], 1, &Fn[0], 1);
453
454 return Integral(Fn);
455}
456
457/** @brief: This method gets all of the factors which are
458 required as part of the Gradient Jump Penalty
459 stabilisation and involves the product of the normal and
460 geometric factors along the element trace.
461*/
464 Array<OneD, Array<OneD, NekDouble>> &d0factors,
465 Array<OneD, Array<OneD, NekDouble>> &d1factors)
466{
467 boost::ignore_unused(d0factors, d1factors); // for 2D&3D shapes
468 int nquad = GetNumPoints(0);
470 m_metricinfo->GetDerivFactors(GetPointsKeys());
471
472 if (factors.size() <= 2)
473 {
477 }
478
479 // Outwards normal
484
485 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
486 {
487 factors[0][0] = gmat[0][nquad - 1] * normal_0[0][0];
488 factors[1][0] = gmat[0][0] * normal_1[0][0];
489
490 for (int n = 1; n < normal_0.size(); ++n)
491 {
492 factors[0][0] += gmat[n][0] * normal_0[n][0];
493 factors[1][0] += gmat[n][nquad - 1] * normal_1[n][0];
494 }
495 }
496 else
497 {
498 factors[0][0] = gmat[0][0] * normal_0[0][0];
499 factors[1][0] = gmat[0][0] * normal_1[0][0];
500
501 for (int n = 1; n < normal_0.size(); ++n)
502 {
503 factors[0][0] += gmat[n][0] * normal_0[n][0];
504 factors[1][0] += gmat[n][0] * normal_1[n][0];
505 }
506 }
507}
508
510 Array<OneD, int> &idmap, const int nq0,
511 const int nq1)
512{
513 boost::ignore_unused(orient, nq0, nq1);
514
515 if (idmap.size() != 1)
516 {
517 idmap = Array<OneD, int>(1);
518 }
519
520 idmap[0] = 0;
521}
522
524{
525 boost::ignore_unused(traceid);
526 h = GetGeom()->GetVertex(1)->dist(*GetGeom()->GetVertex(0));
527 p = m_ncoeffs - 1;
528}
529
530} // namespace LocalRegions
531} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
Represents a basis of a given type.
Definition: Basis.h:200
virtual void v_AddRobinTraceContribution(const int vert, const Array< OneD, const NekDouble > &primCoeffs, const Array< OneD, NekDouble > &incoeffs, Array< OneD, NekDouble > &coeffs) override
virtual void v_ReOrientTracePhysMap(const StdRegions::Orientation orient, Array< OneD, int > &idmap, const int nq0, const int nq1) override
void AddHDGHelmholtzTraceTerms(const NekDouble tau, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_AddRobinMassMatrix(const int vert, const Array< OneD, const NekDouble > &primCoeffs, DNekMatSharedPtr &inoutmat) override
void AddNormTraceInt(const int dir, Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual NekDouble v_VectorFlux(const Array< OneD, Array< OneD, NekDouble > > &vec) override
virtual void v_TraceNormLen(const int traceid, NekDouble &h, NekDouble &p) override
virtual void v_NormalTraceDerivFactors(Array< OneD, Array< OneD, NekDouble > > &factors, Array< OneD, Array< OneD, NekDouble > > &d0factors, Array< OneD, Array< OneD, NekDouble > > &d1factors) override
: This method gets all of the factors which are required as part of the Gradient Jump Penalty stabili...
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition: Expansion1D.cpp:47
SpatialDomains::GeometrySharedPtr GetGeom() const
Definition: Expansion.cpp:171
ExpansionSharedPtr GetLeftAdjacentElementExp() const
Definition: Expansion.h:443
int GetLeftAdjacentElementTrace() const
Definition: Expansion.h:456
SpatialDomains::GeomFactorsSharedPtr m_metricinfo
Definition: Expansion.h:276
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition: Expansion.cpp:88
const NormalVector & GetTraceNormal(const int id)
Definition: Expansion.cpp:255
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void GetBoundaryMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:675
const LibUtilities::BasisSharedPtr & GetBasis(int dir) const
This function gets the shared point to basis in the dir direction.
Definition: StdExpansion.h:118
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
Definition: StdExpansion.h:130
const LibUtilities::PointsKeyVector GetPointsKeys() const
int GetVertexMap(const int localVertexId, bool useCoeffPacking=false)
Definition: StdExpansion.h:685
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Definition: StdExpansion.h:224
Array< OneD, LibUtilities::BasisSharedPtr > m_base
NekDouble Integral(const Array< OneD, const NekDouble > &inarray)
This function integrates the specified function over the domain.
Definition: StdExpansion.h:479
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:87
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:128
@ eDeformed
Geometry is curved or has non-constant factors.
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:408
StdRegions::ConstFactorMap factors
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
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.
Definition: Vmath.cpp:207
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:513
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:569
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:487
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191