13 #include "sll_working_precision.h"
46 sll_int32 :: nrowcol(3,2)
79 & linear_operator_a, &
80 & linear_operator_b, &
81 & linear_operator_c, &
94 character(len=*),
optional,
intent(in) :: filename
96 sll_int32,
parameter :: input_file_id = 111
97 character(len=256) :: solver_filename_a =
""
98 character(len=20) :: solver_name_a =
""
99 character(len=256) :: solver_filename_b =
""
100 character(len=20) :: solver_name_b =
""
101 character(len=256) :: solver_filename_c =
""
102 character(len=20) :: solver_name_c =
""
107 namelist /linear_solver/ solver_name_a, &
108 & solver_filename_a, &
110 & solver_filename_b, &
116 if (
present(filename))
then
120 open(unit=input_file_id, file=trim(filename))
121 read( input_file_id, linear_solver)
125 solver_name_a =
"lapack_lu"
126 solver_name_b =
"lapack_lu"
127 solver_name_c =
"lapack_lu"
132 if (
present(linear_solver_a))
then
133 self % ptr_linear_solver_a => linear_solver_a
136 if (
present(linear_operator_a))
then
139 & linear_operator_a, &
140 & self % p_linear_solver_a, &
144 self % ptr_linear_solver_a => self % p_linear_solver_a
148 stop
"create_linear_solver_kron: linear_operator_a is expected"
155 if (
present(linear_solver_b))
then
156 self % ptr_linear_solver_b => linear_solver_b
159 if (
present(linear_operator_b))
then
162 & linear_operator_b, &
163 & self % p_linear_solver_b, &
167 self % ptr_linear_solver_b => self % p_linear_solver_b
171 stop
"create_linear_solver_kron: linear_operator_b is expected"
178 if (
present(linear_solver_c))
then
179 self % ptr_linear_solver_c => linear_solver_c
182 if (
present(linear_operator_c))
then
185 & linear_operator_c, &
186 & self % p_linear_solver_c, &
190 self % ptr_linear_solver_c => self % p_linear_solver_c
203 self % nrowcol(1, 1) = self % ptr_linear_solver_a % n_global_rows
204 self % nrowcol(1, 2) = self % ptr_linear_solver_a % n_global_cols
208 self % nrowcol(2, 1) = self % ptr_linear_solver_b % n_global_rows
209 self % nrowcol(2, 2) = self % ptr_linear_solver_b % n_global_cols
213 if (
associated(self % ptr_linear_solver_c))
then
214 self % nrowcol(3, 1) = self % ptr_linear_solver_c % n_global_rows
215 self % nrowcol(3, 2) = self % ptr_linear_solver_c % n_global_cols
236 character(len=*) ,
intent(in) :: solver_name
239 logical ,
intent(out) :: flag
249 if (.not.
allocated(linear_solver))
then
255 select type (matrix => linear_operator)
264 select type (solver => linear_solver)
266 call solver % create( linear_operator, &
270 call solver % create( linear_operator, &
276 stop
'sll_create_linear_solver_with_name: could not allocate the linear solver'
290 character(len=*) ,
intent(in) :: solver_name
292 logical ,
intent(out) :: flag
299 select case (solver_name)
319 logical ,
intent(in) :: verbose
322 call self % set_verbose_abstract(verbose)
336 character(len=*) ,
intent(in) :: filename
351 sll_real64,
dimension(:),
intent(in ) :: rhs
352 sll_real64,
dimension(:),
intent( out) :: unknown
356 if (.not.
associated(self % ptr_linear_solver_c))
then
358 & self % ptr_linear_solver_a, &
359 & self % ptr_linear_solver_b, &
376 & linear_solver_a, linear_solver_b, &
382 sll_real64,
dimension(:),
intent(in ) :: rhs
383 sll_real64,
dimension(:),
intent( out) :: unknown
385 sll_real64,
dimension(:,:),
allocatable :: y
386 sll_real64,
dimension(:,:),
allocatable :: xprim
387 sll_real64,
dimension(:,:),
allocatable :: xprim_trans
388 sll_real64,
dimension(:,:),
allocatable :: x_sol_trans
389 sll_real64,
dimension(:,:),
allocatable :: x_sol
390 sll_int32 :: n_rows_a
391 sll_int32 :: n_rows_b
392 sll_int32 :: n_cols_a
393 sll_int32 :: n_cols_b
397 n_cols_a = linear_solver_a % n_global_cols
398 n_rows_a = linear_solver_a % n_global_rows
399 n_cols_b = linear_solver_b % n_global_cols
400 n_rows_b = linear_solver_b % n_global_rows
404 allocate(y(n_rows_b, n_rows_a))
405 allocate(xprim(n_cols_b, n_rows_a))
406 allocate(xprim_trans(n_rows_a, n_cols_b))
407 allocate(x_sol_trans(n_rows_a, n_cols_b))
408 allocate(x_sol(n_cols_b, n_rows_a))
419 do i_col_b = 1, n_cols_b
420 call linear_solver_b % solve_real( y(:, i_col_b), &
430 x_sol_trans = 0.0_f64
431 do i_col_b = 1, n_cols_b
432 call linear_solver_a % solve_real( xprim_trans(:, i_col_b), &
433 & x_sol_trans(:, i_col_b))
447 if(self%verbose)
then
448 print*,
'solve_2_real_linear_solver_kron, verbose = true: not yet implemented'
464 sll_real64,
dimension(:),
intent(in ) :: rhs
465 sll_real64,
dimension(:),
intent( out) :: unknown
468 sll_int32 :: i,j,k,istart,iend
469 sll_int32 :: stride, counter, ind3d
471 sll_real64 :: scratch_nrow_a( self%nrowcol(1,1) )
472 sll_real64 :: scratch_nrow_b( self%nrowcol(2,1) )
473 sll_real64 :: scratch_nrow_c( self%nrowcol(3,1) )
474 sll_real64 :: scratch_2_13( self%nrowcol(2,2), self%nrowcol(1,1)*self%nrowcol(3,2) )
475 sll_real64 :: scratch_3_21( self%nrowcol(3,2), self%nrowcol(2,1)*self%nrowcol(1,1) )
477 stride = self%nrowcol(1,1)
479 iend = self%nrowcol(1,2)
480 do k=1, self%nrowcol(3,2)
481 do j=1, self%nrowcol(2,2)
482 call self % ptr_linear_solver_a%solve ( rhs(istart:iend), scratch_nrow_a )
483 do i=1, self%nrowcol(1,1)
484 scratch_2_13(j,(k-1)*stride+i) = scratch_nrow_a(i)
487 iend = iend + self%nrowcol(1,2)
491 stride = self%nrowcol(2,1)
493 do k=1, self%nrowcol(3,2)
494 do i=1, self%nrowcol(1,1)
495 call self % ptr_linear_solver_b%solve ( scratch_2_13(:, counter), scratch_nrow_b )
496 do j=1, self%nrowcol(2,1)
497 scratch_3_21(k,(i-1)*stride+j) = scratch_nrow_b(j)
504 stride = self%nrowcol(3,1)
506 do i=1, self%nrowcol(1,1)
507 do j=1, self%nrowcol(2,1)
508 call self % ptr_linear_solver_c%solve ( scratch_3_21(:, counter), scratch_nrow_c )
509 ind3d = i+(j-1)*self%nrowcol(1,1)
510 do k=1, self%nrowcol(3,1)
511 unknown(ind3d) = scratch_nrow_c(k)
512 ind3d = ind3d + self%nrowcol(1,1)*self%nrowcol(2,1)
520 if(self%verbose)
then
521 print*,
'solve_3_real_linear_solver_kron, verbose = true: not yet implemented'
538 print *,
">>>> linear_solver_kron"
539 print *,
"* verbose : ", self % verbose
555 if (
allocated(self % p_linear_solver_a))
then
556 call self % p_linear_solver_a % free()
557 deallocate(self % p_linear_solver_a)
558 self % ptr_linear_solver_a => null()
563 if (
allocated(self % p_linear_solver_b))
then
564 call self % p_linear_solver_b % free()
565 deallocate(self % p_linear_solver_b)
566 self % ptr_linear_solver_b => null()
571 if (
allocated(self % p_linear_solver_c))
then
572 call self % p_linear_solver_c % free()
573 deallocate(self % p_linear_solver_c)
574 self % ptr_linear_solver_c => null()
module for abstract linear operator
module for a linear operator of kronecker solver
recursive subroutine, public sll_transpose(x, x_t)
returnes the transpose of a 2d array
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
module for abstract linear solver
module for conjugate gradient method in pure form
module for kronecker linear solver
subroutine solve_3_real_linear_solver_kron(self, rhs, unknown)
apply the solve operation with real vectors
subroutine set_verbose_linear_solver_kron(self, verbose)
sets the verbose for the linear solver object
subroutine free_linear_solver_kron(self)
destroys the current object
subroutine sll_allocate_linear_solver(solver_name, linear_solver, flag)
allocate the linear solver object
subroutine solve_2_real_linear_solver_kron(self, linear_solver_a, linear_solver_b, rhs, unknown)
solves the linear system with real vectors
subroutine solve_real_linear_solver_kron(self, rhs, unknown)
solves the linear system with real vectors
subroutine read_from_file_linear_solver_kron(self, filename)
read from file
subroutine create_linear_solver_kron(self, linear_operator_a, linear_operator_b, linear_operator_c, linear_solver_a, linear_solver_b, linear_solver_c, filename)
creates a kronecker linear solver the user must provide
subroutine print_info_linear_solver_kron(self)
destroys a finite element cell
subroutine sll_create_linear_solver_with_name(solver_name, linear_operator, linear_solver, flag, pc_left)
create an linear solver using its name and a linear operator
module for a sequential gmres
module for abstract matrix
class for abstract linear operator
class for a linear operator
class for abstract linear solver
class for the cg linear solver
class for the kronecker linear solver
class for a sequential gmres linear solver
abstract class for matrix