00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCJastrow.h"
00014
00015
00016
00017 static const bool showTimings = false;
00018
00019
00020
00021 static const bool printJastrow = false;
00022
00023 QMCJastrow::QMCJastrow()
00024 {
00025 }
00026
00027 QMCJastrow::~QMCJastrow()
00028 {
00029 for(int i=0; i<grad_sum_U.dim1(); i++)
00030 grad_sum_U(i).deallocate();
00031
00032 sum_U.deallocate();
00033 grad_sum_U.deallocate();
00034 laplacian_sum_U.deallocate();
00035
00036 for(int i=0; i<p2_xa.dim1(); i++)
00037 for(int j=0; j<p2_xa.dim2(); j++)
00038 p2_xa(i,j).deallocate();
00039
00040 p_a.deallocate();
00041 p2_xa.deallocate();
00042 p3_xxa.deallocate();
00043 }
00044
00045 void QMCJastrow::initialize(QMCInput * input)
00046 {
00047 Input = input;
00048 JastrowElectronNuclear.initialize(Input);
00049 JastrowElectronElectron.initialize(Input);
00050
00051 if (Input->flags.use_three_body_jastrow == 1)
00052 ThreeBodyJastrow.initialize(Input);
00053
00054 int walkersPerPass = Input->flags.walkers_per_pass;
00055 sum_U.allocate(walkersPerPass);
00056 grad_sum_U.allocate(walkersPerPass);
00057 laplacian_sum_U.allocate(walkersPerPass);
00058
00059 int numJW = globalInput.JP.getNumberJWParameters();
00060 p_a.allocate(walkersPerPass,numJW);
00061 p2_xa.allocate(walkersPerPass,numJW);
00062 p3_xxa.allocate(walkersPerPass,numJW);
00063
00064 for(int i=0; i<p2_xa.dim1(); i++)
00065 for(int j=0; j<p2_xa.dim2(); j++)
00066 p2_xa(i,j).allocate(Input->WF.getNumberElectrons(),3);
00067
00068 #ifdef QMC_GPU
00069 GPUQMCJastrowElectronElectron temp(JastrowElectronElectron, Input->flags.getNumGPUWalkers());
00070 gpuJEE = temp;
00071 #endif
00072 }
00073
00074 QMCDouble QMCJastrow::getJastrow(int which)
00075 {
00076 return QMCDouble(1.0,1.0,0.0,sum_U(which));
00077 }
00078
00079 double QMCJastrow::get_p_a(int which, int ai)
00080 {
00081 return getJastrow(which)*p_a(which,ai);
00082 }
00083
00084 double QMCJastrow::getLnJastrow(int which)
00085 {
00086 return sum_U(which);
00087 }
00088
00089 double QMCJastrow::get_p_a_ln(int which, int ai)
00090 {
00091 return p_a(which,ai);
00092 }
00093
00094 Array2D<double> * QMCJastrow::getGradientLnJastrow(int which)
00095 {
00096 return &grad_sum_U(which);
00097 }
00098
00099 Array2D<double> * QMCJastrow::get_p2_xa_ln(int which, int ai)
00100 {
00101 return &p2_xa(which,ai);
00102 }
00103
00104 double QMCJastrow::getLaplacianLnJastrow(int which)
00105 {
00106 return laplacian_sum_U(which);
00107 }
00108
00109 double QMCJastrow::get_p3_xxa_ln(int which, int ai)
00110 {
00111 return p3_xxa(which,ai);
00112 }
00113
00114 void QMCJastrow::evaluate(Array1D<QMCWalkerData *> &walkerData,
00115 Array1D<Array2D<double>*> &X, int num, int start)
00116 {
00117 evaluate(Input->JP,walkerData,X,num,start);
00118 }
00119
00120 void QMCJastrow::evaluate(Array2D<double> & R)
00121 {
00122 Array1D< Array2D<double>* > temp(1);
00123 temp(0) = &R;
00124
00125 QMCWalkerData wd;
00126 wd.initialize(3,-1,-1);
00127 wd.updateDistances(R);
00128 Array1D<QMCWalkerData *> wdArray(1);
00129 wdArray(0) = &wd;
00130 evaluate(Input->JP,wdArray,temp,1,0);
00131 }
00132
00133 void QMCJastrow::evaluate(QMCJastrowParameters & JP,
00134 Array1D<QMCWalkerData *> &walkerData,
00135 Array1D<Array2D<double>*> &X, int num, int start)
00136 {
00137 static double averageJ = 0, timeJ = 0;
00138 static double numT = -5;
00139 static int multiplicity = 1;
00140
00141 Stopwatch sw = Stopwatch();
00142 sw.reset();
00143
00144 for(int walker = start; walker < start+num; walker++)
00145 {
00146 JastrowElectronNuclear.evaluate(JP,walkerData(walker),*X(walker));
00147
00148 if(showTimings){sw.start();}
00149 JastrowElectronElectron.evaluate(JP,walkerData(walker),*X(walker));
00150 if(showTimings){sw.stop();}
00151
00152 if (Input->flags.use_three_body_jastrow == 1)
00153 ThreeBodyJastrow.evaluate(JP,walkerData(walker),*X(walker));
00154
00155 sum_U(walker) = walkerData(walker)->U;
00156 grad_sum_U(walker) = walkerData(walker)->U_x;
00157 laplacian_sum_U(walker) = walkerData(walker)->U_xx;
00158
00159 if(Input->flags.calculate_Derivatives == 1)
00160 {
00161
00162
00163
00164 int numEE = globalInput.JP.getNumberEEParameters();
00165 for(int ai=0; ai<numEE; ai++)
00166 {
00167 p_a(walker,ai) = JastrowElectronElectron.get_p_a_ln(ai);
00168 p2_xa(walker,ai) = *JastrowElectronElectron.get_p2_xa_ln(ai);
00169 p3_xxa(walker,ai) = JastrowElectronElectron.get_p3_xxa_ln(ai);
00170 }
00171 int shift = numEE;
00172 int numNE = globalInput.JP.getNumberNEParameters();
00173 for(int ai=0; ai<numNE; ai++)
00174 {
00175 p_a(walker,ai+shift) = JastrowElectronNuclear.get_p_a_ln(ai);
00176 p2_xa(walker,ai+shift) = *JastrowElectronNuclear.get_p2_xa_ln(ai);
00177 p3_xxa(walker,ai+shift) = JastrowElectronNuclear.get_p3_xxa_ln(ai);
00178 }
00179 shift += numNE;
00180 int numJW = globalInput.JP.getNumberJWParameters();
00181 for(int ai=shift; ai<numJW; ai++)
00182 {
00183 p_a(walker,ai) = ThreeBodyJastrow.get_p_a_ln(ai-shift);
00184 p2_xa(walker,ai) = *ThreeBodyJastrow.get_p2_xa_ln(ai-shift);
00185 p3_xxa(walker,ai) = ThreeBodyJastrow.get_p3_xxa_ln(ai-shift);
00186 }
00187 }
00188 }
00189 if(showTimings)
00190 {
00191 timeJ = sw.timeUS();
00192 if(numT >= 0) averageJ += sw.timeUS();
00193 if( num > 1) numT++;
00194 cout << "cpu ee: " << (int)(timeJ/multiplicity+0.5) << " ( " << (int)(averageJ/(numT*multiplicity)+0.5) << ")\n";
00195 }
00196 }
00197
00198 #ifdef QMC_GPU
00199 void QMCJastrow::gpuEvaluate(Array1D<Array2D<double>*> &X, int num)
00200 {
00201 Array2D<double> * grad_JEN;
00202 Array2D<double> * grad_3body;
00203 Array2D<double> * grad_JEE;
00204 gpuJEE.unloadResults();
00205
00206 for(int walker = 0; walker < num; walker++)
00207 {
00208 JastrowElectronNuclear.evaluate(Input->JP,*X(walker));
00209
00210 sum_U(walker) =
00211 JastrowElectronNuclear.getLnJastrow() + gpuJEE.getLnJastrow(walker);
00212
00213 laplacian_sum_U(walker) =
00214 JastrowElectronNuclear.getLaplacianLnJastrow() +
00215 gpuJEE.getLaplacianLnJastrow(walker);
00216
00217 grad_JEN = JastrowElectronNuclear.getGradientLnJastrow();
00218
00219 grad_JEE = gpuJEE.getGradientLnJastrow(walker);
00220
00221 grad_sum_U(walker).allocate(X(walker)->dim1(),3);
00222
00223 for(int i=0; i<grad_JEE->dim1(); i++)
00224 for(int j=0; j<grad_JEE->dim2(); j++)
00225 (grad_sum_U(walker))(i,j) = (*grad_JEE)(i,j) + (*grad_JEN)(i,j);
00226
00227 if (Input->flags.use_three_body_jastrow == 1)
00228 {
00229 ThreeBodyJastrow.evaluate(Input->JP,*X(walker));
00230
00231 sum_U(walker) += ThreeBodyJastrow.getLnJastrow();
00232 laplacian_sum_U(walker) += ThreeBodyJastrow.getLaplacianLnJastrow();
00233
00234 grad_3body = ThreeBodyJastrow.getGradientLnJastrow();
00235 for (int i=0; i<grad_3body->dim1(); i++)
00236 for (int j=0; j<grad_3body->dim2(); j++)
00237 (grad_sum_U(walker))(i,j) += (*grad_3body)(i,j);
00238 }
00239
00240 if(printJastrow)
00241 {
00242 printf("%4d: ",walker);
00243 printf("lnJEE # %s%18.15e ",gpuJEE.getLnJastrow(walker)<0?"":" ",gpuJEE.getLnJastrow(walker) );
00244 printf("laplnJEE # %s%18.15g\n",gpuJEE.getLaplacianLnJastrow(walker)<0?"":" ",gpuJEE.getLaplacianLnJastrow(walker) );
00245 }
00246 }
00247 }
00248 void QMCJastrow::setUpGPU(GLuint aElectrons, GLuint bElectrons, int num)
00249 {
00250 static double averageJ = 0, timeJ = 0;
00251 static double numT = -5;
00252 static int multiplicity = gpuJEE.getNumIterations();
00253
00254 Stopwatch sw = Stopwatch();
00255 if(showTimings)
00256 {
00257 sw.reset(); sw.start();
00258 }
00259 gpuJEE.runCalculation(aElectrons, bElectrons, num);
00260 if(showTimings)
00261 {
00262 glFinish();
00263 sw.stop();
00264 timeJ = sw.timeUS();
00265 if(numT >= 0) averageJ += sw.timeUS();
00266 if( num > 1) numT++;
00267 cout << "gpu ee: " << (int)(timeJ/multiplicity+0.5) << " ( " << (int)(averageJ/(numT*multiplicity)+0.5) << ")\n";
00268 }
00269 }
00270 #endif
00271
00272 void QMCJastrow::operator=(const QMCJastrow & rhs )
00273 {
00274 Input = rhs.Input;
00275
00276 sum_U = rhs.sum_U;
00277 grad_sum_U = rhs.grad_sum_U;
00278 laplacian_sum_U = rhs.laplacian_sum_U;
00279 JastrowElectronNuclear = rhs.JastrowElectronNuclear;
00280
00281 JastrowElectronElectron = rhs.JastrowElectronElectron;
00282
00283 if (Input->flags.use_three_body_jastrow == 1)
00284 ThreeBodyJastrow = rhs.ThreeBodyJastrow;
00285
00286 #ifdef QMC_GPU
00287 gpuJEE = rhs.gpuJEE;
00288 #endif
00289 }