V3FIT
tridslv.f
1  SUBROUTINE tridslv(a, d, b, c, jmin, jmax, mnd1, ns, nrhs)
2  USE stel_kinds
3  IMPLICIT NONE
4 C-----------------------------------------------
5 C D u m m y A r g u m e n t s
6 C-----------------------------------------------
7  INTEGER, INTENT(in) :: jmax, mnd1, ns, nrhs
8  INTEGER, DIMENSION(0:mnd1), INTENT(in) :: jmin
9  REAL(rprec), DIMENSION(ns,0:mnd1) :: a, d, b
10  REAL(rprec), DIMENSION(ns,0:mnd1, nrhs), INTENT(inout) :: c
11 C-----------------------------------------------
12 C L o c a l P a r a m e t e r s
13 C-----------------------------------------------
14  REAL(rprec), PARAMETER :: zero = 0, one = 1
15 C-----------------------------------------------
16 C L o c a l V a r i a b l e s
17 C-----------------------------------------------
18  INTEGER :: mn, in, i0, in1, jrhs
19  REAL(rprec), ALLOCATABLE, DIMENSION(:,:) :: alf
20  REAL(rprec), DIMENSION(0:mnd1) :: psi0
21 C-----------------------------------------------
22 !
23 ! SOLVES B(I)*X(I-1)+D(I)*X(I)+A(I)*X(I+1)=C(I), I=IN,JMAX
24 ! AND RETURNS ANSWER IN C(I)
25 ! ADDED VECTORIZATION ON FOURIER MODE ARGUMENT (01-2000)
26 ! AND NEW ARGUMENT (NRHS) TO DO MULTIPLE RIGHT SIDES SIMULTANEOUSLY
27 !
28  IF (jmax .gt. ns) stop 'jmax>ns in tridslv'
29 
30  ALLOCATE (alf(ns,0:mnd1), stat = in)
31  IF (in .ne. 0) stop 'Allocation error in tridslv'
32 
33  in = minval(jmin)
34 !
35 ! FILL IN MN BELOW MAX(JMIN) WITH DUMMY VALUES
36 ! TO ALLOW VECTORIZATION ON MN INDEX
37 !
38  DO mn = 0, mnd1
39  in1 = jmin(mn)-1
40  IF (in1 .ge. in) THEN
41  d(in:in1, mn) = 1
42  c(in:in1, mn, 1:nrhs) = 0
43  b(in:in1, mn) = 0
44  a(in:in1, mn) = 0
45  END IF
46  END DO
47 
48  in1 = in + 1
49 
50  psi0(:)= d(in,:)
51  IF (any(psi0 .eq. zero)) stop 'psi0 == 0 error in tridslv'
52  psi0 = one/psi0
53  DO jrhs = 1, nrhs
54  c(in,:,jrhs) = c(in,:,jrhs)*psi0(:)
55  END DO
56 
57  DO i0 = in1,jmax
58  alf(i0-1,:) = a(i0-1,:)*psi0(:)
59  psi0 = d(i0,:) - b(i0,:)*alf(i0-1,:)
60  IF (any(abs(psi0) .le. 1.e-8_dp*abs(d(i0,:))))
61  1 stop 'psi0/d(i0) < 1.E-8: possible singularity in tridslv'
62  psi0 = one/psi0
63  DO jrhs = 1, nrhs
64  c(i0,:,jrhs) = (c(i0,:,jrhs) - b(i0,:)*c(i0-1,:,jrhs))
65  1 * psi0
66  END DO
67  END DO
68 
69  DO i0 = jmax - 1, in, -1
70  DO jrhs = 1,nrhs
71  c(i0,:,jrhs) = c(i0,:,jrhs) - alf(i0,:)*c(i0+1,:,jrhs)
72  END DO
73  END DO
74 
75  DEALLOCATE (alf)
76 
77  END SUBROUTINE tridslv
78 
79 !
80 ! ADDED 10/3/14 TO HANDLE DATA-LAYOUT IN PARALLEL VERSION OF VMEC2000
81  SUBROUTINE tridslv_par(a, d, b, c, jmin, jmax, mnd1, ns, nrhs)
82  USE stel_kinds
83  IMPLICIT NONE
84 C-----------------------------------------------
85 C D u m m y A r g u m e n t s
86 C-----------------------------------------------
87  INTEGER, INTENT(in) :: jmax, mnd1, ns, nrhs
88  INTEGER, DIMENSION(0:mnd1), INTENT(in) :: jmin
89  REAL(rprec), DIMENSION(0:mnd1,ns) :: a, d, b
90  REAL(rprec), DIMENSION(0:mnd1,ns,nrhs), INTENT(inout) :: c
91 C-----------------------------------------------
92 C L o c a l P a r a m e t e r s
93 C-----------------------------------------------
94  REAL(rprec), PARAMETER :: zero = 0, one = 1
95 C-----------------------------------------------
96 C L o c a l V a r i a b l e s
97 C-----------------------------------------------
98  INTEGER :: mn, in, i0, in1, jrhs
99  REAL(rprec), ALLOCATABLE, DIMENSION(:,:) :: alf
100  REAL(rprec), DIMENSION(0:mnd1) :: psi0
101 C-----------------------------------------------
102 !
103 ! SOLVES B(I)*X(I-1)+D(I)*X(I)+A(I)*X(I+1)=C(I), I=IN,JMAX
104 ! AND RETURNS ANSWER IN C(I)
105 ! ADDED VECTORIZATION ON FOURIER MODE ARGUMENT (01-2000)
106 ! AND NEW ARGUMENT (NRHS) TO DO MULTIPLE RIGHT SIDES SIMULTANEOUSLY
107 !
108  IF (jmax .gt. ns) stop 'jmax>ns in tridslv_par'
109 
110  ALLOCATE (alf(0:mnd1,ns), stat=in)
111  IF (in .ne. 0) stop 'Allocation error in tridslv_par'
112 
113  in = minval(jmin)
114 !
115 ! FILL IN MN BELOW MAX(JMIN) WITH DUMMY VALUES
116 ! TO ALLOW VECTORIZATION ON MN INDEX
117 !
118  DO mn = 0, mnd1
119  in1 = jmin(mn)-1
120  IF (in1 .ge. in) THEN
121  d(mn, in:in1) = 1
122  c(mn, in:in1, 1:nrhs) = 0
123  b(mn, in:in1) = 0
124  a(mn, in:in1) = 0
125  END IF
126  END DO
127 
128  in1 = in + 1
129 
130  psi0(:)= d(:,in)
131  IF (any(psi0 .eq. zero)) stop 'psi0 == 0 error in tridslv_par'
132  psi0 = one/psi0
133  DO jrhs = 1, nrhs
134  c(:,in,jrhs) = c(:,in,jrhs)*psi0(:)
135  END DO
136 
137  DO i0 = in1,jmax
138  alf(:,i0-1) = a(:,i0-1)*psi0(:)
139  psi0 = d(:,i0) - b(:,i0)*alf(:,i0-1)
140  IF (any(abs(psi0) .le. 1.e-8_dp*abs(d(:,i0))))
141  1 stop 'psi0/d(i0) < 1.E-8: possible singularity in tridslv'
142  psi0 = one/psi0
143  DO jrhs = 1, nrhs
144  c(:,i0,jrhs) = (c(:,i0,jrhs) - b(:,i0)*c(:,i0-1,jrhs))
145  1 * psi0
146  END DO
147  END DO
148 
149  DO i0 = jmax - 1, in, -1
150  DO jrhs = 1,nrhs
151  c(:,i0,jrhs) = c(:,i0,jrhs) - alf(:,i0)*c(:,i0+1,jrhs)
152  END DO
153  END DO
154 
155  DEALLOCATE (alf)
156 
157  END SUBROUTINE tridslv_par
158