Changeset 139 for codes/icosagcm
- Timestamp:
- 02/18/13 15:12:18 (11 years ago)
- Location:
- codes/icosagcm/trunk/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
codes/icosagcm/trunk/src/caldyn.f90
r134 r139 20 20 CASE('gcm') 21 21 CALL init_caldyn_gcm 22 !CASE('adv')23 !CALL init_caldyn_adv22 CASE('adv') 23 CALL init_caldyn_adv 24 24 CASE DEFAULT 25 25 PRINT*,'Bad selector for variable caldyn : <', TRIM(caldyn_type),'> options are <gcm>, <adv>' … … 52 52 CALL caldyn_gcm(write_out,f_phis, f_ps, f_theta_rhodz, f_u, f_q, & 53 53 f_hflux, f_wflux, f_dps, f_dtheta_rhodz, f_du) 54 ! CASE('adv') 55 ! CALL caldyn_adv(write_out,f_phis, f_ps, f_theta_rhodz, f_u, f_q, f_dps, f_dtheta_rhodz, f_du) 54 CASE('adv') 55 CALL caldyn_adv(write_out,f_phis, f_ps, f_theta_rhodz, f_u, f_q, & 56 f_hflux, f_wflux, f_dps, f_dtheta_rhodz, f_du) 56 57 END SELECT 57 58 -
codes/icosagcm/trunk/src/caldyn_adv.f90
r129 r139 2 2 USE icosa 3 3 4 TYPE(t_field),POINTER :: f_out(:) 5 REAL(rstd),POINTER :: out(:,:) 6 TYPE(t_field),POINTER :: f_out_u(:) 7 REAL(rstd),POINTER :: out_u(:,:) 8 TYPE(t_field),POINTER :: f_out_z(:) 9 REAL(rstd),POINTER :: out_z(:,:) 10 11 4 IMPLICIT NONE 5 PRIVATE 6 PUBLIC :: init_caldyn, caldyn 7 12 8 CONTAINS 13 9 14 10 SUBROUTINE init_caldyn 15 USE icosa16 IMPLICIT NONE17 18 CALL allocate_caldyn19 20 11 END SUBROUTINE init_caldyn 21 22 SUBROUTINE allocate_caldyn 23 USE icosa 24 IMPLICIT NONE 25 26 CALL allocate_field(f_out,field_t,type_real,llm) 27 CALL allocate_field(f_out_u,field_u,type_real,llm) 28 CALL allocate_field(f_out_z,field_z,type_real,llm) 29 30 END SUBROUTINE allocate_caldyn 31 32 SUBROUTINE swap_caldyn(ind) 33 IMPLICIT NONE 34 INTEGER,INTENT(IN) :: ind 35 out=f_out(ind) 36 out_u=f_out_u(ind) 37 out_z=f_out_z(ind) 38 39 END SUBROUTINE swap_caldyn 40 12 41 13 SUBROUTINE check_mass_conservation(f_ps,f_dps) 42 USE icosa 43 IMPLICIT NONE 14 USE icosa 44 15 TYPE(t_field),POINTER :: f_ps(:) 45 16 TYPE(t_field),POINTER :: f_dps(:) … … 48 19 REAL(rstd) :: mass_tot,dmass_tot 49 20 INTEGER :: ind,i,j,ij 50 21 51 22 mass_tot=0 52 23 dmass_tot=0 53 24 54 25 CALL transfert_request(f_dps,req_i1) 55 26 CALL transfert_request(f_ps,req_i1) 56 27 57 28 DO ind=1,ndomain 58 CALL swap_dimensions(ind) 59 CALL swap_geometry(ind) 60 61 ps=f_ps(ind) 62 dps=f_dps(ind) 63 64 DO j=jj_begin,jj_end 65 DO i=ii_begin,ii_end 29 CALL swap_dimensions(ind) 30 CALL swap_geometry(ind) 31 32 ps=f_ps(ind) 33 dps=f_dps(ind) 34 35 DO j=jj_begin,jj_end 36 DO i=ii_begin,ii_end 37 ij=(j-1)*iim+i 38 IF (domain(ind)%own(i,j)) THEN 39 mass_tot=mass_tot+ps(ij)*Ai(ij)/g 40 dmass_tot=dmass_tot+dps(ij)*Ai(ij)/g 41 ENDIF 42 ENDDO 43 ENDDO 44 45 ENDDO 46 PRINT*, "mass_tot ", mass_tot," dmass_tot ",dmass_tot 47 48 END SUBROUTINE check_mass_conservation 49 50 51 SUBROUTINE caldyn(write_out,f_phis, f_ps, f_theta_rhodz, f_u, f_q, & 52 f_hflux, f_wflux, f_dps, f_dtheta_rhodz, f_du) 53 USE icosa 54 USE vorticity_mod 55 USE kinetic_mod 56 USE theta2theta_rhodz_mod 57 IMPLICIT NONE 58 LOGICAL,INTENT(IN) :: write_out 59 TYPE(t_field),POINTER :: f_phis(:) 60 TYPE(t_field),POINTER :: f_ps(:) 61 TYPE(t_field),POINTER :: f_theta_rhodz(:) 62 TYPE(t_field),POINTER :: f_u(:) 63 TYPE(t_field),POINTER :: f_q(:) 64 TYPE(t_field),POINTER :: f_hflux(:), f_wflux(:) 65 TYPE(t_field),POINTER :: f_dps(:) 66 TYPE(t_field),POINTER :: f_dtheta_rhodz(:) 67 TYPE(t_field),POINTER :: f_du(:) 68 69 REAL(rstd),POINTER :: ps(:) 70 REAL(rstd),POINTER :: u(:,:) 71 REAL(rstd),POINTER :: dps(:) 72 REAL(rstd),POINTER :: hflux(:,:), wflux(:,:) 73 REAL(rstd),POINTER :: dtheta_rhodz(:,:), du(:,:) ! set to 0 74 INTEGER :: ind 75 76 CALL transfert_request(f_ps,req_i1) 77 CALL transfert_request(f_u,req_e1) 78 79 DO ind=1,ndomain 80 CALL swap_dimensions(ind) 81 CALL swap_geometry(ind) 82 ps=f_ps(ind) 83 u=f_u(ind) 84 dps=f_dps(ind) 85 hflux=f_hflux(ind) 86 wflux=f_wflux(ind) 87 dtheta_rhodz=f_dtheta_rhodz(ind) 88 du=f_du(ind) 89 90 !$OMP PARALLEL DEFAULT(SHARED) 91 CALL compute_caldyn(ps,u,hflux, wflux, dps, dtheta_rhodz, du) 92 !$OMP END PARALLEL 93 ENDDO 94 95 IF (write_out) THEN 96 CALL writefield("ps",f_ps) 97 CALL writefield("wflux",f_wflux) 98 ENDIF 99 ! CALL check_mass_conservation(f_ps,f_dps) 100 101 END SUBROUTINE caldyn 102 103 104 SUBROUTINE compute_caldyn(ps,u, hflux,wflux,dps, dtheta_rhodz,du) 105 USE icosa 106 USE disvert_mod 107 IMPLICIT NONE 108 REAL(rstd),INTENT(IN) :: ps(iim*jjm) 109 REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm) 110 REAL(rstd),INTENT(OUT) :: du(iim*3*jjm,llm), hflux(iim*3*jjm,llm) ! hflux in kg/s 111 REAL(rstd),INTENT(OUT) :: dtheta_rhodz(iim*jjm,llm) 112 REAL(rstd),INTENT(OUT) :: dps(iim*jjm) 113 REAL(rstd),INTENT(OUT) :: wflux(iim*jjm,llm+1) ! vertical mass flux (kg/m2/s) 114 115 REAL(rstd),ALLOCATABLE :: rhodz(:,:) 116 REAL(rstd),ALLOCATABLE :: divm(:,:) ! mass flux divergence 117 118 INTEGER :: i,j,ij,l 119 LOGICAL,SAVE :: first=.TRUE. 120 121 ALLOCATE(rhodz(iim*jjm,llm)) 122 ALLOCATE(divm(iim*jjm,llm)) ! mass flux divergence 123 124 dtheta_rhodz(:,:)=0. 125 du(:,:)=0. 126 127 !!! Compute mass 128 DO l = 1, llm 129 DO j=jj_begin-1,jj_end+1 130 DO i=ii_begin-1,ii_end+1 131 ij=(j-1)*iim+i 132 rhodz(ij,l) = (ap(l)-ap(l+1) + ps(ij)*(bp(l)-bp(l+1)) )/g 133 ENDDO 134 ENDDO 135 ENDDO 136 137 DO l = 1, llm 138 !!! Mass fluxes 139 DO j=jj_begin-1,jj_end+1 140 DO i=ii_begin-1,ii_end+1 141 ij=(j-1)*iim+i 142 hflux(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right) 143 hflux(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup) 144 hflux(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown) 145 ENDDO 146 ENDDO 147 !!! Horizontal divergence of fluxes 148 DO j=jj_begin,jj_end 149 DO i=ii_begin,ii_end 150 ij=(j-1)*iim+i 151 ! divm = +div(mass flux), sign convention as in Ringler et al. 2012, eq. 21 152 divm(ij,l)= 1./Ai(ij)*(ne(ij,right)*hflux(ij+u_right,l) + & 153 ne(ij,rup)*hflux(ij+u_rup,l) + & 154 ne(ij,lup)*hflux(ij+u_lup,l) + & 155 ne(ij,left)*hflux(ij+u_left,l) + & 156 ne(ij,ldown)*hflux(ij+u_ldown,l) + & 157 ne(ij,rdown)*hflux(ij+u_rdown,l)) 158 ENDDO 159 ENDDO 160 ENDDO 161 162 !!! cumulate mass flux divergence from top to bottom 163 DO l = llm-1, 1, -1 164 !$OMP DO 165 DO j=jj_begin,jj_end 166 DO i=ii_begin,ii_end 167 ij=(j-1)*iim+i 168 divm(ij,l) = divm(ij,l) + divm(ij,l+1) 169 ENDDO 170 ENDDO 171 ENDDO 172 173 !!! Compute vertical mass flux 174 DO l = 1,llm-1 175 DO j=jj_begin,jj_end 176 DO i=ii_begin,ii_end 177 ij=(j-1)*iim+i 178 ! w = int(z,ztop,div(flux)dz) + B(eta)dps/dt 179 ! => w>0 for upward transport 180 wflux( ij, l+1 ) = divm( ij, l+1 ) - bp(l+1) * divm( ij, 1 ) 181 ENDDO 182 ENDDO 183 ENDDO 184 185 ! compute dps, set vertical mass flux at the surface to 0 186 DO j=jj_begin,jj_end 187 DO i=ii_begin,ii_end 66 188 ij=(j-1)*iim+i 67 IF (domain(ind)%own(i,j)) THEN 68 mass_tot=mass_tot+ps(ij)*Ai(ij)/g 69 dmass_tot=dmass_tot+dps(ij)*Ai(ij)/g 70 ENDIF 71 ENDDO 72 ENDDO 73 74 ENDDO 75 PRINT*, "mass_tot ", mass_tot," dmass_tot ",dmass_tot 76 77 END SUBROUTINE check_mass_conservation 78 79 80 81 SUBROUTINE caldyn(write_out,f_phis, f_ps, f_theta_rhodz, f_u, f_q, f_dps, f_dtheta_rhodz, f_du) 82 USE icosa 83 USE vorticity_mod 84 USE kinetic_mod 85 USE theta2theta_rhodz_mod 86 IMPLICIT NONE 87 LOGICAL,INTENT(IN) :: write_out 88 TYPE(t_field),POINTER :: f_phis(:) 89 TYPE(t_field),POINTER :: f_ps(:) 90 TYPE(t_field),POINTER :: f_theta_rhodz(:) 91 TYPE(t_field),POINTER :: f_u(:) 92 TYPE(t_field),POINTER :: f_q(:) 93 TYPE(t_field),POINTER :: f_dps(:) 94 TYPE(t_field),POINTER :: f_dtheta_rhodz(:) 95 TYPE(t_field),POINTER :: f_du(:) 96 97 REAL(rstd),POINTER :: phis(:) 98 REAL(rstd),POINTER :: ps(:) 99 REAL(rstd),POINTER :: theta_rhodz(:,:) 100 REAL(rstd),POINTER :: u(:,:) 101 REAL(rstd),POINTER :: dps(:) 102 REAL(rstd),POINTER :: dtheta_rhodz(:,:) 103 REAL(rstd),POINTER :: du(:,:) 104 INTEGER :: ind 105 106 107 CALL transfert_request(f_phis,req_i1) 108 CALL transfert_request(f_ps,req_i1) 109 CALL transfert_request(f_theta_rhodz,req_i1) 110 CALL transfert_request(f_u,req_e1) 111 CALL transfert_request(f_u,req_e1) 112 113 DO ind=1,ndomain 114 CALL swap_dimensions(ind) 115 CALL swap_geometry(ind) 116 CALL swap_caldyn(ind) 117 118 phis=f_phis(ind) 119 ps=f_ps(ind) 120 theta_rhodz=f_theta_rhodz(ind) 121 u=f_u(ind) 122 dps=f_dps(ind) 123 dtheta_rhodz=f_dtheta_rhodz(ind) 124 du=f_du(ind) 125 126 !$OMP PARALLEL DEFAULT(SHARED) 127 CALL compute_caldyn(phis, ps, theta_rhodz, u, dps, dtheta_rhodz, du) 128 !$OMP END PARALLEL 129 ENDDO 130 131 CALL transfert_request(f_out_u,req_e1) 132 CALL transfert_request(f_out_u,req_e1) 133 134 135 IF (write_out) THEN 136 CALL writefield("ps",f_ps) 137 ENDIF 138 ! CALL check_mass_conservation(f_ps,f_dps) 139 140 END SUBROUTINE caldyn 141 142 143 SUBROUTINE compute_caldyn(phis, ps, theta_rhodz, u, dps, dtheta_rhodz, du) 144 USE icosa 145 USE disvert_mod 146 IMPLICIT NONE 147 REAL(rstd),INTENT(IN) :: phis(iim*jjm) 148 REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm) 149 REAL(rstd),INTENT(IN) :: theta_rhodz(iim*jjm,llm) 150 REAL(rstd),INTENT(IN) :: ps(iim*jjm) 151 REAL(rstd),INTENT(OUT) :: du(iim*3*jjm,llm) 152 REAL(rstd),INTENT(OUT):: dtheta_rhodz(iim*jjm,llm) 153 REAL(rstd),INTENT(OUT):: dps(iim*jjm) 189 wflux(ij,1) = 0. 190 ! dps/dt = -int(div flux)dz 191 dps(ij)=-divm(ij,1) * g 192 ENDDO 193 ENDDO 194 195 DEALLOCATE(rhodz) 196 DEALLOCATE(divm) 154 197 155 INTEGER :: i,j,ij,l156 REAL(rstd) :: ww,uu157 REAL(rstd) :: delta158 REAL(rstd) :: etav,hv159 REAL(rstd),ALLOCATABLE,SAVE :: theta(:,:) ! potential temperature160 REAL(rstd),ALLOCATABLE,SAVE :: p(:,:) ! pression161 REAL(rstd),ALLOCATABLE,SAVE :: pk(:,:) ! Exner function162 REAL(rstd),ALLOCATABLE,SAVE :: pks(:)163 ! Intermediate variable to compute exner function164 REAL(rstd),ALLOCATABLE,SAVE :: alpha(:,:)165 REAL(rstd),ALLOCATABLE,SAVE :: beta(:,:)166 !167 REAL(rstd),ALLOCATABLE,SAVE :: phi(:,:) ! geopotential168 REAL(rstd),ALLOCATABLE,SAVE :: mass(:,:) ! mass169 REAL(rstd),ALLOCATABLE,SAVE :: rhodz(:,:) ! mass density170 REAL(rstd),ALLOCATABLE,SAVE :: Fe(:,:) ! mass flux171 REAL(rstd),ALLOCATABLE,SAVE :: Ftheta(:,:) ! theta flux172 REAL(rstd),ALLOCATABLE,SAVE :: convm(:,:) ! mass flux convergence173 REAL(rstd),ALLOCATABLE,SAVE :: w(:,:) ! vertical velocity174 REAL(rstd),ALLOCATABLE,SAVE :: qv(:,:) ! potential velocity175 REAL(rstd),ALLOCATABLE,SAVE :: berni(:,:) ! bernouilli term176 177 LOGICAL,SAVE :: first=.TRUE.178 !$OMP THREADPRIVATE(first)179 180 !$OMP BARRIER181 !$OMP MASTER182 IF (first) THEN183 ALLOCATE(theta(iim*jjm,llm)) ! potential temperature184 ALLOCATE(p(iim*jjm,llm+1)) ! pression185 ALLOCATE(pk(iim*jjm,llm)) ! Exner function186 ALLOCATE(pks(iim*jjm))187 ALLOCATE(alpha(iim*jjm,llm))188 ALLOCATE(beta(iim*jjm,llm))189 ALLOCATE(phi(iim*jjm,llm)) ! geopotential190 ALLOCATE(mass(iim*jjm,llm)) ! mass191 ALLOCATE(rhodz(iim*jjm,llm)) ! mass density192 ALLOCATE(Fe(3*iim*jjm,llm)) ! mass flux193 ALLOCATE(Ftheta(3*iim*jjm,llm)) ! theta flux194 ALLOCATE(convm(iim*jjm,llm)) ! mass flux convergence195 ALLOCATE(w(iim*jjm,llm)) ! vertical velocity196 ALLOCATE(qv(2*iim*jjm,llm)) ! potential velocity197 ALLOCATE(berni(iim*jjm,llm)) ! bernouilli term198 first=.FALSE.199 ENDIF200 !$OMP END MASTER201 !$OMP BARRIER202 203 !!! Compute pression204 dtheta_rhodz(:,:)=0.205 du(:,:)=0.206 207 DO l = 1, llm+1208 !$OMP DO209 DO j=jj_begin-1,jj_end+1210 DO i=ii_begin-1,ii_end+1211 ij=(j-1)*iim+i212 p(ij,l) = ap(l) + bp(l) * ps(ij)213 ENDDO214 ENDDO215 ENDDO216 217 218 !!! Compute mass219 DO l = 1, llm220 !$OMP DO221 DO j=jj_begin-1,jj_end+1222 DO i=ii_begin-1,ii_end+1223 ij=(j-1)*iim+i224 mass(ij,l) = ( p(ij,l) - p(ij,l+1) ) * Ai(ij)/g225 rhodz(ij,l) = mass(ij,l) / Ai(ij)226 ENDDO227 ENDDO228 ENDDO229 230 231 !!! Compute mass flux232 !! question à thomas : meilleure pondération de la masse sur les liens ?233 234 DO l = 1, llm235 !$OMP DO236 DO j=jj_begin-1,jj_end+1237 DO i=ii_begin-1,ii_end+1238 ij=(j-1)*iim+i239 Fe(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right)240 Fe(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup)241 Fe(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown)242 ENDDO243 ENDDO244 ENDDO245 246 247 !!! mass flux convergence computation248 249 ! horizontal convergence250 DO l = 1, llm251 !$OMP DO252 DO j=jj_begin,jj_end253 DO i=ii_begin,ii_end254 ij=(j-1)*iim+i255 !signe ?256 convm(ij,l)= 1./Ai(ij)*(ne(ij,right)*Fe(ij+u_right,l) + &257 ne(ij,rup)*Fe(ij+u_rup,l) + &258 ne(ij,lup)*Fe(ij+u_lup,l) + &259 ne(ij,left)*Fe(ij+u_left,l) + &260 ne(ij,ldown)*Fe(ij+u_ldown,l) + &261 ne(ij,rdown)*Fe(ij+u_rdown,l))262 ENDDO263 ENDDO264 ENDDO265 266 267 ! vertical integration from up to down268 DO l = llm-1, 1, -1269 !$OMP DO270 DO j=jj_begin,jj_end271 DO i=ii_begin,ii_end272 ij=(j-1)*iim+i273 convm(ij,l) = convm(ij,l) + convm(ij,l+1)274 ENDDO275 ENDDO276 ENDDO277 278 279 !!! Compute dps280 !$OMP DO281 DO j=jj_begin,jj_end282 DO i=ii_begin,ii_end283 ij=(j-1)*iim+i284 dps(ij)=-convm(ij,1) * g285 ENDDO286 ENDDO287 288 198 END SUBROUTINE compute_caldyn 289 290 291 199 292 200 END MODULE caldyn_adv_mod -
codes/icosagcm/trunk/src/caldyn_gcm.f90
r138 r139 302 302 REAL(rstd),INTENT(OUT) :: wflux(iim*jjm,llm+1) ! vertical mass flux (kg/m2/s) 303 303 304 INTEGER :: i,j,ij,l305 REAL(rstd) :: ww,uu306 REAL(rstd) :: delta307 REAL(rstd) :: etav,hv, du2308 309 304 REAL(rstd),ALLOCATABLE,SAVE :: theta(:,:) ! potential temperature 310 305 REAL(rstd),ALLOCATABLE,SAVE :: pk(:,:), pks(:) ! Exner function … … 315 310 REAL(rstd),ALLOCATABLE,SAVE :: berni(:,:) ! Bernouilli function 316 311 312 INTEGER :: i,j,ij,l 313 REAL(rstd) :: ww,uu 314 317 315 LOGICAL,SAVE :: first=.TRUE. 318 316 !$OMP THREADPRIVATE(first) … … 328 326 ALLOCATE(phi(iim*jjm,llm)) ! geopotential 329 327 ALLOCATE(Ftheta(3*iim*jjm,llm)) ! theta flux 330 ALLOCATE(divm(iim*jjm,llm)) ! mass flux convergence328 ALLOCATE(divm(iim*jjm,llm)) ! mass flux divvergence 331 329 ALLOCATE(berni(iim*jjm,llm)) ! bernouilli term 332 330 … … 344 342 DO l = 1, llm 345 343 !!! Compute mass and theta fluxes 346 !$OMP DO347 344 DO j=jj_begin-1,jj_end+1 348 345 DO i=ii_begin-1,ii_end+1 … … 359 356 360 357 !!! compute horizontal divergence of fluxes 361 !$OMP DO362 358 DO j=jj_begin,jj_end 363 359 DO i=ii_begin,ii_end -
codes/icosagcm/trunk/src/timeloop_gcm.f90
r138 r139 163 163 ENDIF 164 164 165 !CALL guided(it*dt,f_ps,f_theta_rhodz,f_u,f_q)165 CALL guided(it*dt,f_ps,f_theta_rhodz,f_u,f_q) 166 166 167 167 DO stage=1,nb_stage
Note: See TracChangeset
for help on using the changeset viewer.