OGS
LinAlg.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <cassert>
7
8#include "BaseLib/Error.h"
9#include "LinAlgEnums.h"
10
11#ifdef USE_PETSC
12#include <petscsystypes.h>
13
14#include "PETSc/PETScVector.h"
15#endif
16
17namespace MathLib
18{
19
30namespace LinAlg
31{
32
33// Matrix or Vector
34
36template <typename MatrixOrVector>
37void copy(MatrixOrVector const& x, MatrixOrVector& y)
38{
39 y = x;
40}
41
43template <typename MatrixOrVector>
44void scale(MatrixOrVector& x, double const a)
45{
46 x *= a;
47}
48
50template <typename MatrixOrVector>
51void aypx(MatrixOrVector& y, double const a, MatrixOrVector const& x)
52{
53 y = a * y + x;
54}
55
57template <typename MatrixOrVector>
58void axpy(MatrixOrVector& y, double const a, MatrixOrVector const& x)
59{
60 y += a * x;
61}
62
64template <typename MatrixOrVector>
65void axpby(MatrixOrVector& y, double const a, double const b,
66 MatrixOrVector const& x)
67{
68 y = a * x + b * y;
69}
70
72template <typename MatrixOrVector>
73void componentwiseDivide(MatrixOrVector& w, MatrixOrVector const& x,
74 MatrixOrVector const& y);
75
77template <typename MatrixOrVector>
78double norm1(MatrixOrVector const& x);
79
81template <typename MatrixOrVector>
82double norm2(MatrixOrVector const& x);
83
85template <typename MatrixOrVector>
86double normMax(MatrixOrVector const& x);
87
88template <typename MatrixOrVector>
89double norm(MatrixOrVector const& x, MathLib::VecNormType type)
90{
91 switch (type)
92 {
94 return norm1(x);
96 return norm2(x);
98 return normMax(x);
99 default:
100 OGS_FATAL("Invalid norm type given.");
101 }
102}
103
104template <typename Matrix>
105void finalizeAssembly(Matrix& /*A*/);
106
107// Matrix and Vector
108
115template <typename Matrix, typename Vector>
116void matMult(Matrix const& A, Vector const& x, Vector& y)
117{
118 assert(&x != &y);
119 y = A * x;
120}
121
128template <typename Matrix, typename Vector>
129void matMultAdd(Matrix const& A, Vector const& v1, Vector const& v2, Vector& v3)
130{
131 assert(&v1 != &v3);
132 v3 = v2 + A * v1;
133}
134
135} // namespace LinAlg
136} // namespace MathLib
137
138// Global PETScMatrix/PETScVector //////////////////////////////////////////
139#ifdef USE_PETSC
140
141namespace MathLib
142{
143
144class PETScMatrix;
145class PETScVector;
146
147namespace LinAlg
148{
149
150// Vector
151
154void setLocalAccessibleVector(PETScVector const& x);
155
156void set(PETScVector& x, PetscScalar const a);
157
158void copy(PETScVector const& x, PETScVector& y);
159
160void scale(PETScVector& x, PetscScalar const a);
161
162// y = a*y + X
163void aypx(PETScVector& y, PetscScalar const a, PETScVector const& x);
164
165// y = a*x + y
166void axpy(PETScVector& y, PetscScalar const a, PETScVector const& x);
167
168// y = a*x + b*y
169void axpby(PETScVector& y, PetscScalar const a, PetscScalar const b,
170 PETScVector const& x);
174double dot(PETScVector const& a, PETScVector const& b);
175
176// Matrix
177
178void copy(PETScMatrix const& A, PETScMatrix& B);
179
180// A = a*A
181void scale(PETScMatrix& A, PetscScalar const a);
182
183// Y = a*Y + X
184void aypx(PETScMatrix& Y, PetscScalar const a, PETScMatrix const& X);
185
186// Y = a*X + Y
187void axpy(PETScMatrix& Y, PetscScalar const a, PETScMatrix const& X);
188
189// Matrix and Vector
190
191// v3 = A*v1 + v2
192void matMult(PETScMatrix const& A, PETScVector const& x, PETScVector& y);
193
194// y = A*x
195void matMultAdd(PETScMatrix const& A, PETScVector const& v1,
196 PETScVector const& v2, PETScVector& v3);
197
198// new_A = A^T * A
199// new_b = A^T * b
200void linearSysNormalize(PETScMatrix const& A, PETScMatrix& new_A,
201 PETScVector const& b, PETScVector& new_b);
202
203void finalizeAssembly(PETScMatrix& A);
204void finalizeAssembly(PETScVector& x);
205
206} // namespace LinAlg
207} // namespace MathLib
208
209// Sparse global EigenMatrix/EigenVector
210// //////////////////////////////////////////
211#else
212
213namespace MathLib
214{
215
216class EigenMatrix;
217class EigenVector;
218
219namespace LinAlg
220{
221
222// Vector
223
232void setLocalAccessibleVector(EigenVector const& x);
233
234void set(EigenVector& x, double const a);
235
236void copy(EigenVector const& x, EigenVector& y);
237
238void scale(EigenVector& x, double const a);
239
240// y = a*y + X
241void aypx(EigenVector& y, double const a, EigenVector const& x);
242
243// y = a*x + y
244void axpy(EigenVector& y, double const a, EigenVector const& x);
245
246// y = a*x + b*y
247void axpby(EigenVector& y, double const a, double const b,
248 EigenVector const& x);
250double dot(EigenVector const& a, EigenVector const& b);
251
252// Matrix
253
254void copy(EigenMatrix const& A, EigenMatrix& B);
255
256// A = a*A
257void scale(EigenMatrix& A, double const a);
258
259// Y = a*Y + X
260void aypx(EigenMatrix& Y, double const a, EigenMatrix const& X);
261
262// Y = a*X + Y
263void axpy(EigenMatrix& Y, double const a, EigenMatrix const& X);
264
265// Matrix and Vector
266
267// y = A*x
268void matMult(EigenMatrix const& A, EigenVector const& x, EigenVector& y);
269
270// v3 = A*v1 + v2
271void matMultAdd(EigenMatrix const& A, EigenVector const& v1,
272 EigenVector const& v2, EigenVector& v3);
273// new_A = A^T * A
274// new_b = A^T * b
275void linearSysNormalize(EigenMatrix const& A, EigenMatrix& new_A,
276 EigenVector const& b, EigenVector& new_b);
277void finalizeAssembly(EigenMatrix& x);
278void finalizeAssembly(EigenVector& A);
279
280} // namespace LinAlg
281
282} // namespace MathLib
283
284#endif
285
286namespace MathLib::LinAlg
287{
288
297template <typename VectorType>
298double computeRelativeNorm(VectorType const& x, VectorType const& y,
299 MathLib::VecNormType norm_type)
300{
301 if (norm_type == MathLib::VecNormType::INVALID)
302 {
303 OGS_FATAL("An invalid norm type has been passed");
304 }
305
306 // Stores \f$diff = x-y\f$.
307 VectorType diff;
308 MathLib::LinAlg::copy(x, diff);
309 MathLib::LinAlg::axpy(diff, -1.0, y);
310
311 const double norm_diff = MathLib::LinAlg::norm(diff, norm_type);
312
313 const double norm_x = MathLib::LinAlg::norm(x, norm_type);
314 if (norm_x > std::numeric_limits<double>::epsilon())
315 {
316 return norm_diff / norm_x;
317 }
318
319 // Both of norm_x and norm_diff are close to zero
320 if (norm_diff < std::numeric_limits<double>::epsilon())
321 {
322 return 1.0;
323 }
324
325 // Only norm_x is close to zero
326 return norm_diff / std::numeric_limits<double>::epsilon();
327}
328} // namespace MathLib::LinAlg
#define OGS_FATAL(...)
Definition Error.h:10
Global vector based on Eigen vector.
Definition EigenVector.h:19
Wrapper class for PETSc matrix routines for matrix.
Definition PETScMatrix.h:23
Wrapper class for PETSc vector.
Definition PETScVector.h:28
double norm(MatrixOrVector const &x, MathLib::VecNormType type)
Definition LinAlg.h:89
double dot(PETScVector const &a, PETScVector const &b)
Definition LinAlg.cpp:64
void linearSysNormalize(PETScMatrix const &, PETScMatrix &, PETScVector const &, PETScVector &)
Definition LinAlg.cpp:172
void finalizeAssembly(PETScMatrix &A)
Definition LinAlg.cpp:200
double norm1(PETScVector const &x)
Definition LinAlg.cpp:92
double normMax(PETScVector const &x)
Definition LinAlg.cpp:112
void copy(PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:30
void componentwiseDivide(PETScVector &w, PETScVector const &x, PETScVector const &y)
Definition LinAlg.cpp:83
void setLocalAccessibleVector(PETScVector const &x)
Definition LinAlg.cpp:20
void set(PETScVector &x, PetscScalar const a)
Definition LinAlg.cpp:25
void matMult(PETScMatrix const &A, PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:151
double computeRelativeNorm(VectorType const &x, VectorType const &y, MathLib::VecNormType norm_type)
Definition LinAlg.h:298
void matMultAdd(PETScMatrix const &A, PETScVector const &v1, PETScVector const &v2, PETScVector &v3)
Definition LinAlg.cpp:161
double norm2(PETScVector const &x)
Definition LinAlg.cpp:102
void scale(PETScVector &x, PetscScalar const a)
Definition LinAlg.cpp:37
void aypx(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:43
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:50
void axpby(PETScVector &y, PetscScalar const a, PetscScalar const b, PETScVector const &x)
Definition LinAlg.cpp:57
double const GaussLegendre< 1 >::X[1]