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

Contents of /trunk/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 119 - (show annotations)
Wed Jan 7 14:34:57 2015 UTC (9 years, 4 months ago) by guez
File size: 9252 byte(s)
Removed procedure fxyhyper. Useless intermediary between inigeom and
fxhyp, fyhyp. Removed argument yprimv of fyhyp, not used in
inigeom. Downgraded rlonm025 and rlonp025 from arguments to local
variables of fxhyp, not used in inigeom. Downgraded arguments
champmin, champmax of fxhyp and fyhyp to local variables: print them
in fxhyp and fyhyp instead of fxyhyper.

Removed arguments xzoomdeg, grossism, dzooma, tau of fxhyp. Use
directly module variables clon, grossismx, dzoomx, taux instead.

Removed arguments yzoomdeg, grossism, dzooma, tau of fyhyp. Use
directly module variables clat, grossismy, dzoomy, tauy instead.

In procedure yamada4, l0 does not need the save attribute. It is
defined at each call.

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

  ViewVC Help
Powered by ViewVC 1.1.21