Octopus
ylm_wannier.F90
Go to the documentation of this file.
1 !
2 ! Copyright (C) 2003-2013 Quantum ESPRESSO and Wannier90 groups
3 ! This file is distributed under the terms of the
4 ! GNU General Public License. See the file "License"
5 ! in the root directory of the present distribution,
6 ! or http://www.gnu.org/copyleft/gpl.txt .
7 !
8 ! routine adapted from the original Pwscf interface PP/pw2wannier90.f90
9 !
10#include "global.h"
11
13 use global_oct_m
14 use, intrinsic :: iso_fortran_env
16
17 implicit none
18
19 private
20
21 public :: ylm_wannier
22
23contains
24 subroutine ylm_wannier(ylm, l, mr, rr, xx, nr)
25 ! this routine returns in ylm(r) the values at the nr points r(1:3,1:nr)
26 ! of the spherical harmonic identified by indices (l,mr)
27 ! in table 3.1 of the wannierf90 specification.
28 !
29 ! No reference to the particular ylm ordering internal to octopus
30 ! is assumed.
31 !
32 ! If ordering in wannier90 code is changed or extended this should be the
33 ! only place to be modified accordingly
34 !
35
36 ! I/O variables
37 !
38 real(real64), intent(inout) :: ylm(nr)
39 integer, intent(in) :: l, mr, nr
40 real(real64), intent(inout) :: rr(nr), xx(3, nr)
41 !
42 ! local variables
43 !
44 ! real(real64), EXTERNAL :: s, pz,px,py, dz2, dxz, dyz, dx2my2, dxy
45 ! real(real64), EXTERNAL :: fz3, fxz2, fyz2, fzx2my2, fxyz, fxx2m3y2, fy3x2my2
46 real(real64) :: cost, phi
47 integer :: ir
48 real(real64) :: bs2, bs3, bs6, bs12
49 bs2 = m_one / sqrt(m_two)
50 bs3 = m_one / sqrt(m_three)
51 bs6 = m_one / sqrt(6.0_real64)
52 bs12 = m_one / sqrt(12.0_real64)
53
54 if (l > 3 .or. l < -5) stop 'ylm_wannier l out of range '
55 if (l >= 0) then
56 if (mr < 1 .or. mr > 2*l + 1) stop 'ylm_wannier mr out of range'
57 else
58 if (mr < 1 .or. mr > abs(l) + 1) stop 'ylm_wannier mr out of range'
59 end if
60
61 do ir = 1, nr
62 ! if r=0, direction is undefined => make ylm=0 except for l=0
63 if (rr(ir) < 1e-12_real64) then
64 if (l == 0) then
65 ylm(ir) = s()
66 else
67 ylm(ir) = m_zero
68 end if
69 cycle
70 end if
71
72 cost = xx(3, ir) / rr(ir)
73 !
74 ! beware the arc tan, it is defined modulo M_PI
75 !
76 if (xx(1, ir) > 1e-12_real64) then
77 phi = atan(xx(2, ir) / xx(1, ir))
78 else if (xx(1,ir) < -1e-12_real64) then
79 phi = atan(xx(2, ir) / xx(1, ir)) + m_pi
80 else
81 phi = sign(m_pi / m_two, xx(2, ir))
82 end if
83
84 select case (l)
85 case (0) ! s orbital
86 ylm(ir) = s()
87 case (1) ! p orbitals
88 if (mr == 1) ylm(ir) = pz(cost)
89 if (mr == 2) ylm(ir) = px(cost, phi)
90 if (mr == 3) ylm(ir) = py(cost, phi)
91 case (2) ! d orbitals
92 if (mr == 1) ylm(ir) = dz2(cost)
93 if (mr == 2) ylm(ir) = dxz(cost, phi)
94 if (mr == 3) ylm(ir) = dyz(cost, phi)
95 if (mr == 4) ylm(ir) = dx2my2(cost, phi)
96 if (mr == 5) ylm(ir) = dxy(cost, phi)
97 case (3) ! f orbitals
98 if (mr == 1) ylm(ir) = fz3(cost)
99 if (mr == 2) ylm(ir) = fxz2(cost, phi)
100 if (mr == 3) ylm(ir) = fyz2(cost, phi)
101 if (mr == 4) ylm(ir) = fzx2my2(cost, phi)
102 if (mr == 5) ylm(ir) = fxyz(cost, phi)
103 if (mr == 6) ylm(ir) = fxx2m3y2(cost, phi)
104 if (mr == 7) ylm(ir) = fy3x2my2(cost, phi)
105 case (-1) ! sp hybrids
106 if (mr == 1) ylm(ir) = bs2 * (s() + px(cost, phi))
107 if (mr == 2) ylm(ir) = bs2 * (s() - px(cost, phi))
108 case (-2) ! sp2 hybrids
109 if (mr == 1) ylm(ir) = bs3 * s() - bs6 * px(cost, phi) + bs2 * py(cost, phi)
110 if (mr == 2) ylm(ir) = bs3 * s() - bs6 * px(cost, phi) - bs2 * py(cost, phi)
111 if (mr == 3) ylm(ir) = bs3 * s() + m_two * bs6 * px(cost, phi)
112 case (-3) ! sp3 hybrids
113 if (mr == 1) ylm(ir) = m_half*(s() + px(cost, phi) + py(cost, phi) + pz(cost))
114 if (mr == 2) ylm(ir) = m_half*(s() + px(cost, phi) - py(cost, phi) - pz(cost))
115 if (mr == 3) ylm(ir) = m_half*(s() - px(cost, phi) + py(cost, phi) - pz(cost))
116 if (mr == 4) ylm(ir) = m_half*(s() - px(cost, phi) - py(cost, phi) + pz(cost))
117 case (-4) ! sp3d hybrids
118 if (mr == 1) ylm(ir) = bs3 * s() - bs6 * px(cost, phi) + bs2 * py(cost, phi)
119 if (mr == 2) ylm(ir) = bs3 * s() - bs6 * px(cost, phi) - bs2 * py(cost, phi)
120 if (mr == 3) ylm(ir) = bs3 * s() + m_two * bs6 * px(cost, phi)
121 if (mr == 4) ylm(ir) = bs2 * pz(cost) + bs2 * dz2(cost)
122 if (mr == 5) ylm(ir) =-bs2 * pz(cost) + bs2 * dz2(cost)
123 case (-5) ! sp3d2 hybrids
124 if (mr == 1) ylm(ir) = bs6 * s() - bs2 * px(cost, phi) -bs12 * dz2(cost) + m_half * dx2my2(cost, phi)
125 if (mr == 2) ylm(ir) = bs6 * s() + bs2 * px(cost, phi) -bs12 * dz2(cost) + m_half * dx2my2(cost, phi)
126 if (mr == 3) ylm(ir) = bs6 * s() - bs2 * py(cost, phi) -bs12 * dz2(cost) - m_half * dx2my2(cost, phi)
127 if (mr == 4) ylm(ir) = bs6 * s() + bs2 * py(cost, phi) -bs12 * dz2(cost) - m_half * dx2my2(cost, phi)
128 if (mr == 5) ylm(ir) = bs6 * s() - bs2 * pz(cost) +bs3 * dz2(cost)
129 if (mr == 6) ylm(ir) = bs6 * s() + bs2 * pz(cost) +bs3 * dz2(cost)
130 end select
131
132 end do
133 end subroutine ylm_wannier
134
135 !======== l = 0 =====================================================================
136 function s()
137 real(real64) :: s
138 s = m_one / sqrt((m_four * m_pi))
139 end function s
140
141 !======== l = 1 =====================================================================
142 function pz(cost)
143 real(real64) ::pz, cost
144 pz = sqrt(m_three / (m_four * m_pi)) * cost
145 end function pz
146
147 function px(cost, phi)
148 real(real64) ::px, cost, phi, sint
149 sint = sqrt(abs(m_one - cost * cost))
150 px = sqrt(m_three / (m_four * m_pi)) * sint * cos(phi)
151 end function px
152
153 function py(cost, phi)
154 real(real64) ::py, cost, phi, sint
155 sint = sqrt(abs(m_one - cost * cost))
156 py = sqrt(m_three / (m_four * m_pi)) * sint * sin(phi)
157 end function py
158
159 !======== l = 2 =====================================================================
160 function dz2(cost)
161 real(real64) ::dz2, cost
162 dz2 = sqrt(1.25_real64 / (m_four * m_pi)) * (m_three* cost * cost - m_one)
163 end function dz2
164
165 function dxz(cost, phi)
166 real(real64) ::dxz, cost, phi, sint
167 sint = sqrt(abs(m_one - cost * cost))
168 dxz = sqrt(15.0_real64 / (m_four * m_pi)) * sint * cost * cos(phi)
169 end function dxz
170
171 function dyz(cost, phi)
172 real(real64) ::dyz, cost, phi, sint
173 sint = sqrt(abs(m_one - cost * cost))
174 dyz = sqrt(15.0_real64 / (m_four * m_pi)) * sint * cost * sin(phi)
175 end function dyz
176
177 function dx2my2(cost, phi)
178 real(real64) ::dx2my2, cost, phi, sint
179 sint = sqrt(abs(m_one - cost * cost))
180 dx2my2 = sqrt(3.750_real64 / (m_four * m_pi)) * sint * sint * cos(m_two * phi)
181 end function dx2my2
182
183 function dxy(cost, phi)
184 real(real64) ::dxy, cost, phi, sint
185 sint = sqrt(abs(m_one - cost * cost))
186 dxy = sqrt(3.750_real64 / (m_four * m_pi)) * sint * sint * sin(m_two * phi)
187 end function dxy
188
189 !======== l = 3 =====================================================================
190 function fz3(cost)
191 real(real64) ::fz3, cost
192 fz3 = 0.25_real64 * sqrt(7.0_real64 / m_pi) * (5.0_real64 * cost * cost - m_three) * cost
193 end function fz3
194
195 function fxz2(cost, phi)
196 real(real64) ::fxz2, cost, phi, sint
197 sint = sqrt(abs(m_one - cost * cost))
198 fxz2 = 0.25_real64 * sqrt(10.5_real64 / m_pi) * (5.0_real64 * cost * cost - m_one) * sint * cos(phi)
199 end function fxz2
200
201 function fyz2(cost, phi)
202 real(real64) ::fyz2, cost, phi, sint
203 sint = sqrt(abs(m_one - cost * cost))
204 fyz2 = 0.25_real64 * sqrt(10.5_real64 / m_pi) * (5.0_real64 * cost * cost - m_one) * sint * sin(phi)
205 end function fyz2
206
207 function fzx2my2(cost, phi)
208 real(real64) ::fzx2my2, cost, phi, sint
209 sint = sqrt(abs(m_one - cost * cost))
210 fzx2my2 = 0.25_real64 * sqrt(105.0_real64 / m_pi) * sint * sint * cost * cos(m_two * phi)
211 end function fzx2my2
212
213 function fxyz(cost, phi)
214 real(real64) ::fxyz, cost, phi, sint
215 sint = sqrt(abs(m_one - cost * cost))
216 fxyz = 0.25_real64*sqrt(105.0_real64 / m_pi) * sint * sint * cost * sin(m_two * phi)
217 end function fxyz
218
219 function fxx2m3y2(cost, phi)
220 real(real64) ::fxx2m3y2, cost, phi, sint
221 sint = sqrt(abs(m_one - cost * cost))
222 fxx2m3y2 = 0.25_real64 * sqrt(17.5_real64 / m_pi) * sint * sint * sint * cos(m_three * phi)
223 end function fxx2m3y2
224
225 function fy3x2my2(cost, phi)
226 real(real64) ::fy3x2my2, cost, phi, sint
227 sint = sqrt(abs(m_one - cost * cost))
228 fy3x2my2 = 0.25_real64 * sqrt(17.5_real64 / m_pi) * sint * sint * sint * sin(m_three * phi)
229 end function fy3x2my2
230
231end module ylm_wannier_oct_m
double sin(double __x) __attribute__((__nothrow__
double atan(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_two
Definition: global.F90:189
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_four
Definition: global.F90:191
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:185
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public m_one
Definition: global.F90:188
real(real64), parameter, public m_three
Definition: global.F90:190
real(real64) function fxx2m3y2(cost, phi)
real(real64) function fy3x2my2(cost, phi)
real(real64) function py(cost, phi)
real(real64) function fxz2(cost, phi)
real(real64) function fz3(cost)
real(real64) function dz2(cost)
real(real64) function dxz(cost, phi)
real(real64) function pz(cost)
real(real64) function fzx2my2(cost, phi)
real(real64) function dxy(cost, phi)
real(real64) function fxyz(cost, phi)
real(real64) function dyz(cost, phi)
real(real64) function dx2my2(cost, phi)
real(real64) function px(cost, phi)
subroutine, public ylm_wannier(ylm, l, mr, rr, xx, nr)
real(real64) function s()
real(real64) function fyz2(cost, phi)