Nektar++
Loading...
Searching...
No Matches
StdNodalTriExp.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: StdNodalTriExp.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: Nodal triangle routines built upon StdExpansion2D
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <LibUtilities/Foundations/ManagerAccess.h> // for PointsManager, etc
37
38using namespace std;
39
40namespace Nektar::StdRegions
41{
43 const LibUtilities::BasisKey &Bb,
45 : StdExpansion(LibUtilities::StdTriData::getNumberOfCoefficients(
46 Ba.GetNumModes(), Bb.GetNumModes()),
47 2, Ba, Bb),
48 StdExpansion2D(LibUtilities::StdTriData::getNumberOfCoefficients(
49 Ba.GetNumModes(), Bb.GetNumModes()),
50 Ba, Bb),
51 StdTriExp(Ba, Bb), m_nodalPointsKey(Ba.GetNumModes(), Ntype)
52{
53 ASSERTL0(m_base[0]->GetNumModes() == m_base[1]->GetNumModes(),
54 "Nodal basis initiated with different orders in the a "
55 "and b directions");
56
57 // cache integration weights for future use
58 m_weights.push_back(m_base[0]->GetW());
59
60 StdFacKey w1key(eWeights1, Bb);
61 // get weights[1] from manager where points are rescaled
62 m_weights.push_back(GetStdFac(w1key));
63}
64
66{
67 return true;
68}
69
70//-------------------------------
71// Nodal basis specific routines
72//-------------------------------
73
86
87// Operate with transpose of NodalToModal transformation
101
103 Array<OneD, NekDouble> &outarray)
104{
108 DNekMatSharedPtr vdm = GetStdMatrix(Nkey);
109
110 // Multiply out matrix
111 NekVector<NekDouble> modal(m_ncoeffs, inarray, eWrapper);
112 NekVector<NekDouble> nodal(m_ncoeffs, outarray, eWrapper);
113 nodal = (*vdm) * modal;
114}
115
121
123{
124 int i, j;
128
130 GetNodalPoints(r, s);
131
132 // Store the values of m_phys in a temporary array
133 int nqtot = GetTotPoints();
134 Array<OneD, NekDouble> phys(nqtot);
135
136 for (i = 0; i < m_ncoeffs; ++i)
137 {
138 // fill physical space with mode i
139 StdTriExp::v_FillMode(i, phys);
140
141 // interpolate mode i to the Nodal points 'j' and
142 // store in outarray
143 for (j = 0; j < m_ncoeffs; ++j)
144 {
145 c[0] = r[j];
146 c[1] = s[j];
147 (*Mat)(j, i) = StdExpansion2D::v_PhysEvaluate(c, phys);
148 }
149 }
150 return Mat;
151}
152
153//---------------------------------------
154// Transforms
155//---------------------------------------
156
158 Array<OneD, NekDouble> &outarray)
159{
161 v_NodalToModal(inarray, tmp);
162 StdTriExp::v_BwdTrans(tmp, outarray);
163}
164
165//---------------------------------------
166// Inner product functions
167//---------------------------------------
168
170 const Array<OneD, const NekDouble> &inarray,
171 Array<OneD, NekDouble> &outarray)
172{
173 StdTriExp::v_IProductWRTBase(inarray, outarray);
174 NodalToModalTranspose(outarray, outarray);
175}
176
178 const int dir, const Array<OneD, const NekDouble> &inarray,
179 Array<OneD, NekDouble> &outarray)
180{
181 StdTriExp::v_IProductWRTDerivBase(dir, inarray, outarray);
182 NodalToModalTranspose(outarray, outarray);
183}
184
185//---------------------------------------
186// Evaluation functions
187//---------------------------------------
188
189void StdNodalTriExp::v_FillMode(const int mode,
190 Array<OneD, NekDouble> &outarray)
191{
192 ASSERTL2(mode >= m_ncoeffs,
193 "calling argument mode is larger than total expansion order");
194
195 Vmath::Zero(m_ncoeffs, outarray, 1);
196 outarray[mode] = 1.0;
197 v_BwdTrans(outarray, outarray);
198}
199
200//---------------------------
201// Helper functions
202//---------------------------
203
208
210{
211 return 3 + (GetBasisNumModes(0) - 2) + 2 * (GetBasisNumModes(1) - 2);
212}
213
215 const int i, [[maybe_unused]] const int j,
216 [[maybe_unused]] bool UseGLL) const
217{
218 ASSERTL2(i >= 0 && i <= 2, "edge id is out of range");
219
220 // Get basiskey (0 or 1) according to edge id i
221 int dir = (i != 0);
222
223 switch (m_base[dir]->GetBasisType())
224 {
227 {
228 switch (m_base[dir]->GetPointsType())
229 {
231 {
233 m_base[dir]
234 ->GetBasisKey()
235 .GetPointsKey()
236 .GetNumPoints(),
239 m_base[dir]->GetNumModes(),
240 pkey);
241 }
242 break;
243 default:
244 {
246 "Unexpected points distribution " +
248 [m_base[dir]->GetPointsType()] +
249 " in StdNodalTriExp::v_GetTraceBasisKey");
250 }
251 }
252 }
253 break;
256 {
257 switch (m_base[dir]->GetPointsType())
258 {
259 case LibUtilities::eGaussRadauMAlpha1Beta0:
260 {
262 m_base[dir]
263 ->GetBasisKey()
264 .GetPointsKey()
265 .GetNumPoints() +
266 1,
269 m_base[dir]->GetNumModes(),
270 pkey);
271 }
272 break;
273 default:
274 {
276 "Unexpected points distribution " +
278 [m_base[dir]->GetPointsType()] +
279 " in StdNodalTriExp::v_GetTraceBasisKey");
280 }
281 }
282 }
283 break;
284 default:
285 {
287 "Information not available to set edge key");
288 }
289 }
291}
292
293//--------------------------
294// Mappings
295//--------------------------
296
297int StdNodalTriExp::v_GetVertexMap(const int localVertexId,
298 [[maybe_unused]] bool useCoeffPacking)
299{
300 ASSERTL0(localVertexId >= 0 && localVertexId <= 2,
301 "Local Vertex ID must be between 0 and 2");
302 return localVertexId;
303}
304
307 Array<OneD, int> &signarray,
308 Orientation edgeOrient, int P,
309 [[maybe_unused]] int Q)
310{
311 ASSERTL0(eid >= 0 && eid <= 2, "Local Edge ID must be between 0 and 2");
312
313 const int nEdgeCoeffs = GetTraceNcoeffs(eid);
314
315 ASSERTL0(P == -1 || P == nEdgeCoeffs,
316 "Nodal triangle not set up to deal with variable "
317 "polynomial order.");
318
319 if (maparray.size() != nEdgeCoeffs)
320 {
321 maparray = Array<OneD, unsigned int>(nEdgeCoeffs);
322 }
323
324 if (signarray.size() != nEdgeCoeffs)
325 {
326 signarray = Array<OneD, int>(nEdgeCoeffs, 1);
327 }
328 else
329 {
330 fill(signarray.data(), signarray.data() + nEdgeCoeffs, 1);
331 }
332
333 Orientation orient = edgeOrient;
334 if (eid == 2)
335 {
336 orient = orient == eForwards ? eBackwards : eForwards;
337 }
338
339 maparray[0] = eid;
340 maparray[nEdgeCoeffs - 1] = eid == 2 ? 0 : eid + 1;
341 for (int i = 2; i < nEdgeCoeffs; i++)
342 {
343 maparray[i - 1] = eid * (nEdgeCoeffs - 2) + 1 + i;
344 }
345
346 if (orient == eBackwards)
347 {
348 reverse(maparray.data(), maparray.data() + nEdgeCoeffs);
349 }
350}
351
353 const int eid, Array<OneD, unsigned int> &maparray,
354 Array<OneD, int> &signarray, const Orientation edgeOrient)
355{
356 ASSERTL0(eid >= 0 && eid <= 2, "Local Edge ID must be between 0 and 2");
357
358 const int nEdgeIntCoeffs = GetTraceNcoeffs(eid) - 2;
359
360 if (maparray.size() != nEdgeIntCoeffs)
361 {
362 maparray = Array<OneD, unsigned int>(nEdgeIntCoeffs);
363 }
364
365 if (signarray.size() != nEdgeIntCoeffs)
366 {
367 signarray = Array<OneD, int>(nEdgeIntCoeffs, 1);
368 }
369 else
370 {
371 fill(signarray.data(), signarray.data() + nEdgeIntCoeffs, 1);
372 }
373
374 Orientation orient = edgeOrient;
375 if (eid == 2)
376 {
377 orient = orient == eForwards ? eBackwards : eForwards;
378 }
379
380 for (int i = 0; i < nEdgeIntCoeffs; i++)
381 {
382 maparray[i] = eid * nEdgeIntCoeffs + 3 + i;
383 }
384
385 if (orient == eBackwards)
386 {
387 reverse(maparray.data(), maparray.data() + nEdgeIntCoeffs);
388 }
389}
390
392{
393 unsigned int i;
394 if (outarray.size() != GetNcoeffs() - NumBndryCoeffs())
395 {
397 }
398
399 for (i = NumBndryCoeffs(); i < GetNcoeffs(); i++)
400 {
401 outarray[i - NumBndryCoeffs()] = i;
402 }
403}
404
406{
407 unsigned int i;
408 if (outarray.size() != NumBndryCoeffs())
409 {
411 }
412
413 for (i = 0; i < NumBndryCoeffs(); i++)
414 {
415 outarray[i] = i;
416 }
417}
418
419//---------------------------------------
420// Wrapper functions
421//---------------------------------------
422
424{
426
427 switch (mkey.GetMatrixType())
428 {
429 case eNBasisTrans:
430 Mat = GenNBasisTransMatrix();
431 break;
432 default:
434 break;
435 }
436
437 return Mat;
438}
439
444
445//---------------------------------------
446// Operator evaluation functions
447//---------------------------------------
448
450 Array<OneD, NekDouble> &outarray,
451 const StdMatrixKey &mkey)
452{
453 StdExpansion::MassMatrixOp_MatFree(inarray, outarray, mkey);
454}
455
457 const Array<OneD, const NekDouble> &inarray,
458 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
459{
461 mkey);
462}
463
465 const int k1, const int k2, const Array<OneD, const NekDouble> &inarray,
466 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
467
468{
469 StdExpansion::LaplacianMatrixOp_MatFree(k1, k2, inarray, outarray, mkey);
470}
471
473 const int i, const Array<OneD, const NekDouble> &inarray,
474 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
475{
476 StdExpansion::WeakDerivMatrixOp_MatFree(i, inarray, outarray, mkey);
477}
478
480 const Array<OneD, const NekDouble> &inarray,
481 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
482{
484 mkey);
485}
486
487//---------------------------------------
488// Private helper functions
489//---------------------------------------
490
491} // namespace Nektar::StdRegions
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
PointsType GetPointsType() const
Definition Points.h:90
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
The base class for all shapes.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
void WeakDerivMatrixOp_MatFree(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
void LaplacianMatrixOp_MatFree_GenericImpl(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
virtual NekDouble v_PhysEvaluate(const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &physvals)
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
void LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Array< OneD, const NekDouble > GetStdFac(const StdFacKey &mkey)
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)=0
Calculates the inner product of a given function f with the different modes of the expansion.
void HelmholtzMatrixOp_MatFree_GenericImpl(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
int GetBasisNumModes(const int dir) const
This function returns the number of expansion modes in the dir direction.
Array< OneD, LibUtilities::BasisSharedPtr > m_base
std::vector< Array< OneD, const NekDouble > > m_weights
void MassMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
MatrixType GetMatrixType() const
void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_NodalToModal(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
void NodalToModalTranspose(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
void GetNodalPoints(Array< OneD, const NekDouble > &x, Array< OneD, const NekDouble > &y)
void ModalToNodal(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_GetTraceInteriorToElementMap(const int eid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation edgeOrient=eForwards) override
void v_GetTraceToElementMap(const int eid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation edgeOrient=eForwards, int P=-1, int Q=-1) override
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Calculate the inner product of inarray with respect to the basis B=base0*base1 and put into outarray.
int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
LibUtilities::ShapeType v_DetShapeType() const final
LibUtilities::PointsKey m_nodalPointsKey
const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int j, bool UseGLL=false) const override
void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_WeakDerivMatrixOp(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Backward tranform for triangular elements.
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
const std::string kPointsTypeStr[]
PointsManagerT & PointsManager(void)
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eModified_B
Principle Modified Functions .
Definition BasisType.h:49
@ eOrtho_A
Principle Orthogonal Functions .
Definition BasisType.h:42
@ eGLL_Lagrange
Lagrange for SEM basis .
Definition BasisType.h:56
@ eOrtho_B
Principle Orthogonal Functions .
Definition BasisType.h:44
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
static VarFactorsMap NullVarFactorsMap
static ConstFactorMap NullConstFactorMap
static VarCoeffMap NullVarCoeffMap
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
std::shared_ptr< DNekMat > DNekMatSharedPtr
void Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
STL namespace.