1 |
C $Header: /u/gcmpack/MITgcm/pkg/exf/exf_interp.F,v 1.28 2012/01/01 15:25:23 jmc Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "EXF_OPTIONS.h" |
5 |
|
6 |
C-- File exf_interp.F: Routines to interpolate input field on to model grid |
7 |
C-- Contents |
8 |
C-- o S/R EXF_INTERPOLATE |
9 |
C-- o FCT LAGRAN |
10 |
|
11 |
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| |
12 |
|
13 |
CBOP |
14 |
C !ROUTINE: LAGRAN |
15 |
C !INTERFACE: |
16 |
_RL FUNCTION LAGRAN(i,x,a,sp) |
17 |
|
18 |
C !DESCRIPTION: \bv |
19 |
C *==========================================================* |
20 |
C | FUNCTION LAGRAN |
21 |
C | o Provide linear (sp=2) and cubic (sp=4) interpolation |
22 |
C | weight as lagrange polynomial coefficient. |
23 |
C *==========================================================* |
24 |
C \ev |
25 |
|
26 |
C !USES: |
27 |
IMPLICIT NONE |
28 |
|
29 |
C !INPUT/OUTPUT PARAMETERS: |
30 |
INTEGER i |
31 |
_RS x |
32 |
_RL a(4) |
33 |
INTEGER sp |
34 |
|
35 |
C !LOCAL VARIABLES: |
36 |
INTEGER k |
37 |
_RL numer,denom |
38 |
|
39 |
numer = 1. _d 0 |
40 |
denom = 1. _d 0 |
41 |
|
42 |
#ifdef TARGET_NEC_SX |
43 |
!CDIR UNROLL=8 |
44 |
#endif /* TARGET_NEC_SX */ |
45 |
DO k=1,sp |
46 |
IF ( k .NE. i) THEN |
47 |
denom = denom*(a(i) - a(k)) |
48 |
numer = numer*(x - a(k)) |
49 |
ENDIF |
50 |
ENDDO |
51 |
|
52 |
LAGRAN = numer/denom |
53 |
|
54 |
RETURN |
55 |
END |
56 |
|
57 |
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| |
58 |
|
59 |
CBOP |
60 |
C !ROUTINE: EXF_INTERPOLATE |
61 |
C !INTERFACE: |
62 |
SUBROUTINE EXF_INTERPOLATE( |
63 |
I inFile, irecord, method, |
64 |
I nxIn, nyIn, x_in, y_in, |
65 |
I arrayin, |
66 |
O arrayout, |
67 |
I xG, yG, |
68 |
I w_ind, s_ind, |
69 |
I bi, bj, myThid ) |
70 |
|
71 |
C !DESCRIPTION: \bv |
72 |
C *==========================================================* |
73 |
C | SUBROUTINE EXF_INTERPOLATE |
74 |
C | o Interpolate a regular lat-lon input field |
75 |
C | on to the model grid location |
76 |
C *==========================================================* |
77 |
C \ev |
78 |
|
79 |
C !USES: |
80 |
IMPLICIT NONE |
81 |
C === Global variables === |
82 |
#include "SIZE.h" |
83 |
#include "EEPARAMS.h" |
84 |
#include "PARAMS.h" |
85 |
|
86 |
C !INPUT/OUTPUT PARAMETERS: |
87 |
C inFile :: name of the binary input file (direct access) |
88 |
C irecord :: record number in input file |
89 |
C method :: 1,11,21 for bilinear; 2,12,22 for bicubic |
90 |
C :: 1,2 for tracer; 11,12 for U; 21,22 for V |
91 |
C nxIn,nyIn :: size in x & y direction of input field |
92 |
C x_in :: longitude vector defining input field grid |
93 |
C y_in :: latitude vector defining input field grid |
94 |
C arrayin :: input field array (loaded from file) |
95 |
C arrayout :: output array |
96 |
C xG, yG :: coordinates for output grid to interpolate to |
97 |
C w_ind :: input field longitudinal index, on western side of model grid pt |
98 |
C s_ind :: input field latitudinal index, on southern side of model grid pt |
99 |
C bi, bj :: tile indices |
100 |
C myThid :: My Thread Id number |
101 |
|
102 |
CHARACTER*(*) inFile |
103 |
INTEGER irecord, method |
104 |
INTEGER nxIn, nyIn |
105 |
_RL x_in(-1:nxIn+2), y_in(-1:nyIn+2) |
106 |
_RL arrayin( -1:nxIn+2, -1:nyIn+2 ) |
107 |
_RL arrayout(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
108 |
_RS xG (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
109 |
_RS yG (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
110 |
INTEGER w_ind(sNx,sNy), s_ind(sNx,sNy) |
111 |
INTEGER bi, bj, myThid |
112 |
|
113 |
C !FUNCTIONS: |
114 |
EXTERNAL LAGRAN |
115 |
_RL LAGRAN |
116 |
INTEGER ILNBLNK |
117 |
EXTERNAL ILNBLNK |
118 |
|
119 |
C !LOCAL VARIABLES: |
120 |
C px_ind :: local copy of longitude position around current model grid pt |
121 |
C py_ind :: local copy of latitude position around current model grid pt |
122 |
C ew_val :: intermediate field value after interpolation in East-West dir. |
123 |
C sp :: number of input-field values used in 1.d interpolation |
124 |
C i, j, k, l :: loop indices |
125 |
C msgBuf :: Informational/error message buffer |
126 |
_RL px_ind(4), py_ind(4), ew_val(4) |
127 |
INTEGER sp |
128 |
INTEGER i, j, k, l |
129 |
CHARACTER*(MAX_LEN_MBUF) msgBuf |
130 |
#ifdef TARGET_NEC_SX |
131 |
_RL ew_val1, ew_val2, ew_val3, ew_val4 |
132 |
#endif |
133 |
CEOP |
134 |
|
135 |
IF (method.EQ.1 .OR. method.EQ.11 .OR. method.EQ.21) THEN |
136 |
|
137 |
C-- Bilinear interpolation |
138 |
sp = 2 |
139 |
DO j=1,sNy |
140 |
DO i=1,sNx |
141 |
arrayout(i,j,bi,bj) = 0. |
142 |
DO l=0,1 |
143 |
px_ind(l+1) = x_in(w_ind(i,j)+l) |
144 |
py_ind(l+1) = y_in(s_ind(i,j)+l) |
145 |
ENDDO |
146 |
#ifndef TARGET_NEC_SX |
147 |
DO k=1,2 |
148 |
ew_val(k) = arrayin(w_ind(i,j) ,s_ind(i,j)+k-1) |
149 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
150 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j)+k-1) |
151 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
152 |
arrayout(i,j,bi,bj) = arrayout(i,j,bi,bj) |
153 |
& + ew_val(k)*LAGRAN(k,yG(i,j,bi,bj),py_ind,sp) |
154 |
ENDDO |
155 |
#else |
156 |
ew_val1 = arrayin(w_ind(i,j) ,s_ind(i,j) ) |
157 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
158 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j) ) |
159 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
160 |
ew_val2 = arrayin(w_ind(i,j) ,s_ind(i,j)+1) |
161 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
162 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j)+1) |
163 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
164 |
arrayout(i,j,bi,bj)= |
165 |
& +ew_val1*LAGRAN(1,yG(i,j,bi,bj),py_ind,sp) |
166 |
& +ew_val2*LAGRAN(2,yG(i,j,bi,bj),py_ind,sp) |
167 |
#endif /* TARGET_NEC_SX defined */ |
168 |
ENDDO |
169 |
ENDDO |
170 |
ELSEIF (method .EQ. 2 .OR. method.EQ.12 .OR. method.EQ.22) THEN |
171 |
|
172 |
C-- Bicubic interpolation |
173 |
sp = 4 |
174 |
DO j=1,sNy |
175 |
DO i=1,sNx |
176 |
arrayout(i,j,bi,bj) = 0. |
177 |
DO l=-1,2 |
178 |
px_ind(l+2) = x_in(w_ind(i,j)+l) |
179 |
py_ind(l+2) = y_in(s_ind(i,j)+l) |
180 |
ENDDO |
181 |
#ifndef TARGET_NEC_SX |
182 |
DO k=1,4 |
183 |
ew_val(k) = arrayin(w_ind(i,j)-1,s_ind(i,j)+k-2) |
184 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
185 |
& + arrayin(w_ind(i,j) ,s_ind(i,j)+k-2) |
186 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
187 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j)+k-2) |
188 |
& *LAGRAN(3,xG(i,j,bi,bj),px_ind,sp) |
189 |
& + arrayin(w_ind(i,j)+2,s_ind(i,j)+k-2) |
190 |
& *LAGRAN(4,xG(i,j,bi,bj),px_ind,sp) |
191 |
arrayout(i,j,bi,bj) = arrayout(i,j,bi,bj) |
192 |
& + ew_val(k)*LAGRAN(k,yG(i,j,bi,bj),py_ind,sp) |
193 |
ENDDO |
194 |
#else |
195 |
ew_val1 = arrayin(w_ind(i,j)-1,s_ind(i,j)-1) |
196 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
197 |
& + arrayin(w_ind(i,j) ,s_ind(i,j)-1) |
198 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
199 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j)-1) |
200 |
& *LAGRAN(3,xG(i,j,bi,bj),px_ind,sp) |
201 |
& + arrayin(w_ind(i,j)+2,s_ind(i,j)-1) |
202 |
& *LAGRAN(4,xG(i,j,bi,bj),px_ind,sp) |
203 |
ew_val2 = arrayin(w_ind(i,j)-1,s_ind(i,j) ) |
204 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
205 |
& + arrayin(w_ind(i,j) ,s_ind(i,j) ) |
206 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
207 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j) ) |
208 |
& *LAGRAN(3,xG(i,j,bi,bj),px_ind,sp) |
209 |
& + arrayin(w_ind(i,j)+2,s_ind(i,j) ) |
210 |
& *LAGRAN(4,xG(i,j,bi,bj),px_ind,sp) |
211 |
ew_val3 = arrayin(w_ind(i,j)-1,s_ind(i,j)+1) |
212 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
213 |
& + arrayin(w_ind(i,j) ,s_ind(i,j)+1) |
214 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
215 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j)+1) |
216 |
& *LAGRAN(3,xG(i,j,bi,bj),px_ind,sp) |
217 |
& + arrayin(w_ind(i,j)+2,s_ind(i,j)+1) |
218 |
& *LAGRAN(4,xG(i,j,bi,bj),px_ind,sp) |
219 |
ew_val4 = arrayin(w_ind(i,j)-1,s_ind(i,j)+2) |
220 |
& *LAGRAN(1,xG(i,j,bi,bj),px_ind,sp) |
221 |
& + arrayin(w_ind(i,j) ,s_ind(i,j)+2) |
222 |
& *LAGRAN(2,xG(i,j,bi,bj),px_ind,sp) |
223 |
& + arrayin(w_ind(i,j)+1,s_ind(i,j)+2) |
224 |
& *LAGRAN(3,xG(i,j,bi,bj),px_ind,sp) |
225 |
& + arrayin(w_ind(i,j)+2,s_ind(i,j)+2) |
226 |
& *LAGRAN(4,xG(i,j,bi,bj),px_ind,sp) |
227 |
arrayout(i,j,bi,bj) = |
228 |
& ew_val1*LAGRAN(1,yG(i,j,bi,bj),py_ind,sp) |
229 |
& +ew_val2*LAGRAN(2,yG(i,j,bi,bj),py_ind,sp) |
230 |
& +ew_val3*LAGRAN(3,yG(i,j,bi,bj),py_ind,sp) |
231 |
& +ew_val4*LAGRAN(4,yG(i,j,bi,bj),py_ind,sp) |
232 |
#endif /* TARGET_NEC_SX defined */ |
233 |
ENDDO |
234 |
ENDDO |
235 |
ELSE |
236 |
l = ILNBLNK(inFile) |
237 |
WRITE(msgBuf,'(3A,I6)') |
238 |
& 'EXF_INTERPOLATE: file="', inFile(1:l), '", rec=', irecord |
239 |
CALL PRINT_ERROR( msgBuf, myThid ) |
240 |
WRITE(msgBuf,'(A,I8,A)') |
241 |
& 'EXF_INTERPOLATE: method=', method,' not supported' |
242 |
CALL PRINT_ERROR( msgBuf, myThid ) |
243 |
STOP 'ABNORMAL END: S/R EXF_INTERPOLATE: invalid method' |
244 |
ENDIF |
245 |
|
246 |
RETURN |
247 |
END |