libMesh
Loading...
Searching...
No Matches
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
24namespace 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
48namespace libMesh
49{
50class MeshBase;
51class System;
52class DofMap;
53class Elem;
54template <typename>
55class LinearSolver;
56template <typename>
57class NumericVector;
58template <typename>
59class Preconditioner;
60class StaticCondensationPreconditioner;
61class StaticCondensationDofMap;
62
63typedef Eigen::Matrix<Number, Eigen::Dynamic, Eigen::Dynamic> EigenMatrix;
64typedef Eigen::Matrix<Number, Eigen::Dynamic, 1> EigenVector;
65
67{
68public:
70 System & system,
71 const DofMap & full_dof_map,
72 StaticCondensationDofMap & reduced_dof_map);
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,
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
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
203private:
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
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
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
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
315namespace libMesh
316{
317class MeshBase;
318class System;
319class DofMap;
320class StaticCondensationPreconditioner;
321class StaticCondensationDofMap;
322
323class StaticCondensation : public SparseMatrix<Number>
324{
325public:
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
Defines a dense matrix for use in Finite Element-type computations.
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
This is the base class from which all geometric element types are derived.
Definition elem.h:96
This base class can be inherited from to provide interfaces to linear solvers from different packages...
This is the MeshBase class.
Definition mesh_base.h:81
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
This class allows to use a PETSc shell matrix as a PetscMatrix.
Generic sparse matrix.
A class holding degree of freedom information pertinent to static condensation.
virtual numeric_index_type row_start() const override
virtual void set(const numeric_index_type i, const numeric_index_type j, const Number value) override
Set the element (i,j) to value.
virtual numeric_index_type col_stop() const override
virtual void get_diagonal(NumericVector< Number > &dest) const override
Copies the diagonal part of the matrix into dest.
virtual Number operator()(const numeric_index_type, const numeric_index_type) const override
virtual void clear() override
clear() is called from the destructor, so it should not throw.
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,...
DenseMatrix< Number > _size_one_mat
Helper data member for adding individual matrix elements.
virtual void get_diagonal(NumericVector< Number > &) const override
Copies the diagonal part of the matrix into dest.
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...
void set_current_elem(const Elem &elem)
Set the current element.
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.
virtual void add(const Number, const SparseMatrix< Number > &) override
Compute for scalar a, matrix X.
virtual std::unique_ptr< SparseMatrix< Number > > clone() const override
dof_id_type _current_elem_id
The current element ID.
virtual void init(ParallelType) override
Initialize this matrix using the sparsity structure computed by dof_map.
virtual numeric_index_type n() const override
virtual Real l1_norm() const override
std::unique_ptr< LinearSolver< Number > > _reduced_solver
The solver for the uncondensed degrees of freedom.
virtual void clear() noexcept override
clear() is called from the destructor, so it should not throw.
virtual bool initialized() const override
ParallelType _parallel_type
The parallel type to use for the reduced matrix.
virtual numeric_index_type row_stop() const override
virtual numeric_index_type row_stop() const override
virtual void close() override
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
virtual bool require_sparsity_pattern() const override
virtual std::unique_ptr< SparseMatrix< Number > > zero_clone() const override
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 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 get_transpose(SparseMatrix< Number > &) const override
Copies the transpose of the matrix into dest, which may be *this.
virtual SparseMatrix< Number > & operator=(const SparseMatrix< Number > &) override
This looks like a copy assignment operator, but note that, unlike normal copy assignment operators,...
virtual Real l1_norm() const override
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.
virtual Real linfty_norm() const override
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.
virtual void add(const numeric_index_type, const numeric_index_type, const Number) override
Add value to the element (i,j).
virtual numeric_index_type col_start() const override
std::unique_ptr< NumericVector< Number > > _ghosted_full_sol
This is a ghosted representation of the full (uncondensed + condensed) solution. Note that.
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.
LinearSolver< Number > & reduced_system_solver()
const std::unordered_set< unsigned int > & uncondensed_vars() const
virtual numeric_index_type m() const override
void dont_condense_vars(const std::unordered_set< unsigned int > &)
virtual Real linfty_norm() const override
virtual bool closed() const override
virtual void zero() override
Set all entries to 0.
virtual std::unique_ptr< SparseMatrix< Number > > clone() const override
virtual numeric_index_type m() const override
StaticCondensationDofMap & _reduced_dof_map
bool _uncondensed_dofs_only
whether this matrix represents uncondensed dofs only.
virtual void set(const numeric_index_type, const numeric_index_type, const Number) override
Set the element (i,j) to value.
void uncondensed_dofs_only()
Sets whether this matrix represents uncondensed dofs only.
virtual std::unique_ptr< SparseMatrix< Number > > zero_clone() const override
StaticCondensationPreconditioner & get_preconditioner()
Get the preconditioning wrapper.
std::unique_ptr< NumericVector< Number > > _reduced_rhs
RHS corresponding to the uncondensed degrees of freedom.
std::unordered_map< dof_id_type, MatrixData > _elem_to_matrix_data
A map from element ID to Schur complement data.
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.
void apply(const NumericVector< Number > &, NumericVector< Number > &)
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 > &vars)
Add vars to the list of variables not to condense.
std::unique_ptr< NumericVector< Number > > _reduced_sol
solution for the uncondensed degrees of freedom
virtual void get_transpose(SparseMatrix< Number > &dest) const override
Copies the transpose of the matrix into dest, which may be *this.
virtual SolverPackage solver_package() override
virtual SparseMatrix< Number > & operator=(const SparseMatrix< Number > &) override
This looks like a copy assignment operator, but note that, unlike normal copy assignment operators,...
virtual numeric_index_type row_start() const override
bool _have_cached_values
Whether we have cached values via add_XXX()
void init()
Size the element matrices.
std::unique_ptr< StaticCondensationPreconditioner > _scp
Preconditioner object which will call back to us for the preconditioning action.
void apply(const NumericVector< Number > &full_rhs, NumericVector< Number > &full_sol)
Perform our three stages, forward_elimination(), a solve() on the condensed system,...
virtual void close() override
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
virtual void add(const numeric_index_type i, const numeric_index_type j, const Number value) override
Add value to the element (i,j).
bool _sc_is_initialized
Whether our object has been initialized.
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 void zero() override
Set all entries to 0.
virtual void get_row(numeric_index_type, std::vector< numeric_index_type > &, std::vector< Number > &) const override
Get a row from the matrix.
virtual Number operator()(const numeric_index_type i, const numeric_index_type j) const override
const SparseMatrix< Number > & get_condensed_mat() const
void setup()
A no-op to be consistent with shimming from the StaticCondenstionPreconditioner.
virtual bool closed() const override
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
MeshBase & mesh
The libMesh namespace provides an interface to certain functionality in the library.
Eigen::Matrix< Number, Eigen::Dynamic, Eigen::Dynamic > EigenMatrix
ParallelType
Defines an enum for parallel data structure types.
libmesh_assert(ctx)
OStreamProxy out
dof_id_type numeric_index_type
Definition id_types.h:99
SolverPackage
Defines an enum for various linear solver packages.
Eigen::Matrix< Number, Eigen::Dynamic, 1 > EigenVector
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Data stored on a per-element basis used to compute element Schur complements and their applications t...
std::remove_const< decltype(Acc.partialPivLu())>::type AccFactor
EigenMatrix Auu
uncondensed-uncondensed matrix entries
EigenMatrix Acc
condensed-condensed matrix entries
EigenMatrix Auc
uncondensed-condensed matrix entries
EigenMatrix Acu
condensed-uncondensed matrix entries
static const bool value
Definition xdr_io.C:55