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

Contents of /trunk/dyn3d/fxhyp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 265 - (show annotations)
Tue Mar 20 09:35:59 2018 UTC (6 years, 1 month ago) by guez
File size: 5434 byte(s)
Rename module dimens_m to dimensions.
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 x_f(\tilde x) à dérivée tangente hyperbolique.
14
15 ! Il vaut mieux avoir : grossismx \times delta < pi
16
17 ! Le premier point scalaire pour une grille regulière (grossismx =
18 ! 1) avec clon = 0 est à - 180 degrés.
19
20 USE dimensions, ONLY: iim
21 use dynetat0_m, only: clon, grossismx, dzoomx, taux
22 use invert_zoom_x_m, only: invert_zoom_x, nmax
23 use nr_util, only: pi, pi_d, twopi, twopi_d, arth
24 use principal_cshift_m, only: principal_cshift
25 use tanh_cautious_m, only: tanh_cautious
26
27 REAL, intent(out):: xprimm025(:) ! (iim + 1)
28
29 REAL, intent(out):: rlonv(:) ! (iim + 1)
30 ! longitudes of points of the "scalar" and "v" grid, in rad
31
32 REAL, intent(out):: xprimv(:) ! (iim + 1)
33 ! 2 pi / iim * (derivative of the longitudinal zoom function)(rlonv)
34
35 real, intent(out):: rlonu(:) ! (iim + 1)
36 ! longitudes of points of the "u" grid, in rad
37
38 real, intent(out):: xprimu(:) ! (iim + 1)
39 ! 2 pi / iim * (derivative of the longitudinal zoom function)(rlonu)
40
41 real, intent(out):: xprimp025(:) ! (iim + 1)
42
43 ! Local:
44 real rlonm025(iim + 1), rlonp025(iim + 1), d_rlonv(iim)
45 REAL delta, h
46 DOUBLE PRECISION, dimension(0:nmax):: xtild, fhyp, G, Xf, ffdx
47 DOUBLE PRECISION beta
48 INTEGER i, is2
49 DOUBLE PRECISION xmoy(nmax), fxm(nmax)
50
51 !----------------------------------------------------------------------
52
53 print *, "Call sequence information: fxhyp"
54
55 if (grossismx == 1.) then
56 h = twopi / iim
57
58 xprimm025(:iim) = h
59 xprimp025(:iim) = h
60 xprimv(:iim) = h
61 xprimu(:iim) = h
62
63 rlonv(:iim) = arth(- pi + clon, h, iim)
64 rlonm025(:iim) = rlonv(:iim) - 0.25 * h
65 rlonp025(:iim) = rlonv(:iim) + 0.25 * h
66 rlonu(:iim) = rlonv(:iim) + 0.5 * h
67 else
68 delta = dzoomx * twopi_d
69 xtild = arth(0d0, pi_d / nmax, nmax + 1)
70 forall (i = 1:nmax) xmoy(i) = 0.5d0 * (xtild(i-1) + xtild(i))
71
72 ! Compute fhyp:
73 fhyp(1:nmax - 1) = tanh_cautious(taux * (delta / 2d0 &
74 - xtild(1:nmax - 1)), xtild(1:nmax - 1) &
75 * (pi_d - xtild(1:nmax - 1)))
76 fhyp(0) = 1d0
77 fhyp(nmax) = -1d0
78
79 fxm = tanh_cautious(taux * (delta / 2d0 - xmoy), xmoy * (pi_d - xmoy))
80
81 ! Compute \int_0 ^{\tilde x} F:
82
83 ffdx(0) = 0d0
84
85 DO i = 1, nmax
86 ffdx(i) = ffdx(i - 1) + fxm(i) * (xtild(i) - xtild(i-1))
87 END DO
88
89 print *, "ffdx(nmax) = ", ffdx(nmax)
90 beta = (pi_d - grossismx * ffdx(nmax)) / (pi_d - ffdx(nmax))
91 print *, "beta = ", beta
92
93 IF (2d0 * beta - grossismx <= 0d0) THEN
94 print *, 'Bad choice of grossismx, taux, dzoomx.'
95 print *, 'Decrease dzoomx or grossismx.'
96 STOP 1
97 END IF
98
99 G = beta + (grossismx - beta) * fhyp
100
101 Xf(:nmax - 1) = beta * xtild(:nmax - 1) + (grossismx - beta) &
102 * ffdx(:nmax - 1)
103 Xf(nmax) = pi_d
104
105 call invert_zoom_x(beta, xf, xtild, G, rlonm025(:iim), xprimm025(:iim), &
106 xuv = - 0.25d0)
107 call invert_zoom_x(beta, xf, xtild, G, rlonv(:iim), xprimv(:iim), &
108 xuv = 0d0)
109 call invert_zoom_x(beta, xf, xtild, G, rlonu(:iim), xprimu(:iim), &
110 xuv = 0.5d0)
111 call invert_zoom_x(beta, xf, xtild, G, rlonp025(:iim), xprimp025(:iim), &
112 xuv = 0.25d0)
113 end if
114
115 is2 = 0
116
117 IF (MINval(rlonm025(:iim)) < - pi - 0.1 &
118 .or. MAXval(rlonm025(:iim)) > pi + 0.1) THEN
119 IF (clon <= 0.) THEN
120 is2 = 1
121
122 do while (rlonm025(is2) < - pi .and. is2 < iim)
123 is2 = is2 + 1
124 end do
125
126 if (rlonm025(is2) < - pi) then
127 print *, 'Rlonm025 plus petit que - pi !'
128 STOP 1
129 end if
130 ELSE
131 is2 = iim
132
133 do while (rlonm025(is2) > pi .and. is2 > 1)
134 is2 = is2 - 1
135 end do
136
137 if (rlonm025(is2) > pi) then
138 print *, 'Rlonm025 plus grand que pi !'
139 STOP 1
140 end if
141 END IF
142 END IF
143
144 call principal_cshift(is2, rlonm025, xprimm025)
145 call principal_cshift(is2, rlonv, xprimv)
146 call principal_cshift(is2, rlonu, xprimu)
147 call principal_cshift(is2, rlonp025, xprimp025)
148
149 forall (i = 1: iim) d_rlonv(i) = rlonv(i + 1) - rlonv(i)
150 print *, "Minimum longitude step:", MINval(d_rlonv) * 180. / pi, "degrees"
151 print *, "Maximum longitude step:", MAXval(d_rlonv) * 180. / pi, "degrees"
152
153 ! Check that rlonm025 <= rlonv <= rlonp025 <= rlonu:
154 DO i = 1, iim + 1
155 IF (rlonp025(i) < rlonv(i)) THEN
156 print *, 'rlonp025(', i, ') = ', rlonp025(i)
157 print *, "< rlonv(", i, ") = ", rlonv(i)
158 STOP 1
159 END IF
160
161 IF (rlonv(i) < rlonm025(i)) THEN
162 print *, 'rlonv(', i, ') = ', rlonv(i)
163 print *, "< rlonm025(", i, ") = ", rlonm025(i)
164 STOP 1
165 END IF
166
167 IF (rlonp025(i) > rlonu(i)) THEN
168 print *, 'rlonp025(', i, ') = ', rlonp025(i)
169 print *, "> rlonu(", i, ") = ", rlonu(i)
170 STOP 1
171 END IF
172 END DO
173
174 END SUBROUTINE fxhyp
175
176 end module fxhyp_m

  ViewVC Help
Powered by ViewVC 1.1.21