SICOPOLIS V3.0
 All Classes Files Functions Variables Macros
tri_sle.F90
Go to the documentation of this file.
1 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 !
3 ! Subroutine : t r i _ s l e
4 !
5 !> @file
6 !!
7 !! Solution of a system of linear equations Ax=b with tridiagonal matrix A.
8 !!
9 !! @section Copyright
10 !!
11 !! Copyright 2009-2013 Ralf Greve
12 !!
13 !! @section License
14 !!
15 !! This file is part of SICOPOLIS.
16 !!
17 !! SICOPOLIS is free software: you can redistribute it and/or modify
18 !! it under the terms of the GNU General Public License as published by
19 !! the Free Software Foundation, either version 3 of the License, or
20 !! (at your option) any later version.
21 !!
22 !! SICOPOLIS is distributed in the hope that it will be useful,
23 !! but WITHOUT ANY WARRANTY; without even the implied warranty of
24 !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 !! GNU General Public License for more details.
26 !!
27 !! You should have received a copy of the GNU General Public License
28 !! along with SICOPOLIS. If not, see <http://www.gnu.org/licenses/>.
29 !<
30 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31 
32 !-------------------------------------------------------------------------------
33 !> Solution of a system of linear equations Ax=b with tridiagonal matrix A.
34 !! @param[in] a0 a0(j) is element A_(j,j-1) of Matrix A
35 !! @param[in] a1 a1(j) is element A_(j,j) of Matrix A
36 !! @param[in] a2 a2(j) is element A_(j,j+1) of Matrix A
37 !! @param[in] b inhomogeneity vector
38 !! @param[in] nzeilen size of matrix A (indices run from 0 (!!!) to nzeilen)
39 !! @param[out] x Solution vector.
40 !<------------------------------------------------------------------------------
41 subroutine tri_sle(a0, a1, a2, x, b, nzeilen)
42 
43 use sico_types
44 
45 implicit none
46 
47 real(dp), dimension(0:*) :: a0, a1, a2, x, b
48 real(dp), allocatable, dimension(:) :: help_x
49 integer(i4b) :: nzeilen
50 integer(i4b) :: n
51 
52 !-------- Generate an upper triangular matrix
53 ! ('obere Dreiecksmatrix') --------
54 
55 do n=1, nzeilen
56  a1(n) = a1(n) - a0(n)/a1(n-1)*a2(n-1)
57 end do
58 
59 do n=1, nzeilen
60  b(n) = b(n) - a0(n)/a1(n-1)*b(n-1)
61 ! a0(n) = 0.0_dp , not needed in the following, therefore
62 ! not set
63 end do
64 
65 !-------- Iterative solution of the new system --------
66 
67 ! x(nzeilen) = b(nzeilen)/a1(nzeilen)
68 
69 ! do n=nzeilen-1, 0, -1
70 ! x(n) = (b(n)-a2(n)*x(n+1))/a1(n)
71 ! end do
72 
73 allocate(help_x(0:nzeilen))
74 
75 help_x(0) = b(nzeilen)/a1(nzeilen)
76 
77 do n=1, nzeilen
78  help_x(n) = b(nzeilen-n)/a1(nzeilen-n) &
79  -a2(nzeilen-n)/a1(nzeilen-n)*help_x(n-1)
80 end do
81 
82 do n=0, nzeilen
83  x(n) = help_x(nzeilen-n)
84 end do
85 
86 ! (The trick with the help_x was introduced in order to avoid
87 ! the negative step in the original, blanked-out loop.)
88 
89 deallocate(help_x)
90 
91 ! WARNING: Subroutine does not check for elements of the main
92 ! diagonal becoming zero. In this case it crashes even
93 ! though the system may be solvable. Otherwise ok.
94 
95 end subroutine tri_sle
96 !