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 8486 for branches/2017/dev_r8183_ICEMODEL/NEMOGCM/NEMO/LIM_SRC_3/icevar.F90 – NEMO

Ignore:
Timestamp:
2017-09-01T15:49:35+02:00 (7 years ago)
Author:
clem
Message:

changes in style - part1 - (now the code looks better txs to Gurvan's comments)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2017/dev_r8183_ICEMODEL/NEMOGCM/NEMO/LIM_SRC_3/icevar.F90

    r8426 r8486  
    3131   !! History :   -   ! 2006-01 (M. Vancoppenolle) Original code 
    3232   !!            3.4  ! 2011-02 (G. Madec) dynamical allocation 
     33   !!            3.5  ! 2012    (M. Vancoppenolle)  add ice_var_itd 
     34   !!            3.6  ! 2014-01 (C. Rousset) add ice_var_zapsmall, rewrite ice_var_itd 
    3335   !!---------------------------------------------------------------------- 
    3436#if defined key_lim3 
    3537   !!---------------------------------------------------------------------- 
    3638   !!   'key_lim3'                                      LIM3 sea-ice model 
     39   !!---------------------------------------------------------------------- 
     40   !!   ice_var_agg       : integrate variables over layers and categories 
     41   !!   ice_var_glo2eqv   : transform from VGLO to VEQV 
     42   !!   ice_var_eqv2glo   : transform from VEQV to VGLO 
     43   !!   ice_var_salprof   : salinity profile in the ice 
     44   !!   ice_var_bv        : brine volume 
     45   !!   ice_var_salprof1d : salinity profile in the ice 1D 
     46   !!   ice_var_zapsmall  : remove very small area and volume 
     47   !!   ice_var_itd       : convert 1-cat to multiple cat 
    3748   !!---------------------------------------------------------------------- 
    3849   USE par_oce        ! ocean parameters 
     
    5970 
    6071   !!---------------------------------------------------------------------- 
    61    !! NEMO/LIM3 3.5 , UCL - NEMO Consortium (2011) 
     72   !! NEMO/ICE 4.0 , NEMO Consortium (2017) 
    6273   !! $Id: icevar.F90 8422 2017-08-08 13:58:05Z clem $ 
    6374   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt) 
     
    6980      !!                ***  ROUTINE ice_var_agg  *** 
    7081      !! 
    71       !! ** Purpose :   aggregates ice-thickness-category variables to all-ice variables 
    72       !!              i.e. it turns VGLO into VAGG 
    73       !! ** Method  : 
    74       !! 
    75       !! ** Arguments : n = 1, at_i vt_i only 
    76       !!                n = 2 everything 
    77       !! 
    78       !! note : you could add an argument when you need only at_i, vt_i 
    79       !!        and when you need everything 
    80       !!------------------------------------------------------------------ 
    81       INTEGER, INTENT( in ) ::   kn     ! =1 at_i & vt only ; = what is needed 
    82       ! 
    83       INTEGER  ::   ji, jj, jk, jl   ! dummy loop indices 
    84       !!------------------------------------------------------------------ 
    85  
    86       ! integrated values 
    87       vt_i (:,:) = SUM( v_i, dim=3 ) 
    88       vt_s (:,:) = SUM( v_s, dim=3 ) 
    89       at_i (:,:) = SUM( a_i, dim=3 ) 
     82      !! ** Purpose :   aggregates ice-thickness-category variables to  
     83      !!              all-ice variables, i.e. it turns VGLO into VAGG 
     84      !!------------------------------------------------------------------ 
     85      INTEGER, INTENT( in ) ::   kn     ! =1 state variables only 
     86      !                                 ! >1 state variables + others 
     87      ! 
     88      INTEGER ::   ji, jj, jk, jl   ! dummy loop indices 
     89      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   z1_at_i, z1_vt_i 
     90      !!------------------------------------------------------------------ 
     91      ! 
     92      !                                      ! integrated values 
     93      vt_i(:,:) =       SUM( v_i(:,:,:)           , dim=3 ) 
     94      vt_s(:,:) =       SUM( v_s(:,:,:)           , dim=3 ) 
     95      at_i(:,:) =       SUM( a_i(:,:,:)           , dim=3 ) 
    9096      et_s(:,:)  = SUM( SUM( e_s(:,:,:,:), dim=4 ), dim=3 ) 
    9197      et_i(:,:)  = SUM( SUM( e_i(:,:,:,:), dim=4 ), dim=3 ) 
    9298 
    9399      ! MV MP 2016 
    94       IF ( ln_pnd ) THEN 
    95          at_ip(:,:) = SUM( a_ip, dim=3 ) 
    96          vt_ip(:,:) = SUM( v_ip, dim=3 ) 
     100      IF ( ln_pnd ) THEN                     ! Melt pond 
     101         at_ip(:,:) = SUM( a_ip(:,:,:), dim=3 ) 
     102         vt_ip(:,:) = SUM( v_ip(:,:,:), dim=3 ) 
    97103      ENDIF 
    98104      ! END MP 2016 
    99105 
    100       ! open water fraction 
    101       DO jj = 1, jpj 
     106      DO jj = 1, jpj                         ! open water fraction 
    102107         DO ji = 1, jpi 
    103108            ato_i(ji,jj) = MAX( 1._wp - at_i(ji,jj), 0._wp )    
    104109         END DO 
    105110      END DO 
     111!!gm I think this should do the work : 
     112!      ato_i(:,:) = MAX( 1._wp - at_i(:,:), 0._wp )   
     113!!gm end 
    106114 
    107115      IF( kn > 1 ) THEN 
    108  
    109          ! mean ice/snow thickness 
    110          DO jj = 1, jpj 
    111             DO ji = 1, jpi 
    112                rswitch      = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi10 ) )  
    113                htm_i(ji,jj) = vt_i(ji,jj) / MAX( at_i(ji,jj) , epsi10 ) * rswitch 
    114                htm_s(ji,jj) = vt_s(ji,jj) / MAX( at_i(ji,jj) , epsi10 ) * rswitch 
    115             ENDDO 
    116          ENDDO 
    117  
    118          ! mean temperature (K), salinity and age 
    119          smt_i(:,:) = 0._wp 
    120          tm_i(:,:)  = 0._wp 
    121          tm_su(:,:) = 0._wp 
    122          tm_si(:,:) = 0._wp 
    123          om_i (:,:) = 0._wp 
    124          DO jl = 1, jpl 
    125              
    126             DO jj = 1, jpj 
    127                DO ji = 1, jpi 
    128                   rswitch      = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) 
    129                   tm_su(ji,jj) = tm_su(ji,jj) + rswitch * ( t_su(ji,jj,jl) - rt0 ) * a_i(ji,jj,jl) / MAX( at_i(ji,jj) , epsi10 ) 
    130                   tm_si(ji,jj) = tm_si(ji,jj) + rswitch * ( t_si(ji,jj,jl) - rt0 ) * a_i(ji,jj,jl) / MAX( at_i(ji,jj) , epsi10 ) 
    131                   om_i (ji,jj) = om_i (ji,jj) + rswitch *   oa_i(ji,jj,jl)                         / MAX( at_i(ji,jj) , epsi06 ) 
    132                END DO 
    133             END DO 
    134              
    135             DO jk = 1, nlay_i 
    136                DO jj = 1, jpj 
    137                   DO ji = 1, jpi 
    138                      rswitch = MAX( 0._wp , SIGN( 1._wp , vt_i(ji,jj) - epsi10 ) ) 
    139                      tm_i(ji,jj)  = tm_i(ji,jj)  + r1_nlay_i * rswitch * ( t_i(ji,jj,jk,jl) - rt0 ) * v_i(ji,jj,jl)  & 
    140                         &            / MAX( vt_i(ji,jj) , epsi10 ) 
    141                      smt_i(ji,jj) = smt_i(ji,jj) + r1_nlay_i * rswitch * s_i(ji,jj,jk,jl) * v_i(ji,jj,jl)  & 
    142                         &            / MAX( vt_i(ji,jj) , epsi10 ) 
    143                   END DO 
    144                END DO 
    145             END DO 
    146          END DO 
    147          tm_i  = tm_i  + rt0 
    148          tm_su = tm_su + rt0 
    149          tm_si = tm_si + rt0 
    150          ! 
     116         ! 
     117         ALLOCATE( z1_at_i(jpi,jpj) , z1_vt_i(jpi,jpj) ) 
     118         WHERE( at_i(:,:) > epsi10 )   ;   z1_at_i(:,:) = 1._wp / at_i(:,:) 
     119         ELSEWHERE                     ;   z1_at_i(:,:) = 0._wp 
     120         END WHERE 
     121         WHERE( vt_i(:,:) > epsi10 )   ;   z1_vt_i(:,:) = 1._wp / vt_i(:,:) 
     122         ELSEWHERE                     ;   z1_vt_i(:,:) = 0._wp 
     123         END WHERE 
     124         ! 
     125         !                          ! mean ice/snow thickness 
     126         htm_i(:,:) = vt_i(:,:) * z1_at_i(:,:) 
     127         htm_s(:,:) = vt_s(:,:) * z1_at_i(:,:) 
     128         !          
     129         !                          ! mean temperature (K), salinity and age 
     130         tm_su(:,:) = SUM( t_su(:,:,:) * a_i(:,:,:) , dim=3 ) * z1_at_i(ji,jj) 
     131         tm_si(:,:) = SUM( t_si(:,:,:) * a_i(:,:,:) , dim=3 ) * z1_at_i(ji,jj) 
     132         om_i (:,:) = SUM( oa_i(:,:,:)              , dim=3 ) * z1_at_i(ji,jj) 
     133         ! 
     134         tm_i (:,:) = r1_nlay_i * SUM( SUM( t_i(:,:,:,:) * v_i(:,:,:), dim=4 ) , dim=3 ) * z1_vt_i(:,:) 
     135         smt_i(:,:) = r1_nlay_i * SUM( SUM( s_i(:,:,:,:) * v_i(:,:,:), dim=4 ) , dim=3 ) * z1_vt_i(:,:) 
     136! 
     137!!gm  QUESTION 1 : why salinity is named smt_i  and not just sm_i ?   since the 4D field is named s_i. (NB for temp: tm_i, t_i) 
     138         ! 
     139         DEALLOCATE( z1_at_i , z1_vt_i ) 
    151140      ENDIF 
    152141      ! 
     
    158147      !!                ***  ROUTINE ice_var_glo2eqv *** 
    159148      !! 
    160       !! ** Purpose :   computes equivalent variables as function of global variables  
    161       !!              i.e. it turns VGLO into VEQV 
     149      !! ** Purpose :   computes equivalent variables as function of  
     150      !!              global variables, i.e. it turns VGLO into VEQV 
    162151      !!------------------------------------------------------------------ 
    163152      INTEGER  ::   ji, jj, jk, jl   ! dummy loop indices 
    164       REAL(wp) ::   ze_i, zaaa, zbbb, zccc, zdiscrim     ! local scalars 
    165       REAL(wp) ::   ztmelts, ze_s, zfac1, zfac2   !   -      - 
    166       !!------------------------------------------------------------------ 
     153      REAL(wp) ::   ze_i, z1_CpR, zdiscrim, zaaa, z1_2aaa             ! local scalars 
     154      REAL(wp) ::   ze_s, zL_Cp , ztmelts , zbbb, zccc                !   -      - 
     155      REAL(wp) ::   zhmax, z1_zhmax, zsm_i, zcpMcpic, zt_i   !   -      - 
     156      REAL(wp) ::   zlay_i, zlay_s   !   -      - 
     157      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z1_a_i, z1_v_i 
     158      !!------------------------------------------------------------------ 
     159 
     160!!gm Question 1:  here use epsi20 , in ice_var_agg it is epsi10 which is used...  why ?? 
     161 
     162!!gm Question 2:  It is possible to define existence of sea-ice in a common way between  
     163!!                ice area and ice volume ? 
     164!!                the idea is to be able to define one for all at the begining of this routine 
     165!!                a criteria for icy area (i.e. a_i > epsi20 and v_i > epsi20 ) 
    167166 
    168167      !------------------------------------------------------- 
    169168      ! Ice thickness, snow thickness, ice salinity, ice age 
    170169      !------------------------------------------------------- 
    171       DO jl = 1, jpl 
    172          DO jj = 1, jpj 
    173             DO ji = 1, jpi 
    174                rswitch = MAX( 0._wp , SIGN( 1._wp, a_i(ji,jj,jl) - epsi20 ) )   !0 if no ice and 1 if yes 
    175                ht_i(ji,jj,jl) = v_i (ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch 
    176             END DO 
    177          END DO 
    178       END DO 
    179       ! Force the upper limit of ht_i to always be < hi_max (99 m). 
    180       DO jj = 1, jpj 
    181          DO ji = 1, jpi 
    182             rswitch = MAX( 0._wp , SIGN( 1._wp, ht_i(ji,jj,jpl) - epsi20 ) ) 
    183             ht_i(ji,jj,jpl) = MIN( ht_i(ji,jj,jpl) , hi_max(jpl) ) 
    184             a_i (ji,jj,jpl) = v_i(ji,jj,jpl) / MAX( ht_i(ji,jj,jpl) , epsi20 ) * rswitch 
    185          END DO 
    186       END DO 
    187  
    188       DO jl = 1, jpl 
    189          DO jj = 1, jpj 
    190             DO ji = 1, jpi 
    191                rswitch = MAX( 0._wp , SIGN( 1._wp, a_i(ji,jj,jl) - epsi20 ) )   !0 if no ice and 1 if yes 
    192                ht_s(ji,jj,jl) = v_s (ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch 
    193                o_i(ji,jj,jl)  = oa_i(ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch 
    194             END DO 
    195          END DO 
    196       END DO 
     170      !                                            !--- inverse of the ice area 
     171      WHERE( a_i(:,:,:) > epsi20 )   ;   z1_a_i(:,:,:) = 1._wp / a_i(:,:,:) 
     172      ELSEWHERE                      ;   z1_a_i(:,:,:) = 0._wp 
     173      END WHERE 
     174      ! 
     175      ht_i(:,:,:) = v_i (:,:,:) * z1_a_i(:,:,:)    !--- ice thickness 
     176 
     177     zhmax    =          hi_max(jpl) 
     178      z1_zhmax =  1._wp / hi_max(jpl)                
     179      WHERE( ht_i(:,:,jpl) > zhmax )               !--- bound ht_i by hi_max (i.e. 99 m) with associated update of ice area 
     180         ht_i  (:,:,jpl) = zhmax 
     181         a_i   (:,:,jpl) = v_i(:,:,jpl) * z1_zhmax  
     182         z1_a_i(:,:,jpl) = zhmax / v_i(:,:,jpl)          ! NB: v_i always /=0 as ht_i > hi_max 
     183      END WHERE 
     184 
     185      ht_s(:,:,:) = v_s (:,:,:) * z1_a_i(:,:,:)    !--- snow thickness 
    197186       
    198       IF(  nn_icesal == 2  )THEN 
    199          DO jl = 1, jpl 
    200             DO jj = 1, jpj 
    201                DO ji = 1, jpi 
    202                   rswitch = MAX( 0._wp , SIGN( 1._wp, v_i(ji,jj,jl) - epsi20 ) )   !0 if no ice and 1 if yes 
    203                   sm_i(ji,jj,jl) = smv_i(ji,jj,jl) / MAX( v_i(ji,jj,jl) , epsi20 ) * rswitch 
    204                   !                                      ! bounding salinity 
    205                   sm_i(ji,jj,jl) = MAX( sm_i(ji,jj,jl), rn_simin ) 
    206                END DO 
    207             END DO 
    208          END DO 
     187      o_i(:,:,:)  = oa_i(:,:,:) * z1_a_i(:,:,:)    !--- ice age 
     188 
     189      IF( nn_icesal == 2 )THEN                     !--- salinity (with a minimum value imposed everywhere) 
     190         WHERE( v_i(:,:,:) > epsi20 )   ;   sm_i(:,:,:) = MAX( rn_simin , smv_i(:,:,:) / v_i(:,:,:) ) 
     191         ELSEWHERE                      ;   sm_i(:,:,:) = rn_simin 
     192         END WHERE 
    209193      ENDIF 
    210194 
     
    212196 
    213197      !------------------- 
    214       ! Ice temperatures 
     198      ! Ice temperature   [K]   (with a minimum value (rt0 - 100.) imposed everywhere) 
    215199      !------------------- 
     200      zlay_i   = REAL( nlay_i , wp )    ! number of layers 
     201      zaaa     = cpic                   ! Conversion q(S,T) -> T (second order equation) 
     202      z1_2aaa  = 1._wp / 2._wp *zaaa 
     203      zcpMcpic = rcp - cpic 
    216204      DO jl = 1, jpl 
    217205         DO jk = 1, nlay_i 
    218206            DO jj = 1, jpj 
    219207               DO ji = 1, jpi 
    220                   !                                                              ! Energy of melting e(S,T) [J.m-3] 
    221                   rswitch = MAX( 0.0 , SIGN( 1.0 , v_i(ji,jj,jl) - epsi20 ) )     ! rswitch = 0 if no ice and 1 if yes 
    222                   ze_i    = rswitch * e_i(ji,jj,jk,jl) / MAX( v_i(ji,jj,jl) , epsi20 ) * REAL(nlay_i,wp)  
    223                   ztmelts = -tmut * s_i(ji,jj,jk,jl) + rt0              ! Ice layer melt temperature 
    224                   ! 
    225                   zaaa       =  cpic                  ! Conversion q(S,T) -> T (second order equation) 
    226                   zbbb       =  ( rcp - cpic ) * ( ztmelts - rt0 ) + ze_i * r1_rhoic - lfus 
    227                   zccc       =  lfus * (ztmelts-rt0) 
    228                   zdiscrim   =  SQRT( MAX(zbbb*zbbb - 4._wp*zaaa*zccc , 0._wp) ) 
    229                   t_i(ji,jj,jk,jl) = rt0 + rswitch *( - zbbb - zdiscrim ) / ( 2.0 *zaaa ) 
    230                   t_i(ji,jj,jk,jl) = MIN( ztmelts, MAX( rt0 - 100._wp, t_i(ji,jj,jk,jl) ) )  ! -100 < t_i < ztmelts 
     208                  IF ( v_i(ji,jj,jl) > epsi20 ) THEN     !--- icy area  
     209                     ! 
     210                     ze_i    =   e_i(ji,jj,jk,jl) / v_i(ji,jj,jl) * zlay_i               ! Energy of melting e(S,T) [J.m-3] 
     211                     ztmelts = - s_i(ji,jj,jk,jl) * tmut                                 ! Ice layer melt temperature [C] 
     212                     ! 
     213                     zbbb     =  zcpMcpic * ztmelts + ze_i * r1_rhoic - lfus 
     214                     zccc     =  lfus * ztmelts 
     215                     zdiscrim =  SQRT(  MAX( zbbb*zbbb - 4._wp*zaaa*zccc , 0._wp)  ) 
     216                     zt_i     = - ( zbbb + zdiscrim ) * z1_2aaa                          ! [C] 
     217                     t_i(ji,jj,jk,jl) = MAX( -100._wp , MIN( zt_i , ztmelts )  ) + rt0   ! [K] with bounds: -100 < zt_i < ztmelts 
     218                     ! 
     219                  ELSE                                !--- no ice 
     220                     t_i(ji,jj,jk,jl) =  rt0 - 100._wp                                   ! impose 173.15 K (i.e. -100 C) 
     221!!clem: I think we should impose rt0 instead 
     222                  ENDIF 
    231223               END DO 
    232224            END DO 
     
    235227 
    236228      !-------------------- 
    237       ! Snow temperatures 
     229      ! Snow temperature   [K]   (with a minimum value (rt0 - 100.) imposed everywhere) 
    238230      !-------------------- 
    239       zfac1 = 1._wp / ( rhosn * cpic ) 
    240       zfac2 = lfus / cpic   
    241       DO jl = 1, jpl 
    242          DO jk = 1, nlay_s 
    243             DO jj = 1, jpj 
    244                DO ji = 1, jpi 
    245                   !Energy of melting q(S,T) [J.m-3] 
    246                   rswitch = MAX( 0._wp , SIGN( 1._wp , v_s(ji,jj,jl) - epsi20 ) )     ! rswitch = 0 if no ice and 1 if yes 
    247                   ze_s  = rswitch * e_s(ji,jj,jk,jl) / MAX( v_s(ji,jj,jl) , epsi20 ) * REAL(nlay_s,wp) 
    248                   ! 
    249                   t_s(ji,jj,jk,jl) = rt0 + rswitch * ( - zfac1 * ze_s + zfac2 ) 
    250                   t_s(ji,jj,jk,jl) = MIN( rt0, MAX( rt0 - 100._wp , t_s(ji,jj,jk,jl) ) )     ! -100 < t_s < rt0 
    251                END DO 
    252             END DO 
    253          END DO 
     231      z1_CpR = 1._wp / ( cpic * rhosn ) 
     232      zL_Cp  = lfus  /   cpic 
     233      zlay_s = REAL( nlay_s , wp ) 
     234      DO jk = 1, nlay_s 
     235         WHERE( v_s(:,:,:) > epsi20 )        !--- icy area 
     236            t_s(:,:,jk,:) = MAX(  -100._wp , MIN( - z1_CpR * ( e_s(:,:,jk,:)/v_s(:,:,:)*zlay_s ) + zL_Cp , 0._wp )  ) + rt0        
     237         ELSEWHERE                           !--- no ice 
     238            t_s(:,:,jk,:) =  rt0 - 100._wp         ! impose 173.15 K (i.e. -100 C) 
     239         END WHERE 
    254240      END DO 
     241!!gm perhaps better like this (?) :  (if this compile, yes! one test instead of nlay_s tests) 
     242!      WHERE( v_s(:,:,:) > epsi20 )        !--- icy area 
     243!         DO jk = 1, nlay_s 
     244!            t_s(:,:,jk,:) = MAX(  -100._wp , MIN( - z1_CpR * ( e_s(:,:,jk,:)/v_s(:,:,:)*zlay_s ) + zL_Cp , 0._wp )  ) + rt0        
     245!         END DO 
     246!      ELSEWHERE                           !--- no ice 
     247!         DO jk = 1, nlay_s 
     248!            t_s(:,:,jk,:) =  rt0 - 100._wp      ! impose 173.15 K (i.e. -100 C) 
     249!         END DO 
     250!      END WHERE 
     251!!gm end better ? 
    255252 
    256253      ! integrated values  
     
    259256      at_i (:,:) = SUM( a_i, dim=3 ) 
    260257 
    261       ! MV MP 2016 
    262       ! probably should resum for melt ponds ??? 
     258! MV MP 2016 
     259! probably should resum for melt ponds ??? 
    263260 
    264261      ! 
     
    270267      !!                ***  ROUTINE ice_var_eqv2glo *** 
    271268      !! 
    272       !! ** Purpose :   computes global variables as function of equivalent variables 
    273       !!                i.e. it turns VEQV into VGLO 
    274       !! ** Method  : 
    275       !! 
    276       !! ** History :  (01-2006) Martin Vancoppenolle, UCL-ASTR 
    277       !!------------------------------------------------------------------ 
    278       ! 
    279       v_i(:,:,:)   = ht_i(:,:,:) * a_i(:,:,:) 
    280       v_s(:,:,:)   = ht_s(:,:,:) * a_i(:,:,:) 
     269      !! ** Purpose :   computes global variables as function of  
     270      !!              equivalent variables,  i.e. it turns VEQV into VGLO 
     271      !!------------------------------------------------------------------ 
     272      ! 
     273      v_i  (:,:,:) = ht_i(:,:,:) * a_i(:,:,:) 
     274      v_s  (:,:,:) = ht_s(:,:,:) * a_i(:,:,:) 
    281275      smv_i(:,:,:) = sm_i(:,:,:) * v_i(:,:,:) 
    282276      ! 
     
    300294      !!------------------------------------------------------------------ 
    301295      INTEGER  ::   ji, jj, jk, jl   ! dummy loop index 
    302       REAL(wp) ::   zfac0, zfac1, zsal 
    303       REAL(wp) ::   zswi0, zswi01, zargtemp , zs_zero    
    304       REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z_slope_s, zalpha 
     296      REAL(wp) ::   zsal, z1_dS 
     297      REAL(wp) ::   zargtemp , zs0, zs 
     298      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   z_slope_s, zalpha    ! case 2 only 
    305299      REAL(wp), PARAMETER :: zsi0 = 3.5_wp 
    306300      REAL(wp), PARAMETER :: zsi1 = 4.5_wp 
    307301      !!------------------------------------------------------------------ 
    308302 
    309       !--------------------------------------- 
    310       ! Vertically constant, constant in time 
    311       !--------------------------------------- 
    312       IF(  nn_icesal == 1  )  THEN 
     303!!gm  much much more secure to defined when reading nn_icesal in the namelist integers =1, 2, 3  with explicit names 
     304!!       for example np_Scst_noProfile = 1  ;  np_Svar_linProfile = 2   ;   np_Scst_fixProfile 
     305 
     306!!gm Question: Remove the option 3 ?  How many years since it last use ?  
     307 
     308      SELECT CASE ( nn_icesal ) 
     309      ! 
     310      !              !---------------------------------------! 
     311      CASE( 1 )      !  constant salinity in time and space  ! 
     312         !           !---------------------------------------! 
    313313         s_i (:,:,:,:) = rn_icesal 
    314314         sm_i(:,:,:)   = rn_icesal 
    315       ENDIF 
    316  
    317       !----------------------------------- 
    318       ! Salinity profile, varying in time 
    319       !----------------------------------- 
    320       IF(  nn_icesal == 2  ) THEN 
     315         ! 
     316         !           !---------------------------------------------! 
     317      CASE( 2 )      !  time varying salinity with linear profile  ! 
     318         !           !---------------------------------------------! 
     319         ! 
     320         ALLOCATE( z_slope_s(jpi,jpj,jpl) , zalpha(jpi,jpj,jpl) ) 
    321321         ! 
    322322         DO jk = 1, nlay_i 
    323323            s_i(:,:,jk,:)  = sm_i(:,:,:) 
    324324         END DO 
    325          ! 
    326          DO jl = 1, jpl                               ! Slope of the linear profile  
    327             DO jj = 1, jpj 
    328                DO ji = 1, jpi 
    329                   rswitch = MAX( 0._wp , SIGN( 1._wp , ht_i(ji,jj,jl) - epsi20 ) ) 
    330                   z_slope_s(ji,jj,jl) = rswitch * 2._wp * sm_i(ji,jj,jl) / MAX( epsi20 , ht_i(ji,jj,jl) ) 
    331                END DO 
    332             END DO 
    333          END DO 
    334          ! 
    335          zfac0 = 1._wp / ( zsi0 - zsi1 )       ! Weighting factor between zs_zero and zs_inf 
    336          zfac1 = zsi1  / ( zsi1 - zsi0 ) 
    337          ! 
    338          zalpha(:,:,:) = 0._wp 
     325         !                                      ! Slope of the linear profile  
     326         WHERE( ht_i(:,:,:) > epsi20 )   ;   z_slope_s(:,:,:) = 2._wp * sm_i(:,:,:) / ht_i(:,:,:) 
     327         ELSEWHERE                       ;   z_slope_s(:,:,:) = 0._wp 
     328         END WHERE 
     329         ! 
     330         z1_dS = 1._wp / ( zsi1 - zsi0 ) 
    339331         DO jl = 1, jpl 
    340332            DO jj = 1, jpj 
    341333               DO ji = 1, jpi 
    342                   ! zswi0 = 1 if sm_i le zsi0 and 0 otherwise 
    343                   zswi0  = MAX( 0._wp   , SIGN( 1._wp  , zsi0 - sm_i(ji,jj,jl) ) )  
    344                   ! zswi01 = 1 if sm_i is between zsi0 and zsi1 and 0 othws  
    345                   zswi01 = ( 1._wp - zswi0 ) * MAX( 0._wp   , SIGN( 1._wp  , zsi1 - sm_i(ji,jj,jl) ) )  
    346                   ! If 2.sm_i GE sss_m then rswitch = 1 
    347                   ! this is to force a constant salinity profile in the Baltic Sea 
    348                   rswitch = MAX( 0._wp , SIGN( 1._wp , 2._wp * sm_i(ji,jj,jl) - sss_m(ji,jj) ) ) 
    349                   zalpha(ji,jj,jl) = zswi0  + zswi01 * ( sm_i(ji,jj,jl) * zfac0 + zfac1 ) 
    350                   zalpha(ji,jj,jl) = zalpha(ji,jj,jl) * ( 1._wp - rswitch ) 
     334                  zalpha(ji,jj,jl) = MAX(  0._wp , MIN( ( zsi1 - sm_i(ji,jj,jl) ) * z1_dS , 1._wp )  ) 
     335                  !                             ! force a constant profile when SSS too low (Baltic Sea) 
     336                  IF( 2._wp * sm_i(ji,jj,jl) >= sss_m(ji,jj) )   zalpha(ji,jj,jl) = 0._wp   
    351337               END DO 
    352338            END DO 
     
    358344               DO jj = 1, jpj 
    359345                  DO ji = 1, jpi 
    360                      !                                      ! linear profile with 0 at the surface 
    361                      zs_zero = z_slope_s(ji,jj,jl) * ( REAL(jk,wp) - 0.5_wp ) * ht_i(ji,jj,jl) * r1_nlay_i 
    362                      !                                      ! weighting the profile 
    363                      s_i(ji,jj,jk,jl) = zalpha(ji,jj,jl) * zs_zero + ( 1._wp - zalpha(ji,jj,jl) ) * sm_i(ji,jj,jl) 
    364                      !                                      ! bounding salinity 
    365                      s_i(ji,jj,jk,jl) = MIN( rn_simax, MAX( s_i(ji,jj,jk,jl), rn_simin ) ) 
     346                     !                          ! linear profile with 0 surface value 
     347                     zs0 = z_slope_s(ji,jj,jl) * ( REAL(jk,wp) - 0.5_wp ) * ht_i(ji,jj,jl) * r1_nlay_i 
     348                     zs  = zalpha(ji,jj,jl) * zs0 + ( 1._wp - zalpha(ji,jj,jl) ) * sm_i(ji,jj,jl)     ! weighting the profile 
     349                     s_i(ji,jj,jk,jl) = MIN( rn_simax, MAX( zs, rn_simin ) ) 
    366350                  END DO 
    367351               END DO 
     
    369353         END DO 
    370354         ! 
    371       ENDIF ! nn_icesal 
    372  
    373       !------------------------------------------------------- 
    374       ! Vertically varying salinity profile, constant in time 
    375       !------------------------------------------------------- 
    376  
    377       IF(  nn_icesal == 3  ) THEN      ! Schwarzacher (1959) multiyear salinity profile (mean = 2.30) 
     355         DEALLOCATE( z_slope_s , zalpha ) 
     356         ! 
     357         !           !-------------------------------------------! 
     358      CASE( 3 )      ! constant salinity with a fix profile      ! (Schwarzacher (1959) multiyear salinity profile 
     359         !           !-------------------------------------------!                                   (mean = 2.30) 
    378360         ! 
    379361         sm_i(:,:,:) = 2.30_wp 
     362!!gm Remark: if we keep the case 3, then compute an store one for all time-step 
     363!!           a array  S_prof(1:nlay_i) containing the calculation and just do: 
     364!         DO jk = 1, nlay_i 
     365!            s_i(:,:,jk,:) = S_prof(jk) 
     366!         END DO 
     367!!gm end 
    380368         ! 
    381369         DO jl = 1, jpl 
    382370            DO jk = 1, nlay_i 
    383371               zargtemp  = ( REAL(jk,wp) - 0.5_wp ) * r1_nlay_i 
    384                zsal =  1.6_wp * (  1._wp - COS( rpi * zargtemp**(0.407_wp/(0.573_wp+zargtemp)) )  ) 
    385                s_i(:,:,jk,jl) =  zsal 
    386             END DO 
    387          END DO 
    388          ! 
    389       ENDIF ! nn_icesal 
     372               s_i(:,:,jk,jl) =  1.6_wp * (  1._wp - COS( rpi * zargtemp**(0.407_wp/(0.573_wp+zargtemp)) )  ) 
     373            END DO 
     374         END DO 
     375         ! 
     376      END SELECT 
    390377      ! 
    391378   END SUBROUTINE ice_var_salprof 
     
    405392      !!------------------------------------------------------------------ 
    406393      ! 
    407       bvm_i(:,:)   = 0._wp 
     394!!gm I prefere to use WHERE / ELSEWHERE  to set it to zero only where needed   <<<=== to be done 
     395!!   instead of setting everything to zero as just below 
    408396      bv_i (:,:,:) = 0._wp 
    409397      DO jl = 1, jpl 
    410398         DO jk = 1, nlay_i 
    411             DO jj = 1, jpj 
    412                DO ji = 1, jpi 
    413                   rswitch        = ( 1._wp - MAX( 0._wp , SIGN( 1._wp , (t_i(ji,jj,jk,jl) - rt0) + epsi10 ) )  ) 
    414                   bv_i(ji,jj,jl) = bv_i(ji,jj,jl) - rswitch * tmut * s_i(ji,jj,jk,jl) * r1_nlay_i  & 
    415                      &                            / MIN( t_i(ji,jj,jk,jl) - rt0, - epsi10 ) 
    416                END DO 
    417             END DO 
    418          END DO 
    419           
    420          DO jj = 1, jpj 
    421             DO ji = 1, jpi 
    422                rswitch      = MAX( 0._wp , SIGN( 1._wp , vt_i(ji,jj) - epsi10 ) ) 
    423                bvm_i(ji,jj) = bvm_i(ji,jj) + rswitch * bv_i(ji,jj,jl) * v_i(ji,jj,jl) / MAX( vt_i(ji,jj), epsi10 ) 
    424             END DO 
     399            WHERE( t_i(:,:,jk,jl) < rt0 - epsi10 )    
     400               bv_i(:,:,jl) = bv_i(:,:,jl) - tmut * s_i(:,:,jk,jl) * r1_nlay_i / ( t_i(:,:,jk,jl) - rt0 ) 
     401            END WHERE 
    425402         END DO 
    426403      END DO 
    427       ! 
     404      WHERE( vt_i(:,:) > epsi20 )   bvm_i(:,:) = SUM( bv_i(:,:,:) * v_i(:,:,:) , dim=3 ) / vt_i(:,:) 
     405      ELSEWHERE                     bvm_i(:,:) = 0._wp 
     406     END WHERE 
     407     ! 
    428408   END SUBROUTINE ice_var_bv 
    429409 
     
    437417      !!------------------------------------------------------------------- 
    438418      INTEGER  ::   ji, jk    ! dummy loop indices 
    439       REAL(wp) ::   zfac0, zfac1, zargtemp, zsal   ! local scalars 
    440       REAL(wp) ::   zalpha, zswi0, zswi01, zs_zero              !   -      - 
    441       ! 
    442       REAL(wp), DIMENSION(jpij) ::   z_slope_s 
     419      REAL(wp) ::   zargtemp, zsal, z1_dS   ! local scalars 
     420      REAL(wp) ::   zalpha, zs, zs0              !   -      - 
     421      ! 
     422      REAL(wp), ALLOCATABLE, DIMENSION(:) ::   z_slope_s   ! 
    443423      REAL(wp), PARAMETER :: zsi0 = 3.5_wp 
    444424      REAL(wp), PARAMETER :: zsi1 = 4.5_wp 
    445425      !!--------------------------------------------------------------------- 
    446  
    447       !--------------------------------------- 
    448       ! Vertically constant, constant in time 
    449       !--------------------------------------- 
    450       IF( nn_icesal == 1 )   s_i_1d(:,:) = rn_icesal 
    451  
    452       !------------------------------------------------------ 
    453       ! Vertically varying salinity profile, varying in time 
    454       !------------------------------------------------------ 
    455  
    456       IF(  nn_icesal == 2  ) THEN 
    457          ! 
    458          DO ji = 1, nidx          ! Slope of the linear profile zs_zero 
     426      ! 
     427      SELECT CASE ( nn_icesal ) 
     428      ! 
     429      !              !---------------------------------------! 
     430      CASE( 1 )      !  constant salinity in time and space  ! 
     431         !           !---------------------------------------! 
     432         s_i_1d(:,:) = rn_icesal 
     433         ! 
     434         !           !---------------------------------------------! 
     435      CASE( 2 )      !  time varying salinity with linear profile  ! 
     436         !           !---------------------------------------------! 
     437         ! 
     438         ALLOCATE( z_slope_s(jpij) ) 
     439         ! 
     440         DO ji = 1, nidx          ! Slope of the linear profile 
    459441            rswitch = MAX( 0._wp , SIGN( 1._wp , ht_i_1d(ji) - epsi20 ) ) 
    460442            z_slope_s(ji) = rswitch * 2._wp * sm_i_1d(ji) / MAX( epsi20 , ht_i_1d(ji) ) 
    461443         END DO 
    462444 
    463          ! Weighting factor between zs_zero and zs_inf 
    464          !--------------------------------------------- 
    465          zfac0 = 1._wp / ( zsi0 - zsi1 ) 
    466          zfac1 = zsi1 / ( zsi1 - zsi0 ) 
     445         z1_dS = 1._wp / ( zsi1 - zsi0 ) 
    467446         DO jk = 1, nlay_i 
    468447            DO ji = 1, nidx 
    469                ! zswi0 = 1 if sm_i le zsi0 and 0 otherwise 
    470                zswi0  = MAX( 0._wp , SIGN( 1._wp  , zsi0 - sm_i_1d(ji) ) )  
    471                ! zswi01 = 1 if sm_i is between zsi0 and zsi1 and 0 othws  
    472                zswi01 = ( 1._wp - zswi0 ) * MAX( 0._wp , SIGN( 1._wp , zsi1 - sm_i_1d(ji) ) )  
    473                ! if 2.sm_i GE sss_m then rswitch = 1 
    474                ! this is to force a constant salinity profile in the Baltic Sea 
    475                rswitch = MAX( 0._wp , SIGN( 1._wp , 2._wp * sm_i_1d(ji) - sss_1d(ji) ) ) 
     448               zalpha = MAX(  0._wp , MIN(  ( zsi1 - sm_i_1d(ji) ) * z1_dS , 1._wp  )  ) 
     449               IF( 2._wp * sm_i_1d(ji) >= sss_1d(ji) )   zalpha = 0._wp               ! cst profile when SSS too low (Baltic Sea) 
    476450               ! 
    477                zalpha = (  zswi0 + zswi01 * ( sm_i_1d(ji) * zfac0 + zfac1 )  ) * ( 1._wp - rswitch ) 
    478                ! 
    479                zs_zero = z_slope_s(ji) * ( REAL(jk,wp) - 0.5_wp ) * ht_i_1d(ji) * r1_nlay_i 
    480                ! weighting the profile 
    481                s_i_1d(ji,jk) = zalpha * zs_zero + ( 1._wp - zalpha ) * sm_i_1d(ji) 
    482                ! bounding salinity 
    483                s_i_1d(ji,jk) = MIN( rn_simax, MAX( s_i_1d(ji,jk), rn_simin ) ) 
    484             END DO  
    485          END DO  
    486  
    487       ENDIF  
    488  
    489       !------------------------------------------------------- 
    490       ! Vertically varying salinity profile, constant in time 
    491       !------------------------------------------------------- 
    492  
    493       IF( nn_icesal == 3 ) THEN      ! Schwarzacher (1959) multiyear salinity profile (mean = 2.30) 
     451               zs0 = z_slope_s(ji) * ( REAL(jk,wp) - 0.5_wp ) * ht_i_1d(ji) * r1_nlay_i   ! linear profile with 0 surface value 
     452               zs  = zalpha * zs0 + ( 1._wp - zalpha ) * sm_i_1d(ji)                      ! weighting the profile 
     453               s_i_1d(ji,jk) = MIN( rn_simax , MAX( zs , rn_simin ) )                     ! bounding salinity 
     454            END DO 
     455         END DO 
     456         ! 
     457         DEALLOCATE( z_slope_s ) 
     458 
     459         !           !-------------------------------------------! 
     460      CASE( 3 )      ! constant salinity with a fix profile      ! (Schwarzacher (1959) multiyear salinity profile 
     461         !           !-------------------------------------------!                                   (mean = 2.30) 
    494462         ! 
    495463         sm_i_1d(:) = 2.30_wp 
    496464         ! 
     465!!gm cf remark in ice_var_salprof routine, CASE( 3 ) 
    497466         DO jk = 1, nlay_i 
    498467            zargtemp  = ( REAL(jk,wp) - 0.5_wp ) * r1_nlay_i 
     
    503472         END DO 
    504473         ! 
    505       ENDIF 
     474      END SELECT 
    506475      ! 
    507476   END SUBROUTINE ice_var_salprof1d 
     477 
    508478 
    509479   SUBROUTINE ice_var_zapsmall 
     
    512482      !! 
    513483      !! ** Purpose :   Remove too small sea ice areas and correct fluxes 
    514       !! 
    515       !! history : LIM3.5 - 01-2014 (C. Rousset) original code 
    516484      !!------------------------------------------------------------------- 
    517485      INTEGER  ::   ji, jj, jl, jk   ! dummy loop indices 
    518486      REAL(wp) ::   zsal, zvi, zvs, zei, zes, zvp 
    519487      !!------------------------------------------------------------------- 
    520       DO jl = 1, jpl 
    521  
     488      ! 
     489      DO jl = 1, jpl       !==  loop over the categories  ==! 
     490         ! 
    522491         !----------------------------------------------------------------- 
    523492         ! Zap ice energy and use ocean heat to melt ice 
     
    526495            DO jj = 1 , jpj 
    527496               DO ji = 1 , jpi 
     497!!gm I think we can do better/faster  :  to be discussed 
    528498                  rswitch          = MAX( 0._wp , SIGN( 1._wp, a_i(ji,jj,jl) - epsi10 ) ) 
    529499                  rswitch          = MAX( 0._wp , SIGN( 1._wp, v_i(ji,jj,jl) - epsi10 ) ) * rswitch 
     
    588558 
    589559      ! to be sure that at_i is the sum of a_i(jl) 
    590       at_i (:,:) = 0._wp 
    591       DO jl = 1, jpl 
     560      at_i (:,:) = a_i(:,:,1) 
     561     vt_i (:,:) = v_i(:,:,1) 
     562      DO jl = 2, jpl 
    592563         at_i(:,:) = at_i(:,:) + a_i(:,:,jl) 
     564        vt_i(:,:) = vt_i(:,:) + v_i(:,:,jl) 
    593565      END DO 
    594566 
    595       ! open water = 1 if at_i=0 
     567      ! open water = 1 if at_i=0 (no re-calculation of ato_i here) 
    596568      DO jj = 1, jpj 
    597569         DO ji = 1, jpi 
     
    600572         END DO 
    601573      END DO 
    602  
    603574      ! 
    604575   END SUBROUTINE ice_var_zapsmall 
     576 
    605577 
    606578   SUBROUTINE ice_var_itd( zhti, zhts, zai, zht_i, zht_s, za_i ) 
     
    633605      !! 
    634606      !!  (Example of application: BDY forcings when input are cell averaged)   
    635       !! 
    636607      !!------------------------------------------------------------------- 
    637       !! History : LIM3.5 - 2012    (M. Vancoppenolle)  Original code 
    638       !!                    2014    (C. Rousset)        Rewriting 
    639       !!------------------------------------------------------------------- 
    640       !! Local variables 
    641608      INTEGER  :: ji, jk, jl             ! dummy loop indices 
    642609      INTEGER  :: ijpij, i_fill, jl0   
     
    645612      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   zht_i, zht_s, za_i ! output ice/snow variables 
    646613      INTEGER , DIMENSION(4)                  ::   itest 
    647   
     614      !!------------------------------------------------------------------- 
     615 
    648616      !-------------------------------------------------------------------- 
    649617      ! initialisation of variables 
    650618      !-------------------------------------------------------------------- 
    651       ijpij = SIZE(zhti,1) 
     619      ijpij = SIZE( zhti , 1 ) 
    652620      zht_i(1:ijpij,1:jpl) = 0._wp 
    653621      zht_s(1:ijpij,1:jpl) = 0._wp 
     
    766734               zht_s(ji,jl) = MAX( 0._wp, zht_s(ji,jl) - zdh * rhoic * r1_rhosn ) 
    767735            ENDIF 
    768          ENDDO 
    769       ENDDO 
     736         END DO 
     737      END DO 
    770738      ! 
    771739    END SUBROUTINE ice_var_itd 
    772  
    773740 
    774741#else 
     
    776743   !!   Default option         Dummy module          NO  LIM3 sea-ice model 
    777744   !!---------------------------------------------------------------------- 
    778 CONTAINS 
    779    SUBROUTINE ice_var_itd 
    780    END SUBROUTINE ice_var_itd 
    781745#endif 
    782746 
Note: See TracChangeset for help on using the changeset viewer.