grayl split in several f90 modules. only spline routines missing.

This commit is contained in:
Lorenzo Figini 2015-06-12 10:25:18 +00:00
parent 1e1406ff2a
commit 139f42fee2
13 changed files with 7680 additions and 7951 deletions

View File

@ -3,9 +3,11 @@ EXE=gray
# Objects list
MAINOBJ=gray.o
OTHOBJ=dispersion.o eierf.o dqagmv.o grayl.o reflections.o green_func_p.o \
const_and_precisions.o graydata_flags.o graydata_par.o graydata_anequil.o \
magsurf_data.o interp_eqprof.o
OTHOBJ=conical.o const_and_precisions.o dispersion.o eierf.o \
graydata_flags.o graydata_par.o graydata_anequil.o grayl.o \
green_func_p.o interp_eqprof.o magsurf_data.o math.o minpack.o \
numint.o quadpack.o reflections.o utils.o
# Alternative search paths
vpath %.f90 src
@ -24,16 +26,24 @@ $(EXE): $(MAINOBJ) $(OTHOBJ)
$(FC) $(FFLAGS) -o $@ $^
# Dependencies on modules
gray.o: dispersion.o dqagmv.o green_func_p.o reflections.o const_and_precisions.o \
graydata_flags.o graydata_par.o graydata_anequil.o magsurf_data.o interp_eqprof.o
green_func_p.o: const_and_precisions.o
reflections.o: const_and_precisions.o
dispersion.o: const_and_precisions.o eierf.o dqagmv.o
gray.o: const_and_precisions.o conical.o dispersion.o green_func_p.o \
graydata_flags.o graydata_par.o graydata_anequil.o interp_eqprof.o \
magsurf_data.o math.o minpack.o numint.o quadpack.o reflections.o \
utils.o
grayl.o: const_and_precisions.o
green_func_p.o: const_and_precisions.o numint.o
numint.o: const_and_precisions.o
reflections.o: const_and_precisions.o utils.o
conical.o: const_and_precisions.o
dispersion.o: const_and_precisions.o eierf.o math.o quadpack.o
math.o: const_and_precisions.o
minpack.o: const_and_precisions.o
graydata_flags.o: const_and_precisions.o
graydata_par.o: const_and_precisions.o
graydata_anequil.o: const_and_precisions.o
magsurf_data.o: const_and_precisions.o
interp_eqprof.o: const_and_precisions.o
utils.o: const_and_precisions.o
# General object compilation command
%.o: %.f90

853
src/conical.f90 Normal file
View File

@ -0,0 +1,853 @@
module conical
use const_and_precisions, only : wp_
implicit none
contains
function fconic(x,tau,m)
!
! this function subprogram computes the conical functions of the
! first kind P sub(-1/2 + i*tau) (x) for m = 0 and m = 1.
! Ref. in Kolbig, Comp. Phys. Commun. 23 (1981) 51
!
implicit none
real(wp_), intent(in) :: x, tau
integer, intent(in) :: m
real(wp_) :: fconic
real(wp_) :: t(7),h(9),v(11)
real(wp_) :: aa,a0,a1,a2,a3,a4,a5,a6,b0,b1,fm,fn,fn1,r1,r2,s,s0,s1
real(wp_) :: x1,y,y2,y3,z
integer :: jp,j,n
real(wp_), parameter :: rpi=1.7724538509055_wp_,pi2=0.63661977236758_wp_
real(wp_), parameter :: eps=1.0e-14_wp_
integer, parameter :: nout=2,nmax=200
!
complex(wp_) a,b,c,ti,r,rr,q,u,u0,u1,u2,uu
complex(wp_) v0,v1,v2,vv,w(19)
!
logical lm0,lm1,lta
fconic=0.0_wp_
lm0=m == 0
lm1=m == 1
if(.not.(lm0 .or. lm1)) then
write(nout,"(1x,'fconic ... illegal value for m = ',i4)") m
return
end if
fm=m
fconic=1.0_wp_-fm
if(x == 1.0_wp_) return
!
fconic=0.0_wp_
if(tau == 0.0_wp_ .and. abs(x-1.0_wp_) > 0.01_wp_) then
if(x > 1.0_wp_) then
y=sqrt((x-1.0_wp_)/(x+1.0_wp_))
z=ellick(y)
s=sqrt(0.5_wp_*(x+1.0_wp_))
if(lm0) fconic=pi2*z/s
if(lm1) fconic=pi2*s*(ellice(y)-z)/sqrt(x**2-1.0_wp_)
return
else
y=sqrt(0.5_wp_*(1.0_wp_-x))
z=ellick(y)
if(lm0) fconic=pi2*z
if(lm1) fconic=pi2*(ellice(y)-0.5_wp_*(1.0_wp_+x)*z)/ &
sqrt(1.0_wp_-x**2)
return
end if
else
ti=cmplx(0._wp_,tau)
!
if((-1._wp_ < x .and. x <= 0.0_wp_).or. &
(0.0_wp_ < x .and. x <= 0.1_wp_ .and.tau<= 17.0_wp_).or. &
(0.1_wp_ < x .and. x <= 0.2_wp_ .and.tau<= 5.0_wp_)) then
lta=tau <= 10.0_wp_
x1=x**2
a=0.5_wp_*(0.5_wp_-fm-ti)
b=0.5_wp_*(0.5_wp_-fm+ti)
c=0.5_wp_
jp=30
else if((0.1_wp_ < x .and. x <= 0.2_wp_ .and.tau<= 17.0_wp_) &
.or.(0.2_wp_ < x .and. x <= 1.5_wp_ .and.tau<= 20.0_wp_)) &
then
lta=x > 1.0_wp_ .or. x <= 1.0_wp_ .and. tau <= 5.0_wp_
x1=(1.0_wp_-x)/2._wp_
a=0.5_wp_+fm-ti
b=0.5_wp_+fm+ti
c=fm+1.0_wp_
jp=32
else if(1.5_wp_ < x .and. tau <= max(20.0_wp_,x)) then
lta=.true.
x1=1.0_wp_/x**2
u=exp((-0.5_wp_+ti)*log(2.0_wp_*x)+clogam(1.0_wp_+ti) &
-clogam(1.5_wp_-fm+ti))
a=0.5_wp_*(0.5_wp_-fm-ti)
b=0.5_wp_*(1.5_wp_-fm-ti)
c=1.0_wp_-ti
jp=33
else
if(x > 1.0_wp_) then
s=sqrt(x**2-1.0_wp_)
t(1)=log(x+s)
h(1)=tau*t(1)
b0=besj0l(h(1))
b1=besj1l(h(1))
z=1.0_wp_
else
s=sqrt(1.0_wp_-x**2)
t(1)=acos(x)
h(1)=tau*t(1)
b0=besi0(h(1))
b1=besi1(h(1))
z=-1.0_wp_
end if
h(1)=t(1)*x/s
v(1)=tau
do j = 2,7
t(j)=t(j-1)*t(1)
h(j)=h(j-1)*h(1)
end do
do j = 2,11
v(j)=v(j-1)*v(1)
end do
!
if(lm1) then
aa=-1.0_wp_
a0=3.0_wp_*(1.0_wp_-h(1))/(8.0_wp_*t(1))
a1=(-15.0_wp_*h(2)+6.0_wp_*h(1)+9.0_wp_+z*8.0_wp_*t(2))/ &
(128.0_wp_*t(2))
a2=3.0_wp_*(-35.0_wp_*h(3)-15.0_wp_*h(2)+15.0_wp_*h(1)+35.0_wp_ &
+z*t(2)*(32.0_wp_*h(1)+8.0_wp_))/(1024.0_wp_*t(3))
a3=(-4725.0_wp_*h(4)-6300.0_wp_*h(3)-3150.0_wp_*h(2)+3780.0_wp_*h(1) &
+10395.0_wp_-1216.0_wp_*t(4)+z*t(2)*(6000.0_wp_*h(2) &
+5760.0_wp_*h(1)+1680.0_wp_)) /(32768.0_wp_*t(4))
a4=7.0_wp_*(-10395.0_wp_*h(5)-23625.0_wp_*h(4)-28350.0_wp_*h(3) &
-14850.0_wp_*h(2)+19305.0_wp_*h(1)+57915.0_wp_ &
-t(4)*(6336.0_wp_*h(1)+6080.0_wp_)+z*t(2)*(16800.0_wp_*h(3) &
+30000.0_wp_*h(2)+25920.0_wp_*h(1)+7920.0_wp_))/ &
(262144.0_wp_*t(5))
a5=(-2837835.0_wp_*h(6)-9168390.0_wp_*h(5)-16372125.0_wp_*h(4) &
-18918900*h(3) -10135125.0_wp_*h(2)+13783770.0_wp_*h(1) &
+43648605.0_wp_-t(4)*(3044160.0_wp_*h(2)+5588352.0_wp_*h(1) &
+4213440.0_wp_)+z*t(2)*(5556600.0_wp_*h(4)+14817600.0_wp_*h(3) &
+20790000.0_wp_*h(2)+17297280.0_wp_*h(1)+5405400.0_wp_ &
+323072.0_wp_*t(4)))/ (4194304.0_wp_*t(6))
a6=0.0_wp_
else
aa=0.0_wp_
a0=1.0_wp_
a1=(h(1)-1.0_wp_)/(8.0_wp_*t(1))
a2=(9.0_wp_*h(2)+6.0_wp_*h(1)-15.0_wp_-z*8.0_wp_*t(2))/ &
(128.0_wp_*t(2))
a3=5.0_wp_*(15.0_wp_*h(3)+27.0_wp_*h(2)+21.0_wp_*h(1)-63.0_wp_ &
-z*t(2)*(16.0_wp_*h(1)+24.0_wp_))/(1024.0_wp_*t(3))
a4=7.0_wp_*(525.0_wp_*h(4)+1500.0_wp_*h(3)+2430.0_wp_*h(2) &
+1980.0_wp_*h(1)-6435.0_wp_+192.0_wp_*t(4)-z*t(2)* &
(720.0_wp_*h(2)+1600.0_wp_*h(1)+2160.0_wp_))/(32768.0_wp_*t(4))
a5=21.0_wp_*(2835.0_wp_*h(5)+11025.0_wp_*h(4)+24750.0_wp_*h(3) &
+38610.0_wp_*h(2)+32175.0_wp_*h(1)-109395.0_wp_+t(4) &
*(1984.0_wp_*h(1)+4032.0_wp_)-z*t(2) &
*(4800.0_wp_*h(3)+15120.0_wp_*h(2)+26400.0_wp_*h(1)+34320.0_wp_)) &
/(262144.0_wp_*t(5))
a6=11.0_wp_*(218295.0_wp_*h(6)+1071630.0_wp_*h(5)+3009825.0_wp_*h(4) &
+6142500.0_wp_*h(3)+9398025.0_wp_*h(2)+7936110.0_wp_*h(1) &
-27776385.0_wp_+t(4)*(254016.0_wp_*h(2) &
+749952.0_wp_*h(1)+1100736.0_wp_)-z*t(2)*(441000.0_wp_*h(4) &
+1814400.0_wp_*h(3)+4127760.0_wp_*h(2)+6552000.0_wp_*h(1) &
+8353800.0_wp_+31232.0_wp_*t(4)))/(4194304.0_wp_*t(6))
end if
s0=a0+(-4.0_wp_*a3/t(1)+a4)/v(4)+(-192.0_wp_*a5/t(3) &
+144.0_wp_*a6/t(2))/v(8)+z*(-a2/v(2)+(-24.0_wp_*a4/t(2) &
+12.0_wp_*a5/t(1)-a6)/v(6)+(-1920.0_wp_*a6/t(4))/v(10))
s1=a1/v(1)+(8.0_wp_*(a3/t(2)-a4/t(1))+a5)/v(5)+(384.0_wp_*a5/t(4) &
-768.0_wp_*a6/t(3))/v(9)+z*(aa*v(1)+(2.0_wp_*a2/t(1)-a3)/v(3) &
+(48.0_wp_*a4/t(3)-72.0_wp_*a5/t(2) &
+18.0_wp_*a6/t(1))/v(7)+(3840.0_wp_*a6/t(5))/v(11))
fconic=sqrt(t(1)/s)*(b0*s0+b1*s1)
return
end if
!
do
if(lta) then
y=-x1
y2=y**2
y3=y**3
w(1)=a+1.0_wp_
w(2)=a+2.0_wp_
w(3)=b+1.0_wp_
w(4)=b+2.0_wp_
w(5)=c+1.0_wp_
w(6)=c*w(5)
w(7)=a+b
w(8)=a*b
w(9)=(w(8)/c)*y
w(10)=w(1)*w(3)
w(11)=w(2)*w(4)
w(12)=1.0_wp_+(w(11)/(2.0_wp_*w(5)))*y
w(13)=w(7)-6.0_wp_
w(14)=w(7)+6.0_wp_
w(15)=2.0_wp_-w(8)
w(16)=w(15)-2.0_wp_*w(7)
!
v0=1.0_wp_
v1=1.0_wp_+(w(10)/(2.0_wp_*c))*y
v2=w(12)+(w(10)*w(11)/(12.0_wp_*w(6)))*y2
u0=1.0_wp_
u1=v1-w(9)
u2=v2-w(9)*w(12)+(w(8)*w(10)/(2.0_wp_*w(6)))*y2
!
r=1.0_wp_
n=2
do
n=n+1
if(n > nmax) then
write(nout,200) x,tau,m
return
end if
rr=r
fn=n
h(1)=fn-1.0_wp_
h(2)=fn-2.0_wp_
h(3)=fn-3.0_wp_
h(4)=2.0_wp_*fn
h(5)=h(4)-3.0_wp_
h(6)=2.0_wp_*h(5)
h(7)=4.0_wp_*(h(4)-1.0_wp_)*h(5)
h(8)=8.0_wp_*h(5)**2*(h(4)-5.0_wp_)
h(9)=3.0_wp_*fn**2
w(1)=a+h(1)
w(2)=a+h(2)
w(3)=b+h(1)
w(4)=b+h(2)
w(5)=c+h(1)
w(6)=c+h(2)
w(7)=c+h(3)
w(8)=h(2)-a
w(9)=h(2)-b
w(10)=h(1)-c
w(11)=w(1)*w(3)
w(12)=w(5)*w(6)
!
w(17)=1.0_wp_+((h(9)+w(13)*fn+w(16))/(h(6)*w(5)))*y
w(18)=-((w(11)*w(10)/h(6)+(h(9)-w(14)*fn+w(15))* &
w(11)*y/h(7))/w(12))*y
w(19)=(w(2)*w(11)*w(4)*w(8)*w(9)/(h(8)*w(7)*w(12)))*y3
vv=w(17)*v2+w(18)*v1+w(19)*v0
uu=w(17)*u2+w(18)*u1+w(19)*u0
r=uu/vv
if(abs(r-rr) < eps) exit
v0=v1
v1=v2
v2=vv
u0=u1
u1=u2
u2=uu
end do
else
r=1.0_wp_
q=1.0_wp_
do n = 1,nmax
fn=n
fn1=fn-1.0_wp_
rr=r
q=q*x1*(a+fn1)*(b+fn1)/((c+fn1)*fn)
r=r+q
if(abs(r-rr) < eps) exit
end do
if (n > nmax) then
write(nout,200) x,tau,m
return
end if
end if
if (jp/=30) exit
r1=real(r)/abs(exp(clogam(a+0.5_wp_)))**2
a=0.5_wp_*(1.5_wp_-fm-ti)
b=0.5_wp_*(1.5_wp_-fm+ti)
c=1.5_wp_
jp=31
end do
if (jp==31) then
r2=real(r)/abs(exp(clogam(a-0.5_wp_)))**2
fconic=rpi*(r1-2.0_wp_*x*r2)
if(lm1) fconic=(2.0_wp_/sqrt(1.0_wp_-x1))*fconic
return
else if (jp==32) then
fconic=real(r)
if(.not.lm0) then
fconic=0.5_wp_*(tau**2+0.25_wp_)*sqrt(abs(x**2-1.0_wp_))*fconic
if(x > 1.0_wp_) fconic=-fconic
end if
return
else if (jp==33) then
fconic=2.0_wp_*real(u*r*(0.5_wp_-fm+ti)/ti)/rpi
if(lm1) fconic=fconic/sqrt(1.0_wp_-x1)
return
end if
end if
!
200 format(1x,'fconic ... convergence difficulties for c function, x = ', &
e12.4,5x,'tau = ',e12.4,5x,'m = ',i5)
!
end function fconic
function clogam(z)
!
implicit none
complex(wp_) :: clogam
complex(wp_), intent(in) :: z
complex(wp_) :: v,h,r
integer :: i,n
real(wp_) :: x,t,a,c,d,e,f
integer, parameter :: nout=2
real(wp_), parameter :: pi=3.1415926535898_wp_
real(wp_), dimension(10), parameter :: b= &
(/+8.3333333333333e-2_wp_, -2.7777777777778e-3_wp_, &
+7.9365079365079e-4_wp_, -5.9523809523810e-4_wp_, &
+8.4175084175084e-4_wp_, -1.9175269175269e-3_wp_, &
+6.4102564102564e-3_wp_, -2.9550653594771e-2_wp_, &
+1.7964437236883e-1_wp_, -1.3924322169059e+0_wp_/)
!
x=real(z)
t=aimag(z)
if(-abs(x) == aint(x) .and. t == 0.0_wp_) then
write(nout,'(1x,f20.2)') x
clogam=(0.0_wp_,0.0_wp_)
return
end if
f=abs(t)
v=cmplx(x,f)
if(x < 0.0_wp_) v=1.0_wp_-v
h=(0.0_wp_,0.0_wp_)
c=real(v)
if(c < 7.0_wp_) then
n=6-int(c)
h=v
d=aimag(v)
a=atan2(d,c)
do i = 1,n
c=c+1.0_wp_
v=cmplx(c,d)
h=h*v
a=a+atan2(d,c)
end do
h=cmplx(0.5_wp_*log(real(h)**2+aimag(h)**2),a,wp_)
v=v+1.0_wp_
end if
r=1.0_wp_/v**2
clogam=0.91893853320467_wp_+(v-0.5_wp_)*log(v)-v+(b(1)+r*(b(2)+r*(b(3) &
+r*(b(4)+r*(b(5)+r*(b(6)+r*(b(7)+r*(b(8)+r*(b(9)+r*b(10)))))))))) &
/v-h
if(x < 0.0_wp_) then
!
a=aint(x)-1.0_wp_
c=pi*(x-a)
d=pi*f
e=exp(-2.0_wp_*d)
f=sin(c)
e=d+0.5_wp_*log(e*f**2+0.25_wp_*(1.0_wp_-e)**2)
f=atan2(cos(c)*tanh(d),f)-a*pi
clogam=1.1447298858494_wp_-cmplx(e,f)-clogam
!
end if
if(t < 0.0_wp_) clogam=conjg(clogam)
!
end function clogam
function ellick(xk)
implicit none
real(wp_), intent(in) :: xk
real(wp_) :: ellick, ellice
integer :: i
real(wp_) :: eta,pa,pb,pc,pd
real(wp_), dimension(10), parameter :: &
a=(/9.6573590280856e-2_wp_, 3.0885146271305e-2_wp_, &
1.4938013532687e-2_wp_, 8.7898018745551e-3_wp_, &
6.1796274460533e-3_wp_, 6.8479092826245e-3_wp_, &
9.8489293221769e-3_wp_, 8.0030039806500e-3_wp_, &
2.2966348983970e-3_wp_, 1.3930878570066e-4_wp_/), &
b=(/1.2499999999991e-1_wp_, 7.0312499739038e-2_wp_, &
4.8828041906862e-2_wp_, 3.7377739758624e-2_wp_, &
3.0124849012899e-2_wp_, 2.3931913323111e-2_wp_, &
1.5530941631977e-2_wp_, 5.9739042991554e-3_wp_, &
9.2155463496325e-4_wp_, 2.9700280966556e-5_wp_/), &
c=(/4.4314718056089e-1_wp_, 5.6805194567559e-2_wp_, &
2.1831811676130e-2_wp_, 1.1569595745295e-2_wp_, &
7.5950934225594e-3_wp_, 7.8204040609596e-3_wp_, &
1.0770635039866e-2_wp_, 8.6384421736041e-3_wp_, &
2.4685033304607e-3_wp_, 1.4946621757181e-4_wp_/), &
d=(/2.4999999999990e-1_wp_, 9.3749999721203e-2_wp_, &
5.8593661255531e-2_wp_, 4.2717890547383e-2_wp_, &
3.3478943665762e-2_wp_, 2.6145014700314e-2_wp_, &
1.6804023346363e-2_wp_, 6.4321465864383e-3_wp_, &
9.8983328462254e-4_wp_, 3.1859195655502e-5_wp_/)
!
if(abs(xk) >= 1.0_wp_) then
ellick=0.0_wp_
return
end if
eta=1.0_wp_-xk**2
pa=a(10)
do i = 1,9
pa=pa*eta+a(10-i)
end do
pa=pa*eta
pb=b(10)
do i = 1,9
pb=pb*eta+b(10-i)
end do
pb=pb*eta
ellick=1.3862943611199_wp_+pa-log(eta)*(0.5_wp_+pb)
return
!
entry ellice(xk)
!
if (abs(xk) >= 1.0_wp_) then
if (abs(xk) > 1.0_wp_) then
ellick=0.0_wp_
else
ellick=1.0_wp_
end if
return
end if
eta=1.0_wp_-xk**2
pc=c(10)
do i = 1,9
pc=pc*eta+c(10-i)
end do
pc=pc*eta
pd=d(10)
do i = 1,9
pd=pd*eta+d(10-i)
end do
pd=pd*eta
ellick=1.0_wp_+pc-log(eta)*pd
end function ellick
function besjy(x)
implicit none
real(wp_), intent(in) :: x
real(wp_) :: besjy,besj0l,besj1l
real(wp_) :: besy0,besy1
logical :: l
real(wp_) :: v,f,a,b,p,q
integer, parameter :: nout=2
!
entry besj0l(x)
!
l=.true.
v=abs(x)
if(v >= 8.0_wp_) go to 4
8 f=0.0625_wp_*x**2-2.0_wp_
a = - 0.0000000000000008_wp_
b = f * a + 0.0000000000000413_wp_
a = f * b - a - 0.0000000000019438_wp_
b = f * a - b + 0.0000000000784870_wp_
a = f * b - a - 0.0000000026792535_wp_
b = f * a - b + 0.0000000760816359_wp_
a = f * b - a - 0.0000017619469078_wp_
b = f * a - b + 0.0000324603288210_wp_
a = f * b - a - 0.0004606261662063_wp_
b = f * a - b + 0.0048191800694676_wp_
a = f * b - a - 0.0348937694114089_wp_
b = f * a - b + 0.1580671023320973_wp_
a = f * b - a - 0.3700949938726498_wp_
b = f * a - b + 0.2651786132033368_wp_
a = f * b - a - 0.0087234423528522_wp_
a = f * a - b + 0.3154559429497802_wp_
besjy=0.5_wp_*(a-b)
if(l) return
!
a = + 0.0000000000000016_wp_
b = f * a - 0.0000000000000875_wp_
a = f * b - a + 0.0000000000040263_wp_
b = f * a - b - 0.0000000001583755_wp_
a = f * b - a + 0.0000000052487948_wp_
b = f * a - b - 0.0000001440723327_wp_
a = f * b - a + 0.0000032065325377_wp_
b = f * a - b - 0.0000563207914106_wp_
a = f * b - a + 0.0007531135932578_wp_
b = f * a - b - 0.0072879624795521_wp_
a = f * b - a + 0.0471966895957634_wp_
b = f * a - b - 0.1773020127811436_wp_
a = f * b - a + 0.2615673462550466_wp_
b = f * a - b + 0.1790343140771827_wp_
a = f * b - a - 0.2744743055297453_wp_
a = f * a - b - 0.0662922264065699_wp_
besjy=0.636619772367581_wp_*log(x)*besjy+0.5_wp_*(a-b)
return
!
4 f=256.0_wp_/x**2-2.0_wp_
b = + 0.0000000000000007_wp_
a = f * b - 0.0000000000000051_wp_
b = f * a - b + 0.0000000000000433_wp_
a = f * b - a - 0.0000000000004305_wp_
b = f * a - b + 0.0000000000051683_wp_
a = f * b - a - 0.0000000000786409_wp_
b = f * a - b + 0.0000000016306465_wp_
a = f * b - a - 0.0000000517059454_wp_
b = f * a - b + 0.0000030751847875_wp_
a = f * b - a - 0.0005365220468132_wp_
a = f * a - b + 1.9989206986950373_wp_
p=a-b
b = - 0.0000000000000006_wp_
a = f * b + 0.0000000000000043_wp_
b = f * a - b - 0.0000000000000334_wp_
a = f * b - a + 0.0000000000003006_wp_
b = f * a - b - 0.0000000000032067_wp_
a = f * b - a + 0.0000000000422012_wp_
b = f * a - b - 0.0000000007271916_wp_
a = f * b - a + 0.0000000179724572_wp_
b = f * a - b - 0.0000007414498411_wp_
a = f * b - a + 0.0000683851994261_wp_
a = f * a - b - 0.0311117092106740_wp_
q=8.0_wp_*(a-b)/v
f=v-0.785398163397448_wp_
a=cos(f)
b=sin(f)
f=0.398942280401432_wp_/sqrt(v)
if(l) go to 6
besjy=f*(q*a+p*b)
return
6 besjy=f*(p*a-q*b)
return
!
entry besj1l(x)
!
l=.true.
v=abs(x)
if(v >= 8.0_wp_) go to 5
3 f=0.0625_wp_*x**2-2.0_wp_
b = + 0.0000000000000114_wp_
a = f * b - 0.0000000000005777_wp_
b = f * a - b + 0.0000000000252812_wp_
a = f * b - a - 0.0000000009424213_wp_
b = f * a - b + 0.0000000294970701_wp_
a = f * b - a - 0.0000007617587805_wp_
b = f * a - b + 0.0000158870192399_wp_
a = f * b - a - 0.0002604443893486_wp_
b = f * a - b + 0.0032402701826839_wp_
a = f * b - a - 0.0291755248061542_wp_
b = f * a - b + 0.1777091172397283_wp_
a = f * b - a - 0.6614439341345433_wp_
b = f * a - b + 1.2879940988576776_wp_
a = f * b - a - 1.1918011605412169_wp_
a = f * a - b + 1.2967175412105298_wp_
besjy=0.0625_wp_*(a-b)*x
if(l) return
!
b = - 0.0000000000000244_wp_
a = f * b + 0.0000000000012114_wp_
b = f * a - b - 0.0000000000517212_wp_
a = f * b - a + 0.0000000018754703_wp_
b = f * a - b - 0.0000000568844004_wp_
a = f * b - a + 0.0000014166243645_wp_
b = f * a - b - 0.0000283046401495_wp_
a = f * b - a + 0.0004404786298671_wp_
b = f * a - b - 0.0051316411610611_wp_
a = f * b - a + 0.0423191803533369_wp_
b = f * a - b - 0.2266249915567549_wp_
a = f * b - a + 0.6756157807721877_wp_
b = f * a - b - 0.7672963628866459_wp_
a = f * b - a - 0.1286973843813500_wp_
a = f * a - b + 0.0406082117718685_wp_
besjy=0.636619772367581_wp_*log(x)*besjy-0.636619772367581_wp_/x &
+0.0625_wp_*(a-b)*x
return
!
5 f=256.0_wp_/x**2-2.0_wp_
b = - 0.0000000000000007_wp_
a = f * b + 0.0000000000000055_wp_
b = f * a - b - 0.0000000000000468_wp_
a = f * b - a + 0.0000000000004699_wp_
b = f * a - b - 0.0000000000057049_wp_
a = f * b - a + 0.0000000000881690_wp_
b = f * a - b - 0.0000000018718907_wp_
a = f * b - a + 0.0000000617763396_wp_
b = f * a - b - 0.0000039872843005_wp_
a = f * b - a + 0.0008989898330859_wp_
a = f * a - b + 2.0018060817200274_wp_
p=a-b
b = + 0.0000000000000007_wp_
a = f * b - 0.0000000000000046_wp_
b = f * a - b + 0.0000000000000360_wp_
a = f * b - a - 0.0000000000003264_wp_
b = f * a - b + 0.0000000000035152_wp_
a = f * b - a - 0.0000000000468636_wp_
b = f * a - b + 0.0000000008229193_wp_
a = f * b - a - 0.0000000209597814_wp_
b = f * a - b + 0.0000009138615258_wp_
a = f * b - a - 0.0000962772354916_wp_
a = f * a - b + 0.0935555741390707_wp_
q=8.0_wp_*(a-b)/v
f=v-2.356194490192345_wp_
a=cos(f)
b=sin(f)
f=0.398942280401432_wp_/sqrt(v)
if(l) go to 7
besjy=f*(q*a+p*b)
return
7 besjy=f*(p*a-q*b)
if(x < 0.0_wp_) besjy=-besjy
return
!
entry besy0(x)
!
if(x <= 0.0_wp_) go to 9
l=.false.
v=x
if(v >= 8.0_wp_) go to 4
go to 8
entry besy1(x)
!
if(x <= 0.0_wp_) go to 9
l=.false.
v=x
if(v >= 8.0_wp_) go to 5
go to 3
!
9 besjy=0.0_wp_
write(nout,"(1x,'besjy ... non-positive argument x = ',e15.4)") x
end function besjy
function besik(x)
implicit none
real(wp_), intent(in) :: x
real(wp_) :: besik,ebesi0,besi0,ebesi1,besi1,ebesk0,besk0,ebesk1,besk1
logical :: l,e
real(wp_) :: v,f,a,b,z
integer, parameter :: nout=2
!
entry ebesi0(x)
!
e=.true.
go to 1
!
entry besi0(x)
!
e=.false.
1 l=.true.
v=abs(x)
if(v >= 8.0_wp_) go to 4
8 f=0.0625_wp_*x**2-2.0_wp_
a = 0.000000000000002_wp_
b = f * a + 0.000000000000120_wp_
a = f * b - a + 0.000000000006097_wp_
b = f * a - b + 0.000000000268828_wp_
a = f * b - a + 0.000000010169727_wp_
b = f * a - b + 0.000000326091051_wp_
a = f * b - a + 0.000008738315497_wp_
b = f * a - b + 0.000192469359688_wp_
a = f * b - a + 0.003416331766012_wp_
b = f * a - b + 0.047718748798174_wp_
a = f * b - a + 0.509493365439983_wp_
b = f * a - b + 4.011673760179349_wp_
a = f * b - a + 22.274819242462231_wp_
b = f * a - b + 82.489032744024100_wp_
a = f * b - a + 190.494320172742844_wp_
a = f * a - b + 255.466879624362167_wp_
besik=0.5_wp_*(a-b)
if(l .and. e) besik=exp(-v)*besik
if(l) return
!
a = + 0.000000000000003_wp_
b = f * a + 0.000000000000159_wp_
a = f * b - a + 0.000000000007658_wp_
b = f * a - b + 0.000000000318588_wp_
a = f * b - a + 0.000000011281211_wp_
b = f * a - b + 0.000000335195256_wp_
a = f * b - a + 0.000008216025940_wp_
b = f * a - b + 0.000162708379043_wp_
a = f * b - a + 0.002536308188086_wp_
b = f * a - b + 0.030080722420512_wp_
a = f * b - a + 0.259084432434900_wp_
b = f * a - b + 1.511535676029228_wp_
a = f * b - a + 5.283632866873920_wp_
b = f * a - b + 8.005368868700334_wp_
a = f * b - a - 4.563433586448395_wp_
a = f * a - b - 21.057660177402440_wp_
besik=-log(0.125_wp_*x)*besik+0.5_wp_*(a-b)
if(e) besik=exp(x)*besik
return
!
4 f=32.0_wp_/v-2.0_wp_
b = - 0.000000000000001_wp_
a = f * b - 0.000000000000001_wp_
b = f * a - b + 0.000000000000004_wp_
a = f * b - a + 0.000000000000010_wp_
b = f * a - b - 0.000000000000024_wp_
a = f * b - a - 0.000000000000104_wp_
b = f * a - b + 0.000000000000039_wp_
a = f * b - a + 0.000000000000966_wp_
b = f * a - b + 0.000000000001800_wp_
a = f * b - a - 0.000000000004497_wp_
b = f * a - b - 0.000000000033127_wp_
a = f * b - a - 0.000000000078957_wp_
b = f * a - b + 0.000000000029802_wp_
a = f * b - a + 0.000000001238425_wp_
b = f * a - b + 0.000000008513091_wp_
a = f * b - a + 0.000000056816966_wp_
b = f * a - b + 0.000000513587727_wp_
a = f * b - a + 0.000007247591100_wp_
b = f * a - b + 0.000172700630778_wp_
a = f * b - a + 0.008445122624921_wp_
a = f * a - b + 2.016558410917480_wp_
besik=0.199471140200717_wp_*(a-b)/sqrt(v)
if(e) return
besik=exp(v)*besik
return
!
entry ebesi1(x)
!
e=.true.
go to 2
!
entry besi1(x)
!
e=.false.
2 l=.true.
v=abs(x)
if(v >= 8.0_wp_) go to 3
7 f=0.0625_wp_*x**2-2.0_wp_
a = + 0.000000000000001_wp_
b = f * a + 0.000000000000031_wp_
a = f * b - a + 0.000000000001679_wp_
b = f * a - b + 0.000000000079291_wp_
a = f * b - a + 0.000000003227617_wp_
b = f * a - b + 0.000000111946285_wp_
a = f * b - a + 0.000003264138122_wp_
b = f * a - b + 0.000078756785754_wp_
a = f * b - a + 0.001543019015627_wp_
b = f * a - b + 0.023993079147841_wp_
a = f * b - a + 0.287855511804672_wp_
b = f * a - b + 2.571459906347755_wp_
a = f * b - a + 16.334550552522066_wp_
b = f * a - b + 69.395917633734448_wp_
a = f * b - a + 181.312616040570265_wp_
a = f * a - b + 259.890237806477292_wp_
besik=0.0625_wp_*(a-b)*x
if(l .and. e) besik=exp(-v)*besik
if(l) return
!
a = + 0.000000000000001_wp_
b = f * a + 0.000000000000042_wp_
a = f * b - a + 0.000000000002163_wp_
b = f * a - b + 0.000000000096660_wp_
a = f * b - a + 0.000000003696783_wp_
b = f * a - b + 0.000000119367971_wp_
a = f * b - a + 0.000003202510692_wp_
b = f * a - b + 0.000070010627855_wp_
a = f * b - a + 0.001217056994516_wp_
b = f * a - b + 0.016300049289816_wp_
a = f * b - a + 0.161074301656148_wp_
b = f * a - b + 1.101461993004852_wp_
a = f * b - a + 4.666387026862842_wp_
b = f * a - b + 9.361617831395389_wp_
a = f * b - a - 1.839239224286199_wp_
a = f * a - b - 26.688095480862668_wp_
besik=log(0.125_wp_*x)*besik+1.0_wp_/x-0.0625_wp_*(a-b)*x
if(e) besik=exp(x)*besik
return
!
3 f=32.0_wp_/v-2.0_wp_
b = + 0.000000000000001_wp_
a = f * b + 0.000000000000001_wp_
b = f * a - b - 0.000000000000005_wp_
a = f * b - a - 0.000000000000010_wp_
b = f * a - b + 0.000000000000026_wp_
a = f * b - a + 0.000000000000107_wp_
b = f * a - b - 0.000000000000053_wp_
a = f * b - a - 0.000000000001024_wp_
b = f * a - b - 0.000000000001804_wp_
a = f * b - a + 0.000000000005103_wp_
b = f * a - b + 0.000000000035408_wp_
a = f * b - a + 0.000000000081531_wp_
b = f * a - b - 0.000000000047563_wp_
a = f * b - a - 0.000000001401141_wp_
b = f * a - b - 0.000000009613873_wp_
a = f * b - a - 0.000000065961142_wp_
b = f * a - b - 0.000000629724239_wp_
a = f * b - a - 0.000009732146728_wp_
b = f * a - b - 0.000277205360764_wp_
a = f * b - a - 0.024467442963276_wp_
a = f * a - b + 1.951601204652572_wp_
besik=0.199471140200717_wp_*(a-b)/sqrt(v)
if(x < 0.0_wp_) besik=-besik
if(e) return
besik=exp(v)*besik
return
!
entry ebesk0 (x)
!
e=.true.
go to 11
!
entry besk0(x)
!
e=.false.
11 if(x <= 0.0_wp_) go to 9
l=.false.
v=x
if(x < 5.0_wp_) go to 8
f=20.0_wp_/x-2.0_wp_
a = - 0.000000000000002_wp_
b = f * a + 0.000000000000011_wp_
a = f * b - a - 0.000000000000079_wp_
b = f * a - b + 0.000000000000581_wp_
a = f * b - a - 0.000000000004580_wp_
b = f * a - b + 0.000000000039044_wp_
a = f * b - a - 0.000000000364547_wp_
b = f * a - b + 0.000000003792996_wp_
a = f * b - a - 0.000000045047338_wp_
b = f * a - b + 0.000000632575109_wp_
a = f * b - a - 0.000011106685197_wp_
b = f * a - b + 0.000269532612763_wp_
a = f * b - a - 0.011310504646928_wp_
a = f * a - b + 1.976816348461652_wp_
besik=0.626657068657750_wp_*(a-b)/sqrt(x)
if(e) return
z=besik
besik=0.0_wp_
if(x < 180.0_wp_) besik=exp(-x)*z
return
!
entry ebesk1(x)
!
e=.true.
go to 12
!
entry besk1(x)
!
e=.false.
12 if(x <= 0.0_wp_) go to 9
l=.false.
v=x
if(x < 5.0_wp_) go to 7
f=20.0_wp_/x-2.0_wp_
a = + 0.000000000000002_wp_
b = f * a - 0.000000000000013_wp_
a = f * b - a + 0.000000000000089_wp_
b = f * a - b - 0.000000000000663_wp_
a = f * b - a + 0.000000000005288_wp_
b = f * a - b - 0.000000000045757_wp_
a = f * b - a + 0.000000000435417_wp_
b = f * a - b - 0.000000004645555_wp_
a = f * b - a + 0.000000057132218_wp_
b = f * a - b - 0.000000845172048_wp_
a = f * b - a + 0.000016185063810_wp_
b = f * a - b - 0.000468475028167_wp_
a = f * b - a + 0.035465291243331_wp_
a = f * a - b + 2.071901717544716_wp_
besik=0.626657068657750_wp_*(a-b)/sqrt(x)
if(e) return
z=besik
besik=0.0_wp_
if(x < 180.0_wp_) besik=exp(-x)*z
return
9 besik=0.0_wp_
write(nout,"(1x,'besik ... non-positive argument x = ',e15.4)") x
end function besik
!
! routines for conical function: end
!
end module conical

View File

@ -1,7 +1,6 @@
module dispersion
!
use const_and_precisions, only : wp_,zero,one,im,czero,cunit,pi,sqrt_pi
use eierf, only : calcei3
implicit none
! local constants
integer, parameter :: npts=500
@ -255,6 +254,7 @@ subroutine diel_tens_fr(xg,yg,mu,npl,e330,cr,ci,epsl,lrm,fast)
! Fully relativistic case computation of dielectric tensor elements
! up to third order in Larmor radius for hermitian part
!
use math, only : fact
implicit none
! arguments
integer :: lrm,fast
@ -360,6 +360,7 @@ end subroutine diel_tens_fr
!
!
subroutine hermitian(rr,yg,mu,npl,cr,fast,lrm)
use eierf, only : calcei3
implicit none
! arguments
integer :: lrm,fast
@ -572,6 +573,7 @@ end subroutine hermitian
!
!
subroutine hermitian_2(rr,yg,mu,npl,cr,fast,lrm)
use quadpack, only : dqagsmv !dqagimv
implicit none
! local constants
integer,parameter :: lw=5000,liw=lw/4,npar=7
@ -621,9 +623,9 @@ subroutine hermitian_2(rr,yg,mu,npl,cr,fast,lrm)
if(n.eq.0.and.m.eq.0) ihmin=2
do ih=ihmin,2
apar(7) = real(ih,wp_)
! call dqagi(fhermit,bound,2,epsa,epsr,resfh,
call dqagsmv(fhermit,-tmax,tmax,apar,npar,epsa, &
epsr,resfh,epp,neval,ier,liw,lw,last,iw,w)
! call dqagimv(fhermit,bound,2,apar,npar,epsa,epsr,resfh,
call dqagsmv(fhermit,-tmax,tmax,apar,npar,epsa,epsr,resfh, &
epp,neval,ier,liw,lw,last,iw,w)
rr(n,ih,m) = resfh
end do
end do
@ -719,6 +721,7 @@ end subroutine hermitian_2
!
!
function fhermit(t,apar,npar)
use eierf, only : calcei3
implicit none
! arguments
integer, intent(in) :: npar
@ -771,6 +774,7 @@ end function fhermit
!
!
subroutine antihermitian(ri,yg,mu,npl,ci,lrm)
use math, only : fact
implicit none
! local constants
integer, parameter :: lmx=20,nmx=lmx+2
@ -866,6 +870,7 @@ end subroutine antihermitian
!
!
subroutine ssbi(zz,n,l,fsbi)
use math, only : gamm
implicit none
! local constants
integer, parameter :: lmx=20,nmx=lmx+2
@ -876,7 +881,7 @@ subroutine ssbi(zz,n,l,fsbi)
real(wp_), dimension(nmx) :: fsbi
! local variables
integer :: k,m,mm
real(wp_) :: c0,c1,sbi,gamm
real(wp_) :: c0,c1,sbi
!
do m=n,l+2
c0=one/gamm(dble(m)+1.5_wp_)
@ -909,29 +914,11 @@ end subroutine expinit
!
!
!
function fact(k)
implicit none
! arguments
real(wp_) :: fact
! local variables
integer :: i,k
!
fact=0.0_wp_
if(k.lt.0) return
fact=1.0_wp_
if(k.eq.0) return
do i=1,k
fact=fact*i
end do
!
end function fact
!
!
!
subroutine diel_tens_wr(xg,yg,mu,npl,e330,epsl,lrm)
! Weakly relativistic dielectric tensor computation of dielectric
! tensor elements (Krivenki and Orefice, JPP 30,125 - 1983)
!
use math, only : fact
implicit none
! arguments
integer :: lrm
@ -939,7 +926,7 @@ subroutine diel_tens_wr(xg,yg,mu,npl,e330,epsl,lrm)
complex(wp_) :: e330,epsl(3,3,lrm)
! local variables
integer :: l,lm,is,k
real(wp_) :: npl2,fcl,w,asl,bsl,fact
real(wp_) :: npl2,fcl,w,asl,bsl
complex(wp_) :: ca11,ca12,ca13,ca22,ca23,ca33,cq0p,cq0m,cq1p,cq1m,cq2p
complex(wp_), dimension(0:lrm,0:2) :: cefp,cefm
!
@ -996,7 +983,7 @@ subroutine diel_tens_wr(xg,yg,mu,npl,e330,epsl,lrm)
epsl(3,2,l) = - epsl(2,3,l)
end do
!
end
end subroutine diel_tens_wr
!
!
!
@ -1144,7 +1131,202 @@ subroutine fsup(cefp,cefm,lrm,yg,npl,mu)
!
end do
!
end
end subroutine fsup
!
! PLASMA DISPERSION FUNCTION Z of complex argument
! Z(z) = i sqrt(pi) w(z)
! Function w(z) from:
! algorithm 680, collected algorithms from acm.
! this work published in transactions on mathematical software,
! vol. 16, no. 1, pp. 47.
!
subroutine zetac (xi, yi, zr, zi, iflag)
!
! given a complex number z = (xi,yi), this subroutine computes
! the value of the faddeeva-function w(z) = exp(-z**2)*erfc(-i*z),
! where erfc is the complex complementary error-function and i
! means sqrt(-1).
! the accuracy of the algorithm for z in the 1st and 2nd quadrant
! is 14 significant digits; in the 3rd and 4th it is 13 significant
! digits outside a circular region with radius 0.126 around a zero
! of the function.
! all real variables in the program are real(8).
!
!
! the code contains a few compiler-dependent parameters :
! rmaxreal = the maximum value of rmaxreal equals the root of
! rmax = the largest number which can still be
! implemented on the computer in real(8)
! floating-point arithmetic
! rmaxexp = ln(rmax) - ln(2)
! rmaxgoni = the largest possible argument of a real(8)
! goniometric function (cos, sin, ...)
! the reason why these parameters are needed as they are defined will
! be explained in the code by means of comments
!
!
! parameter list
! xi = real part of z
! yi = imaginary part of z
! u = real part of w(z)
! v = imaginary part of w(z)
! iflag = an error flag indicating whether overflow will
! occur or not; type integer;
! the values of this variable have the following
! meaning :
! iflag=0 : no error condition
! iflag=1 : overflow will occur, the routine
! becomes inactive
! xi, yi are the input-parameters
! u, v, iflag are the output-parameters
!
! furthermore the parameter factor equals 2/sqrt(pi)
!
! the routine is not underflow-protected but any variable can be
! put to 0 upon underflow;
!
! reference - gpm poppe, cmj wijers; more efficient computation of
! the complex error-function, acm trans. math. software.
!
implicit none
real(wp_), intent(in) :: xi, yi
real(wp_), intent(out) :: zr, zi
integer, intent(out) :: iflag
real(wp_) :: xabs,yabs,x,y,qrho,xabsq,xquad,yquad,xsum,ysum,xaux,daux, &
u,u1,u2,v,v1,v2,h,h2,qlambda,c,rx,ry,sx,sy,tx,ty,w1
integer :: i,j,n,nu,kapn,np1
real(wp_), parameter :: factor = 1.12837916709551257388_wp_, &
rpi = 2.0_wp_/factor, &
rmaxreal = 0.5e+154_wp_, &
rmaxexp = 708.503061461606_wp_, &
rmaxgoni = 3.53711887601422e+15_wp_
iflag=0
xabs = abs(xi)
yabs = abs(yi)
x = xabs/6.3_wp_
y = yabs/4.4_wp_
!
! the following if-statement protects
! qrho = (x**2 + y**2) against overflow
!
if ((xabs>rmaxreal).or.(yabs>rmaxreal)) then
iflag=1
return
end if
qrho = x**2 + y**2
xabsq = xabs**2
xquad = xabsq - yabs**2
yquad = 2*xabs*yabs
if (qrho<0.085264_wp_) then
!
! if (qrho<0.085264_wp_) then the faddeeva-function is evaluated
! using a power-series (abramowitz/stegun, equation (7.1.5), p.297)
! n is the minimum number of terms needed to obtain the required
! accuracy
!
qrho = (1-0.85_wp_*y)*sqrt(qrho)
n = idnint(6 + 72*qrho)
j = 2*n+1
xsum = 1.0_wp_/j
ysum = 0.0_wp_
do i=n, 1, -1
j = j - 2
xaux = (xsum*xquad - ysum*yquad)/i
ysum = (xsum*yquad + ysum*xquad)/i
xsum = xaux + 1.0_wp_/j
end do
u1 = -factor*(xsum*yabs + ysum*xabs) + 1.0_wp_
v1 = factor*(xsum*xabs - ysum*yabs)
daux = exp(-xquad)
u2 = daux*cos(yquad)
v2 = -daux*sin(yquad)
u = u1*u2 - v1*v2
v = u1*v2 + v1*u2
else
!
! if (qrho>1.o) then w(z) is evaluated using the laplace
! continued fraction
! nu is the minimum number of terms needed to obtain the required
! accuracy
!
! if ((qrho>0.085264_wp_).and.(qrho<1.0)) then w(z) is evaluated
! by a truncated taylor expansion, where the laplace continued fraction
! is used to calculate the derivatives of w(z)
! kapn is the minimum number of terms in the taylor expansion needed
! to obtain the required accuracy
! nu is the minimum number of terms of the continued fraction needed
! to calculate the derivatives with the required accuracy
!
if (qrho>1.0_wp_) then
h = 0.0_wp_
kapn = 0
qrho = sqrt(qrho)
nu = idint(3 + (1442/(26*qrho+77)))
else
qrho = (1-y)*sqrt(1-qrho)
h = 1.88_wp_*qrho
h2 = 2*h
kapn = idnint(7 + 34*qrho)
nu = idnint(16 + 26*qrho)
endif
if (h>0.0_wp_) qlambda = h2**kapn
rx = 0.0_wp_
ry = 0.0_wp_
sx = 0.0_wp_
sy = 0.0_wp_
do n=nu, 0, -1
np1 = n + 1
tx = yabs + h + np1*rx
ty = xabs - np1*ry
c = 0.5_wp_/(tx**2 + ty**2)
rx = c*tx
ry = c*ty
if ((h>0.0_wp_).and.(n<=kapn)) then
tx = qlambda + sx
sx = rx*tx - ry*sy
sy = ry*tx + rx*sy
qlambda = qlambda/h2
endif
end do
if (h==0.0_wp_) then
u = factor*rx
v = factor*ry
else
u = factor*sx
v = factor*sy
end if
if (yabs==0.0_wp_) u = exp(-xabs**2)
end if
!
! evaluation of w(z) in the other quadrants
!
if (yi<0.0_wp_) then
if (qrho<0.085264_wp_) then
u2 = 2*u2
v2 = 2*v2
else
xquad = -xquad
!
! the following if-statement protects 2*exp(-z**2)
! against overflow
!
if ((yquad>rmaxgoni).or. (xquad>rmaxexp)) then
iflag=1
return
end if
w1 = 2.0_wp_*exp(xquad)
u2 = w1*cos(yquad)
v2 = -w1*sin(yquad)
end if
u = u2 - u
v = v2 - v
if (xi>0.0_wp_) v = -v
else
if (xi<0.0_wp_) v = -v
end if
zr = -v*rpi
zi = u*rpi
end subroutine zetac
!
end module dispersion

File diff suppressed because it is too large Load Diff

View File

@ -1054,6 +1054,7 @@ c
c
subroutine read_beams
use graydata_flags, only : filenmbm, ibeam
use utils, only : locate
implicit real*8(a-h,o-z)
parameter(nstrmx=50)
@ -1165,6 +1166,7 @@ c
c
subroutine equidata
use const_and_precisions, only : pi
use utils, only : vmaxmini
use graydata_flags, only : ipsinorm,sspl,ixp,icocos,neqdsk
use graydata_par, only : sgnbphi,sgniphi,factb
use interp_eqprof, only : nsrt,nszt,nsft,rlim,zlim,nlim,nr,nz,
@ -1613,6 +1615,8 @@ c
c
c
subroutine points_ox(rz,zz,rf,zf,psinvf,info)
use const_and_precisions, only : comp_eps
use minpack, only : hybrj1
implicit real*8 (a-h,o-z)
parameter(n=2,ldfjac=n,lwa=(n*(n+13))/2)
dimension xvec(n),fvec(n),fjac(ldfjac,n),wa(lwa)
@ -1620,7 +1624,7 @@ c
common/psival/psinv
xvec(1)=rz
xvec(2)=zz
tol = sqrt(dpmpar(1))
tol = sqrt(comp_eps)
call hybrj1(fcnox,n,xvec,fvec,fjac,ldfjac,tol,info,wa,lwa)
if(info.gt.1) then
print'(a,i2,a,2f8.4)',' info subr points_ox =',info,
@ -1664,6 +1668,8 @@ c
c
c
subroutine points_tgo(rz,zz,rf,zf,psin,info)
use const_and_precisions, only : comp_eps
use minpack, only : hybrj1
implicit real*8 (a-h,o-z)
parameter(n=2,ldfjac=n,lwa=(n*(n+13))/2)
dimension xvec(n),fvec(n),fjac(ldfjac,n),wa(lwa)
@ -1672,7 +1678,7 @@ c
h=psin
xvec(1)=rz
xvec(2)=zz
tol = sqrt(dpmpar(1))
tol = sqrt(comp_eps)
call hybrj1(fcntgo,n,xvec,fvec,fjac,ldfjac,tol,info,wa,lwa)
if(info.gt.1) then
end if
@ -1717,6 +1723,7 @@ c
c
subroutine print_prof
use interp_eqprof, only : psinr,qpsi,nr
use utils, only : intlin
implicit real*8 (a-h,o-z)
parameter(eps=1.d-4)
@ -1782,6 +1789,7 @@ c
subroutine surfq(qval,psival)
use magsurf_data, only : npoints
use interp_eqprof, only : nr,psinr,qpsi
use utils, only : locate, intlin
implicit real*8 (a-h,o-z)
dimension rcn(npoints),zcn(npoints)
@ -4469,6 +4477,7 @@ c
use graydata_flags, only : iprof
use graydata_anequil, only : te0,dte0,alt1,alt2
use interp_eqprof, only : psrad,ct,npp
use utils, only : locate
implicit real*8 (a-h,o-z)
c
@ -4493,6 +4502,7 @@ c
use graydata_flags, only : iprof
use graydata_anequil, only : zeffan
use interp_eqprof, only : psrad,cz,npp
use utils, only : locate
implicit real*8 (a-h,o-z)
c
@ -4514,6 +4524,7 @@ c beam tracing initial conditions igrad=1
c
subroutine ic_gb
use const_and_precisions, only : izero,zero,one,pi,cvdr=>degree
use math, only : catand
use graydata_flags, only : ipol
use graydata_par, only : rwmax,psipol0,chipol0
@ -4530,8 +4541,6 @@ c
complex*16 ui,sss,ddd,phic,qi1,qi2,tc,ts,qqxx,qqxy,qqyy
complex*16 dqi1,dqi2,dqqxx,dqqyy,dqqxy
complex*16 d2qi1,d2qi2,d2qqxx,d2qqyy,d2qqxy
complex*16 catand
external catand
c
common/nray/nrayr,nrayth
common/parwv/ak0,akinv,fhz
@ -5382,14 +5391,14 @@ c
use green_func_p, only: SpitzFuncCoeff
use const_and_precisions, only : pi,qesi=>e_,mesi=>me_,vcsi=>c_,
* qe=>ecgs_,me=>mecgs_,vc=>ccgs_,mc2=>mc2_
use conical, only : fconic
implicit none
real*8 anum,denom,resp,resj,effjcd,coullog,dens
real*8 yg,anpl,anpr,amu,anprre,anprim
real*8 mc2m2,anucc,canucc,ddens
real*8 ceff,Zeff,psinv
real*8 rbn,rbx,alams,fp0s,pa,fc
real*8 fjch,fjncl,fjch0,fconic
real*8 fjch,fjncl,fjch0
real*8 cst2,eccdpar(5)
complex*16 ex,ey,ez
integer ieccd,nhmn,nhmx,nhn,ithn,ierr,iokhawa
@ -5477,6 +5486,7 @@ c
c
subroutine curr_int(yg,anpl,anprre,amu,ex,ey,ez,nhn,ithn,cst2,
* fcur,eccdpar,necp,resj,resp,iokhawa,ierr)
use quadpack, only : dqagsmv
implicit real*8(a-h,o-z)
parameter(epsa=0.0d0,epsr=1.0d-2)
parameter(xxcr=16.0d0)
@ -5639,6 +5649,7 @@ c extrapar(14) = uplm
c extrapar(15) = ygn
c
use const_and_precisions, only : ui=>im
use math, only : fact
implicit real*8 (a-h,o-z)
complex*16 ex,ey,ez,emxy,epxy
dimension extrapar(npar)
@ -5726,6 +5737,7 @@ c extrapar(18) = alams
c extrapar(19) = pa
c extrapar(20) = fp0s
c
use conical, only : fconic
implicit real*8 (a-h,o-z)
complex*16 ex,ey,ez
dimension extrapar(npar)
@ -6013,8 +6025,10 @@ c
c
subroutine pec(pabs,currt)
use const_and_precisions, only : pi,one
use numint, only : simpson
use graydata_flags, only : ipec,ieccd,iequil,nnd,dst
use graydata_anequil, only : rr0m,rpam
use utils, only : locatex, locate, intlin
implicit real*8(a-h,o-z)
parameter(nndmx=5001,jmx=31,kmx=36,nmx=8000)
@ -6359,6 +6373,7 @@ c
subroutine profwidth(nd,xx,yy,rhotmx,rhopmx,ypk,drhot,drhop)
use const_and_precisions, only : emn1
use graydata_flags, only : ipec,iequil
use utils, only : locatex, locate, intlin, vmaxmini
implicit real*8(a-h,o-z)
dimension xx(nd),yy(nd)

File diff suppressed because it is too large Load Diff

View File

@ -388,6 +388,7 @@
! dKdu - its derivative
!=======================================================================
use const_and_precisions, only : zero,one
use numint, only : quanc8
IMPLICIT NONE
REAL(wp_), INTENT(in) :: Zeff,fc,u,q,gam
REAL(wp_), INTENT(out) :: K,dKdu

125
src/math.f90 Normal file
View File

@ -0,0 +1,125 @@
module math
use const_and_precisions, only : wp_, zero, one
implicit none
contains
function catand(z)
!***begin prologue catan
!***purpose compute the complex arc tangent.
!***library slatec (fnlib)
!***category c4a
!***type complex (catan-c)
!***keywords arc tangent, elementary functions, fnlib, trigonometric
!***author fullerton, w., (lanl)
!***description
!
! catan(z) calculates the complex trigonometric arc tangent of z.
! the result is in units of radians, and the real part is in the first
! or fourth quadrant.
!
!***references (none)
!***routines called (none)
!***revision history (yymmdd)
! 770801 date written
! 890531 changed all specific intrinsics to generic. (wrb)
! 890531 revision date from version 3.2
! 891214 prologue converted to version 4.0 format. (bab)
! 900315 calls to xerror changed to calls to xermsg. (thj)
! 900326 removed duplicate information from description section.
! (wrb)
!***end prologue catan
use const_and_precisions, only : comp_eps, pi2=>pihalf, czero, cunit
implicit none
complex(wp_) :: catand
complex(wp_), intent(in) :: z
complex(wp_) :: z2
real(wp_) :: r,x,y,r2,xans,yans,twoi
integer :: i
logical, save :: first=.true.
integer, save :: nterms
real(wp_), save :: rmin, rmax, sqeps
!***first executable statement catan
if (first) then
! nterms = log(eps)/log(rbnd) where rbnd = 0.1
nterms = int(-0.4343_wp_*log(0.5_wp_*comp_eps) + 1.0_wp_)
sqeps = sqrt(comp_eps)
rmin = sqrt (1.5_wp_*comp_eps)
rmax = 2.0_wp_/comp_eps
endif
first = .false.
!
r = abs(z)
if (r<=0.1_wp_) then
!
catand = z
if (r<rmin) return
!
catand = czero
z2 = z*z
do i=1,nterms
twoi = 2*(nterms-i) + 1
catand = 1.0_wp_/twoi - z2*catand
end do
catand = z*catand
!
else if (r<=rmax) then
x = real(z)
y = aimag(z)
r2 = r*r
if (r2==one.and.x==zero) print*,'catand, z is +i or -i'
if (abs(r2-one)<=sqeps) then
if (abs(cunit+z*z) < sqeps) &
print*,'catand, answer lt half precision, z**2 close to -1'
!
end if
xans = 0.5_wp_*atan2(2.0_wp_*x, one)
yans = 0.25_wp_*log((r2+2.0_wp_*y+one)/(r2-2.0_wp_*y+one))
catand = cmplx(xans, yans, wp_)
!
else
catand = cmplx(pi2, zero, wp_)
if (real(z)<zero) catand = cmplx(-pi2, zero, wp_)
end if
end function catand
function fact(k)
implicit none
integer, intent(in) :: k
real(wp_) :: fact
integer :: i
! Factorial function
fact=zero
if(k<0) return
fact=one
if(k==0) return
do i=1,k
fact=fact*i
end do
end function fact
function gamm(xx)
implicit none
real(wp_) :: gamm
real(wp_), intent(in) :: xx
! Returns the value Gamma(xx) for xx > 0.
INTEGER :: j
real(wp_) :: ser,tmp,x,y
real(wp_), parameter :: stp=2.5066282746310005_wp_
real(wp_), dimension(6), parameter :: cof=(/76.18009172947146_wp_, &
-86.50532032941677_wp_,24.01409824083091_wp_,-1.231739572450155_wp_, &
.1208650973866179e-2_wp_,-.5395239384953e-5_wp_/)
x=xx
y=x
tmp=x+5.5_wp_
tmp=(x+0.5_wp_)*log(tmp)-tmp
ser=1.000000000190015_wp_
do j=1,6
y=y+1._wp_
ser=ser+cof(j)/y
end do
gamm=exp(tmp)*(stp*ser/x)
end function gamm
end module math

1401
src/minpack.f90 Normal file

File diff suppressed because it is too large Load Diff

257
src/numint.f90 Normal file
View File

@ -0,0 +1,257 @@
module numint
use const_and_precisions, only : wp_, zero, one
implicit none
contains
subroutine simpson (n,h,fi,s)
! subroutine for integration over f(x) with the simpson rule. fi:
! integrand f(x); h: interval; s: integral. copyright (c) tao pang 1997.
implicit none
integer, intent(in) :: n
real(wp_), intent(in) :: h
real(wp_), dimension(n), intent(in) :: fi
real(wp_), intent(out) :: s
integer :: i
real(wp_) :: s0,s1,s2
s = zero
s0 = zero
s1 = zero
s2 = zero
do i = 2, n-1, 2
s1 = s1+fi(i-1)
s0 = s0+fi(i)
s2 = s2+fi(i+1)
end do
s = h*(s1+4.0_wp_*s0+s2)/3.0_wp_
! if n is even, add the last slice separately
if (mod(n,2).eq.0) s = s+h*(5.0_wp_*fi(n)+8.0_wp_*fi(n-1)-fi(n-2))/12.0_wp_
end subroutine simpson
subroutine trapezoid(n,xi,fi,s)
! subroutine for integration with the trapezoidal rule.
! fi: integrand f(x); xi: abscissa x;
! s: integral Int_{xi(1)}^{xi(n)} f(x)dx
implicit none
integer, intent(in) :: n
real(wp_), dimension(n), intent(in) :: xi,fi
real(wp_), intent(out) :: s
integer :: i
s = zero
do i = 1, n-1
s = s+(xi(i+1)-xi(i))*(fi(i+1)-fi(i))
end do
s = 0.5_wp_*s
end subroutine trapezoid
subroutine quanc8(fun,a,b,abserr,relerr,result,errest,nofun,flag)
implicit none
real(wp_), intent(in) :: a, b, abserr, relerr
real(wp_), intent(out) :: result, errest, flag
integer, intent(out) :: nofun
!
! estimate the integral of fun(x) from a to b
! to a user provided tolerance.
! an automatic adaptive routine based on
! the 8-panel newton-cotes rule.
!
! input ..
!
! fun the name of the integrand function subprogram fun(x).
! a the lower limit of integration.
! b the upper limit of integration.(b may be less than a.)
! relerr a relative error tolerance. (should be non-negative)
! abserr an absolute error tolerance. (should be non-negative)
!
! output ..
!
! result an approximation to the integral hopefully satisfying the
! least stringent of the two error tolerances.
! errest an estimate of the magnitude of the actual error.
! nofun the number of function values used in calculation of result.
! flag a reliability indicator. if flag is zero, then result
! probably satisfies the error tolerance. if flag is
! xxx.yyy , then xxx = the number of intervals which have
! not converged and 0.yyy = the fraction of the interval
! left to do when the limit on nofun was approached.
!
real(wp_) :: w0,w1,w2,w3,w4,area,x0,f0,stone,step,cor11,temp
real(wp_) :: qprev,qnow,qdiff,qleft,esterr,tolerr
real(wp_), dimension(31) :: qright
real(wp_), dimension(16) :: f,x
real(wp_), dimension(8,30) :: fsave,xsave
integer :: levmin,levmax,levout,nomax,nofin,lev,nim,i,j
interface
function fun(x)
use const_and_precisions, only : wp_
implicit none
real(wp_), intent(in) :: x
real(wp_) :: fun
end function fun
end interface
!
! *** stage 1 *** general initialization
! set constants.
!
levmin = 1
levmax = 30
levout = 6
nomax = 5000
nofin = nomax - 8*(levmax-levout+2**(levout+1))
!
! trouble when nofun reaches nofin
!
w0 = 3956.0_wp_ / 14175.0_wp_
w1 = 23552.0_wp_ / 14175.0_wp_
w2 = -3712.0_wp_ / 14175.0_wp_
w3 = 41984.0_wp_ / 14175.0_wp_
w4 = -18160.0_wp_ / 14175.0_wp_
!
! initialize running sums to zero.
!
flag = zero
result = zero
cor11 = zero
errest = zero
area = zero
nofun = 0
if (a .eq. b) return
!
! *** stage 2 *** initialization for first interval
!
lev = 0
nim = 1
x0 = a
x(16) = b
qprev = zero
f0 = fun(x0)
stone = (b - a) / 16.0_wp_
x(8) = (x0 + x(16)) / 2.0_wp_
x(4) = (x0 + x(8)) / 2.0_wp_
x(12) = (x(8) + x(16)) / 2.0_wp_
x(2) = (x0 + x(4)) / 2.0_wp_
x(6) = (x(4) + x(8)) / 2.0_wp_
x(10) = (x(8) + x(12)) / 2.0_wp_
x(14) = (x(12) + x(16)) / 2.0_wp_
do j = 2, 16, 2
f(j) = fun(x(j))
end do
nofun = 9
!
! *** stage 3 *** central calculation
! requires qprev,x0,x2,x4,...,x16,f0,f2,f4,...,f16.
! calculates x1,x3,...x15, f1,f3,...f15,qleft,qright,qnow,qdiff,area.
!
do
do
x(1) = (x0 + x(2)) / 2.0_wp_
f(1) = fun(x(1))
do j = 3, 15, 2
x(j) = (x(j-1) + x(j+1)) / 2.0_wp_
f(j) = fun(x(j))
end do
nofun = nofun + 8
step = (x(16) - x0) / 16.0_wp_
qleft = (w0*(f0 + f(8)) + w1*(f(1)+f(7)) + w2*(f(2)+f(6)) &
+ w3*(f(3)+f(5)) + w4*f(4)) * step
qright(lev+1)=(w0*(f(8)+f(16))+w1*(f(9)+f(15))+w2*(f(10)+f(14)) &
+ w3*(f(11)+f(13)) + w4*f(12)) * step
qnow = qleft + qright(lev+1)
qdiff = qnow - qprev
area = area + qdiff
!
! *** stage 4 *** interval convergence test
!
esterr = abs(qdiff) / 1023.0_wp_
tolerr = max(abserr,relerr*abs(area)) * (step/stone)
if (lev .ge. levmin) then
!
! *** stage 6 *** trouble section
! number of function values is about to exceed limit.
!
if (lev .ge. levmax) then
!
! current level is levmax.
!
flag = flag + one
exit
end if
if (nofun .gt. nofin) then
nofin = 2*nofin
levmax = levout
flag = flag + (b - x0) / (b - a)
exit
end if
if (esterr .le. tolerr) exit
end if
!
! *** stage 5 *** no convergence
! locate next interval.
!
nim = 2*nim
lev = lev+1
!
! store right hand elements for future use.
!
do i = 1, 8
fsave(i,lev) = f(i+8)
xsave(i,lev) = x(i+8)
end do
!
! assemble left hand elements for immediate use.
!
qprev = qleft
do i = 1, 8
j = -i
f(2*j+18) = f(j+9)
x(2*j+18) = x(j+9)
end do
end do
!
! *** stage 7 *** interval converged
! add contributions into running sums.
!
result = result + qnow
errest = errest + esterr
cor11 = cor11 + qdiff / 1023.0_wp_
!
! locate next interval.
!
do
if (nim .eq. 2*(nim/2)) exit
nim = nim/2
lev = lev-1
end do
nim = nim + 1
if (lev .le. 0) exit
!
! assemble elements required for the next interval.
!
qprev = qright(lev)
x0 = x(16)
f0 = f(16)
do i = 1, 8
f(2*i) = fsave(i,lev)
x(2*i) = xsave(i,lev)
end do
end do
!
! *** stage 8 *** finalize and return
!
result = result + cor11
!
! make sure errest not less than roundoff level.
!
if (errest .eq. zero) return
do
temp = abs(result) + errest
if (temp .ne. abs(result)) return
errest = 2.0_wp_*errest
end do
end subroutine quanc8
end module numint

4541
src/quadpack.f90 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -75,6 +75,7 @@ subroutine inters_linewall(xv,kv,rw,zw,nw,sint,normw)
end subroutine inters_linewall
subroutine linecone_coord(xv,kv,rs,zs,s,t,n)
use utils, only : bubble
implicit none
real(wp_), intent(in), dimension(3) :: xv,kv
real(wp_), intent(in), dimension(2) :: rs,zs
@ -155,7 +156,7 @@ subroutine interssegm_coord(xa,ya,xb,yb,s,t,ierr)
dxb = xb(2)-xb(1)
dyb = yb(2)-yb(1)
crossprod = dxb*dya - dxa*dyb
if (abs(crossprod)<tiny(crossprod)) then
if (abs(crossprod)<comp_tiny) then
s = zero
t = zero
ierr = 1
@ -179,6 +180,7 @@ function interssegm(xa,ya,xb,yb)
end function interssegm
function inside(xc,yc,n,x,y)
use utils, only : locatef, locate_unord, intlinf, bubble
implicit none
integer, intent(in) :: n
real(wp_), dimension(n), intent(in) :: xc,yc
@ -196,92 +198,12 @@ function inside(xc,yc,n,x,y)
inside=.false.
if (nj==0) return
do i=1,nj
xint(i)=intlin(yclosed(jint(i)),xclosed(jint(i)), &
xint(i)=intlinf(yclosed(jint(i)),xclosed(jint(i)), &
yclosed(jint(i)+1),xclosed(jint(i)+1),y)
end do
call bubble(xint,nj)
inside=(mod(locate(xint,nj,x),2)==1)
inside=(mod(locatef(xint,nj,x),2)==1)
end function inside
function intlin(x1,y1,x2,y2,x) result(y)
!linear interpolation
!must be x1 != x2
implicit none
real(wp_),intent(in) :: x1,y1,x2,y2,x
real(wp_) :: y
real(wp_) :: a
a=(x2-x)/(x2-x1)
y=a*y1+(one-a)*y2
end function intlin
subroutine locate_unord(a,n,x,j,m,nj)
implicit none
integer, intent(in) :: n,m
integer, intent(out) :: nj
real(wp_), dimension(n), intent(in) :: a
real(wp_), intent(in) :: x
integer, dimension(m), intent(inout) :: j
integer :: i
nj=0
do i=1,n-1
if (x>a(i).neqv.x>a(i+1)) then
nj=nj+1
if (nj<=m) j(nj)=i
end if
end do
end subroutine locate_unord
function locate(a,n,x) result(j)
!Given an array a(n), and a value x, with a(n) monotonic, either
!increasing or decreasing, returns a value j such that
!a(j) < x <= a(j+1) for a increasing, and such that
!a(j+1) < x <= a(j) for a decreasing.
!j=0 or j=n indicate that x is out of range (Numerical Recipes)
implicit none
integer, intent(in) :: n
real(wp_), dimension(n), intent(in) :: a
real(wp_), intent(in) :: x
integer :: j
integer :: jl,ju,jm
logical :: incr
jl=0
ju=n+1
incr=a(n)>a(1)
do while ((ju-jl)>1)
jm=(ju+jl)/2
if(incr.eqv.(x>a(jm))) then
jl=jm
else
ju=jm
endif
end do
j=jl
end function locate
subroutine order(p,q)
!returns p,q in ascending order
implicit none
real(wp_), intent(inout) :: p,q
real(wp_) :: temp
if (p>q) then
temp=p
p=q
q=temp
end if
end subroutine order
subroutine bubble(a,n)
!bubble sorting of array a
implicit none
integer, intent(in) :: n
real(wp_), dimension(n), intent(inout) :: a
integer :: i, j
do i=1,n
do j=n,i+1,-1
call order(a(j-1), a(j))
end do
end do
end subroutine bubble
end module reflections

249
src/utils.f90 Normal file
View File

@ -0,0 +1,249 @@
module utils
use const_and_precisions, only : wp_
implicit none
contains
function locatef(a,n,x) result(j)
! Given an array a(n), and a value x, with a(n) monotonic, either
! increasing or decreasing, returns a value j such that
! a(j) < x <= a(j+1) for a increasing, and such that
! a(j+1) < x <= a(j) for a decreasing.
! j=0 or j=n indicate that x is out of range (Numerical Recipes)
implicit none
integer, intent(in) :: n
real(wp_), dimension(n), intent(in) :: a
real(wp_), intent(in) :: x
integer :: j
integer :: jl,ju,jm
logical :: incr
jl=0
ju=n+1
incr=a(n)>a(1)
do while ((ju-jl)>1)
jm=(ju+jl)/2
if(incr.eqv.(x>a(jm))) then
jl=jm
else
ju=jm
endif
end do
j=jl
end function locatef
subroutine locate(xx,n,x,j)
implicit none
integer, intent(in) :: n
real(wp_), intent(in) :: xx(n), x
integer, intent(out) :: j
integer :: jl,ju,jm
logical :: incr
!
! Given an array xx(n), and a value x
! returns a value j such that xx(j) < x < xx(j+1)
! xx(n) must be monotonic, either increasing or decreasing.
! j=0 or j=n indicate that x is out of range (Numerical Recipes)
!
jl=0
ju=n+1
incr=xx(n)>xx(1)
do while ((ju-jl)>1)
jm=(ju+jl)/2
if(incr .eqv. (x>xx(jm))) then
jl=jm
else
ju=jm
endif
end do
j=jl
end subroutine locate
subroutine locatex(xx,n,n1,n2,x,j)
implicit none
integer, intent(in) :: n,n1,n2
real(wp_), intent(in) :: xx(n), x
integer, intent(out) :: j
integer :: jl,ju,jm
!
! Given an array xx(n), and a value x
! returns a value j such that xx(j) < x < xx(j+1)
! xx(n) must be monotonic, either increasing or decreasing.
! j=n1-1or j=n2+1 indicate that x is out of range
! modified from subr. locate (Numerical Recipes)
!
jl=n1-1
ju=n2+1
do while ((ju-jl)>1)
jm=(ju+jl)/2
if((xx(n2)>xx(n1)) .eqv. (x>xx(jm))) then
jl=jm
else
ju=jm
endif
end do
j=jl
end subroutine locatex
subroutine locate_unord(a,n,x,j,m,nj)
implicit none
integer, intent(in) :: n,m
integer, intent(out) :: nj
real(wp_), dimension(n), intent(in) :: a
real(wp_), intent(in) :: x
integer, dimension(m), intent(inout) :: j
integer :: i
nj=0
do i=1,n-1
if (x>a(i).neqv.x>a(i+1)) then
nj=nj+1
if (nj<=m) j(nj)=i
end if
end do
end subroutine locate_unord
function intlinf(x1,y1,x2,y2,x) result(y)
!linear interpolation
!must be x1 != x2
use const_and_precisions, only : one
implicit none
real(wp_),intent(in) :: x1,y1,x2,y2,x
real(wp_) :: y
real(wp_) :: a
a=(x2-x)/(x2-x1)
y=a*y1+(one-a)*y2
end function intlinf
subroutine intlin(x1,y1,x2,y2,x,y)
implicit none
real(wp_), intent(in) :: x1,y1,x2,y2,x
real(wp_), intent(out) :: y
real(wp_) :: dx,aa,bb
!
! linear interpolation
! (x1,y1) < (x,y) < (x2,y2)
!
dx=x2-x1
aa=(x2-x)/dx
bb=1.0_wp_-aa
y=aa*y1+bb*y2
end subroutine intlin
subroutine vmax(x,n,xmax,imx)
implicit none
integer, intent(in) :: n
real(wp_), intent(in) :: x(n)
real(wp_), intent(out) :: xmax
integer, intent(out) :: imx
integer :: i
if (n<1) then
imx=0
return
end if
imx=1
xmax=x(1)
do i=2,n
if(x(i)>xmax) then
xmax=x(i)
imx=i
end if
end do
end subroutine vmax
subroutine vmin(x,n,xmin,imn)
implicit none
integer, intent(in) :: n
real(wp_), intent(in) :: x(n)
real(wp_), intent(out) :: xmin
integer, intent(out) :: imn
integer :: i
if (n<1) then
imn=0
return
end if
imn=1
xmin=x(1)
do i=2,n
if(x(i)<xmin) then
xmin=x(i)
imn=i
end if
end do
end subroutine vmin
subroutine vmaxmini(x,n,xmin,xmax,imn,imx)
implicit none
integer, intent(in) :: n
real(wp_), intent(in) :: x(n)
real(wp_), intent(out) :: xmin, xmax
integer, intent(out) :: imn, imx
integer :: i
if (n<1) then
imn=0
imx=0
return
end if
imn=1
imx=1
xmin=x(1)
xmax=x(1)
do i=2,n
if(x(i)<xmin) then
xmin=x(i)
imn=i
else if(x(i)>xmax) then
xmax=x(i)
imx=i
end if
end do
end subroutine vmaxmini
subroutine vmaxmin(x,n,xmin,xmax)
implicit none
integer, intent(in) :: n
real(wp_), intent(in) :: x(n)
real(wp_), intent(out) :: xmin, xmax
integer :: i
if (n<1) then
return
end if
xmin=x(1)
xmax=x(1)
do i=2,n
if(x(i)<xmin) then
xmin=x(i)
else if(x(i)>xmax) then
xmax=x(i)
end if
end do
end subroutine vmaxmin
subroutine order(p,q)
! returns p,q in ascending order
implicit none
real(wp_), intent(inout) :: p,q
real(wp_) :: temp
if (p>q) then
temp=p
p=q
q=temp
end if
end subroutine order
subroutine bubble(a,n)
! bubble sorting of array a
implicit none
integer, intent(in) :: n
real(wp_), dimension(n), intent(inout) :: a
integer :: i, j
do i=1,n
do j=n,i+1,-1
call order(a(j-1), a(j))
end do
end do
end subroutine bubble
end module utils