source: trunk/LMDZ.GENERIC/libf/filtrez/filtreg_mod.F90 @ 1974

Last change on this file since 1974 was 1422, checked in by milmd, 10 years ago

In GENERIC, MARS and COMMON models replace some include files by modules (usefull for decoupling physics with dynamics).

  • Property svn:executable set to *
File size: 16.8 KB
Line 
1MODULE filtreg_mod
2
3CONTAINS
4
5      SUBROUTINE inifilr
6!
7!    ... H. Upadhyaya, O.Sharma   ...
8!
9      USE logic_mod, ONLY: fxyhypb,ysinus
10      USE serre_mod, ONLY: alphax
11
12      IMPLICIT NONE
13!
14!     version 3 .....
15
16!     Correction  le 28/10/97    P. Le Van .
17!  -------------------------------------------------------------------
18#include "dimensions.h"
19#include "paramet.h"
20#include "parafilt.h"
21!  -------------------------------------------------------------------
22#include "comgeom.h"
23#include "coefils.h"
24
25      REAL  dlonu(iim),dlatu(jjm)
26      REAL  rlamda( iim ),  eignvl( iim )
27!
28
29      REAL    lamdamax,pi,cof
30      INTEGER i,j,modemax,imx,k,kf,ii
31      REAL dymin,dxmin,colat0
32      REAL eignft(iim,iim), coff
33      REAL matriceun,matriceus,matricevn,matricevs,matrinvn,matrinvs
34      COMMON/matrfil/matriceun(iim,iim,nfilun),matriceus(iim,iim,nfilus) &
35                   , matricevn(iim,iim,nfilvn),matricevs(iim,iim,nfilvs) &
36                   ,  matrinvn(iim,iim,nfilun),matrinvs (iim,iim,nfilus)
37#ifdef CRAY
38      INTEGER   ISMIN
39      EXTERNAL  ISMIN
40      INTEGER iymin
41      INTEGER ixmineq
42#endif
43      EXTERNAL  inifgn
44!
45! ------------------------------------------------------------
46!   This routine computes the eigenfunctions of the laplacien
47!   on the stretched grid, and the filtering coefficients
48!     
49!  We designate:
50!   eignfn   eigenfunctions of the discrete laplacien
51!   eigenvl  eigenvalues
52!   jfiltn   indexof the last scalar line filtered in NH
53!   jfilts   index of the first line filtered in SH
54!   modfrst  index of the mode from where modes are filtered
55!   modemax  maximum number of modes ( im )
56!   coefil   filtering coefficients ( lamda_max*cos(rlat)/lamda )
57!   sdd      SQRT( dx )
58!     
59!     the modes are filtered from modfrst to modemax
60     
61!-----------------------------------------------------------
62!
63
64       pi       = 2. * ASIN( 1. )
65
66       DO i = 1,iim
67        dlonu(i) = xprimu( i )
68       ENDDO
69!
70       CALL inifgn(eignvl)
71!
72        print *,' EIGNVL '
73        PRINT 250,eignvl
74250     FORMAT( 1x,5e13.6)
75!
76! compute eigenvalues and eigenfunctions
77!
78!
79!.................................................................
80!
81!  compute the filtering coefficients for scalar lines and
82!  meridional wind v-lines
83!
84!  we filter all those latitude lines where coefil < 1
85!  NO FILTERING AT POLES
86!
87!  colat0 is to be used  when alpha (stretching coefficient)
88!  is set equal to zero for the regular grid case
89!
90!    .......   Calcul  de  colat0   .........
91!     .....  colat0 = minimum de ( 0.5, min dy/ min dx )   ...
92!
93!
94      DO 45 j = 1,jjm
95         dlatu( j ) = rlatu( j ) - rlatu( j+1 )
96 45   CONTINUE
97!
98#ifdef CRAY
99      iymin   = ISMIN( jjm, dlatu, 1 )
100      ixmineq = ISMIN( iim, dlonu, 1 )
101      dymin   = dlatu( iymin )
102      dxmin   = dlonu( ixmineq )
103#else
104      dxmin   =  dlonu(1)
105       DO  i  = 2, iim
106        dxmin = MIN( dxmin,dlonu(i) )
107       ENDDO
108      dymin  = dlatu(1)
109       DO j  = 2, jjm
110        dymin = MIN( dymin,dlatu(j) )
111       ENDDO
112#endif
113!
114!
115      colat0  =  MIN( 0.5, dymin/dxmin )
116!
117      IF( .NOT.fxyhypb.AND.ysinus )  THEN
118           colat0 = 0.6
119!         ...... a revoir  pour  ysinus !   .......
120           alphax = 0.
121      ENDIF
122!
123      PRINT 50, colat0,alphax
124  50  FORMAT(/15x,' Inifilr colat0 alphax ',2e16.7)
125!
126      IF(alphax.EQ.1. )  THEN
127        PRINT *,' Inifilr  alphax doit etre  <  a 1.  Corriger '
128         STOP
129      ENDIF
130!
131      lamdamax = iim / ( pi * colat0 * ( 1. - alphax ) )
132
133!c                        ... Correction  le 28/10/97  ( P.Le Van ) ..
134!
135      DO 71 i = 2,iim
136       rlamda( i ) = lamdamax/ SQRT( ABS( eignvl(i) ) )
137 71   CONTINUE
138!
139
140      DO 72 j = 1,jjm
141            DO 73 i = 1,iim
142            coefilu( i,j )  = 0.0
143            coefilv( i,j )  = 0.0
144            coefilu2( i,j ) = 0.0
145            coefilv2( i,j ) = 0.0
146 73     CONTINUE
147 72   CONTINUE
148
149!
150!    ... Determination de jfiltnu,jfiltnv,jfiltsu,jfiltsv ....
151!    .........................................................
152!
153       modemax = iim
154
155!ccc    imx = modemax - 4 * (modemax/iim)
156
157       imx  = iim
158!
159       PRINT *,' TRUNCATION AT ',imx
160!
161      DO 75 j = 2, jjm/2+1
162       cof = COS( rlatu(j) )/ colat0
163            IF ( cof .LT. 1. ) THEN
164          IF( rlamda(imx) * COS(rlatu(j) ).LT.1. ) jfiltnu= j
165        ENDIF
166
167       cof = COS( rlatu(jjp1-j+1) )/ colat0
168            IF ( cof .LT. 1. ) THEN
169          IF( rlamda(imx) * COS(rlatu(jjp1-j+1) ).LT.1. ) &
170            jfiltsu= jjp1-j+1
171        ENDIF
172 75   CONTINUE
173!
174      DO 76 j = 1, jjm/2
175       cof = COS( rlatv(j) )/ colat0
176            IF ( cof .LT. 1. ) THEN
177          IF( rlamda(imx) * COS(rlatv(j) ).LT.1. ) jfiltnv= j
178        ENDIF
179
180       cof = COS( rlatv(jjm-j+1) )/ colat0
181            IF ( cof .LT. 1. ) THEN
182          IF( rlamda(imx) * COS(rlatv(jjm-j+1) ).LT.1. ) &
183             jfiltsv= jjm-j+1
184        ENDIF
185 76   CONTINUE
186!                                 
187
188      IF( jfiltnu.LE.0 .OR. jfiltnu.GT. jjm/2 +1 )  THEN
189        PRINT *,' jfiltnu en dehors des valeurs acceptables ' ,jfiltnu
190        STOP
191      ENDIF
192
193      IF( jfiltsu.LE.0 .OR. jfiltsu.GT.  jjm  +1 )  THEN
194        PRINT *,' jfiltsu en dehors des valeurs acceptables ' ,jfiltsu
195        STOP
196      ENDIF
197
198      IF( jfiltnv.LE.0 .OR. jfiltnv.GT. jjm/2    )  THEN
199        PRINT *,' jfiltnv en dehors des valeurs acceptables ' ,jfiltnv
200        STOP
201      ENDIF
202
203      IF( jfiltsv.LE.0 .OR. jfiltsv.GT.     jjm  )  THEN
204        PRINT *,' jfiltsv en dehors des valeurs acceptables ' ,jfiltsv
205        STOP
206      ENDIF
207
208       PRINT *,' jfiltnv jfiltsv jfiltnu jfiltsu ' , &
209                 jfiltnv,jfiltsv,jfiltnu,jfiltsu
210
211!                                 
212!   ... Determination de coefilu,coefilv,n=modfrstu,modfrstv ....
213!................................................................
214!
215!
216      DO 77 j = 1,jjm
217          modfrstu( j ) = iim
218          modfrstv( j ) = iim
219 77   CONTINUE
220!
221      DO 84 j = 2,jfiltnu
222       DO 81 k = 2,modemax
223             cof = rlamda(k) * COS( rlatu(j) )
224         IF ( cof .LT. 1. ) GOTO 82
225 81    CONTINUE
226      GOTO 84
227 82   modfrstu( j ) = k
228!
229          kf = modfrstu( j )
230           DO 83 k = kf , modemax
231        cof = rlamda(k) * COS( rlatu(j) )
232            coefilu(k,j) = cof - 1.
233            coefilu2(k,j) = cof*cof - 1.
234 83    CONTINUE
235 84   CONTINUE
236!                                 
237!
238      DO 89 j = 1,jfiltnv
239!
240       DO 86 k = 2,modemax
241            cof = rlamda(k) * COS( rlatv(j) )
242         IF ( cof .LT. 1. ) GOTO 87
243 86    CONTINUE
244      GOTO 89
245 87   modfrstv( j ) = k
246!
247           kf = modfrstv( j )
248           DO 88 k = kf , modemax
249        cof = rlamda(k) * COS( rlatv(j) )
250            coefilv(k,j) = cof - 1.
251            coefilv2(k,j) = cof*cof - 1.
252 88    CONTINUE
253!
254 89    CONTINUE
255!
256      DO 94 j = jfiltsu,jjm
257       DO 91 k = 2,modemax
258            cof = rlamda(k) * COS( rlatu(j) )
259         IF ( cof .LT. 1. ) GOTO 92
260 91    CONTINUE
261      GOTO 94
262 92   modfrstu( j ) = k
263!
264        kf = modfrstu( j )
265         DO 93 k = kf , modemax
266          cof = rlamda(k) * COS( rlatu(j) )
267          coefilu(k,j) = cof - 1.
268          coefilu2(k,j) = cof*cof - 1.
269 93      CONTINUE
270 94    CONTINUE
271!                                 
272      DO 99 j = jfiltsv,jjm
273       DO 96 k = 2,modemax
274             cof = rlamda(k) * COS( rlatv(j) )
275         IF ( cof .LT. 1. ) GOTO 97
276 96    CONTINUE
277      GOTO 99
278 97   modfrstv( j ) = k
279!
280       kf = modfrstv( j )
281           DO 98 k = kf , modemax
282        cof = rlamda(k) * COS( rlatv(j) )
283            coefilv(k,j) = cof - 1.
284            coefilv2(k,j) = cof*cof - 1.
285 98    CONTINUE
286 99   CONTINUE
287!
288
289       IF(jfiltnv.GE.jjm/2 .OR. jfiltnu.GE.jjm/2)THEN
290
291         IF(jfiltnv.EQ.jfiltsv)jfiltsv=1+jfiltnv
292         IF(jfiltnu.EQ.jfiltsu)jfiltsu=1+jfiltnu
293
294          PRINT *,'jfiltnv jfiltsv jfiltnu jfiltsu' , &
295              jfiltnv,jfiltsv,jfiltnu,jfiltsu
296       ENDIF
297
298       PRINT *,'   Modes premiers  v  '
299       PRINT 334,modfrstv
300       PRINT *,'   Modes premiers  u  '
301       PRINT 334,modfrstu
302
303     
304      IF( nfilun.LT. jfiltnu )  THEN
305       PRINT *,' le parametre nfilun utilise pour la matrice ', &
306         ' matriceun  est trop petit ! '
307       PRINT *,'Le changer dans parafilt.h et le mettre a  ',jfiltnu
308        PRINT *,' Pour information, nfilun,nfilus,nfilvn,nfilvs ' &
309       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
310        ,jfiltnv,jjm-jfiltsv+1
311               STOP
312      ENDIF
313      IF( nfilun.GT. jfiltnu+ 2 )  THEN
314           PRINT *,' le parametre nfilun utilise pour la matrice ', &
315      ' matriceun est trop grand ! Gachis de memoire ! '
316       PRINT *,'Le changer dans parafilt.h et le mettre a  ',jfiltnu
317        PRINT *,' Pour information, nfilun,nfilus,nfilvn,nfilvs ' &
318       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
319        ,jfiltnv,jjm-jfiltsv+1
320!              STOP
321      ENDIF
322      IF( nfilus.LT. jjm - jfiltsu +1 )  THEN
323            PRINT *,' le parametre nfilus utilise pour la matrice ', &
324         ' matriceus  est trop petit !  '
325       PRINT *,' Le changer dans parafilt.h et le mettre a  ', &
326       jjm - jfiltsu + 1
327        PRINT *,' Pour information , nfilun,nfilus,nfilvn,nfilvs ' &
328       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
329        ,jfiltnv,jjm-jfiltsv+1
330               STOP
331      ENDIF
332      IF( nfilus.GT. jjm - jfiltsu + 3 )  THEN
333           PRINT *,' le parametre nfilus utilise pour la matrice ', &
334       ' matriceus  est trop grand ! '
335       PRINT *,' Le changer dans parafilt.h et le mettre a  ' , &
336       jjm - jfiltsu + 1
337        PRINT *,' Pour information , nfilun,nfilus,nfilvn,nfilvs ' &
338       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
339        ,jfiltnv,jjm-jfiltsv+1
340!              STOP
341      ENDIF
342      IF( nfilvn.LT. jfiltnv )  THEN
343            PRINT *,' le parametre nfilvn utilise pour la matrice ', &
344         ' matricevn  est trop petit ! ' 
345       PRINT *,'Le changer dans parafilt.h et le mettre a  ',jfiltnv
346        PRINT *,' Pour information , nfilun,nfilus,nfilvn,nfilvs ' &
347       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
348        ,jfiltnv,jjm-jfiltsv+1
349               STOP
350      ENDIF
351      IF( nfilvn.GT. jfiltnv+ 2 )  THEN
352           PRINT *,' le parametre nfilvn utilise pour la matrice ', &
353      ' matricevn est trop grand !  Gachis de memoire ! '
354       PRINT *,'Le changer dans parafilt.h et le mettre a  ',jfiltnv
355        PRINT *,' Pour information , nfilun,nfilus,nfilvn,nfilvs ' &
356       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
357        ,jfiltnv,jjm-jfiltsv+1
358!              STOP
359      ENDIF
360      IF( nfilvs.LT. jjm - jfiltsv +1 )  THEN
361            PRINT *,' le parametre nfilvs utilise pour la matrice ', &
362         ' matricevs  est trop petit !  Le changer dans parafilt.h '
363       PRINT *,' Le changer dans parafilt.h et le mettre a  ' &
364       , jjm - jfiltsv + 1
365        PRINT *,' Pour information , nfilun,nfilus,nfilvn,nfilvs ' &
366       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
367        ,jfiltnv,jjm-jfiltsv+1
368               STOP
369      ENDIF
370      IF( nfilvs.GT. jjm - jfiltsv + 3 )  THEN
371           PRINT *,' le parametre nfilvs utilise pour la matrice ', &
372       ' matricevs  est trop grand ! Gachis de memoire ! '
373       PRINT *,' Le changer dans parafilt.h et le mettre a  ' &
374         ,  jjm - jfiltsv + 1
375        PRINT *,' Pour information , nfilun,nfilus,nfilvn,nfilvs ' &
376       ,'doivent etre egaux successivement a  ',jfiltnu,jjm-jfiltsu+1 &
377        ,jfiltnv,jjm-jfiltsv+1
378!              STOP
379      ENDIF
380
381
382!   ...................................................................
383!
384!   ... Calcul de la matrice filtre 'matriceu'  pour les champs situes
385!                       sur la grille scalaire                 ........
386!   ...................................................................
387!
388        DO j = 2, jfiltnu
389
390         DO i=1,iim
391          coff = coefilu(i,j)
392          IF( i.LT.modfrstu(j) ) coff = 0.
393           DO k=1,iim
394            eignft(i,k) = eignfnv(k,i) * coff
395           ENDDO
396         ENDDO
397#ifdef CRAY
398         CALL MXM( eignfnv,iim,eignft,iim,matriceun(1,1,j),iim )
399#else
400#ifdef BLAS
401         CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, &
402         eignfnv, iim, eignft, iim, 0.0, matriceun(1,1,j), iim)
403#else
404         DO k = 1, iim
405         DO i = 1, iim
406            matriceun(i,k,j) = 0.0
407            DO ii = 1, iim
408               matriceun(i,k,j) = matriceun(i,k,j) &
409                                + eignfnv(i,ii)*eignft(ii,k)
410            ENDDO
411         ENDDO
412         ENDDO
413#endif
414#endif
415
416        ENDDO
417
418        DO j = jfiltsu, jjm
419
420         DO i=1,iim
421          coff = coefilu(i,j)
422          IF( i.LT.modfrstu(j) ) coff = 0.
423            DO k=1,iim
424             eignft(i,k) = eignfnv(k,i) * coff
425            ENDDO
426         ENDDO
427#ifdef CRAY
428         CALL MXM(eignfnv,iim,eignft,iim,matriceus(1,1,j-jfiltsu+1),iim)
429#else
430#ifdef BLAS
431      CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, &
432                 eignfnv, iim, eignft, iim, 0.0, &
433                 matriceus(1,1,j-jfiltsu+1), iim)
434#else
435         DO k = 1, iim
436         DO i = 1, iim
437            matriceus(i,k,j-jfiltsu+1) = 0.0
438            DO ii = 1, iim
439               matriceus(i,k,j-jfiltsu+1) = matriceus(i,k,j-jfiltsu+1) &
440                                          + eignfnv(i,ii)*eignft(ii,k)
441            ENDDO
442         ENDDO
443         ENDDO
444#endif
445#endif
446
447        ENDDO
448
449!   ...................................................................
450!
451!   ... Calcul de la matrice filtre 'matricev'  pour les champs situes
452!                       sur la grille   de V ou de Z           ........
453!   ...................................................................
454!
455        DO j = 1, jfiltnv
456
457         DO i = 1, iim
458          coff = coefilv(i,j)
459          IF( i.LT.modfrstv(j) ) coff = 0.
460           DO k = 1, iim
461            eignft(i,k) = eignfnu(k,i) * coff
462           ENDDO
463         ENDDO
464#ifdef CRAY
465          CALL MXM( eignfnu,iim,eignft,iim,matricevn(1,1,j),iim )
466#else
467#ifdef BLAS
468      CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, &
469           eignfnu, iim, eignft, iim, 0.0, matricevn(1,1,j), iim)
470#else
471         DO k = 1, iim
472         DO i = 1, iim
473            matricevn(i,k,j) = 0.0
474            DO ii = 1, iim
475               matricevn(i,k,j) = matricevn(i,k,j) &
476                                + eignfnu(i,ii)*eignft(ii,k)
477            ENDDO
478         ENDDO
479         ENDDO
480#endif
481#endif
482
483        ENDDO
484
485        DO j = jfiltsv, jjm
486
487         DO i = 1, iim
488          coff = coefilv(i,j)
489          IF( i.LT.modfrstv(j) ) coff = 0.
490            DO k = 1, iim
491             eignft(i,k) = eignfnu(k,i) * coff
492            ENDDO
493         ENDDO
494#ifdef CRAY
495         CALL MXM(eignfnu,iim,eignft,iim,matricevs(1,1,j-jfiltsv+1),iim)
496#else
497#ifdef BLAS
498      CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, &
499                 eignfnu, iim, eignft, iim, 0.0, &
500                 matricevs(1,1,j-jfiltsv+1), iim)
501#else
502         DO k = 1, iim
503         DO i = 1, iim
504            matricevs(i,k,j-jfiltsv+1) = 0.0
505            DO ii = 1, iim
506               matricevs(i,k,j-jfiltsv+1) = matricevs(i,k,j-jfiltsv+1) &
507                                + eignfnu(i,ii)*eignft(ii,k)
508            ENDDO
509         ENDDO
510         ENDDO
511#endif
512#endif
513
514        ENDDO
515
516!   ...................................................................
517!
518!   ... Calcul de la matrice filtre 'matrinv'  pour les champs situes
519!              sur la grille scalaire , pour le filtre inverse ........
520!   ...................................................................
521!
522        DO j = 2, jfiltnu
523
524         DO i = 1,iim
525          coff = coefilu(i,j)/ ( 1. + coefilu(i,j) )
526          IF( i.LT.modfrstu(j) ) coff = 0.
527           DO k=1,iim
528            eignft(i,k) = eignfnv(k,i) * coff
529           ENDDO
530         ENDDO
531#ifdef CRAY
532          CALL MXM( eignfnv,iim,eignft,iim,matrinvn(1,1,j),iim )
533#else
534#ifdef BLAS
535      CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, &
536           eignfnv, iim, eignft, iim, 0.0, matrinvn(1,1,j), iim)
537#else
538         DO k = 1, iim
539         DO i = 1, iim
540            matrinvn(i,k,j) = 0.0
541            DO ii = 1, iim
542               matrinvn(i,k,j) = matrinvn(i,k,j) &
543                                + eignfnv(i,ii)*eignft(ii,k)
544            ENDDO
545         ENDDO
546         ENDDO
547#endif
548#endif
549
550        ENDDO
551
552        DO j = jfiltsu, jjm
553
554         DO i = 1,iim
555          coff = coefilu(i,j) / ( 1. + coefilu(i,j) )
556          IF( i.LT.modfrstu(j) ) coff = 0.
557            DO k=1,iim
558             eignft(i,k) = eignfnv(k,i) * coff
559            ENDDO
560         ENDDO
561#ifdef CRAY
562         CALL MXM(eignfnv,iim,eignft,iim,matrinvs(1,1,j-jfiltsu+1),iim)
563#else
564#ifdef BLAS
565      CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, &
566       eignfnv, iim, eignft, iim, 0.0, matrinvs(1,1,j-jfiltsu+1), iim)
567#else
568         DO k = 1, iim
569         DO i = 1, iim
570            matrinvs(i,k,j-jfiltsu+1) = 0.0
571            DO ii = 1, iim
572               matrinvs(i,k,j-jfiltsu+1) = matrinvs(i,k,j-jfiltsu+1) &
573                                + eignfnv(i,ii)*eignft(ii,k)
574            ENDDO
575         ENDDO
576         ENDDO
577#endif
578#endif
579
580        ENDDO
581
582!   ...................................................................
583
584!
585334    FORMAT(1x,24i3)
586755    FORMAT(1x,6f10.3,i3)
587
588       RETURN
589       END SUBROUTINE inifilr
590
591END MODULE  filtreg_mod
Note: See TracBrowser for help on using the repository browser.