Nektar++
Loading...
Searching...
No Matches
StdRegions.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: StdRegions.hpp
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: Definition of enum lists and constants
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#ifndef STDREGIONS_HPP
36#define STDREGIONS_HPP
37
41#include <array>
42#include <map>
43#include <utility>
44
45namespace Nektar::StdRegions
46{
70
71const char *const ElementTypeMap[] = {
72 //"StdPointExp",
73 "StdSegExp", "SegExp", "StdQuadExp", "StdTriExp", "StdNodalTriExp",
74 "QuadExp", "TriExp", "NodalTriExp", "StdHexExp", "StdPrismExp",
75 "StdPyrExp", "StdTetExp", "StdNodalTetExp", "HexExp", "PrismExp",
76 "PyrExp", "TetExp", "NodalTetExp",
77};
78
79/** @todo we need to tidy up matrix construction approach
80 * probably using a factory type approach
81 */
147
148const char *const MatrixTypeMap[] = {
149 "NoMatrixType",
150 "Mass",
151 "Mass with Diagonal GJP",
152 "InvMass",
153 "Laplacian",
154 "Laplacian00",
155 "Laplacian01",
156 "Laplacian02",
157 "Laplacian10",
158 "Laplacian11",
159 "Laplacian12",
160 "Laplacian20",
161 "Laplacian21",
162 "Laplacian22",
163 "InvLaplacianWithUnityMean",
164 "WeakDeriv0",
165 "WeakDeriv1",
166 "WeakDeriv2",
167 "WeakDirectionalDeriv",
168 "MassLevelCurvature",
169 "LinearAdvection",
170 "LinearAdvectionReaction",
171 "LinearAdvectionDiffusionReaction",
172 "LinearAdvectionDiffusionReaction with Diagonal GJP",
173 "NBasisTrans",
174 "InvNBasisTrans",
175 "BwdTrans",
176 "InvBwdTrans",
177 "BwdMat",
178 "IProductWRTBase",
179 "InvIProductWRTBase",
180 "IProductWRTDerivBase0",
181 "IProductWRTDerivBase1",
182 "IProductWRTDerivBase2",
183 "DerivBase0",
184 "DerivBase1",
185 "DerivBase2",
186 "Helmholtz",
187 "Helmholtz with Diagonal GJP",
188 "HybridDGHelmholz",
189 "InvHybridDGHelmholtz",
190 "HybridDGHelmBndLam",
191 "HybridDGLamToQ0",
192 "HybridDGLamToQ1",
193 "HybridDGLamToQ2",
194 "HybridDGLamToU",
195 "FwdTrans",
196 "PreconR",
197 "PreconRMass",
198 "PreconLinearSpace",
199 "PreconLinearSpaceMass",
200 "InterpGauss",
201 "GaussDG",
202 "PhysInterpToEquiSpaced",
203 "PhysInterpToGLL",
204 "CoeffsToEquiSpaced",
205 "EquiSpacedToCoeffs",
206 "CoeffsToGLL",
207 "GLLToCoeffs",
208 "EquiSpacedToPhys",
209 "NormDerivOnTrace"};
210
249
250const char *const VarCoeffTypeMap[] = {
251 "VarCoeffMass", "VarCoeffLaplacian", "VarCoeffWeakDeriv",
252 "VarCoeffD00", "VarCoeffD01", "VarCoeffD02",
253 "VarCoeffD10", "VarCoeffD11", "VarCoeffD12",
254 "VarCoeffD20", "VarCoeffD21", "VarCoeffD22",
255 "VarCoeffVelX", "VarCoeffVelY", "VarCoeffVelZ",
256 "VarCoeffMF1x", "VarCoeffMF1y", "VarCoeffMF1z",
257 "VarCoeffMF1Div", "VarCoeffMF1Mag", "VarCoeffMF2x",
258 "VarCoeffMF2y", "VarCoeffMF2z", "VarCoeffMF2Div",
259 "VarCoeffMF2Mag", "VarCoeffMF3x", "VarCoeffMF3y",
260 "VarCoeffMF3z", "VarCoeffMF3Div", "VarCoeffMF3Mag",
261 "VarCoeffMF", "VarCoeffMFDiv", "VarCoeffGmat",
262 "VarCoeffGJPNormVel", "VarCoeffTraceWeight"};
263
264// Structure to map matrix type to relevant variable coefficients
265// Note the mappings require manual definition and are used via
266// StdMatrixKey::HasVarCoeffForMatrixType(MatrixType)
268{
270 std::size_t size;
271
272 // Optional helpers to allow range-for
273 constexpr const VarCoeffType *begin() const
274 {
275 return data;
276 }
277 constexpr const VarCoeffType *end() const
278 {
279 return data + size;
280 }
281};
282
283// The mass matrix has an elemental variable coefficient multiplying every entry
284constexpr std::array<VarCoeffType, 1> massVarCoeffs{eVarCoeffMass};
285
286// The laplacian matrix has an elemental variable coefficient "eLaplacian"
287// and coefficients for each compoennt of the diffusion tensor in 1D, 2D, and 3D
291
292// The advection matrix has a variable coefficient for each advection velocity
293constexpr std::array<VarCoeffType, 3> advectionVarCoeffs{
295
296constexpr std::array<std::pair<MatrixType, VarCoeffList>, 3>
304
305/**
306 * @brief Representation of a variable coefficient.
307 *
308 * Variable coefficients are entries stored inside a #VarCoeffMap which
309 * are defined at each quadrature/solution point within an element. This
310 * class wraps that concept, storing the values in #m_coeffs, but also
311 * stores alongside this a hash of the data in #m_hash. This is then
312 * used within MultiRegions::GlobalMatrixKey to efficiently distinguish
313 * between matrix keys that have variable coefficients defined, but
314 * whose entries are different.
315 *
316 * For that reason the entries here are deliberately protected by const
317 * references; i.e. the entries inside of #m_coeffs should not be
318 * modified in-place, but a new array copied in so that the hash can be
319 * recalculated.
320 */
322{
323 /// Default constructor.
324 VarCoeffEntry() = default;
325
326 /**
327 * @brief Copy an array of values into this entry.
328 *
329 * Upon copy into #m_coeffs, compute the hash of this entry using
330 * #ComputeHash.
331 *
332 * @param input Variable coefficients to be defined at each
333 * solution point.
334 */
336 {
337 ComputeHash();
338 }
339
340 /**
341 * @brief Access an entry @p idx within #m_coeffs.
342 *
343 * @param idx Index of the entry to access.
344 */
345 const NekDouble &operator[](std::size_t idx) const
346 {
347 return m_coeffs[idx];
348 }
349
350 /**
351 * @brief Assignment operator given an array @p rhs.
352 *
353 * Upon copy into #m_coeffs, compute the hash of this entry using
354 * #ComputeHash.
355 *
356 * @param rhs Variable coefficients to be defined at each
357 * solution point.
358 */
360 {
361 m_coeffs = rhs;
362 ComputeHash();
363 }
364
365 /**
366 * @brief Returns a const reference to the coefficients.
367 */
369 {
370 return m_coeffs;
371 }
372
373 /**
374 * @brief Returns the hash of this entry.
375 */
376 std::size_t GetHash() const
377 {
378 return m_hash;
379 }
380
381 /*
382 * @brief Create sub-VarCoeffEntry without copying data.
383 *
384 * @param offset Offset from the first entry of the m_coeff array.
385 * @param size Length of the new sub-set of the original m_coeff array.
386 *
387 * The restrict function returns a VarCoeffEntry that
388 * holds a m_coeff array with a subset of the original
389 * VarCoeffEntry.
390 */
391 VarCoeffEntry restrict(size_t offset, size_t size) const
392 {
393 VarCoeffEntry tmp;
394
395 // This avoids copy of Array
396 tmp.m_coeffs = Array<OneD, NekDouble>(size, m_coeffs + offset);
397
398 // The logic is that since we are using a 'window' into the original
399 // data we should preserve the original hash of that data.
400 // Giving just m_hash will result in the same hash for all collections.
401 // This is sufficient, because if we only need to update once every time
402 // step. For possible future changes, we could combine it with the
403 // offset and size to make it different enough to the original hash, if
404 // necessary.
405 tmp.m_hash = m_hash;
406
407 return tmp;
408 }
409
410protected:
411 /**
412 * @brief Computes the hash of this entry using #hash_range.
413 */
415 {
416 if (m_coeffs.size() == 0)
417 {
418 m_hash = 0;
419 return;
420 }
421
422 m_hash = hash_range(m_coeffs.begin(), m_coeffs.end());
423 }
424
425 /// Hash of the entries inside #m_coeffs.
426 std::size_t m_hash = 0;
427
428 /// Storage for the variable coefficient entries.
430};
431
432typedef std::map<StdRegions::VarCoeffType, VarCoeffEntry> VarCoeffMap;
434
435inline VarCoeffMap RestrictCoeffMap(const VarCoeffMap &m, size_t offset,
436 size_t cnt)
437{
438 VarCoeffMap ret;
439
440 for (auto &x : m)
441 {
442 ret[x.first] = x.second.restrict(offset, cnt);
443 }
444
445 return ret;
446}
447
470
471const char *const ConstFactorTypeMap[] = {"FactorLambda",
472 "FactorCoeffD00",
473 "FactorCoeffD11",
474 "FactorCoeffD22",
475 "FactorCoeffD01",
476 "FactorCoeffD02",
477 "FactorCoeffD12",
478 "FactorTau",
479 "FactorTime",
480 "FactorSVVCutoffRatio",
481 "FactorSVVDiffCoeff",
482 "FactorSVVPowerKerDiffCoeff",
483 "FactorSVVDGKerDiffCoeff",
484 "FactorGaussVertex",
485 "FactorGaussEdge",
486 "FactorGJP",
487 "FactorGJPTraceWeight",
488 "FactorConstant"};
489typedef std::map<ConstFactorType, NekDouble> ConstFactorMap;
491
492// FactorMap
495
496// Variable FactorMap
497typedef std::map<StdRegions::ConstFactorType, Array<OneD, NekDouble>>
500
502{
508 eDir1FwdDir1_Dir2FwdDir2, // These flags are interpreted as
509 eDir1FwdDir1_Dir2BwdDir2, // taking the first direction to the
510 eDir1BwdDir1_Dir2FwdDir2, // second direction. So Dir1FwdDir2 takes
511 eDir1BwdDir1_Dir2BwdDir2, // direction 1 in the original face and makes it
512 eDir1FwdDir2_Dir2FwdDir1, // backwards to direction 2 in the mapped face.
513 eDir1FwdDir2_Dir2BwdDir1, // Note be careful not to flip this
514 eDir1BwdDir2_Dir2FwdDir1, // convention especially when using
515 eDir1BwdDir2_Dir2BwdDir1, // transposed mappings.
518
519const char *const OrientationMap[] = {"NoOrientation",
520 "Fwd",
521 "Bwd",
522 "Forwards",
523 "Backwards",
524 "Dir1FwdDir1_Dir2FwdDir2",
525 "Dir1FwdDir1_Dir2BwdDir2",
526 "Dir1BwdDir1_Dir2FwdDir2",
527 "Dir1BwdDir1_Dir2BwdDir2",
528 "Dir1FwdDir2_Dir2FwdDir1",
529 "Dir1FwdDir2_Dir2BwdDir1",
530 "Dir1BwdDir2_Dir2FwdDir1",
531 "Dir1BwdDir2_Dir2BwdDir1"};
532
533// Defines a "fast find"
534// Assumes that first/last define the beginning/ending of
535// a continuous range of classes, and that start is
536// an iterator between first and last
537
538template <class InputIterator, class EqualityComparable>
539InputIterator find(InputIterator first, InputIterator last,
540 InputIterator startingpoint, const EqualityComparable &value)
541{
542 InputIterator val;
543
544 if (startingpoint == first)
545 {
546 val = find(first, last, value);
547 }
548 else
549 {
550 val = find(startingpoint, last, value);
551 if (val == last)
552 {
553 val = find(first, startingpoint, value);
554 if (val == startingpoint)
555 {
556 val = last;
557 }
558 }
559 }
560 return val;
561}
562
563// Optimized Kernel Entries
565const int kSVVDGFiltermodesmax = 11;
566// Optimized Kernel Entries for p = 2 - 10
567const NekDouble kSVVDGFilter[9][11] = {
568 {0, 0.36212, 1, 0, 0, 0, 0, 0, 0, 0, 0},
569 {0, 0.70546, 0.078836, 1, 0, 0, 0, 0, 0, 0, 0},
570 {0, 0, 0.49411, 0.072394, 1, 0, 0, 0, 0, 0, 0},
571 {0, 0, 0.000073566, 0.40506, 0.094122, 1, 0, 0, 0, 0, 0},
572 {0, 0, 0, 0.0001422, 0.36863, 0.11815, 1, 0, 0, 0, 0},
573 {0, 0, 0, 0, 0.00019497, 0.41397, 0.16927, 1, 0, 0, 0},
574 {0, 0, 0, 0, 0, 0.0009762, 0.12747, 0.13763, 1, 0, 0},
575 {0, 0, 0, 0, 0, 0, 0.0023592, 0.23683, 0.17196, 1, 0},
576 {0, 0, 0, 0, 0, 0, 0, 0.0026055, 0.28682, 0.22473, 1}};
577
578} // namespace Nektar::StdRegions
579
580#endif // STDREGIONS_H
constexpr std::array< VarCoeffType, 1 > massVarCoeffs
constexpr std::array< std::pair< MatrixType, VarCoeffList >, 3 > MatrixTypeToVarCoeffsMap
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
const int kSVVDGFiltermodesmin
std::map< StdRegions::ConstFactorType, Array< OneD, NekDouble > > VarFactorsMap
static FactorMap NullFactorMap
static VarFactorsMap NullVarFactorsMap
const char *const VarCoeffTypeMap[]
const int kSVVDGFiltermodesmax
constexpr std::array< VarCoeffType, 10 > laplacianVarCoeffs
const NekDouble kSVVDGFilter[9][11]
const char *const ConstFactorTypeMap[]
const char *const ElementTypeMap[]
const char *const MatrixTypeMap[]
VarCoeffMap RestrictCoeffMap(const VarCoeffMap &m, size_t offset, size_t cnt)
std::map< ConstFactorType, NekDouble > ConstFactorMap
constexpr std::array< VarCoeffType, 3 > advectionVarCoeffs
static ConstFactorMap NullConstFactorMap
const char *const OrientationMap[]
ConstFactorMap FactorMap
static VarCoeffMap NullVarCoeffMap
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
std::size_t hash_range(Iter first, Iter last)
Definition HashUtils.hpp:64
Representation of a variable coefficient.
VarCoeffEntry restrict(size_t offset, size_t size) const
Array< OneD, NekDouble > m_coeffs
Storage for the variable coefficient entries.
std::size_t m_hash
Hash of the entries inside m_coeffs.
std::size_t GetHash() const
Returns the hash of this entry.
VarCoeffEntry()=default
Default constructor.
void ComputeHash()
Computes the hash of this entry using hash_range.
void operator=(const Array< OneD, const NekDouble > &rhs)
Assignment operator given an array rhs.
VarCoeffEntry(const Array< OneD, const NekDouble > &input)
Copy an array of values into this entry.
const Array< OneD, const NekDouble > & GetValue() const
Returns a const reference to the coefficients.
const NekDouble & operator[](std::size_t idx) const
Access an entry idx within m_coeffs.
constexpr const VarCoeffType * begin() const
constexpr const VarCoeffType * end() const