13 #include "sll_working_precision.h"
35 sll_int32,
dimension(:),
allocatable :: arr_n_rows
37 sll_int32,
dimension(:),
allocatable :: arr_n_cols
40 sll_real64,
dimension(:,:),
allocatable :: arr_coeffs
65 sll_int32 ,
intent(in) :: n_block_rows
66 sll_int32 ,
intent(in) :: n_block_cols
68 sll_int32 :: i_block_row
69 sll_int32 :: i_block_col
72 self % n_block_rows = n_block_rows
73 self % n_block_cols = n_block_cols
77 call self % initialize_abstract ()
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))
90 self % arr_coeffs = 1.0_f64
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()
114 deallocate(self % arr_n_rows)
115 deallocate(self % arr_n_cols)
116 deallocate(self % linear_operators)
117 deallocate(self % arr_coeffs)
134 sll_int32 ,
intent(in) :: i_block_row
135 sll_int32 ,
intent(in) :: i_block_col
137 sll_real64,
optional,
intent(in) :: r_coeff
139 logical,
parameter :: verbose = .false.
143 if (
present(r_coeff))
then
144 self % arr_coeffs(i_block_row, i_block_col) = r_coeff
149 self % linear_operators(i_block_row, i_block_col) % ptr_linear_operator => linop
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)
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)
176 print *,
">>> linear_operator_block"
177 call self % print_info_abstract()
179 print *,
"* arr_n_rows : ", self % arr_n_rows
180 print *,
"* arr_n_cols : ", self % arr_n_cols
195 sll_real64,
dimension(:),
intent(in ) :: x
196 sll_real64,
dimension(:),
intent( out) :: y
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
207 sll_real64,
dimension(:),
allocatable :: z
210 allocate(z(self % n_global_rows))
215 n_block_rows = self % n_block_rows
216 n_block_cols = self % n_block_cols
222 do i_block_row = 1, n_block_rows
223 i_end_row = i_begin_row - 1 + self % arr_n_rows(i_block_row)
227 do i_block_col = 1, n_block_cols
228 i_end_col = i_begin_col - 1 + self % arr_n_cols(i_block_col)
231 ptr_linop => self % linear_operators(i_block_row, i_block_col) % ptr_linear_operator
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)
239 i_begin_col = i_begin_col + self % arr_n_cols(i_block_col)
242 i_begin_row = i_begin_row + self % arr_n_rows(i_block_row)
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 for abstract linear operator
class that contains a pointer to a linear operator
class for a linear operator_block