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.
bdyini.F90 in branches/UKMO/CCRS_NUS_MC_STABLE/NEMOGCM/NEMO/OPA_SRC/BDY – NEMO

source: branches/UKMO/CCRS_NUS_MC_STABLE/NEMOGCM/NEMO/OPA_SRC/BDY/bdyini.F90 @ 10064

Last change on this file since 10064 was 10064, checked in by csanchez, 6 years ago

Added changes from Bijoy and Enda's for sponge layer, no tidal harm, and rimwidth=1

File size: 86.5 KB
Line 
1MODULE bdyini
2   !!======================================================================
3   !!                       ***  MODULE  bdyini  ***
4   !! Unstructured open boundaries : initialisation
5   !!======================================================================
6   !! History :  1.0  !  2005-01  (J. Chanut, A. Sellar)  Original code
7   !!             -   !  2007-01  (D. Storkey) Update to use IOM module
8   !!             -   !  2007-01  (D. Storkey) Tidal forcing
9   !!            3.0  !  2008-04  (NEMO team)  add in the reference version
10   !!            3.3  !  2010-09  (E.O'Dea) updates for Shelf configurations
11   !!            3.3  !  2010-09  (D.Storkey) add ice boundary conditions
12   !!            3.4  !  2011     (D. Storkey) rewrite in preparation for OBC-BDY merge
13   !!            3.4  !  2012     (J. Chanut) straight open boundary case update
14   !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Updates for the
15   !!                             optimization of BDY communications
16   !!----------------------------------------------------------------------
17#if defined key_bdy
18   !!----------------------------------------------------------------------
19   !!   'key_bdy'                     Unstructured Open Boundary Conditions
20   !!----------------------------------------------------------------------
21   !!   bdy_init       : Initialization of unstructured open boundaries
22   !!----------------------------------------------------------------------
23   USE wrk_nemo        ! Memory Allocation
24   USE timing          ! Timing
25   USE oce             ! ocean dynamics and tracers variables
26   USE dom_oce         ! ocean space and time domain
27   USE bdy_oce         ! unstructured open boundary conditions
28   USE in_out_manager  ! I/O units
29   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
30   USE lib_mpp         ! for mpp_sum 
31   USE iom             ! I/O
32   USE sbctide, ONLY: lk_tide ! Tidal forcing or not
33   USE phycst, ONLY: rday
34
35   IMPLICIT NONE
36   PRIVATE
37
38   PUBLIC   bdy_init   ! routine called in nemo_init
39
40   INTEGER, PARAMETER          :: jp_nseg = 100
41   INTEGER, PARAMETER          :: nrimmax = 20 ! maximum rimwidth in structured
42                                               ! open boundary data files
43   ! Straight open boundary segment parameters:
44   INTEGER  :: nbdysege, nbdysegw, nbdysegn, nbdysegs 
45   INTEGER, DIMENSION(jp_nseg) :: jpieob, jpjedt, jpjeft, npckge
46   INTEGER, DIMENSION(jp_nseg) :: jpiwob, jpjwdt, jpjwft, npckgw
47   INTEGER, DIMENSION(jp_nseg) :: jpjnob, jpindt, jpinft, npckgn
48   INTEGER, DIMENSION(jp_nseg) :: jpjsob, jpisdt, jpisft, npckgs
49   !!----------------------------------------------------------------------
50   !! NEMO/OPA 4.0 , NEMO Consortium (2011)
51   !! $Id$
52   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
53   !!----------------------------------------------------------------------
54CONTAINS
55   
56   SUBROUTINE bdy_init
57      !!----------------------------------------------------------------------
58      !!                 ***  ROUTINE bdy_init  ***
59      !!         
60      !! ** Purpose :   Initialization of the dynamics and tracer fields with
61      !!              unstructured open boundaries.
62      !!
63      !! ** Method  :   Read initialization arrays (mask, indices) to identify
64      !!              an unstructured open boundary
65      !!
66      !! ** Input   :  bdy_init.nc, input file for unstructured open boundaries
67      !!----------------------------------------------------------------------     
68      ! namelist variables
69      !-------------------
70      CHARACTER(LEN=80),DIMENSION(jpbgrd)  ::   clfile
71      CHARACTER(LEN=1)   ::   ctypebdy
72      INTEGER :: nbdyind, nbdybeg, nbdyend
73
74      ! local variables
75      !-------------------
76      INTEGER  ::   ib_bdy, ii, ij, ik, igrd, ib, ir, iseg ! dummy loop indices
77      INTEGER  ::   icount, icountr, ibr_max, ilen1, ibm1  ! local integers
78      INTEGER  ::   iwe, ies, iso, ino, inum, id_dummy         !   -       -
79      INTEGER  ::   igrd_start, igrd_end, jpbdta           !   -       -
80      INTEGER  ::   jpbdtau, jpbdtas                       !   -       -
81      INTEGER  ::   ib_bdy1, ib_bdy2, ib1, ib2             !   -       -
82      INTEGER  ::   i_offset, j_offset                     !   -       -
83      INTEGER, POINTER  ::  nbi, nbj, nbr                  ! short cuts
84      REAL(wp), POINTER  ::  flagu, flagv                  !    -   -
85      REAL(wp), POINTER, DIMENSION(:,:)       ::   pmask    ! pointer to 2D mask fields
86      REAL(wp) ::   zefl, zwfl, znfl, zsfl                 ! local scalars
87      INTEGER, DIMENSION (2)                  ::   kdimsz
88      INTEGER, DIMENSION(jpbgrd,jp_bdy)       ::   nblendta         ! Length of index arrays
89      INTEGER, ALLOCATABLE, DIMENSION(:,:,:)  ::   nbidta, nbjdta   ! Index arrays: i and j indices of bdy dta
90      INTEGER, ALLOCATABLE, DIMENSION(:,:,:)  ::   nbrdta           ! Discrete distance from rim points
91      CHARACTER(LEN=1),DIMENSION(jpbgrd)      ::   cgrid
92      INTEGER :: com_east, com_west, com_south, com_north          ! Flags for boundaries sending
93      INTEGER :: com_east_b, com_west_b, com_south_b, com_north_b  ! Flags for boundaries receiving
94      INTEGER :: iw_b(4), ie_b(4), is_b(4), in_b(4)                ! Arrays for neighbours coordinates
95      REAL(wp), POINTER, DIMENSION(:,:)       ::   zfmask  ! temporary fmask array excluding coastal boundary condition (shlat)
96
97      !! CEOD sponge
98      NAMELIST/nambdy/ nb_bdy, ln_coords_file, cn_coords_file,                 &
99         &             ln_mask_file, cn_mask_file, cn_dyn2d, nn_dyn2d_dta,     &
100         &             cn_dyn3d, nn_dyn3d_dta, cn_tra, nn_tra_dta,             & 
101         &             ln_tra_dmp, ln_dyn3d_dmp, rn_time_dmp, rn_time_dmp_out, &
102         &             cn_ice_lim, nn_ice_lim_dta,                           &
103         &             rn_ice_tem, rn_ice_sal, rn_ice_age,                 &
104         &             ln_vol, nn_volctl, nn_rimwidth,                      &
105         &             ln_sponge, rn_sponge !CEOD
106      !!
107      NAMELIST/nambdy_index/ ctypebdy, nbdyind, nbdybeg, nbdyend
108     
109     
110!      ! JT
111      NAMELIST/nambdy_ssh/ ln_ssh_bdy
112!      ! JT
113      INTEGER  ::   ios                 ! Local integer output status for namelist read
114      !!----------------------------------------------------------------------
115
116      IF( nn_timing == 1 ) CALL timing_start('bdy_init')
117
118      IF(lwp) WRITE(numout,*)
119      IF(lwp) WRITE(numout,*) 'bdy_init : initialization of open boundaries'
120      IF(lwp) WRITE(numout,*) '~~~~~~~~'
121      !
122
123      IF( jperio /= 0 )   CALL ctl_stop( 'Cyclic or symmetric,',   &
124         &                               ' and general open boundary condition are not compatible' )
125
126      cgrid= (/'t','u','v'/)
127     
128      ! ------------------------
129      ! Read namelist parameters
130      ! ------------------------
131
132      REWIND( numnam_ref )              ! Namelist nambdy in reference namelist :Unstructured open boundaries 
133      READ  ( numnam_ref, nambdy, IOSTAT = ios, ERR = 901)
134901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy in reference namelist', lwp )
135
136      REWIND( numnam_cfg )              ! Namelist nambdy in configuration namelist :Unstructured open boundaries
137      READ  ( numnam_cfg, nambdy, IOSTAT = ios, ERR = 902 )
138902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy in configuration namelist', lwp )
139      IF(lwm) WRITE ( numond, nambdy )
140      !JT Read nambdy_ssh namelist
141      REWIND( numnam_ref )              ! Namelist nambdy in reference namelist :Unstructured open boundaries 
142      READ  ( numnam_ref, nambdy_ssh, IOSTAT = ios, ERR = 905)
143905   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy_ssh in reference namelist', lwp )
144
145      REWIND( numnam_cfg )              ! Namelist nambdy in configuration namelist :Unstructured open boundaries
146      READ  ( numnam_cfg, nambdy_ssh, IOSTAT = ios, ERR = 906)
147906   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy_ssh in configuration namelist', lwp )
148      IF(lwm) WRITE ( numond, nambdy_ssh )
149     
150      IF(lwp) WRITE(numout,*)
151      IF(lwp) WRITE(numout,*) 'nambdy_ssh : use of ssh boundaries'
152      IF(lwp) WRITE(numout,*) '~~~~~~~~'
153      IF(lwp) WRITE(numout,*) '      ln_ssh_bdy: '
154      DO ib_bdy = 1,nb_bdy
155        IF(lwp) WRITE(numout,*) '      ln_ssh_bdy(',ib_bdy,'): ',ln_ssh_bdy(ib_bdy)
156      ENDDO
157      IF(lwp) WRITE(numout,*) '~~~~~~~~'
158      IF(lwp) WRITE(numout,*) 
159      !JT
160
161      ! -----------------------------------------
162      ! Check and write out namelist parameters
163      ! -----------------------------------------
164      !                                   ! control prints
165      IF(lwp) WRITE(numout,*) '         nambdy'
166
167      IF( nb_bdy .eq. 0 ) THEN
168        IF(lwp) WRITE(numout,*) 'nb_bdy = 0, NO OPEN BOUNDARIES APPLIED.'
169      ELSE
170        IF(lwp) WRITE(numout,*) 'Number of open boundary sets : ',nb_bdy
171      ENDIF
172
173      DO ib_bdy = 1,nb_bdy
174        IF(lwp) WRITE(numout,*) ' ' 
175        IF(lwp) WRITE(numout,*) '------ Open boundary data set ',ib_bdy,'------' 
176
177        IF( ln_coords_file(ib_bdy) ) THEN
178           IF(lwp) WRITE(numout,*) 'Boundary definition read from file '//TRIM(cn_coords_file(ib_bdy))
179        ELSE
180           IF(lwp) WRITE(numout,*) 'Boundary defined in namelist.'
181        ENDIF
182        IF(lwp) WRITE(numout,*)
183
184        IF(lwp) WRITE(numout,*) 'Boundary conditions for barotropic solution:  '
185        SELECT CASE( cn_dyn2d(ib_bdy) )                 
186          CASE('none')         
187             IF(lwp) WRITE(numout,*) '      no open boundary condition'       
188             dta_bdy(ib_bdy)%ll_ssh = .false.
189             dta_bdy(ib_bdy)%ll_u2d = .false.
190             dta_bdy(ib_bdy)%ll_v2d = .false.
191          CASE('frs')         
192             IF(lwp) WRITE(numout,*) '      Flow Relaxation Scheme'
193             dta_bdy(ib_bdy)%ll_ssh = .false.
194             dta_bdy(ib_bdy)%ll_u2d = .true.
195             dta_bdy(ib_bdy)%ll_v2d = .true.
196          CASE('flather')     
197             IF(lwp) WRITE(numout,*) '      Flather radiation condition'
198             dta_bdy(ib_bdy)%ll_ssh = .true.
199             dta_bdy(ib_bdy)%ll_u2d = .true.
200             dta_bdy(ib_bdy)%ll_v2d = .true.
201          CASE('orlanski')     
202             IF(lwp) WRITE(numout,*) '      Orlanski (fully oblique) radiation condition with adaptive nudging'
203             dta_bdy(ib_bdy)%ll_ssh = .false.
204             dta_bdy(ib_bdy)%ll_u2d = .true.
205             dta_bdy(ib_bdy)%ll_v2d = .true.
206          CASE('orlanski_npo') 
207             IF(lwp) WRITE(numout,*) '      Orlanski (NPO) radiation condition with adaptive nudging'
208             dta_bdy(ib_bdy)%ll_ssh = .false.
209             dta_bdy(ib_bdy)%ll_u2d = .true.
210             dta_bdy(ib_bdy)%ll_v2d = .true.
211          CASE DEFAULT   ;   CALL ctl_stop( 'unrecognised value for cn_dyn2d' )
212        END SELECT
213       
214        !JT override dta_bdy(ib_bdy)%ll_ssh with namelist value (ln_ssh_bdy)
215        IF(lwp) WRITE(numout,*) 'nambdy_ssh : use of ssh boundaries'
216        IF(lwp) WRITE(numout,*) '~~~~~~~~'
217        IF(lwp) WRITE(numout,*) '      ib_bdy: ',ib_bdy
218        IF(lwp) WRITE(numout,*) '      Prior to Implementation of nambdy_ssh'
219        IF(lwp) WRITE(numout,*) '      dta_bdy(ib_bdy)%ll_ssh: ',dta_bdy(ib_bdy)%ll_ssh
220       
221        dta_bdy(ib_bdy)%ll_ssh = ln_ssh_bdy(ib_bdy)
222       
223        IF(lwp) WRITE(numout,*) '      After to Implementation of nambdy_ssh'
224        IF(lwp) WRITE(numout,*) '      dta_bdy(ib_bdy)%ll_ssh: ',dta_bdy(ib_bdy)%ll_ssh
225        IF(lwp) WRITE(numout,*) '~~~~~~~~'
226       
227        !JT         
228       
229        IF( cn_dyn2d(ib_bdy) /= 'none' ) THEN
230           SELECT CASE( nn_dyn2d_dta(ib_bdy) )                   !
231              CASE( 0 )      ;   IF(lwp) WRITE(numout,*) '      initial state used for bdy data'       
232              CASE( 1 )      ;   IF(lwp) WRITE(numout,*) '      boundary data taken from file'
233              CASE( 2 )      ;   IF(lwp) WRITE(numout,*) '      tidal harmonic forcing taken from file'
234              CASE( 3 )      ;   IF(lwp) WRITE(numout,*) '      boundary data AND tidal harmonic forcing taken from files'
235              CASE DEFAULT   ;   CALL ctl_stop( 'nn_dyn2d_dta must be between 0 and 3' )
236           END SELECT
237           IF (( nn_dyn2d_dta(ib_bdy) .ge. 2 ).AND.(.NOT.lk_tide)) THEN
238             CALL ctl_stop( 'You must activate key_tide to add tidal forcing at open boundaries' )
239           ENDIF
240        ENDIF
241        IF(lwp) WRITE(numout,*)
242
243        IF(lwp) WRITE(numout,*) 'Boundary conditions for baroclinic velocities:  '
244        SELECT CASE( cn_dyn3d(ib_bdy) )                 
245          CASE('none')
246             IF(lwp) WRITE(numout,*) '      no open boundary condition'       
247             dta_bdy(ib_bdy)%ll_u3d = .false.
248             dta_bdy(ib_bdy)%ll_v3d = .false.
249          CASE('frs')       
250             IF(lwp) WRITE(numout,*) '      Flow Relaxation Scheme'
251             dta_bdy(ib_bdy)%ll_u3d = .true.
252             dta_bdy(ib_bdy)%ll_v3d = .true.
253          CASE('specified')
254             IF(lwp) WRITE(numout,*) '      Specified value'
255             dta_bdy(ib_bdy)%ll_u3d = .true.
256             dta_bdy(ib_bdy)%ll_v3d = .true.
257          CASE('neumann') 
258             IF(lwp) WRITE(numout,*) '      Neumann conditions' 
259             dta_bdy(ib_bdy)%ll_u3d = .false. 
260             dta_bdy(ib_bdy)%ll_v3d = .false. 
261          CASE('zerograd') 
262             IF(lwp) WRITE(numout,*) '      Zero gradient for baroclinic velocities' 
263             dta_bdy(ib_bdy)%ll_u3d = .false. 
264             dta_bdy(ib_bdy)%ll_v3d = .false.
265          CASE('zero')
266             IF(lwp) WRITE(numout,*) '      Zero baroclinic velocities (runoff case)'
267             dta_bdy(ib_bdy)%ll_u3d = .false.
268             dta_bdy(ib_bdy)%ll_v3d = .false.
269          CASE('orlanski')
270             IF(lwp) WRITE(numout,*) '      Orlanski (fully oblique) radiation condition with adaptive nudging'
271             dta_bdy(ib_bdy)%ll_u3d = .true.
272             dta_bdy(ib_bdy)%ll_v3d = .true.
273          CASE('orlanski_npo')
274             IF(lwp) WRITE(numout,*) '      Orlanski (NPO) radiation condition with adaptive nudging'
275             dta_bdy(ib_bdy)%ll_u3d = .true.
276             dta_bdy(ib_bdy)%ll_v3d = .true.
277          CASE DEFAULT   ;   CALL ctl_stop( 'unrecognised value for cn_dyn3d' )
278        END SELECT
279        IF( cn_dyn3d(ib_bdy) /= 'none' ) THEN
280           SELECT CASE( nn_dyn3d_dta(ib_bdy) )                   !
281              CASE( 0 )      ;   IF(lwp) WRITE(numout,*) '      initial state used for bdy data'       
282              CASE( 1 )      ;   IF(lwp) WRITE(numout,*) '      boundary data taken from file'
283              CASE DEFAULT   ;   CALL ctl_stop( 'nn_dyn3d_dta must be 0 or 1' )
284           END SELECT
285        ENDIF
286
287        IF ( ln_dyn3d_dmp(ib_bdy) ) THEN
288           IF ( cn_dyn3d(ib_bdy) == 'none' ) THEN
289              IF(lwp) WRITE(numout,*) 'No open boundary condition for baroclinic velocities: ln_dyn3d_dmp is set to .false.'
290              ln_dyn3d_dmp(ib_bdy)=.false.
291           ELSEIF ( cn_dyn3d(ib_bdy) == 'frs' ) THEN
292              CALL ctl_stop( 'Use FRS OR relaxation' )
293           ELSE
294              IF(lwp) WRITE(numout,*) '      + baroclinic velocities relaxation zone'
295              IF(lwp) WRITE(numout,*) '      Damping time scale: ',rn_time_dmp(ib_bdy),' days'
296              IF((lwp).AND.rn_time_dmp(ib_bdy)<0) CALL ctl_stop( 'Time scale must be positive' )
297              dta_bdy(ib_bdy)%ll_u3d = .true.
298              dta_bdy(ib_bdy)%ll_v3d = .true.
299           ENDIF
300        ELSE
301           IF(lwp) WRITE(numout,*) '      NO relaxation on baroclinic velocities'
302        ENDIF
303        IF(lwp) WRITE(numout,*)
304
305        IF(lwp) WRITE(numout,*) 'Boundary conditions for temperature and salinity:  '
306        SELECT CASE( cn_tra(ib_bdy) )                 
307          CASE('none')
308             IF(lwp) WRITE(numout,*) '      no open boundary condition'       
309             dta_bdy(ib_bdy)%ll_tem = .false.
310             dta_bdy(ib_bdy)%ll_sal = .false.
311          CASE('frs')
312             IF(lwp) WRITE(numout,*) '      Flow Relaxation Scheme'
313             dta_bdy(ib_bdy)%ll_tem = .true.
314             dta_bdy(ib_bdy)%ll_sal = .true.
315          CASE('specified')
316             IF(lwp) WRITE(numout,*) '      Specified value'
317             dta_bdy(ib_bdy)%ll_tem = .true.
318             dta_bdy(ib_bdy)%ll_sal = .true.
319          CASE('neumann')
320             IF(lwp) WRITE(numout,*) '      Neumann conditions'
321             dta_bdy(ib_bdy)%ll_tem = .false.
322             dta_bdy(ib_bdy)%ll_sal = .false.
323          CASE('runoff')
324             IF(lwp) WRITE(numout,*) '      Runoff conditions : Neumann for T and specified to 0.1 for salinity'
325             dta_bdy(ib_bdy)%ll_tem = .false.
326             dta_bdy(ib_bdy)%ll_sal = .false.
327          CASE('orlanski')
328             IF(lwp) WRITE(numout,*) '      Orlanski (fully oblique) radiation condition with adaptive nudging'
329             dta_bdy(ib_bdy)%ll_tem = .true.
330             dta_bdy(ib_bdy)%ll_sal = .true.
331          CASE('orlanski_npo')
332             IF(lwp) WRITE(numout,*) '      Orlanski (NPO) radiation condition with adaptive nudging'
333             dta_bdy(ib_bdy)%ll_tem = .true.
334             dta_bdy(ib_bdy)%ll_sal = .true.
335          CASE DEFAULT   ;   CALL ctl_stop( 'unrecognised value for cn_tra' )
336        END SELECT
337        IF( cn_tra(ib_bdy) /= 'none' ) THEN
338           SELECT CASE( nn_tra_dta(ib_bdy) )                   !
339              CASE( 0 )      ;   IF(lwp) WRITE(numout,*) '      initial state used for bdy data'       
340              CASE( 1 )      ;   IF(lwp) WRITE(numout,*) '      boundary data taken from file'
341              CASE DEFAULT   ;   CALL ctl_stop( 'nn_tra_dta must be 0 or 1' )
342           END SELECT
343        ENDIF
344
345        IF ( ln_tra_dmp(ib_bdy) ) THEN
346           IF ( cn_tra(ib_bdy) == 'none' ) THEN
347              IF(lwp) WRITE(numout,*) 'No open boundary condition for tracers: ln_tra_dmp is set to .false.'
348              ln_tra_dmp(ib_bdy)=.false.
349           ELSEIF ( cn_tra(ib_bdy) == 'frs' ) THEN
350              CALL ctl_stop( 'Use FRS OR relaxation' )
351           ELSE
352              IF(lwp) WRITE(numout,*) '      + T/S relaxation zone'
353              IF(lwp) WRITE(numout,*) '      Damping time scale: ',rn_time_dmp(ib_bdy),' days'
354              IF(lwp) WRITE(numout,*) '      Outflow damping time scale: ',rn_time_dmp_out(ib_bdy),' days'
355              IF((lwp).AND.rn_time_dmp(ib_bdy)<0) CALL ctl_stop( 'Time scale must be positive' )
356              dta_bdy(ib_bdy)%ll_tem = .true.
357              dta_bdy(ib_bdy)%ll_sal = .true.
358           ENDIF
359        ELSE
360           IF(lwp) WRITE(numout,*) '      NO T/S relaxation'
361        ENDIF
362        IF(lwp) WRITE(numout,*)
363
364#if defined key_lim2
365        IF(lwp) WRITE(numout,*) 'Boundary conditions for sea ice:  '
366        SELECT CASE( cn_ice_lim(ib_bdy) )                 
367          CASE('none')
368             IF(lwp) WRITE(numout,*) '      no open boundary condition'       
369             dta_bdy(ib_bdy)%ll_frld  = .false.
370             dta_bdy(ib_bdy)%ll_hicif = .false.
371             dta_bdy(ib_bdy)%ll_hsnif = .false.
372          CASE('frs')
373             IF(lwp) WRITE(numout,*) '      Flow Relaxation Scheme'
374             dta_bdy(ib_bdy)%ll_frld  = .true.
375             dta_bdy(ib_bdy)%ll_hicif = .true.
376             dta_bdy(ib_bdy)%ll_hsnif = .true.
377          CASE DEFAULT   ;   CALL ctl_stop( 'unrecognised value for cn_ice_lim' )
378        END SELECT
379        IF( cn_ice_lim(ib_bdy) /= 'none' ) THEN
380           SELECT CASE( nn_ice_lim_dta(ib_bdy) )                   !
381              CASE( 0 )      ;   IF(lwp) WRITE(numout,*) '      initial state used for bdy data'       
382              CASE( 1 )      ;   IF(lwp) WRITE(numout,*) '      boundary data taken from file'
383              CASE DEFAULT   ;   CALL ctl_stop( 'nn_ice_lim_dta must be 0 or 1' )
384           END SELECT
385        ENDIF
386        IF(lwp) WRITE(numout,*)
387#elif defined key_lim3
388        IF(lwp) WRITE(numout,*) 'Boundary conditions for sea ice:  '
389        SELECT CASE( cn_ice_lim(ib_bdy) )                 
390          CASE('none')
391             IF(lwp) WRITE(numout,*) '      no open boundary condition'       
392             dta_bdy(ib_bdy)%ll_a_i  = .false.
393             dta_bdy(ib_bdy)%ll_ht_i = .false.
394             dta_bdy(ib_bdy)%ll_ht_s = .false.
395          CASE('frs')
396             IF(lwp) WRITE(numout,*) '      Flow Relaxation Scheme'
397             dta_bdy(ib_bdy)%ll_a_i  = .true.
398             dta_bdy(ib_bdy)%ll_ht_i = .true.
399             dta_bdy(ib_bdy)%ll_ht_s = .true.
400          CASE DEFAULT   ;   CALL ctl_stop( 'unrecognised value for cn_ice_lim' )
401        END SELECT
402        IF( cn_ice_lim(ib_bdy) /= 'none' ) THEN
403           SELECT CASE( nn_ice_lim_dta(ib_bdy) )                   !
404              CASE( 0 )      ;   IF(lwp) WRITE(numout,*) '      initial state used for bdy data'       
405              CASE( 1 )      ;   IF(lwp) WRITE(numout,*) '      boundary data taken from file'
406              CASE DEFAULT   ;   CALL ctl_stop( 'nn_ice_lim_dta must be 0 or 1' )
407           END SELECT
408        ENDIF
409        IF(lwp) WRITE(numout,*)
410        IF(lwp) WRITE(numout,*) '      tem of bdy sea-ice = ', rn_ice_tem(ib_bdy)         
411        IF(lwp) WRITE(numout,*) '      sal of bdy sea-ice = ', rn_ice_sal(ib_bdy)         
412        IF(lwp) WRITE(numout,*) '      age of bdy sea-ice = ', rn_ice_age(ib_bdy)         
413#endif
414
415        IF(lwp) WRITE(numout,*) '      Width of relaxation zone = ', nn_rimwidth(ib_bdy)
416        IF(lwp) WRITE(numout,*)
417!CEOD
418        IF( ln_sponge(ib_bdy) ) THEN                     ! check sponge layer choice
419             IF(lwp) WRITE(numout,*) 'Sponge layer applied at open boundaries'
420             IF(lwp) WRITE(numout,*) 'Multiplier for diffusion in sponge layer :', rn_sponge
421             IF(lwp) WRITE(numout,*)
422           ELSE
423             IF(lwp) WRITE(numout,*) 'No volume correction applied at open boundaries'
424             IF(lwp) WRITE(numout,*)
425           ENDIF
426!
427      ENDDO
428
429     IF (nb_bdy .gt. 0) THEN
430        IF( ln_vol ) THEN                     ! check volume conservation (nn_volctl value)
431          IF(lwp) WRITE(numout,*) 'Volume correction applied at open boundaries'
432          IF(lwp) WRITE(numout,*)
433          SELECT CASE ( nn_volctl )
434            CASE( 1 )      ;   IF(lwp) WRITE(numout,*) '      The total volume will be constant'
435            CASE( 0 )      ;   IF(lwp) WRITE(numout,*) '      The total volume will vary according to the surface E-P flux'
436            CASE DEFAULT   ;   CALL ctl_stop( 'nn_volctl must be 0 or 1' )
437          END SELECT
438          IF(lwp) WRITE(numout,*)
439        ELSE
440          IF(lwp) WRITE(numout,*) 'No volume correction applied at open boundaries'
441          IF(lwp) WRITE(numout,*)
442        ENDIF
443     ENDIF
444     sponge_factor(:,:) = 1.0 !CEOD
445
446      ! -------------------------------------------------
447      ! Initialise indices arrays for open boundaries
448      ! -------------------------------------------------
449
450      ! Work out global dimensions of boundary data
451      ! ---------------------------------------------
452      REWIND( numnam_cfg )     
453
454      !!----------------------------------------------------------------------
455
456             
457               
458      nblendta(:,:) = 0
459      nbdysege = 0
460      nbdysegw = 0
461      nbdysegn = 0
462      nbdysegs = 0
463      icount   = 0 ! count user defined segments
464      ! Dimensions below are used to allocate arrays to read external data
465      jpbdtas = 1 ! Maximum size of boundary data (structured case)
466      jpbdtau = 1 ! Maximum size of boundary data (unstructured case)
467
468      DO ib_bdy = 1, nb_bdy
469
470         IF( .NOT. ln_coords_file(ib_bdy) ) THEN ! Work out size of global arrays from namelist parameters
471 
472            icount = icount + 1
473            ! No REWIND here because may need to read more than one nambdy_index namelist.
474            ! Read only namelist_cfg to avoid unseccessfull overwrite
475!!          REWIND( numnam_ref )              ! Namelist nambdy_index in reference namelist : Open boundaries indexes
476!!          READ  ( numnam_ref, namrun, IOSTAT = ios, ERR = 903)
477!!903       IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy_index in reference namelist', lwp )
478
479!!          REWIND( numnam_cfg )              ! Namelist nambdy_index in configuration namelist : Open boundaries indexes
480            READ  ( numnam_cfg, nambdy_index, IOSTAT = ios, ERR = 904 )
481904         IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy_index in configuration namelist', lwp )
482            IF(lwm) WRITE ( numond, nambdy_index )
483
484            SELECT CASE ( TRIM(ctypebdy) )
485              CASE( 'N' )
486                 IF( nbdyind == -1 ) THEN  ! Automatic boundary definition: if nbdysegX = -1
487                    nbdyind  = jpjglo - 2  ! set boundary to whole side of model domain.
488                    nbdybeg  = 2
489                    nbdyend  = jpiglo - 1
490                 ENDIF
491                 nbdysegn = nbdysegn + 1
492                 npckgn(nbdysegn) = ib_bdy ! Save bdy package number
493                 jpjnob(nbdysegn) = nbdyind
494                 jpindt(nbdysegn) = nbdybeg
495                 jpinft(nbdysegn) = nbdyend
496                 !
497              CASE( 'S' )
498                 IF( nbdyind == -1 ) THEN  ! Automatic boundary definition: if nbdysegX = -1
499                    nbdyind  = 2           ! set boundary to whole side of model domain.
500                    nbdybeg  = 2
501                    nbdyend  = jpiglo - 1
502                 ENDIF
503                 nbdysegs = nbdysegs + 1
504                 npckgs(nbdysegs) = ib_bdy ! Save bdy package number
505                 jpjsob(nbdysegs) = nbdyind
506                 jpisdt(nbdysegs) = nbdybeg
507                 jpisft(nbdysegs) = nbdyend
508                 !
509              CASE( 'E' )
510                 IF( nbdyind == -1 ) THEN  ! Automatic boundary definition: if nbdysegX = -1
511                    nbdyind  = jpiglo - 2  ! set boundary to whole side of model domain.
512                    nbdybeg  = 2
513                    nbdyend  = jpjglo - 1
514                 ENDIF
515                 nbdysege = nbdysege + 1 
516                 npckge(nbdysege) = ib_bdy ! Save bdy package number
517                 jpieob(nbdysege) = nbdyind
518                 jpjedt(nbdysege) = nbdybeg
519                 jpjeft(nbdysege) = nbdyend
520                 !
521              CASE( 'W' )
522                 IF( nbdyind == -1 ) THEN  ! Automatic boundary definition: if nbdysegX = -1
523                    nbdyind  = 2           ! set boundary to whole side of model domain.
524                    nbdybeg  = 2
525                    nbdyend  = jpjglo - 1
526                 ENDIF
527                 nbdysegw = nbdysegw + 1
528                 npckgw(nbdysegw) = ib_bdy ! Save bdy package number
529                 jpiwob(nbdysegw) = nbdyind
530                 jpjwdt(nbdysegw) = nbdybeg
531                 jpjwft(nbdysegw) = nbdyend
532                 !
533              CASE DEFAULT   ;   CALL ctl_stop( 'ctypebdy must be N, S, E or W' )
534            END SELECT
535
536            ! For simplicity we assume that in case of straight bdy, arrays have the same length
537            ! (even if it is true that last tangential velocity points
538            ! are useless). This simplifies a little bit boundary data format (and agrees with format
539            ! used so far in obc package)
540
541            nblendta(1:jpbgrd,ib_bdy) =  (nbdyend - nbdybeg + 1) * nn_rimwidth(ib_bdy)
542            jpbdtas = MAX(jpbdtas, (nbdyend - nbdybeg + 1))
543            IF (lwp.and.(nn_rimwidth(ib_bdy)>nrimmax)) &
544            & CALL ctl_stop( 'rimwidth must be lower than nrimmax' )
545
546         ELSE            ! Read size of arrays in boundary coordinates file.
547            CALL iom_open( cn_coords_file(ib_bdy), inum )
548            DO igrd = 1, jpbgrd
549               id_dummy = iom_varid( inum, 'nbi'//cgrid(igrd), kdimsz=kdimsz ) 
550               !clem nblendta(igrd,ib_bdy) = kdimsz(1)
551               !clem jpbdtau = MAX(jpbdtau, kdimsz(1))
552               nblendta(igrd,ib_bdy) = MAXVAL(kdimsz)
553               jpbdtau = MAX(jpbdtau, MAXVAL(kdimsz))
554            ENDDO
555            CALL iom_close( inum )
556
557         ENDIF
558
559      ENDDO ! ib_bdy
560
561      IF (nb_bdy>0) THEN
562         jpbdta = MAXVAL(nblendta(1:jpbgrd,1:nb_bdy))
563
564         ! Allocate arrays
565         !---------------
566         ALLOCATE( nbidta(jpbdta, jpbgrd, nb_bdy), nbjdta(jpbdta, jpbgrd, nb_bdy),    &
567            &      nbrdta(jpbdta, jpbgrd, nb_bdy) )
568
569         ALLOCATE( dta_global(jpbdtau, 1, jpk) )
570         IF ( icount>0 ) ALLOCATE( dta_global2(jpbdtas, nrimmax, jpk) )
571         !
572      ENDIF
573
574      ! Now look for crossings in user (namelist) defined open boundary segments:
575      !--------------------------------------------------------------------------
576      IF ( icount>0 ) CALL bdy_ctl_seg
577
578      ! Calculate global boundary index arrays or read in from file
579      !------------------------------------------------------------               
580      ! 1. Read global index arrays from boundary coordinates file.
581      DO ib_bdy = 1, nb_bdy
582
583         IF( ln_coords_file(ib_bdy) ) THEN
584
585            CALL iom_open( cn_coords_file(ib_bdy), inum )
586            DO igrd = 1, jpbgrd
587               CALL iom_get( inum, jpdom_unknown, 'nbi'//cgrid(igrd), dta_global(1:nblendta(igrd,ib_bdy),:,1) )
588               DO ii = 1,nblendta(igrd,ib_bdy)
589                  nbidta(ii,igrd,ib_bdy) = INT( dta_global(ii,1,1) )
590               END DO
591               CALL iom_get( inum, jpdom_unknown, 'nbj'//cgrid(igrd), dta_global(1:nblendta(igrd,ib_bdy),:,1) )
592               DO ii = 1,nblendta(igrd,ib_bdy)
593                  nbjdta(ii,igrd,ib_bdy) = INT( dta_global(ii,1,1) )
594               END DO
595               CALL iom_get( inum, jpdom_unknown, 'nbr'//cgrid(igrd), dta_global(1:nblendta(igrd,ib_bdy),:,1) )
596               DO ii = 1,nblendta(igrd,ib_bdy)
597                  nbrdta(ii,igrd,ib_bdy) = INT( dta_global(ii,1,1) )
598               END DO
599
600               ibr_max = MAXVAL( nbrdta(:,igrd,ib_bdy) )
601               IF(lwp) WRITE(numout,*)
602               IF(lwp) WRITE(numout,*) ' Maximum rimwidth in file is ', ibr_max
603               IF(lwp) WRITE(numout,*) ' nn_rimwidth from namelist is ', nn_rimwidth(ib_bdy)
604               IF (ibr_max < nn_rimwidth(ib_bdy))   &
605                     CALL ctl_stop( 'nn_rimwidth is larger than maximum rimwidth in file',cn_coords_file(ib_bdy) )
606            END DO
607            CALL iom_close( inum )
608
609         ENDIF
610
611      ENDDO     
612   
613      ! 2. Now fill indices corresponding to straight open boundary arrays:
614      ! East
615      !-----
616      DO iseg = 1, nbdysege
617         ib_bdy = npckge(iseg)
618         !
619         ! ------------ T points -------------
620         igrd=1
621         icount=0
622         DO ir = 1, nn_rimwidth(ib_bdy)
623            DO ij = jpjedt(iseg), jpjeft(iseg)
624               icount = icount + 1
625               nbidta(icount, igrd, ib_bdy) = jpieob(iseg) + 2 - ir
626               nbjdta(icount, igrd, ib_bdy) = ij
627               nbrdta(icount, igrd, ib_bdy) = ir
628            ENDDO
629         ENDDO
630         !
631         ! ------------ U points -------------
632         igrd=2
633         icount=0
634         DO ir = 1, nn_rimwidth(ib_bdy)
635            DO ij = jpjedt(iseg), jpjeft(iseg)
636               icount = icount + 1
637               nbidta(icount, igrd, ib_bdy) = jpieob(iseg) + 1 - ir
638               nbjdta(icount, igrd, ib_bdy) = ij
639               nbrdta(icount, igrd, ib_bdy) = ir
640            ENDDO
641         ENDDO
642         !
643         ! ------------ V points -------------
644         igrd=3
645         icount=0
646         DO ir = 1, nn_rimwidth(ib_bdy)
647!            DO ij = jpjedt(iseg), jpjeft(iseg) - 1
648            DO ij = jpjedt(iseg), jpjeft(iseg)
649               icount = icount + 1
650               nbidta(icount, igrd, ib_bdy) = jpieob(iseg) + 2 - ir
651               nbjdta(icount, igrd, ib_bdy) = ij
652               nbrdta(icount, igrd, ib_bdy) = ir
653            ENDDO
654            nbidta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
655            nbjdta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
656         ENDDO
657      ENDDO
658      !
659      ! West
660      !-----
661      DO iseg = 1, nbdysegw
662         ib_bdy = npckgw(iseg)
663         !
664         ! ------------ T points -------------
665         igrd=1
666         icount=0
667         DO ir = 1, nn_rimwidth(ib_bdy)
668            DO ij = jpjwdt(iseg), jpjwft(iseg)
669               icount = icount + 1
670               nbidta(icount, igrd, ib_bdy) = jpiwob(iseg) + ir - 1
671               nbjdta(icount, igrd, ib_bdy) = ij
672               nbrdta(icount, igrd, ib_bdy) = ir
673            ENDDO
674         ENDDO
675         !
676         ! ------------ U points -------------
677         igrd=2
678         icount=0
679         DO ir = 1, nn_rimwidth(ib_bdy)
680            DO ij = jpjwdt(iseg), jpjwft(iseg)
681               icount = icount + 1
682               nbidta(icount, igrd, ib_bdy) = jpiwob(iseg) + ir - 1
683               nbjdta(icount, igrd, ib_bdy) = ij
684               nbrdta(icount, igrd, ib_bdy) = ir
685            ENDDO
686         ENDDO
687         !
688         ! ------------ V points -------------
689         igrd=3
690         icount=0
691         DO ir = 1, nn_rimwidth(ib_bdy)
692!            DO ij = jpjwdt(iseg), jpjwft(iseg) - 1
693            DO ij = jpjwdt(iseg), jpjwft(iseg)
694               icount = icount + 1
695               nbidta(icount, igrd, ib_bdy) = jpiwob(iseg) + ir - 1
696               nbjdta(icount, igrd, ib_bdy) = ij
697               nbrdta(icount, igrd, ib_bdy) = ir
698            ENDDO
699            nbidta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
700            nbjdta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
701         ENDDO
702      ENDDO
703      !
704      ! North
705      !-----
706      DO iseg = 1, nbdysegn
707         ib_bdy = npckgn(iseg)
708         !
709         ! ------------ T points -------------
710         igrd=1
711         icount=0
712         DO ir = 1, nn_rimwidth(ib_bdy)
713            DO ii = jpindt(iseg), jpinft(iseg)
714               icount = icount + 1
715               nbidta(icount, igrd, ib_bdy) = ii
716               nbjdta(icount, igrd, ib_bdy) = jpjnob(iseg) + 2 - ir 
717               nbrdta(icount, igrd, ib_bdy) = ir
718            ENDDO
719         ENDDO
720         !
721         ! ------------ U points -------------
722         igrd=2
723         icount=0
724         DO ir = 1, nn_rimwidth(ib_bdy)
725!            DO ii = jpindt(iseg), jpinft(iseg) - 1
726            DO ii = jpindt(iseg), jpinft(iseg)
727               icount = icount + 1
728               nbidta(icount, igrd, ib_bdy) = ii
729               nbjdta(icount, igrd, ib_bdy) = jpjnob(iseg) + 2 - ir
730               nbrdta(icount, igrd, ib_bdy) = ir
731            ENDDO
732            nbidta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
733            nbjdta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
734         ENDDO
735         !
736         ! ------------ V points -------------
737         igrd=3
738         icount=0
739         DO ir = 1, nn_rimwidth(ib_bdy)
740            DO ii = jpindt(iseg), jpinft(iseg)
741               icount = icount + 1
742               nbidta(icount, igrd, ib_bdy) = ii
743               nbjdta(icount, igrd, ib_bdy) = jpjnob(iseg) + 1 - ir
744               nbrdta(icount, igrd, ib_bdy) = ir
745            ENDDO
746         ENDDO
747      ENDDO
748      !
749      ! South
750      !-----
751      DO iseg = 1, nbdysegs
752         ib_bdy = npckgs(iseg)
753         !
754         ! ------------ T points -------------
755         igrd=1
756         icount=0
757         DO ir = 1, nn_rimwidth(ib_bdy)
758            DO ii = jpisdt(iseg), jpisft(iseg)
759               icount = icount + 1
760               nbidta(icount, igrd, ib_bdy) = ii
761               nbjdta(icount, igrd, ib_bdy) = jpjsob(iseg) + ir - 1
762               nbrdta(icount, igrd, ib_bdy) = ir
763            ENDDO
764         ENDDO
765         !
766         ! ------------ U points -------------
767         igrd=2
768         icount=0
769         DO ir = 1, nn_rimwidth(ib_bdy)
770!            DO ii = jpisdt(iseg), jpisft(iseg) - 1
771            DO ii = jpisdt(iseg), jpisft(iseg)
772               icount = icount + 1
773               nbidta(icount, igrd, ib_bdy) = ii
774               nbjdta(icount, igrd, ib_bdy) = jpjsob(iseg) + ir - 1
775               nbrdta(icount, igrd, ib_bdy) = ir
776            ENDDO
777            nbidta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
778            nbjdta(icount, igrd, ib_bdy) = -ib_bdy ! Discount this point
779         ENDDO
780         !
781         ! ------------ V points -------------
782         igrd=3
783         icount=0
784         DO ir = 1, nn_rimwidth(ib_bdy)
785            DO ii = jpisdt(iseg), jpisft(iseg)
786               icount = icount + 1
787               nbidta(icount, igrd, ib_bdy) = ii
788               nbjdta(icount, igrd, ib_bdy) = jpjsob(iseg) + ir - 1
789               nbrdta(icount, igrd, ib_bdy) = ir
790            ENDDO
791         ENDDO
792      ENDDO
793
794      !  Deal with duplicated points
795      !-----------------------------
796      ! We assign negative indices to duplicated points (to remove them from bdy points to be updated)
797      ! if their distance to the bdy is greater than the other
798      ! If their distance are the same, just keep only one to avoid updating a point twice
799      DO igrd = 1, jpbgrd
800         DO ib_bdy1 = 1, nb_bdy
801            DO ib_bdy2 = 1, nb_bdy
802               IF (ib_bdy1/=ib_bdy2) THEN
803                  DO ib1 = 1, nblendta(igrd,ib_bdy1)
804                     DO ib2 = 1, nblendta(igrd,ib_bdy2)
805                        IF ((nbidta(ib1, igrd, ib_bdy1)==nbidta(ib2, igrd, ib_bdy2)).AND. &
806                        &   (nbjdta(ib1, igrd, ib_bdy1)==nbjdta(ib2, igrd, ib_bdy2))) THEN
807!                           IF ((lwp).AND.(igrd==1)) WRITE(numout,*) ' found coincident point ji, jj:', &
808!                                                       &              nbidta(ib1, igrd, ib_bdy1),      &
809!                                                       &              nbjdta(ib2, igrd, ib_bdy2)
810                           ! keep only points with the lowest distance to boundary:
811                           IF (nbrdta(ib1, igrd, ib_bdy1)<nbrdta(ib2, igrd, ib_bdy2)) THEN
812                             nbidta(ib2, igrd, ib_bdy2) =-ib_bdy2
813                             nbjdta(ib2, igrd, ib_bdy2) =-ib_bdy2
814                           ELSEIF (nbrdta(ib1, igrd, ib_bdy1)>nbrdta(ib2, igrd, ib_bdy2)) THEN
815                             nbidta(ib1, igrd, ib_bdy1) =-ib_bdy1
816                             nbjdta(ib1, igrd, ib_bdy1) =-ib_bdy1
817                           ! Arbitrary choice if distances are the same:
818                           ELSE
819                             nbidta(ib1, igrd, ib_bdy1) =-ib_bdy1
820                             nbjdta(ib1, igrd, ib_bdy1) =-ib_bdy1
821                           ENDIF
822                        END IF
823                     END DO
824                  END DO
825               ENDIF
826            END DO
827         END DO
828      END DO
829
830      ! Work out dimensions of boundary data on each processor
831      ! ------------------------------------------------------
832
833      ! Rather assume that boundary data indices are given on global domain
834      ! TO BE DISCUSSED ?
835!      iw = mig(1) + 1            ! if monotasking and no zoom, iw=2
836!      ie = mig(1) + nlci-1 - 1   ! if monotasking and no zoom, ie=jpim1
837!      is = mjg(1) + 1            ! if monotasking and no zoom, is=2
838!      in = mjg(1) + nlcj-1 - 1   ! if monotasking and no zoom, in=jpjm1     
839      iwe = mig(1) - jpizoom + 2         ! if monotasking and no zoom, iw=2
840      ies = mig(1) + nlci - jpizoom - 1  ! if monotasking and no zoom, ie=jpim1
841      iso = mjg(1) - jpjzoom + 2         ! if monotasking and no zoom, is=2
842      ino = mjg(1) + nlcj - jpjzoom - 1  ! if monotasking and no zoom, in=jpjm1
843
844      ALLOCATE( nbondi_bdy(nb_bdy))
845      ALLOCATE( nbondj_bdy(nb_bdy))
846      nbondi_bdy(:)=2
847      nbondj_bdy(:)=2
848      ALLOCATE( nbondi_bdy_b(nb_bdy))
849      ALLOCATE( nbondj_bdy_b(nb_bdy))
850      nbondi_bdy_b(:)=2
851      nbondj_bdy_b(:)=2
852
853      ! Work out dimensions of boundary data on each neighbour process
854      IF(nbondi .eq. 0) THEN
855         iw_b(1) = jpizoom + nimppt(nowe+1)
856         ie_b(1) = jpizoom + nimppt(nowe+1)+nlcit(nowe+1)-3
857         is_b(1) = jpjzoom + njmppt(nowe+1)
858         in_b(1) = jpjzoom + njmppt(nowe+1)+nlcjt(nowe+1)-3
859
860         iw_b(2) = jpizoom + nimppt(noea+1)
861         ie_b(2) = jpizoom + nimppt(noea+1)+nlcit(noea+1)-3
862         is_b(2) = jpjzoom + njmppt(noea+1)
863         in_b(2) = jpjzoom + njmppt(noea+1)+nlcjt(noea+1)-3
864      ELSEIF(nbondi .eq. 1) THEN
865         iw_b(1) = jpizoom + nimppt(nowe+1)
866         ie_b(1) = jpizoom + nimppt(nowe+1)+nlcit(nowe+1)-3
867         is_b(1) = jpjzoom + njmppt(nowe+1)
868         in_b(1) = jpjzoom + njmppt(nowe+1)+nlcjt(nowe+1)-3
869      ELSEIF(nbondi .eq. -1) THEN
870         iw_b(2) = jpizoom + nimppt(noea+1)
871         ie_b(2) = jpizoom + nimppt(noea+1)+nlcit(noea+1)-3
872         is_b(2) = jpjzoom + njmppt(noea+1)
873         in_b(2) = jpjzoom + njmppt(noea+1)+nlcjt(noea+1)-3
874      ENDIF
875
876      IF(nbondj .eq. 0) THEN
877         iw_b(3) = jpizoom + nimppt(noso+1)
878         ie_b(3) = jpizoom + nimppt(noso+1)+nlcit(noso+1)-3
879         is_b(3) = jpjzoom + njmppt(noso+1)
880         in_b(3) = jpjzoom + njmppt(noso+1)+nlcjt(noso+1)-3
881
882         iw_b(4) = jpizoom + nimppt(nono+1)
883         ie_b(4) = jpizoom + nimppt(nono+1)+nlcit(nono+1)-3
884         is_b(4) = jpjzoom + njmppt(nono+1)
885         in_b(4) = jpjzoom + njmppt(nono+1)+nlcjt(nono+1)-3
886      ELSEIF(nbondj .eq. 1) THEN
887         iw_b(3) = jpizoom + nimppt(noso+1)
888         ie_b(3) = jpizoom + nimppt(noso+1)+nlcit(noso+1)-3
889         is_b(3) = jpjzoom + njmppt(noso+1)
890         in_b(3) = jpjzoom + njmppt(noso+1)+nlcjt(noso+1)-3
891      ELSEIF(nbondj .eq. -1) THEN
892         iw_b(4) = jpizoom + nimppt(nono+1)
893         ie_b(4) = jpizoom + nimppt(nono+1)+nlcit(nono+1)-3
894         is_b(4) = jpjzoom + njmppt(nono+1)
895         in_b(4) = jpjzoom + njmppt(nono+1)+nlcjt(nono+1)-3
896      ENDIF
897
898      DO ib_bdy = 1, nb_bdy
899         DO igrd = 1, jpbgrd
900            icount  = 0
901            icountr = 0
902            idx_bdy(ib_bdy)%nblen(igrd)    = 0
903            idx_bdy(ib_bdy)%nblenrim(igrd) = 0
904            DO ib = 1, nblendta(igrd,ib_bdy)
905               ! check that data is in correct order in file
906               ibm1 = MAX(1,ib-1)
907               IF(lwp) THEN         ! Since all procs read global data only need to do this check on one proc...
908                  IF( nbrdta(ib,igrd,ib_bdy) < nbrdta(ibm1,igrd,ib_bdy) ) THEN
909                     CALL ctl_stop('bdy_init : ERROR : boundary data in file must be defined ', &
910                          &        ' in order of distance from edge nbr A utility for re-ordering ', &
911                          &        ' boundary coordinates and data files exists in the TOOLS/OBC directory')
912                  ENDIF   
913               ENDIF
914               ! check if point is in local domain
915               IF(  nbidta(ib,igrd,ib_bdy) >= iwe .AND. nbidta(ib,igrd,ib_bdy) <= ies .AND.   &
916                  & nbjdta(ib,igrd,ib_bdy) >= iso .AND. nbjdta(ib,igrd,ib_bdy) <= ino      ) THEN
917                  !
918                  icount = icount  + 1
919                  !
920                  IF( nbrdta(ib,igrd,ib_bdy) == 1 )   icountr = icountr+1
921               ENDIF
922            ENDDO
923            idx_bdy(ib_bdy)%nblenrim(igrd) = icountr !: length of rim boundary data on each proc
924            idx_bdy(ib_bdy)%nblen   (igrd) = icount  !: length of boundary data on each proc       
925         ENDDO  ! igrd
926
927         ! Allocate index arrays for this boundary set
928         !--------------------------------------------
929         ilen1 = MAXVAL(idx_bdy(ib_bdy)%nblen(:))
930         ALLOCATE( idx_bdy(ib_bdy)%nbi(ilen1,jpbgrd) )
931         ALLOCATE( idx_bdy(ib_bdy)%nbj(ilen1,jpbgrd) )
932         ALLOCATE( idx_bdy(ib_bdy)%nbr(ilen1,jpbgrd) )
933         ALLOCATE( idx_bdy(ib_bdy)%nbd(ilen1,jpbgrd) )
934         ALLOCATE( idx_bdy(ib_bdy)%nbdout(ilen1,jpbgrd) )
935         ALLOCATE( idx_bdy(ib_bdy)%nbmap(ilen1,jpbgrd) )
936         ALLOCATE( idx_bdy(ib_bdy)%nbw(ilen1,jpbgrd) )
937         ALLOCATE( idx_bdy(ib_bdy)%flagu(ilen1,jpbgrd) )
938         ALLOCATE( idx_bdy(ib_bdy)%flagv(ilen1,jpbgrd) )
939
940         ! Dispatch mapping indices and discrete distances on each processor
941         ! -----------------------------------------------------------------
942
943         com_east = 0
944         com_west = 0
945         com_south = 0
946         com_north = 0
947
948         com_east_b = 0
949         com_west_b = 0
950         com_south_b = 0
951         com_north_b = 0
952
953         DO igrd = 1, jpbgrd
954            icount  = 0
955            ! Loop on rimwidth to ensure outermost points come first in the local arrays.
956            DO ir=1, nn_rimwidth(ib_bdy)
957               DO ib = 1, nblendta(igrd,ib_bdy)
958                  ! check if point is in local domain and equals ir
959                  IF(  nbidta(ib,igrd,ib_bdy) >= iwe .AND. nbidta(ib,igrd,ib_bdy) <= ies .AND.   &
960                     & nbjdta(ib,igrd,ib_bdy) >= iso .AND. nbjdta(ib,igrd,ib_bdy) <= ino .AND.   &
961                     & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
962                     !
963                     icount = icount  + 1
964
965                     ! Rather assume that boundary data indices are given on global domain
966                     ! TO BE DISCUSSED ?
967!                     idx_bdy(ib_bdy)%nbi(icount,igrd)   = nbidta(ib,igrd,ib_bdy)- mig(1)+1
968!                     idx_bdy(ib_bdy)%nbj(icount,igrd)   = nbjdta(ib,igrd,ib_bdy)- mjg(1)+1
969                     idx_bdy(ib_bdy)%nbi(icount,igrd)   = nbidta(ib,igrd,ib_bdy)- mig(1)+jpizoom
970                     idx_bdy(ib_bdy)%nbj(icount,igrd)   = nbjdta(ib,igrd,ib_bdy)- mjg(1)+jpjzoom
971                     ! check if point has to be sent
972                     ii = idx_bdy(ib_bdy)%nbi(icount,igrd)
973                     ij = idx_bdy(ib_bdy)%nbj(icount,igrd)
974                     if((com_east .ne. 1) .and. (ii .eq. (nlci-1)) .and. (nbondi .le. 0)) then
975                        com_east = 1
976                     elseif((com_west .ne. 1) .and. (ii .eq. 2) .and. (nbondi .ge. 0) .and. (nbondi .ne. 2)) then
977                        com_west = 1
978                     endif
979                     if((com_south .ne. 1) .and. (ij .eq. 2) .and. (nbondj .ge. 0) .and. (nbondj .ne. 2)) then
980                        com_south = 1
981                     elseif((com_north .ne. 1) .and. (ij .eq. (nlcj-1)) .and. (nbondj .le. 0)) then
982                        com_north = 1
983                     endif
984                     idx_bdy(ib_bdy)%nbr(icount,igrd)   = nbrdta(ib,igrd,ib_bdy)
985                     idx_bdy(ib_bdy)%nbmap(icount,igrd) = ib
986                  ENDIF
987                  ! check if point has to be received from a neighbour
988                  IF(nbondi .eq. 0) THEN
989                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(1) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(1) .AND.   &
990                       & nbjdta(ib,igrd,ib_bdy) >= is_b(1) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(1) .AND.   &
991                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
992                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(1)+2
993                       if((com_west_b .ne. 1) .and. (ii .eq. (nlcit(nowe+1)-1))) then
994                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(1)+2
995                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
996                            com_south = 1
997                          elseif((ij .eq. nlcjt(nowe+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
998                            com_north = 1
999                          endif
1000                          com_west_b = 1
1001                       endif
1002                     ENDIF
1003                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(2) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(2) .AND.   &
1004                       & nbjdta(ib,igrd,ib_bdy) >= is_b(2) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(2) .AND.   &
1005                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1006                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(2)+2
1007                       if((com_east_b .ne. 1) .and. (ii .eq. 2)) then
1008                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(2)+2
1009                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
1010                            com_south = 1
1011                          elseif((ij .eq. nlcjt(noea+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
1012                            com_north = 1
1013                          endif
1014                          com_east_b = 1
1015                       endif
1016                     ENDIF
1017                  ELSEIF(nbondi .eq. 1) THEN
1018                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(1) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(1) .AND.   &
1019                       & nbjdta(ib,igrd,ib_bdy) >= is_b(1) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(1) .AND.   &
1020                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1021                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(1)+2
1022                       if((com_west_b .ne. 1) .and. (ii .eq. (nlcit(nowe+1)-1))) then
1023                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(1)+2
1024                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
1025                            com_south = 1
1026                          elseif((ij .eq. nlcjt(nowe+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
1027                            com_north = 1
1028                          endif
1029                          com_west_b = 1
1030                       endif
1031                     ENDIF
1032                  ELSEIF(nbondi .eq. -1) THEN
1033                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(2) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(2) .AND.   &
1034                       & nbjdta(ib,igrd,ib_bdy) >= is_b(2) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(2) .AND.   &
1035                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1036                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(2)+2
1037                       if((com_east_b .ne. 1) .and. (ii .eq. 2)) then
1038                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(2)+2
1039                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
1040                            com_south = 1
1041                          elseif((ij .eq. nlcjt(noea+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
1042                            com_north = 1
1043                          endif
1044                          com_east_b = 1
1045                       endif
1046                     ENDIF
1047                  ENDIF
1048                  IF(nbondj .eq. 0) THEN
1049                     IF(com_north_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(4)-1  &
1050                       & .OR. nbidta(ib,igrd,ib_bdy) == ie_b(4)+1) .AND. &
1051                       & nbjdta(ib,igrd,ib_bdy) == is_b(4) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
1052                       com_north_b = 1 
1053                     ENDIF
1054                     IF(com_south_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(3)-1  &
1055                       &.OR. nbidta(ib,igrd,ib_bdy) == ie_b(3)+1) .AND. &
1056                       & nbjdta(ib,igrd,ib_bdy) == in_b(3) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
1057                       com_south_b = 1 
1058                     ENDIF
1059                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(3) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(3) .AND.   &
1060                       & nbjdta(ib,igrd,ib_bdy) >= is_b(3) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(3) .AND.   &
1061                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1062                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(3)+2
1063                       if((com_south_b .ne. 1) .and. (ij .eq. (nlcjt(noso+1)-1))) then
1064                          com_south_b = 1
1065                       endif
1066                     ENDIF
1067                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(4) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(4) .AND.   &
1068                       & nbjdta(ib,igrd,ib_bdy) >= is_b(4) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(4) .AND.   &
1069                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1070                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(4)+2
1071                       if((com_north_b .ne. 1) .and. (ij .eq. 2)) then
1072                          com_north_b = 1
1073                       endif
1074                     ENDIF
1075                  ELSEIF(nbondj .eq. 1) THEN
1076                     IF( com_south_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(3)-1 .OR. &
1077                       & nbidta(ib,igrd,ib_bdy) == ie_b(3)+1) .AND. &
1078                       & nbjdta(ib,igrd,ib_bdy) == in_b(3) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
1079                       com_south_b = 1 
1080                     ENDIF
1081                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(3) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(3) .AND.   &
1082                       & nbjdta(ib,igrd,ib_bdy) >= is_b(3) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(3) .AND.   &
1083                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1084                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(3)+2
1085                       if((com_south_b .ne. 1) .and. (ij .eq. (nlcjt(noso+1)-1))) then
1086                          com_south_b = 1
1087                       endif
1088                     ENDIF
1089                  ELSEIF(nbondj .eq. -1) THEN
1090                     IF(com_north_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(4)-1  &
1091                       & .OR. nbidta(ib,igrd,ib_bdy) == ie_b(4)+1) .AND. &
1092                       & nbjdta(ib,igrd,ib_bdy) == is_b(4) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
1093                       com_north_b = 1 
1094                     ENDIF
1095                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(4) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(4) .AND.   &
1096                       & nbjdta(ib,igrd,ib_bdy) >= is_b(4) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(4) .AND.   &
1097                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
1098                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(4)+2
1099                       if((com_north_b .ne. 1) .and. (ij .eq. 2)) then
1100                          com_north_b = 1
1101                       endif
1102                     ENDIF
1103                  ENDIF
1104               ENDDO
1105            ENDDO
1106         ENDDO 
1107
1108         ! definition of the i- and j- direction local boundaries arrays
1109         ! used for sending the boudaries
1110         IF((com_east .eq. 1) .and. (com_west .eq. 1)) THEN
1111            nbondi_bdy(ib_bdy) = 0
1112         ELSEIF ((com_east .eq. 1) .and. (com_west .eq. 0)) THEN
1113            nbondi_bdy(ib_bdy) = -1
1114         ELSEIF ((com_east .eq. 0) .and. (com_west .eq. 1)) THEN
1115            nbondi_bdy(ib_bdy) = 1
1116         ENDIF
1117
1118         IF((com_north .eq. 1) .and. (com_south .eq. 1)) THEN
1119            nbondj_bdy(ib_bdy) = 0
1120         ELSEIF ((com_north .eq. 1) .and. (com_south .eq. 0)) THEN
1121            nbondj_bdy(ib_bdy) = -1
1122         ELSEIF ((com_north .eq. 0) .and. (com_south .eq. 1)) THEN
1123            nbondj_bdy(ib_bdy) = 1
1124         ENDIF
1125
1126         ! definition of the i- and j- direction local boundaries arrays
1127         ! used for receiving the boudaries
1128         IF((com_east_b .eq. 1) .and. (com_west_b .eq. 1)) THEN
1129            nbondi_bdy_b(ib_bdy) = 0
1130         ELSEIF ((com_east_b .eq. 1) .and. (com_west_b .eq. 0)) THEN
1131            nbondi_bdy_b(ib_bdy) = -1
1132         ELSEIF ((com_east_b .eq. 0) .and. (com_west_b .eq. 1)) THEN
1133            nbondi_bdy_b(ib_bdy) = 1
1134         ENDIF
1135
1136         IF((com_north_b .eq. 1) .and. (com_south_b .eq. 1)) THEN
1137            nbondj_bdy_b(ib_bdy) = 0
1138         ELSEIF ((com_north_b .eq. 1) .and. (com_south_b .eq. 0)) THEN
1139            nbondj_bdy_b(ib_bdy) = -1
1140         ELSEIF ((com_north_b .eq. 0) .and. (com_south_b .eq. 1)) THEN
1141            nbondj_bdy_b(ib_bdy) = 1
1142         ENDIF
1143
1144         ! Compute rim weights for FRS scheme
1145         ! ----------------------------------
1146         DO igrd = 1, jpbgrd
1147            DO ib = 1, idx_bdy(ib_bdy)%nblen(igrd)
1148               nbr => idx_bdy(ib_bdy)%nbr(ib,igrd)
1149!               idx_bdy(ib_bdy)%nbw(ib,igrd) = 1.- TANH( FLOAT( nbr - 1 ) *  0.5  & 
1150!                                            &  *(10./ FLOAT(nn_rimwidth(ib_bdy))) ) ! JGraham:modified for rim=15
1151               idx_bdy(ib_bdy)%nbw(ib,igrd) = 1.- TANH( FLOAT( nbr - 1 ) *0.5 )      ! tanh formulation !CBIJ MC config rim=1
1152!               idx_bdy(ib_bdy)%nbw(ib,igrd) = (FLOAT(nn_rimwidth(ib_bdy)+1-nbr)/FLOAT(nn_rimwidth(ib_bdy)))**2.  ! quadratic
1153!               idx_bdy(ib_bdy)%nbw(ib,igrd) =  FLOAT(nn_rimwidth(ib_bdy)+1-nbr)/FLOAT(nn_rimwidth(ib_bdy))       ! linear
1154            END DO
1155         END DO 
1156
1157         ! Compute damping coefficients
1158         ! ----------------------------
1159         DO igrd = 1, jpbgrd
1160            DO ib = 1, idx_bdy(ib_bdy)%nblen(igrd)
1161               nbr => idx_bdy(ib_bdy)%nbr(ib,igrd)
1162               idx_bdy(ib_bdy)%nbd(ib,igrd) = 1. / ( rn_time_dmp(ib_bdy) * rday ) & 
1163               & *(FLOAT(nn_rimwidth(ib_bdy)+1-nbr)/FLOAT(nn_rimwidth(ib_bdy)))**2.   ! quadratic
1164               idx_bdy(ib_bdy)%nbdout(ib,igrd) = 1. / ( rn_time_dmp_out(ib_bdy) * rday ) & 
1165               & *(FLOAT(nn_rimwidth(ib_bdy)+1-nbr)/FLOAT(nn_rimwidth(ib_bdy)))**2.   ! quadratic
1166            END DO
1167         END DO 
1168      ! Compute multiplier for diffusion for sponge layer !CEOD
1169           ! -------------------------------------------------
1170           IF( ln_sponge(ib_bdy) ) THEN
1171              igrd=1
1172              DO ib = 1, idx_bdy(ib_bdy)%nblen(igrd)
1173                 nbi => idx_bdy(ib_bdy)%nbi(ib,igrd)
1174                 nbj => idx_bdy(ib_bdy)%nbj(ib,igrd)
1175                 nbr => idx_bdy(ib_bdy)%nbr(ib,igrd)
1176                 sponge_factor(nbi,nbj) = 1.0 + (rn_sponge-1.0) * ( 1.- TANH( FLOAT( nbr - 1 ) *0.5 ) )
1177                 ! 0.5 factor says how fast tanh goes to 1 - reduce this to have
1178                 ! effect on more of the rimwidth
1179              END DO
1180           ENDIF
1181
1182      ENDDO
1183
1184      ! ------------------------------------------------------
1185      ! Initialise masks and find normal/tangential directions
1186      ! ------------------------------------------------------
1187
1188      ! Read global 2D mask at T-points: bdytmask
1189      ! -----------------------------------------
1190      ! bdytmask = 1  on the computational domain AND on open boundaries
1191      !          = 0  elsewhere   
1192 
1193      IF( ln_mask_file ) THEN
1194         CALL iom_open( cn_mask_file, inum )
1195         CALL iom_get ( inum, jpdom_data, 'bdy_msk', bdytmask(:,:) )
1196         CALL iom_close( inum )
1197
1198         ! Derive mask on U and V grid from mask on T grid
1199         bdyumask(:,:) = 0.e0
1200         bdyvmask(:,:) = 0.e0
1201         DO ij=1, jpjm1
1202            DO ii=1, jpim1
1203               bdyumask(ii,ij)=bdytmask(ii,ij)*bdytmask(ii+1, ij )
1204               bdyvmask(ii,ij)=bdytmask(ii,ij)*bdytmask(ii  ,ij+1) 
1205            END DO
1206         END DO
1207         CALL lbc_lnk( bdyumask(:,:), 'U', 1. )   ;   CALL lbc_lnk( bdyvmask(:,:), 'V', 1. )      ! Lateral boundary cond.
1208
1209
1210         ! Mask corrections
1211         ! ----------------
1212         DO ik = 1, jpkm1
1213            DO ij = 1, jpj
1214               DO ii = 1, jpi
1215                  tmask(ii,ij,ik) = tmask(ii,ij,ik) * bdytmask(ii,ij)
1216                  umask(ii,ij,ik) = umask(ii,ij,ik) * bdyumask(ii,ij)
1217                  vmask(ii,ij,ik) = vmask(ii,ij,ik) * bdyvmask(ii,ij)
1218                  bmask(ii,ij)    = bmask(ii,ij)    * bdytmask(ii,ij)
1219               END DO     
1220            END DO
1221         END DO
1222
1223         DO ik = 1, jpkm1
1224            DO ij = 2, jpjm1
1225               DO ii = 2, jpim1
1226                  fmask(ii,ij,ik) = fmask(ii,ij,ik) * bdytmask(ii,ij  ) * bdytmask(ii+1,ij  )   &
1227                     &                              * bdytmask(ii,ij+1) * bdytmask(ii+1,ij+1)
1228               END DO     
1229            END DO
1230         END DO
1231
1232         tmask_i (:,:) = ssmask(:,:) * tmask_i(:,:)
1233
1234      ENDIF ! ln_mask_file=.TRUE.
1235     
1236      bdytmask(:,:) = ssmask(:,:)
1237      IF( .not. ln_mask_file ) THEN
1238         ! If .not. ln_mask_file then we need to derive mask on U and V grid
1239         ! from mask on T grid here.
1240         bdyumask(:,:) = 0.e0
1241         bdyvmask(:,:) = 0.e0
1242         DO ij=1, jpjm1
1243            DO ii=1, jpim1
1244               bdyumask(ii,ij)=bdytmask(ii,ij)*bdytmask(ii+1, ij )
1245               bdyvmask(ii,ij)=bdytmask(ii,ij)*bdytmask(ii  ,ij+1) 
1246            END DO
1247         END DO
1248         CALL lbc_lnk( bdyumask(:,:), 'U', 1. )   ;   CALL lbc_lnk( bdyvmask(:,:), 'V', 1. )      ! Lateral boundary cond.
1249      ENDIF
1250
1251      ! bdy masks and bmask are now set to zero on boundary points:
1252      igrd = 1       ! In the free surface case, bmask is at T-points
1253      DO ib_bdy = 1, nb_bdy
1254        DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd)     
1255          bmask(idx_bdy(ib_bdy)%nbi(ib,igrd), idx_bdy(ib_bdy)%nbj(ib,igrd)) = 0.e0
1256        ENDDO
1257      ENDDO
1258      !
1259      igrd = 1
1260      DO ib_bdy = 1, nb_bdy
1261        DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd)     
1262          bdytmask(idx_bdy(ib_bdy)%nbi(ib,igrd), idx_bdy(ib_bdy)%nbj(ib,igrd)) = 0.e0
1263        ENDDO
1264      ENDDO
1265      !
1266      igrd = 2
1267      DO ib_bdy = 1, nb_bdy
1268        DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd)
1269          bdyumask(idx_bdy(ib_bdy)%nbi(ib,igrd), idx_bdy(ib_bdy)%nbj(ib,igrd)) = 0.e0
1270        ENDDO
1271      ENDDO
1272      !
1273      igrd = 3
1274      DO ib_bdy = 1, nb_bdy
1275        DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd)
1276          bdyvmask(idx_bdy(ib_bdy)%nbi(ib,igrd), idx_bdy(ib_bdy)%nbj(ib,igrd)) = 0.e0
1277        ENDDO
1278      ENDDO
1279
1280      ! For the flagu/flagv calculation below we require a version of fmask without
1281      ! the land boundary condition (shlat) included:
1282      CALL wrk_alloc(jpi,jpj,zfmask) 
1283      DO ij = 2, jpjm1
1284         DO ii = 2, jpim1
1285            zfmask(ii,ij) = tmask(ii,ij  ,1) * tmask(ii+1,ij  ,1)   &
1286           &              * tmask(ii,ij+1,1) * tmask(ii+1,ij+1,1)
1287         END DO     
1288      END DO
1289
1290      ! Lateral boundary conditions
1291      CALL lbc_lnk( zfmask       , 'F', 1. )
1292      CALL lbc_lnk( fmask        , 'F', 1. )   ;   CALL lbc_lnk( bdytmask(:,:), 'T', 1. )
1293      CALL lbc_lnk( bdyumask(:,:), 'U', 1. )   ;   CALL lbc_lnk( bdyvmask(:,:), 'V', 1. )
1294
1295      DO ib_bdy = 1, nb_bdy       ! Indices and directions of rim velocity components
1296
1297         idx_bdy(ib_bdy)%flagu(:,:) = 0.e0
1298         idx_bdy(ib_bdy)%flagv(:,:) = 0.e0
1299         icount = 0 
1300
1301         ! Calculate relationship of U direction to the local orientation of the boundary
1302         ! flagu = -1 : u component is normal to the dynamical boundary and its direction is outward
1303         ! flagu =  0 : u is tangential
1304         ! flagu =  1 : u is normal to the boundary and is direction is inward
1305 
1306         DO igrd = 1,jpbgrd 
1307            SELECT CASE( igrd )
1308               CASE( 1 )
1309                  pmask => umask(:,:,1)
1310                  i_offset = 0
1311               CASE( 2 ) 
1312                  pmask => bdytmask
1313                  i_offset = 1
1314               CASE( 3 ) 
1315                  pmask => zfmask(:,:)
1316                  i_offset = 0
1317            END SELECT
1318            icount = 0
1319            DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd) 
1320               nbi => idx_bdy(ib_bdy)%nbi(ib,igrd)
1321               nbj => idx_bdy(ib_bdy)%nbj(ib,igrd)
1322               zefl = pmask(nbi+i_offset-1,nbj)
1323               zwfl = pmask(nbi+i_offset,nbj)
1324               ! This error check only works if you are using the bdyXmask arrays
1325               IF( i_offset == 1 .and. zefl + zwfl == 2 ) THEN
1326                  icount = icount + 1
1327                  IF(lwp) WRITE(numout,*) 'Problem with igrd = ',igrd,' at (global) nbi, nbj : ',mig(nbi),mjg(nbj)
1328               ELSE
1329                  idx_bdy(ib_bdy)%flagu(ib,igrd) = -zefl + zwfl
1330               ENDIF
1331            END DO
1332            IF( icount /= 0 ) THEN
1333               IF(lwp) WRITE(numout,*)
1334               IF(lwp) WRITE(numout,*) ' E R R O R : Some ',cgrid(igrd),' grid points,',   &
1335                  ' are not boundary points (flagu calculation). Check nbi, nbj, indices for boundary set ',ib_bdy
1336               IF(lwp) WRITE(numout,*) ' ========== '
1337               IF(lwp) WRITE(numout,*)
1338               nstop = nstop + 1
1339            ENDIF
1340         END DO
1341
1342         ! Calculate relationship of V direction to the local orientation of the boundary
1343         ! flagv = -1 : v component is normal to the dynamical boundary but its direction is outward
1344         ! flagv =  0 : v is tangential
1345         ! flagv =  1 : v is normal to the boundary and is direction is inward
1346
1347         DO igrd = 1,jpbgrd 
1348            SELECT CASE( igrd )
1349               CASE( 1 )
1350                  pmask => vmask(:,:,1)
1351                  j_offset = 0
1352               CASE( 2 )
1353                  pmask => zfmask(:,:)
1354                  j_offset = 0
1355               CASE( 3 )
1356                  pmask => bdytmask
1357                  j_offset = 1
1358            END SELECT
1359            icount = 0
1360            DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd) 
1361               nbi => idx_bdy(ib_bdy)%nbi(ib,igrd)
1362               nbj => idx_bdy(ib_bdy)%nbj(ib,igrd)
1363               znfl = pmask(nbi,nbj+j_offset-1  )
1364               zsfl = pmask(nbi,nbj+j_offset)
1365               ! This error check only works if you are using the bdyXmask arrays
1366               IF( j_offset == 1 .and. znfl + zsfl == 2 ) THEN
1367                  IF(lwp) WRITE(numout,*) 'Problem with igrd = ',igrd,' at (global) nbi, nbj : ',mig(nbi),mjg(nbj)
1368                  icount = icount + 1
1369               ELSE
1370                  idx_bdy(ib_bdy)%flagv(ib,igrd) = -znfl + zsfl
1371               END IF
1372            END DO
1373            IF( icount /= 0 ) THEN
1374               IF(lwp) WRITE(numout,*)
1375               IF(lwp) WRITE(numout,*) ' E R R O R : Some ',cgrid(igrd),' grid points,',   &
1376                  ' are not boundary points (flagv calculation). Check nbi, nbj, indices for boundary set ',ib_bdy
1377               IF(lwp) WRITE(numout,*) ' ========== '
1378               IF(lwp) WRITE(numout,*)
1379               nstop = nstop + 1
1380            ENDIF
1381         END DO
1382
1383      END DO
1384
1385      ! Compute total lateral surface for volume correction:
1386      ! ----------------------------------------------------
1387      ! JC: this must be done at each time step with key_vvl
1388      bdysurftot = 0.e0 
1389      IF( ln_vol ) THEN 
1390         igrd = 2      ! Lateral surface at U-points
1391         DO ib_bdy = 1, nb_bdy
1392            DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd)
1393               nbi => idx_bdy(ib_bdy)%nbi(ib,igrd)
1394               nbj => idx_bdy(ib_bdy)%nbj(ib,igrd)
1395               flagu => idx_bdy(ib_bdy)%flagu(ib,igrd)
1396               bdysurftot = bdysurftot + hu     (nbi  , nbj)                           &
1397                  &                    * e2u    (nbi  , nbj) * ABS( flagu ) &
1398                  &                    * tmask_i(nbi  , nbj)                           &
1399                  &                    * tmask_i(nbi+1, nbj)                   
1400            ENDDO
1401         ENDDO
1402
1403         igrd=3 ! Add lateral surface at V-points
1404         DO ib_bdy = 1, nb_bdy
1405            DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd)
1406               nbi => idx_bdy(ib_bdy)%nbi(ib,igrd)
1407               nbj => idx_bdy(ib_bdy)%nbj(ib,igrd)
1408               flagv => idx_bdy(ib_bdy)%flagv(ib,igrd)
1409               bdysurftot = bdysurftot + hv     (nbi, nbj  )                           &
1410                  &                    * e1v    (nbi, nbj  ) * ABS( flagv ) &
1411                  &                    * tmask_i(nbi, nbj  )                           &
1412                  &                    * tmask_i(nbi, nbj+1)
1413            ENDDO
1414         ENDDO
1415         !
1416         IF( lk_mpp )   CALL mpp_sum( bdysurftot )      ! sum over the global domain
1417      END IF   
1418      !
1419      ! Tidy up
1420      !--------
1421      IF (nb_bdy>0) THEN
1422         DEALLOCATE(nbidta, nbjdta, nbrdta)
1423      ENDIF
1424
1425      CALL wrk_dealloc(jpi,jpj,zfmask) 
1426
1427      IF( nn_timing == 1 ) CALL timing_stop('bdy_init')
1428
1429   END SUBROUTINE bdy_init
1430
1431   SUBROUTINE bdy_ctl_seg
1432      !!----------------------------------------------------------------------
1433      !!                 ***  ROUTINE bdy_ctl_seg  ***
1434      !!
1435      !! ** Purpose :   Check straight open boundary segments location
1436      !!
1437      !! ** Method  :   - Look for open boundary corners
1438      !!                - Check that segments start or end on land
1439      !!----------------------------------------------------------------------
1440      INTEGER  ::   ib, ib1, ib2, ji ,jj, itest 
1441      INTEGER, DIMENSION(jp_nseg,2) :: icorne, icornw, icornn, icorns 
1442      REAL(wp), DIMENSION(2) ::   ztestmask
1443      !!----------------------------------------------------------------------
1444      !
1445      IF (lwp) WRITE(numout,*) ' '
1446      IF (lwp) WRITE(numout,*) 'bdy_ctl_seg: Check analytical segments'
1447      IF (lwp) WRITE(numout,*) '~~~~~~~~~~~~'
1448      !
1449      IF(lwp) WRITE(numout,*) 'Number of east  segments     : ', nbdysege
1450      IF(lwp) WRITE(numout,*) 'Number of west  segments     : ', nbdysegw
1451      IF(lwp) WRITE(numout,*) 'Number of north segments     : ', nbdysegn
1452      IF(lwp) WRITE(numout,*) 'Number of south segments     : ', nbdysegs
1453      ! 1. Check bounds
1454      !----------------
1455      DO ib = 1, nbdysegn
1456         IF (lwp) WRITE(numout,*) '**check north seg bounds pckg: ', npckgn(ib)
1457         IF ((jpjnob(ib).ge.jpjglo-1).or.& 
1458            &(jpjnob(ib).le.1))        CALL ctl_stop( 'nbdyind out of domain' )
1459         IF (jpindt(ib).ge.jpinft(ib)) CALL ctl_stop( 'Bdy start index is greater than end index' )
1460         IF (jpindt(ib).le.1     )     CALL ctl_stop( 'Start index out of domain' )
1461         IF (jpinft(ib).ge.jpiglo)     CALL ctl_stop( 'End index out of domain' )
1462      END DO
1463      !
1464      DO ib = 1, nbdysegs
1465         IF (lwp) WRITE(numout,*) '**check south seg bounds pckg: ', npckgs(ib)
1466         IF ((jpjsob(ib).ge.jpjglo-1).or.& 
1467            &(jpjsob(ib).le.1))        CALL ctl_stop( 'nbdyind out of domain' )
1468         IF (jpisdt(ib).ge.jpisft(ib)) CALL ctl_stop( 'Bdy start index is greater than end index' )
1469         IF (jpisdt(ib).le.1     )     CALL ctl_stop( 'Start index out of domain' )
1470         IF (jpisft(ib).ge.jpiglo)     CALL ctl_stop( 'End index out of domain' )
1471      END DO
1472      !
1473      DO ib = 1, nbdysege
1474         IF (lwp) WRITE(numout,*) '**check east  seg bounds pckg: ', npckge(ib)
1475         IF ((jpieob(ib).ge.jpiglo-1).or.& 
1476            &(jpieob(ib).le.1))        CALL ctl_stop( 'nbdyind out of domain' )
1477         IF (jpjedt(ib).ge.jpjeft(ib)) CALL ctl_stop( 'Bdy start index is greater than end index' )
1478         IF (jpjedt(ib).le.1     )     CALL ctl_stop( 'Start index out of domain' )
1479         IF (jpjeft(ib).ge.jpjglo)     CALL ctl_stop( 'End index out of domain' )
1480      END DO
1481      !
1482      DO ib = 1, nbdysegw
1483         IF (lwp) WRITE(numout,*) '**check west  seg bounds pckg: ', npckgw(ib)
1484         IF ((jpiwob(ib).ge.jpiglo-1).or.& 
1485            &(jpiwob(ib).le.1))        CALL ctl_stop( 'nbdyind out of domain' )
1486         IF (jpjwdt(ib).ge.jpjwft(ib)) CALL ctl_stop( 'Bdy start index is greater than end index' )
1487         IF (jpjwdt(ib).le.1     )     CALL ctl_stop( 'Start index out of domain' )
1488         IF (jpjwft(ib).ge.jpjglo)     CALL ctl_stop( 'End index out of domain' )
1489      ENDDO
1490      !
1491      !     
1492      ! 2. Look for segment crossings
1493      !------------------------------
1494      IF (lwp) WRITE(numout,*) '**Look for segments corners  :'
1495      !
1496      itest = 0 ! corner number
1497      !
1498      ! flag to detect if start or end of open boundary belongs to a corner
1499      ! if not (=0), it must be on land.
1500      ! if a corner is detected, save bdy package number for further tests
1501      icorne(:,:)=0. ; icornw(:,:)=0. ; icornn(:,:)=0. ; icorns(:,:)=0.
1502      ! South/West crossings
1503      IF ((nbdysegw > 0).AND.(nbdysegs > 0)) THEN
1504         DO ib1 = 1, nbdysegw       
1505            DO ib2 = 1, nbdysegs
1506               IF (( jpisdt(ib2)<=jpiwob(ib1)).AND. &
1507                &  ( jpisft(ib2)>=jpiwob(ib1)).AND. &
1508                &  ( jpjwdt(ib1)<=jpjsob(ib2)).AND. &
1509                &  ( jpjwft(ib1)>=jpjsob(ib2))) THEN
1510                  IF ((jpjwdt(ib1)==jpjsob(ib2)).AND.(jpisdt(ib2)==jpiwob(ib1))) THEN 
1511                     ! We have a possible South-West corner                     
1512!                     WRITE(numout,*) ' Found a South-West corner at (i,j): ', jpisdt(ib2), jpjwdt(ib1)
1513!                     WRITE(numout,*) ' between segments: ', npckgw(ib1), npckgs(ib2)
1514                     icornw(ib1,1) = npckgs(ib2)
1515                     icorns(ib2,1) = npckgw(ib1)
1516                  ELSEIF ((jpisft(ib2)==jpiwob(ib1)).AND.(jpjwft(ib1)==jpjsob(ib2))) THEN
1517                     IF(lwp) WRITE(numout,*)
1518                     IF(lwp) WRITE(numout,*) ' E R R O R : Found an acute open boundary corner at point (i,j)= ', &
1519                     &                                     jpisft(ib2), jpjwft(ib1)
1520                     IF(lwp) WRITE(numout,*) ' ==========  Not allowed yet'
1521                     IF(lwp) WRITE(numout,*) '             Crossing problem with West segment: ',npckgw(ib1), & 
1522                     &                                                    ' and South segment: ',npckgs(ib2)
1523                     IF(lwp) WRITE(numout,*)
1524                     nstop = nstop + 1
1525                  ELSE
1526                     IF(lwp) WRITE(numout,*)
1527                     IF(lwp) WRITE(numout,*) ' E R R O R : Check South and West Open boundary indices'
1528                     IF(lwp) WRITE(numout,*) ' ==========  Crossing problem with West segment: ',npckgw(ib1) , &
1529                     &                                                    ' and South segment: ',npckgs(ib2)
1530                     IF(lwp) WRITE(numout,*)
1531                     nstop = nstop+1
1532                  END IF
1533               END IF
1534            END DO
1535         END DO
1536      END IF
1537      !
1538      ! South/East crossings
1539      IF ((nbdysege > 0).AND.(nbdysegs > 0)) THEN
1540         DO ib1 = 1, nbdysege
1541            DO ib2 = 1, nbdysegs
1542               IF (( jpisdt(ib2)<=jpieob(ib1)+1).AND. &
1543                &  ( jpisft(ib2)>=jpieob(ib1)+1).AND. &
1544                &  ( jpjedt(ib1)<=jpjsob(ib2)  ).AND. &
1545                &  ( jpjeft(ib1)>=jpjsob(ib2)  )) THEN
1546                  IF ((jpjedt(ib1)==jpjsob(ib2)).AND.(jpisft(ib2)==jpieob(ib1)+1)) THEN
1547                     ! We have a possible South-East corner
1548!                     WRITE(numout,*) ' Found a South-East corner at (i,j): ', jpisft(ib2), jpjedt(ib1)
1549!                     WRITE(numout,*) ' between segments: ', npckge(ib1), npckgs(ib2)
1550                     icorne(ib1,1) = npckgs(ib2)
1551                     icorns(ib2,2) = npckge(ib1)
1552                  ELSEIF ((jpjeft(ib1)==jpjsob(ib2)).AND.(jpisdt(ib2)==jpieob(ib1)+1)) THEN
1553                     IF(lwp) WRITE(numout,*)
1554                     IF(lwp) WRITE(numout,*) ' E R R O R : Found an acute open boundary corner at point (i,j)= ', &
1555                     &                                     jpisdt(ib2), jpjeft(ib1)
1556                     IF(lwp) WRITE(numout,*) ' ==========  Not allowed yet'
1557                     IF(lwp) WRITE(numout,*) '             Crossing problem with East segment: ',npckge(ib1), &
1558                     &                                                    ' and South segment: ',npckgs(ib2)
1559                     IF(lwp) WRITE(numout,*)
1560                     nstop = nstop + 1
1561                  ELSE
1562                     IF(lwp) WRITE(numout,*)
1563                     IF(lwp) WRITE(numout,*) ' E R R O R : Check South and East Open boundary indices'
1564                     IF(lwp) WRITE(numout,*) ' ==========  Crossing problem with East segment: ',npckge(ib1), &
1565                     &                                                    ' and South segment: ',npckgs(ib2)
1566                     IF(lwp) WRITE(numout,*)
1567                     nstop = nstop + 1
1568                  END IF
1569               END IF
1570            END DO
1571         END DO
1572      END IF
1573      !
1574      ! North/West crossings
1575      IF ((nbdysegn > 0).AND.(nbdysegw > 0)) THEN
1576         DO ib1 = 1, nbdysegw       
1577            DO ib2 = 1, nbdysegn
1578               IF (( jpindt(ib2)<=jpiwob(ib1)  ).AND. &
1579                &  ( jpinft(ib2)>=jpiwob(ib1)  ).AND. &
1580                &  ( jpjwdt(ib1)<=jpjnob(ib2)+1).AND. &
1581                &  ( jpjwft(ib1)>=jpjnob(ib2)+1)) THEN
1582                  IF ((jpjwft(ib1)==jpjnob(ib2)+1).AND.(jpindt(ib2)==jpiwob(ib1))) THEN
1583                     ! We have a possible North-West corner
1584!                     WRITE(numout,*) ' Found a North-West corner at (i,j): ', jpindt(ib2), jpjwft(ib1)
1585!                     WRITE(numout,*) ' between segments: ', npckgw(ib1), npckgn(ib2)
1586                     icornw(ib1,2) = npckgn(ib2)
1587                     icornn(ib2,1) = npckgw(ib1)
1588                  ELSEIF ((jpjwdt(ib1)==jpjnob(ib2)+1).AND.(jpinft(ib2)==jpiwob(ib1))) THEN
1589                     IF(lwp) WRITE(numout,*)
1590                     IF(lwp) WRITE(numout,*) ' E R R O R : Found an acute open boundary corner at point (i,j)= ', &
1591                     &                                     jpinft(ib2), jpjwdt(ib1)
1592                     IF(lwp) WRITE(numout,*) ' ==========  Not allowed yet'
1593                     IF(lwp) WRITE(numout,*) '             Crossing problem with West segment: ',npckgw(ib1), &
1594                     &                                                    ' and North segment: ',npckgn(ib2)
1595                     IF(lwp) WRITE(numout,*)
1596                     nstop = nstop + 1
1597                  ELSE
1598                     IF(lwp) WRITE(numout,*)
1599                     IF(lwp) WRITE(numout,*) ' E R R O R : Check North and West Open boundary indices'
1600                     IF(lwp) WRITE(numout,*) ' ==========  Crossing problem with West segment: ',npckgw(ib1), &
1601                     &                                                    ' and North segment: ',npckgn(ib2)
1602                     IF(lwp) WRITE(numout,*)
1603                     nstop = nstop + 1
1604                  END IF
1605               END IF
1606            END DO
1607         END DO
1608      END IF
1609      !
1610      ! North/East crossings
1611      IF ((nbdysegn > 0).AND.(nbdysege > 0)) THEN
1612         DO ib1 = 1, nbdysege       
1613            DO ib2 = 1, nbdysegn
1614               IF (( jpindt(ib2)<=jpieob(ib1)+1).AND. &
1615                &  ( jpinft(ib2)>=jpieob(ib1)+1).AND. &
1616                &  ( jpjedt(ib1)<=jpjnob(ib2)+1).AND. &
1617                &  ( jpjeft(ib1)>=jpjnob(ib2)+1)) THEN
1618                  IF ((jpjeft(ib1)==jpjnob(ib2)+1).AND.(jpinft(ib2)==jpieob(ib1)+1)) THEN
1619                     ! We have a possible North-East corner
1620!                     WRITE(numout,*) ' Found a North-East corner at (i,j): ', jpinft(ib2), jpjeft(ib1)
1621!                     WRITE(numout,*) ' between segments: ', npckge(ib1), npckgn(ib2)
1622                     icorne(ib1,2) = npckgn(ib2)
1623                     icornn(ib2,2) = npckge(ib1)
1624                  ELSEIF ((jpjedt(ib1)==jpjnob(ib2)+1).AND.(jpindt(ib2)==jpieob(ib1)+1)) THEN
1625                     IF(lwp) WRITE(numout,*)
1626                     IF(lwp) WRITE(numout,*) ' E R R O R : Found an acute open boundary corner at point (i,j)= ', &
1627                     &                                     jpindt(ib2), jpjedt(ib1)
1628                     IF(lwp) WRITE(numout,*) ' ==========  Not allowed yet'
1629                     IF(lwp) WRITE(numout,*) '             Crossing problem with East segment: ',npckge(ib1), &
1630                     &                                                    ' and North segment: ',npckgn(ib2)
1631                     IF(lwp) WRITE(numout,*)
1632                     nstop = nstop + 1
1633                  ELSE
1634                     IF(lwp) WRITE(numout,*)
1635                     IF(lwp) WRITE(numout,*) ' E R R O R : Check North and East Open boundary indices'
1636                     IF(lwp) WRITE(numout,*) ' ==========  Crossing problem with East segment: ',npckge(ib1), &
1637                     &                                                    ' and North segment: ',npckgn(ib2)
1638                     IF(lwp) WRITE(numout,*)
1639                     nstop = nstop + 1
1640                  END IF
1641               END IF
1642            END DO
1643         END DO
1644      END IF
1645      !
1646      ! 3. Check if segment extremities are on land
1647      !--------------------------------------------
1648      !
1649      ! West segments
1650      DO ib = 1, nbdysegw
1651         ! get mask at boundary extremities:
1652         ztestmask(1:2)=0.
1653         DO ji = 1, jpi
1654            DO jj = 1, jpj             
1655              IF (((ji + nimpp - 1) == jpiwob(ib)).AND. & 
1656               &  ((jj + njmpp - 1) == jpjwdt(ib))) ztestmask(1)=tmask(ji,jj,1)
1657              IF (((ji + nimpp - 1) == jpiwob(ib)).AND. & 
1658               &  ((jj + njmpp - 1) == jpjwft(ib))) ztestmask(2)=tmask(ji,jj,1) 
1659            END DO
1660         END DO
1661         IF( lk_mpp )   CALL mpp_sum( ztestmask, 2 )   ! sum over the global domain
1662
1663         IF (ztestmask(1)==1) THEN
1664            IF (icornw(ib,1)==0) THEN
1665               IF(lwp) WRITE(numout,*)
1666               IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckgw(ib)
1667               IF(lwp) WRITE(numout,*) ' ==========  does not start on land or on a corner'                                                 
1668               IF(lwp) WRITE(numout,*)
1669               nstop = nstop + 1
1670            ELSE
1671               ! This is a corner
1672               IF(lwp) WRITE(numout,*) 'Found a South-West corner at (i,j): ', jpiwob(ib), jpjwdt(ib)
1673               CALL bdy_ctl_corn(npckgw(ib), icornw(ib,1))
1674               itest=itest+1
1675            ENDIF
1676         ENDIF
1677         IF (ztestmask(2)==1) THEN
1678            IF (icornw(ib,2)==0) THEN
1679               IF(lwp) WRITE(numout,*)
1680               IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckgw(ib)
1681               IF(lwp) WRITE(numout,*) ' ==========  does not end on land or on a corner'                                                 
1682               IF(lwp) WRITE(numout,*)
1683               nstop = nstop + 1
1684            ELSE
1685               ! This is a corner
1686               IF(lwp) WRITE(numout,*) 'Found a North-West corner at (i,j): ', jpiwob(ib), jpjwft(ib)
1687               CALL bdy_ctl_corn(npckgw(ib), icornw(ib,2))
1688               itest=itest+1
1689            ENDIF
1690         ENDIF
1691      END DO
1692      !
1693      ! East segments
1694      DO ib = 1, nbdysege
1695         ! get mask at boundary extremities:
1696         ztestmask(1:2)=0.
1697         DO ji = 1, jpi
1698            DO jj = 1, jpj             
1699              IF (((ji + nimpp - 1) == jpieob(ib)+1).AND. & 
1700               &  ((jj + njmpp - 1) == jpjedt(ib))) ztestmask(1)=tmask(ji,jj,1)
1701              IF (((ji + nimpp - 1) == jpieob(ib)+1).AND. & 
1702               &  ((jj + njmpp - 1) == jpjeft(ib))) ztestmask(2)=tmask(ji,jj,1) 
1703            END DO
1704         END DO
1705         IF( lk_mpp )   CALL mpp_sum( ztestmask, 2 )   ! sum over the global domain
1706
1707         IF (ztestmask(1)==1) THEN
1708            IF (icorne(ib,1)==0) THEN
1709               IF(lwp) WRITE(numout,*)
1710               IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckge(ib)
1711               IF(lwp) WRITE(numout,*) ' ==========  does not start on land or on a corner'                                                 
1712               IF(lwp) WRITE(numout,*)
1713               nstop = nstop + 1 
1714            ELSE
1715               ! This is a corner
1716               IF(lwp) WRITE(numout,*) 'Found a South-East corner at (i,j): ', jpieob(ib)+1, jpjedt(ib)
1717               CALL bdy_ctl_corn(npckge(ib), icorne(ib,1))
1718               itest=itest+1
1719            ENDIF
1720         ENDIF
1721         IF (ztestmask(2)==1) THEN
1722            IF (icorne(ib,2)==0) THEN
1723               IF(lwp) WRITE(numout,*)
1724               IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckge(ib)
1725               IF(lwp) WRITE(numout,*) ' ==========  does not end on land or on a corner'                                                 
1726               IF(lwp) WRITE(numout,*)
1727               nstop = nstop + 1
1728            ELSE
1729               ! This is a corner
1730               IF(lwp) WRITE(numout,*) 'Found a North-East corner at (i,j): ', jpieob(ib)+1, jpjeft(ib)
1731               CALL bdy_ctl_corn(npckge(ib), icorne(ib,2))
1732               itest=itest+1
1733            ENDIF
1734         ENDIF
1735      END DO
1736      !
1737      ! South segments
1738      DO ib = 1, nbdysegs
1739         ! get mask at boundary extremities:
1740         ztestmask(1:2)=0.
1741         DO ji = 1, jpi
1742            DO jj = 1, jpj             
1743              IF (((jj + njmpp - 1) == jpjsob(ib)).AND. & 
1744               &  ((ji + nimpp - 1) == jpisdt(ib))) ztestmask(1)=tmask(ji,jj,1)
1745              IF (((jj + njmpp - 1) == jpjsob(ib)).AND. & 
1746               &  ((ji + nimpp - 1) == jpisft(ib))) ztestmask(2)=tmask(ji,jj,1) 
1747            END DO
1748         END DO
1749         IF( lk_mpp )   CALL mpp_sum( ztestmask, 2 )   ! sum over the global domain
1750
1751         IF ((ztestmask(1)==1).AND.(icorns(ib,1)==0)) THEN
1752            IF(lwp) WRITE(numout,*)
1753            IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckgs(ib)
1754            IF(lwp) WRITE(numout,*) ' ==========  does not start on land or on a corner'                                                 
1755            IF(lwp) WRITE(numout,*)
1756            nstop = nstop + 1
1757         ENDIF
1758         IF ((ztestmask(2)==1).AND.(icorns(ib,2)==0)) THEN
1759            IF(lwp) WRITE(numout,*)
1760            IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckgs(ib)
1761            IF(lwp) WRITE(numout,*) ' ==========  does not end on land or on a corner'                                                 
1762            IF(lwp) WRITE(numout,*)
1763            nstop = nstop + 1
1764         ENDIF
1765      END DO
1766      !
1767      ! North segments
1768      DO ib = 1, nbdysegn
1769         ! get mask at boundary extremities:
1770         ztestmask(1:2)=0.
1771         DO ji = 1, jpi
1772            DO jj = 1, jpj             
1773              IF (((jj + njmpp - 1) == jpjnob(ib)+1).AND. & 
1774               &  ((ji + nimpp - 1) == jpindt(ib))) ztestmask(1)=tmask(ji,jj,1)
1775              IF (((jj + njmpp - 1) == jpjnob(ib)+1).AND. & 
1776               &  ((ji + nimpp - 1) == jpinft(ib))) ztestmask(2)=tmask(ji,jj,1) 
1777            END DO
1778         END DO
1779         IF( lk_mpp )   CALL mpp_sum( ztestmask, 2 )   ! sum over the global domain
1780
1781         IF ((ztestmask(1)==1).AND.(icornn(ib,1)==0)) THEN
1782            IF(lwp) WRITE(numout,*)
1783            IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckgn(ib)
1784            IF(lwp) WRITE(numout,*) ' ==========  does not start on land'                                                 
1785            IF(lwp) WRITE(numout,*)
1786            nstop = nstop + 1
1787         ENDIF
1788         IF ((ztestmask(2)==1).AND.(icornn(ib,2)==0)) THEN
1789            IF(lwp) WRITE(numout,*)
1790            IF(lwp) WRITE(numout,*) ' E R R O R : Open boundary segment ', npckgn(ib)
1791            IF(lwp) WRITE(numout,*) ' ==========  does not end on land'                                                 
1792            IF(lwp) WRITE(numout,*)
1793            nstop = nstop + 1
1794         ENDIF
1795      END DO
1796      !
1797      IF ((itest==0).AND.(lwp)) WRITE(numout,*) 'NO open boundary corner found'
1798      !
1799      ! Other tests TBD:
1800      ! segments completly on land
1801      ! optimized open boundary array length according to landmask
1802      ! Nudging layers that overlap with interior domain
1803      !
1804   END SUBROUTINE bdy_ctl_seg
1805
1806   SUBROUTINE bdy_ctl_corn( ib1, ib2 )
1807      !!----------------------------------------------------------------------
1808      !!                 ***  ROUTINE bdy_ctl_corn  ***
1809      !!
1810      !! ** Purpose :   Check numerical schemes consistency between
1811      !!                segments having a common corner
1812      !!
1813      !! ** Method  :   
1814      !!----------------------------------------------------------------------
1815      INTEGER, INTENT(in)  ::   ib1, ib2
1816      INTEGER :: itest
1817      !!----------------------------------------------------------------------
1818      itest = 0
1819
1820      IF (cn_dyn2d(ib1)/=cn_dyn2d(ib2)) itest = itest + 1
1821      IF (cn_dyn3d(ib1)/=cn_dyn3d(ib2)) itest = itest + 1
1822      IF (cn_tra(ib1)/=cn_tra(ib2)) itest = itest + 1
1823      !
1824      IF (nn_dyn2d_dta(ib1)/=nn_dyn2d_dta(ib2)) itest = itest + 1
1825      IF (nn_dyn3d_dta(ib1)/=nn_dyn3d_dta(ib2)) itest = itest + 1
1826      IF (nn_tra_dta(ib1)/=nn_tra_dta(ib2)) itest = itest + 1
1827      !
1828      IF (nn_rimwidth(ib1)/=nn_rimwidth(ib2)) itest = itest + 1   
1829      !
1830      IF ( itest>0 ) THEN
1831         IF(lwp) WRITE(numout,*) ' E R R O R : Segments ', ib1, 'and ', ib2
1832         IF(lwp) WRITE(numout,*) ' ==========  have different open bdy schemes'                                                 
1833         IF(lwp) WRITE(numout,*)
1834         nstop = nstop + 1
1835      ENDIF
1836      !
1837   END SUBROUTINE bdy_ctl_corn
1838
1839#else
1840   !!---------------------------------------------------------------------------------
1841   !!   Dummy module                                   NO open boundaries
1842   !!---------------------------------------------------------------------------------
1843CONTAINS
1844   SUBROUTINE bdy_init      ! Dummy routine
1845   END SUBROUTINE bdy_init
1846#endif
1847
1848   !!=================================================================================
1849END MODULE bdyini
Note: See TracBrowser for help on using the repository browser.