1
1
/*BHEADER**********************************************************************
2
* Copyright (c) 2006 The Regents of the University of California.
2
* Copyright (c) 2008, Lawrence Livermore National Security, LLC.
3
3
* Produced at the Lawrence Livermore National Laboratory.
4
* Written by the HYPRE team. UCRL-CODE-222953.
7
* This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/).
8
* Please see the COPYRIGHT_and_LICENSE file for the copyright notice,
9
* disclaimer, contact information and the GNU Lesser General Public License.
11
* HYPRE is free software; you can redistribute it and/or modify it under the
12
* terms of the GNU General Public License (as published by the Free Software
13
* Foundation) version 2.1 dated February 1999.
15
* HYPRE is distributed in the hope that it will be useful, but WITHOUT ANY
16
* WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS
17
* FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU General
18
* Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public License
21
* along with this program; if not, write to the Free Software Foundation,
22
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4
* This file is part of HYPRE. See file COPYRIGHT for details.
6
* HYPRE is free software; you can redistribute it and/or modify it under the
7
* terms of the GNU Lesser General Public License (as published by the Free
8
* Software Foundation) version 2.1 dated February 1999.
25
11
***********************************************************************EHEADER*/
30
17
/******************************************************************************
32
19
* Preconditioned conjugate gradient (Omin) functions
52
39
hypre_PCGFunctions *
53
40
hypre_PCGFunctionsCreate(
54
char * (*CAlloc) ( int count, int elt_size ),
41
char * (*CAlloc) ( size_t count, size_t elt_size ),
55
42
int (*Free) ( char *ptr ),
56
43
int (*CommInfo) ( void *A, int *my_id, int *num_procs ),
57
44
void * (*CreateVector) ( void *vector ),
110
97
(pcg_data -> tol) = 1.0e-06;
111
98
(pcg_data -> atolf) = 0.0;
112
99
(pcg_data -> cf_tol) = 0.0;
100
(pcg_data -> a_tol) = 0.0;
113
101
(pcg_data -> max_iter) = 1000;
114
102
(pcg_data -> two_norm) = 0;
115
103
(pcg_data -> rel_change) = 0;
104
(pcg_data -> recompute_residual) = 0;
116
105
(pcg_data -> stop_crit) = 0;
117
106
(pcg_data -> converged) = 0;
118
107
(pcg_data -> owns_matvec_data ) = 1;
233
221
(*(pcg_functions->MatvecDestroy))(pcg_data -> matvec_data);
234
222
(pcg_data -> matvec_data) = (*(pcg_functions->MatvecCreate))(A, x);
236
ierr = precond_setup(precond_data, A, b, x);
224
precond_setup(precond_data, A, b, x);
238
226
/*-----------------------------------------------------
239
227
* Allocate space for log info
282
270
hypre_PCGData *pcg_data = pcg_vdata;
283
271
hypre_PCGFunctions *pcg_functions = pcg_data->functions;
285
double tol = (pcg_data -> tol);
273
double r_tol = (pcg_data -> tol);
274
double a_tol = (pcg_data -> a_tol);
286
275
double atolf = (pcg_data -> atolf);
287
276
double cf_tol = (pcg_data -> cf_tol);
288
277
int max_iter = (pcg_data -> max_iter);
289
278
int two_norm = (pcg_data -> two_norm);
290
279
int rel_change = (pcg_data -> rel_change);
280
int recompute_residual = (pcg_data -> recompute_residual);
291
281
int stop_crit = (pcg_data -> stop_crit);
293
283
int converged = (pcg_data -> converged);
389
379
else if ( atolf>0 ) /* mixed relative and absolute tolerance */
390
380
bi_prod += atolf;
381
else /* DEFAULT (stop_crit and atolf exist for backwards compatibilty
382
and are not in the reference manual) */
384
/* convergence criteria: <C*r,r> <= max( a_tol^2, r_tol^2 * <C*b,b> )
385
note: default for a_tol is 0.0, so relative residual criteria is used unless
386
user specifies a_tol, or sets r_tol = 0.0, which means absolute
387
tol only is checked */
388
eps = hypre_max(r_tol*r_tol, a_tol*a_tol/bi_prod);
392
392
else /* bi_prod==0.0: the rhs vector b is zero */
546
/* check for convergence */
547
if (i_prod / bi_prod < eps)
552
/*--------------------------------------------------------------------
553
* check for convergence
554
*--------------------------------------------------------------------*/
555
if (i_prod / bi_prod < eps) /* the basic convergence test */
556
tentatively_converged = 1;
557
if ( tentatively_converged && recompute_residual )
558
/* At user request, don't trust the convergence test until we've recomputed
559
the residual from scratch. This is expensive in the usual case where an
560
the norm is the energy norm.
561
This calculation is coded on the assumption that r's accuracy is only a
562
concern for problems where CG takes many iterations. */
549
if (rel_change && i_prod > guard_zero_residual)
565
(*(pcg_functions->CopyVector))(b, r);
566
(*(pcg_functions->Matvec))(matvec_data, -1.0, A, x, 1.0, r);
568
/* set i_prod for convergence test */
570
i_prod = (*(pcg_functions->InnerProd))(r,r);
574
(*(pcg_functions->ClearVector))(s);
575
precond(precond_data, A, r, s);
576
/* iprod = gamma = <r,s> */
577
i_prod = (*(pcg_functions->InnerProd))(r, s);
579
if (i_prod / bi_prod >= eps) tentatively_converged = 0;
581
if ( tentatively_converged && rel_change && (i_prod > guard_zero_residual ))
582
/* At user request, don't treat this as converged unless x didn't change
583
much in the last iteration. */
551
585
pi_prod = (*(pcg_functions->InnerProd))(p,p);
552
586
xi_prod = (*(pcg_functions->InnerProd))(x,x);
553
587
ratio = alpha*alpha*pi_prod/xi_prod;
556
(pcg_data -> converged) = 1;
562
(pcg_data -> converged) = 1;
588
if (ratio >= eps) tentatively_converged = 0;
590
if ( tentatively_converged )
591
/* we've passed all the convergence tests, it's for real */
593
(pcg_data -> converged) = 1;
567
597
if ( (gamma<1.0e-292) && ((-gamma)<1.0e-292) ) {
599
hypre_error(HYPRE_ERROR_CONV);
571
603
/* ... gamma should be >=0. IEEE subnormal numbers are < 2**(-1022)=2.2e-308
590
622
enough to pass the convergence test. Therefore initial guess was good,
591
623
and we're just calculating garbage - time to bail out before the
592
624
next step, which will be a divide by zero (or close to it). */
626
hypre_error(HYPRE_ERROR_CONV);
596
630
cf_ave_1 = pow( i_prod / i_prod_0, 1.0/(2.0*i));
605
639
if (weight * cf_ave_1 > cf_tol) break;
642
/*--------------------------------------------------------------------
643
* back to the core CG calculations
644
*--------------------------------------------------------------------*/
608
646
/* beta = gamma / gamma_old */
609
647
beta = gamma / gamma_old;
613
651
(*(pcg_functions->Axpy))(1.0, s, p);
616
if ( print_level > 1 && my_id==0 ) /* formerly for par_csr only */
654
/*--------------------------------------------------------------------
655
* Finish up with some outputs.
656
*--------------------------------------------------------------------*/
658
if ( print_level > 1 && my_id==0 )
619
661
(pcg_data -> num_iterations) = i;
648
689
hypre_PCGData *pcg_data = pcg_vdata;
651
691
*tol = (pcg_data -> tol);
693
return hypre_error_flag;
695
/*--------------------------------------------------------------------------
696
* hypre_PCGSetAbsoluteTol, hypre_PCGGetAbsoluteTol
697
*--------------------------------------------------------------------------*/
700
hypre_PCGSetAbsoluteTol( void *pcg_vdata,
703
hypre_PCGData *pcg_data = pcg_vdata;
705
(pcg_data -> a_tol) = a_tol;
707
return hypre_error_flag;
711
hypre_PCGGetAbsoluteTol( void *pcg_vdata,
714
hypre_PCGData *pcg_data = pcg_vdata;
716
*a_tol = (pcg_data -> a_tol);
718
return hypre_error_flag;
656
721
/*--------------------------------------------------------------------------
786
846
int * rel_change )
788
848
hypre_PCGData *pcg_data = pcg_vdata;
791
851
*rel_change = (pcg_data -> rel_change);
853
return hypre_error_flag;
856
/*--------------------------------------------------------------------------
857
* hypre_PCGSetRecomputeResidual, hypre_PCGGetRecomputeResidual
858
*--------------------------------------------------------------------------*/
861
hypre_PCGSetRecomputeResidual( void *pcg_vdata,
862
int recompute_residual )
864
hypre_PCGData *pcg_data = pcg_vdata;
867
(pcg_data -> recompute_residual) = recompute_residual;
869
return hypre_error_flag;
873
hypre_PCGGetRecomputeResidual( void *pcg_vdata,
874
int * recompute_residual )
876
hypre_PCGData *pcg_data = pcg_vdata;
879
*recompute_residual = (pcg_data -> recompute_residual);
881
return hypre_error_flag;
796
884
/*--------------------------------------------------------------------------
850
938
hypre_PCGData *pcg_data = pcg_vdata;
851
939
hypre_PCGFunctions *pcg_functions = pcg_data->functions;
854
942
(pcg_functions -> precond) = precond;
855
943
(pcg_functions -> precond_setup) = precond_setup;
856
944
(pcg_data -> precond_data) = precond_data;
946
return hypre_error_flag;
861
949
/*--------------------------------------------------------------------------