libMesh
Public Member Functions | Protected Attributes | List of all members
SparseMatrixTest< DerivedClass > Class Template Reference

#include <sparse_matrix_test.h>

Inheritance diagram for SparseMatrixTest< DerivedClass >:
[legend]

Public Member Functions

void setUp ()
 
void tearDown ()
 
void setValues ()
 
void testValues ()
 
void testGetAndSet ()
 
void testReadMatlab (const std::string &filename)
 
void testReadMatlab1 ()
 
void testReadMatlab2 ()
 
void testReadMatlab4 ()
 
void testReadHDF5 ()
 
void testTransposeNorms ()
 
void testWriteAndRead ()
 
void testClone ()
 

Protected Attributes

std::string libmesh_suite_name
 
libMesh::Parallel::Communicatormy_comm = nullptr
 
std::unique_ptr< DerivedClass > matrix
 
libMesh::numeric_index_type nonsquare = 1
 
libMesh::numeric_index_type local_m
 
libMesh::numeric_index_type local_n
 
libMesh::numeric_index_type global_m
 
libMesh::numeric_index_type global_n
 
const libMesh::Real _tolerance = libMesh::TOLERANCE * libMesh::TOLERANCE
 

Detailed Description

template<class DerivedClass>
class SparseMatrixTest< DerivedClass >

Definition at line 35 of file sparse_matrix_test.h.

Member Function Documentation

◆ setUp()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::setUp ( )
inline

Definition at line 39 of file sparse_matrix_test.h.

40  {
41  // By default we'll use the whole communicator in parallel;
42  // Serial-only NumericVector subclasses will need to override
43  // this and set something else first.
44  if (!my_comm)
46 
47  matrix = std::make_unique<DerivedClass>(*my_comm);
48 
49  // Use the same even partitioning that we'll auto-deduce in matrix
50  // read, to make it easier to test parallel reads
51 
52  global_m = global_n = my_comm->size() * 5.75 - 1;
53  if (nonsquare)
54  global_n *= 1.3;
55 
57  row_start = my_comm->rank() * global_m / my_comm->size(),
58  row_stop = (my_comm->rank()+1) * global_m / my_comm->size();
60  col_start = my_comm->rank() * global_n / my_comm->size(),
61  col_stop = (my_comm->rank()+1) * global_n / my_comm->size();
62 
63  local_m = row_stop - row_start;
64  local_n = col_stop - col_start;
65 
66  // Let's just play around with locally dense blocks for now
67  matrix->init(global_m,
68  global_n,
69  local_m,
70  local_n,
71  /*nnz=*/local_n,
72  /*noz=*/5);
73  }
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
libMesh::Parallel::Communicator * my_comm
processor_id_type rank() const
libMesh::numeric_index_type local_n
processor_id_type size() const
std::unique_ptr< DerivedClass > matrix
libMesh::numeric_index_type global_m
libMesh::numeric_index_type nonsquare
libMesh::numeric_index_type global_n
libMesh::numeric_index_type local_m
uint8_t dof_id_type
Definition: id_types.h:67

◆ setValues()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::setValues ( )
inline

Definition at line 79 of file sparse_matrix_test.h.

Referenced by SparseMatrixTest< LaspackMatrix< Number > >::testClone(), SparseMatrixTest< LaspackMatrix< Number > >::testGetAndSet(), SparseMatrixTest< LaspackMatrix< Number > >::testTransposeNorms(), and SparseMatrixTest< LaspackMatrix< Number > >::testWriteAndRead().

80  {
81  std::vector<libMesh::numeric_index_type> rows(local_m);
82  std::iota(rows.begin(), rows.end(), matrix->row_start());
83  std::vector<libMesh::numeric_index_type> cols(local_n);
84  std::iota(cols.begin(), cols.end(), matrix->col_start());
85 
87 
88  for (auto i : libMesh::make_range(local_m))
89  for (auto j : libMesh::make_range(local_n))
90  local(i, j) = (i + 1) * (j + 1) * (my_comm->rank() + 1);
91 
92  matrix->zero();
93 
94  matrix->add_matrix(local, rows, cols);
95  matrix->close();
96  }
libMesh::Parallel::Communicator * my_comm
processor_id_type rank() const
libMesh::numeric_index_type local_n
void iota(ForwardIter first, ForwardIter last, T value)
Utility::iota was created back when std::iota was just an SGI STL extension.
Definition: utility.h:229
std::unique_ptr< DerivedClass > matrix
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
Defines a dense matrix for use in Finite Element-type computations.
Definition: dof_map.h:75
libMesh::numeric_index_type local_m

◆ tearDown()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::tearDown ( )
inline

Definition at line 76 of file sparse_matrix_test.h.

76 {}

◆ testClone()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testClone ( )
inline

Definition at line 259 of file sparse_matrix_test.h.

260  {
261  LOG_UNIT_TEST;
262 
263  setValues();
264 
265  // Matrix must be closed before it can be cloned.
266  matrix->close();
267 
268  {
269  // Create copy, test that it can go out of scope
270  auto copy = matrix->clone();
271 
272  // Check that matrices have the same local/global sizes
273  CPPUNIT_ASSERT_EQUAL(copy->m(), matrix->m());
274  CPPUNIT_ASSERT_EQUAL(copy->n(), matrix->n());
275  CPPUNIT_ASSERT_EQUAL(copy->local_m(), matrix->local_m());
276  CPPUNIT_ASSERT_EQUAL(copy->row_start(), matrix->row_start());
277  CPPUNIT_ASSERT_EQUAL(copy->row_stop(), matrix->row_stop());
278 
279  // Check that copy has same values as original
280  LIBMESH_ASSERT_FP_EQUAL(copy->l1_norm(), matrix->l1_norm(), _tolerance);
281  CPPUNIT_ASSERT(relative_fuzzy_equals(*matrix, *copy));
282  copy->scale(2);
283  CPPUNIT_ASSERT(!relative_fuzzy_equals(*matrix, *copy));
284  }
285 
286  {
287  // Create zero copy
288  auto zero_copy = matrix->zero_clone();
289 
290  // Check that matrices have the same local/global sizes
291  CPPUNIT_ASSERT_EQUAL(zero_copy->m(), matrix->m());
292  CPPUNIT_ASSERT_EQUAL(zero_copy->n(), matrix->n());
293  CPPUNIT_ASSERT_EQUAL(zero_copy->local_m(), matrix->local_m());
294  CPPUNIT_ASSERT_EQUAL(zero_copy->row_start(), matrix->row_start());
295  CPPUNIT_ASSERT_EQUAL(zero_copy->row_stop(), matrix->row_stop());
296 
297  // Check that zero_copy has same values as original
298  LIBMESH_ASSERT_FP_EQUAL(0.0, zero_copy->l1_norm(), _tolerance);
299  }
300  }
std::unique_ptr< DerivedClass > matrix
const libMesh::Real _tolerance
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

◆ testGetAndSet()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testGetAndSet ( )
inline

Definition at line 139 of file sparse_matrix_test.h.

140  {
141  LOG_UNIT_TEST;
142 
143  setValues();
144 
145  testValues();
146  }

◆ testReadHDF5()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testReadHDF5 ( )
inline

Definition at line 194 of file sparse_matrix_test.h.

195  {
196 #ifdef LIBMESH_HAVE_HDF5
197  LOG_UNIT_TEST;
198 
199  matrix->clear();
200  auto matrix2 = std::make_unique<DerivedClass>(*my_comm);
201  matrix->read("matrices/geom_1_extraction_op.m");
202  matrix2->read("matrices/geom_1_extraction_op.h5");
203 
204  // We need some more SparseMatrix operators, but not today
205  CPPUNIT_ASSERT(matrix->l1_norm() == matrix2->l1_norm());
206  CPPUNIT_ASSERT(matrix->linfty_norm() == matrix2->linfty_norm());
207 #endif // LIBMESH_HAVE_HDF5
208  }
std::unique_ptr< DerivedClass > matrix

◆ testReadMatlab()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testReadMatlab ( const std::string &  filename)
inline

Definition at line 149 of file sparse_matrix_test.h.

Referenced by SparseMatrixTest< LaspackMatrix< Number > >::testReadMatlab1(), SparseMatrixTest< LaspackMatrix< Number > >::testReadMatlab2(), and SparseMatrixTest< LaspackMatrix< Number > >::testReadMatlab4().

150  {
151  // Laspack doesn't handle non-square matrices)
152  if (matrix->solver_package() == libMesh::LASPACK_SOLVERS)
153  return;
154 
155  matrix->clear();
156 
157  auto matrix2 = std::make_unique<DerivedClass>(*my_comm);
158 
159  matrix->read(filename);
160 
161 #ifndef LIBMESH_HAVE_GZSTREAM
162  return;
163 #endif
164 
165  matrix2->read(std::string(filename)+".gz");
166 
167  // We need some more SparseMatrix operators, but not today
168  CPPUNIT_ASSERT(matrix->l1_norm() == matrix2->l1_norm());
169  CPPUNIT_ASSERT(matrix->linfty_norm() == matrix2->linfty_norm());
170  }
std::unique_ptr< DerivedClass > matrix

◆ testReadMatlab1()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testReadMatlab1 ( )
inline

Definition at line 173 of file sparse_matrix_test.h.

174  {
175  LOG_UNIT_TEST;
176  testReadMatlab("matrices/geom_1_extraction_op.m");
177  }
void testReadMatlab(const std::string &filename)

◆ testReadMatlab2()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testReadMatlab2 ( )
inline

Definition at line 180 of file sparse_matrix_test.h.

181  {
182  LOG_UNIT_TEST;
183  testReadMatlab("matrices/geom_2_extraction_op.m");
184  }
void testReadMatlab(const std::string &filename)

◆ testReadMatlab4()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testReadMatlab4 ( )
inline

Definition at line 187 of file sparse_matrix_test.h.

188  {
189  LOG_UNIT_TEST;
190  testReadMatlab("matrices/geom_4_extraction_op.m");
191  }
void testReadMatlab(const std::string &filename)

◆ testTransposeNorms()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testTransposeNorms ( )
inline

Definition at line 211 of file sparse_matrix_test.h.

212  {
213  LOG_UNIT_TEST;
214 
215  setValues();
216 
217  auto matrix2 = std::make_unique<DerivedClass>(*my_comm);
218  matrix->get_transpose(*matrix2);
219  LIBMESH_ASSERT_FP_EQUAL(matrix->l1_norm(), matrix2->linfty_norm(), _tolerance);
220  LIBMESH_ASSERT_FP_EQUAL(matrix2->l1_norm(), matrix->linfty_norm(), _tolerance);
221  }
std::unique_ptr< DerivedClass > matrix
const libMesh::Real _tolerance

◆ testValues()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testValues ( )
inline

Definition at line 99 of file sparse_matrix_test.h.

Referenced by SparseMatrixTest< LaspackMatrix< Number > >::testGetAndSet(), and SparseMatrixTest< LaspackMatrix< Number > >::testWriteAndRead().

100  {
101  auto functor = [this]()
102  {
103  std::vector<libMesh::numeric_index_type> cols_to_get;
104  std::vector<libMesh::Number> values;
105  const libMesh::numeric_index_type col_start =
106  matrix->col_start();
108  libMesh::make_range(matrix->row_start(),
109  matrix->row_stop()))
110  {
111  matrix->get_row(i, cols_to_get, values);
112  for (libMesh::numeric_index_type col_j :
113  libMesh::index_range(cols_to_get))
114  {
115  CPPUNIT_ASSERT_EQUAL(cols_to_get[col_j], col_start + col_j);
116  LIBMESH_ASSERT_NUMBERS_EQUAL
117  ((i - matrix->row_start() + 1) * (col_j + 1) * (my_comm->rank() + 1),
118  values[col_j], _tolerance);
119  }
120  }
121  };
122 
123 #ifdef LIBMESH_HAVE_CXX11_THREAD
124  auto num_threads = std::min(unsigned(2),
125  std::max(
126  std::thread::hardware_concurrency(),
127  unsigned(1)));
128  std::vector<std::thread> threads(num_threads);
129  for (unsigned int thread = 0; thread < num_threads; ++thread)
130  threads[thread] = std::thread(functor);
131  std::for_each(threads.begin(), threads.end(),
132  [](std::thread & x){x.join();});
133 #else
134  functor();
135 #endif
136  }
libMesh::Parallel::Communicator * my_comm
processor_id_type rank() const
dof_id_type numeric_index_type
Definition: id_types.h:99
std::unique_ptr< DerivedClass > matrix
const libMesh::Real _tolerance
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117

◆ testWriteAndRead()

template<class DerivedClass>
void SparseMatrixTest< DerivedClass >::testWriteAndRead ( )
inline

Definition at line 224 of file sparse_matrix_test.h.

225  {
226  LOG_UNIT_TEST;
227 
228  setValues();
229 
230  // If we're working with serial matrices then just print one of
231  // them so they don't step on the others' toes.
232  //
233  // Use a very short filename, because we had a bug with that and
234  // we want to test it.
235  if (matrix->n_processors() > 1 ||
236  TestCommWorld->rank() == 0)
237  matrix->print_matlab("M.m");
238 
239  matrix->clear();
240 
241  // Let's make sure we don't have any race conditions; we have
242  // multiple SparseMatrix subclasses that might be trying to read
243  // and write the same file.
244 
246 
247 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
248  // We're not supporting complex reads quite yet
249  return;
250 #endif
251 
252  matrix->read("M.m");
253 
255 
256  testValues();
257  }
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
void barrier() const
processor_id_type rank() const
std::unique_ptr< DerivedClass > matrix

Member Data Documentation

◆ _tolerance

template<class DerivedClass>
const libMesh::Real SparseMatrixTest< DerivedClass >::_tolerance = libMesh::TOLERANCE * libMesh::TOLERANCE
protected

◆ global_m

template<class DerivedClass>
libMesh::numeric_index_type SparseMatrixTest< DerivedClass >::global_m
protected

◆ global_n

template<class DerivedClass>
libMesh::numeric_index_type SparseMatrixTest< DerivedClass >::global_n
protected

◆ libmesh_suite_name

template<class DerivedClass>
std::string SparseMatrixTest< DerivedClass >::libmesh_suite_name
protected

Definition at line 304 of file sparse_matrix_test.h.

◆ local_m

template<class DerivedClass>
libMesh::numeric_index_type SparseMatrixTest< DerivedClass >::local_m
protected

◆ local_n

template<class DerivedClass>
libMesh::numeric_index_type SparseMatrixTest< DerivedClass >::local_n
protected

◆ matrix

template<class DerivedClass>
std::unique_ptr<DerivedClass> SparseMatrixTest< DerivedClass >::matrix
protected

◆ my_comm

template<class DerivedClass>
libMesh::Parallel::Communicator* SparseMatrixTest< DerivedClass >::my_comm = nullptr
protected

◆ nonsquare

template<class DerivedClass>
libMesh::numeric_index_type SparseMatrixTest< DerivedClass >::nonsquare = 1
protected

The documentation for this class was generated from the following file: