1 #include "Average_generator.h"
2 #include "qmc_io.h"
3 #include "gesqua.h"
4 #include "ulec.h"
5 #include "Average_density_matrix.h"
6 #include "Average_ekt.h"
7 #include "Average_region_fluctuation.h"
8 #include "Average_enmoment.h"
9 #include "Average_derivative_dm.h"
10 #include "Average_quadrupole.h"
11 #include "Average_so.h"
12 #include "Properties_point.h"
13 #include "jsontools.h"
14 
15 //-----------------------------------------------------------------------------
decide_averager(string & label,Average_generator * & avg)16 int decide_averager(string & label, Average_generator *& avg) {
17   if(caseless_eq(label, "DIPOLE") )
18     avg=new Average_dipole;
19   else if(caseless_eq(label,"SK"))
20     avg=new Average_structure_factor;
21   else if(caseless_eq(label, "GR"))
22     avg=new Average_twobody_correlation;
23   else if(caseless_eq(label, "MANYBODY_POL"))
24     avg=new Average_manybody_polarization;
25   else if(caseless_eq(label, "OBDM"))
26     avg=new Average_obdm;
27   else if(caseless_eq(label, "EKT"))
28     avg=new Average_ekt;
29   else if(caseless_eq(label, "TBDM"))
30     avg=new Average_tbdm;
31   else if(caseless_eq(label, "LM"))
32     avg=new Average_local_moments;
33   else if(caseless_eq(label,"DENSITY_MOMENTS"))
34     avg=new Average_density_moments;
35   else if(caseless_eq(label, "LINEAR_DER"))
36     avg=new Average_linear_derivative;
37   else if(caseless_eq(label, "LINEAR_DELTA_DER"))
38     avg=new Average_linear_delta_derivative;
39    else if(caseless_eq(label, "SPHERICAL_DENSITY"))
40     avg=new Average_spherical_density;
41   else if(caseless_eq(label, "SPHERICAL_DENSITY_GRID"))
42     avg=new Average_spherical_density_grid;
43   else if(caseless_eq(label, "LINE_DENSITY"))
44     avg=new Average_line_density;
45   else if(caseless_eq(label, "TBDM_BASIS"))
46     avg=new Average_tbdm_basis;
47   else if(caseless_eq(label,"REGION_FLUCTUATION"))
48     avg=new Average_region_fluctuation;
49   else if(caseless_eq(label,"REGION_DENSITY_MATRIX"))
50     avg=new Average_region_density_matrix;
51   else if(caseless_eq(label,"WF_PARMDERIV"))
52     avg=new Average_wf_parmderivs;
53   else if(caseless_eq(label,"ENMOMENT"))
54     avg=new Average_enmoment;
55   else if(caseless_eq(label,"FOURIER_DENSITY"))
56     avg=new Average_fourier_density;
57   else if(caseless_eq(label,"AVERAGE_DERIVATIVE_DM"))
58     avg=new Average_derivative_dm;
59   else if(caseless_eq(label,"QUADRUPOLE"))
60     avg=new Average_quadrupole;
61   else if(caseless_eq(label,"PSP_SO"))
62     avg=new Average_so;
63   else
64     error("Didn't understand ", label, " in Average_generator.");
65 
66   return 1;
67 }
68 
69 
70 //-----------------------------------------------------------------------------
71 
72 
allocate(vector<string> & words,System * sys,Wavefunction_data * wfdata,Average_generator * & avg)73 int allocate(vector<string> & words, System * sys, Wavefunction_data * wfdata, Average_generator * & avg) {
74   decide_averager(words[0], avg);
75   avg->read(sys, wfdata, words);
76   return 1;
77 }
78 //-----------------------------------------------------------------------------
79 
80 
allocate(vector<string> & words,Average_generator * & avg)81 int allocate(vector<string> & words, Average_generator * & avg) {
82   decide_averager(words[0], avg);
83   avg->read(words);
84   return 1;
85 }
86 //############################################################################
87 //Average_dipole
88 
89 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)90 void Average_dipole::read(System * sys, Wavefunction_data * wfdata, vector <string> & words) {
91 }
92 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)93 void Average_dipole::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
94                               System * sys, Sample_point * sample, Average_return & avg ) {
95   avg.type="dipole";
96   int ndim=3;
97   avg.vals.Resize(ndim);
98   avg.vals=0.0;
99   int nelectrons=sample->electronSize();
100   Array1 <doublevar> pos(ndim);
101   for(int e=0; e< nelectrons; e++) {
102     sample->getElectronPos(e,pos);
103     for(int d=0; d< ndim; d++) {
104       avg.vals(d)-=pos(d);
105     }
106   }
107   int nions=sample->ionSize();
108   for(int at=0; at < nions; at++) {
109     sample->getIonPos(at,pos);
110     doublevar charge=sample->getIonCharge(at);
111     for(int d=0; d< ndim; d++) {
112       avg.vals(d)+=charge*pos(d);
113     }
114   }
115 }
116 
write_init(string & indent,ostream & os)117 void Average_dipole::write_init(string & indent, ostream & os) {
118   os << indent << "dipole \n";
119 }
120 
read(vector<string> & words)121 void Average_dipole::read(vector <string> & words) {
122 
123 }
124 
write_summary(Average_return & avg,Average_return & err,ostream & os)125 void Average_dipole::write_summary(Average_return & avg, Average_return & err, ostream & os) {
126   int ndim=avg.vals.GetDim(0);
127   assert(ndim <= err.vals.GetDim(0));
128   //Could put this in Debye if we want to be nice.
129   os << "Dipole moment (a.u.) \n";
130   for(int d=0; d< ndim; d++) {
131     if(d==0) os << "x ";
132     else if(d==1) os << "y ";
133     else if(d==2) os << "z ";
134     os << avg.vals(d) << " +/- " << err.vals(d) << endl;
135   }
136 
137 }
138 //############################################################################
139 
140 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)141 void Average_structure_factor::read(System * sys, Wavefunction_data * wfdata, vector <string> & words) {
142   unsigned int pos=0;
143   int np_side;
144   if(!readvalue(words, pos=0, np_side, "NGRID"))
145     np_side=5;
146 
147   Array2 <doublevar> gvec;
148   vector <string> gvec_sec;
149   if(readsection(words, pos=0, gvec_sec, "GVEC")) {
150     int count=0;
151     gvec.Resize(3,3);
152     for(int i=0; i< 3; i++) {
153       for(int j=0; j< 3; j++) {
154         gvec(i,j)=atof(gvec_sec[count++].c_str());
155       }
156     }
157   }
158   else {
159     if(!sys->getRecipLattice(gvec))
160       error("You don't have a periodic cell and you haven't specified GVEC for S(k)");
161   }
162 
163   int direction;
164   if(readvalue(words, pos=0, direction, "DIRECTION")) {
165     npoints=np_side;
166     kpts.Resize(npoints, 3);
167     kpts=0;
168     for(int ix=0; ix < np_side; ix++) {
169       for(int i=0; i< 3; i++)
170         kpts(ix,i)=2*pi*gvec(direction,i)*ix;
171     }
172   }
173   else {
174     npoints=np_side*np_side*np_side;
175 
176     kpts.Resize(npoints, 3);
177     kpts=0;
178     int c=0;
179     for(int ix=0; ix < np_side; ix++) {
180       for(int iy=0; iy < np_side; iy++) {
181         for(int iz=0; iz < np_side; iz++) {
182           for(int i=0; i< 3; i++)
183             kpts(c,i)+=2*pi*(gvec(0,i)*ix+gvec(1,i)*iy+gvec(2,i)*iz);
184           c++;
185         }
186       }
187     }
188   }
189 }
190 
191 //-----------------------------------------------------------------------------
192 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)193 void Average_structure_factor::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
194                                         System * sys, Sample_point * sample, Average_return & avg) {
195   avg.type="sk";
196   int nelectrons=sample->electronSize();
197 
198   Array1 <doublevar> pos(3);
199   avg.vals.Resize(npoints);
200   avg.vals=0;
201   for(int p=0; p < npoints; p++) {
202     doublevar sum_cos=0, sum_sin=0;
203 
204     for(int e=0; e< nelectrons; e++) {
205       sample->getElectronPos(e,pos);
206       doublevar dot=0;
207       for(int d=0; d< 3; d++) dot+=pos(d)*kpts(p,d);
208       sum_cos+=cos(dot);
209       sum_sin+=sin(dot);
210     }
211     avg.vals(p)+=(sum_cos*sum_cos+sum_sin*sum_sin)/nelectrons;
212 
213   }
214 
215 }
216 
217 //-----------------------------------------------------------------------------
218 
write_init(string & indent,ostream & os)219 void Average_structure_factor::write_init(string & indent, ostream & os) {
220   os << indent << "sk\n";
221   for(int i=0; i< npoints; i++) {
222     os << indent << "kpoint { " << kpts(i,0) << " " << kpts(i,1) << " "
223     << kpts(i,2) << " } " <<endl;
224   }
225 }
226 //-----------------------------------------------------------------------------
227 
read(vector<string> & words)228 void Average_structure_factor::read(vector <string> & words) {
229   vector <vector <string> > kpttext;
230   vector <string> tmp;
231   unsigned int pos=0;
232   while(readsection(words, pos, tmp, "KPOINT")) kpttext.push_back(tmp);
233   npoints=kpttext.size();
234   kpts.Resize(npoints,3);
235   for(int i=0; i< npoints; i++) {
236     for(int d=0; d< 3; d++) {
237       kpts(i,d)=atof(kpttext[i][d].c_str());
238     }
239   }
240 }
241 //-----------------------------------------------------------------------------
242 
write_summary(Average_return & avg,Average_return & err,ostream & os)243 void Average_structure_factor::write_summary(Average_return & avg, Average_return & err, ostream & os) {
244   os << "Structure factor \n";
245   os << "    k  s(k) s(k)err  kx  ky  kz" << endl;
246   assert(avg.vals.GetDim(0) >=npoints);
247   assert(err.vals.GetDim(0) >=npoints);
248 
249   for(int i=0; i< npoints; i++) {
250     doublevar sk=avg.vals(i);
251     doublevar skerr=err.vals(i);
252     doublevar r=0;
253     for(int d=0; d< 3; d++) r+=kpts(i,d)*kpts(i,d);
254     r=sqrt(r);
255     os << "sk_out " <<  r << "   " << sk << "   " << skerr
256       << "  " << kpts(i,0) << "   " << kpts(i,1) << "   " << kpts(i,2) << endl;
257   }
258 
259 }
260 
261 //--------------------------------------------------------------------------------
jsonOutput(Average_return & avg,Average_return & err,ostream & os)262 void Average_structure_factor::jsonOutput(Average_return & avg, Average_return & err, ostream & os) {
263 
264   assert(avg.vals.GetDim(0) >=npoints);
265   assert(err.vals.GetDim(0) >=npoints);
266 
267   os << "\"" << avg.type << "\":{" << endl;
268   os << "\"k\":[" << endl;
269   for(int i=0; i< npoints; i++) {
270     doublevar r=0;
271     for(int d=0; d< 3; d++) r+=kpts(i,d)*kpts(i,d);
272     r=sqrt(r);
273     os << r;
274     if(i<npoints-1) os << ",";
275   }
276   os << endl;
277   os << "]," << endl;
278 
279   os << "\"value\":[" << endl;
280   for(int i=0; i< npoints; i++) {
281     doublevar sk=avg.vals(i);
282     os << sk;
283     if( i<npoints-1) os << ",";
284   }
285   os << endl;
286   os << "]," << endl;
287 
288   os << "\"error\":[" << endl;
289   for(int i=0; i< npoints; i++) {
290     doublevar skerr=err.vals(i);
291     os << skerr;
292     if(i< npoints-1) os << ",";
293   }
294   os << endl;
295   os << "]," << endl;
296 
297   os << "\"kx\":[" << endl;
298   for(int i=0; i< npoints; i++) {
299     os << kpts(i,0);
300     if(i< npoints-1) os << ",";
301   }
302   os << endl;
303   os << "]," << endl;
304 
305   os << "\"ky\":[" << endl;
306   for(int i=0; i< npoints; i++) {
307     os << kpts(i,1);
308     if(i< npoints-1) os << ",";
309   }
310   os << endl;
311   os << "]," << endl;
312 
313   os << "\"kz\":[" << endl;
314   for(int i=0; i< npoints; i++) {
315     os << kpts(i,2);
316     if(i< npoints-1) os << ",";
317   }
318   os << endl;
319   os << "]" << endl;
320 
321   os << "}" << endl;
322 }
323 
324 //############################################################################
325 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)326 void Average_fourier_density::read(System * sys, Wavefunction_data * wfdata, vector <string> & words) {
327   unsigned int pos=0;
328   int np_side;
329   if(!readvalue(words, pos=0, np_side, "NGRID"))
330     np_side=5;
331 
332   Array2 <doublevar> gvec;
333   vector <string> gvec_sec;
334   if(readsection(words, pos=0, gvec_sec, "GVEC")) {
335     int count=0;
336     gvec.Resize(3,3);
337     for(int i=0; i< 3; i++) {
338       for(int j=0; j< 3; j++) {
339         gvec(i,j)=atof(gvec_sec[count++].c_str());
340       }
341     }
342   }
343   else {
344     if(!sys->getRecipLattice(gvec))
345       error("You don't have a periodic cell and you haven't specified GVEC for Fourier_density");
346   }
347 
348   npoints=np_side*np_side*np_side;
349   kpts.Resize(npoints, 3);
350   kpts=0;
351   int c=0;
352   for(int ix=0; ix < np_side; ix++) {
353     for(int iy=0; iy < np_side; iy++) {
354       for(int iz=0; iz < np_side; iz++) {
355         for(int i=0; i< 3; i++)
356           kpts(c,i)+=2*pi*(gvec(0,i)*ix+gvec(1,i)*iy+gvec(2,i)*iz);
357         c++;
358       }
359     }
360   }
361 }
362 
363 //-----------------------------------------------------------------------------
364 
write_init(string & indent,ostream & os)365 void Average_fourier_density::write_init(string & indent, ostream & os) {
366   os << indent << "fourier_density\n";
367   for(int i=0; i< npoints; i++) {
368     os << indent << "kpoint { " << kpts(i,0) << " " << kpts(i,1) << " "
369     << kpts(i,2) << " } " <<endl;
370   }
371 }
372 //-----------------------------------------------------------------------------
373 
read(vector<string> & words)374 void Average_fourier_density::read(vector <string> & words) {
375   vector <vector <string> > kpttext;
376   vector <string> tmp;
377   unsigned int pos=0;
378   while(readsection(words, pos, tmp, "KPOINT")) kpttext.push_back(tmp);
379   npoints=kpttext.size();
380   kpts.Resize(npoints,3);
381   for(int i=0; i< npoints; i++) {
382     for(int d=0; d< 3; d++) {
383       kpts(i,d)=atof(kpttext[i][d].c_str());
384     }
385   }
386 }
387 //-----------------------------------------------------------------------------
388 
389 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)390 void Average_fourier_density::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
391                                         System * sys, Sample_point * sample, Average_return & avg) {
392   avg.type="fourier_density";
393   int nelectrons=sample->electronSize();
394   int start[2],end[2],ne[2];
395   ne[0]=sys->nelectrons(0);
396   ne[1]=sys->nelectrons(1);
397   start[0]=0; start[1]=ne[0];
398   end[0]=ne[0]; end[1]=ne[0]+ne[1];
399   int nspin=2;
400   int stride=10;
401   Array1 <doublevar> pos(3),pos2(3);
402   avg.vals.Resize(stride*npoints); //(upcos,upsin,downcos,downsin,upupcos,upupsin)
403   avg.vals=0;
404 
405   for(int p=0; p < npoints; p++) {
406     //----------Here we do the total density
407     for(int s=0; s<nspin; s++) {
408       doublevar sum_cos=0, sum_sin=0;
409       for(int e=start[s]; e< end[s]; e++) {
410         sample->getElectronPos(e,pos);
411         doublevar dot=0;
412         for(int d=0; d< 3; d++) dot+=pos(d)*kpts(p,d);
413         sum_cos+=cos(dot);
414         sum_sin+=sin(dot);
415       }
416       avg.vals(stride*p+s*2)+=sum_cos/ne[s];
417       avg.vals(stride*p+s*2+1)+=sum_sin/ne[s];
418     }
419     //------And here we do the pair density
420 
421     for(int s1=0; s1 < nspin; s1++) {
422       for(int e1=start[s1]; e1 < end[s1]; e1++) {
423         sample->getElectronPos(e1,pos);
424         for(int s2=0; s2 < nspin; s2++) {
425           doublevar sum_cos=0, sum_sin=0;
426           for(int e2=start[s2]; e2 < end[s2]; e2++) {
427             sample->getElectronPos(e2,pos2);
428             doublevar dot=0;
429             for(int d=0; d< 3; d++) dot+=kpts(p,d)*(pos2(d)-pos(d));
430             sum_cos+=cos(dot);
431             sum_sin+=sin(dot);
432           }
433           int offset=stride*p+nspin*2+2*(s1+s2);
434           avg.vals(offset)+=sum_cos/ne[s2];
435           avg.vals(offset+1)+=sum_sin/ne[s2];
436         }
437       }
438     }
439   }
440 
441 
442 }
443 
write_summary(Average_return & avg,Average_return & err,ostream & os)444 void Average_fourier_density::write_summary(Average_return & avg, Average_return & err, ostream & os) {
445   //To get an output in table form, do
446   //gosling log  | grep fourier_out | awk '{$1=""; print $0}'
447   int stride=avg.vals.GetDim(0)/npoints;
448   os << "fourier_out kx ky kz upcos upcoserr upsin upsinerr downcos downcoserr downsin downsinerr uucos uucoserr uusin uusinerr udcos udcoserr udsin udsinerr  ddcos ddcoserr ddsin ddsinerr \n";
449   for(int p=0; p < npoints; p++) {
450      os << "fourier_out ";
451      for(int d=0; d< 3; d++) os << " " << kpts(p,d);
452      for(int i=0; i< stride; i++)
453        os << " " << avg.vals(stride*p+i) << " " << err.vals(stride*p+i);
454      os << endl;
455   }
456 
457 }
458 
459 //############################################################################
460 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)461 void Average_twobody_correlation::read(System * sys, Wavefunction_data * wfdata,
462                                        vector <string> & words) {
463   doublevar range;
464   unsigned int pos=0;
465   if(!readvalue(words,pos=0,resolution, "RESOLUTION"))
466     resolution=0.1;
467   if(!readvalue(words,pos=0,range,"RANGE"))
468     range=10.0;
469   if(readvalue(words, pos=0, direction, "DIRECTION")) {
470     direction+=2;
471   }
472   else
473     direction=0;
474 
475   npoints=int(range/resolution)+1;
476 
477 }
478 
479 //-----------------------------------------------------------------------------
480 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)481 void Average_twobody_correlation::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
482                                         System * sys, Sample_point * sample, Average_return & avg) {
483   avg.type="gr";
484   int nelectrons=sample->electronSize();
485   avg.vals.Resize(2*npoints); //for like and unlike
486   avg.vals=0;
487   int nup=sys->nelectrons(0);
488   sample->updateEEDist();
489   Array1 <doublevar> dist(5);
490   for(int e=0; e< nup; e++) {
491     for(int e2=e+1; e2 < nup; e2++) {
492       sample->getEEDist(e,e2,dist);
493       int place=int(fabs(dist(direction))/resolution);
494       if(place < npoints) {
495         avg.vals(place)+=1;
496       }
497     }
498     for(int e2=nup; e2 < nelectrons; e2++) {
499       sample->getEEDist(e,e2,dist);
500       int place=int(fabs(dist(direction))/resolution);
501       if(place < npoints) {
502         avg.vals(npoints+place)+=1;
503       }
504     }
505   }
506 
507   for(int e=nup; e < nelectrons; e++) {
508     for(int e2=e+1; e2< nelectrons; e2++) {
509       sample->getEEDist(e,e2,dist);
510       int place=int(fabs(dist(direction))/resolution);
511       if(place < npoints) {
512         avg.vals(place) += 1.0;
513       }
514     }
515   }
516 
517 
518 
519 }
520 
521 //-----------------------------------------------------------------------------
522 
write_init(string & indent,ostream & os)523 void Average_twobody_correlation::write_init(string & indent, ostream & os) {
524   os << indent << "gr\n";
525   os << indent << "npoints " << npoints << endl;
526   os << indent << "resolution " << resolution << endl;
527   os << indent << "direction " << direction << endl;
528 }
529 //-----------------------------------------------------------------------------
530 
read(vector<string> & words)531 void Average_twobody_correlation::read(vector <string> & words) {
532   unsigned int pos=0;
533   readvalue(words, pos=0, resolution, "resolution");
534   readvalue(words, pos=0, npoints, "npoints");
535   readvalue(words, pos=0, direction, "direction");
536 }
537 //-----------------------------------------------------------------------------
538 
write_summary(Average_return & avg,Average_return & err,ostream & os)539 void Average_twobody_correlation::write_summary(Average_return & avg, Average_return & err, ostream & os) {
540   os << "Electron correlation for like and unlike spins\n";
541   os << "    r  g(r) sigma(g(r))   g(r)  sigma(g(r))" << endl;
542   assert(avg.vals.GetDim(0) >=2*npoints);
543   assert(err.vals.GetDim(0) >=2*npoints);
544 
545 
546   for(int i=0; i< npoints; i++) {
547     os << "gr_out " << i*resolution << " " << avg.vals(i) << " " << err.vals(i)
548     << "  " << avg.vals(i+npoints) << "  " << err.vals(i+npoints) << endl;
549   }
550 
551 }
552 //-----------------------------------------------------------------------------
553 
jsonOutput(Average_return & avg,Average_return & err,ostream & os)554 void Average_twobody_correlation::jsonOutput(Average_return & avg,Average_return & err, ostream & os) {
555   assert(avg.vals.GetDim(0) >=2*npoints);
556   assert(err.vals.GetDim(0) >=2*npoints);
557 
558   os << "\"" << avg.type << "\":{" << endl;
559   os << "\"r\":[" << endl;
560   for(int i=0; i< npoints; i++) {
561     os << i*resolution;
562     if(i<npoints-1) os << ",";
563   }
564   os << endl;
565   os << "]," << endl;
566 
567   os << "\"like\":[" << endl;
568   for(int i=0; i< npoints; i++) {
569     os << avg.vals(i);
570     if( i<npoints-1) os << ",";
571   }
572   os << endl;
573   os << "]," << endl;
574 
575   os << "\"unlike\":[" << endl;
576   for(int i=0; i< npoints; i++) {
577     os << avg.vals(i+npoints);
578     if( i<npoints-1) os << ",";
579   }
580   os << endl;
581   os << "]," << endl;
582 
583 
584   os << "\"like_err\":[" << endl;
585   for(int i=0; i< npoints; i++) {
586     os << err.vals(i);
587     if( i<npoints-1) os << ",";
588   }
589   os << endl;
590   os << "]," << endl;
591 
592   os << "\"unlike_err\":[" << endl;
593   for(int i=0; i< npoints; i++) {
594     os << err.vals(i+npoints);
595     if( i<npoints-1) os << ",";
596   }
597   os << endl;
598   os << "]" << endl;
599 
600   os << "}" << endl;
601 
602 }
603 
604 
605 
606 //############################################################################
607 
608 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)609 void Average_manybody_polarization::read(System *sys, Wavefunction_data * wfdata, vector <string> & words) {
610   gvec.Resize(3,3);
611   if(!sys->getRecipLattice(gvec) ) {
612     error("The manybody polarization operator works only for periodic systems!");
613   }
614 }
615 
616 //-----------------------------------------------------------------------------
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)617 void Average_manybody_polarization::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
618                                              System * sys, Sample_point * sample, Average_return & avg) {
619   avg.type="manybody_pol";
620   int nelectrons=sample->electronSize();
621   avg.vals.Resize(6);
622   Array1 <doublevar> sum(3,0.0);
623   Array1 <doublevar> pos(3);
624   for(int e=0; e< nelectrons; e++) {
625     sample->getElectronPos(e,pos);
626     for(int i=0; i< 3; i++) {
627       for(int d=0; d< 3; d++) {
628         sum(i)+=gvec(i,d)*pos(d);
629       }
630     }
631   }
632   for(int i=0; i< 3; i++) {
633     avg.vals(2*i)=cos(2*pi*sum(i));
634     avg.vals(2*i+1)=sin(2*pi*sum(i));
635   }
636 }
637 //-----------------------------------------------------------------------------
638 
write_init(string & indent,ostream & os)639 void Average_manybody_polarization::write_init(string & indent, ostream & os) {
640   os << indent << "manybody_pol" << endl;
641   os << indent << "gvec { ";
642   for(int i=0; i< 3; i++)
643     for(int j=0; j< 3; j++) os << gvec(i,j) << "  ";
644   os << "}\n";
645 }
646 //-----------------------------------------------------------------------------
read(vector<string> & words)647 void Average_manybody_polarization::read(vector <string> & words) {
648   unsigned int pos=0;
649   vector <string> gvec_sec;
650   readsection(words, pos=0, gvec_sec, "gvec");
651   int count=0;
652   gvec.Resize(3,3);
653   for(int i=0; i< 3; i++)
654     for(int j=0; j< 3; j++) gvec(i,j)=atof(gvec_sec[count++].c_str());
655 
656 }
657 //-----------------------------------------------------------------------------
658 
659 
write_summary(Average_return & avg,Average_return & err,ostream & os)660 void Average_manybody_polarization::write_summary(Average_return & avg, Average_return & err, ostream & os) {
661   os << "Manybody polarization operator " << endl;
662   for(int i=0; i< 3; i++) {
663     os << avg.vals(2*i) << " + i " << avg.vals(2*i+1) << " +/- " << err.vals(2*i) << " + i " << err.vals(2*i+1) << endl;
664   }
665 }
666 
667 //--------------------------------------------------------------------------------
jsonOutput(Average_return & avg,Average_return & err,ostream & os)668 void Average_manybody_polarization::jsonOutput(Average_return & avg, Average_return & err, ostream & os) {
669   os << "\"" << avg.type << "\":{" << endl;
670   os <<"\"value\":[";
671   for(int i=0; i< 3; i++) {
672     os << "[" << avg.vals(2*i) << "," << avg.vals(2*i+1) <<"]";
673     if(i<2) os <<",";
674   }
675   os <<"]," << endl;
676 
677   os <<"\"error\":[";
678   for(int i=0; i< 3; i++) {
679     os << "[" << err.vals(2*i) << "," << err.vals(2*i+1) <<"]";
680     if(i<2) os <<",";
681   }
682   os <<"]" << endl;
683   os << "}" << endl;
684 }
685 
686 //############################################################################
687 
688 /*!
689 Auxiliary function returning smallest "height" of the simulation cell
690 in a periodic system. Used in one- and two-body density matrices to get
691 a sensible upper cut-off of distances for which elements of the density
692 matrices are evaluated.
693 */
smallest_height(Array2<doublevar> & latVec)694 doublevar smallest_height(Array2 <doublevar> & latVec) {
695 
696   int ndim=3;
697   Array2 <doublevar> crossProduct(ndim,ndim);
698   crossProduct(0,0)=(latVec(1,1)*latVec(2,2)-latVec(1,2)*latVec(2,1));
699   crossProduct(0,1)=(latVec(1,2)*latVec(2,0)-latVec(1,0)*latVec(2,2));
700   crossProduct(0,2)=(latVec(1,0)*latVec(2,1)-latVec(1,1)*latVec(2,0));
701 
702   crossProduct(1,0)=(latVec(2,1)*latVec(0,2)-latVec(2,2)*latVec(0,1));
703   crossProduct(1,1)=(latVec(2,2)*latVec(0,0)-latVec(2,0)*latVec(0,2));
704   crossProduct(1,2)=(latVec(2,0)*latVec(0,1)-latVec(2,1)*latVec(0,0));
705 
706   crossProduct(2,0)=(latVec(0,1)*latVec(1,2)-latVec(0,2)*latVec(1,1));
707   crossProduct(2,1)=(latVec(0,2)*latVec(1,0)-latVec(0,0)*latVec(1,2));
708   crossProduct(2,2)=(latVec(0,0)*latVec(1,1)-latVec(0,1)*latVec(1,0));
709 
710   doublevar smallestheight=1e99;
711   for(int i=0; i< ndim; i++) {
712     doublevar tempheight=0;
713     doublevar length=0;
714     for(int j=0; j< ndim; j++) {
715       tempheight+=crossProduct(i,j)*latVec(i,j);
716       length+=crossProduct(i,j)*crossProduct(i,j);
717     }
718     tempheight=fabs(tempheight)/sqrt(length);
719     if(tempheight < smallestheight ) smallestheight=tempheight;
720   }
721 
722   return smallestheight;
723 
724 }
725 
726 //-----------------------------------------------------------------------------
727 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)728 void Average_obdm::read(System * sys, Wavefunction_data * wfdata,
729 			vector <string> & words) {
730 
731   single_write(cout, "One-body density matrix will be calculated.\n");
732 
733   unsigned int pos=0;
734   if(!readvalue(words, pos=0, npoints, "NGRID"))
735     npoints=5;
736 
737   // maximum distance for OBDM evaluation
738 
739   pos=0;
740   doublevar cutoff;
741   if(!readvalue(words, pos=0, cutoff, "CUTOFF")) {
742     Array2 <doublevar> latVec(3,3);
743     Array1 <doublevar> origin(3);
744     if(!sys->getBounds(latVec,origin))
745       error("In non-periodic systems, CUTOFF has to be given in the OBDM section.");
746     cutoff=smallest_height(latVec)/2;
747   }
748   dR=cutoff/npoints;
749 
750   // angles and weights for Gaussian quadrature (spherical averaging)
751 
752   pos=0;
753   if(!readvalue(words, pos=0, np_aver, "AIP")) np_aver=1;
754   wt.Resize(np_aver);
755   ptc.Resize(np_aver,3);             //!< cartesian coordinates of int. points
756   Array1 <doublevar> x(np_aver), y(np_aver), z(np_aver);
757 
758   switch (np_aver) {
759   case 1:
760     // no spherical averaging
761     wt=1;
762     ptc(0,0)=1.0;
763     ptc(0,1)=0.0;
764     ptc(0,2)=0.0;
765     break;
766   default:
767     gesqua(np_aver,x,y,z,wt);
768     for (int i=0; i<np_aver; i++) {
769       ptc(i,0)=x(i);
770       ptc(i,1)=y(i);
771       ptc(i,2)=z(i);
772     }
773   }
774 }
775 
776 //-----------------------------------------------------------------------------
777 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)778 void Average_obdm::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
779 			    System * sys, Sample_point * sample,
780 			    Average_return & avg) {
781   avg.type="obdm";
782   avg.vals.Resize(npoints);
783   avg.vals=0;
784 
785   int nwf=wf->nfunc();
786   Wf_return wfval_new(nwf,2);   // this structure I just don't understand
787   Wf_return wfval_old(nwf,2);
788   Storage_container wfStore;
789   Array1 <doublevar> oldpos(3), newpos(3), transl(3);
790 
791   Array1 <doublevar> x(3), y(3), z(3);
792   Array2 <doublevar> pt(np_aver,3);
793   generate_random_rotation(x,y,z);
794   for (int i=0; i<np_aver; i++) {
795     pt(i,0)=ptc(i,0)*x(0)+ptc(i,1)*y(0)+ptc(i,2)*z(0);
796     pt(i,1)=ptc(i,0)*x(1)+ptc(i,1)*y(1)+ptc(i,2)*z(1);
797     pt(i,2)=ptc(i,0)*x(2)+ptc(i,1)*y(2)+ptc(i,2)*z(2);
798   }
799 
800   wf->updateVal(wfdata, sample);
801   wfStore.initialize(sample, wf);
802   wfStore.saveUpdate(sample,wf,0);
803   wf->getVal(wfdata, 0, wfval_old);
804   sample->getElectronPos(0,oldpos);
805 
806   for( int i=0; i<npoints; i++) {
807     for ( int k=0; k<np_aver; k++) {
808       // shift makes sense only up to half the lattice vector, we are hitting
809       // periodicity for larger distances
810       transl(0)=(i+1)*dR*pt(k,0);
811       transl(1)=(i+1)*dR*pt(k,1);
812       transl(2)=(i+1)*dR*pt(k,2);
813       sample->translateElectron(0,transl);
814       // TODO: check k-points /= Gamma
815       wf->updateVal(wfdata, sample);
816       wf->getVal(wfdata, 0, wfval_new);
817       // how to handle the possibility of wf_old=0? Can it happen?
818       avg.vals(i)+=wt(k)*wfval_new.sign(0)*wfval_old.sign(0)
819         *exp(wfval_new.amp(0,0)-wfval_old.amp(0,0));
820       sample->setElectronPos(0,oldpos);
821       wfStore.restoreUpdate(sample,0);
822     }
823   }
824 
825   wfStore.restoreUpdate(sample,wf,0);
826 
827 }
828 
829 //-----------------------------------------------------------------------------
830 
write_init(string & indent,ostream & os)831 void Average_obdm::write_init(string & indent, ostream & os) {
832   os << indent << "obdm" << endl;
833   os << indent << "ngrid " << npoints << endl;
834   os << indent << "cutoff " << dR*npoints << endl;
835   os << indent << "aip " << np_aver << endl;
836 }
837 
838 //-----------------------------------------------------------------------------
839 
read(vector<string> & words)840 void Average_obdm::read(vector <string> & words) {
841   unsigned int pos=0;
842   readvalue(words, pos, npoints, "ngrid");
843   doublevar cutoff;
844   readvalue(words, pos=0, cutoff, "cutoff");
845   dR=cutoff/npoints;
846   readvalue(words, pos=0, np_aver, "aip");
847 }
848 
849 //-----------------------------------------------------------------------------
850 
write_summary(Average_return & avg,Average_return & err,ostream & os)851 void Average_obdm::write_summary(Average_return & avg, Average_return & err,
852 				 ostream & os) {
853   os << "One-body density matrix, spherically averaged with AIP = "
854      << np_aver << endl;
855   os << "    r  rho(r) rho(r)err" << endl;
856   assert(avg.vals.GetDim(0) >=npoints);
857   assert(err.vals.GetDim(0) >=npoints);
858 
859   for(int i=0; i< npoints; i++) {
860     doublevar rho=avg.vals(i);
861     doublevar rhoerr=err.vals(i);
862     doublevar r=(i+1)*dR;
863     os << "obdm_out " <<  r << "   " << rho << "   " << rhoerr << endl;
864   }
865   os << endl;
866 
867 }
868 
869 //############################################################################
870 
871 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)872 void Average_tbdm::read(System * sys, Wavefunction_data * wfdata,
873 			vector <string> & words) {
874 
875   single_write(cout, "Tne-body density matrix will be calculated.\n");
876 
877   nelectrons=sys->nelectrons(0)+sys->nelectrons(1);
878 
879   unsigned int pos=0;
880   if(!readvalue(words, pos=0, npoints, "NGRID"))
881     npoints=5;
882 
883   // maximum distance for TBDM evaluation
884 
885   pos=0;
886   doublevar cutoff;
887   if(!readvalue(words, pos=0, cutoff, "CUTOFF")) {
888     Array2 <doublevar> latVec(3,3);
889     Array1 <doublevar> origin(3);
890     if(!sys->getBounds(latVec,origin))
891       error("In non-periodic systems, CUTOFF has to be given in the TBDM section.");
892     cutoff=smallest_height(latVec)/2;
893   }
894   dR=cutoff/npoints;
895 
896   // angles and weights for Gaussian quadrature (spherical averaging)
897 
898   pos=0;
899   if(!readvalue(words, pos=0, np_aver, "AIP")) np_aver=1;
900   wt.Resize(np_aver);
901   ptc.Resize(np_aver,3);             //!< cartesian coordinates of int. points
902   Array1 <doublevar> x(np_aver), y(np_aver), z(np_aver);
903 
904   switch (np_aver) {
905   case 1:
906     // no spherical averaging
907     wt=1;
908     ptc(0,0)=1.0;
909     ptc(0,1)=0.0;
910     ptc(0,2)=0.0;
911     break;
912   default:
913     gesqua(np_aver,x,y,z,wt);
914     for (int i=0; i<np_aver; i++) {
915       ptc(i,0)=x(i);
916       ptc(i,1)=y(i);
917       ptc(i,2)=z(i);
918     }
919   }
920 }
921 
922 //-----------------------------------------------------------------------------
923 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)924 void Average_tbdm::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
925 			    System * sys, Sample_point * sample,
926 			    Average_return & avg) {
927   avg.type="tbdm";
928   avg.vals.Resize(npoints);
929   avg.vals=0;
930 
931   int nwf=wf->nfunc();
932   Wf_return wfval_new(nwf,2);   // this structure I just don't understand
933   Wf_return wfval_old(nwf,2);
934 
935   Wavefunction_storage * wfStore=NULL;
936   Sample_storage * sampleStorage0=NULL, * sampleStorage1 = NULL;
937 
938   Array1 <doublevar> oldpos(3), newpos(3), transl(3);
939   Array1 <doublevar> oldpos2(3);
940 
941   Array1 <doublevar> x(3), y(3), z(3);
942   Array2 <doublevar> pt(np_aver,3);
943   generate_random_rotation(x,y,z);
944   for (int i=0; i<np_aver; i++) {
945     pt(i,0)=ptc(i,0)*x(0)+ptc(i,1)*y(0)+ptc(i,2)*z(0);
946     pt(i,1)=ptc(i,0)*x(1)+ptc(i,1)*y(1)+ptc(i,2)*z(1);
947     pt(i,2)=ptc(i,0)*x(2)+ptc(i,1)*y(2)+ptc(i,2)*z(2);
948   }
949 
950   wf->updateVal(wfdata, sample);
951 
952   //We need to generate storage capable to store two electron moves
953   wf->generateStorage( wfStore );
954   sample->generateStorage( sampleStorage0 );
955   sample->generateStorage( sampleStorage1 );
956 
957   //The two elecrons to be moved should have opposite spin
958   int e0=0, e1=nelectrons-1;
959   //assert( spin(e0) != spin(e1) );
960 
961   wf->saveUpdate(sample,e0,e1,wfStore);
962   sample->saveUpdate( e0, sampleStorage0 );
963   sample->saveUpdate( e1, sampleStorage1 );
964 
965   wf->getVal(wfdata, e0, wfval_old);
966   sample->getElectronPos(e0,oldpos);
967   sample->getElectronPos(e1,oldpos2);
968 
969   for ( int k=0; k<np_aver; k++) {
970 
971     transl(0)=dR*pt(k,0);
972     transl(1)=dR*pt(k,1);
973     transl(2)=dR*pt(k,2);
974 
975     for( int i=0; i<npoints; i++) {
976 
977       sample->translateElectron(e0,transl);
978       sample->translateElectron(e1,transl);
979       wf->updateVal(wfdata, sample);
980 
981       wf->getVal(wfdata, e1, wfval_new);
982 
983       // how to handle the possibility of wf_old=0? Can it happen?
984       avg.vals(i)+=wt(k)*wfval_new.sign(0)*wfval_old.sign(0)
985 	*exp(wfval_new.amp(0,0)-wfval_old.amp(0,0));
986     }
987 
988     //The samples need to be restore because we're using the
989     //translateElectron function (important for k-points)
990     sample->setElectronPos(e0,oldpos);
991     sample->setElectronPos(e1,oldpos2);
992 
993     sample->restoreUpdate(e1, sampleStorage1 );
994     sample->restoreUpdate(e0, sampleStorage0 );
995     wf->restoreUpdate(sample,e0,e1,wfStore);
996   }
997 
998   if(wfStore != NULL) delete wfStore;
999   if(sampleStorage0 != NULL) delete sampleStorage0;
1000   if(sampleStorage1 != NULL) delete sampleStorage1;
1001 
1002 }
1003 
1004 //-----------------------------------------------------------------------------
1005 
write_init(string & indent,ostream & os)1006 void Average_tbdm::write_init(string & indent, ostream & os) {
1007   os << indent << "tbdm" << endl;
1008   os << indent << "ngrid " << npoints << endl;
1009   os << indent << "cutoff " << dR*npoints << endl;
1010   os << indent << "aip " << np_aver << endl;
1011 }
1012 
1013 //-----------------------------------------------------------------------------
1014 
read(vector<string> & words)1015 void Average_tbdm::read(vector <string> & words) {
1016   unsigned int pos=0;
1017   readvalue(words, pos, npoints, "ngrid");
1018   doublevar cutoff;
1019   readvalue(words, pos=0, cutoff, "cutoff");
1020   dR=cutoff/npoints;
1021   readvalue(words, pos=0, np_aver, "aip");
1022 }
1023 
1024 //-----------------------------------------------------------------------------
1025 
write_summary(Average_return & avg,Average_return & err,ostream & os)1026 void Average_tbdm::write_summary(Average_return & avg, Average_return & err,
1027 				 ostream & os) {
1028   os << "Projected two-body density matrix, spherically averaged with AIP = "
1029      << np_aver << endl;
1030   os << "    r  rho(r) rho(r)err" << endl;
1031   assert(avg.vals.GetDim(0) >=npoints);
1032   assert(err.vals.GetDim(0) >=npoints);
1033 
1034   for(int i=0; i< npoints; i++) {
1035     doublevar rho=avg.vals(i);
1036     doublevar rhoerr=err.vals(i);
1037     doublevar r=(i+1)*dR;
1038     os << "tbdm_out " <<  r << "   " << rho << "   " << rhoerr << endl;
1039   }
1040   os << endl;
1041 
1042 }
1043 
1044 
1045 //############################################################################
1046 
1047 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1048 void Average_local_moments::read(System * sys, Wavefunction_data * wfdata,
1049 				 vector <string> & words) {
1050 
1051   single_write(cout, "Local moments and charges will be calculated.\n");
1052 
1053   nup=sys->nelectrons(0);
1054   nelectrons=nup+sys->nelectrons(1);
1055 
1056   sys->getAtomicLabels(atomnames);
1057   natoms=atomnames.size();
1058   rMT.Resize(natoms+1);
1059   rMT=-1;
1060   for ( int i=0; i < natoms; i++) {
1061     doublevar r;
1062     unsigned int pos;
1063     if(readvalue(words, pos=0, r, atomnames[i].c_str())) rMT(i)=r;
1064   }
1065   single_write(cout,"Muffin-tin radii:\n");
1066   for (int i=0; i < natoms; i++) {
1067     if ( rMT(i) > 0 ) {
1068       single_write(cout,atomnames[i],"  ",rMT(i),"\n");
1069     } else {
1070       rMT(i)=2;
1071       single_write(cout,atomnames[i],"  ",rMT(i)," (default used)\n");
1072     }
1073   }
1074   atomnames.push_back("interst.");
1075 
1076 }
1077 
1078 //-----------------------------------------------------------------------------
1079 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1080 void Average_local_moments::evaluate(Wavefunction_data * wfdata,
1081 				     Wavefunction * wf,
1082 				     System * sys, Sample_point * sample,
1083 				     Average_return & avg) {
1084 
1085   // the content of avg.vals is:
1086   //    0          ... natoms-1   spin moments on atoms
1087   //    natoms                    spin moments in interstitial
1088   //    natoms+1   ... 2*natoms   charges on atoms
1089   //    2*natoms+1                charge in interstitial
1090 
1091   avg.type="lm";
1092   avg.vals.Resize(2*natoms+2);
1093   avg.vals=0;
1094 
1095   Array1 <doublevar> dist(5);
1096   sample->updateEIDist();
1097 
1098   for(int e=0; e<nup; e++) {
1099     bool interstitial=true;
1100     for(int i=0; i<natoms; i++) {
1101       sample->getEIDist(e,i,dist);
1102       // zero element of dist is norm, second is norm^2
1103       if ( dist(0) < rMT(i) ) {
1104 	avg.vals(i)+=1;
1105 	avg.vals(i+natoms+1)+=1;
1106 	interstitial=false;
1107       }
1108     }
1109     if ( interstitial ) {
1110       avg.vals(natoms)+=1;
1111       avg.vals(2*natoms+1)+=1;
1112     }
1113   }
1114 
1115   for(int e=nup; e<nelectrons; e++) {
1116     bool interstitial=true;
1117     for(int i=0; i<natoms; i++) {
1118       sample->getEIDist(e,i,dist);
1119       if ( dist(0) < rMT(i) ) {
1120 	avg.vals(i)-=1;
1121 	avg.vals(i+natoms+1)+=1;
1122 	interstitial=false;
1123       }
1124     }
1125     if ( interstitial ) {
1126       avg.vals(natoms)-=1;
1127       avg.vals(2*natoms+1)+=1;
1128     }
1129   }
1130 
1131 }
1132 
1133 //-----------------------------------------------------------------------------
1134 
write_init(string & indent,ostream & os)1135 void Average_local_moments::write_init(string & indent, ostream & os) {
1136   os << indent << "lm" << endl;
1137   for (int i=0; i<natoms+1; i++) {
1138     os << indent << "atom {"
1139        << " name " << atomnames[i]
1140        << " rMT " << rMT(i) << " }" << endl;
1141   }
1142 }
1143 
1144 //-----------------------------------------------------------------------------
1145 
read(vector<string> & words)1146 void Average_local_moments::read(vector <string> & words) {
1147   vector <string> atom_entry;
1148   vector < vector <string> > atom_entries;
1149   unsigned int pos=0;
1150   while(readsection(words, pos, atom_entry, "atom"))
1151     atom_entries.push_back(atom_entry);
1152   if ( atomnames.size() > 0 ) atomnames.clear();
1153   natoms=atom_entries.size()-1;
1154   rMT.Resize(natoms+1);
1155   for (int i=0; i<natoms+1; i++) {
1156     string atomname;
1157     readvalue(atom_entries[i], pos=0, atomname, "name");
1158     atomnames.push_back(atomname);
1159     readvalue(atom_entries[i], pos=0, rMT(i), "rMT");
1160   }
1161 }
1162 
1163 //-----------------------------------------------------------------------------
1164 
write_summary(Average_return & avg,Average_return & err,ostream & os)1165 void Average_local_moments::write_summary(Average_return & avg,
1166 					  Average_return & err,
1167 					  ostream & os) {
1168   os << "Local spin moments and charges integrated over muffin-tin spheres"
1169      << endl;
1170   os << "       atom name    rMT    moment   moment_err  charge  charge_err"
1171      << endl;
1172   ios::fmtflags saved_flags=os.flags(ios::fixed);
1173   streamsize saved_precision=os.precision(2);
1174 
1175   assert(avg.vals.GetDim(0) >=2*natoms+2);
1176   assert(err.vals.GetDim(0) >=2*natoms+2);
1177 
1178   doublevar totm=0.0;
1179   doublevar totc=0.0;
1180   for(int i=0; i< natoms+1; i++) {
1181     os << "lm_out  " << setw(8) << atomnames[i] << "  " << setw(5);
1182     if ( rMT(i) < 0.0 ) {
1183       os << "    ";
1184     } else {
1185       os << rMT(i);
1186     }
1187     os << setw(10) << avg.vals(i) << setw(10) << err.vals(i) << setw(10)
1188        << avg.vals(i+natoms+1) << setw(10) << err.vals(i+natoms+1) << endl;
1189     totm+=avg.vals(i);
1190     totc+=avg.vals(i+natoms+1);
1191   }
1192   os << "total moment in the cell" << setw(7) << totm << endl;
1193   os << "total charge in the cell" << setw(7) << totc << endl;
1194   os << endl;
1195 
1196   // restore output stream formating to default
1197   os.flags(saved_flags);
1198   os.precision(saved_precision);
1199 
1200 }
1201 
1202 
1203 //############################################################################
1204 //Average_density_moments
1205 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1206 void Average_density_moments::read(System * sys, Wavefunction_data * wfdata, vector <string> & words) {
1207 }
1208 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1209 void Average_density_moments::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1210                               System * sys, Sample_point * sample, Average_return & avg ) {
1211   avg.type="density_moments";
1212   int ndim=3;
1213   avg.vals.Resize(ndim);
1214   avg.vals=0.0;
1215   int nelectrons=sample->electronSize();
1216   Array1 <doublevar> pos(ndim);
1217   for(int e=0; e< nelectrons; e++) {
1218     sample->getElectronPos(e,pos);
1219     doublevar r=sqrt( pos(0)*pos(0) + pos(1)*pos(1) + pos(2)*pos(2) );
1220     doublevar r2=r*r;
1221     doublevar r3=r2*r;
1222     avg.vals(0)+=r;
1223     avg.vals(1)+=r2;
1224     avg.vals(2)+=r3;
1225   }
1226 }
1227 
write_init(string & indent,ostream & os)1228 void Average_density_moments::write_init(string & indent, ostream & os) {
1229   os << indent << "density_moments \n";
1230 }
1231 
read(vector<string> & words)1232 void Average_density_moments::read(vector <string> & words) {
1233 
1234 }
1235 
write_summary(Average_return & avg,Average_return & err,ostream & os)1236 void Average_density_moments::write_summary(Average_return & avg, Average_return & err, ostream & os) {
1237   int ndim=avg.vals.GetDim(0);
1238   assert(ndim <= err.vals.GetDim(0));
1239   //Could put this in Debye if we want to be nice.
1240   os << "Density moments (a.u.) \n";
1241   for(int d=0; d< ndim; d++) {
1242     if(d==0) os << "|r| ";
1243     else if(d==1) os << "|r**2| ";
1244     else if(d==2) os << "|r**3| ";
1245     os << avg.vals(d) << " +/- " << err.vals(d) << endl;
1246   }
1247 }
1248 
1249 //############################################################################
1250 //derivatives of multideterminant/pfaffian wf without jastrow(stored in symvals)
1251 //needed un SH_DMC
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1252 void Average_linear_derivative::read(System * sys, Wavefunction_data * wfdata, vector <string> & words) {
1253   unsigned int pos=0;
1254   if(!readvalue(words, pos=0, tau, "TIMESTEP"))
1255     tau=0.01;
1256   if(haskeyword(words, pos=0, "UNR"))
1257     unr=1;
1258   else
1259     unr=0;
1260 }
1261 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1262 void Average_linear_derivative::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1263                               System * sys, Sample_point * sample, Average_return & avg ) {
1264   Parm_deriv_return derivatives;
1265   int nfunctions=wf->nfunc();
1266   Wf_return vals;
1267   Wf_return symvals;
1268 
1269   vals.Resize(nfunctions,5);
1270   symvals.Resize(nfunctions,2);
1271   avg.type="linear_der";
1272   if(!wfdata->supports(parameter_derivatives))
1273     error("Wavefunction needs to supports analytic parameter derivatives");
1274 
1275   derivatives.need_hessian=0;
1276 
1277   int ndim=wfdata->nparms();
1278   avg.vals.Resize(ndim+1);
1279   avg.vals=0.0;
1280 
1281   if(!unr){
1282     wf->updateVal(wfdata, sample);
1283     wf->getVal(wfdata, 0, vals);
1284   }
1285   else{
1286     wf->updateLap(wfdata, sample);
1287     wf->getLap(wfdata, 0, vals);
1288   }
1289 
1290 
1291   wf->getSymmetricVal(wfdata, 0, symvals);
1292   wf->getParmDeriv(wfdata, sample, derivatives);
1293   //cout <<symvals.amp(0,0)<<"  "<<vals.amp(0,0)<< endl;
1294 
1295   doublevar Jastrow_w2_inverse=exp(-2*symvals.amp(0,0));
1296   doublevar gamma=1.0;
1297   if(unr){
1298     //possibly drift in like UNR sampling
1299     doublevar drift=vals.amp(0,1)*vals.amp(0,1)+vals.amp(0,2)*vals.amp(0,2)+vals.amp(0,3)*vals.amp(0,3);
1300     doublevar teff=tau;
1301     teff*=drift;
1302 
1303     gamma=(-1+sqrt(1+2*teff))/teff;
1304     //if(gamma<0.5)
1305     // cout <<" gamma "<<gamma<<endl;
1306   }
1307   for(int d=0; d< ndim; d++){
1308     //cout <<" derivatives.gradient("<<d<<")= "<<derivatives.gradient(d)<<endl;
1309     avg.vals(d)=Jastrow_w2_inverse*derivatives.gradient(d)*gamma;
1310     //avg.vals(d)=derivatives.gradient(d);
1311   }
1312   avg.vals(ndim)=Jastrow_w2_inverse;
1313 }
1314 
write_init(string & indent,ostream & os)1315 void Average_linear_derivative::write_init(string & indent, ostream & os) {
1316   os << indent << "linear_der\n";
1317   os << indent << "TIMESTEP "<<tau<<"\n";
1318   if(unr)
1319     os << indent << "UNR\n";
1320 }
1321 
read(vector<string> & words)1322 void Average_linear_derivative::read(vector <string> & words) {
1323 
1324 }
1325 
write_summary(Average_return & avg,Average_return & err,ostream & os)1326 void Average_linear_derivative::write_summary(Average_return & avg, Average_return & err, ostream & os) {
1327   int ndim=avg.vals.GetDim(0)-1;
1328   assert(ndim <= err.vals.GetDim(0));
1329   os << "Linear derivatives \n";
1330   for(int d=0; d< ndim; d++) {
1331     os << avg.vals(d)/avg.vals(ndim) << " +/- " << err.vals(d)/avg.vals(ndim) << endl;
1332   }
1333   os <<" normalization "<<avg.vals(ndim)<<" +/- " << err.vals(ndim) << endl;
1334 
1335 }
1336 //############################################################################
1337 
1338 //############################################################################
1339 //derivatives of multideterminant/pfaffian wf without jastrow(stored in symvals)
1340 //needed un SH_DMC only differences
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1341 void Average_linear_delta_derivative::read(System * sys, Wavefunction_data * wfdata, vector <string> & words) {
1342   unsigned int pos=0;
1343   if(!readvalue(words, pos=0, tau, "TIMESTEP"))
1344     tau=0.01;
1345   if(haskeyword(words, pos=0, "UNR"))
1346     unr=1;
1347   else
1348     unr=0;
1349 }
1350 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1351 void Average_linear_delta_derivative::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1352                               System * sys, Sample_point * sample, Average_return & avg ) {
1353   Parm_deriv_return derivatives;
1354   int nfunctions=wf->nfunc();
1355   Wf_return vals;
1356   Wf_return symvals;
1357 
1358   vals.Resize(nfunctions,5);
1359   symvals.Resize(nfunctions,2);
1360 
1361   avg.type="linear_delta_der";
1362   if(!wfdata->supports(parameter_derivatives))
1363     error("Wavefunction needs to supports analytic parameter derivatives");
1364 
1365   derivatives.need_hessian=0;
1366 
1367   int ndim=wfdata->nparms();
1368   avg.vals.Resize(ndim+1);
1369   avg.vals=0.0;
1370 
1371   if(!unr){
1372     wf->updateVal(wfdata, sample);
1373     wf->getVal(wfdata, 0, vals);
1374   }
1375   else{
1376     wf->updateLap(wfdata, sample);
1377     wf->getLap(wfdata, 0, vals);
1378   }
1379 
1380   wf->getSymmetricVal(wfdata, 0, symvals);
1381   wf->getParmDeriv(wfdata, sample, derivatives);
1382   //cout <<symvals.amp(0,0)<<"  "<<vals.amp(0,0)<< endl;
1383 
1384   doublevar Jastrow_w2_inverse=exp(-2*symvals.amp(0,0));
1385   doublevar gamma=1.0;
1386   if(unr){
1387     //possibly drift in like UNR sampling
1388     doublevar drift=vals.amp(0,1)*vals.amp(0,1)+vals.amp(0,2)*vals.amp(0,2)+vals.amp(0,3)*vals.amp(0,3);
1389     doublevar teff=tau;
1390     teff*=drift;
1391 
1392     gamma=(-1+sqrt(1+2*teff))/teff;
1393     //if(gamma<0.5)
1394     // cout <<" gamma "<<gamma<<endl;
1395   }
1396 
1397 
1398   for(int d=0; d< ndim; d++){
1399     //cout <<" derivatives.gradient("<<d<<")= "<<derivatives.gradient(d)<<endl;
1400     avg.vals(d)=Jastrow_w2_inverse*derivatives.gradient(d)*gamma;
1401     //avg.vals(d)=derivatives.gradient(d);
1402   }
1403   avg.vals(ndim)=Jastrow_w2_inverse;
1404 }
1405 
write_init(string & indent,ostream & os)1406 void Average_linear_delta_derivative::write_init(string & indent, ostream & os) {
1407   os << indent << "linear_delta_der\n";
1408   os << indent << "TIMESTEP "<<tau<<"\n";
1409   if(unr)
1410     os << indent << "UNR\n";
1411 }
1412 
read(vector<string> & words)1413 void Average_linear_delta_derivative::read(vector <string> & words) {
1414 
1415 }
1416 
write_summary(Average_return & avg,Average_return & err,ostream & os)1417 void Average_linear_delta_derivative::write_summary(Average_return & avg, Average_return & err, ostream & os) {
1418   int ndim=avg.vals.GetDim(0)-1;
1419   assert(ndim <= err.vals.GetDim(0));
1420   os << "Linear derivatives \n";
1421   for(int d=0; d< ndim; d++) {
1422     os << avg.vals(d)/avg.vals(ndim) << " +/- " << err.vals(d)/avg.vals(ndim) << endl;
1423   }
1424   os <<" normalization "<<avg.vals(ndim)<<" +/- " << err.vals(ndim) << endl;
1425 
1426 }
1427 
1428 //############################################################################
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1429 void Average_spherical_density::read(System * sys, Wavefunction_data * wfdata,
1430 			vector <string> & words) {
1431 
1432   single_write(cout, "Spherically averaged density  will be calculated.\n");
1433 
1434   unsigned int pos=0;
1435   if(!readvalue(words, pos=0, npoints, "NGRID"))
1436     npoints=5;
1437 
1438   pos=0;
1439   //doublevar cutoff;
1440   if(!readvalue(words, pos=0, cutoff, "CUTOFF")) {
1441     Array2 <doublevar> latVec(3,3);
1442     Array1 <doublevar> origin(3);
1443     if(!sys->getBounds(latVec,origin))
1444       error("In non-periodic systems, CUTOFF has to be given in the OBDM section.");
1445     cutoff=smallest_height(latVec)/2;
1446   }
1447   dR=cutoff/npoints;
1448 
1449   nup=sys->nelectrons(0);
1450   ndown=sys->nelectrons(1);
1451 
1452   if(!readvalue(words, pos=0, nfunc, "NFUNC"))
1453     error ("need nfunc in the the Average_spherical_density");
1454 
1455   //vector <string> basistext;
1456 
1457   if(!readsection(words, pos=0, basistext, "BASIS"))
1458      error ("need BASIS in the the Average_spherical_density");
1459 
1460   allocate(basistext, basis);
1461   string indent="  ";
1462   basis->showinfo(indent, cout);
1463   single_write(cout, "Spherically averaged density: done read \n");
1464 
1465 }
1466 
1467 //-----------------------------------------------------------------------------
1468 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1469 void Average_spherical_density::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1470 			    System * sys, Sample_point * sample,
1471 			    Average_return & avg) {
1472 
1473   //single_write(cout, "Spherically averaged density: start evaluate \n");
1474   avg.type="spherical_density";
1475   //avg.vals.Resize(npoints);
1476   avg.vals.Resize(2*nfunc);
1477   avg.vals=0;
1478 
1479   int nwf=wf->nfunc();
1480   Wf_return wfval_new(nwf,2);   // this structure I just don't understand
1481   Wf_return wfval_old(nwf,2);
1482 
1483   //  Storage_container wfStore;
1484   Array1 <doublevar> oldpos(3), newpos(3), transl(3);
1485   Array1 <doublevar> x(3), y(3), z(3);
1486   for(int e=0; e < nup+ndown; e++){
1487     sample->getElectronPos(e,oldpos);
1488     doublevar distance2=oldpos(0)*oldpos(0)+oldpos(1)*oldpos(1)+oldpos(2)*oldpos(2);
1489     doublevar distance=sqrt(distance2);
1490     //for( int i=0; i<npoints; i++) {
1491     //  if(distance > i*dR && distance< (i+1)*dR)
1492     //	avg.vals(i)+= 1/distance2;
1493     //}
1494     Array1 <doublevar> R(5);
1495     R(0)=distance;
1496     Array1 <doublevar> basisvals(nfunc);
1497     int currfunc=0;
1498     basis->calcVal(R, basisvals, currfunc);
1499     for( int i=0; i<nfunc; i++) {
1500       if(e<nup)
1501 	avg.vals(i)+=basisvals(i)/(4.0*pi);
1502       //avg.vals(i)+=distance2*basisvals(i);
1503       else
1504 	avg.vals(i+nfunc)+=basisvals(i)/(4.0*pi);
1505       //avg.vals(i+nfunc)+=distance2*basisvals(i);
1506     }
1507   }
1508 }
1509 
1510 //-----------------------------------------------------------------------------
1511 
write_init(string & indent,ostream & os)1512 void Average_spherical_density::write_init(string & indent, ostream & os) {
1513   os << indent << "spherical_density" << endl;
1514   os << indent << "ngrid " << npoints << endl;
1515   os << indent << "cutoff " << dR*npoints << endl;
1516   os << indent << "nfunc " <<  nfunc << endl;
1517   os << indent << "BASIS { ";
1518   for(unsigned int i=0; i<basistext.size();i++)
1519     os << basistext[i]<<" ";
1520   os <<" } "<<endl;
1521 }
1522 
1523 //-----------------------------------------------------------------------------
1524 
read(vector<string> & words)1525 void Average_spherical_density::read(vector <string> & words) {
1526   unsigned int pos=0;
1527   readvalue(words, pos, npoints, "ngrid");
1528   //doublevar cutoff;
1529   readvalue(words, pos=0, cutoff, "cutoff");
1530   dR=cutoff/npoints;
1531   readvalue(words, pos=0, nfunc, "nfunc");
1532   //vector <string> basistext;
1533   readsection(words, pos=0, basistext, "BASIS");
1534   allocate(basistext, basis);
1535 }
1536 
1537 //-----------------------------------------------------------------------------
1538 
write_summary(Average_return & avg,Average_return & err,ostream & os)1539 void Average_spherical_density::write_summary(Average_return & avg, Average_return & err,
1540 				 ostream & os) {
1541   os << "Spherically averaged density "<< endl;
1542 
1543   /*
1544   assert(avg.vals.GetDim(0) >=npoints);
1545   assert(err.vals.GetDim(0) >=npoints);
1546 
1547   doublevar integral=0.0;
1548   for(int i=0; i< npoints; i++) {
1549     doublevar r=(i+0.5)*dR;
1550     doublevar rho=avg.vals(i);
1551     integral+=rho*r*r*dR;
1552   }
1553   cout <<" integral "<<integral<<" nelectrons "<<nelectrons<<endl;
1554 
1555   for(int i=0; i< npoints; i++) {
1556     avg.vals(i)*=1/integral;
1557     err.vals(i)*=1/integral;
1558     doublevar rho=avg.vals(i);
1559     doublevar rhoerr=err.vals(i);
1560     doublevar r=(i+0.5)*dR;
1561     os << "density_out " <<  r << "   " << rho << "   " << rhoerr << endl;
1562   }
1563 
1564 
1565   doublevar summ1=0;
1566   doublevar summ2=0;
1567   for(int i=0; i< npoints; i++) {
1568     doublevar rho=0.0;
1569     avg.vals(i);
1570 
1571     doublevar r=(i+0.5)*dR;
1572     os << "density_out " <<  r << "   " << rho << "   " << rhoerr << endl;
1573   }
1574   */
1575 
1576 
1577   os.setf(ios::scientific);
1578   os <<"Used basis info :"<<endl;
1579   string indent="  ";
1580   basis->showinfo(indent, os);
1581   os <<"Spin-up and spin-down density in above basis"<<endl;
1582   //doublevar summ1=0;
1583   //doublevar summ2=0;
1584   for(int i=0; i< nfunc; i++) {
1585     os << i+1 <<setw(20)<<setprecision(10)<< avg.vals(i) <<setw(20)<<setprecision(10)<<  err.vals(i);
1586     os <<setw(20)<<setprecision(10)<< avg.vals(i+nfunc) <<setw(20)<<setprecision(10)<<  err.vals(i+nfunc) << endl;
1587   }
1588 
1589 
1590   Array1 <doublevar> R(5);
1591   Array1 <doublevar> basisvals(nfunc);
1592   os << "densities on the grid"<<endl;
1593   os << "r  rho(r) rho(r)err  rho(r) rho(r)err"  << endl;
1594   doublevar  norm1=0.0;
1595   doublevar  norm2=0.0;
1596   //for(int i=0;i<npoints;i++){
1597   //R(0)=(i+0.5)*dR;
1598   R(0)=1.000000000000e-06;
1599   doublevar lastR=0.0;
1600   doublevar rf=100.0;
1601   doublevar ri=1e-6;
1602   int npts=5001;
1603   doublevar ratio=exp(log(rf/ri)/(npts-1)); //1.003690930920;
1604 
1605   while (R(0)<cutoff) {
1606     int currfunc=0;
1607     basis->calcVal(R, basisvals, currfunc);
1608     Array1 <doublevar> sum(6);
1609     sum=0;
1610     Array1 <doublevar> sum_error(6);
1611     sum_error=0;
1612     for(int k=0;k<nfunc;k++){
1613       sum(0)+=basisvals(k)*avg.vals(k);
1614       sum_error(0)+=basisvals(k)*err.vals(k)*basisvals(k)*err.vals(k);
1615       /*
1616       if(abs(avg.vals(k))>2.0*err.vals(k)){
1617 	sum(1)+=basisvals(k)*avg.vals(k);
1618 	sum_error(1)+=basisvals(k)*err.vals(k)*basisvals(k)*err.vals(k);
1619       }
1620       if(abs(avg.vals(k))>4.0*err.vals(k)){
1621 	sum(2)+=basisvals(k)*avg.vals(k);
1622 	sum_error(2)+=basisvals(k)*err.vals(k)*basisvals(k)*err.vals(k);
1623       }
1624       */
1625 
1626       sum(3)+=basisvals(k)*avg.vals(k+nfunc);
1627       sum_error(3)+=basisvals(k)*err.vals(k+nfunc)*basisvals(k)*err.vals(k+nfunc);
1628 
1629       /*
1630       if(abs(avg.vals(k+nfunc))>2.0*err.vals(k+nfunc)){
1631 	sum(4)+=basisvals(k)*avg.vals(k+nfunc);
1632 	sum_error(4)+=basisvals(k)*err.vals(k+nfunc)*basisvals(k)*err.vals(k+nfunc);
1633       }
1634       if(abs(avg.vals(k+nfunc))>4.0*err.vals(k+nfunc)){
1635 	sum(5)+=basisvals(k)*avg.vals(k+nfunc);
1636 	sum_error(5)+=basisvals(k)*err.vals(k+nfunc)*basisvals(k)*err.vals(k+nfunc);
1637       }
1638       */
1639 
1640     }//k
1641 
1642     norm1+=4.0*pi*R(0)*R(0)*sum(0)*(R(0)-lastR);
1643     //norm1+=sum(0)*dR;
1644     norm2+=4.0*pi*R(0)*R(0)*sum(3)*(R(0)-lastR);
1645     //norm2+=sum(3)*dR;
1646     os <<R(0)<<setw(20)<<setprecision(10)<<sum(0)<<setw(20)<<setprecision(10)<<sqrt(sum_error(0))
1647       //<<setw(20)<<setprecision(10)<<sum(1)<<setw(20)<<setprecision(10)<<sqrt(sum_error(1))
1648       //<<setw(20)<<setprecision(10)<<sum(2)<<setw(20)<<setprecision(10)<<sqrt(sum_error(2))
1649       <<setw(20)<<setprecision(10)<<sum(3)<<setw(20)<<setprecision(10)<<sqrt(sum_error(3))
1650       //<<setw(20)<<setprecision(10)<<sum(4)<<setw(20)<<setprecision(10)<<sqrt(sum_error(4))
1651       //<<setw(20)<<setprecision(10)<<sum(5)<<setw(20)<<setprecision(10)<<sqrt(sum_error(5))
1652        <<endl;
1653     lastR=R(0);
1654     R(0)*=ratio;
1655 
1656   }//i
1657   os <<"integrated  spin-up density "<<norm1<<" and spin-up density "<<norm2<<endl;
1658   os << endl;
1659   os.unsetf(ios::scientific);
1660   os<<setprecision(6);
1661 }
1662 
1663 
1664 
1665 
1666 
1667 
1668 
1669 //-----------------------------------------------------------------------------
1670 
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1671 void Average_spherical_density_grid::read(System * sys, Wavefunction_data * wfdata,
1672 			vector <string> & words) {
1673 
1674   single_write(cout, "Spherically averaged density  on the grid will be calculated.\n");
1675 
1676   unsigned int pos=0;
1677   if(!readvalue(words, pos=0, npoints, "NGRID"))
1678     npoints=5;
1679 
1680   pos=0;
1681   doublevar cutoff;
1682   if(!readvalue(words, pos=0, cutoff, "CUTOFF")) {
1683     Array2 <doublevar> latVec(3,3);
1684     Array1 <doublevar> origin(3);
1685     if(!sys->getBounds(latVec,origin))
1686       error("In non-periodic systems, CUTOFF has to be given in the OBDM section.");
1687     cutoff=smallest_height(latVec)/2;
1688   }
1689   dR=cutoff/npoints;
1690 
1691   nup=sys->nelectrons(0);
1692   ndown=sys->nelectrons(1);
1693 }
1694 
1695 //-----------------------------------------------------------------------------
1696 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1697 void Average_spherical_density_grid::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1698 			    System * sys, Sample_point * sample,
1699 			    Average_return & avg) {
1700 
1701   //single_write(cout, "Spherically averaged density on grid : start evaluate \n");
1702   avg.type="spherical_density_grid";
1703   avg.vals.Resize(2*npoints);
1704   avg.vals=0;
1705 
1706   //  Storage_container wfStore;
1707   Array1 <doublevar> oldpos(3), newpos(3), transl(3);
1708   Array1 <doublevar> x(3), y(3), z(3);
1709   for(int e=0; e < nup+ndown; e++){
1710     sample->getElectronPos(e,oldpos);
1711     doublevar distance2=oldpos(0)*oldpos(0)+oldpos(1)*oldpos(1)+oldpos(2)*oldpos(2);
1712     doublevar distance=sqrt(distance2);
1713     if(distance2 < 1.0e-6){
1714       cout <<"electron # "<<e+1<< "very close to origin: R= "<<distance<<endl;
1715     }
1716     for( int i=0; i<npoints; i++) {
1717       if(distance > i*dR && distance< (i+1)*dR){
1718 	//doublevar r=(i+0.5)*dR;
1719 	if(e<nup){
1720 	  // if(i==0){
1721 	  //  cout <<"electron # "<<e+1<< "very close to origin: R= "<<distance<<" value "<<1.0/(distance2*4.0*pi*dR)<<endl;
1722 	  //  if(distance > 0.5*dR)
1723 	  //    avg.vals(i)+= 1.0/(distance2*4.0*pi*dR*0.5);
1724 	  // }
1725 	  //else{
1726 	  //avg.vals(i)+= 1.0/(distance2*4.0*pi*dR);
1727 	  avg.vals(i)+= 1.0/(4.0*pi*dR);
1728 
1729 	  //}
1730 	}
1731 	else{
1732 	  //if(i==0){
1733 	  // cout <<"electron # "<<e+1<< "very close to origin: R= "<<distance<<" value "<<1.0/(distance2*4.0*pi*dR)<<endl;
1734 	  //  if(distance > 0.5*dR)
1735 	  //    avg.vals(i+npoints)+= 1.0/(distance2*4.0*pi*dR*0.5);
1736 	  //}
1737 	  //else{
1738 	  //avg.vals(i+npoints)+= 1.0/(distance2*4.0*pi*dR);
1739 	  avg.vals(i+npoints)+= 1.0/(4.0*pi*dR);
1740 	    //}
1741 	}
1742       }
1743     }
1744   }
1745 
1746   // for( int i=0; i<npoints; i++)
1747   //  cout <<avg.vals(i)<<" "<<avg.vals(i+npoints)<<endl;
1748 
1749 
1750 }
1751 
1752 //-----------------------------------------------------------------------------
1753 
write_init(string & indent,ostream & os)1754 void Average_spherical_density_grid::write_init(string & indent, ostream & os) {
1755   os << indent << "spherical_density_grid" << endl;
1756   os << indent << "ngrid " << npoints << endl;
1757   os << indent << "cutoff " << dR*npoints << endl;
1758   os << indent << "nup " << nup << endl;
1759   os << indent << "ndown " << ndown << endl;
1760 }
1761 
1762 //-----------------------------------------------------------------------------
1763 
read(vector<string> & words)1764 void Average_spherical_density_grid::read(vector <string> & words) {
1765   unsigned int pos=0;
1766   readvalue(words, pos, npoints, "ngrid");
1767   doublevar cutoff;
1768   readvalue(words, pos=0, cutoff, "cutoff");
1769   dR=cutoff/npoints;
1770   readvalue(words, pos=0, nup, "nup");
1771   readvalue(words, pos=0, ndown, "ndown");
1772 }
1773 
1774 //-----------------------------------------------------------------------------
1775 
write_summary(Average_return & avg,Average_return & err,ostream & os)1776 void Average_spherical_density_grid::write_summary(Average_return & avg, Average_return & err,
1777 				 ostream & os) {
1778   os << "Spherically averaged density on grid"<< endl;
1779 
1780 
1781   assert(avg.vals.GetDim(0) >=2*npoints);
1782   assert(err.vals.GetDim(0) >=2*npoints);
1783 
1784   doublevar integral1=0.0;
1785   doublevar integral2=0.0;
1786   doublevar alpha=10.0/(npoints*dR*npoints*dR);
1787   doublevar check_intg=0.0;
1788   doublevar C=sqrt(pi)/(4.0*pow(alpha,1.5));
1789 
1790   for(int i=0; i< npoints; i++) {
1791     doublevar r=(i+0.5)*dR;
1792     doublevar rho1=avg.vals(i);
1793     doublevar rho2=avg.vals(i+npoints);
1794     //integral1+=4*pi*rho1*r*r*dR;
1795     integral1+=4*pi*rho1*dR;
1796     //integral2+=4*pi*rho2*r*r*dR;
1797     integral2+=4*pi*rho2*dR;
1798     check_intg+=dR*r*r*exp(-alpha*r*r)/C;
1799 
1800   }
1801   //os.setf(ios::scientific);
1802 
1803   //os <<" alpha "<<alpha<<" C "<<C<<" integration error "<<setw(20)<<abs(1.0-check_intg)<<endl;
1804   os <<"spin-up integtated density "<<integral1<<" # electrons "<<nup<<"  spin-down integtated density "<<integral2<<" # electrons "<<ndown
1805      <<" integration error "<<setw(20)<<abs(1.0-check_intg)<<endl;
1806 
1807   os.setf(ios::scientific);
1808   for(int i=0; i< npoints; i++) {
1809     //avg.vals(i)*=nup/integral1;
1810     //err.vals(i)*=nup/integral1;
1811 
1812     //avg.vals(i+npoints)*=ndown/integral2;
1813     //err.vals(i+npoints)*=ndown/integral2;
1814     doublevar r=(i+0.5)*dR; //plot in the middle of the interval
1815     //doublevar r2=r*r;
1816     doublevar rho1=avg.vals(i);
1817     doublevar rhoerr1=err.vals(i);
1818     doublevar rho2=avg.vals(i+npoints);
1819     doublevar rhoerr2=err.vals(i+npoints);
1820 
1821 
1822     os << "density_out " <<setw(20)<<  r<< setw(20)<<"  "<<setw(20)<< rho1 <<"  "<<setw(20)<<rhoerr1<<setw(20)<< rho2 <<"  "<<setw(20)<<rhoerr2<< endl;
1823   }
1824   os.unsetf(ios::scientific);
1825   os<<setprecision(6);
1826 }
1827 
1828 //############################################################################
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)1829 void Average_line_density::read(System * sys, Wavefunction_data * wfdata,
1830                                        vector <string> & words) {
1831   unsigned int pos=0;
1832   doublevar length=10.0;
1833   vec.Resize(3);
1834   origin.Resize(3);
1835   vec=0; vec(2)=1.0;
1836   origin=0;
1837   if(!readvalue(words,pos=0,resolution, "RESOLUTION"))
1838     resolution=0.1;
1839   readvalue(words,pos=0,length,"LENGTH");
1840   vector<string> dirwords;
1841   if(readsection(words, pos=0, dirwords, "DIRECTION")) {
1842     if(dirwords.size()==3) {
1843       for(int i=0; i< 3; i++) {
1844         vec(i)=atof(dirwords[i].c_str());
1845       }
1846     }
1847     else { error("Wrong number of elements in DIRECTION"); }
1848   }
1849   vector <string> originwords;
1850   if(readsection(words,pos=0,originwords, "ORIGIN" )) {
1851     if(originwords.size()!=3) error("Wrong number of elements in ORIGIN");
1852     for(int i=0; i<3; i++) {
1853       origin(i)=atof(originwords[i].c_str());
1854     }
1855   }
1856 
1857   double norm=0;
1858   for(int d=0; d< 3; d++) {
1859     norm+=vec(d);
1860   }
1861   for(int d=0; d< 3; d++) vec(d)/=sqrt(norm);
1862 
1863   npoints=int(length/resolution)+1;
1864 
1865 }
1866 
1867 //-----------------------------------------------------------------------------
1868 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1869 void Average_line_density::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1870                                         System * sys, Sample_point * sample, Average_return & avg) {
1871   avg.type="line_density";
1872   int nelectrons=sample->electronSize();
1873   avg.vals.Resize(2*npoints); //for up and down
1874   avg.vals=0;
1875   int nup=sys->nelectrons(0);
1876   Array1 <doublevar> epos(3);
1877   for(int e=0; e< nelectrons; e++) {
1878     sample->getElectronPos(e,epos);
1879     for(int d=0; d< 3; d++)
1880       epos(d)-=origin(d);
1881     double scalar=0;
1882     for(int d=0; d< 3; d++)
1883       scalar+=epos(d)*vec(d);
1884 
1885     int place=int(fabs(scalar)/resolution);
1886     if(place < npoints && place > 0) {
1887       if(e< nup)
1888         avg.vals(place)+=1;
1889       else
1890         avg.vals(npoints+place)+=1;
1891     }
1892   }
1893 
1894 }
1895 
1896 //-----------------------------------------------------------------------------
1897 
write_init(string & indent,ostream & os)1898 void Average_line_density::write_init(string & indent, ostream & os) {
1899   os << indent << "line_density\n";
1900   os << indent << "npoints " << npoints << endl;
1901   os << indent << "resolution " << resolution << endl;
1902   os << indent << "direction { ";
1903   for(int d=0; d< 3; d++) os << vec(d) << " ";
1904   os << " } " << endl;
1905   os << indent << "origin { ";
1906   for(int d=0; d< 3; d++) os << vec(d) << " ";
1907   os << " } " <<  endl;
1908 }
1909 //-----------------------------------------------------------------------------
1910 
read(vector<string> & words)1911 void Average_line_density::read(vector <string> & words) {
1912   unsigned int pos=0;
1913   readvalue(words, pos=0, resolution, "resolution");
1914   readvalue(words, pos=0, npoints, "npoints");
1915   vector <string> sec;
1916   readsection(words, pos=0,sec, "direction");
1917   vec.Resize(sec.size());
1918   for(unsigned int i=0; i< sec.size(); i++) vec(i)=atof(sec[i].c_str());
1919   sec.clear();
1920   readsection(words,pos=0, sec, "origin");
1921   origin.Resize(sec.size());
1922   for(unsigned int i=0; i< sec.size(); i++) origin(i)=atof(sec[i].c_str());
1923 
1924 }
1925 //-----------------------------------------------------------------------------
1926 
write_summary(Average_return & avg,Average_return & err,ostream & os)1927 void Average_line_density::write_summary(Average_return & avg, Average_return & err, ostream & os) {
1928   os << "Electron Density along a line. \n";
1929   os << "    r  p(r) sigma(p(r))   p(r)  sigma(p(r))" << endl;
1930   assert(avg.vals.GetDim(0) >=2*npoints);
1931   assert(err.vals.GetDim(0) >=2*npoints);
1932 
1933   for(int i=0; i< npoints; i++) {
1934     os << "line_out " << i*resolution << " " << avg.vals(i) << " " << err.vals(i)
1935     << "  " << avg.vals(i+npoints) << "  " << err.vals(i+npoints) << endl;
1936   }
1937 
1938 }
1939 
1940 //######################################################################
1941 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Average_return & avg)1942 void Average_wf_parmderivs::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1943                        System * sys, Sample_point * sample, Average_return & avg) {
1944   error("Must use the properties_point version of evaluate with wf_parmderivs");
1945 }
1946 
1947 
evaluate(Wavefunction_data * wfdata,Wavefunction * wf,System * sys,Sample_point * sample,Properties_point & pt,Average_return & avg)1948 void Average_wf_parmderivs::evaluate(Wavefunction_data * wfdata, Wavefunction * wf,
1949                        System * sys, Sample_point * sample, Properties_point & pt,
1950                        Average_return & avg) {
1951 
1952   Parm_deriv_return deriv;
1953   deriv.need_hessian=0;
1954   int nparms=wfdata->nparms();
1955   avg.type="wf_parmderivs";
1956   if(!wf->getParmDeriv(wfdata, sample,deriv)) {
1957     error("WF needs to support parmderivs for now.");
1958   }
1959   avg.vals.Resize(3*nparms+3*nparms*nparms+1);
1960   avg.vals=0.0;
1961 
1962   for(int i=0; i< nparms; i++) {
1963     avg.vals(i)=deriv.gradient(i)*pt.energy(0);
1964     avg.vals(nparms+i)=deriv.gradient(i);
1965     //cout << "grad " << deriv.gradient(i) << " en " << pt.energy(0) << endl;
1966   }
1967   for(int i=0;i< nparms; i++) {
1968     for(int j=0; j< nparms; j++) {
1969       avg.vals(3*nparms+i*nparms+j)=deriv.gradient(i)*deriv.gradient(j);
1970     }
1971   }
1972   int offset=3*nparms+nparms*nparms;
1973   for(int i=0; i< nparms; i++) {
1974     for(int j=0; j< nparms; j++) {
1975       avg.vals(offset+i*nparms+j)=deriv.gradient(i)*deriv.gradient(j)*pt.energy(0);
1976     }
1977   }
1978   //approximate the derivative of elocal by finite differences
1979   //and assuming that only the kinetic energy changes (this neglects the
1980   //pseudopotential changes for now..)
1981   Array1 <doublevar> el(nparms),kin(1);
1982   Array1 <doublevar> alpha0(nparms),alpha(nparms);
1983   wfdata->getVarParms(alpha0);
1984   doublevar base_kinetic=pt.kinetic(0);
1985   doublevar delta=1e-10;
1986   int nelectrons=sample->electronSize();
1987   for(int i=0; i< nparms; i++) {
1988 //    alpha=alpha0;
1989 //    alpha(i)+=delta;
1990 //    wfdata->setVarParms(alpha);
1991 //    wf->updateLap(wfdata,sample);
1992 //    sys->calcKinetic(wfdata,sample,wf,kin);
1993 //    el(i)=(kin(0)-base_kinetic)/delta;
1994      el(i)=0;
1995      for(int e=0; e< nelectrons; e++) {
1996        el(i)+=-0.5*deriv.gradderiv(i,e,3);
1997      }
1998      //cout << "el " << el(i) << endl;
1999   }
2000   //wfdata->setVarParms(alpha0);
2001 
2002   for(int i=0; i< nparms; i++) {
2003     avg.vals(2*nparms+i)=el(i);
2004   }
2005   offset+=nparms*nparms;
2006   for(int i=0; i< nparms; i++) {
2007     for(int j=0; j< nparms; j++) {
2008       avg.vals(offset+i*nparms+j)=deriv.gradient(i)*el(j);
2009     }
2010   }
2011 
2012   avg.vals(offset+nparms*nparms)=exp(2*pt.wf_val.amp(0,0));
2013 }
2014 //-----------------------------------------------------------------------------
read(System * sys,Wavefunction_data * wfdata,vector<string> & words)2015 void Average_wf_parmderivs::read(System * sys, Wavefunction_data * wfdata, vector
2016                    <string> & words) {
2017 }
2018 //-----------------------------------------------------------------------------
write_init(string & indent,ostream & os)2019 void Average_wf_parmderivs::write_init(string & indent, ostream & os) {
2020   os << indent << "WF_PARMDERIV" << endl;
2021 }
2022 //-----------------------------------------------------------------------------
read(vector<string> & words)2023 void Average_wf_parmderivs::read(vector <string> & words) {
2024 }
2025 //-----------------------------------------------------------------------------
write_summary(Average_return & avg,Average_return & err,ostream & os)2026 void Average_wf_parmderivs::write_summary(Average_return &avg ,Average_return & err, ostream & os) {
2027    os << "Wavefunction parameter derivatives" << endl;
2028 
2029    int n=sqrt(1.0+avg.vals.GetDim(0))-1;
2030 
2031    os << "energy " << endl;
2032    for(int i=0; i < n; i++) {
2033      os << i << " " << avg.vals(i) << " +/- " << err.vals(i)
2034         << " " << avg.vals(n+i) << " +/- " << err.vals(n+i) <<  endl;
2035    }
2036 
2037 }
2038 //-----------------------------------------------------------------------------
2039 
2040 //-----------------------------------------------------------------------------
jsonOutput(Average_return & avg,Average_return & err,ostream & os)2041 void Average_wf_parmderivs::jsonOutput(Average_return &avg ,Average_return & err, ostream & os) {
2042   os << "\"" << avg.type << "\":{" << endl;
2043    int M=avg.vals.GetDim(0);
2044    int n=(sqrt(1.0-4*(1-M)/3.)-1)/2;
2045    os << "\"n\":"<< n<<",\n";
2046 
2047    Array1<doublevar> dpE(n),dpE_err(n),dp(n),dp_err(n),dE(n),dE_err(n);
2048 
2049 
2050    for(int i=0; i < n; i++) {
2051      dpE(i)=avg.vals(i);
2052      dpE_err(i)=err.vals(i);
2053      dp(i)=avg.vals(n+i);
2054      dp_err(i)=err.vals(n+i);
2055      dE(i)=avg.vals(2*n+i);
2056      dE_err(i)=err.vals(2*n+i);
2057    }
2058 
2059 
2060    Array2<doublevar> dpij(n,n),dpij_err(n,n);
2061    Array2<doublevar> dpijE(n,n),dpijE_err(n,n),dpidE(n,n),dpidE_err(n,n);
2062    for(int i=0; i< n; i++) {
2063      for(int j=0; j< n; j++) {
2064        dpij(i,j)=avg.vals(3*n+i*n+j);
2065        dpij_err(i,j)=err.vals(3*n+i*n+j);
2066      }
2067    }
2068    int offset=3*n+n*n;
2069    for(int i=0; i< n; i++) {
2070      for(int j=0; j< n; j++) {
2071        dpijE(i,j)=avg.vals(offset+i*n+j);
2072        dpijE_err(i,j)=err.vals(offset+i*n+j);
2073      }
2074    }
2075    offset+=n*n;
2076    for(int i=0; i< n; i++) {
2077      for(int j=0; j< n; j++) {
2078        dpidE(i,j)=avg.vals(offset+i*n+j);
2079        dpidE_err(i,j)=err.vals(offset+i*n+j);
2080      }
2081    }
2082 
2083 
2084    os << "\"dpE\":";
2085    jsonarray(os,dpE);
2086    os << ",\n";
2087 
2088    os << "\"dpE_err\":";
2089    jsonarray(os,dpE_err);
2090    os << ",\n";
2091 
2092    os << "\"dp\":";
2093    jsonarray(os,dp);
2094    os << ",\n";
2095 
2096    os << "\"dp_err\":";
2097    jsonarray(os,dp_err);
2098    os << ",\n";
2099 
2100 
2101    os << "\"dE\":";
2102    jsonarray(os,dE);
2103    os << ",\n";
2104 
2105    os << "\"dE_err\":";
2106    jsonarray(os,dE_err);
2107    os << ",\n";
2108 
2109 
2110    os << "\"dpij\":";
2111    jsonarray(os,dpij);
2112    os << ",\n";
2113 
2114    os << "\"dpij_err\":";
2115    jsonarray(os,dpij_err);
2116    os << ",\n";
2117 
2118    os << "\"dpijE\":";
2119    jsonarray(os,dpijE);
2120    os << ",\n";
2121 
2122    os << "\"dpijE_err\":";
2123    jsonarray(os,dpijE_err);
2124    os << ",\n";
2125 
2126    os << "\"dpidE\":";
2127    jsonarray(os,dpidE);
2128    os << ",\n";
2129 
2130    os << "\"dpidE_err\":";
2131    jsonarray(os,dpidE_err);
2132    os << "\n";
2133 
2134 
2135    os << "}\n";
2136 
2137 /*
2138   for(int i=0;i< nparms; i++) {
2139     for(int j=0; j< nparms; j++) {
2140       avg.vals(3*nparms+i*nparms+j)=deriv.gradient(i)*deriv.gradient(j);
2141     }
2142   }
2143   int offset=3*nparms+nparms*nparms;
2144   for(int i=0; i< nparms; i++) {
2145     for(int j=0; j< nparms; j++) {
2146       avg.vals(offset+i*nparms+j)=deriv.gradient(i)*deriv.gradient(j)*pt.energy(0);
2147     }
2148   }
2149 
2150   for(int i=0; i< nparms; i++) {
2151     avg.vals(2*nparms+i)=el(i);
2152   }
2153   offset+=nparms*nparms;
2154   for(int i=0; i< nparms; i++) {
2155     for(int j=0; j< nparms; j++) {
2156       avg.vals(offset+i*nparms+j)=deriv.gradient(i)*el(j);
2157     }
2158   }
2159   */
2160 
2161 
2162 }
2163 //-----------------------------------------------------------------------------
2164 
2165 
2166 
2167