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

Contents of /trunk/dyn3d/fyhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 118 - (show annotations)
Thu Dec 18 17:30:24 2014 UTC (9 years, 4 months ago) by guez
File size: 8298 byte(s)
In file grilles_gcm.nc, renamed variable phis to orog, deleted
variable presnivs.

Removed variable bug_ozone from module clesphys.

In procedure ozonecm, moved computation of sint and cost out of the
loops on horizontal position and vertical level. Inverted the order of
the two loops. We can then move all computations from slat to aprim
out of the loop on vertical levels. Created variable slat2, following
LMDZ. Moved the limitation of column-density of ozone in cell at 1e-12
from radlwsw to ozonecm, following LMDZ.

Removed unused arguments u, albsol, rh, cldfra, rneb, diafra, cldliq,
pmflxr, pmflxs, prfl, psfl of phytrac.

In procedure yamada4, for all the arrays, replaced the dimension klon
by ngrid. At the end of the procedure, for the computation of kmn,kn,
kq and q2, changed the upper limit of the loop index from klon to ngrid.

In radlwsw, for the calculation of pozon, removed the factor
paprs(iof+i, 1)/101325, as in LMDZ. In procedure sw, removed the
factor 101325.0/PPSOL(JL), as in LMDZ.

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

  ViewVC Help
Powered by ViewVC 1.1.21