Skip to content

myfunc.h and XC functionals #674

@wenfei-li

Description

@wenfei-li

Some XC functionals are defined multiple times in the code. For example, in myfunc.h (realized in xc_1.cpp) we have

void becke88(double rho, double grho, double &sx, double &v1x, double &v2x)
{
    //-----------------------------------------------------------------------
    // Becke exchange: A.D. Becke, PRA 38, 3098 (1988)
    // only gradient-corrected part, no Slater term included
    //
    // USE kinds
    // implicit none
    // real(kind=DP) :: rho, grho, sx, v1x, v2x
    double beta, third, two13;
    // parameter :
    beta = 0.00420;
    // parameter :
    third = 1.0 / 3.0;
    two13 = 1.2599210498948730;
    // two13 = 2^(1/3)
    double rho13, rho43, xs, xs2, sa2b8, shm1, dd, dd2, ee;

    rho13 = pow(rho, third);
    rho43 = pow(rho13, 4);
    xs = two13 * sqrt(grho) / rho43;
    xs2 = xs * xs;
    sa2b8 = sqrt(1.00 + xs2);
    shm1 = log(xs + sa2b8);
    dd = 1.00 + 6.00 * beta * xs * shm1;
    dd2 = dd * dd;
    ee = 6.00 * beta * xs2 / sa2b8 - 1.0;
    sx = two13 * grho / rho43 * (- beta / dd);
    v1x = - (4.0 / 3.0) / two13 * xs2 * beta * rho13 * ee / dd2;
    v2x = two13 * beta * (ee - dd) / (rho43 * dd2);

    return;
} // end subroutine becke88

while in the XC_Functional class (xc_functional.cpp) we have basically the same thing:

void XC_Functional::becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x)
{
    //-----------------------------------------------------------------------
    // Becke exchange: A.D. Becke, PRA 38, 3098 (1988)
    // only gradient-corrected part, no Slater term included
    //
    double beta, third, two13;
    beta = 0.00420;
    third = 1.0 / 3.0;
    two13 = 1.2599210498948730;
    double rho13, rho43, xs, xs2, sa2b8, shm1, dd, dd2, ee;

    rho13 = pow(rho, third);
    rho43 = pow(rho13, 4);
    xs = two13 * sqrt(grho) / rho43;
    xs2 = xs * xs;
    sa2b8 = sqrt(1.00 + xs2);
    shm1 = log(xs + sa2b8);
    dd = 1.00 + 6.00 * beta * xs * shm1;
    dd2 = dd * dd;
    ee = 6.00 * beta * xs2 / sa2b8 - 1.0;
    sx = two13 * grho / rho43 * (- beta / dd);
    v1x = - (4.0 / 3.0) / two13 * xs2 * beta * rho13 * ee / dd2;
    v2x = two13 * beta * (ee - dd) / (rho43 * dd2);

    return;
} // end subroutine becke88

The XC_functional::becke88 is the one actually used in ABACUS. However, some other functionals such as OPTX are only defined in myfunc.h but not xc_functional.h, as a result, we have the following lines of code:

	// exchange
    if (rho <= small)
    {
        sx = 0.00;
        v1x = 0.00;
        v2x = 0.00;
    }
    else if (GlobalC::xcf.igcx_now == 1)
    {
        XC_Functional::becke88(rho, grho, sx, v1x, v2x);
    }
    else if (GlobalC::xcf.igcx_now == 2)
    {
        XC_Functional::ggax(rho, grho, sx, v1x, v2x);
    }
    else if (GlobalC::xcf.igcx_now == 3)
    {
		//mohan modify 2009-12-15
		// 0 stands for PBE, 1 stands for revised PBE
        XC_Functional::pbex(rho, grho, 0, sx, v1x, v2x);
    }
    else if (GlobalC::xcf.igcx_now == 4)
    {
		// revised PBE.
        XC_Functional::pbex(rho, grho, 1, sx, v1x, v2x);
    }
    else if (GlobalC::xcf.igcx_now == 5 && GlobalC::xcf.igcc_now == 5)
    {
        hcth(rho, grho, sx, v1x, v2x);
    }
    else if (GlobalC::xcf.igcx_now == 6)
    {
        optx(rho, grho, sx, v1x, v2x);
    }
	else if (GlobalC::xcf.igcx_now == 8)
	{
		XC_Functional::pbex (rho, grho, 0, sx, v1x, v2x);
		sx *= 0.75;
		v1x *= 0.75;
		v2x *= 0.75;
	}

where XC_Functional::XXX is used in some cases but not the other ones. Would it be better if we move everything from myfunc.h to xc_functional.h and remove myfunc.h?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions