TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Matrice_Morse_Sym.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Matrice_Morse_Sym.h>
17#include <TRUSTArrays.h>
18#include <Array_tools.h>
19#include <TRUSTTabs.h>
20
21#include <Sparskit.h>
22#include <Noms.h>
23
24Implemente_instanciable_sans_constructeur(Matrice_Morse_Sym,"Matrice_Morse_Sym",Matrice_Morse);
25
26/*! @brief Ecrit les trois tableaux de la structure de stockage Morse sur un flot de sortie.
27 *
28 * @param (Sortie& s) un flot de sortie
29 * @return (Sortie& s) le flot de sortie modifie
30 */
32{
33 s<<get_est_definie()<<finl;
34 return Matrice_Morse::printOn(s);
35}
36
37
38/*! @brief NON CODE
39 *
40 * @param (Entree& s) un flot d'entree
41 * @return (Entree& s) le flot d'entree
42 * @throws NON CODE
43 */
45{
46 int est_def;
47 s>>est_def;
48 set_est_definie(est_def);
49 return Matrice_Morse::readOn(s) ;
50}
51
52/*! @brief Constructeur d'une Matrice_Morse_Sym comportant n1 lignes et pouvant stocker n2 elements non-nuls (au maximum).
53 *
54 * Les elements de la matrice et la table des connectivites
55 * sont donnes dans les 3 derniers parametres.
56 *
57 * @param (int n1) le nombre de ligne de la matrice
58 * @param (int n2) le nombre d'element non nuls stockable par la matrice
59 * @param (IntLists& voisins) liste des voisins de chaque lignes
60 * @param (DoubleLists& valeurs) liste des valeurs
61 * @param (DoubleVect& terme_diag) le vecteur des termes diagonaux
62 */
63Matrice_Morse_Sym::Matrice_Morse_Sym(int n1, int n2, const IntLists& voisins,
64 const DoubleLists& valeurs,
65 const DoubleVect& terme_diag)
66 : Matrice_Morse(n1, n2)
67{
69 remplir(voisins, valeurs, terme_diag);
71}
72
73
74/*! @brief Constructeur d'une Matrice_Morse_Sym par copie d'une Matrice_Morse.
75 *
76 * @param (Matrice_Morse& acopier) la matrice a copier
77 */
87{
88 const Matrice_Base& A_base=A.valeur();
89 if(sub_type(Matrice_Morse_Sym, A_base))
90 *this=ref_cast(Matrice_Morse_Sym, A_base);
91 else if(sub_type(Matrice_Morse, A_base))
92 *this=ref_cast(Matrice_Morse, A_base);
95}
110{
111 const Matrice_Base& A_base=A.valeur();
112 if(sub_type(Matrice_Morse_Sym, A_base))
113 *this=ref_cast(Matrice_Morse_Sym, A_base);
114 else if(sub_type(Matrice_Morse, A_base))
115 *this=ref_cast(Matrice_Morse, A_base);
117 return *this;
118}
119
120/*! @brief Constructeur d'une Matrice_Morse_Sym par copie d'une Matrice_Morse.
121 *
122 * @param (Matrice_Morse& acopier) la matrice a copier
123 */
131
132/*! @brief Operation de multiplication-accumulation (saxpy) matrice matrice (matrice represente par un tableau)
133 *
134 * Operation: RESU = RESU + A*X
135 *
136 * @param (DoubleTab& x) la matrice a multiplier
137 * @param (DoubleTab& resu) la matrice resultat de l'operation
138 * @return (DoubleTab&) la matrice resultat de l'operation
139 * @throws taille du resultat incompatible avec la taille de x
140 */
141DoubleTab& Matrice_Morse_Sym::ajouter_multTab_(const DoubleTab& x, DoubleTab& resu) const
142{
143 if ( (x.nb_dim() == 1) && (resu.nb_dim() == 1))
144 {
145 ajouter_multvect(x,resu);
146 return resu;
147 }
148
150 int i,j;
151 double aij;
152 int comp;
153 int nb_com=x.dimension(1);
154 assert(resu.dimension(1)==nb_com);
155 double* t=new double[nb_com];
156 int n=nb_lignes();
157 for(i=0; i<n; i++)
158 {
159 for(comp=0; comp<nb_com; comp++)
160 t[comp] = coeff_(tab1_(i)-1)*x(i,comp);
161 for (auto k=tab1_(i); k<tab1_(i+1)-1; k++)
162 {
163 j = tab2_(k)-1;
164 aij = coeff_(k);
165 for(comp=0; comp<nb_com; comp++)
166 {
167 t[comp] += aij*x(j,comp);
168 resu(j,comp) += aij*x(i,comp);
169 }
170 }
171 for(comp=0; comp<nb_com; comp++)
172 resu(i,comp) += t[comp] ;
173 }
174 delete [] t;
175 return resu;
176}
177
178double Matrice_Morse_Sym::multvect_et_prodscal(const DoubleVect& x, DoubleVect& resu) const
179{
181
182 assert(x.size_totale() == nb_lignes() || x.size() == nb_lignes());
183 assert(resu.size_totale() == nb_lignes() || resu.size() == nb_lignes());
184 assert(m_ <= x.size_totale());
185
186 double prod_scal_local = 0.;
187 operator_egal(resu, 0.);
188
189 const int fin = nb_lignes() + 1;
190 {
191 const double * thecoef = get_coeff().addr() - 1;
192 const double * xx = x.addr() - 1;
193 double * res = resu.addr() - 1;
194 const auto * index1 = get_tab1().addr() - 1;
195 const int * index2 = get_tab2().addr() - 1;
196#ifdef COMPILER_BLRTS_XLC
197#pragma disjoint (*coef, *xx, *res)
198#endif
199 int i;
200 for (i = 1; i < fin; i++)
201 {
202 auto j = index1[i];
203 auto j_next= index1[i+1];
204 //int ncoeffs = j_next - j;
205 assert(i==index2[j]); // La diagonale meme nulle doit etre stockee dans une Mat_Morse_Sym
206 double xi = xx[i];
207 double resu_tmp = res[i] + thecoef[j] * xi;
208 j++;
209 for (; j < j_next; j++)
210 {
211 int nj = index2[j];
212 double coef_j = thecoef[j];
213 double xn = xx[nj];
214 resu_tmp += coef_j * xn;
215 res[nj] += coef_j * xi;
216 }
217 res[i] = resu_tmp;
218 prod_scal_local += resu_tmp * xi;
219 }
220 }
221
222 return prod_scal_local;
223}
224
225
226/*! @brief Operation de multiplication-accumulation (saxpy) matrice vecteur.
227 *
228 * Operation: resu = resu + A*x
229 *
230 * @param (DoubleVect& x) le vecteur a multiplier
231 * @param (DoubleVect& resu) le vecteur resultat de l'operation
232 * @return (DoubleVect&) le vecteur resultat de l'operation
233 */
234
235DoubleVect& Matrice_Morse_Sym::ajouter_multvect_(const DoubleVect& x, DoubleVect& resu) const
236{
238
239 assert(x.size_totale() == nb_lignes() || x.size() == nb_lignes());
240 assert(resu.size_totale() == nb_lignes() || resu.size() == nb_lignes());
241 assert(m_ <= x.size_totale());
242
243 const int fin = nb_lignes() + 1;
244 {
245 const double * thecoef = get_coeff().addr() - 1;
246 const double * xx = x.addr() - 1;
247 double * res = resu.addr() - 1;
248 const auto * index1 = get_tab1().addr() - 1;
249 const int * index2 = get_tab2().addr() - 1;
250#ifdef COMPILER_BLRTS_XLC
251#pragma disjoint (*coef, *xx, *res)
252#endif
253 int i;
254 for (i = 1; i < fin; i++)
255 {
256 auto j = index1[i];
257 auto j_next= index1[i+1];
258 assert(i==index2[j]); // La diagonale meme nulle doit etre stockee dans une Mat_Morse_Sym
259#if 0
260 // Note B.M.: sur les procs intel ce deroulage n'a aucun effet benefique.
261 int ncoeffs = j_next - j;
262 if (ncoeffs == 4)
263 {
264 int n2 = index2[j+1];
265 int n3 = index2[j+2];
266 int n4 = index2[j+3];
267 double xi = xx[i];
268 double res_i = res[i];
269 double res_n2 = res[n2];
270 double res_n3 = res[n3];
271 double res_n4 = res[n4];
272 double a1 = thecoef[j];
273 double a2 = thecoef[j+1];
274 double a3 = thecoef[j+2];
275 double a4 = thecoef[j+3];
276 res[i] = res_i + a1 * xi + a2 * xx[n2] + a3 * xx[n3] + a4 * xx[n4];
277 res[n2] = res_n2 + a2 * xi;
278 res[n3] = res_n3 + a3 * xi;
279 res[n4] = res_n4 + a4 * xi;
280 }
281 else
282#endif
283 {
284 double xi = xx[i];
285 double resu_tmp = res[i] + thecoef[j] * xi;
286 j++;
287 for (; j < j_next; j++)
288 {
289 int nj = index2[j];
290 double coef_j = thecoef[j];
291 double xn = xx[nj];
292 resu_tmp += coef_j * xn;
293 res[nj] += coef_j * xi;
294 }
295 res[i] = resu_tmp;
296 }
297 }
298 }
299#if 0
300 int fin2,l;
301 m=tab1_(0);
302 for(i=debut; i<n; i++)
303 {
304 xi=x(i);
305 l=m;
306 m=tab1_(i+1);
307 t = coeff_(l-1)*xi;
308 assert(i==tab2(l-1)-1); // La diagonale meme nulle doit etre stockee dans une Mat_Morse_Sym
309 //aij=coeff_(tab1_(i)-1);
310 fin2=m-1;
311 for (k=l; k<fin2; k++)
312 {
313 j = tab2_(k)-1;
314 assert(j<n);
315 aij = coeff_(k);
316 t += aij*x(j);
317 resu(j) += aij*xi;
318 }
319 resu(i) += t ;
320 }
321#endif
322 return resu;
323}
324
325
326/*! @brief Operation de multiplication-accumulation (saxpy) matrice vecteur, par la matrice transposee.
327 *
328 * Operation: resu = resu + A^{T}*x
329 *
330 * @param (DoubleVect& x) le vecteur a multiplier
331 * @param (DoubleVect& resu) le vecteur resultat de l'operation
332 * @return (DoubleVect&) le vecteur resultat de l'operation
333 */
334DoubleVect& Matrice_Morse_Sym::ajouter_multvectT_(const DoubleVect& x,DoubleVect& resu) const
335{
336 Cerr <<"Matrice_Morse_Sym::ajouter_multvectT_ is not coded" << finl;
337 exit();
338 return resu;
339}
340
341
342/*! @brief Fonction (hors classe) amie de la classe Matrice_Morse_Sym NE FAIT RIEN : NON CODE
343 *
344 * @param (Matrice_Morse_Sym&)
345 * @param (Matrice_Morse_Sym&)
346 * @return (Matrice_Morse_Sym)
347 */
349{
350 //Il faut evidemment que les matrices soient de meme taille
351 if (A.nb_lignes() != B.nb_lignes())
352 {
353 Cerr << "Error in Matrice_Morse_Sym::operator+" << finl;
354 Cerr << "The 2 matrices must have the same dimension" << finl;
355 Cerr << "The first matrix is of dimension: " << A.nb_lignes()<< finl;
356 Cerr << "The second matrix is of dimension: " << B.nb_lignes()<< finl;
358 }
359
360 Matrice_Morse_Sym somme(A.nb_lignes(),(int)(A.nb_coeff()+B.nb_coeff()));
361 IntList colonnes_A_ligne_i,colonnes_B_ligne_i;
362 int min_colonnes_A,min_colonnes_B,non_nuls_ligne_i;
363 DoubleList coeffs_A_ligne_i,coeffs_B_ligne_i;
364 double coeff_A,coeff_B;
365
366 //Pour s'assurer que compacte() va marcher
367 for (auto i=0; i<somme.get_coeff().size(); i++)
368 somme.get_set_coeff()(i) = 0.;
369
370 //On va remplir tab2_ par ordre croissant de colonnes
371 somme.get_set_tab1()(0) = 1;
372 for (int i=0; i<A.nb_lignes(); i++) //boucle sur les lignes
373 {
374 //Pour eviter les effets de bord
375 if (!colonnes_A_ligne_i.est_vide()) colonnes_A_ligne_i.vide();
376 if (!colonnes_B_ligne_i.est_vide()) colonnes_B_ligne_i.vide();
377
378 //Initialisation des colonnes_A et colonnes_B
379 //ATTENTION a la numerotation C++
380 for (auto j=0; j<A.get_tab1()(i+1)-A.get_tab1()(i); j++)
381 {
382 colonnes_A_ligne_i.add_if_not(A.get_tab2()(A.get_tab1()(i)+j-1));
383 coeffs_A_ligne_i.add(A.get_coeff()(A.get_tab1()(i)+j-1));
384 }//fin for
385
386 for (auto j=0; j<B.get_tab1()(i+1)-B.get_tab1()(i); j++)
387 {
388 colonnes_B_ligne_i.add_if_not(B.get_tab2()(B.get_tab1()(i)+j-1));
389 coeffs_B_ligne_i.add(B.get_coeff()(B.get_tab1()(i)+j-1));
390 }//fin for
391
392 //On initialise d'autres varibles
393 non_nuls_ligne_i = 0;
394
395 //Debut de l'algorithme
396 while (!colonnes_A_ligne_i.est_vide() || !colonnes_B_ligne_i.est_vide())
397 {
398 //Si l'une des listes est vide et pas l'autre
399 if (colonnes_A_ligne_i.est_vide() && !colonnes_B_ligne_i.est_vide())
400 {
401 somme.get_set_tab2()(somme.get_tab1()(i)+non_nuls_ligne_i-1) =
402 colonnes_B_ligne_i[0];
403
404 somme.get_set_coeff()(somme.get_tab1()(i)+non_nuls_ligne_i-1) =
405 coeffs_B_ligne_i[0] ;
406
407 colonnes_B_ligne_i.suppr(colonnes_B_ligne_i[0]);
408 coeffs_B_ligne_i.suppr(coeffs_B_ligne_i[0]);
409 non_nuls_ligne_i++;
410 }//fin if
411
412 if (colonnes_B_ligne_i.est_vide() && !colonnes_A_ligne_i.est_vide())
413 {
414 somme.get_set_tab2()(somme.get_tab1()(i)+non_nuls_ligne_i-1) =
415 colonnes_A_ligne_i[0];
416
417 somme.get_set_coeff()(somme.get_tab1()(i)+non_nuls_ligne_i-1) =
418 coeffs_A_ligne_i[0];
419
420 colonnes_A_ligne_i.suppr(colonnes_A_ligne_i[0]);
421 coeffs_A_ligne_i.suppr(coeffs_A_ligne_i[0]);
422 non_nuls_ligne_i++;
423 }//fin if
424
425 //Aucune des deux listes n'est vide
426 min_colonnes_A = colonnes_A_ligne_i[0];
427 min_colonnes_B = colonnes_B_ligne_i[0];
428 coeff_A = coeffs_A_ligne_i[0];
429 coeff_B = coeffs_B_ligne_i[0];
430
431 if (min_colonnes_A < min_colonnes_B)
432 {
433 somme.get_set_tab2()(somme.get_tab1()(i)+non_nuls_ligne_i-1) = min_colonnes_A;
434 somme.get_set_coeff()(somme.get_tab1()(i)+non_nuls_ligne_i-1) = coeff_A;
435
436 colonnes_A_ligne_i.suppr(min_colonnes_A);
437 coeffs_A_ligne_i.suppr(coeff_A);
438 non_nuls_ligne_i++;
439 }//fin if
440
441 if (min_colonnes_B < min_colonnes_A)
442 {
443 somme.get_set_tab2()(somme.get_tab1()(i)+non_nuls_ligne_i-1) = min_colonnes_B;
444 somme.get_set_coeff()(somme.get_tab1()(i)+non_nuls_ligne_i-1) = coeff_B;
445
446 colonnes_B_ligne_i.suppr(min_colonnes_B);
447 coeffs_B_ligne_i.suppr(coeff_B);
448 non_nuls_ligne_i++;
449 }//fin if
450
451 if (min_colonnes_A == min_colonnes_B)
452 {
453 somme.get_set_tab2()(somme.get_tab1()(i)+non_nuls_ligne_i-1) = min_colonnes_A;
454 somme.get_set_coeff()(somme.get_tab1()(i)+non_nuls_ligne_i-1) = coeff_A+coeff_B;
455
456 colonnes_A_ligne_i.suppr(min_colonnes_A);
457 colonnes_B_ligne_i.suppr(min_colonnes_B);
458 coeffs_A_ligne_i.suppr(coeff_A);
459 coeffs_B_ligne_i.suppr(coeff_B);
460 non_nuls_ligne_i++;
461 }//fin if
462
463 }// fin while
464
465 somme.get_set_tab1()(i+1) = somme.get_tab1()(i)+non_nuls_ligne_i;//?????
466 }// fin for
467
468 somme.compacte();
470 return somme;
471}
472
473
474/*! @brief Fonction (hors classe) amie de la classe Matrice_Morse_Sym NE FAIT RIEN : NON CODE
475 *
476 * @param (double)
477 * @param (Matrice_Morse_Sym& A)
478 * @return (Matrice_Morse_Sym)
479 * @throws NON CODE
480 */
481Matrice_Morse_Sym operator *(double x, const Matrice_Morse_Sym& A)
482{
483 Matrice_Morse_Sym mat_res(A);
484 mat_res.get_set_coeff()*=x;
486 return(mat_res);
487}
488
489
490/*! @brief Fonction (hors classe) amie de la classe Matrice_Morse_Sym Simple appel a operator*(double,const Matrice_Morse_Sym&) (qui est NON CODE)
491 *
492 * @param (Matrice_Morse_Sym& A) la matrice a multiplier par x
493 * @param (double x) un scalaire
494 * @return (Matrice_Morse_Sym) le resultat de l'appel sous-jacent
495 */
496Matrice_Morse_Sym operator *(const Matrice_Morse_Sym& A, double x)
497{
498 return(x*A);
499}
500
501
502/*! @brief NE FAIT RIEN : NON CODE
503 *
504 * @param (double)
505 * @return (Matrice_Morse_Sym)
506 * @throws NON CODE
507 */
509{
510 scale( x );
511 return(*this);
512}
513
514void Matrice_Morse_Sym::scale( const double x )
515{
516 coeff_ *= x;
517}
518
519void Matrice_Morse_Sym::get_stencil( Stencil& stencil ) const
520{
522
523 Stencil symmetric_stencil;
524 get_symmetric_stencil( symmetric_stencil );
525
527 symmetric_stencil,
528 stencil );
529}
530
531void Matrice_Morse_Sym::get_symmetric_stencil( Stencil& stencil ) const
532{
534
535 stencil.resize( 0, 2 );
536
537
538 ArrOfInt tmp;
539
540
541 const int nb_lines = nb_lignes( );
542 for ( int i=0; i<nb_lines; ++i )
543 {
544 auto k0 = tab1_( i ) - 1;
545 auto k1 = tab1_( i + 1 ) - 1;
546 int size = (int)(k1 - k0);
547
548 tmp.resize_array( 0 );
549 tmp.resize_array( size );
550
551 for ( int k=0; k<size; ++k )
552 {
553 tmp[ k ] = tab2_( k + k0 ) - 1;
554 }
555
556 tmp.ordonne_array( );
557
558 for ( int k=0; k<size; ++k )
559 {
560 stencil.append_line( i, tmp[ k ] );
561 }
562 }
563
564 const int new_size = stencil.dimension( 0 );
565
566 stencil.resize( new_size, 2 );
567}
568
570 StencilCoeffs& coefficients ) const
571{
573
574 Stencil symmetric_stencil;
575 StencilCoeffs symmetric_coefficients;
576 get_symmetric_stencil_and_coefficients( symmetric_stencil, symmetric_coefficients );
577
579 symmetric_stencil,
580 symmetric_coefficients,
581 stencil,
582 coefficients );
583}
584
585
587 StencilCoeffs& coefficients ) const
588{
590
591 stencil.resize( 0, 2 );
592
593
594 coefficients.resize( 0 );
595
596
597 IntTab tmp1(0);
598
599
600 ArrOfDouble tmp2;
601
602
603 ArrOfInt index;
604
605
606 const int nb_lines = nb_lignes( );
607 for ( int i=0; i<nb_lines; ++i )
608 {
609 auto k0 = tab1_( i ) - 1;
610 auto k1 = tab1_( i + 1 ) - 1;
611 int size = (int)(k1 - k0);
612
613 index.resize_array( 0 );
614
615 tmp1.resize( 0 );
616 tmp1.resize( size );
617
618 tmp2.resize_array( 0 );
619 tmp2.resize_array( size );
620
621 for ( int k=0; k<size; ++k )
622 {
623 tmp1( k ) = tab2_( k + k0 ) - 1;
624 tmp2[ k ] = coeff_( k + k0 );
625 }
626 tri_lexicographique_tableau_indirect( tmp1, index );
627
628 for ( int k=0; k<size; ++k )
629 {
630 int l = index[ k ];
631 stencil.append_line( i, tmp1[ l ] );
632 coefficients.append_array( tmp2[ l ] );
633 }
634 }
635
636 const int new_size = stencil.dimension( 0 );
637 assert( coefficients.size_array( ) == new_size );
638
639
640 stencil.resize( new_size, 2 );
641
642
643 coefficients.resize_array( new_size );
644}
645
646/*! @brief Operateur de negation unaire, renvoie l'opposee de la matrice: - A.
647 *
648 * Appelle operator*(const Matrice_Morse_Sym&,double)
649 *
650 */
652{
653 return((*this)*(-1));
654}
655/*
656static int commun(const ArrOfInt& items,
657 int prems,
658 int der,
659 int val,
660 int& item_courant)
661{
662 if (val==items[item_courant])
663 return item_courant;
664 if((val<items[0]) || (val>items[der]))
665 return item_courant;
666 if (val<items[item_courant])
667 {
668 --item_courant;
669 if(val>=items[item_courant]) return item_courant;
670 der=item_courant;
671 item_courant=(prems+item_courant)/2;
672 return commun(items,prems,der,val,item_courant);
673 }
674 if (val>items[item_courant])
675 {
676 ++item_courant;
677 if(val<items[item_courant]) return (--item_courant);
678 if(val==items[item_courant]) return (item_courant);
679 prems=item_courant;
680 item_courant=(item_courant+der)/2;
681 return commun(items,prems,der,val,item_courant);
682 }
683 return item_courant;
684}
685*/
686
687
688/*! @brief Operateur d'affectatiob d'une Matrice_Morse_Sym dans une Matrice_Morse_Sym.
689 *
690 * @param (Matrice_Morse_Sym& a) la partie droite de l'affectation
691 * @return (Matrice_Morse_Sym&) le resultat de l'affectation (*this)
692 */
704
705int Matrice_Morse_Sym_test()
706{
707 return 1;
708}
709
710
711int Matrice_Morse_Sym::inverse(const DoubleVect& secmem, DoubleVect& solution,
712 double coeff_seuil) const
713{
714 Cerr << "Not coded." << finl;
715 exit();
716 return 0;
717}
718
719int Matrice_Morse_Sym::inverse(const DoubleVect& secmem, DoubleVect& solution,
720 double coeff_seuil, int max_iter) const
721{
722 Cerr << "Not coded." << finl;
723 exit();
724 return 0;
725}
726
731
732/*! @brief Suppression des doublons on ordonne tab2;
733 *
734 * Verification de la diagonale: tous ses elements doivent etre stockes
735 *
736 */
737void Matrice_Morse_Sym::compacte(int elim_coeff_nul)
738{
739 Matrice_Morse::compacte(elim_coeff_nul);
740 // Verification si tous les elements de la diagonale sont bien stockes
741 int n=nb_lignes();
742 int elements_diagonaux_non_stockes=0;
743 auto size_tab2_ = tab2_.size_array();
744 for (int i=0; i<n; i++)
745 {
746 auto k=tab1_(i)-1;
747 if (k>=size_tab2_ || i!=tab2_(k)-1)
748 {
749 elements_diagonaux_non_stockes++;
750 // Cerr << "Probleme rencontre dans une Matrice_Morse_Sym:" << finl;
751 // Cerr << "La ligne "<<i<<" n'a pas sa diagonale correctement stockee." << finl;
752 // Cerr << "Les elements diagonaux meme nuls doivent etre stockes dans une Mat_Morse_Sym TRUST." << finl;
753 }
754 }
755 if (elements_diagonaux_non_stockes)
756 {
757 // On resize
758 auto nnz=size_tab2_+elements_diagonaux_non_stockes;
759 tab2_.resize(nnz);
760 coeff_.resize(nnz);
761 // On change la matrice en partant de la fin
762 for (int i=n-1; i>=0; i--)
763 {
764 // On copie en decalant
765 auto k1=tab1_(i)-1;
766 auto k2=tab1_(i+1)-1;
767 for (auto j=k2-1; j>=k1; j--)
768 {
769 tab2_(j+elements_diagonaux_non_stockes)=tab2_(j);
770 coeff_(j+elements_diagonaux_non_stockes)=coeff_(j);
771 }
772 tab1_(i+1)+=elements_diagonaux_non_stockes;
773
774 if (k1>=size_tab2_ || i!=tab2_(k1)-1)
775 {
776 // On insere l'element diagonal nul manquant
777 elements_diagonaux_non_stockes--;
778 tab2_(k1+elements_diagonaux_non_stockes)=i+1;
779 coeff_(k1+elements_diagonaux_non_stockes)=0.;
780 }
781 }
782 assert(elements_diagonaux_non_stockes==0);
783 }
785}
786
787/*! @brief Renumerotation d'une matrice afin de reduire la largeur de bande
788 *
789 */
791{
792 Cerr << "Bandwidth of the matrix : " << largeur_de_bande() << finl;
793 Cerr << "Renumbering the matrix ..." << finl;
794 const Matrice_Morse_Sym& matrice_initial = *this;
795 ArrOfInt& tab_iperm = matrice_initial.permutation_inverse();
796
797 // transformation d une matrice morse symetrique en matrice morse
798 Matrice_Morse matrice2(matrice_initial);
799 Matrice_Morse matrice(matrice_initial);
800
801 int mon_ordre = matrice.ordre();
802 matrice2.transpose(matrice);
803 for (int i=0; i<mon_ordre; i++) matrice2(i, i) = 0.;
804 matrice2 += matrice ;
805
806 // calcul de la permutation a effectuer
807 const int n = mon_ordre;
808 matrice2.set_tab1_int32();
809 const int* tab1tmp = matrice2.get_tab1_int32().addr();
810 const int* tab2tmp = matrice2.get_tab2().addr();
811 int init = 1;
812 tab_iperm.resize_array(n);
813 tab_iperm[0] = 1;
814
815 int* masktmp = new int[n];
816 for (int i=0 ; i<n; i++) masktmp[i] = 1;
817 const int* mask = (const int*) masktmp;
818 const int maskval = 1;
819 // GF passage a n+1 pour permettre de faire du Cholesky sur 1 maillage 1xN
820 int* level = new int[n+1];
821 int nlev;
822
823 // renumerotation des noeuds
824 // subroutine perphn(n,ja,ia,init,iperm,mask,maskval,nlev,riord,levels)
825 // SPARSKIT2/ORDERINGS/levset.f
826 F77NAME(PERPHN)(&n, tab2tmp, tab1tmp, &init, mask, &maskval,
827 &nlev, tab_iperm.addr(), level);
828
829 delete []masktmp;
830 delete []level;
831
832 ArrOfInt tab_perm(n);
833 for (int i=0 ; i<n; i++ ) tab_perm[tab_iperm[i] - 1] = i + 1;
834
835 matrice2 = matrice;
836
837 const double* a = matrice.get_coeff().addr();
838 const int* ja = matrice.get_tab2().addr();
839 matrice.set_tab1_int32();
840 const int* ia = matrice.get_tab1_int32().addr();
841 const double* tao = matrice2.get_coeff().addr();
842 double* ao = (double*)tao;
843 const int* tjao = matrice2.get_tab2().addr();
844 int* jao = (int*)tjao;
845 matrice2.set_tab1_int32();
846 const int* tiao = matrice2.get_tab1_int32().addr();
847 int* iao = (int*)tiao;
848
849 const int* perm = tab_perm.addr();
850 const int* perm_inv = tab_iperm.addr();//normalement inutile
851 const int job = 1;
852
853 // permutation de la matrice2 i.e. calcul de P A tP
854 // ici on ne permute que la partie superieure
855
856 // subroutine dperm (nrow,a,ja,ia,ao,jao,iao,perm,qperm,job)
857 // SPARSKIT2/FORMATS/unary.f
858 F77NAME(DPERM) (&n, a, ja, ia, ao, jao, iao, perm, perm_inv, &job);
859 matrice2.set_tab1(matrice2.get_tab1_int32());
860
861 matrice.transpose(matrice2);
862 for (int i=0; i<mon_ordre; i++) matrice2(i, i) = 0.;
863 matrice2 += matrice;
864 matrice.partie_sup(matrice2);
865 matrice_renumerotee_.typer("Matrice_Morse_Sym");
866 ref_cast(Matrice_Morse_Sym,matrice_renumerotee_.valeur()) = matrice;
867
868 // Construction de permutation() rovisoire deja fait avec
869 int size=permutation_inverse().size_array();
871 for(int i=0; i<size; i++)
872 permutation()[permutation_inverse()[i]-1]=i+1;
873 Cerr << "Bandwidth of the renumbered matrix : " << ref_cast(Matrice_Morse,matrice_renumerotee_.valeur()).largeur_de_bande() << finl;
875}
876
878{
879 if ( ! ( check_morse_matrix_structure( ) ) )
880 {
881 Cerr << "Invalid morse structure" << finl;
882 return false;
883 }
884
885 const int nb_lines = nb_lignes( );
886 for ( int i=0; i<nb_lines; ++i )
887 {
888 auto k0 = tab1_( i ) - 1;
889 auto k1 = tab1_( i + 1 ) - 1;
890
891 for ( auto k=k0; k<k1; ++k )
892 {
893 int j = tab2_( k ) - 1;
894 if ( j < i )
895 {
896 Cerr << "( j < i ) : line index : " << i << " and column index " << j << finl;
897 return false;
898 }
899 }
900 }
901 return true;
902}
903
905{
907 {
908 return false;
909 }
910
911 const int nb_lines = nb_lignes( );
912 for ( int i=0; i<nb_lines; ++i )
913 {
914 auto k0 = tab1_( i ) - 1;
915 auto k1 = tab1_( i + 1 ) - 1;
916
917 for ( auto k=k0; k<k1; ++k )
918 {
919 int j = tab2_( k ) - 1;
920 if ( j < i )
921 {
922 Cerr << "( j < i ) : line index : " << i << " and column index " << j << finl;
923 return false;
924 }
925 }
926 }
927 return true;
928}
929
930
932{
934#ifndef NDEBUG
936 {
937 Cerr << "Error in 'Matrice_Morse_Sym::assert_check_symmetric_morse_matrix_structure( )':" << finl;
938 Cerr << " Exiting..." << finl;
939 Process::exit( );
940 }
941 else
943#endif
944}
945
947{
949#ifndef NDEBUG
951 {
952 Cerr << "Error in 'Matrice_Morse_Sym::assert_check_sorted_symmetric_morse_matrix_structure( )':" << finl;
953 Cerr << " Exiting..." << finl;
954 Process::exit( );
955 }
956 else
958#endif
959}
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Matrice_Base Classe de base de la hierarchie des matrices.
bool is_stencil_up_to_date_
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
bool is_stencil_up_to_date() const
Classe Matrice_Morse_Sym Represente une matrice M (creuse) symetrique stockee au format Morse.
void assert_check_sorted_symmetric_morse_matrix_structure() const
void compacte(int elim_coeff_nul=0)
Suppression des doublons on ordonne tab2;.
DoubleVect & ajouter_multvectT_(const DoubleVect &, DoubleVect &) const override
Operation de multiplication-accumulation (saxpy) matrice vecteur, par la matrice transposee.
Matrice_Morse_Sym & operator*=(double)
NE FAIT RIEN : NON CODE.
bool check_symmetric_morse_matrix_structure() const
void get_symmetric_stencil_and_coefficients(Stencil &stencil, StencilCoeffs &coefficients) const override
void get_stencil(Stencil &stencil) const override
ArrOfInt & permutation()
Matrice_Morse_Sym(int n1=1, int n2=1)
void renumerote() const
Renumerotation d'une matrice afin de reduire la largeur de bande.
bool check_sorted_symmetric_morse_matrix_structure() const
DoubleVect & ajouter_multvect_(const DoubleVect &, DoubleVect &) const override
Operation de multiplication-accumulation (saxpy) matrice vecteur.
friend Matrice_Morse_Sym operator+(const Matrice_Morse_Sym &, const Matrice_Morse_Sym &)
Fonction (hors classe) amie de la classe Matrice_Morse_Sym NE FAIT RIEN : NON CODE.
int inverse(const DoubleVect &, DoubleVect &, double) const override
Calcule la solution du systeme lineaire: A * solution = secmem.
void assert_check_symmetric_morse_matrix_structure() const
void get_stencil_and_coefficients(Stencil &stencil, StencilCoeffs &coefficients) const override
Matrice_Morse_Sym & operator=(const Matrice_Morse_Sym &)
Operateur d'affectatiob d'une Matrice_Morse_Sym dans une Matrice_Morse_Sym.
ArrOfInt & permutation_inverse()
Matrice_Morse_Sym operator-() const
Operateur de negation unaire, renvoie l'opposee de la matrice: - A.
Sortie & imprimer_formatte(Sortie &s) const override
DoubleTab & ajouter_multTab_(const DoubleTab &, DoubleTab &) const override
Operation de multiplication-accumulation (saxpy) matrice matrice (matrice represente par un tableau).
void scale(const double x) override
virtual double multvect_et_prodscal(const DoubleVect &, DoubleVect &) const
void get_symmetric_stencil(Stencil &stencil) const override
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
int largeur_de_bande() const
Calcule la largeur de bande d'une matrice morse.
int morse_matrix_structure_has_changed_
bool check_morse_matrix_structure() const
auto nb_coeff() const
bool check_sorted_morse_matrix_structure() const
auto & get_set_tab2()
DoubleVect coeff_
const auto & get_tab2() const
int ordre() const override
Renvoie l'ordre de la matrice: - le nombre de lignes si la matrice est carree.
void set_tab1(const IntVect &tab1_int32)
Sortie & imprimer_formatte(Sortie &s) const override
virtual Matrice_Morse & transpose(const Matrice_Morse &a)
*this = a transposee.
const IntVect & get_tab1_int32() const
const auto & get_tab1() const
auto & get_set_coeff()
int get_symmetric() const
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
auto & get_set_tab1()
const auto & get_coeff() const
void remplir(const IntLists &, const DoubleLists &, const DoubleVect &)
virtual Matrice_Morse & partie_sup(const Matrice_Morse &a)
int nb_lignes() const override
Return local number of lines (=size on the current proc).
void compacte(int elim_coeff_nul=0)
Method to check/clean the Matrice_Morse matrix: -Suppress coefficient defined several times.
void set_tab1_int32() const
void set_est_definie(int)
int get_est_definie() const
void unsymmetrize_stencil_and_coefficients(const int nb_lines, const Stencil &symmetric_stencil, const StencilCoeffs &symmetric_coefficients, Stencil &stencil, StencilCoeffs &coefficients) const
void unsymmetrize_stencil(const int nb_lines, const Stencil &symmetric_stencil, Stencil &stencil) const
Classe Matrice Classe generique de la hierarchie des matrices.
Definition Matrice.h:34
friend class Sortie
Definition Objet_U.h:75
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
_TYPE_ * addr()
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void ordonne_array()
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTArray.h:156
int est_vide() const
TRUSTList & add(_TYPE_)
insertion en queue
Definition TRUSTList.tpp:85
TRUSTList & add_if_not(_TYPE_)
Ajout d'un element a la liste ssi il n'existe pas deja.
void suppr(_TYPE_)
Supprime un element contenu dans la liste.
void vide()
Vide la liste.
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
void append_line(_TYPE_)
Definition TRUSTTab.tpp:213
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61