123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- module num_interp
- implicit none
-
-
-
- private
-
- public :: Interp_Lin
- public :: Interp_Lin_Weight
- public :: CircInterp_Lin
- public :: Interp_MuHerm
-
-
- character(len=*), parameter :: mname = 'num_interp'
-
-
-
-
- interface Interp_Lin
- module procedure linterp_1
- module procedure linterp_1_row
- module procedure linterp_2
- module procedure linterp_3
- end interface
-
-
- interface CircInterp_Lin
- module procedure linterp_1_circ
- end interface
-
- contains
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- subroutine linterp_1( x,y, x0, y0, last, status )
- use GO, only : gol, goErr
- use num_tools, only : interval
-
- real, intent(in) :: x(:), y(:)
- real, intent(in) :: x0
- real, intent(out) :: y0
- integer, intent(inout) :: last
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/linterp_1'
-
- integer :: mflag
- integer :: n
-
-
- n = size(x)
- if ( size(y) /= n ) then
- write (gol,'("x and y should have same lengths:")'); call goErr
- write (gol,'(" size(x) : ",i6)') size(x); call goErr
- write (gol,'(" size(y) : ",i6)') size(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end if
-
- call Interval( x, x0, last, mflag )
- if ( mflag == 0 ) then
- y0 = y(last) + (x0-x(last))*(y(last+1)-y(last))/(x(last+1)-x(last))
- else if ( mflag .lt. 0 ) then
-
- y0 = y(1)
- else
-
- y0 = y(n)
- endif
-
-
- status = 0
- end subroutine linterp_1
-
-
-
- subroutine linterp_2( x, y, x0, y0, last, status )
- use GO , only : gol, goErr
- use num_tools, only : interval
-
- real, intent(in) :: x(:), y(:,:)
- real, intent(in) :: x0
- real, intent(out) :: y0(:)
- integer, intent(inout) :: last
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/linterp_2'
-
- integer :: mflag
- integer :: n
-
-
- n = size(x)
- if ( size(y,2) /= n ) then
- write (gol,'("dim 2 of y should have same length as x :")'); call goErr
- write (gol,'(" size(x) : ", i6)') size(x); call goErr
- write (gol,'(" shape(y) : ",2i6)') shape(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- stop
- end if
- if ( size(y0) /= size(y,1) ) then
- write (gol,'("output y0 should have same number of elements as first dim of y:")'); call goErr
- write (gol,'(" size(y0) : ", i6)') size(y0); call goErr
- write (gol,'(" shape(y) : ",2i6)') shape(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- stop
- end if
-
- call Interval( x, x0, last, mflag )
-
- if ( mflag == 0 ) then
- y0 = y(:,last) + (x0-x(last))*(y(:,last+1)-y(:,last))/(x(last+1)-x(last))
- else if ( mflag .lt. 0 ) then
-
- y0 = y(:,1)
- else
-
- y0 = y(:,n)
- endif
-
-
- status = 0
- end subroutine linterp_2
-
-
-
- subroutine linterp_3( x, y, x0, y0, last, status )
- use GO , only : gol, goErr
- use num_tools, only : interval
-
- real, intent(in) :: x(:), y(:,:,:)
- real, intent(in) :: x0
- real, intent(out) :: y0(size(y,1),size(y,2))
- integer, intent(inout) :: last
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/linterp_3'
-
- integer :: n
- integer :: mflag
-
-
- n = size(x)
- if ( size(y,3) /= n ) then
- write (gol,'("dim 3 of y should have same length as x :")'); call goErr
- write (gol,'(" size(x) : ", i6)') size(x); call goErr
- write (gol,'(" shape(y) : ",3i6)') shape(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- stop
- end if
- if ( (size(y0,1) /= size(y,1)) .or. (size(y0,2) /= size(y,2)) ) then
- write (gol,'("output y0 should have same shape as first dims of y:")'); call goErr
- write (gol,'(" shape(y0) : ",2i6)') shape(y0); call goErr
- write (gol,'(" shape(y) : ",3i6)') shape(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- stop
- end if
-
- call Interval( x, x0, last, mflag )
-
- if ( mflag == 0 ) then
-
- y0 = y(:,:,last) + (x0-x(last))*(y(:,:,last+1)-y(:,:,last))/(x(last+1)-x(last))
- else if ( mflag .lt. 0 ) then
-
- y0 = y(:,:,1)
- else
-
- y0 = y(:,:,n)
- endif
-
- status = 0
- end subroutine linterp_3
-
-
-
-
-
-
-
-
-
- subroutine Interp_Lin_Weight( x, x0, w, status )
- use GO , only : gol, goErr
- use num_tools, only : interval
-
- real, intent(in) :: x(:)
- real, intent(in) :: x0
- real, intent(out) :: w(:)
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/Interp_Lin_Weight'
-
- integer :: last
- integer :: mflag
- integer :: n
-
-
- n = size(x)
- if ( size(w) /= n ) then
- write (gol,'("arrays x and w should have same length:")'); call goErr
- write (gol,'(" size(x) : ",i6)') size(x); call goErr
- write (gol,'(" size(w) : ",i6)') size(w); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end if
-
-
- w = 0.0
- last = 1
- call Interval( x, x0, last, mflag )
- if ( mflag == 0 ) then
-
-
- w(last+1) = (x0-x(last))/(x(last+1)-x(last))
- w(last ) = 1.0 - w(last+1)
- else if ( mflag .lt. 0 ) then
-
-
- w(1) = 1.0
- else
-
-
- w(n) = 1.0
- endif
-
-
- status = 0
- end subroutine Interp_Lin_Weight
-
-
-
-
-
-
- subroutine linterp_1_circ( x, p, y, x0, y0, last, status )
- use GO , only : gol, goErr
- use num_tools, only : Interval
-
- real, intent(in) :: x(:), y(:)
- real, intent(in) :: p
- real, intent(in) :: x0
- real, intent(out) :: y0
- integer, intent(inout) :: last
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/linterp_1_circ'
-
- integer :: mflag
- integer :: n, i
- real :: x0p
-
-
- n = size(x)
- if ( size(y) /= n ) then
- write (gol,'("x and y should have same lengths:")'); call goErr
- write (gol,'(" size(x) : ",i6)') size(x); call goErr
- write (gol,'(" size(y) : ",i6)') size(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end if
-
- if ( x0 >= x(1) .and. x0 <= x(n) ) then
-
- x0p = x0
- else
-
- x0p = x(1) + modulo(x0-x(1),p)
- end if
-
- call Interval( x, x0p, last, mflag )
- if ( mflag == 0 ) then
-
- y0 = y(last) + (x0p-x(last))*(y(last+1)-y(last))/(x(last+1)-x(last))
- else if ( mflag < 0 ) then
-
- write (gol,'("internal error: x0 is smaller than x(1) :")'); call goErr
- write (gol,'(" x0 : ",e16.4)') x0; call goErr
- write (gol,'(" p : ",e16.4)') p; call goErr
- write (gol,'(" x0p : ",e16.4)') x0p; call goErr
- write (gol,'(" x : ",e16.4)') x; call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- else
-
- i = 1
- do
- if ( x(n) < p+x(i) ) exit
- i = i + 1
- end do
- y0 = y(n) + (x0p-x(n))*(y(i)-y(n))/(modulo(x(i),p)-modulo(x(n),p))
- end if
-
-
- status = 0
- end subroutine linterp_1_circ
-
- subroutine linterp_1_row( x,y, x0, y0, status )
- use GO, only : gol, goErr
-
- real, intent(in) :: x(:), y(:)
- real, intent(in) :: x0(:)
- real, intent(out) :: y0(:)
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/linterp_1_row'
-
- integer :: n
- integer :: i
- integer :: last
-
-
- n = size(x0)
- if ( size(y0) /= n ) then
- write (gol,'("x and y should have same lengths:")'); call goErr
- write (gol,'(" size(x) : ",i6)') size(x); call goErr
- write (gol,'(" size(y) : ",i6)') size(y); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end if
-
- last = 0
- do i = 1, n
- call Interp_lin( x, y, x0(i), y0(i), last, status )
- if (status/=0) then; write (gol,'("ERROR in ",a)') rname; status=1; return; end if
- end do
-
-
- status = 0
- end subroutine linterp_1_row
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- subroutine Interp_MuHerm( x, y, x0, y0, status )
-
- real, intent(in) :: x(:)
- real, intent(in) :: y(size(x))
- real, intent(in) :: x0(:)
- real, intent(out) :: y0(size(x0))
- integer, intent(out) :: status
-
- character(len=*), parameter :: rname = mname//'/Interp_MuHerm'
-
- integer :: n, m
- integer :: last, mflag
- real :: fx(size(x))
- real :: a1, a2, a3, a4
- real :: g1, g2, g3
- real :: hp, hm
- real :: xi
- integer :: i, k
- integer :: il
-
- n = size(x)
- m = size(x0)
-
-
- g1=(2*x(1)-x(2)-x(3))/(x(1)-x(2))/(x(1)-x(3))
- g2=(x(1)-x(3))/(x(2)-x(1))/(x(2)-x(3))
- g3=(x(1)-x(2))/(x(3)-x(1))/(x(3)-x(2))
- fx(1)=g1*y(1)+g2*y(2)+g3*y(3)
- g1=(x(n)-x(n-1))/(x(n-2)-x(n-1))/(x(n-2)-x(n))
- g2=(x(n)-x(n-2))/(x(n-1)-x(n-2))/(x(n-1)-x(n))
- g3=(2*x(n)-x(n-1)-x(n-2))/(x(n)-x(n-2))/(x(n)-x(n-1))
- fx(n)=g1*y(n-2)+g2*y(n-1)+g3*y(n)
- do i = 2, n-1
- hp=x(i+1)-x(i)
- hm=x(i)-x(i-1)
- g1=-hp/(hm*(hp+hm))
- g2=(hp-hm)/(hp*hm)
- g3=hm/(hp*(hp+hm))
- fx(i)=y(i-1)*g1+y(i)*g2+y(i+1)*g3
- end do
-
-
- il=1
- do k = 1, m
- if(x0(k).lt.x(1)) then
- y0(k)=y(1)+fx(1)*(x0(k)-x(1))
- else if(x0(k).gt.x(n)) then
- y0(k)=y(n)+fx(n)*(x0(k)-x(n))
- else
- do
- if ( x0(k) .gt. x(il+1) ) then
- il=il+1
- cycle
- else
- xi=(x0(k)-x(il))/(x(il+1)-x(il))
- a1=f1(1-xi)
- a2=f1(xi)
- a3=-f2(1-xi)
- a4=f2(xi)
- y0(k)=a1*y(il)+a2*y(il+1)+(x(il+1)-x(il))*(a3*fx(il)+a4*fx(il+1))
- exit
- end if
- end do
- endif
- end do
-
- status = 0
- return
- contains
- real function f1(u)
- real, intent(in) :: u
- f1 = u*u*(-2*u+3)
- end function f1
- real function f2(u)
- real, intent(in) :: u
- f2 = u*u*(u-1)
- end function f2
- end subroutine Interp_MuHerm
-
-
- end module num_interp
|