Line data Source code
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 :
19 :
20 : #ifndef LIBMESH_DENSE_MATRIX_BASE_H
21 : #define LIBMESH_DENSE_MATRIX_BASE_H
22 :
23 : // Local Includes
24 : #include "libmesh/libmesh_common.h"
25 : #include "libmesh/compare_types.h"
26 : #include "libmesh/int_range.h"
27 :
28 : // C++ includes
29 :
30 : namespace libMesh
31 : {
32 :
33 : // Forward declarations
34 : template <typename T> class DenseVectorBase;
35 : template <typename T> class DenseVector;
36 :
37 : /**
38 : * Defines an abstract dense matrix base class for use in Finite Element-type
39 : * computations. Specialized dense matrices, for example DenseSubMatrices,
40 : * can be derived from this class.
41 : *
42 : * \author John W. Peterson
43 : * \date 2003
44 : */
45 : template<typename T>
46 278114 : class DenseMatrixBase
47 : {
48 :
49 : protected:
50 : /**
51 : * Constructor. Creates a dense matrix of dimension \p m by \p n.
52 : * Protected so that there is no way the user can create one.
53 : */
54 105596279 : DenseMatrixBase(const unsigned int new_m=0,
55 106330953 : const unsigned int new_n=0) : _m(new_m), _n(new_n) {}
56 :
57 : public:
58 : /**
59 : * The 5 special functions can be defaulted for this class, as it
60 : * does not manage any memory itself.
61 : */
62 0 : DenseMatrixBase (DenseMatrixBase &&) = default;
63 840664 : DenseMatrixBase (const DenseMatrixBase &) = default;
64 262370 : DenseMatrixBase & operator= (const DenseMatrixBase &) = default;
65 : DenseMatrixBase & operator= (DenseMatrixBase &&) = default;
66 5041762 : virtual ~DenseMatrixBase() = default;
67 :
68 : /**
69 : * Set every element in the matrix to 0. You must redefine
70 : * what you mean by zeroing the matrix since it depends on
71 : * how your values are stored.
72 : */
73 : virtual void zero() = 0;
74 :
75 : /**
76 : * \returns The \p (i,j) element of the matrix.
77 : * Since internal data representations may differ, you
78 : * must redefine this function.
79 : */
80 : virtual T el(const unsigned int i,
81 : const unsigned int j) const = 0;
82 :
83 : /**
84 : * \returns The \p (i,j) element of the matrix as a writable reference.
85 : * Since internal data representations may differ, you
86 : * must redefine this function.
87 : */
88 : virtual T & el(const unsigned int i,
89 : const unsigned int j) = 0;
90 :
91 : /**
92 : * Performs the operation: (*this) <- M2 * (*this)
93 : */
94 : virtual void left_multiply (const DenseMatrixBase<T> & M2) = 0;
95 :
96 : /**
97 : * Performs the operation: (*this) <- (*this) * M3
98 : */
99 : virtual void right_multiply (const DenseMatrixBase<T> & M3) = 0;
100 :
101 : /**
102 : * \returns The row-dimension of the matrix.
103 : */
104 194200118 : unsigned int m() const { return _m; }
105 :
106 : /**
107 : * \returns The column-dimension of the matrix.
108 : */
109 163729154 : unsigned int n() const { return _n; }
110 :
111 : /**
112 : * Pretty-print the matrix, by default to \p libMesh::out.
113 : */
114 : void print(std::ostream & os = libMesh::out) const;
115 :
116 : /**
117 : * Formatted print as above but allows you to do
118 : * DenseMatrix K;
119 : * libMesh::out << K << std::endl;
120 : */
121 0 : friend std::ostream & operator << (std::ostream & os, const DenseMatrixBase<T> & m)
122 : {
123 0 : m.print(os);
124 0 : return os;
125 : }
126 :
127 : /**
128 : * Prints the matrix entries with more decimal places in
129 : * scientific notation.
130 : */
131 : void print_scientific(std::ostream & os, unsigned precision=8) const;
132 :
133 : /**
134 : * Adds \p factor to every element in the matrix.
135 : * This should only work if T += T2 * T3 is valid C++ and
136 : * if T2 is scalar. Return type is void
137 : */
138 : template <typename T2, typename T3>
139 : typename boostcopy::enable_if_c<
140 : ScalarTraits<T2>::value, void >::type
141 : add (const T2 factor,
142 : const DenseMatrixBase<T3> & mat);
143 :
144 : /**
145 : * Return the matrix diagonal
146 : */
147 : DenseVector<T> diagonal() const;
148 :
149 : protected:
150 :
151 : /**
152 : * Helper function -
153 : * Performs the computation M1 = M2 * M3 where:
154 : * M1 = (m x n)
155 : * M2 = (m x p)
156 : * M3 = (p x n)
157 : */
158 : static void multiply (DenseMatrixBase<T> & M1,
159 : const DenseMatrixBase<T> & M2,
160 : const DenseMatrixBase<T> & M3);
161 :
162 : /**
163 : * Condense-out the \p (i,j) entry of the matrix, forcing
164 : * it to take on the value \p val. This is useful in numerical
165 : * simulations for applying boundary conditions. Preserves the
166 : * symmetry of the matrix.
167 : */
168 : void condense(const unsigned int i,
169 : const unsigned int j,
170 : const T val,
171 : DenseVectorBase<T> & rhs);
172 :
173 : /**
174 : * The row dimension.
175 : */
176 : unsigned int _m;
177 :
178 : /**
179 : * The column dimension.
180 : */
181 : unsigned int _n;
182 : };
183 :
184 :
185 :
186 :
187 :
188 :
189 :
190 : template<typename T>
191 : template<typename T2, typename T3>
192 : inline
193 : typename boostcopy::enable_if_c<
194 : ScalarTraits<T2>::value, void >::type
195 : DenseMatrixBase<T>::add (const T2 factor,
196 : const DenseMatrixBase<T3> & mat)
197 : {
198 : libmesh_assert_equal_to (this->m(), mat.m());
199 : libmesh_assert_equal_to (this->n(), mat.n());
200 :
201 : for (auto j : make_range(this->n()))
202 : for (auto i : make_range(this->m()))
203 : this->el(i,j) += factor*mat.el(i,j);
204 : }
205 :
206 :
207 : } // namespace libMesh
208 :
209 : #endif // LIBMESH_DENSE_MATRIX_BASE_H
|