Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/base/libmesh_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,15 @@ template <typename T>
inline bool libmesh_isinf(std::complex<T> a)
{ return (std::isinf(std::real(a)) || std::isinf(std::imag(a))); }

// std::isfinite() doesn't support complex, but we really want an
// isfinite to support Number, at least in our own namespace
template <typename T>
inline bool isfinite(std::complex<T> a)
{
using std::isfinite;
return (isfinite(std::real(a)) && isfinite(std::imag(a)));
}

// Define the value type for unknowns in simulations.
// This is either Real or Complex, depending on how
// the library was configures
Expand Down
12 changes: 12 additions & 0 deletions include/numerics/dense_matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,18 @@ T DenseMatrix<T>::transpose (const unsigned int i,
// }


template <typename T>
bool isfinite (const DenseMatrix<T> & var)
{
using std::isfinite;
using libMesh::isfinite; // for T==complex
const auto m = var.m(), n = var.n();
for (auto i : make_range(m))
for (auto j : make_range(n))
if (!isfinite(var(i,j)))
return false;
return true;
}


} // namespace libMesh
Expand Down
14 changes: 14 additions & 0 deletions include/numerics/dense_submatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,20 @@ T & DenseSubMatrix<T>::operator () (const unsigned int i,
}


template <typename T>
bool isfinite (const DenseSubMatrix<T> & var)
{
using std::isfinite;
using libMesh::isfinite; // for T==complex
const auto m = var.m(), n = var.n();
for (auto i : make_range(m))
for (auto j : make_range(n))
if (!isfinite(var(i,j)))
return false;
return true;
}


} // namespace libMesh


Expand Down
15 changes: 15 additions & 0 deletions include/numerics/dense_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,21 @@ void DenseVector<T>::get_principal_subvector (unsigned int sub_n,
dest(i) = _val[i];
}


template <typename T>
bool isfinite (const DenseVector<T> & var)
{
using std::isfinite;
using libMesh::isfinite; // for T==complex
for (auto i : make_range(var.size()))
if (!isfinite(var(i)))
return false;
return true;
}




} // namespace libMesh

#ifdef LIBMESH_HAVE_METAPHYSICL
Expand Down
14 changes: 14 additions & 0 deletions include/numerics/type_tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,20 @@ void TypeTensor<T>::print(std::ostream & os) const
#endif
}


template <typename T>
bool isfinite (const TypeTensor<T> & var)
{
using std::isfinite;
using libMesh::isfinite; // for T==complex
for (unsigned int i=0; i<LIBMESH_DIM; i++)
for (unsigned int j=0; j<LIBMESH_DIM; j++)
if (!isfinite(var(i,j)))
return false;
return true;
}


template <typename T, typename T2>
inline
TypeTensor<typename CompareTypes<T, T2>::supertype>
Expand Down
13 changes: 13 additions & 0 deletions include/numerics/type_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,19 @@ void TypeVector<T>::print(std::ostream & os) const
#endif
}


template <typename T>
bool isfinite (const TypeVector<T> & var)
{
using std::isfinite;
using libMesh::isfinite; // for T==complex
for (unsigned int i=0; i<LIBMESH_DIM; i++)
if (!isfinite(var(i)))
return false;
return true;
}


template <typename T>
struct CompareTypes<TypeVector<T>, TypeVector<T>>
{
Expand Down
7 changes: 5 additions & 2 deletions tests/libmesh_cppunit.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,tolerance)
#endif

#ifdef LIBMESH_USE_COMPLEX_NUMBERS
# define LIBMESH_ASSERT_NUMBERS_EQUAL(expected,actual,tolerance) \
# define LIBMESH_ASSERT_COMPLEX_EQUAL(expected,actual,tolerance) \
do { \
LIBMESH_ASSERT_FP_EQUAL(libMesh::libmesh_real(expected),libMesh::libmesh_real(actual),tolerance); \
LIBMESH_ASSERT_FP_EQUAL(libMesh::libmesh_imag(expected),libMesh::libmesh_imag(actual),tolerance); \
} while (0)

#ifdef LIBMESH_USE_COMPLEX_NUMBERS
# define LIBMESH_ASSERT_NUMBERS_EQUAL(expected,actual,tolerance) \
LIBMESH_ASSERT_COMPLEX_EQUAL(expected,actual,tolerance)
#else
# define LIBMESH_ASSERT_NUMBERS_EQUAL(expected,actual,tolerance) \
LIBMESH_ASSERT_FP_EQUAL(expected,actual,tolerance)
Expand Down
30 changes: 30 additions & 0 deletions tests/numerics/dense_matrix_test.C
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// libmesh includes
#include <libmesh/dense_matrix.h>
#include <libmesh/dense_submatrix.h>
#include <libmesh/dense_vector.h>

#ifdef LIBMESH_HAVE_PETSC
Expand All @@ -8,6 +9,7 @@

#include "libmesh_cppunit.h"

#include <limits>

using namespace libMesh;

Expand All @@ -20,6 +22,7 @@ public:

LIBMESH_CPPUNIT_TEST_SUITE(DenseMatrixTest);

CPPUNIT_TEST(testIsFinite);
CPPUNIT_TEST(testOuterProduct);
CPPUNIT_TEST(testSVD);
CPPUNIT_TEST(testEVDreal);
Expand All @@ -32,6 +35,33 @@ public:

private:

void testIsFinite()
{
LOG_UNIT_TEST;

DenseMatrix<Real> a(2, 2, {1, 2,
3, 4});
CPPUNIT_ASSERT(isfinite(a));

DenseVector<Real> diag = a.diagonal();
CPPUNIT_ASSERT(isfinite(diag));

DenseSubMatrix suba1(a,0,0,1,1);
CPPUNIT_ASSERT(isfinite(suba1));

DenseSubMatrix suba2(a,1,1,1,1);
CPPUNIT_ASSERT(isfinite(suba2));

a(0, 0) = std::numeric_limits<Real>::infinity();
CPPUNIT_ASSERT(!isfinite(a));
CPPUNIT_ASSERT(!isfinite(suba1));
CPPUNIT_ASSERT(isfinite(suba2));

CPPUNIT_ASSERT(isfinite(diag));
diag = a.diagonal();
CPPUNIT_ASSERT(!isfinite(diag));
}

void testOuterProduct()
{
LOG_UNIT_TEST;
Expand Down
16 changes: 16 additions & 0 deletions tests/numerics/type_tensor_test.C
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public:
CPPUNIT_TEST(testRotation);
#endif
CPPUNIT_TEST(testRowCol);
CPPUNIT_TEST(testIsFinite);
CPPUNIT_TEST(testIsZero);
CPPUNIT_TEST(testIsHPD);
#ifdef LIBMESH_HAVE_METAPHYSICL
Expand Down Expand Up @@ -91,6 +92,21 @@ private:
LIBMESH_ASSERT_FP_EQUAL(28, product(2, 2), tol);
}

void testIsFinite()
{
LOG_UNIT_TEST;

{
TensorValue<double> tensor;
CPPUNIT_ASSERT(isfinite(tensor));
}
{
TensorValue<double> tensor(0,1,0,2,3);
tensor(0,0) = std::numeric_limits<double>::infinity();
CPPUNIT_ASSERT(!isfinite(tensor));
}
}

void testIsZero()
{
LOG_UNIT_TEST;
Expand Down
Loading