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

Contents of /trunk/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 276 - (show annotations)
Thu Jul 12 14:49:20 2018 UTC (5 years, 10 months ago) by guez
File size: 8598 byte(s)
Move procedure read_serre from module read_serre_m to module
dynetat0_m, to avoid side effet on variables of module dynetat0_m.

Create procedure set_unit_nml to avoid side effect on variable of
module unit_nml_m.

Downgrade pctsrf from variable of module etat0_m to argument of etat0
and limit to avoid side effect on pctsrf.

Move variable zmasq from module dimphy to module phyetat0_m to avoid
side effect on zmasq.

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

  ViewVC Help
Powered by ViewVC 1.1.21