TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Matrice_Bloc.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 <Matrice_Morse.h>
18#include <Matrice_Bloc.h>
19#include <Matrix_tools.h>
20#include <TRUSTArrays.h>
21#include <TRUSTTabs.h>
22#include <Matrice_Nulle.h>
23
24Implemente_instanciable_sans_constructeur(Matrice_Bloc,"Matrice_Bloc",Matrice_Base);
25
26/*! @brief
27 *
28 */
30{
31 os << nb_blocs_ << finl;
32 os << N_ << finl;
33 os << M_ << finl;
34 for ( int i=0; i<nb_blocs_; ++i )
35 {
36 os << blocs_[i] << finl;
37 }
38 return os;
39}
40
41/*! @brief
42 *
43 */
45{
46 is >> nb_blocs_;
47 is >> N_;
48 is >> M_;
49 blocs_.dimensionner( nb_blocs_ );
50 for ( int i=0; i<nb_blocs_; ++i )
51 {
52 is >> blocs_[i];
53 }
54 return is;
55}
56
58{
59 if ( M_ == N_)
60 {
61 return N_;
62 }
63 return 0;
64}
65
67{
68 int sum=0;
69 for( int i=0; i<N_; ++i )
70 {
71 // Codage pour fonctionner avec le stockage de Mat_Bloc_Sym (j>=i)
72 sum += get_bloc(i,M_-1).valeur( ).nb_lignes();
73 }
74 return sum;
75}
76
78{
79 int sum=0;
80 for( int i=0; i<M_; ++i )
81 {
82 sum += get_bloc(0,i).valeur( ).nb_colonnes();
83 }
84 return sum;
85}
86
87DoubleVect& Matrice_Bloc::ajouter_multvect_( const DoubleVect& x,
88 DoubleVect& r ) const
89{
90 const double * const_x_addr = x.addr( );
91 double * x_addr = ( double * ) const_x_addr;
92 double * r_addr = r.addr( );
93
94 DoubleVect x_bloc; // Une sous-partie de x
95 DoubleVect r_bloc; // Une sous-partie de y
96
97 int r_bloc_debut = 0; // Premier element de r du bloc courant
98 // Boucle sur les lignes de blocs
99 for ( int i_ligne = 0; i_ligne < N_; ++i_ligne )
100 {
101 const int r_bloc_size = get_bloc( i_ligne, 0 ).valeur( ).nb_lignes( );
102 r_bloc.ref_data( r_addr + r_bloc_debut, r_bloc_size );
103 assert( r_bloc_debut+r_bloc_size <= r.size_array( ) );
104 int x_bloc_debut = 0; // Premier element de x du bloc courant
105 // Boucle sur les colonnes de blocs
106 for ( int i_colonne = 0; i_colonne < M_; ++i_colonne )
107 {
108 const Matrice& sub_bloc = get_bloc( i_ligne, i_colonne );
109 const int x_bloc_size = sub_bloc.valeur( ).nb_colonnes( );
110 x_bloc.ref_data( x_addr + x_bloc_debut, x_bloc_size );
111 assert( x_bloc_debut+x_bloc_size <= x.size_array( ) );
112 sub_bloc.valeur( ).ajouter_multvect_( x_bloc, r_bloc );
113 x_bloc_debut += x_bloc_size;
114 }
115 r_bloc_debut += r_bloc_size;
116 }
117 return r;
118}
119
120DoubleVect& Matrice_Bloc::ajouter_multvectT_(const DoubleVect& x,
121 DoubleVect& r) const
122{
123 const double * const_x_addr = x.addr( );
124 double * x_addr = ( double * ) const_x_addr;
125 double * r_addr = r.addr( );
126
127 DoubleVect x_bloc; // Une sous-partie de x
128 DoubleVect r_bloc; // Une sous-partie de r
129
130 int r_bloc_debut = 0; // Premier element de r du bloc courant
131 // Boucle sur les lignes de blocs
132 for ( int i_ligne = 0; i_ligne < M_; ++i_ligne )
133 {
134 const int r_bloc_size = get_bloc( 0, i_ligne ).valeur( ).nb_colonnes( );
135 r_bloc.ref_data( r_addr + r_bloc_debut, r_bloc_size );
136 assert( r_bloc_debut+r_bloc_size <= r.size_array( ) );
137 int x_bloc_debut = 0; // Premier element de x du bloc courant
138 // Boucle sur les colonnes de blocs
139 for ( int i_colonne = 0; i_colonne < N_; ++i_colonne )
140 {
141 const Matrice& sub_bloc = get_bloc( i_colonne, i_ligne );
142 const int x_bloc_size = sub_bloc.valeur( ).nb_lignes( );
143 x_bloc.ref_data( x_addr + x_bloc_debut, x_bloc_size );
144 assert( x_bloc_debut+x_bloc_size <= x.size_array( ) );
145 sub_bloc.valeur( ).ajouter_multvectT_( x_bloc, r_bloc );
146 x_bloc_debut += x_bloc_size;
147 }
148 r_bloc_debut += r_bloc_size;
149 }
150 return r;
151}
152
153DoubleTab& Matrice_Bloc::ajouter_multTab_(const DoubleTab& x,
154 DoubleTab& r) const
155{
156 Cerr << "Error in 'Matrice_Bloc::ajouter_multTab_()':" << finl;
157 Cerr << " Not yet implemented" << finl;
158 Process::exit( );
159
160 return r;
161}
162
163void Matrice_Bloc::scale( const double x )
164{
165 const int nb_line_blocks = nb_bloc_lignes( );
166 const int nb_column_blocks = nb_bloc_colonnes( );
167
168 for (int i=0; i<nb_line_blocks; i++)
169 {
170 for (int j=0; j<nb_column_blocks; j++)
171 {
172 Matrice_Base& matrix = get_bloc( i, j ).valeur( );
173 matrix.scale( x );
174 }
175 }
176}
177
179{
180
182 {
183 for ( const auto& b : blocs_non_nuls_ )
184 {
185 b->clean( );
186 }
187 }
188 else
189 {
190
191 for (int i=0; i<nb_blocs_; ++i)
192 {
193 Matrice_Base& matrix = blocs_[ i ].valeur( );
194 matrix.clean( );
195 }
196 }
197}
198
199void Matrice_Bloc::get_stencil( Stencil& stencil ) const
200{
203 {
204 stencil = stencil_;
205 return;
206 }
207
208 const int nb_line_blocks = nb_bloc_lignes( );
209 const int nb_column_blocks = nb_bloc_colonnes( );
210 const int nb_stencils = nb_line_blocks * nb_column_blocks;
211
212 VECT( Stencil ) local_stencils;
213 local_stencils.dimensionner( nb_stencils );
214
215 int imin = 0;
216 int imax = 0;
217 int jmin = 0;
218 int jmax = 0;
219
220 for ( int i=0; i<nb_line_blocks; ++i )
221 {
222 for ( int j=0; j<nb_column_blocks; ++j )
223 {
224 const Matrice_Base& local_matrix = get_bloc( i, j ).valeur( );
225
226 imax = imin + local_matrix.nb_lignes( );
227 jmax = jmin + local_matrix.nb_colonnes( );
228
229 Stencil& local_stencil = local_stencils[ i * nb_column_blocks + j ];
230 local_matrix.get_stencil( local_stencil );
231
232 const int size = local_stencil.dimension( 0 );
233 for ( int k=0; k<size; ++k )
234 {
235 local_stencil( k, 0 ) += imin;
236 local_stencil( k, 1 ) += jmin;
237 }
238 jmin = jmax;
239 }
240 imin = imax;
241 jmin = 0;
242 }
243
244 const int nb_lines = nb_lignes( );
245 ArrOfInt offsets( nb_lines + 1 );
246 offsets[ 0 ] = 0;
247
248 for ( int i=0; i<nb_stencils; ++i )
249 {
250 const Stencil& local_stencil = local_stencils[ i ];
251 const int size = local_stencil.dimension( 0 );
252
253 for ( int k=0; k<size; ++k )
254 {
255 const int line = local_stencil( k, 0 );
256 offsets[ line + 1 ] += 1;
257 }
258 }
259
260 for ( int i=0; i<nb_lines; ++i )
261 {
262 offsets[ i + 1 ] += offsets[ i ];
263 }
264
265 const int stencil_size = offsets[ nb_lines ];
266 stencil.resize( stencil_size, 2 );
267
268 stencil = -1;
269
270 for ( int i=0; i<nb_stencils; ++i )
271 {
272 const Stencil& local_stencil = local_stencils[ i ];
273 const int size = local_stencil.dimension( 0 );
274
275 for ( int k=0; k<size; ++k )
276 {
277 const int line = local_stencil( k, 0 );
278 const int column = local_stencil( k, 1 );
279 const int index = offsets[ line ];
280
281 assert( stencil( index, 0 ) < 0 );
282 assert( stencil( index, 1 ) < 0 );
283 assert( index < offsets[ line + 1 ] );
284
285 stencil( index, 0 ) = line;
286 stencil( index, 1 ) = column;
287 offsets[ line ] += 1;
288 }
289 }
290
291}
292
293
295{
296 std::fill(line_offsets_.begin( ),line_offsets_.end( ), 0.);
297 std::fill(column_offsets_.begin( ),column_offsets_.end( ), 0.);
298 blocs_non_nuls_.clear( );
299
300 const int nb_line_blocks = nb_bloc_lignes( );
301 const int nb_column_blocks = nb_bloc_colonnes( );
302 const int nb_stencils = nb_line_blocks * nb_column_blocks;
303
304
305 VECT( Stencil ) local_stencils;
306 local_stencils.dimensionner( nb_stencils );
307
308 int imin = 0;
309 int imax = 0;
310 int jmin = 0;
311 int jmax = 0;
312
313 for ( int i=0; i<nb_line_blocks; ++i )
314 {
315 for ( int j=0; j<nb_column_blocks; ++j )
316 {
317 const Matrice_Base& local_matrix = get_bloc( i, j ).valeur( );
318 if ( ! sub_type( Matrice_Nulle, local_matrix ))
319 {
320 blocs_non_nuls_.push_back( &get_bloc( i, j ).valeur( ) );
321 line_offsets_.push_back( imin );
322 column_offsets_.push_back( jmin );
323 }
324
325 imax = imin + local_matrix.nb_lignes( );
326 jmax = jmin + local_matrix.nb_colonnes( );
327
328 Stencil& local_stencil = local_stencils[ i * nb_column_blocks + j ];
329 local_matrix.get_stencil( local_stencil );
330
331 const int size = local_stencil.dimension( 0 );
332 for ( int k=0; k<size; ++k )
333 {
334 local_stencil( k, 0 ) += imin;
335 local_stencil( k, 1 ) += jmin;
336 }
337 jmin = jmax;
338 }
339 imin = imax;
340 jmin = 0;
341 }
342
343 const int nb_lines = nb_lignes( );
344 ArrOfInt offsets( nb_lines + 1 );
345 offsets[ 0 ] = 0;
346
347 for ( int i=0; i<nb_stencils; ++i )
348 {
349 const Stencil& local_stencil = local_stencils[ i ];
350 const int size = local_stencil.dimension( 0 );
351
352 for ( int k=0; k<size; ++k )
353 {
354 const int line = local_stencil( k, 0 );
355 offsets[ line + 1 ] += 1;
356 }
357 }
358
359 for ( int i=0; i<nb_lines; ++i )
360 {
361 offsets[ i + 1 ] += offsets[ i ];
362 }
363
364 offsets_ = offsets ;
365
366 const int stencil_size = offsets[ nb_lines ];
367 stencil_.resize( stencil_size, 2 );
368
369 stencil_ = -1;
370
371 for ( int i=0; i<nb_stencils; ++i )
372 {
373 const Stencil& local_stencil = local_stencils[ i ];
374 const int size = local_stencil.dimension( 0 );
375
376 for ( int k=0; k<size; ++k )
377 {
378 const int line = local_stencil( k, 0 );
379 const int column = local_stencil( k, 1 );
380 const int index = offsets[ line ];
381
382 assert( stencil_( index, 0 ) < 0 );
383 assert( stencil_( index, 1 ) < 0 );
384 assert( index < offsets[ line + 1 ] );
385
386 stencil_( index, 0 ) = line;
387 stencil_( index, 1 ) = column;
388 offsets[ line ] += 1;
389 }
390 }
391
393}
394
395// Local template method: copy either values or ptrs to value!
396namespace
397{
398template<typename _TAB_T_> static inline void _get_sub_stencil_coeff(const Matrice_Base& mat, Stencil& sten, _TAB_T_& coeff);
399
400template<> inline void _get_sub_stencil_coeff<StencilCoeffs>(const Matrice_Base& mat, Stencil& sten, StencilCoeffs& coeff)
401{
402 mat.get_stencil_and_coefficients( sten, coeff );
403}
404
405template<> inline void _get_sub_stencil_coeff<std::vector<const double*>>(const Matrice_Base& mat, Stencil& sten, std::vector<const double*>& coeff)
406{
407 mat.get_stencil_and_coeff_ptrs( sten, coeff );
408}
409}
410
411template<typename _TAB_T_, typename _VAL_T_>
412void Matrice_Bloc::get_stencil_coeff_templ( Stencil& stencil, _TAB_T_& coeff_sp) const
413{
415 const int nb_line_blocks = nb_bloc_lignes( );
416 const int nb_column_blocks = nb_bloc_colonnes( );
417
418 int imin = 0;
419 int imax = 0;
420 int jmin = 0;
421 int jmax = 0;
422
424 {
425 stencil = stencil_;
426 ArrOfInt offsets = offsets_;
427
428 Stencil local_stencil;
429 _TAB_T_ local_coeff;
430
431
432 for ( size_t i=0; i<blocs_non_nuls_.size(); ++i )
433 {
434 const Matrice_Base& local_matrix = *blocs_non_nuls_[ i ];
435
436 imin = line_offsets_[i];
437 jmin = column_offsets_[i];
438 imax = imin + local_matrix.nb_lignes( );
439 jmax = jmin + local_matrix.nb_colonnes( );
440
441 _get_sub_stencil_coeff<_TAB_T_>(local_matrix, local_stencil, local_coeff);
442
443 const int size = local_stencil.dimension( 0 );
444
445 for ( int k=0; k<size; ++k )
446 {
447 const int line = local_stencil( k, 0 ) + imin;
448 const int index = offsets[ line ];
449
450 coeff_sp[index] = local_coeff[ k ];
451
452 offsets[ line ] += 1;
453 }
454 }
455 return;
456 }
457 const int nb_stencils = nb_line_blocks * nb_column_blocks;
458
459 std::vector<Stencil> vect_local_stencils(nb_stencils);
460 std::vector<_TAB_T_> vect_local_coefficients(nb_stencils);
461
462 for ( int i=0; i<nb_line_blocks; ++i )
463 {
464 for ( int j=0; j<nb_column_blocks; ++j )
465 {
466 const Matrice_Base& local_matrix = get_bloc( i, j ).valeur( );
467
468 imax = imin + local_matrix.nb_lignes( );
469 jmax = jmin + local_matrix.nb_colonnes( );
470
471 Stencil& local_stencil = vect_local_stencils[ i * nb_column_blocks + j ];
472 _TAB_T_& local_coefficients = vect_local_coefficients[i * nb_column_blocks + j ];
473
474 _get_sub_stencil_coeff<_TAB_T_>(local_matrix, local_stencil, local_coefficients);
475
476 const int size = local_stencil.dimension( 0 );
477 for ( int k=0; k<size; ++k )
478 {
479 local_stencil( k, 0 ) += imin;
480 local_stencil( k, 1 ) += jmin;
481 }
482 jmin = jmax;
483 }
484 imin = imax;
485 jmin = 0;
486 }
487
488 const int nb_lines = nb_lignes( );
489 ArrOfInt offsets( nb_lines + 1 );
490 offsets[ 0 ] = 0;
491
492 for ( int i=0; i<nb_stencils; ++i )
493 {
494 const Stencil& local_stencil = vect_local_stencils[ i ];
495 const int size = local_stencil.dimension( 0 );
496
497 for ( int k=0; k<size; ++k )
498 {
499 const int line = local_stencil( k, 0 );
500 offsets[ line + 1 ] += 1;
501 }
502 }
503
504 for ( int i=0; i<nb_lines; ++i )
505 {
506 offsets[ i + 1 ] += offsets[ i ];
507 }
508
509 const int stencil_size = offsets[ nb_lines ];
510 stencil.resize( stencil_size, 2 );
511 coeff_sp.resize(stencil_size); // LUCKILY both ArrOfDouble and std::vector<> have resize() method !
512
513 stencil = -1;
514
515 for ( int i=0; i<nb_stencils; ++i )
516 {
517 const Stencil& local_stencil= vect_local_stencils[ i ];
518 const _TAB_T_& local_coefficients = vect_local_coefficients[ i ];
519
520 const int size = local_stencil.dimension( 0 );
521
522 for ( int k=0; k<size; ++k )
523 {
524 const int line = local_stencil( k, 0 );
525 const int column = local_stencil( k, 1 );
526 const int index = offsets[ line ];
527
528 assert( stencil( index, 0 ) < 0 );
529 assert( stencil( index, 1 ) < 0 );
530 assert( index < offsets[ line + 1 ] );
531
532 stencil( index, 0 ) = line;
533 stencil( index, 1 ) = column;
534
535 coeff_sp[index] = local_coefficients[ k ];
536
537 offsets[ line ] += 1;
538 }
539 }
540}
541
542void Matrice_Bloc::get_stencil_and_coeff_ptrs(Stencil& stencil, std::vector<const double *>& coeff_ptr) const
543{
545 {
546 Cerr << "Error in Matrice_Morse::get_stencil_and_coeff_ptrs( )"<<finl;
547 Cerr << " stencil up to date - function not impl. in this case."<<finl;
548 Cerr << " Aborting..." << finl;
550 return;
551 }
552
553 get_stencil_coeff_templ<std::vector<const double *>, const double *>(stencil, coeff_ptr);
554}
555
556void Matrice_Bloc::get_stencil_and_coefficients(Stencil& stencil, StencilCoeffs& coefficients) const
557{
559 {
560 const int stencil_size = stencil_.dimension(0);
561 coefficients.resize_array( stencil_size );
562 }
563
565}
566
568{
569 for ( int i=0; i<N_; ++i )
570 {
571 for ( int j=0; j<M_; ++j )
572 {
573 os << "Bloc (" << i << "," << j << ")" << finl;
574 get_bloc( i, j ).valeur( ).imprimer( os );
575 }
576 }
577 return os;
578}
579
581{
582 for ( int i=0; i<N_; ++i )
583 {
584 for ( int j=0; j<M_; ++j )
585 {
586 os << "Bloc (" << i << "," << j << ")" << finl;
587 get_bloc( i, j ).valeur( ).imprimer_formatte( os );
588 }
589 }
590 return os;
591}
592
593void Matrice_Bloc::dimensionner( int N, int M )
594{
595 N_ = N;
596 M_ = M;
597 nb_blocs_ = N*M;
598 blocs_.dimensionner(nb_blocs_);
599}
600
601const Matrice& Matrice_Bloc::get_bloc( int i, int j ) const
602{
603 if ( ( i<0 ) || ( i>=N_ ) )
604 {
605 Cerr << "Error in 'Matrice_Bloc::get_bloc()': " << finl;
606 Cerr << " Line index is out of range" << finl;
607 Process::exit( );
608 }
609
610 if ( ( j<0 ) || ( j>=M_ ) )
611 {
612 Cerr << "Error in 'Matrice_Bloc::get_bloc()': " << finl;
613 Cerr << " Column index is out of range" << finl;
614 Process::exit( );
615 }
616
617 return blocs_[i * M_ + j];
618}
619
621{
622 if ( ( i<0 ) || ( i>=N_ ) )
623 {
624 Cerr << "Error in 'Matrice_Bloc::get_bloc()': " << finl;
625 Cerr << " Line index is out of range" << finl;
626 Process::exit( );
627 }
628
629 if ( ( j<0 ) || ( j>=M_ ) )
630 {
631 Cerr << "Error in 'Matrice_Bloc::get_bloc()': " << finl;
632 Cerr << " Column index is out of range" << finl;
633 Process::exit( );
634 }
635
636 return blocs_[i * M_ + j];
637}
638
640{
641 dimensionner(N,M);
642 is_stencil_up_to_date_ = false ;
643}
644
645int Matrice_Bloc::dim( int d ) const
646{
647 if ( d==0 )
648 {
649 return N_;
650 }
651 else
652 {
653 return M_;
654 }
655}
656
658{
659 return N_;
660}
661
663{
664 return M_;
665}
666
667/*!
668 * Remplissage d'une Matrice_Morse par une Matrice_Bloc de Matrice_Morse quelconques
669 */
671{
672 Matrix_tools::convert_to_morse_matrix( (*this), result );
673}
674
675void Matrice_Bloc::block_to_morse_with_ptr( Matrice_Morse& result, std::vector<const double *>& coeffs) const
676{
677 Matrix_tools::convert_to_morse_matrix_with_ptrs( (*this), result, coeffs );
678}
679
680
682{
683 Matrix_tools::convert_to_morse_matrix( (*this), result );
684}
685
686
687//Produit matrice-vecteur
688
689// Remplissage partiel (i premieres lignes) d'une matrice bloc par une matrice morse symetrique
690// RR | RV
691// ------
692// VR | VV
693void Matrice_Bloc::remplir(const IntLists& voisins, const DoubleLists& valeurs, const DoubleVect& terme_diag, const int i, const int n)
694{
695 dimensionner(2, 2) ;
696 get_bloc(0,0).typer("Matrice_Morse_Sym"); // Bloc RR
697 get_bloc(0,1).typer("Matrice_Morse"); // Bloc RV
698 get_bloc(1,0).typer("Matrice_Morse"); // Bloc VR
699 get_bloc(1,1).typer("Matrice_Morse"); // Bloc VV
700 remplir(voisins, valeurs, terme_diag, i, n, i, n);
701}
702
703// Remplissage partiel (n premieres lignes, m premieres colonnes) d'une matrice bloc par une matrice morse non symetrique
704// RR | RV
705// ------
706// VR | VV
707void Matrice_Bloc::remplir(const IntLists& voisins, const DoubleLists& valeurs, const int i, const int n, const int j, const int m)
708{
709 dimensionner(2, 2) ;
710 get_bloc(0,0).typer("Matrice_Morse"); // Bloc RR
711 get_bloc(0,1).typer("Matrice_Morse"); // Bloc RV
712 get_bloc(1,0).typer("Matrice_Morse"); // Bloc VR
713 get_bloc(1,1).typer("Matrice_Morse"); // Bloc VV
714 DoubleVect diagonale_vide;
715 remplir(voisins, valeurs, diagonale_vide, i, n, j, m);
716}
717
718// Remplissage partiel (i premieres lignes, j premieres colonnes) d'une matrice bloc par une matrice morse symetrique ou non
719// RR | RV
720// ------
721// VR | VV
722void Matrice_Bloc::remplir(const IntLists& voisins, const DoubleLists& valeurs, const DoubleVect& terme_diag, const int i, const int n, const int j, const int m)
723{
724 Matrice_Morse& RR=ref_cast(Matrice_Morse,get_bloc(0,0).valeur());
725 Matrice_Morse& RV=ref_cast(Matrice_Morse,get_bloc(0,1).valeur());
726 Matrice_Morse& VR=ref_cast(Matrice_Morse,get_bloc(1,0).valeur());
727 Matrice_Morse& VV=ref_cast(Matrice_Morse,get_bloc(1,1).valeur());
728
729 // Premiere passe pour le dimensionnement
730 int RR_compteur;
731 auto RR_rang=0;
732 int RV_compteur;
733 auto RV_rang=0;
734 int VR_compteur;
735 auto VR_rang=0;
736 int VV_compteur;
737 auto VV_rang=0;
738
739 int num_elem;
740 for (num_elem=0; num_elem<n; num_elem++)
741 {
742 IntList_Curseur liste_vois(voisins[num_elem]);
743 DoubleList_Curseur liste_val(valeurs[num_elem]);
744
745 RR_compteur=0;
746 RV_compteur=0;
747 VR_compteur=0;
748 VV_compteur=0;
749
750 // Diagonale
751 if (terme_diag.size_array()!=0)
752 {
753 if (num_elem<i)
754 RR_compteur++;
755 else
756 VV_compteur++;
757 }
758
759 while (liste_vois)
760 {
761 int colonne = liste_vois.valeur();
762 if (colonne<j)
763 {
764 if (num_elem<i)
765 RR_compteur++; // Sous Bloc RR
766 else
767 VR_compteur++; // Sous Bloc VR
768 }
769 else
770 {
771 if (num_elem<i)
772 RV_compteur++; // Sous Bloc RV
773 else
774 VV_compteur++; // Sous Bloc VV
775 }
776 ++liste_vois;
777 ++liste_val;
778 }
779 RR_rang += RR_compteur;
780 RV_rang += RV_compteur;
781 VR_rang += VR_compteur;
782 VV_rang += VV_compteur;
783 }
784 RR.dimensionner(i, j, RR_rang); // Dimension RR
785 RV.dimensionner(i, m-j, RV_rang); // Dimension RV
786 VR.dimensionner(n-i, j, VR_rang); // Dimension VR
787 VV.dimensionner(n-i, m-j, VV_rang); // Dimension VV
788
789 // Initialisations necessaires
790 RR.get_set_tab1()=1;
791 RV.get_set_tab1()=1;
792 VR.get_set_tab1()=1;
793 VV.get_set_tab1()=1;
794
795 // Deuxieme passe pour le remplissage
796 // Tableaux tab1, tab2 et coeff_ pour le bloc RR
797 auto* RR_tab1 = RR.get_set_tab1().addr();
798 int* RR_tab2 = RR.get_set_tab2().addr();
799 double* RR_coeff = RR.get_set_coeff().addr();
800 int* RR_tab2_ptr = RR_tab2;
801
802 // Tableaux tab1, tab2 et coeff_ pour le bloc RV
803 auto* RV_tab1 = RV.get_set_tab1().addr();
804 int* RV_tab2 = RV.get_set_tab2().addr();
805 double* RV_coeff = RV.get_set_coeff().addr();
806 int* RV_tab2_ptr = RV_tab2;
807
808 // Tableaux tab1, tab2 et coeff_ pour le bloc VR
809 auto* VR_tab1 = VR.get_set_tab1().addr();
810 int* VR_tab2 = VR.get_set_tab2().addr();
811 double* VR_coeff = VR.get_set_coeff().addr();
812 int* VR_tab2_ptr = VR_tab2;
813
814 // Tableaux tab1, tab2 et coeff_ pour le bloc VV
815 auto* VV_tab1 = VV.get_set_tab1().addr();
816 int* VV_tab2 = VV.get_set_tab2().addr();
817 double* VV_coeff = VV.get_set_coeff().addr();
818 int* VV_tab2_ptr = VV_tab2;
819
820 RR_rang=0;
821 RV_rang=0;
822 VR_rang=0;
823 VV_rang=0;
824 for (num_elem=0; num_elem<n; num_elem++)
825 {
826 IntList_Curseur liste_vois(voisins[num_elem]);
827 DoubleList_Curseur liste_val(valeurs[num_elem]);
828
829 RR_compteur=0;
830 RV_compteur=0;
831 VR_compteur=0;
832 VV_compteur=0;
833 if (num_elem<i)
834 {
835 *RR_tab1++ = RR_rang;
836 *RV_tab1++ = RV_rang;
837 }
838 else
839 {
840 *VR_tab1++ = VR_rang;
841 *VV_tab1++ = VV_rang;
842 }
843 // Diagonale eventuelle
844 if (terme_diag.size_array()!=0)
845 {
846 if (num_elem<i)
847 {
848 *RR_tab2_ptr++ = num_elem;
849 *RR_coeff++ = terme_diag[num_elem];
850 RR_compteur++;
851 }
852 else
853 {
854 *VV_tab2_ptr++ = num_elem-i;
855 *VV_coeff++ = terme_diag[num_elem];
856 VV_compteur++;
857 }
858 }
859 while (liste_vois)
860 {
861 int colonne = liste_vois.valeur();
862 double coeff = liste_val.valeur();
863 if (colonne<j)
864 {
865 if (num_elem<i) // Sous Bloc RR
866 {
867 *RR_tab2_ptr++ = colonne;
868 *RR_coeff++ = coeff;
869 RR_compteur++;
870 }
871 else // Sous Bloc VR
872 {
873 *VR_tab2_ptr++ = colonne;
874 *VR_coeff++ = coeff;
875 VR_compteur++;
876 }
877 }
878 else
879 {
880 if (num_elem<i) // Sous Bloc RV
881 {
882 *RV_tab2_ptr++ = colonne-j;
883 *RV_coeff++ = coeff;
884 RV_compteur++;
885 }
886 else // Sous Bloc VV
887 {
888 *VV_tab2_ptr++ = colonne-j;
889 *VV_coeff++ = coeff;
890 VV_compteur++;
891 }
892 }
893 ++liste_vois;
894 ++liste_val;
895 }
896 RR_rang += RR_compteur;
897 RV_rang += RV_compteur;
898 VR_rang += VR_compteur;
899 VV_rang += VV_compteur;
900 }
901 RR.get_set_tab1()(i)=RR_rang;
902 RV.get_set_tab1()(i)=RV_rang;
903 VR.get_set_tab1()(n-i)=VR_rang;
904 VV.get_set_tab1()(n-i)=VV_rang;
905 // Passage a la numerotation Fortran
906 RR.formeF();
907 RV.formeF();
908 VR.formeF();
909 VV.formeF();
910
911 // Compactage de la matrice
912 RR.compacte();
913 RV.compacte();
914 VR.compacte();
915 VV.compacte();
916}
917
919{
920 scale( x );
921 return *this;
922}
923
925{
926 const int nb_line_blocks = nb_bloc_lignes( );
927 const int nb_column_blocks = nb_bloc_colonnes( );
928
929
930 for ( int i=0; i<nb_line_blocks; ++i )
931 {
932 int nb_lines = get_bloc( i, 0 ).valeur( ).nb_lignes( );
933
934 for ( int j=0; j<nb_column_blocks; ++j )
935 {
936 if ( nb_lines != get_bloc( i, j ).valeur( ).nb_lignes( ) )
937 {
938 Cerr << "Invalid number of lines in bloc ( " << i << ", " << j << " )" << finl;
939 return false;
940 }
941 }
942 }
943
944 for ( int j=0; j<nb_column_blocks; ++j )
945 {
946 int nb_columns = get_bloc( 0, j ).valeur( ).nb_colonnes( );
947
948 for ( int i=0; i<nb_line_blocks; ++i )
949 {
950 if ( nb_columns != get_bloc( i, j ).valeur( ).nb_colonnes( ) )
951 {
952 Cerr << "Invalid number of columns in bloc ( " << i << ", " << j << " )" << finl;
953 return false;
954 }
955 }
956 }
957
958 return true;
959}
960
962{
963#ifndef NDEBUG
964 if ( ! ( check_block_matrix_structure( ) ) )
965 {
966 Cerr << "Error in 'Matrice_Bloc::assert_check_block_matrix_structure( )':" << finl;
967 Cerr << " Exiting..." << finl;
968 Process::exit( );
969 }
970#endif
971}
972
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.
virtual void get_stencil(Stencil &stencil) const
bool is_stencil_up_to_date_
virtual int nb_lignes() const =0
Return local number of lines (=size on the current proc).
virtual int nb_colonnes() const =0
Return local number of columns (=size on the current proc).
Stencil stencil_
virtual void get_stencil_and_coeff_ptrs(Stencil &stencil, std::vector< const double * > &coeff_ptr) const
virtual void get_stencil_and_coefficients(Stencil &stencil, StencilCoeffs &coefficients) const
virtual void scale(const double x)=0
virtual void clean()
void block_to_morse_with_ptr(Matrice_Morse &result, std::vector< const double * > &coeffs) const
void get_stencil_coeff_templ(Stencil &stencil, _TAB_T_ &coeff_sp) const
Sortie & imprimer_formatte(Sortie &s) const override
VECT(Matrice) blocs_
Matrice_Bloc(int N=0, int M=0)
virtual void dimensionner(int N, int M)
int nb_bloc_lignes() const
int ordre() const override
If square matrix, returns number of lines, otherwise 0.
DoubleVect & ajouter_multvect_(const DoubleVect &x, DoubleVect &r) const override
int dim(int d) const
void scale(const double x) override
DoubleTab & ajouter_multTab_(const DoubleTab &x, DoubleTab &r) const override
int nb_bloc_colonnes(void) const
void block_to_morse(Matrice_Morse &matrix) const
bool check_block_matrix_structure() const
void BlocToMatMorse(Matrice_Morse &matrix) const
void get_stencil_and_coeff_ptrs(Stencil &stencil, std::vector< const double * > &coeff_ptr) const override
DoubleVect & ajouter_multvectT_(const DoubleVect &x, DoubleVect &r) const override
virtual const Matrice & get_bloc(int i, int j) const
ArrOfInt offsets_
void remplir(const IntLists &voisins, const DoubleLists &valeurs, const DoubleVect &terme_diag, const int i, const int n)
int nb_lignes() const override
Return local number of lines (=size on the current proc).
void clean() override
void build_stencil() override
void get_stencil_and_coefficients(Stencil &stencil, StencilCoeffs &coefficients) const override
std::vector< Matrice_Base * > blocs_non_nuls_
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
Sortie & imprimer(Sortie &s) const override
std::vector< int > line_offsets_
void get_stencil(Stencil &stencil) const override
std::vector< int > column_offsets_
void assert_check_block_matrix_structure() const
Matrice_Bloc & operator*=(double x)
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
auto & get_set_tab2()
void dimensionner(int n, _SIZE_ nnz)
Size the matrix with n lines and n columns and nnz zero-values coefficients.
auto & get_set_coeff()
auto & get_set_tab1()
void compacte(int elim_coeff_nul=0)
Method to check/clean the Matrice_Morse matrix: -Suppress coefficient defined several times.
Classe Matrice Classe generique de la hierarchie des matrices.
Definition Matrice.h:34
static void convert_to_morse_matrix_with_ptrs(const Matrice_Base &in, Matrice_Morse &out, std::vector< const double * > &coeffs)
static void convert_to_morse_matrix(const Matrice_Base &in, Matrice_Morse &out)
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 abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
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
_SIZE_ size_array() const
_TYPE_ * addr()
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_TYPE_ valeur() const
Definition TRUSTList.h:115
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
void ref_data(_TYPE_ *ptr, _SIZE_ new_size) override