49 #ifndef Intrepid2_TestUtils_h 50 #define Intrepid2_TestUtils_h 52 #include "Kokkos_Core.hpp" 53 #include "Kokkos_DynRankView.hpp" 63 #include "Teuchos_UnitTestHarness.hpp" 71 #ifdef KOKKOS_ENABLE_CUDA 78 template <
class Scalar>
79 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType
82 using ST = Teuchos::ScalarTraits<Scalar>;
83 return ST::magnitude(Teuchos::RelErrSmallNumber<ST::hasMachineParameters,Scalar>::smallNumber());
87 template <
class Scalar1,
class Scalar2>
88 KOKKOS_INLINE_FUNCTION
90 relErrMeetsTol(
const Scalar1 &s1,
const Scalar2 &s2,
const typename Teuchos::ScalarTraits<
typename std::common_type<Scalar1,Scalar2>::type >::magnitudeType &smallNumber,
const double &tol )
92 using Scalar =
typename std::common_type<Scalar1,Scalar2>::type;
93 const Scalar s1Abs = fabs(s1);
94 const Scalar s2Abs = fabs(s2);
95 const Scalar maxAbs = (s1Abs > s2Abs) ? s1Abs : s2Abs;
96 const Scalar relErr = fabs( s1 - s2 ) / (
smallNumber + maxAbs );
100 template <
class Scalar1,
class Scalar2>
101 KOKKOS_INLINE_FUNCTION
103 errMeetsAbsAndRelTol(
const Scalar1 &s1,
const Scalar2 &s2,
const double &relTol,
const double &absTol )
105 return fabs( s1 - s2 ) <= absTol + fabs(s1) * relTol;
108 static const double TEST_TOLERANCE_TIGHT = 1.e2 * std::numeric_limits<double>::epsilon();
111 template<
typename ScalarType,
typename DeviceType>
112 using ViewType = Kokkos::DynRankView<ScalarType,DeviceType>;
114 template<
typename ScalarType,
typename DeviceType>
115 using FixedRankViewType = Kokkos::View<ScalarType,DeviceType>;
117 template<
typename ScalarType>
118 KOKKOS_INLINE_FUNCTION
bool valuesAreSmall(
const ScalarType &a,
const ScalarType &b,
const double &epsilon)
121 return (abs(a) < epsilon) && (abs(b) < epsilon);
124 inline bool approximatelyEqual(
double a,
double b,
double epsilon)
126 const double larger_magnitude = (std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a));
127 return std::abs(a - b) <= larger_magnitude * epsilon;
130 inline bool essentiallyEqual(
double a,
double b,
double epsilon)
132 const double smaller_magnitude = (std::abs(a) > std::abs(b) ? std::abs(b) : std::abs(a));
133 return std::abs(a - b) <= smaller_magnitude * epsilon;
137 KOKKOS_INLINE_FUNCTION
double fromZeroOne(
double x_zero_one)
139 return x_zero_one * 2.0 - 1.0;
143 KOKKOS_INLINE_FUNCTION
double toZeroOne(
double x_minus_one_one)
145 return (x_minus_one_one + 1.0) / 2.0;
149 KOKKOS_INLINE_FUNCTION
double fromZeroOne_dx(
double dx_zero_one)
151 return dx_zero_one / 2.0;
155 KOKKOS_INLINE_FUNCTION
double toZeroOne_dx(
double dx_minus_one_one)
157 return dx_minus_one_one * 2.0;
160 template<
class DeviceViewType>
161 typename DeviceViewType::HostMirror getHostCopy(
const DeviceViewType &deviceView)
163 typename DeviceViewType::HostMirror hostView = Kokkos::create_mirror(deviceView);
164 Kokkos::deep_copy(hostView, deviceView);
168 template<
class BasisFamily>
169 inline Teuchos::RCP< Intrepid2::Basis<DefaultTestDeviceType,double,double> > getBasisUsingFamily(shards::CellTopology cellTopo, Intrepid2::EFunctionSpace fs,
170 int polyOrder_x,
int polyOrder_y=-1,
int polyOrder_z = -1)
172 using BasisPtr =
typename BasisFamily::BasisPtr;
177 if (cellTopo.getBaseKey() == shards::Line<>::key)
179 basis = getLineBasis<BasisFamily>(fs,polyOrder_x);
181 else if (cellTopo.getBaseKey() == shards::Quadrilateral<>::key)
183 INTREPID2_TEST_FOR_EXCEPTION(polyOrder_y < 0, std::invalid_argument,
"polyOrder_y must be specified");
184 basis = getQuadrilateralBasis<BasisFamily>(fs,polyOrder_x,polyOrder_y);
186 else if (cellTopo.getBaseKey() == shards::Triangle<>::key)
188 basis = getTriangleBasis<BasisFamily>(fs,polyOrder_x);
190 else if (cellTopo.getBaseKey() == shards::Hexahedron<>::key)
192 INTREPID2_TEST_FOR_EXCEPTION(polyOrder_y < 0, std::invalid_argument,
"polyOrder_y must be specified");
193 INTREPID2_TEST_FOR_EXCEPTION(polyOrder_z < 0, std::invalid_argument,
"polyOrder_z must be specified");
194 basis = getHexahedronBasis<BasisFamily>(fs,polyOrder_x,polyOrder_y,polyOrder_z);
196 else if (cellTopo.getBaseKey() == shards::Tetrahedron<>::key)
198 basis = getTetrahedronBasis<BasisFamily>(fs, polyOrder_x);
202 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported cell topology");
207 template<
bool defineVertexFunctions>
208 inline Teuchos::RCP< Intrepid2::Basis<DefaultTestDeviceType,double,double> > getHierarchicalBasis(shards::CellTopology cellTopo, Intrepid2::EFunctionSpace fs,
209 int polyOrder_x,
int polyOrder_y=-1,
int polyOrder_z = -1)
212 using Scalar = double;
222 return getBasisUsingFamily<BasisFamily>(cellTopo, fs, polyOrder_x, polyOrder_y, polyOrder_z);
225 template<
typename ValueType,
typename DeviceType,
class ... DimArgs>
226 inline ViewType<ValueType,DeviceType> getView(
const std::string &label, DimArgs... dims)
228 const bool allocateFadStorage = !std::is_pod<ValueType>::value;
229 if (!allocateFadStorage)
231 return ViewType<ValueType,DeviceType>(label,dims...);
240 template<
typename ValueType,
class ... DimArgs>
241 inline FixedRankViewType<
typename RankExpander<ValueType,
sizeof...(DimArgs) >::value_type,
DefaultTestDeviceType > getFixedRankView(
const std::string &label, DimArgs... dims)
243 const bool allocateFadStorage = !std::is_pod<ValueType>::value;
244 using value_type =
typename RankExpander<ValueType,
sizeof...(dims) >::value_type;
245 if (!allocateFadStorage)
247 return FixedRankViewType<value_type,DefaultTestDeviceType>(label,dims...);
261 template <
typename Po
intValueType,
typename DeviceType>
262 inline ViewType<PointValueType,DeviceType>
getInputPointsView(shards::CellTopology &cellTopo,
int numPoints_1D)
264 const ordinal_type order = numPoints_1D - 1;
266 ordinal_type spaceDim = cellTopo.getDimension();
268 ViewType<PointValueType,DeviceType> inputPoints = getView<PointValueType,DeviceType>(
"input points",numPoints,spaceDim);
274 template<
typename OutputValueType,
typename DeviceType>
275 inline ViewType<OutputValueType,DeviceType> getOutputView(Intrepid2::EFunctionSpace fs,
Intrepid2::EOperator op,
int basisCardinality,
int numPoints,
int spaceDim)
278 case Intrepid2::FUNCTION_SPACE_HGRAD:
280 case Intrepid2::OPERATOR_VALUE:
281 return getView<OutputValueType,DeviceType>(
"H^1 value output",basisCardinality,numPoints);
282 case Intrepid2::OPERATOR_GRAD:
283 return getView<OutputValueType,DeviceType>(
"H^1 derivative output",basisCardinality,numPoints,spaceDim);
284 case Intrepid2::OPERATOR_D1:
285 case Intrepid2::OPERATOR_D2:
286 case Intrepid2::OPERATOR_D3:
287 case Intrepid2::OPERATOR_D4:
288 case Intrepid2::OPERATOR_D5:
289 case Intrepid2::OPERATOR_D6:
290 case Intrepid2::OPERATOR_D7:
291 case Intrepid2::OPERATOR_D8:
292 case Intrepid2::OPERATOR_D9:
293 case Intrepid2::OPERATOR_D10:
296 return getView<OutputValueType,DeviceType>(
"H^1 derivative output",basisCardinality,numPoints,dkcard);
299 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported op/fs combination");
301 case Intrepid2::FUNCTION_SPACE_HCURL:
303 case Intrepid2::OPERATOR_VALUE:
304 return getView<OutputValueType,DeviceType>(
"H(curl) value output",basisCardinality,numPoints,spaceDim);
305 case Intrepid2::OPERATOR_CURL:
307 return getView<OutputValueType,DeviceType>(
"H(curl) derivative output",basisCardinality,numPoints);
308 else if (spaceDim == 3)
309 return getView<OutputValueType,DeviceType>(
"H(curl) derivative output",basisCardinality,numPoints,spaceDim);
311 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported op/fs combination");
313 case Intrepid2::FUNCTION_SPACE_HDIV:
315 case Intrepid2::OPERATOR_VALUE:
316 return getView<OutputValueType,DeviceType>(
"H(div) value output",basisCardinality,numPoints,spaceDim);
317 case Intrepid2::OPERATOR_DIV:
318 return getView<OutputValueType,DeviceType>(
"H(div) derivative output",basisCardinality,numPoints);
320 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported op/fs combination");
323 case Intrepid2::FUNCTION_SPACE_HVOL:
325 case Intrepid2::OPERATOR_VALUE:
326 return getView<OutputValueType,DeviceType>(
"H(vol) value output",basisCardinality,numPoints);
327 case Intrepid2::OPERATOR_D1:
328 case Intrepid2::OPERATOR_D2:
329 case Intrepid2::OPERATOR_D3:
330 case Intrepid2::OPERATOR_D4:
331 case Intrepid2::OPERATOR_D5:
332 case Intrepid2::OPERATOR_D6:
333 case Intrepid2::OPERATOR_D7:
334 case Intrepid2::OPERATOR_D8:
335 case Intrepid2::OPERATOR_D9:
336 case Intrepid2::OPERATOR_D10:
339 return getView<OutputValueType,DeviceType>(
"H(vol) derivative output",basisCardinality,numPoints,dkcard);
342 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported op/fs combination");
345 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported op/fs combination");
351 inline std::vector< std::vector<int> > getBasisTestCasesUpToDegree(
int spaceDim,
int minDegree,
int polyOrder_x,
int polyOrder_y=-1,
int polyOrder_z = -1)
353 std::vector<int> degrees(spaceDim);
354 degrees[0] = polyOrder_x;
355 if (spaceDim > 1) degrees[1] = polyOrder_y;
356 if (spaceDim > 2) degrees[2] = polyOrder_z;
358 int numCases = degrees[0];
359 for (
unsigned d=1; d<degrees.size(); d++)
361 numCases = numCases * (degrees[d] + 1 - minDegree);
363 std::vector< std::vector<int> > subBasisDegreeTestCases(numCases);
364 for (
int caseOrdinal=0; caseOrdinal<numCases; caseOrdinal++)
366 std::vector<int> subBasisDegrees(degrees.size());
367 int caseRemainder = caseOrdinal;
368 for (
int d=degrees.size()-1; d>=0; d--)
370 int subBasisDegree = caseRemainder % (degrees[d] + 1 - minDegree);
371 caseRemainder = caseRemainder / (degrees[d] + 1 - minDegree);
372 subBasisDegrees[d] = subBasisDegree + minDegree;
374 subBasisDegreeTestCases[caseOrdinal] = subBasisDegrees;
376 return subBasisDegreeTestCases;
380 template<
class Functor,
class Scalar,
int rank>
383 INTREPID2_TEST_FOR_EXCEPTION(rank !=
getFunctorRank(deviceFunctor), std::invalid_argument,
"functor rank must match the template argument");
386 ViewType<Scalar,DeviceType> view;
387 const std::string label =
"functor copy";
388 const auto &f = deviceFunctor;
392 view = getView<Scalar,DeviceType>(label);
395 view = getView<Scalar,DeviceType>(label, f.extent_int(0));
398 view = getView<Scalar,DeviceType>(label, f.extent_int(0), f.extent_int(1));
401 view = getView<Scalar,DeviceType>(label, f.extent_int(0), f.extent_int(1), f.extent_int(2));
404 view = getView<Scalar,DeviceType>(label, f.extent_int(0), f.extent_int(1), f.extent_int(2), f.extent_int(3));
407 view = getView<Scalar,DeviceType>(label, f.extent_int(0), f.extent_int(1), f.extent_int(2), f.extent_int(3), f.extent_int(4));
410 view = getView<Scalar,DeviceType>(label, f.extent_int(0), f.extent_int(1), f.extent_int(2), f.extent_int(3), f.extent_int(4), f.extent_int(5));
413 view = getView<Scalar,DeviceType>(label, f.extent_int(0), f.extent_int(1), f.extent_int(2), f.extent_int(3), f.extent_int(4), f.extent_int(5), f.extent_int(6));
416 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported functor rank");
419 int entryCount = view.size();
421 using ExecutionSpace =
typename ViewType<Scalar,DeviceType>::execution_space;
426 Kokkos::RangePolicy < ExecutionSpace > policy(0,entryCount);
427 Kokkos::parallel_for( policy,
428 KOKKOS_LAMBDA (
const int &enumerationIndex )
430 ViewIteratorScalar vi(view);
431 FunctorIteratorScalar fi(f);
433 vi.setEnumerationIndex(enumerationIndex);
434 fi.setEnumerationIndex(enumerationIndex);
440 auto hostView = Kokkos::create_mirror_view(view);
441 Kokkos::deep_copy(hostView, view);
445 template<
class FunctorType,
typename Scalar,
int rank>
446 void printFunctor(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
448 auto functorHostCopy = copyFunctorToHostView<FunctorType, Scalar, rank>(functor);
450 std::string name = (functorName ==
"") ?
"Functor" : functorName;
452 out <<
"\n******** " << name <<
" (rank " << rank <<
") ********\n";
453 out <<
"dimensions: (";
454 for (
int r=0; r<rank; r++)
456 out << functor.extent_int(r);
457 if (r<rank-1) out <<
",";
463 bool moreEntries =
true;
466 Scalar value = vi.get();
468 auto location = vi.getLocation();
469 out << functorName <<
"(";
470 for (ordinal_type i=0; i<rank; i++)
478 out <<
") " << value << std::endl;
480 moreEntries = (vi.increment() != -1);
485 template<
class FunctorType>
486 void printFunctor1(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
488 using Scalar =
typename std::remove_reference<decltype(functor(0))>::type;
489 printFunctor<FunctorType, Scalar, 1>(functor, out, functorName);
492 template<
class FunctorType>
493 void printFunctor2(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
495 using Scalar =
typename std::remove_const<typename std::remove_reference<decltype(functor(0,0))>::type>::type;
496 printFunctor<FunctorType, Scalar, 2>(functor, out, functorName);
499 template<
class FunctorType>
500 void printFunctor3(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
502 using Scalar =
typename std::remove_const<typename std::remove_reference<decltype(functor(0,0,0))>::type>::type;
503 printFunctor<FunctorType, Scalar, 3>(functor, out, functorName);
506 template<
class FunctorType>
507 void printFunctor4(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
509 using Scalar =
typename std::remove_const<typename std::remove_reference<decltype(functor(0,0,0,0))>::type>::type;
510 printFunctor<FunctorType, Scalar, 4>(functor, out, functorName);
513 template<
class FunctorType>
514 void printFunctor5(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
516 using Scalar =
typename std::remove_const<typename std::remove_reference<decltype(functor(0,0,0,0,0))>::type>::type;
517 printFunctor<FunctorType, Scalar, 5>(functor, out, functorName);
520 template<
class FunctorType>
521 void printFunctor6(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
523 using Scalar =
typename std::remove_const<typename std::remove_reference<decltype(functor(0,0,0,0,0,0))>::type>::type;
524 printFunctor<FunctorType, Scalar, 6>(functor, out, functorName);
527 template<
class FunctorType>
528 void printFunctor7(
const FunctorType &functor, std::ostream &out,
const std::string &functorName =
"")
530 using Scalar =
typename std::remove_const<typename std::remove_reference<decltype(functor(0,0,0,0,0,0,0))>::type>::type;
531 printFunctor<FunctorType, Scalar, 7>(functor, out, functorName);
535 void printView(
const View &view, std::ostream &out,
const std::string &viewName =
"")
537 using Scalar =
typename View::value_type;
538 using HostView =
typename View::HostMirror;
541 auto hostView = getHostCopy(view);
543 HostViewIteratorScalar vi(hostView);
545 bool moreEntries = (vi.nextIncrementRank() != -1);
548 Scalar value = vi.get();
550 auto location = vi.getLocation();
551 out << viewName <<
"(";
560 out <<
") " << value << std::endl;
562 moreEntries = (vi.increment() != -1);
566 template <
class FunctorType1,
class FunctorType2,
int rank,
typename Scalar=
typename FunctorType1::value_type,
class ExecutionSpace =
typename FunctorType1::execution_space>
567 typename std::enable_if< !supports_rank<FunctorType1,rank>::value,
void >::type
568 testFloatingEquality(
const FunctorType1 &functor1,
const FunctorType2 &functor2,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
569 std::string functor1Name =
"Functor 1", std::string functor2Name =
"Functor 2")
571 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"testFloatingEquality() called on FunctorType1 that does not support the specified rank.\n");
575 template <
class FunctorType1,
class FunctorType2,
int rank,
typename Scalar=
typename FunctorType1::value_type,
class ExecutionSpace =
typename FunctorType1::execution_space>
576 typename std::enable_if< supports_rank<FunctorType1,rank>::value,
void >::type
577 testFloatingEquality(
const FunctorType1 &functor1,
const FunctorType2 &functor2,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
578 std::string functor1Name =
"Functor 1", std::string functor2Name =
"Functor 2")
585 TEUCHOS_TEST_FOR_EXCEPTION(
getFunctorRank(functor1) != rank, std::invalid_argument,
"functor1 and functor2 must agree in rank");
586 TEUCHOS_TEST_FOR_EXCEPTION(
getFunctorRank(functor2) != rank, std::invalid_argument,
"functor1 and functor2 must agree in rank");
591 TEUCHOS_TEST_FOR_EXCEPTION(functor1.extent_int(i) != functor2.extent_int(i), std::invalid_argument,
592 "functor1 and functor2 must agree in size in each dimension; functor1 has extent " 593 + std::to_string(functor1.extent_int(i)) +
" in dimension " + std::to_string(i)
594 +
"; functor2 has extent " + std::to_string(functor2.extent_int(i)) );
595 entryCount *= functor1.extent_int(i);
597 if (entryCount == 0)
return;
599 ViewType<bool,ExecutionSpace> valuesMatch = getView<bool,ExecutionSpace>(
"valuesMatch", entryCount);
601 Kokkos::RangePolicy < ExecutionSpace > policy(0,entryCount);
602 Kokkos::parallel_for( policy,
603 KOKKOS_LAMBDA (
const int &enumerationIndex )
605 Functor1IteratorScalar vi1(functor1);
606 Functor2IteratorScalar vi2(functor2);
608 vi1.setEnumerationIndex(enumerationIndex);
609 vi2.setEnumerationIndex(enumerationIndex);
611 const Scalar & value1 = vi1.get();
612 const Scalar & value2 = vi2.get();
614 bool errMeetsTol = errMeetsAbsAndRelTol(value1, value2, relTol, absTol);
615 valuesMatch(enumerationIndex) = errMeetsTol;
619 int failureCount = 0;
620 Kokkos::RangePolicy<ExecutionSpace > reducePolicy(0, entryCount);
621 Kokkos::parallel_reduce( reducePolicy,
622 KOKKOS_LAMBDA(
const int &enumerationIndex,
int &reducedValue )
624 reducedValue += valuesMatch(enumerationIndex) ? 0 : 1;
627 const bool allValuesMatch = (failureCount == 0);
628 success = success && allValuesMatch;
633 auto functor1CopyHost = copyFunctorToHostView<FunctorType1,Scalar,rank>(functor1);
634 auto functor2CopyHost = copyFunctorToHostView<FunctorType2,Scalar,rank>(functor2);
636 auto valuesMatchHost = getHostCopy(valuesMatch);
642 bool moreEntries =
true;
645 bool errMeetsTol = viMatch.
get();
649 const Scalar value1 = vi1.
get();
650 const Scalar value2 = vi2.
get();
654 out <<
"At location (";
663 out <<
") " << functor1Name <<
" value != " << functor2Name <<
" value (";
664 out << value1 <<
" != " << value2 <<
"); diff is " << std::abs(value1-value2) << std::endl;
668 moreEntries = moreEntries && (vi2.
increment() != -1);
669 moreEntries = moreEntries && (viMatch.
increment() != -1);
674 template <
class ViewType,
class FunctorType>
675 void testFloatingEquality1(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
676 std::string view1Name =
"View", std::string view2Name =
"Functor")
678 testFloatingEquality<ViewType, FunctorType, 1>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
681 template <
class ViewType,
class FunctorType>
682 void testFloatingEquality2(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
683 std::string view1Name =
"View", std::string view2Name =
"Functor")
685 testFloatingEquality<ViewType, FunctorType, 2>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
688 template <
class ViewType,
class FunctorType>
689 void testFloatingEquality3(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
690 std::string view1Name =
"View", std::string view2Name =
"Functor")
692 testFloatingEquality<ViewType, FunctorType, 3>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
695 template <
class ViewType,
class FunctorType>
696 void testFloatingEquality4(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
697 std::string view1Name =
"View", std::string view2Name =
"Functor")
699 testFloatingEquality<ViewType, FunctorType, 4>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
702 template <
class ViewType,
class FunctorType>
703 void testFloatingEquality5(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
704 std::string view1Name =
"View", std::string view2Name =
"Functor")
706 testFloatingEquality<ViewType, FunctorType, 5>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
709 template <
class ViewType,
class FunctorType>
710 void testFloatingEquality6(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
711 std::string view1Name =
"View", std::string view2Name =
"Functor")
713 testFloatingEquality<ViewType, FunctorType, 6>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
716 template <
class ViewType,
class FunctorType>
717 void testFloatingEquality7(
const ViewType &view,
const FunctorType &functor,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
718 std::string view1Name =
"View", std::string view2Name =
"Functor")
720 testFloatingEquality<ViewType, FunctorType, 7>(view, functor, relTol, absTol, out, success, view1Name, view2Name);
723 template <
class ViewType1,
class ViewType2>
724 void testViewFloatingEquality(
const ViewType1 &view1,
const ViewType2 &view2,
double relTol,
double absTol, Teuchos::FancyOStream &out,
bool &success,
725 std::string view1Name =
"View 1", std::string view2Name =
"View 2")
728 TEUCHOS_TEST_FOR_EXCEPTION(view1.rank() != view2.rank(), std::invalid_argument,
"views must agree in rank");
729 for (
unsigned i=0; i<view1.rank(); i++)
731 TEUCHOS_TEST_FOR_EXCEPTION(view1.extent_int(i) != view2.extent_int(i), std::invalid_argument,
"views must agree in size in each dimension");
734 if (view1.size() == 0)
return;
736 const int rank = view1.rank();
739 case 0: testFloatingEquality<ViewType1, ViewType2, 0>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
740 case 1: testFloatingEquality<ViewType1, ViewType2, 1>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
741 case 2: testFloatingEquality<ViewType1, ViewType2, 2>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
742 case 3: testFloatingEquality<ViewType1, ViewType2, 3>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
743 case 4: testFloatingEquality<ViewType1, ViewType2, 4>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
744 case 5: testFloatingEquality<ViewType1, ViewType2, 5>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
745 case 6: testFloatingEquality<ViewType1, ViewType2, 6>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
746 case 7: testFloatingEquality<ViewType1, ViewType2, 7>(view1, view2, relTol, absTol, out, success, view1Name, view2Name);
break;
747 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unsupported rank");
753 #ifdef HAVE_INTREPID2_SACADO 754 using Sacado_Fad_DFadType = Sacado::Fad::DFad<double>;
755 #define INTREPID2_POINTSCALAR_TEST_INSTANT(GROUP_NAME, TEST_NAME) \ 757 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( GROUP_NAME, TEST_NAME, double ) \ 759 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( GROUP_NAME, TEST_NAME, Sacado_Fad_DFadType ) \ 761 #define INTREPID2_OUTPUTSCALAR_POINTSCALAR_TEST_INSTANT(GROUP_NAME, TEST_NAME) \ 763 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( GROUP_NAME, TEST_NAME, double, double ) \ 765 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( GROUP_NAME, TEST_NAME, Sacado_Fad_DFadType, Sacado_Fad_DFadType ) \ 768 #define INTREPID2_POINTSCALAR_TEST_INSTANT(GROUP_NAME, TEST_NAME) \ 770 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( GROUP_NAME, TEST_NAME, double ) \ 772 #define INTREPID2_OUTPUTSCALAR_POINTSCALAR_TEST_INSTANT(GROUP_NAME, TEST_NAME) \ 774 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( GROUP_NAME, TEST_NAME, double, double ) \ enable_if_t< M==0 > KOKKOS_INLINE_FUNCTION get() const
Stateless classes that act as factories for two families of hierarchical bases. HierarchicalBasisFami...
Teuchos::RCP< Basis< DeviceType, OutputType, PointType > > BasisPtr
Basis Pointer.
KOKKOS_INLINE_FUNCTION int increment()
Stateless class representing a family of basis functions, templated on H(vol) and H(grad) on the line...
KOKKOS_INLINE_FUNCTION Kokkos::Array< int, 7 > & getLocation()
KOKKOS_INLINE_FUNCTION ScalarType get()
SFINAE helper to detect whether a type supports a rank-integral-argument operator().
Header function for Intrepid2::Util class and other utility functions.
ViewType< Scalar, DefaultTestDeviceType >::HostMirror copyFunctorToHostView(const Functor &deviceFunctor)
Copy the values for the specified functor.
Helper to get Scalar[*+] where the number of *'s matches the given rank.
KOKKOS_INLINE_FUNCTION ordinal_type getDkCardinality(const EOperator operatorType, const ordinal_type spaceDim)
Returns multiplicities of dx, dy, and dz based on the enumeration of the partial derivative, its order and the space dimension. Inverse of the getDkEnumeration() method.
Basis defining Legendre basis on the line, a polynomial subspace of L^2 (a.k.a. H(vol)) on the line...
constexpr int MAX_FAD_DERIVATIVES_FOR_TESTS
Maximum number of derivatives to track for Fad types in tests.
EOperator
Enumeration of primitive operators available in Intrepid. Primitive operators act on reconstructed fu...
Basis defining integrated Legendre basis on the line, a polynomial subspace of H(grad) on the line...
ViewType< PointValueType, DeviceType > getInputPointsView(shards::CellTopology &cellTopo, int numPoints_1D)
Returns a DynRankView containing regularly-spaced points on the specified cell topology.
essentially, a read-only variant of ViewIterator, for a general functor (extent_int() and rank() supp...
Defines the Intrepid2::FunctorIterator class, as well as the Intrepid2::functor_returns_ref SFINAE he...
A family of basis functions, constructed from H(vol) and H(grad) bases on the line.
KOKKOS_INLINE_FUNCTION int increment()
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types...
KOKKOS_INLINE_FUNCTION bool relErrMeetsTol(const Scalar1 &s1, const Scalar2 &s2, const typename Teuchos::ScalarTraits< typename std::common_type< Scalar1, Scalar2 >::type >::magnitudeType &smallNumber, const double &tol)
Adapted from Teuchos::relErr(); for use in code that may be executed on device.
const Teuchos::ScalarTraits< Scalar >::magnitudeType smallNumber()
Use Teuchos small number determination on host; pass this to Intrepid2::relErr() on device...
A helper class that allows iteration over some part of a Kokkos View, while allowing the calling code...
enable_if_t< has_rank_method< Functor >::value, unsigned > KOKKOS_INLINE_FUNCTION getFunctorRank(const Functor &functor)
typename Kokkos::DefaultExecutionSpace::device_type DefaultTestDeviceType
Default Kokkos::Device to use for tests; depends on platform.
Header file for the abstract base class Intrepid2::Basis.