Commit ae9f1ceb authored by incardon's avatar incardon

Refactoring residual norm calculator

parent 859e3b0c
...@@ -37,6 +37,19 @@ public: ...@@ -37,6 +37,19 @@ public:
#define SOLVER_PRINT_RESIDUAL_NORM_INFINITY 1 #define SOLVER_PRINT_RESIDUAL_NORM_INFINITY 1
#define SOLVER_PRINT_DETERMINANT 2 #define SOLVER_PRINT_DETERMINANT 2
// It contain statistic of the error of the calculated solution
struct solError
{
// infinity norm of the error
PetscReal err_inf;
// L1 norm of the error
PetscReal err_norm;
// Number of iterations
PetscInt its;
};
size_t cpu_rank; size_t cpu_rank;
/*! \brief This class is able to do Matrix inversion in parallel with PETSC solvers /*! \brief This class is able to do Matrix inversion in parallel with PETSC solvers
...@@ -48,19 +61,6 @@ size_t cpu_rank; ...@@ -48,19 +61,6 @@ size_t cpu_rank;
template<> template<>
class petsc_solver<double> class petsc_solver<double>
{ {
// It contain statistic of the error of the calculated solution
struct solError
{
// infinity norm of the error
PetscReal err_inf;
// L1 norm of the error
PetscReal err_norm;
// Number of iterations
PetscInt its;
};
//It contain statistic of the error at each iteration //It contain statistic of the error at each iteration
struct itError struct itError
{ {
...@@ -625,43 +625,18 @@ class petsc_solver<double> ...@@ -625,43 +625,18 @@ class petsc_solver<double>
*/ */
static solError statSolutionError(Mat & A_, const Vec & b_, Vec & x_, KSP ksp) static solError statSolutionError(Mat & A_, const Vec & b_, Vec & x_, KSP ksp)
{ {
PetscScalar neg_one = -1.0; solError err;
// We set the size of x according to the Matrix A
PetscInt row;
PetscInt col;
PetscInt row_loc;
PetscInt col_loc;
PetscInt its;
PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
/*
Here we calculate the residual error
*/
PetscReal norm;
PetscReal norm_inf;
// Get a vector r for the residual
Vector<double,PETSC_BASE> r(row,row_loc);
Vec & r_ = r.getVec();
PETSC_SAFE_CALL(MatMult(A_,x_,r_)); err = getSolNormError(A_,b_,x_);
PETSC_SAFE_CALL(VecAXPY(r_,neg_one,b_));
PETSC_SAFE_CALL(VecNorm(r_,NORM_1,&norm)); PetscInt its;
PETSC_SAFE_CALL(VecNorm(r_,NORM_INFINITY,&norm_inf));
PETSC_SAFE_CALL(KSPGetIterationNumber(ksp,&its)); PETSC_SAFE_CALL(KSPGetIterationNumber(ksp,&its));
solError err;
err.err_norm = norm / col;
err.err_inf = norm_inf;
err.its = its; err.its = its;
return err; return err;
} }
/*! \brief initialize the KSP object /*! \brief initialize the KSP object
* *
* *
...@@ -694,6 +669,49 @@ class petsc_solver<double> ...@@ -694,6 +669,49 @@ class petsc_solver<double>
KSPDestroy(&ksp); KSPDestroy(&ksp);
} }
/*! \brief Return the norm error of the solution
*
* \param A_ the matrix that identity the linear system
* \param x_ the solution
* \param b_ the right-hand-side
*
*/
static solError getSolNormError(const Mat & A_, const Vec & x_, const Vec & b_)
{
PetscScalar neg_one = -1.0;
// We set the size of x according to the Matrix A
PetscInt row;
PetscInt col;
PetscInt row_loc;
PetscInt col_loc;
PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
/*
Here we calculate the residual error
*/
PetscReal norm;
PetscReal norm_inf;
// Get a vector r for the residual
Vector<double,PETSC_BASE> r(row,row_loc);
Vec & r_ = r.getVec();
PETSC_SAFE_CALL(MatMult(A_,x_,r_));
PETSC_SAFE_CALL(VecAXPY(r_,neg_one,b_));
PETSC_SAFE_CALL(VecNorm(r_,NORM_1,&norm));
PETSC_SAFE_CALL(VecNorm(r_,NORM_INFINITY,&norm_inf));
solError err;
err.err_norm = norm / col;
err.err_inf = norm_inf;
return err;
}
public: public:
typedef Vector<double,PETSC_BASE> return_type; typedef Vector<double,PETSC_BASE> return_type;
...@@ -887,6 +905,15 @@ public: ...@@ -887,6 +905,15 @@ public:
return x; return x;
} }
/*! \brief It return the resiual error
*
*
*/
solError get_residual_error(SparseMatrix<double,int,PETSC_BASE> & A, const Vector<double,PETSC_BASE> & x, const Vector<double,PETSC_BASE> & b)
{
return getSolNormError(A.getMat(),x.getVec(),b.getVec());
}
/*! \brief Here we invert the matrix and solve the system /*! \brief Here we invert the matrix and solve the system
* *
* \warning umfpack is not a parallel solver, this function work only with one processor * \warning umfpack is not a parallel solver, this function work only with one processor
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment