14#include "arcane/utils/ArcanePrecomp.h"
16#include "arcane/utils/Array.h"
17#include "arcane/utils/ArgumentException.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/TraceAccessor.h"
20#include "arcane/utils/OStringStream.h"
21#include "arcane/utils/StringBuilder.h"
23#include "arcane/matvec/Matrix.h"
35 throw FatalErrorException(
"Division by zero");
40namespace Arcane::MatVec
47solve(
const Matrix& matrix,
const Vector& vector_b,Vector& vector_x)
53 Integer nb_row = matrix.nbRow();
56 full_matrix_values.fill(0.0);
57 solution_values.copy(vector_b.values());
58 for( Integer row=0; row<nb_row; ++row ){
59 for( Integer j=rows[row]; j<rows[row+1]; ++j ){
60 full_matrix_values[row*nb_row + columns[j]] = mat_values[j];
63 _solve(full_matrix_values,solution_values,nb_row);
64 vector_x.values().copy(solution_values);
72 throw FatalErrorException(
"DirectSolver",
"Null matrix");
73 vec_values[0] /= mat_values[0];
77 for( Integer k=0; k<size-1; ++k ){
79 for( Integer j=k+1; j<size; ++j ){
81 Real factor = mat_values[j*size+k] / mat_values[k*size+k];
82 for( Integer m=k+1; m<size; ++m )
83 mat_values[j*size+m] -= factor * mat_values[k*size+m];
84 vec_values[j] -= factor * vec_values[k];
90 for( Integer k=(size-1); k>0; --k ){
91 vec_values[k] /= mat_values[k*size+k];
92 for( Integer j=0; j<k; ++j ){
94 vec_values[j] -= vec_values[k] * mat_values[j*size+k];
98 vec_values[0] /= mat_values[0];
104Matrix MatrixOperation2::
105matrixMatrixProduct(
const Matrix& left_matrix,
const Matrix& right_matrix)
107 Integer nb_left_col = left_matrix.nbColumn();
108 Integer nb_right_col = right_matrix.nbColumn();
109 Integer nb_right_row = right_matrix.nbRow();
110 Integer nb_left_row = left_matrix.nbRow();
111 if (nb_left_col!=nb_right_row)
112 throw new ArgumentException(
"MatrixMatrixProduction",
"Bad size");
113 Integer nb_row_col = nb_left_col;
123 Matrix new_matrix(nb_left_row,nb_right_col);
128 for( Integer i=0; i<nb_left_row; ++i ){
130 for( Integer j=0; j<nb_right_col; ++j){
132 for( Integer k=0; k<nb_row_col; ++k ){
141 v += left_matrix.value(i,k) * right_matrix.value(k,j);
145 new_matrix_columns.add(j);
146 new_matrix_values.add(v);
149 new_matrix_rows_size[i] = local_nb_col;
151 new_matrix.setRowsSize(new_matrix_rows_size);
152 new_matrix.setValues(new_matrix_columns,new_matrix_values);
156Matrix MatrixOperation2::
157matrixMatrixProductFast(
const Matrix& left_matrix,
const Matrix& right_matrix)
159 Integer nb_left_col = left_matrix.nbColumn();
160 Integer nb_right_col = right_matrix.nbColumn();
161 Integer nb_right_row = right_matrix.nbRow();
162 Integer nb_left_row = left_matrix.nbRow();
163 if (nb_left_col!=nb_right_row)
164 throw new ArgumentException(
"MatrixMatrixProduction",
"Bad size");
175 Matrix new_matrix(nb_left_row,nb_right_col);
186 col_right_columns_size.fill(0);
187 for( Integer i=0; i<nb_right_row; ++i ){
188 for( Integer j=right_rows_index[i]; j<right_rows_index[i+1]; ++j ){
189 ++col_right_columns_size[right_columns[j]];
194 for( Integer j=0; j<nb_right_col; ++j ){
195 col_right_columns_index[j] = index;
196 index += col_right_columns_size[j];
198 col_right_columns_index[nb_right_col] = index;
200 col_right_rows.resize(index);
201 col_right_values.resize(index);
204 col_right_columns_size.fill(0);
205 for( Integer i=0; i<nb_right_row; ++i ){
206 for( Integer j=right_rows_index[i]; j<right_rows_index[i+1]; ++j ){
207 Integer col = right_columns[j];
208 Real value = right_values[j];
209 Integer col_index = col_right_columns_size[col] + col_right_columns_index[col];
210 ++col_right_columns_size[col];
211 col_right_rows[col_index] = i;
212 col_right_values[col_index] = value;
219 current_row_values.fill(0.0);
220 for( Integer i=0; i<nb_left_row; ++i ){
223 for( Integer z=left_rows_index[i] ,zs=left_rows_index[i+1]; z<zs; ++z ){
224 current_row_values[ left_columns[z] ] = left_values[z];
235 for( Integer j=0; j<nb_right_col; ++j ){
237 for( Integer zj=col_right_columns_index[j]; zj<col_right_columns_index[j+1]; ++zj ){
246 v += col_right_values[zj] * current_row_values[ col_right_rows[zj] ];
250 new_matrix_columns.add(j);
251 new_matrix_values.add(v);
255 new_matrix_rows_size[i] = local_nb_col;
258 for( Integer z=left_rows_index[i] ,zs=left_rows_index[i+1]; z<zs; ++z )
259 current_row_values[ left_columns[z] ] = 0.0;
261 new_matrix.setRowsSize(new_matrix_rows_size);
262 new_matrix.setValues(new_matrix_columns,new_matrix_values);
266void MatrixOperation2::
270 Integer nb_col = columns_index.size() - 1;
271 o <<
"(ColumnMatrix nb_col=" << nb_col;
272 for( Integer j=0; j<nb_col; ++j ){
273 for( Integer z=columns_index[j], zs=columns_index[j+1]; z<zs; ++z ){
276 o <<
" ["<<i<<
","<<j<<
"]="<<v;
282Matrix MatrixOperation2::
283transpose(
const Matrix& matrix)
285 Integer nb_column = matrix.nbColumn();
286 Integer nb_row = matrix.nbRow();
292 Integer new_matrix_nb_row = nb_column;
293 Integer new_matrix_nb_column = nb_row;
294 Matrix new_matrix(new_matrix_nb_row,new_matrix_nb_column);
299 for( Integer i=0; i<new_matrix_nb_row; ++i ){
301 for( Integer j=0; j<new_matrix_nb_column; ++j ){
302 Real v = matrix.value(j,i);
305 new_matrix_columns.add(j);
306 new_matrix_values.add(v);
309 new_matrix_rows_size[i] = local_nb_col;
311 new_matrix.setRowsSize(new_matrix_rows_size);
312 new_matrix.setValues(new_matrix_columns,new_matrix_values);
319Matrix MatrixOperation2::
320transposeFast(
const Matrix& matrix)
322 Integer nb_column = matrix.nbColumn();
323 Integer nb_row = matrix.nbRow();
329 Integer new_matrix_nb_row = nb_column;
330 Integer new_matrix_nb_column = nb_row;
331 Matrix new_matrix(new_matrix_nb_row,new_matrix_nb_column);
336 new_matrix_rows_size.fill(0);
337 Integer nb_element = values.size();
338 for( Integer i=0, is=columns.size(); i<is; ++i ){
339 ++new_matrix_rows_size[ columns[i] ];
341 new_matrix.setRowsSize(new_matrix_rows_size);
344 new_matrix_rows_size.fill(0);
349 for( Integer row=0, is=nb_row; row<is; ++row ){
350 for( Integer j=rows_index[row]; j<rows_index[row+1]; ++j ){
351 Integer col_index = columns[j];
352 Integer pos = new_matrix_rows_index[col_index] + new_matrix_rows_size[col_index];
354 new_matrix_columns[pos] = row;
355 new_matrix_values[pos] = values[j];
356 ++new_matrix_rows_size[col_index];
360 new_matrix.setValues(new_matrix_columns,new_matrix_values);
367Matrix MatrixOperation2::
368applyGalerkinOperator(
const Matrix& left_matrix,
const Matrix& matrix,
369 const Matrix& right_matrix)
371 Integer nb_original_row = matrix.nbRow();
372 Integer nb_final_row = left_matrix.nbRow();
397 for( Integer ic = 0; ic<nb_final_row; ++ic ){
399 p_marker[ic] = jj_counter;
400 jj_row_begining = jj_counter;
404 for( Integer jj1=left_matrix_rows[ic]; jj1<left_matrix_rows[ic+1]; ++jj1 ){
405 Integer i1 = left_matrix_columns[jj1];
408 for( Integer jj2=matrix_rows[i1]; jj2<matrix_rows[i1+1]; ++jj2 ){
409 Integer i2 = matrix_columns[jj2];
414 if (a_marker[i2]!=ic){
419 for( Integer jj3=right_matrix_rows[i2]; jj3<right_matrix_rows[i2+1]; ++jj3 ){
420 Integer i3 = right_matrix_columns[jj3];
426 if (p_marker[i3] < jj_row_begining){
427 p_marker[i3] = jj_counter;
434 new_matrix_rows_size[ic] = jj_counter - jj_row_begining;
436 static Integer total_rap_size = 0;
437 total_rap_size += jj_counter;
439 cout <<
"** RAP_SIZE=" << jj_counter <<
" TOTAL=" << total_rap_size <<
'\n';
440 Matrix new_matrix(nb_final_row,nb_final_row);
441 new_matrix.setRowsSize(new_matrix_rows_size);
451 for( Integer ic = 0; ic<nb_final_row; ++ic ){
453 p_marker[ic] = jj_counter;
454 jj_row_begining = jj_counter;
455 new_matrix_columns[jj_counter] = ic;
456 new_matrix_values[jj_counter] = 0.0;
459 for( Integer jj1=left_matrix_rows[ic]; jj1<left_matrix_rows[ic+1]; ++jj1 ){
460 Integer i1 = left_matrix_columns[jj1];
461 Real r_entry = left_matrix_values[jj1];
464 for( Integer jj2=matrix_rows[i1]; jj2<matrix_rows[i1+1]; ++jj2 ){
465 Integer i2 = matrix_columns[jj2];
466 Real r_a_product = r_entry * matrix_values[jj2];
471 if (a_marker[i2] != ic){
476 for( Integer jj3=right_matrix_rows[i2]; jj3<right_matrix_rows[i2+1]; ++jj3 ){
477 Integer i3 = right_matrix_columns[jj3];
478 Real r_a_p_product = r_a_product * right_matrix_values[jj3];
484 if (p_marker[i3] < jj_row_begining){
485 p_marker[i3] = jj_counter;
486 new_matrix_values[jj_counter] = r_a_p_product;
487 new_matrix_columns[jj_counter] = i3;
491 new_matrix_values[p_marker[i3]] += r_a_p_product;
500 for( Integer jj3=right_matrix_rows[i2]; jj3<right_matrix_rows[i2+1]; ++jj3 ){
501 Integer i3 = right_matrix_columns[jj3];
502 Real r_a_p_product = r_a_product * right_matrix_values[jj3];
503 new_matrix_values[p_marker[i3]] += r_a_p_product;
516Matrix MatrixOperation2::
517applyGalerkinOperator2(
const Matrix& left_matrix,
const Matrix& matrix,
518 const Matrix& right_matrix)
520 Integer nb_original_row = matrix.nbRow();
521 Integer nb_final_row = left_matrix.nbRow();
527 const Integer* left_matrix_rows = left_matrix.rowsIndex().data();
528 const Integer* left_matrix_columns = left_matrix.columns().data();
529 const Real* left_matrix_values = left_matrix.values().data();
531 const Integer* right_matrix_rows = right_matrix.rowsIndex().data();
532 const Integer* right_matrix_columns = right_matrix.columns().data();
533 const Real* right_matrix_values = right_matrix.values().data();
535 const Integer* matrix_rows = matrix.rowsIndex().data();
536 const Integer* matrix_columns = matrix.columns().data();
537 const Real* matrix_values = matrix.values().data();
546 for( Integer ic = 0; ic<nb_final_row; ++ic ){
548 p_marker[ic] = jj_counter;
549 jj_row_begining = jj_counter;
553 for( Integer jj1=left_matrix_rows[ic]; jj1<left_matrix_rows[ic+1]; ++jj1 ){
554 Integer i1 = left_matrix_columns[jj1];
557 for( Integer jj2=matrix_rows[i1]; jj2<matrix_rows[i1+1]; ++jj2 ){
558 Integer i2 = matrix_columns[jj2];
563 if (a_marker[i2]!=ic){
568 for( Integer jj3=right_matrix_rows[i2]; jj3<right_matrix_rows[i2+1]; ++jj3 ){
569 Integer i3 = right_matrix_columns[jj3];
575 if (p_marker[i3] < jj_row_begining){
576 p_marker[i3] = jj_counter;
583 new_matrix_rows_size[ic] = jj_counter - jj_row_begining;
586 Matrix new_matrix(nb_final_row,nb_final_row);
587 new_matrix.setRowsSize(new_matrix_rows_size);
590 Integer* ARCANE_RESTRICT new_matrix_columns = new_matrix.columns().data();
591 Real* ARCANE_RESTRICT new_matrix_values = new_matrix.values().data();
597 for( Integer ic = 0; ic<nb_final_row; ++ic ){
599 p_marker[ic] = jj_counter;
600 jj_row_begining = jj_counter;
601 new_matrix_columns[jj_counter] = ic;
602 new_matrix_values[jj_counter] = 0.0;
605 for( Integer jj1=left_matrix_rows[ic]; jj1<left_matrix_rows[ic+1]; ++jj1 ){
606 Integer i1 = left_matrix_columns[jj1];
607 Real r_entry = left_matrix_values[jj1];
610 for( Integer jj2=matrix_rows[i1]; jj2<matrix_rows[i1+1]; ++jj2 ){
611 Integer i2 = matrix_columns[jj2];
612 Real r_a_product = r_entry * matrix_values[jj2];
617 if (a_marker[i2] != ic){
622 for( Integer jj3=right_matrix_rows[i2]; jj3<right_matrix_rows[i2+1]; ++jj3 ){
623 Integer i3 = right_matrix_columns[jj3];
624 Real r_a_p_product = r_a_product * right_matrix_values[jj3];
630 if (p_marker[i3] < jj_row_begining){
631 p_marker[i3] = jj_counter;
632 new_matrix_values[jj_counter] = r_a_p_product;
633 new_matrix_columns[jj_counter] = i3;
637 new_matrix_values[p_marker[i3]] += r_a_p_product;
646 for( Integer jj3=right_matrix_rows[i2]; jj3<right_matrix_rows[i2+1]; ++jj3 ){
647 Integer i3 = right_matrix_columns[jj3];
648 Real r_a_p_product = r_a_product * right_matrix_values[jj3];
649 new_matrix_values[p_marker[i3]] += r_a_p_product;
666 TYPE_SPECIAL_FINE = 3
680 virtual void buildLevel(
Matrix matrix,Real alpha);
684 return m_fine_matrix;
688 return m_coarse_matrix;
690 Matrix prolongationMatrix()
692 return m_prolongation_matrix;
694 Matrix restrictionMatrix()
696 return m_restriction_matrix;
698 Integer nbCoarsePoint()
const
700 return m_coarse_matrix.nbRow();
704 return m_points_type;
706 void printLevelInfo();
712 Matrix m_prolongation_matrix;
713 Matrix m_restriction_matrix;
718 void _buildCoarsePoints(Real alpha,
727 void _printLevelInfo(
Matrix matrix);
740 void build(
Matrix matrix);
766 for( Integer i=0; i<m_levels.size(); ++i )
778 for( Integer i=1; i<100; ++i ){
779 AMGLevel* level =
new AMGLevel(
traceMng(),i);
795solve(
const Vector& vector_b,Vector& vector_x)
801 for( Integer i=0; i<20; ++i )
802 ostr() <<
"VECTOR_F_"<< i <<
" = " << v_values[i] <<
" X=" << vector_x.values()[i] <<
'\n';
803 for( Integer i=0; i<v_values.size(); ++i )
804 if (math::abs(v_values[i])>1e-5)
805 ostr() <<
"VECTOR_F_"<< i <<
" = " << v_values[i] <<
'\n';
806 info() <<
"VECTOR_F\n" << ostr.str();
809 _solve(vector_b,vector_x,0);
825_relax1(
const Matrix& matrix,
const Vector& vector_b,Vector& vector_x,
828 Vector r(vector_x.size());
829 MatrixOperation mat_op;
830 for( Integer i=0; i<nb_relax; ++i ){
832 mat_op.matrixVectorProduct(matrix,vector_x,r);
833 mat_op.negateVector(r);
834 mat_op.addVector(r,vector_b);
837 mat_op.addVector(vector_x,r);
845_relax(
const Matrix& matrix,
const Vector& vector_b,Vector& vector_x,
848 Real epsilon = 1.0e-10;
849 DiagonalPreconditioner p(matrix);
850 ConjugateGradientSolver solver;
851 solver.setMaxIteration(nb_relax);
859 solver.solve(matrix,vector_b,vector_x,epsilon,&p);
873_relaxJacobi(
const Matrix& matrix,
const Vector& vector_b,Vector& vector_x,
883 Integer nb_row = matrix.nbRow();
889 for( Integer i=(nb_row-1); i>(nb_row-v); --i )
890 ostr() <<
"BEFORE_B=" << i <<
"=" << b_values[i] <<
" U=" << x_values[i] <<
" T=" << tmp_values[i] <<
'\n';
891 info() <<
"B = X=" << x_values.data() <<
" T=" << tmp_values.data() <<
"\n" << ostr.str();
893 Real one_minus_weight = 1.0 - weight;
894 for( Integer row=0; row<nb_row; ++row ){
895 Real diag = mat_values[rows[row]];
898 Real res = b_values[row];
899 for( Integer j=rows[row]+1; j<rows[row+1]; ++j ){
901 res -= mat_values[j] * tmp_values[col];
903 x_values[row] *= one_minus_weight;
904 x_values[row] += (weight * res) / diag;
909 for( Integer i=(nb_row-1); i>(nb_row-v); --i )
910 ostr() <<
"AFTER_B=" << i <<
"=" << b_values[i] <<
" U=" << x_values[i] <<
'\n';
911 info() <<
"B\n" << ostr.str();
919_relaxGaussSeidel(
const Matrix& matrix,
const Vector& vector_b,Vector& vector_x,
931 const Integer* rows = matrix.rowsIndex().data();
932 const Integer* columns = matrix.columns().data();
933 const Real* mat_values = matrix.values().data();
935 Real* ARCANE_RESTRICT x_values = vector_x.values().data();
936 const Real* b_values = vector_b.values().data();
937 const Integer* points_type = points_type2.data();
940 Integer nb_row = matrix.nbRow();
942 info() <<
" RELAX nb_relax=" <<
" nb_row=" << nb_row
943 <<
" point_type=" << point_type;
946 for( Integer i=(nb_row-1); i>(nb_row-v); --i )
947 ostr() <<
"BEFORE_B=" << i <<
"=" << b_values[i] <<
" U=" << x_values[i] <<
'\n';
948 info() <<
"B\n" << ostr.str();
950 for( Integer row=0; row<nb_row; ++row ){
951 Real diag = mat_values[rows[row]];
954 Real res = b_values[row];
955 for( Integer j=rows[row]+1; j<rows[row+1]; ++j ){
957 res -= mat_values[j] * x_values[col];
959 x_values[row] = res / diag;
964 for( Integer i=(nb_row-1); i>(nb_row-v); --i )
965 ostr() <<
"AFTER_B=" << i <<
"=" << b_values[i] <<
" U=" << x_values[i] <<
'\n';
966 info() <<
"B\n" << ostr.str();
974_relaxSymmetricGaussSeidel(
const Matrix& matrix,
const Vector& vector_b,Vector& vector_x)
983 Integer nb_row = matrix.nbRow();
986 for( Integer row=0; row<nb_row; ++row ){
987 Real diag = mat_values[rows[row]];
990 Real res = b_values[row];
991 for( Integer j=rows[row]+1; j<rows[row+1]; ++j ){
993 res -= mat_values[j] * x_values[col];
995 x_values[row] = res / diag;
998 for( Integer row=nb_row-1; row>-1; --row ){
999 Real diag = mat_values[rows[row]];
1002 Real res = b_values[row];
1003 for( Integer j=rows[row]+1; j<rows[row+1]; ++j ){
1005 res -= mat_values[j] * x_values[col];
1007 x_values[row] = res / diag;
1016_solve(
const Vector& vector_b,Vector& vector_x,Integer level)
1018 AMGLevel* current_level = m_levels[level];
1019 Integer vector_size = vector_b.size();
1020 Integer nb_coarse = current_level->nbCoarsePoint();
1021 Matrix fine_matrix = current_level->fineMatrix();
1022 Matrix restriction_matrix = current_level->restrictionMatrix();
1023 Matrix coarse_matrix = current_level->coarseMatrix();
1024 Matrix prolongation_matrix = current_level->prolongationMatrix();
1026 Integer new_nb_row = nb_coarse;
1027 Vector new_b(new_nb_row);
1028 Vector new_x(new_nb_row);
1029 Vector tmp(vector_size);
1031 MatrixOperation mat_op;
1033 bool is_final_level = (level+1) == m_levels.size();
1035 const bool use_gauss_seidel =
false;
1037 Real jacobi_weight = 2.0 / 3.0;
1038 if (use_gauss_seidel){
1039 for( Integer i=0; i<nb_relax1; ++i )
1040 _relaxGaussSeidel(fine_matrix,vector_b,vector_x,TYPE_FINE,current_level->pointsType());
1041 for( Integer i=0; i<nb_relax1; ++i )
1042 _relaxGaussSeidel(fine_matrix,vector_b,vector_x,TYPE_COARSE,current_level->pointsType());
1047 for( Integer i=0; i<nb_relax1; ++i ){
1049 _relaxJacobi(fine_matrix,vector_b,vector_x,jacobi_weight);
1060 mat_op.matrixVectorProduct(fine_matrix,vector_x,tmp);
1063 mat_op.negateVector(tmp);
1064 mat_op.addVector(tmp,vector_b);
1067 mat_op.matrixVectorProduct(restriction_matrix,tmp,new_b);
1070 info() << ostr.str();
1077 if (is_final_level){
1083 ds.solve(coarse_matrix,new_b,new_x);
1087 Real epsilon = 1.0e-14;
1088 DiagonalPreconditioner p(coarse_matrix);
1089 ConjugateGradientSolver solver;
1091 new_x.values().fill(0.0);
1092 solver.solve(coarse_matrix,new_b,new_x,epsilon,&p);
1099 info() <<
"SOLVE COARSE MATRIX nb_iter=" << solver.nbIteration();
1105 new_x.values().fill(0.0);
1106 _solve(new_b,new_x,level+1);
1111 mat_op.matrixVectorProduct(prolongation_matrix,new_x,tmp);
1112 mat_op.addVector(vector_x,tmp);
1121 if (use_gauss_seidel){
1122 for( Integer i=0; i<nb_relax1; ++i )
1123 _relaxGaussSeidel(fine_matrix,vector_b,vector_x,TYPE_FINE,current_level->pointsType());
1124 for( Integer i=0; i<nb_relax1; ++i )
1125 _relaxGaussSeidel(fine_matrix,vector_b,vector_x,TYPE_COARSE,current_level->pointsType());
1130 for( Integer i=0; i<nb_relax1; ++i ){
1132 _relaxJacobi(fine_matrix,vector_b,vector_x,jacobi_weight);
1144_printResidualInfo(
const Matrix& a,
const Vector& b,
const Vector& x)
1147 Vector tmp(b.size());
1149 MatrixOperation mat_op;
1150 mat_op.matrixVectorProduct(a,x,tmp);
1153 mat_op.negateVector(tmp);
1154 mat_op.addVector(tmp,b);
1155 Real r = mat_op.dot(tmp);
1158 for( Integer i=0; i<v; ++i )
1159 info() <<
"R_" << i <<
" = " << tmp.values()[i];
1161 info() <<
" AMG_RESIDUAL_NORM=" << r <<
" sqrt=" <<
math::sqrt(r);
1177 PointInfo() : m_lambda(0), m_index(0) {}
1187 if (m_lambda==
rhs.m_lambda)
1188 return m_index<
rhs.m_index;
1189 return (m_lambda>
rhs.m_lambda);
1199 _printLevelInfo(m_prolongation_matrix);
1200 _printLevelInfo(m_coarse_matrix);
1204_printLevelInfo(Matrix matrix)
1207 Integer nb_row = matrix.nbRow();
1208 Integer nb_column = matrix.nbColumn();
1213 Integer nb_value = values.size();
1218 max_val = values[0];
1219 min_val = values[0];
1222 Real max_row_sum = 0.0;
1223 Real min_row_sum = 0.0;
1224 for( Integer row=0; row<nb_row; ++row ){
1226 for( Integer z=rows[row] ,zs=rows[row+1]; z<zs; ++z ){
1236 max_row_sum = row_sum;
1237 min_row_sum = row_sum;
1239 if (row_sum>max_row_sum)
1240 max_row_sum = row_sum;
1241 if (row_sum<max_row_sum)
1242 min_row_sum = row_sum;
1247 ostr() <<
"level=" << m_level
1248 <<
" nb_row=" << nb_row
1249 <<
" nb_col=" << nb_column
1250 <<
" nb_nonzero=" << nb_value
1251 <<
" sparsity=" << sparsity
1252 <<
" min=" << min_val
1253 <<
" max=" << max_val
1254 <<
" min_row=" << min_row_sum
1255 <<
" max_row=" << max_row_sum;
1257 info() <<
"INFO: " << ostr.str();
1264_buildCoarsePoints(
Real alpha,
1266 UniqueArray< SharedArray<Integer> >& depends,
1273 Integer nb_row = m_fine_matrix.nbRow();
1277 UniqueArray< SharedArray<Integer> > influences(nb_row);
1278 depends.resize(nb_row);
1280 m_points_type.
resize(nb_row);
1281 m_points_type.
fill(TYPE_UNDEFINED);
1283 weak_depends.resize(mat_values.size());
1284 weak_depends.fill(0);
1286 const bool type_hypre =
true;
1288 rows_max_val.resize(nb_row);
1289 for( Integer row=0; row<nb_row; ++row ){
1292 Real diag_val = mat_values[rows_index[row]];
1294 for( Integer z=rows_index[row]+1 ,zs=rows_index[row+1]; z<zs; ++z ){
1296 Real mv = mat_values[z];
1308 rows_max_val[row] = max_val * alpha;
1310 rows_max_val[row] = min_val * alpha;
1313 rows_max_val[row] = max_val * alpha;
1317 for( Integer row=0; row<nb_row; ++row ){
1319 Real max_val = rows_max_val[row];
1320 Real diag_val = mat_values[rows_index[row]];
1321 for( Integer z=rows_index[row]+1 ,zs=rows_index[row+1]; z<zs; ++z ){
1323 Real mv = mat_values[z];
1329 info() <<
" ADD INFLUENCE: ROW=" << row <<
" COL=" << column;
1331 depends[row].add(column);
1332 influences[column].add(row);
1333 weak_depends[z] = 2;
1336 weak_depends[z] = 1;
1342 info() <<
" ADD INFLUENCE: ROW=" << row <<
" COL=" << column;
1344 depends[row].add(column);
1345 influences[column].add(row);
1346 weak_depends[z] = 2;
1349 weak_depends[z] = 1;
1353 if (math::abs(mv)>max_val){
1356 info() <<
" ADD INFLUENCE: ROW=" << row <<
" COL=" << column;
1358 depends[row].add(column);
1359 influences[column].add(row);
1360 weak_depends[z] = 2;
1363 weak_depends[z] = 1;
1376 ostr() <<
"GRAPH\n";
1377 for( Integer i=0; i<n; ++i ){
1378 ostr() <<
" GRAPH I=" << i <<
" ";
1379 for( Integer j=0; j<depends[i].size(); ++j ){
1381 ostr() <<
" " << depends[i][j];
1383 ostr() <<
" index=" << index <<
'\n';
1385 ostr() <<
"\n MAXTRIX\n";
1387 for( Integer i=0; i<n; ++i ){
1388 ostr() <<
"MATRIX I=" << i <<
" ";
1389 for( Integer j=rows_index[i]; j<rows_index[i+1]; ++j ){
1391 ostr() <<
" " << columns[j] <<
" " << mat_values[j];
1393 ostr() <<
" index=" << index <<
'\n';
1395 info() << ostr.str();
1402 m_is_verbose =
false;
1405 for( Integer row=0; row<nb_row; ++row ){
1406 if (depends[row].size()==0){
1407 m_points_type[row] = TYPE_FINE;
1410 info() <<
"FIRST MARK FINE point=" << row;
1415 for( Integer row=0; row<nb_row; ++row ){
1416 if (m_points_type[row]!=TYPE_FINE && lambdas[row]<=0){
1417 m_points_type[row]=TYPE_FINE;
1420 info() <<
"INIT MARK FINE NULL MEASURE point=" << row <<
" measure=" << lambdas[row];
1421 for( Integer j=0, js=depends[row].size(); j<js; ++j ){
1422 Integer col = depends[row][j];
1423 if (m_points_type[col]!=TYPE_FINE)
1427 printf(
"ADD MEASURE NULL point=%d measure=%d\n",(
int)col,lambdas[col]);
1433 typedef std::set<PointInfo> PointSet;
1434 PointSet undefined_points;
1435 for( Integer i=0; i<nb_row; ++i ){
1436 if (m_points_type[i]==TYPE_UNDEFINED)
1437 undefined_points.insert(PointInfo(lambdas[i],i));
1440 while(nb_done<nb_row && nb_iter<100000){
1454 if (undefined_points.empty())
1455 fatal() <<
"Undefined points is empty";
1456 PointSet::iterator max_point = undefined_points.begin();
1457 Integer max_value_index = max_point->m_index;
1458 Integer max_value = max_point->m_lambda;
1459 m_points_type[max_value_index] = TYPE_COARSE;
1462 undefined_points.erase(max_point);
1464 cout <<
"MARK COARSE point=" << max_value_index
1465 <<
" measure=" << max_value
1466 <<
" left=" << (nb_row-nb_done)
1469 for( Integer i=0, is=point_influences.size(); i<is; ++i ){
1471 Integer pt = point_influences[i];
1473 if (m_points_type[pt]==TYPE_UNDEFINED){
1474 m_points_type[ pt ] = TYPE_FINE;
1477 undefined_points.erase(PointInfo(lambdas[pt],pt));
1479 cout <<
"MARK FINE point=" << pt
1480 <<
" measure=" << lambdas[pt]
1481 <<
" left=" << (nb_row-nb_done)
1483 for( Integer z=0, zs=depends[pt].size(); z<zs; ++z ){
1487 if (m_points_type[pt2]==TYPE_UNDEFINED){
1488 undefined_points.erase(PointInfo(lambdas[pt2],pt2));
1490 undefined_points.insert(PointInfo(lambdas[pt2],pt2));
1495 for( Integer i=0, is=depends[max_value_index].size(); i<is; ++i ){
1496 Integer pt3 = depends[max_value_index][i];
1497 if (m_points_type[pt3]==TYPE_UNDEFINED){
1498 undefined_points.erase(PointInfo(lambdas[pt3],pt3));
1503 undefined_points.insert(PointInfo(lambdas[pt3],pt3));
1507 info() <<
"LAMBDA MAX = " << max_value <<
" index=" << max_value_index <<
" nb_done=" << nb_done;
1512 info() <<
"NB ROW=" << nb_row <<
" nb_done=" << nb_done <<
" nb_fine=" << nb_fine
1513 <<
" nb_coarse=" << nb_coarse <<
" nb_iter=" << nb_iter;
1514 if (nb_done!=nb_row)
1515 fatal() <<
"Can not find all COARSE or FINE points nb_done=" << nb_done <<
" nb_point=" << nb_row;
1522 points_marker.fill(-1);
1525 bool C_i_nonempty =
false;
1526 for( Integer row=0; row<nb_row; ++row ){
1527 if ( (ci_tilde_mark |= row) )
1529 if (m_points_type[row]==TYPE_FINE){
1530 for( Integer z=0, zs=depends[row].size(); z<zs; ++z ){
1533 Integer col = depends[row][z];
1534 if (m_points_type[col]==TYPE_COARSE)
1535 points_marker[col] = row;
1537 for( Integer z=0, zs=depends[row].size(); z<zs; ++z ){
1540 Integer col = depends[row][z];
1541 if (m_points_type[col]==TYPE_FINE){
1542 bool set_empty =
true;
1543 for( Integer z2=0, zs2=depends[row].size(); z2<zs2; ++z2 ){
1546 Integer col2 = depends[row][z2];
1547 if (points_marker[col2]==row){
1554 m_points_type[row] = TYPE_COARSE;
1557 m_points_type[ci_tilde]= TYPE_FINE;
1559 printf(
"SECOND PASS MARK FINE point=%d\n",ci_tilde);
1562 C_i_nonempty =
false;
1566 ci_tilde_mark = row;
1567 m_points_type[col] = TYPE_COARSE;
1569 printf(
"SECOND PASS MARK COARSE2 point=%d\n",col);
1570 C_i_nonempty =
true;
1584 static int matrix_number = 0;
1586 info() <<
"READ HYPRE CF_marker n=" << matrix_number;
1587 StringBuilder fname(
"CF_marker-");
1588 fname += matrix_number;
1589 std::ifstream ifile(fname.toString().localstr());
1591 ifile >> ws >> nb_read_point >> ws;
1592 if (nb_read_point!=nb_row)
1593 fatal() <<
"Bad number of points for reading Hypre CF_marker read=" << nb_read_point
1594 <<
" expected=" << nb_row <<
" matrix_number=" << matrix_number;
1597 for( Integer i=0; i<nb_row; ++i ){
1601 fatal() <<
"Can not read marker point number=" << i;
1602 if (pt==(-1) || pt==(-3)){
1603 m_points_type[i] = TYPE_FINE;
1607 m_points_type[i] = TYPE_COARSE;
1611 fatal() <<
"Bad value read=" << pt <<
" expected 1 or -1";
1617 for( Integer i=0; i<nb_row; ++i ){
1618 if (m_points_type[i]==TYPE_UNDEFINED)
1619 fatal() <<
" Point " << i <<
" is undefined";
1620 if (m_points_type[i]!=TYPE_FINE){
1628 for( Integer z=0, zs=depends[i].size(); z<zs; ++z ){
1629 if (m_points_type[depends[i][z]]==TYPE_COARSE){
1641 for( Integer i=0; i<nb_row; ++i ){
1642 ostr() <<
" POINT i=" << i <<
" type=" << m_points_type[i] <<
" depends=";
1643 for( Integer j=0, js=depends[i].size(); j<js; ++j )
1644 ostr() << depends[i][j] <<
' ';
1647 info() << ostr.str();
1650 nb_fine = nb_row - nb_coarse;
1652 for( Integer i=0; i<nb_row; ++i )
1653 graph_size += depends[i].size();
1655 info() <<
" NB COARSE=" << nb_coarse <<
" NB FINE=" << nb_fine
1656 <<
" MAXTRIX NON_ZEROS=" << m_fine_matrix.
rowsIndex()[nb_row]
1657 <<
" GRAPH_SIZE=" << graph_size;
1658 bool dump_matrix =
false;
1659 bool has_error =
false;
1660 if (nb_fine==0 || graph_size==0){
1670 ostr() <<
"GRAPH\n";
1671 for( Integer i=0; i<n; ++i ){
1672 ostr() <<
" GRAPH I=" << i <<
" ";
1673 for( Integer j=0; j<depends[i].size(); ++j ){
1675 ostr() <<
" " << depends[i][j];
1677 ostr() <<
" index=" << index <<
'\n';
1680 ostr() <<
"\n MAXTRIX\n";
1682 for( Integer i=0; i<n; ++i ){
1683 ostr() <<
"MATRIX I=" << i <<
" ";
1684 for( Integer j=rows_index[i]; j<rows_index[i+1]; ++j ){
1686 ostr() <<
" " << columns[j] <<
" " << mat_values[j];
1688 ostr() <<
" index=" << index <<
'\n';
1690 info() << ostr.str();
1693 throw FatalErrorException(
"AMGLevel::_buildCoarsePoints");
1700buildLevel(Matrix matrix,
Real alpha)
1706 m_fine_matrix = matrix;
1713 UniqueArray< SharedArray<Integer> > depends;
1716 _buildCoarsePoints(alpha,rows_max_val,depends,weak_depends);
1717 _buildInterpolationMatrix(rows_max_val,depends,weak_depends);
1725 UniqueArray< SharedArray<Integer> >& depends,
1728 ARCANE_UNUSED(rows_max_val);
1733 Integer nb_row = m_fine_matrix.nbRow();
1736 points_in_coarse.fill(-1);
1741 for( Integer i=0; i<nb_row; ++i ){
1742 if (m_points_type[i]==TYPE_COARSE){
1743 points_in_coarse[i] = nb_coarse;
1748 bool type_hypre =
true;
1755 for( Integer row = 0; row<nb_row; ++row ){
1757 if (m_points_type[row]==TYPE_FINE){
1758 Real weak_connect_sum = 0.0;
1760 Real diag = mat_values[rows_index[row]];
1764 for( Integer z=rows_index[row]+1 ,zs=rows_index[row+1]; z<zs; ++z ){
1766 if (weak_depends[z]==1){
1767 Real mv = mat_values[z];
1769 weak_connect_sum += mv;
1772 weak_connect_sum += mv;
1780 info() <<
"ROW row=" << row <<
" weak_connect_sum=" << weak_connect_sum;
1783 for( Integer z=rows_index[row]+1 ,zs=rows_index[row+1]; z<zs; ++z ){
1784 Integer j_column = columns[z];
1785 if (m_points_type[j_column]!=TYPE_COARSE)
1787 if (weak_depends[z]!=2)
1790 Real mv = mat_values[z];
1791 for( Integer z2=0, zs2=depends[row].size(); z2<zs2; ++ z2){
1792 Integer k_column = depends[row][z2];
1795 if (m_points_type[k_column]!=TYPE_FINE)
1797 Real sum_coarse = 0.0;
1802 for( Integer z3=0 ,zs3=depends[row].size(); z3<zs3; ++z3 ){
1803 Integer m_column = depends[row][z3];
1806 if (m_points_type[m_column]==TYPE_COARSE){
1807 Real w = m_fine_matrix.
value(k_column,m_column);
1819 sum_coarse += math::abs(w);
1827 Real akj = m_fine_matrix.
value(k_column,j_column);
1828 bool do_add =
false;
1836 akj = math::abs(akj);
1841 to_add = math::divide(m_fine_matrix.
value(row,k_column) * akj,sum_coarse);
1845 Real weight = - ( mv + num_add ) / ( diag + weak_connect_sum);
1846 Integer new_column = points_in_coarse[j_column];
1852 if (new_column>=nb_coarse || new_column<0)
1853 fatal() <<
" BAD COLUMN for fine point column=" << new_column <<
" nb=" << nb_coarse
1854 <<
" jcolumn=" << j_column;
1855 prolongation_matrix_columns.add(new_column);
1856 prolongation_matrix_values.add(weight);
1862 Integer column = points_in_coarse[row];
1863 if (column>=nb_coarse || column<0)
1864 fatal() <<
" BAD COLUMN for coarse point j=" << column <<
" nb=" << nb_coarse
1866 prolongation_matrix_columns.add(column);
1867 prolongation_matrix_values.add(1.0);
1870 prolongation_matrix_rows_size[row] = nb_column;
1873 m_prolongation_matrix = Matrix(nb_row,nb_coarse);
1874 m_prolongation_matrix.
setRowsSize(prolongation_matrix_rows_size);
1876 m_prolongation_matrix.
setValues(prolongation_matrix_columns,prolongation_matrix_values);
1885 for( Integer i=0; i<n; ++i ){
1886 ostr() <<
"PROLONG I=" << i <<
" ";
1887 for( Integer j=p_rows[i]; j<p_rows[i+1]; ++j ){
1889 ostr() <<
" " << p_columns[j] <<
" " << p_values[j];
1891 ostr() <<
" index=" << index <<
'\n';
1893 info() <<
"PROLONG\n" << ostr.str();
1896 MatrixOperation2 mat_op2;
1898 m_restriction_matrix = mat_op2.transposeFast(m_prolongation_matrix);
1900 m_restriction_matrix = mat_op2.transpose(m_prolongation_matrix);
1903 ostr() <<
"PROLONGATION_MATRIX ";
1904 m_prolongation_matrix.
dump(ostr());
1906 ostr() <<
"RESTRICTION_MATRIX ";
1907 m_restriction_matrix.
dump(ostr());
1908 info() << ostr.str();
1913 const bool old =
false;
1915 Matrix n1 = mat_op2.matrixMatrixProductFast(m_fine_matrix,m_prolongation_matrix);
1919 info() <<
"N1_MATRIX " << ostr.str();
1921 m_coarse_matrix = mat_op2.matrixMatrixProductFast(m_restriction_matrix,n1);
1924 m_coarse_matrix = mat_op2.applyGalerkinOperator2(m_restriction_matrix,m_fine_matrix,m_prolongation_matrix);
1927 m_coarse_matrix.
dump(ostr());
1928 info() <<
"level= " << m_level <<
" COARSE_MATRIX=" << ostr.str();
1944void AMGPreconditioner::
1945apply(Vector& out_vec,
const Vector& vec)
1947 m_amg->solve(vec,out_vec);
1953void AMGPreconditioner::
1954build(
const Matrix& matrix)
1957 m_amg =
new AMG(m_trace_mng);
1958 m_amg->build(matrix);
1977build(
const Matrix& matrix)
1980 m_amg =
new AMG(m_trace_mng);
1981 m_amg->build(matrix);
1988solve(
const Vector& vector_b,Vector& vector_x)
1990 m_amg->solve(vector_b,vector_x);
Tableau d'items de types quelconques.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Matrice avec stockage CSR.
void sortDiagonale()
Arrange le stockage pour que la diagonale soit le premier élément.
IntegerConstArrayView rowsIndex() const
Indices des premiers éléments de chaque ligne.
Real value(Integer row, Integer column) const
Retourne la valeur d'un élément de la matrice.
void setRowsSize(IntegerConstArrayView rows_size)
Positionne le nombre d'éléments non nuls de chaque ligne.
void setValues(IntegerConstArrayView columns, RealConstArrayView values)
Positionne les valeurs des éléments de la matrice.
IntegerConstArrayView columns() const
Indices des colonnes des valeurs.
void dump(std::ostream &o) const
Imprime la matrice.
RealConstArrayView values() const
Valeurs de la matrice.
bool operator<(const PointInfo &rhs) const
Vecteur d'algèbre linéraire.
Matrix class, to be used by user.
void fill(const T &o) noexcept
Remplit le tableau avec la valeur o.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void fill(ConstReferenceType value)
Remplit le tableau avec la valeur value.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
Classe d'accès aux traces.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
Vecteur 1D de données avec sémantique par valeur (style STL).
ARCCORE_HOST_DEVICE Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
Espace de nom pour les fonctions mathématiques.
bool isZero(const BuiltInProxy< _Type > &a)
Teste si une valeur est exactement égale à zéro.
ARCCORE_HOST_DEVICE double sqrt(double v)
Racine carrée de v.
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
ConstArrayView< Real > RealConstArrayView
Equivalent C d'un tableau à une dimension de réels.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Array< Integer > IntegerArray
Tableau dynamique à une dimension d'entiers.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
UniqueArray< Real > RealUniqueArray
Tableau dynamique à une dimension de réels.
Array< Real > RealArray
Tableau dynamique à une dimension de réels.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
ArrayView< Real > RealArrayView
Equivalent C d'un tableau à une dimension de réels.
Int32 Integer
Type représentant un entier.