OGS
LinAlg.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <cassert>
14
15#include "BaseLib/Error.h"
16#include "LinAlgEnums.h"
17
18#ifdef USE_PETSC
19#include <petscsystypes.h>
20
21#include "PETSc/PETScVector.h"
22#endif
23
24namespace MathLib
25{
26
37namespace LinAlg
38{
39
40// Matrix or Vector
41
43template <typename MatrixOrVector>
44void copy(MatrixOrVector const& x, MatrixOrVector& y)
45{
46 y = x;
47}
48
50template <typename MatrixOrVector>
51void scale(MatrixOrVector& x, double const a)
52{
53 x *= a;
54}
55
57template <typename MatrixOrVector>
58void aypx(MatrixOrVector& y, double const a, MatrixOrVector const& x)
59{
60 y = a * y + x;
61}
62
64template <typename MatrixOrVector>
65void axpy(MatrixOrVector& y, double const a, MatrixOrVector const& x)
66{
67 y += a * x;
68}
69
71template <typename MatrixOrVector>
72void axpby(MatrixOrVector& y, double const a, double const b,
73 MatrixOrVector const& x)
74{
75 y = a * x + b * y;
76}
77
79template <typename MatrixOrVector>
80void componentwiseDivide(MatrixOrVector& w, MatrixOrVector const& x,
81 MatrixOrVector const& y);
82
84template <typename MatrixOrVector>
85double norm1(MatrixOrVector const& x);
86
88template <typename MatrixOrVector>
89double norm2(MatrixOrVector const& x);
90
92template <typename MatrixOrVector>
93double normMax(MatrixOrVector const& x);
94
95template <typename MatrixOrVector>
96double norm(MatrixOrVector const& x, MathLib::VecNormType type)
97{
98 switch (type)
99 {
101 return norm1(x);
103 return norm2(x);
105 return normMax(x);
106 default:
107 OGS_FATAL("Invalid norm type given.");
108 }
109}
110
111template <typename Matrix>
112void finalizeAssembly(Matrix& /*A*/);
113
114// Matrix and Vector
115
122template <typename Matrix, typename Vector>
123void matMult(Matrix const& A, Vector const& x, Vector& y)
124{
125 assert(&x != &y);
126 y = A * x;
127}
128
135template <typename Matrix, typename Vector>
136void matMultAdd(Matrix const& A, Vector const& v1, Vector const& v2, Vector& v3)
137{
138 assert(&v1 != &v3);
139 v3 = v2 + A * v1;
140}
141
142} // namespace LinAlg
143} // namespace MathLib
144
145// Global PETScMatrix/PETScVector //////////////////////////////////////////
146#ifdef USE_PETSC
147
148namespace MathLib
149{
150
151class PETScMatrix;
152class PETScVector;
153
154namespace LinAlg
155{
156
157// Vector
158
161void setLocalAccessibleVector(PETScVector const& x);
162
163void set(PETScVector& x, PetscScalar const a);
164
165void copy(PETScVector const& x, PETScVector& y);
166
167void scale(PETScVector& x, PetscScalar const a);
168
169// y = a*y + X
170void aypx(PETScVector& y, PetscScalar const a, PETScVector const& x);
171
172// y = a*x + y
173void axpy(PETScVector& y, PetscScalar const a, PETScVector const& x);
174
175// y = a*x + b*y
176void axpby(PETScVector& y, PetscScalar const a, PetscScalar const b,
177 PETScVector const& x);
178
179// Matrix
180
181void copy(PETScMatrix const& A, PETScMatrix& B);
182
183// A = a*A
184void scale(PETScMatrix& A, PetscScalar const a);
185
186// Y = a*Y + X
187void aypx(PETScMatrix& Y, PetscScalar const a, PETScMatrix const& X);
188
189// Y = a*X + Y
190void axpy(PETScMatrix& Y, PetscScalar const a, PETScMatrix const& X);
191
192// Matrix and Vector
193
194// v3 = A*v1 + v2
195void matMult(PETScMatrix const& A, PETScVector const& x, PETScVector& y);
196
197// y = A*x
198void matMultAdd(PETScMatrix const& A, PETScVector const& v1,
199 PETScVector const& v2, PETScVector& v3);
200
201// new_A = A^T * A
202// new_b = A^T * b
203void linearSysNormalize(PETScMatrix const& A, PETScMatrix& new_A,
204 PETScVector const& b, PETScVector& new_b);
205
206void finalizeAssembly(PETScMatrix& A);
207void finalizeAssembly(PETScVector& x);
208
209} // namespace LinAlg
210} // namespace MathLib
211
212// Sparse global EigenMatrix/EigenVector
213// //////////////////////////////////////////
214#else
215
216namespace MathLib
217{
218
219class EigenMatrix;
220class EigenVector;
221
222namespace LinAlg
223{
224
225// Vector
226
235void setLocalAccessibleVector(EigenVector const& x);
236
237void set(EigenVector& x, double const a);
238
239void copy(EigenVector const& x, EigenVector& y);
240
241void scale(EigenVector& x, double const a);
242
243// y = a*y + X
244void aypx(EigenVector& y, double const a, EigenVector const& x);
245
246// y = a*x + y
247void axpy(EigenVector& y, double const a, EigenVector const& x);
248
249// y = a*x + b*y
250void axpby(EigenVector& y, double const a, double const b,
251 EigenVector const& x);
252
253// Matrix
254
255void copy(EigenMatrix const& A, EigenMatrix& B);
256
257// A = a*A
258void scale(EigenMatrix& A, double const a);
259
260// Y = a*Y + X
261void aypx(EigenMatrix& Y, double const a, EigenMatrix const& X);
262
263// Y = a*X + Y
264void axpy(EigenMatrix& Y, double const a, EigenMatrix const& X);
265
266// Matrix and Vector
267
268// y = A*x
269void matMult(EigenMatrix const& A, EigenVector const& x, EigenVector& y);
270
271// v3 = A*v1 + v2
272void matMultAdd(EigenMatrix const& A, EigenVector const& v1,
273 EigenVector const& v2, EigenVector& v3);
274// new_A = A^T * A
275// new_b = A^T * b
276void linearSysNormalize(EigenMatrix const& A, EigenMatrix& new_A,
277 EigenVector const& b, EigenVector& new_b);
278void finalizeAssembly(EigenMatrix& x);
279void finalizeAssembly(EigenVector& A);
280
281} // namespace LinAlg
282
283} // namespace MathLib
284
285#endif
286
287namespace MathLib::LinAlg
288{
289
298template <typename VectorType>
299double computeRelativeNorm(VectorType const& x, VectorType const& y,
300 MathLib::VecNormType norm_type)
301{
302 if (norm_type == MathLib::VecNormType::INVALID)
303 {
304 OGS_FATAL("An invalid norm type has been passed");
305 }
306
307 // Stores \f$diff = x-y\f$.
308 VectorType diff;
309 MathLib::LinAlg::copy(x, diff);
310 MathLib::LinAlg::axpy(diff, -1.0, y);
311
312 const double norm_diff = MathLib::LinAlg::norm(diff, norm_type);
313
314 const double norm_x = MathLib::LinAlg::norm(x, norm_type);
315 if (norm_x > std::numeric_limits<double>::epsilon())
316 {
317 return norm_diff / norm_x;
318 }
319
320 // Both of norm_x and norm_diff are close to zero
321 if (norm_diff < std::numeric_limits<double>::epsilon())
322 {
323 return 1.0;
324 }
325
326 // Only norm_x is close to zero
327 return norm_diff / std::numeric_limits<double>::epsilon();
328}
329} // namespace MathLib::LinAlg
#define OGS_FATAL(...)
Definition Error.h:26
Declaration of class PETScVector, which provides an interface to PETSc vector routines.
double norm(MatrixOrVector const &x, MathLib::VecNormType type)
Definition LinAlg.h:96
void linearSysNormalize(PETScMatrix const &, PETScMatrix &, PETScVector const &, PETScVector &)
Definition LinAlg.cpp:170
void finalizeAssembly(PETScMatrix &A)
Definition LinAlg.cpp:198
double norm1(PETScVector const &x)
Definition LinAlg.cpp:90
double normMax(PETScVector const &x)
Definition LinAlg.cpp:110
void copy(PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:37
void componentwiseDivide(PETScVector &w, PETScVector const &x, PETScVector const &y)
Definition LinAlg.cpp:81
void setLocalAccessibleVector(PETScVector const &x)
Definition LinAlg.cpp:27
void set(PETScVector &x, PetscScalar const a)
Definition LinAlg.cpp:32
void matMult(PETScMatrix const &A, PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:149
double computeRelativeNorm(VectorType const &x, VectorType const &y, MathLib::VecNormType norm_type)
Definition LinAlg.h:299
void matMultAdd(PETScMatrix const &A, PETScVector const &v1, PETScVector const &v2, PETScVector &v3)
Definition LinAlg.cpp:159
double norm2(PETScVector const &x)
Definition LinAlg.cpp:100
void scale(PETScVector &x, PetscScalar const a)
Definition LinAlg.cpp:44
void aypx(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:50
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:57
void axpby(PETScVector &y, PetscScalar const a, PetscScalar const b, PETScVector const &x)
Definition LinAlg.cpp:64