2 * SparseMatrixPetsc.cxx
4 * Created on: 04/11/2017
8 #include "SparseMatrixPetsc.hxx"
9 #include "CdmathException.hxx"
15 //----------------------------------------------------------------------
16 SparseMatrixPetsc::SparseMatrixPetsc()
17 //----------------------------------------------------------------------
24 PetscInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
27 //----------------------------------------------------------------------
28 SparseMatrixPetsc::SparseMatrixPetsc( int numberOfRows, int numberOfColumns)
29 //----------------------------------------------------------------------
31 _numberOfRows = numberOfRows;
32 _numberOfColumns=numberOfColumns;
34 PetscInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
35 MatCreateSeqAIJ(MPI_COMM_SELF,_numberOfRows,_numberOfColumns,PETSC_DEFAULT,NULL,&_mat);
38 //----------------------------------------------------------------------
39 SparseMatrixPetsc::SparseMatrixPetsc( Mat mat )
40 //----------------------------------------------------------------------
42 PetscInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
45 //extract number of row and column
46 MatGetSize(mat,&_numberOfRows,&_numberOfColumns);
48 //extract an upper bound for the total number of non zero coefficients
50 MatGetInfo(mat,MAT_LOCAL,&info);
51 _numberOfNonZeros = info.nz_allocated;
54 //----------------------------------------------------------------------
55 SparseMatrixPetsc::SparseMatrixPetsc( int numberOfRows, int numberOfColumns, int nnz )
56 //----------------------------------------------------------------------
58 _numberOfRows = numberOfRows;
59 _numberOfColumns=numberOfColumns;
60 _numberOfNonZeros=nnz;
63 PetscInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
64 MatCreateSeqAIJ(MPI_COMM_SELF,_numberOfRows,_numberOfColumns,_numberOfNonZeros,NULL,&_mat);
67 //----------------------------------------------------------------------
68 SparseMatrixPetsc::SparseMatrixPetsc( int blockSize, int numberOfRows, int numberOfColumns, int nnz )
69 //----------------------------------------------------------------------
71 _numberOfRows = numberOfRows;
72 _numberOfColumns=numberOfColumns;
73 _numberOfNonZeros=nnz;
76 PetscInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
77 MatCreateSeqBAIJ(MPI_COMM_SELF,blockSize, _numberOfRows,_numberOfColumns,_numberOfNonZeros,NULL,&_mat);
80 //----------------------------------------------------------------------
81 SparseMatrixPetsc::SparseMatrixPetsc(const SparseMatrixPetsc& matrix)
82 //----------------------------------------------------------------------
84 _isSparseMatrix=matrix.isSparseMatrix();
85 MatDuplicate(matrix.getPetscMatrix(), MAT_COPY_VALUES,&_mat);
86 MatGetSize(_mat,&_numberOfRows,&_numberOfColumns);
87 //extract an upper bound for the total number of non zero coefficients
89 MatGetInfo(_mat,MAT_LOCAL,&info);
90 _numberOfNonZeros = info.nz_allocated;
94 SparseMatrixPetsc::transpose() const
97 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
98 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
100 MatTranspose(_mat,MAT_INITIAL_MATRIX, &mattranspose);
101 return SparseMatrixPetsc(mattranspose);
105 SparseMatrixPetsc::setValue( int i, int j, double value )
107 MatSetValues(_mat,1, &i, 1, &j, &value, INSERT_VALUES);
111 SparseMatrixPetsc::addValue( int i, int j, double value )
113 MatSetValues(_mat,1, &i, 1, &j, &value, ADD_VALUES);
117 SparseMatrixPetsc::setValue( int i, int j, Matrix M )
120 for (int k=0; k<M.getNumberOfRows(); k++)
121 for (int l=0; l<M.getNumberOfColumns(); l++)
125 MatSetValues(_mat,1, &I, 1, &J, &M(k,l), INSERT_VALUES);
130 SparseMatrixPetsc::addValue( int i, int j, Matrix M )
133 for (int k=0; k<M.getNumberOfRows(); k++)
134 for (int l=0; l<M.getNumberOfColumns(); l++)
138 MatSetValues(_mat,1, &I, 1, &J, &M(k,l), ADD_VALUES);
143 SparseMatrixPetsc::setValuesBlocked( int i, int j, Matrix M )
146 MatGetBlockSize(_mat,&blockSize);
147 if(blockSize!=M.getNumberOfRows() || blockSize!=M.getNumberOfColumns())
148 throw CdmathException("SparseMatrixPetsc::setValuesBlocked : matrix size is different from sparse matrix block structure");
149 double petscValues[blockSize*blockSize];
150 for (int k=0; k<M.getNumberOfRows(); k++)
151 for (int l=0; l<M.getNumberOfColumns(); l++)
152 petscValues[k*blockSize+l]=M(k,l);
153 MatSetValuesBlocked(_mat,1, &i, 1, &j, petscValues, INSERT_VALUES);
157 SparseMatrixPetsc::addValuesBlocked( int i, int j, Matrix M )
160 MatGetBlockSize(_mat,&blockSize);
161 if(blockSize!=M.getNumberOfRows() || blockSize!=M.getNumberOfColumns())
162 throw CdmathException("SparseMatrixPetsc::addValuesBlocked : matrix size is different from sparse matrix block structure");
163 double petscValues[blockSize*blockSize];
164 for (int k=0; k<M.getNumberOfRows(); k++)
165 for (int l=0; l<M.getNumberOfColumns(); l++)
166 petscValues[k*blockSize+l]=M(k,l);
167 MatSetValuesBlocked(_mat,1, &i, 1, &j, petscValues, ADD_VALUES);
170 //----------------------------------------------------------------------
172 SparseMatrixPetsc::operator()( int i, int j ) const
173 //----------------------------------------------------------------------
177 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
178 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
180 MatGetValues(_mat,1,&idxm,1, &idxn,&res);
184 //----------------------------------------------------------------------
185 SparseMatrixPetsc::~SparseMatrixPetsc()
186 //----------------------------------------------------------------------
194 SparseMatrixPetsc::getPetscMatrix() const
196 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
197 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
203 SparseMatrixPetsc::containsPetscMatrix() const
207 //----------------------------------------------------------------------
208 const SparseMatrixPetsc&
209 SparseMatrixPetsc::operator= ( const SparseMatrixPetsc& matrix )
210 //----------------------------------------------------------------------
212 _isSparseMatrix=matrix.isSparseMatrix();
213 MatDuplicate(matrix.getPetscMatrix(), MAT_COPY_VALUES,&_mat);
214 MatGetSize(_mat,&_numberOfRows,&_numberOfColumns);
215 //extract an upper bound for the total number of non zero coefficients
217 MatGetInfo(_mat,MAT_LOCAL,&info);
218 _numberOfNonZeros = info.nz_allocated;
223 operator+ (const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2)
225 int numberOfRows = matrix1.getNumberOfRows();
226 int numberOfColumns = matrix1.getNumberOfColumns();
227 int numberOfRows2 = matrix2.getNumberOfRows();
228 int numberOfColumns2 = matrix2.getNumberOfColumns();
230 if(numberOfRows2!=numberOfRows || numberOfColumns2!=numberOfColumns)
232 string msg="SparseMatrixPetsc::operator()+(const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2): number of rows or columns of the matrices is different!";
233 throw CdmathException(msg);
236 Mat mat1=matrix1.getPetscMatrix();
237 Mat mat2=matrix2.getPetscMatrix();
239 MatDuplicate(mat1, MAT_COPY_VALUES,&mat);
240 MatAXPY(mat,1,mat2,DIFFERENT_NONZERO_PATTERN);
242 return SparseMatrixPetsc(mat);
246 operator- (const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2)
248 int numberOfRows = matrix1.getNumberOfRows();
249 int numberOfColumns = matrix1.getNumberOfColumns();
250 int numberOfRows2 = matrix2.getNumberOfRows();
251 int numberOfColumns2 = matrix2.getNumberOfColumns();
253 if(numberOfRows2!=numberOfRows || numberOfColumns2!=numberOfColumns)
255 string msg="SparseMatrixPetsc::operator()-(const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2): number of rows or columns of the matrices is different!";
256 throw CdmathException(msg);
258 Mat mat1=matrix1.getPetscMatrix();
259 Mat mat2=matrix2.getPetscMatrix();
261 MatDuplicate(mat1, MAT_COPY_VALUES,&mat);
262 MatAXPY(mat,-1,mat2,DIFFERENT_NONZERO_PATTERN);
264 return SparseMatrixPetsc(mat);
268 operator* (double value , const SparseMatrixPetsc& matrix )
271 MatDuplicate(matrix.getPetscMatrix(), MAT_COPY_VALUES,&mat);
272 MatScale(mat, value);
274 return SparseMatrixPetsc(mat);
278 operator* (const SparseMatrixPetsc& matrix, double value )
281 MatDuplicate(matrix.getPetscMatrix(), MAT_COPY_VALUES,&mat);
282 MatScale(mat, value);
284 return SparseMatrixPetsc(mat);
288 operator/ (const SparseMatrixPetsc& matrix, double value)
292 string msg="SparseMatrixPetsc SparseMatrixPetsc::operator()/(const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2): division by zero";
293 throw CdmathException(msg);
296 MatDuplicate(matrix.getPetscMatrix(), MAT_COPY_VALUES,&mat);
297 MatScale(mat, 1/value);
299 return SparseMatrixPetsc(mat);
303 operator*(const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2)
305 Mat mat1=matrix1.getPetscMatrix();
306 Mat mat2=matrix2.getPetscMatrix();
308 MatMatMult(mat1, mat2, MAT_INITIAL_MATRIX,PETSC_DEFAULT,&mat);
310 return SparseMatrixPetsc(mat);
314 SparseMatrixPetsc::operator*= (const SparseMatrixPetsc& matrix)
316 Mat mat1=matrix.getPetscMatrix();
317 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
318 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
321 MatMatMult(_mat, mat1, MAT_INITIAL_MATRIX,PETSC_DEFAULT,&mat2);
325 MatGetSize(_mat,&_numberOfRows,&_numberOfColumns);
326 //extract an upper bound for the total number of non zero coefficients
328 MatGetInfo(_mat,MAT_LOCAL,&info);
329 _numberOfNonZeros = info.nz_allocated;
334 SparseMatrixPetsc::operator* (const Vector& vec) const
336 int numberOfRows=vec.getNumberOfRows();
337 Vec X=vectorToVec(vec);
340 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
341 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
344 return vecToVector(Y);
348 SparseMatrixPetsc::operator+= (const SparseMatrixPetsc& matrix)
350 Mat mat1=matrix.getPetscMatrix();
351 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
352 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
353 MatAXPY(_mat,1,mat1,DIFFERENT_NONZERO_PATTERN);
355 //extract an upper bound for the total number of non zero coefficients
357 MatGetInfo(_mat,MAT_LOCAL,&info);
358 _numberOfNonZeros = info.nz_allocated;
364 SparseMatrixPetsc::operator-= (const SparseMatrixPetsc& matrix)
366 Mat mat1=matrix.getPetscMatrix();
367 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
368 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
369 MatAXPY(_mat,-1,mat1,DIFFERENT_NONZERO_PATTERN);
371 //extract an upper bound for the total number of non zero coefficients
373 MatGetInfo(_mat,MAT_LOCAL,&info);
374 _numberOfNonZeros = info.nz_allocated;
380 SparseMatrixPetsc::operator*= (double value)
382 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
383 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
384 MatScale(_mat, value);
389 SparseMatrixPetsc::operator/= (double value)
393 string msg="SparseMatrixPetsc SparseMatrixPetsc::operator()/=(const SparseMatrixPetsc& matrix1, const SparseMatrixPetsc& matrix2): division by zero";
394 throw CdmathException(msg);
396 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
397 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
398 MatScale(_mat, 1/value);
403 SparseMatrixPetsc::viewMatrix() const
405 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
406 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
408 MatView(_mat,PETSC_VIEWER_STDOUT_SELF);
411 SparseMatrixPetsc::getMatrixCoeff(int i, int j) const
415 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
416 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
418 MatGetValues(_mat,1,&idxm,1, &idxn,&res);
423 SparseMatrixPetsc::diagonalShift(double lambda)
425 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
426 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
428 MatShift(_mat, lambda);
432 SparseMatrixPetsc::zeroEntries()
434 MatZeroEntries(_mat);
438 SparseMatrixPetsc::vecToVector(const Vec& vec) const
440 PetscInt numberOfRows;
441 VecGetSize(vec,&numberOfRows);
442 double * petscValues;
443 VecGetArray(vec,&petscValues);
445 DoubleTab values (numberOfRows,petscValues);
446 Vector result(numberOfRows);
447 result.setValues(values);
452 SparseMatrixPetsc::vectorToVec(const Vector& myVector) const
454 int numberOfRows=myVector.getNumberOfRows();
455 const double* values = myVector.getValues().getValues();
458 VecCreate(PETSC_COMM_WORLD,&result);
459 VecSetSizes(result,PETSC_DECIDE,numberOfRows);
460 VecSetBlockSize(result,numberOfRows);
461 VecSetFromOptions(result);
462 int idx=0;//Index where to add the block of values
463 VecSetValuesBlocked(result,1,&idx,values,INSERT_VALUES);
465 VecAssemblyBegin(result);
466 VecAssemblyEnd(result);
471 bool SparseMatrixPetsc::isSymmetric(double tol) const
473 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
474 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
476 //Check that the matrix is symmetric
477 PetscBool isSymetric;
478 MatIsSymmetric(_mat,tol,&isSymetric);
484 SparseMatrixPetsc::computeSpectrum(int nev, double ** valP, double ***vecP, EPSWhich which, double tol) const
486 EPS eps; /* eigenproblem solver context */
491 PetscInt i,maxit,its, nconv;
493 SlepcInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
495 MatAssemblyBegin(_mat,MAT_FINAL_ASSEMBLY);
496 MatAssemblyEnd(_mat,MAT_FINAL_ASSEMBLY);
498 MatCreateVecs(_mat,NULL,&xr);
499 MatCreateVecs(_mat,NULL,&xi);
501 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
502 Create the eigensolver and set various options
503 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
505 Create eigensolver context
507 EPSCreate(PETSC_COMM_WORLD,&eps);
510 Set operators. In this case, it is a standard eigenvalue problem
512 EPSSetOperators(eps,_mat,NULL);
513 //if(isSymmetric(tol))
514 //EPSSetProblemType(eps,EPS_HEP);
516 EPSSetProblemType(eps,EPS_NHEP);
517 EPSSetWhichEigenpairs(eps,which);
518 EPSSetDimensions(eps,nev,PETSC_DEFAULT,PETSC_DEFAULT);
519 EPSSetTolerances(eps,tol,PETSC_DEFAULT);
522 Set solver parameters at runtime
524 EPSSetFromOptions(eps);
526 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
527 Solve the eigensystem
528 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
532 Optional: Get some information from the solver and display it
534 EPSGetIterationNumber(eps,&its);
535 PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",its);
536 EPSGetType(eps,&type);
537 PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);
538 EPSGetDimensions(eps,&nev,NULL,NULL);
539 PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);
540 EPSGetTolerances(eps,&tol,&maxit);
541 PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);
543 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
544 Display solution and clean up
545 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
547 Get number of converged approximate eigenpairs
549 EPSGetConverged(eps,&nconv);
550 PetscPrintf(PETSC_COMM_WORLD," Number of converged eigenpairs: %D\n\n",nconv);
552 *valP=new double[nconv];
553 *vecP=new double * [nconv];
558 Display eigenvalues and relative errors
560 PetscPrintf(PETSC_COMM_WORLD,
561 " k ||Ax-kx||/||kx||\n"
562 " ----------------- ------------------\n");
564 for (int i=0;i<nconv;i++) {
566 Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and
569 EPSGetEigenpair(eps,i,&kr,&ki,xr,xi);
571 Compute the relative error associated to each eigenpair
573 EPSComputeError(eps,i,EPS_ERROR_RELATIVE,&error);
576 PetscPrintf(PETSC_COMM_WORLD," %9f%+9fi %12g\n",(double)kr,(double)ki,(double)error);
578 PetscPrintf(PETSC_COMM_WORLD," %12f %12g\n",(double)kr,(double)error);
581 VecGetArray(xr,&myVecp);
582 *(*vecP+ i)=new double [_numberOfRows];
583 memcpy(*(*vecP+ i),myVecp,_numberOfRows*sizeof(double)) ;
585 PetscPrintf(PETSC_COMM_WORLD,"\n");
606 throw CdmathException("SparseMatrixPetsc::computeSpectrum : No eigenvector found");
611 SparseMatrixPetsc::computeSVD(int nsv, double ** valS, SVDWhich which, double tol) const
613 SVD svd; /* Singular value decomposition solver context */
617 PetscInt i,maxit,its, nconv;
619 SlepcInitialize(0, (char ***)"", PETSC_NULL, PETSC_NULL);
621 MatAssemblyBegin(_mat,MAT_FINAL_ASSEMBLY);
622 MatAssemblyEnd(_mat,MAT_FINAL_ASSEMBLY);
624 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
625 Create the singular value solver and set various options
626 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
628 Create singular value decomposition context
630 SVDCreate(PETSC_COMM_WORLD,&svd);
633 Set operators. In this case, it is a standard singular value problem
635 SVDSetOperator(svd,_mat);
636 SVDSetWhichSingularTriplets(svd,which);
637 SVDSetDimensions(svd,nsv,PETSC_DEFAULT,PETSC_DEFAULT);
638 SVDSetTolerances(svd,tol,PETSC_DEFAULT);
641 Set solver parameters at runtime
643 SVDSetFromOptions(svd);
645 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
646 Solve the SVD problem
647 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
651 Optional: Get some information from the solver and display it
653 SVDGetIterationNumber(svd,&its);
654 PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",its);
655 SVDGetType(svd,&type);
656 PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);
657 SVDGetDimensions(svd,&nsv,NULL,NULL);
658 PetscPrintf(PETSC_COMM_WORLD," Number of requested eingular values: %D\n",nsv);
659 SVDGetTolerances(svd,&tol,&maxit);
660 PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);
662 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
663 Display solution and clean up
664 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
666 Get number of converged approximate singular values
668 SVDGetConverged(svd,&nconv);
669 PetscPrintf(PETSC_COMM_WORLD," Number of converged singular values: %D\n\n",nconv);
671 *valS=new double[nconv];
675 Display eigenvalues and relative errors
677 PetscPrintf(PETSC_COMM_WORLD,
678 " k ||Ax-kx||/||kx||\n"
679 " ----------------- ------------------\n");
681 for (int i=0;i<nconv;i++) {
683 Get converged singular values: i-th eigenvalue is stored in valS
685 SVDGetSingularTriplet(svd,i,*valS+i,NULL,NULL);
687 Compute the relative error associated to each singular value
689 SVDComputeError( svd, i, SVD_ERROR_RELATIVE, &error );
691 PetscPrintf(PETSC_COMM_WORLD," %12f %12g\n",(double)*(*valS+i),(double)error);
693 PetscPrintf(PETSC_COMM_WORLD,"\n");
710 throw CdmathException("SparseMatrixPetsc::computeSVD : singular value decomposition failed");
714 std::vector< double >
715 SparseMatrixPetsc::getEigenvalues(int nev, EPSWhich which, double tol) const
721 nconv=computeSpectrum(nev, &valP, &vecP, which, tol);
723 std::vector< double > result(nconv);
725 for (int i=0;i<nconv;i++)
729 for (int i=0;i<nconv;i++)
736 std::vector< Vector >
737 SparseMatrixPetsc::getEigenvectors(int nev, EPSWhich which, double tol) const
743 nconv=computeSpectrum(nev, &valP, &vecP, which, tol);
745 std::vector< Vector > result(nconv);
747 for (int i=0;i<nconv;i++)
749 DoubleTab values (_numberOfRows,vecP[i]);
750 Vector myVecP(_numberOfRows);
751 myVecP.setValues(values);
756 for (int i=0;i<nconv;i++)
763 MEDCoupling::DataArrayDouble *
764 SparseMatrixPetsc::getEigenvectorsDataArrayDouble(int nev, EPSWhich which, double tol) const
770 nconv=computeSpectrum(nev, &valP, &vecP, which, tol);
772 std::vector< int > compoId(1);
773 MEDCoupling::DataArrayDouble *arrays=MEDCoupling::DataArrayDouble::New();
774 MEDCoupling::DataArrayDouble *array =MEDCoupling::DataArrayDouble::New();
775 arrays->alloc(_numberOfRows,nconv);
777 for (int i=0;i<nconv;i++)
779 array->useArray(vecP[i],true, MEDCoupling::DeallocType::CPP_DEALLOC, _numberOfRows,1);
781 arrays->setSelectedComponents(array,compoId);
782 arrays->setInfoOnComponent(i,std::to_string(valP[i]));
791 SparseMatrixPetsc::getConditionNumber(bool isSingular, double tol) const
793 if(isSymmetric(tol))//Eigenvalues computation is more robust that singular values computation
796 double lambda_max, lambda_min;
797 std::vector< double > my_ev;
799 /*** Lowest eigenvalue, first check if matrix is singular ***/
805 my_ev=getEigenvalues( nev, EPS_SMALLEST_MAGNITUDE, tol);
808 throw CdmathException("SparseMatrixPetsc::getConditionNumber could not find the smallest eigenvalue");
809 lambda_min=my_ev[nev-1];
811 /*** Largest eigenvalue ***/
813 my_ev=getEigenvalues( nev, EPS_LARGEST_MAGNITUDE, tol);
816 throw CdmathException("SparseMatrixPetsc::getConditionNumber could not find the largest eigenvalue");
817 lambda_max=my_ev[nev-1];
819 return fabs(lambda_max)/fabs(lambda_min);
821 else//Singular values computation is more robust than eigenvalues computation
825 double sigma_max, sigma_min;
827 /*** Lowest singular value, first check if matrix is singular ***/
833 nconv=computeSVD(nsv, &valS, SVD_SMALLEST, tol);
835 throw CdmathException("SparseMatrixPetsc::getConditionNumber could not find the smallest singular value");
836 sigma_min=valS[nsv-1];
839 /*** Largest singular value ***/
841 nconv=computeSVD(nsv, &valS, SVD_LARGEST, tol);
843 throw CdmathException("SparseMatrixPetsc::getConditionNumber could not find the largest singular value");
844 sigma_max=valS[nsv-1];
847 return sigma_max/sigma_min;
851 std::vector< double >
852 SparseMatrixPetsc::getSingularValues(int nsv, SVDWhich which, double tol) const
857 nconv=computeSVD(nsv, &valS, which, tol);
859 std::vector< double > result(nconv);
861 for (int i=0;i<nconv;i++)
870 SparseMatrixPetsc::leftDiagonalScale(Vector v)
872 Vec vec=vectorToVec(v);
874 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
875 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
877 MatDiagonalScale(_mat, vec, NULL);
880 SparseMatrixPetsc::rightDiagonalScale(Vector v)
882 Vec vec=vectorToVec(v);
884 MatAssemblyBegin(_mat, MAT_FINAL_ASSEMBLY);
885 MatAssemblyEnd(_mat, MAT_FINAL_ASSEMBLY);
887 MatDiagonalScale(_mat, NULL, vec);