G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsGMRes.hpp
Go to the documentation of this file.
1 
14 // TODO: Fix matrices sizes such that we don't resize on every iteration! (default can be 100 + 100 +...)
15 
16 namespace gismo
17 {
18 
19 template<class T>
21  typename gsGMRes<T>::VectorType& x )
22 {
23  if (Base::initIteration(rhs,x))
24  return true;
25 
26  m_mat->apply(x,tmp);
27  tmp = rhs - tmp;
28  m_precond->apply(tmp, residual);
29  beta = residual.norm(); // This is ||r||
30 
31  m_error = beta/m_rhs_norm;
32  if(m_error < m_tol)
33  return true;
34 
35  v.push_back(residual/beta);
36  g.setZero(2,1);
37  g(0,0) = beta;
38  Omega = gsMatrix<T>::Identity(2, 2);
39  Omega_prev = gsMatrix<T>::Identity(2, 2);
40 
41  return false;
42 }
43 
44 template<class T>
46 {
47  //Remove last row of H and g
48  H.resize(m_num_iter,m_num_iter);
49  H = H_prev.block(0,0,m_num_iter,m_num_iter);
50  g_tmp.resize(m_num_iter,1);
51  g_tmp = g.block(0,0,m_num_iter,1);
52 
53  //Solve H*y = g;
54  solveUpperTriangular(H, g_tmp);
55 
56  //Create the matrix from the column matrix in v.
57  gsMatrix<T> V(m_mat->rows(),m_num_iter);
58  for (index_t k = 0; k< m_num_iter; ++k)
59  {
60  V.col(k) = v[k];
61  }
62  //Update solution
63  x += V*y;
64 
65  // cleanup temporaries
66  tmp.clear();
67  g.clear();
68  g_tmp.clear();
69  h_tmp.clear();
70  y.clear();
71  w.clear();
72  residual.clear();
73  H_prev.clear();
74  H.clear();
75  Omega.clear();
76  Omega_prev.clear();
77  Omega_tmp.clear();
78  Omega_prev_tmp.clear();
79  v.clear();
80 }
81 
82 template<class T>
84 {
85  // The iterate x is never updated! Use finalizeIteration to obtain x.
86  const index_t k = m_num_iter-1;
87  H.setZero(k+2,k+1);
88  h_tmp.setZero(k+2,1);
89 
90  if (k != 0)
91  {
92  H.block(0,0,k+1,k) = H_prev;
93  }
94 
95  Omega = gsMatrix<T>::Identity(k+2, k+2);
96  m_mat->apply(v[k],tmp);
97  m_precond->apply(tmp, w);
98 
99  for (index_t i = 0; i< k+1; ++i)
100  {
101  h_tmp(i,0) = (w.transpose()*v[i]).value(); //Typo h_l,k
102  w = w - h_tmp(i,0)*v[i];
103  }
104  h_tmp(k+1,0) = w.norm();
105 
106  // if (math::abs(h_tmp(k+1,0)) < 1e-16) //If exact solution
107  // return true;
108 
109  v.push_back(w/h_tmp(k+1,0));
110 
111  h_tmp = Omega_prev*h_tmp;
112  H.block(0,k,k+2,1) = h_tmp;
113 
114  //Find coef in rotation matrix
115  T sk = H(k+1,k)/(math::sqrt(H(k,k)*H(k,k) + H(k+1,k)*H(k+1,k)));
116  T ck = H(k, k)/(math::sqrt(H(k,k)*H(k,k) + H(k+1,k)*H(k+1,k)));
117  Omega(k,k) = ck; Omega(k,k+1) = sk;
118  Omega(k+1,k) =-sk; Omega(k+1,k+1) = ck;
119 
120  //Rotate H and g
121  H = Omega*H;
122  H_prev = H;
123  g_tmp.setZero(k+2,1);
124  if (k != 0)
125  g_tmp.block(0,0,k+1,1) = g;
126  else
127  g_tmp = g;
128  g.noalias() = Omega * g_tmp;
129 
130  T residualNorm2 = g(k+1,0)*g(k+1,0);
131  m_error = math::sqrt(residualNorm2) / m_rhs_norm;
132  if(m_error < m_tol)
133  return true;
134 
135  //Resize rotation product
136  Omega_prev_tmp.setZero(k+3,k+3);
137  Omega_prev_tmp.block(0,0,k+2,k+2) = Omega_prev;
138  Omega_prev_tmp(k+2,k+2) = 1;
139 
140  Omega_tmp.setZero(k+3,k+3);
141  Omega_tmp.block(0,0,k+2,k+2) = Omega;
142  Omega_tmp(k+2,k+2) = 1;
143 
144  Omega_prev = Omega_tmp*Omega_prev_tmp;
145  return false;
146 }
147 
148 }
#define index_t
Definition: gsConfig.h:32
bool step(VectorType &x)
Perform one step, requires initIteration.
Definition: gsGMRes.hpp:83
bool initIteration(const VectorType &rhs, VectorType &x)
Init the iteration.
Definition: gsGMRes.hpp:20
void finalizeIteration(VectorType &x)
Some post-processing might be required.
Definition: gsGMRes.hpp:45