Changeset 920 for codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.F90
- Timestamp:
- 06/19/19 00:40:30 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.F90
r836 r920 10 10 SAVE 11 11 12 PUBLIC :: compute_ geopot, compute_caldyn_vert, compute_caldyn_vert_nh12 PUBLIC :: compute_caldyn_vert, compute_caldyn_vert_nh 13 13 14 14 CONTAINS 15 15 16 !**************************** Geopotential *****************************17 18 SUBROUTINE compute_geopot(rhodz,theta, ps,pk,geopot)19 REAL(rstd),INTENT(IN) :: rhodz(iim*jjm,llm)20 REAL(rstd),INTENT(IN) :: theta(iim*jjm,llm,nqdyn) ! active scalars : theta/entropy, moisture, ...21 REAL(rstd),INTENT(INOUT) :: ps(iim*jjm)22 REAL(rstd),INTENT(OUT) :: pk(iim*jjm,llm) ! Exner function (compressible) /Lagrange multiplier (Boussinesq)23 REAL(rstd),INTENT(INOUT) :: geopot(iim*jjm,llm+1) ! geopotential24 25 INTEGER :: i,j,ij,l26 REAL(rstd) :: p_ik, exner_ik, Cp_ik, temp_ik, qv, chi, Rmix, gv27 INTEGER :: ij_omp_begin_ext, ij_omp_end_ext28 29 CALL trace_start("compute_geopot")30 31 !$OMP BARRIER32 33 CALL distrib_level(ij_begin_ext,ij_end_ext, ij_omp_begin_ext,ij_omp_end_ext)34 35 IF(dysl_geopot) THEN36 #include "../kernels_hex/compute_geopot.k90"37 ELSE38 ! Pressure is computed first top-down (temporarily stored in pk)39 ! Then Exner pressure and geopotential are computed bottom-up40 ! Works also when caldyn_eta=eta_mass41 42 IF(boussinesq) THEN ! compute geopotential and pk=Lagrange multiplier43 ! specific volume 1 = dphi/g/rhodz44 ! IF (is_omp_level_master) THEN ! no openMP on vertical due to dependency45 DO l = 1,llm46 !DIR$ SIMD47 DO ij=ij_omp_begin_ext,ij_omp_end_ext48 geopot(ij,l+1) = geopot(ij,l) + g*rhodz(ij,l)49 ENDDO50 ENDDO51 ! use hydrostatic balance with theta*rhodz to find pk (Lagrange multiplier=pressure)52 ! uppermost layer53 !DIR$ SIMD54 DO ij=ij_begin_ext,ij_end_ext55 pk(ij,llm) = ptop + (.5*g)*theta(ij,llm,1)*rhodz(ij,llm)56 END DO57 ! other layers58 DO l = llm-1, 1, -159 ! !$OMP DO SCHEDULE(STATIC)60 !DIR$ SIMD61 DO ij=ij_begin_ext,ij_end_ext62 pk(ij,l) = pk(ij,l+1) + (.5*g)*(theta(ij,l,1)*rhodz(ij,l)+theta(ij,l+1,1)*rhodz(ij,l+1))63 END DO64 END DO65 ! now pk contains the Lagrange multiplier (pressure)66 ELSE ! non-Boussinesq, compute pressure, Exner pressure or temperature, then geopotential67 ! uppermost layer68 69 SELECT CASE(caldyn_thermo)70 CASE(thermo_theta, thermo_entropy)71 !DIR$ SIMD72 DO ij=ij_omp_begin_ext,ij_omp_end_ext73 pk(ij,llm) = ptop + (.5*g)*rhodz(ij,llm)74 END DO75 ! other layers76 DO l = llm-1, 1, -177 !DIR$ SIMD78 DO ij=ij_omp_begin_ext,ij_omp_end_ext79 pk(ij,l) = pk(ij,l+1) + (.5*g)*(rhodz(ij,l)+rhodz(ij,l+1))80 END DO81 END DO82 ! surface pressure (for diagnostics)83 IF(caldyn_eta==eta_lag) THEN84 DO ij=ij_omp_begin_ext,ij_omp_end_ext85 ps(ij) = pk(ij,1) + (.5*g)*rhodz(ij,1)86 END DO87 END IF88 CASE(thermo_moist) ! theta(ij,l,2) = qv = mv/md89 !DIR$ SIMD90 DO ij=ij_omp_begin_ext,ij_omp_end_ext91 pk(ij,llm) = ptop + (.5*g)*rhodz(ij,llm)*(1.+theta(ij,l,2))92 END DO93 ! other layers94 DO l = llm-1, 1, -195 !DIR$ SIMD96 DO ij=ij_omp_begin_ext,ij_omp_end_ext97 pk(ij,l) = pk(ij,l+1) + (.5*g)*( &98 rhodz(ij,l) *(1.+theta(ij,l,2)) + &99 rhodz(ij,l+1)*(1.+theta(ij,l+1,2)) )100 END DO101 END DO102 ! surface pressure (for diagnostics)103 IF(caldyn_eta==eta_lag) THEN104 DO ij=ij_omp_begin_ext,ij_omp_end_ext105 ps(ij) = pk(ij,1) + (.5*g)*rhodz(ij,1)*(1.+theta(ij,l,2))106 END DO107 END IF108 END SELECT109 110 DO l = 1,llm111 SELECT CASE(caldyn_thermo)112 CASE(thermo_theta)113 !DIR$ SIMD114 DO ij=ij_omp_begin_ext,ij_omp_end_ext115 p_ik = pk(ij,l)116 exner_ik = cpp * (p_ik/preff) ** kappa117 pk(ij,l) = exner_ik118 ! specific volume v = kappa*theta*pi/p = dphi/g/rhodz119 geopot(ij,l+1) = geopot(ij,l) + (g*kappa)*rhodz(ij,l)*theta(ij,l,1)*exner_ik/p_ik120 ENDDO121 CASE(thermo_entropy) ! theta is in fact entropy = cpp*log(theta/Treff) = cpp*log(T/Treff) - Rd*log(p/preff)122 !DIR$ SIMD123 DO ij=ij_omp_begin_ext,ij_omp_end_ext124 p_ik = pk(ij,l)125 temp_ik = Treff*exp((theta(ij,l,1) + Rd*log(p_ik/preff))/cpp)126 pk(ij,l) = temp_ik127 ! specific volume v = Rd*T/p = dphi/g/rhodz128 geopot(ij,l+1) = geopot(ij,l) + (g*Rd)*rhodz(ij,l)*temp_ik/p_ik129 ENDDO130 CASE(thermo_moist) ! theta is moist pseudo-entropy per dry air mass131 DO ij=ij_omp_begin_ext,ij_omp_end_ext132 p_ik = pk(ij,l)133 qv = theta(ij,l,2) ! water vaper mixing ratio = mv/md134 Rmix = Rd+qv*Rv135 chi = ( theta(ij,l,1) + Rmix*log(p_ik/preff) ) / (cpp + qv*cppv) ! log(T/Treff)136 temp_ik = Treff*exp(chi)137 pk(ij,l) = temp_ik138 ! specific volume v = R*T/p = dphi/g/rhodz139 ! R = (Rd + qv.Rv)/(1+qv)140 geopot(ij,l+1) = geopot(ij,l) + g*Rmix*rhodz(ij,l)*temp_ik/(p_ik*(1+qv))141 ENDDO142 CASE DEFAULT143 STOP144 END SELECT145 ENDDO146 END IF147 148 END IF ! dysl149 150 !ym flush geopot151 !$OMP BARRIER152 153 CALL trace_end("compute_geopot")154 155 END SUBROUTINE compute_geopot156 16 157 17 SUBROUTINE compute_caldyn_vert(u,theta,rhodz,convm, wflux,wwuu, dps,dtheta_rhodz,du) … … 160 20 REAL(rstd),INTENT(IN) :: rhodz(iim*jjm,llm) 161 21 REAL(rstd),INTENT(INOUT) :: convm(iim*jjm,llm) ! mass flux convergence 162 163 22 REAL(rstd),INTENT(INOUT) :: wflux(iim*jjm,llm+1) ! vertical mass flux (kg/m2/s) 164 23 REAL(rstd),INTENT(INOUT) :: wwuu(iim*3*jjm,llm+1) … … 341 200 342 201 END SUBROUTINE compute_caldyn_vert_NH 202 343 203 END MODULE caldyn_kernels_base_mod
Note: See TracChangeset
for help on using the changeset viewer.