Intrepid2
Intrepid2_TestUtils.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),
38 // Mauro Perego (mperego@sandia.gov), or
39 // Nate Roberts (nvrober@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
49 #ifndef Intrepid2_TestUtils_h
50 #define Intrepid2_TestUtils_h
51 
52 #include "Kokkos_Core.hpp"
53 #include "Kokkos_DynRankView.hpp"
54 
55 #include "Intrepid2_Basis.hpp"
58 #include "Intrepid2_Sacado.hpp" // Sacado includes, guarded by the appropriate preprocessor variable
59 #include "Intrepid2_Utils.hpp"
60 
61 #include "Teuchos_UnitTestHarness.hpp"
62 
63 static const double TEST_TOLERANCE_TIGHT = 1.e2 * std::numeric_limits<double>::epsilon();
64 
65 // we use DynRankView for both input points and values
66 template<typename ScalarType>
67 using ViewType = Kokkos::DynRankView<ScalarType,Kokkos::DefaultExecutionSpace>;
68 
69 template<typename ScalarType>
70 inline bool valuesAreSmall(ScalarType a, ScalarType b, double epsilon)
71 {
72  using std::abs;
73  return (abs(a) < epsilon) && (abs(b) < epsilon);
74 }
75 
76 inline bool approximatelyEqual(double a, double b, double epsilon)
77 {
78  const double larger_magnitude = (std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a));
79  return std::abs(a - b) <= larger_magnitude * epsilon;
80 }
81 
82 inline bool essentiallyEqual(double a, double b, double epsilon)
83 {
84  const double smaller_magnitude = (std::abs(a) > std::abs(b) ? std::abs(b) : std::abs(a));
85  return std::abs(a - b) <= smaller_magnitude * epsilon;
86 }
87 
88 // conversion from the ref element [0,1] (used by ESEAS) to the ref element [-1,1] (used by Intrepid2)
89 KOKKOS_INLINE_FUNCTION double fromZeroOne(double x_zero_one)
90 {
91  return x_zero_one * 2.0 - 1.0;
92 }
93 
94 // conversion from the ref element [-1,1] (used by Intrepid2) to the ref element [0,1] (used by ESEAS)
95 KOKKOS_INLINE_FUNCTION double toZeroOne(double x_minus_one_one)
96 {
97  return (x_minus_one_one + 1.0) / 2.0;
98 }
99 
100 // conversion from the ref element [0,1] (used by ESEAS) to the ref element [-1,1] (used by Intrepid2)
101 KOKKOS_INLINE_FUNCTION double fromZeroOne_dx(double dx_zero_one)
102 {
103  return dx_zero_one / 2.0;
104 }
105 
106 // conversion from the ref element [-1,1] (used by Intrepid2) to the ref element [0,1] (used by ESEAS)
107 KOKKOS_INLINE_FUNCTION double toZeroOne_dx(double dx_minus_one_one)
108 {
109  return dx_minus_one_one * 2.0;
110 }
111 
112 template<class DeviceViewType>
113 typename DeviceViewType::HostMirror getHostCopy(const DeviceViewType &deviceView)
114 {
115  typename DeviceViewType::HostMirror hostView = Kokkos::create_mirror(deviceView);
116  Kokkos::deep_copy(hostView, deviceView);
117  return hostView;
118 }
119 
120 template<class BasisFamily>
121 inline Teuchos::RCP< Intrepid2::Basis<Kokkos::DefaultExecutionSpace,double,double> > getBasisUsingFamily(shards::CellTopology cellTopo, Intrepid2::EFunctionSpace fs,
122  int polyOrder_x, int polyOrder_y=-1, int polyOrder_z = -1)
123 {
124  using BasisPtr = typename BasisFamily::BasisPtr;
125 
126  BasisPtr basis;
127  using namespace Intrepid2;
128 
129  if (cellTopo.getBaseKey() == shards::Line<>::key)
130  {
131  basis = getLineBasis<BasisFamily>(fs,polyOrder_x);
132  }
133  else if (cellTopo.getBaseKey() == shards::Quadrilateral<>::key)
134  {
135  INTREPID2_TEST_FOR_EXCEPTION(polyOrder_y < 0, std::invalid_argument, "polyOrder_y must be specified");
136  basis = getQuadrilateralBasis<BasisFamily>(fs,polyOrder_x,polyOrder_y);
137  }
138  else if (cellTopo.getBaseKey() == shards::Triangle<>::key)
139  {
140  basis = getTriangleBasis<BasisFamily>(fs,polyOrder_x);
141  }
142  else if (cellTopo.getBaseKey() == shards::Hexahedron<>::key)
143  {
144  INTREPID2_TEST_FOR_EXCEPTION(polyOrder_y < 0, std::invalid_argument, "polyOrder_y must be specified");
145  INTREPID2_TEST_FOR_EXCEPTION(polyOrder_z < 0, std::invalid_argument, "polyOrder_z must be specified");
146  basis = getHexahedronBasis<BasisFamily>(fs,polyOrder_x,polyOrder_y,polyOrder_z);
147  }
148  else if (cellTopo.getBaseKey() == shards::Tetrahedron<>::key)
149  {
150  basis = getTetrahedronBasis<BasisFamily>(fs, polyOrder_x);
151  }
152  else
153  {
154  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported cell topology");
155  }
156  return basis;
157 }
158 
159 template<bool defineVertexFunctions>
160 inline Teuchos::RCP< Intrepid2::Basis<Kokkos::DefaultExecutionSpace,double,double> > getHierarchicalBasis(shards::CellTopology cellTopo, Intrepid2::EFunctionSpace fs,
161  int polyOrder_x, int polyOrder_y=-1, int polyOrder_z = -1)
162 {
163  using ExecSpace = Kokkos::DefaultExecutionSpace;
164  using Scalar = double;
165  using namespace Intrepid2;
166 
171 
173 
174  return getBasisUsingFamily<BasisFamily>(cellTopo, fs, polyOrder_x, polyOrder_y, polyOrder_z);
175 }
176 
177 template<typename ValueType, class ... DimArgs>
178 inline ViewType<ValueType> getView(const std::string &label, DimArgs... dims)
179 {
180  const bool allocateFadStorage = !std::is_pod<ValueType>::value;
181  constexpr int maxDerivatives = 3; // maximum derivatives used for fad types in unit tests
182  if (!allocateFadStorage)
183  {
184  return ViewType<ValueType>(label,dims...);
185  }
186  else
187  {
188  return ViewType<ValueType>(label,dims...,maxDerivatives+1);
189  }
190 }
191 
195 template <typename PointValueType>
196 inline ViewType<PointValueType> lineInputPointsView(int numPoints)
197 {
198  ViewType<PointValueType> inputPoints = getView<PointValueType>("line input points",numPoints,1);
199  Kokkos::parallel_for(numPoints, KOKKOS_LAMBDA(const int i)
200  {
201  double x_zero_one = i * 1.0 / (numPoints-1); // the x value on [0,1]
202  inputPoints(i,0) = PointValueType(fromZeroOne(x_zero_one)); // standard Intrepid2 element
203  });
204  return inputPoints;
205 }
206 
212 template <typename PointValueType>
213 inline ViewType<PointValueType> hexInputPointsView(int numPoints_1D)
214 {
215  ViewType<PointValueType> inputPoints = getView<PointValueType>("hex input points",numPoints_1D*numPoints_1D*numPoints_1D,3);
216  Kokkos::parallel_for(numPoints_1D, KOKKOS_LAMBDA(const int i)
217  {
218  double x_zero_one = i * 1.0 / (numPoints_1D-1); // the x value on [0,1]
219  for (int j=0; j<numPoints_1D; j++)
220  {
221  double y_zero_one = j * 1.0 / (numPoints_1D-1); // the y value on [0,1]
222  for (int k=0; k<numPoints_1D; k++)
223  {
224  double z_zero_one = k * 1.0 / (numPoints_1D-1); // the z value on [0,1]
225  int pointOrdinal = (i*numPoints_1D+j)*numPoints_1D+k;
226  inputPoints(pointOrdinal,0) = PointValueType(fromZeroOne(x_zero_one)); // standard Intrepid2 element
227  inputPoints(pointOrdinal,1) = PointValueType(fromZeroOne(y_zero_one)); // standard Intrepid2 element
228  inputPoints(pointOrdinal,2) = PointValueType(fromZeroOne(z_zero_one)); // standard Intrepid2 element
229  }
230  }
231  });
232  return inputPoints;
233 }
234 
240 template <typename PointValueType>
241 inline ViewType<PointValueType> quadInputPointsView(int numPoints_1D)
242 {
243  ViewType<PointValueType> inputPoints = getView<PointValueType>("quad input points",numPoints_1D*numPoints_1D,2);
244 
245  Kokkos::parallel_for(numPoints_1D, KOKKOS_LAMBDA(const int i)
246  {
247  double x_zero_one = i * 1.0 / (numPoints_1D-1); // the x value on [0,1]
248  for (int j=0; j<numPoints_1D; j++)
249  {
250  double y_zero_one = j * 1.0 / (numPoints_1D-1); // the y value on [0,1]
251  int pointOrdinal = i*numPoints_1D+j;
252  inputPoints(pointOrdinal,0) = PointValueType(fromZeroOne(x_zero_one)); // standard Intrepid2 element
253  inputPoints(pointOrdinal,1) = PointValueType(fromZeroOne(y_zero_one)); // standard Intrepid2 element
254  }
255  });
256  return inputPoints;
257 }
258 
264 template <typename PointValueType>
265 inline ViewType<PointValueType> tetInputPointsView(int numPointsBase)
266 {
267  const int numPoints = numPointsBase*(numPointsBase+1)*(numPointsBase+2)/6;
268  ViewType<PointValueType> inputPoints = getView<PointValueType>("tetrahedron input points",numPoints,3);
269  Kokkos::parallel_for(numPointsBase, KOKKOS_LAMBDA(const int d0) // d0 generalizes row
270  {
271  // the following might be the formula for the nested for loop below, but we need to check this
272  // for now, we comment this out and do the clearer thing that requires more computation
273 // const int n = numPointsBase-d0;
274 // const int pointOrdinalOffset = n*(n+1)*(n+2)/6;
275  int pointOrdinalOffset = 0;
276  for (int i=0; i<d0; i++)
277  {
278  for (int j=0; j<numPointsBase-i; j++)
279  {
280  pointOrdinalOffset += (numPointsBase - i - j);
281  }
282  }
283 
284  double z_zero_one = d0 * 1.0 / (numPointsBase-1); // z value on [0,1]
285  int pointOrdinal = pointOrdinalOffset;
286  for (int d1=0; d1<numPointsBase-d0; d1++) // d1 generalizes column
287  {
288  double y_zero_one = d1 * 1.0 / (numPointsBase-1); // the y value on [0,1]
289  for (int d2=0; d2<numPointsBase-d0-d1; d2++)
290  {
291  double x_zero_one = d2 * 1.0 / (numPointsBase-1); // the x value on [0,1]
292 
293  inputPoints(pointOrdinal,0) = PointValueType(x_zero_one);
294  inputPoints(pointOrdinal,1) = PointValueType(y_zero_one);
295  inputPoints(pointOrdinal,2) = PointValueType(z_zero_one);
296 
297  pointOrdinal++;
298  }
299  }
300  });
301  return inputPoints;
302 }
303 
309 template <typename PointValueType>
310 inline ViewType<PointValueType> triInputPointsView(int numPointsBase)
311 {
312  const int numPoints = numPointsBase*(numPointsBase+1)/2;
313  ViewType<PointValueType> inputPoints = getView<PointValueType>("triangle input points",numPoints,2);
314  Kokkos::parallel_for(numPointsBase, KOKKOS_LAMBDA(const int row)
315  {
316  int rowPointOrdinalOffset = 0;
317  for (int i=0; i<row; i++)
318  {
319  rowPointOrdinalOffset += (numPointsBase - i);
320  }
321  double y_zero_one = row * 1.0 / (numPointsBase-1); // y value on [0,1]
322  for (int col=0; col<numPointsBase-row; col++)
323  {
324  const int pointOrdinal = rowPointOrdinalOffset + col;
325  double x_zero_one = col * 1.0 / (numPointsBase-1); // the x value on [0,1]
326  inputPoints(pointOrdinal,0) = PointValueType(x_zero_one);
327  inputPoints(pointOrdinal,1) = PointValueType(y_zero_one);
328  }
329  });
330  return inputPoints;
331 }
332 
333 template <typename PointValueType>
334 inline ViewType<PointValueType> getInputPointsView(shards::CellTopology &cellTopo, int numPoints_1D)
335 {
336  if (cellTopo.getBaseKey() == shards::Line<>::key)
337  {
338  return lineInputPointsView<PointValueType>(numPoints_1D);
339  }
340  else if (cellTopo.getBaseKey() == shards::Quadrilateral<>::key)
341  {
342  return quadInputPointsView<PointValueType>(numPoints_1D);
343  }
344  else if (cellTopo.getBaseKey() == shards::Hexahedron<>::key)
345  {
346  return hexInputPointsView<PointValueType>(numPoints_1D);
347  }
348  else if (cellTopo.getBaseKey() == shards::Triangle<>::key)
349  {
350  return triInputPointsView<PointValueType>(numPoints_1D);
351  }
352  else if (cellTopo.getBaseKey() == shards::Tetrahedron<>::key)
353  {
354  return tetInputPointsView<PointValueType>(numPoints_1D);
355  }
356  else
357  {
358  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported Cell Topology");
359  }
360 }
361 
362 template<typename OutputValueType>
363 inline ViewType<OutputValueType> getOutputView(Intrepid2::EFunctionSpace fs, Intrepid2::EOperator op, int basisCardinality, int numPoints, int spaceDim)
364 {
365  switch (fs) {
366  case Intrepid2::FUNCTION_SPACE_HGRAD:
367  switch (op) {
368  case Intrepid2::OPERATOR_VALUE:
369  return getView<OutputValueType>("H^1 value output",basisCardinality,numPoints);
370  case Intrepid2::OPERATOR_GRAD:
371  return getView<OutputValueType>("H^1 derivative output",basisCardinality,numPoints,spaceDim);
372  case Intrepid2::OPERATOR_D1:
373  case Intrepid2::OPERATOR_D2:
374  case Intrepid2::OPERATOR_D3:
375  case Intrepid2::OPERATOR_D4:
376  case Intrepid2::OPERATOR_D5:
377  case Intrepid2::OPERATOR_D6:
378  case Intrepid2::OPERATOR_D7:
379  case Intrepid2::OPERATOR_D8:
380  case Intrepid2::OPERATOR_D9:
381  case Intrepid2::OPERATOR_D10:
382  {
383  const auto dkcard = getDkCardinality(op, spaceDim);
384  return getView<OutputValueType>("H^1 derivative output",basisCardinality,numPoints,dkcard);
385  }
386  default:
387  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported op/fs combination");
388  }
389  case Intrepid2::FUNCTION_SPACE_HCURL:
390  switch (op) {
391  case Intrepid2::OPERATOR_VALUE:
392  return getView<OutputValueType>("H(curl) value output",basisCardinality,numPoints,spaceDim);
393  case Intrepid2::OPERATOR_CURL:
394  if (spaceDim == 2)
395  return getView<OutputValueType>("H(curl) derivative output",basisCardinality,numPoints);
396  else if (spaceDim == 3)
397  return getView<OutputValueType>("H(curl) derivative output",basisCardinality,numPoints,spaceDim);
398  default:
399  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported op/fs combination");
400  }
401  case Intrepid2::FUNCTION_SPACE_HDIV:
402  switch (op) {
403  case Intrepid2::OPERATOR_VALUE:
404  return getView<OutputValueType>("H(div) value output",basisCardinality,numPoints,spaceDim);
405  case Intrepid2::OPERATOR_DIV:
406  return getView<OutputValueType>("H(div) derivative output",basisCardinality,numPoints);
407  default:
408  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported op/fs combination");
409  }
410 
411  case Intrepid2::FUNCTION_SPACE_HVOL:
412  switch (op) {
413  case Intrepid2::OPERATOR_VALUE:
414  return getView<OutputValueType>("H(vol) value output",basisCardinality,numPoints);
415  case Intrepid2::OPERATOR_D1:
416  case Intrepid2::OPERATOR_D2:
417  case Intrepid2::OPERATOR_D3:
418  case Intrepid2::OPERATOR_D4:
419  case Intrepid2::OPERATOR_D5:
420  case Intrepid2::OPERATOR_D6:
421  case Intrepid2::OPERATOR_D7:
422  case Intrepid2::OPERATOR_D8:
423  case Intrepid2::OPERATOR_D9:
424  case Intrepid2::OPERATOR_D10:
425  {
426  const auto dkcard = getDkCardinality(op, spaceDim);
427  return getView<OutputValueType>("H(vol) derivative output",basisCardinality,numPoints,dkcard);
428  }
429  default:
430  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported op/fs combination");
431  }
432  default:
433  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported op/fs combination");
434  }
435 }
436 
437 // ! This returns a vector whose entries are vector<int>s containing 1-3 polynomial orders from 1 up to and including those specified
438 // ! Intended for testing bases that support anisotropic polynomial degree, such as the hierarchical bases
439 inline std::vector< std::vector<int> > getBasisTestCasesUpToDegree(int spaceDim, int minDegree, int polyOrder_x, int polyOrder_y=-1, int polyOrder_z = -1)
440 {
441  std::vector<int> degrees(spaceDim);
442  degrees[0] = polyOrder_x;
443  if (spaceDim > 1) degrees[1] = polyOrder_y;
444  if (spaceDim > 2) degrees[2] = polyOrder_z;
445 
446  int numCases = degrees[0];
447  for (unsigned d=1; d<degrees.size(); d++)
448  {
449  numCases = numCases * (degrees[d] + 1 - minDegree);
450  }
451  std::vector< std::vector<int> > subBasisDegreeTestCases(numCases);
452  for (int caseOrdinal=0; caseOrdinal<numCases; caseOrdinal++)
453  {
454  std::vector<int> subBasisDegrees(degrees.size());
455  int caseRemainder = caseOrdinal;
456  for (int d=degrees.size()-1; d>=0; d--)
457  {
458  int subBasisDegree = caseRemainder % (degrees[d] + 1 - minDegree);
459  caseRemainder = caseRemainder / (degrees[d] + 1 - minDegree);
460  subBasisDegrees[d] = subBasisDegree + minDegree;
461  }
462  subBasisDegreeTestCases[caseOrdinal] = subBasisDegrees;
463  }
464  return subBasisDegreeTestCases;
465 }
466 
467 template <class ViewType>
468 void testViewFloatingEquality(ViewType &view1, ViewType &view2, double relTol, double absTol, Teuchos::FancyOStream &out, bool &success,
469  std::string view1Name = "View 1", std::string view2Name = "View 2")
470 {
471  using Scalar = typename ViewType::value_type;
472  using HostView = typename ViewType::HostMirror;
473  using HostViewIteratorScalar = Intrepid2::ViewIterator<HostView, Scalar>;
474 
475  auto hostView1 = getHostCopy(view1);
476  auto hostView2 = getHostCopy(view2);
477 
478  // check that rank/size match
479  TEUCHOS_TEST_FOR_EXCEPTION(view1.rank() != view2.rank(), std::invalid_argument, "views must agree in rank");
480  for (unsigned i=0; i<view1.rank(); i++)
481  {
482  TEUCHOS_TEST_FOR_EXCEPTION(view1.extent_int(i) != view2.extent_int(i), std::invalid_argument, "views must agree in size in each dimension");
483  }
484 
485  if (view1.size() == 0) return; // nothing to test
486 
487  HostViewIteratorScalar vi1(hostView1);
488  HostViewIteratorScalar vi2(hostView2);
489 
490  double maxDiff = 0.0;
491  double maxRelativeDiff = 0.0;
492  bool differencesFound = false;
493 
494  bool moreEntries = (vi1.nextIncrementRank() != -1) && (vi2.nextIncrementRank() != -1);
495  while (moreEntries)
496  {
497  Scalar value1 = vi1.get();
498  Scalar value2 = vi2.get();
499 
500  const bool small = valuesAreSmall(value1, value2, absTol);
501  const bool valuesMatch = small || essentiallyEqual(value1, value2, relTol);
502 
503  if (!valuesMatch)
504  {
505  differencesFound = true;
506  success = false;
507  auto location = vi1.getLocation();
508  out << "At location (";
509  for (unsigned i=0; i<view1.rank(); i++)
510  {
511  out << location[i];
512  if (i<view1.rank()-1)
513  {
514  out << ",";
515  }
516  }
517  out << ") " << view1Name << " value != " << view2Name << " value (";
518  out << value1 << " != " << value2 << "); diff is " << std::abs(value1-value2) << std::endl;
519 
520  maxDiff = std::max(maxDiff, std::abs(value1-value2));
521  double smallerMagnitude = (std::abs(value1) > std::abs(value2) ? std::abs(value2) : std::abs(value1));
522  if (smallerMagnitude > 0)
523  {
524  const double relativeDiff = std::abs(value1 - value2) / smallerMagnitude;
525  maxRelativeDiff = std::max(maxRelativeDiff, relativeDiff);
526  }
527  }
528 
529  moreEntries = (vi1.increment() != -1);
530  moreEntries = moreEntries && (vi2.increment() != -1);
531  }
532 
533  if (differencesFound)
534  {
535  out << "max difference = " << maxDiff << std::endl;
536  out << "max relative difference = " << maxRelativeDiff << std::endl;
537  }
538 }
539 
540 #ifdef HAVE_INTREPID2_SACADO
541 #include <Sacado.hpp>
542 using Sacado_Fad_DFadType = Sacado::Fad::DFad<double>;
543 #define INTREPID2_OUTPUTSCALAR_POINTSCALAR_TEST_INSTANT(GROUP_NAME, TEST_NAME) \
544 \
545 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( GROUP_NAME, TEST_NAME, double, double ) \
546 \
547 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( GROUP_NAME, TEST_NAME, Sacado_Fad_DFadType, Sacado_Fad_DFadType ) \
548 
549 #else
550 #define INTREPID2_OUTPUTSCALAR_POINTSCALAR_TEST_INSTANT(GROUP_NAME, TEST_NAME) \
551 \
552 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( GROUP_NAME, TEST_NAME, double, double ) \
553 
554 #endif
555 
556 #endif /* Intrepid2_TestUtils_h */
Header file for the abstract base class Intrepid2::Basis.
KOKKOS_INLINE_FUNCTION ordinal_type getDkCardinality(const EOperator operatorType, const ordinal_type spaceDim)
Returns cardinality of Dk, i.e., the number of all derivatives of order k.
Stateless class representing a family of basis functions, templated on H(vol) and H(grad) on the line...
Stateless classes that act as factories for two families of hierarchical bases. HierarchicalBasisFami...
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types.
ViewType< PointValueType > tetInputPointsView(int numPointsBase)
Returns a View containing regularly-spaced points on the tetrahedron.
ViewType< PointValueType > hexInputPointsView(int numPoints_1D)
Returns a View containing equispaced points on the hexahedron.
ViewType< PointValueType > triInputPointsView(int numPointsBase)
Returns a View containing regularly-spaced points on the triangle.
ViewType< PointValueType > quadInputPointsView(int numPoints_1D)
Returns a View containing equispaced points on the quadrilateral.
ViewType< PointValueType > lineInputPointsView(int numPoints)
Returns a View containing equispaced points on the line.
Header function for Intrepid2::Util class and other utility functions.
A family of basis functions, constructed from H(vol) and H(grad) bases on the line.
Basis defining integrated Legendre basis on the line, a polynomial subspace of H(grad) on the line.
Basis defining Legendre basis on the line, a polynomial subspace of L^2 (a.k.a. H(vol)) on the line.
A helper class that allows iteration over some part of a Kokkos View, while allowing the calling code...