1 //------------------------------------------------------------------------
2 //src/Backflow_wf_data.cpp
3 
4 #include "Qmc_std.h"
5 #include "qmc_io.h"
6 #include "Backflow_wf_data.h"
7 #include "Wavefunction_data.h"
8 #include "Backflow_wf.h"
9 #include <algorithm>
10 
11 
backflow_config(Sample_point * sample,int e,Array3<doublevar> & corr,Array3<doublevar> & onebody,Array3<doublevar> & threebody_diffspin,Sample_point * temp_samp)12 void backflow_config(Sample_point * sample,
13 		     int e,
14 		     Array3 <doublevar> & corr,
15 		     Array3 <doublevar> & onebody,
16 		     Array3 <doublevar> & threebody_diffspin,
17 		     Sample_point * temp_samp) {
18   //cout << "bfconfig " << endl;
19   int nelectrons=sample->electronSize();
20   Array1 <doublevar> newpos(3);
21   sample->updateEEDist();
22   sample->updateEIDist();
23   sample->getElectronPos(e,newpos);
24 
25   Array1 <doublevar> dist(5);
26   for(int j=0; j< e; j++) {
27     sample->getEEDist(j,e,dist);
28     for(int d=0; d< 3; d++) {
29       newpos(d)+=corr(j,e,0)*dist(d+2);
30     }
31   }
32   for(int k=e+1; k< nelectrons; k++) {
33     sample->getEEDist(e,k,dist);
34     for(int d=0; d< 3; d++) {
35       newpos(d)-=corr(e,k,0)*dist(d+2);
36     }
37   }
38 
39   //cout << "here" << e << endl;
40 
41   int natoms=sample->ionSize();
42   for(int at=0; at< natoms; at++) {
43     sample->getEIDist(e,at,dist);
44     for(int d=0; d< 3; d++) {
45       //start: added for ei back-flow
46       newpos(d)+=(onebody(e,at,0)+threebody_diffspin(e,at,0))*dist(d+2);
47       //end: added for ei back-flow
48     }
49   }
50 
51 
52   //Array1 <doublevar> oldpos(3);
53   //sample->getElectronPos(e,oldpos);
54   //for(int d=0; d< 3; d++) {
55   //  newpos(d)+=onebody(e,0)*oldpos(d);
56   //}
57 
58   temp_samp->setElectronPos(0,newpos);
59 
60 
61 }
62 
63 //start: added for ei back-flow
updateLapjastgroup(Sample_point * sample,int e,Array3<doublevar> & threebody_diffspin)64 void Backflow_wrapper::updateLapjastgroup(Sample_point * sample, int e, Array3 <doublevar> & threebody_diffspin){
65   //cout <<"updateLapjastgroup:start"<<endl;
66   int nelectrons=sample->electronSize();
67   int natoms=sample->ionSize();
68   int eibasis_max=jgroupdata.maxEIBasis();
69   int eebasis_max=jgroupdata.nEEBasis();
70   threebody_diffspin.Resize(nelectrons, natoms, 5);
71   threebody_diffspin=0.0;
72 
73   if(has_electron_ion_bf){
74     Array4 <doublevar> eibasis_save(nelectrons, natoms, eibasis_max ,5);
75     Array3 <doublevar> eebasis(nelectrons, eebasis_max, 5);
76     Array3 <doublevar> eibasis(natoms, eibasis_max ,5);
77     for(int i=0; i< nelectrons; i++) {
78       jgroupdata.updateEIBasis(i,sample,eibasis);
79       for(int at=0; at< natoms; at++) {
80 	for(int j=0; j< eibasis_max; j++) {
81 	  for(int d=0; d< 5; d++) {
82 	    eibasis_save(i,at,j,d)=eibasis(at,j,d);
83 	  }
84 	}
85       }
86     }
87 
88 
89     jgroupdata.updateEEBasis(e,sample,eebasis);
90     jgroupdata.three_body_diffspin.updateLap_E_I(e,eibasis_save,eebasis,threebody_diffspin);
91   }
92   //cout <<"done"<<endl;
93 }
94 
updateValjastgroup(Sample_point * sample,int e,Array3<doublevar> & threebody_diffspin)95 void Backflow_wrapper::updateValjastgroup(Sample_point * sample, int e, Array3 <doublevar> & threebody_diffspin){
96   int nelectrons=sample->electronSize();
97   int natoms=sample->ionSize();
98   int eibasis_max=jgroupdata.maxEIBasis();
99   int eebasis_max=jgroupdata.nEEBasis();
100 
101   threebody_diffspin.Resize(nelectrons, natoms, 5);
102   threebody_diffspin=0.0;
103   if(has_electron_ion_bf){
104     Array4 <doublevar> eibasis_save(nelectrons, natoms, eibasis_max ,5);
105     Array3 <doublevar> eebasis(nelectrons, eebasis_max, 5);
106     Array3 <doublevar> eibasis(natoms, eibasis_max ,5);
107     for(int i=0; i< nelectrons; i++) {
108       jgroupdata.updateEIBasis(i,sample,eibasis);
109       for(int at=0; at< natoms; at++) {
110 	for(int j=0; j< eibasis_max; j++) {
111 	  for(int d=0; d< 5; d++) {
112 	    eibasis_save(i,at,j,d)=eibasis(at,j,d);
113 	  }
114 	}
115       }
116     }
117 
118 
119     jgroupdata.updateEEBasis(e,sample,eebasis);
120     jgroupdata.three_body_diffspin.updateVal_E_I(e,eibasis_save,eebasis,threebody_diffspin);
121   }
122 }
123 //end: added for ei back-flow
124 
125 
updateVal(Sample_point * sample,Jastrow2_wf & jast,int e,int listnum,Array2<doublevar> & newvals)126 void Backflow_wrapper::updateVal(Sample_point * sample,
127 				 Jastrow2_wf & jast,
128 				 int e,
129 				 int listnum,
130 				 Array2 <doublevar> & newvals) {
131 
132   int nelectrons=sample->electronSize();
133   Array3<doublevar> jast_corr;
134   jast.updateVal(&jdata,sample);
135   jast.get_twobody(jast_corr);
136   Array3 <doublevar> onebody;
137   jast.get_onebody(onebody);
138   //start: added for ei back-flow
139   Array3 <doublevar> threebody_diffspin;
140   updateValjastgroup(sample,e,threebody_diffspin);
141   //end: added for ei back-flow
142   backflow_config(sample,e,jast_corr,onebody,threebody_diffspin,temp_samp);
143   temp_samp->updateEIDist();
144   molecorb->updateVal(temp_samp,0,listnum,newvals);
145 }
146 
getNeighbors(Sample_point * sample,Jastrow2_wf & jast,int e,Array1<int> & list,int & nlist)147 void Backflow_wrapper::getNeighbors(Sample_point * sample,
148 				    Jastrow2_wf & jast,
149 				    int e, Array1 <int> & list,
150 				    int & nlist) {
151 
152   //needs to be changed in the future
153   //does not check for neighbors of ei back-flow term: threebody_diffspin.
154   //which in principle is using different ee, ei basis.
155   nlist=0;
156   int nelectrons=sample->electronSize();
157   list.Resize(nelectrons);
158   Array3 <doublevar> jast_corr;
159   jast.updateLap(&jdata,sample);
160   jast.get_twobody(jast_corr);
161   doublevar threshold=1e-10;
162   for(int j=0; j< 3; j++) {
163     if(fabs(jast_corr(j,e,0)) > threshold) {
164       list(nlist++)=j;
165     }
166   }
167   list(nlist++)=e;
168   for(int k=e+1; k< nelectrons; k++) {
169     if(fabs(jast_corr(e,k,0)) > threshold) {
170       list(nlist++)=k;
171     }
172   }
173 }
174 
175 
updateLap(Sample_point * sample,Jastrow2_wf & jast,int e,int listnum,Array2<doublevar> & newvals,Array3<doublevar> & coor_deriv,Array2<doublevar> & coor_laplacian)176 void Backflow_wrapper::updateLap(Sample_point * sample,
177 				 Jastrow2_wf & jast,
178 				 int e,
179 				 int listnum,
180 				 Array2 <doublevar> & newvals,
181 				 //!<(mo,[val,grad,hess])
182 				 Array3 <doublevar>& coor_deriv,
183 				 //!< (i,alpha,beta)
184 				 Array2 <doublevar> & coor_laplacian
185 				 //!< (i,alpha)
186 				 ) {
187 
188   //cout << "Backflow_wrapper: updateLap " << endl;
189   int nelectrons=sample->electronSize();
190   int natoms=sample->ionSize();
191 
192   Array3 <doublevar> jast_corr;
193   jast.updateLap(&jdata,sample);
194   jast.get_twobody(jast_corr);
195   Array3 <doublevar> onebody;
196   jast.get_onebody(onebody);
197   //start: added for ei back-flow
198   Array3 <doublevar> threebody_diffspin;
199   updateLapjastgroup(sample,e,threebody_diffspin);
200   //end: added for ei back-flow
201   backflow_config(sample,e,jast_corr,onebody,threebody_diffspin,temp_samp);
202 
203   //Array1 <doublevar> tmp_pos(3);
204   //cout << "Backflow_wrapper::updateLap"<<endl;
205   //temp_samp->getElectronPos(0,tmp_pos);
206   //cout <<"xyz: "<<tmp_pos(0)<<",  "<<tmp_pos(1)<<",  "<<tmp_pos(2)<<endl;
207 
208   temp_samp->updateEIDist();
209   molecorb->updateHessian(temp_samp,0,listnum,newvals);
210 
211   coor_deriv.Resize(nelectrons,3,3);
212   coor_laplacian.Resize(nelectrons,3);
213   coor_deriv=0;
214   coor_laplacian=0;
215   //self-derivative..
216 
217   for(int d=0; d< 3;d ++)
218     coor_deriv(e,d,d)=1;
219 
220   Array1 <doublevar> dist(5);
221 
222   for(int at=0; at < natoms; at++) {
223     sample->getEIDist(e,at,dist);
224     for(int a=0;a < 3; a++) {
225       for(int b=0; b< 3; b++) {
226 	coor_deriv(e,a,b)+=onebody(e,at,a+1)*dist(b+2);
227       }
228       coor_deriv(e,a,a)+=onebody(e,at,0);
229       coor_laplacian(e,a)+=2.0*onebody(e,at,a+1)
230 	                  +onebody(e,at,4)*dist(a+2);
231     }
232   }
233 
234 
235 
236   for(int k=0; k < e; k++) {
237     sample->getEEDist(k,e,dist);
238     for(int a=0; a< 3; a++) {
239       coor_deriv(e,a,a)-=jast_corr(k,e,0);
240       for(int b=0; b< 3; b++) {
241 	coor_deriv(e,a,b)+=jast_corr(e,k,a+1)*dist(b+2);
242       }
243       coor_laplacian(e,a)+=jast_corr(e,k,4)*dist(a+2)
244 	-2*jast_corr(e,k,a+1);
245     }
246   }
247 
248   for(int k=e+1; k < nelectrons; k++) {
249     sample->getEEDist(e,k,dist);
250     for(int a=0; a< 3; a++) {
251       coor_deriv(e,a,a)-=jast_corr(e,k,0);
252       for(int b=0; b< 3; b++) {
253 	coor_deriv(e,a,b)-=jast_corr(e,k,a+1)*dist(b+2);
254       }
255       coor_laplacian(e,a)-= jast_corr(e,k,4)*dist(a+2)
256 	+2*jast_corr(e,k,a+1);
257     }
258   }
259 
260 
261   //cout << "middle " <<endl;
262   //for(int d=0; d< 3; d++) {
263   //  cout << "lap " << coor_laplacian(e,d) << endl;
264   //}
265 
266   /*
267   cout << "jast corr " << endl;
268   for(int i=0; i< nelectrons; i++) {
269     for(int j=0; j< nelectrons; j++) {
270       cout << jast_corr(i,j,4) << "   ";
271     }
272     cout << endl;
273   }
274   */
275 
276 
277   for(int i=0; i< e; i++) {
278     sample->getEEDist(i,e,dist);
279     for(int a=0; a< 3; a++) {
280       for(int b=0; b< 3; b++) {
281 	coor_deriv(i,a,b)+=jast_corr(i,e,a+1)*dist(b+2);
282       }
283       coor_deriv(i,a,a)+=jast_corr(i,e,0);
284       coor_laplacian(i,a)= jast_corr(i,e,4)*dist(a+2)
285 	+2*jast_corr(i,e,a+1);
286     }
287   }
288   for(int j=e+1; j<nelectrons; j++) {
289     sample->getEEDist(e,j,dist);
290     for(int a=0; a< 3; a++) {
291       for(int b=0; b< 3; b++) {
292 	coor_deriv(j,a,b)-=jast_corr(j,e,a+1)*dist(b+2);
293       }
294       coor_deriv(j,a,a)+=jast_corr(e,j,0);
295       coor_laplacian(j,a)= -jast_corr(j,e,4)*dist(a+2)+2*jast_corr(j,e,a+1);
296     }
297   }
298 
299   //start: added for ei back-flow
300   //extra three body stuff
301   //diagonal contribution
302   for(int at=0; at < natoms; at++) {
303     sample->getEIDist(e,at,dist);
304     for(int a=0;a < 3; a++) {
305       for(int b=0; b< 3; b++) {
306 	coor_deriv(e,a,b)+=threebody_diffspin(e,at,a+1)*dist(b+2);
307       }
308       coor_deriv(e,a,a)+=threebody_diffspin(e,at,0);
309       coor_laplacian(e,a)+=2.0*threebody_diffspin(e,at,a+1)+threebody_diffspin(e,at,4)*dist(a+2);
310     }
311   }
312 
313   //off-diagonal contribution
314   for(int at=0; at < natoms; at++) {
315     sample->getEIDist(e,at,dist);
316     for(int i=0; i< e; i++) {
317       for(int a=0;a < 3; a++) {
318 	for(int b=0; b< 3; b++) {
319 	  coor_deriv(i,a,b)+=threebody_diffspin(i,at,a+1)*dist(b+2);
320 	}
321 	coor_laplacian(i,a)+=threebody_diffspin(i,at,4)*dist(a+2);
322       }
323     }
324     for(int j=e+1; j<nelectrons; j++) {
325       for(int a=0;a < 3; a++) {
326 	for(int b=0; b< 3; b++) {
327 	  coor_deriv(j,a,b)+=threebody_diffspin(j,at,a+1)*dist(b+2);
328 	}
329 	coor_laplacian(j,a)+=threebody_diffspin(j,at,4)*dist(a+2);
330       }
331     }
332   }
333   //end: added for ei back-flow
334 
335 
336   //for(int d=0; d< 3; d++) {
337   //  cout << "lap " << coor_laplacian(e,d) << endl;
338   //}
339   //cout << "done " << endl;
340 
341 }
342 
343 //----------------------------------------------------------------------
344 
readOrbitals(System * sys,vector<string> & words)345 void Backflow_wrapper::readOrbitals(System * sys,
346 			    vector <string> & words) {
347   unsigned int pos=0;
348   vector <string> mowords;
349   if(!readsection(words, pos=0, mowords, "ORBITALS"))
350     error("Need ORBITALS section");
351   allocate(mowords,sys, molecorb);
352 }
353 
354 //----------------------------------------------------------------------
355 
init(System * sys,Array1<Array1<int>> & totoccupation,vector<string> & words)356 void Backflow_wrapper::init(System * sys,
357 			    Array1 <Array1 <int> > & totoccupation,
358 			    vector <string> & words) {
359 
360   //cout <<"Backflow_wrapper::init"<<endl;
361   unsigned int pos=0;
362   //vector <string> mowords;
363   //if(!readsection(words, pos=0, mowords, "ORBITALS"))
364   //  error("Need ORBITALS section");
365   //allocate(mowords,sys, molecorb);
366 
367   molecorb->buildLists(totoccupation);
368   sys->generateSample(temp_samp);
369 
370   vector <string> jwords;
371   if(!readsection(words,pos=0,jwords, "EE_BF"))
372     error("Need EE_BF section");
373   pos=0;
374   jdata.read(jwords,pos,sys);
375   //start: added for ei back-flow
376   vector <string> jgroupwords;
377   if(readsection(words,pos=0,jgroupwords, "EI_BF")){
378     has_electron_ion_bf=1;
379     jgroupdata.set_up(jgroupwords, sys);
380     if(jgroupdata.hasThreeBodySpin()==0)
381       error("EI_BF works only with Three body spin jastrow group!");
382   }
383   else
384     has_electron_ion_bf=0;
385   //end: added for ei back-flow
386   //cout <<"end of: Backflow_wrapper::init"<<endl;
387 }
388 
389 //----------------------------------------------------------------------
390 
showinfo(ostream & os)391 void Backflow_wrapper::showinfo(ostream & os) {
392   os << "Molecular Orbital object : ";
393   molecorb->showinfo(os);
394   os << "\n";
395 
396   os<< "Electron-electron backflow : "<<endl;
397   jdata.showinfo(os);
398   //start: added for ei back-flow
399   if(has_electron_ion_bf){
400     os<< "Electron-ion backflow : "<<endl;
401     string indent="  ";
402     jgroupdata.showinfo(indent,os);
403   }
404   //end: added for ei back-flow
405 }
406 
407 
408 //----------------------------------------------------------------------
409 
writeinput(string & indent,ostream & os)410 void Backflow_wrapper::writeinput(string & indent, ostream & os) {
411   os << indent << "ORBITALS {\n";
412   string indent2=indent+"  ";
413   molecorb->writeinput(indent2, os);
414   os << indent << "}\n";
415 
416   os << indent << "EE_BF { \n";
417   jdata.writeinput(indent2,os);
418   os << indent << "}" << endl;
419   //start: added for ei back-flow
420   if(has_electron_ion_bf){
421     os << indent << "EI_BF { \n";
422     jgroupdata.writeinput(indent2,os);
423     os << indent << "}" << endl;
424   }
425   //end: added for ei back-flow
426 }
427 
428 //######################################################################
429 //----------------------------------------------------------------------
430 //######################################################################
431 
read(vector<string> & words,System * sys)432 void Determinant_keeper::read(vector <string> & words, System * sys) {
433 
434   unsigned int pos=0;
435   optimize_det=haskeyword(words, pos=0, "OPTIMIZE_DET");
436 
437   vector <string> strdetwt;
438   readsection(words, pos=0, strdetwt, "DETWT");
439   ndet=strdetwt.size();
440   detwt.Resize(ndet);
441   for(int det=0; det < ndet; det++)
442     detwt(det)=atof(strdetwt[det].c_str());
443 
444   vector <string>  statevec;
445   if(!readsection(words, pos=0, statevec, "STATES"))
446     error("Need STATES in Backflow wave function");
447 
448 
449   nelectrons.Resize(2);
450   nelectrons(0)=sys->nelectrons(0);
451   nelectrons(1)=sys->nelectrons(1);
452 
453   //pos=startpos;
454   unsigned int canonstates=ndet*(nelectrons(0)+nelectrons(1));
455   if( canonstates != statevec.size())  {
456     error("in STATES section, expecting to find ", canonstates,
457 	  " states(as calculated from NSPIN), but found ",
458 	  statevec.size(), " instead.");
459   }
460 
461 
462   int tote=nelectrons(0)+nelectrons(1);
463 
464   occupation_orig.Resize(ndet, 2);
465   for(int det=0; det < ndet; det++) {
466     for(int s=0; s<2; s++) {
467       occupation_orig(det,s).Resize(nelectrons(s));
468     }
469   }
470 
471   int counter=0;
472   for(int det=0; det<ndet; det++) {
473     for(int s=0; s<2; s++) {
474       for(int e=0; e<nelectrons(s); e++) {
475 	occupation_orig(det,s)(e)=atoi(statevec[counter].c_str())-1;
476 
477 	counter++;
478       }
479     }
480   }
481 
482   //Fill up calculation helpers
483 
484   spin.Resize(tote);
485   opspin.Resize(tote);
486   rede.Resize(tote);
487 
488   int eup=nelectrons(0);
489   for(int e=0; e<eup; e++) {
490     spin(e)=0;
491     opspin(e)=1;
492     rede(e)=e;
493   }
494   for(int e=eup; e<tote; e++) {
495     spin(e)=1;
496     opspin(e)=0;
497     rede(e)=e-eup;
498   }
499 
500 }
501 
502 //----------------------------------------------------------------------
503 
getOccupation(Array1<Array1<int>> & totoccupation,Array2<Array1<int>> & occupation)504 void Determinant_keeper::getOccupation(Array1 <Array1 <int> > & totoccupation,
505 				       Array2 <Array1 <int> > & occupation) {
506   occupation.Resize(ndet, 2);
507 
508   for(int det=0; det < ndet; det++) {
509     for(int s=0; s<2; s++) {
510         //cout << det << " "  << s << endl;
511         occupation(det,s).Resize(nelectrons(s));
512     }
513   }
514 
515 
516 
517 
518 
519   //Find what MO's are necessary for each spin
520 
521   totoccupation.Resize(2);
522   for(int s=0; s<2; s++)  {
523     vector <int> totocctemp;
524     for(int det=0; det<ndet; det++)  {
525       for(int mo=0; mo < nelectrons(s); mo++) {
526 	int place=-1;
527 	int ntot=totocctemp.size();
528 	for(int i=0; i< ntot; i++) {
529 	  if(occupation_orig(det,s)(mo)==totocctemp[i]) {
530 	    place=i;
531 	    break;
532 	  }
533 	}
534 	if(place==-1) { //if we didn't find the MO
535 	  occupation(det,s)(mo)=totocctemp.size();
536 	  totocctemp.push_back(occupation_orig(det,s)(mo));
537 	}
538 	else {
539 	  occupation(det,s)(mo)=place;
540 	}
541       }
542     }
543 
544     //cout << "done assignment " << endl;
545 
546     totoccupation(s).Resize(totocctemp.size());
547     for(int i=0; i<totoccupation(s).GetDim(0); i++)
548     {
549       totoccupation(s)(i) = totocctemp[i];
550       //cout << "total occupation for " << s<< " : "
551       // << totoccupation(s)(i) << endl;
552     }
553   }
554 
555 }
556 
557 
558 //----------------------------------------------------------------------
559 
showinfo(ostream & os)560 void Determinant_keeper::showinfo(ostream & os ) {
561   if(ndet > 1)
562     os << ndet << " Determinants\n";
563   else
564     os << "Determinant" << endl;
565 
566   int nfunc=1;
567   for(int f=0; f< nfunc; f++)
568   {
569     if(nfunc > 1)
570       os << "For function " << f << endl;
571     for(int det=0; det<ndet; det++)
572       {
573 	if(ndet > 1) {
574 	  os << "Determinant " << det << ":\n";
575 	  os << "Weight: " << detwt(det) << endl;
576 	}
577 
578 	os << "State: \n";
579 	for(int s=0; s<2; s++)
580 	  {
581 	    if(s==0)
582 	      os << "spin up:\n";
583 	    if(s==1)
584 	      os << "spin down: \n";
585 
586 	    os << "  ";
587 	    for(int e=0; e<nelectrons(s); e++)
588 	      {
589 		os << occupation_orig(det,s)(e)+1 << " ";
590 		if((e+1)%10 == 0)
591 		  os << endl << "  ";
592 	      }
593 	    os << endl;
594 	  }
595       }
596   }
597 }
598 
599 //----------------------------------------------------------------------
600 
writeinput(string & indent,ostream & os)601 void Determinant_keeper::writeinput(string & indent, ostream & os ) {
602   os << indent << "DETWT { ";
603   for(int det=0; det < ndet; det++) {
604     os << detwt(det) << "  ";
605   }
606   os << "}" << endl;
607 
608   os << indent << "STATES { " << endl << indent <<"  ";
609   for(int det=0; det < ndet; det++) {
610     for(int s=0; s<2; s++) {
611       for(int e=0; e< nelectrons(s); e++) {
612 	os << occupation_orig(det,s)(e)+1 << " ";
613 	if((e+1)%20 ==0)
614 	  os << endl << indent << "  ";
615       }
616       os << endl << indent << "  ";
617     }
618   }
619   os << "}" << endl;
620 
621 }
622 
623 //######################################################################
624 //----------------------------------------------------------------------
625 //######################################################################
626 
627 /*!
628 */
read(vector<string> & words,unsigned int & pos,System * sys)629 void Backflow_wf_data::read(vector <string> & words, unsigned int & pos,
630                         System * sys)
631 {
632   unsigned int startpos=pos;
633   //optimize_backflow=haskeyword(words, pos=startpos,"OPTIMIZE_BACKFLOW");
634   vector <string> detwords;
635   if(!readsection(words, pos=0, detwords,"DETERMINANT"))
636     error("Couldn't find DETERMINANT section");
637   vector <string> bfwords;
638   if(!readsection(words,pos=0, bfwords,"BFLOW"))
639     error("Couldn't find BACKFLOW section");
640 
641   bfwrapper.readOrbitals(sys,bfwords);
642   dkeeper.read(detwords,sys);
643   Array1 <Array1 <int> > totoccupation;
644   dkeeper.getOccupation(totoccupation, occupation);
645   bfwrapper.init(sys, totoccupation, bfwords);
646 
647 }
648 
649 //----------------------------------------------------------------------
650 
supports(wf_support_type support)651 int Backflow_wf_data::supports(wf_support_type support) {
652   switch(support) {
653   case laplacian_update:
654     return 1;
655   case density:
656     return 0;
657   case parameter_derivatives:
658     return 0;
659   default:
660     return 0;
661   }
662 }
663 
664 //----------------------------------------------------------------------
665 
666 
667 
generateWavefunction(Wavefunction * & wf)668 void Backflow_wf_data::generateWavefunction(Wavefunction *& wf)
669 {
670   assert(wf==NULL);
671 
672   wf=new Backflow_wf;
673   Backflow_wf * slatwf;
674   recast(wf, slatwf);
675   slatwf->init(this);
676   attachObserver(slatwf);
677 }
678 
showinfo(ostream & os)679 int Backflow_wf_data::showinfo(ostream & os)
680 {
681   os << "Backflow-Slater" << endl;
682   dkeeper.showinfo(os);
683   bfwrapper.showinfo(os);
684   return 1;
685 }
686 
687 //----------------------------------------------------------------------
688 
writeinput(string & indent,ostream & os)689 int Backflow_wf_data::writeinput(string & indent, ostream & os)
690 {
691 
692 
693   os << indent << "BACKFLOW" << endl;
694   os << indent << "BFLOW { " << endl;
695   string indent2=indent+"  ";
696   bfwrapper.writeinput(indent2,os);
697   os << indent << "}" << endl;
698   os << indent << "DETERMINANT { " << endl;
699   dkeeper.writeinput(indent2,os);
700   os << indent << "}" << endl;
701 
702   return 1;
703 }
704 
705 //------------------------------------------------------------------------
getVarParms(Array1<doublevar> & parms)706 void Backflow_wf_data::getVarParms(Array1 <doublevar> & parms)
707 {
708   //cout <<"start getVarParms"<<endl;
709 
710   /*
711   if(optimize_backflow) {
712     error("need to do parms for backflow");
713   }
714   else if(optimize_det) {
715     parms.Resize(detwt.GetDim(0)-1);
716     for(int i=1; i< detwt.GetDim(0); i++) {
717       parms(i-1)=detwt(i);
718     }
719   }
720   else {
721     parms.Resize(0);
722   }
723   */
724   //error("need to do parameter optimization");
725   //cout <<"done getVarParms"<<endl;
726 
727   parms.Resize(nparms());
728   Array1 <doublevar> parms_tmp1;
729   Array1 <doublevar> parms_tmp2;
730   bfwrapper.jdata.getVarParms(parms_tmp1);
731   //start: added for ei back-flow
732   if(bfwrapper.has_electron_ion_bf){
733     bfwrapper.jgroupdata.getVarParms(parms_tmp2);
734   }
735   //end: added for ei back-flow
736   int sizetotal=bfwrapper.nparms();
737   int sizejdata=bfwrapper.jdata.nparms();
738   parms.Resize(sizetotal);
739   //start: added for ei back-flow
740   for(int i=0;i<sizetotal;i++){
741     if(i<sizejdata)
742       parms(i)=parms_tmp1(i);
743     else
744       parms(i)=parms_tmp2(i-sizejdata);
745   }
746   //end: added for ei back-flow
747   //cout <<"done getVarParms"<<endl;
748 }
749 
setVarParms(Array1<doublevar> & parms)750 void Backflow_wf_data::setVarParms(Array1 <doublevar> & parms)
751 {
752   //cout <<"start setVarParms"<<endl;
753   assert(parms.GetDim(0)==nparms());
754   /*
755   if(optimize_backflow) {
756 
757   }
758   else if(optimize_det) {
759     for(int i=1; i< detwt.GetDim(0); i++) {
760       detwt(i)=parms(i-1);
761     }
762   }
763   else {
764     parms.Resize(0);
765   }
766   */
767   //error("need to do parameter optimization");
768   Array1 <doublevar> parms_tmp1(bfwrapper.jdata.nparms());
769   //start: added for ei back-flow
770   Array1 <doublevar> parms_tmp2(bfwrapper.jgroupdata.nparms());
771   //end: added for ei back-flow
772 
773   int sizetotal=bfwrapper.nparms();
774   int sizejdata=bfwrapper.jdata.nparms();
775   for(int i=0;i<sizetotal;i++){
776     if(i<sizejdata)
777       parms_tmp1(i)=parms(i);
778     else
779       parms_tmp2(i-sizejdata)=parms(i);
780   }
781   bfwrapper.jdata.setVarParms(parms_tmp1);
782   //start: added for ei back-flow
783   if(bfwrapper.has_electron_ion_bf){
784     bfwrapper.jgroupdata.setVarParms(parms_tmp2);
785   }
786   //end: added for ei back-flow
787   int max=wfObserver.size();
788   //cout << "slatmax " << max << endl;
789   for(int i=0; i< max; i++) {
790     wfObserver[i]->notify(all_wf_parms_change, 0);
791   }
792   //cout <<"done setVarParms"<<endl;
793 }
794