/[lmdze]/trunk/filtrez/inifilr.f
ViewVC logotype

Annotation of /trunk/filtrez/inifilr.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 151 - (hide annotations)
Tue Jun 23 15:14:20 2015 UTC (8 years, 11 months ago) by guez
Original Path: trunk/Sources/filtrez/inifilr.f
File size: 8512 byte(s)
In procedure inifilr, only a part of the arrays modfrstu and modfrstv
were defined. Split these into 4 arrays that are fully defined and
used: modfrst[ns][uv].

Clarified the logic for the computation of jfilt[ns][uv]. Changed the
initial value of the search so that the initial values for northern
hemisphere and southern hemisphere cannot be the same.

Clarified the logic for the computation of modfrst[ns][uv]: removed
the cycle and exit instructions.

1 guez 54 module inifilr_m
2 guez 3
3 guez 32 IMPLICIT NONE
4 guez 3
5 guez 54 INTEGER jfiltnu, jfiltsu, jfiltnv, jfiltsv
6 guez 140 ! jfiltn index of the last scalar line filtered in NH
7     ! jfilts index of the first line filtered in SH
8 guez 3
9 guez 136 ! North:
10     real, allocatable:: matriceun(:, :, :), matrinvn(:, :, :)
11     ! (iim, iim, 2:jfiltnu)
12 guez 3
13 guez 136 real, allocatable:: matricevn(:, :, :) ! (iim, iim, jfiltnv)
14 guez 3
15 guez 136 ! South:
16     real, allocatable:: matriceus(:, :, :), matrinvs(:, :, :)
17     ! (iim, iim, jfiltsu:jjm)
18    
19     real, allocatable:: matricevs(:, :, :) ! (iim, iim, jfiltsv:jjm)
20    
21 guez 54 contains
22 guez 3
23 guez 54 SUBROUTINE inifilr
24 guez 3
25 guez 54 ! From filtrez/inifilr.F, version 1.1.1.1 2004/05/19 12:53:09
26     ! H. Upadhyaya, O. Sharma
27 guez 3
28 guez 54 ! This routine computes the eigenfunctions of the laplacian on the
29 guez 140 ! stretched grid, and the filtering coefficients. The modes are
30     ! filtered from modfrst to iim.
31 guez 3
32 guez 54 USE dimens_m, ONLY : iim, jjm
33 guez 139 USE dynetat0_m, ONLY : rlatu, rlatv, xprimu, grossismx
34 guez 140 use inifgn_m, only: inifgn, eignfnu, eignfnv
35 guez 143 use jumble, only: new_unit
36 guez 54 use nr_util, only: pi
37 guez 3
38 guez 54 ! Local:
39 guez 132 REAL dlatu(jjm)
40 guez 140 REAL rlamda(2: iim)
41 guez 151 real eignvl(iim) ! eigenvalues sorted in descending order
42 guez 143 REAL cof
43 guez 151 INTEGER i, j, k, unit
44     REAL colat0 ! > 0
45 guez 54 REAL eignft(iim, iim), coff
46 guez 3
47 guez 140 ! Filtering coefficients (lamda_max * cos(rlat) / lamda):
48     real coefilu(iim, jjm), coefilv(iim, jjm)
49     real coefilu2(iim, jjm), coefilv2(iim, jjm)
50    
51 guez 151 ! Index of the mode from where modes are filtered:
52     integer, allocatable:: modfrstnu(:), modfrstsu(:)
53     integer, allocatable:: modfrstnv(:), modfrstsv(:)
54 guez 140
55 guez 54 !-----------------------------------------------------------
56 guez 3
57 guez 54 print *, "Call sequence information: inifilr"
58 guez 3
59 guez 54 CALL inifgn(eignvl)
60 guez 3
61 guez 54 ! compute eigenvalues and eigenfunctions
62     ! compute the filtering coefficients for scalar lines and
63     ! meridional wind v-lines
64     ! we filter all those latitude lines where coefil < 1
65     ! NO FILTERING AT POLES
66     ! colat0 is to be used when alpha (stretching coefficient)
67     ! is set equal to zero for the regular grid case
68 guez 3
69 guez 54 ! Calcul de colat0
70 guez 143 forall (j = 1:jjm) dlatu(j) = rlatu(j) - rlatu(j + 1)
71     colat0 = min(0.5, minval(dlatu) / minval(xprimu(:iim)))
72 guez 54 PRINT *, 'colat0 = ', colat0
73 guez 3
74 guez 143 rlamda = iim / (pi * colat0 / grossismx) / sqrt(abs(eignvl(2: iim)))
75 guez 3
76 guez 151 ! Determination de jfiltnu, jfiltsu, jfiltnv, jfiltsv
77 guez 3
78 guez 151 jfiltnu = (jjm + 1) / 2
79     do while (cos(rlatu(jfiltnu)) >= colat0 &
80     .or. rlamda(iim) * cos(rlatu(jfiltnu)) >= 1.)
81     jfiltnu = jfiltnu - 1
82     end do
83 guez 3
84 guez 151 jfiltsu = jjm / 2 + 2
85     do while (cos(rlatu(jfiltsu)) >= colat0 &
86     .or. rlamda(iim) * cos(rlatu(jfiltsu)) >= 1.)
87     jfiltsu = jfiltsu + 1
88     end do
89 guez 3
90 guez 151 jfiltnv = jjm / 2
91     do while ((cos(rlatv(jfiltnv)) >= colat0 &
92     .or. rlamda(iim) * cos(rlatv(jfiltnv)) >= 1.) .and. jfiltnv >= 2)
93     jfiltnv = jfiltnv - 1
94     end do
95 guez 3
96 guez 151 if (cos(rlatv(jfiltnv)) >= colat0 &
97     .or. rlamda(iim) * cos(rlatv(jfiltnv)) >= 1.) then
98     ! {jfiltnv == 1}
99     PRINT *, 'Could not find jfiltnv.'
100 guez 54 STOP 1
101     END IF
102 guez 3
103 guez 151 jfiltsv = (jjm + 1)/ 2 + 1
104     do while ((cos(rlatv(jfiltsv)) >= colat0 &
105     .or. rlamda(iim) * cos(rlatv(jfiltsv)) >= 1.) .and. jfiltsv <= jjm - 1)
106     jfiltsv = jfiltsv + 1
107     end do
108 guez 3
109 guez 151 IF (cos(rlatv(jfiltsv)) >= colat0 &
110     .or. rlamda(iim) * cos(rlatv(jfiltsv)) >= 1.) THEN
111     ! {jfiltsv == jjm}
112     PRINT *, 'Could not find jfiltsv.'
113 guez 54 STOP 1
114     END IF
115 guez 3
116 guez 151 PRINT *, 'jfiltnu =', jfiltnu
117     PRINT *, 'jfiltsu =', jfiltsu
118     PRINT *, 'jfiltnv =', jfiltnv
119     PRINT *, 'jfiltsv =', jfiltsv
120 guez 3
121 guez 151 ! Determination de coefilu, coefilv, modfrst[ns][uv]:
122 guez 32
123 guez 151 allocate(modfrstnu(2:jfiltnu), modfrstsu(jfiltsu:jjm))
124     allocate(modfrstnv(jfiltnv), modfrstsv(jfiltsv:jjm))
125     coefilu = 0.
126     coefilv = 0.
127     coefilu2 = 0.
128     coefilv2 = 0.
129 guez 32
130 guez 54 DO j = 2, jfiltnu
131 guez 151 modfrstnu(j) = 2
132     do while (rlamda(modfrstnu(j)) * cos(rlatu(j)) >= 1. &
133     .and. modfrstnu(j) <= iim - 1)
134     modfrstnu(j) = modfrstnu(j) + 1
135     end do
136 guez 32
137 guez 151 if (rlamda(modfrstnu(j)) * cos(rlatu(j)) < 1.) then
138     DO k = modfrstnu(j), iim
139     cof = rlamda(k) * cos(rlatu(j))
140     coefilu(k, j) = cof - 1.
141     coefilu2(k, j) = cof**2 - 1.
142     end DO
143     end if
144 guez 54 END DO
145 guez 32
146 guez 54 DO j = 1, jfiltnv
147 guez 151 modfrstnv(j) = 2
148     do while (rlamda(modfrstnv(j)) * cos(rlatv(j)) >= 1. &
149     .and. modfrstnv(j) <= iim - 1)
150     modfrstnv(j) = modfrstnv(j) + 1
151     end do
152 guez 32
153 guez 151 if (rlamda(modfrstnv(j)) * cos(rlatv(j)) < 1.) then
154     DO k = modfrstnv(j), iim
155     cof = rlamda(k) * cos(rlatv(j))
156     coefilv(k, j) = cof - 1.
157     coefilv2(k, j) = cof**2 - 1.
158     end DO
159     end if
160 guez 54 end DO
161 guez 32
162 guez 54 DO j = jfiltsu, jjm
163 guez 151 modfrstsu(j) = 2
164     do while (rlamda(modfrstsu(j)) * cos(rlatu(j)) >= 1. &
165     .and. modfrstsu(j) <= iim - 1)
166     modfrstsu(j) = modfrstsu(j) + 1
167     end do
168 guez 32
169 guez 151 if (rlamda(modfrstsu(j)) * cos(rlatu(j)) < 1.) then
170     DO k = modfrstsu(j), iim
171     cof = rlamda(k) * cos(rlatu(j))
172     coefilu(k, j) = cof - 1.
173     coefilu2(k, j) = cof**2 - 1.
174     end DO
175     end if
176 guez 54 end DO
177 guez 32
178 guez 54 DO j = jfiltsv, jjm
179 guez 151 modfrstsv(j) = 2
180     do while (rlamda(modfrstsv(j)) * cos(rlatv(j)) >= 1. &
181     .and. modfrstsv(j) <= iim - 1)
182     modfrstsv(j) = modfrstsv(j) + 1
183     end do
184 guez 32
185 guez 151 if (rlamda(modfrstsv(j)) * cos(rlatv(j)) < 1.) then
186     DO k = modfrstsv(j), iim
187     cof = rlamda(k) * cos(rlatv(j))
188     coefilv(k, j) = cof - 1.
189     coefilv2(k, j) = cof**2 - 1.
190     end DO
191     end if
192 guez 54 END DO
193 guez 32
194 guez 151 call new_unit(unit)
195     open(unit, file = "inifilr_out.txt", status = "replace", action = "write")
196     write(unit, fmt = *) '"EIGNVL"', eignvl
197     write(unit, fmt = *) '"modfrstnu"', modfrstnu
198     write(unit, fmt = *) '"modfrstsu"', modfrstsu
199     write(unit, fmt = *) '"modfrstnv"', modfrstnv
200     write(unit, fmt = *) '"modfrstsv"', modfrstsv
201     close(unit)
202 guez 32
203 guez 136 allocate(matriceun(iim, iim, 2:jfiltnu), matrinvn(iim, iim, 2:jfiltnu))
204     allocate(matricevn(iim, iim, jfiltnv))
205     allocate(matricevs(iim, iim, jfiltsv:jjm))
206     allocate(matriceus(iim, iim, jfiltsu:jjm), matrinvs(iim, iim, jfiltsu:jjm))
207 guez 32
208 guez 54 ! Calcul de la matrice filtre 'matriceu' pour les champs situes
209     ! sur la grille scalaire
210 guez 32
211 guez 54 DO j = 2, jfiltnu
212     DO i = 1, iim
213 guez 151 IF (i < modfrstnu(j)) then
214 guez 54 coff = 0.
215     else
216     coff = coefilu(i, j)
217     end IF
218 guez 140 eignft(i, :) = eignfnv(:, i) * coff
219 guez 54 END DO
220     matriceun(:, :, j) = matmul(eignfnv, eignft)
221     END DO
222 guez 32
223 guez 54 DO j = jfiltsu, jjm
224     DO i = 1, iim
225 guez 151 IF (i < modfrstsu(j)) then
226 guez 54 coff = 0.
227     else
228     coff = coefilu(i, j)
229     end IF
230     eignft(i, :) = eignfnv(:, i) * coff
231     END DO
232 guez 136 matriceus(:, :, j) = matmul(eignfnv, eignft)
233 guez 54 END DO
234 guez 32
235 guez 54 ! Calcul de la matrice filtre 'matricev' pour les champs situes
236     ! sur la grille de V ou de Z
237 guez 32
238 guez 54 DO j = 1, jfiltnv
239     DO i = 1, iim
240 guez 151 IF (i < modfrstnv(j)) then
241 guez 54 coff = 0.
242     else
243     coff = coefilv(i, j)
244     end IF
245 guez 140 eignft(i, :) = eignfnu(:, i) * coff
246 guez 54 END DO
247     matricevn(:, :, j) = matmul(eignfnu, eignft)
248     END DO
249 guez 32
250 guez 54 DO j = jfiltsv, jjm
251     DO i = 1, iim
252 guez 151 IF (i < modfrstsv(j)) then
253 guez 54 coff = 0.
254     else
255     coff = coefilv(i, j)
256     end IF
257 guez 140 eignft(i, :) = eignfnu(:, i) * coff
258 guez 54 END DO
259 guez 136 matricevs(:, :, j) = matmul(eignfnu, eignft)
260 guez 54 END DO
261 guez 32
262 guez 54 ! Calcul de la matrice filtre 'matrinv' pour les champs situes
263     ! sur la grille scalaire , pour le filtre inverse
264 guez 32
265 guez 54 DO j = 2, jfiltnu
266     DO i = 1, iim
267 guez 151 IF (i < modfrstnu(j)) then
268 guez 54 coff = 0.
269     else
270 guez 140 coff = coefilu(i, j) / (1. + coefilu(i, j))
271 guez 54 end IF
272 guez 140 eignft(i, :) = eignfnv(:, i) * coff
273 guez 54 END DO
274     matrinvn(:, :, j) = matmul(eignfnv, eignft)
275     END DO
276 guez 32
277 guez 54 DO j = jfiltsu, jjm
278     DO i = 1, iim
279 guez 151 IF (i < modfrstsu(j)) then
280 guez 54 coff = 0.
281     else
282 guez 140 coff = coefilu(i, j) / (1. + coefilu(i, j))
283 guez 54 end IF
284 guez 140 eignft(i, :) = eignfnv(:, i) * coff
285 guez 54 END DO
286 guez 136 matrinvs(:, :, j) = matmul(eignfnv, eignft)
287 guez 54 END DO
288 guez 32
289 guez 54 END SUBROUTINE inifilr
290 guez 32
291 guez 54 end module inifilr_m

  ViewVC Help
Powered by ViewVC 1.1.21