source: trunk/LMDZ.COMMON/libf/dyn3d/inidissip.F90 @ 825

Last change on this file since 825 was 776, checked in by emillour, 12 years ago

Common dynamics: updates to keep up with LMDZ5 Earth (rev 1649)
See file "DOC/chantiers/commit_importants.log" for details.
EM

File size: 6.6 KB
RevLine 
[1]1!
[270]2! $Id: inidissip.F90 1502 2011-03-21 16:07:54Z jghattas $
[1]3!
[270]4SUBROUTINE inidissip ( lstardis,nitergdiv,nitergrot,niterh  , &
5     tetagdiv,tetagrot,tetatemp             )
6  !=======================================================================
7  !   initialisation de la dissipation horizontale
8  !=======================================================================
9  !-----------------------------------------------------------------------
10  !   declarations:
11  !   -------------
[1]12
[270]13  USE control_mod, only : dissip_period,iperiod
[1]14
[270]15  IMPLICIT NONE
16  include "dimensions.h"
17  include "paramet.h"
18  include "comdissipn.h"
19  include "comconst.h"
20  include "comvert.h"
21  include "logic.h"
22  include "iniprint.h"
[1]23
[270]24  LOGICAL,INTENT(in) :: lstardis
25  INTEGER,INTENT(in) :: nitergdiv,nitergrot,niterh
26  REAL,INTENT(in) :: tetagdiv,tetagrot,tetatemp
[1]27
[270]28! Local variables:
29  REAL fact,zvert(llm),zz
[776]30  REAL zh(ip1jmp1),zu(ip1jmp1), gx(ip1jmp1), divgra(ip1jmp1)
31  real zv(ip1jm), gy(ip1jm), deltap(ip1jmp1,llm)
[270]32  REAL ullm,vllm,umin,vmin,zhmin,zhmax
[776]33  REAL zllm
[1]34
[270]35  INTEGER l,ij,idum,ii
36  REAL tetamin
37  REAL Pup
38  character (len=80) :: abort_message
[1]39
[270]40  REAL ran1
[1]41
42
[270]43  !-----------------------------------------------------------------------
44  !
45  !   calcul des valeurs propres des operateurs par methode iterrative:
46  !   -----------------------------------------------------------------
[1]47
[270]48  crot     = -1.
49  cdivu    = -1.
50  cdivh    = -1.
51
52  !   calcul de la valeur propre de divgrad:
53  !   --------------------------------------
54  idum = 0
55  DO l = 1, llm
56     DO ij = 1, ip1jmp1
[1]57        deltap(ij,l) = 1.
[270]58     ENDDO
59  ENDDO
[1]60
[270]61  idum  = -1
62  zh(1) = RAN1(idum)-.5
63  idum  = 0
64  DO ij = 2, ip1jmp1
65     zh(ij) = RAN1(idum) -.5
66  ENDDO
[1]67
[270]68  CALL filtreg (zh,jjp1,1,2,1,.TRUE.,1)
[1]69
[270]70  CALL minmax(iip1*jjp1,zh,zhmin,zhmax )
[1]71
[270]72  IF ( zhmin .GE. zhmax  )     THEN
73     write(lunout,*)'  Inidissip  zh min max  ',zhmin,zhmax
74     abort_message='probleme generateur alleatoire dans inidissip'
75     call abort_gcm('inidissip',abort_message,1)
76  ENDIF
[1]77
[270]78  zllm = ABS( zhmax )
79  DO l = 1,50
80     IF(lstardis) THEN
[776]81        CALL divgrad2(1,zh,deltap,niterh,divgra)
[270]82     ELSE
[776]83        CALL divgrad (1,zh,niterh,divgra)
[270]84     ENDIF
[1]85
[776]86     zllm  = ABS(maxval(divgra))
87     zh = divgra / zllm
[270]88  ENDDO
[1]89
[270]90  IF(lstardis) THEN
91     cdivh = 1./ zllm
92  ELSE
93     cdivh = zllm ** ( -1./niterh )
94  ENDIF
[1]95
[270]96  !   calcul des valeurs propres de gradiv (ii =1) et  nxgrarot(ii=2)
97  !   -----------------------------------------------------------------
98  write(lunout,*)'inidissip: calcul des valeurs propres'
[1]99
[270]100  DO    ii = 1, 2
101     !
102     DO ij = 1, ip1jmp1
103        zu(ij)  = RAN1(idum) -.5
104     ENDDO
105     CALL filtreg (zu,jjp1,1,2,1,.TRUE.,1)
106     DO ij = 1, ip1jm
107        zv(ij) = RAN1(idum) -.5
108     ENDDO
109     CALL filtreg (zv,jjm,1,2,1,.FALSE.,1)
[1]110
[270]111     CALL minmax(iip1*jjp1,zu,umin,ullm )
112     CALL minmax(iip1*jjm, zv,vmin,vllm )
[1]113
[270]114     ullm = ABS ( ullm )
115     vllm = ABS ( vllm )
[1]116
[270]117     DO    l = 1, 50
118        IF(ii.EQ.1) THEN
119           !cccc             CALL covcont( 1,zu,zv,zu,zv )
120           IF(lstardis) THEN
[776]121              CALL gradiv2( 1,zu,zv,nitergdiv,gx,gy )
[270]122           ELSE
[776]123              CALL gradiv ( 1,zu,zv,nitergdiv,gx,gy )
[270]124           ENDIF
125        ELSE
126           IF(lstardis) THEN
[776]127              CALL nxgraro2( 1,zu,zv,nitergrot,gx,gy )
[270]128           ELSE
[776]129              CALL nxgrarot( 1,zu,zv,nitergrot,gx,gy )
[270]130           ENDIF
131        ENDIF
[1]132
[776]133        zllm = max(abs(maxval(gx)), abs(maxval(gy)))
134        zu = gx / zllm
135        zv = gy / zllm
[270]136     end DO
[1]137
[270]138     IF ( ii.EQ.1 ) THEN
139        IF(lstardis) THEN
140           cdivu  = 1./zllm
141        ELSE
142           cdivu  = zllm **( -1./nitergdiv )
143        ENDIF
144     ELSE
145        IF(lstardis) THEN
146           crot   = 1./ zllm
147        ELSE
148           crot   = zllm **( -1./nitergrot )
149        ENDIF
150     ENDIF
[1]151
[270]152  end DO
[1]153
[270]154  !   petit test pour les operateurs non star:
155  !   ----------------------------------------
[1]156
[270]157  !     IF(.NOT.lstardis) THEN
158  fact    = rad*24./REAL(jjm)
159  fact    = fact*fact
160  write(lunout,*)'inidissip: coef u ', fact/cdivu, 1./cdivu
161  write(lunout,*)'inidissip: coef r ', fact/crot , 1./crot
162  write(lunout,*)'inidissip: coef h ', fact/cdivh, 1./cdivh
163  !     ENDIF
[1]164
[270]165  !-----------------------------------------------------------------------
166  !   variation verticale du coefficient de dissipation:
167  !   --------------------------------------------------
[1]168
[270]169! First step: going from 1 to dissip_fac_mid (in gcm.def)
170!============
171  DO l=1,llm
172     zz      = 1. - preff/presnivs(l)
173     zvert(l)= dissip_fac_mid -( dissip_fac_mid-1.)/( 1.+zz*zz )
174  ENDDO
[108]175
[270]176  write(lunout,*) 'Dissipation : '
177  write(lunout,*) 'Multiplication de la dissipation en altitude :'
178  write(lunout,*) '  dissip_fac_mid =', dissip_fac_mid
[108]179
[270]180! Second step if ok_strato:  from dissip_fac_mid to dissip_fac_up (in gcm.def)
181!==========================
182! Utilisation de la fonction tangente hyperbolique pour augmenter
183! arbitrairement la dissipation et donc la stabilite du modele a
184! partir d'une certaine altitude.
[108]185
[270]186!   Le facteur multiplicatif de basse atmosphere etant deja pris
187!   en compte, il faut diviser le facteur multiplicatif de haute
188!   atmosphere par celui-ci.
[108]189
[270]190  if (ok_strato) then
[108]191
[270]192    Pup = dissip_pupstart*exp(-0.5*dissip_deltaz/dissip_hdelta)
193    do l=1,llm
194      zvert(l)= zvert(l)*(1.0+( (dissip_fac_up/dissip_fac_mid-1) &
195                *(1-(0.5*(1+tanh(-6./dissip_deltaz*              &
196               (-dissip_hdelta*log(presnivs(l)/Pup))  ))))  ))
197    enddo
[108]198
[270]199    write(*,*) '  dissip_fac_up =', dissip_fac_up
200    write(*,*) 'Transition mid /up:  Pupstart,delta =',           &
201                   dissip_pupstart,'Pa', dissip_deltaz , '(km)'
[108]202
[270]203  endif
[1]204
205
[270]206  write(lunout,*)'inidissip: Constantes de temps de la diffusion horizontale'
[1]207
[270]208  tetamin =  1.e+6
[1]209
[270]210  DO l=1,llm
211     tetaudiv(l)   = zvert(l)/tetagdiv
212     tetaurot(l)   = zvert(l)/tetagrot
213     tetah(l)      = zvert(l)/tetatemp
[1]214
[270]215     IF( tetamin.GT. (1./tetaudiv(l)) ) tetamin = 1./ tetaudiv(l)
216     IF( tetamin.GT. (1./tetaurot(l)) ) tetamin = 1./ tetaurot(l)
217     IF( tetamin.GT. (1./   tetah(l)) ) tetamin = 1./    tetah(l)
218  ENDDO
[1]219
[270]220  ! If dissip_period=0 calculate value for dissipation period, else keep value read from gcm.def
221  IF (dissip_period == 0) THEN
222     dissip_period = INT( tetamin/( 2.*dtvr*iperiod) ) * iperiod
223     write(lunout,*)'inidissip: tetamin dtvr iperiod dissip_period(intermed) ',tetamin,dtvr,iperiod,dissip_period
224     dissip_period = MAX(iperiod,dissip_period)
225  END IF
[1]226
[270]227  dtdiss  = dissip_period * dtvr
228  write(lunout,*)'inidissip: dissip_period=',dissip_period,' dtdiss=',dtdiss,' dtvr=',dtvr
[1]229
[270]230  DO l = 1,llm
231     write(lunout,*)zvert(l),dtdiss*tetaudiv(l),dtdiss*tetaurot(l), &
232          dtdiss*tetah(l)
233  ENDDO
234
235END SUBROUTINE inidissip
Note: See TracBrowser for help on using the repository browser.