libMesh
static_condensation.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 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 // Forward declarations
24 namespace libMesh {
25  class Elem;
26 }
27 
28 // shell matrices currently only work with petsc,
29 // and we currently rely on Eigen for local LU factorizations
30 #if defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_HAVE_PETSC)
31 
32 #include "libmesh/petsc_matrix_shell_matrix.h"
33 #include "libmesh/id_types.h"
34 #include "libmesh/libmesh_common.h"
35 #include "libmesh/dense_matrix.h"
36 #include "libmesh/variable.h"
37 #include "libmesh/sparsity_pattern.h"
38 
39 #include <unordered_map>
40 #include <memory>
41 #include <vector>
42 
43 // Warnings about stack protection
44 #include "libmesh/ignore_warnings.h"
45 #include <Eigen/Dense>
46 #include "libmesh/restore_warnings.h"
47 
48 namespace libMesh
49 {
50 class MeshBase;
51 class System;
52 class DofMap;
53 class Elem;
54 template <typename>
56 template <typename>
57 class NumericVector;
58 template <typename>
59 class Preconditioner;
62 
63 typedef Eigen::Matrix<Number, Eigen::Dynamic, Eigen::Dynamic> EigenMatrix;
64 typedef Eigen::Matrix<Number, Eigen::Dynamic, 1> EigenVector;
65 
67 {
68 public:
70  System & system,
71  const DofMap & full_dof_map,
72  StaticCondensationDofMap & reduced_dof_map);
73  virtual ~StaticCondensation();
74 
75  //
76  // SparseMatrix overrides
77  //
78 
79  virtual SparseMatrix<Number> & operator=(const SparseMatrix<Number> &) override;
80 
81  virtual SolverPackage solver_package() override;
82 
83  virtual void init(const numeric_index_type m,
84  const numeric_index_type n,
85  const numeric_index_type m_l,
86  const numeric_index_type n_l,
87  const numeric_index_type nnz = 30,
88  const numeric_index_type noz = 10,
89  const numeric_index_type blocksize = 1) override;
90 
91  virtual void init(const ParallelType type) override;
92 
93  virtual bool initialized() const override;
94 
95  virtual void clear() noexcept override;
96 
97  virtual void zero() override;
98 
99  virtual std::unique_ptr<SparseMatrix<Number>> zero_clone() const override;
100 
101  virtual std::unique_ptr<SparseMatrix<Number>> clone() const override;
102 
103  virtual void close() override;
104 
105  virtual numeric_index_type m() const override;
106 
107  virtual numeric_index_type n() const override { return this->m(); }
108 
109  virtual numeric_index_type row_start() const override;
110 
111  virtual numeric_index_type row_stop() const override;
112 
113  virtual numeric_index_type col_start() const override { return this->row_start(); }
114 
115  virtual numeric_index_type col_stop() const override { return this->row_stop(); }
116 
117  virtual void
118  set(const numeric_index_type i, const numeric_index_type j, const Number value) override;
119 
120  virtual void
121  add(const numeric_index_type i, const numeric_index_type j, const Number value) override;
122 
123  virtual void add_matrix(const DenseMatrix<Number> & dm,
124  const std::vector<numeric_index_type> & rows,
125  const std::vector<numeric_index_type> & cols) override;
126 
127  virtual void add_matrix(const DenseMatrix<Number> & dm,
128  const std::vector<numeric_index_type> & dof_indices) override;
129 
130  virtual void add(const Number a, const SparseMatrix<Number> & X) override;
131 
132  virtual Number operator()(const numeric_index_type i, const numeric_index_type j) const override;
133 
134  virtual Real l1_norm() const override;
135 
136  virtual Real linfty_norm() const override;
137 
138  virtual bool closed() const override;
139 
140  virtual void print_personal(std::ostream & os = libMesh::out) const override;
141 
142  virtual void get_diagonal(NumericVector<Number> & dest) const override;
143 
144  virtual void get_transpose(SparseMatrix<Number> & dest) const override;
145 
146  virtual void get_row(numeric_index_type i,
147  std::vector<numeric_index_type> & indices,
148  std::vector<Number> & values) const override;
149 
150  //
151  // Unique methods
152  //
153 
157  void init();
158 
163  void setup();
164 
169  void apply(const NumericVector<Number> & full_rhs, NumericVector<Number> & full_sol);
170 
171  const SparseMatrix<Number> & get_condensed_mat() const;
172 
176  void set_current_elem(const Elem & elem);
177 
182 
187 
188  virtual bool require_sparsity_pattern() const override { return false; }
189 
195 
201  void dont_condense_vars(const std::unordered_set<unsigned int> & vars);
202 
203 private:
208  static void set_local_vectors(const NumericVector<Number> & global_vector,
209  const std::vector<dof_id_type> & elem_dof_indices,
210  std::vector<Number> & elem_dof_values_vec,
211  EigenVector & elem_dof_values);
212 
218  void forward_elimination(const NumericVector<Number> & full_rhs);
219 
226  void backwards_substitution(const NumericVector<Number> & full_rhs,
227  NumericVector<Number> & full_sol);
228 
233  struct MatrixData
234  {
243 
244  // Acc LU decompositions
245  typename std::remove_const<decltype(Acc.partialPivLu())>::type AccFactor;
246  };
247 
249  std::unordered_map<dof_id_type, MatrixData> _elem_to_matrix_data;
250 
251  const MeshBase & _mesh;
255 
257  std::unique_ptr<SparseMatrix<Number>> _reduced_sys_mat;
259  std::unique_ptr<NumericVector<Number>> _reduced_sol;
263  std::unique_ptr<NumericVector<Number>> _reduced_rhs;
265  std::unique_ptr<LinearSolver<Number>> _reduced_solver;
267  // this is, in general, *not equal* to the system solution, e.g. this may correspond to the
268  // solution for the Newton *update*
269  std::unique_ptr<NumericVector<Number>> _ghosted_full_sol;
270 
274 
277 
279  std::unique_ptr<StaticCondensationPreconditioner> _scp;
280 
283 
286 
289 
294 };
295 
297 {
299  return *_reduced_sys_mat;
300 }
301 
303 {
304  libmesh_assert_msg(_reduced_solver, "Reduced system solver not built yet");
305  return *_reduced_solver;
306 }
307 
308 }
309 
310 #else
311 
312 #include "libmesh/sparse_matrix.h"
313 #include <unordered_set>
314 
315 namespace libMesh
316 {
317 class MeshBase;
318 class System;
319 class DofMap;
320 class StaticCondensationPreconditioner;
321 class StaticCondensationDofMap;
322 
323 class StaticCondensation : public SparseMatrix<Number>
324 {
325 public:
326  StaticCondensation(const MeshBase &,
327  const System &,
328  const DofMap & full_dof_map,
329  StaticCondensationDofMap & reduced_dof_map);
330 
331  const std::unordered_set<unsigned int> & uncondensed_vars() const { libmesh_not_implemented(); }
332  StaticCondensationPreconditioner & get_preconditioner() { libmesh_not_implemented(); }
334  {
335  libmesh_not_implemented();
336  }
337  virtual SolverPackage solver_package() override { libmesh_not_implemented(); }
338  virtual void init(const numeric_index_type,
339  const numeric_index_type,
340  const numeric_index_type,
341  const numeric_index_type,
342  const numeric_index_type = 30,
343  const numeric_index_type = 10,
344  const numeric_index_type = 1) override
345  {
346  libmesh_not_implemented();
347  }
348  virtual void init(ParallelType) override { libmesh_not_implemented(); }
349  virtual void clear() override { libmesh_not_implemented(); }
350  virtual void zero() override { libmesh_not_implemented(); }
351  virtual std::unique_ptr<SparseMatrix<Number>> zero_clone() const override
352  {
353  libmesh_not_implemented();
354  }
355  virtual std::unique_ptr<SparseMatrix<Number>> clone() const override
356  {
357  libmesh_not_implemented();
358  }
359  virtual void close() override { libmesh_not_implemented(); }
360  virtual numeric_index_type m() const override { libmesh_not_implemented(); }
361  virtual numeric_index_type n() const override { libmesh_not_implemented(); }
362  virtual numeric_index_type row_start() const override { libmesh_not_implemented(); }
363  virtual numeric_index_type row_stop() const override { libmesh_not_implemented(); }
364  virtual numeric_index_type col_start() const override { libmesh_not_implemented(); }
365  virtual numeric_index_type col_stop() const override { libmesh_not_implemented(); }
366  virtual void set(const numeric_index_type, const numeric_index_type, const Number) override
367  {
368  libmesh_not_implemented();
369  }
370  virtual void add(const numeric_index_type, const numeric_index_type, const Number) override
371  {
372  libmesh_not_implemented();
373  }
374  virtual void add_matrix(const DenseMatrix<Number> &,
375  const std::vector<numeric_index_type> &,
376  const std::vector<numeric_index_type> &) override
377  {
378  libmesh_not_implemented();
379  }
380  virtual void add_matrix(const DenseMatrix<Number> &,
381  const std::vector<numeric_index_type> &) override
382  {
383  libmesh_not_implemented();
384  }
385  virtual void add(const Number, const SparseMatrix<Number> &) override
386  {
387  libmesh_not_implemented();
388  }
389  virtual Number operator()(const numeric_index_type, const numeric_index_type) const override
390  {
391  libmesh_not_implemented();
392  }
393  virtual Real l1_norm() const override { libmesh_not_implemented(); }
394  virtual Real linfty_norm() const override { libmesh_not_implemented(); }
395  virtual bool closed() const override { libmesh_not_implemented(); }
396  virtual void print_personal(std::ostream & = libMesh::out) const override
397  {
398  libmesh_not_implemented();
399  }
400  virtual void get_diagonal(NumericVector<Number> &) const override { libmesh_not_implemented(); }
401  virtual void get_transpose(SparseMatrix<Number> &) const override { libmesh_not_implemented(); }
403  std::vector<numeric_index_type> &,
404  std::vector<Number> &) const override
405  {
406  libmesh_not_implemented();
407  }
408  void init() { libmesh_not_implemented(); }
409  void setup() { libmesh_not_implemented(); }
410  void apply(const NumericVector<Number> &, NumericVector<Number> &) { libmesh_not_implemented(); }
411 
412  void set_current_elem(const Elem &) {}
413  void dont_condense_vars(const std::unordered_set<unsigned int> &) {}
414 };
415 }
416 
417 #endif // LIBMESH_HAVE_EIGEN && LIBMESH_HAVE_PETSC
418 #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.
void set_current_elem(const Elem &)
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:80
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:98
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
void dont_condense_vars(const std::unordered_set< unsigned int > &)
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:55
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.