New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 14072 for NEMO/trunk/src/OCE/SBC/sbcblk_algo_ncar.F90 – NEMO

Ignore:
Timestamp:
2020-12-04T08:48:38+01:00 (3 years ago)
Author:
laurent
Message:

Merging branch "2020/dev_r13648_ASINTER-04_laurent_bulk_ice", ticket #2369

File:
1 edited

Legend:

Unmodified
Added
Removed
  • NEMO/trunk/src/OCE/SBC/sbcblk_algo_ncar.F90

    r13460 r14072  
    55   !!   * bulk transfer coefficients C_D, C_E and C_H 
    66   !!   * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed 
    7    !!   * the effective bulk wind speed at 10m U_blk 
     7   !!   * the effective bulk wind speed at 10m Ubzu 
    88   !!   => all these are used in bulk formulas in sbcblk.F90 
    99   !! 
     
    1616   !!===================================================================== 
    1717   !! History :  3.6  !  2016-02  (L.Brodeau) successor of old turb_ncar of former sbcblk_core.F90 
     18   !!            4.2  !  2020-12  (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 
    1819   !!---------------------------------------------------------------------- 
    1920 
     
    2324   !!                   returns the effective bulk wind speed at 10m 
    2425   !!---------------------------------------------------------------------- 
    25    USE oce             ! ocean dynamics and tracers 
    2626   USE dom_oce         ! ocean space and time domain 
     27   USE sbc_oce, ONLY: ln_cdgw 
     28   USE sbcwave, ONLY: cdn_wave ! wave module 
    2729   USE phycst          ! physical constants 
    28    USE sbc_oce         ! Surface boundary condition: ocean fields 
    29    USE sbcwave, ONLY   :  cdn_wave ! wave module 
    30 #if defined key_si3 || defined key_cice 
    31    USE sbc_ice         ! Surface boundary condition: ice fields 
    32 #endif 
    33    ! 
    34    USE iom             ! I/O manager library 
    35    USE lib_mpp         ! distribued memory computing library 
    36    USE in_out_manager  ! I/O manager 
    37    USE prtctl          ! Print control 
    38    USE lib_fortran     ! to use key_nosignedzero 
    39  
    40    USE sbcblk_phy      ! all thermodynamics functions, rho_air, q_sat, etc... !LB 
     30   USE sbc_phy         ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 
    4131 
    4232   IMPLICIT NONE 
     
    4535   PUBLIC :: TURB_NCAR   ! called by sbcblk.F90 
    4636 
    47    INTEGER , PARAMETER ::   nb_itt = 5        ! number of itterations 
    4837   !! * Substitutions 
    4938#  include "do_loop_substitute.h90" 
     
    5241CONTAINS 
    5342 
    54    SUBROUTINE turb_ncar( zt, zu, sst, t_zt, ssq, q_zt, U_zu, & 
    55       &                  Cd, Ch, Ce, t_zu, q_zu, U_blk,      & 
    56       &                  Cdn, Chn, Cen                       ) 
     43   SUBROUTINE turb_ncar(    zt, zu, sst, t_zt, ssq, q_zt, U_zu, & 
     44      &                     Cd, Ch, Ce, t_zu, q_zu, Ubzu,       & 
     45      &                     nb_iter, CdN, ChN, CeN               ) 
    5746      !!---------------------------------------------------------------------------------- 
    5847      !!                      ***  ROUTINE  turb_ncar  *** 
     
    6150      !!                fluxes according to Large & Yeager (2004) and Large & Yeager (2008) 
    6251      !!                If relevant (zt /= zu), adjust temperature and humidity from height zt to zu 
    63       !!                Returns the effective bulk wind speed at 10m to be used in the bulk formulas 
    64       !! 
     52      !!                Returns the effective bulk wind speed at zu to be used in the bulk formulas 
    6553      !! 
    6654      !! INPUT : 
     
    8270      !!    *  t_zu   : pot. air temperature adjusted at wind height zu       [K] 
    8371      !!    *  q_zu   : specific humidity of air        //                    [kg/kg] 
    84       !!    *  U_blk  : bulk wind speed at zu                                 [m/s] 
    85       !! 
     72      !!    *  Ubzu   : bulk wind speed at zu                                 [m/s] 
     73      !! 
     74      !! OPTIONAL OUTPUT: 
     75      !! ---------------- 
     76      !!    * CdN      : neutral-stability drag coefficient 
     77      !!    * ChN      : neutral-stability sensible heat coefficient 
     78      !!    * CeN      : neutral-stability evaporation coefficient 
    8679      !! 
    8780      !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) 
     
    9992      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   t_zu     ! pot. air temp. adjusted at zu               [K] 
    10093      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   q_zu     ! spec. humidity adjusted at zu           [kg/kg] 
    101       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   U_blk    ! bulk wind speed at zu                     [m/s] 
    102       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cdn, Chn, Cen ! neutral transfer coefficients 
    103       ! 
    104       INTEGER :: j_itt 
     94      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Ubzu    ! bulk wind speed at zu                     [m/s] 
     95      ! 
     96      INTEGER , INTENT(in   ), OPTIONAL                     :: nb_iter  ! number of iterations 
     97      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   CdN 
     98      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   ChN 
     99      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   CeN 
     100      ! 
     101      INTEGER :: nbit, jit                    ! iterations... 
    105102      LOGICAL :: l_zt_equal_zu = .FALSE.      ! if q and t are given at same height as U 
    106103      ! 
    107       REAL(wp), DIMENSION(jpi,jpj) ::   Cx_n10        ! 10m neutral latent/sensible coefficient 
    108       REAL(wp), DIMENSION(jpi,jpj) ::   sqrt_Cd_n10   ! root square of Cd_n10 
     104      REAL(wp), DIMENSION(jpi,jpj) ::   zCdN, zCeN, zChN        ! 10m neutral latent/sensible coefficient 
     105      REAL(wp), DIMENSION(jpi,jpj) ::   zsqrt_Cd, zsqrt_CdN   ! root square of Cd and Cd_neutral 
    109106      REAL(wp), DIMENSION(jpi,jpj) ::   zeta_u        ! stability parameter at height zu 
    110       REAL(wp), DIMENSION(jpi,jpj) ::   zpsi_h_u 
    111107      REAL(wp), DIMENSION(jpi,jpj) ::   ztmp0, ztmp1, ztmp2 
    112       REAL(wp), DIMENSION(jpi,jpj) ::   stab          ! stability test integer 
    113       !!---------------------------------------------------------------------------------- 
     108      !!---------------------------------------------------------------------------------- 
     109      nbit = nb_iter0 
     110      IF( PRESENT(nb_iter) ) nbit = nb_iter 
     111 
    114112      l_zt_equal_zu = ( ABS(zu - zt) < 0.01_wp ) ! testing "zu == zt" is risky with double precision 
    115113 
    116       U_blk = MAX( 0.5_wp , U_zu )   !  relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s 
     114      Ubzu = MAX( 0.5_wp , U_zu )   !  relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s 
    117115 
    118116      !! First guess of stability: 
    119117      ztmp0 = virt_temp(t_zt, q_zt) - virt_temp(sst, ssq) ! air-sea difference of virtual pot. temp. at zt 
    120       stab  = 0.5_wp + sign(0.5_wp,ztmp0)                           ! stab = 1 if dTv > 0  => STABLE, 0 if unstable 
     118      ztmp1 = 0.5_wp + SIGN(0.5_wp,ztmp0)                 ! ztmp1 = 1 if dTv > 0  => STABLE, 0 if unstable 
    121119 
    122120      !! Neutral coefficients at 10m: 
    123121      IF( ln_cdgw ) THEN      ! wave drag case 
    124122         cdn_wave(:,:) = cdn_wave(:,:) + rsmall * ( 1._wp - tmask(:,:,1) ) 
    125          ztmp0   (:,:) = cdn_wave(:,:) 
     123         zCdN   (:,:) = cdn_wave(:,:) 
    126124      ELSE 
    127       ztmp0 = cd_neutral_10m( U_blk ) 
     125      zCdN = cd_n10_ncar( Ubzu ) 
    128126      ENDIF 
    129127 
    130       sqrt_Cd_n10 = SQRT( ztmp0 ) 
     128      zsqrt_CdN = SQRT( zCdN ) 
    131129 
    132130      !! Initializing transf. coeff. with their first guess neutral equivalents : 
    133       Cd = ztmp0 
    134       Ce = 1.e-3_wp*( 34.6_wp * sqrt_Cd_n10 ) 
    135       Ch = 1.e-3_wp*sqrt_Cd_n10*(18._wp*stab + 32.7_wp*(1._wp - stab)) 
    136       stab = sqrt_Cd_n10   ! Temporaty array !!! stab == SQRT(Cd) 
    137   
     131      Cd = zCdN 
     132      Ce = ce_n10_ncar( zsqrt_CdN ) 
     133      Ch = ch_n10_ncar( zsqrt_CdN , ztmp1 )   ! ztmp1 is stability (1/0) 
     134      zsqrt_Cd = zsqrt_CdN 
     135 
    138136      IF( ln_cdgw ) THEN 
    139    Cen = Ce 
    140    Chn = Ch 
     137         zCeN = Ce 
     138         zChN = Ch 
    141139      ENDIF 
    142140 
    143       !! First guess of temperature and humidity at height zu: 
     141      !! Initializing values at z_u with z_t values: 
    144142      t_zu = MAX( t_zt ,  180._wp )   ! who knows what's given on masked-continental regions... 
    145143      q_zu = MAX( q_zt , 1.e-6_wp )   !               " 
    146144 
     145 
    147146      !! ITERATION BLOCK 
    148       DO j_itt = 1, nb_itt 
     147      DO jit = 1, nbit 
    149148         ! 
    150149         ztmp1 = t_zu - sst   ! Updating air/sea differences 
    151150         ztmp2 = q_zu - ssq 
    152151 
    153          ! Updating turbulent scales :   (L&Y 2004 eq. (7)) 
    154          ztmp0 = stab*U_blk       ! u*       (stab == SQRT(Cd)) 
    155          ztmp1 = Ch/stab*ztmp1    ! theta*   (stab == SQRT(Cd)) 
    156          ztmp2 = Ce/stab*ztmp2    ! q*       (stab == SQRT(Cd)) 
    157  
    158          ! Estimate the inverse of Monin-Obukov length (1/L) at height zu: 
     152         ! Updating turbulent scales :   (L&Y 2004 Eq. (7)) 
     153         ztmp0 = zsqrt_Cd*Ubzu       ! u* 
     154         ztmp1 = Ch/zsqrt_Cd*ztmp1    ! theta* 
     155         ztmp2 = Ce/zsqrt_Cd*ztmp2    ! q* 
     156 
     157         ! Estimate the inverse of Obukov length (1/L) at height zu: 
    159158         ztmp0 = One_on_L( t_zu, q_zu, ztmp0, ztmp1, ztmp2 ) 
    160           
     159 
    161160         !! Stability parameters : 
    162161         zeta_u   = zu*ztmp0 
    163          zeta_u = sign( min(abs(zeta_u),10._wp), zeta_u ) 
    164          zpsi_h_u = psi_h( zeta_u ) 
    165  
    166          !! Shifting temperature and humidity at zu (L&Y 2004 eq. (9b-9c)) 
     162         zeta_u   = sign( min(abs(zeta_u),10._wp), zeta_u ) 
     163 
     164         !! Shifting temperature and humidity at zu (L&Y 2004 Eq. (9b-9c)) 
    167165         IF( .NOT. l_zt_equal_zu ) THEN 
    168             !! Array 'stab' is free for the moment so using it to store 'zeta_t' 
    169             stab = zt*ztmp0 
    170             stab = SIGN( MIN(ABS(stab),10._wp), stab )  ! Temporaty array stab == zeta_t !!! 
    171             stab = LOG(zt/zu) + zpsi_h_u - psi_h(stab)                   ! stab just used as temp array again! 
    172             t_zu = t_zt - ztmp1/vkarmn*stab    ! ztmp1 is still theta*  L&Y 2004 eq.(9b) 
    173             q_zu = q_zt - ztmp2/vkarmn*stab    ! ztmp2 is still q*      L&Y 2004 eq.(9c) 
    174             q_zu = max(0._wp, q_zu) 
    175          ENDIF 
    176  
    177          ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)... 
     166            ztmp0 = zt*ztmp0 ! zeta_t ! 
     167            ztmp0 = SIGN( MIN(ABS(ztmp0),10._wp), ztmp0 )  ! Temporaty array ztmp0 == zeta_t !!! 
     168            ztmp0 = LOG(zt/zu) + psi_h_ncar(zeta_u) - psi_h_ncar(ztmp0)                   ! ztmp0 just used as temp array again! 
     169            t_zu = t_zt - ztmp1/vkarmn*ztmp0    ! ztmp1 is still theta*  L&Y 2004 Eq. (9b) 
     170            !! 
     171            q_zu = q_zt - ztmp2/vkarmn*ztmp0    ! ztmp2 is still q*      L&Y 2004 Eq. (9c) 
     172            q_zu = MAX(0._wp, q_zu) 
     173         END IF 
     174 
     175         ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 Eq. 9a)... 
    178176         !   In very rare low-wind conditions, the old way of estimating the 
    179177         !   neutral wind speed at 10m leads to a negative value that causes the code 
    180178         !   to crash. To prevent this a threshold of 0.25m/s is imposed. 
    181          ztmp2 = psi_m(zeta_u) 
     179         ztmp2 = psi_m_ncar(zeta_u) 
    182180         IF( ln_cdgw ) THEN      ! surface wave case 
    183             stab = vkarmn / ( vkarmn / sqrt_Cd_n10 - ztmp2 )  ! (stab == SQRT(Cd)) 
    184             Cd   = stab * stab 
    185             ztmp0 = (LOG(zu/10._wp) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 
    186             ztmp2 = stab / sqrt_Cd_n10   ! (stab == SQRT(Cd)) 
    187             ztmp1 = 1._wp + Chn * ztmp0      
    188             Ch    = Chn * ztmp2 / ztmp1  ! L&Y 2004 eq. (10b) 
    189             ztmp1 = 1._wp + Cen * ztmp0 
    190             Ce    = Cen * ztmp2 / ztmp1  ! L&Y 2004 eq. (10c) 
     181            zsqrt_Cd = vkarmn / ( vkarmn / zsqrt_CdN - ztmp2 ) 
     182            Cd   = zsqrt_Cd * zsqrt_Cd 
     183            ztmp0 = (LOG(zu/10._wp) - psi_h_ncar(zeta_u)) / vkarmn / zsqrt_CdN 
     184            ztmp2 = zsqrt_Cd / zsqrt_CdN 
     185            ztmp1 = 1._wp + zChN * ztmp0 
     186            Ch    = zChN * ztmp2 / ztmp1  ! L&Y 2004 eq. (10b) 
     187            ztmp1 = 1._wp + zCeN * ztmp0 
     188            Ce    = zCeN * ztmp2 / ztmp1  ! L&Y 2004 eq. (10c) 
    191189 
    192190         ELSE 
    193          ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)... 
    194          !   In very rare low-wind conditions, the old way of estimating the 
    195          !   neutral wind speed at 10m leads to a negative value that causes the code 
    196          !   to crash. To prevent this a threshold of 0.25m/s is imposed. 
    197          ztmp0 = MAX( 0.25_wp , U_blk/(1._wp + sqrt_Cd_n10/vkarmn*(LOG(zu/10._wp) - ztmp2)) ) ! U_n10 (ztmp2 == psi_m(zeta_u)) 
    198          ztmp0 = cd_neutral_10m(ztmp0)                                               ! Cd_n10 
    199          Cdn(:,:) = ztmp0 
    200          sqrt_Cd_n10 = sqrt(ztmp0) 
    201  
    202          stab    = 0.5_wp + sign(0.5_wp,zeta_u)                        ! update stability 
    203          Cx_n10  = 1.e-3_wp*sqrt_Cd_n10*(18._wp*stab + 32.7_wp*(1._wp - stab))  ! L&Y 2004 eq. (6c-6d)    (Cx_n10 == Ch_n10) 
    204          Chn(:,:) = Cx_n10 
     191         ztmp0 = MAX( 0.25_wp , UN10_from_CD(zu, Ubzu, Cd, ppsi=ztmp2) ) ! U_n10 (ztmp2 == psi_m_ncar(zeta_u)) 
     192 
     193         zCdN = cd_n10_ncar(ztmp0) 
     194         zsqrt_CdN = sqrt(zCdN) 
    205195 
    206196         !! Update of transfer coefficients: 
    207          ztmp1 = 1._wp + sqrt_Cd_n10/vkarmn*(LOG(zu/10._wp) - ztmp2)   ! L&Y 2004 eq. (10a) (ztmp2 == psi_m(zeta_u)) 
    208          Cd      = ztmp0 / ( ztmp1*ztmp1 ) 
    209          stab = SQRT( Cd ) ! Temporary array !!! (stab == SQRT(Cd)) 
    210  
    211          ztmp0 = (LOG(zu/10._wp) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 
    212          ztmp2 = stab / sqrt_Cd_n10   ! (stab == SQRT(Cd)) 
    213          ztmp1 = 1._wp + Cx_n10*ztmp0    ! (Cx_n10 == Ch_n10) 
    214          Ch  = Cx_n10*ztmp2 / ztmp1   ! L&Y 2004 eq. (10b) 
    215  
    216          Cx_n10  = 1.e-3_wp * (34.6_wp * sqrt_Cd_n10)  ! L&Y 2004 eq. (6b)    ! Cx_n10 == Ce_n10 
    217          Cen(:,:) = Cx_n10 
    218          ztmp1 = 1._wp + Cx_n10*ztmp0 
    219          Ce  = Cx_n10*ztmp2 / ztmp1  ! L&Y 2004 eq. (10c) 
     197 
     198         !! C_D 
     199         ztmp1  = 1._wp + zsqrt_CdN/vkarmn*(LOG(zu/10._wp) - ztmp2)   ! L&Y 2004 Eq. (10a) (ztmp2 == psi_m(zeta_u)) 
     200         Cd     = MAX( zCdN / ( ztmp1*ztmp1 ), Cx_min ) 
     201 
     202         !! C_H and C_E 
     203         zsqrt_Cd = SQRT( Cd ) 
     204         ztmp0 = ( LOG(zu/10._wp) - psi_h_ncar(zeta_u) ) / vkarmn / zsqrt_CdN 
     205         ztmp2 = zsqrt_Cd / zsqrt_CdN 
     206 
     207         ztmp1 = 0.5_wp + SIGN(0.5_wp,zeta_u)                                ! update stability 
     208         zChN  = 1.e-3_wp * zsqrt_CdN*(18._wp*ztmp1 + 32.7_wp*(1._wp - ztmp1))  ! L&Y 2004 eq. (6c-6d) 
     209         zCeN  = 1.e-3_wp * (34.6_wp * zsqrt_CdN)                             ! L&Y 2004 eq. (6b) 
     210 
     211         Ch    = MAX( zChN*ztmp2 / ( 1._wp + zChN*ztmp0 ) , Cx_min ) ! L&Y 2004 eq. (10b) 
     212         Ce    = MAX( zCeN*ztmp2 / ( 1._wp + zCeN*ztmp0 ) , Cx_min ) ! L&Y 2004 eq. (10c) 
     213 
    220214         ENDIF 
    221215 
    222       END DO !DO j_itt = 1, nb_itt 
     216      END DO !DO jit = 1, nbit 
     217 
     218      IF(PRESENT(CdN)) CdN(:,:) = zCdN(:,:) 
     219      IF(PRESENT(CeN)) CeN(:,:) = zCeN(:,:) 
     220      IF(PRESENT(ChN)) ChN(:,:) = zChN(:,:) 
    223221 
    224222   END SUBROUTINE turb_ncar 
    225223 
    226224 
    227    FUNCTION cd_neutral_10m( pw10 ) 
    228       !!----------------------------------------------------------------------------------       
     225   FUNCTION cd_n10_ncar( pw10 ) 
     226      !!---------------------------------------------------------------------------------- 
    229227      !! Estimate of the neutral drag coefficient at 10m as a function 
    230228      !! of neutral wind  speed at 10m 
    231229      !! 
    232       !! Origin: Large & Yeager 2008 eq.(11a) and eq.(11b) 
     230      !! Origin: Large & Yeager 2008, Eq. (11) 
    233231      !! 
    234232      !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    235233      !!---------------------------------------------------------------------------------- 
    236234      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pw10           ! scalar wind speed at 10m (m/s) 
    237       REAL(wp), DIMENSION(jpi,jpj)             :: cd_neutral_10m 
     235      REAL(wp), DIMENSION(jpi,jpj)             :: cd_n10_ncar 
    238236      ! 
    239237      INTEGER  ::     ji, jj     ! dummy loop indices 
     
    242240      ! 
    243241      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 
    244          ! 
    245          zw  = pw10(ji,jj) 
    246          zw6 = zw*zw*zw 
    247          zw6 = zw6*zw6 
    248          ! 
    249          ! When wind speed > 33 m/s => Cyclone conditions => special treatment 
    250          zgt33 = 0.5_wp + SIGN( 0.5_wp, (zw - 33._wp) )   ! If pw10 < 33. => 0, else => 1 
    251          ! 
    252          cd_neutral_10m(ji,jj) = 1.e-3_wp * ( & 
    253             &       (1._wp - zgt33)*( 2.7_wp/zw + 0.142_wp + zw/13.09_wp - 3.14807E-10_wp*zw6) & ! wind <  33 m/s 
    254             &      +    zgt33   *      2.34_wp )                                                 ! wind >= 33 m/s 
    255          ! 
    256          cd_neutral_10m(ji,jj) = MAX(cd_neutral_10m(ji,jj), 1.E-6_wp) 
    257          ! 
     242            ! 
     243            zw  = pw10(ji,jj) 
     244            zw6 = zw*zw*zw 
     245            zw6 = zw6*zw6 
     246            ! 
     247            ! When wind speed > 33 m/s => Cyclone conditions => special treatment 
     248            zgt33 = 0.5_wp + SIGN( 0.5_wp, (zw - 33._wp) )   ! If pw10 < 33. => 0, else => 1 
     249            ! 
     250            cd_n10_ncar(ji,jj) = 1.e-3_wp * ( & 
     251               &       (1._wp - zgt33)*( 2.7_wp/zw + 0.142_wp + zw/13.09_wp - 3.14807E-10_wp*zw6) & ! wind <  33 m/s 
     252               &      +    zgt33   *      2.34_wp )                                                 ! wind >= 33 m/s 
     253            ! 
     254            cd_n10_ncar(ji,jj) = MAX( cd_n10_ncar(ji,jj), Cx_min ) 
     255            ! 
    258256      END_2D 
    259257      ! 
    260    END FUNCTION cd_neutral_10m 
    261  
    262  
    263    FUNCTION psi_m( pzeta ) 
     258   END FUNCTION cd_n10_ncar 
     259 
     260 
     261   FUNCTION ch_n10_ncar( psqrtcdn10 , pstab ) 
     262      !!---------------------------------------------------------------------------------- 
     263      !! Estimate of the neutral heat transfer coefficient at 10m      !! 
     264      !! Origin: Large & Yeager 2008, Eq. (9) and (12) 
     265 
     266      !!---------------------------------------------------------------------------------- 
     267      REAL(wp), DIMENSION(jpi,jpj)             :: ch_n10_ncar 
     268      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psqrtcdn10 ! sqrt( CdN10 ) 
     269      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pstab      ! stable ABL => 1 / unstable ABL => 0 
     270      !!---------------------------------------------------------------------------------- 
     271      IF( ANY(pstab < -0.00001) .OR. ANY(pstab >  1.00001) ) THEN 
     272         PRINT *, 'ERROR: ch_n10_ncar@mod_blk_ncar.f90: pstab =' 
     273         PRINT *, pstab 
     274         STOP 
     275      END IF 
     276      ! 
     277      ch_n10_ncar = MAX( 1.e-3_wp * psqrtcdn10*( 18._wp*pstab + 32.7_wp*(1._wp - pstab) )  , Cx_min )   ! Eq. (9) & (12) Large & Yeager, 2008 
     278      ! 
     279   END FUNCTION ch_n10_ncar 
     280 
     281   FUNCTION ce_n10_ncar( psqrtcdn10 ) 
     282      !!---------------------------------------------------------------------------------- 
     283      !! Estimate of the neutral heat transfer coefficient at 10m      !! 
     284      !! Origin: Large & Yeager 2008, Eq. (9) and (13) 
     285      !!---------------------------------------------------------------------------------- 
     286      REAL(wp), DIMENSION(jpi,jpj)             :: ce_n10_ncar 
     287      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psqrtcdn10 ! sqrt( CdN10 ) 
     288      !!---------------------------------------------------------------------------------- 
     289      ce_n10_ncar = MAX( 1.e-3_wp * ( 34.6_wp * psqrtcdn10 ) , Cx_min ) 
     290      ! 
     291   END FUNCTION ce_n10_ncar 
     292 
     293 
     294   FUNCTION psi_m_ncar( pzeta ) 
    264295      !!---------------------------------------------------------------------------------- 
    265296      !! Universal profile stability function for momentum 
    266       !!    !! Psis, L&Y 2004 eq. (8c), (8d), (8e) 
     297      !!    !! Psis, L&Y 2004, Eq. (8c), (8d), (8e) 
    267298      !! 
    268299      !! pzeta : stability paramenter, z/L where z is altitude measurement 
     
    271302      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    272303      !!---------------------------------------------------------------------------------- 
    273       REAL(wp), DIMENSION(jpi,jpj) :: psi_m 
     304      REAL(wp), DIMENSION(jpi,jpj) :: psi_m_ncar 
    274305      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta 
    275306      ! 
    276307      INTEGER  ::   ji, jj    ! dummy loop indices 
    277       REAL(wp) :: zx2, zx, zstab   ! local scalars 
     308      REAL(wp) :: zta, zx2, zx, zpsi_unst, zpsi_stab, zstab   ! local scalars 
    278309      !!---------------------------------------------------------------------------------- 
    279310      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 
    280          zx2 = SQRT( ABS( 1._wp - 16._wp*pzeta(ji,jj) ) ) 
    281          zx2 = MAX( zx2 , 1._wp ) 
    282          zx  = SQRT( zx2 ) 
    283          zstab = 0.5_wp + SIGN( 0.5_wp , pzeta(ji,jj) ) 
    284          ! 
    285          psi_m(ji,jj) =        zstab  * (-5._wp*pzeta(ji,jj))       &          ! Stable 
    286             &          + (1._wp - zstab) * (2._wp*LOG((1._wp + zx)*0.5_wp)   &          ! Unstable 
    287             &               + LOG((1._wp + zx2)*0.5_wp) - 2._wp*ATAN(zx) + rpi*0.5_wp)  !    " 
    288          ! 
     311            zta = pzeta(ji,jj) 
     312            ! 
     313            zx2 = SQRT( ABS(1._wp - 16._wp*zta) )  ! (1 - 16z)^0.5 
     314            zx2 = MAX( zx2 , 1._wp ) 
     315            zx  = SQRT(zx2)                          ! (1 - 16z)^0.25 
     316            zpsi_unst = 2._wp*LOG( (1._wp + zx )*0.5_wp )   & 
     317               &            + LOG( (1._wp + zx2)*0.5_wp )   & 
     318               &          - 2._wp*ATAN(zx) + rpi*0.5_wp 
     319            ! 
     320            zpsi_stab = -5._wp*zta 
     321            ! 
     322            zstab = 0.5_wp + SIGN(0.5_wp, zta) ! zta > 0 => zstab = 1 
     323            ! 
     324            psi_m_ncar(ji,jj) =          zstab  * zpsi_stab &  ! (zta > 0) Stable 
     325               &              + (1._wp - zstab) * zpsi_unst    ! (zta < 0) Unstable 
     326            ! 
     327            ! 
    289328      END_2D 
    290    END FUNCTION psi_m 
    291  
    292  
    293    FUNCTION psi_h( pzeta ) 
     329   END FUNCTION psi_m_ncar 
     330 
     331 
     332   FUNCTION psi_h_ncar( pzeta ) 
    294333      !!---------------------------------------------------------------------------------- 
    295334      !! Universal profile stability function for temperature and humidity 
    296       !!    !! Psis, L&Y 2004 eq. (8c), (8d), (8e) 
     335      !!    !! Psis, L&Y 2004, Eq. (8c), (8d), (8e) 
    297336      !! 
    298337      !! pzeta : stability paramenter, z/L where z is altitude measurement 
     
    301340      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    302341      !!---------------------------------------------------------------------------------- 
    303       REAL(wp), DIMENSION(jpi,jpj) :: psi_h 
     342      REAL(wp), DIMENSION(jpi,jpj) :: psi_h_ncar 
    304343      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta 
    305344      ! 
    306345      INTEGER  ::   ji, jj     ! dummy loop indices 
    307       REAL(wp) :: zx2, zstab  ! local scalars 
     346      REAL(wp) :: zta, zx2, zpsi_unst, zpsi_stab, zstab  ! local scalars 
    308347      !!---------------------------------------------------------------------------------- 
    309348      ! 
    310349      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 
    311          zx2 = SQRT( ABS( 1._wp - 16._wp*pzeta(ji,jj) ) ) 
    312          zx2 = MAX( zx2 , 1._wp ) 
    313          zstab = 0.5_wp + SIGN( 0.5_wp , pzeta(ji,jj) ) 
    314          ! 
    315          psi_h(ji,jj) =         zstab  * (-5._wp*pzeta(ji,jj))        &  ! Stable 
    316             &           + (1._wp - zstab) * (2._wp*LOG( (1._wp + zx2)*0.5_wp ))   ! Unstable 
    317          ! 
     350            ! 
     351            zta = pzeta(ji,jj) 
     352            ! 
     353            zx2 = SQRT( ABS(1._wp - 16._wp*zta) )  ! (1 -16z)^0.5 
     354            zx2 = MAX( zx2 , 1._wp ) 
     355            zpsi_unst = 2._wp*LOG( 0.5_wp*(1._wp + zx2) ) 
     356            ! 
     357            zpsi_stab = -5._wp*zta 
     358            ! 
     359            zstab = 0.5_wp + SIGN(0.5_wp, zta) ! zta > 0 => zstab = 1 
     360            ! 
     361            psi_h_ncar(ji,jj) =          zstab  * zpsi_stab &  ! (zta > 0) Stable 
     362               &              + (1._wp - zstab) * zpsi_unst    ! (zta < 0) Unstable 
     363            ! 
    318364      END_2D 
    319    END FUNCTION psi_h 
     365   END FUNCTION psi_h_ncar 
    320366 
    321367   !!====================================================================== 
Note: See TracChangeset for help on using the changeset viewer.