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

Contents of /trunk/dyn3d/fxhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 112 - (show annotations)
Thu Sep 18 13:36:51 2014 UTC (9 years, 8 months ago) by guez
File size: 10489 byte(s)
Removed 8 first arguments of fxyhyper, use variables of module serre
instead.

Moved reading of variables of module serre from procedure conf_gcm to
new procedure read_serre.

In guide, added conditions to avoid useless calls to tau2alpha and
writefield. Bugfix: offline corresponds to alpha = 1. Open only one
NetCDF file to read number of vertical levels.

In tau2alpha, added conditions to avoid useless computations of dxdyu
and dxdyv. gamma is not needed for a regular grid.

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

  ViewVC Help
Powered by ViewVC 1.1.21