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