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

Contents of /trunk/dyn3d/fxhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 119 - (show annotations)
Wed Jan 7 14:34:57 2015 UTC (9 years, 4 months ago) by guez
File size: 10799 byte(s)
Removed procedure fxyhyper. Useless intermediary between inigeom and
fxhyp, fyhyp. Removed argument yprimv of fyhyp, not used in
inigeom. Downgraded rlonm025 and rlonp025 from arguments to local
variables of fxhyp, not used in inigeom. Downgraded arguments
champmin, champmax of fxhyp and fyhyp to local variables: print them
in fxhyp and fyhyp instead of fxyhyper.

Removed arguments xzoomdeg, grossism, dzooma, tau of fxhyp. Use
directly module variables clon, grossismx, dzoomx, taux instead.

Removed arguments yzoomdeg, grossism, dzooma, tau of fyhyp. Use
directly module variables clat, grossismy, dzoomy, tauy instead.

In procedure yamada4, l0 does not need the save attribute. It is
defined at each call.

1 module fxhyp_m
2
3 IMPLICIT NONE
4
5 contains
6
7 SUBROUTINE fxhyp(xprimm025, rlonv, xprimv, rlonu, xprimu, xprimp025)
8
9 ! From LMDZ4/libf/dyn3d/fxhyp.F, version 1.2, 2005/06/03 09:11:32
10 ! Author: P. Le Van, from formulas by R. Sadourny
11
12 ! Calcule les longitudes et dérivées dans la grille du GCM pour
13 ! une fonction f(x) à dérivée tangente hyperbolique.
14
15 ! On doit avoir grossismx \times dzoomx < pi (radians)
16
17 USE dimens_m, ONLY: iim
18 use nr_util, only: pi_d, twopi_d
19 use serre, only: clon, grossismx, dzoomx, taux
20
21 REAL, intent(out):: xprimm025(:), rlonv(:), xprimv(:) ! (iim + 1)
22 real, intent(out):: rlonu(:), xprimu(:), xprimp025(:) ! (iim + 1)
23
24 ! Local:
25
26 DOUBLE PRECISION champmin, champmax
27 real rlonm025(iim + 1), rlonp025(iim + 1)
28 INTEGER, PARAMETER:: nmax = 30000, nmax2 = 2*nmax
29
30 LOGICAL, PARAMETER:: scal180 = .TRUE.
31 ! scal180 = .TRUE. si on veut avoir le premier point scalaire pour
32 ! une grille reguliere (grossismx = 1., taux=0., clon=0.) a
33 ! -180. degres. sinon scal180 = .FALSE.
34
35 REAL dzoom
36 DOUBLE PRECISION xlon(iim + 1), xprimm(iim + 1), xuv
37 DOUBLE PRECISION xtild(0:nmax2)
38 DOUBLE PRECISION fhyp(0:nmax2), ffdx, beta, Xprimt(0:nmax2)
39 DOUBLE PRECISION Xf(0:nmax2), xxpr(0:nmax2)
40 DOUBLE PRECISION xvrai(iim + 1), xxprim(iim + 1)
41 DOUBLE PRECISION my_eps, xzoom, fa, fb
42 DOUBLE PRECISION Xf1, Xfi, a0, a1, a2, a3, xi2
43 INTEGER i, it, ik, iter, ii, idif, ii1, ii2
44 DOUBLE PRECISION xi, xo1, xmoy, xlon2, fxm, Xprimin
45 DOUBLE PRECISION decalx
46 INTEGER, save:: is2
47
48 !----------------------------------------------------------------------
49
50 my_eps = 1e-3
51 xzoom = clon * pi_d / 180.
52
53 IF (grossismx == 1. .AND. scal180) THEN
54 decalx = 1.
55 else
56 decalx = 0.75
57 END IF
58
59 IF (dzoomx < 1.) THEN
60 dzoom = dzoomx * twopi_d
61 ELSE IF (dzoomx < 25.) THEN
62 print *, "Le paramètre dzoomx pour fxhyp est trop petit. " &
63 // "L'augmenter et relancer."
64 STOP 1
65 ELSE
66 dzoom = dzoomx * pi_d / 180.
67 END IF
68
69 print *, 'dzoom (rad):', dzoom
70
71 DO i = 0, nmax2
72 xtild(i) = - pi_d + REAL(i) * twopi_d / nmax2
73 END DO
74
75 DO i = nmax, nmax2
76 fa = taux* (dzoom / 2. - xtild(i))
77 fb = xtild(i) * (pi_d - xtild(i))
78
79 IF (200.* fb < - fa) THEN
80 fhyp(i) = - 1.
81 ELSE IF (200. * fb < fa) THEN
82 fhyp(i) = 1.
83 ELSE
84 IF (ABS(fa) < 1e-13.AND.ABS(fb) < 1e-13) THEN
85 IF (200.*fb + fa < 1e-10) THEN
86 fhyp(i) = - 1.
87 ELSE IF (200.*fb - fa < 1e-10) THEN
88 fhyp(i) = 1.
89 END IF
90 ELSE
91 fhyp(i) = TANH(fa / fb)
92 END IF
93 END IF
94
95 IF (xtild(i) == 0.) fhyp(i) = 1.
96 IF (xtild(i) == pi_d) fhyp(i) = -1.
97 END DO
98
99 ! Calcul de beta
100
101 ffdx = 0.
102
103 DO i = nmax + 1, nmax2
104 xmoy = 0.5 * (xtild(i-1) + xtild(i))
105 fa = taux* (dzoom / 2. - xmoy)
106 fb = xmoy * (pi_d - xmoy)
107
108 IF (200.* fb < - fa) THEN
109 fxm = - 1.
110 ELSE IF (200. * fb < fa) THEN
111 fxm = 1.
112 ELSE
113 IF (ABS(fa) < 1e-13.AND.ABS(fb) < 1e-13) THEN
114 IF (200.*fb + fa < 1e-10) THEN
115 fxm = - 1.
116 ELSE IF (200.*fb - fa < 1e-10) THEN
117 fxm = 1.
118 END IF
119 ELSE
120 fxm = TANH(fa / fb)
121 END IF
122 END IF
123
124 IF (xmoy == 0.) fxm = 1.
125 IF (xmoy == pi_d) fxm = -1.
126
127 ffdx = ffdx + fxm * (xtild(i) - xtild(i-1))
128 END DO
129
130 beta = (grossismx * ffdx - pi_d) / (ffdx - pi_d)
131
132 IF (2. * beta - grossismx <= 0.) THEN
133 print *, 'Attention ! La valeur beta calculée dans fxhyp est mauvaise.'
134 print *, 'Modifier les valeurs de grossismx, taux ou dzoomx et relancer.'
135 STOP 1
136 END IF
137
138 ! calcul de Xprimt
139
140 DO i = nmax, nmax2
141 Xprimt(i) = beta + (grossismx - beta) * fhyp(i)
142 END DO
143
144 DO i = nmax + 1, nmax2
145 Xprimt(nmax2 - i) = Xprimt(i)
146 END DO
147
148 ! Calcul de Xf
149
150 Xf(0) = - pi_d
151
152 DO i = nmax + 1, nmax2
153 xmoy = 0.5 * (xtild(i-1) + xtild(i))
154 fa = taux* (dzoom / 2. - xmoy)
155 fb = xmoy * (pi_d - xmoy)
156
157 IF (200.* fb < - fa) THEN
158 fxm = - 1.
159 ELSE IF (200. * fb < fa) THEN
160 fxm = 1.
161 ELSE
162 fxm = TANH(fa / fb)
163 END IF
164
165 IF (xmoy == 0.) fxm = 1.
166 IF (xmoy == pi_d) fxm = -1.
167 xxpr(i) = beta + (grossismx - beta) * fxm
168 END DO
169
170 DO i = nmax + 1, nmax2
171 xxpr(nmax2-i + 1) = xxpr(i)
172 END DO
173
174 DO i=1, nmax2
175 Xf(i) = Xf(i-1) + xxpr(i) * (xtild(i) - xtild(i-1))
176 END DO
177
178 ! xuv = 0. si calcul aux points scalaires
179 ! xuv = 0.5 si calcul aux points U
180
181 loop_ik: DO ik = 1, 4
182 IF (ik == 1) THEN
183 xuv = -0.25
184 ELSE IF (ik == 2) THEN
185 xuv = 0.
186 ELSE IF (ik == 3) THEN
187 xuv = 0.50
188 ELSE IF (ik == 4) THEN
189 xuv = 0.25
190 END IF
191
192 xo1 = 0.
193
194 ii1=1
195 ii2=iim
196 IF (ik == 1.and.grossismx == 1.) THEN
197 ii1 = 2
198 ii2 = iim + 1
199 END IF
200
201 DO i = ii1, ii2
202 xlon2 = - pi_d + (REAL(i) + xuv - decalx) * twopi_d / REAL(iim)
203 Xfi = xlon2
204
205 it = nmax2
206 do while (xfi < xf(it) .and. it >= 1)
207 it = it - 1
208 end do
209
210 ! Calcul de Xf(xi)
211
212 xi = xtild(it)
213
214 IF (it == nmax2) THEN
215 it = nmax2 -1
216 Xf(it + 1) = pi_d
217 END IF
218
219 ! Appel de la routine qui calcule les coefficients a0, a1,
220 ! a2, a3 d'un polynome de degre 3 qui passe par les points
221 ! (Xf(it), xtild(it)) et (Xf(it + 1), xtild(it + 1))
222
223 CALL coefpoly(Xf(it), Xf(it + 1), Xprimt(it), Xprimt(it + 1), &
224 xtild(it), xtild(it + 1), a0, a1, a2, a3)
225
226 Xf1 = Xf(it)
227 Xprimin = a1 + 2.* a2 * xi + 3.*a3 * xi *xi
228
229 iter = 1
230
231 do
232 xi = xi - (Xf1 - Xfi) / Xprimin
233 IF (ABS(xi - xo1) <= my_eps .or. iter == 300) exit
234 xo1 = xi
235 xi2 = xi * xi
236 Xf1 = a0 + a1 * xi + a2 * xi2 + a3 * xi2 * xi
237 Xprimin = a1 + 2.* a2 * xi + 3.* a3 * xi2
238 end DO
239
240 if (ABS(xi - xo1) > my_eps) then
241 ! iter == 300
242 print *, 'Pas de solution.'
243 print *, i, xlon2
244 STOP 1
245 end if
246
247 xxprim(i) = twopi_d / (REAL(iim) * Xprimin)
248 xvrai(i) = xi + xzoom
249 end DO
250
251 IF (ik == 1 .and. grossismx == 1.) THEN
252 xvrai(1) = xvrai(iim + 1)-twopi_d
253 xxprim(1) = xxprim(iim + 1)
254 END IF
255
256 DO i = 1, iim
257 xlon(i) = xvrai(i)
258 xprimm(i) = xxprim(i)
259 END DO
260
261 DO i = 1, iim -1
262 IF (xvrai(i + 1) < xvrai(i)) THEN
263 print *, 'Problème avec rlonu(', i + 1, &
264 ') plus petit que rlonu(', i, ')'
265 STOP 1
266 END IF
267 END DO
268
269 ! Réorganisation des longitudes pour les avoir entre - pi et pi
270
271 champmin = 1e12
272 champmax = -1e12
273 DO i = 1, iim
274 champmin = MIN(champmin, xvrai(i))
275 champmax = MAX(champmax, xvrai(i))
276 END DO
277
278 IF (.not. (champmin >= -pi_d - 0.1 .and. champmax <= pi_d + 0.1)) THEN
279 print *, 'Reorganisation des longitudes pour avoir entre - pi', &
280 ' et pi '
281
282 IF (xzoom <= 0.) THEN
283 IF (ik == 1) THEN
284 i = 1
285
286 do while (xvrai(i) < - pi_d .and. i < iim)
287 i = i + 1
288 end do
289
290 if (xvrai(i) < - pi_d) then
291 print *, 'Xvrai plus petit que - pi !'
292 STOP 1
293 end if
294
295 is2 = i
296 END IF
297
298 IF (is2.NE. 1) THEN
299 DO ii = is2, iim
300 xlon(ii-is2 + 1) = xvrai(ii)
301 xprimm(ii-is2 + 1) = xxprim(ii)
302 END DO
303 DO ii = 1, is2 -1
304 xlon(ii + iim-is2 + 1) = xvrai(ii) + twopi_d
305 xprimm(ii + iim-is2 + 1) = xxprim(ii)
306 END DO
307 END IF
308 ELSE
309 IF (ik == 1) THEN
310 i = iim
311
312 do while (xvrai(i) > pi_d .and. i > 1)
313 i = i - 1
314 end do
315
316 if (xvrai(i) > pi_d) then
317 print *, 'Xvrai plus grand que pi !'
318 STOP 1
319 end if
320
321 is2 = i
322 END IF
323
324 idif = iim -is2
325
326 DO ii = 1, is2
327 xlon(ii + idif) = xvrai(ii)
328 xprimm(ii + idif) = xxprim(ii)
329 END DO
330
331 DO ii = 1, idif
332 xlon(ii) = xvrai(ii + is2) - twopi_d
333 xprimm(ii) = xxprim(ii + is2)
334 END DO
335 END IF
336 END IF
337
338 ! Fin de la reorganisation
339
340 xlon(iim + 1) = xlon(1) + twopi_d
341 xprimm(iim + 1) = xprimm(1)
342
343 DO i = 1, iim + 1
344 xvrai(i) = xlon(i)*180. / pi_d
345 END DO
346
347 IF (ik == 1) THEN
348 DO i = 1, iim + 1
349 rlonm025(i) = xlon(i)
350 xprimm025(i) = xprimm(i)
351 END DO
352 ELSE IF (ik == 2) THEN
353 rlonv = xlon
354 xprimv = xprimm
355 ELSE IF (ik == 3) THEN
356 DO i = 1, iim + 1
357 rlonu(i) = xlon(i)
358 xprimu(i) = xprimm(i)
359 END DO
360 ELSE IF (ik == 4) THEN
361 DO i = 1, iim + 1
362 rlonp025(i) = xlon(i)
363 xprimp025(i) = xprimm(i)
364 END DO
365 END IF
366 end DO loop_ik
367
368 print *
369
370 DO i = 1, iim
371 xlon(i) = rlonv(i + 1) - rlonv(i)
372 END DO
373 champmin = 1e12
374 champmax = -1e12
375 DO i = 1, iim
376 champmin = MIN(champmin, xlon(i))
377 champmax = MAX(champmax, xlon(i))
378 END DO
379 champmin = champmin * 180. / pi_d
380 champmax = champmax * 180. / pi_d
381
382 DO i = 1, iim + 1
383 IF (rlonp025(i) < rlonv(i)) THEN
384 print *, ' Attention ! rlonp025 < rlonv', i
385 STOP 1
386 END IF
387
388 IF (rlonv(i) < rlonm025(i)) THEN
389 print *, ' Attention ! rlonm025 > rlonv', i
390 STOP 1
391 END IF
392
393 IF (rlonp025(i) > rlonu(i)) THEN
394 print *, ' Attention ! rlonp025 > rlonu', i
395 STOP 1
396 END IF
397 END DO
398
399 print *, ' Longitudes '
400 print 3, champmin, champmax
401
402 3 Format(1x, ' Au centre du zoom, la longueur de la maille est', &
403 ' d environ ', f0.2, ' degres ', /, &
404 ' alors que la maille en dehors de la zone du zoom est ', &
405 "d'environ", f0.2, ' degres ')
406
407 END SUBROUTINE fxhyp
408
409 end module fxhyp_m

  ViewVC Help
Powered by ViewVC 1.1.21