source: trunk/LMDZ.MARS/libf/filtrez/filtreg_mod.F90 @ 1403

Last change on this file since 1403 was 1403, checked in by emillour, 10 years ago

All models: Reorganizing the physics/dynamics interface.

  • makelmdz and makelmdz_fcm scripts adapted to handle the new directory settings
  • misc: (replaces what was the "bibio" directory)
  • Should only contain extremely generic (and non physics or dynamics-specific) routines
  • Therefore moved initdynav.F90, initfluxsto.F, inithist.F, writedynav.F90, write_field.F90, writehist.F to "dyn3d_common"
  • dynlonlat_phylonlat: (new interface directory)
  • This directory contains routines relevent to physics/dynamics grid interactions, e.g. routines gr_dyn_fi or gr_fi_dyn and calfis
  • Moreover the dynlonlat_phylonlat contains directories "phy*" corresponding to each physics package "phy*" to be used. These subdirectories should only contain specific interfaces (e.g. iniphysiq) or main programs (e.g. newstart)
  • phy*/dyn1d: this subdirectory contains the 1D model using physics from phy*

EM

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