SICOPOLIS V3.0
 All Classes Files Functions Variables Macros
sor_sprs.F90
Go to the documentation of this file.
1 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 !
3 ! Subroutine : s o r _ s p r s
4 !
5 !> @file
6 !!
7 !! SOR solver for a system of linear equations lgs_a*lgs_x=lgs_b
8 !! [matrix in compressed row storage CRS,
9 !! represented by arrays lgs_a_value(values), lgs_a_index (indices)
10 !! and lgs_a_ptr (pointers)].
11 !!
12 !! @section Copyright
13 !!
14 !! Copyright 2009-2013 Ralf Greve, Tatsuru Sato
15 !!
16 !! @section License
17 !!
18 !! This file is part of SICOPOLIS.
19 !!
20 !! SICOPOLIS is free software: you can redistribute it and/or modify
21 !! it under the terms of the GNU General Public License as published by
22 !! the Free Software Foundation, either version 3 of the License, or
23 !! (at your option) any later version.
24 !!
25 !! SICOPOLIS is distributed in the hope that it will be useful,
26 !! but WITHOUT ANY WARRANTY; without even the implied warranty of
27 !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 !! GNU General Public License for more details.
29 !!
30 !! You should have received a copy of the GNU General Public License
31 !! along with SICOPOLIS. If not, see <http://www.gnu.org/licenses/>.
32 !<
33 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34 
35 !-------------------------------------------------------------------------------
36 !> SOR solver for a system of linear equations lgs_a*lgs_x=lgs_b
37 !! [matrix in compressed row storage CRS,
38 !! represented by arrays lgs_a_value(values), lgs_a_index (indices)
39 !! and lgs_a_ptr (pointers)].
40 !<------------------------------------------------------------------------------
41 subroutine sor_sprs(lgs_a_value, lgs_a_index, lgs_a_diag_index, lgs_a_ptr, &
42  lgs_b_value, &
43  nnz, nmax, omega, eps_sor, lgs_x_value, ierr)
44 
45 use sico_types
46 
47 implicit none
48 
49 integer(i4b), intent(in) :: nnz, nmax
50 real(dp), intent(in) :: omega, eps_sor
51 integer(i4b), dimension(nmax+1), intent(in) :: lgs_a_ptr
52 integer(i4b), dimension(nnz), intent(in) :: lgs_a_index
53 integer(i4b), dimension(nmax), intent(in) :: lgs_a_diag_index
54 real(dp), dimension(nnz), intent(in) :: lgs_a_value
55 real(dp), dimension(nmax), intent(in) :: lgs_b_value
56 
57 integer(i4b), intent(out) :: ierr
58 real(dp), dimension(nmax), intent(inout) :: lgs_x_value
59 
60 integer(i4b) :: iter
61 integer(i4b) :: nr, k
62 real(dp), allocatable, dimension(:) :: lgs_x_value_prev
63 real(dp) :: b_nr
64 logical :: flag_convergence
65 
66 allocate(lgs_x_value_prev(nmax))
67 
68 iter_loop : do iter=1, 1000
69 
70  lgs_x_value_prev = lgs_x_value
71 
72  do nr=1, nmax
73 
74  b_nr = 0.0_dp
75 
76  do k=lgs_a_ptr(nr), lgs_a_ptr(nr+1)-1
77  b_nr = b_nr + lgs_a_value(k)*lgs_x_value(lgs_a_index(k))
78  end do
79 
80  lgs_x_value(nr) = lgs_x_value(nr) &
81  -omega*(b_nr-lgs_b_value(nr)) &
82  /lgs_a_value(lgs_a_diag_index(nr))
83 
84  end do
85 
86  flag_convergence = .true.
87  do nr=1, nmax
88  if (abs(lgs_x_value(nr)-lgs_x_value_prev(nr)) > eps_sor) then
89  flag_convergence = .false.
90  exit
91  end if
92  end do
93 
94  if (flag_convergence) then
95  write(6,'(11x,a,i5)') 'sor_sprs: iter = ', iter
96  ierr = 0 ! convergence criterion fulfilled
97  deallocate(lgs_x_value_prev)
98  return
99  end if
100 
101 end do iter_loop
102 
103 write(6,'(a,i5)') 'sor_sprs: iter = ', iter
104 ierr = -1 ! convergence criterion not fulfilled
105 deallocate(lgs_x_value_prev)
106 
107 end subroutine sor_sprs
108 !