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

Contents of /trunk/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (show annotations)
Wed Jan 28 16:10:02 2015 UTC (9 years, 3 months ago) by guez
File size: 8946 byte(s)
In procedure fxhyp, extracted the body of the loop on ik into a new
procedure:  fxhyp_loop_ik.

dzoomx and dzoomy must now be fractions of the entire range, they
cannot be ranges in degrees or rad.

In fxhyp, force Xf(2 * nmax) = pi_d instead of possibly doing it in
fxhyp_loop_ik.

In fxhyp_loop_ik, when testing whether xvrai is between -pi and pi,
changed the boundaries from -pi - 0.1 to - pi_d - 1d-5 and from pi +
0.1 to pi_d + 1d-5. This reveals a misconception of the
code. Therefore, this version does not work.

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

  ViewVC Help
Powered by ViewVC 1.1.21