00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "QMCWalkerData.h"
00013 #include "QMCPotential_Energy.h"
00014
00015 using namespace std;
00016
00024 QMCWalkerData::QMCWalkerData()
00025 {
00026 }
00027
00028 QMCWalkerData::~QMCWalkerData()
00029 {
00030 }
00031
00032 void QMCWalkerData::partialCopy(const QMCWalkerData & rhs)
00033 {
00034 localEnergy = rhs.localEnergy;
00035 kineticEnergy = rhs.kineticEnergy;
00036 potentialEnergy = rhs.potentialEnergy;
00037 neEnergy = rhs.neEnergy;
00038 eeEnergy = rhs.eeEnergy;
00039
00040 D = rhs.D;
00041 D_x = rhs.D_x;
00042 D_xx = rhs.D_xx;
00043
00044 psi = rhs.psi;
00045 singular = rhs.singular;
00046
00047 gradPsiRatio = rhs.gradPsiRatio;
00048 modifiedGradPsiRatio = rhs.modifiedGradPsiRatio;
00049 riA = rhs.riA;
00050 riA_uvec = rhs.riA_uvec;
00051 }
00052
00053 void QMCWalkerData::initialize(int numDimensions, int numNucForceDim1, int numNucForceDim2)
00054 {
00055 int numElectrons = globalInput.WF.getNumberElectrons();
00056 int numNuclei = globalInput.Molecule.getNumberAtoms();
00057 int numCI = globalInput.WF.getNumberDeterminants();
00058 int na = globalInput.WF.getNumberElectrons(true);
00059 int nb = globalInput.WF.getNumberElectrons(false);
00060
00061
00062 whichE = -1;
00063 if(globalInput.flags.one_e_per_iter ||
00064 globalInput.flags.use_psuedopotential)
00065 {
00066 Dc_invA.allocate(numCI);
00067 Dc_invB.allocate(numCI);
00068
00069 for(int ci=0; ci<numCI; ci++)
00070 {
00071 Dc_invA(ci).allocate(na,na);
00072 Dc_invB(ci).allocate(nb,nb);
00073 }
00074 DcA.allocate(numCI);
00075 DcB.allocate(numCI);
00076 }
00077
00078 if(globalInput.flags.one_e_per_iter)
00079 {
00080 int no = globalInput.WF.OrbitalCoeffs.dim1();
00081
00082 D_xxA.allocate(na,no);
00083 D_xxB.allocate(nb,no);
00084 D_xA.allocate(3);
00085 D_xB.allocate(3);
00086 for(int i=0; i<3; i++)
00087 {
00088 D_xA(i).allocate(na,no);
00089 D_xB(i).allocate(nb,no);
00090 }
00091
00092 rDc_xxA.allocate(numCI);
00093 rDc_xxB.allocate(numCI);
00094 rDc_xA.allocate(numCI,numElectrons,3);
00095 rDc_xB.allocate(numCI,numElectrons,3);
00096 }
00097
00098 gradPsiRatio.allocate(numElectrons,numDimensions);
00099 modifiedGradPsiRatio.allocate(numElectrons,numDimensions);
00100 D_x.allocate(numElectrons,numDimensions);
00101
00102 int numAI = globalInput.getNumberAIParameters();
00103 rp_a.allocate(numAI);
00104 p3_xxa.allocate(numAI);
00105
00106 modificationRatio = 0.0;
00107 psi = 0.0;
00108 D = 0.0;
00109 singular = false;
00110
00111 rij.allocate(numElectrons, numElectrons);
00112 rij_uvec.allocate(numElectrons, numElectrons, 3);
00113 riA.allocate(numElectrons, numNuclei);
00114 riA_uvec.allocate(numElectrons, numNuclei, 3);
00115
00116 Uij.allocate(numElectrons, numElectrons);
00117 Uij_x.allocate(numElectrons, numElectrons, 3);
00118 Uij_xx.allocate(numElectrons, numElectrons);
00119 Uij = 0.0;
00120 Uij_x = 0.0;
00121 Uij_xx = 0.0;
00122
00123 UiA.allocate(numElectrons, numNuclei);
00124 UiA_x.allocate(numElectrons, numNuclei, 3);
00125 UiA_xx.allocate(numElectrons, numNuclei);
00126 UiA = 0.0;
00127 UiA_x = 0.0;
00128 UiA_xx = 0.0;
00129
00130 if(globalInput.flags.use_three_body_jastrow == 1)
00131 {
00132 UijA.allocate(numElectrons, numElectrons);
00133 UijA_xx.allocate(numElectrons, numElectrons);
00134 UijA = 0.0;
00135 UijA_xx = 0.0;
00136
00137 UijA_x1.allocate(3);
00138 UijA_x2.allocate(3);
00139 for(int xyz=0; xyz<UijA_x1.dim1(); xyz++)
00140 {
00141 UijA_x1(xyz).allocate(numElectrons,numElectrons);
00142 UijA_x1(xyz) = 0.0;
00143 UijA_x2(xyz).allocate(numElectrons,numElectrons);
00144 UijA_x2(xyz) = 0.0;
00145 }
00146 }
00147
00148 U_x.allocate(numElectrons,3);
00149 U = 0.0;
00150 U_x = 0.0;
00151 U_xx = 0.0;
00152
00153 if(globalInput.flags.nuclear_derivatives != "none")
00154 nuclearDerivatives.allocate(numNucForceDim1, numNucForceDim2);
00155
00156 if (globalInput.flags.calculate_bf_density == 1)
00157 chiDensity.allocate(globalInput.WF.getNumberBasisFunctions());
00158 }
00159
00160 double QMCWalkerData::getModifiedLocalEnergy()
00161 {
00162
00163
00164
00165
00166
00167 if(globalInput.flags.energy_cutoff_type == "none")
00168 {
00169 return localEnergy;
00170 }
00171 else if(globalInput.flags.energy_cutoff_type == "umrigar93")
00172 {
00173
00174 return localEnergy * modificationRatio;
00175 }
00176 else if(globalInput.flags.energy_cutoff_type == "bdjm-push88")
00177 {
00178
00179
00180
00181
00182
00183
00184
00185 static const double cutoff = 2.0 / sqrt(globalInput.flags.dt);
00186
00187 double el = localEnergy - globalInput.flags.energy_estimated_original;
00188 if(fabs(el) > cutoff)
00189 {
00190 double sign = el < 0.0 ? -1.0 : 1.0;
00191 return globalInput.flags.energy_estimated_original + sign * cutoff;
00192 }
00193 return localEnergy;
00194 } else {
00195 clog << "ERROR: Unknown energy cutoff type " << globalInput.flags.energy_cutoff_type
00196 << "!" << endl;
00197 exit(1);
00198 }
00199 return 0.0;
00200 }
00201
00202 void QMCWalkerData::zero()
00203 {
00204 localEnergy = 0.0;
00205 kineticEnergy = 0.0;
00206 potentialEnergy = 0.0;
00207 neEnergy = 0.0;
00208 eeEnergy = 0.0;
00209 D_xx = 0.0;
00210 }
00211
00212 void QMCWalkerData::writeConfigs(Array2D<double> & Positions, double weight)
00213 {
00214 globalInput.outputer.writeCorrelatedSamplingConfiguration(Positions,
00215 D_xx,
00216 D_x,
00217 U,
00218 potentialEnergy,
00219 weight);
00220 }
00221
00222 bool QMCWalkerData::isSingular()
00223 {
00224 if(singular) return true;
00225 if( IeeeMath::isNaN(kineticEnergy) )
00226 singular = true;
00227 if( IeeeMath::isNaN(potentialEnergy) )
00228 singular = true;
00229 if( IeeeMath::isNaN(U_xx) )
00230 singular = true;
00231 if( IeeeMath::isNaN(D_xx) )
00232 singular = true;
00233 return singular;
00234 }
00235
00236 ostream& operator<<(ostream & strm, const QMCWalkerData & rhs)
00237 {
00238 int w = 25;
00239 int p = 15;
00240
00241 strm.width(10);
00242 strm << " Psi = "
00243 << setw(w) << setprecision(p)
00244 << scientific << (double)(rhs.psi);
00245 strm.width(10);
00246 strm << " E = "
00247 << setw(w) << setprecision(p)
00248 << fixed << rhs.localEnergy;
00249 strm.width(10);
00250 if(rhs.singular)
00251 strm << " * ";
00252 strm << endl;
00253
00254
00255 strm.width(10);
00256 strm << " U = "
00257 << setw(w) << setprecision(p)
00258 << scientific << (double)(QMCDouble(1.0,1.0,0.0,rhs.U));
00259 strm.width(10);
00260 strm << " U_xx = "
00261 << setw(w) << setprecision(p)
00262 << fixed << rhs.U_xx;
00263 strm << endl;
00264
00265 strm.width(10);
00266 strm << " D = "
00267 << setw(w) << setprecision(p)
00268 << scientific << (double)(rhs.D);
00269 strm.width(10);
00270 strm << " D_xx = "
00271 << setw(w) << setprecision(p)
00272 << fixed << rhs.D_xx;
00273 strm << endl;
00274
00275 strm.width(10);
00276 strm << " KE = "
00277 << setw(w) << setprecision(p)
00278 << fixed << rhs.kineticEnergy;
00279 strm.width(10);
00280 strm << " PE = "
00281 << setw(w) << setprecision(p)
00282 << fixed << rhs.potentialEnergy;
00283 strm << endl;
00284
00285 strm.width(10);
00286 strm << " EE = "
00287 << setw(w) << setprecision(p)
00288 << fixed << rhs.eeEnergy;
00289 strm.width(10);
00290 strm << " NE = "
00291 << setw(w) << setprecision(p)
00292 << fixed << rhs.neEnergy;
00293 strm << endl;
00294
00295 return strm;
00296 }
00297
00298 void QMCWalkerData::updateDistances(Array2D<double> & R)
00299 {
00300 if(whichE == -1)
00301 {
00302 for(int i=0; i<R.dim1(); i++)
00303 {
00304 for(int j=0; j<i; j++)
00305 {
00306 rij(i,j) = MathFunctions::rij(R,i,j);
00307 for(int xyz=0; xyz<3; xyz++)
00308 rij_uvec(i,j,xyz) = (R(i,xyz) - R(j, xyz)) / rij(i,j);
00309 }
00310
00311 for(int j=0; j<globalInput.Molecule.getNumberAtoms(); j++)
00312 {
00313 double r = MathFunctions::rij(R,globalInput.Molecule.Atom_Positions,i,j);
00314 riA(i,j) = r;
00315 for(int xyz=0; xyz<3; xyz++)
00316 riA_uvec(i,j,xyz) = (R(i,xyz) - globalInput.Molecule.Atom_Positions(j,xyz)) / r;
00317 }
00318 }
00319 } else {
00320 for(int j=0; j<R.dim1(); j++)
00321 {
00322 if(j == whichE) continue;
00323 double r = MathFunctions::rij(R,j,whichE);
00324 int e1 = max(whichE,j);
00325 int e2 = min(whichE,j);
00326
00327 rij(e1,e2) = r;
00328 for(int xyz=0; xyz<3; xyz++)
00329 rij_uvec(e1,e2,xyz) = (R(e1,xyz) - R(e2, xyz)) / r;
00330 }
00331
00332 for(int j=0; j<globalInput.Molecule.getNumberAtoms(); j++)
00333 {
00334 riA(whichE,j) =
00335 MathFunctions::rij(R,globalInput.Molecule.Atom_Positions,whichE,j);
00336 for(int xyz=0; xyz<3; xyz++)
00337 riA_uvec(whichE,j,xyz) = (R(whichE,xyz) - globalInput.Molecule.Atom_Positions(j,xyz)) / riA(whichE,j);
00338 }
00339 }
00340 }
00341
00342