16#include <Matrice_Morse.h>
18#include <unordered_map>
19#include <Matrice_Morse_Sym.h>
20#include <Check_espace_virtuel.h>
24#include <Array_tools.h>
64 for(
int i=0; i<n; i++)
67 s <<
"--------------------------------" << finl;
71 <<
" k= " << k << finl;
85 int numerotation_fortran=(
tab1_[0]==1);
90 s <<
"Matrix morse on the processor " << proc <<
" : " << finl;
94 for(
int i=0; i<n; i++)
105 for (
int j=0; j<i; j++)
107 for (
auto k=
tab1_(j)-numerotation_fortran; k<
tab1_(j+1)-numerotation_fortran; k++)
108 if (
tab2_(k)-numerotation_fortran==i)
111 int ligne=
tab2_(
tab1_(i)-numerotation_fortran)-numerotation_fortran;
114 Cerr <<
"Problem detected on this Matrice_Morse_Sym." << finl;
115 Cerr <<
"The diagonal of the line " << ligne <<
" must be stored even if it is null." << finl;
119 for (
auto k=
tab1_(i)-numerotation_fortran; k<
tab1_(i+1)-numerotation_fortran; k++)
120 if (
tab2_(k)+!numerotation_fortran==0)
121 Cerr<<
"Line " <<i<<
" no coefficient "<<k<<finl;
125 tab_imp[
tab2_(k)-numerotation_fortran]=
" ";
127 tab_imp[
tab2_(k)-numerotation_fortran]=
"";
147 int numerotation_fortran=(
tab1_[0]==1);
152 s <<
"Matrix morse on the processor " << proc <<
" : " << finl;
156 for(
int i=0; i<n; i++)
159 tab_imp[k]=
"\u2588\u2588";
167 for (
int j=0; j<i; j++)
169 for (
auto k=
tab1_(j)-numerotation_fortran; k<
tab1_(j+1)-numerotation_fortran; k++)
170 if (
tab2_(k)-numerotation_fortran==i)
171 tab_imp[j] = (std::abs(
coeff_(k)) < 1e-20) ?
" " :
"\u2592\u2592";
173 int ligne=
tab2_(
tab1_(i)-numerotation_fortran)-numerotation_fortran;
176 Cerr <<
"Problem detected on this Matrice_Morse_Sym." << finl;
177 Cerr <<
"The diagonal of the line " << ligne <<
" must be stored even if it is null." << finl;
181 for (
auto k=
tab1_(i)-numerotation_fortran; k<
tab1_(i+1)-numerotation_fortran; k++)
182 if (
tab2_(k)+!numerotation_fortran==0)
183 Cerr<<
"Line " <<i<<
" no coefficient "<<k<<finl;
185 tab_imp[
tab2_(k)-numerotation_fortran] = (std::abs(
coeff_(k)) < 1e-20) ?
" " :
"\u2592\u2592";
201 Cerr <<
"Warning, matrix market format is not available yet in parallel." << finl;
210 mtx.
setf(ios::scientific);
212 Cerr <<
"Matrix (" << rows <<
" lines) written into file: " << filename <<
" ... " << finl;
213 mtx <<
"%%MatrixMarket matrix coordinate real " << (sub_type(
Matrice_Morse_Sym, *
this) ?
"symmetric" :
"general") << finl;
214 Cerr <<
"Matrix (" << rows <<
" lines) written into file: " << filename << finl;
215 mtx <<
"%%matrix" << finl;
216 mtx << rows <<
" " << rows <<
" " <<
get_tab1()[rows] << finl;
217 for (
int row=0; row<rows; row++)
247template<
typename _SIZE_>
272template<
typename _SIZE_>
282 const DoubleLists& valeurs,
283 const DoubleVect& terme_diag)
287 remplir(voisins, valeurs, terme_diag);
304template<
typename _SIZE_>
324 if (Ind.
size()==0)
return;
327 assert(Ind.
nb_dim() == 2);
339 for (
int i=0; i<nInd; i++)
341 if (n < Ind(i,0)) n = Ind(i,0);
342 if (m < Ind(i,1)) m = Ind(i,1);
346 if (n < n_ancien) n = n_ancien;
347 if (m < m_ancien) m = m_ancien;
351 auto tab1_temp(
tab1_);
358 for (
int i=1; i<=n_ancien; i++)
359 tab1_[i] = tab1_temp[i] - tab1_temp[i-1];
360 for (
int i=n_ancien+1; i<=n; i++)
367 for (
int i=0; i<nInd; i++)
370 int i1 = Ind(i,1) + 1;
372 int test_present = 0;
376 auto kmin = tab1_temp[i0]-1;
377 auto kmax = tab1_temp[i0+1]-1;
378 for (
auto k=kmin; k<kmax; k++)
399 for (
int i=1; i<=n; i++)
402 auto nnz_ancien =
tab2_.size_array();
403 auto nnz = nnz_ancien + i_nouveaux;
405 auto tab2_temp(
tab2_);
414 for (
int i=0; i<n_ancien; i++)
416 for (
auto j1 = tab1_temp[i]-1, j2 =
tab1_[i]-1;
417 j1 < tab1_temp[i+1]-1;
420 tab2_[j2] = tab2_temp[j1];
421 coeff_[j2] = coeff_temp[j1];
425 for (
int i=0; i<nInd; i++)
428 int j1 = Ind(i,1) + 1;
446 for(
int i=0; i<nbis; i++)
450 for (
auto k2=k; k2<
tab1_(i+1)-1; k2++)
469template<
typename _SIZE_>
477 if (
tab1_.size_array()!=(n+1) || (
tab1_[n]-1)!=nnz )
496 operator()(i,i) = 1.0;
524 int coeff_quasi_nuls=0;
525 auto tab_elim_coeff(
tab2_);
529 ArrOfDouble tab_coeff_max(n);
535 auto tab1 =
tab1_.view_ro();
536 CDoubleArrView coeff =
coeff_.view_ro();
537 DoubleArrView coeff_max = tab_coeff_max.view_rw();
538 auto elim_coeff = tab_elim_coeff.view_rw();
539 IntArrView cnt = tab_cnt.view_rw();
540 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
543 auto k2 = tab1(i+1)-1;
544 for (
auto k = k1; k < k2; k++)
546 double abs_c = Kokkos::fabs(coeff(k));
547 if (abs_c > coeff_max(i)) coeff_max(i) = abs_c;
550 Kokkos::atomic_add(&cnt(0), 1);
555 end_gpu_timer(__KERNEL_NAME__);
556 coeff_nuls = tab_cnt(0);
559 if (elim_coeff_nul==2)
565 auto tab1 =
tab1_.view_ro();
566 CDoubleArrView coeff =
coeff_.view_ro();
567 CDoubleArrView coeff_max = tab_coeff_max.view_ro();
568 IntArrView elim_coeff = tab_elim_coeff.view_rw();
569 IntArrView cnt = tab_cnt.view_rw();
570 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
572 double cm = coeff_max(i);
573 if (!est_egal(cm, 0., eps) && cm < 1e10)
575 auto k1 = tab1(i) - 1;
576 auto k2 = tab1(i + 1) - 1;
577 for (
auto k = k1; k < k2; k++)
578 if (coeff(k) != 0 && est_egal(Kokkos::fabs(coeff(k)) / cm, 0., eps))
580 Kokkos::atomic_add(&cnt(0), 1);
585 end_gpu_timer(__KERNEL_NAME__);
586 coeff_quasi_nuls = tab_cnt(0);
592 auto tab1 =
tab1_.view_ro();
593 CIntArrView tab2 =
tab2_.view_ro();
594 CDoubleArrView coeff =
coeff_.view_ro();
595 IntArrView elim_coeff = tab_elim_coeff.view_rw();
596 ArrOfInt tab_doublons(1);
598 ArrOfInt tab_error(1);
600 IntArrView doublons = tab_doublons.view_rw();
601 IntArrView error = tab_error.view_rw();
602 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
605 auto k2 = tab1(i+1)-1;
607 for (
auto k = k1; k < k2; k++)
615 for (
auto kk = k-1; kk >= k1; kk--)
621 Kokkos::atomic_add(&doublons(0), 1);
624 if (coeff(kk) != coeff(k))
625 Kokkos::atomic_add(&error(0), 1);
632 end_gpu_timer(__KERNEL_NAME__);
633 nb_doublons = tab_doublons(0);
636 Cerr <<
"Error in a Matrix Morse: duplicate entries with different values!" << finl;
643 if (nb_doublons || coeff_nuls || coeff_quasi_nuls)
646 ArrOfInt tab_kept_per_row(n);
648 auto tab1 =
tab1_.view_ro();
649 CIntArrView elim_coeff = tab_elim_coeff.view_ro();
650 IntArrView kept_per_row = tab_kept_per_row.view_wo();
651 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
655 auto k2 = tab1(i+1)-1;
656 for (
auto k = k1; k < k2; k++)
657 if (!elim_coeff(k)) count++;
658 kept_per_row(i) = count;
660 end_gpu_timer(__KERNEL_NAME__);
664 auto old_tab1(
tab1_);
667 using tab1_scan_t =
decltype(nnz);
669 auto tab1 =
tab1_.view_rw();
670 CIntArrView kept_per_row = tab_kept_per_row.view_ro();
671 Kokkos::parallel_scan(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i, tab1_scan_t& update,
const bool final)
673 update += kept_per_row(i);
674 if (
final) tab1(i+1) = update + 1;
676 end_gpu_timer(__KERNEL_NAME__);
683 auto new_tab2(
tab2_);
685 auto tab1 =
tab1_.view_ro();
686 auto old_tab1_ro = old_tab1.view_ro();
687 CDoubleArrView coeff_src =
coeff_.view_ro();
688 CIntArrView tab2_src =
tab2_.view_ro();
689 DoubleArrView coeff_dst = new_coeff.view_wo();
690 IntArrView tab2_dst = new_tab2.view_wo();
691 CIntArrView elim_coeff = tab_elim_coeff.view_ro();
692 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
694 auto new_pos = tab1(i) - 1;
695 auto k1 = old_tab1_ro(i)-1;
696 auto k2 = old_tab1_ro(i+1)-1;
697 for (
auto k = k1; k < k2; k++)
700 coeff_dst(new_pos) = coeff_src(k);
701 tab2_dst(new_pos) = tab2_src(k);
705 end_gpu_timer(__KERNEL_NAME__);
710 auto tab2 =
tab2_.view_rw();
711 auto coeff =
coeff_.view_rw();
712 CIntArrView new_tab2_ro = new_tab2.view_ro();
713 CDoubleArrView new_coeff_ro = new_coeff.view_ro();
714 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nnz), KOKKOS_LAMBDA(
const int i)
716 tab2(i) = new_tab2_ro(i);
717 coeff(i) = new_coeff_ro(i);
719 end_gpu_timer(__KERNEL_NAME__);
764 Cerr <<
"Matrice_Morse::transpose bad dimensions" << finl;
771 Cerr <<
"Matrice_Morse::transpose bad dimensions" << finl;
775 for(
int i=0; i<=jk; i++ )
tab1_[i] = 0 ;
776 for(
int i=0; i<n; i++)
778 for(
auto k=a.
tab1_[i]-1; k<a.
tab1_[i+1]-1; k++)
786 for(
int i=0; i<n; i++)
788 for(
auto k=a.
tab1_[i]-1; k<a.
tab1_[i+1]-1; k++)
790 int j = a.
tab2_[k]-1 ;
791 auto next =
tab1_[j] ;
793 tab2_[next-1] = i+1 ;
797 for(
int i=jk-1; i>=0; i--)
tab1_[i+1] =
tab1_[i] ;
815 Cerr <<
"Matrice_Morse::diagmulmat bad dimensions" << finl;
818 F77NAME(DIAMUA)(&m ,&l,
832 Cerr <<
"Matrice_Morse::partie_sup : bad dimensions m!=n." << finl;
840 for(
int i=0; i< n; i++)
844 for(
auto k = a.
tab1_[i]-1; k< a.
tab1_[i+1]-1; k++)
846 if (a.
tab2_[k]-1 >= i)
851 if (a.
tab2_[k] == i) kdiag = ko ;
854 if (kdiag != -1 && kdiag != kfirst)
861 tab1_[i] = kfirst+1 ;
863 auto nnz = (ko + 1) ;
865 tab1_[n] = (nnz) + 1 ;
880 const int n =
tab1_.size_array() - 1;
889 auto tab1 =
tab1_.view_ro();
890 CIntArrView tab2 =
tab2_.view_ro();
891 CDoubleArrView coeff =
coeff_.view_ro();
892 CDoubleArrView x = tab_x.view_ro();
893 DoubleArrView resu = tab_resu.view_rw();
894 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
895 Kokkos::RangePolicy<>(0, n), KOKKOS_LAMBDA(
898 auto start = tab1(i)-1;
899 auto end = tab1(i + 1)-1;
902 for (
auto k = start; k < end; k++)
905 tmp+= coeff(k) * x(j);
909 end_gpu_timer(__KERNEL_NAME__);
915 coeff_.ensureDataOnHost();
917 const DoubleVect& x = tab_x;
918 DoubleVect& resu = tab_resu;
919 const auto *tab1_ptr =
tab1_.addr() + 1;
920 const int *tab2_ptr =
tab2_.addr();
921 const double *coeff_ptr =
coeff_.addr();
922 const double *x_fortran = x.
addr() - 1;
924 for (
int i = 0; i < n; i++, tab1_ptr++)
926 const auto kmax = *tab1_ptr;
927 assert(kmax >= k_fortran && kmax <=
tab2_.size_array() + 1);
929 assert(k_fortran ==
tab1_[i] && tab2_ptr ==
tab2_.addr() + (k_fortran - 1));
930 for (; k_fortran < kmax; k_fortran++, tab2_ptr++, coeff_ptr++)
932 int colonne = *tab2_ptr;
934 t += (*coeff_ptr) * x_fortran[colonne];
945 ToDo_Kokkos(
"critical ?");
951 for(
int i=0; i<n; i++)
957 if (est_reel_pas_com[j]) t +=
coeff_(k)*x[j];
985 double* t=
new double[nb_comp];
988 for(
int i=0; i<n; i++)
990 for (ncomp=0; ncomp<nb_comp; ncomp++)
993 for (ncomp=0; ncomp<nb_comp; ncomp++)
995 for (ncomp=0; ncomp<nb_comp; ncomp++)
996 resu(i,ncomp) += t[ncomp] ;
1016 for(
int i=0; i<n; i++)
1033 for(
int i=0; i<n; i++)
1035 if (est_reel_pas_com[i])
1062#ifndef TRUST_USE_GPU
1070 &nzmax, iw.
addr(), &ierr);
1092 using idx_t = std::remove_reference_t<
decltype(c_tab1[0])>;
1096 std::unordered_map<int, idx_t> col_to_pos;
1097 col_to_pos.reserve(256);
1098 for (
int i = 0; i < nrow; ++i)
1103 for (
auto k = a_tab1[i] - 1; k < a_tab1[i + 1] - 1; ++k)
1105 c_tab2[nnz_c] = (int) a_tab2[k];
1106 c_coeff[nnz_c] = a_coeff[k];
1107 col_to_pos[(int) a_tab2[k]] = nnz_c;
1112 for (
auto k = b_tab1[i] - 1; k < b_tab1[i + 1] - 1; ++k)
1114 const int col = (int) b_tab2[k];
1115 auto it = col_to_pos.find(col);
1116 if (it != col_to_pos.end())
1117 c_coeff[it->second] += b_coeff[k];
1120 c_tab2[nnz_c] = col;
1121 c_coeff[nnz_c] = b_coeff[k];
1122 col_to_pos[col] = nnz_c;
1127 c_tab1[i + 1] = nnz_c + 1;
1130 const auto nnz = C.
tab1_[nrow] - 1;
1140 for (
int i = 0; i < nrow; i++)
1144 if (ncoeff != ncoeff_A)
return false;
1146 for (
auto i = 0; i < ncoeff; i++)
1171 double coeff_seuil)
const
1173 return inverse(secmem, solution, coeff_seuil, -1);
1180 double coeff_seuil,
int max_iter)
const
1184 Cerr <<
"Matrice_Morse::inverse has never been tested in parallel" << finl;
1185 Cerr <<
"Try 'Solveur Gmres { diag }' or 'Solveur Petsc Gmres { precond diag { } }'" << finl;
1186 Cerr <<
"instead of 'Solveur Gmres { }' which is not parallelized yet." << finl;
1190 const bool retry_on_failure = (max_iter < 0);
1192 DoubleVect toto(secmem);
1195 int lf = std::min(lf_min,
ordre()/2);
1197 int ima = std::min(lf_min,
ordre()/2);
1200 DoubleVect Resini(toto);
1205 double r, coeff_seuilr;
1210 int iw = (int)(n2 + 2);
1226 Cerr <<
"Error in ilut 'matrix may be wrong' dixit SAAD" << finl;
1230 Cerr <<
"Error in ilut : overflow in L" << finl;
1234 Cerr <<
"Error in ilut : overflow in U" << finl;
1238 Cerr <<
"Illegal value for lfil : it may be a memory trouble" << finl;
1242 Cerr <<
"Empty line met" << finl;
1246 Cerr <<
"Pivot null met ! at step " << ie << finl;
1254 assert_espace_virtuel_vect(solution);
1257 r = mp_prodscal(Resini, Resini);
1259 Cout <<
" Initial residu : " << r << finl;
1260 coeff_seuilr = (r == 0) ? DMAXFLOAT : coeff_seuil/r;
1263 int maxits = std::max(minits, retry_on_failure ? nn : max_iter);
1265 F77NAME(PGMRES)(&nn, &ima, toto.
addr(), solution.
addr(), vv.
addr(), &coeff_seuilr,
1271 Cout <<
" ** PGMRES has converged **" << finl;
1274 Cout <<
" ** No convergence after " << maxits <<
" iterations **" << finl;
1275 if (retry_on_failure)
1281 Cerr <<
" The degree of the preconditioning matrix LU is increased: " << lf << finl;
1282 n2 = (int)
tab2_.size_array()+(2*lf*nn);
1291 Cerr <<
"Convergence after 0 iterations !! 'stationnary state may be obtained'" << finl;
1294 Cerr <<
"Something abnormal has happened : it is preferable to stop." << finl;
1313 for(
auto k =
tab1_(i)-1; k<
tab1_(i+1)-1; k++)
1334 tab1_.resize(nrow+1);
1341 tab2_.resize(nzmax);
1349 if (job != 0) values = 1 ;
1353 for(ii=0; ii< nrow; ii++)
1355 for(
auto ka=a.
tab1_[ii]-1; ka < a.
tab1_[ii+1]-1; ka++)
1357 if (values == 1) scal = a.
coeff_[ka] ;
1358 jj = a.
tab2_[ka] - 1 ;
1359 for (
auto kb=b.
tab1_[jj]-1; kb < b.
tab1_[jj+1]-1; kb++)
1361 int jcol = b.
tab2_[kb] -1 ;
1362 int jpos = iw[jcol] ;
1371 tab2_.resize(nzmax);
1373 tab2_[len] = jcol + 1 ;
1374 iw[jcol]= (int)len ;
1384 for (
auto k=
tab1_[ii]-1; k < len+1 ; k++) iw[
tab2_[k]-1] = -1 ;
1385 tab1_[ii+1] = (len+1) + 1 ;
1418 return((-1)*(*
this));
1435 for (
auto i=0; i<size; i++)
1477 auto nnz =
tab2_.size_array();
1484 decltype(nnz) compteur = 0;
1487 for (
int i=0; i<nb_lines; ++i )
1489 auto k0 =
tab1_( i ) - 1;
1490 auto k1 =
tab1_( i + 1 ) - 1;
1491 const auto size = k1 - k0;
1492 const int size_int = (int)size;
1497 for (
int k=0; k<size_int; ++k )
1499 tmp[ k ] =
tab2_( k + k0 ) - 1;
1504 for (
int k=0; k<size_int; ++k )
1506 stencil( k+compteur , 0 ) = i;
1507 stencil( k+compteur , 1 ) = tmp[ k ];
1518template<
typename _T_>
static inline void _fill_slot(_T_& dest,
const double& src);
1519template<>
inline void _fill_slot<double>(
double& dest,
const double& src)
1523template<>
inline void _fill_slot<const double *>(
const double*& dest,
const double& src)
1530template<
typename _TAB_T_,
typename _VALUE_T_>
1533 auto nnz =
tab2_.size_array();
1534 coeffs_span.resize(nnz);
1536 decltype(nnz) compteur = 0;
1538 for (
int i=0; i<nb_lines; ++i )
1540 const auto k0 =
tab1_( i ) - 1;
1541 const auto k1 =
tab1_( i + 1 ) - 1;
1542 const int size_int = (int)(k1 - k0);
1543 for (
int k=0; k<size_int; ++k )
1545 stencil( compteur + k , 0 ) = i;
1546 stencil( compteur + k , 1 ) =
tab2_( k + k0 ) - 1;
1547 ::_fill_slot<_VALUE_T_>(coeffs_span[ compteur + k ],
coeff_(k+k0));
1549 compteur += size_int;
1557 std::vector<const double *>& coeff_ptr)
const
1563 Cerr <<
"Error in Matrice_Morse::get_symmetric_stencil_and_coeff_ptrs( )"<<finl;
1564 Cerr <<
" stencil up to date - function not impl. in this case."<<finl;
1565 Cerr <<
" Aborting..." << finl;
1571 assert( (trustIdType)coeff_ptr.size( ) == stencil.
dimension( 0 ));
1576 StencilCoeffs& coefficients )
const
1580 if(
coeff_.size( ) == 0 )
1582 Cerr <<
"Error in Matrice_Morse::get_stencil_and_coefficients( )"<<finl;
1583 Cerr <<
" The coefficients are not filled."<<finl;
1584 Cerr <<
" Aborting..." << finl;
1588 {
const auto sz =
coeff_.size_array(); coefficients.
resize(sz);
for (
auto k=sz-sz; k<sz; k++) coefficients[k] =
coeff_[k]; }
1614 const DoubleLists& valeurs,
1615 const DoubleVect& terme_diag)
1619 int compteur,rang =0;
1622 auto* p_tab1 =
tab1_.addr();
1623 int* p_tab2 =
tab2_.addr();
1624 double* p_coeff =
coeff_.addr();
1626 int* tab2_ptr = p_tab2;
1629 for (num_elem=0; num_elem<n; num_elem++)
1632 IntList_Curseur liste_vois(voisins[num_elem]);
1633 DoubleList_Curseur liste_val(valeurs[num_elem]);
1637 *tab2_ptr++=num_elem;
1638 *p_coeff++ = terme_diag[num_elem];
1642 *tab2_ptr++ = liste_vois.
valeur();
1643 *p_coeff++ = liste_val.
valeur();
1649 rang += (compteur + 1);
1651 tab1_(num_elem)=rang;
1658 const DoubleLists& valeurs)
1662 int compteur,rang =0;
1665 auto* p_tab1 =
tab1_.addr();
1666 int* p_tab2 =
tab2_.addr();
1667 double* p_coeff =
coeff_.addr();
1669 int* tab2_ptr = p_tab2;
1672 for (num_elem=0; num_elem<n; num_elem++)
1675 IntList_Curseur liste_vois(voisins[num_elem]);
1676 DoubleList_Curseur liste_val(valeurs[num_elem]);
1682 *tab2_ptr++ = liste_vois.
valeur();
1683 *p_coeff++ = liste_val.
valeur();
1691 tab1_(num_elem)=rang;
1714 int lordre = L.
ordre();
1715 for (
int i=0; i<lordre; i++)
1718 matrice_locale += L;
1722 auto nnz=matrice_locale.
nb_coeff();
1727 int mon_nb_lignes=matrice_locale.
nb_lignes();
1728 assert(mon_nb_lignes+ideb<=n);
1729 for (
int i=0; i<ideb; i++)
1731 for (
int i=0; i<mon_nb_lignes; i++)
1733 for (
int i=mon_nb_lignes+ideb; i<n+1; i++)
1734 tab1_(i)=matrice_locale.
tab1_(mon_nb_lignes);
1737 for (
auto i=0; i<nnz; i++)
1741 for (
auto i=0; i<nnz; i++)
1751 for(
int ii=0; ii<=n; ii++)
1753 for(
int ii=0; ii<n; ii++)
1764 for(
int ii=0; ii<=n; ii++)
1779int Matrice_Morse_test()
1799 const auto* p_tab1_ =
get_tab1().addr();
1800 const int* p_tab2_ =
get_tab2().addr();
1803 for(
int i=0; i<N; i++)
1804 for(
auto k = p_tab1_[i]; k < p_tab1_[i+1]; k++)
1806 if (p_tab2_[k-1]-1<N)
1808 ldist = p_tab2_[k-1] - i;
1809 if( min < ldist ) min = ldist;
1819 const auto nb_coefficients =
tab1_( nb_lines ) - 1;
1821 if (
tab2_.size_array( ) != nb_coefficients )
1823 Cerr <<
"invalid tab2 size" << finl;
1827 if (
coeff_.size_array( ) != nb_coefficients )
1829 Cerr <<
"invalid coeff size" << finl;
1833 ArrOfBit flags( nb_columns );
1835 for (
int i=0; i<nb_lines; ++i )
1839 auto k0 =
tab1_( i ) - 1;
1840 auto k1 =
tab1_( i + 1 ) - 1;
1842 for (
auto k=k0; k<k1; ++k )
1844 int j =
tab2_( k ) - 1;
1848 Cerr <<
"invalid column index (<0): " << j << finl;
1852 if ( j >= nb_columns )
1854 Cerr <<
"invalid column index (>nb_cols): " << j <<
" > " << nb_columns << finl;
1860 Cerr <<
"invalid coefficient ( " << i <<
", " << j <<
" ): already defined ( " << k <<
" )" << finl;
1875 const auto nb_coefficients =
tab1_( nb_lines ) - 1;
1877 if (
tab2_.size_array( ) != nb_coefficients )
1879 Cerr <<
"invalid tab2 size" << finl;
1883 if (
coeff_.size_array( ) != nb_coefficients )
1885 Cerr <<
"invalid coeff size" << finl;
1889 ArrOfBit flags( nb_columns );
1891 for (
int i=0; i<nb_lines; ++i )
1895 auto k0 =
tab1_( i ) - 1;
1896 auto k1 =
tab1_( i + 1 ) - 1;
1898 int j0 =
tab2_( k0 ) - 1 - 1;
1900 for (
auto k=k0; k<k1; ++k )
1902 int j =
tab2_( k ) - 1;
1906 Cerr <<
"invalid column index (<0): " << j << finl;
1910 if ( j >= nb_columns )
1912 Cerr <<
"invalid column index (>nb_cols): " << j <<
" > " << nb_columns << finl;
1918 Cerr <<
"invalid coefficient ( " << i <<
", " << j <<
" ): already defined ( " << k <<
" )" << finl;
1924 Cerr <<
"unsorted coefficient: ( " << i <<
", " << j <<
" ) after ( " << i <<
", " << j0 <<
" ) " << finl;;
1943 Cerr <<
"Error in 'Matrice_Morse::assert_check_morse_matrix_structure( )':" << finl;
1944 Cerr <<
" Exiting..." << finl;
1958 Cerr <<
"Error in 'Matrice_Morse::assert_check_sorted_morse_matrix_structure( )':" << finl;
1959 Cerr <<
" Exiting..." << finl;
1980 IntTab loca((
int)max_nnz, 2);
1981 DoubleTab sub_coeffs((
int)max_nnz);
1982 for (
int li=nl0; li <= nl1; li++)
1984 auto idx_coeff =
tab1_(li)-1;
1985 int nb_coeff_on_line = (int)(
tab1_(li+1)-
tab1_(li));
1986 for (
int j=0; j < nb_coeff_on_line; j++)
1988 int col_idx =
tab2_(j+idx_coeff)-1;
1989 if (col_idx >= nc0 && col_idx <= nc1)
1991 loca(tot, 0) = li - nl0;
1992 loca(tot, 1) = col_idx - nc0;
1993 sub_coeffs(tot) =
coeff_(j+idx_coeff);
2003 for (
int i =0 ; i < tot; i++)
2005 int il = loca(i, 0);
2006 int ic = loca(i, 1);
2007 result.
coef(il, ic) = sub_coeffs(i);
2014 for (
int i = 0; i + 1 <
tab1_.size_array(); i++)
2025 for (
int i = 0; i < n; i++)
2027 const auto k0 =
tab1_( i ) - 1;
2028 const auto k1 =
tab1_( i + 1 ) - 1;
2029 for (
auto k=k0; k<k1-1; k++)
2047 for (
int i = 0; i < n; i++)
2050 const auto k2 =
get_tab1()(i + 1) - 1;
2051 for (
auto k = k1; k < k2; k++)
void setbit(int_t i) const
Met le bit e a 1.
Class defining operators and methods for all reading operation in an input flow (file,...
Classe Matrice_Base Classe de base de la hierarchie des matrices.
bool is_stencil_up_to_date_
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication d'un vecteur par la matrice.
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.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
void clean() override
Remplit la matrice avec des zeros.
friend Matrice_Morse operator+(const Matrice_Morse &, const Matrice_Morse &)
Fonction (hors classe) amie de la classe Matrice_Morse Addition de 2 matrices au format Morse.
int largeur_de_bande() const
Calcule la largeur de bande d'une matrice morse.
int morse_matrix_structure_has_changed_
Matrice_Morse & affecte_prod(const Matrice_Morse &A, const Matrice_Morse &B)
Affecte le produit de 2 matrices Morse A et B a l'objet (this).
void get_stencil_and_coeff_ptrs(Stencil &stencil, std::vector< const double * > &coeff_ptr) const override
void get_stencil(Stencil &stencil) const override
bool check_morse_matrix_structure() const
Sortie & imprimer_image(Sortie &s) const
Matrice_Morse & operator*=(double)
Operateur de multiplication (de tous les elements) d'une matrice par un scalaire.
void WriteFileMTX(const Nom &) const
bool check_sorted_morse_matrix_structure() const
Matrice_Morse & operator=(const Matrice_Morse &)
Operateur d'affectation d'une Matrice_Morse dans une autre Matrice_Morse.
void assert_check_morse_matrix_structure() const
void scale(const double x) override
virtual Matrice_Morse & diagmulmat(const DoubleVect &x)
Matrice_Morse & operator/=(double)
Operateur de division (de tous les elements) d'une matrice par un scalaire.
void get_stencil_and_coefficients(Stencil &stencil, StencilCoeffs &coefficients) const override
const auto & get_tab2() const
int ordre() const override
Renvoie l'ordre de la matrice: - le nombre de lignes si la matrice est carree.
bool is_sorted_stencil() const
Sortie & imprimer_formatte(Sortie &s) const override
virtual int inverse(const DoubleVect &, DoubleVect &, double) const
Calcule la solution du systeme lineaire: A * solution = secmem.
virtual Matrice_Morse & transpose(const Matrice_Morse &a)
*this = a transposee.
const IntVect & get_tab1_int32() const
Sortie & imprimer(Sortie &s) const override
void dimensionner(int n, _SIZE_ nnz)
Size the matrix with n lines and n columns and nnz zero-values coefficients.
const auto & get_tab1() const
void set_nb_columns(const int)
DoubleVect & ajouter_multvect_(const DoubleVect &, DoubleVect &) const override
Operation de multiplication-accumulation (saxpy) matrice vecteur.
DoubleVect & ajouter_multvectT_(const DoubleVect &, DoubleVect &) const override
Operation de multiplication-accumulation (saxpy) matrice vecteur, par la matrice transposee.
void get_stencil_coeff_templ(Stencil &stencil, _TAB_T_ &coeffs_span) const
void assert_check_sorted_morse_matrix_structure() const
Matrice_Morse & operator+=(const Matrice_Morse &)
NE FAIT RIEN.
double coef(int i, int j) const
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
bool has_same_morse_matrix_structure(const Matrice_Morse &) const
Matrice_Morse operator-() const
Operateur de negation unaire, renvoie l'opposee de la matrice: - A Appelle operator*(double,...
const auto & get_coeff() const
void set_symmetric(const int)
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 construire_sous_bloc(int nl0, int nc0, int nl1, int nc1, Matrice_Morse &result) const
void unite()
Initialisation a la matrice unite (modif MT).
void set_tab1_int32() const
DoubleTab & ajouter_multTab_(const DoubleTab &, DoubleTab &) const override
Operation de multiplication-accumulation (saxpy) matrice matrice (matrice X representee par un tablea...
class Nom Une chaine de caractere pour nommer les objets de TRUST
Un tableau de chaine de caracteres (VECT(Nom)).
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
static double precision_geom
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
static bool is_parallel()
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
void precision(int pre) override
void setf(IOS_FORMAT code) override
Classe de base des flux de sortie.
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
bool isDataOnDevice() const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)