Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_operator_kron.F90
Go to the documentation of this file.
1 
13 
14 
16  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 #include "sll_working_precision.h"
18 
21 
22  implicit none
23 
24  public :: &
26  sll_transpose, &
29 
30  private
31  ! ..................................................
35  sll_int32 :: n_rows_a = 0
36  sll_int32 :: n_cols_a = 0
37  sll_int32 :: n_rows_b = 0
38  sll_int32 :: n_cols_b = 0
39  sll_int32 :: n_rows_c = 0
40  sll_int32 :: n_cols_c = 0
41 
42  class(sll_t_linear_operator_abstract), pointer :: ptr_linop_a => null()
43  class(sll_t_linear_operator_abstract), pointer :: ptr_linop_b => null()
44  class(sll_t_linear_operator_abstract), pointer :: ptr_linop_c => null()
45 
46  contains
47  procedure :: create => create_linear_operator_kron
48  procedure :: free => free_linear_operator_kron
49  procedure :: dot => dot_linear_operator_kron
50  procedure :: print_info => print_info_linear_operator_kron
52  ! ..................................................
53 
54 contains
55 
56  ! ............................................
63  subroutine create_linear_operator_kron( self, &
64  & linop_a, linop_b, linop_c)
65  implicit none
66  class(sll_t_linear_operator_kron) , intent(inout) :: self
67  class(sll_t_linear_operator_abstract), target , intent(in) :: linop_a
68  class(sll_t_linear_operator_abstract), target , intent(in) :: linop_b
69  class(sll_t_linear_operator_abstract), target, optional, intent(in) :: linop_c
70  ! local
71  ! ...
72  self % n_rows_a = linop_a % n_rows
73  self % n_cols_a = linop_a % n_cols
74  self % ptr_linop_a => linop_a
75 
76  self % n_rows_b = linop_b % n_rows
77  self % n_cols_b = linop_b % n_cols
78  self % ptr_linop_b => linop_b
79 
80  self % n_rows = linop_a % n_rows * linop_b % n_rows
81  self % n_cols = linop_a % n_cols * linop_b % n_cols
82 
83  self % n_block_rows = linop_a % n_block_rows * linop_b % n_block_rows
84  self % n_block_cols = linop_a % n_block_cols * linop_b % n_block_cols
85 
86  self % n_global_rows = linop_a % n_global_rows * linop_b % n_global_rows
87  self % n_global_cols = linop_a % n_global_cols * linop_b % n_global_cols
88 
89  if (present(linop_c)) then
90  self % n_rows_c = linop_c % n_rows
91  self % n_cols_c = linop_c % n_cols
92  self % ptr_linop_c => linop_c
93 
94  self % n_rows = self % n_rows * linop_c % n_rows
95  self % n_cols = self % n_cols * linop_c % n_cols
96 
97  self % n_block_rows = self % n_block_rows * linop_c % n_block_rows
98  self % n_block_cols = self % n_block_cols * linop_c % n_block_cols
99 
100  self % n_global_rows = self % n_global_rows * linop_c % n_global_rows
101  self % n_global_cols = self % n_global_cols * linop_c % n_global_cols
102  end if
103  ! ...
104 
105  ! ...
106  call self % initialize_abstract ()
107  ! ...
108 
109  end subroutine create_linear_operator_kron
110  ! ............................................
111 
112  ! ............................................
116  subroutine free_linear_operator_kron(self)
117  implicit none
118  class(sll_t_linear_operator_kron), intent(inout) :: self
119  ! TODO
120  end subroutine free_linear_operator_kron
121  ! ............................................
122 
123  ! ...................................................
129  subroutine dot_linear_operator_kron(self, x, y)
130  implicit none
131  class(sll_t_linear_operator_kron), intent(in) :: self
132  sll_real64,dimension(:), intent(in ) :: x
133  sll_real64,dimension(:), intent( out) :: y
134  ! local
135 
136  ! ...
137  if (.not. associated(self % ptr_linop_c)) then
138  call dot_2_linear_operator_kron(self, self % ptr_linop_a, self % ptr_linop_b, x, y)
139  else
140  call dot_3_linear_operator_kron(self, self % ptr_linop_a, self % ptr_linop_b, self % ptr_linop_c, x, y)
141  end if
142  ! ...
143 
144  end subroutine dot_linear_operator_kron
145  ! ...................................................
146 
147  ! ...................................................
155  subroutine dot_2_linear_operator_kron(self, linop_1, linop_2, x, y)
156  implicit none
157  class(sll_t_linear_operator_kron), intent(in) :: self
158  class(sll_t_linear_operator_abstract), intent(in) :: linop_1
159  class(sll_t_linear_operator_abstract), intent(in) :: linop_2
160  sll_real64, dimension(:), intent(in) :: x
161  sll_real64, dimension(:), intent(inout) :: y
162  ! local
163  sll_int32 :: i
164  sll_int32 :: n_rows_a
165  sll_int32 :: n_rows_b
166  sll_int32 :: n_cols_a
167  sll_int32 :: n_cols_b
168 
169  sll_real64,dimension(:,:), allocatable :: x_matrix
170  sll_real64,dimension(:,:), allocatable :: x_matrix_trans
171  sll_real64,dimension(:,:), allocatable :: x_prime
172  sll_real64,dimension(:,:), allocatable :: x_prime_trans
173  sll_real64,dimension(:,:), allocatable :: y_matrix
174 
175  ! ...
176  n_cols_a = linop_1 % n_cols
177  n_rows_a = linop_1 % n_rows
178  n_cols_b = linop_2 % n_cols
179  n_rows_b = linop_2 % n_rows
180  ! ...
181 
182  ! ...
183  allocate(x_matrix(n_cols_b, n_cols_a))
184  allocate(x_matrix_trans(n_cols_a, n_cols_b))
185  allocate(x_prime(n_cols_b, n_rows_a))
186  allocate(x_prime_trans(n_rows_a, n_cols_b))
187  allocate(y_matrix(n_rows_b, n_rows_a))
188 
189  x_matrix = 0.0_f64
190 
191  ! ...
192  call sll_vector_to_matrix(x,x_matrix)
193 
194  call sll_transpose(x_matrix, x_matrix_trans)
195 
196  do i=1,n_cols_b
197  call linop_1 % dot(x_matrix_trans(:,i), x_prime_trans(:,i))
198  enddo
199 
200  call sll_transpose(x_prime_trans, x_prime)
201 
202  do i=1,n_rows_a
203  call linop_2 % dot(x_prime(:,i), y_matrix(:,i))
204  enddo
205 
206  call sll_matrix_to_vector(y_matrix, y)
207 
208 
209  ! ...
210  deallocate(y_matrix)
211  deallocate(x_matrix_trans)
212  deallocate(x_prime)
213  deallocate(x_prime_trans)
214  deallocate(x_matrix)
215  ! ...
216 
217  end subroutine dot_2_linear_operator_kron
218  ! ...................................................
219 
220  ! ...................................................
229  subroutine dot_3_linear_operator_kron(self, linop_1, linop_2, linop_3, x, y)
230  implicit none
231  class(sll_t_linear_operator_kron), intent(in) :: self
232  class(sll_t_linear_operator_abstract), intent(in) :: linop_1
233  class(sll_t_linear_operator_abstract), intent(in) :: linop_2
234  class(sll_t_linear_operator_abstract), intent(in) :: linop_3
235  sll_real64, dimension(:), intent(in) :: x
236  sll_real64, dimension(:), intent(inout) :: y
237  ! local
238  sll_int32 :: i
239  sll_int32 :: n_rows_1
240  sll_int32 :: n_rows_23
241  sll_int32 :: n_cols_1
242  sll_int32 :: n_cols_23
243  sll_real64,dimension(:,:), allocatable :: x_matrix
244  sll_real64,dimension(:,:), allocatable :: x_matrix_trans
245  sll_real64,dimension(:,:), allocatable :: x_prime
246  sll_real64,dimension(:,:), allocatable :: x_prime_trans
247  sll_real64,dimension(:,:), allocatable :: y_matrix
248 
249  ! ...
250  n_rows_1 = linop_1 % n_rows
251  n_rows_23 = linop_2 % n_rows * linop_3 % n_rows
252  ! ...
253 
254  ! ...
255  n_cols_1 = linop_1 % n_cols
256  n_cols_23 = linop_2 % n_cols * linop_3 % n_cols
257  ! ...
258 
259  ! ...
260  allocate(y_matrix(n_rows_23, n_rows_1))
261  allocate(x_prime(n_cols_23, n_rows_1))
262  allocate(x_prime_trans(n_rows_1, n_cols_23))
263  allocate(x_matrix(n_cols_23, n_cols_1))
264  allocate(x_matrix_trans(n_cols_1, n_cols_23))
265  ! ...
266 
267  ! ...
268  call sll_vector_to_matrix(x,x_matrix)
269  call sll_transpose(x_matrix, x_matrix_trans)
270 
271  !print*, "This is the matrix from vector x", x_matrix
272  do i=1,n_cols_23
273  call linop_1 % dot(x_matrix_trans(:,i),x_prime_trans(:,i))
274  enddo
275 
276 
277  call sll_transpose(x_prime_trans, x_prime)
278 
279  !print*, "This is the x_prime matrix!", x_prime
280 
281  do i=1,n_rows_1
282  call dot_2_linear_operator_kron( self, &
283  & self % ptr_linop_b, &
284  & self % ptr_linop_c, &
285  & x_prime(:,i), &
286  & y_matrix(:,i))
287  enddo
288 
289  call sll_matrix_to_vector(y_matrix,y)
290  ! ...
291 
292  ! ...
293  deallocate(y_matrix)
294  deallocate(x_prime_trans)
295  deallocate(x_matrix)
296  deallocate(x_matrix_trans)
297  ! ...
298 
299  end subroutine dot_3_linear_operator_kron
300  ! ...................................................
301 
302 
303  ! ...................................................
308  implicit none
309  class(sll_t_linear_operator_kron), intent(in) :: self
310  ! local
311 
312  print *, ">>>> linear_operator_kron"
313  call self % print_info_abstract()
314 
315  print *, "* n_rows_a : ", self % n_rows_a
316  print *, "* n_cols_a : ", self % n_cols_a
317  print *, "* n_rows_b : ", self % n_rows_b
318  print *, "* n_cols_b : ", self % n_cols_b
319  print *, "<<<< "
320 
321  end subroutine print_info_linear_operator_kron
322  ! ...................................................
323 
324 
325  ! ..................................................
330  recursive subroutine sll_transpose(x, x_t)
331  implicit none
332  sll_real64, dimension(:,:), intent(in) :: x
333  sll_real64, dimension(:,:), intent(out) :: x_t
334  ! local
335  sll_int32 :: m
336  sll_int32 :: n
337  sll_int32 :: i
338  sll_int32 :: j
339 
340  ! ... x of size (m,n) and x_t of size (n,m)
341  m = size(x, 1)
342  n = size(x, 2)
343  ! ...
344 
346  ! ...
347  do i=1, n
348  do j=1, m
349  x_t(i,j) = x(j,i)
350  end do
351  end do
352  ! ...
353 
354  end subroutine sll_transpose
355  ! ..................................................
356 
357  ! ..................................................
362  subroutine sll_vector_to_matrix(vec, mat)
363  implicit none
364  sll_real64, dimension(:) , intent(in) :: vec
365  sll_real64, dimension(:,:), intent(inout) :: mat
366  ! local
367  sll_int32 :: n
368  sll_int32 :: m
369  sll_int32 :: j
370  sll_int32 :: l
371 
372  ! ...
373  n = size(mat, 1)
374  m = size(mat, 2)
375  l = size(vec)
376  ! ...
377 
378  ! ...
379  do j=1, m
380  mat(1:n, j) = vec(1+(j-1)*n:j*n)
381  end do
382  ! ...
383 
384  end subroutine sll_vector_to_matrix
385  ! ..................................................
386 
387  ! ..................................................
392  subroutine sll_matrix_to_vector(mat, vec)
393  implicit none
394  sll_real64, dimension(:,:), intent(in) :: mat
395  sll_real64, dimension(:) , intent(inout) :: vec
396  !local
397  sll_int32 :: n
398  sll_int32 :: m
399  sll_int32 :: j
400 
401  ! ...
402  n = size(mat, 1)
403  m = size(mat, 2)
404  ! ...
405 
406  ! ...
407  do j=1, m
408  vec(1+(j-1)*n:j*n) = mat(1:n, j)
409  end do
410  ! ...
411 
412  end subroutine sll_matrix_to_vector
413  ! ..................................................
414 
415 
417 
418 
module for abstract linear operator
module for a linear operator of kronecker solver
subroutine dot_2_linear_operator_kron(self, linop_1, linop_2, x, y)
apply the dot operation
subroutine dot_3_linear_operator_kron(self, linop_1, linop_2, linop_3, x, y)
apply the dot operation
recursive subroutine, public sll_transpose(x, x_t)
returnes the transpose of a 2d array
subroutine free_linear_operator_kron(self)
destroys the current object
subroutine create_linear_operator_kron(self, linop_a, linop_b, linop_c)
creates a linear operator
subroutine, public sll_matrix_to_vector(mat, vec)
converts a matrix to a vector
subroutine, public sll_vector_to_matrix(vec, mat)
converts a vector to a matrix
subroutine print_info_linear_operator_kron(self)
prints a linear operator
subroutine dot_linear_operator_kron(self, x, y)
apply the dot operation
    Report Typos and Errors