11 #include "sll_assert.h"
12 #include "sll_errors.h"
13 #include "sll_memory.h"
14 #include "sll_working_precision.h"
20 sll_s_uniform_bsplines_eval_basis
54 sll_int32,
intent( in ) :: n_cells(3)
55 sll_int32,
intent( in ) :: deg(3)
56 sll_int32,
intent( in ) :: component
60 sll_int32,
optional,
intent( in ) :: n_cells_min(3)
61 sll_int32,
optional,
intent( in ) :: n_cells_max(3)
63 sll_int32 :: i1, i2, i3, ind, k, begin(3), limit(3)
64 sll_int32 :: q(3), start
65 sll_real64 :: mass_line_b( 1:(7*deg(1)**2-deg(1)-2)/2*(2*deg(2)+1)*(2*deg(3)+1))
66 sll_real64 :: mass_line( 1:(2*deg(1)+1)*(2*deg(2)+1)*(2*deg(3)+1))
67 sll_real64,
allocatable :: xw_gauss_d1(:,:), xw_gauss_d2(:,:), xw_gauss_d3(:,:)
68 sll_real64,
allocatable :: bspl_d1(:,:), bspl_d2(:,:), bspl_d3(:,:)
71 allocate( xw_gauss_d1(1:2, 1:q(1)) )
72 allocate( xw_gauss_d2(1:2, 1:q(2)) )
73 allocate( xw_gauss_d3(1:2, 1:q(3)) )
74 allocate( bspl_d1(1:deg(1)+1, 1:q(1)) )
75 allocate( bspl_d2(1:deg(2)+1, 1:q(2)) )
76 allocate( bspl_d3(1:deg(3)+1, 1:q(3)) )
78 if(
present(n_cells_min) .and.
present(n_cells_max) )
then
79 ind=1+((n_cells_min(2)-1)+(n_cells_min(3)-1)*n_cells(2))*&
80 ( ((n_cells(1)-deg(1))*(2*deg(1)+1)+(3*deg(1)**2+deg(1)))*&
81 (2*deg(2)+1)*(2*deg(3)+1) )
98 call sll_s_uniform_bsplines_eval_basis( deg(1), xw_gauss_d1(1,k), bspl_d1(:, k) )
104 call sll_s_uniform_bsplines_eval_basis( deg(2), xw_gauss_d2(1,k), bspl_d2(:,k) )
110 call sll_s_uniform_bsplines_eval_basis( deg(3), xw_gauss_d3(1,k), bspl_d3(:,k) )
114 do i3=begin(3), limit(3)
115 do i2=begin(2), limit(2)
116 call sll_s_spline_fem_mass_line_boundary( q, deg, profile, [1,i2,i3], n_cells, component, mass_line_b, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1, bspl_d2, bspl_d3, spline )
119 mass_line_b=mass_line_b/real(n_cells(1)*n_cells(2)*n_cells(3),f64)
125 sll_assert( ind == start+(7*deg(1)**2-deg(1)-2)/2*(2*deg(2)+1)*(2*deg(3)+1))
126 do i1 = 2*deg(1), n_cells(1)-deg(1)+1
127 call sll_s_spline_fem_mass_line( q, deg, profile, [i1-deg(1),i2,i3], n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1, bspl_d2, bspl_d3 )
129 mass_line=mass_line/real(n_cells(1)*n_cells(2)*n_cells(3),f64)
132 call sll_s_spline_fem_mass_line_boundary( q, deg, profile, [n_cells(1)+1,i2,i3], n_cells, component, mass_line_b, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1, bspl_d2, bspl_d3, spline )
135 mass_line_b=mass_line_b/real(n_cells(1)*n_cells(2)*n_cells(3),f64)
138 do i1= n_cells(1)-deg(1)+2, n_cells(1)+deg(1)
141 sll_assert( ind == start+(7*deg(1)**2-deg(1)-2)/2*(2*deg(2)+1)*(2*deg(3)+1))
148 subroutine sll_s_spline_fem_mass_line_boundary ( q, deg, profile, row, n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1, bspl_d2, bspl_d3, spline )
149 sll_int32,
intent( in ) :: q(3)
150 sll_int32,
intent( in ) :: deg(3)
152 sll_int32,
intent( in ) :: row(3)
153 sll_int32,
intent( in ) :: n_cells(3)
154 sll_int32,
intent( in ) :: component
155 sll_real64,
intent( out ) :: mass_line((7*deg(1)**2-deg(1)-2)/2*(2*deg(2)+1)*(2*deg(3)+1))
157 sll_real64,
intent ( in ) :: xw_gauss_d1(2, q(1)), xw_gauss_d2(2, q(2)), xw_gauss_d3(2, q(3))
158 sll_real64,
intent( in ) :: bspl_d1(deg(1)+1, q(1)), bspl_d2(deg(2)+1, q(2)), bspl_d3(deg(3)+1, q(3))
161 sll_int32 :: int1, int2, int3, j1, j2, j3, k1, k2, k3, interval
163 sll_int32 :: limit(3), ind1(3), ind2(3), ind3(3), ind4(3)
164 sll_real64 :: bspl_b(1:deg(1)+1, 1:q(1),1:2*deg(1)-1)
168 do interval = 1, deg(1)-1
171 bspl_b(j1,k1,interval) =
sll_f_spline_pp_horner_1d( deg(1), spline%poly_coeffs_boundary_left(:,:,interval), xw_gauss_d1(1,k1), j1)
175 do interval = deg(1), 2*deg(1)-1
176 bspl_b(:,:,interval)=bspl_d1
178 if( row(1) < 2*deg(1) )
then
180 else if ( row(1) > n_cells(1) - deg(1)+1 .and. row(1) <= n_cells(1)+deg(1) )
then
185 do j3 = 1, 2*deg(3)+1
196 ind2(3)=deg(3)+1-int3+j3
197 ind3(3)=deg(3)+1-int3
202 ind4(3)=deg(3)+j3-int3
205 do j2 = 1, 2*deg(2)+1
214 do int2= j2, limit(2)
216 ind2(2)=deg(2)+1-int2+j2
217 ind3(2)=deg(2)+1-int2
222 ind4(2)=deg(2)+j2-int2
226 do interval = 1, 2*deg(1)-1
228 do j1 = interval, min(interval+deg(1),2*deg(1)-1)
230 do int1 = interval, deg(1)+interval
231 if(j1 <= deg(1)+1)
then
232 ind1(1) = int1+((j1-1)*(2*deg(1)+j1))/2
233 else if(j1 > deg(1)+1 .and. j1 < 2*deg(1))
then
234 ind1(1) = int1 + (j1-deg(1)-1)*2*deg(1)+(3*deg(1)**2+deg(1))/2
236 ind2(1) = j1-interval+1
237 ind3(1) = int1-interval+1
241 c(3)=(xw_gauss_d3(1,k3)+ real( row(3)-1+ind4(3)-((row(3)-1+ind4(3))/n_cells(3))*n_cells(3),f64 ))/real(n_cells(3),f64)
243 c(2)=(xw_gauss_d2(1,k2)+ real( row(2)-1+ind4(2)-((row(2)-1+ind4(2))/n_cells(2))*n_cells(2),f64 ))/real(n_cells(2),f64)
245 c(1)=(real(ind4(1),f64)*xw_gauss_d1(1,k1)+real(row(1)-1+ind4(1)*(interval-1),f64))/real(n_cells(1),f64)
247 mass_line(ind1(1)+(ind1(2)-1)*(7*deg(1)**2-deg(1)-2)/2+(ind1(3)-1)*(7*deg(1)**2-deg(1)-2)/2*(2*deg(2)+1)) = &
248 mass_line(ind1(1)+(ind1(2)-1)*(7*deg(1)**2-deg(1)-2)/2+(ind1(3)-1)*(7*deg(1)**2-deg(1)-2)/2*(2*deg(2)+1)) + &
249 xw_gauss_d1(2,k1)* xw_gauss_d2(2,k2)* xw_gauss_d3(2,k3) *&
250 bspl_b(ind2(1), k1,interval)*&
251 bspl_d2(ind2(2), k2)*&
252 bspl_d3(ind2(3), k3)*&
253 bspl_b(ind3(1), k1,interval)*&
254 bspl_d2(ind3(2), k2)*&
255 bspl_d3(ind3(3), k3)*&
256 profile( c, [component] )
272 sll_int32,
intent( in ) :: n_cells(3)
273 sll_int32,
intent( in ) :: deg1(3), deg2(3)
274 sll_int32,
intent( in ) :: component(2)
279 sll_int32,
optional,
intent( in ) :: n_cells_min(3)
280 sll_int32,
optional,
intent( in ) :: n_cells_max(3)
282 sll_int32 :: q(3), begin(3), limit(3)
283 sll_int32 :: i1, i2, i3, ind, k, start
284 sll_real64 :: mass_line_b( 1:((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)*(deg1(2)+deg2(2)+1)*(deg1(3)+deg2(3)+1) )
285 sll_real64 :: mass_line( 1:(deg1(1)+deg2(1)+1)*(deg1(2)+deg2(2)+1)*(deg1(3)+deg2(3)+1) )
286 sll_real64,
allocatable :: xw_gauss_d1(:,:), xw_gauss_d2(:,:), xw_gauss_d3(:,:)
287 sll_real64,
allocatable :: bspl_d1a(:,:), bspl_d2a(:,:), bspl_d3a(:,:)
288 sll_real64,
allocatable :: bspl_d1b(:,:), bspl_d2b(:,:), bspl_d3b(:,:)
293 allocate( xw_gauss_d1(1:2, 1:q(1)) )
294 allocate( xw_gauss_d2(1:2, 1:q(2)) )
295 allocate( xw_gauss_d3(1:2, 1:q(3)) )
296 allocate( bspl_d1a(1:deg1(1)+1, 1:q(1)) )
297 allocate( bspl_d2a(1:deg1(2)+1, 1:q(2)) )
298 allocate( bspl_d3a(1:deg1(3)+1, 1:q(3)) )
299 allocate( bspl_d1b(1:deg2(1)+1, 1:q(1)) )
300 allocate( bspl_d2b(1:deg2(2)+1, 1:q(2)) )
301 allocate( bspl_d3b(1:deg2(3)+1, 1:q(3)) )
303 if(
present(n_cells_min) .and.
present(n_cells_max) )
then
304 ind=1+( (n_cells_min(2)-1)+(n_cells_min(3)-1)*n_cells(2) )*&
305 ( ((n_cells(1)-deg1(1))*(deg1(1)+deg2(1)+1)+deg1(1)*(2*deg2(1)+deg1(1)+1))*&
306 (deg1(2)+deg2(2)+1)*(deg1(3)+deg2(3)+1) )
323 call sll_s_uniform_bsplines_eval_basis( deg1(1),xw_gauss_d1(1,k), bspl_d1a(1:deg1(1)+1, k) )
324 call sll_s_uniform_bsplines_eval_basis( deg2(1),xw_gauss_d1(1,k), bspl_d1b(1:deg2(1)+1, k) )
331 call sll_s_uniform_bsplines_eval_basis( deg1(2),xw_gauss_d2(1,k), bspl_d2a(1:deg1(2)+1, k) )
332 call sll_s_uniform_bsplines_eval_basis( deg2(2),xw_gauss_d2(1,k), bspl_d2b(1:deg2(2)+1, k) )
339 call sll_s_uniform_bsplines_eval_basis( deg1(3),xw_gauss_d3(1,k), bspl_d3a(1:deg1(3)+1, k) )
340 call sll_s_uniform_bsplines_eval_basis( deg2(3),xw_gauss_d3(1,k), bspl_d3b(1:deg2(3)+1, k) )
345 do i3=begin(3), limit(3)
346 do i2=begin(2), limit(2)
347 call sll_s_spline_fem_mixedmass_line_boundary( q, deg1, deg2, profile, [1,i2,i3], n_cells, component, mass_line_b, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1a, bspl_d2a, bspl_d3a, bspl_d1b, bspl_d2b, bspl_d3b, spline1, spline2 )
350 mass_line_b=mass_line_b/real(n_cells(1)*n_cells(2)*n_cells(3),f64)
352 do i1=1, deg1(1)+deg2(1)
355 sll_assert( ind == start+((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)*(deg1(2)+deg2(2)+1)*(deg1(3)+deg2(3)+1) )
356 do i1=deg1(1)+deg2(1)+1, n_cells(1)-deg2(1)
357 call sll_s_spline_fem_mixedmass_line( q, deg1, deg2, profile, [i1-deg1(1),i2,i3], n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1a, bspl_d2a, bspl_d3a, bspl_d1b, bspl_d2b, bspl_d3b )
359 mass_line=mass_line/real(n_cells(1)*n_cells(2)*n_cells(3),f64)
362 call sll_s_spline_fem_mixedmass_line_boundary( q, deg1, deg2, profile, [n_cells(1)+1,i2,i3], n_cells, component, mass_line_b, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1a, bspl_d2a, bspl_d3a, bspl_d1b, bspl_d2b, bspl_d3b, spline1, spline2 )
365 mass_line_b=mass_line_b/real(n_cells(1)*n_cells(2)*n_cells(3),f64)
367 do i1 = n_cells(1)-deg2(1)+1, n_cells(1)+deg1(1)
370 sll_assert( ind == start+((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)*(deg1(2)+deg2(2)+1)*(deg1(3)+deg2(3)+1) )
374 deallocate( xw_gauss_d1 )
375 deallocate( xw_gauss_d2 )
376 deallocate( xw_gauss_d3 )
377 deallocate( bspl_d1a )
378 deallocate( bspl_d2a )
379 deallocate( bspl_d3a )
380 deallocate( bspl_d1b )
381 deallocate( bspl_d2b )
382 deallocate( bspl_d3b )
388 subroutine sll_s_spline_fem_mixedmass_line_boundary( q, deg1, deg2, profile, row, n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1a, bspl_d2a, bspl_d3a, bspl_d1b, bspl_d2b, bspl_d3b, spline1, spline2 )
389 sll_int32,
intent( in ) :: q(3)
390 sll_int32,
intent( in ) :: deg1(3), deg2(3)
392 sll_int32,
intent( in ) :: row(3)
393 sll_int32,
intent( in ) :: n_cells(3)
394 sll_int32,
intent( in ) :: component(2)
395 sll_real64,
intent( out ) :: mass_line( 1:((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)*(deg1(2)+deg2(2)+1)*(deg1(3)+deg2(3)+1) )
396 sll_real64,
intent( in ) :: xw_gauss_d1(2, q(1)), xw_gauss_d2(2, q(2)), xw_gauss_d3(2, q(3))
397 sll_real64,
intent( in ) :: bspl_d1a(deg1(1)+1, q(1)), bspl_d2a(deg1(2)+1, q(2)), bspl_d3a(deg1(3)+1, q(3))
398 sll_real64,
intent( in ) :: bspl_d1b(deg2(1)+1, q(1)), bspl_d2b(deg2(2)+1, q(2)), bspl_d3b(deg2(3)+1, q(3))
402 sll_int32 :: int1, int2, int3, j1, j2, j3, k1, k2, k3, interval
404 sll_int32 :: limit(3), ind1(3), ind2(3), ind3(3), ind4(3)
405 sll_real64 :: bspl_b1(1:deg1(1)+1, 1:q(1),1:deg1(1)+deg2(1))
406 sll_real64 :: bspl_b2(1:deg2(1)+1, 1:q(1),1:deg1(1)+deg2(1))
410 do interval = 1, deg1(1)-1
413 bspl_b1(j1,k1,interval) =
sll_f_spline_pp_horner_1d( deg1(1), spline1%poly_coeffs_boundary_left(:,:,interval), xw_gauss_d1(1,k1), j1)
417 if( deg1(1) == 0 )
then
418 do interval = 1, deg2(1)
419 bspl_b1(:,:,interval)=bspl_d1a
422 do interval = deg1(1), deg1(1)+deg2(1)
423 bspl_b1(:,:,interval)=bspl_d1a
427 do interval = 1, deg2(1)-1
430 bspl_b2(j1,k1,interval) =
sll_f_spline_pp_horner_1d( deg2(1), spline2%poly_coeffs_boundary_left(:,:,interval), xw_gauss_d1(1,k1), j1)
434 if( deg2(1) == 0 )
then
435 do interval = 1, deg1(1)
436 bspl_b2(:,:,interval)=bspl_d1b
439 do interval = deg2(1), deg1(1)+deg2(1)
440 bspl_b2(:,:,interval)=bspl_d1b
444 if( row(1) <= deg1(1)+deg2(1) )
then
446 else if ( row(1) > n_cells(1) - deg2(1) .and. row(1) <= n_cells(1)+deg1(1) )
then
452 do j3 = 1, deg1(3)+deg2(3)+1
457 limit(3)=deg1(3)+deg2(3)+1
461 do int3=j3, min(limit(3),j3+deg2(3))
463 ind2(3)=deg1(3)+1-int3+j3
464 ind3(3)=deg2(3)+1-int3
467 ind2(3)=limit(3)-int3+1
468 ind3(3)=deg2(3)+1-int3+j3
469 ind4(3)=int3-deg2(3)-1
472 do j2 = 1, deg1(2)+deg2(2)+1
477 limit(2)=deg1(2)+deg2(2)+1
481 do int2=j2, min(limit(2),j2+deg2(2))
483 ind2(2)=deg1(2)+1-int2+j2
484 ind3(2)=deg2(2)+1-int2
487 ind2(2)=limit(2)-int2+1
488 ind3(2)=deg2(2)+1-int2+j2
489 ind4(2)=int2-deg2(2)-1
493 do interval = 1, deg1(1)+deg2(1)
495 do j1 = interval, min(interval+deg1(1),deg1(1)+deg2(1))
497 do int1 = interval, deg2(1)+interval
498 if(j1 <= deg1(1)+1)
then
499 ind1(1) = int1 + ((j1-1)*(2*deg2(1)+j1))/2
500 else if(j1 > deg1(1)+1 .and. j1 <= deg1(1)+deg2(1))
then
501 ind1(1) = int1 + (j1-deg1(1)-1)*(deg1(1)+deg2(1)) + (deg1(1)*(2*deg2(1)+deg1(1)+1))/2
503 ind2(1) = j1-interval+1
504 ind3(1) = int1-interval+1
507 c(3)=(xw_gauss_d3(1,k3)+ real( row(3)-1+ind4(3)-((row(3)-1+ind4(3))/n_cells(3))*n_cells(3),f64 ))/real(n_cells(3),f64)
509 c(2)=(xw_gauss_d2(1,k2)+ real( row(2)-1+ind4(2)-((row(2)-1+ind4(2))/n_cells(2))*n_cells(2),f64 ))/real(n_cells(2),f64)
511 c(1)=(real(ind4(1),f64)*xw_gauss_d1(1,k1)+real(row(1)-1+ind4(1)*(interval-1),f64))/real(n_cells(1),f64)
513 mass_line(ind1(1)+(ind1(2)-1)*((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)+(ind1(3)-1)*((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)*(deg1(2)+deg2(2)+1)) = &
514 mass_line(ind1(1)+(ind1(2)-1)*((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)+(ind1(3)-1)*((deg1(1)+deg2(1))**2+(2*deg2(1)+deg1(1)-deg1(1)**2)/2)*(deg1(2)+deg2(2)+1)) + &
515 xw_gauss_d1(2,k1)* xw_gauss_d2(2,k2)* xw_gauss_d3(2,k3) *&
516 bspl_b1(ind2(1), k1,interval)*&
517 bspl_d2a(ind2(2), k2)*&
518 bspl_d3a(ind2(3), k3)*&
519 bspl_b2(ind3(1), k1,interval)*&
520 bspl_d2b(ind3(2), k2)*&
521 bspl_d3b(ind3(3), k3)*&
522 profile( c, component )
539 sll_int32,
intent( in ) :: n_dofs(3)
540 sll_real64,
intent( in ) :: delta_x(3)
541 sll_int32,
intent( in ) :: s_deg_0(3)
542 sll_real64,
intent( in ) :: field_in(:)
543 sll_real64,
intent( out ) :: field_out(:)
546 sll_int32 :: stride, stride_end
547 sll_int32 :: ind3d, ind1d
550 coef = 1.0_f64/ delta_x(1)
558 field_out(ind3d) = real(s_deg_0(1),f64)*coef*( field_in(ind1d+1) )
559 do i = 2, s_deg_0(1)-1
562 field_out(ind3d) = real(s_deg_0(1),f64)/real(i,f64)*coef*( field_in(ind1d+1) - field_in(ind1d) )
564 do i = s_deg_0(1), n_dofs(1)-s_deg_0(1)
567 field_out(ind3d) = coef*( field_in(ind1d+1) - field_in(ind1d) )
569 do i = n_dofs(1)-s_deg_0(1)+1, n_dofs(1)-2
572 field_out(ind3d) = real(s_deg_0(1),f64)/real(n_dofs(1)-i,f64)*coef*( field_in(ind1d+1) - field_in(ind1d) )
576 field_out(ind3d) = real(s_deg_0(1),f64)*coef*( - field_in(ind1d) )
581 coef = 1.0_f64/ delta_x(2)
583 stride_end = (1-n_dofs(2))*n_dofs(1)
589 field_out(ind3d) = 0._f64
590 do i = 2, n_dofs(1)-1
593 field_out(ind3d) = coef * ( field_in(ind1d) - field_in(ind1d-stride_end) )
597 field_out(ind3d) = 0._f64
602 field_out(ind3d) = 0._f64
603 do i = 2, n_dofs(1)-1
606 field_out(ind3d) = coef * ( field_in(ind1d) - field_in(ind1d-stride) )
610 field_out(ind3d) = 0._f64
614 coef = 1.0_f64/ delta_x(3)
615 stride = n_dofs(1)*n_dofs(2)
616 stride_end = (1-n_dofs(3))*n_dofs(1)*n_dofs(2)
622 field_out(ind3d) = 0._f64
623 do i = 2, n_dofs(1)-1
626 field_out(ind3d) = coef * ( field_in(ind1d) - field_in(ind1d-stride_end) )
630 field_out(ind3d) = 0._f64
636 field_out(ind3d) = 0._f64
637 do i = 2, n_dofs(1)-1
640 field_out(ind3d) = coef * ( field_in(ind1d) - field_in(ind1d-stride) )
644 field_out(ind3d) = 0._f64
653 sll_int32,
intent( in ) :: n_dofs(3)
654 sll_real64,
intent( in ) :: delta_x(3)
655 sll_int32,
intent( in ) :: s_deg_0(3)
656 sll_real64,
intent( in ) :: field_in(:)
657 sll_real64,
intent( out ) :: field_out(:)
660 sll_int32 :: stride, stride_end
661 sll_int32 :: ind3d, ind1d
665 coef = 1.0_f64/ delta_x(1)
673 field_out(ind1d) = 0._f64
677 field_out(ind1d) = real(s_deg_0(1),f64)*coef*( field_in(ind3d-1)/real(i-1,f64) - field_in(ind3d)/real(i,f64) )
679 do i = s_deg_0(1)+1, n_dofs(1)-s_deg_0(1)
682 field_out(ind1d) = coef*( field_in(ind3d-1) - field_in(ind3d) )
684 do i = n_dofs(1)-s_deg_0(1)+1, n_dofs(1)-1
687 field_out(ind1d) = real(s_deg_0(1),f64)*coef*( field_in(ind3d-1)/real(n_dofs(1)+1-i,f64) - field_in(ind3d)/real(n_dofs(1)-i,f64) )
691 field_out(ind1d) = 0._f64
697 coef = 1.0_f64/ delta_x(2)
699 stride_end = (1-n_dofs(2))*n_dofs(1)
703 do j = 1, n_dofs(2)-1
706 field_out(ind1d) = 0._f64
707 do i = 2, n_dofs(1)-1
711 field_out(ind1d) = field_out(ind1d) + &
712 coef * ( field_in(ind3d) - field_in(ind3d+stride) )
717 field_out(ind1d) = 0._f64
721 field_out(ind1d) = 0._f64
726 field_out(ind1d) = field_out(ind1d) + &
727 coef * ( field_in(ind3d) - field_in(ind3d+stride_end) )
732 field_out(ind1d) = 0._f64
734 coef = 1.0_f64/ delta_x(3)
735 stride = n_dofs(1)*n_dofs(2)
736 stride_end = (1-n_dofs(3))*n_dofs(1)*n_dofs(2)
739 do k = 1, n_dofs(3)-1
743 field_out(ind1d) = 0._f64
744 do i = 2, n_dofs(1)-1
748 field_out(ind1d) = field_out(ind1d) + &
749 coef * ( field_in(ind3d) - field_in(ind3d+stride) )
753 field_out(ind1d) = 0._f64
759 field_out(ind1d) = 0._f64
760 do i = 2, n_dofs(1)-1
764 field_out(ind1d) = field_out(ind1d) + &
765 coef * ( field_in(ind3d) - field_in(ind3d+stride_end) )
769 field_out(ind1d) = 0._f64
777 sll_int32,
intent( in ) :: n_dofs(3)
778 sll_real64,
intent( in ) :: delta_x(3)
779 sll_int32,
intent( in ) :: s_deg_0(3)
780 sll_real64,
intent( in ) :: field_in(:)
781 sll_real64,
intent( out ) :: field_out(:)
783 sll_real64 :: coef(2)
784 sll_int32 :: stride(2), jump(2), indp(2), n_total0, n_total1
785 sll_int32 :: i,j,k, ind3d, ind3d_1, ind3d_2, ind
787 n_total0 = product(n_dofs)
788 n_total1 = (n_dofs(1)-1)*n_dofs(2)*n_dofs(3)
792 coef(1) = 1.0_f64/ delta_x(2)
793 coef(2) = -1.0_f64/ delta_x(3)
795 stride(1) = n_dofs(1)
796 stride(2) = n_dofs(1)*n_dofs(2)
798 jump(1) = n_total1+n_total0
805 indp(2) = stride(2)*(n_dofs(3)-1)
807 indp(2) = - stride(2)
811 indp(1) = stride(1)*(n_dofs(2)-1)
813 indp(1) = - stride(1)
816 field_out(ind3d) = 0._f64
817 do i = 2, n_dofs(1)-1
820 ind3d_1 = ind3d +indp(1)+jump(1)
821 ind3d_2 = ind3d +indp(2)+jump(2)
824 coef(1) * ( field_in( ind3d+jump(1) ) -&
825 field_in( ind3d_1 )) + &
826 coef(2) * ( field_in(ind3d+jump(2) ) - &
831 field_out(ind3d) = 0._f64
837 coef(1) = 1.0_f64/ delta_x(3)
838 coef(2) = -1.0_f64/ delta_x(1)
840 stride(1) = (n_dofs(1)-1)*n_dofs(2)
849 indp(1) = stride(1)*(n_dofs(3)-1)
851 indp(1) = - stride(1)
856 ind3d_1 = ind3d +indp(1)+jump(1)
857 ind3d_2 = ind -stride(2)+jump(2)
860 coef(1) * ( field_in( ind3d+jump(1) ) -&
861 field_in( ind3d_1 ) )+ &
862 real(s_deg_0(1),f64)*coef(2)* &
863 ( field_in(ind+jump(2)+1 ) )
864 do i = 2, s_deg_0(1)-1
867 ind3d_1 = ind3d +indp(1)+jump(1)
868 ind3d_2 = ind -stride(2)+jump(2)
871 coef(1) * ( field_in( ind3d+jump(1) ) -&
872 field_in( ind3d_1 ) )+ &
873 real(s_deg_0(1),f64)/
real(i,f64)*coef(2)* &
874 ( field_in(ind+jump(2)+1 ) - &
875 field_in( ind3d_2+1 ) )
877 do i = s_deg_0(1), n_dofs(1)-s_deg_0(1)
880 ind3d_1 = ind3d +indp(1)+jump(1)
881 ind3d_2 = ind -stride(2)+jump(2)
884 coef(1) * ( field_in( ind3d+jump(1) ) -&
885 field_in( ind3d_1 ) )+ &
886 coef(2) * ( field_in(ind+jump(2)+1 ) - &
887 field_in( ind3d_2+1 ) )
889 do i = n_dofs(1)-s_deg_0(1)+1, n_dofs(1)-2
892 ind3d_1 = ind3d +indp(1)+jump(1)
893 ind3d_2 = ind -stride(2)+jump(2)
896 coef(1) * ( field_in( ind3d+jump(1) ) -&
897 field_in( ind3d_1 ) )+ &
898 real(s_deg_0(1),f64)/
real(n_dofs(1)-i,f64) * &
899 coef(2) * ( field_in(ind+jump(2)+1 ) - &
900 field_in( ind3d_2+1 ) )
904 ind3d_1 = ind3d +indp(1)+jump(1)
905 ind3d_2 = ind -stride(2)+jump(2)
908 coef(1) * ( field_in( ind3d+jump(1) ) -&
909 field_in( ind3d_1 ) )+ &
910 real(s_deg_0(1),f64) * &
911 coef(2) * ( - field_in( ind3d_2+1 ) )
917 coef(1) = 1.0_f64/ delta_x(1)
918 coef(2) = -1.0_f64/ delta_x(2)
921 stride(2) = n_dofs(1)-1
924 jump(2) = -(n_total0+n_total1)
931 indp(2) = stride(2)*(n_dofs(2)-1)
933 indp(2) = - stride(2)
937 ind3d_1 = ind -stride(1)+jump(1)
938 ind3d_2 = ind3d +indp(2)+jump(2)
941 real(s_deg_0(1),f64) * &
942 coef(1) * ( field_in( ind+jump(1)+1 ) )+ &
943 coef(2)*( field_in(ind3d+jump(2) ) - &
944 field_in( ind3d_2 ) )
945 do i = 2, s_deg_0(1)-1
948 ind3d_1 = ind -stride(1)+jump(1)
949 ind3d_2 = ind3d +indp(2)+jump(2)
952 real(s_deg_0(1),f64)/
real(i,f64) * &
953 coef(1) * ( field_in( ind+jump(1)+1 ) -&
954 field_in( ind3d_1+1 ) )+ &
955 coef(2)*( field_in(ind3d+jump(2) ) - &
956 field_in( ind3d_2 ) )
958 do i = s_deg_0(1), n_dofs(1)-s_deg_0(1)
961 ind3d_1 = ind -stride(1)+jump(1)
962 ind3d_2 = ind3d +indp(2)+jump(2)
965 coef(1) * ( field_in( ind+jump(1)+1 ) -&
966 field_in( ind3d_1+1 ) )+ &
967 coef(2) * ( field_in(ind3d+jump(2) ) - &
968 field_in( ind3d_2 ) )
970 do i = n_dofs(1)-s_deg_0(1)+1, n_dofs(1)-2
973 ind3d_1 = ind -stride(1)+jump(1)
974 ind3d_2 = ind3d +indp(2)+jump(2)
977 real(s_deg_0(1),f64)/
real(n_dofs(1)-i,f64) * &
978 coef(1) * ( field_in( ind+jump(1)+1 ) -&
979 field_in( ind3d_1+1 ) )+ &
980 coef(2) * ( field_in(ind3d+jump(2) ) - &
981 field_in( ind3d_2 ) )
985 ind3d_1 = ind -stride(1)+jump(1)
986 ind3d_2 = ind3d +indp(2)+jump(2)
989 real(s_deg_0(1),f64) * &
990 coef(1) * ( - field_in( ind3d_1+1 ) )+ &
991 coef(2) * ( field_in(ind3d+jump(2) ) - &
992 field_in( ind3d_2 ) )
1003 sll_int32,
intent( in ) :: n_dofs(3)
1004 sll_real64,
intent( in ) :: delta_x(3)
1005 sll_int32,
intent( in ) :: s_deg_0(3)
1006 sll_real64,
intent( in ) :: field_in(:)
1007 sll_real64,
intent( out ) :: field_out(:)
1009 sll_real64 :: coef(2)
1010 sll_int32 :: stride(2), jump(2), indp(2), n_total0, n_total1
1011 sll_int32 :: i,j,k, ind3d, ind3d_1, ind3d_2, ind
1013 n_total0 = product(n_dofs)
1014 n_total1 = (n_dofs(1)-1)*n_dofs(2)*n_dofs(3)
1018 coef(1) = -1.0_f64/ delta_x(2)
1019 coef(2) = 1.0_f64/ delta_x(3)
1021 stride(1) = n_dofs(1)-1
1022 stride(2) = (n_dofs(1)-1)*n_dofs(2)
1025 jump(2) = n_total0+n_total1
1030 if (k == n_dofs(3))
then
1031 indp(2) = -stride(2)*(n_dofs(3)-1)
1036 if ( j== n_dofs(2))
then
1037 indp(1) = -stride(1)*(n_dofs(2)-1)
1041 do i = 1, n_dofs(1)-1
1044 ind3d_1 = ind3d +indp(1)+jump(2)
1045 ind3d_2 = ind3d +indp(2)+jump(1)
1047 field_out(ind3d) = &
1048 coef(1) * ( field_in( ind3d+jump(2) ) -&
1049 field_in( ind3d_1 )) + &
1050 coef(2) * ( field_in(ind3d+jump(1) ) - &
1051 field_in( ind3d_2 ))
1059 coef(1) = -1.0_f64/ delta_x(3)
1060 coef(2) = 1.0_f64/ delta_x(1)
1062 stride(1) = n_dofs(1)*n_dofs(2)
1071 if (k == n_dofs(3))
then
1072 indp(1) = -stride(1)*(n_dofs(3)-1)
1079 ind3d_1 = ind3d +indp(1)+jump(2)
1081 field_out(ind3d) = 0._f64
1086 do i = 2, s_deg_0(1)
1089 ind3d_1 = ind3d +indp(1)+jump(2)
1090 ind3d_2 = ind -stride(2)+jump(1)
1091 field_out(ind3d) = &
1092 coef(1) * ( field_in( ind3d+jump(2) ) -&
1093 field_in( ind3d_1 ) )+ &
1094 real(s_deg_0(1),f64)*coef(2) * &
1095 ( field_in( ind3d_2 )/
real(i-1,f64) - &
1096 field_in( ind+jump(1) )/
real(i,f64) )
1098 do i= s_deg_0(1)+1, n_dofs(1)-s_deg_0(1)
1101 ind3d_1 = ind3d +indp(1)+jump(2)
1102 ind3d_2 = ind -stride(2)+jump(1)
1104 field_out(ind3d) = &
1105 coef(1) * ( field_in( ind3d+jump(2) ) -&
1106 field_in( ind3d_1 ) )+ &
1107 coef(2) * ( field_in(ind3d_2 ) - &
1108 field_in( ind+jump(1) ))
1110 do i = n_dofs(1)-s_deg_0(1)+1, n_dofs(1)-1
1113 ind3d_1 = ind3d +indp(1)+jump(2)
1114 ind3d_2 = ind -stride(2)+jump(1)
1116 field_out(ind3d) = &
1117 coef(1) * ( field_in( ind3d+jump(2) ) -&
1118 field_in( ind3d_1 ) )+ &
1119 real(s_deg_0(1),f64)*coef(2) * &
1120 ( field_in(ind3d_2 )/
real(n_dofs(1)+1-i,f64) - &
1121 field_in( ind+jump(1) )/
real(n_dofs(1)-i,f64) )
1125 ind3d_1 = ind3d +indp(1)+jump(2)
1126 ind3d_2 = ind -stride(2)+jump(1)
1127 field_out(ind3d) = 0._f64
1137 coef(1) = -1.0_f64/ delta_x(1)
1138 coef(2) = 1.0_f64/ delta_x(2)
1141 stride(2) = n_dofs(1)
1143 jump(1) = -(n_total1+n_total0)
1149 if (j == n_dofs(2))
then
1150 indp(2) = -stride(2)*(n_dofs(2)-1)
1156 ind3d_2 = ind3d +indp(2)+jump(1)
1158 field_out(ind3d) = 0._f64
1163 do i = 2, s_deg_0(1)
1166 ind3d_1 = ind -stride(1)+jump(2)
1167 ind3d_2 = ind3d +indp(2)+jump(1)
1169 field_out(ind3d) = &
1170 real(s_deg_0(1),f64) * coef(1) * &
1171 ( field_in( ind3d_1 )/
real(i-1,f64) -&
1172 field_in( ind+jump(2) )/
real(i,f64) )+ &
1173 coef(2) * ( field_in(ind3d+jump(1) ) - &
1174 field_in( ind3d_2 ))
1176 do i = s_deg_0(1)+1, n_dofs(1)-s_deg_0(1)
1179 ind3d_1 = ind -stride(1)+jump(2)
1180 ind3d_2 = ind3d +indp(2)+jump(1)
1182 field_out(ind3d) = &
1183 coef(1) * ( field_in( ind3d_1 ) -&
1184 field_in( ind+jump(2)) )+ &
1185 coef(2) * ( field_in(ind3d+jump(1) ) - &
1186 field_in( ind3d_2 ))
1189 do i = n_dofs(1)-s_deg_0(1)+1, n_dofs(1)-1
1192 ind3d_1 = ind -stride(1)+jump(2)
1193 ind3d_2 = ind3d +indp(2)+jump(1)
1195 field_out(ind3d) = &
1196 real(s_deg_0(1),f64) * coef(1) * &
1197 ( field_in( ind3d_1 )/
real(n_dofs(1)+1-i,f64) -&
1198 field_in( ind+jump(2) )/
real(n_dofs(1)-i,f64) )+ &
1199 coef(2) * ( field_in(ind3d+jump(1) ) - &
1200 field_in( ind3d_2 ))
1204 ind3d_1 = ind -stride(1)+jump(2)
1205 ind3d_2 = ind3d +indp(2)+jump(1)
1207 field_out(ind3d) = 0._f64
1221 sll_int32,
intent( in ) :: n_dofs
1222 sll_real64,
intent( in ) :: delta_x
1223 sll_int32,
intent( in ) :: s_deg_0
1224 sll_real64,
intent( in ) :: in(:)
1225 sll_real64,
intent( out ) :: out(:)
1229 out(1) = real(s_deg_0,f64)*( in(2) )/delta_x
1231 out(i) = real(s_deg_0,f64)*( in(i+1) - in(i) )/(real(i,f64)*delta_x)
1233 do i = s_deg_0, n_dofs-s_deg_0
1234 out(i) = ( in(i+1) - in(i) )/delta_x
1236 do i = n_dofs-s_deg_0+1, n_dofs-2
1237 out(i) = real(s_deg_0,f64)*( in(i+1) - in(i) )/(real(n_dofs-i,f64)*delta_x)
1239 out( n_dofs-1) = real(s_deg_0,f64)*( - in( n_dofs-1) )/delta_x
1245 sll_int32,
intent( in ) :: n_dofs
1246 sll_real64,
intent( in ) :: delta_x
1247 sll_int32,
intent( in ) :: s_deg_0
1248 sll_real64,
intent( in ) :: in(:)
1249 sll_real64,
intent( out ) :: out(:)
1255 out(i) = real(s_deg_0,f64)*( in(i-1)/real(i-1,f64) - in(i)/real(i,f64) )/delta_x
1257 do i = s_deg_0+1, n_dofs-s_deg_0
1258 out(i) = ( in(i-1) - in(i) )/delta_x
1260 do i = n_dofs-s_deg_0+1, n_dofs-1
1261 out(i) = real(s_deg_0,f64)*( in(i-1)/real(n_dofs+1-i,f64) - in(i)/real(n_dofs-i,f64) )/delta_x
1263 out(n_dofs) = 0._f64
Gauss-Legendre integration.
real(kind=f64) function, dimension(2, 1:npoints), public sll_f_gauss_legendre_points_and_weights(npoints, a, b)
Returns a 2d array of size (2,npoints) containing gauss-legendre points and weights in the interval [...
Low level arbitrary degree splines.
Module interfaces for coordinate transformation.
module for Compressed Sparse Row Matrix (CSR)
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_spline_fem_mixedmass3d_clamped(n_cells, deg1, deg2, component, matrix, profile, spline1, spline2, n_cells_min, n_cells_max)
Set up 3d clamped mixed mass matrix for specific spline degree and profile function.
subroutine, public sll_s_spline_fem_mass3d_clamped(n_cells, deg, component, matrix, profile, spline, n_cells_min, n_cells_max)
Set up 3d clamped mass matrix for specific spline degrees and profile function.
subroutine sll_s_spline_fem_mass_line_boundary(q, deg, profile, row, n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1, bspl_d2, bspl_d3, spline)
subroutine, public sll_s_multiply_g_clamped(n_dofs, delta_x, s_deg_0, field_in, field_out)
Multiply by dicrete gradient matrix.
subroutine, public sll_s_multiply_gt_clamped_1d(n_dofs, delta_x, s_deg_0, in, out)
Multiplication of the input vector in by the transposed clamped derivative matrix G^T.
subroutine, public sll_s_multiply_c_clamped(n_dofs, delta_x, s_deg_0, field_in, field_out)
Multiply by discrete curl matrix.
subroutine, public sll_s_multiply_gt_clamped(n_dofs, delta_x, s_deg_0, field_in, field_out)
Multiply by transpose of dicrete gradient matrix.
subroutine sll_s_spline_fem_mixedmass_line_boundary(q, deg1, deg2, profile, row, n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1a, bspl_d2a, bspl_d3a, bspl_d1b, bspl_d2b, bspl_d3b, spline1, spline2)
Computes the mixed mass line for a mass matrix with degree splines.
subroutine, public sll_s_multiply_g_clamped_1d(n_dofs, delta_x, s_deg_0, in, out)
Multiplication of the input vector in by the clamped derivative matrix G.
Helper for spline finite elements utilites.
subroutine, public assemble_mixedmass3d_clamped(deg1, deg2, n_cells, mass_line, matrix, row, ind)
Assemble the given row of the clamped mixed mass matrix.
subroutine, public sll_s_spline_fem_sparsity_mixedmass3d_clamped(deg1, deg2, n_cells, spmat)
Helper function to create sparsity pattern of the 3d clamped mixed mass matrix.
subroutine, public assemble_mass3d_clamped_boundary(deg, n_cells, mass_line, matrix, row, ind)
Assemble the boundary part of the clamped mass matrix.
subroutine, public assemble_mass3d_clamped(deg, n_cells, mass_line, matrix, row, ind)
Assemble the given row of the clamped mass matrix.
subroutine, public assemble_mixedmass3d_clamped_boundary(deg1, deg2, n_cells, mass_line, matrix, row, ind)
Assemble the boundary part of the clamped mixed mass matrix.
subroutine, public sll_s_spline_fem_sparsity_mass3d_clamped(deg, n_cells, spmat)
Helper function to create sparsity pattern of the 3d clamped mass matrix.
Utilites for 3D Maxwell solvers with spline finite elements.
subroutine, public sll_s_spline_fem_mixedmass_line(q, deg1, deg2, profile, row, n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1a, bspl_d2a, bspl_d3a, bspl_d1b, bspl_d2b, bspl_d3b)
subroutine, public sll_s_spline_fem_mass_line(q, deg, profile, row, n_cells, component, mass_line, xw_gauss_d1, xw_gauss_d2, xw_gauss_d3, bspl_d1, bspl_d2, bspl_d3)
Computes the mass line for a mass matrix with degree splines.
real(kind=f64) function, public sll_f_spline_pp_horner_1d(degree, pp_coeffs, x, index)
Perform a 1d hornerschema on the pp_coeffs at index.
type collecting functions for analytical coordinate mapping
arbitrary degree 1d spline