Changeset 126
- Timestamp:
- 02/01/13 02:11:24 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
codes/icosagcm/trunk/src/caldyn_gcm.f90
r125 r126 20 20 CHARACTER(len=255) :: def 21 21 22 def=' direct'22 def='enstrophy' 23 23 CALL getin('caldyn_conserv',def) 24 24 SELECT CASE(TRIM(def)) 25 25 CASE('energy') 26 26 caldyn_conserv=1 27 CASE(' direct')27 CASE('enstrophy') 28 28 caldyn_conserv=2 29 29 CASE DEFAULT … … 79 79 END SUBROUTINE allocate_caldyn 80 80 81 SUBROUTINE check_mass_conservation(f_ps,f_dps) 82 USE icosa 83 IMPLICIT NONE 81 SUBROUTINE caldyn(it,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 INTEGER,INTENT(IN) :: it 88 TYPE(t_field),POINTER :: f_phis(:) 84 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(:) 85 93 TYPE(t_field),POINTER :: f_dps(:) 86 REAL(rstd),POINTER :: ps(:) 87 REAL(rstd),POINTER :: dps(:) 88 REAL(rstd) :: mass_tot,dmass_tot 89 INTEGER :: ind,i,j,ij 90 91 mass_tot=0 92 dmass_tot=0 93 94 CALL transfert_request(f_dps,req_i1) 95 CALL transfert_request(f_ps,req_i1) 96 97 DO ind=1,ndomain 98 CALL swap_dimensions(ind) 99 CALL swap_geometry(ind) 100 101 ps=f_ps(ind) 102 dps=f_dps(ind) 103 104 DO j=jj_begin,jj_end 105 DO i=ii_begin,ii_end 106 ij=(j-1)*iim+i 107 IF (domain(ind)%own(i,j)) THEN 108 mass_tot=mass_tot+ps(ij)*Ai(ij)/g 109 dmass_tot=dmass_tot+dps(ij)*Ai(ij)/g 110 ENDIF 111 ENDDO 112 ENDDO 113 114 ENDDO 115 PRINT*, "mass_tot ", mass_tot," dmass_tot ",dmass_tot 116 117 END SUBROUTINE check_mass_conservation 118 119 SUBROUTINE caldyn(it,f_phis, f_ps, f_theta_rhodz, f_u, f_q, f_dps, f_dtheta_rhodz, f_du) 120 USE icosa 121 USE vorticity_mod 122 USE kinetic_mod 123 USE theta2theta_rhodz_mod 124 IMPLICIT NONE 125 INTEGER,INTENT(IN) :: it 126 TYPE(t_field),POINTER :: f_phis(:) 127 TYPE(t_field),POINTER :: f_ps(:) 128 TYPE(t_field),POINTER :: f_theta_rhodz(:) 129 TYPE(t_field),POINTER :: f_u(:) 130 TYPE(t_field),POINTER :: f_q(:) 131 TYPE(t_field),POINTER :: f_dps(:) 132 TYPE(t_field),POINTER :: f_dtheta_rhodz(:) 133 TYPE(t_field),POINTER :: f_du(:) 134 135 REAL(rstd),POINTER :: phis(:), ps(:), dps(:) 136 REAL(rstd),POINTER :: theta_rhodz(:,:), dtheta_rhodz(:,:) 137 REAL(rstd),POINTER :: u(:,:), du(:,:) 138 REAL(rstd),POINTER :: p(:,:), rhodz(:,:), qu(:,:) 139 INTEGER :: ind,ij 140 141 94 TYPE(t_field),POINTER :: f_dtheta_rhodz(:) 95 TYPE(t_field),POINTER :: f_du(:) 96 97 REAL(rstd),POINTER :: phis(:), ps(:), dps(:) 98 REAL(rstd),POINTER :: theta_rhodz(:,:), dtheta_rhodz(:,:) 99 REAL(rstd),POINTER :: u(:,:), du(:,:) 100 REAL(rstd),POINTER :: p(:,:), rhodz(:,:), qu(:,:) 101 INTEGER :: ind,ij 102 142 103 CALL transfert_request(f_phis,req_i1) 143 104 CALL transfert_request(f_ps,req_i1) 144 105 CALL transfert_request(f_theta_rhodz,req_i1) 145 106 CALL transfert_request(f_u,req_e1) 146 147 DO ind=1,ndomain 148 CALL swap_dimensions(ind) 149 CALL swap_geometry(ind) 150 151 phis=f_phis(ind) 152 ps=f_ps(ind) 153 dps=f_dps(ind) 154 theta_rhodz=f_theta_rhodz(ind) 155 dtheta_rhodz=f_dtheta_rhodz(ind) 156 rhodz=f_rhodz(ind) 157 p=f_p(ind) 158 qu=f_qu(ind) 159 u=f_u(ind) 160 du=f_du(ind) 161 out_u=f_out_u(ind) 162 !$OMP PARALLEL DEFAULT(SHARED) 163 CALL compute_caldyn(ps, u, p,rhodz,qu, phis, theta_rhodz, dps, dtheta_rhodz, du) 164 !$OMP END PARALLEL 165 ENDDO 166 167 IF (mod(it,itau_out)==0 ) THEN 168 PRINT *,'CALL write_output_fields' 169 CALL write_output_fields(f_ps, f_phis, f_dps, f_u, f_theta_rhodz, f_q, & 170 f_buf_i, f_buf_v, f_buf_u3d, f_buf_ulon, f_buf_ulat, f_buf_s, f_buf_p) 171 END IF 172 173 ! CALL check_mass_conservation(f_ps,f_dps) 174 175 END SUBROUTINE caldyn 176 177 178 SUBROUTINE compute_caldyn(ps, u, p,rhodz,qu, phis, theta_rhodz, dps, dtheta_rhodz, du) 107 108 SELECT CASE(caldyn_conserv) 109 CASE(1) ! energy-conserving 110 CASE(2) ! enstrophy-conserving 111 DO ind=1,ndomain 112 CALL swap_dimensions(ind) 113 CALL swap_geometry(ind) 114 115 phis=f_phis(ind) 116 ps=f_ps(ind) 117 dps=f_dps(ind) 118 theta_rhodz=f_theta_rhodz(ind) 119 dtheta_rhodz=f_dtheta_rhodz(ind) 120 rhodz=f_rhodz(ind) 121 p=f_p(ind) 122 qu=f_qu(ind) 123 u=f_u(ind) 124 du=f_du(ind) 125 out_u=f_out_u(ind) 126 !$OMP PARALLEL DEFAULT(SHARED) 127 ! CALL compute_caldyn(ps, u, p,rhodz,qu, phis, theta_rhodz, dps, dtheta_rhodz, du) 128 CALL compute_pvort(ps, u, p,rhodz,qu) 129 CALL compute_caldyn(ps, u, p,rhodz,qu, phis, theta_rhodz, dps, dtheta_rhodz, du) 130 !$OMP END PARALLEL 131 ENDDO 132 133 IF (mod(it,itau_out)==0 ) THEN 134 PRINT *,'CALL write_output_fields' 135 CALL write_output_fields(f_ps, f_phis, f_dps, f_u, f_theta_rhodz, f_q, & 136 f_buf_i, f_buf_v, f_buf_u3d, f_buf_ulon, f_buf_ulat, f_buf_s, f_buf_p) 137 END IF 138 139 CASE DEFAULT 140 STOP 141 END SELECT 142 143 ! CALL check_mass_conservation(f_ps,f_dps) 144 145 END SUBROUTINE caldyn 146 147 148 SUBROUTINE compute_pvort(ps, u, p,rhodz,qu) 179 149 USE icosa 180 150 USE disvert_mod 181 151 USE exner_mod 182 152 IMPLICIT NONE 183 REAL(rstd),INTENT(IN) :: phis(iim*jjm)184 153 REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm) 185 REAL(rstd),INTENT(IN) :: theta_rhodz(iim*jjm,llm)186 154 REAL(rstd),INTENT(IN) :: ps(iim*jjm) 187 188 155 REAL(rstd),INTENT(OUT) :: p(iim*jjm,llm+1) 189 156 REAL(rstd),INTENT(OUT) :: rhodz(iim*jjm,llm) 190 157 REAL(rstd),INTENT(OUT) :: qu(iim*3*jjm,llm) 191 192 REAL(rstd),INTENT(OUT) :: du(iim*3*jjm,llm)193 REAL(rstd),INTENT(OUT) :: dtheta_rhodz(iim*jjm,llm)194 REAL(rstd),INTENT(OUT) :: dps(iim*jjm)195 158 196 159 INTEGER :: i,j,ij,l … … 200 163 201 164 REAL(rstd),ALLOCATABLE,SAVE :: theta(:,:) ! potential temperature 202 REAL(rstd),ALLOCATABLE,SAVE :: pk(:,:) ! Exner function 203 REAL(rstd),ALLOCATABLE,SAVE :: pks(:) 204 ! Intermediate variable to compute exner function 205 REAL(rstd),ALLOCATABLE,SAVE :: alpha(:,:) 206 REAL(rstd),ALLOCATABLE,SAVE :: beta(:,:) 207 208 REAL(rstd),ALLOCATABLE,SAVE :: phi(:,:) ! geopotential 209 REAL(rstd),ALLOCATABLE,SAVE :: Fe(:,:) ! mass flux 210 REAL(rstd),ALLOCATABLE,SAVE :: Ftheta(:,:) ! theta flux 211 REAL(rstd),ALLOCATABLE,SAVE :: convm(:,:) ! mass flux convergence 212 REAL(rstd),ALLOCATABLE,SAVE :: w(:,:) ! vertical velocity 213 REAL(rstd),ALLOCATABLE,SAVE :: qv(:,:) ! potential velocity 214 REAL(rstd),ALLOCATABLE,SAVE :: berni(:,:) ! bernouilli term 165 REAL(rstd),ALLOCATABLE,SAVE :: pk(:,:), pks(:) ! Exner function 166 REAL(rstd),ALLOCATABLE,SAVE :: alpha(:,:), beta(:,:) 167 REAL(rstd),ALLOCATABLE,SAVE :: phi(:,:) ! geopotential 168 REAL(rstd),ALLOCATABLE,SAVE :: Fe(:,:), Ftheta(:,:) ! mass flux, theta flux 169 REAL(rstd),ALLOCATABLE,SAVE :: convm(:,:) ! mass flux convergence 170 REAL(rstd),ALLOCATABLE,SAVE :: w(:,:) ! vertical velocity 171 REAL(rstd),ALLOCATABLE,SAVE :: qv(:,:) ! potential velocity 172 REAL(rstd),ALLOCATABLE,SAVE :: berni(:,:) ! Bernouilli function 215 173 216 174 LOGICAL,SAVE :: first=.TRUE. … … 220 178 !$OMP MASTER 221 179 ! IF (first) THEN 222 ALLOCATE(theta(iim*jjm,llm)) ! potential temperature 223 ALLOCATE(pk(iim*jjm,llm)) ! Exner function 224 ALLOCATE(pks(iim*jjm)) 225 ALLOCATE(alpha(iim*jjm,llm)) 226 ALLOCATE(beta(iim*jjm,llm)) 227 ALLOCATE(phi(iim*jjm,llm)) ! geopotential 228 ALLOCATE(Fe(3*iim*jjm,llm)) ! mass flux 229 ALLOCATE(Ftheta(3*iim*jjm,llm)) ! theta flux 230 ALLOCATE(convm(iim*jjm,llm)) ! mass flux convergence 231 ALLOCATE(w(iim*jjm,llm)) ! vertical velocity 232 ALLOCATE(qv(2*iim*jjm,llm)) ! potential velocity 233 ALLOCATE(berni(iim*jjm,llm)) ! bernouilli term 234 ! first=.FALSE. 235 ! ENDIF 236 !$OMP END MASTER 237 !$OMP BARRIER 238 ! du(:,:)=0 239 ! theta=1e10 240 ! p=1e10 241 ! pk=1e10 242 ! pks=1e10 243 ! alpha=1e10 244 ! beta=1e10 245 ! phi=1e10 246 ! mass=1e10 247 ! rhodz=1e10 248 ! Fe=1e10 249 ! Ftheta=1e10 250 ! convm=1e10 251 ! w=1e10 252 ! qv=1e10 253 ! berni=1e10 254 255 !!! Compute pressure 256 257 ! PRINT *, 'Computing pressure' 180 ALLOCATE(theta(iim*jjm,llm)) ! potential temperature 181 ALLOCATE(pk(iim*jjm,llm)) ! Exner function 182 ALLOCATE(pks(iim*jjm)) 183 ALLOCATE(alpha(iim*jjm,llm)) 184 ALLOCATE(beta(iim*jjm,llm)) 185 ALLOCATE(phi(iim*jjm,llm)) ! geopotential 186 ALLOCATE(Fe(3*iim*jjm,llm)) ! mass flux 187 ALLOCATE(Ftheta(3*iim*jjm,llm)) ! theta flux 188 ALLOCATE(convm(iim*jjm,llm)) ! mass flux convergence 189 ALLOCATE(w(iim*jjm,llm)) ! vertical velocity 190 ALLOCATE(qv(2*iim*jjm,llm)) ! potential velocity 191 ALLOCATE(berni(iim*jjm,llm)) ! bernouilli term 192 193 !!! Compute pressure 258 194 DO l = 1, llm+1 259 !$OMP DO260 DO j=jj_begin-1,jj_end+1261 DO i=ii_begin-1,ii_end+1262 ij=(j-1)*iim+i263 p(ij,l) = ap(l) + bp(l) * ps(ij)264 ENDDO265 ENDDO266 ENDDO 267 195 !$OMP DO 196 DO j=jj_begin-1,jj_end+1 197 DO i=ii_begin-1,ii_end+1 198 ij=(j-1)*iim+i 199 p(ij,l) = ap(l) + bp(l) * ps(ij) 200 ENDDO 201 ENDDO 202 ENDDO 203 268 204 !!! Compute mass 269 ! PRINT *, 'Computing mass, theta'270 205 DO l = 1, llm 271 206 !$OMP DO … … 274 209 ij=(j-1)*iim+i 275 210 rhodz(ij,l) = ( p(ij,l) - p(ij,l+1) )/g 276 theta(ij,l) = theta_rhodz(ij,l)/rhodz(ij,l)277 211 ENDDO 278 212 ENDDO … … 309 243 ENDDO 310 244 311 DO j=jj_begin,jj_end 312 DO i=ii_begin,ii_end 313 ij=(j-1)*iim+i 314 qu(ij+u_right,l) = 0.5*(qv(ij+z_rdown,l)+qv(ij+z_rup,l)) 315 qu(ij+u_lup,l) = 0.5*(qv(ij+z_up,l)+qv(ij+z_lup,l)) 316 qu(ij+u_ldown,l) = 0.5*(qv(ij+z_ldown,l)+qv(ij+z_down,l)) 317 END DO 318 END DO 319 320 ENDDO 245 DO j=jj_begin,jj_end 246 DO i=ii_begin,ii_end 247 ij=(j-1)*iim+i 248 qu(ij+u_right,l) = 0.5*(qv(ij+z_rdown,l)+qv(ij+z_rup,l)) 249 qu(ij+u_lup,l) = 0.5*(qv(ij+z_up,l)+qv(ij+z_lup,l)) 250 qu(ij+u_ldown,l) = 0.5*(qv(ij+z_ldown,l)+qv(ij+z_down,l)) 251 END DO 252 END DO 253 254 ENDDO 255 256 !!$OMP BARRIER 257 !!$OMP MASTER 258 DEALLOCATE(theta) ! potential temperature 259 DEALLOCATE(pk) ! Exner function 260 DEALLOCATE(pks) 261 DEALLOCATE(alpha) 262 DEALLOCATE(beta) 263 DEALLOCATE(phi) ! geopotential 264 DEALLOCATE(Fe) ! mass flux 265 DEALLOCATE(Ftheta) ! theta flux 266 DEALLOCATE(convm) ! mass flux convergence 267 DEALLOCATE(w) ! vertical velocity 268 DEALLOCATE(qv) ! potential velocity 269 DEALLOCATE(berni) ! bernouilli term 270 !!$OMP END MASTER 271 !!$OMP BARRIER 272 END SUBROUTINE compute_pvort 273 321 274 322 275 !----------- needed next : rhodz, p --------------! 276 277 SUBROUTINE compute_caldyn(ps, u, p,rhodz,qu, phis, theta_rhodz, dps, dtheta_rhodz, du) 278 USE icosa 279 USE disvert_mod 280 USE exner_mod 281 IMPLICIT NONE 282 REAL(rstd),INTENT(IN) :: phis(iim*jjm) 283 REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm) 284 REAL(rstd),INTENT(IN) :: theta_rhodz(iim*jjm,llm) 285 REAL(rstd),INTENT(IN) :: ps(iim*jjm) 286 REAL(rstd),INTENT(IN) :: p(iim*jjm,llm+1) 287 REAL(rstd),INTENT(IN) :: rhodz(iim*jjm,llm) 288 REAL(rstd),INTENT(IN) :: qu(iim*3*jjm,llm) 289 290 REAL(rstd),INTENT(OUT) :: du(iim*3*jjm,llm) 291 REAL(rstd),INTENT(OUT) :: dtheta_rhodz(iim*jjm,llm) 292 REAL(rstd),INTENT(OUT) :: dps(iim*jjm) 293 294 INTEGER :: i,j,ij,l 295 REAL(rstd) :: ww,uu 296 REAL(rstd) :: delta 297 REAL(rstd) :: etav,hv, du2 298 299 REAL(rstd),ALLOCATABLE,SAVE :: theta(:,:) ! potential temperature 300 REAL(rstd),ALLOCATABLE,SAVE :: pk(:,:), pks(:) ! Exner function 301 REAL(rstd),ALLOCATABLE,SAVE :: alpha(:,:), beta(:,:) 302 REAL(rstd),ALLOCATABLE,SAVE :: phi(:,:) ! geopotential 303 REAL(rstd),ALLOCATABLE,SAVE :: Fe(:,:), Ftheta(:,:) ! mass flux, theta flux 304 REAL(rstd),ALLOCATABLE,SAVE :: convm(:,:) ! mass flux convergence 305 REAL(rstd),ALLOCATABLE,SAVE :: w(:,:) ! vertical velocity 306 REAL(rstd),ALLOCATABLE,SAVE :: qv(:,:) ! potential velocity 307 REAL(rstd),ALLOCATABLE,SAVE :: berni(:,:) ! Bernouilli function 308 309 LOGICAL,SAVE :: first=.TRUE. 310 !$OMP THREADPRIVATE(first) 311 312 !$OMP BARRIER 313 !$OMP MASTER 314 ! IF (first) THEN 315 ALLOCATE(theta(iim*jjm,llm)) ! potential temperature 316 ALLOCATE(pk(iim*jjm,llm)) ! Exner function 317 ALLOCATE(pks(iim*jjm)) 318 ALLOCATE(alpha(iim*jjm,llm)) 319 ALLOCATE(beta(iim*jjm,llm)) 320 ALLOCATE(phi(iim*jjm,llm)) ! geopotential 321 ALLOCATE(Fe(3*iim*jjm,llm)) ! mass flux 322 ALLOCATE(Ftheta(3*iim*jjm,llm)) ! theta flux 323 ALLOCATE(convm(iim*jjm,llm)) ! mass flux convergence 324 ALLOCATE(w(iim*jjm,llm)) ! vertical velocity 325 ALLOCATE(qv(2*iim*jjm,llm)) ! potential velocity 326 ALLOCATE(berni(iim*jjm,llm)) ! bernouilli term 327 328 !!! Compute theta 329 DO l = 1, llm 330 !$OMP DO 331 DO j=jj_begin-1,jj_end+1 332 DO i=ii_begin-1,ii_end+1 333 ij=(j-1)*iim+i 334 theta(ij,l) = theta_rhodz(ij,l)/rhodz(ij,l) 335 ENDDO 336 ENDDO 337 ENDDO 323 338 324 339 DO l = 1, llm … … 577 592 !!$OMP BARRIER 578 593 END SUBROUTINE compute_caldyn 594 595 !-------------------------------- Diagnostics ---------------------------- 596 597 SUBROUTINE check_mass_conservation(f_ps,f_dps) 598 USE icosa 599 IMPLICIT NONE 600 TYPE(t_field),POINTER :: f_ps(:) 601 TYPE(t_field),POINTER :: f_dps(:) 602 REAL(rstd),POINTER :: ps(:) 603 REAL(rstd),POINTER :: dps(:) 604 REAL(rstd) :: mass_tot,dmass_tot 605 INTEGER :: ind,i,j,ij 606 607 mass_tot=0 608 dmass_tot=0 609 610 CALL transfert_request(f_dps,req_i1) 611 CALL transfert_request(f_ps,req_i1) 612 613 DO ind=1,ndomain 614 CALL swap_dimensions(ind) 615 CALL swap_geometry(ind) 616 617 ps=f_ps(ind) 618 dps=f_dps(ind) 619 620 DO j=jj_begin,jj_end 621 DO i=ii_begin,ii_end 622 ij=(j-1)*iim+i 623 IF (domain(ind)%own(i,j)) THEN 624 mass_tot=mass_tot+ps(ij)*Ai(ij)/g 625 dmass_tot=dmass_tot+dps(ij)*Ai(ij)/g 626 ENDIF 627 ENDDO 628 ENDDO 629 630 ENDDO 631 PRINT*, "mass_tot ", mass_tot," dmass_tot ",dmass_tot 632 633 END SUBROUTINE check_mass_conservation 579 634 580 635 SUBROUTINE write_output_fields(f_ps, f_phis, f_dps, f_u, f_theta_rhodz, f_q, &
Note: See TracChangeset
for help on using the changeset viewer.