source: LMDZ6/trunk/libf/dyn3d_common/fyhyp_m.f90 @ 5456

Last change on this file since 5456 was 5271, checked in by abarral, 2 months ago

Move dimensions.h into a module
Nb: doesn't compile yet

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
RevLine 
[2218]1module fyhyp_m
[524]2
[2218]3  IMPLICIT NONE
[524]4
[2218]5contains
[524]6
[2218]7  SUBROUTINE fyhyp(rlatu, yyprimu, rlatv, rlatu2, yprimu2, rlatu1, yprimu1)
[524]8
[2218]9    ! From LMDZ4/libf/dyn3d/fyhyp.F, version 1.2, 2005/06/03 09:11:32
[524]10
[2218]11    ! Author: P. Le Van, from analysis by R. Sadourny
[524]12
[2218]13    ! Calcule les latitudes et dérivées dans la grille du GCM pour une
14    ! fonction f(y) à dérivée tangente hyperbolique.
[524]15
[2218]16    ! Il vaut mieux avoir : grossismy * dzoom < pi / 2
[524]17
[2218]18    use coefpoly_m, only: coefpoly
[2228]19    use nrtype, only: k8
[2598]20    use serre_mod, only: clat, grossismy, dzoomy, tauy
[5271]21    USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[524]22
[2218]23    REAL, intent(out):: rlatu(jjm + 1), yyprimu(jjm + 1)
24    REAL, intent(out):: rlatv(jjm)
25    real, intent(out):: rlatu2(jjm), yprimu2(jjm), rlatu1(jjm), yprimu1(jjm)
[524]26
[2218]27    ! Local:
[524]28
[2228]29    REAL(K8) champmin, champmax
[2218]30    INTEGER, PARAMETER:: nmax=30000, nmax2=2*nmax
31    REAL dzoom ! distance totale de la zone du zoom (en radians)
[2228]32    REAL(K8) ylat(jjm + 1), yprim(jjm + 1)
33    REAL(K8) yuv
34    REAL(K8), save:: yt(0:nmax2)
35    REAL(K8) fhyp(0:nmax2), beta
36    REAL(K8), save:: ytprim(0:nmax2)
37    REAL(K8) fxm(0:nmax2)
38    REAL(K8), save:: yf(0:nmax2)
39    REAL(K8) yypr(0:nmax2)
40    REAL(K8) yvrai(jjm + 1), yprimm(jjm + 1), ylatt(jjm + 1)
41    REAL(K8) pi, pis2, epsilon, y0, pisjm
42    REAL(K8) yo1, yi, ylon2, ymoy, yprimin
43    REAL(K8) yfi, yf1, ffdy
44    REAL(K8) ypn, deply, y00
[2218]45    SAVE y00, deply
[524]46
[2218]47    INTEGER i, j, it, ik, iter, jlat
48    INTEGER jpn, jjpn
49    SAVE jpn
[2228]50    REAL(K8) a0, a1, a2, a3, yi2, heavyy0, heavyy0m
51    REAL(K8) fa(0:nmax2), fb(0:nmax2)
[2218]52    REAL y0min, y0max
[524]53
[2228]54    REAL(K8) heavyside
[524]55
[2218]56    !-------------------------------------------------------------------
[524]57
[2218]58    print *, "Call sequence information: fyhyp"
[524]59
[2218]60    pi = 2.*asin(1.)
61    pis2 = pi/2.
62    pisjm = pi/real(jjm)
63    epsilon = 1e-3
64    y0 = clat*pi/180.
65    dzoom = dzoomy*pi
66    print *, 'yzoom(rad), grossismy, tauy, dzoom (rad):'
67    print *, y0, grossismy, tauy, dzoom
[524]68
[2218]69    DO i = 0, nmax2
70       yt(i) = -pis2 + real(i)*pi/nmax2
71    END DO
[524]72
[2218]73    heavyy0m = heavyside(-y0)
74    heavyy0 = heavyside(y0)
75    y0min = 2.*y0*heavyy0m - pis2
76    y0max = 2.*y0*heavyy0 + pis2
[524]77
[2218]78    fa = 999.999
79    fb = 999.999
[524]80
[2218]81    DO i = 0, nmax2
82       IF (yt(i)<y0) THEN
83          fa(i) = tauy*(yt(i)-y0 + dzoom/2.)
84          fb(i) = (yt(i)-2.*y0*heavyy0m + pis2)*(y0-yt(i))
85       ELSE IF (yt(i)>y0) THEN
86          fa(i) = tauy*(y0-yt(i) + dzoom/2.)
87          fb(i) = (2.*y0*heavyy0-yt(i) + pis2)*(yt(i)-y0)
88       END IF
[524]89
[2218]90       IF (200.*fb(i)<-fa(i)) THEN
91          fhyp(i) = -1.
92       ELSE IF (200.*fb(i)<fa(i)) THEN
93          fhyp(i) = 1.
94       ELSE
95          fhyp(i) = tanh(fa(i)/fb(i))
96       END IF
[524]97
[2218]98       IF (yt(i)==y0) fhyp(i) = 1.
99       IF (yt(i)==y0min .OR. yt(i)==y0max) fhyp(i) = -1.
100    END DO
[524]101
[2218]102    ! Calcul de beta
[524]103
[2218]104    ffdy = 0.
[524]105
[2218]106    DO i = 1, nmax2
107       ymoy = 0.5*(yt(i-1) + yt(i))
108       IF (ymoy<y0) THEN
109          fa(i) = tauy*(ymoy-y0 + dzoom/2.)
110          fb(i) = (ymoy-2.*y0*heavyy0m + pis2)*(y0-ymoy)
111       ELSE IF (ymoy>y0) THEN
112          fa(i) = tauy*(y0-ymoy + dzoom/2.)
113          fb(i) = (2.*y0*heavyy0-ymoy + pis2)*(ymoy-y0)
114       END IF
[524]115
[2218]116       IF (200.*fb(i)<-fa(i)) THEN
117          fxm(i) = -1.
118       ELSE IF (200.*fb(i)<fa(i)) THEN
119          fxm(i) = 1.
120       ELSE
121          fxm(i) = tanh(fa(i)/fb(i))
122       END IF
123       IF (ymoy==y0) fxm(i) = 1.
124       IF (ymoy==y0min .OR. yt(i)==y0max) fxm(i) = -1.
125       ffdy = ffdy + fxm(i)*(yt(i)-yt(i-1))
126    END DO
[524]127
[2218]128    beta = (grossismy*ffdy-pi)/(ffdy-pi)
[524]129
[2218]130    IF (2. * beta - grossismy <= 0.) THEN
131       print *, 'Attention ! La valeur beta calculee dans la routine fyhyp ' &
132            // 'est mauvaise. Modifier les valeurs de grossismy, tauy ou ' &
133            // 'dzoomy et relancer.'
134       STOP 1
135    END IF
[524]136
[2218]137    ! calcul de Ytprim
[524]138
[2218]139    DO i = 0, nmax2
140       ytprim(i) = beta + (grossismy-beta)*fhyp(i)
141    END DO
[524]142
[2218]143    ! Calcul de Yf
[524]144
[2218]145    yf(0) = -pis2
146    DO i = 1, nmax2
147       yypr(i) = beta + (grossismy-beta)*fxm(i)
148    END DO
[524]149
[2218]150    DO i = 1, nmax2
151       yf(i) = yf(i-1) + yypr(i)*(yt(i)-yt(i-1))
152    END DO
[524]153
[2218]154    ! yuv = 0. si calcul des latitudes aux pts. U
155    ! yuv = 0.5 si calcul des latitudes aux pts. V
[524]156
[2218]157    loop_ik: DO ik = 1, 4
158       IF (ik==1) THEN
159          yuv = 0.
160          jlat = jjm + 1
161       ELSE IF (ik==2) THEN
162          yuv = 0.5
163          jlat = jjm
164       ELSE IF (ik==3) THEN
165          yuv = 0.25
166          jlat = jjm
167       ELSE IF (ik==4) THEN
168          yuv = 0.75
169          jlat = jjm
170       END IF
[524]171
[2218]172       yo1 = 0.
173       DO j = 1, jlat
174          yo1 = 0.
175          ylon2 = -pis2 + pisjm*(real(j) + yuv-1.)
176          yfi = ylon2
[524]177
[2218]178          it = nmax2
179          DO while (it >= 1 .and. yfi < yf(it))
180             it = it - 1
181          END DO
[524]182
[2218]183          yi = yt(it)
184          IF (it==nmax2) THEN
185             it = nmax2 - 1
186             yf(it + 1) = pis2
187          END IF
[524]188
[2218]189          ! Interpolation entre yi(it) et yi(it + 1) pour avoir Y(yi)
190          ! et Y'(yi)
[524]191
[2218]192          CALL coefpoly(yf(it), yf(it + 1), ytprim(it), ytprim(it + 1), &
193               yt(it), yt(it + 1), a0, a1, a2, a3)
194
195          yf1 = yf(it)
196          yprimin = a1 + 2.*a2*yi + 3.*a3*yi*yi
197
198          iter = 1
199          DO
200             yi = yi - (yf1-yfi)/yprimin
201             IF (abs(yi-yo1)<=epsilon .or. iter == 300) exit
202             yo1 = yi
203             yi2 = yi*yi
204             yf1 = a0 + a1*yi + a2*yi2 + a3*yi2*yi
205             yprimin = a1 + 2.*a2*yi + 3.*a3*yi2
206          END DO
207          if (abs(yi-yo1) > epsilon) then
208             print *, 'Pas de solution.', j, ylon2
209             STOP 1
210          end if
211
212          yprimin = a1 + 2.*a2*yi + 3.*a3*yi*yi
213          yprim(j) = pi/(jjm*yprimin)
214          yvrai(j) = yi
215       END DO
216
217       DO j = 1, jlat - 1
218          IF (yvrai(j + 1)<yvrai(j)) THEN
219             print *, 'Problème avec rlat(', j + 1, ') plus petit que rlat(', &
220                  j, ')'
221             STOP 1
222          END IF
223       END DO
224
225       print *, 'Reorganisation des latitudes pour avoir entre - pi/2 et pi/2'
226
227       IF (ik==1) THEN
228          ypn = pis2
229          DO j = jjm + 1, 1, -1
230             IF (yvrai(j)<=ypn) exit
231          END DO
232
233          jpn = j
234          y00 = yvrai(jpn)
235          deply = pis2 - y00
236       END IF
237
238       DO j = 1, jjm + 1 - jpn
239          ylatt(j) = -pis2 - y00 + yvrai(jpn + j-1)
240          yprimm(j) = yprim(jpn + j-1)
241       END DO
242
243       jjpn = jpn
244       IF (jlat==jjm) jjpn = jpn - 1
245
246       DO j = 1, jjpn
247          ylatt(j + jjm + 1-jpn) = yvrai(j) + deply
248          yprimm(j + jjm + 1-jpn) = yprim(j)
249       END DO
250
251       ! Fin de la reorganisation
252
[524]253       DO j = 1, jlat
[2218]254          ylat(j) = ylatt(jlat + 1-j)
255          yprim(j) = yprimm(jlat + 1-j)
256       END DO
[524]257
[2218]258       DO j = 1, jlat
259          yvrai(j) = ylat(j)*180./pi
260       END DO
[524]261
[2218]262       IF (ik==1) THEN
263          DO j = 1, jjm + 1
264             rlatu(j) = ylat(j)
265             yyprimu(j) = yprim(j)
266          END DO
267       ELSE IF (ik==2) THEN
268          DO j = 1, jjm
269             rlatv(j) = ylat(j)
270          END DO
271       ELSE IF (ik==3) THEN
272          DO j = 1, jjm
273             rlatu2(j) = ylat(j)
274             yprimu2(j) = yprim(j)
275          END DO
276       ELSE IF (ik==4) THEN
277          DO j = 1, jjm
278             rlatu1(j) = ylat(j)
279             yprimu1(j) = yprim(j)
280          END DO
281       END IF
282    END DO loop_ik
[524]283
[2218]284    DO j = 1, jjm
285       ylat(j) = rlatu(j) - rlatu(j + 1)
286    END DO
287    champmin = 1e12
288    champmax = -1e12
289    DO j = 1, jjm
290       champmin = min(champmin, ylat(j))
291       champmax = max(champmax, ylat(j))
292    END DO
293    champmin = champmin*180./pi
294    champmax = champmax*180./pi
[524]295
[2218]296    DO j = 1, jjm
297       IF (rlatu1(j) <= rlatu2(j)) THEN
298          print *, 'Attention ! rlatu1 < rlatu2 ', rlatu1(j), rlatu2(j), j
299          STOP 13
300       ENDIF
[524]301
[2218]302       IF (rlatu2(j) <= rlatu(j+1)) THEN
303          print *, 'Attention ! rlatu2 < rlatup1 ', rlatu2(j), rlatu(j+1), j
304          STOP 14
305       ENDIF
[524]306
[2218]307       IF (rlatu(j) <= rlatu1(j)) THEN
308          print *, ' Attention ! rlatu < rlatu1 ', rlatu(j), rlatu1(j), j
309          STOP 15
310       ENDIF
[524]311
[2218]312       IF (rlatv(j) <= rlatu2(j)) THEN
313          print *, ' Attention ! rlatv < rlatu2 ', rlatv(j), rlatu2(j), j
314          STOP 16
315       ENDIF
[524]316
[2218]317       IF (rlatv(j) >= rlatu1(j)) THEN
318          print *, ' Attention ! rlatv > rlatu1 ', rlatv(j), rlatu1(j), j
319          STOP 17
320       ENDIF
[524]321
[2218]322       IF (rlatv(j) >= rlatu(j)) THEN
323          print *, ' Attention ! rlatv > rlatu ', rlatv(j), rlatu(j), j
324          STOP 18
325       ENDIF
326    ENDDO
[524]327
[2218]328    print *, 'Latitudes'
329    print 3, champmin, champmax
[524]330
[2218]3313   Format(1x, ' Au centre du zoom, la longueur de la maille est', &
332         ' d environ ', f0.2, ' degres ', /, &
333         ' alors que la maille en dehors de la zone du zoom est ', &
334         "d'environ ", f0.2, ' degres ')
[524]335
[2218]336  END SUBROUTINE fyhyp
[524]337
[2218]338end module fyhyp_m
Note: See TracBrowser for help on using the repository browser.