00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCSCFJastrow.h"
00014
00015 QMCSCFJastrow::QMCSCFJastrow()
00016 {
00017 nalpha = 0;
00018 nbeta = 0;
00019 wd = 0;
00020 x = 0;
00021 }
00022
00023 QMCSCFJastrow::QMCSCFJastrow(QMCInput *INPUT, QMCHartreeFock *HF)
00024 {
00025 initialize(INPUT,HF);
00026 }
00027
00028 QMCSCFJastrow::QMCSCFJastrow(QMCInput *INPUT)
00029 {
00030 QMCHartreeFock* HF = 0;
00031 initialize(INPUT,HF);
00032 }
00033
00034 QMCSCFJastrow::QMCSCFJastrow(const QMCSCFJastrow & rhs )
00035 {
00036 *this = rhs;
00037 }
00038
00039 QMCSCFJastrow::~QMCSCFJastrow()
00040 {
00041 }
00042
00043 void QMCSCFJastrow::operator=(const QMCSCFJastrow & rhs )
00044 {
00045 Input = rhs.Input;
00046
00047 nalpha = rhs.nalpha;
00048 nbeta = rhs.nbeta;
00049
00050 Alpha = rhs.Alpha;
00051 Beta = rhs.Beta;
00052
00053 Jastrow = rhs.Jastrow;
00054 PE = rhs.PE;
00055
00056 Psi = rhs.Psi;
00057 Laplacian_PsiRatio = rhs.Laplacian_PsiRatio;
00058 E_Local = rhs.E_Local;
00059 }
00060
00061 void QMCSCFJastrow::initialize(QMCInput *INPUT, QMCHartreeFock *HF)
00062 {
00063 Input = INPUT;
00064
00065 nalpha = Input->WF.getNumberElectrons(true);
00066 nbeta = Input->WF.getNumberElectrons(false);
00067
00068 Alpha.initialize(Input,
00069 0,
00070 nalpha-1,
00071 true);
00072
00073 Beta.initialize(Input,
00074 nalpha,
00075 Input->WF.getNumberElectrons()-1,
00076 false);
00077
00078 PE.initialize(Input,HF);
00079 Jastrow.initialize(Input);
00080
00081 if(Input->flags.nuclear_derivatives != "none")
00082 nf.initialize(Input);
00083
00084 wd = 0;
00085 x = 0;
00086 }
00087
00088 void QMCSCFJastrow::evaluate(Array1D<QMCWalkerData *> &walkerData,
00089 Array1D<Array2D<double> * > &xData,
00090 int num)
00091 {
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 int gpp = Input->flags.getNumGPUWalkers();
00102
00103 #ifdef QMC_GPU
00104
00105 Alpha.gpuEvaluate(xData,gpp);
00106 Beta.gpuEvaluate(xData,gpp);
00107 Jastrow.setUpGPU(Alpha.gpuBF.getElectronicTexture(),
00108 Beta.gpuBF.getElectronicTexture(), gpp);
00109 #endif
00110
00111
00112
00113
00114
00115
00116 Jastrow.evaluate(walkerData,xData,num-gpp,gpp);
00117 int whichE = walkerData(0)->whichE;
00118
00119 if((whichE >= 0 && whichE < nalpha) || whichE == -1)
00120 Alpha.evaluate(xData,num-gpp,gpp,whichE);
00121 if(whichE >= nalpha || whichE == -1)
00122 Beta.evaluate(xData,num-gpp,gpp,whichE);
00123
00124 if(Input->flags.nuclear_derivatives != "none")
00125 nf.evaluate(walkerData,xData,num);
00126
00127 #ifdef QMC_GPU
00128
00129 if(true)
00130 {
00131 Stopwatch finisher = Stopwatch();
00132 finisher.reset();
00133 finisher.start();
00134 glFinish();
00135 finisher.stop();
00136 printf("finish time: %15d\n", finisher.timeUS() );
00137 }
00138 #endif
00139
00140
00141 Alpha.update_Ds(walkerData);
00142 Beta.update_Ds(walkerData);
00143
00144 PE.evaluate(xData,walkerData,num);
00145 #ifdef QMC_GPU
00146
00147 Jastrow.gpuEvaluate(xData,gpp);
00148 #endif
00149
00150 for(int i=0; i<num; i++)
00151 {
00152
00153
00154
00155
00156 wd = walkerData(i);
00157 x = xData(i);
00158 iWalker = i;
00159
00160 calculate_Psi_quantities();
00161 calculate_Modified_Grad_PsiRatio();
00162 calculate_E_Local(i);
00163
00164 wd->localEnergy = getLocalEnergy();
00165 wd->kineticEnergy = getKineticEnergy();
00166 wd->potentialEnergy = getPotentialEnergy(i);
00167 wd->neEnergy = getEnergyNE(i);
00168 wd->eeEnergy = getEnergyEE(i);
00169 wd->psi = getPsi();
00170 wd->singular |= isSingular(i);
00171
00172
00173 }
00174
00175
00176
00177
00178
00179 wd = 0;
00180 x = 0;
00181 iWalker = -1;
00182 }
00183
00184 void QMCSCFJastrow::evaluate(Array2D<double> &X, QMCWalkerData & data)
00185 {
00186 Array1D< Array2D<double>* > temp(1);
00187 temp(0) = &X;
00188
00189 Array1D<QMCWalkerData *> wdArray(1);
00190 wdArray(0) = &data;
00191
00192 evaluate(wdArray,temp,1);
00193 }
00194
00195
00196
00197 void QMCSCFJastrow::calculate_Psi_quantities()
00198 {
00199 assert(wd);
00200
00201 if(Alpha.isSingular(iWalker) || Beta.isSingular(iWalker))
00202 {
00203
00204
00205
00206
00207
00208 wd->singular = true;
00209 return;
00210 }
00211
00212 term_AlphaGrad = 0;
00213 term_BetaGrad = 0;
00214
00215 alphaPsi = Alpha.getPsi(iWalker);
00216 alphaGrad = Alpha.getGradPsiRatio(iWalker);
00217 alphaLaplacian = Alpha.getLaplacianPsiRatio(iWalker);
00218
00219 betaPsi = Beta.getPsi(iWalker);
00220 betaGrad = Beta.getGradPsiRatio(iWalker);
00221 betaLaplacian = Beta.getLaplacianPsiRatio(iWalker);
00222
00223 update_SCF();
00224
00225 QMCDouble Jastrow_Psi = Jastrow.getJastrow(iWalker);
00226
00227 Psi = wd->D * Jastrow_Psi;
00228
00229
00230 Laplacian_PsiRatio = wd->D_xx + wd->U_xx;
00231
00232 wd->gradPsiRatio = 0.0;
00233 for (int i=0; i<Input->WF.getNumberElectrons(); i++)
00234 for (int j=0; j<3; j++)
00235 {
00236 wd->gradPsiRatio(i,j) = wd->D_x(i,j) + wd->U_x(i,j);
00237
00238
00239 Laplacian_PsiRatio += wd->U_x(i,j) * wd->D_x(i,j) * 2.0;
00240
00241 Laplacian_PsiRatio += wd->U_x(i,j) * wd->U_x(i,j);
00242 }
00243
00244 if(Input->flags.calculate_Derivatives == 1)
00245 {
00246 int numAI = Input->getNumberAIParameters();
00247
00248 if(wd->rp_a.dim1() != numAI)
00249 {
00250 wd->rp_a.allocate(numAI);
00251 wd->p3_xxa.allocate(numAI);
00252 }
00253
00254 wd->p3_xxa = 0.0;
00255
00256 int ai = 0;
00257 calculate_JastrowDerivatives(ai);
00258 calculate_CIDerivatives(ai);
00259 calculate_OrbitalDerivatives(ai);
00260
00261 if(ai != numAI)
00262 {
00263 clog << "Error: our parameter counting went bad...\n"
00264 << " ai = " << ai << endl
00265 << " numAI = " << numAI << endl;
00266 exit(0);
00267 }
00268
00269
00270
00271 wd->p3_xxa *= -0.5;
00272 }
00273
00274
00275 if (Input->flags.calculate_bf_density == 1)
00276 {
00277 wd->chiDensity = 0.0;
00278 if (nalpha > 0)
00279 wd->chiDensity = wd->chiDensity + *(Alpha.getChiDensity(iWalker));
00280 if (nbeta > 0)
00281 wd->chiDensity = wd->chiDensity + *(Beta.getChiDensity(iWalker));
00282 }
00283 }
00284
00285 void QMCSCFJastrow::update_SCF()
00286 {
00287 Array1D<QMCDouble> termPsiRatio(Input->WF.getNumberDeterminants());
00288
00289 termPR.allocate(Input->WF.getNumberDeterminants());
00290
00291 wd->D = 0.0;
00292
00293 for (int ci=0; ci<Input->WF.getNumberDeterminants(); ci++)
00294 {
00295 termPsiRatio(ci) = QMCDouble(Input->WF.CI_coeffs(ci));
00296 termPsiRatio(ci).multiplyBy((*alphaPsi)(ci));
00297 termPsiRatio(ci).multiplyBy((*betaPsi)(ci));
00298 wd->D += termPsiRatio(ci);
00299 }
00300
00301 if(!wd->D.isZero())
00302 termPsiRatio /= wd->D;
00303
00304 for(int ci=0; ci<termPR.dim1(); ci++)
00305 termPR(ci) = (double)termPsiRatio(ci);
00306 termPsiRatio.deallocate();
00307
00308 wd->D_xx = 0.0;
00309 wd->D_x = 0.0;
00310 for (int ci=0; ci<Input->WF.getNumberDeterminants(); ci++)
00311 {
00312 if(alphaGrad) term_AlphaGrad = alphaGrad->array()[ci];
00313 if(betaGrad) term_BetaGrad = betaGrad->array()[ci];
00314
00315 if(nalpha > 0)
00316 wd->D_xx += termPR(ci) * (*alphaLaplacian)(ci);
00317 if(nbeta > 0)
00318 wd->D_xx += termPR(ci) * (*betaLaplacian)(ci);
00319
00320 for (int e=0; e<nalpha; e++)
00321 for (int k=0; k<3; k++)
00322 wd->D_x(e,k) += termPR(ci)*term_AlphaGrad[e][k];
00323
00324 for (int e=0; e<nbeta; e++)
00325 for (int k=0; k<3; k++)
00326 wd->D_x(e+nalpha,k) += termPR(ci)*term_BetaGrad[e][k];
00327 }
00328 }
00329
00330 void QMCSCFJastrow::calculate_Modified_Grad_PsiRatio()
00331 {
00332
00333
00334 double a = 0.0;
00335 double factor = 0.0;
00336
00337 if( Input->flags.QF_modification_type == "none" )
00338
00339 wd->modifiedGradPsiRatio = wd->gradPsiRatio;
00340
00341 else if( Input->flags.QF_modification_type == "umrigar93_equalelectrons" )
00342 {
00343
00344
00345
00346 a = Input->flags.umrigar93_equalelectrons_parameter;
00347
00348 if( a>1 || a<=0 )
00349 {
00350 cerr << "ERROR: Improper value for "
00351 << "umrigar93_equalelectrons_parameter!\n The value should be"
00352 << " between 0 and 1 inclusive of 1 and exclusive of 0."
00353 << endl;
00354 exit(0);
00355 }
00356
00357
00358 double magsqQF = 0.0;
00359 for(int i=0; i<wd->gradPsiRatio.dim1(); i++)
00360 for(int j=0; j<wd->gradPsiRatio.dim2(); j++)
00361 magsqQF += wd->gradPsiRatio(i,j) * wd->gradPsiRatio(i,j);
00362
00363 factor = ( -1.0 + sqrt( 1.0 + 2*a*magsqQF*Input->flags.dt )) /
00364 ( a*magsqQF*Input->flags.dt);
00365
00366 wd->modifiedGradPsiRatio = wd->gradPsiRatio;
00367 wd->modifiedGradPsiRatio *= factor;
00368 }
00369 else if( Input->flags.QF_modification_type == "umrigar93_unequalelectrons" )
00370 {
00371
00372
00373
00374 wd->modifiedGradPsiRatio = wd->gradPsiRatio;
00375 Array1D<double> closest_nucleus_to_electron_norm_vector(3);
00376 Array1D<double> electron_velocity_norm_vector(3);
00377 for(int i=0; i<wd->modifiedGradPsiRatio.dim1(); i++)
00378 {
00379
00380 int closest_nucleus_index = Input->Molecule.findClosestNucleusIndex(wd->riA,i);
00381
00382
00383
00384 int closest_nucleus_Z =
00385 Input->Molecule.Z(closest_nucleus_index);
00386
00387 double closest_nucleus_distance_squared = 0.0;
00388 double temp;
00389
00390
00391 for(int xyz=0; xyz<3; xyz++)
00392 {
00393 temp = (*x)(i,xyz) -
00394 Input->Molecule.Atom_Positions(closest_nucleus_index,xyz);
00395
00396 closest_nucleus_to_electron_norm_vector(xyz) = temp;
00397 closest_nucleus_distance_squared += temp*temp;
00398 }
00399 closest_nucleus_to_electron_norm_vector *=
00400 1.0/sqrt(closest_nucleus_distance_squared);
00401
00402
00403 for(int xyz=0; xyz<3; xyz++)
00404 electron_velocity_norm_vector(xyz) = wd->gradPsiRatio(i,xyz);
00405
00406 double electron_velocity_norm_squared =
00407 electron_velocity_norm_vector * electron_velocity_norm_vector;
00408
00409 if (fabs(electron_velocity_norm_squared) < 1e-10)
00410 electron_velocity_norm_vector *= 0.0;
00411 else
00412 electron_velocity_norm_vector *= 1.0/sqrt(
00413 electron_velocity_norm_squared );
00414
00415
00416 temp = closest_nucleus_Z * closest_nucleus_Z *
00417 closest_nucleus_distance_squared;
00418
00419 a = 0.5*(1.0 + closest_nucleus_to_electron_norm_vector *
00420 electron_velocity_norm_vector) + temp/(10.0*(4.0+temp));
00421
00422
00423 if (fabs(electron_velocity_norm_squared) < 1e-10)
00424 factor = 1.0;
00425 else
00426 factor = (-1.0 + sqrt(1.0+2.0*a*electron_velocity_norm_squared*
00427 Input->flags.dt))/
00428 (a*electron_velocity_norm_squared*Input->flags.dt);
00429
00430
00431 for(int xyz=0; xyz<3; xyz++)
00432 wd->modifiedGradPsiRatio(i,xyz) *= factor;
00433 }
00434 }
00435 else
00436 {
00437 cerr << "ERROR: Unknown value for QF_modification_type set!" << endl;
00438 exit(0);
00439 }
00440
00441 Array2D<double> * tMGPR = & wd->modifiedGradPsiRatio;
00442 Array2D<double> * tGPR = & wd->gradPsiRatio;
00443
00444 double lengthGradTrialModified =
00445 sqrt((*tMGPR).dotAllElectrons(*tMGPR));
00446 double lengthGradTrialUnmodified =
00447 sqrt((*tGPR).dotAllElectrons(*tGPR));
00448
00449 wd->modificationRatio = lengthGradTrialModified/lengthGradTrialUnmodified;
00450
00451 if (IeeeMath::isNaN(lengthGradTrialModified) ||
00452 IeeeMath::isNaN(lengthGradTrialUnmodified) ||
00453 IeeeMath::isNaN(wd->modificationRatio) ||
00454 lengthGradTrialUnmodified == 0)
00455 {
00456 cerr << "WARNING: trial Grad Psi Ratio is NaN ";
00457 cerr << " lengthGradTrialModified = " << lengthGradTrialModified << endl;
00458 cerr << " lengthGradTrialUnmodified = " << lengthGradTrialUnmodified << endl;
00459 wd->singular = true;
00460 }
00461 }
00462
00463 bool QMCSCFJastrow::isSingular(int whichWalker)
00464 {
00465 if(Alpha.isSingular(whichWalker) ||
00466 Beta.isSingular(whichWalker))
00467 return true;
00468 else
00469 return false;
00470 }
00471
00472 void QMCSCFJastrow::calculate_JastrowDerivatives(int & ai)
00473 {
00474 for(int ji=0; ji<Input->JP.getNumberJWParameters(); ji++)
00475 {
00476 wd->rp_a(ai) = Jastrow.get_p_a_ln(iWalker,ji);
00477 wd->p3_xxa(ai) = Jastrow.get_p3_xxa_ln(iWalker,ji);
00478
00479 Array2D<double>* j_p_xa = Jastrow.get_p2_xa_ln(iWalker,ji);
00480
00481 for (int i=0; i<Input->WF.getNumberElectrons(); i++)
00482 for (int j=0; j<3; j++)
00483 {
00484 wd->p3_xxa(ai) += 2.0 * (*j_p_xa)(i,j) * wd->D_x(i,j);
00485 wd->p3_xxa(ai) += 2.0 * (*j_p_xa)(i,j) * wd->U_x(i,j);
00486 }
00487 ai++;
00488 }
00489 }
00490
00491 void QMCSCFJastrow::calculate_CIDerivatives(int & ai)
00492 {
00493 if(Input->WF.getNumberCIParameters() <= 0)
00494 return;
00495
00496 Array1D<double> rp_a(Input->WF.getNumberDeterminants());
00497 rp_a = 0.0;
00498 Array1D<double> p3_xxa(Input->WF.getNumberDeterminants());
00499 p3_xxa = 0.0;
00500
00501 Array1D<double> gradSum(Input->WF.getNumberDeterminants());
00502 gradSum = 0.0;
00503
00504 for(int cj=0; cj<Input->WF.getNumberDeterminants(); cj++)
00505 {
00506 if(alphaGrad) term_AlphaGrad = alphaGrad->array()[cj];
00507 if(betaGrad) term_BetaGrad = betaGrad->array()[cj];
00508 for(int i=0; i<nalpha; i++)
00509 for(int j=0; j<3; j++)
00510 gradSum(cj) += 2.0 * term_AlphaGrad[i][j] * wd->U_x(i,j);
00511 for(int i=0; i<nbeta; i++)
00512 for(int j=0; j<3; j++)
00513 gradSum(cj) += 2.0 * term_BetaGrad[i][j] * wd->U_x(i+nalpha,j);
00514
00515 if(nalpha > 0)
00516 gradSum(cj) += (*alphaLaplacian)(cj);
00517 if(nbeta > 0)
00518 gradSum(cj) += (*betaLaplacian)(cj);
00519
00520 }
00521
00522
00523 for(int ci=0; ci<Input->WF.getNumberDeterminants(); ci++)
00524 {
00525 rp_a(ci) = termPR(ci) / Input->WF.CI_coeffs(ci);
00526
00527 p3_xxa(ci) += (-termPR(ci) * termPR(ci) + termPR(ci)) * gradSum(ci);
00528
00529 for(int cj=0; cj<Input->WF.getNumberDeterminants(); cj++)
00530 {
00531 if(ci == cj) continue;
00532 p3_xxa(ci) += -termPR(ci) * termPR(cj) * gradSum(cj);
00533 }
00534 p3_xxa(ci) /= Input->WF.CI_coeffs(ci);
00535 }
00536
00537 for(int ci=0; ci<Input->WF.getNumberDeterminants(); ci++)
00538 {
00539 int c = Input->WF.CI_constraints(ci);
00540 if(c != -1){
00541 rp_a(c) += rp_a(ci);
00542 rp_a(ci) = 0.0;
00543 p3_xxa(c) += p3_xxa(ci);
00544 p3_xxa(ci) = 0.0;
00545 }
00546 }
00547
00548 for(int ci=0; ci<Input->WF.getNumberDeterminants(); ci++)
00549 {
00550 if(fabs(rp_a(ci)) > 1e-30){
00551
00552 wd->rp_a(ai) = rp_a(ci);
00553 wd->p3_xxa(ai) = p3_xxa(ci);
00554 ai++;
00555 }
00556 }
00557 }
00558
00559 void QMCSCFJastrow::calculate_OrbitalDerivatives(int & aic)
00560 {
00561 int numDet = Input->WF.getNumberDeterminants();
00562 int unusedIndicator = Input->WF.getUnusedIndicator();
00563 Array1D<double> dtermPsi_dai(numDet);
00564 if(aic >= Input->getNumberAIParameters())
00565 return;
00566
00567 Array1D<double> rp_a(Input->WF.OR_constraints.dim1());
00568 rp_a = 0.0;
00569 Array1D<double> p3_xxa(Input->WF.OR_constraints.dim1());
00570 p3_xxa = 0.0;
00571
00572 int ai = -1;
00573 for(int o=0; o<Input->WF.getNumberOrbitals(); o++)
00574 {
00575 bool used = false;
00576 for(int ci=0; ci<Input->WF.getNumberDeterminants(); ci++)
00577 {
00578 if(Input->WF.AlphaOccupation(ci,o) != unusedIndicator ||
00579 Input->WF.BetaOccupation(ci,o) != unusedIndicator)
00580 {
00581 used = true;
00582 break;
00583 }
00584 }
00585
00586
00587 if(!used) continue;
00588
00589
00590 for(int bf=0; bf<Input->WF.getNumberBasisFunctions(); bf++)
00591 {
00592 ai++;
00593 if(globalInput.WF.OR_constraints(ai) == -2)
00594 continue;
00595
00596 dtermPsi_dai = 0.0;
00597 double dSCF_Psi_dai = 0.0;
00598
00599 for(int ci=0; ci<numDet; ci++)
00600 {
00601 int oa = Input->WF.AlphaOccupation(ci,o);
00602 int ob = Input->WF.BetaOccupation(ci,o);
00603
00604 double dtermPsi_a = 0.0;
00605 if(oa != unusedIndicator)
00606 dtermPsi_a += Alpha.get_p_a(iWalker,ci)->get(oa,bf) * (*betaPsi)(ci);
00607 if(ob != unusedIndicator)
00608 dtermPsi_a += Beta.get_p_a(iWalker,ci)->get(ob,bf) * (*alphaPsi)(ci);
00609
00610
00611 if(dtermPsi_a == 0) continue;
00612
00613 dtermPsi_a *= Input->WF.CI_coeffs(ci);
00614 dtermPsi_dai(ci) = dtermPsi_a;
00615 dSCF_Psi_dai += dtermPsi_a;
00616 }
00617
00618 rp_a(ai) = dSCF_Psi_dai / wd->D;
00619
00620 for(int ci=0; ci<numDet; ci++)
00621 {
00622 int oa = Input->WF.AlphaOccupation(ci,o);
00623 int ob = Input->WF.BetaOccupation(ci,o);
00624
00625
00626 double dtermPsiRatio_dai;
00627 dtermPsiRatio_dai = (dtermPsi_dai(ci) - termPR(ci) * dSCF_Psi_dai) / wd->D;
00628
00629
00630 if(nalpha > 0)
00631 p3_xxa(ai) += dtermPsiRatio_dai * (*alphaLaplacian)(ci);
00632 if(nbeta > 0)
00633 p3_xxa(ai) += dtermPsiRatio_dai * (*betaLaplacian)(ci);
00634
00635 if(oa != unusedIndicator)
00636 p3_xxa(ai) += termPR(ci) * Alpha.get_p3_xxa(iWalker,ci)->get(oa,bf);
00637 if(ob != unusedIndicator)
00638 p3_xxa(ai) += termPR(ci) * Beta.get_p3_xxa(iWalker,ci)->get(ob,bf);
00639
00640
00641 double Term_dSlater_a = 0.0;
00642 if(oa != unusedIndicator)
00643 for(int i=0; i<nalpha; i++)
00644 for(int j=0; j<3; j++)
00645 Term_dSlater_a += Alpha.get_p2_xa(iWalker,ci,i,j)->get(oa,bf) * wd->U_x(i,j);
00646 if(ob != unusedIndicator)
00647 for(int i=0; i<nbeta; i++)
00648 for(int j=0; j<3; j++)
00649 Term_dSlater_a += Beta.get_p2_xa(iWalker,ci,i,j)->get(ob,bf) * wd->U_x(i+nalpha,j);
00650 Term_dSlater_a *= 2.0 * termPR(ci);
00651
00652 if(alphaGrad) term_AlphaGrad = alphaGrad->array()[ci];
00653 if(betaGrad) term_BetaGrad = betaGrad->array()[ci];
00654
00655 double Slater_dTerm_a = 0.0;
00656 for(int i=0; i<nalpha; i++)
00657 for(int j=0; j<3; j++)
00658 Slater_dTerm_a += term_AlphaGrad[i][j] * wd->U_x(i,j);
00659 for(int i=0; i<nbeta; i++)
00660 for(int j=0; j<3; j++)
00661 Slater_dTerm_a += term_BetaGrad[i][j] * wd->U_x(i+nalpha,j);
00662 Slater_dTerm_a *= 2.0 * dtermPsiRatio_dai;
00663
00664 p3_xxa(ai) += Slater_dTerm_a + Term_dSlater_a;
00665 }
00666 }
00667 }
00668
00669
00670
00671
00672 for(int ori=0; ori<Input->WF.OR_constraints.dim1(); ori++)
00673 {
00674 int c = Input->WF.OR_constraints(ori);
00675 if(c > 0){
00676 rp_a(c) += rp_a(ori);
00677 rp_a(ori) = 0.0;
00678 p3_xxa(c) += p3_xxa(ori);
00679 p3_xxa(ori) = 0.0;
00680 }
00681 }
00682
00683 for(int ori=0; ori<Input->WF.OR_constraints.dim1(); ori++)
00684 {
00685 if(fabs(rp_a(ori)) > 1e-30){
00686
00687 wd->rp_a(aic) = rp_a(ori);
00688 wd->p3_xxa(aic) = p3_xxa(ori);
00689 aic++;
00690 }
00691 }
00692 }
00693
00694 void QMCSCFJastrow::checkParameterDerivatives()
00695 {
00696 if(Input->flags.iseed == 0)
00697 {
00698 cout << "Error: to check derivatives, iseed must not be 0\n";
00699 exit(0);
00700 }
00701 if(Input->flags.calculate_Derivatives != 1)
00702 {
00703 cout << "Error: to check derivatives, you must calculate derivatives!\n";
00704 exit(0);
00705 }
00706 globalInput.printAISummary();
00707
00708 int aStart = 0;
00709 int aStop = Input->getNumberAIParameters();
00710 Array1D<double> params = Input->getAIParameters();
00711 globalInput.printAIParameters(cout,"Parameters:",25,params,false);
00712 printf("function %23c p %25.15e p2_xx %25.15e\n",
00713 ' ',
00714 (double)wd->psi,
00715 wd->localEnergy);
00716 for(int ai=aStart; ai<aStop; ai++)
00717 printf("ai %3i %25.15e p_a %25.15e p3_xxa %25.15e\n",
00718 ai,
00719 params(ai),
00720 (double)(Psi) * wd->rp_a(ai),
00721 wd->p3_xxa(ai));
00722 exit(0);
00723 }
00724
00725 void QMCSCFJastrow::calculate_CorrelatedSampling(Array1D<QMCWalkerData *> &walkerData,
00726 Array1D<Array2D<double> * > &xData,
00727 int num)
00728 {
00729 for(int cs = globalInput.cs_Parameters.dim1()-1; cs >= 0; cs--)
00730 {
00731 globalInput.setAIParameters( globalInput.cs_Parameters(cs) );
00732
00733
00734 int gpp = 0;
00735
00736 if(globalInput.flags.optimize_Orbitals == 1)
00737 {
00738
00739
00740 Alpha.evaluate(xData,num-gpp,gpp,-1);
00741 Beta.evaluate(xData,num-gpp,gpp,-1);
00742
00743 Alpha.update_Ds(walkerData);
00744 Beta.update_Ds(walkerData);
00745
00746
00747 }
00748
00749
00750
00751
00752
00753 if(globalInput.JP.getNumberJWParameters() > 0)
00754 Jastrow.evaluate(walkerData,xData,num-gpp,gpp);
00755
00756 for(int w=0; w<num; w++)
00757 {
00758 iWalker = w;
00759 wd = walkerData(iWalker);
00760 x = xData(iWalker);
00761
00762 if(globalInput.flags.optimize_CI == 1 ||
00763 globalInput.flags.optimize_Orbitals == 1)
00764 {
00765 alphaPsi = Alpha.getPsi(iWalker);
00766 alphaGrad = Alpha.getGradPsiRatio(iWalker);
00767 alphaLaplacian = Alpha.getLaplacianPsiRatio(iWalker);
00768
00769 betaPsi = Beta.getPsi(iWalker);
00770 betaGrad = Beta.getGradPsiRatio(iWalker);
00771 betaLaplacian = Beta.getLaplacianPsiRatio(iWalker);
00772
00773 update_SCF();
00774 }
00775
00776 QMCDouble Jastrow_Psi = Jastrow.getJastrow(w);
00777
00778
00779
00780
00781
00782 QMCDouble cs_Psi = wd->D * Jastrow_Psi;
00783
00784
00785 double cs_LPR = wd->D_xx + wd->U_xx;
00786
00787 for (int i=0; i<Input->WF.getNumberElectrons(); i++)
00788 for (int j=0; j<3; j++)
00789 {
00790
00791 cs_LPR += wd->U_x(i,j) * wd->D_x(i,j) * 2.0;
00792
00793 cs_LPR += wd->U_x(i,j) * wd->U_x(i,j);
00794 }
00795
00796 QMCDouble weight = cs_Psi / wd->psi;
00797 weight *= weight;
00798
00799 if(wd->cs_LocalEnergy.dim1() != globalInput.cs_Parameters.dim1())
00800 {
00801 wd->cs_LocalEnergy.allocate(globalInput.cs_Parameters.dim1());
00802 wd->cs_Weights.allocate(globalInput.cs_Parameters.dim1());
00803 }
00804
00805 wd->cs_LocalEnergy(cs) = -0.5 * cs_LPR + wd->potentialEnergy;
00806 wd->cs_Weights(cs) = (double)(weight);
00807 }
00808 }
00809
00810
00811
00812
00813
00814 wd = 0;
00815 x = 0;
00816 iWalker = -1;
00817 }