40 subroutine lininter(n,ref_array,ref_value,array,res,flin)
43 integer,
intent(in) :: n
44 real(
r_kind),
dimension(n),
intent(in) :: ref_array
45 real(
r_kind),
dimension(n),
intent(in) :: array
46 real(
r_kind),
intent(in) :: ref_value
47 real(
r_kind),
intent(out) :: res
48 logical,
intent(in),
optional :: flin
55 if (.not.
present(flin))
then
63 if (ref_value .le. ref_array(i))
exit
69 else if (ii.gt.n)
then
72 grad = (ref_value-ref_array(ii-1))/(ref_array(ii)-ref_array(ii-1))
73 res = array(ii-1) + grad*(array(ii)-array(ii-1))
102 integer,
intent(in) :: n
103 real(
r_kind),
dimension(n),
intent(in) :: xp
104 real(
r_kind),
intent(in) :: xb
105 real(
r_kind),
dimension(n),
intent(in) :: yp
106 real(
r_kind),
intent(out) :: res
107 logical,
intent(in),
optional :: flin
108 integer,
intent(in),
optional :: itype
110 integer :: interp_type
114 if (.not.
present(itype))
then
120 if (.not.
present(flin))
then
127 if (interp_type .eq. itype_linear)
then
128 call lininter(n,xp,xb,yp,res,linear)
129 else if (interp_type .eq. itype_cubic)
then
130 call cubinter(n,xp,xb,yp,res,linear)
131 else if (interp_type .eq. itype_akima)
then
133 else if (interp_type .eq. itype_makima)
then
135 else if (interp_type .eq. itype_pchip)
then
140 ". Try to change interp_mode to a valid value.",&
164 integer,
intent(in) :: n
165 real(
r_kind),
dimension(n),
intent(in) :: xp
166 real(
r_kind),
intent(in) :: xb
167 real(
r_kind),
dimension(n),
intent(in) :: yp
168 real(
r_kind),
intent(out) :: res
169 logical,
intent(in),
optional :: flin
172 real(
r_kind) :: x,x1,x2,x3,x4,x12,x13,x14,x23,x24,x34
175 if(
present(flin))
then
183 if (xb .le. xp(ii))
exit
187 else if (x.ge.xp(n))
then
189 else if(ii.le.2)
then
193 res= (yp(1)*x2 - yp(2)*x1)/x12
194 else if(ii.eq.n)
then
198 res= (yp(n-1)*x2 - yp(n)*x1)/x12
200 k= min(max(ii-2,2),n-3)
214 res= yp(k) *x2*x3*x4/(x12*x13*x14) &
215 - yp(k+1)*x1*x3*x4/(x12*x23*x24) &
216 + yp(k+2)*x1*x2*x4/(x13*x23*x34) &
217 - yp(k+3)*x1*x2*x3/(x14*x24*x34)
245 integer,
intent(in) :: n
246 real(
r_kind),
dimension(n),
intent(in) :: xp
247 real(
r_kind),
intent(in) :: xb
248 real(
r_kind),
dimension(n),
intent(in) :: yp
249 real(
r_kind),
intent(out) :: res
250 logical,
intent(in),
optional :: flin
253 real(
r_kind) :: a, b, c, d
254 real(
r_kind) :: hi, him1, hip1
255 real(
r_kind) :: si, sim1, sip1
257 real(
r_kind) :: yi_prime, yip1_prime
262 if(
present(flin))
then
270 if (xb .le. xp(ii))
exit
275 if (xb.le.xp(1))
then
278 else if (xb.ge.xp(n))
then
281 else if(ii.lt.2)
then
285 res= (yp(ii)*x2 - yp(ii+1)*x1)/(x2-x1)
287 else if(ii.gt.n-2)
then
291 res= (yp(ii)*x2 - yp(ii+1)*x1)/(x2-x1)
296 si = (yp(ii+1)-yp(ii))/hi
298 him1 = xp(ii)-xp(ii-1)
299 sim1 = (yp(ii)-yp(ii-1))/him1
301 hip1 = xp(ii+2)-xp(ii+1)
302 sip1 = (yp(ii+2)-yp(ii+1))/hip1
304 pi = (hi*sim1+him1*si)/(hi+him1)
305 pip1 = (hip1*si+hi*sip1)/(hip1+hi)
308 if (si*sim1 .le. 0)
then
310 elseif ((dabs(
pi)>2*dabs(sim1)) .or. (dabs(
pi)>2*dabs(si)))
then
311 yi_prime = 2*sign(1.d0,si)*min(dabs(sim1),dabs(si))
316 if (sip1*si .le. 0)
then
318 elseif ((dabs(pip1)>2*dabs(si)) .or. (dabs(pip1)>2*dabs(sip1)))
then
319 yip1_prime = 2*sign(1.d0,si)*min(dabs(sip1),dabs(si))
324 a = (yi_prime+yip1_prime-2*si)/hi**2
325 b = (3*si-2*yi_prime-yip1_prime)/hi
331 res = a*delt**3 + b*delt**2 + c*delt + d
366 integer,
intent(in) :: n
367 real(
r_kind),
dimension(n),
intent(in) :: xp
368 real(
r_kind),
intent(in) :: xb
369 real(
r_kind),
dimension(n),
intent(in) :: yp
370 real(
r_kind),
intent(out) :: res
371 logical,
intent(in),
optional :: flin
373 real(
r_kind) :: xval(6), yval(6), mval(5), sval(2)
375 real(
r_kind) :: a, b, c, d
380 if(
present(flin))
then
394 if (xb .le. xp(ii))
exit
399 if (xb.le.xp(1))
then
402 else if (xb.ge.xp(n))
then
405 else if(ii.lt.3)
then
409 res= (yp(ii)*x2 - yp(ii+1)*x1)/(x2-x1)
411 else if(ii.gt.n-3)
then
415 res= (yp(ii)*x2 - yp(ii+1)*x1)/(x2-x1)
420 xval(1:6) = xp(ii-2:ii+3)
421 yval(1:6) = yp(ii-2:ii+3)
423 mval(1:5) = (yval(2:6) - yval(1:5)) / (xval(2:6) - xval(1:5))
427 sval(1) = ((dabs(mval(i+1)-mval(i))*mval(i-1) + dabs(mval(i-1)-mval(i-2))*mval(i)))
428 denom = (dabs(mval(i+1)-mval(i)) + dabs(mval(i-1)-mval(i-2)))
430 if (denom .gt. 1e-8)
then
431 sval(1) = sval(1)/denom
433 sval(1) = (mval(i-1)+mval(i))/2d0
435 sval(2) = ((dabs(mval(i+2)-mval(i+1))*mval(i) + dabs(mval(i)-mval(i-1))*mval(i+1)))
436 denom = (dabs(mval(i+2)-mval(i+1)) + dabs(mval(i)-mval(i-1)))
437 if (denom .gt. 1e-8)
then
438 sval(2) = sval(2)/denom
440 sval(2) = (mval(i)+mval(i+1))/2d0
445 c = (3.0d0 * mval(i) - 2.0d0 * sval(1) - sval(2)) / (xval(i+1) - xval(i))
446 d = (sval(1) + sval(2) - 2.0d0 * mval(i)) / (xval(i+1) - xval(i))**2
448 res = a + b * (xb - xval(i)) + c * (xb - xval(i))**2 + d * (xb - xval(i))**3
483 integer,
intent(in) :: n
484 real(
r_kind),
dimension(n),
intent(in) :: xp
485 real(
r_kind),
intent(in) :: xb
486 real(
r_kind),
dimension(n),
intent(in) :: yp
487 real(
r_kind),
intent(out) :: res
488 logical,
intent(in),
optional :: flin
490 real(
r_kind) :: xval(6), yval(6), mval(5), sval(2)
492 real(
r_kind) :: a, b, c, d
497 if(
present(flin))
then
511 if (xb .le. xp(ii))
exit
516 if (xb.le.xp(1))
then
519 else if (xb.ge.xp(n))
then
522 else if(ii.lt.3)
then
526 res= (yp(ii)*x2 - yp(ii+1)*x1)/(x2-x1)
528 else if(ii.gt.n-3)
then
532 res= (yp(ii)*x2 - yp(ii+1)*x1)/(x2-x1)
537 xval(1:6) = xp(ii-2:ii+3)
538 yval(1:6) = yp(ii-2:ii+3)
540 mval(1:5) = (yval(2:6) - yval(1:5)) / (xval(2:6) - xval(1:5))
544 sval(1) = ((dabs(mval(i+1)-mval(i)) + dabs(mval(i+1)+mval(i))/2d0)*mval(i-1) + &
545 (dabs(mval(i-1)-mval(i-2)) + dabs(mval(i-1)+mval(i-2))/2d0)*mval(i))
547 denom = ((dabs(mval(i+1)-mval(i)) + dabs(mval(i+1)+mval(i))/2d0) + &
548 (dabs(mval(i-1)-mval(i-2)) + dabs(mval(i-1)+mval(i-2))/2d0))
550 if (denom .gt. 1e-8)
then
551 sval(1) = sval(1)/denom
553 sval(1) = (mval(i-1)+mval(i))/2d0
555 sval(2) = (((dabs(mval(i+2)-mval(i+1)) + dabs(mval(i+2)+mval(i+1))/2d0)*mval(i) + &
556 (dabs(mval(i)-mval(i-1)) + dabs(mval(i)+mval(i-1))/2d0) *mval(i+1)))
557 denom = ((dabs(mval(i+2)-mval(i+1)) + dabs(mval(i+2)+mval(i+1))/2d0) + &
558 (dabs(mval(i)-mval(i-1)) + dabs(mval(i)+mval(i-1))/2d0))
559 if (denom .gt. 1e-8)
then
560 sval(2) = sval(2)/denom
562 sval(2) = (mval(i)+mval(i+1))/2d0
567 c = (3.0d0 * mval(i) - 2.0d0 * sval(1) - sval(2)) / (xval(i+1) - xval(i))
568 d = (sval(1) + sval(2) - 2.0d0 * mval(i)) / (xval(i+1) - xval(i))**2
570 res = a + b * (xb - xval(i)) + c * (xb - xval(i))**2 + d * (xb - xval(i))**3
589 integer,
intent(in) :: x_dim, y_dim
590 real(
r_kind),
intent(in) :: xval,yval
591 real(
r_kind),
dimension(x_dim),
intent(in) :: x
592 real(
r_kind),
dimension(y_dim),
intent(in) :: y
593 integer,
dimension(2,2),
intent(out) :: indices
599 if (xval .lt. x(i))
exit
606 if (yval .lt. y(i))
exit
625 integer,
intent(in) :: x_dim, y_dim
626 real(
r_kind),
dimension(x_dim, y_dim),
intent(in) :: f
627 real(
r_kind),
dimension(x_dim),
intent(in) :: x
628 real(
r_kind),
dimension(y_dim),
intent(in) :: y
629 real(
r_kind),
dimension(x_dim,y_dim),
intent(inout) :: dfx
630 real(
r_kind),
dimension(x_dim,y_dim),
intent(inout) :: dfy
631 real(
r_kind),
dimension(x_dim,y_dim),
intent(inout) :: dfxy
640 if ((i .gt. 1) .and. (i .lt. x_dim) )
then
641 h1 = abs(x(i) -x(i-1))
642 h2 = abs(x(i+1)-x(i))
643 dfx(i,j) = h1**2*f(i+1,j)+(h2**2-h1**2)*f(i,j)-h2**2*f(i-1,j)
644 dfx(i,j) = dfx(i,j) / (h1*h2*(h1+h2))
645 elseif (i .eq. 1)
then
646 h2 = abs(x(i+1)-x(i))
647 dfx(i,j) = (f(i+1,j)-f(i,j)) / (h2)
648 elseif (i .eq. x_dim)
then
649 h1 = abs(x(i)-x(i-1))
650 dfx(i,j) = (f(i,j)-f(i-1,j)) / (h1)
654 if ((j .gt.1) .and. (j .lt. y_dim))
then
655 h1 = abs(y(j) -y(j-1))
656 h2 = abs(y(j+1)-y(j))
657 dfy(i,j) = h1**2*f(i,j+1)+(h2**2-h1**2)*f(i,j)-h2**2*f(i,j-1)
658 dfy(i,j) = dfy(i,j) / (h1*h2*(h1+h2))
659 elseif (j .eq. 1)
then
660 h2 = abs(y(j+1)-y(j))
661 dfy(i,j) = (f(i,j+1)-f(i,j)) / (h2)
662 elseif (j .eq. y_dim)
then
663 h1 = abs(y(j)-y(j-1))
664 dfy(i,j) = (f(i,j)-f(i,j-1)) / (h1)
672 if ((j .gt. 1) .and. (j .lt. y_dim) )
then
673 h1 = abs(y(j) -y(j-1))
674 h2 = abs(y(j+1)-y(j))
675 dfxy(i,j) = h1**2*dfx(i,j+1)+(h2**2-h1**2)*dfx(i,j)-h2**2*dfx(i,j-1)
676 dfxy(i,j) = dfxy(i,j) / (h1*h2*(h1+h2))
677 elseif (j .eq. 1)
then
678 h2 = abs(y(j+1)-y(j))
679 dfxy(i,j) = (dfx(i,j+1)-dfx(i,j)) / (h2)
680 elseif (j .eq. y_dim)
then
681 h1 = abs(y(j)-y(j-1))
682 dfxy(i,j) = (dfx(i,j)-dfx(i,j-1)) / (h1)
699 function lininter_2d(xin,yin,x,y,f,x_dim,y_dim,indice,extrapolation)
result (wr)
702 integer,
intent(in) :: x_dim, y_dim
703 real(
r_kind),
intent(in) :: xin,yin
704 real(
r_kind),
dimension(x_dim),
intent(in) :: x
705 real(
r_kind),
dimension(y_dim),
intent(in) :: y
706 real(
r_kind),
dimension(x_dim,y_dim),
intent(in) :: f
707 integer,
optional,
intent(in) :: extrapolation
708 integer,
dimension(2,2),
optional,
intent(in) :: indice
711 integer,
dimension(2,2) :: ind
713 real(
r_kind) :: x1, x2, y1, y2
715 real(
r_kind),
dimension(2,2) :: weights
721 if (.not.
present(indice))
then
724 ind(:,:) = indice(:,:)
728 if (.not.
present(extrapolation)) extr=1
729 if (
present(extrapolation)) extr=extrapolation
732 if ((xval .lt. x(1)) .or. (yval .lt. y(1)))
then
736 "inter_module",270003)
742 "inter_module",270004)
744 elseif ((xval .gt. x(x_dim)) .or. (yval .gt. y(y_dim)))
then
748 "inter_module",270003)
750 xval= min(x(x_dim),xval)
751 yval= min(y(y_dim),yval)
754 "inter_module",270004)
765 weights(1,1) = ((x2-xval)*(y2-yval))/((x2-x1)*(y2-y1))
766 weights(1,2) = ((x2-xval)*(yval-y1))/((x2-x1)*(y2-y1))
767 weights(2,1) = ((xval-x1)*(y2-yval))/((x2-x1)*(y2-y1))
768 weights(2,2) = ((xval-x1)*(yval-y1))/((x2-x1)*(y2-y1))
771 wr = weights(1,1)*f(ind(1,1),ind(2,1)) + &
772 weights(1,2)*f(ind(1,1),ind(2,2)) + &
773 weights(2,1)*f(ind(1,2),ind(2,1)) + &
774 weights(2,2)*f(ind(1,2),ind(2,2))
795 function cubinter_2d(xin,yin,x,y,f,dfx,dfy,dfxy,x_dim,y_dim,indice,extrapolation)
result (wr)
798 integer,
intent(in) :: x_dim, y_dim
799 real(
r_kind),
intent(in) :: xin,yin
800 real(
r_kind),
dimension(x_dim),
intent(in) :: x
801 real(
r_kind),
dimension(y_dim),
intent(in) :: y
802 real(
r_kind),
dimension(x_dim,y_dim),
intent(in) :: f,dfx,dfy,dfxy
803 integer,
optional,
intent(in) :: extrapolation
804 integer,
dimension(2,2),
optional,
intent(in) :: indice
808 real(
r_kind),
dimension(16,16) :: a_inv
809 real(
r_kind),
dimension(16) :: vec,alphas
810 integer,
dimension(2,2) :: ind
811 real(
r_kind),
dimension(4,4) :: alphas_r
812 real(
r_kind) :: x1, x2, y1, y2
821 if (.not.
present(indice))
then
824 ind(:,:) = indice(:,:)
828 if (.not.
present(extrapolation)) extr=2
829 if (
present(extrapolation)) extr=extrapolation
832 if ((xval .lt. x(1)) .or. (yval .lt. y(1)))
then
836 "inter_module",270003)
842 "inter_module",270004)
844 elseif ((xval .gt. x(x_dim)) .or. (yval .gt. y(y_dim)))
then
848 "inter_module",270003)
850 xval= min(x(x_dim),xval)
851 yval= min(y(y_dim),yval)
854 "inter_module",270004)
865 xbar = (xval-x1)/(x2-x1)
866 ybar = (yval-y1)/(y2-y1)
870 a_inv = reshape( (/ 1, 0,-3, 2, 0, 0, 0, 0,-3, 0, 9,-6, 2, 0,-6, 4, &
871 0, 0, 3,-2, 0, 0, 0, 0, 0, 0,-9, 6, 0, 0, 6,-4, &
872 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,-9, 6,-2, 0, 6,-4, &
873 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-6, 0, 0,-6, 4, &
874 0, 1,-2, 1, 0, 0, 0, 0, 0,-3, 6,-3, 0, 2,-4, 2, &
875 0, 0,-1, 1, 0, 0, 0, 0, 0, 0, 3,-3, 0, 0,-2, 2, &
876 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,-6, 3, 0,-2, 4,-2, &
877 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 2,-2, &
878 0, 0, 0, 0, 1, 0,-3, 2,-2, 0, 6,-4, 1, 0,-3, 2, &
879 0, 0, 0, 0, 0, 0, 3,-2, 0, 0,-6, 4, 0, 0, 3,-2, &
880 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 3,-2, 1, 0,-3, 2, &
881 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 2, 0, 0, 3,-2, &
882 0, 0, 0, 0, 0, 1,-2, 1, 0,-2, 4,-2, 0, 1,-2, 1, &
883 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 2,-2, 0, 0,-1, 1, &
884 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 2,-1, 0, 1,-2, 1, &
885 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,-1, 0, 0,-1, 1 &
889 vec = (/f(ind(1,1),ind(2,1)),f(ind(1,2),ind(2,1)),f(ind(1,1),ind(2,2)),f(ind(1,2),ind(2,2)),&
890 (x2-x1)*dfx(ind(1,1),ind(2,1)),(x2-x1)*dfx(ind(1,2),ind(2,1)),(x2-x1)*dfx(ind(1,1),ind(2,2)),(x2-x1)*dfx(ind(1,2),ind(2,2)),&
891 (y2-y1)*dfy(ind(1,1),ind(2,1)),(y2-y1)*dfy(ind(1,2),ind(2,1)),(y2-y1)*dfy(ind(1,1),ind(2,2)),(y2-y1)*dfy(ind(1,2),ind(2,2)),&
892 (x2-x1)*(y2-y1)*dfxy(ind(1,1),ind(2,1)),(x2-x1)*(y2-y1)*dfxy(ind(1,2),ind(2,1)),&
893 (x2-x1)*(y2-y1)*dfxy(ind(1,1),ind(2,2)),(x2-x1)*(y2-y1)*dfxy(ind(1,2),ind(2,2))/)
896 alphas = matmul(a_inv,vec)
898 alphas_r = reshape(alphas, (/4,4/))
904 wr = wr + alphas_r(i,j)*xbar**(i-1)*ybar**(j-1)
929 integer,
intent(in) :: n
930 real(
r_kind),
dimension(n),
intent(in) :: xp
931 real(
r_kind),
intent(in) :: xb
932 real(
r_kind),
dimension(n),
intent(in) :: yp
933 real(
r_kind),
intent(inout) :: res
934 logical,
intent(in),
optional :: flin
935 integer,
intent(in),
optional :: itype
936 integer,
intent(in),
optional :: reverse_type
940 integer :: interp_type
945 if (.not.
present(itype))
then
952 if (.not.
present(flin))
then
959 if (.not.
present(reverse_type))
then
966 if (rtype .eq. 1)
then
967 call inverse_nr(n,xp,xb,yp,res,linear,interp_type)
968 else if (rtype .eq. 2)
then
972 "inverse_interp1d", 270004)
1000 integer,
intent(in) :: n
1001 real(
r_kind),
dimension(n),
intent(in) :: xp
1002 real(
r_kind),
intent(in) :: xb
1003 real(
r_kind),
dimension(n),
intent(in) :: yp
1004 real(
r_kind),
intent(inout) :: res
1005 logical,
intent(in) :: flin
1006 integer,
intent(in) :: itype
1009 integer,
parameter :: maxiter=50
1011 real(
r_kind) :: m,y1,y2,xnew,b
1012 real(
r_kind),
parameter :: diff=1d-4
1013 real(
r_kind),
parameter :: tol =1d-10
1014 logical :: converged
1021 inner_loop:
do ii=1,maxiter
1023 call interp1d(n,yp,x1,xp,y1,flin,itype)
1024 call interp1d(n,yp,x2,xp,y2,flin,itype)
1027 if (x1 .ne. x2)
then
1047 if (abs(x1-xnew) .lt. tol)
then
1088 integer,
intent(in) :: n
1089 real(
r_kind),
dimension(n),
intent(in) :: xp
1090 real(
r_kind),
dimension(n),
intent(in) :: yp
1091 real(
r_kind),
intent(in) :: xb
1092 real(
r_kind),
intent(inout) :: res
1093 logical,
intent(in) :: flin
1094 integer,
intent(in) :: itype
1096 real(
r_kind) :: input_res
1099 real(
r_kind) :: a, b, c, d, fa, fb, fc, fs, s
1101 logical :: mflag, converged
1102 real(
r_kind),
parameter :: tol=1d-10
1103 integer,
parameter :: maxiter=100
1110 ii = minloc(abs(yp(:)-res),dim=1)
1114 call interp1d(n,yp,a,xp,y1,flin,itype)
1115 call interp1d(n,yp,b,xp,y2,flin,itype)
1120 if (fa * fb >= 0.0d0)
then
1122 "inverse_brent", 270006)
1126 if (abs(fa) < abs(fb))
then
1130 call interp1d(n,yp,a,xp,y1,flin,itype)
1131 call interp1d(n,yp,b,xp,y2,flin,itype)
1146 if (abs(fb) < tol .or. abs(b - a) < tol)
then
1153 if (fa /= fc .and. fb /= fc)
then
1154 s = a * fb * fc / ((fa - fb) * (fa - fc)) + &
1155 b * fa * fc / ((fb - fa) * (fb - fc)) + &
1156 c * fa * fb / ((fc - fa) * (fc - fb))
1158 s = b - fb * (b - a) / (fb - fa)
1162 if ((s < (3.0 * a + b) / 4.0 .or. s > b) .or. &
1163 (mflag .and. abs(s - b) >= abs(b - c) / 2.0) .or. &
1164 (.not. mflag .and. abs(s - b) >= abs(c - d) / 2.0) .or. &
1165 (mflag .and. abs(b - c) < tol) .or. &
1166 (.not. mflag .and. abs(c - d) < tol))
then
1175 call interp1d(n,yp,s,xp,y1,flin,itype)
1182 if (fa * fs < 0.0)
then
1191 if (abs(fa) < abs(fb))
then
1195 call interp1d(n,yp,a,xp,y1,flin,itype)
1196 call interp1d(n,yp,b,xp,y2,flin,itype)
1203 if (.not. converged)
then