37 #ifndef GMM_SOLVERS_SCHWARZ_ADDITIVE_H__
38 #define GMM_SOLVERS_SCHWARZ_ADDITIVE_H__
41 #if defined(GMM_USES_SUPERLU)
58 struct using_gmres {};
59 struct using_bicgstab {};
62 template <
typename P,
typename local_solver,
typename Matrix>
63 struct actual_precond {
65 static const APrecond &transform(
const P &PP) {
return PP; }
68 template <
typename Matrix1,
typename Precond,
typename Vector>
69 void AS_local_solve(using_cg,
const Matrix1 &A, Vector &x,
const Vector &b,
70 const Precond &P, iteration &iter)
71 { cg(A, x, b, P, iter); }
73 template <
typename Matrix1,
typename Precond,
typename Vector>
74 void AS_local_solve(using_gmres,
const Matrix1 &A, Vector &x,
75 const Vector &b,
const Precond &P, iteration &iter)
76 {
gmres(A, x, b, P, 100, iter); }
78 template <
typename Matrix1,
typename Precond,
typename Vector>
79 void AS_local_solve(using_bicgstab,
const Matrix1 &A, Vector &x,
80 const Vector &b,
const Precond &P, iteration &iter)
81 { bicgstab(A, x, b, P, iter); }
83 template <
typename Matrix1,
typename Precond,
typename Vector>
84 void AS_local_solve(using_qmr,
const Matrix1 &A, Vector &x,
85 const Vector &b,
const Precond &P, iteration &iter)
86 {
qmr(A, x, b, P, iter); }
88 #if defined(GMM_USES_SUPERLU)
89 struct using_superlu {};
91 template <
typename P,
typename Matrix>
92 struct actual_precond<P, using_superlu, Matrix> {
93 typedef typename linalg_traits<Matrix>::value_type value_type;
94 typedef SuperLU_factor<value_type> APrecond;
95 template <
typename PR>
96 static APrecond transform(
const PR &) {
return APrecond(); }
97 static const APrecond &transform(
const APrecond &PP) {
return PP; }
100 template <
typename Matrix1,
typename Precond,
typename Vector>
101 void AS_local_solve(using_superlu,
const Matrix1 &, Vector &x,
102 const Vector &b,
const Precond &P, iteration &iter)
103 { P.solve(x, b); iter.set_iteration(1); }
110 template <
typename Matrix1,
typename Matrix2,
typename Precond,
111 typename local_solver>
112 struct add_schwarz_mat{
113 typedef typename linalg_traits<Matrix1>::value_type value_type;
116 const std::vector<Matrix2> *vB;
117 std::vector<Matrix2> vAloc;
118 mutable iteration iter;
121 mutable std::vector<std::vector<value_type> > gi, fi;
122 std::vector<
typename actual_precond<Precond, local_solver,
123 Matrix1>::APrecond> precond1;
125 void init(
const Matrix1 &A_,
const std::vector<Matrix2> &vB_,
126 iteration iter_,
const Precond &P,
double residual_);
129 add_schwarz_mat(
const Matrix1 &A_,
const std::vector<Matrix2> &vB_,
130 iteration iter_,
const Precond &P,
double residual_)
131 { init(A_, vB_, iter_, P, residual_); }
134 template <
typename Matrix1,
typename Matrix2,
typename Precond,
135 typename local_solver>
136 void add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver>::init(
137 const Matrix1 &A_,
const std::vector<Matrix2> &vB_,
138 iteration iter_,
const Precond &P,
double residual_) {
140 vB = &vB_; A = &A_; iter = iter_;
141 residual = residual_;
144 vAloc.resize(nb_sub);
145 gi.resize(nb_sub); fi.resize(nb_sub);
146 precond1.resize(nb_sub);
147 std::fill(precond1.begin(), precond1.end(),
148 actual_precond<Precond, local_solver, Matrix1>::transform(P));
151 if (iter.get_noisy()) cout <<
"Init pour sub dom ";
153 int size,tranche,borne_sup,borne_inf,rank,tag1=11,tag2=12,tag3=13,sizepr = 0;
155 double t_ref,t_final;
158 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
159 MPI_Comm_size(MPI_COMM_WORLD, &size);
161 borne_inf=rank*tranche;
162 borne_sup=(rank+1)*tranche;
165 cout <<
"Nombre de sous domaines " << borne_sup - borne_inf << endl;
167 int sizeA = mat_nrows(*A);
168 gmm::csr_matrix<value_type> Acsr(sizeA, sizeA), Acsrtemp(sizeA, sizeA);
170 int next = (rank + 1) % size;
171 int previous = (rank + size - 1) % size;
175 for (
int nproc = 0; nproc < size; ++nproc) {
181 cout <<
"Sous domaines " << i <<
" : " << mat_ncols((*vB)[i]) << endl;
185 if (iter.get_noisy())
186 cout << i <<
" " << std::flush;
187 Matrix2 Maux(mat_ncols((*vB)[i]), mat_nrows((*vB)[i]));
190 Matrix2 Maux2(mat_ncols((*vB)[i]), mat_ncols((*vB)[i]));
192 gmm::resize(vAloc[i], mat_ncols((*vB)[i]), mat_ncols((*vB)[i]));
195 gmm::mult(gmm::transposed((*vB)[i]), Acsr, Maux);
199 gmm::resize(vAloc[i], mat_ncols((*vB)[i]), mat_ncols((*vB)[i]));
200 gmm::mult(gmm::transposed((*vB)[i]), *A, Maux);
205 if (nproc == size - 1 ) {
207 precond1[i].build_with(vAloc[i]);
217 if (nproc != size - 1) {
218 MPI_Sendrecv(&(Acsr.jc[0]), sizeA+1, MPI_INT, next, tag2,
219 &(Acsrtemp.jc[0]), sizeA+1, MPI_INT, previous, tag2,
220 MPI_COMM_WORLD, &status);
221 if (Acsrtemp.jc[sizeA] >
size_type(sizepr)) {
222 sizepr = Acsrtemp.jc[sizeA];
226 MPI_Sendrecv(&(Acsr.ir[0]), Acsr.jc[sizeA], MPI_INT, next, tag1,
227 &(Acsrtemp.ir[0]), Acsrtemp.jc[sizeA], MPI_INT, previous, tag1,
228 MPI_COMM_WORLD, &status);
230 MPI_Sendrecv(&(Acsr.pr[0]), Acsr.jc[sizeA], mpi_type(value_type()), next, tag3,
231 &(Acsrtemp.pr[0]), Acsrtemp.jc[sizeA], mpi_type(value_type()), previous, tag3,
232 MPI_COMM_WORLD, &status);
237 cout<<
"temps boucle precond "<< t_final-t_ref<<endl;
239 if (iter.get_noisy()) cout <<
"\n";
242 template <
typename Matrix1,
typename Matrix2,
typename Precond,
243 typename Vector2,
typename Vector3,
typename local_solver>
244 void mult(
const add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver> &M,
245 const Vector2 &p, Vector3 &q) {
248 static double tmult_tot = 0.0;
249 double t_ref = MPI_Wtime();
254 tmult_tot += MPI_Wtime()-t_ref;
255 cout <<
"tmult_tot = " << tmult_tot << endl;
257 std::vector<double> qbis(gmm::vect_size(q));
258 std::vector<double> qter(gmm::vect_size(q));
263 int size,tranche,borne_sup,borne_inf,rank;
265 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
266 MPI_Comm_size(MPI_COMM_WORLD, &size);
268 borne_inf=rank*tranche;
269 borne_sup=(rank+1)*tranche;
278 for (
size_type i = 0; i < M.fi.size(); ++i)
284 gmm::mult(gmm::transposed((*(M.vB))[i]), q, M.fi[i]);
286 AS_local_solve(local_solver(), (M.vAloc)[i], (M.gi)[i],
287 (M.fi)[i],(M.precond1)[i],M.iter);
288 itebilan = std::max(itebilan, M.iter.get_iteration());
292 cout <<
"First AS loop time " << MPI_Wtime() - t_ref << endl;
302 for (
size_type i = 0; i < M.gi.size(); ++i)
320 cout <<
"Second AS loop time " << MPI_Wtime() - t_ref << endl;
326 static double t_tot = 0.0;
345 MPI_Allreduce(&(qbis[0]), &(q[0]),gmm::vect_size(q), MPI_DOUBLE,
346 MPI_SUM,MPI_COMM_WORLD);
348 t_tot += t_final-t_ref;
349 cout<<
"["<< rank<<
"] temps reduce Resol "<< t_final-t_ref <<
" t_tot = " << t_tot << endl;
352 if (M.iter.get_noisy() > 0) cout <<
"itebloc = " << itebilan << endl;
353 M.itebilan += itebilan;
354 M.iter.set_resmax((M.iter.get_resmax() + M.residual) * 0.5);
357 template <
typename Matrix1,
typename Matrix2,
typename Precond,
358 typename Vector2,
typename Vector3,
typename local_solver>
359 void mult(
const add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver> &M,
360 const Vector2 &p,
const Vector3 &q) {
361 mult(M, p,
const_cast<Vector3 &
>(q));
364 template <
typename Matrix1,
typename Matrix2,
typename Precond,
365 typename Vector2,
typename Vector3,
typename Vector4,
366 typename local_solver>
367 void mult(
const add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver> &M,
368 const Vector2 &p,
const Vector3 &p2, Vector4 &q)
371 template <
typename Matrix1,
typename Matrix2,
typename Precond,
372 typename Vector2,
typename Vector3,
typename Vector4,
373 typename local_solver>
374 void mult(
const add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver> &M,
375 const Vector2 &p,
const Vector3 &p2,
const Vector4 &q)
376 {
mult(M, p,
const_cast<Vector4 &
>(q));
add(p2, q); }
382 template <
typename ASM_type,
typename Vect>
383 void AS_global_solve(using_cg,
const ASM_type &ASM, Vect &x,
384 const Vect &b, iteration &iter)
385 { cg(ASM, x, b, *(ASM.A), identity_matrix(), iter); }
387 template <
typename ASM_type,
typename Vect>
388 void AS_global_solve(using_gmres,
const ASM_type &ASM, Vect &x,
389 const Vect &b, iteration &iter)
390 {
gmres(ASM, x, b, identity_matrix(), 100, iter); }
392 template <
typename ASM_type,
typename Vect>
393 void AS_global_solve(using_bicgstab,
const ASM_type &ASM, Vect &x,
394 const Vect &b, iteration &iter)
395 { bicgstab(ASM, x, b, identity_matrix(), iter); }
397 template <
typename ASM_type,
typename Vect>
398 void AS_global_solve(using_qmr,
const ASM_type &ASM, Vect &x,
399 const Vect &b, iteration &iter)
400 {
qmr(ASM, x, b, identity_matrix(), iter); }
402 #if defined(GMM_USES_SUPERLU)
403 template <
typename ASM_type,
typename Vect>
404 void AS_global_solve(using_superlu,
const ASM_type &, Vect &,
405 const Vect &, iteration &) {
406 GMM_ASSERT1(
false,
"You cannot use SuperLU as "
407 "global solver in additive Schwarz meethod");
422 template <
typename Matrix1,
typename Matrix2,
423 typename Vector2,
typename Vector3,
typename Precond,
424 typename local_solver,
typename global_solver>
426 add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver> &ASM, Vector3 &u,
427 const Vector2 &f,
iteration &iter,
const global_solver&) {
429 typedef typename linalg_traits<Matrix1>::value_type value_type;
431 size_type nb_sub = ASM.vB->size(), nb_dof = gmm::vect_size(f);
433 std::vector<value_type> g(nb_dof);
434 std::vector<value_type> gbis(nb_dof);
436 double t_init=MPI_Wtime();
437 int size,tranche,borne_sup,borne_inf,rank;
438 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
439 MPI_Comm_size(MPI_COMM_WORLD, &size);
441 borne_inf=rank*tranche;
442 borne_sup=(rank+1)*tranche;
449 for (size_type i = 0; i < nb_sub; ++i)
456 gmm::mult(gmm::transposed((*(ASM.vB))[i]), f, ASM.fi[i]);
458 AS_local_solve(local_solver(), ASM.vAloc[i], ASM.gi[i], ASM.fi[i],
459 ASM.precond1[i], ASM.iter);
460 ASM.itebilan = std::max(ASM.itebilan, ASM.iter.get_iteration());
462 gmm::mult((*(ASM.vB))[i], ASM.gi[i], gbis,gbis);
464 gmm::mult((*(ASM.vB))[i], ASM.gi[i], g, g);
468 cout<<
"temps boucle init "<< MPI_Wtime()-t_init<<endl;
469 double t_ref,t_final;
471 MPI_Allreduce(&(gbis[0]), &(g[0]),gmm::vect_size(g), MPI_DOUBLE,
472 MPI_SUM,MPI_COMM_WORLD);
474 cout<<
"temps reduce init "<< t_final-t_ref<<endl;
478 cout<<
"begin global AS"<<endl;
480 AS_global_solve(global_solver(), ASM, u, g, iter);
483 cout<<
"temps AS Global Solve "<< t_final-t_ref<<endl;
485 if (iter.get_noisy())
486 cout <<
"Total number of internal iterations : " << ASM.itebilan << endl;
492 template <
typename Matrix1,
typename Matrix2,
493 typename Vector2,
typename Vector3,
typename Precond,
494 typename local_solver,
typename global_solver>
496 const Vector2 &f,
const Precond &P,
497 const std::vector<Matrix2> &vB,
499 local_solver, global_solver) {
501 if (iter.get_rhsnorm() == 0.0) {
gmm::clear(u);
return; }
502 iteration iter2 = iter; iter2.reduce_noisy();
504 add_schwarz_mat<Matrix1, Matrix2, Precond, local_solver>
505 ASM(A, vB, iter2, P, iter.get_resmax());
517 template <
typename Matrixt,
typename MatrixBi>
518 class NewtonAS_struct {
521 typedef Matrixt tangent_matrix_type;
522 typedef MatrixBi B_matrix_type;
523 typedef typename linalg_traits<Matrixt>::value_type value_type;
524 typedef std::vector<value_type> Vector;
527 virtual const std::vector<MatrixBi> &get_vB() = 0;
529 virtual void compute_F(Vector &f, Vector &x) = 0;
530 virtual void compute_tangent_matrix(Matrixt &M, Vector &x) = 0;
532 virtual void compute_sub_tangent_matrix(Matrixt &Mloc, Vector &x,
535 virtual void compute_sub_F(Vector &fi, Vector &x,
size_type i) = 0;
537 virtual ~NewtonAS_struct() {}
540 template <
typename Matrixt,
typename MatrixBi>
541 struct AS_exact_gradient {
542 const std::vector<MatrixBi> &vB;
543 std::vector<Matrixt> vM;
544 std::vector<Matrixt> vMloc;
547 for (
size_type i = 0; i < vB.size(); ++i) {
548 Matrixt aux(gmm::mat_ncols(vB[i]), gmm::mat_ncols(vM[i]));
549 gmm::resize(vMloc[i], gmm::mat_ncols(vB[i]), gmm::mat_ncols(vB[i]));
550 gmm::mult(gmm::transposed(vB[i]), vM[i], aux);
554 AS_exact_gradient(
const std::vector<MatrixBi> &vB_) : vB(vB_) {
555 vM.resize(vB.size()); vMloc.resize(vB.size());
556 for (
size_type i = 0; i < vB.size(); ++i) {
557 gmm::resize(vM[i], gmm::mat_nrows(vB[i]), gmm::mat_nrows(vB[i]));
562 template <
typename Matrixt,
typename MatrixBi,
563 typename Vector2,
typename Vector3>
564 void mult(
const AS_exact_gradient<Matrixt, MatrixBi> &M,
565 const Vector2 &p, Vector3 &q) {
567 typedef typename gmm::linalg_traits<Vector3>::value_type T;
568 std::vector<T> v(gmm::vect_size(p)), w, x;
569 for (
size_type i = 0; i < M.vB.size(); ++i) {
570 w.resize(gmm::mat_ncols(M.vB[i]));
571 x.resize(gmm::mat_ncols(M.vB[i]));
573 gmm::mult(gmm::transposed(M.vB[i]), v, w);
574 #if defined(GMM_USES_SUPERLU)
576 gmm::SuperLU_solve(M.vMloc[i], x, w, rcond);
578 gmm::MUMPS_solve(M.vMloc[i], x, w);
586 template <
typename Matrixt,
typename MatrixBi,
587 typename Vector2,
typename Vector3>
588 void mult(
const AS_exact_gradient<Matrixt, MatrixBi> &M,
589 const Vector2 &p,
const Vector3 &q) {
590 mult(M, p,
const_cast<Vector3 &
>(q));
593 template <
typename Matrixt,
typename MatrixBi,
594 typename Vector2,
typename Vector3,
typename Vector4>
595 void mult(
const AS_exact_gradient<Matrixt, MatrixBi> &M,
596 const Vector2 &p,
const Vector3 &p2, Vector4 &q)
599 template <
typename Matrixt,
typename MatrixBi,
600 typename Vector2,
typename Vector3,
typename Vector4>
601 void mult(
const AS_exact_gradient<Matrixt, MatrixBi> &M,
602 const Vector2 &p,
const Vector3 &p2,
const Vector4 &q)
603 {
mult(M, p,
const_cast<Vector4 &
>(q));
add(p2, q); }
605 struct S_default_newton_line_search {
607 double conv_alpha, conv_r;
608 size_t it, itmax, glob_it;
610 double alpha, alpha_old, alpha_mult, first_res, alpha_max_ratio;
611 double alpha_min_ratio, alpha_min;
613 bool max_ratio_reached;
614 double alpha_max_ratio_reached, r_max_ratio_reached;
618 double converged_value() {
return conv_alpha; };
619 double converged_residual() {
return conv_r; };
621 virtual void init_search(
double r,
size_t git,
double = 0.0) {
622 alpha_min_ratio = 0.9;
624 alpha_max_ratio = 10.0;
627 glob_it = git;
if (git <= 1) count_pat = 0;
628 conv_alpha =
alpha = alpha_old = 1.;
629 conv_r = first_res = r; it = 0;
631 max_ratio_reached =
false;
633 virtual double next_try() {
635 if (alpha >= 0.4)
alpha *= 0.5;
else alpha *= alpha_mult; ++it;
638 virtual bool is_converged(
double r,
double = 0.0) {
640 if (!max_ratio_reached && r < first_res * alpha_max_ratio) {
641 alpha_max_ratio_reached = alpha_old; r_max_ratio_reached = r;
642 it_max_ratio_reached = it; max_ratio_reached =
true;
644 if (max_ratio_reached && r < r_max_ratio_reached * 0.5
645 && r > first_res * 1.1 && it <= it_max_ratio_reached+1) {
646 alpha_max_ratio_reached = alpha_old; r_max_ratio_reached = r;
647 it_max_ratio_reached = it;
649 if (count == 0 || r < conv_r)
650 { conv_r = r; conv_alpha = alpha_old; count = 1; }
651 if (conv_r < first_res) ++count;
653 if (r < first_res * alpha_min_ratio)
654 { count_pat = 0;
return true; }
655 if (count >= 5 || (alpha < alpha_min && max_ratio_reached)) {
656 if (conv_r < first_res * 0.99) count_pat = 0;
658 { conv_r=r_max_ratio_reached; conv_alpha=alpha_max_ratio_reached; }
659 if (conv_r >= first_res * 0.9999) count_pat++;
664 S_default_newton_line_search() { count_pat = 0; }
669 template <
typename Matrixt,
typename MatrixBi,
typename Vector,
670 typename Precond,
typename local_solver,
typename global_solver>
671 void Newton_additive_Schwarz(NewtonAS_struct<Matrixt, MatrixBi> &NS,
673 iteration &iter,
const Precond &P,
674 local_solver, global_solver) {
675 Vector &u =
const_cast<Vector &
>(u_);
676 typedef typename linalg_traits<Vector>::value_type value_type;
677 typedef typename number_traits<value_type>::magnitude_type mtype;
678 typedef actual_precond<Precond, local_solver, Matrixt> chgt_precond;
680 double residual = iter.get_resmax();
682 S_default_newton_line_search internal_ls;
683 S_default_newton_line_search external_ls;
685 typename chgt_precond::APrecond PP = chgt_precond::transform(P);
686 iter.set_rhsnorm(mtype(1));
687 iteration iternc(iter);
688 iternc.reduce_noisy(); iternc.set_maxiter(
size_type(-1));
689 iteration iter2(iternc);
690 iteration iter3(iter2); iter3.reduce_noisy();
691 iteration iter4(iter3);
692 iternc.set_name(
"Local Newton");
693 iter2.set_name(
"Linear System for Global Newton");
694 iternc.set_resmax(residual/100.0);
695 iter3.set_resmax(residual/10000.0);
696 iter2.set_resmax(residual/1000.0);
697 iter4.set_resmax(residual/1000.0);
698 std::vector<value_type> rhs(NS.size()), x(NS.size()), d(NS.size());
699 std::vector<value_type> xi, xii, fi, di;
701 std::vector< std::vector<value_type> > vx(NS.get_vB().size());
702 for (
size_type i = 0; i < NS.get_vB().size(); ++i)
705 Matrixt Mloc, M(NS.size(), NS.size());
706 NS.compute_F(rhs, u);
707 mtype act_res=
gmm::vect_norm2(rhs), act_res_new(0), precond_res = act_res;
710 while(!iter.finished(std::min(act_res, precond_res))) {
711 for (
int SOR_step = 0; SOR_step >= 0; --SOR_step) {
713 for (
size_type isd = 0; isd < NS.get_vB().size(); ++isd) {
714 const MatrixBi &Bi = (NS.get_vB())[isd];
717 xi.resize(si); xii.resize(si); fi.resize(si); di.resize(si);
720 iternc.set_maxiter(30);
721 if (iternc.get_noisy())
722 cout <<
"Non-linear local problem " << isd << endl;
725 NS.compute_sub_F(fi, x, isd); gmm::scale(fi, value_type(-1));
727 if (r > value_type(0)) {
728 iternc.set_rhsnorm(std::max(r, mtype(1)));
729 while(!iternc.finished(r)) {
730 NS.compute_sub_tangent_matrix(Mloc, x, isd);
734 AS_local_solve(local_solver(), Mloc, di, fi, PP, iter3);
736 internal_ls.init_search(r, iternc.get_iteration());
738 alpha = internal_ls.next_try();
739 gmm::add(xi, gmm::scaled(di, -alpha), xii);
740 gmm::mult(Bi, gmm::scaled(xii, -1.0), u, x);
741 NS.compute_sub_F(fi, x, isd); gmm::scale(fi, value_type(-1));
743 }
while (!internal_ls.is_converged(r_t));
745 if (alpha != internal_ls.converged_value()) {
746 alpha = internal_ls.converged_value();
747 gmm::add(xi, gmm::scaled(di, -alpha), xii);
748 gmm::mult(Bi, gmm::scaled(xii, -1.0), u, x);
749 NS.compute_sub_F(fi, x, isd); gmm::scale(fi, value_type(-1));
754 if (iternc.get_noisy()) cout <<
"(step=" <<
alpha <<
")\t";
757 if (SOR_step)
gmm::mult(Bi, gmm::scaled(xii, -1.0), u, u);
758 gmm::mult(Bi, gmm::scaled(xii, -1.0), rhs, rhs);
762 if (SOR_step) cout <<
"SOR step residual = " << precond_res << endl;
763 if (precond_res < residual)
break;
764 cout <<
"Precond residual = " << precond_res << endl;
770 NS.compute_tangent_matrix(M, u);
771 add_schwarz_mat<Matrixt, MatrixBi, Precond, local_solver>
772 ASM(M, NS.get_vB(), iter4, P, iter.get_resmax());
773 AS_global_solve(global_solver(), ASM, d, rhs, iter2);
776 AS_exact_gradient<Matrixt, MatrixBi> eg(NS.get_vB());
777 for (
size_type i = 0; i < NS.get_vB().size(); ++i) {
778 NS.compute_tangent_matrix(eg.vM[i], vx[i]);
781 gmres(eg, d, rhs, gmm::identity_matrix(), 50, iter2);
785 external_ls.init_search(act_res, iter.get_iteration());
787 alpha = external_ls.next_try();
788 gmm::add(gmm::scaled(d, alpha), u, x);
789 NS.compute_F(rhs, x);
791 }
while (!external_ls.is_converged(act_res_new));
793 if (alpha != external_ls.converged_value()) {
794 alpha = external_ls.converged_value();
795 gmm::add(gmm::scaled(d, alpha), u, x);
796 NS.compute_F(rhs, x);
800 if (iter.get_noisy() > 1) cout << endl;
801 act_res = act_res_new;
802 if (iter.get_noisy())
803 cout <<
"(step=" <<
alpha
804 <<
")\t unprecond res = " << act_res <<
" ";
The Iteration object calculates whether the solution has reached the desired accuracy,...
Interface with MUMPS (LU direct solver for sparse matrices).
void mult_add(const L1 &l1, const L2 &l2, L3 &l3)
*/
void copy(const L1 &l1, L2 &l2)
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void resize(V &v, size_type n)
*/
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
void add(const L1 &l1, L2 &l2)
*/
Include the base gmm files.
void additive_schwarz(add_schwarz_mat< Matrix1, Matrix2, Precond, local_solver > &ASM, Vector3 &u, const Vector2 &f, iteration &iter, const global_solver &)
Function to call if the ASM matrix is precomputed for successive solve with the same system.
BiCGStab iterative solver.
Conjugate gradient iterative solver.
GMRES (Generalized Minimum Residual) iterative solver.
void gmres(const Mat &A, Vec &x, const VecB &b, const Precond &M, int restart, iteration &outer, Basis &KS)
Generalized Minimum Residual.
Quasi-Minimal Residual iterative solver.
void qmr(const Matrix &A, Vector &x, const VectorB &b, const Precond1 &M1, iteration &iter)
Quasi-Minimal Residual.
Interface with SuperLU (LU direct solver for sparse matrices).
size_t size_type
used as the common size type in the library
size_type alpha(short_type n, short_type d)
Return the value of which is the number of monomials of a polynomial of variables and degree .