Skip to content

Commit fbd7608

Browse files
author
Roberto Di Remigio
committed
Fortran90-ize metal sphere Green's function subroutines.
1 parent 3c11978 commit fbd7608

File tree

3 files changed

+129
-96
lines changed

3 files changed

+129
-96
lines changed

src/metal/gsfera.F

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/metal/metal_sphere.F90

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
module metal_sphere
2+
3+
use, intrinsic :: iso_c_binding
4+
5+
implicit none
6+
7+
public greens_function
8+
9+
private
10+
11+
contains
12+
13+
subroutine greens_function(epssol, epsre, epsim, radius, &
14+
ps, p1, p2, greenre, greenim) bind(c, name='greens_function')
15+
16+
! Passed variables
17+
real(c_double), intent(in) :: epssol, epsre, epsim, radius
18+
real(c_double), intent(in) :: p1(*), p2(*), ps(*)
19+
real(c_double), intent(out) :: greenre, greenim
20+
! Local variables
21+
complex(16) :: gsfera, green, eps2, ui
22+
23+
ui = (0.0, 1.0)
24+
eps2 = epsre + epsim * ui
25+
green = gsfera(epssol, eps2, ps(1), ps(2), ps(3), radius, &
26+
p1(1), p1(2), p1(3), &
27+
p2(1), p2(2), p2(3))
28+
greenre = real(real(green))
29+
greenim = real(aimag(green))
30+
31+
end subroutine greens_function
32+
33+
complex(16) function gsfera(eps, eps2, xs, ys, zs, rs, &
34+
xi, yi, zi, xj, yj, zj)
35+
! Passed variables
36+
real(8), intent(in) :: eps
37+
complex(16), intent(in) :: eps2
38+
real(8), intent(in) :: xs, ys, zs, rs ! Sphere center and radius
39+
real(8), intent(in) :: xi, yi, zi ! Source point
40+
real(8), intent(in) :: xj, yj, zj ! Probe point
41+
! Local variables
42+
complex(16) :: coefl
43+
real(8) :: di, dj
44+
real(8) :: dim, xim, yim, zim, qim ! Image quantities
45+
real(8) :: gc, cost, aa, arg, argl, gsfera2
46+
integer :: maxl, l, m
47+
48+
!lf print *, eps,eps2
49+
!lf print *, 'Sphere', xs,ys,zs,rs
50+
!lf print *, 'Source', xi,yi,zi
51+
!lf print *, 'Probe ', xj,yj,zj
52+
di = sqrt((xi - xs)**2 + (yi - ys)**2 + (zi - zs)**2)
53+
dj = sqrt((xj - xs)**2 + (yj - ys)**2 + (zj - zs)**2)
54+
dim = rs**2 / di
55+
xim = dim * (xi - xs) / (di + xs)
56+
yim = dim * (yi - ys) / (di + ys)
57+
zim = dim * (zi - zs) / (di + zs)
58+
qim = rs / di
59+
gc = qim / sqrt((xj - xim)**2 + (yj - yim)**2 + (zj - zim)**2)
60+
gc = gc - qim / sqrt((xj - xs)**2 + (yj - ys)**2 + (zj - zs)**2)
61+
cost = (xj - xs) * (xi - xs) + (yj - ys) * (yi - ys) + (zj - zs) * (zi - zs)
62+
cost = cost / (di * dj)
63+
aa = (rs * rs / (di * dj))**4.
64+
maxl = int(800. / (abs(eps2 + eps))**0.4 * aa)
65+
maxl = max(maxl, 10)
66+
!lf write (6,*) "maxl",maxl
67+
arg = rs * rs / (di * dj)
68+
argl = rs / (di * dj)
69+
gsfera2 = 0.0d0
70+
m = 0
71+
do l = 1, maxl
72+
argl = argl * arg
73+
coefl = (eps2 - eps) * float(l) / ((eps2 + eps) * float(l) + 1.0d0)
74+
coefl = coefl - (eps2 - eps) / (eps2 + eps)
75+
gsfera = gsfera + coefl * argl * legendre_polynomial(l, m, cost)
76+
enddo
77+
gsfera = gsfera + gc * (eps2- eps) / (eps2 + eps)
78+
!lf: WARNING: sign change and divided by epsilon of solvent!!!!!!
79+
gsfera = -gsfera / eps
80+
! DEBUGGING STUFF
81+
! arg = rs * rs / (di * dj)
82+
! argl = rs / (di * dj)
83+
! gsfera = 0.0d0
84+
! m = 0
85+
! do l = 1, 5000
86+
! argl = argl * arg
87+
! coefl = (eps2 - eps) * float(l) / ((eps2 + eps) * float(l) + 1.0d0)
88+
! gsfera = gsfera + coefl * argl * legendre_polynomial(l, m, cost)
89+
! enddo
90+
!lf write (6, *) "gsfera2", gsfera
91+
end
92+
93+
real(8) function legendre_polynomial(l, m, x)
94+
! Computes the associated Legendre polynomial P_l^m(x)
95+
! Passed variables
96+
integer, intent(in) :: l, m
97+
real(8), intent(in) :: x
98+
! Local variables
99+
integer :: i, ll
100+
real(8) :: fact, pll, pmm, pmmp1, somx2
101+
102+
pmm = 1.0d0
103+
if (m .gt. 0) then
104+
somx2 = sqrt((1.0 - x) * (1.0 + x))
105+
fact = 1.0d0
106+
do i = 1, m
107+
pmm = -pmm * fact * somx2
108+
fact = fact + 2.0d0
109+
enddo
110+
endif
111+
if (l .eq. m) then
112+
legendre_polynomial = pmm
113+
else
114+
pmmp1 = x * (2 * m + 1) * pmm
115+
if (l .eq. m + 1) then
116+
legendre_polynomial = pmmp1
117+
else
118+
do ll = m + 2, l
119+
pll = (x * (2.0 * ll - 1) * pmmp1 - (ll + m - 1) * pmm) / (ll - m)
120+
pmm = pmmp1
121+
pmmp1 = pll
122+
enddo
123+
legendre_polynomial = pll
124+
endif
125+
endif
126+
127+
end function legendre_polynomial
128+
129+
end module metal_sphere

src/metal/plgndr.F

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)