*** empty log message ***
This commit is contained in:
		
							parent
							
								
									e6fd8cc2e8
								
							
						
					
					
						commit
						57971235dd
					
				
							
								
								
									
										60
									
								
								diis.h
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								diis.h
									
									
									
									
									
								
							@ -9,6 +9,9 @@
 | 
				
			|||||||
#include "la_traits.h"
 | 
					#include "la_traits.h"
 | 
				
			||||||
#include "auxstorage.h"
 | 
					#include "auxstorage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Pulay memorial book  remarks - for numerical stabilization small addition to diagonal
 | 
				
			||||||
 | 
					#define DIISEPS 1e-9 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Typically, T is some solution vector in form of NRVec, NRMat, or NRSMat over double or complex<double> fields
 | 
					// Typically, T is some solution vector in form of NRVec, NRMat, or NRSMat over double or complex<double> fields
 | 
				
			||||||
// actually it can be anything what has operator=(const T&), clear(), dot() , axpy(), norm() and copyonwrite(), and LA_traits<T>::normtype and elementtype
 | 
					// actually it can be anything what has operator=(const T&), clear(), dot() , axpy(), norm() and copyonwrite(), and LA_traits<T>::normtype and elementtype
 | 
				
			||||||
// and get() and put() if external storage is requested
 | 
					// and get() and put() if external storage is requested
 | 
				
			||||||
@ -22,21 +25,23 @@ class DIIS
 | 
				
			|||||||
	int cyclicshift; //circular buffer of last dim vectors
 | 
						int cyclicshift; //circular buffer of last dim vectors
 | 
				
			||||||
	typedef typename LA_traits<T>::elementtype Te;
 | 
						typedef typename LA_traits<T>::elementtype Te;
 | 
				
			||||||
	NRSMat<Te> bmat;
 | 
						NRSMat<Te> bmat;
 | 
				
			||||||
	AuxStorage<Te> *st;
 | 
						AuxStorage<Te> *st, *errst;
 | 
				
			||||||
	T *stor;
 | 
						T *stor, *errstor;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	DIIS() {dim=0;}; //for array of diis
 | 
						DIIS() {dim=0; st=NULL; stor=NULL;}; //for array of diis
 | 
				
			||||||
	DIIS(const int n, const bool core=1);
 | 
						DIIS(const int n, const bool core=1);
 | 
				
			||||||
	void setup(const int n, const bool core=1);
 | 
						void setup(const int n, const bool core=1);
 | 
				
			||||||
	~DIIS();
 | 
						~DIIS();
 | 
				
			||||||
	typename LA_traits<T>::normtype extrapolate(T &vec); //vec is input/output; returns square residual norm
 | 
						typename LA_traits<T>::normtype extrapolate(T &vec, const T &errvec); //vec is input/output; returns square residual norm
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
DIIS<T>::DIIS(const int n, const bool core) : dim(n), incore(core), bmat(n,n)
 | 
					DIIS<T>::DIIS(const int n, const bool core) : dim(n), incore(core), bmat(n,n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
st=incore?NULL: new AuxStorage<Te>;
 | 
					st=incore?NULL: new AuxStorage<Te>;
 | 
				
			||||||
 | 
					errst=incore?NULL: new AuxStorage<Te>;
 | 
				
			||||||
stor= incore? new T[dim] : NULL;
 | 
					stor= incore? new T[dim] : NULL;
 | 
				
			||||||
 | 
					errstor= incore? new T[dim] : NULL;
 | 
				
			||||||
bmat= (Te)0; for(int i=1; i<n; ++i) bmat(0,i) = (Te)-1; 
 | 
					bmat= (Te)0; for(int i=1; i<n; ++i) bmat(0,i) = (Te)-1; 
 | 
				
			||||||
aktdim=cyclicshift=0;
 | 
					aktdim=cyclicshift=0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -48,7 +53,9 @@ dim=n;
 | 
				
			|||||||
incore=core;
 | 
					incore=core;
 | 
				
			||||||
bmat.resize(n);
 | 
					bmat.resize(n);
 | 
				
			||||||
st=incore?NULL: new AuxStorage<Te>;
 | 
					st=incore?NULL: new AuxStorage<Te>;
 | 
				
			||||||
 | 
					errst=incore?NULL: new AuxStorage<Te>;
 | 
				
			||||||
stor= incore? new T[dim] : NULL;
 | 
					stor= incore? new T[dim] : NULL;
 | 
				
			||||||
 | 
					errstor= incore? new T[dim] : NULL;
 | 
				
			||||||
bmat= (Te)0; for(int i=1; i<n; ++i) bmat(0,i) = (Te)-1;
 | 
					bmat= (Te)0; for(int i=1; i<n; ++i) bmat(0,i) = (Te)-1;
 | 
				
			||||||
aktdim=cyclicshift=0;
 | 
					aktdim=cyclicshift=0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -58,12 +65,15 @@ template<typename T>
 | 
				
			|||||||
DIIS<T>::~DIIS()
 | 
					DIIS<T>::~DIIS()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
if(st) delete st;
 | 
					if(st) delete st;
 | 
				
			||||||
 | 
					if(errst) delete errst;
 | 
				
			||||||
if(stor) delete[] stor;
 | 
					if(stor) delete[] stor;
 | 
				
			||||||
 | 
					if(errstor) delete[] errstor;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
typename LA_traits<T>::normtype DIIS<T>::extrapolate(T &vec)
 | 
					typename LA_traits<T>::normtype DIIS<T>::extrapolate(T &vec, const T &errvec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
if(!dim) laerror("attempt to extrapolate from uninitialized DIIS");
 | 
					if(!dim) laerror("attempt to extrapolate from uninitialized DIIS");
 | 
				
			||||||
//if dim exceeded, shift 
 | 
					//if dim exceeded, shift 
 | 
				
			||||||
@ -78,46 +88,44 @@ else
 | 
				
			|||||||
	++aktdim;
 | 
						++aktdim;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//store vector
 | 
					//store vector
 | 
				
			||||||
if(incore) stor[(aktdim-1+cyclicshift)%dim]=vec;
 | 
					if(incore) 
 | 
				
			||||||
else st->put(vec,(aktdim-1+cyclicshift)%dim);
 | 
						{
 | 
				
			||||||
 | 
						stor[(aktdim-1+cyclicshift)%dim]=vec;
 | 
				
			||||||
 | 
						errstor[(aktdim-1+cyclicshift)%dim]=errvec;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					else 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						st->put(vec,(aktdim-1+cyclicshift)%dim);
 | 
				
			||||||
 | 
						errst->put(errvec,(aktdim-1+cyclicshift)%dim);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(aktdim==1) return (typename LA_traits<T>::normtype)1000000000;
 | 
					if(aktdim==1) return (typename LA_traits<T>::normtype)1000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//calculate difference; 
 | 
					 | 
				
			||||||
vec.copyonwrite();
 | 
					 | 
				
			||||||
if(incore) vec.axpy((Te)-1,stor[(aktdim-2+cyclicshift)%dim]);
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	T tmp=vec;
 | 
					 | 
				
			||||||
	st->get(tmp,(aktdim-2+cyclicshift)%dim);
 | 
					 | 
				
			||||||
	vec.axpy((Te)-1,tmp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//calculate overlaps of differences (if storage is cheap, they could rather be stored than recomputed)
 | 
					//calculate overlaps of the new error with old ones
 | 
				
			||||||
typename LA_traits<T>::normtype norm=vec.norm();
 | 
					typename LA_traits<T>::normtype norm=errvec.norm();
 | 
				
			||||||
bmat(aktdim-1,aktdim-1)= norm*norm;
 | 
					bmat(aktdim-1,aktdim-1)= norm*norm + DIISEPS;
 | 
				
			||||||
if(incore)
 | 
					if(incore)
 | 
				
			||||||
	for(int i=1; i<aktdim-1; ++i) 
 | 
						for(int i=1; i<aktdim-1; ++i) 
 | 
				
			||||||
		bmat(i,aktdim-1)=vec.dot(stor[(i+cyclicshift)%dim] - stor[(i-1+cyclicshift)%dim]);
 | 
							bmat(i,aktdim-1)=errvec.dot(errstor[(i+cyclicshift)%dim]);
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	T tmp=vec;
 | 
						T tmp = vec; tmp.copyonwrite(); //copy dimensions
 | 
				
			||||||
	T tmp2=vec; //copy dimensions
 | 
					 | 
				
			||||||
	st->get(tmp2,(0+cyclicshift)%dim);
 | 
					 | 
				
			||||||
	for(int i=1; i<aktdim-1; ++i) 
 | 
						for(int i=1; i<aktdim-1; ++i) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		st->get(tmp,(i+cyclicshift)%dim);
 | 
							st->get(tmp,(i+cyclicshift)%dim);
 | 
				
			||||||
		tmp2 -= tmp;
 | 
							bmat(i,aktdim-1)= errvec.dot(tmp);
 | 
				
			||||||
		bmat(i,aktdim-1)= -vec.dot(tmp2);
 | 
					 | 
				
			||||||
		tmp2=tmp;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//prepare rhs-solution vector
 | 
					//prepare rhs-solution vector
 | 
				
			||||||
NRVec<Te> rhs(dim);
 | 
					NRVec<Te> rhs(dim);
 | 
				
			||||||
rhs= (Te)0; rhs[0]= (Te)-1;
 | 
					rhs= (Te)0; rhs[0]= (Te)-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//solve for coefficients
 | 
					//solve for coefficients
 | 
				
			||||||
 | 
					//@@@@@@ implement checking for bad condition number and eliminating old vectors
 | 
				
			||||||
 | 
					//@@@ explicit solution - cf. remarks in Pulay memorial book
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
NRSMat<Te> amat=bmat;
 | 
					NRSMat<Te> amat=bmat;
 | 
				
			||||||
linear_solve(amat,rhs,NULL,aktdim);
 | 
					linear_solve(amat,rhs,NULL,aktdim);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user