VMEC 8.52
3D Equilibrium solver with nested flux surfaces.
Loading...
Searching...
No Matches
spline_akima_int.f
Go to the documentation of this file.
1!> \file
2 SUBROUTINE spline_akima_int(x,y,xx,yy,npts,iflag)
3! returns the integral from xx(1) to x of the function
4! given by the Akima spline.
5 USE stel_kinds
6 implicit none
7!-----------------------------------------------
8! D u m m y A r g u m e n t s
9!-----------------------------------------------
10 integer, intent(in) :: npts ! number of active points
11 integer, intent(inout) :: iflag
12 real(rprec), intent(in) :: x
13 real(rprec), intent(out) :: y
14 real(rprec), dimension(npts), intent(in) :: xx, yy
15!-----------------------------------------------
16! L o c a l V a r i a b l e s
17!-----------------------------------------------
18 real(rprec), dimension(-1:size(xx)+2) :: a, b, c, d
19 real(rprec), dimension(-1:size(xx)+2) :: xloc, yloc,dxloc
20 real(rprec), dimension(-1:size(xx)+2) :: m, t, dm, p, q
21 real(rprec), dimension(-1:size(xx)+2) :: int_f
22 integer :: i, ix, iv, ivm1
23 real(rprec) :: cl,bl,cr,br,dx
24 real(rprec), parameter :: onethird = 1._dp/3._dp
25!-----------------------------------------------
26
27 iflag = 0 !initialization
28 ix = size(xx)
29 if(npts > ix)
30 > stop 'spline_akima_int: more active points
31 > requested than available'
32 if(ix /= size(yy)) stop 'size mismatch of xx and yy!'
33 iv=npts
34 ivm1 = iv-1
35! initialize local variables
36 a = 0._dp ; b = 0._dp ; c = 0._dp ; d = 0._dp
37 xloc = 0._dp ; yloc = 0._dp
38 m = 0._dp ; t = 0._dp ; dm = 0._dp
39 p = 0._dp ; q = 0._dp
40
41 xloc(1:iv)=xx
42 xloc(-1)= 2*xloc(1)-xloc(3)
43 xloc( 0)= xloc(1)+xloc(2)-xloc(3)
44 xloc(iv+2)= 2*xloc(iv)-xloc(iv-2)
45 xloc(iv+1)= xloc(iv)+xloc(iv-1)-xloc(iv-2)
46 dxloc(-1:iv+1)=xloc(0:iv+2)-xloc(-1:iv+1)
47 yloc(1:iv)=yy
48! calculate linear derivatives as far as existent
49 m(-1:iv+1) = (yloc(0:iv+2)-yloc(-1:iv+1))/
50 > dxloc(-1:iv+1)
51! > (xloc(0:iv+2)-xloc(-1:iv+1))
52! values for i=0, -1 and iv, iv+1 by quadratic extrapolation:
53! the right edge mirrors the left: use the right-edge curvature cr (not cl)
54! for the upper phantom points, so the interpolant is orientation-independent.
55 cl = (m(2)-m(1))/(xloc(3)-xloc(1))
56 bl = m(1) - cl*(xloc(2)-xloc(1))
57 cr = (m(iv-1)-m(iv-2))/(xloc(iv)-xloc(iv-2))
58 br = m(iv-1) - cr*(xloc(iv-1)-xloc(iv))
59 yloc( 0)=yloc(1)+bl*(xloc( 0)-xloc(1))+
60 > cl*(xloc( 0)-xloc(1))**2
61 yloc(-1)=yloc(1)+bl*(xloc(-1)-xloc(1))+
62 > cl*(xloc(-1)-xloc(1))**2
63 yloc(iv+1)=yloc(iv)+br*(xloc(iv+1)-xloc(iv))+
64 > cr*(xloc(iv+1)-xloc(iv))**2
65 yloc(iv+2)=yloc(iv)+br*(xloc(iv+2)-xloc(iv))+
66 > cr*(xloc(iv+2)-xloc(iv))**2
67! rest of linear derivatives
68 m(-1) = (yloc(0)-yloc(-1))/(xloc(0)-xloc(-1))
69 m( 0) = (yloc(1)-yloc( 0))/(xloc(1)-xloc( 0))
70 m(iv ) = (yloc(iv+1)-yloc(iv ))/(xloc(iv+1)-xloc(iv ))
71 m(iv+1) = (yloc(iv+2)-yloc(iv+1))/(xloc(iv+2)-xloc(iv+1))
72! calculate weights for derivatives
73 dm(-1:iv)= abs(m(0:iv+1)-m(-1:iv))
74 where (dm /= 0._dp) !exclude division by zero
75 p(1:iv) = dm(1:iv)/(dm(1:iv)+dm(-1:iv-2))
76 end where
77 where (dm /= 0._dp) !exclude division by zero
78 q(1:iv) = dm(-1:iv-2)/(dm(1:iv)+dm(-1:iv-2))
79 end where
80 t(1:iv) = p(1:iv)*m(0:iv-1)+q(1:iv)*m(1:iv)
81 where ( p(1:iv)+q(1:iv) < tiny(1._dp)) ! in case of two zeros give equal weight
82 t(1:iv) = 0.5_dp*m(0:iv-1)+0.5_dp*m(1:iv)
83 end where
84! fix coefficients
85 a = yloc
86 b = t
87 c(1:iv-1) = (3*m(1:iv-1)-t(2:iv)-2*t(1:iv-1))/
88 > (dxloc(1:iv-1))
89 d(1:iv-1) = (t(2:iv)+t(1:iv-1)-2*m(1:iv-1))/
90 > (dxloc(1:iv-1))**2
91
92! calculation
93 int_f(1:iv-1) = a(1:iv-1)*dxloc(1:iv-1)+
94 > 0.5_dp*b(1:iv-1)*dxloc(1:iv-1)**2 +
95 > onethird*c(1:iv-1)*dxloc(1:iv-1)**3 +
96 > 0.25_dp*d(1:iv-1)*dxloc(1:iv-1)**4
97 if(x >= xloc(iv)) then
98 y = sum(int_f(1:iv-1))
99 iflag = 0
100 if(x>xloc(iv)) iflag=-1
101 return
102 endif
103 if(x <= xloc(1)) then
104 y = 0._dp
105 iflag = 0
106 if(x<xloc(1)) iflag=-1
107 return
108 endif
109 y=0._dp
110 do i=1,iv-1
111 if(x >= xloc(i+1))then
112 y=y + int_f(i)
113 else
114 dx = x-xloc(i)
115 y=y+dx*(a(i)+dx*(.5_dp*b(i)+dx*(
116 > onethird*c(i)+.25_dp*d(i)*dx)))
117 return
118 endif
119 enddo
120
121 END SUBROUTINE spline_akima_int
122
subroutine spline_akima_int(x, y, xx, yy, npts, iflag)