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

Contents of /trunk/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 120 - (show annotations)
Tue Jan 13 14:56:15 2015 UTC (9 years, 4 months ago) by guez
File size: 9204 byte(s)
In procedure fxhyp, removed the possibility to set scal180 to
false. The useful lower bound of fhyp and xxpr is not 0. It does not
make sense to give the save attribute to is2 since fxhyp is only
called one per run. Bug fix: is2 could be used without being
defined. The bug did not appear because is2 had the save attribute so
it was initialized at 0.

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

  ViewVC Help
Powered by ViewVC 1.1.21