8 #include "sll_assert.h"
9 #include "sll_memory.h"
10 #include "sll_working_precision.h"
38 sll_real64,
dimension(:),
pointer :: node_positions
40 sll_real64,
dimension(:),
pointer :: buf
42 sll_int32,
dimension(:),
pointer :: ibuf
43 sll_int32 :: size_ibuf
44 sll_real64,
dimension(:),
pointer :: coeffs
67 sll_int32,
intent(in) :: n_cells
68 sll_int32,
intent(in) :: bc_type
80 sll_int32,
intent(in) :: n_cells
81 sll_int32,
intent(in) :: bc_type
82 sll_int32 :: ierr, size_buf, size_ibuf
84 self%n_cells = n_cells
85 self%bc_type = bc_type
87 sll_allocate(self%node_positions(-2:n_cells + 2), ierr)
88 size_buf = 10*(n_cells + 1)
89 size_ibuf = n_cells + 1
90 self%size_buf = size_buf
91 sll_allocate(self%buf(size_buf), ierr)
92 self%size_ibuf = size_ibuf
93 sll_allocate(self%ibuf(size_ibuf), ierr)
94 sll_allocate(self%coeffs(-1:n_cells + 1), ierr)
95 self%is_setup = .false.
96 self%slope_L = 0.0_f64
97 self%slope_R = 0.0_f64
105 sll_assert(
associated(spline))
106 sll_deallocate(spline%node_positions, ierr)
107 sll_deallocate(spline%buf, ierr)
108 sll_deallocate(spline%coeffs, ierr)
109 sll_deallocate(spline%ibuf, ierr)
110 sll_deallocate(spline, ierr)
115 sll_real64,
dimension(:),
intent(in) :: f
117 sll_real64,
dimension(:),
intent(in),
optional :: node_positions
118 sll_real64,
intent(in),
optional :: sl
119 sll_real64,
intent(in),
optional :: sr
120 sll_int32 ::n_cells, bc_type
121 sll_real64,
dimension(:),
pointer :: node_pos
125 sll_assert(
associated(spline))
126 n_cells = spline%n_cells
127 bc_type = spline%bc_type
130 if (
present(node_positions))
then
131 node_pos => spline%node_positions
132 spline%xmin = node_positions(1)
133 spline%xmax = node_positions(n_cells + 1)
134 length = spline%xmax - spline%xmin
135 node_pos(1:n_cells - 1) = (node_positions(2:n_cells) - node_positions(1))/length
136 node_pos(0) = 0.0_f64
137 node_pos(n_cells) = 1.0_f64
138 select case (bc_type)
139 case (sll_p_periodic)
144 print *,
'ERROR: compute_spline_nonunif_1D(): not recognized boundary condition'
147 spline%is_setup = .true.
150 if (.not. (spline%is_setup))
then
152 print *,
'ERROR: compute_spline_nonunif_1D_periodic(): '
153 print *,
'node_positions are to be given first'
157 select case (bc_type)
158 case (sll_p_periodic)
161 if (
present(sl))
then
164 if (
present(sr))
then
169 print *,
'ERROR: compute_spline_nonunif_1D(): not recognized boundary condition'
176 sll_real64,
dimension(:),
intent(in),
target :: f
178 sll_real64,
dimension(:),
pointer :: buf, fp, coeffs
179 sll_int32,
dimension(:),
pointer :: ibuf
181 if (.not.
associated(spline))
then
183 print *,
'ERROR: compute_spline_nonunif_1D_periodic(): ', &
184 'uninitialized spline object passed as argument. Exiting... '
187 if (.not. (
size(f) .ge. spline%n_cells + 1))
then
189 print *,
'ERROR: compute_spline_nonunif_1D_periodic(): '
190 write (*,
'(a, i8, a, i8)')
'spline object needs data of size >= ', &
191 spline%n_cells + 1,
' . Passed size: ',
size(f)
199 coeffs => spline%coeffs
205 sll_real64,
dimension(:),
intent(in),
target :: f
207 sll_real64,
dimension(:),
pointer :: buf, fp, coeffs
208 sll_int32,
dimension(:),
pointer :: ibuf
210 sll_real64 :: lift(4, 2)
211 if (.not.
associated(spline))
then
213 print *,
'ERROR: compute_spline_nonunif_1D_hermite(): ', &
214 'uninitialized spline object passed as argument. Exiting... '
217 if (.not. (
size(f) .ge. spline%n_cells + 1))
then
219 print *,
'ERROR: compute_spline_nonunif_1D_hermite(): '
220 write (*,
'(a, i8, a, i8)')
'spline object needs data of size >= ', &
221 spline%n_cells + 1,
' . Passed size: ',
size(f)
229 coeffs => spline%coeffs
236 lift(1, 1) = 1._f64/3._f64*(spline%node_positions(1) - spline%node_positions(0))*spline%slope_L
237 lift(1, 2) = -1._f64/3._f64*(spline%node_positions(nc) - spline%node_positions(nc - 1))*spline%slope_R
238 lift(2, 1) = -1._f64/3._f64*(spline%node_positions(1) - spline%node_positions(-1))&
239 &*(spline%node_positions(1) - spline%node_positions(-2))/(spline%node_positions(1) - spline%node_positions(0))*spline%slope_L
240 lift(2, 2) = 1._f64/3._f64*(spline%node_positions(nc + 1) - spline%node_positions(nc - 1))&
241 &*(spline%node_positions(nc+2)-spline%node_positions(nc-1))/(spline%node_positions(nc)-spline%node_positions(nc-1))*spline%slope_R
243 lift(1:2, 1:2) = lift(1:2, 1:2)*(spline%xmax - spline%xmin)
245 lift(3, 1) = (spline%node_positions(2) - spline%node_positions(0))*(spline%node_positions(1) - spline%node_positions(0))
246 lift(3,1) = lift(3,1)-(spline%node_positions(0)-spline%node_positions(-1))*(spline%node_positions(0)-spline%node_positions(-2))
247 lift(3,1) = lift(3,1)/((spline%node_positions(2)-spline%node_positions(-1))*(spline%node_positions(1)-spline%node_positions(0)))
249 lift(3,2) = (spline%node_positions(nc+1)-spline%node_positions(nc))*(spline%node_positions(nc+2)-spline%node_positions(nc-1))
250 lift(3,2) = lift(3,2)/((spline%node_positions(nc+1)-spline%node_positions(nc-2))*(spline%node_positions(nc)-spline%node_positions(nc-1)))
252 lift(4, 1) = (spline%node_positions(0) - spline%node_positions(-1))*(spline%node_positions(1) - spline%node_positions(-2))
253 lift(4,1) = lift(4,1)/((spline%node_positions(2)-spline%node_positions(-1))*(spline%node_positions(1)-spline%node_positions(0)))
255 lift(4, 2) = (spline%node_positions(nc) - spline%node_positions(nc - 2))*(spline%node_positions(nc) - spline%node_positions(nc - 1))
256 lift(4,2) = lift(4,2)-(spline%node_positions(nc+2)-spline%node_positions(nc))*(spline%node_positions(nc+1)-spline%node_positions(nc))
257 lift(4,2) = lift(4,2)/((spline%node_positions(nc+1)-spline%node_positions(nc-2))*(spline%node_positions(nc)-spline%node_positions(nc-1)))
273 sll_real64,
dimension(:),
pointer :: node_pos, buf
274 sll_int32,
intent(in) :: n
275 sll_real64,
dimension(:),
pointer :: a, cts
276 sll_int32,
dimension(:),
pointer :: ipiv, ibuf
279 cts => buf(3*n + 1:10*n)
282 node_pos(-1) = node_pos(n - 1) - (node_pos(n) - node_pos(0))
283 node_pos(-2) = node_pos(n - 2) - (node_pos(n) - node_pos(0))
284 node_pos(n + 1) = node_pos(1) + (node_pos(n) - node_pos(0))
285 node_pos(n + 2) = node_pos(2) + (node_pos(n) - node_pos(0))
290 a(3*i+1)=(node_pos(i+1)-node_pos(i))*(node_pos(i+1)-node_pos(i))/((node_pos(i+1)-node_pos(i-1))*(node_pos(i+1)-node_pos(i-2)))
294 a(3*i+3)=(node_pos(i)-node_pos(i-1))/(node_pos(i+1)-node_pos(i-1))*((node_pos(i)-node_pos(i-1))/(node_pos(i+2)-node_pos(i-1)))
296 a(3*i + 2) = 1.0_f64 - a(3*i + 1) - a(3*i + 3)
306 sll_real64,
dimension(:),
pointer :: node_pos, buf
307 sll_int32,
intent(in) :: n
308 sll_real64,
dimension(:),
pointer :: a, cts
309 sll_int32,
dimension(:),
pointer :: ipiv, ibuf
313 cts => buf(3*np + 1:10*np)
317 node_pos(-1) = 2._f64*node_pos(0) - node_pos(1)
318 node_pos(-2) = 2._f64*node_pos(0) - node_pos(2)
319 node_pos(n + 1) = 2.0_f64*node_pos(n) - node_pos(n - 1)
320 node_pos(n + 2) = 2.0_f64*node_pos(n) - node_pos(n - 2)
323 node_pos(-1) = node_pos(0)
324 node_pos(-2) = node_pos(0)
325 node_pos(n + 1) = node_pos(n)
326 node_pos(n + 2) = node_pos(n)
333 a(2) = (node_pos(2) - node_pos(0))/(node_pos(2) - node_pos(-1))
334 a(3) = 1.0_f64 - a(2)
337 a(3*i + 1) = (node_pos(i + 1) - node_pos(i))**2/((node_pos(i + 1) - node_pos(i - 1))*(node_pos(i + 1) - node_pos(i - 2)))
339 a(3*i + 3) = (node_pos(i) - node_pos(i - 1))**2/((node_pos(i + 1) - node_pos(i - 1))*(node_pos(i + 2) - node_pos(i - 1)))
341 a(3*i + 2) = 1.0_f64 - a(3*i + 1) - a(3*i + 3)
346 a(3*n + 2) = (node_pos(n) - node_pos(n - 2))/(node_pos(n + 1) - node_pos(n - 2))
347 a(3*n + 1) = 1.0_f64 - a(3*n + 2)
357 sll_real64,
dimension(:),
pointer :: f, buf, coeffs
358 sll_int32,
intent(in) :: n
359 sll_real64,
dimension(:),
pointer :: cts
360 sll_int32,
dimension(:),
pointer :: ipiv, ibuf
363 cts => buf(3*n + 1:10*n)
368 coeffs(-1) = coeffs(n - 1)
369 coeffs(n) = coeffs(0)
370 coeffs(n + 1) = coeffs(1)
384 sll_real64,
dimension(:) :: f
385 sll_real64,
dimension(:),
pointer :: buf
386 sll_real64,
dimension(:),
pointer :: coeffs
387 sll_int32,
intent(in) :: n
388 sll_real64,
dimension(:),
pointer :: cts
389 sll_int32,
dimension(:),
pointer :: ipiv, ibuf
390 sll_real64,
dimension(:),
pointer :: a
391 sll_real64,
dimension(:),
allocatable :: b
392 sll_real64,
dimension(:),
pointer :: x
397 cts => buf(3*n + 1:10*n)
404 sll_allocate(b(n), ierr)
409 coeffs(0:n - 1) = 0._f64
419 coeffs(-1) = coeffs(n - 1)
420 coeffs(n) = coeffs(0)
421 coeffs(n + 1) = coeffs(1)
434 sll_real64,
dimension(:),
pointer :: f, buf, coeffs
435 sll_int32,
intent(in) :: n
436 sll_real64,
intent(in) :: lift(4, 2)
437 sll_real64,
dimension(:),
pointer :: cts
438 sll_int32,
dimension(:),
pointer :: ipiv, ibuf
441 cts => buf(3*np + 1:10*np)
445 coeffs(1:n - 1) = f(2:n)
446 coeffs(0) = f(1) + lift(1, 1)
447 coeffs(n) = f(n + 1) + lift(1, 2)
452 coeffs(-1) = lift(3, 1)*coeffs(0) + lift(4, 1)*coeffs(1) + lift(2, 1)
453 coeffs(n + 1) = lift(3, 2)*coeffs(n - 1) + lift(4, 2)*coeffs(n) + lift(2, 2)
461 sll_real64,
intent(in) :: x
465 sll_real64,
dimension(:),
pointer :: xj, coef
467 xx = (x - spline%xmin)/(spline%xmax - spline%xmin)
468 if (.not. ((xx .ge. 0.0_f64) .and. (xx .le. 1.0_f64)))
then
469 print *,
'bad_value of x=', x,
'xmin=', spline%xmin,
'xmax=', spline%xmax, xx, xx - 1.0_f64
470 print *,
'in function interpolate_value_nonunif()'
476 if (xx == 1.0_f64)
then
480 do while (spline%node_positions(j) .le. xx)
484 xj => spline%node_positions(j:)
486 sll_assert((xx .ge. xj(0)) .and. (xx .le. xj(1)))
487 sll_assert((xj(0) == spline%node_positions(j - 1)) .and. (xj(1) == spline%node_positions(j)))
490 w(0) = (xj(1) - xx)*(xj(1) - xx)*(xj(1) - xx)/((xj(1) - xj(0))*(xj(1) - xj(-1))*(xj(1) - xj(-2)));
491 w(1) = (xj(1) - xx)*(xj(1) - xx)*(xx - xj(-2))/((xj(1) - xj(0))*(xj(1) - xj(-1))*(xj(1) - xj(-2)));
492 w(1) = w(1) + (xj(2) - xx)*(xj(1) - xx)*(xx - xj(-1))/((xj(1) - xj(0))*(xj(1) - xj(-1))*(xj(2) - xj(-1)));
493 w(1) = w(1) + (xj(2) - xx)*(xj(2) - xx)*(xx - xj(0))/((xj(1) - xj(0))*(xj(2) - xj(0))*(xj(2) - xj(-1)));
494 w(2) = (xj(1) - xx)*(xx - xj(-1))*(xx - xj(-1))/((xj(1) - xj(0))*(xj(1) - xj(-1))*(xj(2) - xj(-1)));
495 w(2) = w(2) + (xj(2) - xx)*(xx - xj(-1))*(xx - xj(0))/((xj(1) - xj(0))*(xj(2) - xj(0))*(xj(2) - xj(-1)));
496 w(2) = w(2) + (xj(3) - xx)*(xx - xj(0))*(xx - xj(0))/((xj(1) - xj(0))*(xj(2) - xj(0))*(xj(3) - xj(0)));
497 w(3) = (xx - xj(0))*(xx - xj(0))*(xx - xj(0))/((xj(1) - xj(0))*(xj(2) - xj(0))*(xj(3) - xj(0)));
498 coef => spline%coeffs(j - 1:)
505 sll_int32,
intent(in) :: n
506 sll_real64,
dimension(1:n),
intent(in) :: a_in
507 sll_real64,
dimension(1:n),
intent(out) :: a_out
510 sll_int32 :: i, j, shift = 3
512 sll_real64,
dimension(:),
pointer :: xj
513 sll_real64,
dimension(:),
pointer :: coef
517 xx = (x - spline%xmin)/(spline%xmax - spline%xmin)
518 if (.not. ((xx .ge. 0.0_f64) .and. (xx .le. 1.0_f64)))
then
519 print *,
'bad_value of x=', x,
'xmin=', spline%xmin,
'xmax=', spline%xmax, xx, xx - 1.0_f64
520 print *,
'in subroutine sll_s_interpolate_array_value_nonunif()'
527 if (xx == 1.0_f64)
then
530 do while (spline%node_positions(j) .le. xx)
537 x = (a_in(i) - spline%xmin)/(spline%xmax - spline%xmin)
538 if (.not. ((x .ge. 0.0_f64) .and. (x .le. 1.0_f64)))
then
539 print *,
'bad_value of a_in(', i,
')=', a_in(i),
'xmin=', spline%xmin,
'xmax=', spline%xmax
540 print *,
'in subroutine sll_s_interpolate_array_value_nonunif()'
543 if (x == 1.0_f64)
then
547 do while (spline%node_positions(j) .le. x)
551 do while (spline%node_positions(j) .gt. x)
558 xj => spline%node_positions(j - shift:)
562 if (.not. ((xx .ge. xj(0 + shift)) .and. (xx .lt. xj(1 + shift))))
then
563 if (xx .ne. 1.0_f64)
then
564 print *, xj(0 + shift), xx, xj(1 + shift)
569 sll_assert((xx .ge. xj(0 + shift)) .and. (xx .le. xj(1 + shift)))
570 sll_assert((xj(0 + shift) == spline%node_positions(j - 1)) .and. (xj(1 + shift) == spline%node_positions(j)))
573 w(1)=(xj(shift+1)-xx)*(xj(shift+1)-xx)*(xj(shift+1)-xx)/((xj(shift+1)-xj(shift+0))*(xj(shift+1)-xj(shift-1))*(xj(shift+1)-xj(shift-2)));
574 w(2)=(xj(shift+1)-xx)*(xj(shift+1)-xx)*(xx-xj(shift-2))/((xj(shift+1)-xj(shift+0))*(xj(shift+1)-xj(shift-1))*(xj(shift+1)-xj(shift-2)));
575 w(2)=w(2)+(xj(shift+2)-xx)*(xj(shift+1)-xx)*(xx-xj(shift-1))/((xj(shift+1)-xj(shift+0))*(xj(shift+1)-xj(shift-1))*(xj(shift+2)-xj(shift-1)));
576 w(2)=w(2)+(xj(shift+2)-xx)*(xj(shift+2)-xx)*(xx-xj(shift+0))/((xj(shift+1)-xj(shift+0))*(xj(shift+2)-xj(shift+0))*(xj(shift+2)-xj(shift-1)));
577 w(3)=(xj(shift+1)-xx)*(xx-xj(shift-1))*(xx-xj(shift-1))/((xj(shift+1)-xj(shift+0))*(xj(shift+1)-xj(shift-1))*(xj(shift+2)-xj(shift-1)));
578 w(3)=w(3)+(xj(shift+2)-xx)*(xx-xj(shift-1))*(xx-xj(shift+0))/((xj(shift+1)-xj(shift+0))*(xj(shift+2)-xj(shift+0))*(xj(shift+2)-xj(shift-1)));
579 w(3)=w(3)+(xj(shift+3)-xx)*(xx-xj(shift+0))*(xx-xj(shift+0))/((xj(shift+1)-xj(shift+0))*(xj(shift+2)-xj(shift+0))*(xj(shift+3)-xj(shift+0)));
580 w(4)=(xx-xj(shift+0))*(xx-xj(shift+0))*(xx-xj(shift+0))/((xj(shift+1)-xj(shift+0))*(xj(shift+2)-xj(shift+0))*(xj(shift+3)-xj(shift+0)));
585 coef => spline%coeffs(j - 2:)
587 a_out(i) = w(1)*coef(1) + w(2)*coef(2) + w(3)*coef(3) + w(4)*coef(4)
594 sll_int32,
intent(in) :: n, n_cells
595 sll_real64,
dimension(1:n),
intent(in) :: a_in
597 sll_real64,
dimension(1:n),
intent(out) :: a_out
600 sll_int32 :: i, j, shift = 3
602 sll_real64,
dimension(:),
pointer :: xj
603 sll_real64,
dimension(:),
pointer :: coef, coeffs, node_pos
612 if (.not. ((xx .ge. 0.0_f64) .and. (xx .le. 1.0_f64)))
then
613 print *,
'bad_value of x=', x
614 print *,
'in subroutine sll_s_interpolate_array_value_nonunif()'
621 if (xx == 1.0_f64)
then
624 do while (node_pos(j) .le. xx)
632 if (.not. ((x .ge. 0.0_f64) .and. (x .le. 1.0_f64)))
then
633 print *,
'bad_value of a_in(', i,
')=', a_in(i)
634 print *,
'in subroutine sll_s_interpolate_array_value_nonunif()'
637 if (x == 1.0_f64)
then
641 do while (node_pos(j) .le. x)
645 do while (node_pos(j) .gt. x)
652 xj => node_pos(j - shift:)
657 if (.not. ((xx .ge. xj(0 + shift)) .and. (xx .lt. xj(1 + shift))))
then
658 if (xx .ne. 1.0_f64)
then
659 print *, xj(0 + shift), xx, xj(1 + shift)
668 w(1) = (xj(shift + 1) - xx)*(xj(shift + 1) - xx)*(xj(shift + 1) - xx)&
669 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 1) - xj(shift - 1))*(xj(shift + 1) - xj(shift - 2)));
670 w(2) = (xj(shift + 1) - xx)*(xj(shift + 1) - xx)*(xx - xj(shift - 2))&
671 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 1) - xj(shift - 1))*(xj(shift + 1) - xj(shift - 2)));
672 w(2) = w(2) + (xj(shift + 2) - xx)*(xj(shift + 1) - xx)*(xx - xj(shift - 1))&
673 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 1) - xj(shift - 1))*(xj(shift + 2) - xj(shift - 1)));
674 w(2) = w(2) + (xj(shift + 2) - xx)*(xj(shift + 2) - xx)*(xx - xj(shift + 0))&
675 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 2) - xj(shift + 0))*(xj(shift + 2) - xj(shift - 1)));
676 w(3) = (xj(shift + 1) - xx)*(xx - xj(shift - 1))*(xx - xj(shift - 1))&
677 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 1) - xj(shift - 1))*(xj(shift + 2) - xj(shift - 1)));
678 w(3) = w(3) + (xj(shift + 2) - xx)*(xx - xj(shift - 1))*(xx - xj(shift + 0))&
679 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 2) - xj(shift + 0))*(xj(shift + 2) - xj(shift - 1)));
680 w(3) = w(3) + (xj(shift + 3) - xx)*(xx - xj(shift + 0))*(xx - xj(shift + 0))&
681 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 2) - xj(shift + 0))*(xj(shift + 3) - xj(shift + 0)));
682 w(4) = (xx - xj(shift + 0))*(xx - xj(shift + 0))*(xx - xj(shift + 0))&
683 &/((xj(shift + 1) - xj(shift + 0))*(xj(shift + 2) - xj(shift + 0))*(xj(shift + 3) - xj(shift + 0)));
688 coef => coeffs(j - 2:)
689 a_out(i) = w(1)*coef(1) + w(2)*coef(2) + w(3)*coef(3) + w(4)*coef(4)
Solve tridiagonal system (double or complex)
Describe different boundary conditions.
Tridiagonal system solver.
subroutine, public sll_s_setup_cyclic_tridiag(a, n, cts, ipiv)
Give the factorization of the matrix in argument.