16#include <Solv_Gmres.h>
17#include <Matrice_Morse_Sym.h>
18#include <Matrice_Bloc.h>
53 if (
limpr()==1) s<<
" impr ";
54 if (
limpr()==-1) s<<
" quiet ";
65 param.lire_avec_accolades_depuis(is);
93 else if (mot==
"sans_precond")
106 const DoubleVect& secmem,
107 DoubleVect& solution)
112 return Gmres(matrice,secmem,solution);
121 Cerr<<
"Solv_Gmres : WARNING : one is not able to carry out Gmres by blocks"<<finl;
128 Cerr<<
"Solv_Gmres : WARNING : one is not able to carry out parallel calculation with Gmres"<<finl;
134 int retour=
Gmres(MB00,secmem,solution);
139 Cerr<<
"Solv_Gmres : WARNING : only linear systems based on Matrice_Morse_Sym or Matrice_Bloc type matrixes can be solved"<<finl;
155 double epsGMRES=1.e-10*0;
160 int nit1=std::max(nit1_min,nb_ligne_tot);
163 double rec_max = 0.1 ;
168 h.resize(nkr + 1, nkr);
186 Matrice_Morse_View matrice;
188 DoubleArrView Diag =
tab_Diag.view_wo();
189 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), ns, KOKKOS_LAMBDA(
192 Diag[i] = precond_diag ? 1. / matrice(i, i) : 1.;
194 end_gpu_timer(__KERNEL_NAME__);
202 double res0 = local_carre_norme_vect(
tab_v0);
204 CDoubleArrView Diag =
tab_Diag.view_ro();
205 DoubleArrView v0 =
tab_v0.view_rw();
206 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), ns, KOKKOS_LAMBDA(
211 end_gpu_timer(__KERNEL_NAME__);
213 double res = local_carre_norme_vect(
tab_v0);
220 Cout<<
"Gmres : initial residual = "<<res0<<finl;
225 Cerr <<
"Nan detected in Solv_Gmres::gmres_local()" << finl;
226 Cerr <<
"Contact TRUST support." << finl;
229 rec_min = (rec_min<res*epsGMRES) ? res*epsGMRES : rec_min;
230 rec_min = (rec_min<rec_max) ? rec_min : rec_max ;
231 bool legacy = getenv(
"TRUST_GMRES_REDUCE_COLLECTIVES") ==
nullptr;
234 for(
int it=0; it<nit; it++)
236 if (res==0)
return 0;
244 for(
int j=0; j<nkr; j++)
246 tab_v0.echange_espace_virtuel();
249 CDoubleArrView Diag =
tab_Diag.view_ro();
250 DoubleArrView v1 =
tab_v1.view_rw();
251 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), ns, KOKKOS_LAMBDA(
256 end_gpu_timer(__KERNEL_NAME__);
266 for (
int i = 0; i <= j; i++)
268 h(i, j) += mp_prodscal(
tab_v0,
v[i]);
269 tab_v0.ajoute(-
h(i, j),
v[i], VECT_REAL_ITEMS);
271 tem=mp_norme_vect(
tab_v0);
277 for (
int i = 0; i <= j; i++)
281 for (
int i = 0; i <= j; i++)
284 tab_v0.ajoute(-
h(i, j),
v[i], VECT_REAL_ITEMS);
287 for (
int i = 0; i <= j; i++)
292 for (
int i = 0; i <= j; i++)
297 tem=std::sqrt(
dh_loc[j + 1]);
310 for(
int i=0; i<nk; i++)
313 double tem = 1./sqrt(
h(i,i)*
h(i,i) +
h(im,i)*
h(im,i));
314 double ccos =
h(i,i) * tem;
315 double ssin = -
h(im,i) * tem;
316 for(
int j=i; j<nk; j++)
319 h(i,j) = ccos * tem - ssin *
h(im,j);
320 h(im,j) = ssin * tem + ccos *
h(im,j);
327 for(
int i=nk-1; i>=0; i--)
330 for(
int i0=i-1; i0>=0; i0--)
331 r[i0] -=
h(i0,i)*
r[i];
333 for(
int i=0; i<nk; i++)
334 tab_x.
ajoute(
r[i],
v[i], VECT_REAL_ITEMS);
342 double res2=mp_norme_vect(
tab_v0);
345 Cout <<
"The Gmres iterative system is stopped after : " << it+1 <<
" iterations "<<finl;
346 Cout <<
"since an increase of the residue is detected."<< finl;
352 Cout<<
" - At it = "<< it+1 <<
", residu scalar = "<< res2 << finl;
361 Cout <<
"Gmres : Number of iterations to reach convergence : " << it+1 << finl;
362 double residu_relatif = (res0>0?res2/res0:res2);
363 Cout <<
"Final residue: " << res2 <<
" ( " << residu_relatif <<
" )" << finl;
372 Cout <<
"Gmres : Stopped after "<< it+1 <<
" iterations (=nb_it_max)"<< finl;
373 double residu_relatif = (res0>0?res2/res0:res2);
374 Cout <<
"Final residue: " << res2 <<
" ( " << residu_relatif <<
" )" << finl;
376 if (it == (nb_ligne_tot-1))
378 Cerr <<
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<< finl;
379 Cerr <<
"!!! Gmres stopped after a number of iterations equal to the matrix size. "<< finl;
380 Cerr <<
"!!! Either your matrix is ill-conditioned (try cholesky instead), or your convergence threshold is too low. "<< finl;
381 Cerr <<
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<< finl;
389 CDoubleArrView Diag =
tab_Diag.view_ro();
390 DoubleArrView v0 =
tab_v0.view_rw();
391 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), ns, KOKKOS_LAMBDA(
396 end_gpu_timer(__KERNEL_NAME__);
398 res = mp_norme_vect(
tab_v0);
405 const DoubleVect& secmem,
406 DoubleVect& solution)
Class defining operators and methods for all reading operation in an input flow (file,...
Classe Matrice_Base Classe de base de la hierarchie des matrices.
virtual DoubleVect & multvect_(const DoubleVect &, DoubleVect &) const
int nb_bloc_lignes() const
virtual const Matrice & get_bloc(int i, int j) const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
virtual int inverse(const DoubleVect &, DoubleVect &, double) const
Calcule la solution du systeme lineaire: A * solution = secmem.
Une chaine de caractere (Nom) en majuscules.
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
static bool is_parallel()
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
int resoudre_systeme(const Matrice_Base &, const DoubleVect &, DoubleVect &) override
int Gmres(const Matrice_Morse &, const DoubleVect &, DoubleVect &)
int gmres_local(const Matrice_Morse &A, const DoubleVect &b, DoubleVect &tab_x1)
void set_param(Param ¶m) const override
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Classe de base des flux de sortie.
_SIZE_ size_array() const
_SIZE_ size_reelle() const
_SIZE_ size_reelle_ok() const
void ajoute(_SCALAR_TYPE_ alpha, const TRUSTVect &y, Mp_vect_options opt=VECT_ALL_ITEMS)
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")