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();
48 m_trace_mng->info() <<
"STOP CRITERIA NORME B = " << m_nrm2_b;
49 m_criteria_value = m_tol * m_tol * m_nrm2_b;
50 m_sqrt_nrm2_b = std::sqrt(m_nrm2_b);
51 m_value = m_criteria_value + 1;
63 return m_nrm2_b == 0.;
71 bool stop(VectorType
const& r)
73 if (m_iter >= m_max_iteration)
75 m_algebra.dot(r, r, m_f_value);
76 m_status = m_f_value.get() < m_criteria_value;
83 m_trace_mng->info() <<
"iteration (" << m_iter <<
") criteria = " << getValue();
87 ValueType getValue()
const
89 if (m_sqrt_nrm2_b == 0)
92 return std::sqrt(m_value) / m_sqrt_nrm2_b;
95 int operator()()
const
100 bool getStatus()
const
107 AlgebraType& m_algebra;
108 int m_max_iteration = 0;
109 ValueType m_tol = 0.;
111 ValueType m_value = 0.;
112 FutureType m_f_value;
113 ValueType m_criteria_value = 0.;
114 ValueType m_value_init = 0.;
115 ValueType m_nrm2_b = 0.;
116 ValueType m_sqrt_nrm2_b = 0.;
117 bool m_status =
false;
118 ITraceMng* m_trace_mng =
nullptr;
122 BiCGStab(AlgebraType& algebra, ITraceMng* trace_mng =
nullptr)
124 , m_trace_mng(trace_mng)
130 void setOutputLevel(
int level)
132 m_output_level = level;
135 template <
typename PrecondT,
typename iterT>
136 int solve(PrecondT& precond, iterT& iter, MatrixType
const& A,
137 VectorType
const& b, VectorType& x)
141 ValueType rho(0), rho1(0), alpha(0), beta(0), omega(0);
142 VectorType p, phat, s, shat, t, v, r, r0;
144 m_algebra.allocate(AlgebraType::resource(A), p, phat, s, shat, t, v, r, r0);
148 m_algebra.copy(b, r);
149 m_algebra.mult(A, x, r0);
150 m_algebra.axpy(-1., r0, r);
153 m_algebra.copy(r, r0);
154 m_algebra.copy(r, p);
155 rho1 = m_algebra.dot(r, r0);
156 if (m_output_level > 2)
157 _print(0,
"Seq 0",
"rho1", rho1);
167 m_algebra.exec(precond, p, phat);
168 m_algebra.mult(A, phat, v);
169 alpha = m_algebra.dot(v, r0);
171 throw typename AlgebraType::NullValueException(
"alpha");
172 alpha = rho1 / alpha;
173 m_algebra.copy(r, s);
174 m_algebra.axpy(-alpha, v, s);
175 if (m_output_level > 2)
176 _print(0,
"Seq 1",
"alpha", alpha);
180 m_algebra.axpy(alpha, phat, x);
181 m_algebra.free(p, phat, s, shat, t, v, r, r0);
186 m_algebra.exec(precond, s, shat);
187 m_algebra.mult(A, shat, t);
188 omega = m_algebra.dot(t, s);
189 beta = m_algebra.dot(t, t);
194 m_algebra.axpy(alpha, phat, x);
195 m_algebra.free(p, phat, s, shat, t, v, r, r0);
199 throw typename AlgebraType::NullValueException(
"beta");
201 omega = omega / beta;
202 if (m_output_level > 2)
203 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
206 m_algebra.axpy(omega, shat, x);
207 m_algebra.axpy(alpha, phat, x);
208 m_algebra.copy(s, r);
209 m_algebra.axpy(-omega, t, r);
213 if (m_output_level > 2)
214 _print(iter(),
"Seq 3",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
216 while (!iter.stop(r)) {
218 rho1 = m_algebra.dot(r, r0);
219 beta = (rho1 / rho) * (alpha / omega);
220 m_algebra.axpy(-omega, v, p);
221 m_algebra.scal(beta, p);
222 m_algebra.axpy(1., r, p);
223 if (m_output_level > 2)
224 _print(iter(),
"Seq 4",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
227 throw typename AlgebraType::NullValueException(
"rho");
230 m_algebra.exec(precond, p, phat);
231 m_algebra.mult(A, phat, v);
232 alpha = m_algebra.dot(v, r0);
234 throw typename AlgebraType::NullValueException(
"alpha");
236 alpha = rho1 / alpha;
238 m_algebra.copy(r, s);
239 m_algebra.axpy(-alpha, v, s);
241 if (m_output_level > 2)
242 _print(iter(),
"Seq 1",
"alpha", alpha);
244 m_algebra.axpy(alpha, phat, x);
245 m_algebra.free(p, phat, s, shat, t, v, r, r0);
250 m_algebra.exec(precond, s, shat);
251 m_algebra.mult(A, shat, t);
252 omega = m_algebra.dot(t, s);
253 beta = m_algebra.dot(t, t);
255 if (m_output_level > 2)
256 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1,
"omega", omega);
259 m_algebra.axpy(alpha, phat, x);
260 m_algebra.free(p, phat, s, shat, t, v, r, r0);
263 throw typename AlgebraType::NullValueException(
"beta");
266 omega = omega / beta;
269 m_algebra.axpy(omega, shat, x);
270 m_algebra.axpy(alpha, phat, x);
271 m_algebra.copy(s, r);
272 m_algebra.axpy(-omega, t, r);
277 if (m_output_level > 2)
278 _print(iter(),
"end loop",
"beta", beta,
"alpha", alpha,
"rho", rho);
281 m_algebra.free(p, phat, s, shat, t, v, r, r0);
286 template <
typename PrecondT,
typename iterT>
287 int solve2(PrecondT& precond, iterT& iter, MatrixType
const& A,
288 VectorType
const& b, VectorType& x)
293 ValueType rho (0), rho1 (0), alpha (0), beta (0), gamma (0), omega (0);
294 FutureType frho(rho), frho1(rho1), falpha(alpha), fbeta(beta), fgamma(gamma), fomega(omega) ;
295 VectorType p, phat, s, shat, t, v, r, r0;
298 m_algebra.allocate(AlgebraType::resource(A), p, phat, s, shat, t, v, r, r0);
302 m_algebra.copy(b, r);
303 m_algebra.mult(A, x, r0);
304 m_algebra.axpy(-1., r0, r);
307 m_algebra.copy(r, r0);
308 m_algebra.copy(r, p);
309 m_algebra.dot(r, r0, frho1);
310 if (m_output_level > 2)
311 _print(0,
"Seq 0",
"rho1", frho1.get());
321 m_algebra.exec(precond, p, phat);
322 m_algebra.mult(A, phat, v);
323 m_algebra.dot(v, r0, falpha);
324 if (falpha.get() == 0)
325 throw typename AlgebraType::NullValueException(
"alpha");
326 alpha = frho1.get() / alpha;
328 m_algebra.copy(r, s);
329 m_algebra.axpy(-alpha, v, s);
330 if (m_output_level > 2)
331 _print(0,
"Seq 1",
"alpha", alpha);
335 m_algebra.axpy(alpha, phat, x);
336 m_algebra.free(p, phat, s, shat, t, v, r, r0);
341 m_algebra.exec(precond, s, shat);
342 m_algebra.mult(A, shat, t);
343 m_algebra.dot(t, s, fomega);
344 m_algebra.dot(t, t, fbeta);
345 if (fbeta.get() == 0) {
348 m_algebra.axpy(alpha, phat, x);
349 m_algebra.free(p, phat, s, shat, t, v, r, r0);
353 throw typename AlgebraType::NullValueException(
"beta");
355 omega = fomega.get() / beta;
356 if (m_output_level > 2)
357 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
360 m_algebra.axpy(omega, shat, x);
361 m_algebra.axpy(alpha, phat, x);
362 m_algebra.copy(s, r);
363 m_algebra.axpy(-omega, t, r);
367 if (m_output_level > 2)
368 _print(iter(),
"Seq 3",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
370 while (!iter.stop(r)) {
376 m_algebra.dot(r, r0, frho1);
377 beta = (frho1.get() / rho) * (alpha / omega);
378 m_algebra.axpy(-omega, v, p);
379 m_algebra.scal(beta, p);
380 m_algebra.axpy(1., r, p);
381 if (m_output_level > 2)
382 _print(iter(),
"Seq 4",
"beta", beta,
"alpha", alpha,
"rho1", rho1);
385 throw typename AlgebraType::NullValueException(
"rho");
388 m_algebra.exec(precond, p, phat);
389 m_algebra.mult(A, phat, v);
390 m_algebra.dot(v, r0, falpha);
391 if (falpha.get() == 0)
392 throw typename AlgebraType::NullValueException(
"alpha");
394 alpha = rho1 / alpha;
396 m_algebra.copy(r, s);
397 m_algebra.axpy(-alpha, v, s);
398 if (m_output_level > 2)
399 _print(iter(),
"Seq 1",
"alpha", alpha);
402 m_algebra.axpy(alpha, phat, x);
403 m_algebra.free(p, phat, s, shat, t, v, r, r0);
408 m_algebra.exec(precond, s, shat);
409 m_algebra.mult(A, shat, t);
410 m_algebra.dot(t, s, fomega);
411 m_algebra.dot(t, t, fbeta);
412 if (m_output_level > 2)
413 _print(iter(),
"Seq 2",
"beta", beta,
"alpha", alpha,
"rho1", rho1,
"omega", omega);
414 if (fbeta.get() == 0) {
416 m_algebra.axpy(alpha, phat, x);
417 m_algebra.free(p, phat, s, shat, t, v, r, r0);
420 throw typename AlgebraType::NullValueException(
"beta");
423 omega = fomega.get() / beta;
426 m_algebra.axpy(omega, shat, x);
427 m_algebra.axpy(alpha, phat, x);
428 m_algebra.copy(s, r);
429 m_algebra.axpy(-omega, t, r);
434 if (m_output_level > 2)
435 _print(iter(),
"end loop",
"beta", beta,
"alpha", alpha,
"rho", rho);
438 m_algebra.free(p, phat, s, shat, t, v, r, r0);
445 _print(
int iter, std::string
const& msg, std::string
const& label0,
449 m_trace_mng->info() << msg;
450 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label0 <<
" "
456 _print(
int iter, std::string
const& msg, std::string
const& label0,
457 ValueType value0, std::string
const& label1, ValueType value1)
460 _print(iter, msg, label0, value0);
461 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label1 <<
" "
467 _print(
int iter, std::string
const& msg, std::string
const& label0,
468 ValueType value0, std::string
const& label1, ValueType value1,
469 std::string
const& label2, ValueType value2)
472 _print(iter, msg, label0, value0, label1, value1);
473 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label2 <<
" "
479 _print(
int iter, std::string
const& msg, std::string
const& label0,
480 ValueType value0, std::string
const& label1, ValueType value1,
481 std::string
const& label2, ValueType value2,
482 std::string
const& label3, ValueType value3)
485 _print(iter, msg, label0, value0, label1, value1, label2, value2);
486 m_trace_mng->info() <<
"Iterate: " << iter <<
" " << label3 <<
" "
491 AlgebraType& m_algebra;
492 ITraceMng* m_trace_mng =
nullptr;
493 int m_output_level = 0;