Commit e711bb807cee3a51f1eae75b9041469bcb96f2af
1 parent
41811905dd
Exists in
master
and in
2 other branches
ChW 02/2010 for typing errors between sp_kind and ip_kind
git-svn-id: https://lxsd.femto-st.fr/svn/fvn@68 b657c933-2333-4658-acf2-d3c7c2708721
Showing 1 changed file with 20 additions and 19 deletions Inline Diff
fvn_interpol/fvn_interpol.f90
| module fvn_interpol | 1 | 1 | module fvn_interpol | |
| use fvn_common | 2 | 2 | use fvn_common | |
| implicit none | 3 | 3 | implicit none | |
| 4 | 4 | |||
| 5 | 5 | |||
| ! Utility procedure find interval | 6 | 6 | ! Utility procedure find interval | |
| interface fvn_find_interval | 7 | 7 | interface fvn_find_interval | |
| module procedure fvn_s_find_interval,fvn_d_find_interval | 8 | 8 | module procedure fvn_s_find_interval,fvn_d_find_interval | |
| end interface fvn_find_interval | 9 | 9 | end interface fvn_find_interval | |
| 10 | 10 | |||
| ! Quadratic 1D interpolation | 11 | 11 | ! Quadratic 1D interpolation | |
| interface fvn_quad_interpol | 12 | 12 | interface fvn_quad_interpol | |
| module procedure fvn_s_quad_interpol,fvn_d_quad_interpol | 13 | 13 | module procedure fvn_s_quad_interpol,fvn_d_quad_interpol | |
| end interface fvn_quad_interpol | 14 | 14 | end interface fvn_quad_interpol | |
| 15 | 15 | |||
| ! Quadratic 2D interpolation | 16 | 16 | ! Quadratic 2D interpolation | |
| interface fvn_quad_2d_interpol | 17 | 17 | interface fvn_quad_2d_interpol | |
| module procedure fvn_s_quad_2d_interpol,fvn_d_quad_2d_interpol | 18 | 18 | module procedure fvn_s_quad_2d_interpol,fvn_d_quad_2d_interpol | |
| end interface fvn_quad_2d_interpol | 19 | 19 | end interface fvn_quad_2d_interpol | |
| 20 | 20 | |||
| ! Quadratic 3D interpolation | 21 | 21 | ! Quadratic 3D interpolation | |
| interface fvn_quad_3d_interpol | 22 | 22 | interface fvn_quad_3d_interpol | |
| module procedure fvn_s_quad_3d_interpol,fvn_d_quad_3d_interpol | 23 | 23 | module procedure fvn_s_quad_3d_interpol,fvn_d_quad_3d_interpol | |
| end interface fvn_quad_3d_interpol | 24 | 24 | end interface fvn_quad_3d_interpol | |
| 25 | 25 | |||
| ! Akima interpolation | 26 | 26 | ! Akima interpolation | |
| interface fvn_akima | 27 | 27 | interface fvn_akima | |
| module procedure fvn_s_akima,fvn_d_akima | 28 | 28 | module procedure fvn_s_akima,fvn_d_akima | |
| end interface fvn_akima | 29 | 29 | end interface fvn_akima | |
| 30 | 30 | |||
| ! Akima evaluation | 31 | 31 | ! Akima evaluation | |
| interface fvn_spline_eval | 32 | 32 | interface fvn_spline_eval | |
| module procedure fvn_s_spline_eval,fvn_d_spline_eval | 33 | 33 | module procedure fvn_s_spline_eval,fvn_d_spline_eval | |
| end interface fvn_spline_eval | 34 | 34 | end interface fvn_spline_eval | |
| 35 | 35 | |||
| contains | 36 | 36 | contains | |
| 37 | 37 | |||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 38 | 38 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| ! | 39 | 39 | ! | |
| ! Quadratic interpolation of tabulated function of 1,2 or 3 variables | 40 | 40 | ! Quadratic interpolation of tabulated function of 1,2 or 3 variables | |
| ! | 41 | 41 | ! | |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 42 | 42 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| 43 | 43 | |||
| subroutine fvn_s_find_interval(x,i,xdata,n) | 44 | 44 | subroutine fvn_s_find_interval(x,i,xdata,n) | |
| implicit none | 45 | 45 | implicit none | |
| ! This routine find the indice i where xdata(i) <= x < xdata(i+1) | 46 | 46 | ! This routine find the indice i where xdata(i) <= x < xdata(i+1) | |
| ! xdata(n) must contains a set of increasingly ordered values | 47 | 47 | ! xdata(n) must contains a set of increasingly ordered values | |
| ! if x < xdata(1) i=0 is returned | 48 | 48 | ! if x < xdata(1) i=0 is returned | |
| ! if x > xdata(n) i=n is returned | 49 | 49 | ! if x > xdata(n) i=n is returned | |
| ! special case is where x=xdata(n) then n-1 is returned so | 50 | 50 | ! special case is where x=xdata(n) then n-1 is returned so | |
| ! we will not exclude the upper limit | 51 | 51 | ! we will not exclude the upper limit | |
| ! a simple dichotomy method is used | 52 | 52 | ! a simple dichotomy method is used | |
| 53 | 53 | |||
| real(kind=sp_kind), intent(in) :: x | 54 | 54 | real(kind=sp_kind), intent(in) :: x | |
| integer(kind=sp_kind), intent(in) :: n | 55 | 55 | integer(kind=ip_kind), intent(in) :: n | |
| real(kind=sp_kind), intent(in), dimension(n) :: xdata | 56 | 56 | real(kind=sp_kind), intent(in), dimension(n) :: xdata | |
| integer(kind=sp_kind), intent(out) :: i | 57 | 57 | integer(kind=ip_kind), intent(out) :: i | |
| 58 | 58 | |||
| integer(kind=sp_kind) :: imin,imax,imoyen | 59 | 59 | integer(kind=ip_kind) :: imin,imax,imoyen | |
| 60 | 60 | |||
| ! special case is where x=xdata(n) then n-1 is returned so | 61 | 61 | ! special case is where x=xdata(n) then n-1 is returned so | |
| ! we will not exclude the upper limit | 62 | 62 | ! we will not exclude the upper limit | |
| if (x == xdata(n)) then | 63 | 63 | if (x == xdata(n)) then | |
| i=n-1 | 64 | 64 | i=n-1 | |
| return | 65 | 65 | return | |
| end if | 66 | 66 | end if | |
| 67 | 67 | |||
| ! if x < xdata(1) i=0 is returned | 68 | 68 | ! if x < xdata(1) i=0 is returned | |
| if (x < xdata(1)) then | 69 | 69 | if (x < xdata(1)) then | |
| i=0 | 70 | 70 | i=0 | |
| return | 71 | 71 | return | |
| end if | 72 | 72 | end if | |
| 73 | 73 | |||
| ! if x > xdata(n) i=n is returned | 74 | 74 | ! if x > xdata(n) i=n is returned | |
| if (x > xdata(n)) then | 75 | 75 | if (x > xdata(n)) then | |
| i=n | 76 | 76 | i=n | |
| return | 77 | 77 | return | |
| end if | 78 | 78 | end if | |
| 79 | 79 | |||
| ! here xdata(1) <= x <= xdata(n) | 80 | 80 | ! here xdata(1) <= x <= xdata(n) | |
| imin=0 | 81 | 81 | imin=0 | |
| imax=n+1 | 82 | 82 | imax=n+1 | |
| 83 | 83 | |||
| do while((imax-imin) > 1) | 84 | 84 | do while((imax-imin) > 1) | |
| imoyen=(imax+imin)/2 | 85 | 85 | imoyen=(imax+imin)/2 | |
| if (x >= xdata(imoyen)) then | 86 | 86 | if (x >= xdata(imoyen)) then | |
| imin=imoyen | 87 | 87 | imin=imoyen | |
| else | 88 | 88 | else | |
| imax=imoyen | 89 | 89 | imax=imoyen | |
| end if | 90 | 90 | end if | |
| end do | 91 | 91 | end do | |
| 92 | 92 | |||
| i=imin | 93 | 93 | i=imin | |
| 94 | 94 | |||
| end subroutine | 95 | 95 | end subroutine | |
| 96 | 96 | |||
| 97 | 97 | |||
| subroutine fvn_d_find_interval(x,i,xdata,n) | 98 | 98 | subroutine fvn_d_find_interval(x,i,xdata,n) | |
| implicit none | 99 | 99 | implicit none | |
| ! This routine find the indice i where xdata(i) <= x < xdata(i+1) | 100 | 100 | ! This routine find the indice i where xdata(i) <= x < xdata(i+1) | |
| ! xdata(n) must contains a set of increasingly ordered values | 101 | 101 | ! xdata(n) must contains a set of increasingly ordered values | |
| ! if x < xdata(1) i=0 is returned | 102 | 102 | ! if x < xdata(1) i=0 is returned | |
| ! if x > xdata(n) i=n is returned | 103 | 103 | ! if x > xdata(n) i=n is returned | |
| ! special case is where x=xdata(n) then n-1 is returned so | 104 | 104 | ! special case is where x=xdata(n) then n-1 is returned so | |
| ! we will not exclude the upper limit | 105 | 105 | ! we will not exclude the upper limit | |
| ! a simple dichotomy method is used | 106 | 106 | ! a simple dichotomy method is used | |
| 107 | 107 | |||
| real(kind=dp_kind), intent(in) :: x | 108 | 108 | real(kind=dp_kind), intent(in) :: x | |
| integer(kind=sp_kind), intent(in) :: n | 109 | 109 | integer(kind=ip_kind), intent(in) :: n | |
| real(kind=dp_kind), intent(in), dimension(n) :: xdata | 110 | 110 | real(kind=dp_kind), intent(in), dimension(n) :: xdata | |
| integer(kind=sp_kind), intent(out) :: i | 111 | 111 | integer(kind=ip_kind), intent(out) :: i | |
| 112 | 112 | |||
| integer(kind=sp_kind) :: imin,imax,imoyen | 113 | 113 | integer(kind=ip_kind) :: imin,imax,imoyen | |
| 114 | 114 | |||
| ! special case is where x=xdata(n) then n-1 is returned so | 115 | 115 | ! special case is where x=xdata(n) then n-1 is returned so | |
| ! we will not exclude the upper limit | 116 | 116 | ! we will not exclude the upper limit | |
| if (x == xdata(n)) then | 117 | 117 | if (x == xdata(n)) then | |
| i=n-1 | 118 | 118 | i=n-1 | |
| return | 119 | 119 | return | |
| end if | 120 | 120 | end if | |
| 121 | 121 | |||
| ! if x < xdata(1) i=0 is returned | 122 | 122 | ! if x < xdata(1) i=0 is returned | |
| if (x < xdata(1)) then | 123 | 123 | if (x < xdata(1)) then | |
| i=0 | 124 | 124 | i=0 | |
| return | 125 | 125 | return | |
| end if | 126 | 126 | end if | |
| 127 | 127 | |||
| ! if x > xdata(n) i=n is returned | 128 | 128 | ! if x > xdata(n) i=n is returned | |
| if (x > xdata(n)) then | 129 | 129 | if (x > xdata(n)) then | |
| i=n | 130 | 130 | i=n | |
| return | 131 | 131 | return | |
| end if | 132 | 132 | end if | |
| 133 | 133 | |||
| ! here xdata(1) <= x <= xdata(n) | 134 | 134 | ! here xdata(1) <= x <= xdata(n) | |
| imin=0 | 135 | 135 | imin=0 | |
| imax=n+1 | 136 | 136 | imax=n+1 | |
| 137 | 137 | |||
| do while((imax-imin) > 1) | 138 | 138 | do while((imax-imin) > 1) | |
| imoyen=(imax+imin)/2 | 139 | 139 | imoyen=(imax+imin)/2 | |
| if (x >= xdata(imoyen)) then | 140 | 140 | if (x >= xdata(imoyen)) then | |
| imin=imoyen | 141 | 141 | imin=imoyen | |
| else | 142 | 142 | else | |
| imax=imoyen | 143 | 143 | imax=imoyen | |
| end if | 144 | 144 | end if | |
| end do | 145 | 145 | end do | |
| 146 | 146 | |||
| i=imin | 147 | 147 | i=imin | |
| 148 | 148 | |||
| end subroutine | 149 | 149 | end subroutine | |
| 150 | 150 | |||
| 151 | 151 | |||
| function fvn_s_quad_interpol(x,n,xdata,ydata) | 152 | 152 | function fvn_s_quad_interpol(x,n,xdata,ydata) | |
| implicit none | 153 | 153 | implicit none | |
| ! This function evaluate the value of a function defined by a set of points | 154 | 154 | ! This function evaluate the value of a function defined by a set of points | |
| ! and values, using a quadratic interpolation | 155 | 155 | ! and values, using a quadratic interpolation | |
| ! xdata must be increasingly ordered | 156 | 156 | ! xdata must be increasingly ordered | |
| ! x must be within xdata(1) and xdata(n) to actually do interpolation | 157 | 157 | ! x must be within xdata(1) and xdata(n) to actually do interpolation | |
| ! otherwise extrapolation is done | 158 | 158 | ! otherwise extrapolation is done | |
| integer(kind=sp_kind), intent(in) :: n | 159 | 159 | integer(kind=ip_kind), intent(in) :: n | |
| real(kind=sp_kind), intent(in), dimension(n) :: xdata,ydata | 160 | 160 | real(kind=sp_kind), intent(in), dimension(n) :: xdata,ydata | |
| real(kind=sp_kind), intent(in) :: x | 161 | 161 | real(kind=sp_kind), intent(in) :: x | |
| real(kind=sp_kind) :: fvn_s_quad_interpol | 162 | 162 | real(kind=sp_kind) :: fvn_s_quad_interpol | |
| 163 | 163 | |||
| integer(kind=sp_kind) :: iinf,base,i,j | 164 | 164 | integer(kind=ip_kind) :: iinf,base,i,j | |
| real(kind=sp_kind) :: p | 165 | 165 | real(kind=sp_kind) :: p | |
| 166 | 166 | |||
| call fvn_s_find_interval(x,iinf,xdata,n) | 167 | 167 | call fvn_s_find_interval(x,iinf,xdata,n) | |
| 168 | 168 | |||
| ! Settings for extrapolation | 169 | 169 | ! Settings for extrapolation | |
| if (iinf==0) then | 170 | 170 | if (iinf==0) then | |
| ! TODO -> Lower bound extrapolation warning | 171 | 171 | ! TODO -> Lower bound extrapolation warning | |
| iinf=1 | 172 | 172 | iinf=1 | |
| end if | 173 | 173 | end if | |
| 174 | 174 | |||
| if (iinf==n) then | 175 | 175 | if (iinf==n) then | |
| ! TODO -> Higher bound extrapolation warning | 176 | 176 | ! TODO -> Higher bound extrapolation warning | |
| iinf=n-1 | 177 | 177 | iinf=n-1 | |
| end if | 178 | 178 | end if | |
| 179 | 179 | |||
| ! The three points we will use are iinf-1,iinf and iinf+1 with the | 180 | 180 | ! The three points we will use are iinf-1,iinf and iinf+1 with the | |
| ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | 181 | 181 | ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | |
| if (iinf==1) then | 182 | 182 | if (iinf==1) then | |
| base=0 | 183 | 183 | base=0 | |
| else | 184 | 184 | else | |
| base=iinf-2 | 185 | 185 | base=iinf-2 | |
| end if | 186 | 186 | end if | |
| 187 | 187 | |||
| ! The three points we will use are : | 188 | 188 | ! The three points we will use are : | |
| ! xdata/ydata(base+1),xdata/ydata(base+2),xdata/ydata(base+3) | 189 | 189 | ! xdata/ydata(base+1),xdata/ydata(base+2),xdata/ydata(base+3) | |
| 190 | 190 | |||
| ! Straight forward Lagrange polynomial | 191 | 191 | ! Straight forward Lagrange polynomial | |
| fvn_s_quad_interpol=0. | 192 | 192 | fvn_s_quad_interpol=0. | |
| do i=1,3 | 193 | 193 | do i=1,3 | |
| ! polynome i | 194 | 194 | ! polynome i | |
| p=ydata(base+i) | 195 | 195 | p=ydata(base+i) | |
| do j=1,3 | 196 | 196 | do j=1,3 | |
| if (j /= i) then | 197 | 197 | if (j /= i) then | |
| p=p*(x-xdata(base+j))/(xdata(base+i)-xdata(base+j)) | 198 | 198 | p=p*(x-xdata(base+j))/(xdata(base+i)-xdata(base+j)) | |
| end if | 199 | 199 | end if | |
| end do | 200 | 200 | end do | |
| fvn_s_quad_interpol=fvn_s_quad_interpol+p | 201 | 201 | fvn_s_quad_interpol=fvn_s_quad_interpol+p | |
| end do | 202 | 202 | end do | |
| 203 | 203 | |||
| end function | 204 | 204 | end function | |
| 205 | 205 | |||
| 206 | 206 | |||
| function fvn_d_quad_interpol(x,n,xdata,ydata) | 207 | 207 | function fvn_d_quad_interpol(x,n,xdata,ydata) | |
| implicit none | 208 | 208 | implicit none | |
| ! This function evaluate the value of a function defined by a set of points | 209 | 209 | ! This function evaluate the value of a function defined by a set of points | |
| ! and values, using a quadratic interpolation | 210 | 210 | ! and values, using a quadratic interpolation | |
| ! xdata must be increasingly ordered | 211 | 211 | ! xdata must be increasingly ordered | |
| ! x must be within xdata(1) and xdata(n) to actually do interpolation | 212 | 212 | ! x must be within xdata(1) and xdata(n) to actually do interpolation | |
| ! otherwise extrapolation is done | 213 | 213 | ! otherwise extrapolation is done | |
| integer(kind=sp_kind), intent(in) :: n | 214 | 214 | integer(kind=ip_kind), intent(in) :: n | |
| real(kind=dp_kind), intent(in), dimension(n) :: xdata,ydata | 215 | 215 | real(kind=dp_kind), intent(in), dimension(n) :: xdata,ydata | |
| real(kind=dp_kind), intent(in) :: x | 216 | 216 | real(kind=dp_kind), intent(in) :: x | |
| real(kind=dp_kind) :: fvn_d_quad_interpol | 217 | 217 | real(kind=dp_kind) :: fvn_d_quad_interpol | |
| 218 | 218 | |||
| integer(kind=sp_kind) :: iinf,base,i,j | 219 | 219 | integer(kind=ip_kind) :: iinf,base,i,j | |
| real(kind=dp_kind) :: p | 220 | 220 | real(kind=dp_kind) :: p | |
| 221 | 221 | |||
| call fvn_d_find_interval(x,iinf,xdata,n) | 222 | 222 | call fvn_d_find_interval(x,iinf,xdata,n) | |
| 223 | 223 | |||
| ! Settings for extrapolation | 224 | 224 | ! Settings for extrapolation | |
| if (iinf==0) then | 225 | 225 | if (iinf==0) then | |
| ! TODO -> Lower bound extrapolation warning | 226 | 226 | ! TODO -> Lower bound extrapolation warning | |
| iinf=1 | 227 | 227 | iinf=1 | |
| end if | 228 | 228 | end if | |
| 229 | 229 | |||
| if (iinf==n) then | 230 | 230 | if (iinf==n) then | |
| ! TODO Higher bound extrapolation warning | 231 | 231 | ! TODO Higher bound extrapolation warning | |
| iinf=n-1 | 232 | 232 | iinf=n-1 | |
| end if | 233 | 233 | end if | |
| 234 | 234 | |||
| ! The three points we will use are iinf-1,iinf and iinf+1 with the | 235 | 235 | ! The three points we will use are iinf-1,iinf and iinf+1 with the | |
| ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | 236 | 236 | ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | |
| if (iinf==1) then | 237 | 237 | if (iinf==1) then | |
| base=0 | 238 | 238 | base=0 | |
| else | 239 | 239 | else | |
| base=iinf-2 | 240 | 240 | base=iinf-2 | |
| end if | 241 | 241 | end if | |
| 242 | 242 | |||
| ! The three points we will use are : | 243 | 243 | ! The three points we will use are : | |
| ! xdata/ydata(base+1),xdata/ydata(base+2),xdata/ydata(base+3) | 244 | 244 | ! xdata/ydata(base+1),xdata/ydata(base+2),xdata/ydata(base+3) | |
| 245 | 245 | |||
| ! Straight forward Lagrange polynomial | 246 | 246 | ! Straight forward Lagrange polynomial | |
| fvn_d_quad_interpol=0. | 247 | 247 | fvn_d_quad_interpol=0. | |
| do i=1,3 | 248 | 248 | do i=1,3 | |
| ! polynome i | 249 | 249 | ! polynome i | |
| p=ydata(base+i) | 250 | 250 | p=ydata(base+i) | |
| do j=1,3 | 251 | 251 | do j=1,3 | |
| if (j /= i) then | 252 | 252 | if (j /= i) then | |
| p=p*(x-xdata(base+j))/(xdata(base+i)-xdata(base+j)) | 253 | 253 | p=p*(x-xdata(base+j))/(xdata(base+i)-xdata(base+j)) | |
| end if | 254 | 254 | end if | |
| end do | 255 | 255 | end do | |
| fvn_d_quad_interpol=fvn_d_quad_interpol+p | 256 | 256 | fvn_d_quad_interpol=fvn_d_quad_interpol+p | |
| end do | 257 | 257 | end do | |
| 258 | 258 | |||
| end function | 259 | 259 | end function | |
| 260 | 260 | |||
| 261 | 261 | |||
| function fvn_s_quad_2d_interpol(x,y,nx,xdata,ny,ydata,zdata) | 262 | 262 | function fvn_s_quad_2d_interpol(x,y,nx,xdata,ny,ydata,zdata) | |
| implicit none | 263 | 263 | implicit none | |
| ! This function evaluate the value of a two variable function defined by a | 264 | 264 | ! This function evaluate the value of a two variable function defined by a | |
| ! set of points and values, using a quadratic interpolation | 265 | 265 | ! set of points and values, using a quadratic interpolation | |
| ! xdata and ydata must be increasingly ordered | 266 | 266 | ! xdata and ydata must be increasingly ordered | |
| ! the couple (x,y) must be as x within xdata(1) and xdata(nx) and | 267 | 267 | ! the couple (x,y) must be as x within xdata(1) and xdata(nx) and | |
| ! y within ydata(1) and ydata(ny) to actually do interpolation | 268 | 268 | ! y within ydata(1) and ydata(ny) to actually do interpolation | |
| ! otherwise extrapolation is done | 269 | 269 | ! otherwise extrapolation is done | |
| integer(kind=sp_kind), intent(in) :: nx,ny | 270 | 270 | integer(kind=ip_kind), intent(in) :: nx,ny | |
| real(kind=sp_kind), intent(in) :: x,y | 271 | 271 | real(kind=sp_kind), intent(in) :: x,y | |
| real(kind=sp_kind), intent(in), dimension(nx) :: xdata | 272 | 272 | real(kind=sp_kind), intent(in), dimension(nx) :: xdata | |
| real(kind=sp_kind), intent(in), dimension(ny) :: ydata | 273 | 273 | real(kind=sp_kind), intent(in), dimension(ny) :: ydata | |
| real(kind=sp_kind), intent(in), dimension(nx,ny) :: zdata | 274 | 274 | real(kind=sp_kind), intent(in), dimension(nx,ny) :: zdata | |
| real(kind=sp_kind) :: fvn_s_quad_2d_interpol | 275 | 275 | real(kind=sp_kind) :: fvn_s_quad_2d_interpol | |
| 276 | 276 | |||
| integer(kind=sp_kind) :: ixinf,iyinf,basex,basey,i | 277 | 277 | integer(kind=ip_kind) :: ixinf,iyinf,basex,basey,i | |
| real(kind=sp_kind),dimension(3) :: ztmp | 278 | 278 | real(kind=sp_kind),dimension(3) :: ztmp | |
| !real(kind=4), external :: fvn_s_quad_interpol | 279 | 279 | !real(kind=4), external :: fvn_s_quad_interpol | |
| 280 | 280 | |||
| call fvn_s_find_interval(x,ixinf,xdata,nx) | 281 | 281 | call fvn_s_find_interval(x,ixinf,xdata,nx) | |
| call fvn_s_find_interval(y,iyinf,ydata,ny) | 282 | 282 | call fvn_s_find_interval(y,iyinf,ydata,ny) | |
| 283 | 283 | |||
| ! Settings for extrapolation | 284 | 284 | ! Settings for extrapolation | |
| if (ixinf==0) then | 285 | 285 | if (ixinf==0) then | |
| ! TODO -> Lower x bound extrapolation warning | 286 | 286 | ! TODO -> Lower x bound extrapolation warning | |
| ixinf=1 | 287 | 287 | ixinf=1 | |
| end if | 288 | 288 | end if | |
| 289 | 289 | |||
| if (ixinf==nx) then | 290 | 290 | if (ixinf==nx) then | |
| ! TODO -> Higher x bound extrapolation warning | 291 | 291 | ! TODO -> Higher x bound extrapolation warning | |
| ixinf=nx-1 | 292 | 292 | ixinf=nx-1 | |
| end if | 293 | 293 | end if | |
| 294 | 294 | |||
| if (iyinf==0) then | 295 | 295 | if (iyinf==0) then | |
| ! TODO -> Lower y bound extrapolation warning | 296 | 296 | ! TODO -> Lower y bound extrapolation warning | |
| iyinf=1 | 297 | 297 | iyinf=1 | |
| end if | 298 | 298 | end if | |
| 299 | 299 | |||
| if (iyinf==ny) then | 300 | 300 | if (iyinf==ny) then | |
| ! TODO -> Higher y bound extrapolation warning | 301 | 301 | ! TODO -> Higher y bound extrapolation warning | |
| iyinf=ny-1 | 302 | 302 | iyinf=ny-1 | |
| end if | 303 | 303 | end if | |
| 304 | 304 | |||
| ! The three points we will use are iinf-1,iinf and iinf+1 with the | 305 | 305 | ! The three points we will use are iinf-1,iinf and iinf+1 with the | |
| ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | 306 | 306 | ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | |
| if (ixinf==1) then | 307 | 307 | if (ixinf==1) then | |
| basex=0 | 308 | 308 | basex=0 | |
| else | 309 | 309 | else | |
| basex=ixinf-2 | 310 | 310 | basex=ixinf-2 | |
| end if | 311 | 311 | end if | |
| 312 | 312 | |||
| if (iyinf==1) then | 313 | 313 | if (iyinf==1) then | |
| basey=0 | 314 | 314 | basey=0 | |
| else | 315 | 315 | else | |
| basey=iyinf-2 | 316 | 316 | basey=iyinf-2 | |
| end if | 317 | 317 | end if | |
| 318 | 318 | |||
| ! First we make 3 interpolations for x at y(base+1),y(base+2),y(base+3) | 319 | 319 | ! First we make 3 interpolations for x at y(base+1),y(base+2),y(base+3) | |
| ! stored in ztmp(1:3) | 320 | 320 | ! stored in ztmp(1:3) | |
| do i=1,3 | 321 | 321 | do i=1,3 | |
| ztmp(i)=fvn_s_quad_interpol(x,nx,xdata,zdata(:,basey+i)) | 322 | 322 | ztmp(i)=fvn_s_quad_interpol(x,nx,xdata,zdata(:,basey+i)) | |
| end do | 323 | 323 | end do | |
| 324 | 324 | |||
| ! Then we make an interpolation for y using previous interpolations | 325 | 325 | ! Then we make an interpolation for y using previous interpolations | |
| fvn_s_quad_2d_interpol=fvn_s_quad_interpol(y,3,ydata(basey+1:basey+3),ztmp) | 326 | 326 | fvn_s_quad_2d_interpol=fvn_s_quad_interpol(y,3,ydata(basey+1:basey+3),ztmp) | |
| end function | 327 | 327 | end function | |
| 328 | 328 | |||
| 329 | 329 | |||
| function fvn_d_quad_2d_interpol(x,y,nx,xdata,ny,ydata,zdata) | 330 | 330 | function fvn_d_quad_2d_interpol(x,y,nx,xdata,ny,ydata,zdata) | |
| implicit none | 331 | 331 | implicit none | |
| ! This function evaluate the value of a two variable function defined by a | 332 | 332 | ! This function evaluate the value of a two variable function defined by a | |
| ! set of points and values, using a quadratic interpolation | 333 | 333 | ! set of points and values, using a quadratic interpolation | |
| ! xdata and ydata must be increasingly ordered | 334 | 334 | ! xdata and ydata must be increasingly ordered | |
| ! the couple (x,y) must be as x within xdata(1) and xdata(nx) and | 335 | 335 | ! the couple (x,y) must be as x within xdata(1) and xdata(nx) and | |
| ! y within ydata(1) and ydata(ny) to actually do interpolation | 336 | 336 | ! y within ydata(1) and ydata(ny) to actually do interpolation | |
| ! otherwise extrapolation is done | 337 | 337 | ! otherwise extrapolation is done | |
| integer(kind=sp_kind), intent(in) :: nx,ny | 338 | 338 | integer(kind=ip_kind), intent(in) :: nx,ny | |
| real(kind=dp_kind), intent(in) :: x,y | 339 | 339 | real(kind=dp_kind), intent(in) :: x,y | |
| real(kind=dp_kind), intent(in), dimension(nx) :: xdata | 340 | 340 | real(kind=dp_kind), intent(in), dimension(nx) :: xdata | |
| real(kind=dp_kind), intent(in), dimension(ny) :: ydata | 341 | 341 | real(kind=dp_kind), intent(in), dimension(ny) :: ydata | |
| real(kind=dp_kind), intent(in), dimension(nx,ny) :: zdata | 342 | 342 | real(kind=dp_kind), intent(in), dimension(nx,ny) :: zdata | |
| real(kind=dp_kind) :: fvn_d_quad_2d_interpol | 343 | 343 | real(kind=dp_kind) :: fvn_d_quad_2d_interpol | |
| 344 | 344 | |||
| integer(kind=sp_kind) :: ixinf,iyinf,basex,basey,i | 345 | 345 | integer(kind=ip_kind) :: ixinf,iyinf,basex,basey,i | |
| real(kind=dp_kind),dimension(3) :: ztmp | 346 | 346 | real(kind=dp_kind),dimension(3) :: ztmp | |
| !real(kind=8), external :: fvn_d_quad_interpol | 347 | 347 | !real(kind=8), external :: fvn_d_quad_interpol | |
| 348 | 348 | |||
| call fvn_d_find_interval(x,ixinf,xdata,nx) | 349 | 349 | call fvn_d_find_interval(x,ixinf,xdata,nx) | |
| call fvn_d_find_interval(y,iyinf,ydata,ny) | 350 | 350 | call fvn_d_find_interval(y,iyinf,ydata,ny) | |
| 351 | 351 | |||
| ! Settings for extrapolation | 352 | 352 | ! Settings for extrapolation | |
| if (ixinf==0) then | 353 | 353 | if (ixinf==0) then | |
| ! TODO -> Lower x bound extrapolation warning | 354 | 354 | ! TODO -> Lower x bound extrapolation warning | |
| ixinf=1 | 355 | 355 | ixinf=1 | |
| end if | 356 | 356 | end if | |
| 357 | 357 | |||
| if (ixinf==nx) then | 358 | 358 | if (ixinf==nx) then | |
| ! TODO -> Higher x bound extrapolation warning | 359 | 359 | ! TODO -> Higher x bound extrapolation warning | |
| ixinf=nx-1 | 360 | 360 | ixinf=nx-1 | |
| end if | 361 | 361 | end if | |
| 362 | 362 | |||
| if (iyinf==0) then | 363 | 363 | if (iyinf==0) then | |
| ! TODO -> Lower y bound extrapolation warning | 364 | 364 | ! TODO -> Lower y bound extrapolation warning | |
| iyinf=1 | 365 | 365 | iyinf=1 | |
| end if | 366 | 366 | end if | |
| 367 | 367 | |||
| if (iyinf==ny) then | 368 | 368 | if (iyinf==ny) then | |
| ! TODO -> Higher y bound extrapolation warning | 369 | 369 | ! TODO -> Higher y bound extrapolation warning | |
| iyinf=ny-1 | 370 | 370 | iyinf=ny-1 | |
| end if | 371 | 371 | end if | |
| 372 | 372 | |||
| ! The three points we will use are iinf-1,iinf and iinf+1 with the | 373 | 373 | ! The three points we will use are iinf-1,iinf and iinf+1 with the | |
| ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | 374 | 374 | ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | |
| if (ixinf==1) then | 375 | 375 | if (ixinf==1) then | |
| basex=0 | 376 | 376 | basex=0 | |
| else | 377 | 377 | else | |
| basex=ixinf-2 | 378 | 378 | basex=ixinf-2 | |
| end if | 379 | 379 | end if | |
| 380 | 380 | |||
| if (iyinf==1) then | 381 | 381 | if (iyinf==1) then | |
| basey=0 | 382 | 382 | basey=0 | |
| else | 383 | 383 | else | |
| basey=iyinf-2 | 384 | 384 | basey=iyinf-2 | |
| end if | 385 | 385 | end if | |
| 386 | 386 | |||
| ! First we make 3 interpolations for x at y(base+1),y(base+2),y(base+3) | 387 | 387 | ! First we make 3 interpolations for x at y(base+1),y(base+2),y(base+3) | |
| ! stored in ztmp(1:3) | 388 | 388 | ! stored in ztmp(1:3) | |
| do i=1,3 | 389 | 389 | do i=1,3 | |
| ztmp(i)=fvn_d_quad_interpol(x,nx,xdata,zdata(:,basey+i)) | 390 | 390 | ztmp(i)=fvn_d_quad_interpol(x,nx,xdata,zdata(:,basey+i)) | |
| end do | 391 | 391 | end do | |
| 392 | 392 | |||
| ! Then we make an interpolation for y using previous interpolations | 393 | 393 | ! Then we make an interpolation for y using previous interpolations | |
| fvn_d_quad_2d_interpol=fvn_d_quad_interpol(y,3,ydata(basey+1:basey+3),ztmp) | 394 | 394 | fvn_d_quad_2d_interpol=fvn_d_quad_interpol(y,3,ydata(basey+1:basey+3),ztmp) | |
| end function | 395 | 395 | end function | |
| 396 | 396 | |||
| 397 | 397 | |||
| function fvn_s_quad_3d_interpol(x,y,z,nx,xdata,ny,ydata,nz,zdata,tdata) | 398 | 398 | function fvn_s_quad_3d_interpol(x,y,z,nx,xdata,ny,ydata,nz,zdata,tdata) | |
| implicit none | 399 | 399 | implicit none | |
| ! This function evaluate the value of a 3 variables function defined by a | 400 | 400 | ! This function evaluate the value of a 3 variables function defined by a | |
| ! set of points and values, using a quadratic interpolation | 401 | 401 | ! set of points and values, using a quadratic interpolation | |
| ! xdata, ydata and zdata must be increasingly ordered | 402 | 402 | ! xdata, ydata and zdata must be increasingly ordered | |
| ! The triplet (x,y,z) must be within xdata,ydata and zdata to actually | 403 | 403 | ! The triplet (x,y,z) must be within xdata,ydata and zdata to actually | |
| ! perform an interpolation, otherwise extrapolation is done | 404 | 404 | ! perform an interpolation, otherwise extrapolation is done | |
| integer(kind=sp_kind), intent(in) :: nx,ny,nz | 405 | 405 | integer(kind=ip_kind), intent(in) :: nx,ny,nz | |
| real(kind=sp_kind), intent(in) :: x,y,z | 406 | 406 | real(kind=sp_kind), intent(in) :: x,y,z | |
| real(kind=sp_kind), intent(in), dimension(nx) :: xdata | 407 | 407 | real(kind=sp_kind), intent(in), dimension(nx) :: xdata | |
| real(kind=sp_kind), intent(in), dimension(ny) :: ydata | 408 | 408 | real(kind=sp_kind), intent(in), dimension(ny) :: ydata | |
| real(kind=sp_kind), intent(in), dimension(nz) :: zdata | 409 | 409 | real(kind=sp_kind), intent(in), dimension(nz) :: zdata | |
| real(kind=sp_kind), intent(in), dimension(nx,ny,nz) :: tdata | 410 | 410 | real(kind=sp_kind), intent(in), dimension(nx,ny,nz) :: tdata | |
| real(kind=sp_kind) :: fvn_s_quad_3d_interpol | 411 | 411 | real(kind=sp_kind) :: fvn_s_quad_3d_interpol | |
| 412 | 412 | |||
| integer(kind=sp_kind) :: ixinf,iyinf,izinf,basex,basey,basez,i,j | 413 | 413 | integer(kind=ip_kind) :: ixinf,iyinf,izinf,basex,basey,basez,i,j | |
| !real(kind=4), external :: fvn_s_quad_interpol,fvn_s_quad_2d_interpol | 414 | 414 | !real(kind=4), external :: fvn_s_quad_interpol,fvn_s_quad_2d_interpol | |
| real(kind=sp_kind),dimension(3,3) :: ttmp | 415 | 415 | real(kind=sp_kind),dimension(3,3) :: ttmp | |
| 416 | 416 | |||
| call fvn_s_find_interval(x,ixinf,xdata,nx) | 417 | 417 | call fvn_s_find_interval(x,ixinf,xdata,nx) | |
| call fvn_s_find_interval(y,iyinf,ydata,ny) | 418 | 418 | call fvn_s_find_interval(y,iyinf,ydata,ny) | |
| call fvn_s_find_interval(z,izinf,zdata,nz) | 419 | 419 | call fvn_s_find_interval(z,izinf,zdata,nz) | |
| 420 | 420 | |||
| ! Settings for extrapolation | 421 | 421 | ! Settings for extrapolation | |
| if (ixinf==0) then | 422 | 422 | if (ixinf==0) then | |
| ! TODO -> Lower x bound extrapolation warning | 423 | 423 | ! TODO -> Lower x bound extrapolation warning | |
| ixinf=1 | 424 | 424 | ixinf=1 | |
| end if | 425 | 425 | end if | |
| 426 | 426 | |||
| if (ixinf==nx) then | 427 | 427 | if (ixinf==nx) then | |
| ! TODO -> Higher x bound extrapolation warning | 428 | 428 | ! TODO -> Higher x bound extrapolation warning | |
| ixinf=nx-1 | 429 | 429 | ixinf=nx-1 | |
| end if | 430 | 430 | end if | |
| 431 | 431 | |||
| if (iyinf==0) then | 432 | 432 | if (iyinf==0) then | |
| ! TODO -> Lower y bound extrapolation warning | 433 | 433 | ! TODO -> Lower y bound extrapolation warning | |
| iyinf=1 | 434 | 434 | iyinf=1 | |
| end if | 435 | 435 | end if | |
| 436 | 436 | |||
| if (iyinf==ny) then | 437 | 437 | if (iyinf==ny) then | |
| ! TODO -> Higher y bound extrapolation warning | 438 | 438 | ! TODO -> Higher y bound extrapolation warning | |
| iyinf=ny-1 | 439 | 439 | iyinf=ny-1 | |
| end if | 440 | 440 | end if | |
| 441 | 441 | |||
| if (izinf==0) then | 442 | 442 | if (izinf==0) then | |
| ! TODO -> Lower z bound extrapolation warning | 443 | 443 | ! TODO -> Lower z bound extrapolation warning | |
| izinf=1 | 444 | 444 | izinf=1 | |
| end if | 445 | 445 | end if | |
| 446 | 446 | |||
| if (izinf==nz) then | 447 | 447 | if (izinf==nz) then | |
| ! TODO -> Higher z bound extrapolation warning | 448 | 448 | ! TODO -> Higher z bound extrapolation warning | |
| izinf=nz-1 | 449 | 449 | izinf=nz-1 | |
| end if | 450 | 450 | end if | |
| 451 | 451 | |||
| ! The three points we will use are iinf-1,iinf and iinf+1 with the | 452 | 452 | ! The three points we will use are iinf-1,iinf and iinf+1 with the | |
| ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | 453 | 453 | ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | |
| if (ixinf==1) then | 454 | 454 | if (ixinf==1) then | |
| basex=0 | 455 | 455 | basex=0 | |
| else | 456 | 456 | else | |
| basex=ixinf-2 | 457 | 457 | basex=ixinf-2 | |
| end if | 458 | 458 | end if | |
| 459 | 459 | |||
| if (iyinf==1) then | 460 | 460 | if (iyinf==1) then | |
| basey=0 | 461 | 461 | basey=0 | |
| else | 462 | 462 | else | |
| basey=iyinf-2 | 463 | 463 | basey=iyinf-2 | |
| end if | 464 | 464 | end if | |
| 465 | 465 | |||
| if (izinf==1) then | 466 | 466 | if (izinf==1) then | |
| basez=0 | 467 | 467 | basez=0 | |
| else | 468 | 468 | else | |
| basez=izinf-2 | 469 | 469 | basez=izinf-2 | |
| end if | 470 | 470 | end if | |
| 471 | 471 | |||
| ! We first make 9 one dimensional interpolation on variable x. | 472 | 472 | ! We first make 9 one dimensional interpolation on variable x. | |
| ! results are stored in ttmp | 473 | 473 | ! results are stored in ttmp | |
| do i=1,3 | 474 | 474 | do i=1,3 | |
| do j=1,3 | 475 | 475 | do j=1,3 | |
| ttmp(i,j)=fvn_s_quad_interpol(x,nx,xdata,tdata(:,basey+i,basez+j)) | 476 | 476 | ttmp(i,j)=fvn_s_quad_interpol(x,nx,xdata,tdata(:,basey+i,basez+j)) | |
| end do | 477 | 477 | end do | |
| end do | 478 | 478 | end do | |
| 479 | 479 | |||
| ! We then make a 2 dimensionnal interpolation on variables y and z | 480 | 480 | ! We then make a 2 dimensionnal interpolation on variables y and z | |
| fvn_s_quad_3d_interpol=fvn_s_quad_2d_interpol(y,z, & | 481 | 481 | fvn_s_quad_3d_interpol=fvn_s_quad_2d_interpol(y,z, & | |
| 3,ydata(basey+1:basey+3),3,zdata(basez+1:basez+3),ttmp) | 482 | 482 | 3,ydata(basey+1:basey+3),3,zdata(basez+1:basez+3),ttmp) | |
| end function | 483 | 483 | end function | |
| 484 | 484 | |||
| 485 | 485 | |||
| function fvn_d_quad_3d_interpol(x,y,z,nx,xdata,ny,ydata,nz,zdata,tdata) | 486 | 486 | function fvn_d_quad_3d_interpol(x,y,z,nx,xdata,ny,ydata,nz,zdata,tdata) | |
| implicit none | 487 | 487 | implicit none | |
| ! This function evaluate the value of a 3 variables function defined by a | 488 | 488 | ! This function evaluate the value of a 3 variables function defined by a | |
| ! set of points and values, using a quadratic interpolation | 489 | 489 | ! set of points and values, using a quadratic interpolation | |
| ! xdata, ydata and zdata must be increasingly ordered | 490 | 490 | ! xdata, ydata and zdata must be increasingly ordered | |
| ! The triplet (x,y,z) must be within xdata,ydata and zdata to actually | 491 | 491 | ! The triplet (x,y,z) must be within xdata,ydata and zdata to actually | |
| ! perform an interpolation, otherwise extrapolation is done | 492 | 492 | ! perform an interpolation, otherwise extrapolation is done | |
| integer(kind=sp_kind), intent(in) :: nx,ny,nz | 493 | 493 | integer(kind=ip_kind), intent(in) :: nx,ny,nz | |
| real(kind=dp_kind), intent(in) :: x,y,z | 494 | 494 | real(kind=dp_kind), intent(in) :: x,y,z | |
| real(kind=dp_kind), intent(in), dimension(nx) :: xdata | 495 | 495 | real(kind=dp_kind), intent(in), dimension(nx) :: xdata | |
| real(kind=dp_kind), intent(in), dimension(ny) :: ydata | 496 | 496 | real(kind=dp_kind), intent(in), dimension(ny) :: ydata | |
| real(kind=dp_kind), intent(in), dimension(nz) :: zdata | 497 | 497 | real(kind=dp_kind), intent(in), dimension(nz) :: zdata | |
| real(kind=dp_kind), intent(in), dimension(nx,ny,nz) :: tdata | 498 | 498 | real(kind=dp_kind), intent(in), dimension(nx,ny,nz) :: tdata | |
| real(kind=dp_kind) :: fvn_d_quad_3d_interpol | 499 | 499 | real(kind=dp_kind) :: fvn_d_quad_3d_interpol | |
| 500 | 500 | |||
| integer(kind=sp_kind) :: ixinf,iyinf,izinf,basex,basey,basez,i,j | 501 | 501 | integer(kind=ip_kind) :: ixinf,iyinf,izinf,basex,basey,basez,i,j | |
| !real(kind=8), external :: fvn_d_quad_interpol,fvn_d_quad_2d_interpol | 502 | 502 | !real(kind=8), external :: fvn_d_quad_interpol,fvn_d_quad_2d_interpol | |
| real(kind=dp_kind),dimension(3,3) :: ttmp | 503 | 503 | real(kind=dp_kind),dimension(3,3) :: ttmp | |
| 504 | 504 | |||
| call fvn_d_find_interval(x,ixinf,xdata,nx) | 505 | 505 | call fvn_d_find_interval(x,ixinf,xdata,nx) | |
| call fvn_d_find_interval(y,iyinf,ydata,ny) | 506 | 506 | call fvn_d_find_interval(y,iyinf,ydata,ny) | |
| call fvn_d_find_interval(z,izinf,zdata,nz) | 507 | 507 | call fvn_d_find_interval(z,izinf,zdata,nz) | |
| 508 | 508 | |||
| ! Settings for extrapolation | 509 | 509 | ! Settings for extrapolation | |
| if (ixinf==0) then | 510 | 510 | if (ixinf==0) then | |
| ! TODO -> Lower x bound extrapolation warning | 511 | 511 | ! TODO -> Lower x bound extrapolation warning | |
| ixinf=1 | 512 | 512 | ixinf=1 | |
| end if | 513 | 513 | end if | |
| 514 | 514 | |||
| if (ixinf==nx) then | 515 | 515 | if (ixinf==nx) then | |
| ! TODO -> Higher x bound extrapolation warning | 516 | 516 | ! TODO -> Higher x bound extrapolation warning | |
| ixinf=nx-1 | 517 | 517 | ixinf=nx-1 | |
| end if | 518 | 518 | end if | |
| 519 | 519 | |||
| if (iyinf==0) then | 520 | 520 | if (iyinf==0) then | |
| ! TODO -> Lower y bound extrapolation warning | 521 | 521 | ! TODO -> Lower y bound extrapolation warning | |
| iyinf=1 | 522 | 522 | iyinf=1 | |
| end if | 523 | 523 | end if | |
| 524 | 524 | |||
| if (iyinf==ny) then | 525 | 525 | if (iyinf==ny) then | |
| ! TODO -> Higher y bound extrapolation warning | 526 | 526 | ! TODO -> Higher y bound extrapolation warning | |
| iyinf=ny-1 | 527 | 527 | iyinf=ny-1 | |
| end if | 528 | 528 | end if | |
| 529 | 529 | |||
| if (izinf==0) then | 530 | 530 | if (izinf==0) then | |
| ! TODO -> Lower z bound extrapolation warning | 531 | 531 | ! TODO -> Lower z bound extrapolation warning | |
| izinf=1 | 532 | 532 | izinf=1 | |
| end if | 533 | 533 | end if | |
| 534 | 534 | |||
| if (izinf==nz) then | 535 | 535 | if (izinf==nz) then | |
| ! TODO -> Higher z bound extrapolation warning | 536 | 536 | ! TODO -> Higher z bound extrapolation warning | |
| izinf=nz-1 | 537 | 537 | izinf=nz-1 | |
| end if | 538 | 538 | end if | |
| 539 | 539 | |||
| ! The three points we will use are iinf-1,iinf and iinf+1 with the | 540 | 540 | ! The three points we will use are iinf-1,iinf and iinf+1 with the | |
| ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | 541 | 541 | ! exception of the first interval, where iinf=1 we will use 1,2 and 3 | |
| if (ixinf==1) then | 542 | 542 | if (ixinf==1) then | |
| basex=0 | 543 | 543 | basex=0 | |
| else | 544 | 544 | else | |
| basex=ixinf-2 | 545 | 545 | basex=ixinf-2 | |
| end if | 546 | 546 | end if | |
| 547 | 547 | |||
| if (iyinf==1) then | 548 | 548 | if (iyinf==1) then | |
| basey=0 | 549 | 549 | basey=0 | |
| else | 550 | 550 | else | |
| basey=iyinf-2 | 551 | 551 | basey=iyinf-2 | |
| end if | 552 | 552 | end if | |
| 553 | 553 | |||
| if (izinf==1) then | 554 | 554 | if (izinf==1) then | |
| basez=0 | 555 | 555 | basez=0 | |
| else | 556 | 556 | else | |
| basez=izinf-2 | 557 | 557 | basez=izinf-2 | |
| end if | 558 | 558 | end if | |
| 559 | 559 | |||
| ! We first make 9 one dimensional interpolation on variable x. | 560 | 560 | ! We first make 9 one dimensional interpolation on variable x. | |
| ! results are stored in ttmp | 561 | 561 | ! results are stored in ttmp | |
| do i=1,3 | 562 | 562 | do i=1,3 | |
| do j=1,3 | 563 | 563 | do j=1,3 | |
| ttmp(i,j)=fvn_d_quad_interpol(x,nx,xdata,tdata(:,basey+i,basez+j)) | 564 | 564 | ttmp(i,j)=fvn_d_quad_interpol(x,nx,xdata,tdata(:,basey+i,basez+j)) | |
| end do | 565 | 565 | end do | |
| end do | 566 | 566 | end do | |
| 567 | 567 | |||
| ! We then make a 2 dimensionnal interpolation on variables y and z | 568 | 568 | ! We then make a 2 dimensionnal interpolation on variables y and z | |
| fvn_d_quad_3d_interpol=fvn_d_quad_2d_interpol(y,z, & | 569 | 569 | fvn_d_quad_3d_interpol=fvn_d_quad_2d_interpol(y,z, & | |
| 3,ydata(basey+1:basey+3),3,zdata(basez+1:basez+3),ttmp) | 570 | 570 | 3,ydata(basey+1:basey+3),3,zdata(basez+1:basez+3),ttmp) | |
| end function | 571 | 571 | end function | |
| 572 | 572 | |||
| 573 | 573 | |||
| 574 | 574 | |||
| 575 | 575 | |||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 576 | 576 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| ! | 577 | 577 | ! | |
| ! Akima spline interpolation and spline evaluation | 578 | 578 | ! Akima spline interpolation and spline evaluation | |
| ! | 579 | 579 | ! | |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 580 | 580 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| 581 | 581 | |||
| ! Single precision | 582 | 582 | ! Single precision | |
| subroutine fvn_s_akima(n,x,y,br,co) | 583 | 583 | subroutine fvn_s_akima(n,x,y,br,co) | |
| implicit none | 584 | 584 | implicit none | |
| integer, intent(in) :: n | 585 | 585 | integer, intent(in) :: n | |
| real, intent(in) :: x(n) | 586 | 586 | real, intent(in) :: x(n) | |
| real, intent(in) :: y(n) | 587 | 587 | real, intent(in) :: y(n) | |
| real, intent(out) :: br(n) | 588 | 588 | real, intent(out) :: br(n) | |
| real, intent(out) :: co(4,n) | 589 | 589 | real, intent(out) :: co(4,n) | |
| 590 | 590 | |||
| real, allocatable :: var(:),z(:) | 591 | 591 | real, allocatable :: var(:),z(:) | |
| real :: wi_1,wi | 592 | 592 | real :: wi_1,wi | |
| integer :: i | 593 | 593 | integer :: i | |
| real :: dx,a,b | 594 | 594 | real :: dx,a,b | |
| 595 | 595 | |||
| ! br is just a copy of x | 596 | 596 | ! br is just a copy of x | |
| br(:)=x(:) | 597 | 597 | br(:)=x(:) | |
| 598 | 598 | |||
| allocate(var(n+3)) | 599 | 599 | allocate(var(n+3)) | |
| allocate(z(n)) | 600 | 600 | allocate(z(n)) | |
| ! evaluate the variations | 601 | 601 | ! evaluate the variations | |
| do i=1, n-1 | 602 | 602 | do i=1, n-1 | |
| var(i+2)=(y(i+1)-y(i))/(x(i+1)-x(i)) | 603 | 603 | var(i+2)=(y(i+1)-y(i))/(x(i+1)-x(i)) | |
| end do | 604 | 604 | end do | |
| var(n+2)=2.e0*var(n+1)-var(n) | 605 | 605 | var(n+2)=2.e0*var(n+1)-var(n) | |
| var(n+3)=2.e0*var(n+2)-var(n+1) | 606 | 606 | var(n+3)=2.e0*var(n+2)-var(n+1) | |
| var(2)=2.e0*var(3)-var(4) | 607 | 607 | var(2)=2.e0*var(3)-var(4) | |
| var(1)=2.e0*var(2)-var(3) | 608 | 608 | var(1)=2.e0*var(2)-var(3) | |
| 609 | 609 | |||
| do i = 1, n | 610 | 610 | do i = 1, n | |
| wi_1=abs(var(i+3)-var(i+2)) | 611 | 611 | wi_1=abs(var(i+3)-var(i+2)) | |
| wi=abs(var(i+1)-var(i)) | 612 | 612 | wi=abs(var(i+1)-var(i)) | |
| if ((wi_1+wi).eq.0.e0) then | 613 | 613 | if ((wi_1+wi).eq.0.e0) then | |
| z(i)=(var(i+2)+var(i+1))/2.e0 | 614 | 614 | z(i)=(var(i+2)+var(i+1))/2.e0 | |
| else | 615 | 615 | else | |
| z(i)=(wi_1*var(i+1)+wi*var(i+2))/(wi_1+wi) | 616 | 616 | z(i)=(wi_1*var(i+1)+wi*var(i+2))/(wi_1+wi) | |
| end if | 617 | 617 | end if | |
| end do | 618 | 618 | end do | |
| 619 | 619 | |||
| do i=1, n-1 | 620 | 620 | do i=1, n-1 | |
| dx=x(i+1)-x(i) | 621 | 621 | dx=x(i+1)-x(i) | |
| a=(z(i+1)-z(i))*dx ! coeff intermediaires pour calcul wd | 622 | 622 | a=(z(i+1)-z(i))*dx ! coeff intermediaires pour calcul wd | |
| b=y(i+1)-y(i)-z(i)*dx ! coeff intermediaires pour calcul wd | 623 | 623 | b=y(i+1)-y(i)-z(i)*dx ! coeff intermediaires pour calcul wd | |
| co(1,i)=y(i) | 624 | 624 | co(1,i)=y(i) | |
| co(2,i)=z(i) | 625 | 625 | co(2,i)=z(i) | |
| !co(3,i)=-(a-3.*b)/dx**2 ! méthode wd | 626 | 626 | !co(3,i)=-(a-3.*b)/dx**2 ! méthode wd | |
| !co(4,i)=(a-2.*b)/dx**3 ! méthode wd | 627 | 627 | !co(4,i)=(a-2.*b)/dx**3 ! méthode wd | |
| co(3,i)=(3.e0*var(i+2)-2.e0*z(i)-z(i+1))/dx ! méthode JP Moreau | 628 | 628 | co(3,i)=(3.e0*var(i+2)-2.e0*z(i)-z(i+1))/dx ! méthode JP Moreau | |
| co(4,i)=(z(i)+z(i+1)-2.e0*var(i+2))/dx**2 ! | 629 | 629 | co(4,i)=(z(i)+z(i+1)-2.e0*var(i+2))/dx**2 ! | |
| ! les coefficients donnés par imsl sont co(3,i)*2 et co(4,i)*6 | 630 | 630 | ! les coefficients donnés par imsl sont co(3,i)*2 et co(4,i)*6 | |
| ! etrangement la fonction csval corrige et donne la bonne valeur ... | 631 | 631 | ! etrangement la fonction csval corrige et donne la bonne valeur ... | |
| end do | 632 | 632 | end do | |
| co(1,n)=y(n) | 633 | 633 | co(1,n)=y(n) | |
| co(2,n)=z(n) | 634 | 634 | co(2,n)=z(n) | |
| co(3,n)=0.e0 | 635 | 635 | co(3,n)=0.e0 | |
| co(4,n)=0.e0 | 636 | 636 | co(4,n)=0.e0 | |
| 637 | 637 | |||
| deallocate(z) | 638 | 638 | deallocate(z) | |
| deallocate(var) | 639 | 639 | deallocate(var) | |
| 640 | 640 | |||
| end subroutine | 641 | 641 | end subroutine | |
| 642 | 642 | |||
| ! Double precision | 643 | 643 | ! Double precision | |
| subroutine fvn_d_akima(n,x,y,br,co) | 644 | 644 | subroutine fvn_d_akima(n,x,y,br,co) | |
| 645 | 645 | |||
| implicit none | 646 | 646 | implicit none | |
| integer, intent(in) :: n | 647 | 647 | integer, intent(in) :: n |