-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinearSystemGmm.h
149 lines (138 loc) · 4.36 KB
/
linearSystemGmm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Gmsh - Copyright (C) 1997-2020 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
#ifndef LINEAR_SYSTEM_GMM_H
#define LINEAR_SYSTEM_GMM_H
#include <string>
#include "GmshConfig.h"
#include "GmshMessage.h"
#include "linearSystem.h"
#if defined(HAVE_GMM)
#undef BB // can be defined by FlGui.h, and clashes with gmm arg name
#include <gmm.h>
// Consider using linearSystemCSRGmm instead: assembly is much faster
template <class scalar> class linearSystemGmm : public linearSystem<scalar> {
protected:
std::vector<scalar> *_x; // nonLinearSystemGmm has to access to this vector
std::vector<scalar> *_b; // idem
gmm::row_matrix<gmm::wsvector<scalar> > *_a;
private:
std::string _method;
double _tol;
int _noisy;
public:
linearSystemGmm(const std::string &method = "gmres", double tol = 1e-8,
int noisy = 1)
: _x(0), _b(0), _a(0), _method(method), _tol(tol), _noisy(noisy) {}
virtual bool isAllocated() const { return _a != 0; }
virtual void allocate(int nbRows)
{
clear();
_a = new gmm::row_matrix<gmm::wsvector<scalar> >(nbRows, nbRows);
_b = new std::vector<scalar>(nbRows);
_x = new std::vector<scalar>(nbRows);
}
virtual ~linearSystemGmm() { clear(); }
virtual void clear()
{
if(_a) {
delete _a;
delete _b;
delete _x;
}
_a = 0;
}
virtual void addToMatrix(int row, int col, const scalar &val)
{
if(val != 0.0) (*_a)(row, col) += val;
}
virtual void getFromMatrix(int row, int col, scalar &val) const
{
val = (*_a)(row, col);
}
virtual void addToRightHandSide(int row, const scalar &val, int ith = 0)
{
if(val != 0.0) (*_b)[row] += val;
}
virtual void getFromRightHandSide(int row, scalar &val) const
{
val = (*_b)[row];
}
virtual void addToSolution(int row, const scalar &val)
{
if(val != 0.0) (*_x)[row] += val;
}
virtual void getFromSolution(int row, scalar &val) const { val = (*_x)[row]; }
virtual void zeroMatrix() { gmm::clear(*_a); }
virtual void zeroRightHandSide()
{
for(std::size_t i = 0; i < _b->size(); i++) (*_b)[i] = 0.;
}
virtual void zeroSolution()
{
for(std::size_t i = 0; i < _x->size(); i++) (*_x)[i] = 0.;
}
virtual double normInfRightHandSide() const
{
double nor = 0.;
double temp;
for(std::size_t i = 0; i < _b->size(); i++) {
temp = abs((*_b)[i]); // this is valid also for complex
// if(temp<0) temp = -temp;
if(nor < temp) nor = temp;
}
return nor;
}
void setPrec(double p) { _tol = p; }
void setNoisy(int n) { _noisy = n; }
void setGmres(int n) { _method = (n ? "gmres" : "cg"); }
virtual int systemSolve()
{
#if defined(HAVE_MUMPS)
// if(_method == "mumps"){
gmm::MUMPS_solve(*_a, *_x, *_b);
return 1;
// }
#else
//gmm::ilutp_precond<gmm::row_matrix<gmm::wsvector<scalar> > > P(*_a, 25, 0.);
gmm::ildltt_precond<gmm::row_matrix<gmm::wsvector<scalar> > > P(*_a, 30, 1.e-10);
//gmm::ilu_precond<gmm::row_matrix<gmm::wsvector<scalar> > > P(*_a);
gmm::iteration iter(_tol);
iter.set_noisy(_noisy);
if(_method == "gmres")
gmm::gmres(*_a, *_x, *_b, P, 100, iter);
else
gmm::cg(*_a, *_x, *_b, P, iter);
#endif
return 1;
}
};
#else
template <class scalar> class linearSystemGmm : public linearSystem<scalar> {
public:
linearSystemGmm(const std::string &method = "gmres", double tol = 1e-8,
int noisy = 0)
{
Msg::Error("Gmm++ is not available in this version of Gmsh");
}
virtual bool isAllocated() const { return false; }
virtual void allocate(int nbRows) {}
virtual void addToMatrix(int row, int col, const scalar &val) {}
virtual void getFromMatrix(int row, int col, scalar &val) const {}
virtual void addToRightHandSide(int row, const scalar &val, int ith = 0) {}
virtual void getFromRightHandSide(int row, scalar &val) const {}
virtual void addToSolution(int row, const scalar &val) {}
virtual void getFromSolution(int row, scalar &val) const {}
virtual void zeroMatrix() {}
virtual void zeroRightHandSide() {}
virtual void zeroSolution() {}
virtual int systemSolve() { return 0; }
virtual double normInfRightHandSide() const { return 0.; }
void setPrec(double p) {}
virtual void clear() {}
void setNoisy(int n) {}
void setGmres(int n) {}
};
#endif
#endif