00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCRun.h"
00014
00015 QMCRun::~QMCRun()
00016 {
00017 delete QMF;
00018 QMF = 0;
00019 }
00020
00021 QMCRun::QMCRun()
00022 {
00023 populationSizeBiasCorrectionFactor = 1.0;
00024 }
00025
00026 void QMCRun::propagateWalkers(bool writeConfigs, int iteration)
00027 {
00028 int count = 0;
00029 int index = 0;
00030 int wpp = Input->flags.walkers_per_pass;
00031
00032 Array1D<QMCWalkerData *> dataPointers = 0;
00033 Array1D<Array2D<double> *> rPointers = 0;
00034 dataPointers.allocate(wpp);
00035 rPointers.allocate(wpp);
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 for(list<QMCWalker>::iterator wp=wlist.begin();wp!=wlist.end();++wp)
00047 {
00048 wp->initializePropagation(dataPointers(index),rPointers(index), iteration);
00049 count++;
00050 index = count%wpp;
00051 if(index == 0 || count == (int)(wlist.size()))
00052 {
00053 int num = index==0?wpp:index;
00054 QMF->evaluate(dataPointers,rPointers,num);
00055
00056 if(globalInput.cs_Parameters.dim1() > 1)
00057 {
00058
00059
00060 if(iteration >= 0)
00061 QMF->calculate_CorrelatedSampling(dataPointers,rPointers,num);
00062 }
00063 else
00064 {
00065 for(int i=0; i<num; i++)
00066 {
00067 dataPointers(i)->cs_LocalEnergy.deallocate();
00068 dataPointers(i)->cs_Weights.deallocate();
00069 }
00070 }
00071
00072 }
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 for(list<QMCWalker>::iterator wp=wlist.begin();wp!=wlist.end();++wp)
00082 wp->processPropagation(*QMF, writeConfigs);
00083 }
00084
00085 void QMCRun::branchWalkers()
00086 {
00087 if( Input->flags.run_type == "variational" )
00088 {
00089
00090 }
00091 else if( Input->flags.branching_method == "non_branching" )
00092 {
00093
00094 }
00095 else if( Input->flags.branching_method == "unit_weight_branching" )
00096 {
00097
00098
00099
00100
00101
00102 unitWeightBranching();
00103 }
00104 else if( Input->flags.branching_method == "nonunit_weight_branching" )
00105 {
00106
00107
00108
00109
00110
00111 nonunitWeightBranching();
00112 }
00113 else if( Input->flags.branching_method == "ack_reconfiguration" )
00114 {
00115
00116 ack_reconfiguration();
00117 }
00118 else
00119 {
00120 cerr << "ERROR: Unknown branching method!" << endl;
00121 exit(1);
00122 }
00123 }
00124
00125 void QMCRun::zeroOut()
00126 {
00127 for( list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp )
00128 wp->resetFutureWalking();
00129
00130 if (Input->flags.use_equilibration_array == 1)
00131 {
00132 EquilibrationArray.zeroOut();
00133 } else {
00134 Properties.zeroOut();
00135 fwProperties.zeroOut();
00136 }
00137 }
00138
00139 void QMCRun::initializeFunction()
00140 {
00141 QMF = QMCFunctionsFactory::functionsFactory(Input, Input->flags.trial_function_type);
00142
00143 if(Input->flags.trial_function_type == "restricted" ||
00144 Input->flags.trial_function_type == "unrestricted"){
00145 QMCSCFJastrow * qmfHFJ = static_cast<QMCSCFJastrow*>(QMF);
00146 qmfHFJ->initialize(Input,&HartreeFock);
00147 }
00148 }
00149
00150 void QMCRun::initialize(QMCInput *INPUT)
00151 {
00152 Input = INPUT;
00153
00154 initializeFunction();
00155
00156 if (Input->flags.calculate_bf_density == 1)
00157 {
00158 bool calcDensity = true;
00159 fwTimeStepProperties.setCalcDensity(calcDensity,
00160 Input->WF.getNumberBasisFunctions());
00161 if (Input->flags.use_equilibration_array == 1)
00162 EquilibrationArray.setCalcDensity(calcDensity,
00163 Input->WF.getNumberBasisFunctions());
00164 else
00165 fwProperties.setCalcDensity(calcDensity,
00166 Input->WF.getNumberBasisFunctions());
00167 }
00168
00169 if(Input->flags.nuclear_derivatives != "none")
00170 {
00171 int dim1, dim2;
00172 if(Input->flags.nuclear_derivatives != "bin_force_density")
00173 {
00174 dim1 = Input->Molecule.getNumberAtoms();
00175 dim2 = 3;
00176 } else {
00177 dim1 = QMCNuclearForces::getNumBins();
00178 dim2 = 1;
00179 }
00180
00181 bool calcForces = true;
00182 fwTimeStepProperties.setCalcForces(calcForces,dim1,dim2);
00183 if (Input->flags.use_equilibration_array == 1)
00184 {
00185 EquilibrationArray.setCalcForces(calcForces,dim1,dim2);
00186 } else {
00187 fwProperties.setCalcForces(calcForces,dim1,dim2);
00188 }
00189 }
00190
00191 if (Input->flags.use_equilibration_array == 1)
00192 {
00193 EquilibrationArray.zeroOut();
00194 } else {
00195 Properties.zeroOut();
00196 fwProperties.zeroOut();
00197 }
00198
00199 int nalpha = Input->WF.getNumberElectrons(true);
00200 int nbeta = Input->WF.getNumberElectrons(false);
00201
00202 if (Input->flags.write_electron_densities == 1)
00203 {
00204
00205
00206
00207
00208
00209
00210 int max_Z = 0;
00211
00212 if (Input->flags.max_pair_distance < 0)
00213 {
00214 for (int i=0; i<Input->Molecule.getNumberAtoms(); i++)
00215 if ( Input->Molecule.Z(i) > max_Z )
00216 max_Z = Input->Molecule.Z(i);
00217
00218 max_pair_distance = 20.0/max_Z;
00219 }
00220 else
00221 max_pair_distance = Input->flags.max_pair_distance;
00222
00223 dr = max_pair_distance/5000;
00224
00225
00226
00227 if (nalpha > 1 || nbeta > 1)
00228 {
00229 pllSpinHistogram.allocate(5000);
00230 pllSpinHistogram = 0.0;
00231 }
00232
00233 if (nalpha > 0 && nbeta > 0)
00234 {
00235 oppSpinHistogram.allocate(5000);
00236 oppSpinHistogram = 0.0;
00237 }
00238
00239
00240 int nucleiTypes = Input->Molecule.NucleiTypes.dim1();
00241
00242 if (nalpha > 0)
00243 {
00244 alphaHistograms.allocate(nucleiTypes);
00245 for (int k=0; k<nucleiTypes; k++)
00246 {
00247 alphaHistograms(k).allocate(5000);
00248 alphaHistograms(k) = 0.0;
00249 }
00250 }
00251
00252 if (nbeta > 0)
00253 {
00254 betaHistograms.allocate(nucleiTypes);
00255 for (int k=0; k<nucleiTypes; k++)
00256 {
00257 betaHistograms(k).allocate(5000);
00258 betaHistograms(k) = 0.0;
00259 }
00260 }
00261 }
00262
00263 if (nalpha > 1 || nbeta > 1)
00264 {
00265 if (Input->flags.writePllxCorrelationDiagram == 1)
00266 {
00267 if (Input->flags.pllxCorrelationDiagramMin >=
00268 Input->flags.pllxCorrelationDiagramMax)
00269 {
00270 cerr << "ERROR: pllxCorrelationDiagramMin = "
00271 << Input->flags.pllxCorrelationDiagramMin << ", "
00272 << "pllxCorrelationDiagramMax = "
00273 << Input->flags.pllxCorrelationDiagramMax << endl;
00274 exit(1);
00275 }
00276 pllxCorrelationDiagram.allocate(1000);
00277 for (int i=0; i<pllxCorrelationDiagram.dim1(); i++)
00278 {
00279 pllxCorrelationDiagram(i).allocate(1000);
00280 pllxCorrelationDiagram(i) = 0.0;
00281 }
00282 }
00283 if (Input->flags.writePllyCorrelationDiagram == 1)
00284 {
00285 if (Input->flags.pllyCorrelationDiagramMin >=
00286 Input->flags.pllyCorrelationDiagramMax)
00287 {
00288 cerr << "ERROR: pllyCorrelationDiagramMin = "
00289 << Input->flags.pllyCorrelationDiagramMin << ", "
00290 << "pllyCorrelationDiagramMax = "
00291 << Input->flags.pllyCorrelationDiagramMax << endl;
00292 exit(1);
00293 }
00294 pllyCorrelationDiagram.allocate(1000);
00295 for (int i=0; i<pllyCorrelationDiagram.dim1(); i++)
00296 {
00297 pllyCorrelationDiagram(i).allocate(1000);
00298 pllyCorrelationDiagram(i) = 0.0;
00299 }
00300 }
00301 if (Input->flags.writePllzCorrelationDiagram == 1)
00302 {
00303 if (Input->flags.pllzCorrelationDiagramMin >=
00304 Input->flags.pllzCorrelationDiagramMax)
00305 {
00306 cerr << "ERROR: pllzCorrelationDiagramMin = "
00307 << Input->flags.pllzCorrelationDiagramMin << ", "
00308 << "pllzCorrelationDiagramMax = "
00309 << Input->flags.pllzCorrelationDiagramMax << endl;
00310 exit(1);
00311 }
00312 pllzCorrelationDiagram.allocate(1000);
00313 for (int i=0; i<pllzCorrelationDiagram.dim1(); i++)
00314 {
00315 pllzCorrelationDiagram(i).allocate(1000);
00316 pllzCorrelationDiagram(i) = 0.0;
00317 }
00318 }
00319 }
00320
00321 if (nalpha > 0 && nbeta > 0)
00322 {
00323 if (Input->flags.writeOppxCorrelationDiagram == 1)
00324 {
00325 if (Input->flags.oppxCorrelationDiagramMin >=
00326 Input->flags.oppxCorrelationDiagramMax)
00327 {
00328 cerr << "ERROR: oppxCorrelationDiagramMin = "
00329 << Input->flags.oppxCorrelationDiagramMin << ", "
00330 << "oppxCorrelationDiagramMax = "
00331 << Input->flags.oppxCorrelationDiagramMax << endl;
00332 exit(1);
00333 }
00334 oppxCorrelationDiagram.allocate(1000);
00335 for (int i=0; i<oppxCorrelationDiagram.dim1(); i++)
00336 {
00337 oppxCorrelationDiagram(i).allocate(1000);
00338 oppxCorrelationDiagram(i) = 0.0;
00339 }
00340 }
00341 if (Input->flags.writeOppyCorrelationDiagram == 1)
00342 {
00343 if (Input->flags.oppyCorrelationDiagramMin >=
00344 Input->flags.oppyCorrelationDiagramMax)
00345 {
00346 cerr << "ERROR: oppyCorrelationDiagramMin = "
00347 << Input->flags.oppyCorrelationDiagramMin << ", "
00348 << "oppyCorrelationDiagramMax = "
00349 << Input->flags.oppyCorrelationDiagramMax << endl;
00350 exit(1);
00351 }
00352 oppyCorrelationDiagram.allocate(1000);
00353 for (int i=0; i<oppyCorrelationDiagram.dim1(); i++)
00354 {
00355 oppyCorrelationDiagram(i).allocate(1000);
00356 oppyCorrelationDiagram(i) = 0.0;
00357 }
00358 }
00359 if (Input->flags.writeOppzCorrelationDiagram == 1)
00360 {
00361 if (Input->flags.oppzCorrelationDiagramMin >=
00362 Input->flags.oppzCorrelationDiagramMax)
00363 {
00364 cerr << "ERROR: oppzCorrelationDiagramMin = "
00365 << Input->flags.oppzCorrelationDiagramMin << ", "
00366 << "oppzCorrelationDiagramMax = "
00367 << Input->flags.oppzCorrelationDiagramMax << endl;
00368 exit(1);
00369 }
00370 oppzCorrelationDiagram.allocate(1000);
00371 for (int i=0; i<oppzCorrelationDiagram.dim1(); i++)
00372 {
00373 oppzCorrelationDiagram(i).allocate(1000);
00374 oppzCorrelationDiagram(i) = 0.0;
00375 }
00376 }
00377 }
00378
00379 if (Input->flags.use_hf_potential == 1)
00380 HartreeFock.Initialize(Input);
00381 }
00382
00383 void QMCRun::randomlyInitializeWalkers()
00384 {
00385 Array2D<double> temp_R;
00386 int initialization_try = 0;
00387
00388 QMCInitializeWalker * IW =
00389 QMCInitializeWalkerFactory::initializeWalkerFactory(Input,
00390 Input->flags.walker_initialization_method);
00391
00392 wlist.clear();
00393 Input->flags.number_of_walkers = 0;
00394
00395 for (int i=0; i<Input->flags.number_of_walkers_initial; i++)
00396 {
00397 QMCWalker w;
00398 w.initialize(Input);
00399
00400 temp_R = IW->initializeWalkerPosition();
00401 int numtries = 0;
00402 while(w.setR(temp_R) == false){
00403 if(numtries > 10){
00404 cerr << "Error: initial walker " << i << " electronic position is bad, and we've tried " << numtries << " times." << endl;
00405 exit(0);
00406 } else {
00407 cerr << "Error: initial walker " << i << " electronic position is bad, retrying..." << endl;
00408 }
00409 cerr.flush();
00410 temp_R = IW->initializeWalkerPosition();
00411 numtries++;
00412 }
00413
00414 QMF->evaluate(*w.getR(),*w.getWalkerData());
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 double rel_diff = fabs( (w.getWalkerData()->localEnergy -
00426 Input->flags.energy_estimated_original)/
00427 Input->flags.energy_estimated_original);
00428 initialization_try = 1;
00429 while( (w.isSingular() || rel_diff > globalInput.flags.rel_cutoff) && initialization_try < 1000)
00430 {
00431 cerr << "Regenerating Walker " << i
00432 << " with energy " << w.getWalkerData()->localEnergy
00433 << ", rel_diff = " << rel_diff << "..." << endl;
00434 cerr.flush();
00435
00436 temp_R = IW->initializeWalkerPosition();
00437 w.setR(temp_R);
00438 QMF->evaluate(*w.getR(),*w.getWalkerData());
00439
00440 rel_diff = fabs( (w.getWalkerData()->localEnergy -
00441 Input->flags.energy_estimated_original)/
00442 Input->flags.energy_estimated_original);
00443
00444 initialization_try++;
00445 }
00446
00447 int cutoff = 100;
00448 if( initialization_try > cutoff )
00449 {
00450 cerr << "ERROR: " << initialization_try << " consecutive singular configurations while "
00451 << "trying to initialize walker!" << endl;
00452 }
00453
00454 w.newID();
00455 wlist.push_back(w);
00456 Input->flags.number_of_walkers++;
00457 }
00458 delete IW;
00459 IW = 0;
00460 }
00461
00462 void QMCRun::calculateObservables()
00463 {
00464
00465
00466
00467 timeStepProperties.zeroOut();
00468 fwTimeStepProperties.zeroOut();
00469
00470 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end();++wp)
00471 {
00472 wp->calculateObservables( timeStepProperties );
00473 wp->calculateObservables( fwTimeStepProperties );
00474 wp->calculateDerivatives( fwProperties );
00475 }
00476
00477
00478
00479 timeStepProperties.growthRate.newSample(growthRate,1.0);
00480
00481 double totalWeights = getWeights() * populationSizeBiasCorrectionFactor;
00482
00483 if (Input->flags.use_equilibration_array == 1)
00484 {
00485 EquilibrationArray.newSample(&timeStepProperties, totalWeights,
00486 getNumberOfWalkers());
00487 } else {
00488 Properties.newSample(&timeStepProperties,
00489 totalWeights,
00490 getNumberOfWalkers());
00491 fwProperties.newSample(&fwTimeStepProperties,
00492 totalWeights,
00493 getNumberOfWalkers());
00494 }
00495 }
00496
00497 void QMCRun::writeEnergies(ostream& strm)
00498 {
00499
00500
00501 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00502 strm << wp->getLocalEnergyEstimator() << "\t" << wp->getWeight() << endl;
00503 }
00504
00505 void QMCRun::calculateElectronDensities()
00506 {
00507 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00508 wp->calculateElectronDensities(max_pair_distance, dr, pllSpinHistogram,
00509 oppSpinHistogram, alphaHistograms, betaHistograms);
00510
00511 int nalpha = Input->WF.getNumberElectrons(true);
00512 int nbeta = Input->WF.getNumberElectrons(false);
00513
00514 if (nalpha > 1 || nbeta > 1)
00515 {
00516 if (Input->flags.writePllxCorrelationDiagram == 1)
00517 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00518 wp->calculatePllCorrelationDiagram(0,
00519 Input->flags.pllxCorrelationDiagramMin, Input->flags.pllxCorrelationDiagramMax,
00520 pllxCorrelationDiagram);
00521
00522 if (Input->flags.writePllyCorrelationDiagram == 1)
00523 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00524 wp->calculatePllCorrelationDiagram(1,
00525 Input->flags.pllyCorrelationDiagramMin, Input->flags.pllyCorrelationDiagramMax,
00526 pllyCorrelationDiagram);
00527
00528 if (Input->flags.writePllzCorrelationDiagram == 1)
00529 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00530 wp->calculatePllCorrelationDiagram(2,
00531 Input->flags.pllzCorrelationDiagramMin, Input->flags.pllzCorrelationDiagramMax,
00532 pllzCorrelationDiagram);
00533 }
00534
00535 if (nalpha > 0 && nbeta > 0)
00536 {
00537 if (Input->flags.writeOppxCorrelationDiagram == 1)
00538 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00539 wp->calculateOppCorrelationDiagram(0,
00540 Input->flags.oppxCorrelationDiagramMin, Input->flags.oppxCorrelationDiagramMax,
00541 oppxCorrelationDiagram);
00542
00543 if (Input->flags.writeOppyCorrelationDiagram == 1)
00544 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00545 wp->calculateOppCorrelationDiagram(1,
00546 Input->flags.oppyCorrelationDiagramMin, Input->flags.oppyCorrelationDiagramMax,
00547 oppyCorrelationDiagram);
00548
00549 if (Input->flags.writeOppzCorrelationDiagram == 1)
00550 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp)
00551 wp->calculateOppCorrelationDiagram(2,
00552 Input->flags.oppzCorrelationDiagramMin, Input->flags.oppzCorrelationDiagramMax,
00553 oppzCorrelationDiagram);
00554 }
00555 }
00556
00557 Array1D<double>* QMCRun::getPllSpinHistogram()
00558 {
00559 return &pllSpinHistogram;
00560 }
00561
00562 Array1D<double>* QMCRun::getOppSpinHistogram()
00563 {
00564 return &oppSpinHistogram;
00565 }
00566
00567 Array1D< Array1D<double> >* QMCRun::getAlphaHistograms()
00568 {
00569 return &alphaHistograms;
00570 }
00571
00572 Array1D< Array1D<double> >* QMCRun::getBetaHistograms()
00573 {
00574 return &betaHistograms;
00575 }
00576
00577 Array1D< Array1D<double> >* QMCRun::getPllxCorrelationDiagram()
00578 {
00579 return &pllxCorrelationDiagram;
00580 }
00581
00582 Array1D< Array1D<double> >* QMCRun::getPllyCorrelationDiagram()
00583 {
00584 return &pllyCorrelationDiagram;
00585 }
00586
00587 Array1D< Array1D<double> >* QMCRun::getPllzCorrelationDiagram()
00588 {
00589 return &pllzCorrelationDiagram;
00590 }
00591
00592 Array1D< Array1D<double> >* QMCRun::getOppxCorrelationDiagram()
00593 {
00594 return &oppxCorrelationDiagram;
00595 }
00596
00597 Array1D< Array1D<double> >* QMCRun::getOppyCorrelationDiagram()
00598 {
00599 return &oppyCorrelationDiagram;
00600 }
00601
00602 Array1D< Array1D<double> >* QMCRun::getOppzCorrelationDiagram()
00603 {
00604 return &oppzCorrelationDiagram;
00605 }
00606
00607 double QMCRun::getdr()
00608 {
00609 return dr;
00610 }
00611
00612 void QMCRun::unitWeightBranching()
00613 {
00614
00615 list<QMCWalker> WalkersToAdd;
00616 list<list<QMCWalker>::iterator> WalkersToDelete;
00617
00618 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end();++wp)
00619 {
00620 int times_to_branch = 0;
00621 if(wp->branchRecommended())
00622 times_to_branch = int(wp->getWeight() + ran.unidev())-1;
00623
00624
00625 wp->setWeight(1.0);
00626
00627 if( times_to_branch == 0 )
00628 {
00629
00630 }
00631 else if( times_to_branch < 0 )
00632 {
00633
00634
00635 WalkersToDelete.push_back( wp );
00636 }
00637 else
00638 {
00639
00640
00641 for(int i=0; i<times_to_branch; i++)
00642 {
00643 WalkersToAdd.push_back( *wp );
00644 wp->branchID();
00645 }
00646 }
00647 }
00648
00649 for( list< list<QMCWalker>::iterator >::iterator
00650 wtd=WalkersToDelete.begin(); wtd!=WalkersToDelete.end(); ++wtd)
00651 {
00652 wlist.erase( *wtd );
00653 }
00654
00655 wlist.splice( wlist.end(), WalkersToAdd );
00656 }
00657
00658 void QMCRun::nonunitWeightBranching()
00659 {
00660
00661 list<QMCWalker> WalkersToAdd;
00662 list<list<QMCWalker>::iterator> WalkersToDelete;
00663
00664 list<QMCWalker>::iterator TempWalkerToDelete;
00665 bool isTempWalkerToDelete = false;
00666
00667 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end();++wp)
00668 {
00669 if( wp->getWeight() > Input->flags.branching_threshold )
00670 {
00671 if(wp->branchRecommended())
00672 {
00673
00674 wp->setWeight( wp->getWeight()/2.0 );
00675
00676 WalkersToAdd.push_back( *wp );
00677 wp->branchID();
00678 }
00679 }
00680 else if( wp->getWeight() < 0.01 )
00681 {
00682 WalkersToDelete.push_back(wp);
00683 }
00684 else if( wp->getWeight() < Input->flags.fusion_threshold )
00685 {
00686
00687
00688 if( !isTempWalkerToDelete )
00689 {
00690
00691
00692 TempWalkerToDelete = wp;
00693 isTempWalkerToDelete = true;
00694 }
00695 else
00696 {
00697 double weight1 = TempWalkerToDelete->getWeight();
00698 double weight2 = wp->getWeight();
00699 double weight3 = weight1 + weight2;
00700
00701 if( ran.unidev() < weight1/weight3 )
00702 {
00703
00704
00705 TempWalkerToDelete->setWeight( weight3 );
00706 WalkersToDelete.push_back( wp );
00707 }
00708 else
00709 {
00710
00711
00712 wp->setWeight( weight3 );
00713 WalkersToDelete.push_back( TempWalkerToDelete );
00714 }
00715
00716 isTempWalkerToDelete = false;
00717 }
00718 }
00719 else
00720 {
00721
00722 }
00723 }
00724
00725 for(list< list<QMCWalker>::iterator >::iterator wtd=WalkersToDelete.begin();
00726 wtd!=WalkersToDelete.end(); ++wtd)
00727 {
00728 wlist.erase( *wtd );
00729 }
00730
00731 wlist.splice( wlist.end(), WalkersToAdd );
00732 }
00733
00734 void QMCRun::ack_reconfiguration()
00735 {
00736 double aveW = getWeights()/getNumberOfWalkers();
00737
00738 double Nreconfp = 0;
00739 double Nreconfn = 0;
00740 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end();++wp)
00741 {
00742 double w = wp->getWeight()/aveW;
00743 if(w >= 1.0){
00744 Nreconfp += fabs(w-1.0);
00745 } else {
00746 Nreconfn += fabs(w-1.0);
00747 }
00748 }
00749
00750 if(fabs(Nreconfp - Nreconfn) > 1e-5)
00751 {
00752 cerr << "Error: (Nreconfp = " << Nreconfp << ") != (Nreconfn = " << Nreconfn << ")" << endl;
00753 }
00754
00755 int Nreconf = (int)(Nreconfp + ran.unidev());
00756
00757
00758
00759 list<QMCWalker> WalkersToAdd;
00760 list<list<QMCWalker>::iterator> WalkersToDelete;
00761
00762 int numDeleted = 0;
00763 int numToAdd = Nreconf;
00764 numToAdd += Input->flags.number_of_walkers_initial - getNumberOfWalkers();
00765 while(numDeleted < Nreconf || numToAdd != 0)
00766 {
00767
00768
00769
00770
00771
00772 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end();++wp)
00773 {
00774 double w = wp->getWeight()/aveW;
00775
00776 if(w >= 1.0)
00777 {
00778 if( fabs(w - 1.0) >= ran.unidev() && numToAdd > 0)
00779 {
00780
00781 if(wp->branchRecommended())
00782 {
00783 numToAdd--;
00784 WalkersToAdd.push_back( *wp );
00785 wp->branchID();
00786 }
00787 }
00788 }
00789 else if(w > 1e-3)
00790 {
00791 if( fabs(w - 1.0) >= ran.unidev() && numDeleted < Nreconf)
00792 {
00793 numDeleted++;
00794 WalkersToDelete.push_back(wp);
00795 }
00796 }
00797 else
00798 {
00799 numToAdd++;
00800 WalkersToDelete.push_back(wp);
00801 }
00802
00803 }
00804
00805
00806 for(list< list<QMCWalker>::iterator >::iterator wtd=WalkersToDelete.begin();
00807 wtd!=WalkersToDelete.end(); ++wtd)
00808 {
00809 wlist.erase( *wtd );
00810 }
00811 WalkersToDelete.clear();
00812 }
00813
00814 wlist.splice( wlist.end(), WalkersToAdd );
00815
00816 for(list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end();++wp)
00817 {
00818
00819
00820 wp->setWeight(aveW);
00821 }
00822
00823 if(Input->flags.number_of_walkers_initial != getNumberOfWalkers())
00824 {
00825 cerr << "Warning: walkers didn't rebalance (" <<
00826 Input->flags.number_of_walkers_initial << "!=" <<
00827 getNumberOfWalkers() << ")" << endl;
00828 }
00829 }
00830
00831 double QMCRun::getWeights()
00832 {
00833
00834 double total_weights = 0.0;
00835
00836 for( list<QMCWalker>::iterator wp=wlist.begin(); wp!=wlist.end(); ++wp )
00837 total_weights += wp->getWeight();
00838
00839 return total_weights;
00840 }
00841
00842 double QMCRun::getPopulationSizeBiasCorrectionFactor()
00843 {
00844 return populationSizeBiasCorrectionFactor;
00845 }
00846
00847 void QMCRun::toXML(ostream& strm)
00848 {
00849 if (globalInput.flags.run_type == "diffusion")
00850 {
00851 strm << "<populationSizeBiasCorrectionFactor>\n\t"
00852 << populationSizeBiasCorrectionFactor
00853 << "\n</populationSizeBiasCorrectionFactor>" << endl;
00854
00855 queue<double> temp_CD = correctionDivisor;
00856
00857 int cDsize = temp_CD.size();
00858
00859 strm << "<correctionDivisorSize>\n\t" << cDsize
00860 << "\n</correctionDivisorSize>" << endl;
00861 strm << "<correctionDivisor>\n";
00862 for (int i=0; i<cDsize; i++)
00863 {
00864 strm << temp_CD.front() << endl;
00865 temp_CD.pop();
00866 }
00867 strm << "</correctionDivisor>" << endl;
00868 }
00869
00870 if (Input->flags.use_equilibration_array == 1)
00871 EquilibrationArray.toXML(strm);
00872 else
00873 {
00874 Properties.toXML(strm);
00875 if (Input->flags.future_walking.size() > 1)
00876 fwProperties.toXML(strm);
00877 }
00878
00879
00880 strm << "<walkers>" << endl;
00881
00882 for(list <QMCWalker>::iterator wp=wlist.begin();wp!=wlist.end();++wp)
00883 {
00884 wp->toXML(strm);
00885 }
00886 strm << "</walkers>\n" << endl;
00887 }
00888
00889 bool QMCRun::readXML(istream& strm)
00890 {
00891 string temp;
00892
00893 if (globalInput.flags.run_type == "diffusion")
00894 {
00895
00896 strm >> temp;
00897 if (temp != "<populationSizeBiasCorrectionFactor>")
00898 return false;
00899 strm >> temp;
00900 populationSizeBiasCorrectionFactor = atof(temp.c_str());
00901 strm >> temp;
00902 if (temp != "</populationSizeBiasCorrectionFactor>")
00903 return false;
00904
00905 strm >> temp;
00906 if (temp != "<correctionDivisorSize>")
00907 return false;
00908 strm >> temp;
00909 int cDsize = atoi(temp.c_str());
00910 strm >> temp;
00911 if (temp != "</correctionDivisorSize>")
00912 return false;
00913
00914 strm >> temp;
00915 if (temp != "<correctionDivisor>")
00916 return false;
00917 for (int i=0; i<cDsize; i++)
00918 {
00919 strm >> temp;
00920 correctionDivisor.push(atof(temp.c_str()));
00921 }
00922 strm >> temp;
00923 if (temp != "</correctionDivisor>")
00924 return false;
00925 }
00926
00927
00928 if (Input->flags.use_equilibration_array == 1)
00929 {
00930 if (!EquilibrationArray.readXML(strm))
00931 return false;
00932 }
00933 else
00934 {
00935 if (!Properties.readXML(strm))
00936 return false;
00937 if (Input->flags.future_walking.size() > 1)
00938 if (!fwProperties.readXML(strm))
00939 return false;
00940 }
00941
00942
00943
00944 strm >> temp;
00945 if (temp != "<walkers>")
00946 return false;
00947 wlist.clear();
00948 for(int i=0; i<Input->flags.number_of_walkers; i++)
00949 {
00950 QMCWalker w;
00951 w.initialize(Input);
00952
00953
00954 if (!w.readXML(strm,*QMF))
00955 return false;
00956
00957 wlist.push_back(w);
00958 }
00959
00960 strm >> temp;
00961 if (temp != "</walkers>")
00962 return false;
00963
00964 return true;
00965 }
00966
00967 void QMCRun::startTimers()
00968 {
00969 EquilibrationArray.startTimers();
00970 }
00971
00972 void QMCRun::stopTimers()
00973 {
00974 EquilibrationArray.stopTimers();
00975 }
00976
00977 Stopwatch * QMCRun::getPropagationStopwatch()
00978 {
00979 return EquilibrationArray.getPropagationStopwatch();
00980 }
00981
00982 Stopwatch * QMCRun::getEquilibrationStopwatch()
00983 {
00984 return EquilibrationArray.getEquilibrationStopwatch();
00985 }
00986
00987 QMCProperties * QMCRun::getTimeStepProperties()
00988 {
00989 return &timeStepProperties;
00990 }
00991
00992 QMCProperties * QMCRun::getProperties()
00993 {
00994 if (Input->flags.use_equilibration_array == 1)
00995 return EquilibrationArray.chooseDecorrObject();
00996 else
00997 return &Properties;
00998 }
00999
01000 QMCPropertyArrays * QMCRun::getFWTimeStepProperties()
01001 {
01002 return &fwTimeStepProperties;
01003 }
01004
01005 QMCPropertyArrays * QMCRun::getFWProperties()
01006 {
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 return &fwProperties;
01017 }
01018
01019 int QMCRun::getNumberOfWalkers()
01020 {
01021 return (int)wlist.size();
01022 }
01023
01024 bool QMCRun::step(bool writeConfigs, int iteration)
01025 {
01026 propagateWalkers(writeConfigs,iteration);
01027 calculatePopulationSizeBiasCorrectionFactor();
01028 calculateObservables();
01029
01030 int step = iteration + Input->flags.equilibration_steps - 1;
01031
01032 int whichE = -1;
01033 if(globalInput.flags.one_e_per_iter != 0)
01034 whichE = step % globalInput.WF.getNumberElectrons();
01035
01036 if(whichE == -1 || whichE == 0)
01037 {
01038
01039
01040
01041
01042
01043
01044 growthRate = getNumberOfWalkers();
01045 branchWalkers();
01046 growthRate -= getNumberOfWalkers();
01047 }
01048
01049 if(getWeights() <= 0.0 || getNumberOfWalkers() == 0)
01050 {
01051 cerr << "Error on node " << Input->flags.my_rank << ":" << endl;
01052 cerr << " number walkers = " << getNumberOfWalkers() << endl;
01053 cerr << " total weight = " << getWeights() << endl;
01054 cerr << " energy_estimated = " << Input->flags.energy_estimated << endl;
01055 cerr << " energy_trial = " << Input->flags.energy_trial << endl;
01056 cerr << " energy_original = " << Input->flags.energy_estimated_original << endl;
01057 cerr << " we're going to reinitialize all walkers..." << endl;
01058
01059 Input->flags.energy_estimated = Input->flags.energy_estimated_original;
01060 Input->flags.energy_trial = Input->flags.energy_estimated_original;
01061 randomlyInitializeWalkers();
01062 return false;
01063 }
01064 return true;
01065 }
01066
01067 void QMCRun::calculatePopulationSizeBiasCorrectionFactor()
01068 {
01069 if( Input->flags.correct_population_size_bias &&
01070 Input->flags.run_type != "variational" )
01071 {
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 const unsigned int Tp = (int)(1.0/Input->flags.dt);
01085
01086
01087
01088
01089
01090
01091
01092 double temp = Input->flags.energy_trial - Input->flags.energy_estimated_original;
01093
01094
01095
01096 temp *= -Input->flags.dt_effective;
01097
01098 temp = exp(temp);
01099 populationSizeBiasCorrectionFactor *= temp;
01100
01101
01102
01103 correctionDivisor.push(temp);
01104 if(correctionDivisor.size() > Tp)
01105 {
01106 populationSizeBiasCorrectionFactor /= correctionDivisor.front();
01107 correctionDivisor.pop();
01108 }
01109
01110 if (IeeeMath::isNaN(populationSizeBiasCorrectionFactor))
01111 {
01112 cerr << "Error in QMCRun::calculatePopulationSizeBiasCorrectionFactor()" << endl;
01113 cerr << " energy_trial = " << Input->flags.energy_trial << endl;
01114 cerr << " dt_effective = " << Input->flags.dt_effective << endl;
01115 cerr << " multiplier = " << temp << endl;
01116 exit(1);
01117 }
01118 }
01119 }
01120
01121
01122
01123 void QMCRun::updateHFPotential()
01124 {
01125 int numelecs = Input->WF.getNumberElectrons();
01126
01127 for (list<QMCWalker>::iterator wp = wlist.begin(); wp != wlist.end(); ++wp)
01128 {
01129 Array2D<double> positions = *(wp->getR());
01130 for (int i = 0; i < numelecs; i++)
01131 HartreeFock.AddElectron(i,wp->getWeight(),positions(i,0),
01132 positions(i,1), positions(i, 2));
01133 HartreeFock.IncrementSample();
01134 }
01135 }