Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_IntrepidBasisFactory.cpp
Go to the documentation of this file.
2
3#include "Intrepid2_HVOL_C0_FEM.hpp"
4#include "Intrepid2_HVOL_TRI_Cn_FEM.hpp"
5#include "Intrepid2_HVOL_QUAD_Cn_FEM.hpp"
6#include "Intrepid2_HVOL_HEX_Cn_FEM.hpp"
7#include "Intrepid2_HVOL_TET_Cn_FEM.hpp"
8
9#include "Intrepid2_HGRAD_QUAD_C1_FEM.hpp"
10#include "Intrepid2_HGRAD_QUAD_C2_FEM.hpp"
11#include "Intrepid2_HGRAD_QUAD_Cn_FEM.hpp"
12
13#include "Intrepid2_HGRAD_HEX_C1_FEM.hpp"
14#include "Intrepid2_HGRAD_HEX_C2_FEM.hpp"
15#include "Intrepid2_HGRAD_HEX_Cn_FEM.hpp"
16
17#include "Intrepid2_HGRAD_TET_C1_FEM.hpp"
18#include "Intrepid2_HGRAD_TET_C2_FEM.hpp"
19#include "Intrepid2_HGRAD_TET_Cn_FEM.hpp"
20
21#include "Intrepid2_HGRAD_TRI_C1_FEM.hpp"
22#include "Intrepid2_HGRAD_TRI_C2_FEM.hpp"
23#include "Intrepid2_HGRAD_TRI_Cn_FEM.hpp"
24
25#include "Intrepid2_HGRAD_LINE_C1_FEM.hpp"
26#include "Intrepid2_HGRAD_LINE_Cn_FEM.hpp"
27
28#include "Intrepid2_HCURL_TRI_I1_FEM.hpp"
29#include "Intrepid2_HCURL_TRI_In_FEM.hpp"
30
31#include "Intrepid2_HCURL_TET_I1_FEM.hpp"
32#include "Intrepid2_HCURL_TET_In_FEM.hpp"
33
34#include "Intrepid2_HCURL_QUAD_I1_FEM.hpp"
35#include "Intrepid2_HCURL_QUAD_In_FEM.hpp"
36
37#include "Intrepid2_HCURL_HEX_I1_FEM.hpp"
38#include "Intrepid2_HCURL_HEX_In_FEM.hpp"
39
40#include "Intrepid2_HDIV_TRI_I1_FEM.hpp"
41#include "Intrepid2_HDIV_TRI_In_FEM.hpp"
42
43#include "Intrepid2_HDIV_QUAD_I1_FEM.hpp"
44#include "Intrepid2_HDIV_QUAD_In_FEM.hpp"
45
46#include "Intrepid2_HDIV_TET_I1_FEM.hpp"
47#include "Intrepid2_HDIV_TET_In_FEM.hpp"
48
49#include "Intrepid2_HDIV_HEX_I1_FEM.hpp"
50#include "Intrepid2_HDIV_HEX_In_FEM.hpp"
51
52
53namespace panzer {
54
55
69 template <typename DeviceType, typename OutputValueType, typename PointValueType>
70 Teuchos::RCP<Intrepid2::Basis<DeviceType,OutputValueType,PointValueType> >
71 createIntrepid2Basis(const std::string basis_type, int basis_order,
72 const shards::CellTopology & cell_topology)
73 {
74 // Shards supports extended topologies so the names have a "size"
75 // associated with the number of nodes. We prune the size to
76 // avoid combinatorial explosion of checks.
77 std::string cell_topology_type = cell_topology.getName();
78 std::size_t end_position = 0;
79 end_position = cell_topology_type.find("_");
80 std::string cell_type = cell_topology_type.substr(0,end_position);
81
82 Teuchos::RCP<Intrepid2::Basis<DeviceType,OutputValueType,PointValueType> > basis;
83
84 // high order point distribution type;
85 // for now equispaced only; to get a permutation map with different orientation,
86 // orientation coeff matrix should have the same point distribution.
87 const Intrepid2::EPointType point_type = Intrepid2::POINTTYPE_EQUISPACED;
88
89 if ( (basis_type == "Const") && (basis_order == 0) )
90 basis = Teuchos::rcp( new Intrepid2::Basis_HVOL_C0_FEM<DeviceType,OutputValueType,PointValueType>(cell_topology) );
91
92 else if ( (basis_type == "HVol") && (basis_order == 0) )
93 basis = Teuchos::rcp( new Intrepid2::Basis_HVOL_C0_FEM<DeviceType,OutputValueType,PointValueType>(cell_topology) );
94
95 else if ( (basis_type == "HVol") && (cell_type == "Quadrilateral") && (basis_order > 0) )
96 basis = Teuchos::rcp( new Intrepid2::Basis_HVOL_QUAD_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
97
98 else if ( (basis_type == "HVol") && (cell_type == "Triangle") && (basis_order > 0) )
99 basis = Teuchos::rcp( new Intrepid2::Basis_HVOL_TRI_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
100
101 else if ( (basis_type == "HVol") && (cell_type == "Hexahedron") )
102 basis = Teuchos::rcp( new Intrepid2::Basis_HVOL_HEX_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
103
104 else if ( (basis_type == "HVol") && (cell_type == "Tetrahedron") )
105 basis = Teuchos::rcp( new Intrepid2::Basis_HVOL_TET_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
106
107 else if ( (basis_type == "HGrad") && (cell_type == "Hexahedron") && (basis_order == 1) )
108 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_HEX_C1_FEM<DeviceType,OutputValueType,PointValueType> );
109
110 else if ( (basis_type == "HGrad") && (cell_type == "Hexahedron") && (basis_order == 2) )
111 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_HEX_C2_FEM<DeviceType,OutputValueType,PointValueType> );
112
113 else if ( (basis_type == "HGrad") && (cell_type == "Hexahedron") && (basis_order > 2) )
114 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_HEX_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
115
116 else if ( (basis_type == "HCurl") && (cell_type == "Hexahedron") && (basis_order == 1) )
117 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_HEX_I1_FEM<DeviceType,OutputValueType,PointValueType> );
118
119 else if ( (basis_type == "HCurl") && (cell_type == "Hexahedron") && (basis_order > 1) )
120 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_HEX_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
121
122 else if ( (basis_type == "HDiv") && (cell_type == "Hexahedron") && (basis_order == 1) )
123 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_HEX_I1_FEM<DeviceType,OutputValueType,PointValueType> );
124
125 else if ( (basis_type == "HDiv") && (cell_type == "Hexahedron") && (basis_order > 1) )
126 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_HEX_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
127
128 else if ( (basis_type == "HGrad") && (cell_type == "Tetrahedron") && (basis_order == 1) )
129 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_TET_C1_FEM<DeviceType,OutputValueType,PointValueType> );
130
131 else if ( (basis_type == "HGrad") && (cell_type == "Tetrahedron") && (basis_order == 2) )
132 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_TET_C2_FEM<DeviceType,OutputValueType,PointValueType> );
133
134 else if ( (basis_type == "HGrad") && (cell_type == "Tetrahedron") && (basis_order > 2) )
135 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_TET_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
136
137 else if ( (basis_type == "HCurl") && (cell_type == "Tetrahedron") && (basis_order == 1) )
138 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_TET_I1_FEM<DeviceType,OutputValueType,PointValueType> );
139
140 else if ( (basis_type == "HCurl") && (cell_type == "Tetrahedron") && (basis_order > 1) )
141 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_TET_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
142
143 else if ( (basis_type == "HDiv") && (cell_type == "Tetrahedron") && (basis_order == 1) )
144 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_TET_I1_FEM<DeviceType,OutputValueType,PointValueType> );
145
146 else if ( (basis_type == "HDiv") && (cell_type == "Tetrahedron") && (basis_order > 1) )
147 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_TET_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
148
149 else if ( (basis_type == "HGrad") && (cell_type == "Quadrilateral") && (basis_order == 1) )
150 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_QUAD_C1_FEM<DeviceType,OutputValueType,PointValueType> );
151
152 else if ( (basis_type == "HGrad") && (cell_type == "Quadrilateral") && (basis_order == 2) )
153 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_QUAD_C2_FEM<DeviceType,OutputValueType,PointValueType> );
154
155 else if ( (basis_type == "HGrad") && (cell_type == "Quadrilateral") && (basis_order > 2) )
156 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_QUAD_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
157
158 else if ( (basis_type == "HCurl") && (cell_type == "Quadrilateral") && (basis_order == 1) )
159 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_QUAD_I1_FEM<DeviceType,OutputValueType,PointValueType> );
160
161 else if ( (basis_type == "HCurl") && (cell_type == "Quadrilateral") && (basis_order > 1) )
162 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_QUAD_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
163
164 else if ( (basis_type == "HDiv") && (cell_type == "Quadrilateral") && (basis_order == 1) )
165 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_QUAD_I1_FEM<DeviceType,OutputValueType,PointValueType> );
166
167 else if ( (basis_type == "HDiv") && (cell_type == "Quadrilateral") && (basis_order > 1) )
168 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_QUAD_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
169
170 else if ( (basis_type == "HGrad") && (cell_type == "Triangle") && (basis_order == 1) )
171 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_TRI_C1_FEM<DeviceType,OutputValueType,PointValueType> );
172
173 else if ( (basis_type == "HGrad") && (cell_type == "Triangle") && (basis_order == 2) )
174 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_TRI_C2_FEM<DeviceType,OutputValueType,PointValueType> );
175
176 else if ( (basis_type == "HGrad") && (cell_type == "Triangle") && (basis_order > 2) )
177 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_TRI_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
178
179 else if ( (basis_type == "HCurl") && (cell_type == "Triangle") && (basis_order == 1) )
180 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_TRI_I1_FEM<DeviceType,OutputValueType,PointValueType> );
181
182 else if ( (basis_type == "HCurl") && (cell_type == "Triangle") && (basis_order > 1) )
183 basis = Teuchos::rcp( new Intrepid2::Basis_HCURL_TRI_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
184
185 else if ( (basis_type == "HDiv") && (cell_type == "Triangle") && (basis_order == 1) )
186 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_TRI_I1_FEM<DeviceType,OutputValueType,PointValueType> );
187
188 else if ( (basis_type == "HDiv") && (cell_type == "Triangle") && (basis_order > 1) )
189 basis = Teuchos::rcp( new Intrepid2::Basis_HDIV_TRI_In_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
190
191 else if ( (basis_type == "HGrad") && (cell_type == "Line") && (basis_order == 1) )
192 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_LINE_C1_FEM<DeviceType,OutputValueType,PointValueType> );
193
194 else if ( (basis_type == "HGrad") && (cell_type == "Line") && (basis_order >= 2) )
195 basis = Teuchos::rcp( new Intrepid2::Basis_HGRAD_LINE_Cn_FEM<DeviceType,OutputValueType,PointValueType>(basis_order, point_type) );
196
197 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(basis), std::runtime_error,
198 "Failed to create the requestedbasis with basis_type=\"" << basis_type <<
199 "\", basis_order=\"" << basis_order << "\", and cell_type=\"" << cell_type << "\"!\n");
200
201 // we compare that the base topologies are the same
202 // we do so using the NAME. This avoids the ugly task of getting the
203 // cell topology data and constructing a new cell topology object since you cant
204 // just get the baseCellTopology directly from a shards cell topology
205 TEUCHOS_TEST_FOR_EXCEPTION(cell_topology.getBaseName()!=basis->getBaseCellTopology().getName(),
206 std::runtime_error,
207 "Failed to create basis. Intrepid2 basis base topology does not match mesh cell base topology!");
208
209 return basis;
210 }
211
226 template <typename DeviceType, typename OutputValueType, typename PointValueType>
227 Teuchos::RCP<Intrepid2::Basis<DeviceType,OutputValueType,PointValueType> >
228 createIntrepid2Basis(const std::string basis_type, int basis_order,
229 const Teuchos::RCP<const shards::CellTopology> & cell_topology)
230 {
231 return createIntrepid2Basis<DeviceType,OutputValueType,PointValueType>(basis_type,basis_order,*cell_topology);
232 }
233
234}
235
236// Instantiate for the device of every execution space Kokkos has enabled.
237// What callers ask for has to be what is instantiated here, and that depends
238// on what PHX::Device is.
239//
240// The DEVICE form is always needed. Intrepid2's first parameter is a device,
241// so Basis<Kokkos::Serial> and Basis<Kokkos::Device<Serial,HostSpace>> are
242// unrelated types; callers pass PHX::Device, and code that spells a device
243// explicitly -- a host device for a host-only path, say -- asks for one in
244// either configuration. SPACE::device_type is
245// Kokkos::Device<SPACE, SPACE::memory_space>, spelled that way because it
246// carries no comma and so survives macro argument splitting.
247//
248// The bare EXECUTION SPACE form is needed only while PHX::Device is still an
249// execution space, so it is added just for that build. SPACE and
250// SPACE::device_type are always distinct types, so the two can never collide.
251//
252// Each backend macro names a distinct execution space, hence a distinct
253// device, so no two of these can be the same specialization. Naming
254// PHX::Device directly instead would require knowing which backend it is,
255// which the preprocessor cannot work out. PHX::Device is among this list only
256// while its memory space is the execution space's own; a shared memory space
257// makes it distinct from all of them, which is what the guarded instantiation
258// at the end of this file is for.
259#define PANZER_INSTANTIATE_INTREPID2_BASIS_FOR(DEV) \
260 template Teuchos::RCP<Intrepid2::Basis<DEV,double,double> > \
261 panzer::createIntrepid2Basis<DEV,double,double>( \
262 const std::string, int, const shards::CellTopology &); \
263 template Teuchos::RCP<Intrepid2::Basis<DEV,double,double> > \
264 panzer::createIntrepid2Basis<DEV,double,double>( \
265 const std::string, int, const Teuchos::RCP<const shards::CellTopology> &);
266
267#if defined(PHX_DEPRECATED_DEVICE_AS_EXECUTION_SPACE)
268#define PANZER_INSTANTIATE_INTREPID2_BASIS(SPACE) \
269 PANZER_INSTANTIATE_INTREPID2_BASIS_FOR(SPACE::device_type) \
270 PANZER_INSTANTIATE_INTREPID2_BASIS_FOR(SPACE)
271#else
272#define PANZER_INSTANTIATE_INTREPID2_BASIS(SPACE) \
273 PANZER_INSTANTIATE_INTREPID2_BASIS_FOR(SPACE::device_type)
274#endif
275
276#if defined(KOKKOS_ENABLE_SERIAL)
278#endif
279#if defined(KOKKOS_ENABLE_OPENMP)
281#endif
282#if defined(KOKKOS_ENABLE_THREADS)
284#endif
285#if defined(KOKKOS_ENABLE_CUDA)
287#endif
288#if defined(KOKKOS_ENABLE_HIP)
290#endif
291#if defined(KOKKOS_ENABLE_SYCL)
293#endif
294
295// The list above covers PHX::Device only while its memory space is its
296// execution space's own, which is what SPACE::device_type means. A shared
297// memory space breaks that: Kokkos::Device<Cuda,CudaUVMSpace> is not
298// Kokkos::Device<Cuda,CudaSpace>, so PHX::Device needs its own instantiation.
299//
300// Phalanx computes PHX_MEMORY_SPACE_IS_NOT_EXECUTION_SPACE_MEMORY_SPACE for
301// exactly this question, and because the memory space is always either the
302// execution space's own or Kokkos::SharedSpace, it is exact. Not needed in
303// the deprecated mode, where PHX::Device is an execution space and so already
304// instantiated above. The static_assert is a backstop: nothing should be able
305// to reach it.
306#if defined(PHX_MEMORY_SPACE_IS_NOT_EXECUTION_SPACE_MEMORY_SPACE) && \
307 !defined(PHX_DEPRECATED_DEVICE_AS_EXECUTION_SPACE)
308static_assert(!std::is_same<PHX::MemorySpace,
309 PHX::ExecutionSpace::memory_space>::value,
310 "panzer: PHX::Device would repeat one of the instantiations "
311 "above. Narrow the condition on this block -- the configured "
312 "memory space is the execution space's own, so PHX::Device is "
313 "already covered by its backend's SPACE::device_type.");
315#endif
316
317#undef PANZER_INSTANTIATE_INTREPID2_BASIS
318#undef PANZER_INSTANTIATE_INTREPID2_BASIS_FOR
#define PANZER_INSTANTIATE_INTREPID2_BASIS_FOR(DEV)
#define PANZER_INSTANTIATE_INTREPID2_BASIS(SPACE)
Teuchos::RCP< Intrepid2::Basis< DeviceType, OutputValueType, PointValueType > > createIntrepid2Basis(const std::string basis_type, int basis_order, const shards::CellTopology &cell_topology)
Creates an Intrepid2::Basis object given the basis, order and cell topology.