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.
asminc.F90 in branches/2017/dev_merge_2017/NEMOGCM/NEMO/OPA_SRC/ASM – NEMO

source: branches/2017/dev_merge_2017/NEMOGCM/NEMO/OPA_SRC/ASM/asminc.F90 @ 9213

Last change on this file since 9213 was 9213, checked in by gm, 6 years ago

dev_merge_2017: nemogcm.F90 : updated in SAS & OFF + data assimilation initial calls (asm_bkg_wri , tra_asm_inc ...) moved to asm_inc_init + closed sea : restructure namcfg & its control print + set ln_closea = false if domcfg file not read (ln_domcfg=F

  • Property svn:keywords set to Id
File size: 47.7 KB
RevLine 
[2128]1MODULE asminc
2   !!======================================================================
3   !!                       ***  MODULE asminc  ***
4   !! Assimilation increment : Apply an increment generated by data
5   !!                          assimilation
6   !!======================================================================
[2392]7   !! History :       ! 2007-03  (M. Martin)  Met Office version
8   !!                 ! 2007-04  (A. Weaver)  calc_date original code
9   !!                 ! 2007-04  (A. Weaver)  Merge with OPAVAR/NEMOVAR
10   !!   NEMO     3.3  ! 2010-05  (D. Lea)  Update to work with NEMO v3.2
11   !!             -   ! 2010-05  (D. Lea)  add calc_month_len routine based on day_init
[3764]12   !!            3.4  ! 2012-10  (A. Weaver and K. Mogensen) Fix for direct initialization
[6140]13   !!                 ! 2014-09  (D. Lea)  Local calc_date removed use routine from OBS
14   !!                 ! 2015-11  (D. Lea)  Handle non-zero initial time of day
[2392]15   !!----------------------------------------------------------------------
[2128]16
17   !!----------------------------------------------------------------------
[3785]18   !!   asm_inc_init   : Initialize the increment arrays and IAU weights
19   !!   tra_asm_inc    : Apply the tracer (T and S) increments
20   !!   dyn_asm_inc    : Apply the dynamic (u and v) increments
21   !!   ssh_asm_inc    : Apply the SSH increment
[9023]22   !!   ssh_asm_div    : Apply divergence associated with SSH increment
[3785]23   !!   seaice_asm_inc : Apply the seaice increment
[2128]24   !!----------------------------------------------------------------------
[9019]25   USE oce             ! Dynamics and active tracers defined in memory
26   USE par_oce         ! Ocean space and time domain variables
27   USE dom_oce         ! Ocean space and time domain
28   USE domvvl          ! domain: variable volume level
29   USE ldfdyn          ! lateral diffusion: eddy viscosity coefficients
30   USE eosbn2          ! Equation of state - in situ and potential density
31   USE zpshde          ! Partial step : Horizontal Derivative
32   USE asmpar          ! Parameters for the assmilation interface
33   USE c1d             ! 1D initialization
34   USE sbc_oce         ! Surface boundary condition variables.
35   USE diaobs   , ONLY : calc_date     ! Compute the calendar date on a given step
36#if defined key_lim3
37   USE ice      , ONLY : hm_i, at_i, at_i_b
[3764]38#endif
[9019]39   !
40   USE in_out_manager  ! I/O manager
41   USE iom             ! Library to read input files
42   USE lib_mpp         ! MPP library
[2128]43
44   IMPLICIT NONE
45   PRIVATE
[2392]46   
47   PUBLIC   asm_inc_init   !: Initialize the increment arrays and IAU weights
48   PUBLIC   tra_asm_inc    !: Apply the tracer (T and S) increments
49   PUBLIC   dyn_asm_inc    !: Apply the dynamic (u and v) increments
50   PUBLIC   ssh_asm_inc    !: Apply the SSH increment
[9023]51   PUBLIC   ssh_asm_div    !: Apply the SSH divergence
[3764]52   PUBLIC   seaice_asm_inc !: Apply the seaice increment
[2128]53
54#if defined key_asminc
[2392]55    LOGICAL, PUBLIC, PARAMETER :: lk_asminc = .TRUE.   !: Logical switch for assimilation increment interface
[2128]56#else
[2392]57    LOGICAL, PUBLIC, PARAMETER :: lk_asminc = .FALSE.  !: No assimilation increments
[2128]58#endif
[5836]59   LOGICAL, PUBLIC :: ln_bkgwri     !: No output of the background state fields
60   LOGICAL, PUBLIC :: ln_asmiau     !: No applying forcing with an assimilation increment
61   LOGICAL, PUBLIC :: ln_asmdin     !: No direct initialization
62   LOGICAL, PUBLIC :: ln_trainc     !: No tracer (T and S) assimilation increments
63   LOGICAL, PUBLIC :: ln_dyninc     !: No dynamics (u and v) assimilation increments
64   LOGICAL, PUBLIC :: ln_sshinc     !: No sea surface height assimilation increment
65   LOGICAL, PUBLIC :: ln_seaiceinc  !: No sea ice concentration increment
66   LOGICAL, PUBLIC :: ln_salfix     !: Apply minimum salinity check
[3764]67   LOGICAL, PUBLIC :: ln_temnofreeze = .FALSE. !: Don't allow the temperature to drop below freezing
[5836]68   INTEGER, PUBLIC :: nn_divdmp     !: Apply divergence damping filter nn_divdmp times
[2128]69
[2392]70   REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE ::   t_bkg   , s_bkg      !: Background temperature and salinity
71   REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE ::   u_bkg   , v_bkg      !: Background u- & v- velocity components
72   REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE ::   t_bkginc, s_bkginc   !: Increment to the background T & S
73   REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE ::   u_bkginc, v_bkginc   !: Increment to the u- & v-components
74   REAL(wp), PUBLIC, DIMENSION(:)    , ALLOCATABLE ::   wgtiau               !: IAU weights for each time step
[2128]75#if defined key_asminc
[9213]76   REAL(wp), PUBLIC, DIMENSION(:,:)  , ALLOCATABLE ::   ssh_iau              !: IAU-weighted sea surface height increment
[2128]77#endif
[2392]78   !                                !!! time steps relative to the cycle interval [0,nitend-nit000-1]
79   INTEGER , PUBLIC ::   nitbkg      !: Time step of the background state used in the Jb term
80   INTEGER , PUBLIC ::   nitdin      !: Time step of the background state for direct initialization
81   INTEGER , PUBLIC ::   nitiaustr   !: Time step of the start of the IAU interval
82   INTEGER , PUBLIC ::   nitiaufin   !: Time step of the end of the IAU interval
83   !
84   INTEGER , PUBLIC ::   niaufn      !: Type of IAU weighing function: = 0   Constant weighting
85   !                                 !: = 1   Linear hat-like, centred in middle of IAU interval
86   REAL(wp), PUBLIC ::   salfixmin   !: Ensure that the salinity is larger than this  value if (ln_salfix)
[2128]87
[2392]88   REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   ssh_bkg, ssh_bkginc   ! Background sea surface height and its increment
[3764]89   REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   seaice_bkginc         ! Increment to the background sea ice conc
[8030]90#if defined key_cice && defined key_asminc
91   REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   ndaice_da             ! ice increment tendency into CICE
92#endif
[2128]93
[3294]94   !! * Substitutions
95#  include "vectopt_loop_substitute.h90"
[2287]96   !!----------------------------------------------------------------------
[6140]97   !! NEMO/OPA 3.7 , NEMO Consortium (2015)
[2287]98   !! $Id$
[2392]99   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[2287]100   !!----------------------------------------------------------------------
[2128]101CONTAINS
102
103   SUBROUTINE asm_inc_init
104      !!----------------------------------------------------------------------
105      !!                    ***  ROUTINE asm_inc_init  ***
106      !!         
107      !! ** Purpose : Initialize the assimilation increment and IAU weights.
108      !!
109      !! ** Method  : Initialize the assimilation increment and IAU weights.
110      !!
111      !! ** Action  :
112      !!----------------------------------------------------------------------
[4990]113      INTEGER :: ji, jj, jk, jt  ! dummy loop indices
114      INTEGER :: imid, inum      ! local integers
115      INTEGER :: ios             ! Local integer output status for namelist read
[2128]116      INTEGER :: iiauper         ! Number of time steps in the IAU period
117      INTEGER :: icycper         ! Number of time steps in the cycle
[6140]118      REAL(KIND=dp) :: ditend_date     ! Date YYYYMMDD.HHMMSS of final time step
119      REAL(KIND=dp) :: ditbkg_date     ! Date YYYYMMDD.HHMMSS of background time step for Jb term
120      REAL(KIND=dp) :: ditdin_date     ! Date YYYYMMDD.HHMMSS of background time step for DI
121      REAL(KIND=dp) :: ditiaustr_date  ! Date YYYYMMDD.HHMMSS of IAU interval start time step
122      REAL(KIND=dp) :: ditiaufin_date  ! Date YYYYMMDD.HHMMSS of IAU interval final time step
123
[2128]124      REAL(wp) :: znorm        ! Normalization factor for IAU weights
[4990]125      REAL(wp) :: ztotwgt      ! Value of time-integrated IAU weights (should be equal to one)
[2128]126      REAL(wp) :: z_inc_dateb  ! Start date of interval on which increment is valid
127      REAL(wp) :: z_inc_datef  ! End date of interval on which increment is valid
128      REAL(wp) :: zdate_bkg    ! Date in background state file for DI
129      REAL(wp) :: zdate_inc    ! Time axis in increments file
[4990]130      !
[9019]131      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zhdiv   ! 2D workspace
[2392]132      !!
[3764]133      NAMELIST/nam_asminc/ ln_bkgwri,                                      &
[2392]134         &                 ln_trainc, ln_dyninc, ln_sshinc,                &
135         &                 ln_asmdin, ln_asmiau,                           &
136         &                 nitbkg, nitdin, nitiaustr, nitiaufin, niaufn,   &
[4990]137         &                 ln_salfix, salfixmin, nn_divdmp
[2392]138      !!----------------------------------------------------------------------
[2128]139
140      !-----------------------------------------------------------------------
141      ! Read Namelist nam_asminc : assimilation increment interface
142      !-----------------------------------------------------------------------
[5836]143      ln_seaiceinc   = .FALSE.
[3764]144      ln_temnofreeze = .FALSE.
[2128]145
[4147]146      REWIND( numnam_ref )              ! Namelist nam_asminc in reference namelist : Assimilation increment
147      READ  ( numnam_ref, nam_asminc, IOSTAT = ios, ERR = 901)
[9168]148901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'nam_asminc in reference namelist', lwp )
[4147]149      REWIND( numnam_cfg )              ! Namelist nam_asminc in configuration namelist : Assimilation increment
150      READ  ( numnam_cfg, nam_asminc, IOSTAT = ios, ERR = 902 )
[9168]151902   IF( ios >  0 )   CALL ctl_nam ( ios , 'nam_asminc in configuration namelist', lwp )
[4624]152      IF(lwm) WRITE ( numond, nam_asminc )
[4147]153
[2128]154      ! Control print
155      IF(lwp) THEN
156         WRITE(numout,*)
157         WRITE(numout,*) 'asm_inc_init : Assimilation increment initialization :'
158         WRITE(numout,*) '~~~~~~~~~~~~'
[2392]159         WRITE(numout,*) '   Namelist namasm : set assimilation increment parameters'
160         WRITE(numout,*) '      Logical switch for writing out background state          ln_bkgwri = ', ln_bkgwri
161         WRITE(numout,*) '      Logical switch for applying tracer increments            ln_trainc = ', ln_trainc
162         WRITE(numout,*) '      Logical switch for applying velocity increments          ln_dyninc = ', ln_dyninc
163         WRITE(numout,*) '      Logical switch for applying SSH increments               ln_sshinc = ', ln_sshinc
164         WRITE(numout,*) '      Logical switch for Direct Initialization (DI)            ln_asmdin = ', ln_asmdin
[3764]165         WRITE(numout,*) '      Logical switch for applying sea ice increments        ln_seaiceinc = ', ln_seaiceinc
[2392]166         WRITE(numout,*) '      Logical switch for Incremental Analysis Updating (IAU)   ln_asmiau = ', ln_asmiau
167         WRITE(numout,*) '      Timestep of background in [0,nitend-nit000-1]            nitbkg    = ', nitbkg
168         WRITE(numout,*) '      Timestep of background for DI in [0,nitend-nit000-1]     nitdin    = ', nitdin
169         WRITE(numout,*) '      Timestep of start of IAU interval in [0,nitend-nit000-1] nitiaustr = ', nitiaustr
170         WRITE(numout,*) '      Timestep of end of IAU interval in [0,nitend-nit000-1]   nitiaufin = ', nitiaufin
171         WRITE(numout,*) '      Type of IAU weighting function                           niaufn    = ', niaufn
172         WRITE(numout,*) '      Logical switch for ensuring that the sa > salfixmin      ln_salfix = ', ln_salfix
173         WRITE(numout,*) '      Minimum salinity after applying the increments           salfixmin = ', salfixmin
[2128]174      ENDIF
175
[9019]176      nitbkg_r    = nitbkg    + nit000 - 1            ! Background time referenced to nit000
177      nitdin_r    = nitdin    + nit000 - 1            ! Background time for DI referenced to nit000
178      nitiaustr_r = nitiaustr + nit000 - 1            ! Start of IAU interval referenced to nit000
179      nitiaufin_r = nitiaufin + nit000 - 1            ! End of IAU interval referenced to nit000
[2128]180
[9019]181      iiauper     = nitiaufin_r - nitiaustr_r + 1     ! IAU interval length
182      icycper     = nitend      - nit000      + 1     ! Cycle interval length
[2128]183
[9019]184      CALL calc_date( nitend     , ditend_date    )   ! Date of final time step
185      CALL calc_date( nitbkg_r   , ditbkg_date    )   ! Background time for Jb referenced to ndate0
186      CALL calc_date( nitdin_r   , ditdin_date    )   ! Background time for DI referenced to ndate0
187      CALL calc_date( nitiaustr_r, ditiaustr_date )   ! IAU start time referenced to ndate0
188      CALL calc_date( nitiaufin_r, ditiaufin_date )   ! IAU end time referenced to ndate0
[6140]189
[2128]190      IF(lwp) THEN
191         WRITE(numout,*)
192         WRITE(numout,*) '   Time steps referenced to current cycle:'
193         WRITE(numout,*) '       iitrst      = ', nit000 - 1
194         WRITE(numout,*) '       nit000      = ', nit000
195         WRITE(numout,*) '       nitend      = ', nitend
196         WRITE(numout,*) '       nitbkg_r    = ', nitbkg_r
197         WRITE(numout,*) '       nitdin_r    = ', nitdin_r
198         WRITE(numout,*) '       nitiaustr_r = ', nitiaustr_r
199         WRITE(numout,*) '       nitiaufin_r = ', nitiaufin_r
200         WRITE(numout,*)
201         WRITE(numout,*) '   Dates referenced to current cycle:'
202         WRITE(numout,*) '       ndastp         = ', ndastp
203         WRITE(numout,*) '       ndate0         = ', ndate0
[6140]204         WRITE(numout,*) '       nn_time0       = ', nn_time0
205         WRITE(numout,*) '       ditend_date    = ', ditend_date
206         WRITE(numout,*) '       ditbkg_date    = ', ditbkg_date
207         WRITE(numout,*) '       ditdin_date    = ', ditdin_date
208         WRITE(numout,*) '       ditiaustr_date = ', ditiaustr_date
209         WRITE(numout,*) '       ditiaufin_date = ', ditiaufin_date
[2128]210      ENDIF
211
212
213      IF ( ( ln_asmdin ).AND.( ln_asmiau ) )   &
214         & CALL ctl_stop( ' ln_asmdin and ln_asmiau :', &
215         &                ' Choose Direct Initialization OR Incremental Analysis Updating')
216
217      IF (      ( ( .NOT. ln_asmdin ).AND.( .NOT. ln_asmiau ) ) &
[3764]218           .AND.( ( ln_trainc ).OR.( ln_dyninc ).OR.( ln_sshinc ) .OR. ( ln_seaiceinc) )) &
219         & CALL ctl_stop( ' One or more of ln_trainc, ln_dyninc, ln_sshinc and ln_seaiceinc is set to .true.', &
[2128]220         &                ' but ln_asmdin and ln_asmiau are both set to .false. :', &
221         &                ' Inconsistent options')
222
223      IF ( ( niaufn /= 0 ).AND.( niaufn /= 1 ) ) &
224         & CALL ctl_stop( ' niaufn /= 0 or niaufn /=1 :',  &
225         &                ' Type IAU weighting function is invalid')
226
[3764]227      IF ( ( .NOT. ln_trainc ).AND.( .NOT. ln_dyninc ).AND.( .NOT. ln_sshinc ).AND.( .NOT. ln_seaiceinc ) &
[2128]228         &                     )  &
[3764]229         & CALL ctl_warn( ' ln_trainc, ln_dyninc, ln_sshinc and ln_seaiceinc are set to .false. :', &
[2128]230         &                ' The assimilation increments are not applied')
231
232      IF ( ( ln_asmiau ).AND.( nitiaustr == nitiaufin ) ) &
233         & CALL ctl_stop( ' nitiaustr = nitiaufin :',  &
234         &                ' IAU interval is of zero length')
235
236      IF ( ( ln_asmiau ).AND.( ( nitiaustr_r < nit000 ).OR.( nitiaufin_r > nitend ) ) ) &
237         & CALL ctl_stop( ' nitiaustr or nitiaufin :',  &
238         &                ' IAU starting or final time step is outside the cycle interval', &
239         &                 ' Valid range nit000 to nitend')
240
241      IF ( ( nitbkg_r < nit000 - 1 ).OR.( nitbkg_r > nitend ) ) &
242         & CALL ctl_stop( ' nitbkg :',  &
243         &                ' Background time step is outside the cycle interval')
244
245      IF ( ( nitdin_r < nit000 - 1 ).OR.( nitdin_r > nitend ) ) &
246         & CALL ctl_stop( ' nitdin :',  &
247         &                ' Background time step for Direct Initialization is outside', &
248         &                ' the cycle interval')
249
250      IF ( nstop > 0 ) RETURN       ! if there are any errors then go no further
251
252      !--------------------------------------------------------------------
253      ! Initialize the Incremental Analysis Updating weighting function
254      !--------------------------------------------------------------------
255
[9213]256      IF( ln_asmiau ) THEN
257         !
[2128]258         ALLOCATE( wgtiau( icycper ) )
[9213]259         !
[9019]260         wgtiau(:) = 0._wp
[9213]261         !
262         !                                !---------------------------------------------------------
263         IF( niaufn == 0 ) THEN           ! Constant IAU forcing
264            !                             !---------------------------------------------------------
[2128]265            DO jt = 1, iiauper
266               wgtiau(jt+nitiaustr-1) = 1.0 / REAL( iiauper )
267            END DO
[9213]268            !                             !---------------------------------------------------------
269         ELSEIF ( niaufn == 1 ) THEN      ! Linear hat-like, centred in middle of IAU interval
270            !                             !---------------------------------------------------------
[2128]271            ! Compute the normalization factor
[9213]272            znorm = 0._wp
273            IF( MOD( iiauper, 2 ) == 0 ) THEN   ! Even number of time steps in IAU interval
[2128]274               imid = iiauper / 2 
275               DO jt = 1, imid
276                  znorm = znorm + REAL( jt )
277               END DO
278               znorm = 2.0 * znorm
[9213]279            ELSE                                ! Odd number of time steps in IAU interval
[2128]280               imid = ( iiauper + 1 ) / 2       
281               DO jt = 1, imid - 1
282                  znorm = znorm + REAL( jt )
283               END DO
284               znorm = 2.0 * znorm + REAL( imid )
285            ENDIF
286            znorm = 1.0 / znorm
[9213]287            !
[2128]288            DO jt = 1, imid - 1
289               wgtiau(jt+nitiaustr-1) = REAL( jt ) * znorm
290            END DO
291            DO jt = imid, iiauper
292               wgtiau(jt+nitiaustr-1) = REAL( iiauper - jt + 1 ) * znorm
293            END DO
[9213]294            !
[2128]295         ENDIF
296
297         ! Test that the integral of the weights over the weighting interval equals 1
298          IF(lwp) THEN
299             WRITE(numout,*)
300             WRITE(numout,*) 'asm_inc_init : IAU weights'
301             WRITE(numout,*) '~~~~~~~~~~~~'
302             WRITE(numout,*) '             time step         IAU  weight'
303             WRITE(numout,*) '             =========     ====================='
304             ztotwgt = 0.0
305             DO jt = 1, icycper
306                ztotwgt = ztotwgt + wgtiau(jt)
307                WRITE(numout,*) '         ', jt, '       ', wgtiau(jt) 
308             END DO   
309             WRITE(numout,*) '         ==================================='
310             WRITE(numout,*) '         Time-integrated weight = ', ztotwgt
311             WRITE(numout,*) '         ==================================='
312          ENDIF
313         
314      ENDIF
315
316      !--------------------------------------------------------------------
317      ! Allocate and initialize the increment arrays
318      !--------------------------------------------------------------------
319
[9213]320      ALLOCATE( t_bkginc     (jpi,jpj,jpk) )   ;   t_bkginc     (:,:,:) = 0._wp
321      ALLOCATE( s_bkginc     (jpi,jpj,jpk) )   ;   s_bkginc     (:,:,:) = 0._wp
322      ALLOCATE( u_bkginc     (jpi,jpj,jpk) )   ;   u_bkginc     (:,:,:) = 0._wp
323      ALLOCATE( v_bkginc     (jpi,jpj,jpk) )   ;   v_bkginc     (:,:,:) = 0._wp
324      ALLOCATE( ssh_bkginc   (jpi,jpj)     )   ;   ssh_bkginc   (:,:)   = 0._wp
325      ALLOCATE( seaice_bkginc(jpi,jpj)     )   ;   seaice_bkginc(:,:)   = 0._wp
[2128]326#if defined key_asminc
[9213]327      ALLOCATE( ssh_iau      (jpi,jpj)     )   ;   ssh_iau      (:,:)   = 0._wp
[2128]328#endif
[8030]329#if defined key_cice && defined key_asminc
[9213]330      ALLOCATE( ndaice_da    (jpi,jpj)     )   ;   ndaice_da    (:,:)   = 0._wp
[8030]331#endif
[9213]332      !
333      IF ( ln_trainc .OR. ln_dyninc .OR.   &       !--------------------------------------
334         & ln_sshinc .OR. ln_seaiceinc   ) THEN    ! Read the increments from file
335         !                                         !--------------------------------------
[2128]336         CALL iom_open( c_asminc, inum )
[9213]337         !
338         CALL iom_get( inum, 'time'       , zdate_inc   ) 
[2128]339         CALL iom_get( inum, 'z_inc_dateb', z_inc_dateb )
340         CALL iom_get( inum, 'z_inc_datef', z_inc_datef )
341         z_inc_dateb = zdate_inc
342         z_inc_datef = zdate_inc
[9213]343         !
[2128]344         IF(lwp) THEN
345            WRITE(numout,*) 
[9213]346            WRITE(numout,*) 'asm_inc_init : Assimilation increments valid between dates ', z_inc_dateb,' and ', z_inc_datef
[2128]347            WRITE(numout,*) '~~~~~~~~~~~~'
348         ENDIF
[9213]349         !
350         IF ( ( z_inc_dateb < ndastp + nn_time0*0.0001_wp ) .OR.   &
351            & ( z_inc_datef > ditend_date ) ) &
352            &    CALL ctl_warn( ' Validity time of assimilation increments is ', &
353            &                   ' outside the assimilation interval' )
[2128]354
[6140]355         IF ( ( ln_asmdin ).AND.( zdate_inc /= ditdin_date ) ) &
[2128]356            & CALL ctl_warn( ' Validity time of assimilation increments does ', &
357            &                ' not agree with Direct Initialization time' )
358
359         IF ( ln_trainc ) THEN   
360            CALL iom_get( inum, jpdom_autoglo, 'bckint', t_bkginc, 1 )
361            CALL iom_get( inum, jpdom_autoglo, 'bckins', s_bkginc, 1 )
362            ! Apply the masks
363            t_bkginc(:,:,:) = t_bkginc(:,:,:) * tmask(:,:,:)
364            s_bkginc(:,:,:) = s_bkginc(:,:,:) * tmask(:,:,:)
365            ! Set missing increments to 0.0 rather than 1e+20
366            ! to allow for differences in masks
367            WHERE( ABS( t_bkginc(:,:,:) ) > 1.0e+10 ) t_bkginc(:,:,:) = 0.0
368            WHERE( ABS( s_bkginc(:,:,:) ) > 1.0e+10 ) s_bkginc(:,:,:) = 0.0
369         ENDIF
370
371         IF ( ln_dyninc ) THEN   
372            CALL iom_get( inum, jpdom_autoglo, 'bckinu', u_bkginc, 1 )             
373            CALL iom_get( inum, jpdom_autoglo, 'bckinv', v_bkginc, 1 )             
374            ! Apply the masks
375            u_bkginc(:,:,:) = u_bkginc(:,:,:) * umask(:,:,:)
376            v_bkginc(:,:,:) = v_bkginc(:,:,:) * vmask(:,:,:)
377            ! Set missing increments to 0.0 rather than 1e+20
378            ! to allow for differences in masks
379            WHERE( ABS( u_bkginc(:,:,:) ) > 1.0e+10 ) u_bkginc(:,:,:) = 0.0
380            WHERE( ABS( v_bkginc(:,:,:) ) > 1.0e+10 ) v_bkginc(:,:,:) = 0.0
381         ENDIF
382       
383         IF ( ln_sshinc ) THEN
384            CALL iom_get( inum, jpdom_autoglo, 'bckineta', ssh_bkginc, 1 )
385            ! Apply the masks
386            ssh_bkginc(:,:) = ssh_bkginc(:,:) * tmask(:,:,1)
387            ! Set missing increments to 0.0 rather than 1e+20
388            ! to allow for differences in masks
389            WHERE( ABS( ssh_bkginc(:,:) ) > 1.0e+10 ) ssh_bkginc(:,:) = 0.0
390         ENDIF
391
[3764]392         IF ( ln_seaiceinc ) THEN
393            CALL iom_get( inum, jpdom_autoglo, 'bckinseaice', seaice_bkginc, 1 )
394            ! Apply the masks
395            seaice_bkginc(:,:) = seaice_bkginc(:,:) * tmask(:,:,1)
396            ! Set missing increments to 0.0 rather than 1e+20
397            ! to allow for differences in masks
398            WHERE( ABS( seaice_bkginc(:,:) ) > 1.0e+10 ) seaice_bkginc(:,:) = 0.0
399         ENDIF
[9213]400         !
[2128]401         CALL iom_close( inum )
[9213]402         !
[2128]403      ENDIF
[9213]404      !
405      !                                            !--------------------------------------
406      IF ( ln_dyninc .AND. nn_divdmp > 0 ) THEN    ! Apply divergence damping filter
407         !                                         !--------------------------------------
[9019]408         ALLOCATE( zhdiv(jpi,jpj) ) 
[5836]409         !
410         DO jt = 1, nn_divdmp
411            !
[9019]412            DO jk = 1, jpkm1           ! zhdiv = e1e1 * div
413               zhdiv(:,:) = 0._wp
[3764]414               DO jj = 2, jpjm1
415                  DO ji = fs_2, fs_jpim1   ! vector opt.
[9019]416                     zhdiv(ji,jj) = (  e2u(ji  ,jj) * e3u_n(ji  ,jj,jk) * u_bkginc(ji  ,jj,jk)    &
417                        &            - e2u(ji-1,jj) * e3u_n(ji-1,jj,jk) * u_bkginc(ji-1,jj,jk)    &
418                        &            + e1v(ji,jj  ) * e3v_n(ji,jj  ,jk) * v_bkginc(ji,jj  ,jk)    &
419                        &            - e1v(ji,jj-1) * e3v_n(ji,jj-1,jk) * v_bkginc(ji,jj-1,jk)  ) / e3t_n(ji,jj,jk)
[3764]420                  END DO
[3294]421               END DO
[9019]422               CALL lbc_lnk( zhdiv, 'T', 1. )   ! lateral boundary cond. (no sign change)
[5836]423               !
[3764]424               DO jj = 2, jpjm1
425                  DO ji = fs_2, fs_jpim1   ! vector opt.
[6140]426                     u_bkginc(ji,jj,jk) = u_bkginc(ji,jj,jk)                         &
[9019]427                        &               + 0.2_wp * ( zhdiv(ji+1,jj) - zhdiv(ji  ,jj) ) * r1_e1u(ji,jj) * umask(ji,jj,jk)
[6140]428                     v_bkginc(ji,jj,jk) = v_bkginc(ji,jj,jk)                         &
[9019]429                        &               + 0.2_wp * ( zhdiv(ji,jj+1) - zhdiv(ji,jj  ) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk) 
[3764]430                  END DO
[3294]431               END DO
432            END DO
[5836]433            !
[3764]434         END DO
[5836]435         !
[9019]436         DEALLOCATE( zhdiv ) 
[5836]437         !
[3294]438      ENDIF
[9213]439      !
440      !                             !-----------------------------------------------------
441      IF ( ln_asmdin ) THEN         ! Allocate and initialize the background state arrays
442         !                          !-----------------------------------------------------
[5836]443         !
[9213]444         ALLOCATE( t_bkg  (jpi,jpj,jpk) )   ;   t_bkg  (:,:,:) = 0._wp
445         ALLOCATE( s_bkg  (jpi,jpj,jpk) )   ;   s_bkg  (:,:,:) = 0._wp
446         ALLOCATE( u_bkg  (jpi,jpj,jpk) )   ;   u_bkg  (:,:,:) = 0._wp
447         ALLOCATE( v_bkg  (jpi,jpj,jpk) )   ;   v_bkg  (:,:,:) = 0._wp
448         ALLOCATE( ssh_bkg(jpi,jpj)     )   ;   ssh_bkg(:,:)   = 0._wp
[5836]449         !
450         !
[2128]451         !--------------------------------------------------------------------
452         ! Read from file the background state at analysis time
453         !--------------------------------------------------------------------
[5836]454         !
[2128]455         CALL iom_open( c_asmdin, inum )
[5836]456         !
[3764]457         CALL iom_get( inum, 'rdastp', zdate_bkg ) 
[5836]458         !
[2128]459         IF(lwp) THEN
460            WRITE(numout,*) 
[9213]461            WRITE(numout,*) '   ==>>>  Assimilation background state valid at : ', zdate_bkg
462            WRITE(numout,*)
[2128]463         ENDIF
[5836]464         !
[9213]465         IF ( zdate_bkg /= ditdin_date )   &
[2128]466            & CALL ctl_warn( ' Validity time of assimilation background state does', &
467            &                ' not agree with Direct Initialization time' )
[5836]468         !
[2128]469         IF ( ln_trainc ) THEN   
470            CALL iom_get( inum, jpdom_autoglo, 'tn', t_bkg )
471            CALL iom_get( inum, jpdom_autoglo, 'sn', s_bkg )
472            t_bkg(:,:,:) = t_bkg(:,:,:) * tmask(:,:,:)
473            s_bkg(:,:,:) = s_bkg(:,:,:) * tmask(:,:,:)
474         ENDIF
[5836]475         !
[2128]476         IF ( ln_dyninc ) THEN   
477            CALL iom_get( inum, jpdom_autoglo, 'un', u_bkg )
478            CALL iom_get( inum, jpdom_autoglo, 'vn', v_bkg )
479            u_bkg(:,:,:) = u_bkg(:,:,:) * umask(:,:,:)
480            v_bkg(:,:,:) = v_bkg(:,:,:) * vmask(:,:,:)
481         ENDIF
[5836]482         !
[2128]483         IF ( ln_sshinc ) THEN
484            CALL iom_get( inum, jpdom_autoglo, 'sshn', ssh_bkg )
485            ssh_bkg(:,:) = ssh_bkg(:,:) * tmask(:,:,1)
486         ENDIF
[5836]487         !
[2128]488         CALL iom_close( inum )
[5836]489         !
[2128]490      ENDIF
[2392]491      !
[9213]492      IF(lwp) WRITE(numout,*) '   ==>>>   Euler time step switch is ', neuler
493      !
494      IF( lk_asminc ) THEN                            !==  data assimilation  ==!
495         IF( ln_bkgwri )   CALL asm_bkg_wri( nit000 - 1 )      ! Output background fields
496         IF( ln_asmdin ) THEN                                  ! Direct initialization
497            IF( ln_trainc )   CALL tra_asm_inc( nit000 - 1 )      ! Tracers
498            IF( ln_dyninc )   CALL dyn_asm_inc( nit000 - 1 )      ! Dynamics
499            IF( ln_sshinc )   CALL ssh_asm_inc( nit000 - 1 )      ! SSH
500         ENDIF
501      ENDIF
502      !
[2128]503   END SUBROUTINE asm_inc_init
[9213]504   
505   
[2128]506   SUBROUTINE tra_asm_inc( kt )
507      !!----------------------------------------------------------------------
508      !!                    ***  ROUTINE tra_asm_inc  ***
509      !!         
510      !! ** Purpose : Apply the tracer (T and S) assimilation increments
511      !!
512      !! ** Method  : Direct initialization or Incremental Analysis Updating
513      !!
514      !! ** Action  :
515      !!----------------------------------------------------------------------
[5836]516      INTEGER, INTENT(IN) ::   kt   ! Current time step
[2392]517      !
[5836]518      INTEGER  :: ji, jj, jk
519      INTEGER  :: it
[2128]520      REAL(wp) :: zincwgt  ! IAU weight for current time step
[3764]521      REAL (wp), DIMENSION(jpi,jpj,jpk) :: fzptnz ! 3d freezing point values
[2392]522      !!----------------------------------------------------------------------
[5836]523      !
[3764]524      ! freezing point calculation taken from oc_fz_pt (but calculated for all depths)
525      ! used to prevent the applied increments taking the temperature below the local freezing point
[4990]526      DO jk = 1, jpkm1
[6140]527        CALL eos_fzp( tsn(:,:,jk,jp_sal), fzptnz(:,:,jk), gdept_n(:,:,jk) )
[4990]528      END DO
[5836]529         !
530         !                             !--------------------------------------
531      IF ( ln_asmiau ) THEN            ! Incremental Analysis Updating
532         !                             !--------------------------------------
533         !
[2128]534         IF ( ( kt >= nitiaustr_r ).AND.( kt <= nitiaufin_r ) ) THEN
[5836]535            !
[2128]536            it = kt - nit000 + 1
537            zincwgt = wgtiau(it) / rdt   ! IAU weight for the current time step
[5836]538            !
[2128]539            IF(lwp) THEN
540               WRITE(numout,*) 
[4990]541               WRITE(numout,*) 'tra_asm_inc : Tracer IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
[2128]542               WRITE(numout,*) '~~~~~~~~~~~~'
543            ENDIF
[5836]544            !
[2128]545            ! Update the tracer tendencies
546            DO jk = 1, jpkm1
[3764]547               IF (ln_temnofreeze) THEN
548                  ! Do not apply negative increments if the temperature will fall below freezing
549                  WHERE(t_bkginc(:,:,jk) > 0.0_wp .OR. &
550                     &   tsn(:,:,jk,jp_tem) + tsa(:,:,jk,jp_tem) + t_bkginc(:,:,jk) * wgtiau(it) > fzptnz(:,:,jk) ) 
551                     tsa(:,:,jk,jp_tem) = tsa(:,:,jk,jp_tem) + t_bkginc(:,:,jk) * zincwgt 
552                  END WHERE
553               ELSE
554                  tsa(:,:,jk,jp_tem) = tsa(:,:,jk,jp_tem) + t_bkginc(:,:,jk) * zincwgt 
555               ENDIF
556               IF (ln_salfix) THEN
557                  ! Do not apply negative increments if the salinity will fall below a specified
558                  ! minimum value salfixmin
559                  WHERE(s_bkginc(:,:,jk) > 0.0_wp .OR. &
560                     &   tsn(:,:,jk,jp_sal) + tsa(:,:,jk,jp_sal) + s_bkginc(:,:,jk) * wgtiau(it) > salfixmin ) 
561                     tsa(:,:,jk,jp_sal) = tsa(:,:,jk,jp_sal) + s_bkginc(:,:,jk) * zincwgt
562                  END WHERE
563               ELSE
564                  tsa(:,:,jk,jp_sal) = tsa(:,:,jk,jp_sal) + s_bkginc(:,:,jk) * zincwgt
565               ENDIF
[2128]566            END DO
[5836]567            !
[2128]568         ENDIF
[5836]569         !
[2128]570         IF ( kt == nitiaufin_r + 1  ) THEN   ! For bias crcn to work
571            DEALLOCATE( t_bkginc )
572            DEALLOCATE( s_bkginc )
573         ENDIF
[5836]574         !                             !--------------------------------------
575      ELSEIF ( ln_asmdin ) THEN        ! Direct Initialization
576         !                             !--------------------------------------
577         !           
[2128]578         IF ( kt == nitdin_r ) THEN
[5836]579            !
[2128]580            neuler = 0  ! Force Euler forward step
[5836]581            !
[2128]582            ! Initialize the now fields with the background + increment
[3764]583            IF (ln_temnofreeze) THEN
584               ! Do not apply negative increments if the temperature will fall below freezing
[4990]585               WHERE( t_bkginc(:,:,:) > 0.0_wp .OR. tsn(:,:,:,jp_tem) + t_bkginc(:,:,:) > fzptnz(:,:,:) ) 
[3764]586                  tsn(:,:,:,jp_tem) = t_bkg(:,:,:) + t_bkginc(:,:,:)   
587               END WHERE
588            ELSE
589               tsn(:,:,:,jp_tem) = t_bkg(:,:,:) + t_bkginc(:,:,:)   
590            ENDIF
[2128]591            IF (ln_salfix) THEN
[3764]592               ! Do not apply negative increments if the salinity will fall below a specified
593               ! minimum value salfixmin
[4990]594               WHERE( s_bkginc(:,:,:) > 0.0_wp .OR. tsn(:,:,:,jp_sal) + s_bkginc(:,:,:) > salfixmin ) 
[3764]595                  tsn(:,:,:,jp_sal) = s_bkg(:,:,:) + s_bkginc(:,:,:)   
596               END WHERE
597            ELSE
598               tsn(:,:,:,jp_sal) = s_bkg(:,:,:) + s_bkginc(:,:,:)   
[2128]599            ENDIF
600
[4990]601            tsb(:,:,:,:) = tsn(:,:,:,:)                 ! Update before fields
[2128]602
[4990]603            CALL eos( tsb, rhd, rhop, gdept_0(:,:,:) )  ! Before potential and in situ densities
604!!gm  fabien
605!            CALL eos( tsb, rhd, rhop )                ! Before potential and in situ densities
606!!gm
607
[6140]608            IF( ln_zps .AND. .NOT. lk_c1d .AND. .NOT. ln_isfcav)      &
609               &  CALL zps_hde    ( kt, jpts, tsb, gtsu, gtsv,        &  ! Partial steps: before horizontal gradient
610               &                              rhd, gru , grv          )  ! of t, s, rd at the last ocean level
611            IF( ln_zps .AND. .NOT. lk_c1d .AND.       ln_isfcav)      &
612               &  CALL zps_hde_isf( nit000, jpts, tsb, gtsu, gtsv, gtui, gtvi,    &    ! Partial steps for top cell (ISF)
613               &                                  rhd, gru , grv , grui, grvi     )    ! of t, s, rd at the last ocean level
614
[2128]615            DEALLOCATE( t_bkginc )
616            DEALLOCATE( s_bkginc )
617            DEALLOCATE( t_bkg    )
618            DEALLOCATE( s_bkg    )
619         ENDIF
[2392]620         
[2128]621      ENDIF
[3764]622      ! Perhaps the following call should be in step
[5836]623      IF ( ln_seaiceinc  )   CALL seaice_asm_inc ( kt )   ! apply sea ice concentration increment
[2392]624      !
[2128]625   END SUBROUTINE tra_asm_inc
626
[2392]627
[2128]628   SUBROUTINE dyn_asm_inc( kt )
629      !!----------------------------------------------------------------------
630      !!                    ***  ROUTINE dyn_asm_inc  ***
631      !!         
632      !! ** Purpose : Apply the dynamics (u and v) assimilation increments.
633      !!
634      !! ** Method  : Direct initialization or Incremental Analysis Updating.
635      !!
636      !! ** Action  :
637      !!----------------------------------------------------------------------
638      INTEGER, INTENT(IN) :: kt   ! Current time step
[2392]639      !
[2128]640      INTEGER :: jk
641      INTEGER :: it
642      REAL(wp) :: zincwgt  ! IAU weight for current time step
[2392]643      !!----------------------------------------------------------------------
[5836]644      !
645      !                          !--------------------------------------------
646      IF ( ln_asmiau ) THEN      ! Incremental Analysis Updating
647         !                       !--------------------------------------------
648         !
[2128]649         IF ( ( kt >= nitiaustr_r ).AND.( kt <= nitiaufin_r ) ) THEN
[5836]650            !
[2128]651            it = kt - nit000 + 1
652            zincwgt = wgtiau(it) / rdt   ! IAU weight for the current time step
[5836]653            !
[2128]654            IF(lwp) THEN
655               WRITE(numout,*) 
[5836]656               WRITE(numout,*) 'dyn_asm_inc : Dynamics IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
[2128]657               WRITE(numout,*) '~~~~~~~~~~~~'
658            ENDIF
[5836]659            !
[2128]660            ! Update the dynamic tendencies
661            DO jk = 1, jpkm1
662               ua(:,:,jk) = ua(:,:,jk) + u_bkginc(:,:,jk) * zincwgt
663               va(:,:,jk) = va(:,:,jk) + v_bkginc(:,:,jk) * zincwgt
664            END DO
[5836]665            !
[2128]666            IF ( kt == nitiaufin_r ) THEN
667               DEALLOCATE( u_bkginc )
668               DEALLOCATE( v_bkginc )
669            ENDIF
[5836]670            !
[2128]671         ENDIF
[5836]672         !                          !-----------------------------------------
673      ELSEIF ( ln_asmdin ) THEN     ! Direct Initialization
674         !                          !-----------------------------------------
675         !         
[2128]676         IF ( kt == nitdin_r ) THEN
[5836]677            !
[2128]678            neuler = 0                    ! Force Euler forward step
[5836]679            !
[2128]680            ! Initialize the now fields with the background + increment
681            un(:,:,:) = u_bkg(:,:,:) + u_bkginc(:,:,:)
682            vn(:,:,:) = v_bkg(:,:,:) + v_bkginc(:,:,:) 
[5836]683            !
[2128]684            ub(:,:,:) = un(:,:,:)         ! Update before fields
685            vb(:,:,:) = vn(:,:,:)
[5836]686            !
[2128]687            DEALLOCATE( u_bkg    )
688            DEALLOCATE( v_bkg    )
689            DEALLOCATE( u_bkginc )
690            DEALLOCATE( v_bkginc )
691         ENDIF
[2392]692         !
[2128]693      ENDIF
[2392]694      !
[2128]695   END SUBROUTINE dyn_asm_inc
696
[2392]697
[2128]698   SUBROUTINE ssh_asm_inc( kt )
699      !!----------------------------------------------------------------------
700      !!                    ***  ROUTINE ssh_asm_inc  ***
701      !!         
702      !! ** Purpose : Apply the sea surface height assimilation increment.
703      !!
704      !! ** Method  : Direct initialization or Incremental Analysis Updating.
705      !!
706      !! ** Action  :
707      !!----------------------------------------------------------------------
708      INTEGER, INTENT(IN) :: kt   ! Current time step
[2392]709      !
[2128]710      INTEGER :: it
[3764]711      INTEGER :: jk
[2128]712      REAL(wp) :: zincwgt  ! IAU weight for current time step
[2392]713      !!----------------------------------------------------------------------
[5836]714      !
715      !                             !-----------------------------------------
716      IF ( ln_asmiau ) THEN         ! Incremental Analysis Updating
717         !                          !-----------------------------------------
718         !
[2128]719         IF ( ( kt >= nitiaustr_r ).AND.( kt <= nitiaufin_r ) ) THEN
[5836]720            !
[2128]721            it = kt - nit000 + 1
722            zincwgt = wgtiau(it) / rdt   ! IAU weight for the current time step
[5836]723            !
[2128]724            IF(lwp) THEN
725               WRITE(numout,*) 
726               WRITE(numout,*) 'ssh_asm_inc : SSH IAU at time step = ', &
727                  &  kt,' with IAU weight = ', wgtiau(it)
728               WRITE(numout,*) '~~~~~~~~~~~~'
729            ENDIF
[5836]730            !
[2128]731            ! Save the tendency associated with the IAU weighted SSH increment
732            ! (applied in dynspg.*)
733#if defined key_asminc
734            ssh_iau(:,:) = ssh_bkginc(:,:) * zincwgt
735#endif
736            IF ( kt == nitiaufin_r ) THEN
737               DEALLOCATE( ssh_bkginc )
738            ENDIF
[5836]739            !
[8552]740#if defined key_asminc
[8547]741         ELSE IF( kt == nitiaufin_r+1 ) THEN
[8546]742            !
743            ssh_iau(:,:) = 0._wp
744            !
[8552]745#endif
[2128]746         ENDIF
[5836]747         !                          !-----------------------------------------
748      ELSEIF ( ln_asmdin ) THEN     ! Direct Initialization
749         !                          !-----------------------------------------
750         !
[2128]751         IF ( kt == nitdin_r ) THEN
[5836]752            !
753            neuler = 0                                   ! Force Euler forward step
754            !
755            sshn(:,:) = ssh_bkg(:,:) + ssh_bkginc(:,:)   ! Initialize the now fields the background + increment
756            !
757            sshb(:,:) = sshn(:,:)                        ! Update before fields
[6140]758            e3t_b(:,:,:) = e3t_n(:,:,:)
759!!gm why not e3u_b, e3v_b, gdept_b ????
[5836]760            !
[2128]761            DEALLOCATE( ssh_bkg    )
762            DEALLOCATE( ssh_bkginc )
[5836]763            !
[2128]764         ENDIF
[2392]765         !
[2128]766      ENDIF
[2392]767      !
[2128]768   END SUBROUTINE ssh_asm_inc
769
[9213]770
[9023]771   SUBROUTINE ssh_asm_div( kt, phdivn )
772      !!----------------------------------------------------------------------
773      !!                  ***  ROUTINE ssh_asm_div  ***
774      !!
775      !! ** Purpose :   ssh increment with z* is incorporated via a correction of the local divergence         
776      !!                across all the water column
777      !!
778      !! ** Method  :
779      !!                CAUTION : sshiau is positive (inflow) decreasing the
780      !!                          divergence and expressed in m/s
781      !!
782      !! ** Action  :   phdivn   decreased by the ssh increment
783      !!----------------------------------------------------------------------
784      INTEGER, INTENT(IN) :: kt                               ! ocean time-step index
785      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   phdivn   ! horizontal divergence
786      !!
787      INTEGER  ::   jk                                        ! dummy loop index
788      REAL(wp), DIMENSION(:,:)  , POINTER       ::   ztim     ! local array
789      !!----------------------------------------------------------------------
790      !
791#if defined key_asminc
792      CALL ssh_asm_inc( kt ) !==   (calculate increments)
793      !
794      IF( ln_linssh ) THEN
795         phdivn(:,:,1) = phdivn(:,:,1) - ssh_iau(:,:) / e3t_n(:,:,1) * tmask(:,:,1)
796      ELSE
[9044]797         ALLOCATE( ztim(jpi,jpj) )
[9023]798         ztim(:,:) = ssh_iau(:,:) / ( ht_n(:,:) + 1.0 - ssmask(:,:) )
799         DO jk = 1, jpkm1                                 
800            phdivn(:,:,jk) = phdivn(:,:,jk) - ztim(:,:) * tmask(:,:,jk) 
801         END DO
802         !
[9044]803         DEALLOCATE(ztim)
[9023]804      ENDIF
805#endif
806      !
807   END SUBROUTINE ssh_asm_div
[3785]808
[9213]809
[3764]810   SUBROUTINE seaice_asm_inc( kt, kindic )
811      !!----------------------------------------------------------------------
812      !!                    ***  ROUTINE seaice_asm_inc  ***
813      !!         
814      !! ** Purpose : Apply the sea ice assimilation increment.
815      !!
816      !! ** Method  : Direct initialization or Incremental Analysis Updating.
817      !!
818      !! ** Action  :
819      !!
820      !!----------------------------------------------------------------------
[5836]821      INTEGER, INTENT(in)           ::   kt       ! Current time step
[3785]822      INTEGER, INTENT(in), OPTIONAL ::   kindic   ! flag for disabling the deallocation
823      !
824      INTEGER  ::   it
825      REAL(wp) ::   zincwgt   ! IAU weight for current time step
[9019]826#if defined key_lim3
[3785]827      REAL(wp), DIMENSION(jpi,jpj) ::   zofrld, zohicif, zseaicendg, zhicifinc  ! LIM
828      REAL(wp) ::   zhicifmin = 0.5_wp      ! ice minimum depth in metres
[3764]829#endif
[3785]830      !!----------------------------------------------------------------------
[5836]831      !
832      !                             !-----------------------------------------
833      IF ( ln_asmiau ) THEN         ! Incremental Analysis Updating
834         !                          !-----------------------------------------
835         !
[3764]836         IF ( ( kt >= nitiaustr_r ).AND.( kt <= nitiaufin_r ) ) THEN
[5836]837            !
[3764]838            it = kt - nit000 + 1
839            zincwgt = wgtiau(it)      ! IAU weight for the current time step
840            ! note this is not a tendency so should not be divided by rdt (as with the tracer and other increments)
[5836]841            !
[3764]842            IF(lwp) THEN
843               WRITE(numout,*) 
[5836]844               WRITE(numout,*) 'seaice_asm_inc : sea ice conc IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
[3764]845               WRITE(numout,*) '~~~~~~~~~~~~'
846            ENDIF
[5836]847            !
[9019]848            ! Sea-ice : LIM-3 case
[5836]849            !
[9019]850#if defined key_lim3
851            zofrld (:,:) = 1._wp - at_i(:,:)
852            zohicif(:,:) = hm_i(:,:)
[3785]853            !
[9019]854            at_i  (:,:) = 1. - MIN( MAX( 1.-at_i  (:,:) - seaice_bkginc(:,:) * zincwgt, 0.0_wp), 1.0_wp)
855            at_i_b(:,:) = 1. - MIN( MAX( 1.-at_i_b(:,:) - seaice_bkginc(:,:) * zincwgt, 0.0_wp), 1.0_wp)
856            fr_i(:,:) = at_i(:,:)        ! adjust ice fraction
[3785]857            !
[9019]858            zseaicendg(:,:) = zofrld(:,:) - (1. - at_i(:,:))   ! find out actual sea ice nudge applied
[3785]859            !
[3764]860            ! Nudge sea ice depth to bring it up to a required minimum depth
[9019]861            WHERE( zseaicendg(:,:) > 0.0_wp .AND. hm_i(:,:) < zhicifmin ) 
862               zhicifinc(:,:) = (zhicifmin - hm_i(:,:)) * zincwgt   
[3764]863            ELSEWHERE
864               zhicifinc(:,:) = 0.0_wp
865            END WHERE
[3785]866            !
867            ! nudge ice depth
[9019]868            hm_i (:,:) = hm_i (:,:) + zhicifinc(:,:)
[3785]869            !
870            ! seaice salinity balancing (to add)
[3764]871#endif
[9213]872            !
[4245]873#if defined key_cice && defined key_asminc
[3785]874            ! Sea-ice : CICE case. Pass ice increment tendency into CICE
[3764]875            ndaice_da(:,:) = seaice_bkginc(:,:) * zincwgt / rdt
876#endif
[9213]877            !
[3764]878            IF ( kt == nitiaufin_r ) THEN
879               DEALLOCATE( seaice_bkginc )
880            ENDIF
[9213]881            !
[3764]882         ELSE
[9213]883            !
[4245]884#if defined key_cice && defined key_asminc
[5836]885            ndaice_da(:,:) = 0._wp        ! Sea-ice : CICE case. Zero ice increment tendency into CICE
[3764]886#endif
[9213]887            !
[3764]888         ENDIF
[5836]889         !                          !-----------------------------------------
890      ELSEIF ( ln_asmdin ) THEN     ! Direct Initialization
891         !                          !-----------------------------------------
892         !
[3764]893         IF ( kt == nitdin_r ) THEN
[5836]894            !
[3764]895            neuler = 0                    ! Force Euler forward step
[5836]896            !
[9019]897            ! Sea-ice : LIM-3 case
[5836]898            !
[9019]899#if defined key_lim3
900            zofrld (:,:) = 1._wp - at_i(:,:)
901            zohicif(:,:) = hm_i(:,:)
[3785]902            !
[3764]903            ! Initialize the now fields the background + increment
[9019]904            at_i(:,:) = 1. - MIN( MAX( 1.-at_i(:,:) - seaice_bkginc(:,:), 0.0_wp), 1.0_wp)
905            at_i_b(:,:) = at_i(:,:) 
906            fr_i(:,:) = at_i(:,:)        ! adjust ice fraction
[3785]907            !
[9019]908            zseaicendg(:,:) = zofrld(:,:) - (1. - at_i(:,:))   ! find out actual sea ice nudge applied
909            !
[3764]910            ! Nudge sea ice depth to bring it up to a required minimum depth
[9019]911            WHERE( zseaicendg(:,:) > 0.0_wp .AND. hm_i(:,:) < zhicifmin ) 
912               zhicifinc(:,:) = (zhicifmin - hm_i(:,:)) * zincwgt   
[3764]913            ELSEWHERE
[9019]914               zhicifinc(:,:) = 0.0_wp
[3764]915            END WHERE
[3785]916            !
917            ! nudge ice depth
[9019]918            hm_i (:,:) = hm_i (:,:) + zhicifinc(:,:)
[3785]919            !
920            ! seaice salinity balancing (to add)
[3764]921#endif
[5836]922            !
[4245]923#if defined key_cice && defined key_asminc
924            ! Sea-ice : CICE case. Pass ice increment tendency into CICE
[3764]925           ndaice_da(:,:) = seaice_bkginc(:,:) / rdt
926#endif
[5836]927            IF ( .NOT. PRESENT(kindic) ) THEN
928               DEALLOCATE( seaice_bkginc )
929            END IF
930            !
[3764]931         ELSE
[5836]932            !
933#if defined key_cice && defined key_asminc
934            ndaice_da(:,:) = 0._wp     ! Sea-ice : CICE case. Zero ice increment tendency into CICE
[3764]935#endif
[5836]936            !
[3764]937         ENDIF
938
[9019]939!#if defined defined key_lim3 || defined key_cice
[3764]940!
941!            IF (ln_seaicebal ) THEN       
942!             !! balancing salinity increments
943!             !! simple case from limflx.F90 (doesn't include a mass flux)
944!             !! assumption is that as ice concentration is reduced or increased
945!             !! the snow and ice depths remain constant
946!             !! note that snow is being created where ice concentration is being increased
947!             !! - could be more sophisticated and
948!             !! not do this (but would need to alter h_snow)
949!
950!             usave(:,:,:)=sb(:,:,:)   ! use array as a temporary store
951!
952!             DO jj = 1, jpj
953!               DO ji = 1, jpi
954!           ! calculate change in ice and snow mass per unit area
955!           ! positive values imply adding salt to the ocean (results from ice formation)
956!           ! fwf : ice formation and melting
957!
958!                 zfons = ( -nfresh_da(ji,jj)*soce + nfsalt_da(ji,jj) )*rdt
959!
960!           ! change salinity down to mixed layer depth
961!                 mld=hmld_kara(ji,jj)
962!
963!           ! prevent small mld
964!           ! less than 10m can cause salinity instability
965!                 IF (mld < 10) mld=10
966!
967!           ! set to bottom of a level
968!                 DO jk = jpk-1, 2, -1
969!                   IF ((mld > gdepw(ji,jj,jk)) .and. (mld < gdepw(ji,jj,jk+1))) THEN
970!                     mld=gdepw(ji,jj,jk+1)
971!                     jkmax=jk
972!                   ENDIF
973!                 ENDDO
974!
975!            ! avoid applying salinity balancing in shallow water or on land
976!            !
977!
978!            ! dsal_ocn (psu kg m^-2) / (kg m^-3 * m)
979!
980!                 dsal_ocn=0.0_wp
981!                 sal_thresh=5.0_wp        ! minimum salinity threshold for salinity balancing
982!
983!                 if (tmask(ji,jj,1) > 0 .AND. tmask(ji,jj,jkmax) > 0 ) &
984!                              dsal_ocn = zfons / (rhop(ji,jj,1) * mld)
985!
986!           ! put increments in for levels in the mixed layer
987!           ! but prevent salinity below a threshold value
988!
989!                   DO jk = 1, jkmax             
990!
991!                     IF (dsal_ocn > 0.0_wp .or. sb(ji,jj,jk)+dsal_ocn > sal_thresh) THEN
992!                           sb(ji,jj,jk) = sb(ji,jj,jk) + dsal_ocn
993!                           sn(ji,jj,jk) = sn(ji,jj,jk) + dsal_ocn
994!                     ENDIF
995!
996!                   ENDDO
997!
998!      !            !  salt exchanges at the ice/ocean interface
999!      !            zpmess         = zfons / rdt_ice    ! rdt_ice is ice timestep
1000!      !
1001!      !! Adjust fsalt. A +ve fsalt means adding salt to ocean
1002!      !!           fsalt(ji,jj) =  fsalt(ji,jj) + zpmess     ! adjust fsalt 
1003!      !!               
1004!      !!           emps(ji,jj) = emps(ji,jj) + zpmess        ! or adjust emps (see icestp1d)
1005!      !!                                                     ! E-P (kg m-2 s-2)
1006!      !            emp(ji,jj) = emp(ji,jj) + zpmess          ! E-P (kg m-2 s-2)
1007!               ENDDO !ji
1008!             ENDDO !jj!
1009!
1010!            ENDIF !ln_seaicebal
1011!
1012!#endif
[5836]1013         !
[3764]1014      ENDIF
[5836]1015      !
[3764]1016   END SUBROUTINE seaice_asm_inc
[3785]1017   
[2392]1018   !!======================================================================
[2128]1019END MODULE asminc
Note: See TracBrowser for help on using the repository browser.