Nektar++
Loading...
Searching...
No Matches
XmapFactory.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: XmapFactory.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: Simple factory pattern for creation of geometry xmap objects.
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#ifndef NEKTAR_SPATIALDOMAINS_XMAPFACTORY_HPP
36#define NEKTAR_SPATIALDOMAINS_XMAPFACTORY_HPP
37
38#include <functional>
39#include <memory>
40#include <type_traits>
41#include <unordered_map>
42
44{
45
46/**
47 * @brief A simple factory for Xmap objects that is based on the element type,
48 * the basis and quadrature selection.
49 */
50template <class StdExp, int dim> class XmapFactory
51{
52 /// Key for the Xmap: an array of dimension dim which contains the basis
53 /// keys for each coordinate direction.
54 using key_t = std::array<LibUtilities::BasisKey, dim>;
55
56 /// Hash for key_t
57 struct KeyHash
58 {
59 /**
60 * We base key_t on the idea that number of points and modes are almost
61 * certainly < 2^8. Therefore total hash size is at most given by dim *
62 * 4 * 2 <= 48 bits, which comfortably fits in a 64-bit size_t.
63 */
64 size_t operator()(key_t const &key) const
65 {
66
67 size_t hash = 0;
68 for (int d = 0; d < dim; ++d)
69 {
70 // This loop should be unrolled by the compiler.
71 hash = (hash << 8) | (((key[d].GetNumPoints() & 0xFF) << 8) |
72 (key[d].GetNumPoints() & 0xFF));
73 }
74
75 return hash;
76 }
77 };
78
79 struct KeyEqual
80 {
81 bool operator()(key_t const &a, key_t const &b) const
82 {
83 bool equal = true;
84 for (int d = 0; d < dim; ++d)
85 {
86 equal = equal && (a[d].GetNumPoints() == b[d].GetNumPoints() &&
87 a[d].GetNumModes() == b[d].GetNumModes());
88 }
89 return equal;
90 }
91 };
92
93 template <int d, typename std::enable_if<d == 1, int>::type = 0>
94 std::shared_ptr<StdExp> CreateStdExp(const key_t &args)
95 {
96 return std::make_shared<StdExp>(args[0]);
97 }
98
99 template <int d, typename std::enable_if<d == 2, int>::type = 0>
100 std::shared_ptr<StdExp> CreateStdExp(const key_t &args)
101 {
102 return std::make_shared<StdExp>(args[0], args[1]);
103 }
104
105 template <int d, typename std::enable_if<d == 3, int>::type = 0>
106 std::shared_ptr<StdExp> CreateStdExp(const key_t &args)
107 {
108 return std::make_shared<StdExp>(args[0], args[1], args[2]);
109 }
110
111public:
112 XmapFactory() = default;
113
114 /**
115 * @brief Returns (and creates, if necessary) a standard expansion
116 * corresponding to @tparam StdExp and the supplied @p basis.
117 */
119 {
120 auto it = m_xmaps.find(basis);
121
122 if (it != m_xmaps.end())
123 {
124 return it->second;
125 }
126
127 std::shared_ptr<StdExp> xmap = CreateStdExp<dim>(basis);
128 m_xmaps[basis] = xmap;
129
130 return xmap;
131 }
132
133private:
134 /// Storage for created xmap objects.
135 std::unordered_map<key_t, StdRegions::StdExpansionSharedPtr, KeyHash,
136 KeyEqual>
138};
139
140} // namespace Nektar::SpatialDomains
141
142#endif
A simple factory for Xmap objects that is based on the element type, the basis and quadrature selecti...
std::shared_ptr< StdExp > CreateStdExp(const key_t &args)
std::array< LibUtilities::BasisKey, dim > key_t
Key for the Xmap: an array of dimension dim which contains the basis keys for each coordinate directi...
StdRegions::StdExpansionSharedPtr CreateInstance(const key_t &basis)
Returns (and creates, if necessary) a standard expansion corresponding to.
std::unordered_map< key_t, StdRegions::StdExpansionSharedPtr, KeyHash, KeyEqual > m_xmaps
Storage for created xmap objects.
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
bool operator()(key_t const &a, key_t const &b) const
size_t operator()(key_t const &key) const