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
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];
94 vec_values[j] -= vec_values[k] * mat_values[j*size+k];
98 vec_values[0] /= mat_values[0];
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);
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;
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);
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);
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;
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
678 virtual ~AMGLevel(){}
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;
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);
755 void _relaxSymmetricGaussSeidel(
const Matrix& matrix,
const Vector& vector_b,
Vector& vector_x);
756 void _printResidualInfo(
const Matrix& matrix,
const Vector& vector_b,
766 for(
Integer i=0; i<m_levels.size(); ++i )
776 Matrix current_matrix = matrix;
778 for(
Integer i=1; i<100; ++i ){
779 AMGLevel* level =
new AMGLevel(
traceMng(),i);
780 level->buildLevel(current_matrix,0.25);
782 Integer nb_coarse_point = level->nbCoarsePoint();
783 if (nb_coarse_point<20)
785 current_matrix = level->coarseMatrix();
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);
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);
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);
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();
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;
1018 AMGLevel* current_level = m_levels[level];
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);
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);
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) {}
1178 PointInfo(
Integer lambda,
Integer index) : m_lambda(lambda), m_index(index){}
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();
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";
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";
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";
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";
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");
1706 m_fine_matrix = matrix;
1709 matrix.sortDiagonale();
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);
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::
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);
1990 m_amg->solve(vector_b,vector_x);
void fill(const T &o) noexcept
Remplit le tableau avec la valeur o.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface du gestionnaire de traces.
Matrice avec stockage CSR.
bool operator<(const PointInfo &rhs) const
Vecteur d'algèbre linéraire.
Matrix class, to be used by user.
Vecteur 1D de données avec sémantique par référence.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
Espace de nom pour les fonctions mathématiques.
__host__ __device__ double sqrt(double v)
Racine carrée de v.
bool isZero(const BuiltInProxy< _Type > &a)
Teste si une valeur est exactement égale à zéro.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
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.
double Real
Type représentant un réel.
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.
ConstArrayView< Real > RealConstArrayView
Equivalent C d'un tableau à une dimension de réels.