source: LMDZ6/branches/Amaury_dev/libf/dyn3d_common/fxhyp_m.F90

Last change on this file was 5160, checked in by abarral, 7 weeks ago

Put .h into modules

  • 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: 7.1 KB
RevLine 
[2218]1module fxhyp_m
[524]2
[2218]3  IMPLICIT NONE
[524]4
[5119]5CONTAINS
[524]6
[2218]7  SUBROUTINE fxhyp(xprimm025, rlonv, xprimv, rlonu, xprimu, xprimp025)
[524]8
[2218]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
[524]11
[2218]12    ! Calcule les longitudes et dérivées dans la grille du GCM pour
13    ! une fonction f(x) à dérivée tangente hyperbolique.
[524]14
[2218]15    ! Il vaut mieux avoir : grossismx \times dzoom < pi
[524]16
[2218]17    ! Le premier point scalaire pour une grille regulière (grossismx =
18    ! 1., taux=0., clon=0.) est à - 180 degrés.
[524]19
[5159]20    USE lmdz_dimensions, ONLY: iim
[5117]21    USE lmdz_arth, ONLY: arth
22    USE invert_zoom_x_m, ONLY: invert_zoom_x, nmax
23    USE lmdz_physical_constants, ONLY: pi, pi_d, twopi, twopi_d, k8
24    USE principal_cshift_m, ONLY: principal_cshift
25    USE serre_mod, ONLY: clon, grossismx, dzoomx, taux
[524]26
[5159]27    REAL, INTENT(OUT) :: xprimm025(:), rlonv(:), xprimv(:) ! (iim + 1)
28    REAL, INTENT(OUT) :: rlonu(:), xprimu(:), xprimp025(:) ! (iim + 1)
[524]29
[2218]30    ! Local:
[5117]31    REAL rlonm025(iim + 1), rlonp025(iim + 1)
[2218]32    REAL dzoom, step
[5117]33    REAL d_rlonv(iim)
[2228]34    REAL(K8) xtild(0:2 * nmax)
35    REAL(K8) fhyp(nmax:2 * nmax), ffdx, beta, Xprimt(0:2 * nmax)
36    REAL(K8) Xf(0:2 * nmax), xxpr(2 * nmax)
37    REAL(K8) fa, fb
[2218]38    INTEGER i, is2
[2228]39    REAL(K8) xmoy, fxm
[1674]40
[2218]41    !----------------------------------------------------------------------
[1674]42
[5160]43    PRINT *, "Call sequence information: fxhyp"
[1674]44
[5116]45    test_iim: if (iim==1) THEN
[5159]46      rlonv(1) = 0.
47      rlonu(1) = pi
48      rlonv(2) = rlonv(1) + twopi
49      rlonu(2) = rlonu(1) + twopi
[1674]50
[5159]51      xprimm025(:) = 1.
52      xprimv(:) = 1.
53      xprimu(:) = 1.
54      xprimp025(:) = 1.
[2218]55    else test_iim
[5159]56      test_grossismx: if (grossismx == 1.) THEN
57        step = twopi / iim
[524]58
[5159]59        xprimm025(:iim) = step
60        xprimp025(:iim) = step
61        xprimv(:iim) = step
62        xprimu(:iim) = step
[524]63
[5159]64        rlonv(:iim) = arth(- pi + clon / 180. * pi, step, iim)
65        rlonm025(:iim) = rlonv(:iim) - 0.25 * step
66        rlonp025(:iim) = rlonv(:iim) + 0.25 * step
67        rlonu(:iim) = rlonv(:iim) + 0.5 * step
68      else test_grossismx
69        dzoom = dzoomx * twopi_d
70        xtild = arth(- pi_d, pi_d / nmax, 2 * nmax + 1)
[524]71
[5159]72        ! Compute fhyp:
73        DO i = nmax, 2 * nmax
74          fa = taux * (dzoom / 2. - xtild(i))
75          fb = xtild(i) * (pi_d - xtild(i))
[524]76
[5159]77          IF (200. * fb < - fa) THEN
78            fhyp(i) = - 1.
79          ELSE IF (200. * fb < fa) THEN
80            fhyp(i) = 1.
81          ELSE
82            IF (ABS(fa) < 1e-13 .AND. ABS(fb) < 1e-13) THEN
83              IF (200. * fb + fa < 1e-10) THEN
[2218]84                fhyp(i) = - 1.
[5159]85              ELSE IF (200. * fb - fa < 1e-10) THEN
[2218]86                fhyp(i) = 1.
[5159]87              END IF
88            ELSE
89              fhyp(i) = TANH(fa / fb)
90            END IF
91          END IF
[524]92
[5159]93          IF (xtild(i) == 0.) fhyp(i) = 1.
94          IF (xtild(i) == pi_d) fhyp(i) = -1.
95        END DO
[524]96
[5159]97        ! Calcul de beta
[524]98
[5159]99        ffdx = 0.
[524]100
[5159]101        DO i = nmax + 1, 2 * nmax
102          xmoy = 0.5 * (xtild(i - 1) + xtild(i))
103          fa = taux * (dzoom / 2. - xmoy)
104          fb = xmoy * (pi_d - xmoy)
[524]105
[5159]106          IF (200. * fb < - fa) THEN
107            fxm = - 1.
108          ELSE IF (200. * fb < fa) THEN
109            fxm = 1.
110          ELSE
111            IF (ABS(fa) < 1e-13 .AND. ABS(fb) < 1e-13) THEN
112              IF (200. * fb + fa < 1e-10) THEN
[2218]113                fxm = - 1.
[5159]114              ELSE IF (200. * fb - fa < 1e-10) THEN
[2218]115                fxm = 1.
[5159]116              END IF
117            ELSE
118              fxm = TANH(fa / fb)
119            END IF
120          END IF
[524]121
[5159]122          IF (xmoy == 0.) fxm = 1.
123          IF (xmoy == pi_d) fxm = -1.
[524]124
[5159]125          ffdx = ffdx + fxm * (xtild(i) - xtild(i - 1))
126        END DO
[524]127
[5160]128        PRINT *, "ffdx = ", ffdx
[5159]129        beta = (grossismx * ffdx - pi_d) / (ffdx - pi_d)
[5160]130        PRINT *, "beta = ", beta
[524]131
[5159]132        IF (2. * beta - grossismx <= 0.) THEN
[5160]133          PRINT *, 'Bad choice of grossismx, taux, dzoomx.'
134          PRINT *, 'Decrease dzoomx or grossismx.'
[5159]135          STOP 1
136        END IF
[524]137
[5159]138        ! calcul de Xprimt
139        Xprimt(nmax:2 * nmax) = beta + (grossismx - beta) * fhyp
140        xprimt(:nmax - 1) = xprimt(2 * nmax:nmax + 1:- 1)
[524]141
[5159]142        ! Calcul de Xf
[524]143
[5159]144        DO i = nmax + 1, 2 * nmax
145          xmoy = 0.5 * (xtild(i - 1) + xtild(i))
146          fa = taux * (dzoom / 2. - xmoy)
147          fb = xmoy * (pi_d - xmoy)
[524]148
[5159]149          IF (200. * fb < - fa) THEN
150            fxm = - 1.
151          ELSE IF (200. * fb < fa) THEN
152            fxm = 1.
153          ELSE
154            fxm = TANH(fa / fb)
155          END IF
[524]156
[5159]157          IF (xmoy == 0.) fxm = 1.
158          IF (xmoy == pi_d) fxm = -1.
159          xxpr(i) = beta + (grossismx - beta) * fxm
160        END DO
[524]161
[5159]162        xxpr(:nmax) = xxpr(2 * nmax:nmax + 1:- 1)
[524]163
[5159]164        Xf(0) = - pi_d
[524]165
[5159]166        DO i = 1, 2 * nmax - 1
167          Xf(i) = Xf(i - 1) + xxpr(i) * (xtild(i) - xtild(i - 1))
168        END DO
[524]169
[5159]170        Xf(2 * nmax) = pi_d
[524]171
[5159]172        CALL invert_zoom_x(xf, xtild, Xprimt, rlonm025(:iim), &
173                xprimm025(:iim), xuv = - 0.25_k8)
174        CALL invert_zoom_x(xf, xtild, Xprimt, rlonv(:iim), xprimv(:iim), &
175                xuv = 0._k8)
176        CALL invert_zoom_x(xf, xtild, Xprimt, rlonu(:iim), xprimu(:iim), &
177                xuv = 0.5_k8)
178        CALL invert_zoom_x(xf, xtild, Xprimt, rlonp025(:iim), &
179                xprimp025(:iim), xuv = 0.25_k8)
180      end if test_grossismx
[524]181
[5159]182      is2 = 0
[524]183
[5159]184      IF (MINval(rlonm025(:iim)) < - pi - 0.1 &
185              .OR. MAXval(rlonm025(:iim)) > pi + 0.1) THEN
186        IF (clon <= 0.) THEN
187          is2 = 1
[524]188
[5159]189          DO while (rlonm025(is2) < - pi .AND. is2 < iim)
190            is2 = is2 + 1
191          END DO
[524]192
[5159]193          IF (rlonm025(is2) < - pi) THEN
[5160]194            PRINT *, 'Rlonm025 plus petit que - pi !'
[5159]195            STOP 1
196          end if
197        ELSE
198          is2 = iim
[524]199
[5159]200          DO while (rlonm025(is2) > pi .AND. is2 > 1)
201            is2 = is2 - 1
202          END DO
[524]203
[5159]204          IF (rlonm025(is2) > pi) THEN
[5160]205            PRINT *, 'Rlonm025 plus grand que pi !'
[5159]206            STOP 1
207          end if
208        END IF
209      END IF
[524]210
[5159]211      CALL principal_cshift(is2, rlonm025, xprimm025)
212      CALL principal_cshift(is2, rlonv, xprimv)
213      CALL principal_cshift(is2, rlonu, xprimu)
214      CALL principal_cshift(is2, rlonp025, xprimp025)
[524]215
[5159]216      forall (i = 1:iim) d_rlonv(i) = rlonv(i + 1) - rlonv(i)
[5160]217      PRINT *, "Minimum longitude step:", MINval(d_rlonv) * 180. / pi, &
[5159]218              "degrees"
[5160]219      PRINT *, "Maximum longitude step:", MAXval(d_rlonv) * 180. / pi, &
[5159]220              "degrees"
[524]221
[5159]222      ! Check that rlonm025 <= rlonv <= rlonp025 <= rlonu:
223      DO i = 1, iim + 1
224        IF (rlonp025(i) < rlonv(i)) THEN
[5160]225          PRINT *, 'rlonp025(', i, ') = ', rlonp025(i)
226          PRINT *, "< rlonv(", i, ") = ", rlonv(i)
[5159]227          STOP 1
228        END IF
[524]229
[5159]230        IF (rlonv(i) < rlonm025(i)) THEN
[5160]231          PRINT *, 'rlonv(', i, ') = ', rlonv(i)
232          PRINT *, "< rlonm025(", i, ") = ", rlonm025(i)
[5159]233          STOP 1
234        END IF
[524]235
[5159]236        IF (rlonp025(i) > rlonu(i)) THEN
[5160]237          PRINT *, 'rlonp025(', i, ') = ', rlonp025(i)
238          PRINT *, "> rlonu(", i, ") = ", rlonu(i)
[5159]239          STOP 1
240        END IF
241      END DO
[2218]242    end if test_iim
[524]243
[2218]244  END SUBROUTINE fxhyp
[524]245
[5119]246END MODULE fxhyp_m
Note: See TracBrowser for help on using the repository browser.