TrioCFD 1.9.9_beta
TrioCFD documentation
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 Writes the three arrays of the Morse storage structure to an output stream.
27 *
28 * @param (Sortie& s) an output stream
29 * @return (Sortie& s) the modified output stream
30 */
32{
33 s<<get_est_definie()<<finl;
34 return Matrice_Morse::printOn(s);
35}
36
37
38/*! @brief NOT IMPLEMENTED
39 *
40 * @param (Entree& s) an input stream
41 * @return (Entree& s) the input stream
42 * @throws NOT IMPLEMENTED
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 Constructor of a Matrice_Morse_Sym with n1 rows and capable of storing at most n2 non-zero elements.
53 *
54 * The matrix elements and the connectivity table
55 * are given in the last 3 parameters.
56 *
57 * @param (int n1) the number of rows of the matrix
58 * @param (int n2) the maximum number of non-zero elements storable by the matrix
59 * @param (IntLists& voisins) list of neighbours for each row
60 * @param (DoubleLists& valeurs) list of values
61 * @param (DoubleVect& terme_diag) the vector of diagonal terms
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 Copy constructor of a Matrice_Morse_Sym from a Matrice_Morse.
75 *
76 * @param (Matrice_Morse& acopier) the matrix to copy
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 Copy constructor of a Matrice_Morse_Sym from a Matrice_Morse.
121 *
122 * @param (Matrice_Morse& acopier) the matrix to copy
123 */
131
132/*! @brief Matrix-matrix multiply-accumulate operation (saxpy) where the matrix is represented by an array.
133 *
134 * Operation: RESU = RESU + A*X
135 *
136 * @param (DoubleTab& x) the matrix to multiply
137 * @param (DoubleTab& resu) the result matrix of the operation
138 * @return (DoubleTab&) the result matrix of the operation
139 * @throws result size incompatible with the size of 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]); // Even a zero diagonal element must be stored in a 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 Matrix-vector multiply-accumulate operation (saxpy).
227 *
228 * Operation: resu = resu + A*x
229 *
230 * @param (DoubleVect& x) the vector to multiply
231 * @param (DoubleVect& resu) the result vector of the operation
232 * @return (DoubleVect&) the result vector of the 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]); // Even a zero diagonal element must be stored in a 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); // Even a zero diagonal element must be stored in a 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 Transposed-matrix-vector multiply-accumulate operation (saxpy).
327 *
328 * Operation: resu = resu + A^{T}*x
329 *
330 * @param (DoubleVect& x) the vector to multiply
331 * @param (DoubleVect& resu) the result vector of the operation
332 * @return (DoubleVect&) the result vector of the 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 Friend function (non-member) of class Matrice_Morse_Sym. DOES NOTHING: NOT IMPLEMENTED
343 *
344 * @param (Matrice_Morse_Sym&)
345 * @param (Matrice_Morse_Sym&)
346 * @return (Matrice_Morse_Sym)
347 */
349{
350 //The two matrices must obviously have the same size
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 //To ensure that compacte() will work
367 for (auto i=0; i<somme.get_coeff().size(); i++)
368 somme.get_set_coeff()(i) = 0.;
369
370 //Fill tab2_ in ascending column order
371 somme.get_set_tab1()(0) = 1;
372 for (int i=0; i<A.nb_lignes(); i++) //loop over rows
373 {
374 //To avoid boundary effects
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 of colonnes_A and colonnes_B
379 //BEWARE of C++ indexing
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 //Initialize other variables
393 non_nuls_ligne_i = 0;
394
395 //Start of the algorithm
396 while (!colonnes_A_ligne_i.est_vide() || !colonnes_B_ligne_i.est_vide())
397 {
398 //If one list is empty but not the other
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 //Neither list is empty
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 Friend function (non-member) of class Matrice_Morse_Sym. DOES NOTHING: NOT IMPLEMENTED
475 *
476 * @param (double)
477 * @param (Matrice_Morse_Sym& A)
478 * @return (Matrice_Morse_Sym)
479 * @throws NOT IMPLEMENTED
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 Friend function (non-member) of class Matrice_Morse_Sym. Simply calls operator*(double,const Matrice_Morse_Sym&) (which is NOT IMPLEMENTED)
491 *
492 * @param (Matrice_Morse_Sym& A) the matrix to multiply by x
493 * @param (double x) a scalar
494 * @return (Matrice_Morse_Sym) the result of the underlying call
495 */
496Matrice_Morse_Sym operator *(const Matrice_Morse_Sym& A, double x)
497{
498 return(x*A);
499}
500
501
502/*! @brief DOES NOTHING: NOT IMPLEMENTED
503 *
504 * @param (double)
505 * @return (Matrice_Morse_Sym)
506 * @throws NOT IMPLEMENTED
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 Unary negation operator, returns the opposite of the matrix: -A.
647 *
648 * Calls 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 Assignment operator of a Matrice_Morse_Sym into a Matrice_Morse_Sym.
689 *
690 * @param (Matrice_Morse_Sym& a) the right-hand side of the assignment
691 * @return (Matrice_Morse_Sym&) the result of the assignment (*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 Remove duplicates by sorting tab2.
733 *
734 * Check the diagonal: all diagonal elements must be stored.
735 *
736 */
737void Matrice_Morse_Sym::compacte(int elim_coeff_nul)
738{
739 Matrice_Morse::compacte(elim_coeff_nul);
740 // Check whether all diagonal elements are properly stored
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 // Resize
758 auto nnz=size_tab2_+elements_diagonaux_non_stockes;
759 tab2_.resize(nnz);
760 coeff_.resize(nnz);
761 // Modify the matrix starting from the end
762 for (int i=n-1; i>=0; i--)
763 {
764 // Copy with shift
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 // Insert the missing zero diagonal element
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 Renumbers a matrix to reduce its bandwidth.
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 // convert a symmetric Morse matrix to a general Morse matrix
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 // compute the permutation to apply
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: changed to n+1 to allow Cholesky on a 1xN mesh
820 int* level = new int[n+1];
821 int nlev;
822
823 // renumber the nodes
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 // permute matrice2, i.e. compute P A tP
854 // only the upper part is permuted here
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 // Build permutation() - provisional, already done with
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
Matrice_Base class - Base class of the matrix hierarchy.
bool is_stencil_up_to_date_
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Matrix-vector multiply-accumulate operation (saxpy).
bool is_stencil_up_to_date() const
Matrice_Morse_Sym class - Represents a sparse symmetric matrix M stored in Morse format.
void assert_check_sorted_symmetric_morse_matrix_structure() const
void compacte(int elim_coeff_nul=0)
Remove duplicates by sorting tab2.
DoubleVect & ajouter_multvectT_(const DoubleVect &, DoubleVect &) const override
Transposed-matrix-vector multiply-accumulate operation (saxpy).
Matrice_Morse_Sym & operator*=(double)
DOES NOTHING: NOT IMPLEMENTED.
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
Renumbers a matrix to reduce its bandwidth.
bool check_sorted_symmetric_morse_matrix_structure() const
DoubleVect & ajouter_multvect_(const DoubleVect &, DoubleVect &) const override
Matrix-vector multiply-accumulate operation (saxpy).
friend Matrice_Morse_Sym operator+(const Matrice_Morse_Sym &, const Matrice_Morse_Sym &)
Friend function (non-member) of class Matrice_Morse_Sym. DOES NOTHING: NOT IMPLEMENTED.
int inverse(const DoubleVect &, DoubleVect &, double) const override
Computes the solution of the linear system: 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 &)
Assignment operator of a Matrice_Morse_Sym into a Matrice_Morse_Sym.
ArrOfInt & permutation_inverse()
Matrice_Morse_Sym operator-() const
Unary negation operator, returns the opposite of the matrix: -A.
Sortie & imprimer_formatte(Sortie &s) const override
DoubleTab & ajouter_multTab_(const DoubleTab &, DoubleTab &) const override
Matrix-matrix multiply-accumulate operation (saxpy) where the matrix is represented by an array.
void scale(const double x) override
virtual double multvect_et_prodscal(const DoubleVect &, DoubleVect &) const
void get_symmetric_stencil(Stencil &stencil) const override
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
int largeur_de_bande() const
Computes the bandwidth of a Morse matrix.
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
Returns the order of the matrix: - the number of rows if the matrix is square.
void set_tab1(const IntVect &tab1_int32)
Sortie & imprimer_formatte(Sortie &s) const override
virtual Matrice_Morse & transpose(const Matrice_Morse &a)
*this = transpose of a.
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
Matrice class - Generic class in the matrix hierarchy.
Definition Matrice.h:34
friend class Sortie
Definition Objet_U.h:70
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
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