Changeset 22 for codes/icosagcm/trunk/src/advect_tracer.f90
- Timestamp:
- 07/18/12 18:39:59 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
codes/icosagcm/trunk/src/advect_tracer.f90
r19 r22 4 4 INTEGER,PARAMETER::iapp_tracvl= 3 5 5 REAL(rstd),SAVE :: dt 6 6 7 TYPE(t_field),POINTER :: f_normal(:) 8 TYPE(t_field),POINTER :: f_tangent(:) 9 TYPE(t_field),POINTER :: f_gradq3d(:) 10 7 11 PUBLIC init_advect_tracer, advect_tracer 8 12 9 13 CONTAINS 10 14 11 15 SUBROUTINE init_advect_tracer(dt_in) 12 USE advect_mod13 IMPLICIT NONE16 USE advect_mod 17 IMPLICIT NONE 14 18 REAL(rstd),INTENT(IN) :: dt_in 15 19 REAL(rstd),POINTER :: tangent(:,:) 20 REAL(rstd),POINTER :: normal(:,:) 21 16 22 dt=dt_in 17 18 CALL init_advect 19 23 CALL allocate_field(f_normal,field_u,type_real,3) 24 CALL allocate_field(f_tangent,field_u,type_real,3) 25 CALL allocate_field(f_gradq3d,field_t,type_real,llm,3) 26 27 DO ind=1,ndomain 28 CALL swap_dimensions(ind) 29 CALL swap_geometry(ind) 30 normal=f_normal(ind) 31 tangent=f_tangent(ind) 32 CALL init_advect(normal,tangent) 33 END DO 34 20 35 END SUBROUTINE init_advect_tracer 21 22 23 SUBROUTINE advect_tracer(f_ps,f_u, f_q) 24 USE icosa 25 USE advect_mod 26 USE disvert_mod 27 IMPLICIT NONE 28 TYPE(t_field),POINTER :: f_ps(:) 29 TYPE(t_field),POINTER :: f_u(:) 30 TYPE(t_field),POINTER :: f_q(:) 31 REAL(rstd),POINTER :: q(:,:,:) 32 REAL(rstd),POINTER :: u(:,:) 33 REAL(rstd),POINTER :: ps(:) 34 REAL(rstd),POINTER :: massflx(:,:) 35 REAL(rstd),POINTER :: rhodz(:,:) 36 TYPE(t_field),POINTER,SAVE :: f_massflxc(:) 37 TYPE(t_field),POINTER,SAVE :: f_massflx(:) 38 TYPE(t_field),POINTER,SAVE :: f_uc(:) 39 TYPE(t_field),POINTER,SAVE :: f_rhodzm1(:) 40 TYPE(t_field),POINTER,SAVE :: f_rhodz(:) 41 REAL(rstd),POINTER,SAVE :: massflxc(:,:) 42 REAL(rstd),POINTER,SAVE :: uc(:,:) 43 REAL(rstd),POINTER,SAVE :: rhodzm1(:,:) 44 REAL(rstd):: bigt 45 INTEGER :: ind,it,iapptrac,i,j,l,ij 46 INTEGER,SAVE :: iadvtr=0 47 LOGICAL,SAVE:: first=.TRUE. 48 !------------------------------------------------------sarvesh 36 37 SUBROUTINE advect_tracer(f_ps,f_u,f_q) 38 USE icosa 39 USE advect_mod 40 USE disvert_mod 41 IMPLICIT NONE 42 TYPE(t_field),POINTER :: f_ps(:) 43 TYPE(t_field),POINTER :: f_u(:) 44 TYPE(t_field),POINTER :: f_q(:) 45 REAL(rstd),POINTER :: q(:,:,:) 46 REAL(rstd),POINTER :: u(:,:) 47 REAL(rstd),POINTER :: ps(:) 48 REAL(rstd),POINTER :: massflx(:,:) 49 REAL(rstd),POINTER :: rhodz(:,:) 50 TYPE(t_field),POINTER,SAVE :: f_massflxc(:) 51 TYPE(t_field),POINTER,SAVE :: f_massflx(:) 52 TYPE(t_field),POINTER,SAVE :: f_uc(:) 53 TYPE(t_field),POINTER,SAVE :: f_rhodzm1(:) 54 TYPE(t_field),POINTER,SAVE :: f_rhodz(:) 55 REAL(rstd),POINTER,SAVE :: massflxc(:,:) 56 REAL(rstd),POINTER,SAVE :: uc(:,:) 57 REAL(rstd),POINTER,SAVE :: rhodzm1(:,:) 58 REAL(rstd):: bigt 59 INTEGER :: ind,it,i,j,l,ij 60 INTEGER,SAVE :: iadvtr=0 61 LOGICAL,SAVE:: first=.TRUE. 62 !------------------------------------------------------sarvesh 49 63 IF ( first ) THEN 50 CALL allocate_field(f_rhodz,field_t,type_real,llm) 51 CALL allocate_field(f_rhodzm1,field_t,type_real,llm) 52 CALL allocate_field(f_massflxc,field_u,type_real,llm) 53 CALL allocate_field(f_massflx,field_u,type_real,llm) 54 CALL allocate_field(f_uc,field_u,type_real,llm) 55 first = .FALSE. 56 END IF 57 58 DO ind=1,ndomain 59 CALL swap_dimensions(ind) 60 CALL swap_geometry(ind) 61 rhodz=f_rhodz(ind) 62 massflx=f_massflx(ind) 63 ps=f_ps(ind) 64 u=f_u(ind) 65 66 DO l = 1, llm 67 DO j=jj_begin-1,jj_end+1 68 DO i=ii_begin-1,ii_end+1 69 ij=(j-1)*iim+i 70 rhodz(ij,l) = (ap(l) - ap(l+1) + (bp(l)-bp(l+1))*ps(ij))/g 71 ENDDO 72 ENDDO 73 ENDDO 74 75 DO l = 1, llm 76 DO j=jj_begin-1,jj_end+1 77 DO i=ii_begin-1,ii_end+1 78 ij=(j-1)*iim+i 79 massflx(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right) 80 massflx(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup) 81 massflx(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown) 82 ENDDO 83 ENDDO 84 ENDDO 85 86 ENDDO 87 88 89 90 IF ( iadvtr == 0 ) THEN 91 DO ind=1,ndomain 92 CALL swap_dimensions(ind) 93 CALL swap_geometry(ind) 94 rhodz=f_rhodz(ind) 95 rhodzm1 = f_rhodzm1(ind) 96 massflxc = f_massflxc(ind) 97 rhodzm1 = rhodz 98 massflxc = 0.0 99 uc = f_uc(ind) 100 uc = 0.0 101 END DO 102 CALL transfert_request(f_rhodzm1,req_i1) !----> 103 CALL transfert_request(f_massflxc,req_e1) !----> 104 CALL transfert_request(f_massflxc,req_e1) !------> 105 CALL transfert_request(f_uc,req_e1) !----> 106 CALL transfert_request(f_uc,req_e1) 107 END IF 108 109 iadvtr = iadvtr + 1 110 iapptrac = iadvtr 111 112 DO ind=1,ndomain 113 CALL swap_dimensions(ind) 114 CALL swap_geometry(ind) 115 massflx=f_massflx(ind) 116 rhodzm1 = f_rhodzm1(ind) 117 massflxc = f_massflxc(ind) 118 massflxc = massflxc + massflx 119 uc = f_uc(ind) 120 u = f_u(ind) 121 uc = uc + u 64 CALL allocate_field(f_rhodz,field_t,type_real,llm) 65 CALL allocate_field(f_rhodzm1,field_t,type_real,llm) 66 CALL allocate_field(f_massflxc,field_u,type_real,llm) 67 CALL allocate_field(f_massflx,field_u,type_real,llm) 68 CALL allocate_field(f_uc,field_u,type_real,llm) 69 first = .FALSE. 70 END IF 71 72 DO ind=1,ndomain 73 CALL swap_dimensions(ind) 74 CALL swap_geometry(ind) 75 rhodz=f_rhodz(ind) 76 massflx=f_massflx(ind) 77 ps=f_ps(ind) 78 u=f_u(ind) 79 80 DO l = 1, llm 81 DO j=jj_begin-1,jj_end+1 82 DO i=ii_begin-1,ii_end+1 83 ij=(j-1)*iim+i 84 rhodz(ij,l) = (ap(l) - ap(l+1) + (bp(l)-bp(l+1))*ps(ij))/g 85 ENDDO 86 ENDDO 87 ENDDO 88 89 DO l = 1, llm 90 DO j=jj_begin-1,jj_end+1 91 DO i=ii_begin-1,ii_end+1 92 ij=(j-1)*iim+i 93 massflx(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right) 94 massflx(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup) 95 massflx(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown) 96 ENDDO 97 ENDDO 98 ENDDO 99 ENDDO 100 101 IF ( iadvtr == 0 ) THEN 102 DO ind=1,ndomain 103 CALL swap_dimensions(ind) 104 CALL swap_geometry(ind) 105 rhodz=f_rhodz(ind) 106 rhodzm1 = f_rhodzm1(ind) 107 massflxc = f_massflxc(ind) ! accumulated mass fluxes 108 uc = f_uc(ind) ! time-integrated normal velocity to compute back-trajectory (Miura) 109 rhodzm1 = rhodz 110 massflxc = 0.0 111 uc = 0.0 122 112 END DO 123 124 IF ( iadvtr == iapp_tracvl ) THEN 125 bigt = dt*iapp_tracvl 126 DO ind=1,ndomain 127 CALL swap_dimensions(ind) 128 CALL swap_geometry(ind) 129 uc = f_uc(ind) 130 uc = uc/real(iapp_tracvl) 131 END DO 113 CALL transfert_request(f_rhodzm1,req_i1) !----> 114 CALL transfert_request(f_massflxc,req_e1) !----> 115 CALL transfert_request(f_massflxc,req_e1) !------> 116 CALL transfert_request(f_uc,req_e1) !----> 117 CALL transfert_request(f_uc,req_e1) 118 END IF 119 120 iadvtr = iadvtr + 1 121 122 DO ind=1,ndomain 123 CALL swap_dimensions(ind) 124 CALL swap_geometry(ind) 125 massflx = f_massflx(ind) 126 massflxc = f_massflxc(ind) 127 uc = f_uc(ind) 128 u = f_u(ind) 129 massflxc = massflxc + massflx 130 uc = uc + u 131 END DO 132 133 IF ( iadvtr == iapp_tracvl ) THEN 134 bigt = dt*iapp_tracvl 135 DO ind=1,ndomain 136 CALL swap_dimensions(ind) 137 CALL swap_geometry(ind) 138 uc = f_uc(ind) 139 uc = uc/real(iapp_tracvl) 140 massflxc = f_massflx(ind) 141 massflxc = massflxc*dt 142 ! now massflx is time-integrated 143 END DO 132 144 133 145 CALL vlsplt(f_q,f_rhodzm1,f_massflxc,2.0,f_uc,bigt) 134 135 146 iadvtr = 0 147 END IF 136 148 END SUBROUTINE advect_tracer 137 138 !============================================================================== 139 SUBROUTINE advtrac(massflx,wgg) 140 USE domain_mod 141 USE dimensions 142 USE grid_param 143 USE geometry 144 USE metric 145 USE disvert_mod 146 IMPLICIT NONE 147 REAL(rstd),INTENT(IN) :: massflx(iim*3*jjm,llm) 148 REAL(rstd),INTENT(OUT) :: wgg(iim*jjm,llm) 149 150 INTEGER :: i,j,ij,l 151 REAL(rstd) :: convm(iim*jjm,llm) 152 153 DO l = 1, llm 154 DO j=jj_begin,jj_end 155 DO i=ii_begin,ii_end 156 ij=(j-1)*iim+i 157 convm(ij,l)= 1/(Ai(ij))*(ne(ij,right)*massflx(ij+u_right,l) + & 158 ne(ij,rup)*massflx(ij+u_rup,l) + & 159 ne(ij,lup)*massflx(ij+u_lup,l) + & 160 ne(ij,left)*massflx(ij+u_left,l) + & 161 ne(ij,ldown)*massflx(ij+u_ldown,l) + & 162 ne(ij,rdown)*massflx(ij+u_rdown,l)) 163 ENDDO 164 ENDDO 165 ENDDO 166 167 DO l = llm-1, 1, -1 168 DO j=jj_begin,jj_end 169 DO i=ii_begin,ii_end 170 ij=(j-1)*iim+i 171 convm(ij,l) = convm(ij,l) + convm(ij,l+1) 172 ENDDO 173 ENDDO 174 ENDDO 175 176 !!! Compute vertical velocity 177 DO l = 1,llm-1 178 DO j=jj_begin,jj_end 179 DO i=ii_begin,ii_end 180 ij=(j-1)*iim+i 181 wgg( ij, l+1 ) = (convm( ij, l+1 ) - bp(l+1) * convm( ij, 1 )) 182 ENDDO 183 ENDDO 184 ENDDO 185 186 DO j=jj_begin,jj_end 187 DO i=ii_begin,ii_end 188 ij=(j-1)*iim+i 189 wgg(ij,1) = 0. 190 ENDDO 191 ENDDO 192 END SUBROUTINE advtrac 193 194 SUBROUTINE vlsplt(f_q,f_rhodz,f_massflx,pente_max,f_u,bigt) 195 USE field_mod 196 USE domain_mod 197 USE dimensions 198 USE grid_param 199 USE geometry 200 USE metric 201 USE advect_mod 202 IMPLICIT NONE 203 204 TYPE(t_field),POINTER :: f_q(:) 205 TYPE(t_field),POINTER :: f_u(:) 206 TYPE(t_field),POINTER :: f_rhodz(:) 207 TYPE(t_field),POINTER :: f_massflx(:) 208 TYPE(t_field),POINTER,SAVE :: f_wg(:) 209 TYPE(t_field),POINTER,SAVE :: f_zm(:) 210 TYPE(t_field),POINTER,SAVE :: f_zq(:) 211 212 REAL(rstd)::bigt,dt 213 REAL(rstd),POINTER :: q(:,:,:) 214 REAL(rstd),POINTER :: u(:,:) 215 REAL(rstd),POINTER :: rhodz(:,:) 216 REAL(rstd),POINTER :: massflx(:,:) 217 REAL(rstd),POINTER,SAVE :: wg(:,:) 218 REAL(rstd),POINTER,SAVE::zq(:,:,:) 219 REAL(rstd),POINTER,SAVE::zm(:,:) 220 221 REAL(rstd)::pente_max 222 LOGICAL,SAVE::first = .true. 223 INTEGER :: i,ij,l,j,ind,k 224 REAL(rstd) :: zzpbar, zzw 225 REAL::qvmax,qvmin 226 227 IF ( first ) THEN 149 150 SUBROUTINE vlsplt(f_q,f_rhodz,f_massflx,pente_max,f_u,bigt) 151 USE field_mod 152 USE domain_mod 153 USE dimensions 154 USE grid_param 155 USE geometry 156 USE metric 157 USE advect_mod 158 IMPLICIT NONE 159 160 TYPE(t_field),POINTER :: f_q(:) 161 TYPE(t_field),POINTER :: f_u(:) 162 TYPE(t_field),POINTER :: f_rhodz(:) 163 TYPE(t_field),POINTER :: f_massflx(:) 164 165 TYPE(t_field),POINTER,SAVE :: f_wg(:) 166 TYPE(t_field),POINTER,SAVE :: f_zm(:) 167 TYPE(t_field),POINTER,SAVE :: f_zq(:) 168 169 REAL(rstd)::bigt,dt 170 REAL(rstd),POINTER :: q(:,:,:) 171 REAL(rstd),POINTER :: u(:,:) 172 REAL(rstd),POINTER :: rhodz(:,:) 173 REAL(rstd),POINTER :: massflx(:,:) 174 REAL(rstd),POINTER :: wg(:,:) 175 REAL(rstd),POINTER :: zq(:,:,:) 176 REAL(rstd),POINTER :: zm(:,:) 177 REAL(rstd),POINTER :: tangent(:,:) 178 REAL(rstd),POINTER :: normal(:,:) 179 REAL(rstd),POINTER :: gradq3d(:,:,:) 180 181 REAL(rstd)::pente_max 182 LOGICAL,SAVE::first = .true. 183 INTEGER :: i,ij,l,j,ind,k 184 REAL(rstd) :: zzpbar, zzw 185 REAL::qvmax,qvmin 186 187 IF ( first ) THEN 228 188 CALL allocate_field(f_wg,field_t,type_real,llm) 229 189 CALL allocate_field(f_zm,field_t,type_real,llm) 230 190 CALL allocate_field(f_zq,field_t,type_real,llm,nqtot) 231 191 first = .FALSE. 232 END IF233 234 235 CALL swap_dimensions(ind) 236 CALL swap_geometry(ind) 237 238 239 240 241 242 243 244 245 CALL advtrac(massflx,wg) 246 247 248 ! CALL transfert_request(f_wg,req_i1)249 250 251 252 253 254 255 256 192 END IF 193 194 DO ind=1,ndomain 195 CALL swap_dimensions(ind) 196 CALL swap_geometry(ind) 197 q=f_q(ind) 198 rhodz=f_rhodz(ind) 199 zq=f_zq(ind) 200 zm=f_zm(ind) 201 zm = rhodz ; zq = q 202 wg = f_wg(ind) 203 wg = 0.0 204 massflx=f_massflx(ind) 205 CALL advtrac(massflx,wg) ! compute vertical mass fluxes 206 END DO 207 208 ! CALL transfert_request(f_wg,req_i1) 209 210 DO ind=1,ndomain 211 CALL swap_dimensions(ind) 212 CALL swap_geometry(ind) 213 zq=f_zq(ind) 214 zm=f_zm(ind) 215 wg=f_wg(ind) 216 wg=wg*0.5 257 217 DO k = 1, nqtot 258 218 CALL vlz(zq(:,:,k),2.,zm,wg) 259 219 END DO 260 END DO 261 262 DO ind=1,ndomain 263 CALL swap_dimensions(ind) 264 CALL swap_geometry(ind) 265 CALL swap_advect(ind) 266 zq=f_zq(ind) 267 zq = f_zq(ind) 268 zm = f_zm(ind) 269 massflx =f_massflx(ind) 270 u = f_u(ind) 271 DO k = 1,nqtot 272 CALL advect1(zq(:,:,k)) 273 CALL advect2(zq(:,:,k),zm,u,massflx,bigt) 274 END DO 275 END DO 276 277 DO ind=1,ndomain 278 CALL swap_dimensions(ind) 279 CALL swap_geometry(ind) 280 q = f_q(ind) 281 zq = f_zq(ind) 282 zm = f_zm(ind) 283 wg = f_wg(ind) 284 DO k = 1,nqtot 285 CALL vlz(zq(:,:,k),2.,zm,wg) 286 END DO 287 q = zq 288 END DO 289 290 END SUBROUTINE vlsplt 291 292 293 SUBROUTINE vlz(q,pente_max,masse,wgg) 294 !c 295 !c Auteurs: P.Le Van, F.Hourdin, F.Forget 296 !c 297 !c ******************************************************************** 298 !c Shema d'advection " pseudo amont " . 299 !c ******************************************************************** 300 USE icosa 301 IMPLICIT NONE 302 !c 303 !c Arguments: 304 !c ---------- 305 REAL masse(iim*jjm,llm),pente_max 306 REAL q(iim*jjm,llm) 307 REAL wgg(iim*jjm,llm),w(iim*jjm,llm+1) 308 REAL dq(iim*jjm,llm) 309 INTEGER i,ij,l,j,ii 310 !c 311 REAL wq(iim*jjm,llm+1),newmasse 312 313 REAL dzq(iim*jjm,llm),dzqw(iim*jjm,llm),adzqw(iim*jjm,llm),dzqmax 314 REAL sigw 315 316 REAL SSUM 317 318 319 w(:,1:llm) = wgg(:,:) 320 w(:,llm+1) = 0.0 321 322 !c On oriente tout dans le sens de la pression c'est a dire dans le 323 !c sens de W 324 325 DO l=2,llm 326 DO j=jj_begin,jj_end 327 DO i=ii_begin,ii_end 328 ij=(j-1)*iim+i 329 dzqw(ij,l)=q(ij,l-1)-q(ij,l) 330 adzqw(ij,l)=abs(dzqw(ij,l)) 331 ENDDO 332 ENDDO 333 ENDDO 334 335 DO l=2,llm-1 336 DO j=jj_begin,jj_end 337 DO i=ii_begin,ii_end 338 ij=(j-1)*iim+i 339 IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN 220 END DO 221 222 DO ind=1,ndomain 223 CALL swap_dimensions(ind) 224 CALL swap_geometry(ind) 225 zq=f_zq(ind) 226 zq = f_zq(ind) 227 zm = f_zm(ind) 228 massflx =f_massflx(ind) 229 u = f_u(ind) 230 tangent = f_tangent(ind) 231 normal = f_normal(ind) 232 gradq3d = f_gradq3d(ind) 233 234 DO k = 1,nqtot 235 CALL compute_gradq3d(zq(:,:,k),gradq3d) 236 CALL compute_advect_horiz(zq(:,:,k),zm,u,massflx,bigt) 237 END DO 238 END DO 239 240 DO ind=1,ndomain 241 CALL swap_dimensions(ind) 242 CALL swap_geometry(ind) 243 q = f_q(ind) 244 zq = f_zq(ind) 245 zm = f_zm(ind) 246 wg = f_wg(ind) 247 DO k = 1,nqtot 248 CALL vlz(zq(:,:,k),2.,zm,wg) 249 END DO 250 q = zq 251 END DO 252 253 END SUBROUTINE vlsplt 254 255 !============================================================================== 256 SUBROUTINE advtrac(massflx,wgg) 257 USE domain_mod 258 USE dimensions 259 USE grid_param 260 USE geometry 261 USE metric 262 USE disvert_mod 263 IMPLICIT NONE 264 REAL(rstd),INTENT(IN) :: massflx(iim*3*jjm,llm) 265 REAL(rstd),INTENT(OUT) :: wgg(iim*jjm,llm) 266 267 INTEGER :: i,j,ij,l 268 REAL(rstd) :: convm(iim*jjm,llm) 269 270 DO l = 1, llm 271 DO j=jj_begin,jj_end 272 DO i=ii_begin,ii_end 273 ij=(j-1)*iim+i 274 ! divergence of horizontal flux 275 convm(ij,l)= 1/(Ai(ij))*(ne(ij,right)*massflx(ij+u_right,l) + & 276 ne(ij,rup)*massflx(ij+u_rup,l) + & 277 ne(ij,lup)*massflx(ij+u_lup,l) + & 278 ne(ij,left)*massflx(ij+u_left,l) + & 279 ne(ij,ldown)*massflx(ij+u_ldown,l) + & 280 ne(ij,rdown)*massflx(ij+u_rdown,l)) 281 ENDDO 282 ENDDO 283 ENDDO 284 285 ! accumulate divergence from top of model 286 DO l = llm-1, 1, -1 287 DO j=jj_begin,jj_end 288 DO i=ii_begin,ii_end 289 ij=(j-1)*iim+i 290 convm(ij,l) = convm(ij,l) + convm(ij,l+1) 291 ENDDO 292 ENDDO 293 ENDDO 294 295 !!! Compute vertical velocity 296 DO l = 1,llm-1 297 DO j=jj_begin,jj_end 298 DO i=ii_begin,ii_end 299 ij=(j-1)*iim+i 300 wgg( ij, l+1 ) = (convm( ij, l+1 ) - bp(l+1) * convm( ij, 1 )) 301 ENDDO 302 ENDDO 303 ENDDO 304 305 DO j=jj_begin,jj_end 306 DO i=ii_begin,ii_end 307 ij=(j-1)*iim+i 308 wgg(ij,1) = 0. 309 ENDDO 310 ENDDO 311 END SUBROUTINE advtrac 312 313 SUBROUTINE vlz(q,pente_max,masse,wgg) 314 !c 315 !c Auteurs: P.Le Van, F.Hourdin, F.Forget 316 !c 317 !c ******************************************************************** 318 !c Shema d'advection " pseudo amont " . 319 !c ******************************************************************** 320 USE icosa 321 IMPLICIT NONE 322 !c 323 !c Arguments: 324 !c ---------- 325 REAL masse(iim*jjm,llm),pente_max 326 REAL q(iim*jjm,llm) 327 REAL wgg(iim*jjm,llm),w(iim*jjm,llm+1) 328 REAL dq(iim*jjm,llm) 329 INTEGER i,ij,l,j,ii 330 !c 331 REAL wq(iim*jjm,llm+1),newmasse 332 333 REAL dzq(iim*jjm,llm),dzqw(iim*jjm,llm),adzqw(iim*jjm,llm),dzqmax 334 REAL sigw 335 336 REAL SSUM 337 338 339 w(:,1:llm) = -wgg(:,:) ! w>0 for downward transport 340 w(:,llm+1) = 0.0 341 342 !c On oriente tout dans le sens de la pression c'est a dire dans le 343 !c sens de W 344 345 DO l=2,llm 346 DO j=jj_begin,jj_end 347 DO i=ii_begin,ii_end 348 ij=(j-1)*iim+i 349 dzqw(ij,l)=q(ij,l-1)-q(ij,l) 350 adzqw(ij,l)=abs(dzqw(ij,l)) 351 ENDDO 352 ENDDO 353 ENDDO 354 355 DO l=2,llm-1 356 DO j=jj_begin,jj_end 357 DO i=ii_begin,ii_end 358 ij=(j-1)*iim+i 359 IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN 340 360 dzq(ij,l)=0.5*(dzqw(ij,l)+dzqw(ij,l+1)) 341 ELSE361 ELSE 342 362 dzq(ij,l)=0. 343 ENDIF344 dzqmax=pente_max*min(adzqw(ij,l),adzqw(ij,l+1))345 dzq(ij,l)=sign(min(abs(dzq(ij,l)),dzqmax),dzq(ij,l))346 ENDDO347 348 349 350 351 352 DO i=ii_begin,ii_end353 ij=(j-1)*iim+i354 dzq(ij,1)=0.355 dzq(ij,llm)=0.356 ENDDO357 358 359 !c ---------------------------------------------------------------360 !c .... calcul des termes d'advection verticale .......361 !c ---------------------------------------------------------------362 363 !c calcul de - d( q * w )/ d(sigma) qu'on ajoute a dq pour calculer dq364 365 366 367 363 ENDIF 364 dzqmax=pente_max*min(adzqw(ij,l),adzqw(ij,l+1)) 365 dzq(ij,l)=sign(min(abs(dzq(ij,l)),dzqmax),dzq(ij,l)) 366 ENDDO 367 ENDDO 368 ENDDO 369 370 DO l=2,llm-1 371 DO j=jj_begin,jj_end 372 DO i=ii_begin,ii_end 373 ij=(j-1)*iim+i 374 dzq(ij,1)=0. 375 dzq(ij,llm)=0. 376 ENDDO 377 ENDDO 378 ENDDO 379 !c --------------------------------------------------------------- 380 !c .... calcul des termes d'advection verticale ....... 381 !c --------------------------------------------------------------- 382 383 !c calcul de - d( q * w )/ d(sigma) qu'on ajoute a dq pour calculer dq 384 385 DO l = 1,llm-1 386 DO j=jj_begin,jj_end 387 DO i=ii_begin,ii_end 368 388 ij=(j-1)*iim+i 369 389 IF(w(ij,l+1).gt.0.) THEN 370 sigw=w(ij,l+1)/masse(ij,l+1) 371 wq(ij,l+1)=w(ij,l+1)*(q(ij,l+1)+0.5*(1.-sigw)*dzq(ij,l+1)) 390 ! upwind only if downward transport 391 sigw=w(ij,l+1)/masse(ij,l+1) 392 wq(ij,l+1)=w(ij,l+1)*(q(ij,l+1)+0.5*(1.-sigw)*dzq(ij,l+1)) 372 393 ELSE 373 sigw=w(ij,l+1)/masse(ij,l) 374 wq(ij,l+1)=w(ij,l+1)*(q(ij,l)-0.5*(1.+sigw)*dzq(ij,l)) 375 ENDIF 376 ENDDO 377 ENDDO 378 END DO 379 380 DO j=jj_begin,jj_end 381 DO i=ii_begin,ii_end 382 ij=(j-1)*iim+i 383 wq(ij,llm+1)=0. 384 wq(ij,1)=0. 385 ENDDO 386 END DO 387 388 DO l=1,llm 389 DO j=jj_begin,jj_end 390 DO i=ii_begin,ii_end 391 ij=(j-1)*iim+i 392 newmasse=masse(ij,l)+(w(ij,l+1)-w(ij,l)) 393 dq(ij,l) = (wq(ij,l+1)-wq(ij,l)) !================>>>> 394 q(ij,l)=(q(ij,l)*masse(ij,l)+wq(ij,l+1)-wq(ij,l))/newmasse 395 396 masse(ij,l)=newmasse 397 ENDDO 398 ENDDO 399 END DO 400 RETURN 401 END SUBROUTINE vlz 394 ! upwind only if upward transport 395 sigw=w(ij,l+1)/masse(ij,l) 396 wq(ij,l+1)=w(ij,l+1)*(q(ij,l)-0.5*(1.+sigw)*dzq(ij,l)) 397 ENDIF 398 ENDDO 399 ENDDO 400 END DO 401 402 DO j=jj_begin,jj_end 403 DO i=ii_begin,ii_end 404 ij=(j-1)*iim+i 405 wq(ij,llm+1)=0. 406 wq(ij,1)=0. 407 ENDDO 408 END DO 409 410 DO l=1,llm 411 DO j=jj_begin,jj_end 412 DO i=ii_begin,ii_end 413 ij=(j-1)*iim+i 414 ! masse -= dw/dz but w>0 <=> downward 415 newmasse=masse(ij,l)+(w(ij,l+1)-w(ij,l)) 416 ! dq(ij,l) = (wq(ij,l+1)-wq(ij,l)) !================>>>> 417 q(ij,l)=(q(ij,l)*masse(ij,l)+wq(ij,l+1)-wq(ij,l))/newmasse 418 ! masse(ij,l)=newmasse 419 ENDDO 420 ENDDO 421 END DO 422 RETURN 423 END SUBROUTINE vlz 402 424 403 425 END MODULE advect_tracer_mod
Note: See TracChangeset
for help on using the changeset viewer.