*IF DEF,RECON VINTPF1A.2 C *****************************COPYRIGHT****************************** VINTPF1A.3 C (c) CROWN COPYRIGHT 1996, METEOROLOGICAL OFFICE, All Rights Reserved. VINTPF1A.4 C VINTPF1A.5 C Use, duplication or disclosure of this code is subject to the VINTPF1A.6 C restrictions as set forth in the contract. VINTPF1A.7 C VINTPF1A.8 C Meteorological Office VINTPF1A.9 C London Road VINTPF1A.10 C BRACKNELL VINTPF1A.11 C Berkshire UK VINTPF1A.12 C RG12 2SZ VINTPF1A.13 C VINTPF1A.14 C If no contract has been raised with this copy of the code, the use, VINTPF1A.15 C duplication or disclosure of it is strictly prohibited. Permission VINTPF1A.16 C to do so must first be obtained in writing from the Head of Numerical VINTPF1A.17 C Modelling at the above address. VINTPF1A.18 C ******************************COPYRIGHT****************************** VINTPF1A.19 ! VINTPF1A.20 ! Subroutine Interface: VINTPF1A.21Subroutine vert_interp 12VINTPF1A.22 & (data_in, data_points, VINTPF1A.23 & data_levels, desired_r, VINTPF1A.24 & r_at_data, interp_order, VINTPF1A.25 & data_out ) VINTPF1A.26 VINTPF1A.27 ! Purpose: VINTPF1A.28 ! Performs vertical interpolation of a field to a VINTPF1A.29 ! desired r surface given the r value at each of VINTPF1A.30 ! the data points. Where the desired surface is below/above VINTPF1A.31 ! the bottom/top data point a missing data indicator is VINTPF1A.32 ! returned. VINTPF1A.33 ! r can be any quantity that is monotonic increasing with VINTPF1A.34 ! model level, such as height, or potential temperature VINTPF1A.35 ! (assuming that the model is statically stable). VINTPF1A.36 ! VINTPF1A.37 ! Method: VINTPF1A.38 ! Cubic Lagrange interpolation. VINTPF1A.39 ! VINTPF1A.40 ! Original Progammer: Mark H. Mawson VINTPF1A.41 ! Current code owner: I Edmond VINTPF1A.42 ! VINTPF1A.43 ! History: VINTPF1A.44 ! Date Version Comment VINTPF1A.45 ! ---- ------- ------- VINTPF1A.46 ! VINTPF1A.47 ! 22/5/96 4.1 Linear extrapolation added to routine to VINTPF1A.48 ! obtain data at points above/below VINTPF1A.49 ! top/bottom levels. Ian Edmond VINTPF1A.50 ! 29/07/98 4.5 Optimisation changes for T3E UDG5F405.594 ! Author D.M. Goddard UDG5F405.595 ! VINTPF1A.51 ! Code Description: VINTPF1A.52 ! Language: FORTRAN 77 + CRAY extensions VINTPF1A.53 ! This code is written to UMDP3 programming standards. VINTPF1A.54 ! VINTPF1A.55 ! System component covered: ?? VINTPF1A.56 ! System Task: ?? VINTPF1A.57 ! VINTPF1A.58 Implicit None VINTPF1A.59 VINTPF1A.60 ! Arguments with Intent IN. ie: Input variables. VINTPF1A.61 VINTPF1A.62 Integer VINTPF1A.63 & data_points ! number of rows of data VINTPF1A.64 &, data_levels ! number of levels of data VINTPF1A.65 &, interp_order ! 1 = linear, 3 = cubic, 5=quintic VINTPF1A.66 VINTPF1A.67 Real VINTPF1A.68 & data_in (data_points, data_levels) VINTPF1A.69 &, r_at_data (data_points, data_levels) VINTPF1A.70 &, desired_r(data_points) ! desired value to which VINTPF1A.71 & ! data should be interpolated t VINTPF1A.72 VINTPF1A.73 ! Arguments with Intent OUT. ie: Output variables. VINTPF1A.74 Real VINTPF1A.75 & data_out (data_points) VINTPF1A.76 VINTPF1A.77 ! Local variables VINTPF1A.78 VINTPF1A.79 Integer VINTPF1A.80 & j,k VINTPF1A.81 VINTPF1A.82 Integer last UDG5F405.596 Integer VINTPF1A.83 & level_below(data_points) VINTPF1A.84 VINTPF1A.85 Real VINTPF1A.86 & r_here VINTPF1A.87 &, r_here_plus VINTPF1A.88 &, r_here_plus2 VINTPF1A.89 &, r_here_minus VINTPF1A.90 &, r_here_plus3 VINTPF1A.91 &, r_here_minus2 VINTPF1A.92 VINTPF1A.93 ! ---------------------------------------------------------------------- VINTPF1A.94 ! Section 1. Find level below which desired surface is. VINTPF1A.95 ! ---------------------------------------------------------------------- VINTPF1A.96 VINTPF1A.97 last=1 UDG5F405.597 Do j=1, data_points UDG5F405.598 If(r_at_data(j,last) .le .desired_r(j))then UDG5F405.599 Do k=last+1, data_levels UDG5F405.600 If(r_at_data(j,k) .gt .desired_r(j))then UDG5F405.601 level_below(j)=k-1 UDG5F405.602 go to 9876 UDG5F405.603 Endif UDG5F405.604 Enddo UDG5F405.605 level_below(j)=data_levels UDG5F405.606 Else UDG5F405.607 Do k=last-1, 1, -1 UDG5F405.608 If(r_at_data(j,k) .le .desired_r(j))then UDG5F405.609 level_below(j)=k UDG5F405.610 go to 9876 UDG5F405.611 Endif UDG5F405.612 Enddo UDG5F405.613 level_below(j)=0 UDG5F405.614 Endif UDG5F405.615 9876 continue UDG5F405.616 LAST=Max(level_below(j),1) UDG5F405.617 End do UDG5F405.618 VINTPF1A.109 VINTPF1A.110 Do j = 1, data_points VINTPF1A.111 VINTPF1A.112 ! If requested level is above top of model, do linear VINTPF1A.113 ! extrapolation using data on top and second top levels. VINTPF1A.114 If ( desired_r(j) .gt. r_at_data(j,data_levels) ) Then VINTPF1A.115 data_out(j) = data_in(j,data_levels) + (desired_r(j) VINTPF1A.116 & - r_at_data(j,data_levels)) * (data_in(j,data_levels) VINTPF1A.117 & - data_in(j,data_levels-1))/(r_at_data(j,data_levels) VINTPF1A.118 & - r_at_data(j,data_levels-1)) VINTPF1A.119 End If VINTPF1A.120 VINTPF1A.121 ! If requested level is below bottom of model, do linear VINTPF1A.122 ! extrapolation using data on first and second levels. VINTPF1A.123 If ( desired_r(j) .lt. r_at_data(j,1) ) Then VINTPF1A.124 data_out(j) = data_in(j,1) + (desired_r(j) VINTPF1A.125 & - r_at_data(j,1)) * (data_in(j,1) VINTPF1A.126 & - data_in(j,2))/(r_at_data(j,1) - r_at_data(j,2)) VINTPF1A.127 End If VINTPF1A.128 VINTPF1A.129 End Do VINTPF1A.130 VINTPF1A.131 ! ---------------------------------------------------------------------- VINTPF1A.132 ! Section 2. Vertical interpolation. VINTPF1A.133 ! ---------------------------------------------------------------------- VINTPF1A.134 VINTPF1A.135 Do j = 1, data_points VINTPF1A.136 VINTPF1A.137 If (level_below(j) .eq. 0.or. UDG5F405.619 & level_below(j) .eq. data_levels) Then UDG5F405.620 UDG5F405.621 UDG5F405.622 data_out (j) = data_out (j) VINTPF1A.139 VINTPF1A.140 Else if (level_below(j) .eq. 1 .or. VINTPF1A.141 & level_below(j) .eq. data_levels - 1 VINTPF1A.142 & .or. interp_order .eq. 1 ) Then VINTPF1A.143 ! linearly interpolate VINTPF1A.144 data_out (j) = ( (desired_r(j) - VINTPF1A.145 & r_at_data(j,level_below(j)) ) VINTPF1A.146 & * data_in (j,level_below(j)+1) VINTPF1A.147 & -(desired_r(j) - VINTPF1A.148 & r_at_data(j,level_below(j)+1)) * VINTPF1A.149 & data_in (j,level_below(j)) ) / VINTPF1A.150 & ( r_at_data(j,level_below(j)+1) - VINTPF1A.151 & r_at_data(j,level_below(j)) ) VINTPF1A.152 VINTPF1A.153 Else if (level_below(j) .eq. 2 .or. VINTPF1A.154 & level_below(j) .eq. data_levels - 2 VINTPF1A.155 & .or. interp_order .eq. 3 ) Then VINTPF1A.156 VINTPF1A.157 ! cubicly interpolate VINTPF1A.158 VINTPF1A.159 r_here_minus = r_at_data(j,level_below(j)-1) VINTPF1A.160 r_here = r_at_data(j,level_below(j)) VINTPF1A.161 r_here_plus = r_at_data(j,level_below(j)+1) VINTPF1A.162 r_here_plus2 = r_at_data(j,level_below(j)+2) VINTPF1A.163 VINTPF1A.164 data_out (j) = ( (desired_r(j) - r_here) * VINTPF1A.165 & (desired_r(j) - r_here_plus )* VINTPF1A.166 & (desired_r(j) - r_here_plus2 ) ) / VINTPF1A.167 & ( (r_here_minus - r_here) * VINTPF1A.168 & (r_here_minus - r_here_plus )* VINTPF1A.169 & (r_here_minus - r_here_plus2 ) ) * VINTPF1A.170 & data_in (j,level_below(j)-1) + VINTPF1A.171 & ( (desired_r(j) - r_here_minus) * VINTPF1A.172 & (desired_r(j) - r_here_plus )* VINTPF1A.173 & (desired_r(j) - r_here_plus2 ) ) / VINTPF1A.174 & ( (r_here - r_here_minus) * VINTPF1A.175 & (r_here - r_here_plus )* VINTPF1A.176 & (r_here - r_here_plus2 ) ) * VINTPF1A.177 & data_in (j,level_below(j)) + VINTPF1A.178 & ( (desired_r(j) - r_here_minus) * VINTPF1A.179 & (desired_r(j) - r_here )* VINTPF1A.180 & (desired_r(j) - r_here_plus2 ) ) / VINTPF1A.181 & ( (r_here_plus - r_here_minus) * VINTPF1A.182 & (r_here_plus - r_here )* VINTPF1A.183 & (r_here_plus - r_here_plus2 ) ) * VINTPF1A.184 & data_in (j,level_below(j)+1) + VINTPF1A.185 & ( (desired_r(j) - r_here_minus) * VINTPF1A.186 & (desired_r(j) - r_here )* VINTPF1A.187 & (desired_r(j) - r_here_plus ) ) / VINTPF1A.188 & ( (r_here_plus2 - r_here_minus) * VINTPF1A.189 & (r_here_plus2 - r_here )* VINTPF1A.190 & (r_here_plus2 - r_here_plus ) ) * VINTPF1A.191 & data_in (j,level_below(j)+2) VINTPF1A.192 VINTPF1A.193 Else VINTPF1A.194 ! interpolate quinticly VINTPF1A.195 VINTPF1A.196 r_here_minus2 = r_at_data(j,level_below(j)-2) VINTPF1A.197 r_here_minus = r_at_data(j,level_below(j)-1) VINTPF1A.198 r_here = r_at_data(j,level_below(j)) VINTPF1A.199 r_here_plus = r_at_data(j,level_below(j)+1) VINTPF1A.200 r_here_plus2 = r_at_data(j,level_below(j)+2) VINTPF1A.201 r_here_plus3 = r_at_data(j,level_below(j)+3) VINTPF1A.202 VINTPF1A.203 Data_out (j) = ((desired_r(j) - r_here_minus) * VINTPF1A.204 & (desired_r(j) - r_here )* VINTPF1A.205 & (desired_r(j) - r_here_plus )* VINTPF1A.206 & (desired_r(j) - r_here_plus2 )* VINTPF1A.207 & (desired_r(j) - r_here_plus3 ))/ VINTPF1A.208 & ( (r_here_minus2 - r_here_minus) * VINTPF1A.209 & (r_here_minus2 - r_here )* VINTPF1A.210 & (r_here_minus2 - r_here_plus )* VINTPF1A.211 & (r_here_minus2 - r_here_plus2 )* VINTPF1A.212 & (r_here_minus2 - r_here_plus3 ) ) * VINTPF1A.213 & data_in (j,level_below(j)-2) + VINTPF1A.214 & ((desired_r(j) - r_here_minus2) * VINTPF1A.215 & (desired_r(j) - r_here )* VINTPF1A.216 & (desired_r(j) - r_here_plus )* VINTPF1A.217 & (desired_r(j) - r_here_plus2 )* VINTPF1A.218 & (desired_r(j) - r_here_plus3 ))/ VINTPF1A.219 & ( (r_here_minus - r_here_minus2) * VINTPF1A.220 & (r_here_minus - r_here )* VINTPF1A.221 & (r_here_minus - r_here_plus )* VINTPF1A.222 & (r_here_minus - r_here_plus2 )* VINTPF1A.223 & (r_here_minus - r_here_plus3 ) ) * VINTPF1A.224 & data_in (j,level_below(j)-1) + VINTPF1A.225 & ((desired_r(j) - r_here_minus2) * VINTPF1A.226 & (desired_r(j) - r_here_minus )* VINTPF1A.227 & (desired_r(j) - r_here_plus )* VINTPF1A.228 & (desired_r(j) - r_here_plus2 )* VINTPF1A.229 & (desired_r(j) - r_here_plus3 ))/ VINTPF1A.230 & ( (r_here - r_here_minus2) * VINTPF1A.231 & (r_here - r_here_minus )* VINTPF1A.232 & (r_here - r_here_plus )* VINTPF1A.233 & (r_here - r_here_plus2 )* VINTPF1A.234 & (r_here - r_here_plus3 ) ) * VINTPF1A.235 & data_in (j,level_below(j)) + VINTPF1A.236 & ((desired_r(j) - r_here_minus2) * VINTPF1A.237 & (desired_r(j) - r_here_minus )* VINTPF1A.238 & (desired_r(j) - r_here )* VINTPF1A.239 & (desired_r(j) - r_here_plus2 )* VINTPF1A.240 & (desired_r(j) - r_here_plus3 ))/ VINTPF1A.241 & ( (r_here_plus - r_here_minus2) * VINTPF1A.242 & (r_here_plus - r_here_minus )* VINTPF1A.243 & (r_here_plus - r_here )* VINTPF1A.244 & (r_here_plus - r_here_plus2 )* VINTPF1A.245 & (r_here_plus - r_here_plus3 ) ) * VINTPF1A.246 & data_in (j,level_below(j)+1) + VINTPF1A.247 & ((desired_r(j) - r_here_minus2) * VINTPF1A.248 & (desired_r(j) - r_here_minus )* VINTPF1A.249 & (desired_r(j) - r_here )* VINTPF1A.250 & (desired_r(j) - r_here_plus )* VINTPF1A.251 & (desired_r(j) - r_here_plus3 ))/ VINTPF1A.252 & ( (r_here_plus2 - r_here_minus2) * VINTPF1A.253 & (r_here_plus2 - r_here_minus )* VINTPF1A.254 & (r_here_plus2 - r_here )* VINTPF1A.255 & (r_here_plus2 - r_here_plus )* VINTPF1A.256 & (r_here_plus2 - r_here_plus3 ) ) * VINTPF1A.257 & data_in (j,level_below(j)+2) + VINTPF1A.258 & ((desired_r(j) - r_here_minus2) * VINTPF1A.259 & (desired_r(j) - r_here_minus )* VINTPF1A.260 & (desired_r(j) - r_here )* VINTPF1A.261 & (desired_r(j) - r_here_plus )* VINTPF1A.262 & (desired_r(j) - r_here_plus2 ))/ VINTPF1A.263 & ( (r_here_plus3 - r_here_minus2) * VINTPF1A.264 & (r_here_plus3 - r_here_minus )* VINTPF1A.265 & (r_here_plus3 - r_here )* VINTPF1A.266 & (r_here_plus3 - r_here_plus )* VINTPF1A.267 & (r_here_plus3 - r_here_plus2 ) ) * VINTPF1A.268 & data_in (j,level_below(j)+3) VINTPF1A.269 VINTPF1A.270 End If VINTPF1A.271 VINTPF1A.272 End Do VINTPF1A.273 VINTPF1A.274 ! end of routine VINTPF1A.275 VINTPF1A.276 Return VINTPF1A.277 End VINTPF1A.278 *ENDIF VINTPF1A.279