Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_pivotbande.F90
Go to the documentation of this file.
2 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 #include "sll_memory.h"
4 #include "sll_working_precision.h"
5 
6  implicit none
7 
8  public :: &
12 
13  private
14 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 contains
16 
17  subroutine searchband(a, n, l1, l2)
18  implicit none
19  sll_real64, dimension(:, :)::a
20  sll_int32, intent(in) ::n
21  sll_int32, intent(out) ::l1, l2
22  sll_int32, dimension(n) ::b1, b2
23  sll_int32::i, j, ll1, ll2!,width
24 
25  l1 = 0
26  l2 = 0
27  ! let us find the width of the band of the matrix
28  ! to the right (l2) and to the left (1)
29 
30  do j = 1, n
31  do i = j, n
32  if (abs(a(i, j)) > 1d-16) then
33  ll1 = i - j
34  ll2 = i - j
35  end if
36  end do
37  b1(j) = ll1
38  b2(j) = ll2
39  end do
40 
41  l1 = b1(1)
42  l2 = b2(1)
43 
44  do i = 2, n
45  if (b1(i) > l1) l1 = b1(i)
46  if (b2(i) > l2) l2 = b2(i)
47  end do
48 
49  !width = l1 + l2 + 1 ! total width
50 
51  end subroutine searchband
52 
53 !***********************************************
54 
55  subroutine factolub(a, l, u, n, l1, l2)
56  implicit none
57  sll_real64, dimension(:, :), intent(in)::a
58  sll_real64, dimension(:, :), intent(out)::l, u
59  sll_int32, intent(in)::n, l1, l2
60  sll_int32::i, j, k, ll1, ll2
61 
62  !init
63 
64  u = a
65  l = 0._f64
66  do i = 1, n
67  l(i, i) = 1._f64
68  end do
69 
70  !transformation
71 
72  do k = 1, n - 1
73  ll1 = k + l1
74  if (ll1 > n) ll1 = n
75  do i = k + 1, ll1
76  l(i, k) = u(i, k)/u(k, k)
77  ll2 = k + l2
78  if (ll2 > n) ll2 = n
79  do j = k, ll2
80  u(i, j) = u(i, j) - l(i, k)*u(k, j)
81  end do
82  end do
83  end do
84 
85  ! do k = 1,n-1
86  ! do i = k + 1, n
87  ! l(i,k) = u(i,k)/u(k,k)
88  ! print*,i,k,u(k,k),u(i,k) ,l(i,k)
89  ! do j = k,n
90  ! u(i,j) = u(i,j)-l(i,k)*u(k,j)
91  ! enddo
92  ! enddo
93  ! enddo
94 
95  end subroutine factolub
96  !***********************************************
97 
98  subroutine sll_s_factolub_bande(a, l, u, n, l1, l2)
99  implicit none
100  sll_real64, dimension(:, :), intent(in)::a
101  sll_real64, dimension(:, :), intent(out)::l, u
102  sll_int32, intent(in)::n, l1, l2
103  sll_int32::i, j, k, ll1, band, ki, ji, ll1i
104 
105  band = l1 + l2 + 1
106 
107  u = a
108  l = 0._f64
109  ll1 = l1 + 1
110  do i = 1, n
111  l(i, ll1) = 1._f64
112  end do
113 
114  do k = 1, n - 1
115  do i = 1, l1
116  ki = k + i
117  ll1i = ll1 - i
118  if (ki <= n) then
119  if (abs(u(ki, ll1i)) > 1d-16) then
120  l(ki, ll1i) = u(ki, ll1i)/u(k, ll1)
121  !if ( abs(l(ki,ll1i)) > 1e-17 ) then
122  do j = 1, band
123  ji = j + i
124  if (ji <= band) u(ki, j) = u(ki, j) - l(ki, ll1i)*u(k, ji)
125  end do
126  end if
127  end if
128  end do
129  end do
130 
131  end subroutine sll_s_factolub_bande
132 
133  !***********************************************
134 
135  subroutine solvlub(l, u, x, b, n, l1, l2)
136  implicit none
137  sll_real64, dimension(:, :), intent(in)::l, u
138  sll_real64, dimension(:), intent(in)::b
139  sll_int32, intent(in)::l1, l2
140  sll_real64, dimension(:), intent(inout)::x
141  sll_int32, intent(in)::n
142  sll_int32 ::i, j, ll1, ll2
143  sll_real64 ::s
144 
145  x(1) = b(1)/l(1, 1)
146 
147  do i = 2, n
148  s = 0._f64
149  ll1 = i - l1
150  if (ll1 < 1) ll1 = 1
151  do j = ll1, i - 1
152  s = s + l(i, j)*x(j)
153  end do
154  x(i) = (b(i) - s)/l(i, i)
155  end do
156 
157  x(n) = x(n)/u(n, n)
158 
159  do i = n - 1, 1, -1
160  s = 0._f64
161  ll2 = i + l2
162  if (ll2 > n) ll2 = n
163  do j = i + 1, ll2
164  s = s + u(i, j)*x(j)
165  end do
166  x(i) = (x(i) - s)/u(i, i)
167  end do
168 
169  end subroutine solvlub
170 
171  !***********************************************
172 
173  subroutine sll_s_solvlub_bande(l, u, x, b, n, l1, l2)
174  implicit none
175  sll_real64, dimension(:, :), intent(in)::l, u
176  sll_real64, dimension(:), intent(in)::b
177  sll_int32, intent(in)::l1, l2
178  sll_real64, dimension(:), intent(inout)::x
179  sll_int32, intent(in)::n
180  sll_int32 ::i, j, ll1, lll1, ll1j, ij
181  sll_real64 ::s
182 
183  lll1 = l1 + 1
184  x(1) = b(1)/l(1, lll1)
185 
186  do i = 2, n
187  s = 0._f64
188  ll1 = i - lll1
189  do j = 1, l1
190  ll1j = ll1 + j
191  if (ll1j > 0) s = s + l(i, j)*x(ll1j)
192  end do
193  x(i) = (b(i) - s)/l(i, lll1)
194  end do
195 
196  x(n) = x(n)/u(n, lll1)
197 
198  do i = n - 1, 1, -1
199  s = 0._f64
200  do j = 1, l2
201  ij = i + j
202  if (ij <= n) s = s + u(i, lll1 + j)*x(ij)
203  end do
204  x(i) = (x(i) - s)/u(i, lll1)
205  end do
206 
207  end subroutine sll_s_solvlub_bande
208 
209  !***********************************************
210 
211  subroutine gauss_seidel(a, x, b, n)
212  sll_real64, dimension(:, :), intent(in) :: a
213  sll_real64, dimension(:), intent(out):: x
214  sll_real64, dimension(:), intent(in):: b
215  sll_int32, intent(in) :: n
216  sll_real64, dimension(:), allocatable :: x_k, x_k1
217  sll_real64 :: error_l2, s1, s2
218  sll_int32 :: i, j
219 
220  allocate (x_k(n), x_k1(n))
221 
222  x_k = 1._f64
223  x_k1 = x_k
224 
225  error_l2 = 1._f64
226 
227  do while (error_l2 > 1d-12)
228 
229  do i = 1, n
230  s1 = 0._f64
231  s2 = 0._f64
232  if (i - 1 > 0) then
233  do j = 1, i - 1
234  s1 = s1 + a(i, j)*x_k1(j)
235  end do
236  end if
237  do j = i + 1, n
238  s2 = s2 + a(i, j)*x_k(j)
239  end do
240 
241  x_k1(i) = (b(i) - s1 - s2)/a(i, i)
242 
243  end do
244 
245  call residue(a, x_k1, b, n, error_l2)
246 
247  x_k = x_k1
248  end do
249 
250  x = x_k
251 
252  deallocate (x_k, x_k1)
253 
254  end subroutine gauss_seidel
255 
256  subroutine residue(a, x, b, n, error_l2)
257  sll_real64, dimension(:, :), intent(in) :: a
258  sll_real64, dimension(:), intent(in) :: x
259  sll_real64, dimension(:), intent(in) :: b
260  sll_int32, intent(in) :: n
261  sll_real64, intent(out) :: error_l2
262  sll_real64 :: s
263  sll_int32 :: i, j
264 
265  ! computing ||Ax - b ||
266 
267  error_l2 = 0._f64
268 
269  do i = 1, n
270  s = 0._f64
271  do j = 1, n
272  s = s + a(i, j)*x(j)
273  end do
274  error_l2 = error_l2 + (s - b(i))**2
275  end do
276 
277  error_l2 = sqrt(error_l2)
278 
279  end subroutine residue
280 
281  subroutine gauss_seidel_bande(a, x, b, l1, l2, n)
282  sll_real64, dimension(:, :), intent(in) :: a
283  sll_real64, dimension(:), intent(out):: x
284  sll_real64, dimension(:), intent(in):: b
285  sll_int32, intent(in) :: n
286  sll_real64, dimension(:), allocatable :: x_k, x_k1
287  sll_real64 :: error_l2, s1, s2
288  sll_int32, intent(in) :: l1, l2
289  sll_int32 :: i, j, k, l_tot
290 
291  allocate (x_k(n), x_k1(n))
292 
293  x_k = 1._f64
294  x_k1 = x_k
295 
296  error_l2 = 1._f64
297  l_tot = l1 + l2 + 1
298 
299  do while (error_l2 > 1d-12)
300 
301  do i = 1, n
302 
303  s1 = 0._f64
304  s2 = 0._f64
305  k = i - l1 - 1
306 
307  do j = 1, l1
308  if (k + j > 0) s1 = s1 + a(i, j)*x_k1(k + j)
309  end do
310 
311  do j = l1 + 2, l_tot
312  if (k + j <= n) s2 = s2 + a(i, j)*x_k(k + j)
313  end do
314 
315  x_k1(i) = (b(i) - s1 - s2)/a(i, 1 + l1)
316 
317  end do
318 
319  call sll_s_residue_bande(a, x_k1, b, l1, l2, n, error_l2)
320  x_k = x_k1
321 
322  end do
323 
324  x = x_k
325 
326  deallocate (x_k, x_k1)
327 
328  end subroutine gauss_seidel_bande
329 
330  subroutine sll_s_residue_bande(a, x, b, l1, l2, n, error_l2)
331  sll_real64, dimension(:, :), intent(in) :: a
332  sll_real64, dimension(:), intent(in) :: x
333  sll_real64, dimension(:), intent(in) :: b
334  sll_int32, intent(in) :: n
335  sll_int32, intent(in) :: l1, l2
336  sll_real64, intent(out) :: error_l2
337  sll_real64 :: s
338  sll_int32 :: i, j, k, l_tot, kj
339 
340  ! computing ||Ax - b ||
341 
342  error_l2 = 0._f64
343 
344  l_tot = l1 + l2 + 1
345 
346  do i = 1, n
347  s = 0._f64
348  k = i - l1 - 1
349  do j = 1, l_tot
350  kj = k + j
351  if (kj > 0 .and. kj <= n) s = s + a(i, j)*x(kj)
352  end do
353  error_l2 = error_l2 + (s - b(i))**2
354  end do
355 
356  error_l2 = sqrt(error_l2)
357 
358  end subroutine sll_s_residue_bande
359 
360 end module sll_m_pivotbande
subroutine searchband(a, n, l1, l2)
subroutine residue(a, x, b, n, error_l2)
subroutine, public sll_s_solvlub_bande(l, u, x, b, n, l1, l2)
subroutine, public sll_s_factolub_bande(a, l, u, n, l1, l2)
subroutine gauss_seidel_bande(a, x, b, l1, l2, n)
subroutine solvlub(l, u, x, b, n, l1, l2)
subroutine gauss_seidel(a, x, b, n)
subroutine, public sll_s_residue_bande(a, x, b, l1, l2, n, error_l2)
subroutine factolub(a, l, u, n, l1, l2)
    Report Typos and Errors