source: codes/icosagcm/branches/SATURN_DYNAMICO/LMDZ.COMMON/config/ppsrc/dyn/sponge_mod_p.f90 @ 224

Last change on this file since 224 was 224, checked in by ymipsl, 10 years ago
File size: 11.0 KB
Line 
1module sponge_mod_p
2
3implicit none
4
5
6! sponge parameters (set/read via conf_gcm.F)
7logical,save :: callsponge  ! do we use a sponge on upper layers
8integer,save :: mode_sponge ! sponge mode
9integer,save :: nsponge ! number of sponge layers
10real,save :: tetasponge  ! sponge time scale (s) at topmost layer
11
12
13contains
14
15      subroutine sponge_p(ucov,vcov,h,ps,dt,mode)
16
17! Sponge routine: Quench ucov, vcov and potential temperature near the
18!                 top of the model
19! Depending on 'mode' relaxation of variables is towards:
20! mode = 0 : h -> h_mean , ucov -> 0 , vcov -> 0
21! mode = 1 : h -> h_mean , ucov -> ucov_mean , vcov -> 0
22! mode >= 2 : h -> h_mean , ucov -> ucov_mean , vcov -> vcov_mean
23! Number of layer over which sponge is applied is 'nsponge' (read from def file)
24! Time scale for quenching at top level is given by 'tetasponge' (read from
25! def file) and doubles as level indexes decrease.
26! Quenching is modeled as: A(t)=Am+A0exp(-lambda*t)
27! where Am is the zonal average of the field (or zero), and lambda the inverse
28! of the characteristic quenching/relaxation time scale
29! Thus, assuming Am to be time-independent, field at time t+dt is given by:
30! A(t+dt)=A(t)-(A(t)-Am)*(1-exp(-lambda*dt))
31
32      USE Write_Field_p
33      use parallel_lmdz, only: pole_sud,pole_nord,jj_begin,jj_end
34      implicit none
35!-----------------------------------------------------------------------
36!   INCLUDE 'dimensions.h'
37!
38!   dimensions.h contient les dimensions du modele
39!   ndm est tel que iim=2**ndm
40!-----------------------------------------------------------------------
41
42      INTEGER iim,jjm,llm,ndm
43
44      PARAMETER (iim= 128,jjm=96,llm=64,ndm=1)
45
46!-----------------------------------------------------------------------
47!
48! $Header$
49!
50!
51!  ATTENTION!!!!: ce fichier include est compatible format fixe/format libre
52!                 veillez  n'utiliser que des ! pour les commentaires
53!                 et  bien positionner les & des lignes de continuation
54!                 (les placer en colonne 6 et en colonne 73)
55!
56!
57!-----------------------------------------------------------------------
58!   INCLUDE 'paramet.h'
59
60      INTEGER  iip1,iip2,iip3,jjp1,llmp1,llmp2,llmm1
61      INTEGER  kftd,ip1jm,ip1jmp1,ip1jmi1,ijp1llm
62      INTEGER  ijmllm,mvar
63      INTEGER jcfil,jcfllm
64
65      PARAMETER( iip1= iim+1,iip2=iim+2,iip3=iim+3                       &
66     &    ,jjp1=jjm+1-1/jjm)
67      PARAMETER( llmp1 = llm+1,  llmp2 = llm+2, llmm1 = llm-1 )
68      PARAMETER( kftd  = iim/2 -ndm )
69      PARAMETER( ip1jm  = iip1*jjm,  ip1jmp1= iip1*jjp1 )
70      PARAMETER( ip1jmi1= ip1jm - iip1 )
71      PARAMETER( ijp1llm= ip1jmp1 * llm, ijmllm= ip1jm * llm )
72      PARAMETER( mvar= ip1jmp1*( 2*llm+1) + ijmllm )
73      PARAMETER( jcfil=jjm/2+5, jcfllm=jcfil*llm )
74
75!-----------------------------------------------------------------------
76!
77! $Header$
78!
79!-----------------------------------------------------------------------
80! INCLUDE comdissip.h
81
82      COMMON/comdissip/                                                 &
83     &    niterdis,coefdis,tetavel,tetatemp,gamdissip
84
85
86      INTEGER niterdis
87
88      REAL tetavel,tetatemp,coefdis,gamdissip
89
90!-----------------------------------------------------------------------
91!
92! $Id: comvert.h 1654 2012-09-24 15:07:18Z aslmd $
93!
94!-----------------------------------------------------------------------
95!   INCLUDE 'comvert.h'
96
97      COMMON/comvertr/ap(llm+1),bp(llm+1),presnivs(llm),dpres(llm),     &
98     &               pa,preff,nivsigs(llm),nivsig(llm+1),               &
99     &               aps(llm),bps(llm),scaleheight,pseudoalt(llm)
100
101      common/comverti/disvert_type, pressure_exner
102
103      real ap     ! hybrid pressure contribution at interlayers
104      real bp     ! hybrid sigma contribution at interlayer
105      real presnivs ! (reference) pressure at mid-layers
106      real dpres
107      real pa     ! reference pressure (Pa) at which hybrid coordinates
108                  ! become purely pressure
109      real preff  ! reference surface pressure (Pa)
110      real nivsigs
111      real nivsig
112      real aps    ! hybrid pressure contribution at mid-layers
113      real bps    ! hybrid sigma contribution at mid-layers
114      real scaleheight ! atmospheric (reference) scale height (km)
115      real pseudoalt ! pseudo-altitude of model levels (km), based on presnivs(),
116                     ! preff and scaleheight
117
118      integer disvert_type ! type of vertical discretization:
119                           ! 1: Earth (default for planet_type==earth),
120                           !     automatic generation
121                           ! 2: Planets (default for planet_type!=earth),
122                           !     using 'z2sig.def' (or 'esasig.def) file
123
124      logical pressure_exner
125!     compute pressure inside layers using Exner function, else use mean
126!     of pressure values at interfaces
127
128 !-----------------------------------------------------------------------
129!
130! $Header$
131!
132!CDK comgeom2
133      COMMON/comgeom/                                                   &
134     & cu(iip1,jjp1),cv(iip1,jjm),unscu2(iip1,jjp1),unscv2(iip1,jjm)  , &
135     & aire(iip1,jjp1),airesurg(iip1,jjp1),aireu(iip1,jjp1)           , &
136     & airev(iip1,jjm),unsaire(iip1,jjp1),apoln,apols                 , &
137     & unsairez(iip1,jjm),airuscv2(iip1,jjm),airvscu2(iip1,jjm)       , &
138     & aireij1(iip1,jjp1),aireij2(iip1,jjp1),aireij3(iip1,jjp1)       , &
139     & aireij4(iip1,jjp1),alpha1(iip1,jjp1),alpha2(iip1,jjp1)         , &
140     & alpha3(iip1,jjp1),alpha4(iip1,jjp1),alpha1p2(iip1,jjp1)        , &
141     & alpha1p4(iip1,jjp1),alpha2p3(iip1,jjp1),alpha3p4(iip1,jjp1)    , &
142     & fext(iip1,jjm),constang(iip1,jjp1), rlatu(jjp1),rlatv(jjm),      &
143     & rlonu(iip1),rlonv(iip1),cuvsurcv(iip1,jjm),cvsurcuv(iip1,jjm)  , &
144     & cvusurcu(iip1,jjp1),cusurcvu(iip1,jjp1)                        , &
145     & cuvscvgam1(iip1,jjm),cuvscvgam2(iip1,jjm),cvuscugam1(iip1,jjp1), &
146     & cvuscugam2(iip1,jjp1),cvscuvgam(iip1,jjm),cuscvugam(iip1,jjp1) , &
147     & unsapolnga1,unsapolnga2,unsapolsga1,unsapolsga2                , &
148     & unsair_gam1(iip1,jjp1),unsair_gam2(iip1,jjp1)                  , &
149     & unsairz_gam(iip1,jjm),aivscu2gam(iip1,jjm),aiuscv2gam(iip1,jjm)  &
150     & , xprimu(iip1),xprimv(iip1)
151
152
153      REAL                                                               &
154     & cu,cv,unscu2,unscv2,aire,airesurg,aireu,airev,apoln,apols,unsaire &
155     & ,unsairez,airuscv2,airvscu2,aireij1,aireij2,aireij3,aireij4     , &
156     & alpha1,alpha2,alpha3,alpha4,alpha1p2,alpha1p4,alpha2p3,alpha3p4 , &
157     & fext,constang,rlatu,rlatv,rlonu,rlonv,cuvscvgam1,cuvscvgam2     , &
158     & cvuscugam1,cvuscugam2,cvscuvgam,cuscvugam,unsapolnga1           , &
159     & unsapolnga2,unsapolsga1,unsapolsga2,unsair_gam1,unsair_gam2     , &
160     & unsairz_gam,aivscu2gam,aiuscv2gam,cuvsurcv,cvsurcuv,cvusurcu    , &
161     & cusurcvu,xprimu,xprimv
162!
163! $Header$
164!
165!
166! gestion des impressions de sorties et de débogage
167! lunout:    unité du fichier dans lequel se font les sorties
168!                           (par defaut 6, la sortie standard)
169! prt_level: niveau d'impression souhaité (0 = minimum)
170!
171      INTEGER lunout, prt_level
172      COMMON /comprint/ lunout, prt_level
173
174! Arguments:
175!------------
176      real,intent(inout) :: ucov(iip1,jjp1,llm) ! covariant zonal wind
177      real,intent(inout) :: vcov(iip1,jjm,llm) ! covariant meridional wind
178      real,intent(inout) :: h(iip1,jjp1,llm) ! potential temperature
179!      real,intent(in) :: pext(iip1,jjp1) ! extensive pressure
180      real,intent(in) :: ps(iip1,jjp1) ! surface pressure (Pa)
181      real,intent(in) :: dt   ! time step
182      integer,intent(in) :: mode  ! sponge mode
183
184!   Local:
185!   ------
186
187      real,save :: sig_s(llm) !sigma au milieu des couches
188      REAL vm,um,hm,ptot(jjp1)
189      real,save :: cst(llm)
190      real :: pext(iip1,jjp1) ! extensive pressure
191
192      INTEGER l,i,j
193      integer :: jjb,jje
194      integer,save :: l0 ! layer down to which sponge is applied
195
196      real ssum
197
198      real zkm
199      logical,save :: firstcall=.true.
200
201
202
203      if (firstcall) then
204!$OMP BARRIER
205!$OMP MASTER
206       ! build approximative sigma levels at midlayer
207        do l=1,llm
208          sig_s(l)=((ap(l)+ap(l+1))/preff+bp(l)+bp(l+1))/2.
209        enddo
210
211        l0=llm-nsponge+1
212 
213        write(lunout,*)
214        write(lunout,*)'sponge mode',mode
215        write(lunout,*)'nsponge tetasponge ',nsponge,tetasponge
216        write(lunout,*)'Coeffs for the sponge layer'
217        write(lunout,*)'Z (km)         tau             cst'
218        do l=llm,l0,-1
219          ! double time scale with every level, starting from the top
220          cst(l)=1.-exp(-dt/(tetasponge*2**(llm-l)))
221        enddo
222
223        do l=l0,llm
224           zkm=-scaleheight*log(sig_s(l))
225           print*,zkm,tetasponge*2**(llm-l),cst(l)
226        enddo
227        PRINT*
228
229        firstcall=.false.
230!$OMP END MASTER
231!$OMP BARRIER
232      endif ! of if (firstcall)
233
234!-----------------------------------------------------------------------
235!   compute sponge relaxation:
236!   -------------------------
237      jjb=jj_begin
238      jje=jj_end+1 ! +1 because vcov(j) computations require pext(j+1) & ptot(j+1)
239      IF (pole_sud)  jje=jj_end-1+1
240!$OMP MASTER
241      pext(1:iip1,jjb:jje)=ps(1:iip1,jjb:jje)*aire(1:iip1,jjb:jje)
242      do j=jjb,jje
243         ptot(j)=sum(pext(1:iim,j))
244      enddo
245!$OMP END MASTER
246!$OMP BARRIER
247
248
249!   potential temperature
250      jjb=jj_begin
251      jje=jj_end
252!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
253      do l=l0,llm
254         do j=jjb,jje
255            ! compute zonal average
256            hm=0.
257            do i=1,iim
258               hm=hm+h(i,j,l)*pext(i,j)
259            enddo
260            hm=hm/ptot(j)
261            ! update h()
262            do i=1,iim
263               h(i,j,l)=h(i,j,l)-cst(l)*(h(i,j,l)-hm)
264            enddo
265            h(iip1,j,l)=h(1,j,l)
266         enddo
267      enddo
268!$OMP END DO NOWAIT
269
270!   zonal wind
271      jjb=jj_begin
272      jje=jj_end
273      IF (pole_nord) jjb=jj_begin+1
274      IF (pole_sud)  jje=jj_end-1
275!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
276      do l=l0,llm
277         do j=jjb,jje
278            um=0.
279            if(mode.ge.1) then ! compute zonal average
280               do i=1,iim
281                  um=um+0.5*ucov(i,j,l)*(pext(i,j)+pext(i+1,j))/cu(i,j)
282               enddo
283               um=um/ptot(j)
284            endif
285            ! update ucov()
286            do i=1,iim
287               ucov(i,j,l)=ucov(i,j,l)-cst(l)*(ucov(i,j,l)-um*cu(i,j))
288            enddo
289            ucov(iip1,j,l)=ucov(1,j,l)
290         enddo
291      enddo
292!$OMP END DO NOWAIT
293
294!  meridional wind
295      jjb=jj_begin
296      jje=jj_end
297      IF (pole_sud) jje=jj_end-1
298!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
299      do l=l0,llm
300         do j=jjb,jje
301            vm=0.
302            if(mode.ge.2) then ! compute zonal average
303               do i=1,iim
304                  vm=vm+vcov(i,j,l)*(pext(i,j)+pext(i,j+1))/cv(i,j)
305               enddo
306               vm=vm/(ptot(j)+ptot(j+1))
307            endif
308            ! update vcov
309            do i=1,iim
310               vcov(i,j,l)=vcov(i,j,l)-cst(l)*(vcov(i,j,l)-vm*cv(i,j))
311            enddo
312            vcov(iip1,j,l)=vcov(1,j,l)
313         enddo
314      enddo
315!$OMP END DO
316
317      end subroutine sponge_p
318     
319end module sponge_mod_p
320
Note: See TracBrowser for help on using the repository browser.