Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_operator_matrix_c1_block.F90
Go to the documentation of this file.
2 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 #include "sll_assert.h"
4 #include "sll_errors.h"
5 
7 
9 
11 
13 
15 
17 
19 
21 
22  implicit none
23 
25 
26  private
27 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28 
29  ! Working precision
30  integer, parameter :: wp = f64
31 
33 
34  integer :: n1(4)
35  integer :: n2(4)
36  integer :: p1
37  integer :: p2
38 
43 
44  contains
45 
52 
54 
55 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 contains
57 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 
59  ! Initialize linear operator
60  subroutine s_linear_operator_matrix_c1_block__init(self, n1, n2, p1, p2)
61  class(sll_t_linear_operator_matrix_c1_block), intent(inout) :: self
62  integer, intent(in) :: n1(4)
63  integer, intent(in) :: n2(4)
64  integer, intent(in) :: p1
65  integer, intent(in) :: p2
66 
67  self%n1 = n1
68  self%n2 = n2
69  self%p1 = p1
70  self%p2 = p2
71 
72  call self%block1%init(n1(1), n2(1))
73  call self%block2%init(n1(2), n2(2))
74  call self%block3%init(n1(3), n2(3))
75  call self%block4%init(n1(4), n2(4), p1, p2)
76 
78 
79  ! Get shape of linear operator
81  class(sll_t_linear_operator_matrix_c1_block), intent(in) :: self
82  integer :: s(2)
83 
84  s = self%block1%get_shape() + self%block2%get_shape() + &
85  self%block3%get_shape() + self%block4%get_shape()
86 
88 
89  ! Implement y=Ax, with A C1 block matrix, x and y C1 block vectors
91  class(sll_t_linear_operator_matrix_c1_block), intent(in) :: self
92  class(sll_c_vector_space), intent(in) :: x
93  class(sll_c_vector_space), intent(inout) :: y
94 
95  character(len=*), parameter :: this_sub_name = "sll_t_linear_operator_matrix_c1_block % dot"
96  character(len=64) :: err_msg
97 
98  select type (x)
99 
101 
102  select type (y)
103 
105 
106  call self%block1%dot(x%vd, y%vd)
107  call self%block2%dot_incr(x%vs, y%vd)
108  call self%block3%dot(x%vd, y%vs)
109  call self%block4%dot_incr(x%vs, y%vs)
110 
111  class default
112  err_msg = "y must be of type sll_t_vector_space_c1_block"
113  sll_error(this_sub_name, err_msg)
114 
115  end select
116 
117  class default
118  err_msg = "x must be of type sll_t_vector_space_c1_block"
119  sll_error(this_sub_name, err_msg)
120 
121  end select
122 
124 
125  ! Implement y=y+Ax, with A C1 block matrix, x and y C1 block vectors
127  class(sll_t_linear_operator_matrix_c1_block), intent(in) :: self
128  class(sll_c_vector_space), intent(in) :: x
129  class(sll_c_vector_space), intent(inout) :: y
130 
131  character(len=*), parameter :: this_sub_name = "sll_t_linear_operator_matrix_c1_block % dot_incr"
132  character(len=64) :: err_msg
133 
134  select type (x)
135 
137 
138  select type (y)
139 
141 
142  call self%block1%dot_incr(x%vd, y%vd)
143  call self%block2%dot_incr(x%vs, y%vd)
144  call self%block3%dot_incr(x%vd, y%vs)
145  call self%block4%dot_incr(x%vs, y%vs)
146 
147  class default
148  err_msg = "y must be of type sll_t_vector_space_c1_block"
149  sll_error(this_sub_name, err_msg)
150 
151  end select
152 
153  class default
154  err_msg = "x must be of type sll_t_vector_space_c1_block"
155  sll_error(this_sub_name, err_msg)
156 
157  end select
158 
160 
161  ! Convert C1 block matrix to dense matrix
163  class(sll_t_linear_operator_matrix_c1_block), intent(in) :: self
164  real(wp), intent(inout) :: A(:, :)
165 
166  integer :: i, j, i1, i2, j1, j2, k1, k2
167 
168  ! Indices 1,2,3 correspond to dense blocks
169  sll_assert(size(a, 1) == self%n1(1) + self%n1(3))
170  sll_assert(size(a, 2) == self%n2(1) + self%n2(2))
171 
172  associate(n1 => self%n1, &
173  n2 => self%n2, &
174  p1 => self%p1, &
175  p2 => self%p2)
176 
177  a(1:n1(1), 1:n2(1)) = self%block1%A(:, :)
178  a(1:n1(1), n2(1) + 1:n2(1) + n2(2)) = self%block2%A(:, :)
179  a(n1(1) + 1:n1(1) + n1(3), 1:n2(1)) = self%block3%A(:, :)
180 
181  do i2 = 1, n2(4)
182  do i1 = 1, n1(4)
183  do k2 = -p2, p2
184  do k1 = -p1, p1
185  j1 = modulo(i1 - 1 + k1, n1(4)) + 1
186  j2 = modulo(i2 - 1 + k2, n2(4)) + 1
187  i = (i1 - 1)*n2(4) + i2
188  j = (j1 - 1)*n2(4) + j2
189  a(i + 3, j + 3) = self%block4%A(k1, k2, i1, i2)
190  end do
191  end do
192  end do
193  end do
194 
195  end associate
196 
198 
199  ! Free objects
201  class(sll_t_linear_operator_matrix_c1_block), intent(inout) :: self
202 
203  call self%block1%free()
204  call self%block2%free()
205  call self%block3%free()
206  call self%block4%free()
207 
209 
integer function, dimension(2) f_linear_operator_matrix_c1_block__get_shape(self)
subroutine s_linear_operator_matrix_c1_block__init(self, n1, n2, p1, p2)
Abstract type implementing a generic vector space.
Vector space for wrapping 2D Fortran real arrays.
Module to select the kind parameter.
integer, parameter, public f64
f64 is the kind type for 64-bit reals (double precision)
Abstract base class for all vector spaces.
    Report Typos and Errors