/[MITgcm]/MITgcm/pkg/exf/exf_interp.F
ViewVC logotype

Contents of /MITgcm/pkg/exf/exf_interp.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.19 - (show annotations) (download)
Mon Apr 16 23:27:21 2007 UTC (17 years, 5 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint59a, checkpoint59
Changes since 1.18: +3 -0 lines
move EXF header files from lower_case.h to UPPER_CASE.h ;
 add missing cvs Header & Name

1 C $Header: $
2 C $Name: $
3
4 #include "EXF_OPTIONS.h"
5 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
6 C Flux Coupler using C
7 C Bilinear interpolation of forcing fields C
8 C C
9 C B. Cheng (12/2002) C
10 C C
11 C added Bicubic (bnc 1/2003) C
12 C C
13 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
14
15 real*8 function lagran(i,x,a,sp)
16
17 INTEGER i,k,sp
18 _RS x
19 real*8 a(4)
20 real*8 numer,denom
21
22 numer = 1.D0
23 denom = 1.D0
24
25 do k=1,sp
26 if ( k .ne. i) then
27 denom = denom*(a(i) - a(k))
28 numer = numer*(x - a(k))
29 endif
30 enddo
31
32 lagran = numer/denom
33
34 return
35 end
36
37
38 SUBROUTINE exf_interp(
39 I infile,
40 I filePrec,
41 O arrayout,
42 I irecord, xG_in, yG,
43 I lon_0, lon_inc,
44 I lat_0, lat_inc,
45 I nx_in, ny_in, method, mythid)
46
47 implicit none
48
49 C infile = name of the input file (direct access binary)
50 C filePrec = file precicision (currently not used, assumes real*4)
51 C arrout = output arrays (different for each processor)
52 C irecord = record number in global file
53 C xG,yG = coordinates for output grid
54 C lon_0, lat_0 = lon and lat of sw corner of global input grid
55 C lon_inc = scalar x-grid increment
56 C lat_inc = vector y-grid increments
57 C nx_in, ny_in = input x-grid and y-grid size
58 C method = 1,11,21 for bilinear; 2,12,22 for bicubic
59 C 1,2 for tracer; 11,12 for U; 21,22 for V
60 C mythid = thread id
61 C
62
63 #include "SIZE.h"
64 #include "EEPARAMS.h"
65 #include "PARAMS.h"
66
67 C subroutine variables
68 character*(*) infile
69 integer filePrec, irecord, nx_in, ny_in
70 _RL arrayout(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
71 _RS xG_in (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
72 _RS yG (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
73 _RL lon_0, lon_inc
74 _RL lat_0, lat_inc(ny_in-1)
75 integer method, mythid
76
77 C local variables
78 integer e_ind(snx,sny),w_ind(snx,sny)
79 integer n_ind(snx,sny),s_ind(snx,sny)
80 real*8 px_ind(4), py_ind(4), ew_val(4)
81 external lagran
82 real*8 lagran
83 real*4 arrayin(-1:nx_in+2 , -1:ny_in+2)
84 real*8 x_in (-1:nx_in+2), y_in(-1:ny_in+2)
85 real*8 ninety
86 PARAMETER ( ninety = 90. )
87 integer i, j, k, l, js, bi, bj, sp, interp_unit
88 _RS xG(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
89 _RS threeSixtyRS, NorthValue
90 PARAMETER ( threeSixtyRS = 360. )
91
92 C put xG in interval [ lon_0 , lon_0+360 [
93 do bj=myByLo(myThid),myByHi(myThid)
94 do bi=myBxLo(myThid),myBxHi(myThid)
95 do j=1-OLy,sNy+OLy
96 do i=1-OLx,sNx+OLx
97 xG(i,j,bi,bj) = xG_in(i,j,bi,bj)-lon_0
98 & + threeSixtyRS*2.
99 xG(i,j,bi,bj) = lon_0+mod(xG(i,j,bi,bj),threeSixtyRS)
100 enddo
101 enddo
102 enddo
103 enddo
104
105 call exf_interp_read(
106 I infile, filePrec,
107 O arrayin,
108 I irecord, nx_in, ny_in, mythid)
109 _BARRIER
110
111 C _BEGIN_MASTER( myThid )
112
113 C setup input longitude grid
114 do i=-1,nx_in+2
115 x_in(i) = lon_0 + (i-1)*lon_inc
116 enddo
117
118 C setup input latitude grid
119 y_in(0) = lat_0 - lat_inc(1)
120 y_in(-1)= lat_0 - 2.*lat_inc(1)
121 y_in(1) = lat_0
122 do j=2,ny_in
123 y_in(j) = y_in(j-1) + lat_inc(j-1)
124 enddo
125 do j=ny_in+1,ny_in+2
126 if (y_in(j-1).eq.ninety) then
127 y_in(j) = 2 * ninety - y_in(j-2)
128 else
129 y_in(j) = min( y_in(j-1)+lat_inc(ny_in-1), ninety )
130 endif
131 enddo
132
133 C enlarge boundary
134 do j=1,ny_in
135 arrayin(0,j) = arrayin(nx_in,j)
136 arrayin(-1,j) = arrayin(nx_in-1,j)
137 arrayin(nx_in+1,j) = arrayin(1,j)
138 arrayin(nx_in+2,j) = arrayin(2,j)
139 enddo
140 do i=-1,nx_in+2
141 arrayin(i,0) = arrayin(i,1)
142 arrayin(i,-1) = arrayin(i,1)
143 arrayin(i,ny_in+1) = arrayin(i,ny_in)
144 arrayin(i,ny_in+2) = arrayin(i,ny_in)
145 enddo
146
147 C For tracer (method=1,2) set to northernmost zonal-mean value
148 C at 90N to avoid sharp zonal gradients near the Pole.
149 C For U (method=11,12) set to zero at 90N to minimize velocity
150 C gradient at North Pole
151 C For V (method=11,12) set to northernmost zonal value at 90N,
152 C as is already done above in order to allow cross-PoleArctic flow
153 do j=ny_in,ny_in+2
154 if (y_in(j).eq.ninety) then
155 if (method.eq.1 .or. method.eq.2) then
156 NorthValue = 0
157 do i=1,nx_in
158 NorthValue = NorthValue + arrayin(i,j)
159 enddo
160 NorthValue = NorthValue / nx_in
161 do i=-1,nx_in+2
162 arrayin(i,j) = NorthValue
163 enddo
164 elseif (method.eq.11 .or. method.eq.12) then
165 do i=-1,nx_in+2
166 arrayin(i,j) = 0
167 enddo
168 endif
169 endif
170 enddo
171
172 C _END_MASTER( myThid )
173
174 do bj = mybylo(mythid), mybyhi(mythid)
175 do bi = mybxlo(mythid), mybxhi(mythid)
176
177 C check validity of input/output coordinates
178 #ifdef ALLOW_DEBUG
179 if ( debugLevel .ge. debLevB ) then
180 do i=1,snx
181 do j=1,sny
182 if ( xG(i,j,bi,bj) .lt. x_in(0) .or.
183 & xG(i,j,bi,bj) .ge. x_in(nx_in+1) .or.
184 & yG(i,j,bi,bj) .lt. y_in(0) .or.
185 & yG(i,j,bi,bj) .ge. y_in(ny_in+1) ) then
186 print*,'ERROR in S/R EXF_INTERP:'
187 print*,' input grid must encompass output grid.'
188 print*,'i,j,bi,bj' ,i,j,bi,bj
189 print*,'xG,yG' ,xG(i,j,bi,bj),yG(i,j,bi,bj)
190 print*,'nx_in,ny_in' ,nx_in ,ny_in
191 print*,'x_in(0,nx_in+1)',x_in(0) ,x_in(nx_in+1)
192 print*,'y_in(0,ny_in+1)',y_in(0) ,y_in(ny_in+1)
193 STOP ' ABNORMAL END: S/R EXF_INTERP'
194 endif
195 enddo
196 enddo
197 endif
198 #endif /* ALLOW_DEBUG */
199
200 C compute interpolation indices
201 do i=1,snx
202 do j=1,sny
203 if (xG(i,j,bi,bj)-x_in(1) .ge. 0.) then
204 w_ind(i,j) = int((xG(i,j,bi,bj)-x_in(1))/lon_inc) + 1
205 else
206 w_ind(i,j) = int((xG(i,j,bi,bj)-x_in(1))/lon_inc)
207 endif
208 e_ind(i,j) = w_ind(i,j) + 1
209 js = ny_in*.5
210 do while (yG(i,j,bi,bj) .lt. y_in(js))
211 js = (js - 1)*.5
212 enddo
213 do while (yG(i,j,bi,bj) .ge. y_in(js+1))
214 js = js + 1
215 enddo
216 s_ind(i,j) = js
217 n_ind(i,j) = js + 1
218 enddo
219 enddo
220
221 if (method.eq.1 .or. method.eq.11 .or. method.eq.21) then
222
223 C bilinear interpolation
224 sp = 2
225 do j=1,sny
226 do i=1,snx
227 arrayout(i,j,bi,bj) = 0.
228 do l=0,1
229 px_ind(l+1) = x_in(w_ind(i,j)+l)
230 py_ind(l+1) = y_in(s_ind(i,j)+l)
231 enddo
232 do k=1,2
233 ew_val(k) = arrayin(w_ind(i,j),s_ind(i,j)+k-1)
234 & *lagran(1,xG(i,j,bi,bj),px_ind,sp)
235 & +arrayin(e_ind(i,j),s_ind(i,j)+k-1)
236 & *lagran(2,xG(i,j,bi,bj),px_ind,sp)
237 arrayout(i,j,bi,bj)=arrayout(i,j,bi,bj)
238 & +ew_val(k)*lagran(k,yG(i,j,bi,bj),py_ind,sp)
239 enddo
240 enddo
241 enddo
242 elseif (method .eq. 2 .or. method.eq.12 .or. method.eq.22) then
243
244 C bicubic interpolation
245 sp = 4
246 do j=1,sny
247 do i=1,snx
248 arrayout(i,j,bi,bj) = 0.
249 do l=-1,2
250 px_ind(l+2) = x_in(w_ind(i,j)+l)
251 py_ind(l+2) = y_in(s_ind(i,j)+l)
252 enddo
253 do k=1,4
254 ew_val(k) =
255 & arrayin(w_ind(i,j)-1,s_ind(i,j)+k-2)
256 & *lagran(1,xG(i,j,bi,bj),px_ind,sp)
257 & +arrayin(w_ind(i,j) ,s_ind(i,j)+k-2)
258 & *lagran(2,xG(i,j,bi,bj),px_ind,sp)
259 & +arrayin(e_ind(i,j) ,s_ind(i,j)+k-2)
260 & *lagran(3,xG(i,j,bi,bj),px_ind,sp)
261 & +arrayin(e_ind(i,j)+1,s_ind(i,j)+k-2)
262 & *lagran(4,xG(i,j,bi,bj),px_ind,sp)
263 arrayout(i,j,bi,bj)=arrayout(i,j,bi,bj)
264 & +ew_val(k)*lagran(k,yG(i,j,bi,bj),py_ind,sp)
265 enddo
266 enddo
267 enddo
268 else
269 stop 'stop in exf_interp.F: interpolation method not supported'
270 endif
271 enddo
272 enddo
273
274 END

  ViewVC Help
Powered by ViewVC 1.1.22