deal.II version 9.8.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
tridiagonal_matrix.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2005 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13
16#include <deal.II/lac/vector.h>
17
18#include <complex>
19
21
22using namespace LAPACKSupport;
23
24template <typename number>
26 : diagonal(size, 0.)
27 , left((symmetric ? 0 : size), 0.)
28 , right(size, 0.)
30 , state(matrix)
31{}
32
33
34
35template <typename number>
36void
38{
40 diagonal.resize(size);
41 right.resize(size);
42 left.resize(symmetric ? 0 : size);
43 state = matrix;
44}
45
46
47
48template <typename number>
49bool
51{
53
54 return std::all_of(left.begin(),
55 left.end(),
57 std::all_of(diagonal.begin(),
58 diagonal.end(),
60 std::all_of(right.begin(),
61 right.end(),
63}
64
65
66
67template <typename number>
68void
70 const Vector<number> &v,
71 const bool adding) const
72{
74
75 Assert(w.size() == n(), ExcDimensionMismatch(w.size(), n()));
76 Assert(v.size() == n(), ExcDimensionMismatch(v.size(), n()));
77
78 if (n() == 0)
79 return;
80
81 // The actual loop skips the first and last row
82 const size_type e = n() - 1;
83 // Let iterators point to the first entry of each diagonal
84 typename std::vector<number>::const_iterator d = diagonal.begin();
85 typename std::vector<number>::const_iterator r = right.begin();
86 // The left diagonal starts one later or is equal to the right
87 // one for symmetric storage
88 typename std::vector<number>::const_iterator l = left.begin();
89 if (is_symmetric)
90 l = r;
91 else
92 ++l;
93
94 if (adding)
95 {
96 // Treat first row separately
97 w(0) += (*d) * v(0) + (*r) * v(1);
98 ++d;
99 ++r;
100 // All rows with three entries
101 for (size_type i = 1; i < e; ++i, ++d, ++r, ++l)
102 w(i) += (*l) * v(i - 1) + (*d) * v(i) + (*r) * v(i + 1);
103 // Last row is special again
104 w(e) += (*l) * v(e - 1) + (*d) * v(e);
105 }
106 else
107 {
108 w(0) = (*d) * v(0) + (*r) * v(1);
109 ++d;
110 ++r;
111 for (size_type i = 1; i < e; ++i, ++d, ++r, ++l)
112 w(i) = (*l) * v(i - 1) + (*d) * v(i) + (*r) * v(i + 1);
113 w(e) = (*l) * v(e - 1) + (*d) * v(e);
114 }
115}
116
117
118template <typename number>
119void
121 const Vector<number> &v) const
122{
123 vmult(w, v, /*adding = */ true);
124}
125
126
127
128template <typename number>
129void
131 const Vector<number> &v,
132 const bool adding) const
133{
135
136 Assert(w.size() == n(), ExcDimensionMismatch(w.size(), n()));
137 Assert(v.size() == n(), ExcDimensionMismatch(v.size(), n()));
138
139 if (n() == 0)
140 return;
141
142 const size_type e = n() - 1;
143 typename std::vector<number>::const_iterator d = diagonal.begin();
144 typename std::vector<number>::const_iterator r = right.begin();
145 typename std::vector<number>::const_iterator l = left.begin();
146 if (is_symmetric)
147 l = r;
148 else
149 ++l;
150
151 if (adding)
152 {
153 w(0) += (*d) * v(0) + (*l) * v(1);
154 ++d;
155 ++l;
156 for (size_type i = 1; i < e; ++i, ++d, ++r, ++l)
157 w(i) += (*l) * v(i + 1) + (*d) * v(i) + (*r) * v(i - 1);
158 w(e) += (*d) * v(e) + (*r) * v(e - 1);
159 }
160 else
161 {
162 w(0) = (*d) * v(0) + (*l) * v(1);
163 ++d;
164 ++l;
165 for (size_type i = 1; i < e; ++i, ++d, ++r, ++l)
166 w(i) = (*l) * v(i + 1) + (*d) * v(i) + (*r) * v(i - 1);
167 w(e) = (*d) * v(e) + (*r) * v(e - 1);
168 }
169}
170
171
172
173template <typename number>
174void
176 const Vector<number> &v) const
177{
178 Tvmult(w, v, true);
179}
180
181
182
183template <typename number>
184number
186 const Vector<number> &v) const
187{
189
190 const size_type e = n() - 1;
191 typename std::vector<number>::const_iterator d = diagonal.begin();
192 typename std::vector<number>::const_iterator r = right.begin();
193 typename std::vector<number>::const_iterator l = left.begin();
194 if (is_symmetric)
195 l = r;
196 else
197 ++l;
198
199 number result = w(0) * ((*d) * v(0) + (*r) * v(1));
200 ++d;
201 ++r;
202 for (size_type i = 1; i < e; ++i, ++d, ++r, ++l)
203 result += w(i) * ((*l) * v(i - 1) + (*d) * v(i) + (*r) * v(i + 1));
204 result += w(e) * ((*l) * v(e - 1) + (*d) * v(e));
205 return result;
206}
207
208
209
210template <typename number>
211number
216
217
218
219template <typename number>
220void
222{
223#ifdef DEAL_II_WITH_LAPACK
226
227 const types::blas_int nn = n();
228 types::blas_int info;
229 stev(&N,
230 &nn,
231 diagonal.data(),
232 right.data(),
233 static_cast<number *>(nullptr),
234 &one,
235 static_cast<number *>(nullptr),
236 &info);
237 Assert(info == 0, ExcInternalError());
238
240#else
241 AssertThrow(false, ExcNeedsLAPACK());
242#endif
243}
244
245
246
247template <typename number>
248number
255
256
257
258template class TridiagonalMatrix<float>;
259template class TridiagonalMatrix<double>;
260#ifdef DEAL_II_WITH_COMPLEX_VALUES
263#endif
264
LAPACKSupport::State state
void Tvmult_add(Vector< number > &w, const Vector< number > &v) const
void vmult(Vector< number > &w, const Vector< number > &v, const bool adding=false) const
size_type n() const
number matrix_norm_square(const Vector< number > &v) const
std::vector< number > diagonal
void reinit(size_type n, bool symmetric=false)
void vmult_add(Vector< number > &w, const Vector< number > &v) const
std::vector< number > right
types::global_dof_index size_type
void Tvmult(Vector< number > &w, const Vector< number > &v, const bool adding=false) const
number eigenvalue(const size_type i) const
TridiagonalMatrix(size_type n=0, bool symmetric=false)
number matrix_scalar_product(const Vector< number > &u, const Vector< number > &v) const
std::vector< number > left
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNeedsLAPACK()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcState(State arg1)
#define AssertThrow(cond, exc)
void stev(const char *, const ::types::blas_int *, number1 *, number2 *, number3 *, const ::types::blas_int *, number4 *, ::types::blas_int *)
@ matrix
Contents is actually a matrix.
@ eigenvalues
Eigenvalue vector is filled.
@ symmetric
Matrix is symmetric.
constexpr char N
constexpr types::blas_int one
constexpr bool value_is_zero(const Number &value)
Definition numbers.h:874
int blas_int