21 typedef AlgebraT AlgebraType;
22 typedef typename AlgebraType::Matrix MatrixType;
23 typedef typename AlgebraType::Vector VectorType;
24 typedef typename MatrixType::ValueType ValueType;
25 typedef typename AlgebraType::FutureType FutureType;
31 Iteration(AlgebraType& algebra,
35 ITraceMng* trace_mng =
nullptr)
39 , m_max_iteration(max_iter)
42 , m_trace_mng(trace_mng)
44 m_algebra.dot(b, b, m_f_value);
45 m_nrm2_b = m_f_value.get();
47 m_trace_mng->info() <<
"STOP CRITERIA NORME B = " << m_nrm2_b;
48 m_criteria_value = m_tol * m_tol * m_nrm2_b;
49 m_sqrt_nrm2_b = std::sqrt(m_nrm2_b);
50 m_value = m_criteria_value + 1;
62 return m_nrm2_b == 0.;
70 bool stop(VectorType
const& r)
72 if (m_iter >= m_max_iteration)
74 m_algebra.dot(r, r, m_f_value);
75 m_status = m_f_value.get() < m_criteria_value;
82 m_trace_mng->info() <<
"iteration (" << m_iter <<
") criteria = " << getValue();
86 ValueType getValue()
const
88 if (m_sqrt_nrm2_b == 0)
91 return std::sqrt(m_value) / m_sqrt_nrm2_b;
94 int operator()()
const
99 bool getStatus()
const
106 AlgebraType& m_algebra;
107 int m_max_iteration = 0;
108 ValueType m_tol = 0.;
110 ValueType m_value = 0.;
111 FutureType m_f_value;
112 ValueType m_criteria_value = 0.;
113 ValueType m_value_init = 0.;
114 ValueType m_nrm2_b = 0.;
115 ValueType m_sqrt_nrm2_b = 0.;
116 bool m_status =
false;
117 ITraceMng* m_trace_mng =
nullptr;
121 BiCGStab(AlgebraType& algebra, ITraceMng* trace_mng =
nullptr)
123 , m_trace_mng(trace_mng)
129 void setOutputLevel(
int level)
131 m_output_level = level;
134 template <
typename PrecondT,
typename iterT>
135 int solve(PrecondT& precond, iterT& iter, MatrixType
const& A,
136 VectorType
const& b, VectorType& x)
140 ValueType rho(0), rho1(0), alpha(0), beta(0), omega(0);
141 VectorType p, phat, s, shat, t, v, r, r0;
143 m_algebra.allocate(AlgebraType::resource(A), p, phat, s, shat, t, v, r, r0);
147 m_algebra.copy(b, r);
148 m_algebra.mult(A, x, r0);
149 m_algebra.axpy(-1., r0, r);
152 m_algebra.copy(r, r0);
153 m_algebra.copy(r, p);
154 rho1 = m_algebra.dot(r, r0);
155 if (m_output_level > 1)
156 _print(0,
"Seq 0",
"rho1", rho1);
166 m_algebra.exec(precond, p, phat);
167 m_algebra.mult(A, phat, v);
168 alpha = m_algebra.dot(v, r0);
170 throw typename AlgebraType::NullValueException(
"alpha");
171 alpha = rho1 / alpha;
172 m_algebra.copy(r, s);
173 m_algebra.axpy(-alpha, v, s);
174 if (m_output_level > 1)
175 _print(0,
"Seq 1",
"alpha", alpha);
179 m_algebra.axpy(alpha, phat, x);
180 m_algebra.free(p, phat, s, shat, t, v, r, r0);
185 m_algebra.exec(precond, s, shat);
186 m_algebra.mult(A, shat, t);
187 omega = m_algebra.dot(t, s);
188 beta = m_algebra.dot(t, t);
193 m_algebra.axpy(alpha, phat, x);
194 m_algebra.free(p, phat, s, shat, t, v, r, r0);
198 throw typename AlgebraType::NullValueException(
"beta");
200 omega = omega / beta;
201 if (m_output_level > 1)
202 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
205 m_algebra.axpy(omega, shat, x);
206 m_algebra.axpy(alpha, phat, x);
207 m_algebra.copy(s, r);
208 m_algebra.axpy(-omega, t, r);
212 if (m_output_level > 1)
213 _print(iter(),
"Seq 3",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
215 while (!iter.stop(r)) {
217 rho1 = m_algebra.dot(r, r0);
218 beta = (rho1 / rho) * (alpha / omega);
219 m_algebra.axpy(-omega, v, p);
220 m_algebra.scal(beta, p);
221 m_algebra.axpy(1., r, p);
222 if (m_output_level > 1)
223 _print(iter(),
"Seq 4",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
226 throw typename AlgebraType::NullValueException(
"rho");
229 m_algebra.exec(precond, p, phat);
230 m_algebra.mult(A, phat, v);
231 alpha = m_algebra.dot(v, r0);
233 throw typename AlgebraType::NullValueException(
"alpha");
235 alpha = rho1 / alpha;
237 m_algebra.copy(r, s);
238 m_algebra.axpy(-alpha, v, s);
240 if (m_output_level > 1)
241 _print(iter(),
"Seq 1",
"alpha", alpha);
243 m_algebra.axpy(alpha, phat, x);
244 m_algebra.free(p, phat, s, shat, t, v, r, r0);
249 m_algebra.exec(precond, s, shat);
250 m_algebra.mult(A, shat, t);
251 omega = m_algebra.dot(t, s);
252 beta = m_algebra.dot(t, t);
254 if (m_output_level > 1)
255 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1,
"omega", omega);
258 m_algebra.axpy(alpha, phat, x);
259 m_algebra.free(p, phat, s, shat, t, v, r, r0);
262 throw typename AlgebraType::NullValueException(
"beta");
265 omega = omega / beta;
268 m_algebra.axpy(omega, shat, x);
269 m_algebra.axpy(alpha, phat, x);
270 m_algebra.copy(s, r);
271 m_algebra.axpy(-omega, t, r);
276 if (m_output_level > 1)
277 _print(iter(),
"end loop",
"beta", beta,
"alpha", alpha,
"rho", rho);
280 m_algebra.free(p, phat, s, shat, t, v, r, r0);
285 template <
typename PrecondT,
typename iterT>
286 int solve2(PrecondT& precond, iterT& iter, MatrixType
const& A,
287 VectorType
const& b, VectorType& x)
292 ValueType rho (0), rho1 (0), alpha (0), beta (0), gamma (0), omega (0);
293 FutureType frho(rho), frho1(rho1), falpha(alpha), fbeta(beta), fgamma(gamma), fomega(omega) ;
294 VectorType p, phat, s, shat, t, v, r, r0;
297 m_algebra.allocate(AlgebraType::resource(A), p, phat, s, shat, t, v, r, r0);
301 m_algebra.copy(b, r);
302 m_algebra.mult(A, x, r0);
303 m_algebra.axpy(-1., r0, r);
306 m_algebra.copy(r, r0);
307 m_algebra.copy(r, p);
308 m_algebra.dot(r, r0, frho1);
309 if (m_output_level > 1)
310 _print(0,
"Seq 0",
"rho1", frho1.get());
320 m_algebra.exec(precond, p, phat);
321 m_algebra.mult(A, phat, v);
322 m_algebra.dot(v, r0, falpha);
323 if (falpha.get() == 0)
324 throw typename AlgebraType::NullValueException(
"alpha");
325 alpha = frho1.get() / alpha;
327 m_algebra.copy(r, s);
328 m_algebra.axpy(-alpha, v, s);
329 if (m_output_level > 1)
330 _print(0,
"Seq 1",
"alpha", alpha);
334 m_algebra.axpy(alpha, phat, x);
335 m_algebra.free(p, phat, s, shat, t, v, r, r0);
340 m_algebra.exec(precond, s, shat);
341 m_algebra.mult(A, shat, t);
342 m_algebra.dot(t, s, fomega);
343 m_algebra.dot(t, t, fbeta);
344 if (fbeta.get() == 0) {
347 m_algebra.axpy(alpha, phat, x);
348 m_algebra.free(p, phat, s, shat, t, v, r, r0);
352 throw typename AlgebraType::NullValueException(
"beta");
354 omega = fomega.get() / beta;
355 if (m_output_level > 1)
356 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
359 m_algebra.axpy(omega, shat, x);
360 m_algebra.axpy(alpha, phat, x);
361 m_algebra.copy(s, r);
362 m_algebra.axpy(-omega, t, r);
366 if (m_output_level > 1)
367 _print(iter(),
"Seq 3",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
369 while (!iter.stop(r)) {
375 m_algebra.dot(r, r0, frho1);
376 beta = (frho1.get() / rho) * (alpha / omega);
377 m_algebra.axpy(-omega, v, p);
378 m_algebra.scal(beta, p);
379 m_algebra.axpy(1., r, p);
380 if (m_output_level > 1)
381 _print(iter(),
"Seq 4",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
384 throw typename AlgebraType::NullValueException(
"rho");
387 m_algebra.exec(precond, p, phat);
388 m_algebra.mult(A, phat, v);
389 m_algebra.dot(v, r0, falpha);
390 if (falpha.get() == 0)
391 throw typename AlgebraType::NullValueException(
"alpha");
393 alpha = rho1 / alpha;
395 m_algebra.copy(r, s);
396 m_algebra.axpy(-alpha, v, s);
397 if (m_output_level > 1)
398 _print(iter(),
"Seq 1",
"alpha", alpha);
401 m_algebra.axpy(alpha, phat, x);
402 m_algebra.free(p, phat, s, shat, t, v, r, r0);
407 m_algebra.exec(precond, s, shat);
408 m_algebra.mult(A, shat, t);
409 m_algebra.dot(t, s, fomega);
410 m_algebra.dot(t, t, fbeta);
411 if (m_output_level > 1)
412 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1,
"omega", omega);
413 if (fbeta.get() == 0) {
415 m_algebra.axpy(alpha, phat, x);
416 m_algebra.free(p, phat, s, shat, t, v, r, r0);
419 throw typename AlgebraType::NullValueException(
"beta");
422 omega = fomega.get() / beta;
425 m_algebra.axpy(omega, shat, x);
426 m_algebra.axpy(alpha, phat, x);
427 m_algebra.copy(s, r);
428 m_algebra.axpy(-omega, t, r);
433 if (m_output_level > 1)
434 _print(iter(),
"end loop",
"beta", beta,
"alpha", alpha,
"rho", rho);
437 m_algebra.free(p, phat, s, shat, t, v, r, r0);
444 _print(
int iter, std::string
const& msg, std::string
const& label0,
448 m_trace_mng->info() << msg;
449 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label0 <<
" "
455 _print(
int iter, std::string
const& msg, std::string
const& label0,
456 ValueType value0, std::string
const& label1, ValueType value1)
459 _print(iter, msg, label0, value0);
460 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label1 <<
" "
466 _print(
int iter, std::string
const& msg, std::string
const& label0,
467 ValueType value0, std::string
const& label1, ValueType value1,
468 std::string
const& label2, ValueType value2)
471 _print(iter, msg, label0, value0, label1, value1);
472 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label2 <<
" "
478 _print(
int iter, std::string
const& msg, std::string
const& label0,
479 ValueType value0, std::string
const& label1, ValueType value1,
480 std::string
const& label2, ValueType value2,
481 std::string
const& label3, ValueType value3)
484 _print(iter, msg, label0, value0, label1, value1, label2, value2);
485 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label3 <<
" "
490 AlgebraType& m_algebra;
491 ITraceMng* m_trace_mng =
nullptr;
492 int m_output_level = 0;