Changeset 11209 for NEMO/branches/2019/dev_r11085_ASINTER-05_Brodeau_Advanced_Bulk/src/OCE/SBC/sbcblk_phy.F90
- Timestamp:
- 2019-07-03T09:09:17+02:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2019/dev_r11085_ASINTER-05_Brodeau_Advanced_Bulk/src/OCE/SBC/sbcblk_phy.F90
r11182 r11209 8 8 !!---------------------------------------------------------------------- 9 9 10 !! virt_temp : virtual (aka sensible) temperature (potential or absolute) 10 11 !! rho_air : density of (moist) air (depends on T_air, q_air and SLP 12 !! visc_air : kinematic viscosity (aka Nu_air) of air from temperature 13 !! L_vap : latent heat of vaporization of water as a function of temperature 11 14 !! cp_air : specific heat of (moist) air (depends spec. hum. q_air) 15 !! gamma_moist : adiabatic lapse-rate of moist air 16 !! One_on_L : 1. / ( Monin-Obukhov length ) 17 !! Ri_bulk : bulk Richardson number aka BRN 12 18 !! q_sat : saturation humidity as a function of SLP and temperature 13 !! gamma_moist : 14 !! L_vap : latent heat of vaporization of water as a function of temperature 15 !! visc_air : kinematic viscosity (aka Nu_air) of air from temperature 16 19 17 20 USE dom_oce ! ocean space and time domain 18 21 USE phycst ! physical constants … … 21 24 PRIVATE 22 25 26 INTERFACE gamma_moist 27 MODULE PROCEDURE gamma_moist_vctr, gamma_moist_sclr 28 END INTERFACE gamma_moist 29 30 PUBLIC virt_temp 23 31 PUBLIC rho_air 32 PUBLIC visc_air 33 PUBLIC L_vap 24 34 PUBLIC cp_air 35 PUBLIC gamma_moist 36 PUBLIC One_on_L 37 PUBLIC Ri_bulk 25 38 PUBLIC q_sat 26 PUBLIC gamma_moist27 PUBLIC L_vap28 PUBLIC visc_air29 39 30 40 !!---------------------------------------------------------------------- … … 35 45 CONTAINS 36 46 47 FUNCTION virt_temp( pta, pqa ) 48 !!------------------------------------------------------------------------ 49 !! 50 !! Compute the (absolute/potential) virtual temperature, knowing the 51 !! (absolute/potential) temperature and specific humidity 52 !! 53 !! If input temperature is absolute then output vitual temperature is absolute 54 !! If input temperature is potential then output vitual temperature is potential 55 !! 56 !! Author: L. Brodeau, June 2019 / AeroBulk 57 !! (https://github.com/brodeau/aerobulk/) 58 !!------------------------------------------------------------------------ 59 REAL(wp), DIMENSION(jpi,jpj) :: virt_temp !: 1./(Monin Obukhov length) [m^-1] 60 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pta, & !: absolute or potetntial air temperature [K] 61 & pqa !: specific humidity of air [kg/kg] 62 !!------------------------------------------------------------------- 63 ! 64 virt_temp(:,:) = pta(:,:) * (1._wp + rctv0*pqa(:,:)) 65 !! 66 !! This is exactly the same sing that: 67 !! virt_temp = pta * ( pwa + reps0) / (reps0*(1.+pwa)) 68 !! with wpa (mixing ration) defined as : pwa = pqa/(1.-pqa) 69 ! 70 END FUNCTION virt_temp 71 37 72 FUNCTION rho_air( ptak, pqa, pslp ) 38 73 !!------------------------------------------------------------------------------- … … 41 76 !! ** Purpose : compute density of (moist) air using the eq. of state of the atmosphere 42 77 !! 43 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/)78 !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 44 79 !!------------------------------------------------------------------------------- 45 80 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptak ! air temperature [K] … … 53 88 END FUNCTION rho_air 54 89 90 FUNCTION visc_air(ptak) 91 !!---------------------------------------------------------------------------------- 92 !! Air kinetic viscosity (m^2/s) given from temperature in degrees... 93 !! 94 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 95 !!---------------------------------------------------------------------------------- 96 REAL(wp), DIMENSION(jpi,jpj) :: visc_air ! 97 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptak ! air temperature in (K) 98 ! 99 INTEGER :: ji, jj ! dummy loop indices 100 REAL(wp) :: ztc, ztc2 ! local scalar 101 !!---------------------------------------------------------------------------------- 102 ! 103 DO jj = 1, jpj 104 DO ji = 1, jpi 105 ztc = ptak(ji,jj) - rt0 ! air temp, in deg. C 106 ztc2 = ztc*ztc 107 visc_air(ji,jj) = 1.326e-5*(1. + 6.542E-3*ztc + 8.301e-6*ztc2 - 4.84e-9*ztc2*ztc) 108 END DO 109 END DO 110 ! 111 END FUNCTION visc_air 112 113 FUNCTION L_vap( psst ) 114 !!--------------------------------------------------------------------------------- 115 !! *** FUNCTION L_vap *** 116 !! 117 !! ** Purpose : Compute the latent heat of vaporization of water from temperature 118 !! 119 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 120 !!---------------------------------------------------------------------------------- 121 REAL(wp), DIMENSION(jpi,jpj) :: L_vap ! latent heat of vaporization [J/kg] 122 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psst ! water temperature [K] 123 !!---------------------------------------------------------------------------------- 124 ! 125 L_vap = ( 2.501 - 0.00237 * ( psst(:,:) - rt0) ) * 1.e6 126 ! 127 END FUNCTION L_vap 55 128 56 129 FUNCTION cp_air( pqa ) … … 69 142 ! 70 143 END FUNCTION cp_air 144 145 FUNCTION gamma_moist_vctr( ptak, pqa ) 146 !!---------------------------------------------------------------------------------- 147 !! *** FUNCTION gamma_moist_vctr *** 148 !! 149 !! ** Purpose : Compute the moist adiabatic lapse-rate. 150 !! => http://glossary.ametsoc.org/wiki/Moist-adiabatic_lapse_rate 151 !! => http://www.geog.ucsb.edu/~joel/g266_s10/lecture_notes/chapt03/oh10_3_01/oh10_3_01.html 152 !! 153 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 154 !!---------------------------------------------------------------------------------- 155 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptak ! air temperature [K] 156 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pqa ! specific humidity [kg/kg] 157 REAL(wp), DIMENSION(jpi,jpj) :: gamma_moist_vctr ! moist adiabatic lapse-rate 158 ! 159 INTEGER :: ji, jj ! dummy loop indices 160 REAL(wp) :: zta, zqa, zwa, ziRT ! local scalar 161 !!---------------------------------------------------------------------------------- 162 ! 163 DO jj = 1, jpj 164 DO ji = 1, jpi 165 zta = MAX( ptak(ji,jj), 180._wp) ! prevents screw-up over masked regions where field == 0. 166 zqa = MAX( pqa(ji,jj), 1.E-6_wp) ! " " " 167 ! 168 zwa = zqa / (1. - zqa) ! w is mixing ratio w = q/(1-q) | q = w/(1+w) 169 ziRT = 1._wp/(R_dry*zta) ! 1/RT 170 gamma_moist_vctr(ji,jj) = grav * ( 1._wp + rLevap*zwa*ziRT ) / ( rCp_dry + rLevap*rLevap*zwa*reps0*ziRT/zta ) 171 END DO 172 END DO 173 ! 174 END FUNCTION gamma_moist_vctr 175 176 FUNCTION gamma_moist_sclr( ptak, pqa ) 177 !!---------------------------------------------------------------------------------- 178 !! ** Purpose : Compute the moist adiabatic lapse-rate. 179 !! => http://glossary.ametsoc.org/wiki/Moist-adiabatic_lapse_rate 180 !! => http://www.geog.ucsb.edu/~joel/g266_s10/lecture_notes/chapt03/oh10_3_01/oh10_3_01.html 181 !! 182 !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 183 !!---------------------------------------------------------------------------------- 184 REAL(wp) :: gamma_moist_sclr 185 REAL(wp), INTENT(in) :: ptak, pqa ! air temperature (K) and specific humidity (kg/kg) 186 ! 187 REAL(wp) :: zta, zqa, zwa, ziRT ! local scalar 188 !!---------------------------------------------------------------------------------- 189 zta = MAX( ptak, 180._wp) ! prevents screw-up over masked regions where field == 0. 190 zqa = MAX( pqa, 1.E-6_wp) ! " " " 191 !! 192 zwa = zqa / (1._wp - zqa) ! w is mixing ratio w = q/(1-q) | q = w/(1+w) 193 ziRT = 1._wp / (R_dry*zta) ! 1/RT 194 gamma_moist_sclr = grav * ( 1._wp + rLevap*zwa*ziRT ) / ( rCp_dry + rLevap*rLevap*zwa*reps0*ziRT/zta ) 195 !! 196 END FUNCTION gamma_moist_sclr 197 198 FUNCTION One_on_L( ptha, pqa, pus, pts, pqs ) 199 !!------------------------------------------------------------------------ 200 !! 201 !! Evaluates the 1./(Monin Obukhov length) from air temperature and 202 !! specific humidity, and frictional scales u*, t* and q* 203 !! 204 !! Author: L. Brodeau, June 2016 / AeroBulk 205 !! (https://github.com/brodeau/aerobulk/) 206 !!------------------------------------------------------------------------ 207 REAL(wp), DIMENSION(jpi,jpj) :: One_on_L !: 1./(Monin Obukhov length) [m^-1] 208 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptha, & !: average potetntial air temperature [K] 209 & pqa, & !: average specific humidity of air [kg/kg] 210 & pus, pts, pqs !: frictional velocity, temperature and humidity 211 ! 212 INTEGER :: ji, jj ! dummy loop indices 213 REAL(wp) :: zqa ! local scalar 214 !!------------------------------------------------------------------- 215 ! 216 DO jj = 1, jpj 217 DO ji = 1, jpi 218 ! 219 zqa = (1._wp + rctv0*pqa(ji,jj)) 220 ! 221 One_on_L(ji,jj) = grav*vkarmn*(pts(ji,jj) + rctv0*ptha(ji,jj)*pqs(ji,jj)) & 222 & / MAX( pus(ji,jj)*pus(ji,jj)*ptha(ji,jj)*zqa , 1.E-9_wp ) 223 ! 224 END DO 225 END DO 226 ! 227 One_on_L = SIGN( MIN(ABS(One_on_L),200._wp), One_on_L ) ! (prevent FPE from stupid values over masked regions...) 228 ! 229 END FUNCTION One_on_L 230 231 FUNCTION Ri_bulk( pz, psst, ptha, pssq, pqa, pub ) 232 !!---------------------------------------------------------------------------------- 233 !! Bulk Richardson number according to "wide-spread equation"... 234 !! 235 !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) 236 !!---------------------------------------------------------------------------------- 237 REAL(wp), DIMENSION(jpi,jpj) :: Ri_bulk 238 REAL(wp) , INTENT(in) :: pz ! height above the sea (aka "delta z") [m] 239 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psst ! SST [K] 240 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptha ! pot. air temp. at height "pz" [K] 241 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pssq ! 0.98*q_sat(SST) [kg/kg] 242 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pqa ! air spec. hum. at height "pz" [kg/kg] 243 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pub ! bulk wind speed [m/s] 244 ! 245 INTEGER :: ji, jj ! dummy loop indices 246 REAL(wp) :: zqa, zta, zgamma, zdth_v, ztv, zsstv ! local scalars 247 !!------------------------------------------------------------------- 248 ! 249 DO jj = 1, jpj 250 DO ji = 1, jpi 251 ! 252 zqa = 0.5_wp*(pqa(ji,jj)+pssq(ji,jj)) ! ~ mean q within the layer... 253 zta = 0.5_wp*( psst(ji,jj) + ptha(ji,jj) - gamma_moist(ptha(ji,jj),zqa)*pz ) ! ~ mean absolute temperature of air within the layer 254 zta = 0.5_wp*( psst(ji,jj) + ptha(ji,jj) - gamma_moist(zta, zqa)*pz ) ! ~ mean absolute temperature of air within the layer 255 zgamma = gamma_moist(zta, zqa) ! Adiabatic lapse-rate for moist air within the layer 256 ! 257 zsstv = psst(ji,jj)*(1._wp + rctv0*pssq(ji,jj)) ! absolute==potential virtual SST (absolute==potential because z=0!) 258 ! 259 zdth_v = ptha(ji,jj)*(1._wp + rctv0*pqa(ji,jj)) - zsstv ! air-sea delta of "virtual potential temperature" 260 ! 261 ztv = 0.5_wp*( zsstv + (ptha(ji,jj) - zgamma*pz)*(1._wp + rctv0*pqa(ji,jj)) ) ! ~ mean absolute virtual temp. within the layer 262 ! 263 Ri_bulk(ji,jj) = grav*zdth_v*pz / ( ztv*pub(ji,jj)*pub(ji,jj) ) ! the usual definition of Ri_bulk 264 ! 265 END DO 266 END DO 267 END FUNCTION Ri_bulk 71 268 72 269 … … 108 305 109 306 110 FUNCTION gamma_moist( ptak, pqa )111 !!----------------------------------------------------------------------------------112 !! *** FUNCTION gamma_moist ***113 !!114 !! ** Purpose : Compute the moist adiabatic lapse-rate.115 !! => http://glossary.ametsoc.org/wiki/Moist-adiabatic_lapse_rate116 !! => http://www.geog.ucsb.edu/~joel/g266_s10/lecture_notes/chapt03/oh10_3_01/oh10_3_01.html117 !!118 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/)119 !!----------------------------------------------------------------------------------120 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptak ! air temperature [K]121 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pqa ! specific humidity [kg/kg]122 REAL(wp), DIMENSION(jpi,jpj) :: gamma_moist ! moist adiabatic lapse-rate123 !124 INTEGER :: ji, jj ! dummy loop indices125 REAL(wp) :: zrv, ziRT ! local scalar126 !!----------------------------------------------------------------------------------127 !128 DO jj = 1, jpj129 DO ji = 1, jpi130 zrv = pqa(ji,jj) / (1. - pqa(ji,jj))131 ziRT = 1. / (R_dry*ptak(ji,jj)) ! 1/RT132 gamma_moist(ji,jj) = grav * ( 1. + rLevap*zrv*ziRT ) / ( rCp_dry + rLevap*rLevap*zrv*reps0*ziRT/ptak(ji,jj) )133 END DO134 END DO135 !136 END FUNCTION gamma_moist137 138 139 FUNCTION L_vap( psst )140 !!---------------------------------------------------------------------------------141 !! *** FUNCTION L_vap ***142 !!143 !! ** Purpose : Compute the latent heat of vaporization of water from temperature144 !!145 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/)146 !!----------------------------------------------------------------------------------147 REAL(wp), DIMENSION(jpi,jpj) :: L_vap ! latent heat of vaporization [J/kg]148 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psst ! water temperature [K]149 !!----------------------------------------------------------------------------------150 !151 L_vap = ( 2.501 - 0.00237 * ( psst(:,:) - rt0) ) * 1.e6152 !153 END FUNCTION L_vap154 155 156 157 FUNCTION visc_air(ptak)158 !!----------------------------------------------------------------------------------159 !! Air kinetic viscosity (m^2/s) given from temperature in degrees...160 !!161 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/)162 !!----------------------------------------------------------------------------------163 REAL(wp), DIMENSION(jpi,jpj) :: visc_air !164 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: ptak ! air temperature in (K)165 !166 INTEGER :: ji, jj ! dummy loop indices167 REAL(wp) :: ztc, ztc2 ! local scalar168 !!----------------------------------------------------------------------------------169 !170 DO jj = 1, jpj171 DO ji = 1, jpi172 ztc = ptak(ji,jj) - rt0 ! air temp, in deg. C173 ztc2 = ztc*ztc174 visc_air(ji,jj) = 1.326e-5*(1. + 6.542E-3*ztc + 8.301e-6*ztc2 - 4.84e-9*ztc2*ztc)175 END DO176 END DO177 !178 END FUNCTION visc_air179 180 181 307 !!====================================================================== 182 308 END MODULE sbcblk_phy
Note: See TracChangeset
for help on using the changeset viewer.