"""
 Copyright (C) 2017 M.A.L. Marques
               2019 Susi Lehtola

 This Source Code Form is subject to the terms of the Mozilla Public
 License, v. 2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""

# type: mgga_exc

from libxc_codegen import *  # noqa: F401, F403

uu = Symbol("uu")
yy = Symbol("yy")

include('mgga_xc_b98')

# Fitted parameters, given below Eq. 50

edmgga_mu = Float('0.21')

edmgga_a = Float('0.704')

# Eq. 40: F_x'(0)

edmgga_fp0 = Integer(27)*edmgga_mu/Integer(50)

# Eq. 27: lim_(x -> -infinity) F_x(x)

edmgga_fminf = Integer(1)/Integer(3) * (Integer(4)*pi**Integer(2)/Integer(3))**(Integer(1)/Integer(3))

# Eq. 44

edmgga_b = Integer(2)*pi/Integer(9) * sqrt(Integer(6)/Integer(5))

# Eq. 47

edmgga_c1 = edmgga_fminf

# Eq. 48

edmgga_c2 = Integer(1) - edmgga_c1

# Eq. 49

edmgga_c3 = edmgga_c2*sqrt(Integer(2)*edmgga_a)/(Integer(2)*edmgga_b)

# Eq. 50. There's some problem in the equation, since the first line,
# 1/edmgga_c3^3 * (edmgga_c3^2 - edmgga_fp0/(2*edmgga_b^2)) * edmgga_c2,
# does not agree with the second line. The first line evaluates to a
# negative value, which makes the functional blow up. The second line
# yields values that are close to the reported ones, but Tao might have
# used a more accurate numerical value in his implementation since the
# agreement is not perfect. Unfortunately there's no way to check this
# as he has passed away.

edmgga_c4 = Integer(1)/edmgga_c3**Integer(3) * (edmgga_c3**Integer(2) - Float('0.09834')*edmgga_mu)

# Eq. 46.  edmgga_x can be < 0 because Qb can be very negative, where the
# exact a*Qb + sqrt(1 + (a*Qb)^2) cancels catastrophically.  On that
# branch use the y -> -infinity asymptotic of y + sqrt(1 + y^2),
# generated by the pipeline straight from the exact form (expand via
# u = -1/y, u -> 0+; csgn=1 since u > 0) instead of hard-coded
# coefficients.  Gives -1/(2y) + 1/(8y^3) - 1/(16y^5) + 5/(128y^7) - ...

@helper
def edmgga_x_exact(y):
    return y + sqrt(Integer(1) + y**Integer(2))

@helper
def edmgga_x_large(y):
    return maple_eval(convert(maple_eval(maple_series(maple_eval(edmgga_x_exact(yy), yy, -Integer(1)/uu), uu, Integer(0), Integer(8)), csgn, Integer(1)), polynom), uu, -Integer(1)/y)

@helper
def edmgga_x(Qb):
    return (
        my_piecewise3(
        Qb < -Float('1e4')/edmgga_a,
        edmgga_x_large(m_min(edmgga_a*Qb, -Float('1e-4')/edmgga_a)),
        edmgga_x_exact(edmgga_a*Qb)
        )
    )

# Eq. 45

@helper
def edmgga_f_x(x):
    return edmgga_c1 + edmgga_c2*x/(Integer(1) + edmgga_c3*sqrt(x)*xc_asinh(edmgga_c4*(x - Integer(1))))

# the evalf is absolutely necessary to avoid exceptions

@helper
def edmgga_f(x, u, t):
    return edmgga_f_x(edmgga_x(b98_q(x, u, t)))

def f(rs, z, xt, xs0, xs1, u0, u1, t0, t1):
    return mgga_exchange(edmgga_f, rs, z, xs0, xs1, u0, u1, t0, t1)

TYPE = "mgga_exc"
