Added absolute convergence tolerance stopping criteria to GMRES.

This commit is contained in:
baker59 2008-04-25 23:27:23 +00:00
parent 58ec40db69
commit 0d32527875
8 changed files with 124 additions and 31 deletions

View File

@ -114,6 +114,23 @@ HYPRE_GMRESGetTol( HYPRE_Solver solver,
{
return( hypre_GMRESGetTol( (void *) solver, tol ) );
}
/*--------------------------------------------------------------------------
* HYPRE_GMRESSeAtTol, HYPRE_GMRESGetATol
*--------------------------------------------------------------------------*/
int
HYPRE_GMRESSetAbsoluteTol( HYPRE_Solver solver,
double a_tol )
{
return( hypre_GMRESSetAbsoluteTol( (void *) solver, a_tol ) );
}
int
HYPRE_GMRESGetAbsoluteTol( HYPRE_Solver solver,
double * a_tol )
{
return( hypre_GMRESGetAbsoluteTol( (void *) solver, a_tol ) );
}
/*--------------------------------------------------------------------------
* HYPRE_GMRESSetConvergenceFactorTol, HYPRE_GMRESGetConvergenceFactorTol
@ -170,7 +187,7 @@ HYPRE_GMRESGetMaxIter( HYPRE_Solver solver,
}
/*--------------------------------------------------------------------------
* HYPRE_GMRESSetStopCrit, HYPRE_GMRESGetStopCrit
* HYPRE_GMRESSetStopCrit, HYPRE_GMRESGetStopCrit - OBSOLETE
*--------------------------------------------------------------------------*/
int

View File

@ -270,12 +270,24 @@ HYPRE_GMRESSolve(HYPRE_Solver solver,
/**
* (Optional) Set the convergence tolerance.
* (Optional) Set the relative convergence tolerance.
**/
int
HYPRE_GMRESSetTol(HYPRE_Solver solver,
double tol);
/**
* (Optional) Set the absolute convergence tolerance (default is 0).
* If one desires
* the convergence test to check the absolute convergence tolerance {\it only}, then
* set the relative convergence tolerance to 0.0. (The convergence test is
* $\|r_i\| \leq$ max(relative$\_$tolerance*$\|r_0\|$, absolute$\_$tolerance).)
*
**/
int
HYPRE_GMRESSetAbsoluteTol(HYPRE_Solver solver,
double a_tol);
/*
* RE-VISIT
**/
@ -364,7 +376,7 @@ int HYPRE_GMRESGetTol(HYPRE_Solver solver, double *tol);
int HYPRE_GMRESGetConvergenceFactorTol(HYPRE_Solver solver, double *cf_tol);
/*
* RE-VISIT
* OBSOLETE
**/
int HYPRE_GMRESGetStopCrit(HYPRE_Solver solver, int *stop_crit);

View File

@ -101,12 +101,13 @@ hypre_GMRESCreate( hypre_GMRESFunctions *gmres_functions )
/* set defaults */
(gmres_data -> k_dim) = 5;
(gmres_data -> tol) = 1.0e-06;
(gmres_data -> tol) = 1.0e-06; /* relative residual tol */
(gmres_data -> cf_tol) = 0.0;
(gmres_data -> a_tol) = 0.0; /* abs. residual tol */
(gmres_data -> min_iter) = 0;
(gmres_data -> max_iter) = 1000;
(gmres_data -> rel_change) = 0;
(gmres_data -> stop_crit) = 0; /* rel. residual norm */
(gmres_data -> stop_crit) = 0; /* rel. residual norm - this is obsolete!*/
(gmres_data -> converged) = 0;
(gmres_data -> precond_data) = NULL;
(gmres_data -> print_level) = 0;
@ -264,9 +265,9 @@ hypre_GMRESSolve(void *gmres_vdata,
int min_iter = (gmres_data -> min_iter);
int max_iter = (gmres_data -> max_iter);
int rel_change = (gmres_data -> rel_change);
int stop_crit = (gmres_data -> stop_crit);
double accuracy = (gmres_data -> tol);
double r_tol = (gmres_data -> tol);
double cf_tol = (gmres_data -> cf_tol);
double a_tol = (gmres_data -> a_tol);
void *matvec_data = (gmres_data -> matvec_data);
void *r = (gmres_data -> r);
@ -321,8 +322,6 @@ hypre_GMRESSolve(void *gmres_vdata,
if ( logging>0 || print_level>0 )
{
norms = (gmres_data -> norms);
/* not used yet log_file_name = (gmres_data -> log_file_name);*/
/* fp = fopen(log_file_name,"w"); */
}
/* initialize work arrays */
@ -409,20 +408,25 @@ hypre_GMRESSolve(void *gmres_vdata,
if (b_norm > 0.0)
{
/* convergence criterion |r_i|/|b| <= accuracy if |b| > 0 */
/* convergence criterion |r_i|/|b| <= accuracy if |b| > 0 */
den_norm= b_norm;
}
else
{
/* convergence criterion |r_i|/|r0| <= accuracy if |b| = 0 */
/* convergence criterion |r_i|/|r0| <= accuracy if |b| = 0 */
den_norm= r_norm;
};
epsilon= accuracy;
/* convergence criterion |r_i| <= accuracy , absolute residual norm*/
if ( stop_crit && !rel_change )
epsilon = accuracy;
/* convergence criteria: |r_i| <= max( a_tol, r_tol * den_norm)
den_norm = |r_0| or |b|
note: default for a_tol is 0.0, so relative residual criteria is used unless
user specifies a_tol, or sets r_tol = 0.0, which means absolute
tol only is checked */
epsilon = hypre_max(a_tol,r_tol*den_norm);
/* so now our stop criteria is |r_i| <= epsilon */
if ( print_level>1 && my_id == 0 )
{
@ -444,7 +448,6 @@ hypre_GMRESSolve(void *gmres_vdata,
/* once the rel. change check has passed, we do not want to check it again */
rel_change_passed = 0;
/* outer iteration cycle */
@ -467,7 +470,7 @@ hypre_GMRESSolve(void *gmres_vdata,
/* see if we are already converged and
should print the final norm and exit */
if (r_norm/den_norm <= epsilon && iter >= min_iter)
if (r_norm <= epsilon && iter >= min_iter)
{
if (!rel_change) /* shouldn't exit after no iterations if
* relative change is on*/
@ -475,7 +478,7 @@ hypre_GMRESSolve(void *gmres_vdata,
(*(gmres_functions->CopyVector))(b,r);
(*(gmres_functions->Matvec))(matvec_data,-1.0,A,x,1.0,r);
r_norm = sqrt((*(gmres_functions->InnerProd))(r,r));
if (r_norm/den_norm <= epsilon)
if (r_norm <= epsilon)
{
if ( print_level>1 && my_id == 0)
{
@ -573,7 +576,7 @@ hypre_GMRESSolve(void *gmres_vdata,
}
}
/* should we exit the restart cycle? (conv. check) */
if (r_norm/den_norm <= epsilon && iter >= min_iter)
if (r_norm <= epsilon && iter >= min_iter)
{
if (rel_change && !rel_change_passed)
{
@ -664,7 +667,7 @@ hypre_GMRESSolve(void *gmres_vdata,
/* find the norm of x_i - x_i-1 */
w_norm = sqrt( (*(gmres_functions->InnerProd))(r,r) );
relative_error = w_norm/x_norm;
if (relative_error <= epsilon)
if (relative_error <= r_tol)
{
rel_change_passed = 1;
break;
@ -717,14 +720,14 @@ hypre_GMRESSolve(void *gmres_vdata,
/* check for convergence by evaluating the actual residual */
if (r_norm/den_norm <= epsilon && iter >= min_iter)
if (r_norm <= epsilon && iter >= min_iter)
{
/* calculate actual residual norm*/
(*(gmres_functions->CopyVector))(b,r);
(*(gmres_functions->Matvec))(matvec_data,-1.0,A,x,1.0,r);
r_norm = sqrt( (*(gmres_functions->InnerProd))(r,r) );
if (r_norm/den_norm <= epsilon)
if (r_norm <= epsilon)
{
if (rel_change && !rel_change_passed) /* calculate the relative change */
{
@ -750,7 +753,7 @@ hypre_GMRESSolve(void *gmres_vdata,
/* find the norm of x_i - x_i-1 */
w_norm = sqrt( (*(gmres_functions->InnerProd))(r,r) );
relative_error= w_norm/x_norm;
if ( relative_error < epsilon )
if ( relative_error < r_tol )
{
(gmres_data -> converged) = 1;
if ( print_level>1 && my_id == 0 )
@ -821,7 +824,7 @@ hypre_GMRESSolve(void *gmres_vdata,
if (b_norm == 0.0)
(gmres_data -> rel_residual_norm) = r_norm;
if (iter >= max_iter && r_norm/den_norm > epsilon) hypre_error(HYPRE_ERROR_CONV);
if (iter >= max_iter && r_norm > epsilon) hypre_error(HYPRE_ERROR_CONV);
hypre_TFreeF(c,gmres_functions);
@ -894,7 +897,33 @@ hypre_GMRESGetTol( void *gmres_vdata,
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
* hypre_GMRESSetAbsoluteTol, hypre_GMRESGetAbsoluteTol
*--------------------------------------------------------------------------*/
int
hypre_GMRESSetAbsoluteTol( void *gmres_vdata,
double a_tol )
{
hypre_GMRESData *gmres_data = gmres_vdata;
(gmres_data -> a_tol) = a_tol;
return hypre_error_flag;
}
int
hypre_GMRESGetAbsoluteTol( void *gmres_vdata,
double * a_tol )
{
hypre_GMRESData *gmres_data = gmres_vdata;
*a_tol = (gmres_data -> a_tol);
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
* hypre_GMRESSetConvergenceFactorTol, hypre_GMRESGetConvergenceFactorTol
*--------------------------------------------------------------------------*/
@ -1009,6 +1038,8 @@ hypre_GMRESGetRelChange( void *gmres_vdata,
/*--------------------------------------------------------------------------
* hypre_GMRESSetStopCrit, hypre_GMRESGetStopCrit
*
* OBSOLETE
*--------------------------------------------------------------------------*/
int

View File

@ -113,6 +113,7 @@ typedef struct
int converged;
double tol;
double cf_tol;
double a_tol;
double rel_residual_norm;
void *A;

View File

@ -45,7 +45,7 @@ extern "C" {
#endif
/*BHEADER**********************************************************************
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Produced at the Lawrence Livermore National Laboratory.
* Written by the HYPRE team. UCRL-CODE-222953.
* All rights reserved.
@ -72,6 +72,7 @@ extern "C" {
/******************************************************************************
*
* BiCGSTAB bicgstab
@ -241,7 +242,7 @@ hypre_BiCGSTABCreate( hypre_BiCGSTABFunctions * bicgstab_functions );
#endif
/*BHEADER**********************************************************************
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Produced at the Lawrence Livermore National Laboratory.
* Written by the HYPRE team. UCRL-CODE-222953.
* All rights reserved.
@ -269,6 +270,7 @@ hypre_BiCGSTABCreate( hypre_BiCGSTABFunctions * bicgstab_functions );
/******************************************************************************
*
* cgnr (conjugate gradient on the normal equations A^TAx = A^Tb) functions
@ -420,7 +422,7 @@ hypre_CGNRCreate( hypre_CGNRFunctions *cgnr_functions );
#endif
/*BHEADER**********************************************************************
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Produced at the Lawrence Livermore National Laboratory.
* Written by the HYPRE team. UCRL-CODE-222953.
* All rights reserved.
@ -447,6 +449,7 @@ hypre_CGNRCreate( hypre_CGNRFunctions *cgnr_functions );
/******************************************************************************
*
* GMRES gmres
@ -533,6 +536,7 @@ typedef struct
int converged;
double tol;
double cf_tol;
double a_tol;
double rel_residual_norm;
void *A;
@ -608,7 +612,7 @@ hypre_GMRESCreate( hypre_GMRESFunctions *gmres_functions );
#endif
#endif
/*BHEADER**********************************************************************
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
* Produced at the Lawrence Livermore National Laboratory.
* Written by the HYPRE team. UCRL-CODE-222953.
* All rights reserved.
@ -636,6 +640,7 @@ hypre_GMRESCreate( hypre_GMRESFunctions *gmres_functions );
/******************************************************************************
*
* Preconditioned conjugate gradient (Omin) headers
@ -860,6 +865,8 @@ int hypre_GMRESSetKDim ( void *gmres_vdata , int k_dim );
int hypre_GMRESGetKDim ( void *gmres_vdata , int *k_dim );
int hypre_GMRESSetTol ( void *gmres_vdata , double tol );
int hypre_GMRESGetTol ( void *gmres_vdata , double *tol );
int hypre_GMRESSetAbsoluteTol ( void *gmres_vdata , double a_tol );
int hypre_GMRESGetAbsoluteTol ( void *gmres_vdata , double *a_tol );
int hypre_GMRESSetConvergenceFactorTol ( void *gmres_vdata , double cf_tol );
int hypre_GMRESGetConvergenceFactorTol ( void *gmres_vdata , double *cf_tol );
int hypre_GMRESSetMinIter ( void *gmres_vdata , int min_iter );
@ -918,6 +925,8 @@ int HYPRE_GMRESSetKDim ( HYPRE_Solver solver , int k_dim );
int HYPRE_GMRESGetKDim ( HYPRE_Solver solver , int *k_dim );
int HYPRE_GMRESSetTol ( HYPRE_Solver solver , double tol );
int HYPRE_GMRESGetTol ( HYPRE_Solver solver , double *tol );
int HYPRE_GMRESSetAbsoluteTol ( HYPRE_Solver solver , double a_tol );
int HYPRE_GMRESGetAbsoluteTol ( HYPRE_Solver solver , double *a_tol );
int HYPRE_GMRESSetConvergenceFactorTol ( HYPRE_Solver solver , double cf_tol );
int HYPRE_GMRESGetConvergenceFactorTol ( HYPRE_Solver solver , double *cf_tol );
int HYPRE_GMRESSetMinIter ( HYPRE_Solver solver , int min_iter );

View File

@ -123,6 +123,16 @@ HYPRE_ParCSRGMRESSetTol( HYPRE_Solver solver,
{
return( HYPRE_GMRESSetTol( solver, tol ) );
}
/*--------------------------------------------------------------------------
* HYPRE_ParCSRGMRESSetAbsoluteTol
*--------------------------------------------------------------------------*/
int
HYPRE_ParCSRGMRESSetAbsoluteTol( HYPRE_Solver solver,
double a_tol )
{
return( HYPRE_GMRESSetAbsoluteTol( solver, a_tol ) );
}
/*--------------------------------------------------------------------------
* HYPRE_ParCSRGMRESSetMinIter
@ -147,7 +157,7 @@ HYPRE_ParCSRGMRESSetMaxIter( HYPRE_Solver solver,
}
/*--------------------------------------------------------------------------
* HYPRE_ParCSRGMRESSetStopCrit
* HYPRE_ParCSRGMRESSetStopCrit - OBSOLETE
*--------------------------------------------------------------------------*/
int

View File

@ -2038,6 +2038,18 @@ int HYPRE_ParCSRGMRESSetKDim(HYPRE_Solver solver,
int HYPRE_ParCSRGMRESSetTol(HYPRE_Solver solver,
double tol);
/**
* (Optional) Set the absolute convergence tolerance (default is 0).
* If one desires
* the convergence test to check the absolute convergence tolerance {\it only}, then
* set the relative convergence tolerance to 0.0. (The convergence test is
* $\|r_i\| \leq$ max(relative$\_$tolerance*$\|r_0\|$, absolute$\_$tolerance).)
*
**/
int HYPRE_ParCSRGMRESSetAbsoluteTol(HYPRE_Solver solver,
double a_tol);
/*
* RE-VISIT
**/
@ -2051,7 +2063,7 @@ int HYPRE_ParCSRGMRESSetMaxIter(HYPRE_Solver solver,
int max_iter);
/*
* RE-VISIT
* Obsolete
**/
int HYPRE_ParCSRGMRESSetStopCrit(HYPRE_Solver solver,
int stop_crit);

View File

@ -118,7 +118,7 @@ int hypre_AMSSetAlphaAMGOptions ( void *solver , int B_Pi_coarsen_type , int B_P
int hypre_AMSSetBetaAMGOptions ( void *solver , int B_G_coarsen_type , int B_G_agg_levels , int B_G_relax_type , double B_G_theta , int B_G_interp_type , int B_G_Pmax );
int hypre_AMSComputePi ( hypre_ParCSRMatrix *A , hypre_ParCSRMatrix *G , hypre_ParVector *x , hypre_ParVector *y , hypre_ParVector *z , hypre_ParVector *Gx , hypre_ParVector *Gy , hypre_ParVector *Gz , int dim , hypre_ParCSRMatrix **Pi_ptr );
int hypre_AMSComputePixyz ( hypre_ParCSRMatrix *A , hypre_ParCSRMatrix *G , hypre_ParVector *x , hypre_ParVector *y , hypre_ParVector *z , hypre_ParVector *Gx , hypre_ParVector *Gy , hypre_ParVector *Gz , int dim , hypre_ParCSRMatrix **Pix_ptr , hypre_ParCSRMatrix **Piy_ptr , hypre_ParCSRMatrix **Piz_ptr );
int hypre_AMSComputeGPi ( hypre_ParCSRMatrix *A , hypre_ParCSRMatrix *G , hypre_ParVector *x , hypre_ParVector *y , hypre_ParVector *z , hypre_ParVector *Gx , hypre_ParVector *Gy , hypre_ParVector *Gz , int dim , hypre_ParCSRMatrix **Pi_ptr );
int hypre_AMSComputeGPi ( hypre_ParCSRMatrix *A , hypre_ParCSRMatrix *G , hypre_ParVector *x , hypre_ParVector *y , hypre_ParVector *z , hypre_ParVector *Gx , hypre_ParVector *Gy , hypre_ParVector *Gz , int dim , hypre_ParCSRMatrix **GPi_ptr );
int hypre_AMSSetup ( void *solver , hypre_ParCSRMatrix *A , hypre_ParVector *b , hypre_ParVector *x );
int hypre_AMSSolve ( void *solver , hypre_ParCSRMatrix *A , hypre_ParVector *b , hypre_ParVector *x );
int hypre_ParCSRSubspacePrec ( hypre_ParCSRMatrix *A0 , int A0_relax_type , int A0_relax_times , double *A0_l1_norms , double A0_relax_weight , double A0_omega , hypre_ParCSRMatrix **A , HYPRE_Solver *B , hypre_ParCSRMatrix **P , hypre_ParVector **r , hypre_ParVector **g , hypre_ParVector *x , hypre_ParVector *y , hypre_ParVector *r0 , hypre_ParVector *g0 , char *cycle );
@ -369,6 +369,7 @@ int HYPRE_ParCSRGMRESSetup ( HYPRE_Solver solver , HYPRE_ParCSRMatrix A , HYPRE_
int HYPRE_ParCSRGMRESSolve ( HYPRE_Solver solver , HYPRE_ParCSRMatrix A , HYPRE_ParVector b , HYPRE_ParVector x );
int HYPRE_ParCSRGMRESSetKDim ( HYPRE_Solver solver , int k_dim );
int HYPRE_ParCSRGMRESSetTol ( HYPRE_Solver solver , double tol );
int HYPRE_ParCSRGMRESSetAbsoluteTol ( HYPRE_Solver solver , double a_tol );
int HYPRE_ParCSRGMRESSetMinIter ( HYPRE_Solver solver , int min_iter );
int HYPRE_ParCSRGMRESSetMaxIter ( HYPRE_Solver solver , int max_iter );
int HYPRE_ParCSRGMRESSetStopCrit ( HYPRE_Solver solver , int stop_crit );