8 #include "sll_assert.h"
9 #include "sll_errors.h"
10 #include "sll_memory.h"
11 #include "sll_working_precision.h"
14 sll_s_uniform_bsplines_eval_basis
40 sll_real64 :: delta_x2(2)
41 sll_real64 :: domain2(2,2)
44 sll_int32 :: no_particles
49 sll_int32,
allocatable :: n_grid(:)
51 sll_real64,
allocatable :: spline_val(:,:)
78 sll_real64,
intent( in ) :: position(2)
79 sll_int32,
intent( out ) :: indices(2)
85 xi(1:2) = (position(1:2) - self%domain2(:,1)) /&
87 indices = ceiling(xi(1:2))
88 xi(1:2) = xi(1:2) - real(indices -1,f64)
89 indices = indices - self%spline_degree
90 call sll_s_uniform_bsplines_eval_basis(self%spline_degree, xi(1), self%spline_val(1:self%n_span,1))
91 call sll_s_uniform_bsplines_eval_basis(self%spline_degree, xi(2), self%spline_val(1:self%n_span,2))
101 sll_real64,
intent( in ) :: position(self%dim)
102 sll_real64,
intent( in ) :: marker_charge
103 sll_real64,
intent(inout) :: rho_dofs(self%n_dofs )
107 sll_int32 :: indices(2)
108 sll_int32 :: i1, i2, index2d
109 sll_int32 :: index1d(2)
111 xi(1:2) = (position(1:2) - self%domain2(:,1)) /self%delta_x2
112 indices = floor(xi(1:2))+1
113 xi(1:2) = xi(1:2) - real(indices -1,f64)
114 indices = indices - self%spline_degree
118 do i1 = 1, self%n_span
119 index1d(1) = indices(1)+i1-2
120 do i2 = 1, self%n_span
121 index1d(2) = indices(2)+i2-2
123 rho_dofs(index2d) = rho_dofs(index2d) +&
124 ( marker_charge* self%scaling * &
125 self%spline_val(i1,1) * self%spline_val(i2,2))
135 sll_real64,
intent( in ) :: position(self%dim)
136 sll_real64,
intent( in ) :: marker_charge
137 sll_real64,
intent(inout) :: rho_dofs(self%n_dofs )
140 sll_int32 :: i1, i2, index2d
141 sll_int32 :: index1d(2)
142 sll_int32 :: indices(2)
146 do i1 = 1, self%n_span
147 index1d(1) = indices(1)+i1-2
148 do i2 = 1, self%n_span
149 index1d(2) = indices(2)+i2-2
151 rho_dofs(index2d) = rho_dofs(index2d) +&
152 ( marker_charge* self%scaling * &
153 self%spline_val(i1,1) * self%spline_val(i2,2))
163 sll_real64,
intent( in ) :: position_old(self%dim)
164 sll_real64,
intent( in ) :: position_new(self%dim)
165 sll_real64,
intent( in ) :: marker_charge
166 sll_real64,
intent( inout ) :: j_dofs(self%n_dofs)
170 sll_error(
'add_particles_mass_spline_2d',
'add_current not implemented')
178 sll_real64,
intent( in ) :: position_old(self%dim)
179 sll_real64,
intent( in ) :: position_new(self%dim)
180 sll_real64,
intent( in ) :: marker_charge
181 sll_real64,
intent( in ) :: vbar
182 sll_real64,
intent( in ) :: field_dofs(self%n_dofs)
183 sll_real64,
intent( inout ) :: j_dofs(self%n_dofs)
184 sll_real64,
intent( out ) :: field
186 sll_error(
'add_particles_mass_spline_2d',
'add_current not implemented')
194 sll_real64,
intent(in) :: position_old(self%dim)
195 sll_real64,
intent(in) :: position_new(self%dim)
196 sll_real64,
intent(in) :: marker_charge
197 sll_real64,
intent(in) :: qoverm
198 sll_real64,
intent(in) :: bfield_dofs(:)
199 sll_real64,
intent(inout) :: vi(:)
200 sll_real64,
intent(inout) :: j_dofs(:)
202 print*,
'add_current_update_v_spline_2d not implemented.'
209 sll_real64,
intent( in ) :: position(self%dim)
210 sll_real64,
intent( in ) :: marker_charge
211 sll_real64,
intent( inout ) :: particle_mass(:,:)
213 sll_error(
'add_particles_mass_spline_2d',
'add_particle_mass not implemented')
222 sll_real64,
intent(in) :: position_old(self%dim)
223 sll_real64,
intent(in) :: position_new(self%dim)
224 sll_real64,
intent(in) :: marker_charge
225 sll_real64,
intent(in) :: qoverm
226 sll_real64,
intent(in) :: bfield_dofs(:)
227 sll_real64,
intent(inout) :: vi(:)
228 sll_real64,
intent(inout) :: j_dofs(:)
230 print*,
'add_current_update_v_spline_pp_2d not implemented.'
281 sll_real64,
intent( in ) :: position(self%dim)
282 sll_real64,
intent(in) :: field_dofs_pp(:,:)
283 sll_real64,
intent(out) :: field_value
287 sll_int32 :: indices(2)
289 xi(1:2) = (position(1:2) - self%domain2(:,1)) /self%delta_x2
290 indices = floor(xi(1:2))+1
291 xi(1:2) = xi(1:2) - real(indices -1,f64)
302 sll_real64,
intent( in ) :: position(self%dim)
303 sll_real64,
intent(in) :: field_dofs(self%n_dofs)
304 sll_real64,
intent(out) :: field_value
307 sll_int32 :: i1, i2, index2d
308 sll_int32 :: index1d(2)
309 sll_int32 :: indices(2)
315 field_value = 0.0_f64
316 do i1 = 1, self%n_span
317 index1d(1) = indices(1)+i1-2
318 do i2 = 1, self%n_span
319 index1d(2) = indices(2)+i2-2
321 field_value = field_value + &
322 field_dofs(index2d) * &
323 self%spline_val(i1,1) *&
324 self%spline_val(i2,2)
334 sll_real64,
intent( in ) :: position(self%dim)
335 sll_int32,
intent(in) :: components(:)
336 sll_real64,
intent(in) :: field_dofs(:,:)
337 sll_real64,
intent(out) :: field_value(:)
340 sll_int32 :: i1, i2, index2d
341 sll_int32 :: index1d(2)
342 sll_int32 :: indices(2)
348 field_value = 0.0_f64
349 do i1 = 1, self%n_span
350 index1d(1) = indices(1)+i1-2
351 do i2 = 1, self%n_span
352 index1d(2) = indices(2)+i2-2
354 field_value = field_value + &
355 field_dofs(index2d,components) * &
356 self%spline_val(i1,1) *&
357 self%spline_val(i2,2)
367 deallocate(self%n_grid)
368 deallocate(self%spline_val)
377 subroutine init_spline_2d(self, domain, n_grid, no_particles, spline_degree, smoothing_type)
379 sll_int32,
intent(in) :: n_grid(2)
380 sll_real64,
intent(in) :: domain(2,2)
381 sll_int32,
intent(in) :: no_particles
382 sll_int32,
intent(in) :: spline_degree
383 sll_int32,
intent(in) :: smoothing_type
391 self%domain2 = domain
392 sll_allocate(self%n_grid(2), ierr)
394 self%n_dofs = product(n_grid)
395 self%delta_x2 = (domain(:,2)-domain(:,1))/real(n_grid, f64)
398 self%no_particles = no_particles
401 self%spline_degree = spline_degree
402 self%n_span = spline_degree + 1
406 self%scaling = 1.0_f64/product(self%delta_x2)
408 self%scaling = 1.0_f64
410 print*,
'Smoothing Type ', smoothing_type,
' not implemented for kernel_smoother_spline_2d.'
413 allocate( self%spline_val(self%n_span, 2), stat = ierr)
414 sll_assert( ierr == 0)
423 sll_int32,
intent(in) :: n_grid(2)
424 sll_real64,
intent(in) :: domain(2,2)
425 sll_int32,
intent(in) :: no_particles
426 sll_int32,
intent(in) :: spline_degree
427 sll_int32,
intent(in) :: smoothing_type
433 select type (smoother)
435 call smoother%init( domain, n_grid, no_particles, spline_degree, smoothing_type)
444 sll_int32,
intent(in) :: n_grid(2)
445 sll_real64,
intent(in) :: domain(2,2)
446 sll_int32,
intent(in) :: no_particles
447 sll_int32,
intent(in) :: spline_degree
448 sll_int32,
intent(in) :: smoothing_type
454 select type (smoother)
456 call smoother%init( domain, n_grid, no_particles, spline_degree, smoothing_type)
466 sll_int32,
intent(inout) :: index1d(2)
469 index1d(1) = modulo(index1d(1), self%n_grid(1))
470 index1d(2) = modulo(index1d(2), self%n_grid(2))
471 index2d = index1d(1) + index1d(2)*self%n_grid(1) + 1
Low level arbitrary degree splines.
Base class for kernel smoothers for accumulation and field evaluation in PIC.
integer(kind=i32), parameter, public sll_p_collocation
integer(kind=i32), parameter, public sll_p_galerkin
Kernel smoother for 2d with splines of arbitrary degree placed on a uniform mesh.
subroutine compute_shape_factor_spline_2d(self, position, indices)
Helper function computing shape factor.
subroutine add_particle_mass_spline_2d(self, position, marker_charge, particle_mass)
subroutine evaluate_multiple_spline_2d(self, position, components, field_dofs, field_value)
Evaluate multiple fields at position position.
subroutine evaluate_field_single_spline_pp_2d(self, position, field_dofs_pp, field_value)
Evaluate field at at position position using horner scheme.
subroutine init_spline_2d(self, domain, n_grid, no_particles, spline_degree, smoothing_type)
subroutine add_current_evaluate_spline_2d(self, position_old, position_new, marker_charge, vbar, field_dofs, j_dofs, field)
Add current with integration over x.
subroutine add_current_update_v_spline_pp_2d(self, position_old, position_new, marker_charge, qoverm, bfield_dofs, vi, j_dofs)
Add current and update v for single particle.
subroutine, public sll_s_new_particle_mesh_coupling_spline_2d(smoother, domain, n_grid, no_particles, spline_degree, smoothing_type)
Constructor for abstract type (allocatable)
subroutine evaluate_field_single_spline_2d(self, position, field_dofs, field_value)
Evaluate field with given dofs at position position.
integer(kind=i32) function index_1dto2d_column_major(self, index1d)
subroutine free_spline_2d(self)
Destructor.
subroutine add_current_spline_2d(self, position_old, position_new, marker_charge, j_dofs)
Add current with integration over x.
subroutine, public sll_s_new_particle_mesh_coupling_spline_2d_ptr(smoother, domain, n_grid, no_particles, spline_degree, smoothing_type)
Constructor for abstract type (pointer)
subroutine add_current_update_v_spline_2d(self, position_old, position_new, marker_charge, qoverm, bfield_dofs, vi, j_dofs)
Add current and update v for single particle.
subroutine add_charge_single_spline_2d(self, position, marker_charge, rho_dofs)
Add charge of single particle.
subroutine add_charge_single_spline_pp_2d(self, position, marker_charge, rho_dofs)
Add charge of single particle.
real(kind=f64) function, public sll_f_spline_pp_horner_2d(degree, pp_coeffs, x, indices, n_cells)
Perform a 2d hornerschema on the pp_coeffs at the indices.
subroutine, public sll_s_spline_pp_horner_m_2d(self, val, degree, x)
Perform two times a 1d hornerschema on the poly_coeffs.
subroutine, public sll_s_spline_pp_init_2d(self, degree, n_cells, boundary)
Initialize sll_t_spline_pp_2d object.
subroutine, public sll_s_spline_pp_free_2d(self)
Destructor 2d.
Basic type of a kernel smoother used for PIC simulations.
Spline kernel smoother in 2d.
arbitrary degree 2d spline