Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_solver_block.F90
Go to the documentation of this file.
1 
10 
12  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 #include "sll_working_precision.h"
14 #include "sll_errors.h"
15 
16  use sll_m_linear_solver_abstract, only: &
18 
19  implicit none
20 
21  public :: &
23 
24  private
25  ! .........................................................
29  class(sll_t_linear_solver_abstract), pointer :: ptr_linear_solver => null()
31  ! .........................................................
32 
33  ! ..................................................
37  sll_int32, dimension(:), allocatable :: arr_n_rows
38 
39  sll_int32, dimension(:), allocatable :: arr_n_cols
40 
41 
42  sll_real64, dimension(:,:), allocatable :: arr_coeffs
43 
44 
45  sll_int32 :: n_block_rows = 1
46  sll_int32 :: n_block_cols = 1
47 
48  type(jrk_t_linear_solver_pointer), dimension(:,:), allocatable :: linear_solvers
49  contains
50  procedure :: create => create_linear_solver_block
51  procedure :: set => set_linear_solver_block
52  procedure :: read_from_file => read_from_file_linear_solver_block
53  procedure :: set_verbose => set_verbose_linear_solver_block
54  procedure :: solve_real => solve_real_linear_solver_block
55  procedure :: print_info => print_info_linear_solver_block
56  procedure :: free => free_linear_solver_block
58  ! ..................................................
59 
60 contains
61 
62  ! ............................................
69  subroutine create_linear_solver_block(self, n_block_rows, n_block_cols)
70  implicit none
71  class(sll_t_linear_solver_block), intent(inout) :: self
72  sll_int32 , intent(in) :: n_block_rows
73  sll_int32 , intent(in) :: n_block_cols
74  ! local
75  sll_int32 :: i_block_row
76  sll_int32 :: i_block_col
77 
78  ! ...
79  self % n_block_rows = n_block_rows
80  self % n_block_cols = n_block_cols
81  ! ...
82 
83  ! ...
84  !call self % initialize_abstract ()
85  ! ...
86 
87  ! ...
88  allocate(self % arr_n_rows(n_block_rows))
89  allocate(self % arr_n_cols(n_block_cols))
90  allocate(self % linear_solvers(n_block_rows, n_block_cols))
91  allocate(self % arr_coeffs(n_block_rows, n_block_cols))
92  ! ...
93 
94  ! ...
95  self % arr_n_rows = 0
96  self % arr_n_cols = 0
97  self % arr_coeffs = 1.0_f64
98  ! ...
99 
100  ! ...
101  do i_block_col = 1, n_block_cols
102  do i_block_row = 1, n_block_rows
103  self % linear_solvers(i_block_row, i_block_col) % ptr_linear_solver => null()
104  end do
105  end do
106  ! ...
107 
108  end subroutine create_linear_solver_block
109  ! ............................................
110 
111 
112 
113  ! ............................................
121  subroutine set_linear_solver_block(self, i_block_row, i_block_col, linop, r_coeff)
122  implicit none
123  class(sll_t_linear_solver_block) , intent(inout) :: self
124  sll_int32 , intent(in) :: i_block_row
125  sll_int32 , intent(in) :: i_block_col
126  class(sll_t_linear_solver_abstract), target, intent(in) :: linop
127  sll_real64, optional, intent(in) :: r_coeff
128  ! local
129  logical, parameter :: verbose = .false.
131 
132  ! ...
133  if (present(r_coeff)) then
134  self % arr_coeffs(i_block_row, i_block_col) = r_coeff
135  end if
136  ! ...
137 
138  ! ...
139  self % linear_solvers(i_block_row, i_block_col) % ptr_linear_solver => linop
140  ! ...
141 
142  ! ...
143  self % arr_n_rows(i_block_row) = max(self % arr_n_rows(i_block_row), linop % n_global_rows)
144  self % arr_n_cols(i_block_col) = max(self % arr_n_cols(i_block_col), linop % n_global_cols)
145  ! ...
146 
147  ! ...
148  self % n_rows = sum(self % arr_n_rows)
149  self % n_cols = sum(self % arr_n_cols)
150  self % n_global_rows = sum(self % arr_n_rows)
151  self % n_global_cols = sum(self % arr_n_cols)
152  ! ...
153 
154  end subroutine set_linear_solver_block
155  ! ............................................
156 
157  subroutine read_from_file_linear_solver_block(self, filename)
158  class(sll_t_linear_solver_block), intent( inout ) :: self
159  character(len=*), intent( in ) :: filename
160 
162 
163  subroutine set_verbose_linear_solver_block( self, verbose )
164  class(sll_t_linear_solver_block), intent( inout ) :: self
165  logical, intent( in ) :: verbose
166 
167  self%verbose = verbose
168 
169  end subroutine set_verbose_linear_solver_block
170 
171  ! ...................................................
177  subroutine solve_real_linear_solver_block(self, rhs, unknown)
178  implicit none
179  class(sll_t_linear_solver_block), intent(inout) :: self
180  sll_real64,dimension(:), intent(in ) :: rhs
181  sll_real64,dimension(:), intent( out) :: unknown
182  ! local
183  sll_int32 :: n_block_rows
184  sll_int32 :: n_block_cols
185  sll_int32 :: i_block_row
186  sll_int32 :: i_block_col
187  sll_int32 :: i_begin_row
188  sll_int32 :: i_begin_col
189  sll_int32 :: i_end_row
190  sll_int32 :: i_end_col
191  class(sll_t_linear_solver_abstract), pointer :: ptr_linop => null()
192  sll_real64, dimension(:), allocatable :: z
193 
194  ! ...
195  allocate(z(self % n_global_rows))
196  z = 0.0_f64
197  ! ...
198 
199  ! ...
200  n_block_rows = self % n_block_rows
201  n_block_cols = self % n_block_cols
202  ! ...
203 
204  ! ...
205  unknown = 0.0_f64
206  i_begin_row = 1
207  do i_block_row = 1, n_block_rows
208  i_end_row = i_begin_row - 1 + self % arr_n_rows(i_block_row)
209 
210  ! ...
211  i_begin_col = 1
212  do i_block_col = 1, n_block_cols
213  i_end_col = i_begin_col - 1 + self % arr_n_cols(i_block_col)
214 
215  ! ...
216  ptr_linop => self % linear_solvers(i_block_row, i_block_col) % ptr_linear_solver
217 
218  if (associated(ptr_linop)) then
219  call ptr_linop % solve(rhs(i_begin_col:i_end_col), z(i_begin_row:i_end_row))
220  unknown(i_begin_row:i_end_row) = unknown(i_begin_row:i_end_row) &
221  & + z(i_begin_row:i_end_row) * self % arr_coeffs(i_block_row, i_block_col)
222  end if
223 
224  i_begin_col = i_begin_col + self % arr_n_cols(i_block_col)
225  ! ...
226  end do
227  i_begin_row = i_begin_row + self % arr_n_rows(i_block_row)
228  ! ...
229  end do
230  ! ...
231 
232  end subroutine solve_real_linear_solver_block
233  ! ...................................................
234 
235  ! ............................................
240  implicit none
241  class(sll_t_linear_solver_block), intent(in) :: self
242 
243  end subroutine print_info_linear_solver_block
244  ! ............................................
245 
246  ! ............................................
250  subroutine free_linear_solver_block(self)
251  implicit none
252  class(sll_t_linear_solver_block), intent(inout) :: self
253  ! local
254 
255  ! ...
256  deallocate(self % arr_n_rows)
257  deallocate(self % arr_n_cols)
258  deallocate(self % linear_solvers)
259  deallocate(self % arr_coeffs)
260  ! ...
261 
262  end subroutine free_linear_solver_block
263  ! ............................................
264 
265 end module sll_m_linear_solver_block
module for abstract linear solver
module for a block linear solver
subroutine create_linear_solver_block(self, n_block_rows, n_block_cols)
creates a linear solver_block you must sets the linop using set
subroutine solve_real_linear_solver_block(self, rhs, unknown)
apply the dot operation
subroutine set_linear_solver_block(self, i_block_row, i_block_col, linop, r_coeff)
sets a linear solver
subroutine free_linear_solver_block(self)
destroys the current object
subroutine set_verbose_linear_solver_block(self, verbose)
subroutine read_from_file_linear_solver_block(self, filename)
subroutine print_info_linear_solver_block(self)
prints the current object
class that contains a pointer to a linear solver
    Report Typos and Errors