source: branches/2013/dev_LOCEAN_CMCC_INGV_2013/NEMOGCM/NEMO/OPA_SRC/DIA/diahsb.F90 @ 4234

Last change on this file since 4234 was 4234, checked in by cetlod, 7 years ago

dev_LOCEAN_CMCC_INGV_2013 : minor updates

  • Property svn:keywords set to Id
File size: 15.4 KB
Line 
1MODULE diahsb
2   !!======================================================================
3   !!                       ***  MODULE  diahsb  ***
4   !! Ocean diagnostics: Heat, salt and volume budgets
5   !!======================================================================
6   !! History :  3.3  ! 2010-09  (M. Leclair)  Original code
7   !!                 ! 2012-10  (C. Rousset)  add iom_put
8   !!----------------------------------------------------------------------
9
10   !!----------------------------------------------------------------------
11   USE oce             ! ocean dynamics and tracers
12   USE dom_oce         ! ocean space and time domain
13   USE phycst          ! physical constants
14   USE sbc_oce         ! surface thermohaline fluxes
15   USE in_out_manager  ! I/O manager
16   USE domvvl          ! vertical scale factors
17   USE traqsr          ! penetrative solar radiation
18   USE trabbc          ! bottom boundary condition
19   USE lib_mpp         ! distributed memory computing library
20   USE trabbc          ! bottom boundary condition
21   USE obc_par         ! (for lk_obc)
22   USE bdy_par         ! (for lk_bdy)
23   USE timing          ! preformance summary
24   USE iom             ! I/O manager
25   USE lib_fortran     ! glob_sum
26   USE restart         ! ocean restart
27   USE wrk_nemo         ! work arrays
28   USE sbcrnf         ! river runoffd
29
30   IMPLICIT NONE
31   PRIVATE
32
33   PUBLIC   dia_hsb        ! routine called by step.F90
34   PUBLIC   dia_hsb_init   ! routine called by nemogcm.F90
35   PUBLIC   dia_hsb_rst    ! routine called by step.F90
36
37   LOGICAL, PUBLIC ::   ln_diahsb   !: check the heat and salt budgets
38
39   REAL(dp), SAVE                                ::   frc_t      , frc_s     , frc_v   ! global forcing trends
40   REAL(dp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ssh_ini              !
41   REAL(dp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   hc_loc_ini, sc_loc_ini, e3t_ini  !
42   REAL(dp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hcssh_loc_ini, scssh_loc_ini     !
43
44   !! * Substitutions
45#  include "domzgr_substitute.h90"
46#  include "vectopt_loop_substitute.h90"
47
48   !!----------------------------------------------------------------------
49   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
50   !! $Id$
51   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
52   !!----------------------------------------------------------------------
53
54CONTAINS
55
56   SUBROUTINE dia_hsb( kt )
57      !!---------------------------------------------------------------------------
58      !!                  ***  ROUTINE dia_hsb  ***
59      !!     
60      !! ** Purpose: Compute the ocean global heat content, salt content and volume conservation
61      !!
62      !! ** Method : - Compute the deviation of heat content, salt content and volume
63      !!             at the current time step from their values at nit000
64      !!             - Compute the contribution of forcing and remove it from these deviations
65      !!
66      !!---------------------------------------------------------------------------
67      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
68      !!
69      INTEGER    ::   jk                          ! dummy loop indice
70      REAL(dp)   ::   zdiff_hc    , zdiff_sc      ! heat and salt content variations
71      REAL(dp)   ::   zdiff_v1    , zdiff_v2      ! volume variation
72      REAL(dp)   ::   z_hc        , z_sc          ! heat and salt content
73      REAL(dp)   ::   z_v1        , z_v2          ! volume
74      REAL(dp)   ::   zdeltat                     !    -     -
75      REAL(dp)   ::   z_frc_trd_t , z_frc_trd_s   !    -     -
76      REAL(dp)   ::   z_frc_trd_v                 !    -     -
77      REAL(dp), POINTER, DIMENSION(:,:)   ::   zsurf              !
78      !!---------------------------------------------------------------------------
79      IF( nn_timing == 1 )   CALL timing_start('dia_hsb')     
80
81      CALL wrk_alloc( jpi, jpj, zsurf )
82 
83      zsurf(:,:) = e1t(:,:) * e2t(:,:) * tmask(:,:,1) * tmask_i(:,:)      ! masked surface grid cell area
84     
85      ! ------------------------- !
86      ! 1 - Trends due to forcing !
87      ! ------------------------- !
88      z_frc_trd_v = r1_rau0 * glob_sum( - ( emp(:,:) - rnf(:,:) ) * zsurf(:,:) ) ! volume fluxes
89      z_frc_trd_t =           glob_sum( sbc_tsc(:,:,jp_tem) * zsurf(:,:) )       ! heat fluxes
90      z_frc_trd_s =           glob_sum( sbc_tsc(:,:,jp_sal) * zsurf(:,:) )       ! salt fluxes
91      !
92      IF( ln_rnf    )   z_frc_trd_t = z_frc_trd_t + glob_sum( rnf_tsc(:,:,jp_tem) * zsurf(:,:) )
93      IF( ln_rnf_sal)   z_frc_trd_s = z_frc_trd_s + glob_sum( rnf_tsc(:,:,jp_sal) * zsurf(:,:) )
94
95      ! Add penetrative solar radiation
96      IF( ln_traqsr )   z_frc_trd_t = z_frc_trd_t + r1_rau0_rcp * glob_sum( qsr     (:,:) * zsurf(:,:) )
97      ! Add geothermal heat flux
98      IF( ln_trabbc )   z_frc_trd_t = z_frc_trd_t +               glob_sum( qgh_trd0(:,:) * zsurf(:,:) )
99      !
100      frc_v = frc_v + z_frc_trd_v * rdt
101      frc_t = frc_t + z_frc_trd_t * rdt
102      frc_s = frc_s + z_frc_trd_s * rdt
103
104      ! ------------------------ !
105      ! 2a -  Content variations !
106      ! ------------------------ !
107      zdiff_v2 = 0._dp
108      zdiff_hc = 0._dp
109      zdiff_sc = 0._dp
110      ! volume variation (calculated with ssh)
111      zdiff_v1 = glob_sum( zsurf(:,:) * ( sshn(:,:) - ssh_ini(:,:) ) )
112      DO jk = 1, jpkm1
113         ! volume variation (calculated with scale factors)
114         zdiff_v2 = zdiff_v2 &
115            &  + glob_sum( zsurf(:,:) * tmask(:,:,jk) * ( fse3t_n(:,:,jk) - e3t_ini(:,:,jk) ) )
116         ! heat content variation
117         zdiff_hc = zdiff_hc &
118            &  + glob_sum( zsurf(:,:) * tmask(:,:,jk) * ( fse3t_n(:,:,jk) * tsn(:,:,jk,jp_tem)   &
119            &                           - hc_loc_ini(:,:,jk) ) )
120         ! salt content variation
121         zdiff_sc = zdiff_sc &
122            &  + glob_sum( zsurf(:,:) * tmask(:,:,jk) * ( fse3t_n(:,:,jk) * tsn(:,:,jk,jp_sal)   &
123            &                           - sc_loc_ini(:,:,jk) ) )
124      ENDDO
125
126      ! Substract forcing from heat content, salt content and volume variations
127      !frc_v = zdiff_v2 - frc_v
128      !frc_t = zdiff_hc - frc_t
129      !frc_s = zdiff_sc - frc_s
130     
131      ! add ssh if not vvl
132      IF( .NOT. lk_vvl ) THEN
133        zdiff_v2 = zdiff_v2 + zdiff_v1
134        zdiff_hc = zdiff_hc + glob_sum( zsurf(:,:) * ( sshn(:,:) * tsn(:,:,1,jp_tem)   &
135               &                           - hcssh_loc_ini(:,:) ) )
136        zdiff_sc = zdiff_sc + glob_sum( zsurf(:,:) * ( sshn(:,:) * tsn(:,:,1,jp_sal)   &
137               &                           - scssh_loc_ini(:,:) ) )
138      ENDIF
139      !
140      ! ----------------------- !
141      ! 2b -  Content           !
142      ! ----------------------- !
143      z_v2 = 0._dp
144      z_hc = 0._dp
145      z_sc = 0._dp
146      ! volume (calculated with ssh)
147      z_v1 = glob_sum( zsurf(:,:) * sshn(:,:) )
148      DO jk = 1, jpkm1
149         ! volume (calculated with scale factors)
150         z_v2 = z_v2 &
151            &     + glob_sum( zsurf(:,:) * tmask(:,:,jk) * fse3t_n(:,:,jk) )
152         ! heat content
153         z_hc = z_hc &
154            &     + glob_sum( zsurf(:,:) * tmask(:,:,jk) * fse3t_n(:,:,jk) * tsn(:,:,jk,jp_tem) )
155         ! salt content
156         z_sc = z_sc &
157            &     + glob_sum( zsurf(:,:) * tmask(:,:,jk) * fse3t_n(:,:,jk) * tsn(:,:,jk,jp_sal) )
158      ENDDO
159      ! add ssh if not vvl
160      IF( .NOT. lk_vvl ) THEN
161        z_v2 = z_v2 + z_v1
162        z_hc = z_hc + glob_sum( zsurf(:,:) * sshn(:,:) * tsn(:,:,1,jp_tem) )
163        z_sc = z_sc + glob_sum( zsurf(:,:) * sshn(:,:) * tsn(:,:,1,jp_sal) )
164      ENDIF
165
166      ! ----------------------- !
167      ! 3 - Diagnostics writing !
168      ! ----------------------- !
169      zdeltat  = 1.e0 / ( ( kt - nit000 + 1 ) * rdt )
170!
171      CALL iom_put( 'bgtemper' , z_hc / z_v2 )                      ! Temperature (C)
172      CALL iom_put( 'bgsaline' , z_sc / z_v2 )                      ! Salinity (psu)
173      CALL iom_put( 'bgheatco' , zdiff_hc * rau0 * rcp * 1.e-9_dp ) ! Heat content variation (10^9 J)
174      CALL iom_put( 'bgsaltco' , zdiff_sc * 1.e-9 )                 ! Salt content variation (psu*km3)
175      CALL iom_put( 'bgvolssh' , zdiff_v1 * 1.e-9 )                    ! volume ssh (km3) 
176      CALL iom_put( 'bgsshtot' , zdiff_v1 / glob_sum(zsurf) )          ! ssh (m) 
177      CALL iom_put( 'bgvoltot' , zdiff_v2 * 1.e-9 )                 ! volume total (km3)
178      CALL iom_put( 'bgfrcvol' , frc_v * 1.e-9 )                     ! vol - surface forcing (volume)
179      CALL iom_put( 'bgfrctem' , frc_t * rau0 * rcp * 1.e-9_dp ) ! hc  - surface forcing (heat content)
180      CALL iom_put( 'bgfrcsal' , frc_s * 1.e-9 )                     ! sc  - surface forcing (salt content)
181      !
182      CALL wrk_dealloc( jpi, jpj, zsurf )
183      !
184      IF( nn_timing == 1 )   CALL timing_stop('dia_hsb')
185!
186   END SUBROUTINE dia_hsb
187
188
189   SUBROUTINE dia_hsb_init
190      !!---------------------------------------------------------------------------
191      !!                  ***  ROUTINE dia_hsb  ***
192      !!     
193      !! ** Purpose: Initialization for the heat salt volume budgets
194      !!
195      !! ** Method : Compute initial heat content, salt content and volume
196      !!
197      !! ** Action : - Compute initial heat content, salt content and volume
198      !!             - Initialize forcing trends
199      !!             - Compute coefficients for conversion
200      !!---------------------------------------------------------------------------
201      INTEGER            ::   jk       ! dummy loop indice
202      INTEGER            ::   ierror   ! local integer
203      !!
204      NAMELIST/namhsb/ ln_diahsb
205      !
206      INTEGER  ::   ios
207      !!----------------------------------------------------------------------
208
209      IF(lwp) THEN
210         WRITE(numout,*)
211         WRITE(numout,*) 'dia_hsb_init : check the heat and salt budgets'
212         WRITE(numout,*) '~~~~~~~~ '
213      ENDIF
214
215      REWIND( numnam_ref )              ! Namelist namhsb in reference namelist
216      READ  ( numnam_ref, namhsb, IOSTAT = ios, ERR = 901)
217901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namhsb in reference namelist', lwp )
218
219      REWIND( numnam_cfg )              ! Namelist namhsb in configuration namelist
220      READ  ( numnam_cfg, namhsb, IOSTAT = ios, ERR = 902 )
221902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namhsb in configuration namelist', lwp )
222      WRITE ( numond, namhsb )
223
224      !
225      IF(lwp) THEN                   ! Control print
226         WRITE(numout,*)
227         WRITE(numout,*) '   Namelist namhsb : set hsb parameters'
228         WRITE(numout,*) '      Switch for hsb diagnostic (T) or not (F)  ln_diahsb  = ', ln_diahsb
229      ENDIF
230
231      IF( .NOT. ln_diahsb )   RETURN
232
233         ! ------------------- !
234         ! 1 - Allocate memory !
235         ! ------------------- !
236         ALLOCATE( hc_loc_ini(jpi,jpj,jpk), STAT=ierror )
237         IF( ierror > 0 ) THEN
238            CALL ctl_stop( 'dia_hsb: unable to allocate hc_loc_ini' )   ;   RETURN
239         ENDIF
240         ALLOCATE( sc_loc_ini(jpi,jpj,jpk), STAT=ierror )
241         IF( ierror > 0 ) THEN
242            CALL ctl_stop( 'dia_hsb: unable to allocate sc_loc_ini' )   ;   RETURN
243         ENDIF
244         ALLOCATE( hcssh_loc_ini(jpi,jpj), STAT=ierror )
245         IF( ierror > 0 ) THEN
246            CALL ctl_stop( 'dia_hsb: unable to allocate hcssh_loc_ini' )   ;   RETURN
247         ENDIF
248         ALLOCATE( scssh_loc_ini(jpi,jpj), STAT=ierror )
249         IF( ierror > 0 ) THEN
250            CALL ctl_stop( 'dia_hsb: unable to allocate scssh_loc_ini' )   ;   RETURN
251         ENDIF
252         ALLOCATE( e3t_ini(jpi,jpj,jpk)   , STAT=ierror )
253         IF( ierror > 0 ) THEN
254            CALL ctl_stop( 'dia_hsb: unable to allocate e3t_ini' )      ;   RETURN
255         ENDIF
256         ALLOCATE( ssh_ini(jpi,jpj)       , STAT=ierror )
257         IF( ierror > 0 ) THEN
258            CALL ctl_stop( 'dia_hsb: unable to allocate ssh_ini' )      ;   RETURN
259         ENDIF
260         
261         ! ----------------------------------------------- !
262         ! 2 - Time independant variables and file opening !
263         ! ----------------------------------------------- !
264         IF(lwp) WRITE(numout,*) "dia_hsb: heat salt volume budgets activated"
265         IF( lk_obc .or. lk_bdy ) THEN
266            CALL ctl_warn( 'dia_hsb does not take open boundary fluxes into account' )         
267         ENDIF
268         !
269         CALL dia_hsb_rst( nit000, 'READ' )  !* read or initialize all required files
270      !
271   END SUBROUTINE dia_hsb_init
272
273   SUBROUTINE dia_hsb_rst( kt, cdrw )
274     !!---------------------------------------------------------------------
275     !!                   ***  ROUTINE limdia_rst  ***
276     !!                     
277     !! ** Purpose :   Read or write DIA file in restart file
278     !!
279     !! ** Method  :   use of IOM library
280     !!----------------------------------------------------------------------
281     INTEGER         , INTENT(in) ::   kt     ! ocean time-step
282     CHARACTER(len=*), INTENT(in) ::   cdrw   ! "READ"/"WRITE" flag
283     !
284     INTEGER ::   jk   !
285     INTEGER ::   id1   ! local integers
286     !!----------------------------------------------------------------------
287     !
288     IF( TRIM(cdrw) == 'READ' ) THEN        ! Read/initialise
289        IF( ln_rstart ) THEN                   !* Read the restart file
290           !id1 = iom_varid( numror, 'frc_vol'  , ldstop = .FALSE. )
291           !
292           CALL iom_get( numror, 'frc_v', frc_v )
293           CALL iom_get( numror, 'frc_t', frc_t )
294           CALL iom_get( numror, 'frc_s', frc_s )
295
296           CALL iom_get( numror, jpdom_autoglo, 'ssh_ini', ssh_ini )
297           CALL iom_get( numror, jpdom_autoglo, 'e3t_ini', e3t_ini )
298           CALL iom_get( numror, jpdom_autoglo, 'hc_loc_ini', hc_loc_ini )
299           CALL iom_get( numror, jpdom_autoglo, 'sc_loc_ini', sc_loc_ini )
300           CALL iom_get( numror, jpdom_autoglo, 'hcssh_loc_ini', hcssh_loc_ini )
301           CALL iom_get( numror, jpdom_autoglo, 'scssh_loc_ini', scssh_loc_ini )
302       ELSE
303          ssh_ini(:,:) = sshn(:,:)                                       ! initial ssh
304          DO jk = 1, jpk
305             e3t_ini   (:,:,jk) = fse3t_n(:,:,jk)                        ! initial vertical scale factors
306             hc_loc_ini(:,:,jk) = tsn(:,:,jk,jp_tem) * fse3t_n(:,:,jk)   ! initial heat content
307             sc_loc_ini(:,:,jk) = tsn(:,:,jk,jp_sal) * fse3t_n(:,:,jk)   ! initial salt content
308          END DO
309          hcssh_loc_ini(:,:) = tsn(:,:,1,jp_tem) * sshn(:,:)   ! initial heat content in ssh
310          scssh_loc_ini(:,:) = tsn(:,:,1,jp_sal) * sshn(:,:)   ! initial salt content in ssh
311          frc_v = 0._dp                                           
312          frc_t = 0._dp                                           
313          frc_s = 0._dp                                                 
314       ENDIF
315
316     ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN   ! Create restart file
317        !                                   ! -------------------
318        IF(lwp) WRITE(numout,*) '---- dia-rst ----'
319        CALL iom_rstput( kt, nitrst, numrow, 'frc_v'   , frc_v     )
320        CALL iom_rstput( kt, nitrst, numrow, 'frc_t'   , frc_t     )
321        CALL iom_rstput( kt, nitrst, numrow, 'frc_s'   , frc_s     )
322       
323        CALL iom_rstput( kt, nitrst, numrow, 'ssh_ini', ssh_ini )
324        CALL iom_rstput( kt, nitrst, numrow, 'e3t_ini', e3t_ini )
325        CALL iom_rstput( kt, nitrst, numrow, 'hc_loc_ini', hc_loc_ini )
326        CALL iom_rstput( kt, nitrst, numrow, 'sc_loc_ini', sc_loc_ini )
327        CALL iom_rstput( kt, nitrst, numrow, 'hcssh_loc_ini', hcssh_loc_ini )
328        CALL iom_rstput( kt, nitrst, numrow, 'scssh_loc_ini', scssh_loc_ini )
329        !
330     ENDIF
331     !
332   END SUBROUTINE dia_hsb_rst
333
334   !!======================================================================
335END MODULE diahsb
Note: See TracBrowser for help on using the repository browser.