Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_spline_matrix_periodic_banded.F90
Go to the documentation of this file.
1 
5 
7 
8 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 #include "sll_assert.h"
10 #include "sll_errors.h"
11 
12  use sll_m_working_precision, only: f64
13 
14  use sll_m_spline_matrix_base, only: &
16 
17  use schur_complement, only: &
18  schur_complement_solver, &
19  schur_complement_fac, &
20  schur_complement_slv, &
21  schur_complement_free
22 
23  use iso_fortran_env, only: &
24  output_unit
25 
26  implicit none
27 
29 
30  private
31 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32 
34  integer, parameter :: wp = f64
35 
37 
38  integer :: n
39  integer :: kl
40  integer :: ku
41  real(wp), allocatable :: q(:, :)
42  type(schur_complement_solver) :: schur
43 
44  contains
45 
49  procedure :: solve_inplace => s_spline_matrix_periodic_banded__solve_inplace
52 
54 
55 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 contains
57 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 
59  !-----------------------------------------------------------------------------
60  subroutine s_spline_matrix_periodic_banded__init(self, n, kl, ku)
61  class(sll_t_spline_matrix_periodic_banded), intent(out) :: self
62  integer, intent(in) :: n
63  integer, intent(in) :: kl
64  integer, intent(in) :: ku
65 
66  character(len=*), parameter :: &
67  this_sub_name = "sll_t_spline_matrix_periodic_banded % init"
68 
69  sll_assert(n > 0)
70  sll_assert(kl >= 0)
71  sll_assert(ku >= 0)
72  sll_assert(ku + 1 + kl <= n)
73 
74  ! FIXME: current linear solver only works for kl=ku
75  if (kl /= ku) then
76  sll_error(this_sub_name, "Schur complement solver requires kl=ku.")
77  end if
78 
79  self%n = n
80  self%kl = kl
81  self%ku = ku
82 
83  ! Allocate matrix Q for linear system:
84  ! - M is circulant banded matrix (sparse)
85  ! - Q is compressed form of A (circulant diagonals of M are rows of Q)
86  allocate (self%q(ku + 1 + kl, n))
87  self%q(:, :) = 0.0_wp
88 
90 
91  !-----------------------------------------------------------------------------
92  subroutine s_spline_matrix_periodic_banded__set_element(self, i, j, a_ij)
93  class(sll_t_spline_matrix_periodic_banded), intent(inout) :: self
94  integer, intent(in) :: i
95  integer, intent(in) :: j
96  real(wp), intent(in) :: a_ij
97 
98  integer :: d
99 
100  sll_assert(1 <= i .and. i <= self%n)
101  sll_assert(1 <= j .and. j <= self%n)
102 
103  ! Compute diagonal index:
104  ! . d=0 for main diagonal,
105  ! . d>0 for superdiagonals,
106  ! . d<0 for subdiagonals
107  d = j - i
108  if (d > self%n/2) then; d = d - self%n; else &
109  if (d < -self%n/2) then; d = d + self%n; end if
110 
111  ! Verify that diagonal index is valid
112  sll_assert(d >= -self%kl)
113  sll_assert(d <= self%ku)
114 
115  ! Write element in correct position
116  self%q(self%ku + 1 - d, j) = a_ij
117 
119 
120  !-----------------------------------------------------------------------------
122  class(sll_t_spline_matrix_periodic_banded), intent(inout) :: self
123 
124  ! Prepare solution of linear system by performing:
125  ! a) Block decomposition of M = [[A,B],[C,D]] with
126  ! - A (n-k)x(n-k) banded Toeplitz matrix (square, large)
127  ! - B (n-k)x( k) low-rank Toeplitz (rectangular, empty in the center)
128  ! - C ( k)x(n-k) low-rank Toeplitz (rectangular, empty in the center)
129  ! - D ( k)x( k) fully dense Toeplitz matrix (square, small)
130  ! b) LU factorization of matrix A
131  ! c) Calculation of Schur complement of A: H = D - C A^{-1} B
132  ! d) LU factorization of Schur complement H
133  call schur_complement_fac(self%schur, self%n, self%kl, self%q)
134 
136 
137  !-----------------------------------------------------------------------------
139  class(sll_t_spline_matrix_periodic_banded), intent(in) :: self
140  real(wp), intent(inout) :: bx(:)
141 
142  sll_assert(size(bx) == self%n)
143 
144  call schur_complement_slv(self%schur, self%n, self%kl, self%q, bx)
145 
147 
148  !-----------------------------------------------------------------------------
149  subroutine s_spline_matrix_periodic_banded__write(self, unit, fmt)
150  class(sll_t_spline_matrix_periodic_banded), intent(in) :: self
151  integer, optional, intent(in) :: unit
152  character(len=*), optional, intent(in) :: fmt
153 
154  ! Default file unit and print format
155  integer, parameter :: unit_default = output_unit
156  character(len=*), parameter :: fmt_default = 'es9.1'
157 
158  ! Local variables
159  integer :: i, j, d
160  integer :: unit_loc
161  character(len=32) :: fmt_loc
162 
163  ! Overwrite defaults with optional arguments, if present
164  if (present(unit)) then
165  unit_loc = unit
166  else
167  unit_loc = unit_default
168  end if
169 
170  if (present(fmt)) then
171  fmt_loc = fmt
172  else
173  fmt_loc = fmt_default
174  end if
175 
176  ! Finalize format string
177  write (fmt_loc, '(a)') "("//trim(fmt_loc)//")"
178 
179  ! Write full matrix to selected output stream
180  do i = 1, self%n
181  do j = 1, self%n
182  d = modulo(j - i + self%kl, self%n) - self%kl
183  if (-self%kl <= d .and. d <= self%ku) then
184  write (unit_loc, fmt_loc, advance='no') self%q(self%ku + 1 - d, j)
185  else
186  write (unit_loc, fmt_loc, advance='no') 0.0_wp
187  end if
188  end do
189  write (unit_loc, *)
190  end do
191 
193 
194  !-----------------------------------------------------------------------------
196  class(sll_t_spline_matrix_periodic_banded), intent(inout) :: self
197 
198  self%n = -1
199  self%kl = -1
200  self%ku = -1
201  if (allocated(self%q)) deallocate (self%q)
202  if (allocated(self%schur%bb)) call schur_complement_free(self%schur)
203 
205 
Abstract class for small matrix library with basic operations: set matrix element,...
Derived type for periodic banded matrices.
subroutine s_spline_matrix_periodic_banded__set_element(self, i, j, a_ij)
Module to select the kind parameter.
integer, parameter, public f64
f64 is the kind type for 64-bit reals (double precision)
    Report Typos and Errors