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

Contents of /trunk/Sources/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 212 - (show annotations)
Thu Jan 12 12:31:31 2017 UTC (7 years, 3 months ago) by guez
File size: 8695 byte(s)
Moved variables from module com_io_dyn to module inithist_m, where
they are defined.

Split grid_atob.f into grille_m.f and dist_sphe.f. Extracted ASCCI art
to documentation. In grille_m, use automatic arrays instead of maximum
size. In grille_m, instead of printing data for every problematic
point, print a single diagnostic message.

Removed variables top_height, overlap, lev_histhf, lev_histday,
lev_histmth, type_run, ok_isccp, ok_regdyn, lonmin_ins, lonmax_ins,
latmin_ins, latmax_ins of module clesphys, not used.

Removed variable itap of module histwrite_phy_m, not used. There is a
variable itap in module time_phylmdz.

Added output of tro3.

In physiq, no need to compute wo at every time-step, since we only use
it in radlwsw.

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

  ViewVC Help
Powered by ViewVC 1.1.21