Changeset 1010
- Timestamp:
- Jul 24, 2013, 1:36:44 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DOC/chantiers/commit_importants.log
r1000 r1010 1225 1225 Ehouarn: Some cleanup in the dynamics: ismax.F,ismin.F and cray.F (scopy/ssum) 1226 1226 moved to 'bibio' (rather than being in dyn3d and dyn3dpar). 1227 1228 ********************** 1229 **** commit_v1010 **** 1230 ********************** 1231 Ehouarn: Improved sponge layer scheme (top_bound): 1232 - Sponge tendencies are now computed analytically, instead than using 1233 a Forward Euler approximation. 1234 - Sponge tendencies are now added within top_bound. -
trunk/DOC/documentation/top_bound.tex
r108 r1010 37 37 38 38 \vspace{1cm} 39 S\'ebastien Lebonnois 39 S\'ebastien Lebonnois , Ehouarn Millour 40 40 41 41 \vspace{1cm} … … 43 43 \end{center} 44 44 45 %\section{Theoretical aspects} 45 \section{Theoretical aspects} 46 Because of the inevitable numerical boundary at the top of the model, 47 upward travelling waves are found to non-physically reflect down into the 48 atmosphere. 49 A common remedy to this unwanted behaviour is to apply a sponge layer near 50 the top of the model in order to quench these waves and avoid significant 51 reflection thereof. 52 In practice such quenching is done by adding a dissipative term which forces 53 a relaxation of potential temperature and/or winds of the form: 54 \[ 55 A(t)=A_m+A_0 \exp(-\lambda t ) 56 \] 57 Where $A_m$ is the value towards which $A$ is to asymptotically relax, and 58 $\lambda$ is the inverse of the characteristic relaxation time scale. 59 As there is no obvious value of $A_m$ towards which to relax, in practice 60 it is often chosen to be either the zonal average of $A$ (evaluated at time $t$, 61 i.e. conveniently ignoring that $A_m$ then is in fact not time-independent), 62 or zero (at least for winds, since this would have little physical meaning for 63 potential temperature). 46 64 47 65 \section{Pratical aspects in the code} … … 50 68 flag is set to {\em True} in \textsf{gcm.def} 51 69 (this parameter also controls the application of a second step in the 52 horizontal dissipation). 70 determination of vertical variation of coefficients for 71 the horizontal dissipation, see \textsf{inidissip.F} and 72 \textsf{disspi\_horiz.pdf} document). 53 73 54 74 The tendencies for the upper boundary sponge layer are computed separately in 55 the \textsf{top\_bound.F} routine, called from \textsf{leapfrog.F}. 56 These tendencies are \textsf{dutop}, \textsf{dvtop} and \textsf{dhtop}, in 57 unit/s. 75 the \textsf{top\_bound.F} routine (called from \textsf{leapfrog.F}) and 76 added in place. 77 The resulting sponge tendency \textsf{dutop}, in m/s, is also given as an output for 78 diagnostics. 58 79 59 80 Three parameters may be adjusted in the \textsf{gcm.def} file: … … 74 95 averaged value. 75 96 \end{itemize} 76 \item \textsf{tau\_top\_bound}: damping rate (in /s) in the top layer. 97 \item \textsf{tau\_top\_bound}: damping rate ($\lambda$ in equation above, 98 expressed in Hz) in the topmost layer. 77 99 \end{itemize} 78 100 -
trunk/LMDZ.COMMON/libf/dyn3d/conf_gcm.F
r979 r1010 343 343 CALL getin('dissip_pupstart',dissip_pupstart ) 344 344 345 ! Parametres controlant la couche eponge 346 ! Actifs uniquement avec ok_strato=y 347 ! mode = 0 : pas de sponge 348 ! mode = 1 : u et v -> 0 349 ! mode = 2 : u et v -> moyenne zonale 350 ! mode = 3 : u, v et h -> moyenne zonale 345 ! top_bound sponge: only active if ok_strato=.true. and iflag_top_bound!=0 346 ! iflag_top_bound=0 for no sponge 347 ! iflag_top_bound=1 for sponge over 4 topmost layers 348 ! iflag_top_bound=2 for sponge from top to ~1% of top layer pressure 351 349 iflag_top_bound=1 350 CALL getin('iflag_top_bound',iflag_top_bound) 351 352 ! mode_top_bound : fields towards which sponge relaxation will be done: 353 ! mode_top_bound=0: no relaxation 354 ! mode_top_bound=1: u and v relax towards 0 355 ! mode_top_bound=2: u and v relax towards their zonal mean 356 ! mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean 352 357 mode_top_bound=3 358 CALL getin('mode_top_bound',mode_top_bound) 359 360 ! top_bound sponge : inverse of charactericstic relaxation time scale for sponge 353 361 tau_top_bound=1.e-5 354 CALL getin('iflag_top_bound',iflag_top_bound)355 CALL getin('mode_top_bound',mode_top_bound)356 362 CALL getin('tau_top_bound',tau_top_bound) 357 363 -
trunk/LMDZ.COMMON/libf/dyn3d/leapfrog.F
r841 r1010 103 103 104 104 c tendances de la couche superieure */s 105 REAL dvtop(ip1jm,llm),dutop(ip1jmp1,llm) 106 REAL dtetatop(ip1jmp1,llm) 107 REAL dqtop(ip1jmp1,llm,nqtot),dptop(ip1jmp1) 105 c REAL dvtop(ip1jm,llm) 106 REAL dutop(ip1jmp1,llm) 107 c REAL dtetatop(ip1jmp1,llm) 108 c REAL dqtop(ip1jmp1,llm,nqtot),dptop(ip1jmp1) 108 109 109 110 c TITAN : tendances due au forces de marees */s … … 216 217 dtetadis(:,:)=0. 217 218 dutop(:,:) =0. 218 dvtop(:,:) =0.219 dtetatop(:,:)=0.220 dqtop(:,:,:) =0.221 dptop(:) =0.219 c dvtop(:,:) =0. 220 c dtetatop(:,:)=0. 221 c dqtop(:,:,:) =0. 222 c dptop(:) =0. 222 223 dufi(:,:) =0. 223 224 dvfi(:,:) =0. … … 504 505 c ------------------- 505 506 IF (ok_strato) THEN 506 CALL top_bound( vcov,ucov,teta,phi,masse, 507 $ dutop,dvtop,dtetatop) 508 c dqtop=0, dptop=0 509 CALL addfi( dtphys, leapf, forward , 510 $ ucov, vcov, teta , q ,ps , 511 $ dutop, dvtop, dtetatop , dqtop ,dptop ) 507 CALL top_bound(vcov,ucov,teta,masse,dtphys,dutop) 508 dutop(:,:)=dutop(:,:)/dtphys ! convert to a tendency in (m/s)/s 512 509 ENDIF 513 510 … … 543 540 ! Sponge layer (if any) 544 541 IF (ok_strato) THEN 545 CALL top_bound(vcov,ucov,teta,phi, 546 $ masse,dutop,dvtop,dtetatop) 547 c dqtop=0, dptop=0 548 CALL addfi( dtvr, leapf, forward , 549 $ ucov, vcov, teta , q ,ps , 550 $ dutop, dvtop, dtetatop , dqtop ,dptop ) 542 CALL top_bound(vcov,ucov,teta,masse,dtvr,dutop) 543 dutop(:,:)=dutop(:,:)/dtvr ! convert to a tendency in (m/s)/s 551 544 ENDIF ! of IF (ok_strato) 552 545 ENDIF ! of IF (iflag_phys.EQ.2) -
trunk/LMDZ.COMMON/libf/dyn3d/top_bound.F
r110 r1010 1 SUBROUTINE top_bound( vcov,ucov,teta,phi,masse, du,dv,dh ) 1 ! 2 ! $Id: top_bound.F 1793 2013-07-18 07:13:18Z emillour $ 3 ! 4 SUBROUTINE top_bound(vcov,ucov,teta,masse,dt,ducov) 2 5 IMPLICIT NONE 3 6 c … … 24 27 c 25 28 c======================================================================= 26 c-----------------------------------------------------------------------27 c Declarations:28 c -------------29 29 30 ! #include "comgeom.h" 30 ! top_bound sponge layer model: 31 ! Quenching is modeled as: A(t)=Am+A0*exp(-lambda*t) 32 ! where Am is the zonal average of the field (or zero), and lambda the inverse 33 ! of the characteristic quenching/relaxation time scale 34 ! Thus, assuming Am to be time-independent, field at time t+dt is given by: 35 ! A(t+dt)=A(t)-(A(t)-Am)*(1-exp(-lambda*dt)) 36 ! Moreover lambda can be a function of model level (see below), and relaxation 37 ! can be toward the average zonal field or just zero (see below). 38 39 ! NB: top_bound sponge is only called from leapfrog if ok_strato=.true. 40 41 ! sponge parameters: (loaded/set in conf_gcm.F ; stored in comconst.h) 42 ! iflag_top_bound=0 for no sponge 43 ! iflag_top_bound=1 for sponge over 4 topmost layers 44 ! iflag_top_bound=2 for sponge from top to ~1% of top layer pressure 45 ! mode_top_bound=0: no relaxation 46 ! mode_top_bound=1: u and v relax towards 0 47 ! mode_top_bound=2: u and v relax towards their zonal mean 48 ! mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean 49 ! tau_top_bound : inverse of charactericstic relaxation time scale at 50 ! the topmost layer (Hz) 51 52 31 53 #include "comdissipn.h" 54 #include "iniprint.h" 32 55 33 56 c Arguments: 34 57 c ---------- 35 58 36 REAL ucov(iip1,jjp1,llm),vcov(iip1,jjm,llm),teta(iip1,jjp1,llm) 37 REAL phi(iip1,jjp1,llm) ! geopotentiel 38 REAL masse(iip1,jjp1,llm) 39 REAL dv(iip1,jjm,llm),du(iip1,jjp1,llm),dh(iip1,jjp1,llm) 59 real,intent(inout) :: ucov(iip1,jjp1,llm) ! covariant zonal wind 60 real,intent(inout) :: vcov(iip1,jjm,llm) ! covariant meridional wind 61 real,intent(inout) :: teta(iip1,jjp1,llm) ! potential temperature 62 real,intent(in) :: masse(iip1,jjp1,llm) ! mass of atmosphere 63 real,intent(in) :: dt ! time step (s) of sponge model 64 real,intent(out) :: ducov(iip1,jjp1,llm) ! increment on ucov due to sponge 40 65 41 66 c Local: … … 45 70 REAL uzon(jjp1,llm),vzon(jjm,llm),tzon(jjp1,llm) 46 71 47 INTEGER NDAMP48 PARAMETER (NDAMP=4)49 72 integer i 50 REAL,SAVE :: rdamp(llm) 51 ! & (/(0., i =1,llm-NDAMP),0.125E-5,.25E-5,.5E-5,1.E-5/) 73 REAL,SAVE :: rdamp(llm) ! quenching coefficient 74 real,save :: lambda(llm) ! inverse or quenching time scale (Hz) 52 75 53 76 LOGICAL,SAVE :: first=.true. 54 77 55 REAL zkm56 78 INTEGER j,l 57 58 59 C CALCUL DES CHAMPS EN MOYENNE ZONALE:60 79 61 80 if (iflag_top_bound.eq.0) return … … 63 82 if (first) then 64 83 if (iflag_top_bound.eq.1) then 65 ! couche eponge dans les 4 dernieres couches du modele66 rdamp(:)=0.67 rdamp(llm)=tau_top_bound68 rdamp(llm-1)=tau_top_bound/2.69 rdamp(llm-2)=tau_top_bound/4.70 rdamp(llm-3)=tau_top_bound/8.84 ! sponge quenching over the topmost 4 atmospheric layers 85 lambda(:)=0. 86 lambda(llm)=tau_top_bound 87 lambda(llm-1)=tau_top_bound/2. 88 lambda(llm-2)=tau_top_bound/4. 89 lambda(llm-3)=tau_top_bound/8. 71 90 else if (iflag_top_bound.eq.2) then 72 ! couche eponge dans toutes les couches de pression plus faible que73 ! 100 fois la pression de la derniere couche74 rdamp(:)=tau_top_bound91 ! sponge quenching over topmost layers down to pressures which are 92 ! higher than 100 times the topmost layer pressure 93 lambda(:)=tau_top_bound 75 94 s *max(presnivs(llm)/presnivs(:)-0.01,0.) 76 95 endif 77 first=.false. 78 print*,'TOP_BOUND mode',mode_top_bound 79 print*,'Coeffs pour la couche eponge a l equateur' 80 print*,'p (Pa) z(km) tau (s)' 96 97 ! quenching coefficient rdamp(:) 98 ! rdamp(:)=dt*lambda(:) ! Explicit Euler approx. 99 rdamp(:)=1.-exp(-lambda(:)*dt) 100 101 write(lunout,*)'TOP_BOUND mode',mode_top_bound 102 write(lunout,*)'Sponge layer coefficients' 103 write(lunout,*)'p (Pa) z(km) tau(s) 1./tau (Hz)' 81 104 do l=1,llm 82 105 if (rdamp(l).ne.0.) then 83 zkm = phi(iip1/2,jjp1/2,l)/(1000*g) 84 print*,presnivs(l),zkm,1./rdamp(l) 106 write(lunout,'(6(1pe12.4,1x))') 107 & presnivs(l),log(preff/presnivs(l))*scaleheight, 108 & 1./lambda(l),lambda(l) 85 109 endif 86 110 enddo 87 endif 111 first=.false. 112 endif ! of if (first) 88 113 89 114 CALL massbar(masse,massebx,masseby) 90 115 91 c mode = 0 : pas de sponge 92 c mode = 1 : u et v -> 0 93 c mode = 2 : u et v -> moyenne zonale 94 c mode = 3 : u, v et h -> moyenne zonale 95 116 ! compute zonal average of vcov and u 96 117 if (mode_top_bound.ge.2) then 97 118 do l=1,llm … … 100 121 zm=0. 101 122 do i=1,iim 102 ! Rm: on peut travailler directement avec la moyenne zonale de vcov 103 ! plutot qu'avec celle de v car le coefficient cv qui relie les deux 104 ! ne varie qu'en latitude 123 ! NB: we can work using vcov zonal mean rather than v since the 124 ! cv coefficient (which relates the two) only varies with latitudes 105 125 vzon(j,l)=vzon(j,l)+vcov(i,j,l)*masseby(i,j,l) 106 126 zm=zm+masseby(i,j,l) … … 111 131 112 132 do l=1,llm 113 do j=2,jjm 133 do j=2,jjm ! excluding poles 114 134 uzon(j,l)=0. 115 135 zm=0. … … 121 141 enddo 122 142 enddo 123 else 124 125 126 endif 143 else ! ucov and vcov will relax towards 0 144 vzon(:,:)=0. 145 uzon(:,:)=0. 146 endif ! of if (mode_top_bound.ge.2) 127 147 148 ! compute zonal average of potential temperature, if necessary 128 149 if (mode_top_bound.ge.3) then 129 150 do l=1,llm 130 do j=2,jjm 151 do j=2,jjm ! excluding poles 131 152 zm=0. 132 153 tzon(j,l)=0. … … 138 159 enddo 139 160 enddo 140 endif 141 142 C AMORTISSEMENTS LINEAIRES: 161 endif ! of if (mode_top_bound.ge.3) 143 162 144 163 if (mode_top_bound.ge.1) then 164 ! Apply sponge quenching on vcov: 145 165 do l=1,llm 146 166 do i=1,iip1 147 167 do j=1,jjm 148 dv(i,j,l)= -rdamp(l)*(vcov(i,j,l)-vzon(j,l)) 168 vcov(i,j,l)=vcov(i,j,l) 169 & -rdamp(l)*(vcov(i,j,l)-vzon(j,l)) 149 170 enddo 150 171 enddo 151 172 enddo 152 173 174 ! Apply sponge quenching on ucov: 153 175 do l=1,llm 154 176 do i=1,iip1 155 do j=2,jjm 156 du(i,j,l)= -rdamp(l)*(ucov(i,j,l)-cu(i,j)*uzon(j,l)) 177 do j=2,jjm ! excluding poles 178 ducov(i,j,l)=-rdamp(l)*(ucov(i,j,l)-cu(i,j)*uzon(j,l)) 179 ucov(i,j,l)=ucov(i,j,l) 180 & +ducov(i,j,l) 157 181 enddo 158 182 enddo 159 183 enddo 160 endif 184 endif ! of if (mode_top_bound.ge.1) 161 185 162 186 if (mode_top_bound.ge.3) then 187 ! Apply sponge quenching on teta: 163 188 do l=1,llm 164 189 do i=1,iip1 165 do j=2,jjm 166 dh(i,j,l)= -rdamp(l)*(teta(i,j,l)-tzon(j,l)) 190 do j=2,jjm ! excluding poles 191 teta(i,j,l)=teta(i,j,l) 192 & -rdamp(l)*(teta(i,j,l)-tzon(j,l)) 167 193 enddo 168 194 enddo 169 195 enddo 170 endif 171 172 RETURN 196 endif ! of if (mode_top_bound.ge.3) 197 173 198 END -
trunk/LMDZ.COMMON/libf/dyn3dpar/conf_gcm.F
r979 r1010 370 370 CALL getin('dissip_pupstart',dissip_pupstart ) 371 371 372 ! Parametres controlant la couche eponge 373 ! Actifs uniquement avec ok_strato=y 374 ! mode = 0 : pas de sponge 375 ! mode = 1 : u et v -> 0 376 ! mode = 2 : u et v -> moyenne zonale 377 ! mode = 3 : u, v et h -> moyenne zonale 372 ! top_bound sponge: only active if ok_strato=.true. and iflag_top_bound!=0 373 ! iflag_top_bound=0 for no sponge 374 ! iflag_top_bound=1 for sponge over 4 topmost layers 375 ! iflag_top_bound=2 for sponge from top to ~1% of top layer pressure 378 376 iflag_top_bound=1 377 CALL getin('iflag_top_bound',iflag_top_bound) 378 379 ! mode_top_bound : fields towards which sponge relaxation will be done: 380 ! mode_top_bound=0: no relaxation 381 ! mode_top_bound=1: u and v relax towards 0 382 ! mode_top_bound=2: u and v relax towards their zonal mean 383 ! mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean 379 384 mode_top_bound=3 385 CALL getin('mode_top_bound',mode_top_bound) 386 387 ! top_bound sponge : inverse of charactericstic relaxation time scale for sponge 380 388 tau_top_bound=1.e-5 381 CALL getin('iflag_top_bound',iflag_top_bound)382 CALL getin('mode_top_bound',mode_top_bound)383 389 CALL getin('tau_top_bound',tau_top_bound) 384 390 -
trunk/LMDZ.COMMON/libf/dyn3dpar/leapfrog_p.F
r953 r1010 113 113 114 114 c tendances top_bound (sponge layer) 115 REAL,SAVE :: dvtop(ip1jm,llm),dutop(ip1jmp1,llm) 116 REAL,SAVE :: dtetatop(ip1jmp1,llm) 117 REAL,SAVE :: dptop(ip1jmp1) 118 REAL,DIMENSION(:,:,:),ALLOCATABLE,SAVE :: dqtop 115 c REAL,SAVE :: dvtop(ip1jm,llm) 116 REAL,SAVE :: dutop(ip1jmp1,llm) 117 c REAL,SAVE :: dtetatop(ip1jmp1,llm) 118 c REAL,SAVE :: dptop(ip1jmp1) 119 c REAL,DIMENSION(:,:,:),ALLOCATABLE,SAVE :: dqtop 119 120 120 121 c TITAN : tendances due au forces de marees */s … … 247 248 ALLOCATE(dqfi(ip1jmp1,llm,nqtot)) 248 249 ALLOCATE(dqfi_tmp(iip1,llm,nqtot)) 249 ALLOCATE(dqtop(ip1jmp1,llm,nqtot))250 c ALLOCATE(dqtop(ip1jmp1,llm,nqtot)) 250 251 END IF 251 252 c$OMP END MASTER … … 262 263 dtetadis(:,:)=0. 263 264 dutop(:,:) =0. 264 dvtop(:,:) =0.265 dtetatop(:,:)=0.266 dqtop(:,:,:) =0.267 dptop(:) =0.265 c dvtop(:,:) =0. 266 c dtetatop(:,:)=0. 267 c dqtop(:,:,:) =0. 268 c dptop(:) =0. 268 269 dufi(:,:) =0. 269 270 dvfi(:,:) =0. … … 1001 1002 c ------------------- 1002 1003 IF (ok_strato) THEN 1003 CALL top_bound_p( vcov,ucov,teta,phi,masse, 1004 $ dutop,dvtop,dtetatop) 1005 CALL addfi_p( dtphys, leapf, forward , 1006 $ ucov, vcov, teta , q ,ps , 1007 $ dutop, dvtop, dtetatop , dqtop ,dptop ) 1008 1009 ENDIF 1004 CALL top_bound_p(vcov,ucov,teta,masse,dtphys, 1005 $ dutop) 1006 ijb=ij_begin 1007 ije=ij_end 1008 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 1009 DO l=1,llm 1010 dutop(ijb:ije,l)=dutop(ijb:ije,l)/dtphys ! convert to a tendency in (m/s)/s 1011 ENDDO 1012 c$OMP END DO NOWAIT 1013 ENDIF ! of IF (ok_strato) 1010 1014 1011 1015 c$OMP BARRIER … … 1124 1128 ! Sponge layer (if any) 1125 1129 IF (ok_strato) THEN 1126 ! set dutop,dvtop,... to zero 1130 CALL top_bound_p(vcov,ucov,teta,masse,dtvr, 1131 $ dutop) 1127 1132 ijb=ij_begin 1128 1133 ije=ij_end 1129 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 1130 do l=1,llm 1131 dutop(ijb:ije,l)=0 1132 dtetatop(ijb:ije,l)=0 1133 dqtop(ijb:ije,l,1:nqtot)=0 1134 enddo 1135 !$OMP END DO 1136 !$OMP SINGLE 1137 dptop(ijb:ije)=0 1138 !$OMP END SINGLE 1139 ijb=ij_begin 1140 ije=ij_end 1141 if (pole_sud) ije=ije-iip1 1142 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 1143 do l=1,llm 1144 dvtop(ijb:ije,l)=0 1145 enddo 1146 !$OMP END DO 1147 1148 CALL top_bound_p(vcov,ucov,teta,phi,masse, 1149 $ dutop,dvtop,dtetatop) 1150 CALL addfi_p( dtvr, leapf, forward , 1151 $ ucov, vcov, teta , q ,ps , 1152 $ dutop, dvtop, dtetatop , dqtop ,dptop ) 1134 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 1135 DO l=1,llm 1136 dutop(ijb:ije,l)=dutop(ijb:ije,l)/dtvr ! convert to a tendency in (m/s)/s 1137 ENDDO 1138 c$OMP END DO NOWAIT 1153 1139 !$OMP BARRIER 1154 1140 ENDIF ! of IF (ok_strato) -
trunk/LMDZ.COMMON/libf/dyn3dpar/top_bound_p.F
r124 r1010 1 SUBROUTINE top_bound_p( vcov,ucov,teta,phi,masse, du,dv,dh ) 1 ! 2 ! $Id: top_bound_p.F 1793 2013-07-18 07:13:18Z emillour $ 3 ! 4 SUBROUTINE top_bound_p(vcov,ucov,teta,masse,dt,ducov) 2 5 USE parallel 3 6 IMPLICIT NONE … … 25 28 c 26 29 c======================================================================= 27 c----------------------------------------------------------------------- 28 c Declarations: 29 c ------------- 30 31 ! top_bound sponge layer model: 32 ! Quenching is modeled as: A(t)=Am+A0*exp(-lambda*dt) 33 ! where Am is the zonal average of the field (or zero), and lambda the inverse 34 ! of the characteristic quenching/relaxation time scale 35 ! Thus, assuming Am to be time-independent, field at time t+dt is given by: 36 ! A(t+dt)=A(t)-(A(t)-Am)*(1-exp(-lambda*t)) 37 ! Moreover lambda can be a function of model level (see below), and relaxation 38 ! can be toward the average zonal field or just zero (see below). 39 40 ! NB: top_bound sponge is only called from leapfrog if ok_strato=.true. 41 42 ! sponge parameters: (loaded/set in conf_gcm.F ; stored in comconst.h) 43 ! iflag_top_bound=0 for no sponge 44 ! iflag_top_bound=1 for sponge over 4 topmost layers 45 ! iflag_top_bound=2 for sponge from top to ~1% of top layer pressure 46 ! mode_top_bound=0: no relaxation 47 ! mode_top_bound=1: u and v relax towards 0 48 ! mode_top_bound=2: u and v relax towards their zonal mean 49 ! mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean 50 ! tau_top_bound : inverse of charactericstic relaxation time scale at 51 ! the topmost layer (Hz) 52 30 53 31 54 #include "comdissipn.h" 55 #include "iniprint.h" 32 56 33 57 c Arguments: 34 58 c ---------- 35 59 36 REAL ucov(iip1,jjp1,llm),vcov(iip1,jjm,llm),teta(iip1,jjp1,llm) 37 REAL phi(iip1,jjp1,llm) ! geopotentiel 38 REAL masse(iip1,jjp1,llm) 39 REAL dv(iip1,jjm,llm),du(iip1,jjp1,llm),dh(iip1,jjp1,llm) 60 real,intent(inout) :: ucov(iip1,jjp1,llm) ! covariant zonal wind 61 real,intent(inout) :: vcov(iip1,jjm,llm) ! covariant meridional wind 62 real,intent(inout) :: teta(iip1,jjp1,llm) ! potential temperature 63 real,intent(in) :: masse(iip1,jjp1,llm) ! mass of atmosphere 64 real,intent(in) :: dt ! time step (s) of sponge model 65 real,intent(out) :: ducov(iip1,jjp1,llm) ! increment on ucov due to sponge 40 66 41 67 c Local: … … 44 70 REAL uzon(jjp1,llm),vzon(jjm,llm),tzon(jjp1,llm) 45 71 46 INTEGER NDAMP47 PARAMETER (NDAMP=4)48 72 integer i 49 REAL,SAVE :: rdamp(llm) 50 ! & (/(0., i =1,llm-NDAMP),0.125E-5,.25E-5,.5E-5,1.E-5/) 73 REAL,SAVE :: rdamp(llm) ! quenching coefficient 74 real,save :: lambda(llm) ! inverse or quenching time scale (Hz) 51 75 LOGICAL,SAVE :: first=.true. 52 53 REAL zkm54 76 INTEGER j,l,jjb,jje 55 77 56 78 57 79 if (iflag_top_bound == 0) return 80 58 81 if (first) then 59 82 c$OMP BARRIER 60 83 c$OMP MASTER 61 84 if (iflag_top_bound == 1) then 62 ! couche eponge dans les 4 dernieres couches du modele63 rdamp(:)=0.64 rdamp(llm)=tau_top_bound65 rdamp(llm-1)=tau_top_bound/2.66 rdamp(llm-2)=tau_top_bound/4.67 rdamp(llm-3)=tau_top_bound/8.85 ! sponge quenching over the topmost 4 atmospheric layers 86 lambda(:)=0. 87 lambda(llm)=tau_top_bound 88 lambda(llm-1)=tau_top_bound/2. 89 lambda(llm-2)=tau_top_bound/4. 90 lambda(llm-3)=tau_top_bound/8. 68 91 else if (iflag_top_bound == 2) then 69 ! couche eponge dans toutes les couches de pression plus faible que70 ! 100 fois la pression de la derniere couche71 rdamp(:)=tau_top_bound92 ! sponge quenching over topmost layers down to pressures which are 93 ! higher than 100 times the topmost layer pressure 94 lambda(:)=tau_top_bound 72 95 s *max(presnivs(llm)/presnivs(:)-0.01,0.) 73 96 endif 74 first=.false. 75 print*,'TOP_BOUND mode',mode_top_bound 76 print*,'Coeffs pour la couche eponge a l equateur' 77 print*,'p (Pa) z(km) tau (s)' 97 98 ! quenching coefficient rdamp(:) 99 ! rdamp(:)=dt*lambda(:) ! Explicit Euler approx. 100 rdamp(:)=1.-exp(-lambda(:)*dt) 101 102 write(lunout,*)'TOP_BOUND mode',mode_top_bound 103 write(lunout,*)'Sponge layer coefficients' 104 write(lunout,*)'p (Pa) z(km) tau(s) 1./tau (Hz)' 78 105 do l=1,llm 79 106 if (rdamp(l).ne.0.) then 80 zkm = phi(iip1/2,jjp1/2,l)/(1000*g) 81 print*,presnivs(l),zkm,1./rdamp(l) 107 write(lunout,'(6(1pe12.4,1x))') 108 & presnivs(l),log(preff/presnivs(l))*scaleheight, 109 & 1./lambda(l),lambda(l) 82 110 endif 83 111 enddo 112 first=.false. 84 113 c$OMP END MASTER 85 114 c$OMP BARRIER 86 endif 115 endif ! of if (first) 87 116 88 117 89 118 CALL massbar_p(masse,massebx,masseby) 90 119 91 c mode = 0 : pas de sponge 92 c mode = 1 : u et v -> 0 93 c mode = 2 : u et v -> moyenne zonale 94 c mode = 3 : u, v et h -> moyenne zonale 95 96 C POUR V 97 98 C CALCUL DES CHAMPS EN MOYENNE ZONALE: 99 100 jjb=jj_begin 101 jje=jj_end 102 IF (pole_sud) jje=jj_end-1 103 120 ! compute zonal average of vcov (or set it to zero) 104 121 if (mode_top_bound.ge.2) then 105 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 122 jjb=jj_begin 123 jje=jj_end 124 IF (pole_sud) jje=jj_end-1 125 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 106 126 do l=1,llm 107 127 do j=jjb,jje … … 109 129 vzon(j,l)=0 110 130 do i=1,iim 111 ! Rm: on peut travailler directement avec la moyenne zonale de vcov 112 ! plutot qu'avec celle de v car le coefficient cv qui relie les deux 113 ! ne varie qu'en latitude 131 ! NB: we can work using vcov zonal mean rather than v since the 132 ! cv coefficient (which relates the two) only varies with latitudes 114 133 vzon(j,l)=vzon(j,l)+vcov(i,j,l)*masseby(i,j,l) 115 134 zm=zm+masseby(i,j,l) … … 118 137 enddo 119 138 enddo 120 !$OMP END DO NOWAIT139 c$OMP END DO NOWAIT 121 140 else 122 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 123 do l=1,llm 124 do j=jjb,jje 125 vzon(j,l)=0. 126 enddo 127 enddo 128 !$OMP END DO NOWAIT 129 endif 130 131 C AMORTISSEMENTS LINEAIRES: 132 133 if (mode_top_bound.ge.1) then 134 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 135 do l=1,llm 136 do j=jjb,jje 137 do i=1,iip1 138 dv(i,j,l)= -rdamp(l)*(vcov(i,j,l)-vzon(j,l)) 139 enddo 140 enddo 141 enddo 142 !$OMP END DO NOWAIT 143 endif 144 145 C POUR U ET H 146 147 C CALCUL DES CHAMPS EN MOYENNE ZONALE: 148 149 jjb=jj_begin 150 jje=jj_end 151 IF (pole_nord) jjb=jj_begin+1 152 IF (pole_sud) jje=jj_end-1 153 141 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 142 do l=1,llm 143 vzon(:,l)=0. 144 enddo 145 c$OMP END DO NOWAIT 146 endif ! of if (mode_top_bound.ge.2) 147 148 ! compute zonal average of u (or set it to zero) 154 149 if (mode_top_bound.ge.2) then 155 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 150 jjb=jj_begin 151 jje=jj_end 152 IF (pole_nord) jjb=jj_begin+1 153 IF (pole_sud) jje=jj_end-1 154 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 156 155 do l=1,llm 157 156 do j=jjb,jje … … 165 164 enddo 166 165 enddo 167 !$OMP END DO NOWAIT166 c$OMP END DO NOWAIT 168 167 else 169 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 170 do l=1,llm 171 do j=jjb,jje 172 uzon(j,l)=0. 173 enddo 174 enddo 175 !$OMP END DO NOWAIT 176 endif 177 168 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 169 do l=1,llm 170 uzon(:,l)=0. 171 enddo 172 c$OMP END DO NOWAIT 173 endif ! of if (mode_top_bound.ge.2) 174 175 ! compute zonal average of potential temperature, if necessary 178 176 if (mode_top_bound.ge.3) then 179 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 177 jjb=jj_begin 178 jje=jj_end 179 IF (pole_nord) jjb=jj_begin+1 180 IF (pole_sud) jje=jj_end-1 181 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 180 182 do l=1,llm 181 183 do j=jjb,jje … … 189 191 enddo 190 192 enddo 191 !$OMP END DO NOWAIT 192 endif 193 194 C AMORTISSEMENTS LINEAIRES: 193 c$OMP END DO NOWAIT 194 endif ! of if (mode_top_bound.ge.3) 195 195 196 196 if (mode_top_bound.ge.1) then 197 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 197 ! Apply sponge quenching on vcov: 198 jjb=jj_begin 199 jje=jj_end 200 IF (pole_sud) jje=jj_end-1 201 202 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 198 203 do l=1,llm 199 204 do j=jjb,jje 200 205 do i=1,iip1 201 du(i,j,l)= -rdamp(l)*(ucov(i,j,l)-cu(i,j)*uzon(j,l)) 202 enddo 203 enddo 204 enddo 205 !$OMP END DO NOWAIT 206 endif 207 208 if (mode_top_bound.ge.3) then 209 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 206 vcov(i,j,l)=vcov(i,j,l) 207 & -rdamp(l)*(vcov(i,j,l)-vzon(j,l)) 208 enddo 209 enddo 210 enddo 211 c$OMP END DO NOWAIT 212 213 ! Apply sponge quenching on ucov: 214 jjb=jj_begin 215 jje=jj_end 216 IF (pole_nord) jjb=jj_begin+1 217 IF (pole_sud) jje=jj_end-1 218 219 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 210 220 do l=1,llm 211 221 do j=jjb,jje 212 222 do i=1,iip1 213 dh(i,j,l)= -rdamp(l)*(teta(i,j,l)-tzon(j,l)) 214 enddo 215 enddo 216 enddo 217 !$OMP END DO NOWAIT 218 endif 219 220 !$OMP BARRIER 221 RETURN 223 ducov(i,j,l)=-rdamp(l)*(ucov(i,j,l)-cu(i,j)*uzon(j,l)) 224 ucov(i,j,l)=ucov(i,j,l) 225 & +ducov(i,j,l) 226 enddo 227 enddo 228 enddo 229 c$OMP END DO NOWAIT 230 endif ! of if (mode_top_bound.ge.1) 231 232 if (mode_top_bound.ge.3) then 233 ! Apply sponge quenching on teta: 234 jjb=jj_begin 235 jje=jj_end 236 IF (pole_nord) jjb=jj_begin+1 237 IF (pole_sud) jje=jj_end-1 238 239 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 240 do l=1,llm 241 do j=jjb,jje 242 do i=1,iip1 243 teta(i,j,l)=teta(i,j,l) 244 & -rdamp(l)*(teta(i,j,l)-tzon(j,l)) 245 enddo 246 enddo 247 enddo 248 c$OMP END DO NOWAIT 249 endif ! of if (mode_top_bond.ge.3) 250 222 251 END
Note: See TracChangeset
for help on using the changeset viewer.