00001 #include "Anderson2CorrelationFunction.h"
00002
00003 #include "QMCInput.h"
00004 #include <sstream>
00005 #include "StringManipulation.h"
00006
00007
00008
00009
00010 #define WJ_C_TYPE 3
00011
00012 void Anderson2CorrelationFunction::initializeParameters(
00013 Array1D<int> & BeginningIndexOfParameterType,
00014 Array1D<double> &Parameters,
00015 Array1D<int> & BeginningIndexOfConstantType,
00016 Array1D<double> & Constants)
00017 {
00018 if( Constants.dim1() != 1 )
00019 {
00020 cerr << "ERROR: Anderson correlation function entered "
00021 << "without a constant for the cusp condition!" << endl;
00022 exit(0);
00023 }
00024
00025 if( BeginningIndexOfParameterType.dim1() != 2 )
00026 {
00027 cerr << "ERROR: Anderson correlation function entered with an incorrect "
00028 << "number of parameter types!" << endl;
00029 exit(0);
00030 }
00031
00032
00033 g = Constants(0);
00034
00035 L = Parameters(0);
00036
00037
00038
00039
00040 A = Parameters(1);
00041 B = Parameters(2);
00042
00043 if(g <= 0){
00044 cerr << "ERROR: Anderson correlation function can not be used to set cusp condition "
00045 << " g = " << g << endl;
00046 exit(0);
00047 }
00048
00049
00050 s2g = -1.0 * sqrt(2.0 * g / L);
00051 F = s2g / A;
00052 A2 = A * A;
00053 A2F = A2 * F;
00054
00055 n = Parameters.dim1() - 3;
00056
00057 Tn.allocate(n);
00058 dTn.allocate(n);
00059 d2Tn.allocate(n);
00060
00061 if(n >= 0)
00062 {
00063 Tn[0] = 1.0;
00064 dTn[0] = 0.0;
00065 d2Tn[0] = 0.0;
00066 }
00067
00068 if(n >= 1)
00069 {
00070 dTn[1] = 1.0;
00071 d2Tn[1] = 0.0;
00072 }
00073
00074 co.allocate(n);
00075
00076 for(int i=0; i<n; i++)
00077 co[i] = Parameters(i+3);
00078 }
00079
00080 void Anderson2CorrelationFunction::evaluate( double _r )
00081 {
00082 r = _r;
00083 x = r * L;
00084
00085 if(isSingular())
00086 {
00087 FunctionValue = 0.0;
00088 dFunctionValue = 0.0;
00089 d2FunctionValue = -1e10;
00090 return;
00091 }
00092
00093
00094 ir = 1.0 / x;
00095 t1 = exp( x * F );
00096 t2 = A2F * t1 * ir;
00097
00098
00099
00100
00101
00102
00103
00104
00105 yuk = - A2 * (1.0 - t1) * ir;
00106 dyuk = (A2 + t1*(A2F * x - A2)) * ir * ir;
00107 d2yuk = (-2.0 * A2 + t1 * (2.0 * A2 + A2F*x*(F * x - 2.0))) * ir * ir * ir;
00108 FunctionValue = yuk;
00109 dFunctionValue = dyuk;
00110 d2FunctionValue = d2yuk;
00111
00112 if(x > 1.0)
00113 {
00114 dG_a = 0.0;
00115 dG_xa = 0.0;
00116 dG_xxa = 0.0;
00117 pre = 0.0;
00118 dpre = 0.0;
00119 d2pre = 0.0;
00120 dFunctionValue *= L;
00121 d2FunctionValue *= L*L;
00122 return;
00123 }
00124
00125
00126 double dpc0 = pow(x-1,WJ_C_TYPE);
00127 double dpc1 = pow(x-1,WJ_C_TYPE-1);
00128 double dpc2 = pow(x-1,WJ_C_TYPE-2);
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 double s, sd, s2d;
00146 double xbar = 2.0*x*x - 1.0;
00147
00148 ChebyshevT(n,xbar,s,sd,s2d);
00149
00150 s2d = 4.0 * sd + 16.0 * x * x * s2d;
00151 sd *= 4.0 * x;
00152
00153
00154
00155 pre = dpc0 * x * x;
00156 dpre = dpc1 * x * (-2.0 + (2.0+WJ_C_TYPE)*x);
00157 d2pre = dpc2 *(2.0 + (1.0 + WJ_C_TYPE)*x*(-4.0 + (2.0 + WJ_C_TYPE)*x));
00158
00159 FunctionValue += pre*s;
00160 dFunctionValue += pre*sd + dpre*s;
00161 d2FunctionValue += pre*s2d + 2.0*dpre*sd + d2pre*s;
00162
00163
00164 dFunctionValue *= L;
00165 d2FunctionValue *= L*L;
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 }
00176
00177 double Anderson2CorrelationFunction::get_p_a(int ai)
00178 {
00179 double p_a = 0.0;
00180 switch(ai)
00181 {
00182
00183 case 0:
00184 if(globalInput.flags.optimize_L)
00185 {
00186 p_a = dFunctionValue * r / L;
00187 } else {
00188 p_a = 0.0;
00189 }
00190 break;
00191
00192
00193 case 1:
00194 p_a = 2.0 * yuk / A - t1 * s2g;
00195 break;
00196
00197
00198 case 2:
00199 p_a = dG_a;
00200 break;
00201
00202
00203 default:
00204 p_a = pre * Tn[ai-3];
00205 break;
00206 }
00207 return p_a;
00208 }
00209
00210 double Anderson2CorrelationFunction::get_p2_xa(int ai)
00211 {
00212 double p2_xa = 0.0;
00213 switch(ai)
00214 {
00215
00216 case 0:
00217 if(globalInput.flags.optimize_L)
00218 {
00219 p2_xa = dFunctionValue + d2FunctionValue * r / L;
00220 } else {
00221 p2_xa = 0.0;
00222 }
00223 break;
00224
00225
00226 case 1:
00227 p2_xa = 2.0 * dyuk / A - t1 * F * s2g;
00228 break;
00229
00230
00231 case 2:
00232 p2_xa = dG_xa;
00233 break;
00234
00235
00236 default:
00237
00238 p2_xa = 4.0*pre*x*dTn[ai-3] + dpre*Tn[ai-3];
00239 break;
00240 }
00241 return p2_xa * L;
00242 }
00243
00244 double Anderson2CorrelationFunction::get_p3_xxa(int ai)
00245 {
00246 double p3_xxa = 0.0;
00247 switch(ai)
00248 {
00249
00250 case 0:
00251 if(globalInput.flags.optimize_L)
00252 {
00253 p3_xxa = 2.0 * d2FunctionValue / L;
00254 } else {
00255 p3_xxa = 0.0;
00256 }
00257 break;
00258
00259
00260 case 1:
00261 p3_xxa = 2.0 * d2yuk / A - t1 * F * F * s2g;
00262 break;
00263
00264
00265 case 2:
00266 p3_xxa = dG_xxa;
00267 break;
00268
00269
00270 default:
00271 p3_xxa = 4.0*pre*(dTn[ai-3] + 4.0*x*x*d2Tn[ai-3]);
00272 p3_xxa += 8.0*dpre*x*dTn[ai-3] + d2pre*Tn[ai-3];
00273 break;
00274 }
00275 return p3_xxa * L * L;
00276 }
00277
00278 void Anderson2CorrelationFunction::print(ostream& strm)
00279 {
00280 strm << "Anderson Jastrow parameters:" << endl;
00281 int prec = 10;
00282 int width = 18;
00283 strm.precision(prec);
00284 strm << " g = " << g;
00285 strm << " A = " << A << endl;
00286 strm << " B = " << B << endl;
00287 strm << " L = " << L << endl;
00288 strm << " F = " << F << endl;
00289
00290
00291 strm << "x = r / " << (1.0 / L) << endl;
00292 strm << "U[x_] := " << StringManipulation::fancyDoubleToString(prec,0,-A2)
00293 << " (1.0 - Exp[ " << StringManipulation::fancyDoubleToString(prec,0,F) << " x ])/x";
00294 strm << StringManipulation::fancyDoubleToString(prec,0,B)
00295 << " (1/" << WJ_C_TYPE << " + x)(x-1)^" << WJ_C_TYPE;
00296 strm << " + x^2 (x-1)^" << WJ_C_TYPE << " *(";
00297
00298 for(int i=0; i<n; i++)
00299 {
00300 if(i%3 == 0) strm << endl;
00301 strm << StringManipulation::fancyDoubleToString(prec,width,co[i]);
00302 strm << " ChebyshevT[" << setw(2) << 2*i << ",x]";
00303 }
00304 strm << ")" << endl;
00305 }
00306
00307 bool Anderson2CorrelationFunction::isSingular()
00308 {
00309 return g <= 0.0 || A <= 0.0;
00310 }
00311
00312 void Anderson2CorrelationFunction::ChebyshevT(int n, double x, double &s, double &sd, double &s2d)
00313 {
00314 s2d = 0.0;
00315
00316 if (n == 0){
00317 s = co[0];
00318 sd = 0.0;
00319 return;
00320 }
00321
00322 Tn[1] = x;
00323
00324 s = co[0] + co[1]*x;
00325 sd = co[1];
00326
00327 if (n == 1) return;
00328
00329 for (int k = 2; k < n; k++) {
00330 Tn[k] = x * 2.0 * Tn[k-1] - Tn[k-2];
00331 dTn[k] = x * 2.0 * dTn[k-1] + 2.0 * Tn[k-1] - dTn[k-2];
00332 d2Tn[k] = x * 2.0 * d2Tn[k-1] + 4.0 * dTn[k-1] - d2Tn[k-2];
00333
00334 s += co[k]*Tn[k];
00335 sd += co[k]*dTn[k];
00336 s2d += co[k]*d2Tn[k];
00337 }
00338 }
00339
00340 #undef WJ_C_TYPE