libMesh
type_tensor_test.C
Go to the documentation of this file.
1 // libmesh includes
2 #include <libmesh/tensor_value.h>
3 #include <libmesh/vector_value.h>
4 #include <libmesh/point.h>
5 
6 #include "libmesh_cppunit.h"
7 
8 
9 using namespace libMesh;
10 
11 class TypeTensorTest : public CppUnit::TestCase
12 {
13 public:
14  void setUp() {}
15 
16  void tearDown() {}
17 
18  LIBMESH_CPPUNIT_TEST_SUITE(TypeTensorTest);
19 
20 #if LIBMESH_DIM > 2
21  CPPUNIT_TEST(testInverse);
22  CPPUNIT_TEST(testLeftMultiply);
23  CPPUNIT_TEST(testRotation);
24 #endif
25  CPPUNIT_TEST(testRowCol);
26  CPPUNIT_TEST(testIsZero);
27 #ifdef LIBMESH_HAVE_METAPHYSICL
28  CPPUNIT_TEST(testReplaceAlgebraicType);
29 #endif
30  CPPUNIT_TEST_SUITE_END();
31 
32 
33 private:
34  void testInverse()
35  {
36  LOG_UNIT_TEST;
37 
38  // This random input tensor and its inverse came from Octave/Matlab:
39  // > format long e
40  // > A = rand(3)
41  // > inv(A)
42 
43  // The base class, TypeTensor, has a protected constructor. We
44  // are using the derived class, TensorValue, for our tests...
45  TensorValue<double> tensor(9.08973348886179e-01, 3.36455579239923e-01, 5.16389236893863e-01,
46  9.44156071777472e-01, 1.35610910092516e-01, 1.49881119060538e-02,
47  1.15988384086146e-01, 6.79845197685518e-03, 3.77028969454745e-01);
48 
49  TensorValue<double> inverse = tensor.inverse();
50 
51  TensorValue<double> true_inverse(-6.57484735104482e-01, 1.58926633961497e+00, 8.37330721137561e-01,
52  4.56430940967411e+00, -3.64404559823061e+00, -6.10654107858520e+00,
53  1.19965194510943e-01, -4.23210359257434e-01, 2.50483242797707e+00);
54 
55  for (unsigned i=0; i<3; ++i)
56  for (unsigned j=0; j<3; ++j)
57  LIBMESH_ASSERT_FP_EQUAL(inverse(i,j), true_inverse(i,j), 1e-12);
58  }
59 
61  {
62  LOG_UNIT_TEST;
63 
64  TensorValue<Real> tensor(1, 2, 0, 3, 4, 0);
65  VectorValue<Real> vector(5, 6, 0);
66  auto left_mult = vector * tensor;
67  auto right_mult = tensor * vector;
68  LIBMESH_ASSERT_FP_EQUAL(23, left_mult(0), 1e-12);
69  LIBMESH_ASSERT_FP_EQUAL(34, left_mult(1), 1e-12);
70  LIBMESH_ASSERT_FP_EQUAL(17, right_mult(0), 1e-12);
71  LIBMESH_ASSERT_FP_EQUAL(39, right_mult(1), 1e-12);
72  }
73 
75  {
76  LOG_UNIT_TEST;
77 
78  auto tol = TOLERANCE * TOLERANCE;
79  VectorValue<Real> a(2, 3, 4);
80  VectorValue<Real> b(5, 6, 7);
81  auto product = outer_product(a, b);
82  LIBMESH_ASSERT_FP_EQUAL(10, product(0, 0), tol);
83  LIBMESH_ASSERT_FP_EQUAL(12, product(0, 1), tol);
84  LIBMESH_ASSERT_FP_EQUAL(14, product(0, 2), tol);
85  LIBMESH_ASSERT_FP_EQUAL(15, product(1, 0), tol);
86  LIBMESH_ASSERT_FP_EQUAL(18, product(1, 1), tol);
87  LIBMESH_ASSERT_FP_EQUAL(21, product(1, 2), tol);
88  LIBMESH_ASSERT_FP_EQUAL(20, product(2, 0), tol);
89  LIBMESH_ASSERT_FP_EQUAL(24, product(2, 1), tol);
90  LIBMESH_ASSERT_FP_EQUAL(28, product(2, 2), tol);
91  }
92 
93  void testIsZero()
94  {
95  LOG_UNIT_TEST;
96 
97  {
98  TensorValue<double> tensor;
99  CPPUNIT_ASSERT(tensor.is_zero());
100  }
101  {
102  TensorValue<double> tensor(0,1,2,3,4,5,6,7,8);
103  CPPUNIT_ASSERT(!tensor.is_zero());
104  }
105  }
106 
108  {
109  LOG_UNIT_TEST;
110 
111  {
112  Point x(1, 0, 0);
113  const auto R = RealTensorValue::extrinsic_rotation_matrix(90, 0, 0);
114  auto rotated = R * x;
115  constexpr auto tol = TOLERANCE * TOLERANCE;
116  LIBMESH_ASSERT_FP_EQUAL(0, rotated(0), tol);
117  LIBMESH_ASSERT_FP_EQUAL(1, rotated(1), tol);
118  LIBMESH_ASSERT_FP_EQUAL(0, rotated(2), tol);
119 
120  const auto invR = RealTensorValue::inverse_extrinsic_rotation_matrix(90, 0, 0);
121  rotated = invR * rotated;
122  LIBMESH_ASSERT_FP_EQUAL(1, rotated(0), tol);
123  LIBMESH_ASSERT_FP_EQUAL(0, rotated(1), tol);
124  LIBMESH_ASSERT_FP_EQUAL(0, rotated(2), tol);
125  }
126 
127  {
128  Point x(1, 1, 1);
129  const auto R = RealTensorValue::extrinsic_rotation_matrix(90, 90, 90);
130  auto rotated = R * x;
131 
132  constexpr auto tol = TOLERANCE * TOLERANCE;
133  LIBMESH_ASSERT_FP_EQUAL(1, rotated(0), tol);
134  LIBMESH_ASSERT_FP_EQUAL(-1, rotated(1), tol);
135  LIBMESH_ASSERT_FP_EQUAL(1, rotated(2), tol);
136 
137  const auto invR = RealTensorValue::inverse_extrinsic_rotation_matrix(90, 90, 90);
138  rotated = invR * rotated;
139  LIBMESH_ASSERT_FP_EQUAL(1, rotated(0), tol);
140  LIBMESH_ASSERT_FP_EQUAL(1, rotated(1), tol);
141  LIBMESH_ASSERT_FP_EQUAL(1, rotated(2), tol);
142  }
143  }
144 
145  void testRowCol()
146  {
147  LOG_UNIT_TEST;
148 
150  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
151  for (unsigned int j = 0; j < LIBMESH_DIM; j++)
152  t(i, j) = Real(i * LIBMESH_DIM + j);
153 
154  constexpr Real tol = TOLERANCE * TOLERANCE;
155  for (unsigned int k = 0; k < LIBMESH_DIM; k++)
156  {
157  const auto row = t.row(k);
158  for (unsigned int l = 0; l < LIBMESH_DIM; l++)
159  LIBMESH_ASSERT_FP_EQUAL(Real(k * LIBMESH_DIM + l), row(l), tol);
160 
161  const auto col = t.column(k);
162  for (unsigned int l = 0; l < LIBMESH_DIM; l++)
163  LIBMESH_ASSERT_FP_EQUAL(Real(l * LIBMESH_DIM + k), col(l), tol);
164  }
165  }
166 
167 #ifdef LIBMESH_HAVE_METAPHYSICL
169  {
170  typedef typename MetaPhysicL::ReplaceAlgebraicType<
171  std::vector<TypeTensor<double>>,
173  typename MetaPhysicL::ValueType<std::vector<TypeTensor<double>>>::type>::type>::type
174  ReplacedType;
175  constexpr bool assertion =
176  std::is_same<ReplacedType, std::vector<TypeNTensor<3,double>>>::value;
177  CPPUNIT_ASSERT(assertion);
178  }
179 #endif
180 };
181 
static TensorValue< Real > extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg)
Generate the extrinsic rotation matrix associated with the provided Euler angles. ...
Definition: tensor_value.h:372
TypeTensor< typename CompareTypes< T, T2 >::supertype > outer_product(const TypeVector< T > &a, const TypeVector< T2 > &b)
Definition: type_tensor.h:1393
void testReplaceAlgebraicType()
static constexpr Real TOLERANCE
static TensorValue< Real > inverse_extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg)
Invert the rotation that would occur if the same angles were provided to extrinsic_rotation_matrix, e.g.
Definition: tensor_value.h:404
TypeVector< T > row(const unsigned int r) const
Definition: type_tensor.h:765
bool is_zero() const
Definition: type_tensor.h:1288
The libMesh namespace provides an interface to certain functionality in the library.
TypeVector< T > column(const unsigned int r) const
Definition: type_tensor.h:779
CPPUNIT_TEST_SUITE_REGISTRATION(TypeTensorTest)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
TypeTensor< T > inverse() const
Definition: type_tensor.h:1080
static const bool value
Definition: xdr_io.C:54
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.