mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Will start this as a two level algorithm
This commit is contained in:
		
							
								
								
									
										86
									
								
								lib/algorithms/iterative/PrecGeneralisedConjugateResidual.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								lib/algorithms/iterative/PrecGeneralisedConjugateResidual.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					#ifndef GRID_PGCR_H
 | 
				
			||||||
 | 
					#define GRID_PGCR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // Base classes for iterative processes based on operators
 | 
				
			||||||
 | 
					    // single input vec, single output vec.
 | 
				
			||||||
 | 
					    /////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template<class Field> 
 | 
				
			||||||
 | 
					    class ConjugateResidual : public OperatorFunction<Field> {
 | 
				
			||||||
 | 
					  public:                                                
 | 
				
			||||||
 | 
					    RealD   Tolerance;
 | 
				
			||||||
 | 
					    Integer MaxIterations;
 | 
				
			||||||
 | 
					    int verbose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConjugateResidual(RealD tol,Integer maxit) : Tolerance(tol), MaxIterations(maxit) { 
 | 
				
			||||||
 | 
					      verbose=0;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void operator() (LinearOperatorBase<Field> &Linop,const Field &src, Field &psi){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      RealD a, b, c, d;
 | 
				
			||||||
 | 
					      RealD cp, ssq,rsq;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      RealD rAr, rAAr, rArp;
 | 
				
			||||||
 | 
					      RealD pAp, pAAp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      GridBase *grid = src._grid;
 | 
				
			||||||
 | 
					      psi=zero;
 | 
				
			||||||
 | 
					      Field r(grid),  p(grid), Ap(grid), Ar(grid);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      r=src;
 | 
				
			||||||
 | 
					      p=src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Linop.HermOpAndNorm(p,Ap,pAp,pAAp);
 | 
				
			||||||
 | 
					      Linop.HermOpAndNorm(r,Ar,rAr,rAAr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if(verbose) std::cout << "pAp, pAAp"<< pAp<<" "<<pAAp<<std::endl;
 | 
				
			||||||
 | 
					      if(verbose) std::cout << "rAr, rAAr"<< rAr<<" "<<rAAr<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      cp =norm2(r);
 | 
				
			||||||
 | 
					      ssq=norm2(src);
 | 
				
			||||||
 | 
					      rsq=Tolerance*Tolerance*ssq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::cout<<"ConjugateResidual: iteration " <<0<<" residual "<<cp<< " target"<< rsq<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for(int k=1;k<MaxIterations;k++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						a = rAr/pAAp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						axpy(psi,a,p,psi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cp = axpy_norm(r,-a,Ap,r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rArp=rAr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Linop.HermOpAndNorm(r,Ar,rAr,rAAr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b   =rAr/rArp;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
						axpy(p,b,p,r);
 | 
				
			||||||
 | 
						pAAp=axpy_norm(Ap,b,Ap,Ar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(verbose) std::cout<<"ConjugateResidual: iteration " <<k<<" residual "<<cp<< " target"<< rsq<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(cp<rsq) {
 | 
				
			||||||
 | 
						  Linop.HermOp(psi,Ap);
 | 
				
			||||||
 | 
						  axpy(r,-1.0,src,Ap);
 | 
				
			||||||
 | 
						  RealD true_resid = norm2(r);
 | 
				
			||||||
 | 
						  std::cout<<"ConjugateResidual: Converged on iteration " <<k
 | 
				
			||||||
 | 
							   << " computed residual "<<sqrt(cp/ssq)
 | 
				
			||||||
 | 
						           << " true residual "<<true_resid
 | 
				
			||||||
 | 
						           << " target "       <<Tolerance <<std::endl;
 | 
				
			||||||
 | 
						  return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::cout<<"ConjugateResidual did NOT converge"<<std::endl;
 | 
				
			||||||
 | 
					      assert(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Reference in New Issue
	
	Block a user