G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
16namespace gismo
17{
18
19template<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
44template<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
82template<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}
void finalizeIteration(VectorType &x)
Some post-processing might be required.
Definition gsGMRes.hpp:45
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
#define index_t
Definition gsConfig.h:32
The G+Smo namespace, containing all definitions for the library.