Changeset b70503 for pcp/src/excor.c
- Timestamp:
- Apr 21, 2008, 2:19:24 PM (17 years ago)
- Children:
- f7754e
- Parents:
- 6c8ee7
- git-author:
- Frederik Heber <heber@…> (04/18/08 15:29:28)
- git-committer:
- Frederik Heber <heber@…> (04/21/08 14:19:24)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pcp/src/excor.c
r6c8ee7 rb70503 787 787 E->AllLocalDensityEnergy[CorrelationEnergy] = Factor*SumEc; 788 788 E->AllLocalDensityEnergy[ExchangeEnergy] = Factor*(SumEx); // - SumEx_GC); 789 } 790 791 /** Returns \f$y = \sinh^{-1}(x)\f$. 792 * Recall that \f$ x = sinh (y) = \frac{\exp(y)-\exp(-y)}{2}\f$. Then, solve the in \f$\exp(y)\f$ quadratic 793 * equation: \f$\exp(2y) - 1 - 2x\exp(y) = 0\f$ by pq-formula. 794 * \param arg argument \f$x\f$ 795 * \return \f$\sinh^{-1}(x) = \ln(x+\sqrt{x^2+1})\f$ 796 */ 797 inline static double sinh_inverse(double arg) 798 { 799 return log(arg+sqrt(arg*arg+1)); 800 } 801 802 /** Gradient correction according to Becke '92. 803 * \param EC ExCor structure 804 * \param p \f$\rho\f$ local density 805 * \param Dp \f$|\nabla \rho|\f$ local magnitude of density gradient 806 * \return \f$b \rho^{4/3} \frac{x^2}{(1+6bx \sinh^-1 x}\f$ with \f$x = \frac{|\nabla \rho|}{\rho^{4/3}}\f$ 807 */ 808 double CalcSE_GC(struct ExCor *EC, double p, double Dp) 809 { 810 double res = 0.; 811 double b = 0.0042; // in atomic units, empirical constant fitted to noble gas atoms 812 double x = Dp/pow(p, 4./3.); 813 res = b * pow(p, 4./3.) * x/(1+6.*b*x*sinh_inverse(x)); 814 815 return res; 816 } 817 818 /** Evaluates magnitude of gradient by simple 3-star. 819 * \param *density density array 820 * \param i current node 821 * \param *Lev LatticeLevel structure for number of nodes per axis 822 * \param *Lat Lattice structure for axis lengths 823 * \return \f$|\nabla\rho|\f$ 824 */ 825 double DensityGradient(fftw_real *density, int i, struct LatticeLevel *Lev, struct Lattice *Lat) 826 { 827 double res=0., right_diff, left_diff; 828 int neighbour[NDIM], nodes[NDIM]; 829 nodes[0] = Lev->Plan0.plan->local_nx; 830 nodes[1] = Lev->Plan0.plan->N[1]; 831 nodes[2] = Lev->Plan0.plan->N[2]; 832 neighbour[0] = Lev->Plan0.plan->N[1] * Lev->Plan0.plan->N[2]; 833 neighbour[1] = Lev->Plan0.plan->N[2]; 834 neighbour[2] = 1.; 835 int k, l, nr, i_check = i; 836 double h; 837 838 //iS = n[2] + N[2]*(n[1] + N[1]*n0); // howto access the array ... 839 840 for (k=NDIM-1;k>=0;k--) { // for each axis 841 h = 0.; 842 for (l=0;l<NDIM;l++) 843 h += Lat->RealBasis[k*NDIM+l]/Lev->Plan0.plan->N[k]; // finite distance 844 h = sqrt(h); 845 // check which limit exists: right, left, both? 846 right_diff = 0.; 847 left_diff = 0.; 848 nr = 0; // neighbour counter 849 if (i_check % nodes[k] != nodes[k]-1) {// right neighbour? 850 right_diff = density[i] - density[i+neighbour[k]]; 851 nr++; 852 } 853 if (i_check % nodes[k] != 0) { // left neighbour? 854 left_diff = density[i] - density[i-neighbour[k]]; 855 nr++; 856 } 857 res += (left_diff + right_diff)/(h*nr) * (left_diff + right_diff)/(h*nr); 858 i_check /= nodes[k]; // remove axis from i_check 859 } 860 861 return sqrt(res); 789 862 } 790 863
Note:
See TracChangeset
for help on using the changeset viewer.