void Dmc_method::doTmove(Properties_point & pt,Pseudopotential * pseudo, System * sys,
                         Wavefunction_data * wfdata, Wavefunction * wf, Sample_point * sample,
                         Guiding_function * guideingwf) {
  vector <Tmove> tmov;
  pt.setSize(nwf);
  wf->getVal(wfdata,0,pt.wf_val);
  sys->calcKinetic(wfdata,sample,wf,pt.kinetic);
  pt.potential=sys->calcLoc(sample);
  pt.weight=1.0; //this gets set later anyway
  pt.count=1;
  pseudo->calcNonlocTmove(wfdata,sys,sample,wf,pt.nonlocal,tmov);
  doublevar sum=1;
  for(vector<Tmove>::iterator mov=tmov.begin(); mov!=tmov.end(); mov++) {
    assert(mov->vxx < 0);
    sum-=timestep*mov->vxx;
  }
  pt.nonlocal(0)-=(sum-1)/timestep;
  //subtract_out_enwt=-(sum-1)/timestep;
  assert(sum >= 0);
  if(tmoves) { ///Non-size consistent
    doublevar rand=rng.ulec()*sum;
    sum=1; //reset to choose the move
    if(rand > sum) {
      for(vector<Tmove>::iterator mov=tmov.begin(); mov!=tmov.end(); mov++) {
        sum-=timestep*mov->vxx;
        if(rand < sum) {
          sample->translateElectron(mov->e,mov->pos);
          break;
        }
      }
    }
  }
  else { // Size-consistent
    vector < vector<Tmove> > tmv_by_e(nelectrons);
    for(vector<Tmove>::iterator mov=tmov.begin(); mov!=tmov.end(); mov++) {
      tmv_by_e[mov->e].push_back(*mov);
    }
    for(int e=0; e< nelectrons; e++) {
      doublevar sum_e=1.0;
      for(vector<Tmove>::iterator mov=tmv_by_e[e].begin(); mov!=tmv_by_e[e].end(); mov++) {
        sum_e-=timestep*mov->vxx;
      }
      doublevar rand=rng.ulec()*sum_e;
      doublevar sel_sum=1;
      if(rand > sel_sum) {
        for(vector<Tmove>::iterator mov=tmv_by_e[e].begin(); mov!=tmv_by_e[e].end(); mov++) {
          sel_sum-=timestep*mov->vxx;
          if(rand < sel_sum) {
            sample->translateElectron(e,mov->pos);
            break;
          }
        }
      }
    }
  }

}
Пример #2
0
void Maximize_method::run(Program_options & options, ostream & output) {
    Wavefunction * wf=NULL;
    Sample_point * sample=NULL;
    sys->generateSample(sample);
    wfdata->generateWavefunction(wf);
    sample->attachObserver(wf);

    int nconfig=100;
    Array1 <Config_save_point> config_pos(nconfig);
    Array1 <doublevar> epos(3);

    Primary guidewf;
    generate_sample(sample,wf,wfdata,&guidewf,nconfig,config_pos);
    int nelectrons=sample->electronSize();
    Properties_gather mygather;

    string tablename=options.runid+".table";
    ofstream tableout(tablename.c_str());

    for(int e=0; e< nelectrons; e++) {
        sample->getElectronPos(e,epos);
        for(int d=0; d< 3; d++) {
            tableout << "e" << e << "_"<< d << " ";
        }
    }
    tableout << "elocal" << endl;

    for(int i=0; i < nconfig; i++) {
        maximize(sample,wf,config_pos(i));
        for(int e=0; e< nelectrons; e++) {
            sample->getElectronPos(e,epos);
            for(int d=0; d< 3; d++) {
                tableout << epos(d) << " ";
            }
        }
        Properties_point pt;
        mygather.gatherData(pt, pseudo, sys, wfdata, wf,
                            sample, &guidewf);

        tableout << pt.energy(0) << endl;

        config_pos(i).write(cout);
    }

    delete wf;
    delete sample;
}
Пример #3
0
//----------------------------------------------------------------------
int Postprocess_method::gen_point(Wavefunction * wf, Sample_point * sample,
    Config_save_point & configpos, doublevar weight, Properties_point & pt) { 
  Primary guide;
  Properties_gather gather;
  
  configpos.restorePos(sample);
  
  pseudo->randomize();
  if(evaluate_energy) 
    gather.gatherData(pt,pseudo,sys,wfdata,wf,sample,&guide);
  pt.avgrets.Resize(1,average_var.GetDim(0));
  //cout << mpi_info.node << " generating a point with " << average_var.GetDim(0) << " avgrets " << endl;
  for(int i=0; i< average_var.GetDim(0); i++) { 
    average_var(i)->randomize(wfdata,wf,sys,sample);
    average_var(i)->evaluate(wfdata, wf, sys, pseudo,sample,pt, pt.avgrets(0,i));
  }
  for(int i=0; i< densplt.GetDim(0); i++) densplt(i)->accumulate(sample,weight);
  pt.weight(0)=weight;
  
}
void Reptation_method::get_center_avg(deque <Reptile_point> & reptile, 
				      Properties_point & pt) { 
  int nwf=reptile[0].prop.kinetic.GetDim(0);
  int size=reptile.size();
  if(nwf >1) error("nwf > 0 not supported yet");

  pt.setSize(nwf);
  int num=size/2+1;
  pt=reptile[num].prop;

  pt.count=1;

  pt.weight=1;
}
Пример #5
0
//----------------------------------------------------------------------
int Postprocess_method::worker(Wavefunction * wf, Sample_point * sample) { 
#ifdef USE_MPI
  Config_save_point tmpconfig;
  doublevar weight;
  Properties_point pt;
  pt.setSize(1);
  tmpconfig.mpiReceive(0);
  MPI_Recv(weight,0);
  MPI_Status status;
  
  while(true) { 
    gen_point(wf,sample,tmpconfig,weight,pt);
    int done=1;
    MPI_Send(done,0);
    pt.mpiSend(0);
    MPI_Recv(done,0);
    if(done==0) break;
    tmpconfig.mpiReceive(0);
    MPI_Recv(weight,0);
  }
  cout << mpi_info.node << " : done " << endl;

#endif //USE_MPI
}
void Reptation_method::get_avg(deque <Reptile_point> & reptile, 
			       Properties_point & pt) {
  int size=reptile.size();
  int nwf=reptile[0].prop.kinetic.GetDim(0);
  if(nwf >1) error("nwf > 0 not supported yet");

  pt.setSize(nwf);
  
  Reptile_point & last(reptile[size-1]);

  //How to do averaging at either end.  Not doing this right
  //now because of correlated sampling..if we really want energies,
  //usually DMC is a better choice.
  pt=last.prop;
  //Reptile_point & first(reptile[0]);  
  //pt.kinetic(0)=.5*(first.prop.kinetic(0)+last.prop.kinetic(0));
  //pt.nonlocal(0)=.5*(first.prop.nonlocal(0)+last.prop.nonlocal(0));
  //pt.potential(0)=.5*(first.prop.potential(0) + last.prop.potential(0));
  pt.count=1;
  pt.weight=1;
  
}
/*!

*/
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();
}
Пример #8
0
void Postprocess_method::run(Program_options & options, ostream & output) {
  Sample_point * sample=NULL;
  Wavefunction * wf=NULL;
  sys->generateSample(sample);
  wfdata->generateWavefunction(wf);
  sample->attachObserver(wf);
  Properties_gather gather;
  Primary guide;
  int nelec=sample->electronSize();
  int ndim=3;
  int npoints_tot=0;
  FILE * f;
  if(mpi_info.node==0) { 
    f=fopen(configfile.c_str(),"r");
    if(ferror(f)) error("Could not open",configfile);
    fseek(f,0,SEEK_END);
    long int lSize=ftell(f);
    rewind(f);
    npoints_tot=lSize/(sizeof(doublevar)*(nelec*3+1+4));
    output << "Estimated number of samples in this file: " << npoints_tot << endl;
    output << "We are skipping the first " << nskip << " of these " << endl;
    Config_save_point tmpconfig;
    for(int i=0; i< nskip; i++) { 
      doublevar weight;
      tmpconfig.readBinary(f,nelec,ndim,weight);
//     doublevar weight;
//      if(!fread(&weight,sizeof(doublevar),1,f)) error("Misformatting in binary file",configfile, " perhaps nskip is too large?");
    }
  }
    

#ifdef USE_MPI
  if(mpi_info.nprocs<2) error("POSTPROCESS must be run with at least 2 processes if it is run in parallel.");
  if(mpi_info.node==0) { 
    master(wf,sample,f,output);
  }
  else { 
    worker(wf,sample);
  }
#else
  Config_save_point tmpconfig;
  Properties_point pt;
  pt.setSize(1);
  int npoints=0;
  Postprocess_average postavg(average_var.GetDim(0));
  doublevar weight;
  while(tmpconfig.readBinary(f,nelec,ndim,weight)) {
    tmpconfig.restorePos(sample);
    gen_point(wf,sample,tmpconfig,weight,pt);
    postavg.update_average(pt);

    npoints++;
    doublevar progress=doublevar(npoints)/doublevar(npoints_tot);
    if(fabs(progress*10-int(progress*10)) < 0.5/npoints_tot) { 
      cout << "progress: " << progress*100 << "% done" << endl;
    }
    
  }
  postavg.print(average_var,output);
#endif //USE_MPI
  for(int i=0; i< densplt.GetDim(0); i++) densplt(i)->write();

  if(mpi_info.node==0) fclose(f);

  delete sample;
  delete wf;
}
Пример #9
0
int Postprocess_method::master(Wavefunction * wf, Sample_point * sample,FILE * f, ostream & os) { 
#ifdef USE_MPI
  Config_save_point tmpconfig;
  doublevar weight;
  Properties_point pt;
  pt.setSize(1);
  int nelec=sample->electronSize();
  int ndim=3;
  MPI_Status status;
  Postprocess_average postavg(average_var.GetDim(0));
  

  //Get everyone started with data
  cout << "master: sending initial data" << endl;
  for(int r=1; r < mpi_info.nprocs; r++) { 
     if(!tmpconfig.readBinary(f,nelec,ndim,weight)) {  
       error("Binary file may not contain enough walkers; finished after ",r);
     }
     tmpconfig.mpiSend(r);
     MPI_Send(weight,r);
  }
  
  int totcount=0;
  cout << "master : going through file " << endl;
  while(tmpconfig.readBinary(f,nelec,ndim,weight)) {
//    doublevar weight;
//    if(!fread(&weight,sizeof(doublevar),1,f)) error("Misformatting in binary file",configfile);

    //Is anyone done?
    //When done, receive completed point and send out new point
    int done;
    MPI_Recv(&done,1,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_Comm_grp,&status);
    //cout << "master: received " << done << " from " << status.MPI_SOURCE << endl;
    done=1;
    pt.mpiReceive(status.MPI_SOURCE);
    MPI_Send(done,status.MPI_SOURCE);
    tmpconfig.mpiSend(status.MPI_SOURCE);
    MPI_Send(weight,status.MPI_SOURCE);
    //introduce completed point into the average
    //cout << "master: updating average " << endl;
    postavg.update_average(pt);
    totcount++;
    if(totcount%1000==0) cout << "Completed " << totcount << " walkers " << endl;
  }
  
  cout << "master: collecting final averages " << endl;
  
  //Loop through all the nodes and collect their last points, adding them in
  //Write out the final averages.
  for(int r=1; r < mpi_info.nprocs; r++) { 
    int done;
    MPI_Recv(done,r);
    done=0;
    pt.mpiReceive(r);
    MPI_Send(done,r);
    postavg.update_average(pt);
  }
  postavg.print(average_var,os);
  
#endif //USE_MPI
}