1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 JDFTx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with JDFTx.  If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_ELECTRONIC_IONICMINIMIZER_H
21 #define JDFTX_ELECTRONIC_IONICMINIMIZER_H
22 
23 #include <core/RadialFunction.h>
24 #include <core/Minimize.h>
25 #include <core/matrix3.h>
26 
27 //! @addtogroup IonicSystem
28 //! @{
29 //! @file IonicMinimizer.h Class IonicMinimizer and helpers
30 
31 //! Vector space entry for ionic minimization (forces)
32 struct IonicGradient : std::vector< std::vector< vector3<> > >
33 {
34 	void init(const class IonInfo&); //!< initialize to zeroes with the correct species and atom numbers for iInfo
35 	void print(const Everything&, FILE*, const char* prefix="force") const;
36 	void write(const char* fname) const; //binary write to file
37 	void read(const char* fname); //binary read from file
38 
39 	IonicGradient& operator*=(double);
40 	IonicGradient& operator+=(const IonicGradient&);
41 	IonicGradient& operator-=(const IonicGradient&);
42 
43 	IonicGradient operator*(double) const;
44 	IonicGradient operator+(const IonicGradient&) const;
45 	IonicGradient operator-(const IonicGradient&) const;
46 };
47 
48 void axpy(double alpha, const IonicGradient& x, IonicGradient& y); //!< accumulate operation: Y += alpha*X
49 double dot(const IonicGradient& x, const IonicGradient& y); //!< inner product
50 IonicGradient clone(const IonicGradient& x); //!< create a copy
51 void randomize(IonicGradient& x); //!< initialize with random numbers
52 
53 IonicGradient operator*(const matrix3<>&, const IonicGradient&); //!< coordinate transformations
54 
55 //! Ionic minimizer
56 class IonicMinimizer : public Minimizable<IonicGradient>
57 {	Everything& e;
58 
59 public:
60 	IonicMinimizer(Everything& e, bool dynamicsMode=false);
61 	//Virtual functions from Minimizable:
62 	void step(const IonicGradient& dir, double alpha);
63 	double compute(IonicGradient* grad, IonicGradient* Kgrad);
64 	bool report(int iter);
65 	void constrain(IonicGradient&);
66 	static const double maxAtomTestDisplacement; //!< maximum allowed atom displacement in test step
67 	static const double maxWfnsDragDisplacement; //!< maximum atom displacement for which wavefunction drag is allowed
68 	double safeStepSize(const IonicGradient& dir) const; //!< enforces IonicMinimizer::maxAtomTestDisplacement on test step size
69 	double sync(double x) const; //!< All processes minimize together; make sure scalars are in sync to round-off error
70 
71 	double minimize(const MinimizeParams& params); //!< minor addition to Minimizable::minimize to invoke charge analysis at final positions
72 private:
73 	bool populationAnalysisPending; //!< report() has requested a charge analysis output that is yet to be done
74 	bool skipWfnsDrag; //!< whether to temprarily skip wavefunction dragging due to large steps
75 	bool anyConstrained; //!< whether any atoms are constrained
76 	bool dynamicsMode; //!< class used as a helper for IonicDynamics (changes Kgrad to be acceleration in compute)
77 };
78 
79 //! @}
80 #endif // JDFTX_ELECTRONIC_IONICMINIMIZER_H
81