14 #include "sll_working_precision.h"
35 sll_int32 :: n_nnz = 0
36 logical :: is_allocated_ia = .false.
37 logical :: is_allocated_jaa = .false.
39 sll_int32,
dimension(:),
allocatable :: arr_ia
40 sll_int32,
dimension(:),
allocatable :: arr_ja
41 sll_real64,
dimension(:,:),
allocatable :: arr_a
70 & n_rows, n_cols, n_nnz, &
71 & n_block_rows, n_block_cols)
76 sll_int32,
optional,
intent(in) :: n_cols
78 sll_int32,
optional,
intent(in) :: n_rows
80 sll_int32,
optional,
intent(in) :: n_nnz
81 sll_int32,
optional,
intent(in) :: n_block_rows
82 sll_int32,
optional,
intent(in) :: n_block_cols
85 if ( (
present(n_rows)) &
86 & .or. (
present(n_cols)) &
87 & .or. (
present(n_nnz)) )
then
94 n_block_rows=n_block_rows, &
95 n_block_cols=n_block_cols)
99 self % n_global_rows = self % n_rows
100 self % n_global_cols = self % n_cols
102 elseif ((
present(n_block_rows)) .or. (
present(n_block_cols)))
then
104 if ((
present(n_block_rows)))
then
105 self % n_block_rows = n_block_rows
110 if ((
present(n_block_cols)))
then
111 self % n_block_cols = n_block_cols
116 call self % initialize_abstract ()
120 stop
"create_matrix_csr: wrong arguments"
135 & n_rows, n_cols, n_nnz, &
136 & n_block_rows, n_block_cols)
141 sll_int32,
optional,
intent(in) :: n_cols
143 sll_int32,
optional,
intent(in) :: n_rows
145 sll_int32,
optional,
intent(in) :: n_nnz
146 sll_int32,
optional,
intent(in) :: n_block_rows
147 sll_int32,
optional,
intent(in) :: n_block_cols
150 if ((
present(n_block_rows)))
then
151 self % n_block_rows = n_block_rows
156 if ((
present(n_block_cols)))
then
157 self % n_block_cols = n_block_cols
162 call self % initialize_abstract ()
165 if (
present(n_rows))
then
168 allocate(self%arr_ia(self%n_rows+1))
169 self % is_allocated_ia = .true.
172 if (
present(n_cols))
then
176 if (
present(n_nnz))
then
179 allocate(self%arr_ja(self%n_nnz))
180 allocate(self%arr_a(self % n_dof, self%n_nnz))
182 self % is_allocated = .true.
183 self % is_allocated_jaa = .true.
200 if (self % is_allocated_ia)
then
201 deallocate(self%arr_ia)
203 self % is_allocated = .false.
204 self % is_allocated_ia = .false.
209 if (self % is_allocated_jaa)
then
210 deallocate(self%arr_ja)
211 deallocate(self%arr_a)
213 self % is_allocated = .false.
214 self % is_allocated_jaa = .false.
230 sll_real64,
dimension(:),
intent(in ) :: x
231 sll_real64,
dimension(:),
intent( out) :: y
248 sll_real64,
dimension(:),
intent(in ) :: x
249 sll_real64,
dimension(:),
intent( out) :: y
257 sll_int32 :: i_block_row
258 sll_int32 :: i_block_col
261 sll_int32 :: n_block_rows
262 sll_int32 :: n_block_cols
263 sll_int32 :: n_global_rows
264 sll_int32 :: n_global_cols
265 sll_real64,
dimension(:,:),
allocatable :: arr_x
268 n_rows = self % n_rows
269 n_cols = self % n_cols
270 n_block_rows = self % n_block_rows
271 n_block_cols = self % n_block_cols
272 n_global_rows = self % n_global_rows
273 n_global_cols = self % n_global_cols
277 allocate(arr_x(n_block_cols, self % n_global_cols))
282 do i_col = 1, n_global_cols
283 do i_block_col = 1, n_block_cols
286 arr_x(i_block_col, i_col) = x(i)
306 k_min = self % arr_ia ( i_row )
307 k_max = self % arr_ia ( i_row + 1 ) - 1
312 do i_block_row = 1, n_block_rows
313 do i_block_col = 1, n_block_cols
316 i = i_block_row + (i_row - 1) * n_block_rows
317 y(i) = y(i) + dot_product( self % arr_a (i_dof, k_min : k_max ), &
318 arr_x(i_block_col, self%arr_ja ( k_min : k_max ) ) )
346 sll_int32 ,
intent(in) :: i_row
347 sll_int32 ,
intent(in) :: i_col
348 sll_real64,
dimension(:),
intent(in) :: arr_x
354 do k = self % arr_ia(i_row), self % arr_ia(i_row+1)-1
356 if ( j == i_col )
then
357 self % arr_a(:, k) = self % arr_a(:, k) + arr_x(:)
375 sll_int32 ,
intent(in) :: i_row
376 sll_int32 ,
intent(in) :: i_col
377 sll_real64,
dimension(:),
intent(in) :: arr_x
383 do k = self % arr_ia(i_row), self % arr_ia(i_row+1)-1
385 if ( j == i_col )
then
386 self % arr_a(:, k) = arr_x(:)
403 sll_real64,
dimension(:),
intent(inout) :: diag
404 sll_int32,
optional,
intent(in) :: i_diag
411 sll_int32 :: i_block_row
412 sll_int32 :: i_block_col
413 sll_int32 :: n_block_rows
414 sll_int32 :: n_block_cols
415 sll_real64,
dimension(:,:,:),
allocatable :: block_diag
418 n_block_rows = self % n_block_rows * self %n_block_rows
419 n_block_cols = self % n_block_cols * self %n_block_cols
420 n_rows = self % n_rows * self %n_block_rows
421 n_cols = self % n_cols* self %n_block_cols
430 allocate(block_diag(n_block_rows, n_block_cols, min(n_rows, n_cols)))
435 call self % get_diagonal_block(block_diag, i_diag=i_diag)
442 do i_block_row = 1, n_block_rows
443 do i_block_col = 1, n_block_cols
446 if (i_block_row == i_block_col)
then
447 i = i_block_row + (i_row - 1) * n_block_rows
448 diag(i) = block_diag(i_block_row, i_block_row, i_row)
469 sll_real64,
dimension(:,:,:),
intent(inout) :: diag
470 sll_int32,
optional,
intent(in) :: i_diag
472 sll_int32,
parameter :: job = 0
473 sll_int32 :: n_nnz_diag
475 sll_int32 ,
dimension(:),
allocatable :: arr_ind_diag
476 sll_int32 :: l_i_diag
480 sll_int32 :: i_block_row
481 sll_int32 :: i_block_col
482 sll_int32 :: n_block_rows
483 sll_int32 :: n_block_cols
487 if (
present(i_diag))
then
493 n_block_rows = self % n_block_rows
494 n_block_cols = self % n_block_cols
495 n_rows = self % n_rows
496 n_cols = self % n_cols
504 allocate(arr_ind_diag(min(n_rows, n_cols)))
509 do i_block_row = 1, n_block_rows
510 do i_block_col = 1, n_block_cols
513 call getdia(n_rows, n_cols, job, &
514 & self % arr_a(i_dof, :), self % arr_ja, self % arr_ia, &
515 & n_nnz_diag, diag(i_block_row,i_block_col,:), arr_ind_diag, l_i_diag)
522 deallocate(arr_ind_diag)
540 print *,
">>>>> matrix_csr"
541 print *,
"* n_bloc_rows : ", self % n_block_rows
542 print *,
"* n_bloc_cols : ", self % n_block_cols
543 print *,
"* n_rows : ", self % n_rows
544 print *,
"* n_cols : ", self % n_cols
545 print *,
"* n_global_rows : ", self % n_global_rows
546 print *,
"* n_global_cols : ", self % n_global_cols
547 print *,
"* n_nnz : ", self % n_nnz
566 sll_real64,
dimension(:),
allocatable :: arr_a
567 sll_int32,
dimension(:),
allocatable :: arr_ia
568 sll_int32,
dimension(:),
allocatable :: arr_ja
569 sll_int32,
dimension(:),
allocatable :: arr_iw
575 sll_int32 :: n_nnz_max
576 sll_int32,
parameter :: i_job = 1
577 sll_int32,
parameter :: i_current_dof = 1
580 if((self % n_dof)*(mat_a % n_dof).ne.1)
then
581 stop
"multiply_matrix_csr: not implemented yet if n_dof > 1."
586 n_rows = self % n_rows
587 n_cols = mat_a % n_cols
588 n_nnz_max = n_rows * n_cols
592 allocate(arr_iw(n_cols))
593 allocate(arr_ia(n_rows +1))
594 allocate(arr_ja(n_nnz_max))
595 allocate(arr_a(n_nnz_max))
602 call amub ( n_rows, n_cols, i_job, &
603 & self % arr_a(i_current_dof,:), &
604 & self % arr_ja, self % arr_ia, &
605 & mat_a % arr_a(i_current_dof,:), &
606 & mat_a % arr_ja, mat_a % arr_ia, &
607 & arr_a, arr_ja, arr_ia, &
608 & n_nnz_max, arr_iw, i_err)
611 stop
"Error in multiply_matrix_csr: bad matrix_a type."
616 n_nnz = arr_ia(n_rows + 1) -1
621 call mat_b % create( n_rows=n_rows, &
625 mat_b % arr_ia = arr_ia
628 mat_b % arr_ja(i) = arr_ja(i)
629 mat_b % arr_a(i_current_dof, i) = arr_a(i)
632 stop
"Error in multiply_matrix_csr: bad matrix_b type."
module for abstract matrix
module for Compressed Sparse Row Matrix (CSR)
subroutine get_diagonal_default_matrix_csr(self, diag, i_diag)
extracts a specified diagonal from a matrix IMPORTANT: diag is a 1-rank array
subroutine create_matrix_csr(self, n_rows, n_cols, n_nnz, n_block_rows, n_block_cols)
creates a csr matrix
subroutine dot_matrix_csr(self, x, y)
apply the dot operation of real vector
subroutine add_values_matrix_csr(self, i_row, i_col, arr_x)
adds values to the matrix
subroutine allocate_matrix_csr(self, n_rows, n_cols, n_nnz, n_block_rows, n_block_cols)
allocates a csr matrix
subroutine set_values_matrix_csr(self, i_row, i_col, arr_x)
sets values to the matrix
subroutine get_diagonal_block_matrix_csr(self, diag, i_diag)
extracts a specified block diagonal from a matrix IMPORTANT: diag is a 3-rank array
subroutine multiply_matrix_csr(self, mat_a, mat_b)
performs the matrix by matrix product
subroutine dot_vector_default(self, x, y)
sequential dot operation
subroutine print_info_matrix_csr(self)
prints the current object
subroutine free_matrix_csr(self)
destroys the current object
abstract class for matrix