/[lmdze]/trunk/dyn3d/fyhyp.f
ViewVC logotype

Contents of /trunk/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 131 - (show annotations)
Fri Feb 27 16:44:07 2015 UTC (9 years, 2 months ago) by guez
File size: 8971 byte(s)
Renamed procedure fxhyp_loop_ik to invert_zoom_x.

Bug fix. clat is now in rad so there should be no conversion in
fyhyp. (This bug had an effect only if clat was /= 0.)

No need for heavyside to be double precision.

Removed variable tnom of module iniadvtrac_m. Was redundant with tname.

1 module fyhyp_m
2
3 IMPLICIT NONE
4
5 contains
6
7 SUBROUTINE fyhyp(rlatu, yyprimu, rlatv, rlatu2, yprimu2, rlatu1, yprimu1)
8
9 ! From LMDZ4/libf/dyn3d/fyhyp.F, version 1.2, 2005/06/03 09:11:32
10
11 ! Author: P. Le Van, from analysis by R. Sadourny
12
13 ! Calcule les latitudes et dérivées dans la grille du GCM pour une
14 ! fonction f(y) à dérivée tangente hyperbolique.
15
16 ! Il vaut mieux avoir : grossismy * dzoom < pi / 2
17
18 use coefpoly_m, only: coefpoly
19 USE dimens_m, only: jjm
20 use heavyside_m, only: heavyside
21 use serre, only: clat, grossismy, dzoomy, tauy
22
23 REAL, intent(out):: rlatu(jjm + 1), yyprimu(jjm + 1)
24 REAL, intent(out):: rlatv(jjm)
25 real, intent(out):: rlatu2(jjm), yprimu2(jjm), rlatu1(jjm), yprimu1(jjm)
26
27 ! Local:
28
29 DOUBLE PRECISION champmin, champmax
30 INTEGER, PARAMETER:: nmax=30000, nmax2=2*nmax
31 REAL dzoom ! distance totale de la zone du zoom (en radians)
32 DOUBLE PRECISION ylat(jjm + 1), yprim(jjm + 1)
33 DOUBLE PRECISION yuv
34 DOUBLE PRECISION, save:: yt(0:nmax2)
35 DOUBLE PRECISION fhyp(0:nmax2), beta
36 DOUBLE PRECISION, save:: ytprim(0:nmax2)
37 DOUBLE PRECISION fxm(0:nmax2)
38 DOUBLE PRECISION, save:: yf(0:nmax2)
39 DOUBLE PRECISION yypr(0:nmax2)
40 DOUBLE PRECISION yvrai(jjm + 1), yprimm(jjm + 1), ylatt(jjm + 1)
41 DOUBLE PRECISION pi, pis2, epsilon, pisjm
42 DOUBLE PRECISION yo1, yi, ylon2, ymoy, yprimin
43 DOUBLE PRECISION yfi, yf1, ffdy
44 DOUBLE PRECISION ypn, deply, y00
45 SAVE y00, deply
46
47 INTEGER i, j, it, ik, iter, jlat
48 INTEGER jpn, jjpn
49 SAVE jpn
50 DOUBLE PRECISION a0, a1, a2, a3, yi2, heavyy0, heavyy0m
51 DOUBLE PRECISION fa(0:nmax2), fb(0:nmax2)
52 REAL y0min, y0max
53
54 !-------------------------------------------------------------------
55
56 print *, "Call sequence information: fyhyp"
57
58 pi = 2.*asin(1.)
59 pis2 = pi/2.
60 pisjm = pi/real(jjm)
61 epsilon = 1e-3
62 dzoom = dzoomy*pi
63 print *, 'yzoom(rad), grossismy, tauy, dzoom (rad):'
64 print *, clat, grossismy, tauy, dzoom
65
66 DO i = 0, nmax2
67 yt(i) = -pis2 + real(i)*pi/nmax2
68 END DO
69
70 heavyy0m = heavyside(-clat)
71 heavyy0 = heavyside(clat)
72 y0min = 2.*clat*heavyy0m - pis2
73 y0max = 2.*clat*heavyy0 + pis2
74
75 fa = 999.999
76 fb = 999.999
77
78 DO i = 0, nmax2
79 IF (yt(i)<clat) THEN
80 fa(i) = tauy*(yt(i)-clat + dzoom/2.)
81 fb(i) = (yt(i)-2.*clat*heavyy0m + pis2)*(clat-yt(i))
82 ELSE IF (yt(i)>clat) THEN
83 fa(i) = tauy*(clat-yt(i) + dzoom/2.)
84 fb(i) = (2.*clat*heavyy0-yt(i) + pis2)*(yt(i)-clat)
85 END IF
86
87 IF (200.*fb(i)<-fa(i)) THEN
88 fhyp(i) = -1.
89 ELSE IF (200.*fb(i)<fa(i)) THEN
90 fhyp(i) = 1.
91 ELSE
92 fhyp(i) = tanh(fa(i)/fb(i))
93 END IF
94
95 IF (yt(i)==clat) fhyp(i) = 1.
96 IF (yt(i)==y0min .OR. yt(i)==y0max) fhyp(i) = -1.
97 END DO
98
99 ! Calcul de beta
100
101 ffdy = 0.
102
103 DO i = 1, nmax2
104 ymoy = 0.5*(yt(i-1) + yt(i))
105 IF (ymoy<clat) THEN
106 fa(i) = tauy*(ymoy-clat + dzoom/2.)
107 fb(i) = (ymoy-2.*clat*heavyy0m + pis2)*(clat-ymoy)
108 ELSE IF (ymoy>clat) THEN
109 fa(i) = tauy*(clat-ymoy + dzoom/2.)
110 fb(i) = (2.*clat*heavyy0-ymoy + pis2)*(ymoy-clat)
111 END IF
112
113 IF (200.*fb(i)<-fa(i)) THEN
114 fxm(i) = -1.
115 ELSE IF (200.*fb(i)<fa(i)) THEN
116 fxm(i) = 1.
117 ELSE
118 fxm(i) = tanh(fa(i)/fb(i))
119 END IF
120 IF (ymoy==clat) fxm(i) = 1.
121 IF (ymoy==y0min .OR. yt(i)==y0max) fxm(i) = -1.
122 ffdy = ffdy + fxm(i)*(yt(i)-yt(i-1))
123 END DO
124
125 beta = (grossismy*ffdy-pi)/(ffdy-pi)
126
127 IF (2. * beta - grossismy <= 0.) THEN
128 print *, 'Attention ! La valeur beta calculee dans la routine fyhyp ' &
129 // 'est mauvaise. Modifier les valeurs de grossismy, tauy ou ' &
130 // 'dzoomy et relancer.'
131 STOP 1
132 END IF
133
134 ! calcul de Ytprim
135
136 DO i = 0, nmax2
137 ytprim(i) = beta + (grossismy-beta)*fhyp(i)
138 END DO
139
140 ! Calcul de Yf
141
142 yf(0) = -pis2
143 DO i = 1, nmax2
144 yypr(i) = beta + (grossismy-beta)*fxm(i)
145 END DO
146
147 DO i = 1, nmax2
148 yf(i) = yf(i-1) + yypr(i)*(yt(i)-yt(i-1))
149 END DO
150
151 ! yuv = 0. si calcul des latitudes aux pts. U
152 ! yuv = 0.5 si calcul des latitudes aux pts. V
153
154 loop_ik: DO ik = 1, 4
155 IF (ik==1) THEN
156 yuv = 0.
157 jlat = jjm + 1
158 ELSE IF (ik==2) THEN
159 yuv = 0.5
160 jlat = jjm
161 ELSE IF (ik==3) THEN
162 yuv = 0.25
163 jlat = jjm
164 ELSE IF (ik==4) THEN
165 yuv = 0.75
166 jlat = jjm
167 END IF
168
169 yo1 = 0.
170 DO j = 1, jlat
171 yo1 = 0.
172 ylon2 = -pis2 + pisjm*(real(j) + yuv-1.)
173 yfi = ylon2
174
175 it = nmax2
176 DO while (it >= 1 .and. yfi < yf(it))
177 it = it - 1
178 END DO
179
180 yi = yt(it)
181 IF (it==nmax2) THEN
182 it = nmax2 - 1
183 yf(it + 1) = pis2
184 END IF
185
186 ! Interpolation entre yi(it) et yi(it + 1) pour avoir Y(yi)
187 ! et Y'(yi)
188
189 CALL coefpoly(yf(it), yf(it + 1), ytprim(it), ytprim(it + 1), &
190 yt(it), yt(it + 1), a0, a1, a2, a3)
191
192 yf1 = yf(it)
193 yprimin = a1 + 2.*a2*yi + 3.*a3*yi*yi
194
195 iter = 1
196 DO
197 yi = yi - (yf1-yfi)/yprimin
198 IF (abs(yi-yo1)<=epsilon .or. iter == 300) exit
199 yo1 = yi
200 yi2 = yi*yi
201 yf1 = a0 + a1*yi + a2*yi2 + a3*yi2*yi
202 yprimin = a1 + 2.*a2*yi + 3.*a3*yi2
203 END DO
204 if (abs(yi-yo1) > epsilon) then
205 print *, 'Pas de solution.', j, ylon2
206 STOP 1
207 end if
208
209 yprimin = a1 + 2.*a2*yi + 3.*a3*yi*yi
210 yprim(j) = pi/(jjm*yprimin)
211 yvrai(j) = yi
212 END DO
213
214 DO j = 1, jlat - 1
215 IF (yvrai(j + 1)<yvrai(j)) THEN
216 print *, 'Problème avec rlat(', j + 1, ') plus petit que rlat(', &
217 j, ')'
218 STOP 1
219 END IF
220 END DO
221
222 print *, 'Reorganisation des latitudes pour avoir entre - pi/2 et pi/2'
223
224 IF (ik==1) THEN
225 ypn = pis2
226 DO j = jjm + 1, 1, -1
227 IF (yvrai(j)<=ypn) exit
228 END DO
229
230 jpn = j
231 y00 = yvrai(jpn)
232 deply = pis2 - y00
233 END IF
234
235 DO j = 1, jjm + 1 - jpn
236 ylatt(j) = -pis2 - y00 + yvrai(jpn + j-1)
237 yprimm(j) = yprim(jpn + j-1)
238 END DO
239
240 jjpn = jpn
241 IF (jlat==jjm) jjpn = jpn - 1
242
243 DO j = 1, jjpn
244 ylatt(j + jjm + 1-jpn) = yvrai(j) + deply
245 yprimm(j + jjm + 1-jpn) = yprim(j)
246 END DO
247
248 ! Fin de la reorganisation
249
250 DO j = 1, jlat
251 ylat(j) = ylatt(jlat + 1-j)
252 yprim(j) = yprimm(jlat + 1-j)
253 END DO
254
255 DO j = 1, jlat
256 yvrai(j) = ylat(j)*180./pi
257 END DO
258
259 IF (ik==1) THEN
260 DO j = 1, jjm + 1
261 rlatu(j) = ylat(j)
262 yyprimu(j) = yprim(j)
263 END DO
264 ELSE IF (ik==2) THEN
265 DO j = 1, jjm
266 rlatv(j) = ylat(j)
267 END DO
268 ELSE IF (ik==3) THEN
269 DO j = 1, jjm
270 rlatu2(j) = ylat(j)
271 yprimu2(j) = yprim(j)
272 END DO
273 ELSE IF (ik==4) THEN
274 DO j = 1, jjm
275 rlatu1(j) = ylat(j)
276 yprimu1(j) = yprim(j)
277 END DO
278 END IF
279 END DO loop_ik
280
281 DO j = 1, jjm
282 ylat(j) = rlatu(j) - rlatu(j + 1)
283 END DO
284 champmin = 1e12
285 champmax = -1e12
286 DO j = 1, jjm
287 champmin = min(champmin, ylat(j))
288 champmax = max(champmax, ylat(j))
289 END DO
290 champmin = champmin*180./pi
291 champmax = champmax*180./pi
292
293 DO j = 1, jjm
294 IF (rlatu1(j) <= rlatu2(j)) THEN
295 print *, 'Attention ! rlatu1 < rlatu2 ', rlatu1(j), rlatu2(j), j
296 STOP 13
297 ENDIF
298
299 IF (rlatu2(j) <= rlatu(j+1)) THEN
300 print *, 'Attention ! rlatu2 < rlatup1 ', rlatu2(j), rlatu(j+1), j
301 STOP 14
302 ENDIF
303
304 IF (rlatu(j) <= rlatu1(j)) THEN
305 print *, ' Attention ! rlatu < rlatu1 ', rlatu(j), rlatu1(j), j
306 STOP 15
307 ENDIF
308
309 IF (rlatv(j) <= rlatu2(j)) THEN
310 print *, ' Attention ! rlatv < rlatu2 ', rlatv(j), rlatu2(j), j
311 STOP 16
312 ENDIF
313
314 IF (rlatv(j) >= rlatu1(j)) THEN
315 print *, ' Attention ! rlatv > rlatu1 ', rlatv(j), rlatu1(j), j
316 STOP 17
317 ENDIF
318
319 IF (rlatv(j) >= rlatu(j)) THEN
320 print *, ' Attention ! rlatv > rlatu ', rlatv(j), rlatu(j), j
321 STOP 18
322 ENDIF
323 ENDDO
324
325 print *, 'Latitudes'
326 print 3, champmin, champmax
327
328 3 Format(1x, ' Au centre du zoom, la longueur de la maille est', &
329 ' d environ ', f0.2, ' degres ', /, &
330 ' alors que la maille en dehors de la zone du zoom est ', &
331 "d'environ ", f0.2, ' degres ')
332
333 END SUBROUTINE fyhyp
334
335 end module fyhyp_m

  ViewVC Help
Powered by ViewVC 1.1.21