Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_operator_block.F90
Go to the documentation of this file.
1 
10 
12 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 #include "sll_working_precision.h"
14 
17  implicit none
18 
19  public :: &
21 
22  private
23  ! .........................................................
27  class(sll_t_linear_operator_abstract), pointer :: ptr_linear_operator => null()
29  ! .........................................................
30 
31  ! ..................................................
35  sll_int32, dimension(:), allocatable :: arr_n_rows
36 
37  sll_int32, dimension(:), allocatable :: arr_n_cols
38 
39 
40  sll_real64, dimension(:,:), allocatable :: arr_coeffs
41 
42 
43  type(jrk_t_linear_operator_pointer), dimension(:,:), allocatable :: linear_operators
44  contains
45  procedure :: create => create_linear_operator_block
46  procedure :: free => free_linear_operator_block
47  procedure :: dot => dot_linear_operator_block
48  procedure :: set => set_linear_operator_block
49  procedure :: print_info => print_info_linear_operator_block
51  ! ..................................................
52 
53 contains
54 
55  ! ............................................
62  subroutine create_linear_operator_block(self, n_block_rows, n_block_cols)
63  implicit none
64  class(sll_t_linear_operator_block), intent(inout) :: self
65  sll_int32 , intent(in) :: n_block_rows
66  sll_int32 , intent(in) :: n_block_cols
67  ! local
68  sll_int32 :: i_block_row
69  sll_int32 :: i_block_col
70 
71  ! ...
72  self % n_block_rows = n_block_rows
73  self % n_block_cols = n_block_cols
74  ! ...
75 
76  ! ...
77  call self % initialize_abstract ()
78  ! ...
79 
80  ! ...
81  allocate(self % arr_n_rows(n_block_rows))
82  allocate(self % arr_n_cols(n_block_cols))
83  allocate(self % linear_operators(n_block_rows, n_block_cols))
84  allocate(self % arr_coeffs(n_block_rows, n_block_cols))
85  ! ...
86 
87  ! ...
88  self % arr_n_rows = 0
89  self % arr_n_cols = 0
90  self % arr_coeffs = 1.0_f64
91  ! ...
92 
93  ! ...
94  do i_block_col = 1, n_block_cols
95  do i_block_row = 1, n_block_rows
96  self % linear_operators(i_block_row, i_block_col) % ptr_linear_operator => null()
97  end do
98  end do
99  ! ...
100 
101  end subroutine create_linear_operator_block
102  ! ............................................
103 
104  ! ............................................
108  subroutine free_linear_operator_block(self)
109  implicit none
110  class(sll_t_linear_operator_block), intent(inout) :: self
111  ! local
112 
113  ! ...
114  deallocate(self % arr_n_rows)
115  deallocate(self % arr_n_cols)
116  deallocate(self % linear_operators)
117  deallocate(self % arr_coeffs)
118  ! ...
119 
120  end subroutine free_linear_operator_block
121  ! ............................................
122 
123  ! ............................................
131  subroutine set_linear_operator_block(self, i_block_row, i_block_col, linop, r_coeff)
132  implicit none
133  class(sll_t_linear_operator_block) , intent(inout) :: self
134  sll_int32 , intent(in) :: i_block_row
135  sll_int32 , intent(in) :: i_block_col
136  class(sll_t_linear_operator_abstract), target, intent(in) :: linop
137  sll_real64, optional, intent(in) :: r_coeff
138  ! local
139  logical, parameter :: verbose = .false.
141 
142  ! ...
143  if (present(r_coeff)) then
144  self % arr_coeffs(i_block_row, i_block_col) = r_coeff
145  end if
146  ! ...
147 
148  ! ...
149  self % linear_operators(i_block_row, i_block_col) % ptr_linear_operator => linop
150  ! ...
151 
152  ! ...
153  self % arr_n_rows(i_block_row) = max(self % arr_n_rows(i_block_row), linop % n_global_rows)
154  self % arr_n_cols(i_block_col) = max(self % arr_n_cols(i_block_col), linop % n_global_cols)
155  ! ...
156 
157  ! ...
158  self % n_rows = sum(self % arr_n_rows)
159  self % n_cols = sum(self % arr_n_cols)
160  self % n_global_rows = sum(self % arr_n_rows)
161  self % n_global_cols = sum(self % arr_n_cols)
162  ! ...
163 
164  end subroutine set_linear_operator_block
165  ! ............................................
166 
167  ! ............................................
172  implicit none
173  class(sll_t_linear_operator_block), intent(in) :: self
174  ! local
175 
176  print *, ">>> linear_operator_block"
177  call self % print_info_abstract()
178 
179  print *, "* arr_n_rows : ", self % arr_n_rows
180  print *, "* arr_n_cols : ", self % arr_n_cols
181  print *, "<<<"
182 
183  end subroutine print_info_linear_operator_block
184  ! ............................................
185 
186  ! ...................................................
192  subroutine dot_linear_operator_block(self, x, y)
193  implicit none
194  class(sll_t_linear_operator_block), intent(in) :: self
195  sll_real64,dimension(:), intent(in ) :: x
196  sll_real64,dimension(:), intent( out) :: y
197  ! local
198  sll_int32 :: n_block_rows
199  sll_int32 :: n_block_cols
200  sll_int32 :: i_block_row
201  sll_int32 :: i_block_col
202  sll_int32 :: i_begin_row
203  sll_int32 :: i_begin_col
204  sll_int32 :: i_end_row
205  sll_int32 :: i_end_col
206  class(sll_t_linear_operator_abstract), pointer :: ptr_linop => null()
207  sll_real64, dimension(:), allocatable :: z
208 
209  ! ...
210  allocate(z(self % n_global_rows))
211  z = 0.0_f64
212  ! ...
213 
214  ! ...
215  n_block_rows = self % n_block_rows
216  n_block_cols = self % n_block_cols
217  ! ...
218 
219  ! ...
220  y = 0.0_f64
221  i_begin_row = 1
222  do i_block_row = 1, n_block_rows
223  i_end_row = i_begin_row - 1 + self % arr_n_rows(i_block_row)
224 
225  ! ...
226  i_begin_col = 1
227  do i_block_col = 1, n_block_cols
228  i_end_col = i_begin_col - 1 + self % arr_n_cols(i_block_col)
229 
230  ! ...
231  ptr_linop => self % linear_operators(i_block_row, i_block_col) % ptr_linear_operator
232 
233  if (associated(ptr_linop)) then
234  call ptr_linop % dot(x(i_begin_col:i_end_col), z(i_begin_row:i_end_row))
235  y(i_begin_row:i_end_row) = y(i_begin_row:i_end_row) &
236  & + z(i_begin_row:i_end_row) * self % arr_coeffs(i_block_row, i_block_col)
237  end if
238 
239  i_begin_col = i_begin_col + self % arr_n_cols(i_block_col)
240  ! ...
241  end do
242  i_begin_row = i_begin_row + self % arr_n_rows(i_block_row)
243  ! ...
244  end do
245  ! ...
246 
247  end subroutine dot_linear_operator_block
248  ! ...................................................
249 
module for abstract linear operator
module for a block linear operator
subroutine dot_linear_operator_block(self, x, y)
apply the dot operation
subroutine print_info_linear_operator_block(self)
prints the current object
subroutine set_linear_operator_block(self, i_block_row, i_block_col, linop, r_coeff)
sets a linear operator
subroutine free_linear_operator_block(self)
destroys the current object
subroutine create_linear_operator_block(self, n_block_rows, n_block_cols)
creates a linear operator_block you must sets the linop using set
class that contains a pointer to a linear operator
    Report Typos and Errors