//----------------------------------------------------------------------
//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;
	}
      }
    }
  }

}
示例#5
0
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;
}
示例#9
0
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);
}
示例#14
0
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;
    }

  }
*/

}
示例#21
0
 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;
    }
  }


}