rozepsány vektorové verse přesuvných okeffiientů

Former-commit-id: 271b875ff3b42a304563cbc8e69ab3ffbdec5b73
This commit is contained in:
Marek Nečada 2017-03-17 05:19:57 +00:00
parent 61e62b8c3d
commit d93346070d
1 changed files with 128 additions and 2 deletions

View File

@ -4,7 +4,7 @@ from qpms_c import *
import scipy import scipy
from scipy.constants import epsilon_0 as ε_0, c, pi as π, e, hbar as , mu_0 as μ_0 from scipy.constants import epsilon_0 as ε_0, c, pi as π, e, hbar as , mu_0 as μ_0
eV = e eV = e
from scipy.special import lpmn, lpmv, sph_jn, sph_yn, poch from scipy.special import lpmn, lpmv, sph_jn, sph_yn, poch, gammaln
from scipy.misc import factorial from scipy.misc import factorial
import math import math
import cmath import cmath
@ -479,7 +479,9 @@ from py_gmm.gmm import vec_trans as vc
#@ujit #@ujit
def q_max(m,n,μ,ν): def q_max(m,n,μ,ν):
return min(n,ν,(n+ν-abs(m+μ))/2) return min(n,ν,(n+ν-abs(m+μ))/2)
q_max_v = np.vectorize(q_max)
# returns array with indices corresponding to q # returns array with indices corresponding to q
# argument q does nothing for now # argument q does nothing for now
#@ujit #@ujit
@ -491,6 +493,9 @@ def a_q(m,n,μ,ν,q = None):
raise ValueError('Something bad in the fortran subroutine gaunt_xu happened') raise ValueError('Something bad in the fortran subroutine gaunt_xu happened')
return res return res
a_q_v = np.vectorize(a_q)
# All arguments are single numbers (for now) # All arguments are single numbers (for now)
# ZDE VYCHÁZEJÍ DIVNÁ ZNAMÉNKA # ZDE VYCHÁZEJÍ DIVNÁ ZNAMÉNKA
#@ujit #@ujit
@ -612,7 +617,128 @@ def B̃(m,n,μ,ν,kdlj,θlj,φlj,r_ge_d,J):
return presum * np.sum(summandq) return presum * np.sum(summandq)
# vectorised versions - conservative
# ZDE VYCHÁZEJÍ DIVNÁ ZNAMÉNKA
#@ujit
def Ã_v0(m,n,μ,ν,kdlj,θlj,φlj,r_ge_d,J):
"""
The à translation coefficient for spherical vector waves.
Parameters
----------
m, n: int
The indices (degree and order) of the destination basis.
μ, ν: int
The indices of the source basis wave.
kdlj, θlj, φlj: float
The spherical coordinates of the relative position of
the new center vs. the old one (R_new - R_old);
the distance has to be already multiplied by the wavenumber!
r_ge_d: TODO
J: 1, 2, 3 or 4
Type of the wave in the old center.
Returns
-------
TODO
Bugs
----
gevero's gaunt coefficient implementation fails for large m, n (the unsafe territory
is somewhere around -72, 80)
"""
lMax = max(np.amax(n),np.amax(ν))
exponent=(gammaln(2*n+1)-gammaln(n+2)+gammaln(2*ν+3)-gammaln(ν+2)
+gammaln(n+ν+m-μ+1)-gammaln(n-m+1)-gammaln(ν+μ+1)
+gammaln(n+ν+1) - gammaln(2*(n+ν)+1))
presum = np.exp(exponent)
presum = presum * np.exp(1j*(μ-m)*φlj) * (-1)**m * 1j**(ν+n) / (4*n)
qmax = np.floor(q_max(-m,n,μ,ν)) #nemá tu být +m?
q = np.arange(qmax+1, dtype=int)
# N.B. -m !!!!!!
a1q = a_q_v(-m,n,μ,ν) # there is redundant calc. of qmax
ã1q = a1q / a1q[0]
p = n+ν-2*q
if(r_ge_d):
J = 1
zp = zJn(n+ν,kdlj,J)[0][p]
Pp = lpmv(μ-m,p,np.cos(θlj))
summandq = (n*(n+1) + ν*(ν+1) - p*(p+1)) * (-1)**q * ã1q * zp * Pp
# Taylor normalisation v2, proven to be equivalent (NS which is better)
prenormratio = 1j**(ν-n) * np.sqrt(((2*ν+1)/(2*n+1))* np.exp(
gammaln(n+m+1)-gammaln(n-m+1)+gammaln(ν-μ+1)-gammaln(ν+μ+1)))
presum = presum / prenormratio
# Taylor normalisation
#prenormmn = math.sqrt((2*n + 1)*math.factorial(n-m)/(4*π*factorial(n+m)))
#prenormμν = math.sqrt((2*ν + 1)*math.factorial(ν-μ)/(4*π*factorial(ν+μ)))
#presum = presum * prenormμν / prenormmn
return presum * np.sum(summandq)
# ZDE OPĚT JINAK ZNAMÉNKA než v Xu (J. comp. phys 127, 285)
#@ujit
def B̃_v(m,n,μ,ν,kdlj,θlj,φlj,r_ge_d,J):
"""
The B̃ translation coefficient for spherical vector waves.
Parameters
----------
m, n: int
The indices (degree and order) of the destination basis.
μ, ν: int
The indices of the source basis wave.
kdlj, θlj, φlj: float
The spherical coordinates of the relative position of
the new center vs. the old one (R_new - R_old);
the distance has to be already multiplied by the wavenumber!
r_ge_d: TODO
J: 1, 2, 3 or 4
Type of the wave in the old center.
Returns:
--------
TODO
"""
exponent=(gammaln(2*n+3)-gammaln(n+2)+gammaln(2*ν+3)-gammaln(ν+2)
+gammaln(n+ν+m-μ+2)-gammaln(n-m+1)-gammaln(ν+μ+1)
+gammaln(n+ν+2) - gammaln(2*(n+ν)+3))
presum = math.exp(exponent)
presum = presum * np.exp(1j*(μ-m)*φlj) * (-1)**m * 1j**(ν+n+1) / (
(4*n)*(n+1)*(n+m+1))
Qmax = math.floor(q_max(-m,n+1,μ,ν))
q = np.arange(Qmax+1, dtype=int)
if (μ == ν): # it would disappear in the sum because of the factor (ν-μ) anyway
ã2q = 0
else:
a2q = a_q(-m-1,n+1,μ+1,ν)
ã2q = a2q / a2q[0]
a3q = a_q(-m,n+1,μ,ν)
ã3q = a3q / a3q[0]
#print(len(a2q),len(a3q))
p = n+ν-2*q
if(r_ge_d):
J = 1
zp_ = zJn(n+1+ν,kdlj,J)[0][p+1] # je ta +1 správně?
Pp_ = lpmv(μ-m,p+1,math.cos(θlj))
summandq = ((2*(n+1)*(ν-μ)*ã2q
-(-ν*(ν+1) - n*(n+3) - 2*μ*(n+1)+p*(p+3))* ã3q)
*(-1)**q * zp_ * Pp_)
# Taylor normalisation v2, proven to be equivalent
prenormratio = 1j**(ν-n) * math.sqrt(((2*ν+1)/(2*n+1))* math.exp(
gammaln(n+m+1)-gammaln(n-m+1)+gammaln(ν-μ+1)-gammaln(ν+μ+1)))
presum = presum / prenormratio
## Taylor normalisation
#prenormmn = math.sqrt((2*n + 1)*math.factorial(n-m)/(4*π*factorial(n+m)))
#prenormμν = math.sqrt((2*ν + 1)*math.factorial(ν-μ)/(4*π*factorial(ν+μ)))
#presum = presum * prenormμν / prenormmn
return presum * np.sum(summandq)
# In[7]: # In[7]: