libMesh
petsc_matrix_test.C
Go to the documentation of this file.
1 #include <libmesh/libmesh_config.h>
2 
3 #ifdef LIBMESH_HAVE_PETSC
4 
5 #include <libmesh/petsc_matrix.h>
6 
7 #include "sparse_matrix_test.h"
8 
9 using namespace libMesh;
10 
11 class PetscMatrixTest : public SparseMatrixTest<PetscMatrix<Number>>
12 {
13 public:
17  this->libmesh_suite_name = "SparseMatrixTest";
18  else
19  this->libmesh_suite_name = "PetscMatrixTest";
20  }
21 
22  CPPUNIT_TEST_SUITE(PetscMatrixTest);
23 
24  SPARSEMATRIXTEST
25 
26  // Our repo's test files use PetscScalar==double
27 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
28 #ifdef LIBMESH_DEFAULT_DOUBLE_PRECISION
29  CPPUNIT_TEST(testPetscBinaryRead);
30 #endif
31 #endif
32 
33  CPPUNIT_TEST(testPetscBinaryWrite);
34 #if PETSC_RELEASE_GREATER_EQUALS(3, 23, 0)
35  CPPUNIT_TEST(testPetscCopyFromHash);
36 #endif
37  // CPPUNIT_TEST(testPetscHDF5Read);
38  // CPPUNIT_TEST(testPetscHDF5Write);
39 
40  CPPUNIT_TEST_SUITE_END();
41 
43  {
44  auto mat_to_read = std::make_unique<PetscMatrix<Number>>(*my_comm);
45 
46  // Petsc binary formats depend on sizeof(PetscInt) and
47  // sizeof(PetscScalar)
48 #if LIBMESH_DOF_ID_BYTES == 4 && LIBMESH_DEFAULT_DOUBLE_PRECISION
49  mat_to_read->read("matrices/geom_1_extraction_op.petsc32");
50 #elif LIBMESH_DOF_ID_BYTES == 8 && LIBMESH_DEFAULT_DOUBLE_PRECISION
51  mat_to_read->read("matrices/geom_1_extraction_op.petsc64");
52 #else
53  return;
54 #endif
55 
56  CPPUNIT_ASSERT_EQUAL(mat_to_read->m(), dof_id_type(27));
57  CPPUNIT_ASSERT_EQUAL(mat_to_read->n(), dof_id_type(27));
58 
59  // Our read_matlab partitioning doesn't necessarily match PETSc's
60  // MatLoad partitioning, so we'll partition a matrix to compare
61  // against manually. These particular files have bandwidth 8,
62  // so we'll ask for sufficient n_nz and n_oz to handle that
63  // regardless of partitioning.
64  auto mat_ascii_format = std::make_unique<PetscMatrix<Number>>(*my_comm);
65  mat_ascii_format->init(mat_to_read->m(), mat_to_read->n(),
66  mat_to_read->local_m(), mat_to_read->local_n(),
67  8, 7);
68 
69  mat_ascii_format->read_matlab("matrices/geom_1_extraction_op.m");
70 
71  mat_ascii_format->add(-1, *mat_to_read);
72  CPPUNIT_ASSERT_LESS(TOLERANCE, mat_ascii_format->l1_norm());
73  }
74 
75 
77  {
78  auto mat_to_read = std::make_unique<PetscMatrix<Number>>(*my_comm);
79  mat_to_read->read_matlab("matrices/geom_1_extraction_op.m");
80  mat_to_read->print_petsc_binary("geom_1_extraction_op.petsc");
81 
82  // Our read_matlab partitioning doesn't necessarily match PETSc's
83  // MatLoad partitioning, so we'll partition a matrix to compare
84  // against manually. These particular files have bandwidth 8,
85  // so we'll ask for sufficient n_nz and n_oz to handle that
86  // regardless of partitioning.
87  auto mat_reread = std::make_unique<PetscMatrix<Number>>(*my_comm);
88  mat_reread->init(mat_to_read->m(), mat_to_read->n(),
89  mat_to_read->local_m(), mat_to_read->local_n(),
90  8, 7);
91 
92  mat_reread->read_petsc_binary("geom_1_extraction_op.petsc");
93 
94  mat_to_read->add(-1, *mat_reread);
95  CPPUNIT_ASSERT_LESS(TOLERANCE, mat_to_read->l1_norm());
96  }
97 
98 
100  {
101  auto mat_to_read = std::make_unique<PetscMatrix<Number>>(*my_comm);
102  mat_to_read->read_matlab("matrices/geom_1_extraction_op.m");
103  mat_to_read->print_petsc_hdf5("geom_1_extraction_op.hdf5");
104 
105  auto mat_reread = std::make_unique<PetscMatrix<Number>>(*my_comm);
106  mat_reread->read_petsc_hdf5("geom_1_extraction_op.hdf5");
107 
108  mat_to_read->add(-1, *mat_reread);
109  CPPUNIT_ASSERT_LESS(TOLERANCE, mat_to_read->l1_norm());
110  }
111 
112 #if PETSC_RELEASE_GREATER_EQUALS(3, 23, 0)
114  {
115  PetscMatrix<Number> mat(*my_comm);
116  const numeric_index_type M = my_comm->size();
117  const numeric_index_type m = 1;
118  const numeric_index_type blocksize = 1;
119  mat.use_hash_table(true);
120  mat.init_without_preallocation(M, M, m, m, blocksize);
121  mat.finish_initialization();
122 
123  // We'll just write a dense row
124  for (const auto j : make_range(my_comm->size()))
125  mat.add(my_comm->rank(), j, my_comm->rank() * j);
126 
127  auto copy = mat.copy_from_hash();
128  for (const auto j : make_range(my_comm->size()))
129  CPPUNIT_ASSERT_EQUAL((*copy)(my_comm->rank(), j), static_cast<Number>(my_comm->rank() * j));
130  }
131 #endif
132 };
133 
135 
136 #endif
static constexpr Real TOLERANCE
void init_without_preallocation(numeric_index_type m, numeric_index_type n, numeric_index_type m_l, numeric_index_type n_l, numeric_index_type blocksize)
Perform matrix initialization steps sans preallocation.
Definition: petsc_matrix.C:135
CPPUNIT_TEST_SUITE_REGISTRATION(PetscMatrixTest)
The libMesh namespace provides an interface to certain functionality in the library.
void use_hash_table(bool use_hash)
Sets whether to use hash table assembly.
bool summarized_logs_enabled()
Definition: perf_log.h:202
dof_id_type numeric_index_type
Definition: id_types.h:99
std::unique_ptr< PetscMatrix< T > > copy_from_hash()
Creates a copy of the current hash table matrix and then performs assembly.
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value) override
Add value to the element (i,j).
Definition: petsc_matrix.C:987
libMesh::PerfLog * unitlog
Definition: driver.C:173
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
This class provides a nice interface to the PETSc C-based AIJ data structures for parallel...
Definition: petsc_matrix.h:61
void finish_initialization()
Finish up the initialization process.
Definition: petsc_matrix.C:329
uint8_t dof_id_type
Definition: id_types.h:67