19#include <Matrice_Bloc_Sym.h>
21#include <MD_Vector_base.h>
22#include <MD_Vector_tools.h>
23#include <communications.h>
24#include <TRUSTTab_parts.h>
25#include <Perf_counters.h>
39 s<<
" precond " <<le_precond_;
42 if (
limpr()==1) s<<
" impr ";
43 if (
limpr()==-1) s<<
" quiet ";
53 bool precond_nul =
false;
56 Param param((*this).que_suis_je());
61 param.ajouter_flag(
"impr",&impr);
64 param.ajouter_flag(
"quiet",&quiet);
67 param.ajouter(
"precond",&le_precond_);
76 param.ajouter_flag(
"precond_nul",&precond_nul);
85 param.lire_avec_accolades_depuis(is);
89 Cerr <<
"You forgot to define a preconditionner with the keyword precond." << finl;
90 Cerr <<
"If you don't want a preconditionner, add for the solver definition:" << finl;
91 Cerr <<
"precond_nul" << finl;
101 Cerr <<
"'impr' and 'quiet' keywords in Solv_GCP are not compatible. Use only one of them." << finl;
113 statistics().end_count(STD_COUNTERS::system_solver,-1,0);
114 int n =
resoudre_(matrice, secmem, solution, 100);
115 statistics().begin_count(STD_COUNTERS::system_solver,statistics().get_last_opened_counter_level()+1);
122 statistics().end_count(STD_COUNTERS::system_solver,-1,0);
123 int n =
resoudre_(matrice, secmem, solution, nmax);
124 statistics().begin_count(STD_COUNTERS::system_solver,statistics().get_last_opened_counter_level()+1);
135 le_precond_->reinit();
146 Cerr <<
"Error line_size>1 not coded (GCP)" << finl;
157 const int sz = secmem.
size();
159 renum_.resize(sztot_source, RESIZE_OPTIONS::NOCOPY_NOINIT);
163 for (i = sz; i < sztot_source; i++)
166 const auto& tab2 = mat_virt.
get_tab2();
167 const auto n = tab2.size_array();
168 for (i = 0; i < n; i++)
172 const int j = tab2[i]-1 + sz;
177 int nb_lignes_mat_virt = 0;
179 const int n = mat_virt.
get_tab1().size_array() - 1;
180 for (
int i = 0; i < n; i++)
182 nb_lignes_mat_virt++;
193 mem_size += sz_tot * (int)
sizeof(
double);
194 mem_size += sz * (int)
sizeof(
double) * 3;
195 const int nb_lignes_mat = sz;
197 auto nnz_reel_reel(mat.
get_tab1()(0));
199 mem_size += (sz + 1) * (
int)
sizeof(nnz_reel_reel);
200 assert(mat.
get_tab1().size_array() == sz + 1);
204 nnz_reel_reel = mat.
get_coeff().size_array();
209 nnz_reel_reel = mat.
get_coeff().size_array() - sz;
211 mem_size += (int)(nnz_reel_reel * (
int)
sizeof(
double));
212 mem_size += (int)(nnz_reel_reel * (
int)
sizeof(
int));
214 mem_size += (nb_lignes_mat_virt+1) * (
int)
sizeof(nnz_reel_reel);
215 const auto nnz_reel_virtuel = mat_virt.
get_coeff().size_array();
216 assert(mat_virt.
get_tab2().size_array() == nnz_reel_virtuel);
217 mem_size += (int)(nnz_reel_virtuel * (
int)
sizeof(
double));
218 mem_size += (int)(nnz_reel_virtuel * (
int)
sizeof(
int));
220 mem_size += nb_lignes_mat_virt * (int)
sizeof(
int);
222 if (mem_size % 8 != 0)
223 mem_size = (mem_size/8+1)*8;
229 Journal() <<
"Solv_GCP::prepare allocating data chunk : " << mem_size <<
" bytes" << finl;
230 tmp_data_block_.resize_array(mem_size/8, RESIZE_OPTIONS::NOCOPY_NOINIT);
233 resu_.ref_data(ptr, sz);
245 tmp_mat_.get_set_coeff().ref_data(ptr, nnz_reel_reel);
246 ptr += nnz_reel_reel;
247 tmp_mat_virt_.get_set_coeff().ref_data(ptr, nnz_reel_virtuel);
248 ptr += nnz_reel_virtuel;
251 using tab1_ptr_t =
decltype(
tmp_mat_.get_set_tab1().addr());
252 auto * tidptr =
static_cast<tab1_ptr_t
>(
static_cast<void*
>(ptr));
253 tmp_mat_.get_set_tab1().ref_data(tidptr, nb_lignes_mat + 1);
254 tidptr += nb_lignes_mat + 1;
255 tmp_mat_virt_.get_set_tab1().ref_data(tidptr, nb_lignes_mat_virt + 1);
256 tidptr += nb_lignes_mat_virt + 1;
257 int * iptr = (
int*)tidptr;
258 tmp_mat_.get_set_tab2().ref_data(iptr, (
int)nnz_reel_reel);
259 iptr += nnz_reel_reel;
260 tmp_mat_virt_.lignes_non_vides_.ref_data(iptr, nb_lignes_mat_virt);
261 iptr += nb_lignes_mat_virt;
262 tmp_mat_virt_.get_set_tab2().ref_data(iptr, (
int)nnz_reel_virtuel);
263 iptr += nnz_reel_virtuel;
273 for (
auto i = 0; i < nnz_reel_reel; i++)
292 for (i_ligne = 0; i_ligne < nb_lignes_mat; i_ligne++)
296 tmp_mat_.get_set_tab1()(i_ligne) = dest_index + 1;
297 const int ncoeff = (int)(mat.
get_tab1()(i_ligne+1) - mat.
get_tab1()(i_ligne) - 1);
299 assert(mat.
get_tab2()(src_index) == i_ligne + 1);
302 for (
int i = 0; i < ncoeff; i++, src_index++, dest_index++)
307 tmp_mat_.get_set_tab1()(i_ligne) = dest_index + 1;
314 int i_ligne_dest = 0;
316 for (
int i_ligne = 0; i_ligne < nb_lignes_mat; i_ligne++)
318 const int count = (int)(mat_virt.
get_tab1()(i_ligne+1) - mat_virt.
get_tab1()(i_ligne));
324 auto src_index = mat_virt.
get_tab1()(i_ligne) - 1;
325 for (
int i = 0; i < count; i++, src_index++, dest_index++)
329 int j = mat_virt.
get_tab2()(src_index) + sz - 1;
366 resu_.inject_array(secmem,
resu_.size_array());
375static void multiply_sub(DoubleVect& vx, DoubleVect& vy,
double alpha)
379 double *x_ptr = vx.
addr();
380 double *y_ptr = vy.
addr();
381 for (n = n - 1; n > 0; n -= 2, x_ptr += 2, y_ptr += 2)
383 double a = x_ptr[0] * alpha - y_ptr[0];
384 double b = x_ptr[1] * alpha - y_ptr[1];
390 x_ptr[0] = x_ptr[0] * alpha - y_ptr[0];
396static double ajoute_alpha_v_norme(DoubleVect& vx,
double alpha, DoubleVect& vy)
399 assert(vy.
size() == n);
400 double *x_ptr = vx.
addr();
401 double *y_ptr = vy.
addr();
402 double norme1 = 0., norme2 = 0.;
403 for (n = n - 1; n > 0; n -= 2, x_ptr += 2, y_ptr += 2)
405 double a = x_ptr[0] + alpha * y_ptr[0];
406 double b = x_ptr[1] + alpha * y_ptr[1];
415 double a = x_ptr[0] + alpha * y_ptr[0];
419 return norme1 + norme2;
423 const DoubleVect& secmem,
424 DoubleVect& solution,
431 const auto nb_inco_tot = nb_items_seq * ls;
432 auto nmax0 = std::max(nb_inco_tot, (trustIdType)nmax);
433 auto nmaxmax = 10000000;
434 nmax =
static_cast<int>(std::min<trustIdType>(nmax0, nmaxmax));
437 const int avec_precond = bool(le_precond_);
438 const int precond_requires_echange_espace_virtuel =
439 avec_precond && (le_precond_->get_flag_updated_input());
452 resu_.copy(solution, RESIZE_OPTIONS::NOCOPY_NOINIT);
453 residu_.copy(solution, RESIZE_OPTIONS::NOCOPY_NOINIT);
457 resu_.inject_array(secmem);
479 if (precond_requires_echange_espace_virtuel)
480 residu_.echange_espace_virtuel();
495 operator_negate(
tmp_p_, VECT_REAL_ITEMS);
496 double norme = local_carre_norme_vect(
residu_);
497 double norm_b = local_carre_norme_vect(
resu_);
500 double norme_b = sqrt(norm_b);
504 double norme_relative=(norme_b>DMINFLOAT?norme/(norme_b+DMINFLOAT):norme);
505 Cout <<
"Norm of the residue: " << norme <<
" (" << norme_relative <<
")" << finl;
511 while ( ( norme >
seuil_ ) && (niter++ < nmax) &&( niter<nb_it_max))
517 double resu_scalaire_p_local;
528 const double resu_scalaire_p =
mp_sum(resu_scalaire_p_local);
529 const double alfa = dold / resu_scalaire_p;
532 double norme_residu_locale;
535 norme_residu_locale = ajoute_alpha_v_norme(
residu_, alfa,
resu_);
540 norme_residu_locale = local_carre_norme_vect(
residu_);
545 if (precond_requires_echange_espace_virtuel)
546 residu_.echange_espace_virtuel();
552 double residu_scalaire_resu = local_prodscal(
residu_,
resu_);
553 norme = norme_residu_locale;
556 assert(residu_scalaire_resu >= 0);
557 multiply_sub(
tmp_p_,
resu_, residu_scalaire_resu / dold);
558 dold = residu_scalaire_resu;
562 const double dnew = mp_carre_norme_vect(
residu_);
563 norme =
mp_sum(norme_residu_locale);
572 Cout << norme <<
" ";
573 if ((niter % 15) == 0) Cout << finl ;
578 Cerr <<
"No convergence after : " << niter <<
" iterations\n";
579 Cerr <<
" Residue : "<< norme <<
"\n";
580 Cerr <<
" threshold : "<<
seuil_ <<
"\n";
581 Cerr <<
"Change your data set." << finl;
595 double norme_relative=(norme_b>0?norme/(norme_b+DMINFLOAT):norme);
597 Cout <<
"Final residue: " << norme <<
" ( " << norme_relative <<
" )"<<finl;
Class defining operators and methods for all reading operation in an input flow (file,...
virtual int get_nb_items_tot() const
virtual trustIdType nb_items_seq_tot() const
virtual int get_nb_items_reels() const
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Classe Matrice_Base Classe de base de la hierarchie des matrices.
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication d'un vecteur par la matrice.
virtual const Matrice & get_bloc(int i, int j) const
Classe Matrice_Morse_Sym Represente une matrice M (creuse) symetrique stockee au format Morse.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
const auto & get_tab2() const
const auto & get_tab1() const
const auto & get_coeff() const
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.
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 Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
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.
ArrOfDouble tmp_data_block_
Matrice_SuperMorse tmp_mat_virt_
int resoudre_(const Matrice_Base &, const DoubleVect &, DoubleVect &, int)
int resoudre_systeme(const Matrice_Base &, const DoubleVect &, DoubleVect &) override
void prepare_data(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
DoubleVect tmp_p_avec_items_virt_
Matrice_Morse_Sym tmp_mat_
int get_flag_updated_result() const
Classe de base des flux de sortie.
_SIZE_ size_array() const
TRUSTArray & inject_array(const TRUSTArray &source, _SIZE_ nb_elements=-1, _SIZE_ first_element_dest=0, _SIZE_ first_element_source=0)
_SIZE_ size_totale() const
_SIZE_ size_reelle() const
_SIZE_ size_reelle_ok() const
virtual const MD_Vector & get_md_vector() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")