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 4073 for branches/2012 – NEMO

Changeset 4073 for branches/2012


Ignore:
Timestamp:
2013-10-17T19:17:44+02:00 (11 years ago)
Author:
cetlod
Message:

dev_v3_4_STABLE_2012:bugfix in diahsb : global conservation, see ticket #1161

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2012/dev_v3_4_STABLE_2012/NEMOGCM/NEMO/OPA_SRC/DIA/diahsb.F90

    r3294 r4073  
    2121   USE bdy_par         ! (for lk_bdy) 
    2222   USE timing          ! preformance summary 
     23   USE lib_fortran 
     24   USE sbcrnf 
    2325 
    2426   IMPLICIT NONE 
     
    3335   REAL(dp)                                ::   surf_tot   , vol_tot             ! 
    3436   REAL(dp)                                ::   frc_t      , frc_s     , frc_v   ! global forcing trends 
     37   REAL(dp)                                ::   frc_wn_t      , frc_wn_s ! global forcing trends 
    3538   REAL(dp)                                ::   fact1                            ! conversion factors 
    3639   REAL(dp)                                ::   fact21    , fact22               !     -         - 
     
    3841   REAL(dp), DIMENSION(:,:)  , ALLOCATABLE ::   surf      , ssh_ini              ! 
    3942   REAL(dp), DIMENSION(:,:,:), ALLOCATABLE ::   hc_loc_ini, sc_loc_ini, e3t_ini  ! 
     43   REAL(dp), DIMENSION(:,:)  , ALLOCATABLE ::   ssh_hc_loc_ini, ssh_sc_loc_ini 
    4044 
    4145   !! * Substitutions 
     
    6771      INTEGER    ::   jk                          ! dummy loop indice 
    6872      REAL(dp)   ::   zdiff_hc    , zdiff_sc      ! heat and salt content variations 
     73      REAL(dp)   ::   zdiff_hc1   , zdiff_sc1     ! heat and salt content variations of ssh 
    6974      REAL(dp)   ::   zdiff_v1    , zdiff_v2      ! volume variation 
     75      REAL(dp)   ::   zerr_hc1    , zerr_sc1      ! Non conservation due to free surface 
    7076      REAL(dp)   ::   z1_rau0                     ! local scalars 
    7177      REAL(dp)   ::   zdeltat                     !    -     - 
    7278      REAL(dp)   ::   z_frc_trd_t , z_frc_trd_s   !    -     - 
    7379      REAL(dp)   ::   z_frc_trd_v                 !    -     - 
     80      REAL(dp)   ::   z_wn_trd_t , z_wn_trd_s   !    -     - 
     81      REAL(dp)   ::   z_ssh_hc , z_ssh_sc   !    -     - 
    7482      !!--------------------------------------------------------------------------- 
    7583      IF( nn_timing == 1 )   CALL timing_start('dia_hsb') 
     
    7987      ! ------------------------- ! 
    8088      z1_rau0 = 1.e0 / rau0 
    81       z_frc_trd_v = z1_rau0 * SUM( - ( emp(:,:) - rnf(:,:) ) * surf(:,:) )     ! volume fluxes 
    82       z_frc_trd_t =           SUM( sbc_tsc(:,:,jp_tem) * surf(:,:) )     ! heat fluxes 
    83       z_frc_trd_s =           SUM( sbc_tsc(:,:,jp_sal) * surf(:,:) )     ! salt fluxes 
     89      z_frc_trd_v = z1_rau0 * glob_sum( - ( emp(:,:) - rnf(:,:) ) * surf(:,:) )     ! volume fluxes 
     90      z_frc_trd_t =           glob_sum( sbc_tsc(:,:,jp_tem) * surf(:,:) )     ! heat fluxes 
     91      z_frc_trd_s =           glob_sum( sbc_tsc(:,:,jp_sal) * surf(:,:) )     ! salt fluxes 
     92      ! Add runoff heat & salt input 
     93      IF( ln_rnf    )   z_frc_trd_t = z_frc_trd_t + glob_sum( rnf_tsc(:,:,jp_tem) * surf(:,:) ) 
     94      IF( ln_rnf_sal)   z_frc_trd_s = z_frc_trd_s + glob_sum( rnf_tsc(:,:,jp_sal) * surf(:,:) ) 
    8495      ! Add penetrative solar radiation 
    85       IF( ln_traqsr )   z_frc_trd_t = z_frc_trd_t + ro0cpr * SUM( qsr     (:,:) * surf(:,:) ) 
     96      IF( ln_traqsr )   z_frc_trd_t = z_frc_trd_t + r1_rau0_rcp * glob_sum( qsr     (:,:) * surf(:,:) ) 
    8697      ! Add geothermal heat flux 
    87       IF( ln_trabbc )   z_frc_trd_t = z_frc_trd_t + ro0cpr * SUM( qgh_trd0(:,:) * surf(:,:) ) 
    88       IF( lk_mpp ) THEN 
    89          CALL mpp_sum( z_frc_trd_v ) 
    90          CALL mpp_sum( z_frc_trd_t ) 
    91       ENDIF 
     98      IF( ln_trabbc )   z_frc_trd_t = z_frc_trd_t +  glob_sum( qgh_trd0(:,:) * surf(:,:) ) 
     99      IF( .NOT. lk_vvl ) THEN 
     100         z_wn_trd_t = - glob_sum( surf(:,:) * wn(:,:,1) * tsb(:,:,1,jp_tem) ) 
     101         z_wn_trd_s = - glob_sum( surf(:,:) * wn(:,:,1) * tsb(:,:,1,jp_sal) ) 
     102      ENDIF 
     103 
    92104      frc_v = frc_v + z_frc_trd_v * rdt 
    93105      frc_t = frc_t + z_frc_trd_t * rdt 
    94106      frc_s = frc_s + z_frc_trd_s * rdt 
     107      !                                          ! Advection flux through fixed surface (z=0) 
     108      IF( .NOT. lk_vvl ) THEN 
     109         frc_wn_t = frc_wn_t + z_wn_trd_t * rdt 
     110         frc_wn_s = frc_wn_s + z_wn_trd_s * rdt 
     111      ENDIF 
    95112 
    96113      ! ----------------------- ! 
     
    100117      zdiff_hc = 0.d0 
    101118      zdiff_sc = 0.d0 
     119 
    102120      ! volume variation (calculated with ssh) 
    103       zdiff_v1 = SUM( surf(:,:) * tmask(:,:,1) * ( sshn(:,:) - ssh_ini(:,:) ) ) 
     121      zdiff_v1 = glob_sum( surf(:,:) * ( sshn(:,:) - ssh_ini(:,:) ) ) 
     122 
     123      ! heat & salt content variation (associated with ssh) 
     124      IF( .NOT. lk_vvl ) THEN 
     125         z_ssh_hc = glob_sum( surf(:,:) * ( tsn(:,:,1,jp_tem) * sshn(:,:) - ssh_hc_loc_ini(:,:) ) ) 
     126         z_ssh_sc = glob_sum( surf(:,:) * ( tsn(:,:,1,jp_sal) * sshn(:,:) - ssh_sc_loc_ini(:,:) ) ) 
     127      ENDIF 
     128 
    104129      DO jk = 1, jpkm1 
    105          ! volume variation (calculated with scale factors) 
    106          zdiff_v2 = zdiff_v2 + SUM( surf(:,:) * tmask(:,:,jk)   & 
     130        ! volume variation (calculated with scale factors) 
     131         zdiff_v2 = zdiff_v2 + glob_sum( surf(:,:) * tmask(:,:,jk)   & 
    107132            &                       * ( fse3t_n(:,:,jk)         & 
    108133            &                           - e3t_ini(:,:,jk) ) ) 
    109134         ! heat content variation 
    110          zdiff_hc = zdiff_hc + SUM( surf(:,:) * tmask(:,:,jk)          & 
     135         zdiff_hc = zdiff_hc + glob_sum( surf(:,:) * tmask(:,:,jk)          & 
    111136            &                       * ( fse3t_n(:,:,jk) * tsn(:,:,jk,jp_tem)   & 
    112137            &                           - hc_loc_ini(:,:,jk) ) ) 
    113138         ! salt content variation 
    114          zdiff_sc = zdiff_sc + SUM( surf(:,:) * tmask(:,:,jk)          & 
     139         zdiff_sc = zdiff_sc + glob_sum( surf(:,:) * tmask(:,:,jk)          & 
    115140            &                       * ( fse3t_n(:,:,jk) * tsn(:,:,jk,jp_sal)   & 
    116141            &                           - sc_loc_ini(:,:,jk) ) ) 
    117142      ENDDO 
    118143 
    119       IF( lk_mpp ) THEN 
    120          CALL mpp_sum( zdiff_hc ) 
    121          CALL mpp_sum( zdiff_sc ) 
    122          CALL mpp_sum( zdiff_v1 ) 
    123          CALL mpp_sum( zdiff_v2 ) 
    124       ENDIF 
    125  
    126144      ! Substract forcing from heat content, salt content and volume variations 
    127145      zdiff_v1 = zdiff_v1 - frc_v 
    128       zdiff_v2 = zdiff_v2 - frc_v 
     146      IF( lk_vvl )   zdiff_v2 = zdiff_v2 - frc_v 
    129147      zdiff_hc = zdiff_hc - frc_t 
    130148      zdiff_sc = zdiff_sc - frc_s 
     149      IF( .NOT. lk_vvl ) THEN 
     150         zdiff_hc1 = zdiff_hc + z_ssh_hc  
     151         zdiff_sc1 = zdiff_sc + z_ssh_sc 
     152         zerr_hc1  = z_ssh_hc - frc_wn_t 
     153         zerr_sc1  = z_ssh_sc - frc_wn_s 
     154      ENDIF 
    131155       
    132156      ! ----------------------- ! 
     
    134158      ! ----------------------- ! 
    135159      zdeltat  = 1.e0 / ( ( kt - nit000 + 1 ) * rdt ) 
    136       WRITE(numhsb , 9020) kt , zdiff_hc / vol_tot , zdiff_hc * fact1  * zdeltat,                                & 
    137          &                      zdiff_sc / vol_tot , zdiff_sc * fact21 * zdeltat, zdiff_sc * fact22 * zdeltat,   & 
    138          &                      zdiff_v1           , zdiff_v1 * fact31 * zdeltat, zdiff_v1 * fact32 * zdeltat,   & 
    139          &                      zdiff_v2           , zdiff_v2 * fact31 * zdeltat, zdiff_v2 * fact32 * zdeltat 
     160      IF( lk_vvl ) THEN 
     161         WRITE(numhsb , 9020) kt , zdiff_hc / vol_tot , zdiff_hc * fact1  * zdeltat,                                & 
     162            &                      zdiff_sc / vol_tot , zdiff_sc * fact21 * zdeltat, zdiff_sc * fact22 * zdeltat,   & 
     163            &                      zdiff_v1           , zdiff_v1 * fact31 * zdeltat, zdiff_v1 * fact32 * zdeltat,   & 
     164            &                      zdiff_v2           , zdiff_v2 * fact31 * zdeltat, zdiff_v2 * fact32 * zdeltat 
     165      ELSE 
     166         WRITE(numhsb , 9030) kt , zdiff_hc1 / vol_tot , zdiff_hc1 * fact1  * zdeltat,                                & 
     167            &                      zdiff_sc1 / vol_tot , zdiff_sc1 * fact21 * zdeltat, zdiff_sc1 * fact22 * zdeltat,   & 
     168            &                      zdiff_v1            , zdiff_v1  * fact31 * zdeltat, zdiff_v1  * fact32 * zdeltat,   & 
     169            &                      zerr_hc1 / vol_tot  , zerr_sc1 / vol_tot 
     170      ENDIF 
    140171 
    141172      IF ( kt == nitend ) CLOSE( numhsb ) 
     
    144175 
    1451769020  FORMAT(I5,11D15.7) 
     1779030  FORMAT(I5,10D15.7) 
    146178      ! 
    147179   END SUBROUTINE dia_hsb 
     
    179211 
    180212      IF( .NOT. ln_diahsb )   RETURN 
     213      IF( .NOT. lk_mpp_rep ) & 
     214        CALL ctl_stop (' Your global mpp_sum if performed in single precision - 64 bits -', & 
     215             &         ' whereas the global sum to be precise must be done in double precision ',& 
     216             &         ' please add key_mpp_rep') 
    181217 
    182218      ! ------------------- ! 
    183219      ! 1 - Allocate memory ! 
    184220      ! ------------------- ! 
    185       ALLOCATE( hc_loc_ini(jpi,jpj,jpk), STAT=ierror ) 
     221      ALLOCATE( hc_loc_ini(jpi,jpj,jpk), sc_loc_ini(jpi,jpj,jpk), & 
     222         &      ssh_hc_loc_ini(jpi,jpj), ssh_sc_loc_ini(jpi,jpj), & 
     223         &      e3t_ini(jpi,jpj,jpk)                            , & 
     224         &      surf(jpi,jpj),  ssh_ini(jpi,jpj), STAT=ierror ) 
    186225      IF( ierror > 0 ) THEN 
    187226         CALL ctl_stop( 'dia_hsb: unable to allocate hc_loc_ini' )   ;   RETURN 
    188       ENDIF 
    189       ALLOCATE( sc_loc_ini(jpi,jpj,jpk), STAT=ierror ) 
    190       IF( ierror > 0 ) THEN 
    191          CALL ctl_stop( 'dia_hsb: unable to allocate sc_loc_ini' )   ;   RETURN 
    192       ENDIF 
    193       ALLOCATE( e3t_ini(jpi,jpj,jpk)   , STAT=ierror ) 
    194       IF( ierror > 0 ) THEN 
    195          CALL ctl_stop( 'dia_hsb: unable to allocate e3t_ini' )      ;   RETURN 
    196       ENDIF 
    197       ALLOCATE( surf(jpi,jpj)          , STAT=ierror ) 
    198       IF( ierror > 0 ) THEN 
    199          CALL ctl_stop( 'dia_hsb: unable to allocate surf' )         ;   RETURN 
    200       ENDIF 
    201       ALLOCATE( ssh_ini(jpi,jpj)       , STAT=ierror ) 
    202       IF( ierror > 0 ) THEN 
    203          CALL ctl_stop( 'dia_hsb: unable to allocate ssh_ini' )      ;   RETURN 
    204227      ENDIF 
    205228 
     
    214237      cl_name    = 'heat_salt_volume_budgets.txt'                         ! name of output file 
    215238      surf(:,:) = e1t(:,:) * e2t(:,:) * tmask(:,:,1) * tmask_i(:,:)      ! masked surface grid cell area 
    216       surf_tot  = SUM( surf(:,:) )                                       ! total ocean surface area 
     239      surf_tot  = glob_sum( surf(:,:) )                                       ! total ocean surface area 
    217240      vol_tot   = 0.d0                                                   ! total ocean volume 
    218241      DO jk = 1, jpkm1 
    219          vol_tot  = vol_tot + SUM( surf(:,:) * tmask(:,:,jk)     & 
    220             &                      * fse3t_n(:,:,jk)         ) 
     242         vol_tot  = vol_tot + glob_sum( surf(:,:) * tmask(:,:,jk)     & 
     243            &                         * fse3t_n(:,:,jk)         ) 
    221244      END DO 
    222       IF( lk_mpp ) THEN  
    223          CALL mpp_sum( vol_tot ) 
    224          CALL mpp_sum( surf_tot ) 
    225       ENDIF 
    226245 
    227246      CALL ctl_opn( numhsb , cl_name , 'UNKNOWN' , 'FORMATTED' , 'SEQUENTIAL' , 1 , numout , lwp , 1 ) 
    228       !                   12345678901234567890123456789012345678901234567890123456789012345678901234567890 -> 80 
    229       WRITE( numhsb, 9010 ) "kt   |     heat content budget     |            salt content budget             ",   & 
    230          !                                                   123456789012345678901234567890123456789012345 -> 45 
    231          &                                                  "|            volume budget (ssh)             ",   & 
    232          !                                                   678901234567890123456789012345678901234567890 -> 45 
    233          &                                                  "|            volume budget (e3t)             " 
    234       WRITE( numhsb, 9010 ) "     |      [C]         [W/m2]     |     [psu]        [mmm/s]          [SV]     ",   & 
    235          &                                                  "|     [m3]         [mmm/s]          [SV]     ",   & 
    236          &                                                  "|     [m3]         [mmm/s]          [SV]     " 
    237  
     247      IF( lk_vvl ) THEN 
     248         !                   12345678901234567890123456789012345678901234567890123456789012345678901234567890 -> 80 
     249         WRITE( numhsb, 9010 ) "kt   |     heat content budget     |            salt content budget             ",   & 
     250            !                                                   123456789012345678901234567890123456789012345 -> 45 
     251            &                                                  "|            volume budget (ssh)             ",   & 
     252            !                                                   678901234567890123456789012345678901234567890 -> 45 
     253            &                                                  "|            volume budget (e3t)             " 
     254         WRITE( numhsb, 9010 ) "     |      [C]         [W/m2]     |     [psu]        [mmm/s]          [SV]     ",   & 
     255            &                                                  "|     [m3]         [mmm/s]          [SV]     ",   & 
     256            &                                                  "|     [m3]         [mmm/s]          [SV]     " 
     257      ELSE 
     258         !                   12345678901234567890123456789012345678901234567890123456789012345678901234567890 -> 80 
     259         WRITE( numhsb, 9011 ) "kt   |     heat content budget     |            salt content budget             ",   & 
     260            !                                                   123456789012345678901234567890123456789012345 -> 45 
     261            &                                                  "|            volume budget (ssh)             ",   & 
     262            !                                                   678901234567890123456789012345678901234567890 -> 45 
     263            &                                                  "|  Non conservation due to free surface      " 
     264         WRITE( numhsb, 9011 ) "     |      [C]         [W/m2]     |     [psu]        [mmm/s]          [SV]     ",   & 
     265            &                                                  "|     [m3]         [mmm/s]          [SV]     ",   & 
     266            &                                                  "|  [heat - C]     [salt - psu]                " 
     267      ENDIF 
    238268      ! --------------- ! 
    239269      ! 3 - Conversions ! (factors will be multiplied by duration afterwards) 
     
    261291      frc_t = 0.d0                                           ! heat content   -    -   -    -    
    262292      frc_s = 0.d0                                           ! salt content   -    -   -    -          
     293      IF( .NOT. lk_vvl ) THEN 
     294         ssh_hc_loc_ini(:,:) = tsn(:,:,1,jp_tem) * ssh_ini(:,:)   ! initial heat content associated with ssh 
     295         ssh_sc_loc_ini(:,:) = tsn(:,:,1,jp_sal) * ssh_ini(:,:)   ! initial salt content associated with ssh 
     296         frc_wn_t = 0.d0 
     297         frc_wn_s = 0.d0 
     298      ENDIF 
    263299      ! 
    2643009010  FORMAT(A80,A45,A45) 
     3019011  FORMAT(A80,A45,A45) 
    265302      ! 
    266303   END SUBROUTINE dia_hsb_init 
Note: See TracChangeset for help on using the changeset viewer.