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_dense_to_stencil_new.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 
16  implicit none
17 
19 
20  private
21 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 
23  ! Working precision
24  integer, parameter :: wp = f64
25 
27 
28  real(wp), allocatable :: a(:, :, :)
29 
30  integer :: s1
31  integer :: s2
32  integer :: s3
33 
34  contains
35 
41 
43 
44 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
45 contains
46 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 
48  ! Initialize linear operator
50  class(sll_t_linear_operator_matrix_dense_to_stencil_new), intent(inout) :: self
51  integer, intent(in) :: s1
52  integer, intent(in) :: s2
53  integer, intent(in) :: s3
54 
55  allocate (self%A(s1, s2, s3))
56 
57  self%s1 = s1
58  self%s2 = s2
59  self%s3 = s3
60 
62 
63  ! Get shape of linear operator
65  class(sll_t_linear_operator_matrix_dense_to_stencil_new), intent(in) :: self
66  integer :: s(2)
67 
68  s(1) = size(self%A, 1)*size(self%A, 2)
69  s(2) = size(self%A, 3)
70 
72 
73  ! Implement y=Ax, with A dense matrix (2D), x dense vector (1D) and y stencil vector (2D)
75  class(sll_t_linear_operator_matrix_dense_to_stencil_new), intent(in) :: self
76  class(sll_c_vector_space), intent(in) :: x ! dense
77  class(sll_c_vector_space), intent(inout) :: y ! stencil
78 
79  integer :: j1, j2, k
80  real(wp) :: temp
81 
82  character(len=*), parameter :: this_sub_name = "sll_t_linear_operator_matrix_dense_to_stencil_new % dot"
83  character(len=64) :: err_msg
84 
85  select type (x)
86 
88 
89  ! Check dimensions
90  sll_assert(self%s3 == size(x%array))
91 
92  select type (y)
93 
95 
96  associate(p1 => -lbound(y%array, 1) + 1, &
97  p2 => -lbound(y%array, 2) + 1)
98 
99  associate(ny1 => ubound(y%array, 1) - p1, &
100  ny2 => ubound(y%array, 2) - p2)
101 
102  y%array = 0.0_wp
103 
104 !$OMP PARALLEL DO PRIVATE(temp)
105  do j2 = 1, ny2
106  do j1 = 1, p1
107 
108  temp = 0.0_wp
109 
110  do k = 1, size(x%array)
111  temp = temp + self%A(j1, j2, k)*x%array(k)
112  end do
113 
114  y%array(j1, j2) = y%array(j1, j2) + temp
115 
116  end do
117  end do
118 !$OMP END PARALLEL DO
119 
120  ! Update buffer regions
121  y%array(1 - p1:0, :) = y%array(ny1 - p1 + 1:ny1, :)
122  y%array(ny1 + 1:ny1 + p1, :) = y%array(1:p1, :)
123  y%array(:, 1 - p2:0) = y%array(:, ny2 - p2 + 1:ny2)
124  y%array(:, ny2 + 1:ny2 + p2) = y%array(:, 1:p2)
125 
126  end associate
127 
128  end associate
129 
130  class default
131  err_msg = "y must be of type sll_t_vector_space_real_array_2d"
132  sll_error(this_sub_name, err_msg)
133 
134  end select
135 
136  class default
137  err_msg = "x must be of type sll_t_vector_space_real_array_1d"
138  sll_error(this_sub_name, err_msg)
139 
140  end select
141 
143 
144  ! Implement y=y+Ax, with A dense matrix (2D), x dense vector (1D) and y stencil vector (2D)
146  class(sll_t_linear_operator_matrix_dense_to_stencil_new), intent(in) :: self
147  class(sll_c_vector_space), intent(in) :: x ! dense
148  class(sll_c_vector_space), intent(inout) :: y ! stencil
149 
150  integer :: j1, j2, k
151  real(wp) :: temp
152 
153  character(len=*), parameter :: this_sub_name = "sll_t_linear_operator_matrix_dense_to_stencil_new % dot_incr"
154  character(len=64) :: err_msg
155 
156  select type (x)
157 
158  type is (sll_t_vector_space_real_array_1d)
159 
160  ! Check dimensions
161  sll_assert(self%s3 == size(x%array))
162 
163  select type (y)
164 
165  type is (sll_t_vector_space_real_array_2d)
166 
167  associate(p1 => -lbound(y%array, 1) + 1, &
168  p2 => -lbound(y%array, 2) + 1)
169 
170  associate(ny1 => ubound(y%array, 1) - p1, &
171  ny2 => ubound(y%array, 2) - p2)
172 
173 !$OMP PARALLEL DO PRIVATE(temp)
174  do j2 = 1, ny2
175  do j1 = 1, p1
176 
177  temp = 0.0_wp
178 
179  do k = 1, size(x%array)
180  temp = temp + self%A(j1, j2, k)*x%array(k)
181  end do
182 
183  y%array(j1, j2) = y%array(j1, j2) + temp
184 
185  end do
186  end do
187 !$OMP END PARALLEL DO
188 
189  ! Update buffer regions
190  y%array(1 - p1:0, :) = y%array(ny1 - p1 + 1:ny1, :)
191  y%array(ny1 + 1:ny1 + p1, :) = y%array(1:p1, :)
192  y%array(:, 1 - p2:0) = y%array(:, ny2 - p2 + 1:ny2)
193  y%array(:, ny2 + 1:ny2 + p2) = y%array(:, 1:p2)
194 
195  end associate
196 
197  end associate
198 
199  class default
200  err_msg = "y must be of type sll_t_vector_space_real_array_2d"
201  sll_error(this_sub_name, err_msg)
202 
203  end select
204 
205  class default
206  err_msg = "x must be of type sll_t_vector_space_real_array_1d"
207  sll_error(this_sub_name, err_msg)
208 
209  end select
210 
212 
213  ! Free objects
215  class(sll_t_linear_operator_matrix_dense_to_stencil_new), intent(inout) :: self
216 
217  deallocate (self%A)
218 
220 
Abstract type implementing a generic vector space.
Vector space for wrapping 1D Fortran real arrays.
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