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 11785 for NEMO/branches/2019/dev_r11085_ASINTER-05_Brodeau_Advanced_Bulk/src/OCE/SBC/sbcblk_algo_coare3p0.F90 – NEMO

Ignore:
Timestamp:
2019-10-24T12:38:43+02:00 (5 years ago)
Author:
laurent
Message:

Fixes to prevent FPE-related errors at runtime (masked regions).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • NEMO/branches/2019/dev_r11085_ASINTER-05_Brodeau_Advanced_Bulk/src/OCE/SBC/sbcblk_algo_coare3p0.F90

    r11772 r11785  
    4545   PUBLIC :: COARE3P0_INIT, TURB_COARE3P0 
    4646 
    47    !                                              !! COARE own values for given constants: 
    48    REAL(wp), PARAMETER ::   zi0     = 600._wp     ! scale height of the atmospheric boundary layer... 
    49    REAL(wp), PARAMETER ::   Beta0   =   1.25_wp   ! gustiness parameter 
     47   !! COARE own values for given constants: 
     48   REAL(wp), PARAMETER :: zi0   = 600._wp     ! scale height of the atmospheric boundary layer... 
     49   REAL(wp), PARAMETER :: Beta0 =  1.25_wp    ! gustiness parameter 
    5050 
    5151   INTEGER , PARAMETER ::   nb_itt = 10             ! number of itterations 
     
    7171         ierr = 0 
    7272         ALLOCATE ( Tau_ac(jpi,jpj) , Qnt_ac(jpi,jpj), Hz_wl(jpi,jpj), dT_wl(jpi,jpj), STAT=ierr ) 
    73          !IF( ierr > 0 ) STOP ' COARE3P0_INIT => allocation of Tau_ac and Qnt_ac failed!' 
     73         !IF( ierr > 0 ) STOP ' COARE3P0_INIT => allocation of Tau_ac, Qnt_ac, dT_wl & Hz_wl failed!' 
    7474         Tau_ac(:,:) = 0._wp 
    7575         Qnt_ac(:,:) = 0._wp 
     76         dT_wl(:,:)  = 0._wp 
    7677         Hz_wl(:,:)  = Hwl_max 
    77          dT_wl(:,:)  = 0._wp 
    7878      END IF 
    7979      !! 
     
    8181         ierr = 0 
    8282         ALLOCATE ( dT_cs(jpi,jpj), STAT=ierr ) 
    83          !IF( ierr > 0 ) STOP ' COARE3P0_INIT => allocation of dT_cs and Qnt_ac failed!' 
     83         !IF( ierr > 0 ) STOP ' COARE3P0_INIT => allocation of dT_cs failed!' 
    8484         dT_cs(:,:) = -0.25_wp  ! First guess of skin correction 
    8585      END IF 
     
    132132      !!    *  rad_lw : downwelling longwave radiation at the surface  (>0)   [W/m^2] 
    133133      !!    *  slp    : sea-level pressure                                    [Pa] 
     134      !! 
     135      !! OPTIONAL OUTPUT: 
     136      !! ---------------- 
    134137      !!    * pdT_cs  : SST increment "dT" for cool-skin correction           [K] 
    135138      !!    * pdT_wl  : SST increment "dT" for warm-layer correction          [K] 
     
    170173      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   slp      !             [Pa] 
    171174      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pdT_cs 
    172       ! 
    173175      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pdT_wl   !             [K] 
    174176      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pHz_wl   !             [m] 
     
    193195      CHARACTER(len=40), PARAMETER :: crtnm = 'turb_coare3p0@sbcblk_algo_coare3p0' 
    194196      !!---------------------------------------------------------------------------------- 
    195  
    196197      IF ( kt == nit000 ) CALL COARE3P0_INIT(l_use_cs, l_use_wl) 
    197198 
     
    208209 
    209210      IF ( l_use_wl ) THEN 
    210          IF(.NOT.(PRESENT(Qsw) .AND. PRESENT(rad_lw) .AND. PRESENT(slp) )) THEN 
     211         IF( .NOT.(PRESENT(Qsw) .AND. PRESENT(rad_lw) .AND. PRESENT(slp)) ) THEN 
    211212            PRINT *, ' * PROBLEM ('//TRIM(crtnm)//'): you need to provide Qsw, rad_lw & slp to use warm-layer param!'; STOP 
    212213         END IF 
     
    217218         zsst = T_s ! backing up the bulk SST 
    218219         IF( l_use_cs ) T_s = T_s - 0.25_wp   ! First guess of correction 
    219          q_s    = rdct_qsat_salt*q_sat(MAX(T_s, 200._wp), slp) ! First guess of q_s !LOLO WL too!!! 
     220         q_s    = rdct_qsat_salt*q_sat(MAX(T_s, 200._wp), slp) ! First guess of q_s 
    220221      END IF 
    221222 
     
    238239 
    239240      z0     = alfa_charn_3p0(U_zu)*u_star*u_star/grav + 0.11_wp*znu_a/u_star 
    240       z0     = MIN(ABS(z0), 0.001_wp)  ! (prevent FPE from stupid values from masked region later on...) !#LOLO 
     241      z0     = MIN( MAX(ABS(z0), 1.E-9) , 1._wp )                      ! (prevents FPE from stupid values from masked region later on) 
     242 
    241243      z0t    = 1._wp / ( 0.1_wp*EXP(vkarmn/(0.00115/(vkarmn/ztmp1))) ) 
    242       z0t    = MIN(ABS(z0t), 0.001_wp)  ! (prevent FPE from stupid values from masked region later on...) !#LOLO 
     244      z0t    = MIN( MAX(ABS(z0t), 1.E-9) , 1._wp )                      ! (prevents FPE from stupid values from masked region later on) 
    243245 
    244246      Cd     = (vkarmn/ztmp0)**2    ! first guess of Cd 
     
    258260      ztmp0  = vkarmn/(LOG(zu/z0t) - psi_h_coare(zeta_u)) 
    259261 
    260       u_star = U_blk*vkarmn/(LOG(zu) - LOG(z0)  - psi_m_coare(zeta_u)) 
     262      u_star = MAX ( U_blk*vkarmn/(LOG(zu) - LOG(z0)  - psi_m_coare(zeta_u)) , 1.E-9 )  !  (MAX => prevents FPE from stupid values from masked region later on) 
    261263      t_star = dt_zu*ztmp0 
    262264      q_star = dq_zu*ztmp0 
     
    281283         !!Inverse of Monin-Obukov length (1/L) : 
    282284         ztmp0 = One_on_L(t_zu, q_zu, u_star, t_star, q_star)  ! 1/L == 1/[Monin-Obukhov length] 
    283          ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! (prevents FPE from stupid values from masked region later on...) !#LOLO 
     285         ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! (prevents FPE from stupid values from masked region later on...) 
    284286 
    285287         ztmp1 = u_star*u_star   ! u*^2 
     
    305307         ztmp2 = u_star/vkarmn*LOG(10./z0)                                 ! Neutral wind speed at 10m 
    306308         z0    = alfa_charn_3p0(ztmp2)*ztmp1/grav + 0.11_wp*znu_a/u_star   ! Roughness length (eq.6) 
     309         z0     = MIN( MAX(ABS(z0), 1.E-9) , 1._wp )                      ! (prevents FPE from stupid values from masked region later on) 
     310 
    307311         ztmp1 = ( znu_a / (z0*u_star) )**0.6_wp    ! (1./Re_r)^0.72 (Re_r: roughness Reynolds number) COARE3.6-specific! 
    308312         z0t   = MIN( 1.1E-4_wp , 5.5E-5_wp*ztmp1 ) ! Scalar roughness for both theta and q (eq.28) #LOLO: some use 1.15 not 1.1 !!! 
     313         z0t   = MIN( MAX(ABS(z0t), 1.E-9) , 1._wp )                      ! (prevents FPE from stupid values from masked region later on) 
    309314 
    310315         !! Turbulent scales at zu : 
    311316         ztmp0   = psi_h_coare(zeta_u) 
    312          ztmp1   = vkarmn/(LOG(zu) - LOG(z0t) - ztmp0) ! #LOLO: in ztmp0, some use psi_h_coare(zeta_t) rather than psi_h_coare(zeta_t) ??? 
     317         ztmp1   = vkarmn/(LOG(zu) - LOG(z0t) - ztmp0) ! #LB: in ztmp0, some use psi_h_coare(zeta_t) rather than psi_h_coare(zeta_t) ??? 
    313318 
    314319         t_star = dt_zu*ztmp1 
    315320         q_star = dq_zu*ztmp1 
    316          u_star = U_blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) 
     321         u_star = MAX( U_blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 )  !  (MAX => prevents FPE from stupid values from masked region later on) 
    317322 
    318323         IF( .NOT. l_zt_equal_zu ) THEN 
Note: See TracChangeset for help on using the changeset viewer.