Intrepid2
Intrepid2_HGRAD_QUAD_C2_FEMDef.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid2 Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Kyungjoo Kim (kyukim@sandia.gov), or
38 // Mauro Perego (mperego@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 
49 #ifndef __INTREPID2_HGRAD_QUAD_C2_FEM_DEF_HPP__
50 #define __INTREPID2_HGRAD_QUAD_C2_FEM_DEF_HPP__
51 
52 namespace Intrepid2 {
53 
54  // -------------------------------------------------------------------------------------
55 
56  namespace Impl {
57 
58  template<bool serendipity>
59  template<EOperator opType>
60  template<typename OutputViewType,
61  typename inputViewType>
62  KOKKOS_INLINE_FUNCTION
63  void
64  Basis_HGRAD_QUAD_DEG2_FEM<serendipity>::Serial<opType>::
65  getValues( OutputViewType output,
66  const inputViewType input ) {
67  switch (opType) {
68  case OPERATOR_VALUE : {
69  const auto x = input(0);
70  const auto y = input(1);
71 
72  // output is a rank-1 array with dimensions (basisCardinality_)
73  if constexpr (!serendipity) {
74  output.access(0) = x*(x - 1.0)*y*(y - 1.0)/4.0;
75  output.access(1) = x*(x + 1.0)*y*(y - 1.0)/4.0;
76  output.access(2) = x*(x + 1.0)*y*(y + 1.0)/4.0;
77  output.access(3) = x*(x - 1.0)*y*(y + 1.0)/4.0;
78  // edge midpoints basis functions
79  output.access(4) = (1.0 - x)*(1.0 + x)*y*(y - 1.0)/2.0;
80  output.access(5) = x*(x + 1.0)*(1.0 - y)*(1.0 + y)/2.0;
81  output.access(6) = (1.0 - x)*(1.0 + x)*y*(y + 1.0)/2.0;
82  output.access(7) = x*(x - 1.0)*(1.0 - y)*(1.0 + y)/2.0;
83 
84  // quad bubble basis function
85  output.access(8) = (1.0 - x)*(1.0 + x)*(1.0 - y)*(1.0 + y);
86 
87  } else { //serendipity
88 
89  output.access(0) = 0.25*(1.0 - x)*(1.0 - y)*(-x - y - 1.0);
90  output.access(1) = 0.25*(1.0 + x)*(1.0 - y)*( x - y - 1.0);
91  output.access(2) = 0.25*(1.0 + x)*(1.0 + y)*( x + y - 1.0);
92  output.access(3) = 0.25*(1.0 - x)*(1.0 + y)*(-x + y - 1.0);
93 
94  output.access(4) = 0.5*(1.0 - x*x)*(1.0 - y);
95  output.access(5) = 0.5*(1.0 + x)*(1.0 - y*y);
96  output.access(6) = 0.5*(1.0 - x*x)*(1.0 + y);
97  output.access(7) = 0.5*(1.0 - x)*(1.0 - y*y);
98  }
99 
100  break;
101  }
102  case OPERATOR_D1 :
103  case OPERATOR_GRAD : {
104  const auto x = input(0);
105  const auto y = input(1);
106 
107  if constexpr (!serendipity) {
108 
109  output.access(0, 0) = (-0.25 + 0.5*x)*(-1. + y)*y;
110  output.access(0, 1) = (-1.0 + x)*x*(-0.25 + 0.5*y);
111 
112  output.access(1, 0) = (0.25 + 0.5*x)*(-1. + y)*y;
113  output.access(1, 1) = x*(1. + x)*(-0.25 + 0.5*y);
114 
115  output.access(2, 0) = (0.25 + 0.5*x)*y*(1. + y);
116  output.access(2, 1) = x*(1. + x)*(0.25 + 0.5*y);
117 
118  output.access(3, 0) = (-0.25 + 0.5*x)*y*(1. + y);
119  output.access(3, 1) = (-1. + x)*x*(0.25 + 0.5*y);
120 
121  output.access(4, 0) = x*(1.0 - y)*y;
122  output.access(4, 1) = 0.5*(1.0 - x)*(1.0 + x)*(-1.0 + 2.0*y);
123 
124  output.access(5, 0) = 0.5*(1.0 - y)*(1.0 + y)*(1.0 + 2.0*x);
125  output.access(5, 1) =-x*(1.0 + x)*y;
126 
127  output.access(6, 0) =-y*(1.0 + y)*x;
128  output.access(6, 1) = 0.5*(1.0 - x)*(1.0 + x)*(1.0 + 2.0*y);
129 
130  output.access(7, 0) = 0.5*(1.0 - y)*(1.0+ y)*(-1.0 + 2.0*x);
131  output.access(7, 1) = (1.0 - x)*x*y;
132 
133  output.access(8, 0) =-2.0*(1.0 - y)*(1.0 + y)*x;
134  output.access(8, 1) =-2.0*(1.0 - x)*(1.0 + x)*y;
135 
136  } else { //serendipity
137 
138  output.access(0, 0) = -0.25*(1.0-y)*(-x-y-1.0) - 0.25*(1.0-x)*(1.0-y);
139  output.access(0, 1) = -0.25*(1.0-x)*(-x-y-1.0) - 0.25*(1.0-x)*(1.0-y);
140 
141  output.access(1, 0) = 0.25*(1.0-y)*( x-y-1.0) + 0.25*(1.0+x)*(1.0-y);
142  output.access(1, 1) = -0.25*(1.0+x)*( x-y-1.0) - 0.25*(1.0+x)*(1.0-y);
143 
144  output.access(2, 0) = 0.25*(1.0+y)*( x+y-1.0) + 0.25*(1.0+x)*(1.0+y);
145  output.access(2, 1) = 0.25*(1.0+x)*( x+y-1.0) + 0.25*(1.0+x)*(1.0+y);
146 
147  output.access(3, 0) = -0.25*(1.0+y)*(-x+y-1.0) - 0.25*(1.0-x)*(1.0+y);
148  output.access(3, 1) = 0.25*(1.0-x)*(-x+y-1.0) + 0.25*(1.0-x)*(1.0+y);
149 
150  output.access(4, 0) = -x*(1.0-y);
151  output.access(4, 1) = -0.5*(1.0-x*x);
152 
153  output.access(5, 0) = 0.5*(1.0-y*y);
154  output.access(5, 1) = -y*(1.0+x);
155 
156  output.access(6, 0) = -x*(1.0+y);
157  output.access(6, 1) = 0.5*(1.0-x*x);
158 
159  output.access(7, 0) = -0.5*(1.0-y*y);
160  output.access(7, 1) = -y*(1.0-x);
161  }
162  break;
163  }
164  case OPERATOR_CURL : {
165  const auto x = input(0);
166  const auto y = input(1);
167 
168  // output.access is a rank-3 array with dimensions (basisCardinality_, dim0, spaceDim)
169  // CURL(u) = (u_y, -u_x), is rotated GRAD
170 
171  if constexpr (!serendipity) {
172  output.access(0, 1) =-(-0.25 + 0.5*x)*(-1. + y)*y;
173  output.access(0, 0) = (-1.0 + x)*x*(-0.25 + 0.5*y);
174 
175  output.access(1, 1) =-(0.25 + 0.5*x)*(-1. + y)*y;
176  output.access(1, 0) = x*(1. + x)*(-0.25 + 0.5*y);
177 
178  output.access(2, 1) =-(0.25 + 0.5*x)*y*(1. + y);
179  output.access(2, 0) = x*(1. + x)*(0.25 + 0.5*y);
180 
181  output.access(3, 1) =-(-0.25 + 0.5*x)*y*(1. + y);
182  output.access(3, 0) = (-1. + x)*x*(0.25 + 0.5*y);
183 
184  output.access(4, 1) =-x*(1.0 - y)*y;
185  output.access(4, 0) = 0.5*(1.0 - x)*(1.0 + x)*(-1.0 + 2.0*y);
186 
187  output.access(5, 1) =-0.5*(1.0 - y)*(1.0 + y)*(1.0 + 2.0*x);
188  output.access(5, 0) =-x*(1.0 + x)*y;
189 
190  output.access(6, 1) = y*(1.0 + y)*x;
191  output.access(6, 0) = 0.5*(1.0 - x)*(1.0 + x)*(1.0 + 2.0*y);
192 
193  output.access(7, 1) =-0.5*(1.0 - y)*(1.0 + y)*(-1.0 + 2.0*x);
194  output.access(7, 0) = (1.0 - x)*x*y;
195 
196  output.access(8, 1) = 2.0*(1.0 - y)*(1.0 + y)*x;
197  output.access(8, 0) =-2.0*(1.0 - x)*(1.0 + x)*y;
198 
199  } else { //serendipity
200  output.access(0, 1) = 0.25*(1.0-y)*(-x-y-1.0) + 0.25*(1.0-x)*(1.0-y);
201  output.access(0, 0) = -0.25*(1.0-x)*(-x-y-1.0) - 0.25*(1.0-x)*(1.0-y);
202 
203  output.access(1, 1) = -0.25*(1.0-y)*( x-y-1.0) - 0.25*(1.0+x)*(1.0-y);
204  output.access(1, 0) = -0.25*(1.0+x)*( x-y-1.0) - 0.25*(1.0+x)*(1.0-y);
205 
206  output.access(2, 1) = -0.25*(1.0+y)*( x+y-1.0) - 0.25*(1.0+x)*(1.0+y);
207  output.access(2, 0) = 0.25*(1.0+x)*( x+y-1.0) + 0.25*(1.0+x)*(1.0+y);
208 
209  output.access(3, 1) = 0.25*(1.0+y)*(-x+y-1.0) + 0.25*(1.0-x)*(1.0+y);
210  output.access(3, 0) = 0.25*(1.0-x)*(-x+y-1.0) + 0.25*(1.0-x)*(1.0+y);
211 
212  output.access(4, 1) = x*(1.0-y);
213  output.access(4, 0) = -0.5*(1.0-x*x);
214 
215  output.access(5, 1) = -0.5*(1.0-y*y);
216  output.access(5, 0) = -y*(1.0+x);
217 
218  output.access(6, 1) = x*(1.0+y);
219  output.access(6, 0) = 0.5*(1.0-x*x);
220 
221  output.access(7, 1) = 0.5*(1.0-y*y);
222  output.access(7, 0) = -y*(1.0-x);
223  }
224  break;
225  }
226  case OPERATOR_D2 : {
227  const auto x = input(0);
228  const auto y = input(1);
229  // output.access is a rank-3 array with dimensions (basisCardinality_, D2Cardinality=3)
230 
231  if constexpr (!serendipity) {
232 
233  output.access(0, 0) = 0.5*(-1.0 + y)*y;
234  output.access(0, 1) = 0.25 - 0.5*y + x*(-0.5 + 1.*y);
235  output.access(0, 2) = 0.5*(-1.0 + x)*x;
236 
237  output.access(1, 0) = 0.5*(-1.0 + y)*y;
238  output.access(1, 1) =-0.25 + 0.5*y + x*(-0.5 + 1.*y);
239  output.access(1, 2) = 0.5*x*(1.0 + x);
240 
241  output.access(2, 0) = 0.5*y*(1.0 + y);
242  output.access(2, 1) = 0.25 + 0.5*y + x*(0.5 + 1.*y);
243  output.access(2, 2) = 0.5*x*(1.0 + x);
244 
245  output.access(3, 0) = 0.5*y*(1.0 + y);
246  output.access(3, 1) =-0.25 - 0.5*y + x*(0.5 + 1.*y);
247  output.access(3, 2) = 0.5*(-1.0 + x)*x;
248 
249  output.access(4, 0) = (1.0 - y)*y;
250  output.access(4, 1) = x*(1. - 2.*y);
251  output.access(4, 2) = (1.0 - x)*(1.0 + x);
252 
253  output.access(5, 0) = (1.0 - y)*(1.0 + y);
254  output.access(5, 1) = x*(0. - 2.*y) - 1.*y;
255  output.access(5, 2) =-x*(1.0 + x);
256 
257  output.access(6, 0) =-y*(1.0 + y);
258  output.access(6, 1) = x*(-1. - 2.*y);
259  output.access(6, 2) = (1.0 - x)*(1.0 + x);
260 
261  output.access(7, 0) = (1.0 - y)*(1.0 + y);
262  output.access(7, 1) = x*(0. - 2.*y) + 1.*y;
263  output.access(7, 2) = (1.0 - x)*x;
264 
265  output.access(8, 0) =-2.0 + 2.0*y*y;
266  output.access(8, 1) = 4*x*y;
267  output.access(8, 2) =-2.0 + 2.0*x*x;
268 
269  } else { //serendipity
270 
271  output.access(0, 0) = 0.5*(1.0 - y);
272  output.access(0, 1) = 0.25*(1.0 - 2.0*x - 2.0*y);
273  output.access(0, 2) = 0.5*(1.0 - x);
274 
275  output.access(1, 0) = 0.5*(1.0 - y);
276  output.access(1, 1) = -0.25*(1.0 + 2.0*x - 2.0*y);
277  output.access(1, 2) = 0.5*(1.0 + x);
278 
279  output.access(2, 0) = 0.5*(1.0 + y);
280  output.access(2, 1) = 0.25*(1.0 + 2.0*x + 2.0*y);
281  output.access(2, 2) = 0.5*(1.0 + x);
282 
283  output.access(3, 0) = 0.5*(1.0 + y);
284  output.access(3, 1) = -0.25*(1.0 - 2.0*x + 2.0*y);
285  output.access(3, 2) = 0.5*(1.0 - x);
286 
287  output.access(4, 0) = -(1.0 - y);
288  output.access(4, 1) = x;
289  output.access(4, 2) = 0.0;
290 
291  output.access(5, 0) = 0.0;
292  output.access(5, 1) = -y;
293  output.access(5, 2) = -(1.0 + x);
294 
295  output.access(6, 0) = -(1.0 + y);
296  output.access(6, 1) = -x;
297  output.access(6, 2) = 0.0;
298 
299  output.access(7, 0) = 0.0;
300  output.access(7, 1) = y;
301  output.access(7, 2) = -(1.0 - x);
302 
303  }
304  break;
305  }
306  case OPERATOR_D3 : {
307  if constexpr (!serendipity) {
308  const auto x = input(0);
309  const auto y = input(1);
310  output.access(0, 0) = 0.0;
311  output.access(0, 1) =-0.5 + y;
312  output.access(0, 2) =-0.5 + x;
313  output.access(0, 3) = 0.0;
314 
315  output.access(1, 0) = 0.0;
316  output.access(1, 1) =-0.5 + y;
317  output.access(1, 2) = 0.5 + x;
318  output.access(1, 3) = 0.0;
319 
320  output.access(2, 0) = 0.0;
321  output.access(2, 1) = 0.5 + y;
322  output.access(2, 2) = 0.5 + x;
323  output.access(2, 3) = 0.0;
324 
325  output.access(3, 0) = 0.0;
326  output.access(3, 1) = 0.5 + y;
327  output.access(3, 2) =-0.5 + x;
328  output.access(3, 3) = 0.0;
329 
330  output.access(4, 0) = 0.0;
331  output.access(4, 1) = 1.0 - 2.0*y;
332  output.access(4, 2) =-2.0*x;
333  output.access(4, 3) = 0.0;
334 
335  output.access(5, 0) = 0.0;
336  output.access(5, 1) =-2.0*y;
337  output.access(5, 2) =-1.0 - 2.0*x;
338  output.access(5, 3) = 0.0;
339 
340  output.access(6, 0) = 0.0;
341  output.access(6, 1) =-1.0 - 2.0*y;
342  output.access(6, 2) =-2.0*x;
343  output.access(6, 3) = 0.0;
344 
345  output.access(7, 0) = 0.0;
346  output.access(7, 1) =-2.0*y;
347  output.access(7, 2) = 1.0 - 2.0*x;
348  output.access(7, 3) = 0.0;
349 
350  output.access(8, 0) = 0.0;
351  output.access(8, 1) = 4.0*y;
352  output.access(8, 2) = 4.0*x;
353  output.access(8, 3) = 0.0;
354 
355  } else { //serendipity
356 
357  output.access(0, 0) = 0.0;
358  output.access(0, 1) =-0.5;
359  output.access(0, 2) =-0.5;
360  output.access(0, 3) = 0.0;
361 
362  output.access(1, 0) = 0.0;
363  output.access(1, 1) =-0.5;
364  output.access(1, 2) = 0.5;
365  output.access(1, 3) = 0.0;
366 
367  output.access(2, 0) = 0.0;
368  output.access(2, 1) = 0.5;
369  output.access(2, 2) = 0.5;
370  output.access(2, 3) = 0.0;
371 
372  output.access(3, 0) = 0.0;
373  output.access(3, 1) = 0.5;
374  output.access(3, 2) =-0.5;
375  output.access(3, 3) = 0.0;
376 
377  output.access(4, 0) = 0.0;
378  output.access(4, 1) = 1.0;
379  output.access(4, 2) = 0.0;
380  output.access(4, 3) = 0.0;
381 
382  output.access(5, 0) = 0.0;
383  output.access(5, 1) = 0.0;
384  output.access(5, 2) =-1.0;
385  output.access(5, 3) = 0.0;
386 
387  output.access(6, 0) = 0.0;
388  output.access(6, 1) =-1.0;
389  output.access(6, 2) = 0.0;
390  output.access(6, 3) = 0.0;
391 
392  output.access(7, 0) = 0.0;
393  output.access(7, 1) = 0.0;
394  output.access(7, 2) = 1.0;
395  output.access(7, 3) = 0.0;
396  }
397  break;
398  }
399  case OPERATOR_D4 : {
400 
401  const ordinal_type jend = output.extent(1);
402  const ordinal_type iend = output.extent(0);
403 
404  for (ordinal_type j=0;j<jend;++j)
405  for (ordinal_type i=0;i<iend;++i)
406  output.access(i, j) = 0.0;
407 
408  if constexpr (!serendipity) {
409  output.access(0, 2) = 1.0;
410  output.access(1, 2) = 1.0;
411  output.access(2, 2) = 1.0;
412  output.access(3, 2) = 1.0;
413 
414  output.access(4, 2) =-2.0;
415  output.access(5, 2) =-2.0;
416  output.access(6, 2) =-2.0;
417  output.access(7, 2) =-2.0;
418 
419  output.access(8, 2) = 4.0;
420  }
421  break;
422  }
423  case OPERATOR_MAX : {
424  const ordinal_type jend = output.extent(1);
425  const ordinal_type iend = output.extent(0);
426 
427  for (ordinal_type j=0;j<jend;++j)
428  for (ordinal_type i=0;i<iend;++i)
429  output.access(i, j) = 0.0;
430  break;
431  }
432  default: {
433  INTREPID2_TEST_FOR_ABORT( opType != OPERATOR_VALUE &&
434  opType != OPERATOR_GRAD &&
435  opType != OPERATOR_CURL &&
436  opType != OPERATOR_D1 &&
437  opType != OPERATOR_D2 &&
438  opType != OPERATOR_D3 &&
439  opType != OPERATOR_D4 &&
440  opType != OPERATOR_MAX,
441  ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_C2_FEM::Serial::getValues) operator is not supported");
442 
443  }
444  }
445  }
446 
447  template<bool serendipity>
448  template<typename DT,
449  typename outputValueValueType, class ...outputValueProperties,
450  typename inputPointValueType, class ...inputPointProperties>
451  void
452  Basis_HGRAD_QUAD_DEG2_FEM<serendipity>::
453  getValues( const typename DT::execution_space& space,
454  Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
455  const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
456  const EOperator operatorType ) {
457  typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
458  typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
459  typedef typename ExecSpace<typename inputPointViewType::execution_space,typename DT::execution_space>::ExecSpaceType ExecSpaceType;
460 
461  // Number of evaluation points = dim 0 of inputPoints
462  const auto loopSize = inputPoints.extent(0);
463  Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(space, 0, loopSize);
464 
465  switch (operatorType) {
466 
467  case OPERATOR_VALUE: {
468  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_VALUE> FunctorType;
469  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
470  break;
471  }
472  case OPERATOR_GRAD:
473  case OPERATOR_D1: {
474  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_GRAD> FunctorType;
475  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
476  break;
477  }
478  case OPERATOR_CURL: {
479  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_CURL> FunctorType;
480  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
481  break;
482  }
483  case OPERATOR_DIV: {
484  INTREPID2_TEST_FOR_EXCEPTION( (operatorType == OPERATOR_DIV), std::invalid_argument,
485  ">>> ERROR (Basis_HGRAD_QUAD_C2_FEM): DIV is invalid operator for rank-0 (scalar) functions in 2D");
486  break;
487  }
488  case OPERATOR_D2: {
489  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_D2> FunctorType;
490  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
491  break;
492  }
493  case OPERATOR_D3: {
494  // outputValues is a rank-3 array with dimensions (basisCardinality_, dim0, D3Cardinality=4)
495  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_D3> FunctorType;
496  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
497  break;
498  }
499  case OPERATOR_D4: {
500  // outputValues is a rank-3 array with dimensions (basisCardinality_, dim0, D4Cardinality=5)
501  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_D4> FunctorType;
502  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
503  break;
504  }
505  case OPERATOR_D5:
506  case OPERATOR_D6:
507  case OPERATOR_D7:
508  case OPERATOR_D8:
509  case OPERATOR_D9:
510  case OPERATOR_D10: {
511  typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_MAX> FunctorType;
512  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) );
513  break;
514  }
515  default: {
516  INTREPID2_TEST_FOR_EXCEPTION( !( Intrepid2::isValidOperator(operatorType) ), std::invalid_argument,
517  ">>> ERROR (Basis_HGRAD_QUAD_C2_FEM): Invalid operator type");
518  }
519  }
520  }
521 
522  }
523  // -------------------------------------------------------------------------------------
524 
525 
526  template<bool serendipity, typename DT, typename OT, typename PT>
529  this->basisCardinality_ = serendipity ? 8 : 9;
530  this->basisDegree_ = 2;
531  this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() );
532  this->basisType_ = BASIS_FEM_DEFAULT;
533  this->basisCoordinates_ = COORDINATES_CARTESIAN;
534  this->functionSpace_ = FUNCTION_SPACE_HGRAD;
535 
536  {
537  // Basis-dependent intializations
538  const ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag
539  const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim
540  const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal
541  const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell
542 
543  // An array with local DoF tags assigned to basis functions, in the order of their local enumeration
544  ordinal_type tags[36] = { 0, 0, 0, 1,
545  0, 1, 0, 1,
546  0, 2, 0, 1,
547  0, 3, 0, 1,
548  // edge midpoints
549  1, 0, 0, 1,
550  1, 1, 0, 1,
551  1, 2, 0, 1,
552  1, 3, 0, 1,
553  // quad center, not used for serendipity elements
554  2, 0, 0, 1};
555 
556  //host view
557  OrdinalTypeArray1DHost tagView(&tags[0], serendipity ? 32 : 36);
558 
559  // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays:
560  this->setOrdinalTagData(this->tagToOrdinal_,
561  this->ordinalToTag_,
562  tagView,
563  this->basisCardinality_,
564  tagSize,
565  posScDim,
566  posScOrd,
567  posDfOrd);
568  }
569 
570  // dofCoords on host and create its mirror view to device
571  Kokkos::DynRankView<typename ScalarViewType::value_type,typename DT::execution_space::array_layout,Kokkos::HostSpace>
572  dofCoords("dofCoordsHost", this->basisCardinality_,this->basisCellTopology_.getDimension());
573 
574  dofCoords(0,0) = -1.0; dofCoords(0,1) = -1.0;
575  dofCoords(1,0) = 1.0; dofCoords(1,1) = -1.0;
576  dofCoords(2,0) = 1.0; dofCoords(2,1) = 1.0;
577  dofCoords(3,0) = -1.0; dofCoords(3,1) = 1.0;
578 
579  dofCoords(4,0) = 0.0; dofCoords(4,1) = -1.0;
580  dofCoords(5,0) = 1.0; dofCoords(5,1) = 0.0;
581  dofCoords(6,0) = 0.0; dofCoords(6,1) = 1.0;
582  dofCoords(7,0) = -1.0; dofCoords(7,1) = 0.0;
583 
584  if constexpr (!serendipity) {
585  dofCoords(8,0) = 0.0; dofCoords(8,1) = 0.0;
586  }
587 
588  this->dofCoords_ = Kokkos::create_mirror_view(typename DT::memory_space(), dofCoords);
589  Kokkos::deep_copy(this->dofCoords_, dofCoords);
590  }
591 
592 }// namespace Intrepid2
593 #endif
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.