ExaDG
Loading...
Searching...
No Matches
linear_algebra.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef INCLUDE_EXADG_FLUID_STRUCTURE_INTERACTION_ACCELERATION_SCHEMES_LINEAR_ALGEBRA_H_
23#define INCLUDE_EXADG_FLUID_STRUCTURE_INTERACTION_ACCELERATION_SCHEMES_LINEAR_ALGEBRA_H_
24
25// C/C++
26#include <vector>
27
28// deal.II
29#include <deal.II/base/exceptions.h>
30
31namespace ExaDG
32{
33namespace FSI
34{
35/*
36 * Own implementation of matrix class.
37 */
38template<typename Number>
39class Matrix
40{
41public:
42 // Constructor.
43 Matrix(unsigned int const size) : M(size)
44 {
45 data.resize(M * M);
46
47 init();
48 }
49
50 void
51 init()
52 {
53 for(unsigned int i = 0; i < M; ++i)
54 for(unsigned int j = 0; j < M; ++j)
55 data[i * M + j] = Number(0.0);
56 }
57
58 Number
59 get(unsigned int const i, unsigned int const j) const
60 {
61 AssertThrow(i < M and j < M, dealii::ExcMessage("Index exceeds matrix dimensions."));
62
63 return data[i * M + j];
64 }
65
66 void
67 set(Number const value, unsigned int const i, unsigned int const j)
68 {
69 AssertThrow(i < M and j < M, dealii::ExcMessage("Index exceeds matrix dimensions."));
70
71 data[i * M + j] = value;
72 }
73
74private:
75 // number of rows and columns of matrix
76 unsigned int const M;
77 std::vector<Number> data;
78};
79
80template<typename VectorType, typename Number>
81void
82compute_QR_decomposition(std::vector<VectorType> & Q, Matrix<Number> & R, Number const eps = 1.e-2)
83{
84 for(unsigned int i = 0; i < Q.size(); ++i)
85 {
86 Number const norm_initial = Number(Q[i].l2_norm());
87
88 // orthogonalize
89 for(unsigned int j = 0; j < i; ++j)
90 {
91 Number r_ji = Q[j] * Q[i];
92 R.set(r_ji, j, i);
93 Q[i].add(-r_ji, Q[j]);
94 }
95
96 // normalize or drop if linear dependent
97 Number r_ii = Number(Q[i].l2_norm());
98 if(r_ii < eps * norm_initial)
99 {
100 Q[i] = 0.0;
101 for(unsigned int j = 0; j < i; ++j)
102 R.set(0.0, j, i);
103 R.set(1.0, i, i);
104 }
105 else
106 {
107 R.set(r_ii, i, i);
108 Q[i] *= 1. / r_ii;
109 }
110 }
111}
112
113/*
114 * Matrix has to be upper triangular with d_ii != 0 for all 0 <= i < n
115 */
116template<typename Number>
117void
118backward_substitution(Matrix<Number> const & matrix,
119 std::vector<Number> & dst,
120 std::vector<Number> const & rhs)
121{
122 int const n = dst.size();
123
124 for(int i = n - 1; i >= 0; --i)
125 {
126 double value = rhs[i];
127 for(int j = i + 1; j < n; ++j)
128 {
129 value -= matrix.get(i, j) * dst[j];
130 }
131
132 dst[i] = value / matrix.get(i, i);
133 }
134}
135
136template<typename Number, typename VectorType>
137void
138backward_substitution_multiple_rhs(Matrix<Number> const & matrix,
139 std::vector<VectorType> & dst,
140 std::vector<VectorType> const & rhs)
141{
142 int const n = dst.size();
143
144 for(int i = n - 1; i >= 0; --i)
145 {
146 VectorType value = rhs[i];
147 for(int j = i + 1; j < n; ++j)
148 {
149 value.add(-matrix.get(i, j), dst[j]);
150 }
151
152 dst[i].equ(1.0 / matrix.get(i, i), value);
153 }
154}
155
156template<typename VectorType>
157void
158inv_jacobian_times_residual(VectorType & b,
159 std::vector<std::shared_ptr<std::vector<VectorType>>> const & D_history,
160 std::vector<std::shared_ptr<std::vector<VectorType>>> const & R_history,
161 std::vector<std::shared_ptr<std::vector<VectorType>>> const & Z_history,
162 VectorType const & residual)
163{
164 VectorType a = residual;
165
166 // reset
167 b = 0.0;
168
169 for(int idx = Z_history.size() - 1; idx >= 0; --idx)
170 {
171 std::shared_ptr<std::vector<VectorType>> D = D_history[idx];
172 std::shared_ptr<std::vector<VectorType>> R = R_history[idx];
173 std::shared_ptr<std::vector<VectorType>> Z = Z_history[idx];
174
175 int const k = Z->size();
176 std::vector<double> Z_times_a(k, 0.0);
177 for(int i = 0; i < k; ++i)
178 Z_times_a[i] = (*Z)[i] * a;
179
180 // add to b
181 for(int i = 0; i < k; ++i)
182 b.add(Z_times_a[i], (*D)[i]);
183
184 // add to a
185 for(int i = 0; i < k; ++i)
186 a.add(-Z_times_a[i], (*R)[i]);
187 }
188}
189
190} // namespace FSI
191} // namespace ExaDG
192
193#endif /* INCLUDE_EXADG_FLUID_STRUCTURE_INTERACTION_ACCELERATION_SCHEMES_LINEAR_ALGEBRA_H_ */
Definition linear_algebra.h:40
Definition driver.cpp:33