Skip to content

Commit

Permalink
Add fuzzy_equal complex overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
lindsayad committed Jun 25, 2024
1 parent edbdf6b commit 1468055
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
6 changes: 6 additions & 0 deletions include/utils/compare_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ struct ScalarTraits<MetaPhysicL::DualNumber<T, D, asd>>
{
static const bool value = ScalarTraits<T>::value;
};
template <typename T, typename D, bool asd>
struct RealTraits<MetaPhysicL::DualNumber<T, D, asd>>
{
static const bool value = RealTraits<T>::value;
};

} // namespace libMesh

#endif // LIBMESH_HAVE_METAPHYSICL
Expand Down
57 changes: 43 additions & 14 deletions include/utils/fuzzy_equal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,42 @@

namespace libMesh
{
/**
* Function to check whether two variables are equal within an absolute tolerance
* @param var1 The first variable to be checked
* @param var2 The second variable to be checked
* @param tol The tolerance to be used
* @return true if var1 and var2 are equal within tol
*/
template <typename T,
typename T2,
typename T3 = T,
typename std::enable_if<ScalarTraits<T>::value && ScalarTraits<T2>::value &&
ScalarTraits<T3>::value,
int>::type = 0>
bool absolute_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol = TOLERANCE * TOLERANCE);

/**
* Function to check whether both the real and imaginary parts of two complex variables are equal
* within an absolute tolerance
* @param var1 The first complex variable to be checked
* @param var2 The second complex variable to be checked
* @param tol The real tolerance to be used for comparing both real and imgainary parts
* @return true if both real and imginary parts are equal within tol
*/
template <typename T,
typename T2,
typename T3 = T,
typename std::enable_if<ScalarTraits<T3>::value, int>::type = 0>
bool
absolute_fuzzy_equal(const std::complex<T> & var1,
const std::complex<T2> & var2,
const T3 & tol = TOLERANCE * TOLERANCE)
{
return absolute_fuzzy_equal(var1.real(), var2.real(), tol) &&
absolute_fuzzy_equal(var1.imag(), var2.imag(), tol);
}

#ifdef LIBMESH_HAVE_METAPHYSICL

#include "metaphysicl/raw_type.h"
Expand All @@ -38,12 +74,12 @@ namespace libMesh
*/
template <typename T,
typename T2,
typename T3 = T,
typename T3,
typename std::enable_if<ScalarTraits<T>::value && ScalarTraits<T2>::value &&
ScalarTraits<T3>::value,
int>::type = 0>
int>::type>
bool
absolute_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol = TOLERANCE * TOLERANCE)
absolute_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol)
{
return (std::abs(MetaPhysicL::raw_value(var1) - MetaPhysicL::raw_value(var2)) <=
MetaPhysicL::raw_value(tol));
Expand Down Expand Up @@ -90,7 +126,7 @@ relative_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol = TOLERANCE
else
{
// We dare to dream
mooseAssert(var1.size() == var2.size(), "These must be the same size");
libmesh_assert(var1.size() == var2.size());
for (const auto i : index_range(var1))
if (!relative_fuzzy_equal(var1(i), var2(i), tol))
return false;
Expand All @@ -101,21 +137,14 @@ relative_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol = TOLERANCE

#else

/**
* Function to check whether two variables are equal within an absolute tolerance
* @param var1 The first variable to be checked
* @param var2 The second variable to be checked
* @param tol The tolerance to be used
* @return true if var1 and var2 are equal within tol
*/
template <typename T,
typename T2,
typename T3 = T,
typename T3,
typename std::enable_if<ScalarTraits<T>::value && ScalarTraits<T2>::value &&
ScalarTraits<T3>::value,
int>::type = 0>
int>::type>
bool
absolute_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol = TOLERANCE * TOLERANCE)
absolute_fuzzy_equal(const T & var1, const T2 & var2, const T3 & tol)
{
return (std::abs(var1 - var2) <= tol);
}
Expand Down

0 comments on commit 1468055

Please sign in to comment.