31#include "../base/base_uses.f90"
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'splines'
55 REAL(
dp),
INTENT(in) :: x(:), y(:), xnew(:)
56 REAL(
dp) :: ynew(size(xnew))
59 REAL(
dp) :: c(0:4, size(x) - 1)
62 CALL spline3pars(x, y, [2, 2], [0._dp, 0._dp], c)
66 ip = iixmin(xnew(i), x, ip)
67 ynew(i) = poly3(xnew(i), c(:, ip))
82 REAL(
dp),
INTENT(in) :: x(:), y(:), xnew(:)
83 REAL(
dp),
INTENT(out),
OPTIONAL :: ynew(:), dynew(:), d2ynew(:)
86 REAL(
dp) :: c(0:4, size(x) - 1)
88 CALL spline3pars(x, y, [2, 2], [0._dp, 0._dp], c)
92 ip = iixmin(xnew(i), x, ip)
93 IF (
PRESENT(ynew)) ynew(i) = poly3(xnew(i), c(:, ip))
94 IF (
PRESENT(dynew)) dynew(i) = dpoly3(xnew(i), c(:, ip))
95 IF (
PRESENT(d2ynew)) d2ynew(i) = d2poly3(xnew(i), c(:, ip))
107 SUBROUTINE spline3pars(xi, yi, bctype, bcval, c)
110 REAL(
dp),
INTENT(in) :: xi(:), yi(:)
111 INTEGER,
INTENT(in) :: bctype(2)
112 REAL(
dp),
INTENT(in) :: bcval(2)
113 REAL(
dp),
INTENT(out) :: c(0:, :)
115 INTEGER :: i, i2, info, ipiv(4), j, n
116 REAL(
dp) :: ae(4, 4), be(4), bemat(4, 1), c1, c2, c3, c4, ce(4), d2p1, d2pn, x0, xe(4), &
117 ye(4), hi(size(c, 2)), cs(2*size(c, 2)), bs(2*size(c, 2)), bmat(2*size(c, 2), 1), &
119 INTEGER :: ipiv2(2*size(c, 2))
146 IF (bctype(1) < 1 .OR. bctype(1) > 2)
CALL stop_error(
"spline3pars error: bctype /= 1 or 2.")
147 IF (bctype(2) < 1 .OR. bctype(2) > 2)
CALL stop_error(
"spline3pars error: bctype /= 1 or 2.")
148 IF (
SIZE(c, 1) /= 5)
CALL stop_error(
"spline3pars error: size(c,1) /= 5.")
149 IF (
SIZE(c, 2) /=
SIZE(xi) - 1)
CALL stop_error(
"spline3pars error: size(c,2) /= size(xi)-1.")
150 IF (
SIZE(xi) /=
SIZE(yi))
CALL stop_error(
"spline3pars error: size(xi) /= size(yi)")
159 hi(i) = xi(i + 1) - xi(i)
164 IF (bctype(1) == 2)
THEN
165 IF (n < 4)
CALL stop_error(
"spline3pars error: n < 4")
171 ae(i, j) = (xe(i) - x0)**(j - 1)
175 be = ye; bemat(:, 1) = be
176 CALL dgesv(4, 1, ae, 4, ipiv, bemat, 4, info)
177 IF (info /= 0)
CALL stop_error(
"spline3pars error: dgesv error.")
182 IF (bctype(2) == 2)
THEN
183 IF (n < 4)
CALL stop_error(
"spline3pars error: n < 4")
189 ae(i, j) = (xe(i) - x0)**(j - 1)
193 be = ye; bemat(:, 1) = be
194 CALL dgesv(4, 1, ae, 4, ipiv, bemat, 4, info)
195 IF (info /= 0)
CALL stop_error(
"spline3pars error: dgesv error.")
201 IF (bctype(1) == 1) d2p1 = bcval(1)
202 IF (bctype(2) == 1) d2pn = bcval(2)
210 as(4, 1) = 6/hi(1)**2
215 as(5, i2 - 1) = 1/hi(i - 1)
216 as(4, i2) = 2/hi(i - 1)
217 as(3, i2 + 1) = 2/hi(i)
218 as(2, i2 + 2) = 1/hi(i)
219 as(5, i2) = 1/hi(i - 1)**2
220 as(4, i2 + 1) = -1/hi(i)**2
221 bs(i2) = (yi(i + 1) - yi(i))/hi(i) - (yi(i) - yi(i - 1))/hi(i - 1)
225 as(4, 2*(n - 1)) = 6/hi(n - 1)**2
230 CALL dgbsv(2*(n - 1), 1, 2, 1, as, 5, ipiv2, bmat, 2*(n - 1), info)
231 IF (info /= 0)
CALL stop_error(
"spline3pars error: dgbsv error.")
244 c(2, i) = -(c1 - c2 + 2*c3 + c4)/hi(i)
245 c(3, i) = 3*c3/hi(i)**2
246 c(4, i) = (-c3 + c4)/hi(i)**3
260 SUBROUTINE spline3valder(x, xi, c, val, der)
263 REAL(
dp),
INTENT(in) :: x, xi(:), c(0:, :)
264 REAL(
dp),
INTENT(out) :: val, der
279 IF (
SIZE(c, 1) /= 5)
CALL stop_error(
"spline3 error: size(c,1) /= 5.")
280 IF (
SIZE(c, 2) /=
SIZE(xi) - 1)
CALL stop_error(
"spline3 error: size(c,2) /= size(xi)-1.")
284 val = poly3(x, c(:, i1))
285 der = dpoly3(x, c(:, i1))
296 INTEGER FUNCTION iix(x, xi)
RESULT(i1)
302 REAL(
dp),
INTENT(in) :: x, xi(:)
313 CALL stop_error(
"error in iix: n < 2")
322 ELSEIF (x <= xi(1))
THEN
324 ELSEIF (x <= xi(2))
THEN
326 ELSEIF (x <= xi(3))
THEN
328 ELSEIF (x >= xi(n))
THEN
334 IF (i2 - i1 == 1)
EXIT
335 ic = i1 + (i2 - i1)/2
336 IF (x >= xi(ic))
THEN
352 INTEGER FUNCTION iixmin(x, xi, i_min)
RESULT(ip)
354 REAL(
dp),
INTENT(in) :: x, xi(:)
355 INTEGER,
INTENT(in) :: i_min
357 IF (i_min >= 1 .AND. i_min <=
SIZE(xi) - 1)
THEN
358 ip = iix(x, xi(i_min:)) + i_min - 1
374 FUNCTION iixun(x, n, x1, xn)
379 REAL(
dp),
INTENT(in) :: x
380 INTEGER,
INTENT(in) :: n
381 REAL(
dp),
INTENT(in) :: x1, xn
393 i = int((x - x1)/(xn - x1)*(n - 1)) + 1
396 IF (i > n - 1) i = n - 1
411 FUNCTION iixexp(x, n, x1, alpha, beta)
418 REAL(
dp),
INTENT(in) :: x
419 INTEGER,
INTENT(in) :: n
420 REAL(
dp),
INTENT(in) :: x1, alpha, beta
436 i = int(log((x - x1)/alpha + 1)/beta) + 1
439 IF (i > n - 1) i = n - 1
453 REAL(
dp),
INTENT(in) :: x, c(0:)
462 poly3 = c(1) + c(2)*dx + c(3)*dx**2 + c(4)*dx**3
473 FUNCTION dpoly3(x, c)
475 REAL(
dp),
INTENT(in) :: x, c(0:)
484 dpoly3 = c(2) + 2*c(3)*dx + 3*c(4)*dx**2
495 FUNCTION d2poly3(x, c)
497 REAL(
dp),
INTENT(in) :: x, c(0:)
506 d2poly3 = 2*c(3) + 6*c(4)*dx
515 SUBROUTINE stop_error(msg)
517 CHARACTER(LEN=*) :: msg
Defines the basic variable types.
integer, parameter, public dp
Simple splines Splines are fully specified by the interpolation points, except that at the ends,...
subroutine, public spline3ders(x, y, xnew, ynew, dynew, d2ynew)
...
real(dp) function, dimension(size(xnew)), public spline3(x, y, xnew)
...