libMesh
diagonal_matrix.C
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 #include "libmesh/diagonal_matrix.h"
19 #include "libmesh/numeric_vector.h"
20 #include "libmesh/dense_matrix.h"
21 #include "libmesh/dof_map.h"
22 #include "libmesh/libmesh_common.h"
23 
24 
25 // C++ Includes
26 #include <memory>
27 
28 
29 namespace libMesh
30 {
31 
32 template <typename T>
34 {
36 }
37 
38 template <typename T>
41 {
42  *_diagonal = vec;
43  return *this;
44 }
45 
46 template <typename T>
49 {
50  // Don't get confused by the &&: vec is an lvalue reference; the && just
51  // indicates that we are receiving an object that is safe to move from. Note
52  // that we are not going to use std::move here because we do not have
53  // (virtual) move assignment operations defined for NumericVector sub-classes
54  _diagonal->swap(vec);
55  return *this;
56 }
57 
58 template <typename T>
59 void
61  const numeric_index_type /*n*/,
62  const numeric_index_type m_l,
63  const numeric_index_type /*n_l*/,
64  const numeric_index_type /*nnz*/,
65  const numeric_index_type /*noz*/,
66  const numeric_index_type /*blocksize*/)
67 {
68  _diagonal->init(m, m_l);
69 }
70 
71 template <typename T>
72 void
74 {
75  libmesh_assert(this->_dof_map);
76 
77  _diagonal->init(this->_dof_map->n_dofs(),
78  this->_dof_map->n_local_dofs(),
79  /*fast=*/false,
80  type);
81 }
82 
83 template <typename T>
84 void
85 DiagonalMatrix<T>::init(const NumericVector<T> & other, const bool fast)
86 {
87  _diagonal->init(other, fast);
88 }
89 
90 template <typename T>
91 void
92 DiagonalMatrix<T>::init(const DiagonalMatrix<T> & other, const bool fast)
93 {
94  init(other.diagonal(), fast);
95 }
96 
97 template <typename T>
98 void
100 {
101  _diagonal->clear();
102 }
103 
104 template <typename T>
105 void
107 {
108  _diagonal->zero();
109 }
110 
111 template <typename T>
112 std::unique_ptr<SparseMatrix<T>> DiagonalMatrix<T>::zero_clone () const
113 {
114  // Make empty copy with matching comm
115  auto mat_copy = std::make_unique<DiagonalMatrix<T>>(this->comm());
116 
117  // Initialize copy with our same nonzero structure, and explicitly
118  // zero values using fast == false.
119  mat_copy->init(*this, /*fast=*/false);
120 
121  return mat_copy;
122 }
123 
124 
125 
126 template <typename T>
127 std::unique_ptr<SparseMatrix<T>> DiagonalMatrix<T>::clone () const
128 {
129  // Make empty copy with matching comm
130  auto mat_copy = std::make_unique<DiagonalMatrix<T>>(this->comm());
131 
132  // Make copy of our diagonal
133  auto diag_copy = _diagonal->clone();
134 
135  // Swap diag_copy with diagonal in mat_copy
136  *mat_copy = std::move(*diag_copy);
137 
138  return mat_copy;
139 }
140 
141 template <typename T>
142 void
144 {
145  _diagonal->close();
146 }
147 
148 template <typename T>
151 {
152  return _diagonal->size();
153 }
154 
155 template <typename T>
158 {
159  return _diagonal->size();
160 }
161 
162 template <typename T>
165 {
166  return _diagonal->first_local_index();
167 }
168 
169 template <typename T>
172 {
173  return _diagonal->last_local_index();
174 }
175 
176 template <typename T>
179 {
180  return _diagonal->first_local_index();
181 }
182 
183 template <typename T>
186 {
187  return _diagonal->last_local_index();
188 }
189 
190 template <typename T>
191 void
193 {
194  if (i == j)
195  _diagonal->set(i, value);
196 }
197 
198 template <typename T>
199 void
201 {
202  if (i == j)
203  _diagonal->add(i, value);
204 }
205 
206 template <typename T>
207 void
209  const std::vector<numeric_index_type> & rows,
210  const std::vector<numeric_index_type> & cols)
211 {
212  auto m = dm.m();
213  auto n = dm.n();
214 
215  for (decltype(m) i = 0; i < m; ++i)
216  for (decltype(n) j = 0; j < n; ++j)
217  {
218  auto global_i = rows[i];
219  auto global_j = cols[j];
220  if (global_i == global_j)
221  _diagonal->add(global_i, dm(i, j));
222  }
223 }
224 
225 template <typename T>
226 void
228  const std::vector<numeric_index_type> & dof_indices)
229 {
230  _diagonal->add_vector(dm.diagonal(), dof_indices);
231 }
232 
233 template <typename T>
234 void
236 {
237  auto x_diagonal = _diagonal->zero_clone();
238  X.get_diagonal(*x_diagonal);
239  _diagonal->add(a, *x_diagonal);
240 }
241 
242 template <typename T>
243 T
245 {
246  if (i == j)
247  return (*_diagonal)(i);
248  else
249  return 0;
250 }
251 
252 template <typename T>
253 Real
255 {
256  return _diagonal->l1_norm();
257 }
258 
259 template <typename T>
260 Real
262 {
263  return _diagonal->linfty_norm();
264 }
265 
266 template <typename T>
267 bool
269 {
270  return _diagonal->closed();
271 }
272 
273 template <typename T>
274 void
275 DiagonalMatrix<T>::print_personal(std::ostream & os) const
276 {
277  _diagonal->print(os);
278 }
279 
280 
281 
282 template <typename T>
283 void
285 {
286  dest = *_diagonal;
287 }
288 
289 
290 
291 template <typename T>
292 void
294 {
295  auto diagonal_dest = dynamic_cast<DiagonalMatrix<T> *>(&dest);
296  if (diagonal_dest)
297  *diagonal_dest = *_diagonal;
298  else
299  libmesh_error_msg("DenseMatrix<T>::get_transpose currently only accepts another DenseMatrix<T> "
300  "as its argument");
301 }
302 
303 
304 
305 template <typename T>
306 void
308  std::vector<numeric_index_type> & indices,
309  std::vector<T> & values) const
310 {
311  indices.clear();
312  indices.push_back(i);
313  values.clear();
314  values.push_back((*_diagonal)(i));
315 }
316 
317 
318 
319 template <typename T>
320 void
321 DiagonalMatrix<T>::zero_rows(std::vector<numeric_index_type> & rows, T val/*=0*/)
322 {
323  for (auto row : rows)
324  _diagonal->set(row, val);
325 }
326 
327 template <typename T>
328 const NumericVector<T> &
330 {
331  return *_diagonal;
332 }
333 
334 template <typename T>
335 void
337 {
338  _diagonal->zero();
339 }
340 
341 template class LIBMESH_EXPORT DiagonalMatrix<Number>;
342 }
virtual numeric_index_type col_stop() const override
virtual void get_transpose(SparseMatrix< T > &dest) const override
Copies the transpose of the matrix into dest, which may be *this.
virtual void get_row(numeric_index_type i, std::vector< numeric_index_type > &indices, std::vector< T > &values) const override
Get a row from the matrix.
const NumericVector< T > & diagonal() const
DenseVector< T > diagonal() const
Return the matrix diagonal.
virtual numeric_index_type col_start() const override
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
unsigned int m() const
virtual Real l1_norm() const override
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols) override
Add the full matrix dm to the SparseMatrix.
The libMesh namespace provides an interface to certain functionality in the library.
virtual void restore_original_nonzero_pattern() override
Reset the memory storage of the matrix.
virtual void zero() override
Set all entries to 0.
virtual bool closed() const override
virtual numeric_index_type n() const override
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
virtual numeric_index_type m() const override
virtual void close() override
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
dof_id_type numeric_index_type
Definition: id_types.h:99
virtual numeric_index_type row_stop() const override
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libmesh_assert(ctx)
virtual void clear() override
Restores the SparseMatrix<T> to a pristine state.
virtual void get_diagonal(NumericVector< T > &dest) const =0
Copies the diagonal part of the matrix into dest.
DiagonalMatrix(const Parallel::Communicator &comm)
Constructor; initializes the matrix to be empty, without any structure, i.e.
virtual T operator()(const numeric_index_type i, const numeric_index_type j) const override
Diagonal matrix class whose underlying storage is a vector.
virtual void print_personal(std::ostream &os=libMesh::out) const override
Print the contents of the matrix to the screen in a package-personalized style, if available...
virtual void zero_rows(std::vector< numeric_index_type > &rows, T val=0) override
Sets all row entries to 0 then puts diag_value in the diagonal entry.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void get_diagonal(NumericVector< T > &dest) const override
Copies the diagonal part of the matrix into dest.
virtual Real linfty_norm() const override
static const bool value
Definition: xdr_io.C:54
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
DiagonalMatrix & operator=(DiagonalMatrix &&)=default
virtual void set(const numeric_index_type i, const numeric_index_type j, const T value) override
Set the element (i,j) to value.
virtual std::unique_ptr< SparseMatrix< T > > clone() const override
virtual numeric_index_type row_start() const override
std::unique_ptr< NumericVector< T > > _diagonal
Underlying diagonal matrix storage.
virtual void init(const numeric_index_type m, const numeric_index_type n, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz=30, const numeric_index_type noz=10, const numeric_index_type blocksize=1) override
Initialize SparseMatrix with the specified sizes.
unsigned int n() const
Defines a dense matrix for use in Finite Element-type computations.
Definition: dof_map.h:75
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value) override
Add value to the element (i,j).
virtual std::unique_ptr< SparseMatrix< T > > zero_clone() const override
ParallelType
Defines an enum for parallel data structure types.