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 */
Stateless classes that act as factories for two families of hierarchical bases. HierarchicalBasisFami...
Stateless class representing a family of basis functions, templated on H(vol) and H(grad) on the line...
ViewType< PointValueType > quadInputPointsView(int numPoints_1D)
Returns a View containing equispaced points on the quadrilateral.
ViewType< PointValueType > hexInputPointsView(int numPoints_1D)
Returns a View containing equispaced points on the hexahedron.
Header function for Intrepid2::Util class and other utility functions.
ViewType< PointValueType > tetInputPointsView(int numPointsBase)
Returns a View containing regularly-spaced points on the tetrahedron.
ViewType< PointValueType > triInputPointsView(int numPointsBase)
Returns a View containing regularly-spaced points on the triangle.
Basis defining Legendre basis on the line, a polynomial subspace of L^2 (a.k.a. H(vol)) on the line...
ViewType< PointValueType > lineInputPointsView(int numPoints)
Returns a View containing equispaced points on the line.
Basis defining integrated Legendre basis on the line, a polynomial subspace of H(grad) on the line...
A family of basis functions, constructed from H(vol) and H(grad) bases on the line.
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types...
A helper class that allows iteration over some part of a Kokkos View, while allowing the calling code...
Header file for the abstract base class Intrepid2::Basis.