NeoPZ
gmres.h
Go to the documentation of this file.
1 
8 template<class Real>
9 void GeneratePlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn);
10 
13 template<class Real>
14 void ApplyPlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn);
15 
20 template < class Matrix, class Vector >
21 void
22 Update(Vector &x, int64_t k, Matrix &h, Vector &s, Vector v[])
23 {
24  Vector y(s);
25 
26  // Backsolve:
27  for (int64_t i = k; i >= 0; i--) {
28  y(i) /= h(i,i);
29  for (int64_t j = i - 1; j >= 0; j--)
30  y(j) -= h(j,i) * y(i);
31  }
32 
33  for (int64_t j = 0; j <= k; j++)
34  x.ZAXPY(y(j),v[j]);
35 }
36 
41 template < class Real >
42 Real
43 abs(Real x)
44 {
45  return (x > ((Real)0.) ? x : -x);
46 }
47 
68 template < class Operator, class Vector, class Preconditioner,
69 class Matrix, class Real >
70 int
71 GMRES( Operator &A, Vector &x, const Vector &b,
72  Preconditioner &M, Matrix &H, int &m, int64_t &max_iter,
73  Real &tol, Vector *residual,const int FromCurrent)
74 {
75  Real resid;
76  int64_t j = 1, k;
77  Vector s(m+1), cs(m+1), sn(m+1), w1,w;
78 
79  // Real normb = norm(M.Solve(b));
80  Vector resbackup;
81  Vector *res = residual;
82  if(!res) res = &resbackup;
83  Vector &r = *res;
84  M.Solve(b,r);
85  Real normb = TPZExtractVal::val(Norm(r)); // Vector r = b - A*x;
86  if(FromCurrent)
87  {
88  A.MultAdd(x,b,r,-1.,1.);
89  }
90  else
91  {
92  x.Zero();
93  r = b;
94  }
95  M.Solve(r,w);
96  r=w;
97  Real beta = TPZExtractVal::val(Norm(r));
98 
99  if (normb == 0.0)
100  normb = 1;
101 
102  if ((resid = ((Real)TPZExtractVal::val(Norm(r))) / normb) <= tol) {
103  tol = resid;
104  x+=r;
105  max_iter = 0;
106  return 0;
107  }
108 
109  Vector *v = new Vector[m+1];
110 
111  while (j <= max_iter) {
112  int64_t rows = r.Rows();
113  v[0].Resize(rows,1);
114  for (int64_t i=0; i<rows; i++) {
115  v[0](i) = TPZExtractVal::val(r(i)) * ((Real)(1.0/beta));
116  }
117  int64_t srows = s.Rows();
118  for (int64_t i=0; i<srows; i++) {
119  s(i) = REAL(0.);
120  }
121 // v[0] = r * (REAL(1.0 / beta)); // ??? r / beta
122 // s = REAL(0.0);
123  s(0) = beta;
124 
125  for (int64_t i = 0; i < m && j <= max_iter; i++, j++) {
126  A.Multiply(v[i],w1);
127  M.Solve(w1,w);
128  for (k = 0; k <= i; k++) {
129  H(k, i) = Dot(w, v[k]);
130  w.ZAXPY(-H(k, i), v[k]);
131  }
132  H(i+1, i) = Norm(w);
133  v[i+1] = w;
134  v[i+1] *= (1.0)/TPZExtractVal::val(H(i+1,i));
135 
136  for (k = 0; k < i; k++)
137  ApplyPlaneRotation(H(k,i), H(k+1,i), cs(k), sn(k));
138 
139  GeneratePlaneRotation(H(i,i), H(i+1,i), cs(i), sn(i));
140  ApplyPlaneRotation(H(i,i), H(i+1,i), cs(i), sn(i));
141  ApplyPlaneRotation(s(i), s(i+1), cs(i), sn(i));
142  resid = ((Real)fabs(s(i+1)))/normb;
143  if (resid < tol) {
144  Update(x, i, H, s, v);
145  tol = resid;
146  max_iter = j;
147  delete [] v;
148  return 0;
149  }
150  }
151  Update(x, m - 1, H, s, v);
152  A.MultAdd(x,b,r,-1.,1.);
153  M.Solve(r,r);
154  beta = TPZExtractVal::val(Norm(r));
155  resid = beta/normb;
156  if (resid < tol) {
157  std::cout << "iter " << j << " - " << resid << std::endl;
158  tol = resid;
159  max_iter = j;
160  delete [] v;
161  return 0;
162  }
163  }
164 
165  tol = resid;
166  delete [] v;
167  return 1;
168 }
169 
170 
171 #include <math.h>
172 
175 template<class Real>
176 void GeneratePlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn)
177 {
178  if (dy == ((Real)0.0)) {
179  cs = 1.0;
180  sn = 0.0;
181  } else if (abs(dy) > abs(dx)) {
182  Real temp = dx / dy;
183  sn = ((Real)1.0) / sqrt( ((Real)1.0) + temp*temp );
184  cs = temp * sn;
185  } else {
186  Real temp = dy / dx;
187  cs = ((Real)1.0) / sqrt( ((Real)1.0) + temp*temp );
188  sn = temp * cs;
189  }
190 }
191 
194 template<class Real>
195 void ApplyPlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn)
196 {
197  Real temp = cs * dx + sn * dy;
198  dy = -sn * dx + cs * dy;
199  dx = temp;
200 }
201 
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ fabs
Definition: tfadfunc.h:140
int GMRES(Operator &A, Vector &x, const Vector &b, Preconditioner &M, Matrix &H, int &m, int64_t &max_iter, Real &tol, Vector *residual, const int FromCurrent)
GMRES solves the unsymmetric linear system Ax = b using the Generalized Minimum Residual method...
Definition: gmres.h:71
TVar Dot(const TPZFMatrix< TVar > &A, const TPZFMatrix< TVar > &B)
Implement dot product for matrices.
Definition: pzfmatrix.cpp:2083
clarg::argBool h("-h", "help message", false)
void Update(Vector &x, int64_t k, Matrix &h, Vector &s, Vector v[])
Computes back solve. Updates on v vector.
Definition: gmres.h:22
static const double tol
Definition: pzgeoprism.cpp:23
expr_ dx(i) *cos(expr_.val())
TVar Norm(const TPZFMatrix< TVar > &A)
Returns the norm of the matrix A.
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
Definition: tfadfunc.h:120
string res
Definition: test.py:151
static REAL val(const int number)
Definition: pzextractval.h:21
void GeneratePlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn)
Compute the values cs and sn parameters to rotation.
Definition: gmres.h:176
void ApplyPlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn)
Makes rotation of the plane based on the cs and sn parameters.
Definition: gmres.h:195
Definition: vectors.h:81
Real abs(Real x)
Returns absolute value to real.
Definition: gmres.h:43
clarg::argString m("-m", "input matrix file name (text format)", "matrix.txt")