1 /*
2 
3  Copyright (C) 2007 Lucas K. Wagner
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19  */
20 
21 //
22 #ifndef AVERAGE_GENERATOR_H_INCLUDED
23 #define AVERAGE_GENERATOR_H_INCLUDED
24 #include "Qmc_std.h"
25 #include "Wavefunction.h"
26 #include "Wavefunction_data.h"
27 #include "Basis_function.h"
28 #include "System.h"
29 #include "Basis_function.h"
30 struct Properties_point;
31 struct Average_return {
32   string type;
33   Array1 <doublevar> vals;
34 };
35 
36 /*!
37  The average generators are meant to be averages which are not *too* big(ie, < 1000 doubles), and should
38  go into the Properties_point structure.  They will be averaged with error bars, and can do post-processing
39  either in the output of gosling or the main code(they use the same functions, so it's automatic).
40 
41  The interface gives the code writer a lot of power, including the power to mess up the VMC/RMC/DMC calculation.
42  There are thus a few rules of engagement.
43  1) Leave the state of sample and wf as you found them.  The final electronic coordinates should never change.
44  2) Try to keep the amount of data saved to the bare minimum you need, although if you know that in the future
45  you'll need some internal state to make nice output, then go ahead and store it in the logfile in the init section.
46 
47  If you find that you need more information than is provided via the evaluate() function(for example, maybe
48                                                                                          there are special weights for RMC or something), you can do the following:
49  1) Subclass Average_generator with a different evaluate() function.  Try to keep it general so more than
50  one type can be included with the same parameters.
51  2) Make an allocate() function for your subclass and add the subclass to the allocate() for Average_generator
52  3) Keep an array of Subclass *'s in the averaging function and have them evaluate into the Properties_points,
53  appending to the normal list of Average_returns.
54  That's about all.  Assuming that you write the write_init, read, and write_summaries, correctly, everything
55  else should be taken care of.
56 
57  Futher hints:
58  -Averages with weights can be done.  Pack the vals array with val1*weight1, weight1, val2*weight2, weight2, etc.
59  The values and weights will be averaged properly, and in write_summary(), you can report <val1*weight1>/<weight1>
60  as the average value.
61 
62  */
63 class Average_generator {
64 public:
~Average_generator()65   virtual ~Average_generator() {};
66   //these are used in the main program.  evaluate() packs the
67   //averaging data into the 'vals' array.  read() does as normal
68   //write_init will write a section in the log file with relevant data
69   //for gosling
70   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
71                         System * sys, Sample_point * sample, Average_return & )=0;
72 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Properties_point & pt,Average_return & avg)73   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
74                         System * sys, Sample_point * sample, Properties_point & pt,Average_return &avg) {
75     evaluate(wfdata,wf,sys,sample,avg);//in most of the case, just let it be the same;
76   }
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Pseudopotential * psp,Sample_point * sample,Average_return & avg)77   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
78 			System * sys, Pseudopotential * psp, Sample_point * sample, Average_return &avg ) {
79     evaluate(wfdata,wf,sys,sample,avg);//In most of the case, just let it be the same;
80   }
81 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Pseudopotential * psp,Sample_point * sample,Properties_point & pt,Average_return & avg)82   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
83                         System * sys, Pseudopotential *psp, Sample_point * sample,
84                         Properties_point & pt,Average_return &avg) {
85     evaluate(wfdata,wf,sys, sample, pt, avg);
86   }
87 
88   virtual void read(System * sys, Wavefunction_data * wfdata, vector
89                     <string> & words)=0;
90   virtual void write_init(string & indent, ostream & os)=0;
91   //This is used for Average_generators that use some kind of random sampling
92   //in addition what's done already in the larger Monte Carlo stuff.  It's separated
93   //from evaluate() so that correlated sampling can work efficiently
randomize(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample)94   virtual void randomize(Wavefunction_data * wfdata, Wavefunction * wf,
95                         System * sys, Sample_point * sample) { }
96 
97   //these are used in gosling: read will read in the write_init stuff
98   //from above and set any relevant
99   //internal variables.  gosling will average together all the
100   // Average_returns and give a final averaged one
101   //to write_summary, which will give a nice interpretation of the data.
102   virtual void read(vector <string> & words)=0;
103   virtual void write_summary(Average_return &,Average_return &, ostream & os)=0;
jsonOutput(Average_return &,Average_return &,ostream & os)104   virtual void jsonOutput(Average_return &,Average_return &, ostream & os) {
105     error("jsonOutput not implemented for this Average_generator");
106   }
107 
108 };
109 
110 int allocate(vector<string> & words, System * sys, Wavefunction_data * wfdata, Average_generator *& avg);
111 int allocate(vector<string> & words, Average_generator * & avg);
112 
113 //##########################################################################
114 
115 class Average_dipole:public Average_generator {
116 public:
117   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
118                         System * sys, Sample_point * sample, Average_return & );
119   virtual void read(System * sys, Wavefunction_data * wfdata, vector
120                     <string> & words);
121   virtual void write_init(string & indent, ostream & os);
122   virtual void read(vector <string> & words);
123   virtual void write_summary(Average_return &,Average_return &, ostream & os);
124  private:
125 };
126 
127 
128 //----------------------------------------------------------------------------
129 
130 class Average_structure_factor:public Average_generator {
131 public:
132   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
133                         System * sys, Sample_point * sample, Average_return & );
134   virtual void read(System * sys, Wavefunction_data * wfdata, vector
135                     <string> & words);
136   virtual void write_init(string & indent, ostream & os);
137   virtual void read(vector <string> & words);
138   virtual void write_summary(Average_return &,Average_return &, ostream & os);
139   virtual void jsonOutput(Average_return &,Average_return &, ostream & os);
140 private:
141   int npoints;
142   Array2 <doublevar> kpts;
143 
144 };
145 
146 //----------------------------------------------------------------------------
147 class Average_fourier_density:public Average_generator {
148 public:
149   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
150                         System * sys, Sample_point * sample, Average_return & );
151   virtual void read(System * sys, Wavefunction_data * wfdata, vector
152                     <string> & words);
153   virtual void write_init(string & indent, ostream & os);
154   virtual void read(vector <string> & words);
155   virtual void write_summary(Average_return &,Average_return &, ostream & os);
156 private:
157   int npoints;
158   Array2 <doublevar> kpts;
159 
160 };
161 //----------------------------------------------------------------------------
162 
163 
164 class Average_twobody_correlation:public Average_generator {
165 public:
166   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
167                         System * sys, Sample_point * sample, Average_return & );
168   virtual void read(System * sys, Wavefunction_data * wfdata, vector
169                     <string> & words);
170   virtual void write_init(string & indent, ostream & os);
171   virtual void read(vector <string> & words);
172   virtual void write_summary(Average_return &,Average_return &, ostream & os);
173   virtual void jsonOutput(Average_return &,Average_return &, ostream & os);
174 private:
175   double resolution;
176   int npoints;
177   int direction; //we can look only in the x, y, or z direction if we like 0=r, 2=x,3=y,4=z.
178 };
179 
180 //----------------------------------------------------------------------------
181 
182 class Average_manybody_polarization:public Average_generator {
183 public:
184   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
185                         System * sys, Sample_point * sample, Average_return & );
186   virtual void read(System * sys, Wavefunction_data * wfdata, vector
187                     <string> & words);
188   virtual void write_init(string & indent, ostream & os);
189   virtual void read(vector <string> & words);
190   virtual void write_summary(Average_return &,Average_return &, ostream & os);
191   virtual void jsonOutput(Average_return &,Average_return &, ostream & os);
192 
193 private:
194     Array2 <doublevar> gvec;
195 };
196 
197 
198 //----------------------------------------------------------------------------
199 
200 /*!
201 Spherically averaged one-body density matrix.
202 */
203 class Average_obdm:public Average_generator {
204 public:
205   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
206                         System * sys, Sample_point * sample, Average_return & );
207   virtual void read(System * sys, Wavefunction_data * wfdata, vector
208                     <string> & words);
209   virtual void write_init(string & indent, ostream & os);
210   virtual void read(vector <string> & words);
211   virtual void write_summary(Average_return &,Average_return &, ostream & os);
212 private:
213   int npoints;            //!< number of points in the plotting grid
214   doublevar dR;           //!< grid spacing
215   int np_aver;            //!< number of points in quadrature for spherical average
216   Array2 <doublevar> ptc; //!< cartesian coordinates of quadrature points
217   Array1 <doublevar> wt;  //!< weights for quadrature points
218 };
219 
220 //----------------------------------------------------------------------------
221 
222 /*!
223 Projected two-body density matrix, spherically averaged.
224 */
225 class Average_tbdm:public Average_generator {
226 public:
227   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
228                         System * sys, Sample_point * sample, Average_return & );
229   virtual void read(System * sys, Wavefunction_data * wfdata, vector
230                     <string> & words);
231   virtual void write_init(string & indent, ostream & os);
232   virtual void read(vector <string> & words);
233   virtual void write_summary(Average_return &,Average_return &, ostream & os);
234 private:
235   int nelectrons;
236   int npoints;            //!< number of points in the plotting grid
237   doublevar dR;           //!< grid spacing
238   int np_aver;            //!< number of points in quadrature for spherical average
239   Array2 <doublevar> ptc; //!< cartesian coordinates of quadrature points
240   Array1 <doublevar> wt;  //!< weights for quadrature points
241 };
242 
243 //----------------------------------------------------------------------------
244 
245 /*!
246 Local magnetic (spin) moments and charges obtained by integrating electron
247 density in muffin-tin spheres.
248 */
249 class Average_local_moments:public Average_generator {
250 public:
251   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
252                         System * sys, Sample_point * sample, Average_return & );
253   virtual void read(System * sys, Wavefunction_data * wfdata, vector
254                     <string> & words);
255   virtual void write_init(string & indent, ostream & os);
256   virtual void read(vector <string> & words);
257   virtual void write_summary(Average_return &,Average_return &, ostream & os);
258 private:
259   int nelectrons;            //!< number of electrons
260   int nup;                   //!< number of spin-up electrons
261   int natoms;                //!< number of atoms
262   Array1 <doublevar> rMT;    //!< radii of muffin-tin spheres
263   vector <string> atomnames; //!< atom labels
264 };
265 
266 //----------------------------------------------------------------------------
267 
268 //##########################################################################
269 
270 class Average_density_moments:public Average_generator {
271 public:
272   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
273                         System * sys, Sample_point * sample, Average_return & );
274   virtual void read(System * sys, Wavefunction_data * wfdata, vector
275                     <string> & words);
276   virtual void write_init(string & indent, ostream & os);
277   virtual void read(vector <string> & words);
278   virtual void write_summary(Average_return &,Average_return &, ostream & os);
279 };
280 
281 
282 //----------------------------------------------------------------------------
283 
284 //##########################################################################
285 class Average_linear_derivative:public Average_generator {
286 public:
287   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
288                         System * sys, Sample_point * sample, Average_return & );
289   virtual void read(System * sys, Wavefunction_data * wfdata, vector
290                     <string> & words);
291   virtual void write_init(string & indent, ostream & os);
292   virtual void read(vector <string> & words);
293   virtual void write_summary(Average_return &,Average_return &, ostream & os);
294 private:
295   doublevar tau;
296   int unr;
297 
298 };
299 //----------------------------------------------------------------------------
300 
301 //##########################################################################
302 class Average_linear_delta_derivative:public Average_generator {
303 public:
304   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
305                         System * sys, Sample_point * sample, Average_return & );
306   virtual void read(System * sys, Wavefunction_data * wfdata, vector
307                     <string> & words);
308   virtual void write_init(string & indent, ostream & os);
309   virtual void read(vector <string> & words);
310   virtual void write_summary(Average_return &,Average_return &, ostream & os);
311 private:
312   doublevar tau;
313   int unr;
314 
315 
316 };
317 //----------------------------------------------------------------------------
318 /*!
319 Spherically averaged density on the basis
320 */
321 class Average_spherical_density:public Average_generator {
322 public:
323   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
324                         System * sys, Sample_point * sample, Average_return & );
325   virtual void read(System * sys, Wavefunction_data * wfdata, vector
326                     <string> & words);
327   virtual void write_init(string & indent, ostream & os);
328   virtual void read(vector <string> & words);
329   virtual void write_summary(Average_return &,Average_return &, ostream & os);
330 private:
331   int npoints;            //!< number of points in the plotting grid
332   doublevar dR;           //!< grid spacing
333   doublevar cutoff;        //!< grid cutoff
334   int nup,ndown;         //!< number of electrons
335   Basis_function * basis;
336   int nfunc;
337   vector <string> basistext;
338   //int np_aver;            //!< number of points in quadrature for spherical average
339   //Array2 <doublevar> ptc; //!< cartesian coordinates of quadrature points
340   //Array1 <doublevar> wt;  //!< weights for quadrature points
341 };
342 
343 //----------------------------------------------------------------------------
344 
345 
346 
347 //----------------------------------------------------------------------------
348 
349 /*!
350 Spherically averaged density on the grid
351 */
352 class Average_spherical_density_grid:public Average_generator {
353 public:
354   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
355                         System * sys, Sample_point * sample, Average_return & );
356   virtual void read(System * sys, Wavefunction_data * wfdata, vector
357                     <string> & words);
358   virtual void write_init(string & indent, ostream & os);
359   virtual void read(vector <string> & words);
360   virtual void write_summary(Average_return &,Average_return &, ostream & os);
361 private:
362   int npoints;            //!< number of points in the plotting grid
363   doublevar dR;           //!< grid spacing
364   int nup,ndown;         //!< number of elec
365 };
366 
367 //----------------------------------------------------------------------------
368 
369 /*!
370 Density along a line.
371   */
372 class Average_line_density:public Average_generator {
373 public:
374   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
375                         System * sys, Sample_point * sample, Average_return & );
376   virtual void read(System * sys, Wavefunction_data * wfdata, vector
377                     <string> & words);
378   virtual void write_init(string & indent, ostream & os);
379   virtual void read(vector <string> & words);
380   virtual void write_summary(Average_return &,Average_return &, ostream & os);
381  private:
382    Array1 <doublevar> vec;     //!< Line goes in this direction
383    Array1 <doublevar> origin;  //!< Line starts here
384    doublevar resolution;  //!< Bin size
385    int npoints; //Number of points on the line
386 };
387 
388 //----------------------------------------------------------------------------
389 
390 /*!
391  \brief
392  Accumulate the derivative of the wave function with respect to the parameters.
393  */
394 class Average_wf_parmderivs:public Average_generator {
395 public:
396   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
397                         System * sys, Sample_point * sample, Average_return & avg);
398   virtual void evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
399                         System * sys, Sample_point * sample, Properties_point & pt, Average_return & avg);
400   virtual void read(System * sys, Wavefunction_data * wfdata, vector
401                     <string> & words);
402   virtual void write_init(string & indent, ostream & os);
403   virtual void read(vector <string> & words);
404   virtual void write_summary(Average_return &,Average_return &, ostream & os);
405   virtual void jsonOutput(Average_return &,Average_return &, ostream & );
406 
407 private:
408 
409 };
410 
411 
412 
413 
414 
415 #endif //AVERAGE_GENERATOR_H_INCLUDED
416 
417