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