//---------------------------------------------------------------------- //Keeping this separate from calcLoc for efficiency reasons.. //It's most likely faster to add to a double than fill matrices.. //We also don't need to calculate the ion-ion interaction for this void Molecular_system::separatedLocal(Sample_point * sample,Array1 <doublevar> & onebody, Array2 <doublevar> & twobody) { int nions=sample->ionSize(); int nelectrons=sample->electronSize(); onebody.Resize(nelectrons); twobody.Resize(nelectrons,nelectrons); onebody=0.0; twobody=0.0; Array1 <doublevar> R(5); sample->updateEIDist(); sample->updateEEDist(); for(int e=0; e< nelectrons; e++) { for(int i=0; i < nions; i++) { sample->getEIDist(e,i, R); onebody(e)-=sample->getIonCharge(i)/R(0); } } Array1 <doublevar> R2(5); for(int i=0; i< nelectrons; i++) { for(int j=i+1; j<nelectrons; j++) { sample->getEEDist(i,j,R2); twobody(i,j)+= 1/R2(0); } } Array1 <doublevar> pos(3); for(int e=0; e< nelectrons; e++) { sample->getElectronPos(e,pos); for(int d=0; d< 3; d++) onebody(e)-=electric_field(d)*pos(d); } }
int binary_read_checksum(Array1 <doublevar> & a, FILE * f,int nhint) { int ntry=0; while(true) { //First try to read in zeros ntry++; if(ntry>1) cout << "WARNING: detected corruption" << endl; doublevar zero1,zero2; int ntry_zero=0; while(true) { ntry_zero++; if(!fread(&zero1,sizeof(doublevar),1,f)) return 0; //cout << "zero1 " << zero1 << endl; if(zero1==0) { if(!fread(&zero2,sizeof(doublevar),1,f)) return 0; if(zero2==0) break; } } if(ntry_zero> 1) cout << "WARNING: possible corruption: had to search " << ntry_zero << endl; doublevar n_d; fread(&n_d,sizeof(doublevar),1,f); int n=int(n_d); if(n_d-n == 0 and ( nhint<0 or n==nhint)) { a.Resize(n); fread(a.v,sizeof(doublevar),n,f); doublevar check_array=checksum(a); doublevar check_file=1e99; fread(&check_file,sizeof(doublevar),1,f); if(fabs(check_array-check_file) < 1e-10) return ntry; else { cout << "WARNING: detected corruption" << endl; } if(ferror(f)) return 0; } } }
void Force_fitter::fit_force(Array1 <doublevar> & r, Array1 <doublevar> & bare_force, Array1 <doublevar> & fit_force) { int ndim=bare_force.GetDim(0); fit_force=bare_force; return; fit_force.Resize(ndim); fit_force=0; if(r(0) < cut) { for(int d=0; d< ndim; d++) { doublevar basis=0; for(int i=0; i< nexp; i++) { basis+=coeff(i)*pow(r(0),i+m); } fit_force(d)=bare_force(d)*basis; } } else { fit_force=bare_force; } }
void Jastrow_threebody_piece_diffspin::getParms(Array1 <doublevar> & parms) { if(freeze) { parms.Resize(0); } else { parms.Resize(nparms()); int counter=0; int natoms=parm_centers.GetDim(0); for(int s=0; s< unique_parameters_spin.GetSize();s++){ for(int i=0; i< unique_parameters_spin(s).GetDim(0); i++) { for(int j=0; j< _nparms(i); j++) { parms(counter++) = unique_parameters_spin(s)(i,j);//*natoms; } } } } }
void getBlocks(vector <string> & words, vector <string> & labels, Array1 < Array1 < Properties_block> > & allblocks, Array1 < Array1 < Average_generator * > > & avg_gen) { vector < vector < string> > blocktext; vector <string> tmp; unsigned int pos=0; while(readsection(words, pos, tmp, "BLOCK")) blocktext.push_back(tmp); int nblock=blocktext.size(); //cout << blocktext.size() << " blocks \n"; //vector <string> labels; vector <int> belong_to; vector <int> lab_nb; //number of blocks that belong to each label string label; for(int b=0; b< nblock; b++) { if(!readvalue(blocktext[b], pos=0, label, "LABEL")) error("didn't find label in the file"); vector<string>::iterator place=find(labels.begin(), labels.end(), label); belong_to.push_back(place-labels.begin()); if(place==labels.end()) { labels.push_back(label); lab_nb.push_back(1); } else lab_nb[belong_to[b]]++; } int nlabels=labels.size(); //cout << nlabels << " labels" << endl; //for(int i=0; i< nlabels; i++) { // cout << labels[i] << " " << lab_nb[i] << " " << lab_ninit[i] << endl; //} allblocks.Resize(nlabels); for(int i=0; i< nlabels; i++) { allblocks(i).Resize(lab_nb[i]); } Array1 <int> nb_read(nlabels, 0); for(int b=0; b< nblock; b++) { int lab=belong_to[b]; int i=nb_read(lab); nb_read(lab)++; allblocks(lab)(i).restoreFromLog(blocktext[b]); } getInit(words, labels, avg_gen); }
void Rgaussian_function::getVarParms(Array1 <doublevar> & parms) { //cout << "getVarParms " << endl; parms.Resize(nparms()); int count=0; for(int l=0; l < nmax; l++) { for(int e=0; e< numExpansion(l); e++) { parms(count++)=log(gaussexp(l,e)); //parms(count++)=gausscoeff(l,e); } } }
int HEG_system::enforcePbc(Array1 <doublevar> & pos, Array1 <int> & nshifted) { assert(pos.GetDim(0) >=3); int shifted=0; nshifted.Resize(3); nshifted=0; int nshift=0; for(int i=0; i< 3; i++) { int shouldcontinue=1; while(shouldcontinue) { //Whether we're past the origin side doublevar tooshort=0; for(int j=0; j<3;j++) tooshort+=normVec(i,j)*(pos(j)-origin(j)); //Whether we're past the lattice vector doublevar toofar=0; for(int j=0; j< 3; j++) toofar+=normVec(i,j)*(pos(j)-corners(i,j)); //the 1e-12 seems to help avoid numerical problems, esp //when integrating over a grid(which tends to hit the edges) if(tooshort < -1e-12) { //cout <<"tooshort " << tooshort << endl; for(int j=0; j< 3; j++) pos(j)+=latVec(i,j); shifted=1; nshifted(i)+=1; nshift++; } else if(toofar > 1e-12) { //cout << "toofar " << toofar << endl; for(int j=0; j< 3; j++) pos(j)-=latVec(i,j); shifted=1; // JK: here was +1, which works fine for real k-points that // correspond to standing waves. For general (complex) k-points the // wavefunction is "directional", however. nshifted(i)-=1; nshift++; } else { shouldcontinue=0; } if(nshift > 1000) error("Did over 1000 shifts and we're still out of the simulation cell." " There's probably something wrong. Position : ", pos(i)); } } return shifted; }
//We write different versions in case we want to use BLAS routines, which don't template well.. dcomplex InverseUpdateRow(Array2 <dcomplex> & a1, const Array1 <dcomplex> & newRow, const int lRow, const int n) { Array1 <dcomplex> tmpColL; tmpColL.Resize(n); Array1 <dcomplex> prod; prod.Resize(n); dcomplex f=0.0; for(int i=0;i<n;++i) { f += newRow[i]*a1(i,lRow); } f =-1.0/f; for(int j=0;j<n;++j){ prod[j] =0.0; tmpColL[j]=a1(j,lRow); for(int i=0;i<n;++i) { prod[j] += newRow[i]*a1(i,j); } prod[j] *= f; } for(int i=0;i<n;++i) { dcomplex t(tmpColL[i]); for(int j=0;j<n;++j) { a1(i,j) += t*prod[j]; } } f = -f; for(int i=0;i<n;++i) { a1(i,lRow) = f*tmpColL[i]; } return f; }
void getInit(vector <string> & words, vector <string> & labels, Array1 < Array1 <Average_generator*> > & avg_gen) { unsigned int pos=0; pos=0; vector<string> tmp; vector <vector<string> > inittext; while(readsection(words, pos, tmp, "INIT")) inittext.push_back(tmp); int ninit=inittext.size(); int nlabels=labels.size(); //cout << "ninit " << ninit << endl; //if we have multiple init sections, we should check to see that they're //all identical. For now, let's take the first one. avg_gen.Resize(nlabels); if(ninit==0) { for(int i=0; i< nlabels; i++) avg_gen(i).Resize(0); return; } for(int i=0; i< nlabels; i++) { int ini=0; string inilabel; readvalue(inittext[ini],pos=0,inilabel, "LABEL"); while(labels[i]!=inilabel) { ini++; readvalue(inittext[ini],pos=0,inilabel, "LABEL"); if(ini>= ninit) { cout << "Couldn't find init section for label " << labels[i] << ". AVERAGE { } sections will not be reported.\n"; break; } } if(ini < ninit) { vector <vector <string> > gen_secs; pos=0; while(readsection(inittext[ini],pos,tmp, "AVERAGE_GENERATOR")) gen_secs.push_back(tmp); avg_gen(i).Resize(gen_secs.size()); for(int j=0; j< gen_secs.size(); j++) { allocate(gen_secs[j],avg_gen(i)(j)); } } } }
void GeneralizedEigenSystemSolverRealGeneralMatrices(Array2 < doublevar > & Ain, Array1 <dcomplex> & W, Array2 <doublevar> & VL, Array2 <doublevar> & VR) { #ifdef USE_LAPACK //if LAPACK int N=Ain.dim[0]; Array2 <doublevar> A_temp=Ain; //,VL(N,N),VR(N,N); Array1 <doublevar> WORK,RWORK(2*N),WI(N),WR(N); WI.Resize(N); VL.Resize(N,N); VR.Resize(N,N); int info; int NB=64; int NMAX=N; int lda=NMAX; int ldb=NMAX; int LWORK=5*NMAX; WORK.Resize(LWORK); info= dgeev('V','V',N,A_temp.v, lda,WR.v,WI.v,VL.v,lda,VR.v,lda,WORK.v,LWORK); if(info>0) error("Internal error in the LAPACK routine dgeev",info); if(info<0) error("Problem with the input parameter of LAPACK routine dgeev in position ",-info); W.Resize(N); for(int i=0; i< N; i++) { W(i)=dcomplex(WR(i),WI(i)); } // for (int i=0; i<N; i++) // evals(i)=W[N-1-i]; // for (int i=0; i<N; i++) { // for (int j=0; j<N; j++) { // evecs(j,i)=A_temp(N-1-i,j); // } // } //END OF LAPACK #else //IF NO LAPACK error("need LAPACK for eigensystem solver for general matrices"); #endif //END OF NO LAPACK }
void Slat_Jastrow::evalTestPos(Array1 <doublevar> & pos, Sample_point * sample,Array1 <Wf_return> & wf) { Array1 <Wf_return> slat_val,jast_val; slater_wf->evalTestPos(pos,sample,slat_val); jastrow_wf->evalTestPos(pos,sample,jast_val); assert(slat_val.GetDim(0)==jast_val.GetDim(0)); int n=slat_val.GetDim(0); wf.Resize(n); for(int i=0; i< n; i++) { wf(i).Resize(nfunc_,2); if ( slat_val(i).is_complex==1 || jast_val(i).is_complex==1 ) wf(i).is_complex=1; for(int j=0; j< nfunc_; j++) { wf(i).phase(j,0)=slat_val(i).phase(j,0)+jast_val(i).phase(j,0); wf(i).amp(j,0)=slat_val(i).amp(j,0)+jast_val(i).amp(j,0); //add the logarithm } } }
void Molecular_system::locDerivative(int ion, Sample_point * sample, Force_fitter & fitter, Array1 <doublevar> & der) { sample->updateEIDist(); der.Resize(3); der=0; Array1 <doublevar> R(5); int ne=sample->electronSize(); Array1 <doublevar> tmpder(3), tmpder_fit(3); for(int e=0; e< ne; e++) { sample->getEIDist(e,ion, R); for(int d=0; d< 3; d++) //der(d)-=sample->getIonCharge(ion)*R(d+2)/(R(1)*R(0)); tmpder(d)=-sample->getIonCharge(ion)*R(d+2)/(R(1)*R(0)); fitter.fit_force(R,tmpder, tmpder_fit); for(int d=0; d< 3; d++) der(d)+=tmpder_fit(d); } Array1 <doublevar> vec(3); Array1 <doublevar> r_ion(3); sample->getIonPos(ion, r_ion); int nIon=sample->ionSize(); for(int j=0; j< nIon; j++) { if(j!=ion) { sample->getIonPos(j,R); doublevar r2=0; for(int d=0; d <3; d++) vec(d)=r_ion(d)-R(d); for(int d=0; d< 3; d++) r2+=vec(d)*vec(d); doublevar r=sqrt(r2); for(int d=0; d< 3; d++) der(d)-=sample->getIonCharge(ion)*sample->getIonCharge(j)*vec(d)/(r2*r); } } }
void Molecular_system::calcLocWithTestPos(Sample_point * sample, Array1 <doublevar> & tpos, Array1 <doublevar> & Vtest) { int nions=sample->ionSize(); int nelectrons=sample->electronSize(); Vtest.Resize(nelectrons + 1); Vtest = 0; Array1 <doublevar> oldpos(3); //cout << "Calculating local energy\n"; sample->getElectronPos(0, oldpos); sample->setElectronPosNoNotify(0, tpos); Array1 <doublevar> R(5); sample->updateEIDist(); sample->updateEEDist(); for(int i=0; i < nions; i++) { sample->getEIDist(0, i, R); Vtest(nelectrons)+=-sample->getIonCharge(i)/R(0); } doublevar dist = 0.0; for(int d=0; d<3; d++) { dist += (oldpos(d) - tpos(d))*(oldpos(d) - tpos(d)); } dist = sqrt(dist); Vtest(0) = 1/dist; Array1 <doublevar> R2(5); for(int i=1; i< nelectrons; i++) { sample->getEEDist(0,i,R2); Vtest(i)= 1/R2(0); } sample->setElectronPosNoNotify(0, oldpos); sample->updateEIDist(); sample->updateEEDist(); //cout << "elec-elec: " << elecElec << endl; //cout << "pot " << pot << endl; for(int d=0; d< 3; d++) Vtest(nelectrons) -=electric_field(d)*tpos(d); }
int reblock_average(Array1 <Properties_block> & orig_block, int reblock, int equil, Properties_final_average & avg) { int nblock=orig_block.GetDim(0); if(reblock > nblock) return 0; int neffblock=0; Array1<Properties_block> reblocks; reblocks.Resize(nblock/reblock); int start=nblock%reblock; int count=0; for(int i=start; i< nblock; i+=reblock) { int top=min(i+reblock, nblock); reblocks(count++).reduceBlocks(orig_block, i, top); } neffblock=nblock/reblock; avg.blockReduce(reblocks, 0, nblock/reblock, equil); return neffblock; }
void sort_abs_values_descending(const Array1 <doublevar> & vals, Array1 <doublevar> & newvals, Array1 <int> & list){ int n=vals.GetSize(); list.Resize(n); for (int i=0; i < n; i++) { list(i) = i; newvals(i)=vals(i); } for (int i=1; i < n; i++) { const double temp = newvals[i]; const double abstemp = fabs(newvals[i]); int j; for (j=i-1; j>=0 && fabs(newvals[j])<abstemp; j--) { newvals[j+1] = newvals[j]; list[j+1] = list[j]; } newvals[j+1] = temp; list[j+1] = i; } //for (int i=0; i < n; i++) //cout << list[i]<<endl; }
void MO_matrix_standard::getBasisVal(Sample_point * sample, int e, Array1 <doublevar> & newvals ) { newvals.Resize(totbasis); int centermax=centers.size(); centers.updateDistance(e, sample); Basis_function * tempbasis; Array1 <doublevar> R(5); int currfunc=0; newvals=0; for(int ion=0; ion < centermax; ion++) { centers.getDistance(e, ion, R); for(int n=0; n< centers.nbasis(ion); n++) { tempbasis=basis(centers.basis(ion,n)); tempbasis->calcVal(R, newvals, currfunc); currfunc+=tempbasis->nfunc(); } } }
void MO_matrix_blas::updateVal(Sample_point * sample, int e, int listnum, Array2 <doublevar> & newvals) { #ifdef USE_BLAS int centermax=centers.size(); assert(e < sample->electronSize()); assert(newvals.GetDim(1) >=1); Array1 <doublevar> R(5); static Array1 <doublevar> symmvals_temp(maxbasis); static Array1 <doublevar> newvals_T; Array2 <doublevar> & moCoefftmp(moCoeff_list(listnum)); int totbasis=moCoefftmp.GetDim(0); int nmo_list=moCoefftmp.GetDim(1); newvals_T.Resize(nmo_list); newvals_T=0.0; int b; int totfunc=0; centers.updateDistance(e, sample); static Array1 <MOBLAS_CalcObjVal> calcobjs(totbasis); int ncalcobj=0; for(int ion=0; ion < centermax; ion++) { centers.getDistance(e, ion, R); for(int n=0; n< centers.nbasis(ion); n++) { b=centers.basis(ion, n); if(R(0) < obj_cutoff(b)) { basis(b)->calcVal(R, symmvals_temp); int imax=nfunctions(b); for(int i=0; i< imax; i++) { if(R(0) < cutoff(totfunc)) { //cblas_daxpy(nmo_list,symmvals_temp(i), // moCoefftmp.v+totfunc*nmo_list,1, // newvals_T.v,1); calcobjs(ncalcobj).sval=symmvals_temp(i); calcobjs(ncalcobj).moplace=moCoefftmp.v+totfunc*nmo_list; ncalcobj++; } totfunc++; } } else { totfunc+=nfunctions(b); } } } for(int i=0; i< ncalcobj; i++) { cblas_daxpy(nmo_list,calcobjs(i).sval,calcobjs(i).moplace,1,newvals_T.v,1); } for(int m=0; m < nmo_list; m++) { newvals(m,0)=newvals_T(m); } #else error("BLAS libraries not compiled in, so you cannot use BLAS_MO"); #endif }
void get_onebody_parms_diffspin(vector<string> & words, vector<string> & atomnames, Array2 <doublevar> & unique_parameters, int s, Array1 <int> & nparms, vector <string> & parm_labels, Array2 <int> & linear_parms, int & counter, Array1 <int> & parm_centers) { vector < vector < string> > parmtxt; vector <string> parmtmp; unsigned int pos=0; if(s==0){ while(readsection(words, pos,parmtmp, "LIKE_COEFFICIENTS")) parmtxt.push_back(parmtmp); if(parmtxt.size()==0) error("Didn't find LIKE COEFFICIENTS in one of threebody spin Jastrow section"); } else{ while(readsection(words, pos,parmtmp, "UNLIKE_COEFFICIENTS")) parmtxt.push_back(parmtmp); if(parmtxt.size()==0) error("Didn't find UNLIKE COEFFICIENTS in one of threebody spin Jastrow section"); } int nsec=parmtxt.size(); int maxsize=0; nparms.Resize(nsec); for(int i=0; i< nsec; i++) nparms(i)=parmtxt[i].size()-1; for(int i=0; i< nsec; i++) if(maxsize < nparms(i)) maxsize=nparms(i); unique_parameters.Resize(nsec, maxsize); linear_parms.Resize(nsec, maxsize); //cout <<"spin "<<s<<" counter "<<counter<<endl; for(int i=0; i< nsec; i++) { for(int j=0; j< nparms(i); j++) { unique_parameters(i,j)=atof(parmtxt[i][j+1].c_str()); linear_parms(i,j)=counter++; } } parm_labels.resize(nsec); for(int i=0; i< nsec; i++) parm_labels[i]=parmtxt[i][0]; int natoms=atomnames.size(); parm_centers.Resize(natoms); parm_centers=-1; for(int i=0; i< nsec; i++) { int found=0; for(int j=0; j< natoms; j++) { if(atomnames[j]==parm_labels[i]) { parm_centers(j)=i; found=1; } } if(!found) error("Couldn't find a matching center for ", parm_labels[i]); } doublevar scale; if(readvalue(words, pos=0, scale, "SCALE")) { for(int i=0; i< unique_parameters.GetDim(0); i++) { for(int j=0; j< nparms(i); j++) { unique_parameters(i,j)*=scale; } } } }
void Step_function::getVarParms(Array1 <doublevar> & parms) { //cout << "getVarParms " << endl; parms.Resize(0); }
void read_basis(string & basisin, Array1 <Contracted_gaussian> & basis) { ifstream basis_f(basisin.c_str()); if(!basis_f) error("Couldn't open ", basisin); vector <string> words; parsefile(basis_f, words); unsigned int pos=0; vector <vector <string> > sections; vector <string> section_temp; while(readsection(words, pos, section_temp, "BASIS") ) { sections.push_back(section_temp); } int nsections=sections.size(); string label; vector <string> gamesstxt; vector < Contracted_gaussian > basis_tmp; Contracted_gaussian tempgauss; int totgauss=0; for(int sec=0; sec < nsections; sec++) { label=sections[sec][0]; //cout << "label " << label << endl; if(!readsection(sections[sec], pos=0, gamesstxt, "GAMESS") ) { error("Need a GAMESS section"); } unsigned int pos2=0; unsigned int txtsize=gamesstxt.size(); string symm; int nexpand=0; while(pos2 < txtsize) { symm=gamesstxt[pos2]; //cout << "symm " << symm << endl; nexpand=atoi(gamesstxt[++pos2].c_str()); pos2+= 3*nexpand; pos2++; if(symm=="S") totgauss++; else if(symm=="P") totgauss+=3; else if(symm=="D" || symm=="6D") totgauss+=6; else error("Don't understand symmetry ", symm); //cout << "totgauss " << totgauss << endl; } } basis.Resize(totgauss); int gaussnum=0; for(int sec=0; sec < nsections; sec++) { label=sections[sec][0]; //cout << "label " << label << endl; if(!readsection(sections[sec], pos=0, gamesstxt, "GAMESS") ) { error("Need a GAMESS section"); } unsigned int pos2=0; unsigned int txtsize=gamesstxt.size(); string symm; int nexpand=0; while(pos2 < txtsize) { symm=gamesstxt[pos2]; nexpand=atoi(gamesstxt[++pos2].c_str()); tempgauss.alpha.Resize(nexpand); tempgauss.coeff.Resize(nexpand); tempgauss.center_name=label; for(int i=0; i< nexpand; i++) { if(atoi(gamesstxt[++pos2].c_str()) != i+1) error("Some misformatting in basis section"); tempgauss.alpha(i)=atof(gamesstxt[++pos2].c_str()); tempgauss.coeff(i)=atof(gamesstxt[++pos2].c_str()); } if(symm=="S") { tempgauss.lvals(0)=tempgauss.lvals(1)=tempgauss.lvals(2)=0; basis(gaussnum++)=tempgauss; } else if(symm=="P") { for(int i=0; i< 3; i++) { tempgauss.lvals=0; tempgauss.lvals(i)=1; basis(gaussnum++) = tempgauss; } } else if(symm=="D" || symm=="6D") { //xx, yy, zz for(int i=0; i< 3; i++) { tempgauss.lvals=0; tempgauss.lvals(i)=2; basis(gaussnum++) = tempgauss; } //xy tempgauss.lvals(0)=1; tempgauss.lvals(1)=1; tempgauss.lvals(2)=0; basis(gaussnum++) = tempgauss; //xz tempgauss.lvals(0)=1; tempgauss.lvals(1)=0; tempgauss.lvals(2)=1; basis(gaussnum++) = tempgauss; //yz tempgauss.lvals(0)=0; tempgauss.lvals(1)=1; tempgauss.lvals(2)=1; basis(gaussnum++) = tempgauss; } else { error("Unsupported symmetry ", symm); } ++pos2; } } /* for(int i=0; i< totgauss; i++) { cout << "basis " << i << " center " << basis(i).center_name << endl; cout << " lvals "; for(int j=0; j< 3; j++) cout << basis(i).lvals(j) << " "; cout << endl; for(int j=0; j< basis(i).alpha.GetDim(0); j++) { cout << " " << basis(i).alpha(j) << " " << basis(i).coeff(j) << endl; } } */ }
Label_list(int max) { avg.Resize(max); navg=0; }
/*! */ void Reptation_method::runWithVariables(Properties_manager & prop, System * sys, Wavefunction_data * wfdata, Pseudopotential * psp, ostream & output) { allocateIntermediateVariables(sys, wfdata); prop.setSize(wf->nfunc(), nblock, nstep, 1, sys, wfdata); prop.initializeLog(average_var); Properties_manager prop_center; string logfile, label_temp; prop.getLog(logfile, label_temp); label_temp+="_cen"; prop_center.setLog(logfile, label_temp); prop_center.setSize(wf->nfunc(), nblock, nstep, 1, sys, wfdata); prop_center.initializeLog(average_var); cout.precision(10); output.precision(10); Sample_point * center_samp(NULL); sys->generateSample(center_samp); Reptile_point pt; Array1 <Reptile> reptiles; int nreptile=1; if(!readcheck(readconfig,reptiles)) { Array1 <Config_save_point> configs; generate_sample(sample,wf,wfdata,guidewf,nreptile,configs); reptiles.Resize(nreptile); for(int r=0; r< nreptile; r++) { reptiles[r].direction=1; configs(r).restorePos(sample); wf->notify(all_electrons_move,0); wf->updateLap(wfdata,sample); for(int i=0; i< reptile_length; i++) { doublevar main_diffusion; slither(1,reptiles[r].reptile, mygather,pt,main_diffusion); reptiles[r].reptile.push_back(pt); } } } nreptile=reptiles.GetDim(0); //assert(reptile.size()==reptile_length); //Branch limiting variables //we start off with no limiting, and establish the parameters after the //first block. This seems to be reasonably stable, since it's mostly //to keep the reptile from getting stuck. eref=0; energy_cutoff=1e16; //--------begin averaging.. Array3 <doublevar> derivatives_block(nblock, sys->nIons(), 3); for(int block=0; block< nblock; block++) { //clock_t block_start_time=clock(); doublevar avg_age=0; doublevar max_age=0; doublevar main_diff=0; double ntry=0, naccept=0; double nbounce=0; for(int r=0; r< nreptile; r++) { Reptile & curr_reptile=reptiles[r]; //Control variable that will be set to one when //we change direction, which signals to recalculate //the wave function int recalc=1; for(int step=0; step< nstep; step++) { psp->randomize(); if(recalc) { if(curr_reptile.direction==1) curr_reptile.reptile[reptile_length-1].restorePos(sample); else curr_reptile.reptile[0].restorePos(sample); } doublevar main_diffusion; doublevar accept=slither(curr_reptile.direction, curr_reptile.reptile,mygather, pt, main_diffusion); ntry++; if(accept+rng.ulec() > 1.0) { recalc=0; naccept++; main_diff+=main_diffusion; if(curr_reptile.direction==1) { curr_reptile.reptile.pop_front(); curr_reptile.reptile.push_back(pt); } else { curr_reptile.reptile.pop_back(); curr_reptile.reptile[0].branching=pt.branching; curr_reptile.reptile.push_front(pt); } } else { recalc=1; curr_reptile.direction*=-1; nbounce++; } for(deque<Reptile_point>::iterator i=curr_reptile.reptile.begin(); i!=curr_reptile.reptile.end(); i++) { i->age++; avg_age+=i->age/reptile_length; if(i->age > max_age) max_age=i->age; } Properties_point avgpt; get_avg(curr_reptile.reptile, avgpt); avgpt.parent=0; avgpt.nchildren=1; //just one walker avgpt.children(0)=0; prop.insertPoint(step, 0, avgpt); int cpt=reptile_length/2+1; Properties_point centpt; get_center_avg(curr_reptile.reptile, centpt); centpt.parent=0; centpt.nchildren=1; centpt.children(0)=0; prop_center.insertPoint(step, 0, centpt); curr_reptile.reptile[cpt].restorePos(center_samp); for(int i=0; i< densplt.GetDim(0); i++) densplt(i)->accumulate(center_samp,1.0); if(center_trace != "" && (block*nstep+step)%trace_wait==0) { ofstream checkfile(center_trace.c_str(), ios::app); if(!checkfile)error("Couldn't open ", center_trace); checkfile << "SAMPLE_POINT { \n"; write_config(checkfile, sample); checkfile << "}\n\n"; } } //step } //reptile prop.endBlock(); prop_center.endBlock(); double ntot=parallel_sum(nstep); Properties_block lastblock; prop.getLastBlock(lastblock); eref=lastblock.avg(Properties_types::total_energy,0); energy_cutoff=10*sqrt(lastblock.var(Properties_types::total_energy,0)); nbounce=parallel_sum(nbounce); naccept=parallel_sum(naccept); ntry=parallel_sum(ntry); avg_age=parallel_sum(avg_age); for(int i=0; i< densplt.GetDim(0); i++) densplt(i)->write(); storecheck(reptiles, storeconfig); main_diff=parallel_sum(main_diff); if(output) { output << "****Block " << block << " acceptance " << naccept/ntry << " average steps before bounce " << ntot/nbounce << endl; output << "average age " << avg_age/ntot << " max age " << max_age << endl; output << "eref " << eref << " cutoff " << energy_cutoff << endl; output << "Green's function sampler:" << endl; sampler->showStats(output); prop.printBlockSummary(output); output << "Center averaging: " << endl; prop_center.printBlockSummary(output); } sampler->resetStats(); //clock_t block_end_time=clock(); //cout << mpi_info.node << ":CPU block time " //// << double(block_end_time-block_start_time)/double(CLOCKS_PER_SEC) // << endl; } //block if(output) { output << "############## Reptation Done ################\n"; output << "End averages " << endl; prop.printSummary(output,average_var); output << "Center averages " << endl; prop_center.printSummary(output,average_var); //Print out a PDB file with one of the reptiles, for visualization purposes if(print_pdb) { ofstream pdbout("rmc.pdb"); pdbout.precision(3); pdbout << "REMARK 4 Mode COMPLIES WITH FORMAT V. 2.0\n"; int nelectrons=sample->electronSize(); int counter=1; string name="H"; for(int e=0; e<nelectrons; e++) { for(deque<Reptile_point>::iterator i=reptiles[0].reptile.begin(); i!=reptiles[0].reptile.end(); i++) { pdbout<<"ATOM"<<setw(7)<< counter <<" " <<name<<" UNK 1" <<setw(12)<< i->electronpos[e][0] <<setw(8)<< i->electronpos[e][1] <<setw(8)<< i->electronpos[e][2] << " 1.00 0.00\n"; counter++; } } int nions=sys->nIons(); Array1 <doublevar> ionpos(3); vector <string> atomnames; sys->getAtomicLabels(atomnames); for(int i=0; i< nions; i++) { sys->getIonPos(i,ionpos); pdbout<<"ATOM"<<setw(7)<< counter <<" " <<atomnames[i]<<" UNK 1" <<setw(12)<< ionpos[0] <<setw(8)<< ionpos[1] <<setw(8)<< ionpos[2] << " 1.00 0.00\n"; } counter=1; for(int e=0; e<nelectrons; e++) { for(deque<Reptile_point>::iterator i=reptiles[0].reptile.begin(); i!=reptiles[0].reptile.end(); i++) { if(i != reptiles[0].reptile.begin()) { pdbout << "CONECT" << setw(5) << counter << setw(5) << counter-1 << endl; } counter++; } } } //------------Done PDB file } delete center_samp; wfdata->clearObserver(); deallocateIntermediateVariables(); }
void Cutoff_cusp::getVarParms(Array1 <doublevar> & parms) { //cout << "getVarParms " << endl; parms.Resize(1); parms(0)=log(gamma); //cout << "parms out " << parms(0) << endl; }
/*! */ void Md_method::run(Program_options & options, ostream & output) { output.precision(10); string logfile=options.runid+".log"; prop.setLog(logfile, log_label); int natoms=sys->nIons(); Array1 < Array1 <int> > atom_move; Array1 < Array2 <doublevar> > displace; //Even numbered displacements are in + direction, odd are in // - direction if(natoms==2) { //For a dimer, assume they are oriented in the z //direction and only move in that direction. atom_move.Resize(4); displace.Resize(4); int count=0; for(int at=0; at < natoms; at++) { for(int s=0; s< 2; s++) { atom_move(count).Resize(1); displace(count).Resize(1,3); atom_move(count)(0)=at; displace(count)=0; if(s==0) displace(count)(0,2)=0.00025; else displace(count)(0,2)=-0.00025; count++; } } } else { int ndim=0; for(int d=0; d< 3; d++) { if(restrict_dimension(d) ==0) ndim++; } atom_move.Resize(2*ndim*natoms); displace.Resize(2*ndim*natoms); int count=0; for(int at=0; at< natoms; at++) { for(int d=0; d< 3; d++) { if(!restrict_dimension(d) ) { for(int s=0; s< 2; s++) { atom_move(count).Resize(1); displace(count).Resize(1,3); atom_move(count)(0)=at; displace(count)=0; if(s==0) displace(count)(0,d)=0.00025; else displace(count)(0,d)=-0.00025; count++; } } } } } prop.setDisplacement(atom_move, displace); Properties_final_average curravg; string vmcout=options.runid+".embed"; ofstream vmcoutput; if(output) vmcoutput.open(vmcout.c_str()); Array3 <doublevar> ionpos(nstep+2, natoms, 3, 0.0); Array1 <doublevar> temppos(3); for(int s=0; s< 2; s++) { for(int at=0; at< natoms; at++) { sys->getIonPos(at, temppos); for(int d=0; d< 3; d++) { ionpos(s,at,d)=temppos(d); } } } if(readcheckfile != "") { read_check(ionpos); } for(int s=0; s< 2; s++) { Array2 <doublevar> pos(ionpos(s)); recenter(pos, atomic_weights); } for(int step=0; step < nstep; step++) { int currt=step+1; //current time for(int at=0; at< natoms; at++) { for(int d=0; d< 3; d++) { temppos(d)=ionpos(currt, at, d); } sys->setIonPos(at, temppos); } qmc_avg->runWithVariables(prop, sys, wfdata, pseudo, vmcoutput); prop.getFinal(curravg); if(output) output << "*****Step " << step << endl; Array2 <doublevar> force(natoms, 3, 0.0); Array2 <doublevar> force_err(natoms, 3, 0.0); for(int f=0; f< atom_move.GetDim(0); f+=2 ) { for(int m=0; m < atom_move(f).GetDim(0); m++) { int at=atom_move(f)(m); for(int d=0; d< 3; d++) { //Take a finite difference between the two forces doublevar prop=fabs(displace(f)(m,d)/curravg.aux_size(f)); doublevar fin_diff=(curravg.aux_diff(f,0)-curravg.aux_diff(f+1,0)) /(2*curravg.aux_size(f)); force(at,d)+= -prop*fin_diff; force_err(at,d)+=prop*(curravg.aux_differr(f,0) +curravg.aux_differr(f+1,0)) /(2*curravg.aux_size(f))/(2*curravg.aux_size(f)); } } } for(int at=0; at< natoms; at++) { for(int d=0; d< 3; d++) force_err(at,d)=sqrt(force_err(at,d)); } //Make sure that Newton's laws are actually followed for //two atoms; we can do this for more, as well. if(natoms==2) { doublevar average=(force(0,2)-force(1,2))/2.0; force(0,2)=average; force(1,2)=-average; } //Verlet algorithm.. for(int at=0; at< natoms; at++) { for(int d=0; d< 3; d++) { ionpos(currt+1, at, d)=ionpos(currt, at,d) +(1-damp)*(ionpos(currt, at, d)-ionpos(currt-1, at,d)) +tstep*tstep*force(at,d)/atomic_weights(at); //cout << "pos " << ionpos(currt, at,d) // << " last " << ionpos(currt-1, at,d) // << " weight " << atomic_weights(at) << endl; } } Array2 <doublevar> currpos(ionpos(currt+1)); recenter(currpos, atomic_weights); doublevar kinen=0; int field=output.precision() + 15; for(int at=0; at < natoms; at++) { if(output) output << "position" << at << " " << setw(field) << ionpos(currt+1, at, 0) << setw(field) << ionpos(currt+1, at, 1) << setw(field) << ionpos(currt+1, at, 2) << endl; Array1 <doublevar> velocity(3); for(int d=0; d< 3; d++) { velocity(d)=(ionpos(currt+1, at, d)-ionpos(currt-1, at,d))/(2*tstep); } for(int d=0;d < 3; d++) { kinen+=.5*atomic_weights(at)*velocity(d)*velocity(d); } if(output ) { output << "velocity" << at << " " << setw(field) << velocity(0) << setw(field) << velocity(1) << setw(field) << velocity(2) << endl; output << "force" << at << " " << setw(field) << force(at,0) << setw(field) << force(at, 1) << setw(field) << force(at,2) << endl; output << "force_err" << at << setw(field) << force_err(at, 0) << setw(field) << force_err(at, 1) << setw(field) << force_err(at, 2) << endl; //output << "force" << at << "z " << force(at,2) << " +/- " // << force_err(at,2) << endl; } } if(output ) { output << "kinetic_energy " << kinen << endl; output << "electronic_energy " << curravg.total_energy(0) << " +/- " << sqrt(curravg.total_energyerr(0)) << endl; output << "total_energy " << curravg.total_energy(0)+kinen << " +/- " << sqrt(curravg.total_energyerr(0)) << endl; if(writecheckfile != "") if(output) write_check(ionpos, currt+1); } } if(output) vmcoutput.close(); }
void create_local_basis(string & centerin, string & basisin, Array1 <Center> & centers, Array1 <Contracted_gaussian > & basis ) { Array2 <doublevar> centerpos; vector <string> labels; read_centerpos(centerin, centerpos, labels); read_basis(basisin, basis); int ncenters=centerpos.GetDim(0); int nbasis=basis.GetDim(0); centers.Resize(ncenters); for(int cen=0; cen < ncenters; cen++) { for(int d=0; d< 3; d++) centers(cen).pos(d)=centerpos(cen,d); centers(cen).label=labels[cen]; } vector <vector <int> > cenbasis, basiscen; cenbasis.resize(ncenters); basiscen.resize(nbasis); for(int cen=0; cen < ncenters; cen++) { int foundbas=0; for(int bas=0; bas < nbasis; bas++) { if(centers(cen).label==basis(bas).center_name) { foundbas=1; cenbasis[cen].push_back(bas); basiscen[bas].push_back(cen); } } if(!foundbas) cout << "WARNING! Couldn't find a basis set for center " << centers(cen).label << endl; } for(int bas=0; bas < nbasis; bas++) { int ncen=basiscen[bas].size(); basis(bas).center.Resize(ncen); for(int c=0; c< ncen; c++) { basis(bas).center(c)=basiscen[bas][c]; //cout << "basis " << bas << " -> center " << basis(bas).center(c) << endl; } } for(int cen=0; cen < ncenters; cen++) { int nbas=cenbasis[cen].size(); centers(cen).basis.Resize(nbas); for(int b=0; b< nbas; b++) { centers(cen).basis(b)=cenbasis[cen][b]; //cout << "center " << cen << " -> basis " << centers(cen).basis(b) << endl; } } for(int bas=0; bas < nbasis; bas++) { int nalpha=basis(bas).alpha.GetDim(0); //cout << "basis " << bas << endl; for(int a =0; a < nalpha; a++) { int totL=basis(bas).lvals(0)+basis(bas).lvals(1)+basis(bas).lvals(2); doublevar exponent=basis(bas).alpha(a); doublevar fac=sqrt(2.*exponent/pi); doublevar feg=4.*exponent; doublevar feg2=feg*feg; doublevar norm=0; switch(totL) { case 0: norm=sqrt(2.*feg*fac); break; case 1: norm=sqrt(2.*feg2*fac/3.); break; case 2: norm=sqrt(2.*feg*feg2*fac/15.); break; case 3: norm=sqrt(2.*feg2*feg2*fac/105.); break; default: norm=0; error("Unknown symmetry in Cubic_spline::readbasis! Shouldn't be here!"); } basis(bas).coeff(a)*=norm; } } }