libMesh
static_condensation.h
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 #ifndef LIBMESH_STATIC_CONDENSATION_H
19 #define LIBMESH_STATIC_CONDENSATION_H
20 
21 #include "libmesh/libmesh_config.h"
22 
23 // subvectors currently only work with petsc and we rely on Eigen for local LU factorizations
24 #if defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_HAVE_PETSC)
25 
26 #include "libmesh/petsc_matrix_shell_matrix.h"
27 #include "libmesh/id_types.h"
28 #include "libmesh/libmesh_common.h"
29 #include "libmesh/dense_matrix.h"
30 #include "libmesh/variable.h"
31 #include "libmesh/sparsity_pattern.h"
32 
33 #include <unordered_map>
34 #include <memory>
35 #include <vector>
36 
37 // Warnings about stack protection
38 #include "libmesh/ignore_warnings.h"
39 #include <Eigen/Dense>
40 #include "libmesh/restore_warnings.h"
41 
42 namespace libMesh
43 {
44 class MeshBase;
45 class System;
46 class DofMap;
47 class Elem;
48 template <typename>
50 template <typename>
51 class NumericVector;
52 template <typename>
53 class Preconditioner;
56 
57 typedef Eigen::Matrix<Number, Eigen::Dynamic, Eigen::Dynamic> EigenMatrix;
58 typedef Eigen::Matrix<Number, Eigen::Dynamic, 1> EigenVector;
59 
61 {
62 public:
64  System & system,
65  const DofMap & full_dof_map,
66  StaticCondensationDofMap & reduced_dof_map);
67  virtual ~StaticCondensation();
68 
69  //
70  // SparseMatrix overrides
71  //
72 
73  virtual SparseMatrix<Number> & operator=(const SparseMatrix<Number> &) override;
74 
75  virtual SolverPackage solver_package() override;
76 
77  virtual void init(const numeric_index_type m,
78  const numeric_index_type n,
79  const numeric_index_type m_l,
80  const numeric_index_type n_l,
81  const numeric_index_type nnz = 30,
82  const numeric_index_type noz = 10,
83  const numeric_index_type blocksize = 1) override;
84 
85  virtual void init(const ParallelType type) override;
86 
87  virtual bool initialized() const override;
88 
89  virtual void clear() noexcept override;
90 
91  virtual void zero() override;
92 
93  virtual std::unique_ptr<SparseMatrix<Number>> zero_clone() const override;
94 
95  virtual std::unique_ptr<SparseMatrix<Number>> clone() const override;
96 
97  virtual void close() override;
98 
99  virtual numeric_index_type m() const override;
100 
101  virtual numeric_index_type n() const override { return this->m(); }
102 
103  virtual numeric_index_type row_start() const override;
104 
105  virtual numeric_index_type row_stop() const override;
106 
107  virtual numeric_index_type col_start() const override { return this->row_start(); }
108 
109  virtual numeric_index_type col_stop() const override { return this->row_stop(); }
110 
111  virtual void
112  set(const numeric_index_type i, const numeric_index_type j, const Number value) override;
113 
114  virtual void
115  add(const numeric_index_type i, const numeric_index_type j, const Number value) override;
116 
117  virtual void add_matrix(const DenseMatrix<Number> & dm,
118  const std::vector<numeric_index_type> & rows,
119  const std::vector<numeric_index_type> & cols) override;
120 
121  virtual void add_matrix(const DenseMatrix<Number> & dm,
122  const std::vector<numeric_index_type> & dof_indices) override;
123 
124  virtual void add(const Number a, const SparseMatrix<Number> & X) override;
125 
126  virtual Number operator()(const numeric_index_type i, const numeric_index_type j) const override;
127 
128  virtual Real l1_norm() const override;
129 
130  virtual Real linfty_norm() const override;
131 
132  virtual bool closed() const override;
133 
134  virtual void print_personal(std::ostream & os = libMesh::out) const override;
135 
136  virtual void get_diagonal(NumericVector<Number> & dest) const override;
137 
138  virtual void get_transpose(SparseMatrix<Number> & dest) const override;
139 
140  virtual void get_row(numeric_index_type i,
141  std::vector<numeric_index_type> & indices,
142  std::vector<Number> & values) const override;
143 
144  //
145  // Unique methods
146  //
147 
151  void init();
152 
157  void setup();
158 
163  void apply(const NumericVector<Number> & full_rhs, NumericVector<Number> & full_sol);
164 
165  const SparseMatrix<Number> & get_condensed_mat() const;
166 
170  void set_current_elem(const Elem & elem);
171 
176 
181 
182  virtual bool require_sparsity_pattern() const override { return false; }
183 
189 
195  void dont_condense_vars(const std::unordered_set<unsigned int> & vars);
196 
197 private:
202  static void set_local_vectors(const NumericVector<Number> & global_vector,
203  const std::vector<dof_id_type> & elem_dof_indices,
204  std::vector<Number> & elem_dof_values_vec,
205  EigenVector & elem_dof_values);
206 
212  void forward_elimination(const NumericVector<Number> & full_rhs);
213 
220  void backwards_substitution(const NumericVector<Number> & full_rhs,
221  NumericVector<Number> & full_sol);
222 
227  struct MatrixData
228  {
237 
238  // Acc LU decompositions
239  typename std::remove_const<decltype(Acc.partialPivLu())>::type AccFactor;
240  };
241 
243  std::unordered_map<dof_id_type, MatrixData> _elem_to_matrix_data;
244 
245  const MeshBase & _mesh;
249 
251  std::unique_ptr<SparseMatrix<Number>> _reduced_sys_mat;
253  std::unique_ptr<NumericVector<Number>> _reduced_sol;
257  std::unique_ptr<NumericVector<Number>> _reduced_rhs;
259  std::unique_ptr<LinearSolver<Number>> _reduced_solver;
261  // this is, in general, *not equal* to the system solution, e.g. this may correspond to the
262  // solution for the Newton *update*
263  std::unique_ptr<NumericVector<Number>> _ghosted_full_sol;
264 
268 
271 
273  std::unique_ptr<StaticCondensationPreconditioner> _scp;
274 
277 
280 
283 
288 };
289 
291 {
293  return *_reduced_sys_mat;
294 }
295 
297 {
298  libmesh_assert_msg(_reduced_solver, "Reduced system solver not built yet");
299  return *_reduced_solver;
300 }
301 
302 }
303 
304 #else
305 
306 #include "libmesh/sparse_matrix.h"
307 #include <unordered_set>
308 
309 namespace libMesh
310 {
311 class MeshBase;
312 class System;
313 class DofMap;
314 class StaticCondensationPreconditioner;
315 class StaticCondensationDofMap;
316 
317 class StaticCondensation : public SparseMatrix<Number>
318 {
319 public:
320  StaticCondensation(const MeshBase &,
321  const System &,
322  const DofMap & full_dof_map,
323  StaticCondensationDofMap & reduced_dof_map);
324 
325  const std::unordered_set<unsigned int> & uncondensed_vars() const { libmesh_not_implemented(); }
326  StaticCondensationPreconditioner & get_preconditioner() { libmesh_not_implemented(); }
328  {
329  libmesh_not_implemented();
330  }
331  virtual SolverPackage solver_package() override { libmesh_not_implemented(); }
332  virtual void init(const numeric_index_type,
333  const numeric_index_type,
334  const numeric_index_type,
335  const numeric_index_type,
336  const numeric_index_type = 30,
337  const numeric_index_type = 10,
338  const numeric_index_type = 1) override
339  {
340  libmesh_not_implemented();
341  }
342  virtual void init(ParallelType) override { libmesh_not_implemented(); }
343  virtual void clear() override { libmesh_not_implemented(); }
344  virtual void zero() override { libmesh_not_implemented(); }
345  virtual std::unique_ptr<SparseMatrix<Number>> zero_clone() const override
346  {
347  libmesh_not_implemented();
348  }
349  virtual std::unique_ptr<SparseMatrix<Number>> clone() const override
350  {
351  libmesh_not_implemented();
352  }
353  virtual void close() override { libmesh_not_implemented(); }
354  virtual numeric_index_type m() const override { libmesh_not_implemented(); }
355  virtual numeric_index_type n() const override { libmesh_not_implemented(); }
356  virtual numeric_index_type row_start() const override { libmesh_not_implemented(); }
357  virtual numeric_index_type row_stop() const override { libmesh_not_implemented(); }
358  virtual numeric_index_type col_start() const override { libmesh_not_implemented(); }
359  virtual numeric_index_type col_stop() const override { libmesh_not_implemented(); }
360  virtual void set(const numeric_index_type, const numeric_index_type, const Number) override
361  {
362  libmesh_not_implemented();
363  }
364  virtual void add(const numeric_index_type, const numeric_index_type, const Number) override
365  {
366  libmesh_not_implemented();
367  }
368  virtual void add_matrix(const DenseMatrix<Number> &,
369  const std::vector<numeric_index_type> &,
370  const std::vector<numeric_index_type> &) override
371  {
372  libmesh_not_implemented();
373  }
374  virtual void add_matrix(const DenseMatrix<Number> &,
375  const std::vector<numeric_index_type> &) override
376  {
377  libmesh_not_implemented();
378  }
379  virtual void add(const Number, const SparseMatrix<Number> &) override
380  {
381  libmesh_not_implemented();
382  }
383  virtual Number operator()(const numeric_index_type, const numeric_index_type) const override
384  {
385  libmesh_not_implemented();
386  }
387  virtual Real l1_norm() const override { libmesh_not_implemented(); }
388  virtual Real linfty_norm() const override { libmesh_not_implemented(); }
389  virtual bool closed() const override { libmesh_not_implemented(); }
390  virtual void print_personal(std::ostream & = libMesh::out) const override
391  {
392  libmesh_not_implemented();
393  }
394  virtual void get_diagonal(NumericVector<Number> &) const override { libmesh_not_implemented(); }
395  virtual void get_transpose(SparseMatrix<Number> &) const override { libmesh_not_implemented(); }
397  std::vector<numeric_index_type> &,
398  std::vector<Number> &) const override
399  {
400  libmesh_not_implemented();
401  }
402  void init() { libmesh_not_implemented(); }
403  void setup() { libmesh_not_implemented(); }
404  void apply(const NumericVector<Number> &, NumericVector<Number> &) { libmesh_not_implemented(); }
405 };
406 }
407 
408 #endif // LIBMESH_HAVE_EIGEN && LIBMESH_HAVE_PETSC
409 #endif // LIBMESH_STATIC_CONDENSATION_H
void forward_elimination(const NumericVector< Number > &full_rhs)
Takes an incoming "full" RHS from the solver, where full means the union of uncondensed and condennse...
virtual std::unique_ptr< SparseMatrix< Number > > clone() const override
virtual Number operator()(const numeric_index_type i, const numeric_index_type j) const override
virtual void close() override
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
Eigen::Matrix< Number, Eigen::Dynamic, Eigen::Dynamic > EigenMatrix
A class holding degree of freedom information pertinent to static condensation.
static void set_local_vectors(const NumericVector< Number > &global_vector, const std::vector< dof_id_type > &elem_dof_indices, std::vector< Number > &elem_dof_values_vec, EigenVector &elem_dof_values)
Retrieves the degree of freedom values from global_vector corresponding to elem_dof_indices, filling both elem_dof_values_vec and elem_dof_values.
void init()
Size the element matrices.
virtual SparseMatrix< Number > & operator=(const SparseMatrix< Number > &) override
This looks like a copy assignment operator, but note that, unlike normal copy assignment operators...
virtual std::unique_ptr< SparseMatrix< Number > > clone() const override
virtual void clear() override
Restores the SparseMatrix<T> to a pristine state.
void set_current_elem(const Elem &elem)
Set the current element.
StaticCondensationDofMap & _reduced_dof_map
virtual void zero() override
Set all entries to 0.
virtual std::unique_ptr< SparseMatrix< Number > > zero_clone() const override
void backwards_substitution(const NumericVector< Number > &full_rhs, NumericVector< Number > &full_sol)
After performing the solve with the _reduced_rhs and Schur complement matrix (_reduced_sys_mat) to de...
This class allows to use a PETSc shell matrix as a PetscMatrix.
std::unique_ptr< LinearSolver< Number > > _reduced_solver
The solver for the uncondensed degrees of freedom.
void setup()
A no-op to be consistent with shimming from the StaticCondenstionPreconditioner.
ParallelType _parallel_type
The parallel type to use for the reduced matrix.
virtual numeric_index_type row_stop() const override
Eigen::Matrix< Number, Eigen::Dynamic, 1 > EigenVector
virtual bool initialized() const override
virtual void close() override
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
virtual void get_row(numeric_index_type i, std::vector< numeric_index_type > &indices, std::vector< Number > &values) const override
Get a row from the matrix.
std::unique_ptr< NumericVector< Number > > _reduced_sol
solution for the uncondensed degrees of freedom
virtual numeric_index_type col_start() const override
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
virtual numeric_index_type m() const override
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
virtual numeric_index_type n() const override
virtual SolverPackage solver_package() override
The libMesh namespace provides an interface to certain functionality in the library.
EigenMatrix Acu
condensed-uncondensed matrix entries
EigenMatrix Auu
uncondensed-uncondensed matrix entries
dof_id_type _current_elem_id
The current element ID.
virtual Real l1_norm() const override
virtual numeric_index_type row_start() const override
This is the MeshBase class.
Definition: mesh_base.h:75
void dont_condense_vars(const std::unordered_set< unsigned int > &vars)
Add vars to the list of variables not to condense.
virtual numeric_index_type row_stop() const override
virtual bool require_sparsity_pattern() const override
virtual numeric_index_type m() const override
virtual numeric_index_type row_start() const override
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
virtual void init(const numeric_index_type, const numeric_index_type, const numeric_index_type, const numeric_index_type, const numeric_index_type=30, const numeric_index_type=10, const numeric_index_type=1) override
Initialize SparseMatrix with the specified sizes.
const std::unordered_set< unsigned int > & uncondensed_vars() const
This base class can be inherited from to provide interfaces to linear solvers from different packages...
This class provides a uniform interface for preconditioners.
virtual void get_transpose(SparseMatrix< Number > &) const override
Copies the transpose of the matrix into dest, which may be *this.
virtual void get_row(numeric_index_type, std::vector< numeric_index_type > &, std::vector< Number > &) const override
Get a row from the matrix.
virtual void add(const numeric_index_type i, const numeric_index_type j, const Number value) override
Add value to the element (i,j).
void apply(const NumericVector< Number > &full_rhs, NumericVector< Number > &full_sol)
Perform our three stages, forward_elimination(), a solve() on the condensed system, and finally a backwards_substitution()
dof_id_type numeric_index_type
Definition: id_types.h:99
virtual Real l1_norm() const override
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
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 clear() noexcept override
Restores the SparseMatrix<T> to a pristine state.
Data stored on a per-element basis used to compute element Schur complements and their applications t...
libmesh_assert(ctx)
DenseMatrix< Number > _size_one_mat
Helper data member for adding individual matrix elements.
std::unordered_map< dof_id_type, MatrixData > _elem_to_matrix_data
A map from element ID to Schur complement data.
virtual void get_diagonal(NumericVector< Number > &dest) const override
Copies the diagonal part of the matrix into dest.
virtual numeric_index_type col_stop() const override
virtual Number operator()(const numeric_index_type, const numeric_index_type) const override
virtual void add(const numeric_index_type, const numeric_index_type, const Number) override
Add value to the element (i,j).
bool _uncondensed_dofs_only
whether this matrix represents uncondensed dofs only.
virtual void print_personal(std::ostream &=libMesh::out) const override
Print the contents of the matrix to the screen in a package-personalized style, if available...
std::unique_ptr< SparseMatrix< Number > > _reduced_sys_mat
global sparse matrix for the uncondensed degrees of freedom
virtual void add_matrix(const DenseMatrix< Number > &, const std::vector< numeric_index_type > &, const std::vector< numeric_index_type > &) override
Add the full matrix dm to the SparseMatrix.
virtual void add_matrix(const DenseMatrix< Number > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols) override
Add the full matrix dm to the SparseMatrix.
virtual Real linfty_norm() const override
EigenMatrix Auc
uncondensed-condensed matrix entries
std::unique_ptr< NumericVector< Number > > _reduced_rhs
RHS corresponding to the uncondensed degrees of freedom.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
EigenMatrix Acc
condensed-condensed matrix entries
virtual void get_diagonal(NumericVector< Number > &) const override
Copies the diagonal part of the matrix into dest.
virtual Real linfty_norm() const override
OStreamProxy out
void apply(const NumericVector< Number > &, NumericVector< Number > &)
std::unique_ptr< StaticCondensationPreconditioner > _scp
Preconditioner object which will call back to us for the preconditioning action.
static const bool value
Definition: xdr_io.C:54
virtual SparseMatrix< Number > & operator=(const SparseMatrix< Number > &) override
This looks like a copy assignment operator, but note that, unlike normal copy assignment operators...
void uncondensed_dofs_only()
Sets whether this matrix represents uncondensed dofs only.
virtual std::unique_ptr< SparseMatrix< Number > > zero_clone() const override
virtual void add(const Number, const SparseMatrix< Number > &) override
Compute for scalar a, matrix X.
bool _have_cached_values
Whether we have cached values via add_XXX()
std::remove_const< decltype(Acc.partialPivLu())>::type AccFactor
virtual bool closed() const override
const SparseMatrix< Number > & get_condensed_mat() const
virtual void get_transpose(SparseMatrix< Number > &dest) const override
Copies the transpose of the matrix into dest, which may be *this.
StaticCondensation(const MeshBase &mesh, System &system, const DofMap &full_dof_map, StaticCondensationDofMap &reduced_dof_map)
virtual bool closed() const override
virtual void init(ParallelType) override
Initialize this matrix using the sparsity structure computed by dof_map.
SolverPackage
Defines an enum for various linear solver packages.
virtual SolverPackage solver_package() override
virtual void add_matrix(const DenseMatrix< Number > &, const std::vector< numeric_index_type > &) override
Same as add_matrix, but assumes the row and column maps are the same.
LinearSolver< Number > & reduced_system_solver()
virtual void zero() override
Set all entries to 0.
std::unique_ptr< NumericVector< Number > > _ghosted_full_sol
This is a ghosted representation of the full (uncondensed + condensed) solution. Note that...
StaticCondensationPreconditioner & get_preconditioner()
Get the preconditioning wrapper.
uint8_t dof_id_type
Definition: id_types.h:67
ParallelType
Defines an enum for parallel data structure types.
bool _sc_is_initialized
Whether our object has been initialized.