Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_operator_ecsim.F90
Go to the documentation of this file.
2 #include "sll_working_precision.h"
3 
5 
6  use sll_m_spline_fem_utilities, only : &
8 
9  implicit none
10 
12 
13  private
14 
16  sll_int32 :: degree
17  sll_real64 :: dt
18  sll_real64 :: dx
19  sll_real64, allocatable :: mass_line_0(:)
20  sll_real64, allocatable :: mass_line_1(:)
21  sll_real64, pointer :: m1(:,:), m2(:,:), m4(:,:)
22 
23 
24  contains
25  procedure :: create => create_linear_operator_ecsim
26  procedure :: free => free_ecsim
27  procedure :: dot => dot_mono_r2r_ecsim
28  procedure :: print_info => print_info_ecsim
29 
31 
32 contains
33 
34  subroutine create_linear_operator_ecsim( self, n_dof,degree, mass_line_0,mass_line_1, m1,m2, m4)
35  class(sll_t_linear_operator_ecsim), intent( inout ) :: self
36  sll_int32 :: n_dof
37  sll_int32 :: degree
38  sll_real64 :: mass_line_0(:)
39  sll_real64 :: mass_line_1(:)
40  sll_real64,target :: m1(:,:)
41  sll_real64,target :: m2(:,:)
42  sll_real64,target :: m4(:,:)
43 
44 
45  self%n_dof=n_dof
46  self%degree=degree
47  self%dt=0.0_f64
48  self%m1=>m1
49  self%m2=>m2
50  self%m4=>m4
51  allocate(self%mass_line_0(degree+1))
52  allocate(self%mass_line_1(degree))
53  self%mass_line_0=mass_line_0
54  self%mass_line_1=mass_line_1
55 
56 
57  self%n_rows = 3*n_dof
58  self%n_cols = 3*n_dof
59 
60  self%n_global_rows = self%n_rows
61  self%n_global_cols = self%n_cols
62  end subroutine create_linear_operator_ecsim
63 
64 
65  subroutine free_ecsim( self )
66  class(sll_t_linear_operator_ecsim), intent( inout ) :: self
67  deallocate(self%mass_line_0)
68  deallocate(self%mass_line_1)
69  self%m1=>null()
70  self%m2=>null()
71  self%m4=>null()
72 
73  end subroutine free_ecsim
74 
75  subroutine dot_mono_r2r_ecsim( self, x, y )
76  class(sll_t_linear_operator_ecsim), intent( in ) :: self
77  sll_real64, intent( in ) :: x(:)
78  sll_real64, intent( out ) :: y(:)
79  ! local variables
80  sll_int32 :: row, column
81  sll_real64 :: scratch(self%n_dof+1)
82  scratch=0.0_f64
83  y=0.0_f64
84  do row=1, self%n_dof
85  ! Monoplication of the inputvector with entries of the mass and particle-mass matrices
86  y(row) = (self%mass_line_1(1)+0.5_f64*self%dt*self%m1(1,row))*x(row)
87  y(self%n_dof+row)= (self%mass_line_0(1)+0.5_f64*self%dt*self%m4(1,row))*x(self%n_dof+row)
88 
89  scratch(row)=self%mass_line_1(1)*x(2*self%n_dof+row)
90  do column = 2, self%degree
91  y(row) = y(row) +&
92  self%mass_line_1(column) * &
93  (x(modulo(row+column-2,self%n_dof)+1) +&
94  x(modulo(row-column,self%n_dof)+1))+&
95  0.5_f64*self%dt*self%m1(column,row) * &
96  x(modulo(row+column-2,self%n_dof)+1)+&
97  0.5_f64*self%dt*self%m1(column,modulo(row-column,self%n_dof)+1) * &
98  x(modulo(row-column,self%n_dof)+1)
99 
100  scratch(row)=scratch(row)+&
101  self%mass_line_1(column) * &
102  (x(2*self%n_dof+ modulo(row+column-2,self%n_dof)+1) +&
103  x(2*self%n_dof+ modulo(row-column,self%n_dof)+1))
104  end do
105  do column = 2, self%degree+1
106  y(self%n_dof+row) = y(self%n_dof+row) +&
107  self%mass_line_0(column) * &
108  (x(self%n_dof+modulo(row+column-2,self%n_dof)+1) +&
109  x(self%n_dof+ modulo(row-column,self%n_dof)+1))+&
110  0.5_f64*self%dt*self%m4(column,row)*&
111  x(self%n_dof+modulo(row+column-2,self%n_dof)+1)+&
112  0.5_f64*self%dt*self%m4(column,modulo(row-column,self%n_dof)+1)*&
113  x(self%n_dof+modulo(row-column,self%n_dof)+1)
114  end do
115 
116  do column = 1, 2*self%degree
117  y(row) = y(row) - &
118  0.5_f64*self%dt*self%m2(7-column,modulo(column-4+row-1,self%n_dof)+1)*&
119  x(self%n_dof+modulo(row+column-self%degree-2,self%n_dof)+1)
120 
121  y(row+self%n_dof) = y(row+self%n_dof) + &
122  0.5_f64*self%dt*self%m2(column,row) * &
123  x(modulo(row+column-self%degree-1,self%n_dof)+1)
124  end do
125  end do
126  ! Update of the outputvector with derivatives of the inputvector
127  scratch(self%n_dof+1)=scratch(1)
128  do row=1, self%n_dof
129  y(row+self%n_dof)= y(row+self%n_dof)-&
130  0.5_f64*self%dt/self%dx*(scratch(row)-scratch(row+1))
131 
132  y(2*self%n_dof+row)=x(2*self%n_dof+row)+ &
133  0.5_f64*self%dt/self%dx*(x(self%n_dof+row)-x(self%n_dof+modulo(row-2,self%n_dof)+1))
134 
135  end do
136 
137  end subroutine dot_mono_r2r_ecsim
138 
139 
140  subroutine print_info_ecsim( self )
141  class(sll_t_linear_operator_ecsim), intent(in) :: self
142  end subroutine print_info_ecsim
143 
module for abstract linear operator
subroutine create_linear_operator_ecsim(self, n_dof, degree, mass_line_0, mass_line_1, m1, m2, m4)
Utilites for Maxwell solver's with spline finite elements.
subroutine, public sll_s_spline_fem_mass_line(degree, mass_line)
Computes the mass line for a mass matrix with degree splines.
    Report Typos and Errors