Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_operator_schur_eb_cl_3d.F90
Go to the documentation of this file.
2 #include "sll_working_precision.h"
3 
5 
9 
10  use sll_m_linear_operator_block, only : &
12 
13 !!$ use sll_m_matrix_csr, only: &
14 !!$ sll_t_matrix_csr
15 
16  implicit none
17 
19 
20  private
22 
23  type(sll_t_linear_operator_block), pointer :: mass1
24  type(sll_t_linear_operator_block), pointer :: mass2
25  !type(sll_t_matrix_csr), pointer :: mass1d(:,:)
26  sll_int32 :: n_total0, n_total1
27  sll_int32 :: n_dofs(3)
28  sll_int32 :: s_deg_0(3)
29  sll_real64 :: sign = 1.0_f64
30  sll_real64 :: delta_x(3)
31 
32  contains
34  procedure :: free => free_schur_eb_cl_3d
35  procedure :: dot => dot_schur_eb_cl_3d
36  procedure :: print_info => print_info_schur_eb_cl_3d
37 
39 
40 
41 contains
42 
43  subroutine create_linear_operator_schur_eb_cl_3d( self, mass1, mass2, n_dofs, delta_x, s_deg_0 )
44  class(sll_t_linear_operator_schur_eb_cl_3d), intent( inout ) :: self
45  type(sll_t_linear_operator_block), target :: mass1
46  type(sll_t_linear_operator_block), target :: mass2
47  !type(sll_t_matrix_csr), target :: mass1d(3,3)
48  sll_int32 :: n_dofs(3)
49  sll_real64 :: delta_x(3)
50  sll_int32 :: s_deg_0(3)
51 
52  self%mass1 => mass1
53  self%mass2 => mass2
54  !self%mass1d => mass1d
55 
56  self%n_dofs = n_dofs
57  self%delta_x = delta_x
58  self%s_deg_0 = s_deg_0
59  self%n_total0 = product(self%n_dofs)
60  self%n_total1 = (self%n_dofs(1)-1)*self%n_dofs(2)*self%n_dofs(3)
61 
62 
63 
64  self%n_rows = self%n_total1+2*self%n_total0
65  self%n_cols = self%n_total1+2*self%n_total0
66 
67  self%n_global_rows = self%n_rows
68  self%n_global_cols = self%n_cols
69 
71 
72  subroutine free_schur_eb_cl_3d( self )
73  class(sll_t_linear_operator_schur_eb_cl_3d), intent( inout ) :: self
74 
75  self%mass1=> null()
76  self%mass2=> null()
77  !self%mass1d=> null()
78 
79  end subroutine free_schur_eb_cl_3d
80 
81 
82  subroutine dot_schur_eb_cl_3d ( self, x, y )
83  class(sll_t_linear_operator_schur_eb_cl_3d), intent( in ) :: self
84  sll_real64, intent( in ) :: x(:)
85  sll_real64, intent( out ) :: y(:)
86  !local variables
87  ! sll_real64 :: scratch0(1:self%n_total0)
88  sll_real64 :: scratch1(self%n_total1+2*self%n_total0), scratch2(self%n_total0+2*self%n_total1), scratch3(self%n_total0+2*self%n_total1)
89 
90  ! Compute C x
91  call sll_s_multiply_c_clamped( self%n_dofs, self%delta_x, self%s_deg_0, x, scratch2 )
92 
93  ! Compute M2 C x
94  call self%mass2%dot( scratch2, scratch3 )
95 
96  ! Compute C^T M2 C x
97  call sll_s_multiply_ct_clamped( self%n_dofs, self%delta_x, self%s_deg_0, scratch3, scratch1 )
98 !!$
99 !!$ ! Compute C^T M2 C x + M_b C x
100 !!$ call multiply_mass_2dkron( self, [2,2,1], scratch2(1+self%n_total0+self%n_total1:self%n_total0+2*self%n_total1), scratch0 )
101 !!$ scratch1(1+self%n_total1:self%n_total1+self%n_total0)=scratch1(1+self%n_total1:self%n_total1+self%n_total0) - scratch0
102 !!$ call multiply_mass_2dkron( self, [2,1,2], scratch2(1+self%n_total0:self%n_total0+self%n_total1), scratch0 )
103 !!$ scratch1(1+self%n_total1+self%n_total0:self%n_total1+2*self%n_total0)=scratch1(1+self%n_total1+self%n_total0:self%n_total1+2*self%n_total0) + scratch0
104 
105 
106  ! Compute M1 x
107  call self%mass1%dot( x, y )
108 
109  ! Sum up the two parts
110  y = y + self%sign * scratch1
111 
112  end subroutine dot_schur_eb_cl_3d
113 
114 
115  subroutine print_info_schur_eb_cl_3d( self )
116  class(sll_t_linear_operator_schur_eb_cl_3d), intent(in) :: self
117 
118  end subroutine print_info_schur_eb_cl_3d
119 
120 !!$
121 !!$ !> Multiply by the mass matrix
122 !!$ subroutine multiply_mass_2dkron( self, deg, coefs_in, coefs_out )
123 !!$ class(sll_t_linear_operator_schur_eb_cl) :: self
124 !!$ sll_int32, intent( in ) :: deg(:) !< \a deg(i) specifies the degree of the 1d mass matrix in dimension \a i (Note: 1 for 0-form, 2 for 1-form, 3 for 0-1-form mix)
125 !!$ sll_real64, intent( in ) :: coefs_in(:)
126 !!$ sll_real64, intent( out ) :: coefs_out(:)
127 !!$ ! Local variables
128 !!$ sll_int32 :: j,k
129 !!$ sll_real64 :: work3d(self%n_dofs(1), self%n_dofs(2), self%n_dofs(3))
130 !!$ sll_real64 :: work_d2_in(self%n_dofs(2)), work_d2_out(self%n_dofs(2))
131 !!$ sll_real64 :: work_d3_in(self%n_dofs(3)), work_d3_out(self%n_dofs(3))
132 !!$
133 !!$ coefs_out=0._f64
134 !!$ if (deg(1)==2)then
135 !!$ work3d=0._f64
136 !!$ do k=1,self%n_dofs(3)
137 !!$ do j=1,self%n_dofs(2)
138 !!$ work3d(1,j,k) = -coefs_in(1+(j-1)*(self%n_dofs(1)-1)+(k-1)*(self%n_dofs(1)-1)*self%n_dofs(2))
139 !!$ work3d(self%n_dofs(1),j,k) = coefs_in(self%n_dofs(1)-1+(j-1)*(self%n_dofs(1)-1)+(k-1)*(self%n_dofs(1)-1)*self%n_dofs(2))
140 !!$ end do
141 !!$ end do
142 !!$
143 !!$ do k=1,self%n_dofs(3)
144 !!$ work_d2_in = work3d(1,:,k)
145 !!$ call self%mass1d(deg(2),2)%dot( work_d2_in, work_d2_out )
146 !!$ work3d(1,:,k) = work_d2_out
147 !!$
148 !!$ work_d2_in = work3d(self%n_dofs(1),:,k)
149 !!$ call self%mass1d(deg(2),2)%dot( work_d2_in, work_d2_out )
150 !!$ work3d(self%n_dofs(1),:,k) = work_d2_out
151 !!$ end do
152 !!$
153 !!$ do j=1,self%n_dofs(2)
154 !!$ work_d3_in = work3d(1,j,:)
155 !!$ call self%mass1d(deg(3),3)%dot( work_d3_in, work_d3_out )
156 !!$ do k=1,self%n_dofs(3)
157 !!$ coefs_out(1+(j-1)*self%n_dofs(1)+(k-1)*self%n_dofs(1)*self%n_dofs(2)) = work_d3_out(k)
158 !!$ end do
159 !!$ work_d3_in = work3d(self%n_dofs(1),j,:)
160 !!$ call self%mass1d(deg(3),3)%dot( work_d3_in, work_d3_out )
161 !!$ do k=1,self%n_dofs(3)
162 !!$ coefs_out(self%n_dofs(1)+(j-1)*self%n_dofs(1)+(k-1)*self%n_dofs(1)*self%n_dofs(2)) = work_d3_out(k)
163 !!$ end do
164 !!$ end do
165 !!$ else
166 !!$ print*, 'multiply_mass_2dkron not implemented for this degree'
167 !!$ stop
168 !!$ end if
169 !!$
170 !!$ end subroutine multiply_mass_2dkron
171 
172 
173 
174 
module for abstract linear operator
module for a block linear operator
subroutine create_linear_operator_schur_eb_cl_3d(self, mass1, mass2, n_dofs, delta_x, s_deg_0)
Utilites for Maxwell solver's with spline finite elements using sparse matrices.
subroutine, public sll_s_multiply_ct_clamped(n_dofs, delta_x, s_deg_0, field_in, field_out)
Multiply by transpose of discrete curl matrix.
subroutine, public sll_s_multiply_c_clamped(n_dofs, delta_x, s_deg_0, field_in, field_out)
Multiply by discrete curl matrix.
    Report Typos and Errors