libMesh
fuzzy_equals.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef LIBMESH_FUZZY_EQUAL_H
19 #define LIBMESH_FUZZY_EQUAL_H
20 
21 #include "libmesh/libmesh_common.h"
22 #include "libmesh/tensor_tools.h"
23 #include "libmesh/compare_types.h"
24 #include "libmesh/int_range.h"
25 
26 #ifdef LIBMESH_HAVE_METAPHYSICL
27 #include "metaphysicl/raw_type.h"
28 #endif
29 
30 namespace libMesh
31 {
36 auto
37 l1_norm(const T & var)
38 {
39  return std::abs(var);
40 }
41 
45 template <typename T,
46  typename T2,
48 auto
49 l1_norm_diff(const T & var1, const T2 & var2)
50 {
51  return l1_norm(var1 - var2);
52 }
53 
54 #ifdef LIBMESH_HAVE_METAPHYSICL
55 
62 template <typename T, typename T2>
63 bool
64 absolute_fuzzy_equals(const T & var1, const T2 & var2, const Real tol = TOLERANCE * TOLERANCE)
65 {
66  return MetaPhysicL::raw_value(l1_norm_diff(var1, var2)) <= tol;
67 }
68 
76 template <typename T, typename T2>
77 bool
78 relative_fuzzy_equals(const T & var1, const T2 & var2, const Real tol = TOLERANCE * TOLERANCE)
79 {
80  return absolute_fuzzy_equals(
81  var1,
82  var2,
83  tol * (MetaPhysicL::raw_value(l1_norm(var1)) + MetaPhysicL::raw_value(l1_norm(var2))));
84 }
85 #else
86 
93 template <typename T, typename T2>
94 bool
95 absolute_fuzzy_equals(const T & var1, const T2 & var2, const Real tol = TOLERANCE * TOLERANCE)
96 {
97  return l1_norm_diff(var1, var2) <= tol;
98 }
99 
107 template <typename T, typename T2>
108 bool
109 relative_fuzzy_equals(const T & var1, const T2 & var2, const Real tol = TOLERANCE * TOLERANCE)
110 {
111  return absolute_fuzzy_equals(var1, var2, tol * (l1_norm(var1) + l1_norm(var2)));
112 }
113 #endif
114 
115 } // namespace libMesh
116 
117 #endif // LIBMESH_FUZZY_EQUAL_H
static constexpr Real TOLERANCE
The libMesh namespace provides an interface to certain functionality in the library.
auto l1_norm(const NumericVector< T > &vec)
auto l1_norm_diff(const NumericVector< T > &vec1, const NumericVector< T > &vec2)
bool absolute_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: fuzzy_equals.h:64
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const bool value
Definition: xdr_io.C:54
bool relative_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
Definition: fuzzy_equals.h:78
static const bool value
Definition: compare_types.h:64