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.
bdydyn2d.F90 in NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY – NEMO

source: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn2d.F90 @ 11210

Last change on this file since 11210 was 11210, checked in by girrmann, 5 years ago

dev_r10984_HPC-13 : remove some communications in bdy treatment in case nn_hls > 1, see #2285

  • Property svn:keywords set to Id
File size: 17.9 KB
Line 
1MODULE bdydyn2d
2   !!======================================================================
3   !!                       ***  MODULE  bdydyn  ***
4   !! Unstructured Open Boundary Cond. :   Apply boundary conditions to barotropic solution
5   !!======================================================================
6   !! History :  3.4  !  2011     (D. Storkey) new module as part of BDY rewrite
7   !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Optimization of BDY communications
8   !!            3.5  !  2013-07  (J. Chanut) Compliant with time splitting changes
9   !!----------------------------------------------------------------------
10   !!   bdy_dyn2d          : Apply open boundary conditions to barotropic variables.
11   !!   bdy_dyn2d_frs      : Apply Flow Relaxation Scheme
12   !!   bdy_dyn2d_fla      : Apply Flather condition
13   !!   bdy_dyn2d_orlanski : Orlanski Radiation
14   !!   bdy_ssh            : Duplicate sea level across open boundaries
15   !!----------------------------------------------------------------------
16   USE oce, only : sshdta => spgu             ! ocean dynamics and tracers
17   USE dom_oce         ! ocean space and time domain
18   USE bdy_oce         ! ocean open boundary conditions
19   USE bdylib          ! BDY library routines
20   USE phycst          ! physical constants
21   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
22   USE wet_dry         ! Use wet dry to get reference ssh level
23   USE in_out_manager  !
24   USE lib_mpp, ONLY: ctl_stop
25
26   IMPLICIT NONE
27   PRIVATE
28
29   PUBLIC   bdy_dyn2d   ! routine called in dynspg_ts and bdy_dyn
30   PUBLIC   bdy_ssh       ! routine called in dynspg_ts or sshwzv
31
32   !!----------------------------------------------------------------------
33   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
34   !! $Id$
35   !! Software governed by the CeCILL license (see ./LICENSE)
36   !!----------------------------------------------------------------------
37CONTAINS
38
39   SUBROUTINE bdy_dyn2d( kt, pua2d, pva2d, pub2d, pvb2d, phur, phvr, pssh  )
40      !!----------------------------------------------------------------------
41      !!                  ***  SUBROUTINE bdy_dyn2d  ***
42      !!
43      !! ** Purpose : - Apply open boundary conditions for barotropic variables
44      !!
45      !!----------------------------------------------------------------------
46      INTEGER,                      INTENT(in) ::   kt   ! Main time step counter
47      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) :: pua2d, pva2d 
48      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) :: pub2d, pvb2d
49      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) :: phur, phvr
50      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) :: pssh
51      !!
52      INTEGER  ::   ib_bdy, ir     ! BDY set index, rim index
53      LOGICAL  ::   llrim0         ! indicate if rim 0 is treated
54      LOGICAL, DIMENSION(4) :: llsend2, llrecv2, llsend3, llrecv3  ! indicate how communications are to be carried out
55     
56      llsend2(:) = .false.   ;   llrecv2(:) = .false.
57      llsend3(:) = .false.   ;   llrecv3(:) = .false.
58      DO ir = 1, 0, -1   ! treat rim 1 before rim 0
59         IF( ir == 0 ) THEN   ;   llrim0 = .TRUE.
60         ELSE                 ;   llrim0 = .FALSE.
61         END IF
62         DO ib_bdy=1, nb_bdy
63            SELECT CASE( cn_dyn2d(ib_bdy) )
64            CASE('none')
65               CYCLE
66            CASE('frs')   ! treat the whole boundary at once
67               IF( llrim0 )   CALL bdy_dyn2d_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy, pua2d, pva2d )
68            CASE('flather')
69               CALL bdy_dyn2d_fla( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy, pua2d, pva2d, pssh, phur, phvr, llrim0 )
70            CASE('orlanski')
71               CALL bdy_dyn2d_orlanski( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy, &
72                    & pua2d, pva2d, pub2d, pvb2d, llrim0, ll_npo=.false. )
73            CASE('orlanski_npo')
74               CALL bdy_dyn2d_orlanski( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy, &
75                    & pua2d, pva2d, pub2d, pvb2d, llrim0, ll_npo=.true.  )
76            CASE DEFAULT
77               CALL ctl_stop( 'bdy_dyn2d : unrecognised option for open boundaries for barotropic variables' )
78            END SELECT
79         ENDDO
80         !
81         IF( nn_hls > 1 .AND. ir == 1 ) CYCLE   ! at least 2 halos will be corrected -> no need to correct rim 1 before rim 0
82         IF( nn_hls == 1 ) THEN
83            llsend2(:) = .false.   ;   llrecv2(:) = .false.
84            llsend3(:) = .false.   ;   llrecv3(:) = .false.
85         END IF
86         DO ib_bdy=1, nb_bdy
87            SELECT CASE( cn_dyn2d(ib_bdy) )
88            CASE('flather')
89               llsend2(1:2) = llsend2(1:2) .OR. lsend_bdyint(ib_bdy,2,1:2,ir)   ! west/east, U points
90               llsend2(1)   = llsend2(1)   .OR. lsend_bdyext(ib_bdy,2,1,ir)     ! neighbour might search point towards its east bdy
91               llrecv2(1:2) = llrecv2(1:2) .OR. lrecv_bdyint(ib_bdy,2,1:2,ir)   ! west/east, U points
92               llrecv2(2)   = llrecv2(2)   .OR. lrecv_bdyext(ib_bdy,2,2,ir)     ! might search point towards bdy on the east
93               llsend3(3:4) = llsend3(3:4) .OR. lsend_bdyint(ib_bdy,3,3:4,ir)   ! north/south, V points
94               llsend3(3)   = llsend3(3)   .OR. lsend_bdyext(ib_bdy,3,3,ir)     ! neighbour might search point towards its north bdy
95               llrecv3(3:4) = llrecv3(3:4) .OR. lrecv_bdyint(ib_bdy,3,3:4,ir)   ! north/south, V points
96               llrecv3(4)   = llrecv3(4)   .OR. lrecv_bdyext(ib_bdy,3,4,ir)     ! might search point towards bdy on the north
97            CASE('orlanski', 'orlanski_npo')
98               llsend2(:) = llsend2(:) .OR. lsend_bdy(ib_bdy,2,:,ir)   ! possibly every direction, U points
99               llrecv2(:) = llrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:,ir)   ! possibly every direction, U points
100               llsend3(:) = llsend3(:) .OR. lsend_bdy(ib_bdy,3,:,ir)   ! possibly every direction, V points
101               llrecv3(:) = llrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:,ir)   ! possibly every direction, V points
102            END SELECT
103         END DO
104         IF( ANY(llsend2) .OR. ANY(llrecv2) ) THEN   ! if need to send/recv in at least one direction
105            CALL lbc_lnk( 'bdydyn2d', pua2d, 'U', -1., kfillmode=jpfillnothing ,lsend=llsend2, lrecv=llrecv2 )
106         END IF
107         IF( ANY(llsend3) .OR. ANY(llrecv3) ) THEN   ! if need to send/recv in at least one direction
108            CALL lbc_lnk( 'bdydyn2d', pva2d, 'V', -1., kfillmode=jpfillnothing ,lsend=llsend3, lrecv=llrecv3 )
109         END IF
110         !
111      END DO   ! ir
112      !
113   END SUBROUTINE bdy_dyn2d
114
115   SUBROUTINE bdy_dyn2d_frs( idx, dta, ib_bdy, pua2d, pva2d )
116      !!----------------------------------------------------------------------
117      !!                  ***  SUBROUTINE bdy_dyn2d_frs  ***
118      !!
119      !! ** Purpose : - Apply the Flow Relaxation Scheme for barotropic velocities
120      !!                at open boundaries.
121      !!
122      !! References :- Engedahl H., 1995: Use of the flow relaxation scheme in
123      !!               a three-dimensional baroclinic ocean model with realistic
124      !!               topography. Tellus, 365-382.
125      !!----------------------------------------------------------------------
126      TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
127      TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
128      INTEGER,         INTENT(in) ::   ib_bdy  ! BDY set index
129      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) :: pua2d, pva2d 
130      !!
131      INTEGER  ::   jb             ! dummy loop indices
132      INTEGER  ::   ii, ij, igrd   ! local integers
133      REAL(wp) ::   zwgt           ! boundary weight
134      !!----------------------------------------------------------------------
135      !
136      igrd = 2                      ! Relaxation of zonal velocity
137      DO jb = 1, idx%nblen(igrd)
138         ii   = idx%nbi(jb,igrd)
139         ij   = idx%nbj(jb,igrd)
140         zwgt = idx%nbw(jb,igrd)
141         pua2d(ii,ij) = ( pua2d(ii,ij) + zwgt * ( dta%u2d(jb) - pua2d(ii,ij) ) ) * umask(ii,ij,1)
142      END DO
143      !
144      igrd = 3                      ! Relaxation of meridional velocity
145      DO jb = 1, idx%nblen(igrd)
146         ii   = idx%nbi(jb,igrd)
147         ij   = idx%nbj(jb,igrd)
148         zwgt = idx%nbw(jb,igrd)
149         pva2d(ii,ij) = ( pva2d(ii,ij) + zwgt * ( dta%v2d(jb) - pva2d(ii,ij) ) ) * vmask(ii,ij,1)
150      END DO 
151      !
152   END SUBROUTINE bdy_dyn2d_frs
153
154
155   SUBROUTINE bdy_dyn2d_fla( idx, dta, ib_bdy, pua2d, pva2d, pssh, phur, phvr, llrim0 )
156      !!----------------------------------------------------------------------
157      !!                 ***  SUBROUTINE bdy_dyn2d_fla  ***
158      !!             
159      !!              - Apply Flather boundary conditions on normal barotropic velocities
160      !!
161      !! ** WARNINGS about FLATHER implementation:
162      !!1. According to Palma and Matano, 1998 "after ssh" is used.
163      !!   In ROMS and POM implementations, it is "now ssh". In the current
164      !!   implementation (tested only in the EEL-R5 conf.), both cases were unstable.
165      !!   So I use "before ssh" in the following.
166      !!
167      !!2. We assume that the normal ssh gradient at the bdy is zero. As a matter of
168      !!   fact, the model ssh just inside the dynamical boundary is used (the outside 
169      !!   ssh in the code is not updated).
170      !!
171      !! References:  Flather, R. A., 1976: A tidal model of the northwest European
172      !!              continental shelf. Mem. Soc. R. Sci. Liege, Ser. 6,10, 141-164.     
173      !!----------------------------------------------------------------------
174      TYPE(OBC_INDEX),              INTENT(in) ::   idx  ! OBC indices
175      TYPE(OBC_DATA),               INTENT(in) ::   dta  ! OBC external data
176      INTEGER,                      INTENT(in) ::   ib_bdy  ! BDY set index
177      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) :: pua2d, pva2d
178      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pssh, phur, phvr
179      LOGICAL                     , INTENT(in) ::   llrim0   ! indicate if rim 0 is treated
180      INTEGER  ::   ibeg, iend                       ! length of rim to be treated (rim 0 or rim 1)
181      INTEGER  ::   jb, igrd                         ! dummy loop indices
182      INTEGER  ::   ii, ij                           ! 2D addresses
183      INTEGER  ::   iiTrim, ijTrim                   ! T pts i/j-indice on the rim
184      INTEGER  ::   iiToce, ijToce, iiUoce, ijVoce   ! T, U and V pts i/j-indice of the ocean next to the rim
185      REAL(wp) ::   flagu, flagv                     ! short cuts
186      REAL(wp) ::   zfla                             ! Flather correction
187      REAL(wp) ::   z1_2                             !
188      !!----------------------------------------------------------------------
189
190      z1_2 = 0.5_wp
191
192      ! ---------------------------------!
193      ! Flather boundary conditions     :!
194      ! ---------------------------------!
195
196      ! Fill temporary array with ssh data (here we use spgu with the alias sshdta):
197      igrd = 1
198      IF( llrim0 ) THEN   ;   ibeg = 1                       ;   iend = idx%nblenrim0(igrd)
199      ELSE                ;   ibeg = idx%nblenrim0(igrd)+1   ;   iend = idx%nblenrim(igrd)
200      END IF
201      sshdta(:,:) = 0.0
202      DO jb = ibeg, iend
203         ii = idx%nbi(jb,igrd)
204         ij = idx%nbj(jb,igrd)
205         IF( ll_wd ) THEN
206            sshdta(ii, ij) = dta%ssh(jb)  - ssh_ref 
207         ELSE
208            sshdta(ii, ij) = dta%ssh(jb)
209         ENDIF
210      END DO
211      !
212      igrd = 2      ! Flather bc on u-velocity
213      !             ! remember that flagu=-1 if normal velocity direction is outward
214      !             ! I think we should rather use after ssh ?
215      IF( llrim0 ) THEN   ;   ibeg = 1                       ;   iend = idx%nblenrim0(igrd)
216      ELSE                ;   ibeg = idx%nblenrim0(igrd)+1   ;   iend = idx%nblenrim(igrd)
217      END IF
218      DO jb = ibeg, iend
219         ii    = idx%nbi(jb,igrd)
220         ij    = idx%nbj(jb,igrd)
221         flagu = idx%flagu(jb,igrd)
222         IF( flagu == 0. ) THEN
223            pua2d(ii,ij) = dta%u2d(jb)
224         ELSE      ! T pts j-indice       on the rim          on the ocean next to the rim on T and U points
225            IF( flagu ==  1. ) THEN   ;   iiTrim = ii     ;   iiToce = ii+1   ;   iiUoce = ii+1   ;   ENDIF
226            IF( flagu == -1. ) THEN   ;   iiTrim = ii+1   ;   iiToce = ii     ;   iiUoce = ii-1   ;   ENDIF
227            !
228            ! Rare case : rim is parallel to the mpi subdomain border and on the halo : point will be received
229            IF( iiTrim > jpi .OR. iiToce > jpi .OR. iiUoce > jpi .OR. iiUoce < 1 )   CYCLE   
230            !
231            zfla = dta%u2d(jb) - flagu * SQRT( grav * phur(ii, ij) ) * ( pssh(iiToce,ij) - sshdta(iiTrim,ij) )
232            !
233            ! jchanut tschanges, use characteristics method (Blayo et Debreu, 2005) :
234            ! mix Flather scheme with velocity of the ocean next to the rim
235            pua2d(ii,ij) =  z1_2 * ( pua2d(iiUoce,ij) + zfla )
236         END IF
237      END DO
238      !
239      igrd = 3      ! Flather bc on v-velocity
240      !             ! remember that flagv=-1 if normal velocity direction is outward
241      IF( llrim0 ) THEN   ;   ibeg = 1                       ;   iend = idx%nblenrim0(igrd)
242      ELSE                ;   ibeg = idx%nblenrim0(igrd)+1   ;   iend = idx%nblenrim(igrd)
243      END IF
244      DO jb = ibeg, iend
245         ii    = idx%nbi(jb,igrd)
246         ij    = idx%nbj(jb,igrd)
247         flagv = idx%flagv(jb,igrd)
248         IF( flagv == 0. ) THEN
249            pva2d(ii,ij) = dta%v2d(jb)
250         ELSE      ! T pts j-indice       on the rim          on the ocean next to the rim on T and V points
251            IF( flagv ==  1. ) THEN   ;   ijTrim = ij     ;   ijToce = ij+1   ;   ijVoce = ij+1   ;   ENDIF
252            IF( flagv == -1. ) THEN   ;   ijTrim = ij+1   ;   ijToce = ij     ;   ijVoce = ij-1   ;   ENDIF
253            !
254            ! Rare case : rim is parallel to the mpi subdomain border and on the halo : point will be received
255            IF( ijTrim > jpj .OR. ijToce > jpj .OR. ijVoce > jpj .OR. ijVoce < 1 )   CYCLE
256            !
257            zfla = dta%v2d(jb) - flagv * SQRT( grav * phvr(ii, ij) ) * ( pssh(ii,ijToce) - sshdta(ii,ijTrim) )
258            !
259            ! jchanut tschanges, use characteristics method (Blayo et Debreu, 2005) :
260            ! mix Flather scheme with velocity of the ocean next to the rim
261            pva2d(ii,ij) =  z1_2 * ( pva2d(ii,ijVoce) + zfla )
262         END IF
263      END DO
264      !
265   END SUBROUTINE bdy_dyn2d_fla
266
267
268   SUBROUTINE bdy_dyn2d_orlanski( idx, dta, ib_bdy, pua2d, pva2d, pub2d, pvb2d, llrim0, ll_npo )
269      !!----------------------------------------------------------------------
270      !!                 ***  SUBROUTINE bdy_dyn2d_orlanski  ***
271      !!             
272      !!              - Apply Orlanski radiation condition adaptively:
273      !!                  - radiation plus weak nudging at outflow points
274      !!                  - no radiation and strong nudging at inflow points
275      !!
276      !!
277      !! References:  Marchesiello, McWilliams and Shchepetkin, Ocean Modelling vol. 3 (2001)   
278      !!----------------------------------------------------------------------
279      TYPE(OBC_INDEX),              INTENT(in) ::   idx  ! OBC indices
280      TYPE(OBC_DATA),               INTENT(in) ::   dta  ! OBC external data
281      INTEGER,                      INTENT(in) ::   ib_bdy  ! number of current open boundary set
282      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) :: pua2d, pva2d
283      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pub2d, pvb2d 
284      LOGICAL,                      INTENT(in) ::   ll_npo  ! flag for NPO version
285      LOGICAL,                      INTENT(in) ::   llrim0   ! indicate if rim 0 is treated
286      INTEGER  ::   ib, igrd                               ! dummy loop indices
287      INTEGER  ::   ii, ij, iibm1, ijbm1                   ! indices
288      !!----------------------------------------------------------------------
289      !
290      igrd = 2      ! Orlanski bc on u-velocity;
291      !           
292      CALL bdy_orlanski_2d( idx, igrd, pub2d, pua2d, dta%u2d, llrim0, ll_npo )
293
294      igrd = 3      ! Orlanski bc on v-velocity
295     
296      CALL bdy_orlanski_2d( idx, igrd, pvb2d, pva2d, dta%v2d, llrim0, ll_npo )
297      !
298   END SUBROUTINE bdy_dyn2d_orlanski
299
300
301   SUBROUTINE bdy_ssh( zssh )
302      !!----------------------------------------------------------------------
303      !!                  ***  SUBROUTINE bdy_ssh  ***
304      !!
305      !! ** Purpose : Duplicate sea level across open boundaries
306      !!
307      !!----------------------------------------------------------------------
308      REAL(wp), DIMENSION(jpi,jpj,1), INTENT(inout) ::   zssh ! Sea level, need 3 dimensions to be used by bdy_nmn
309      !!
310      INTEGER ::   ib_bdy, ir      ! bdy index, rim index
311      INTEGER ::   ibeg, iend      ! length of rim to be treated (rim 0 or rim 1)
312      LOGICAL ::   llrim0          ! indicate if rim 0 is treated
313      LOGICAL, DIMENSION(4) :: llsend1, llrecv1  ! indicate how communications are to be carried out
314      !!----------------------------------------------------------------------
315      llsend1(:) = .false.   ;   llrecv1(:) = .false.
316      DO ir = 1, 0, -1   ! treat rim 1 before rim 0
317         IF( nn_hls == 1 ) THEN   ;   llsend1(:) = .false.   ;   llrecv1(:) = .false.   ;   END IF
318         IF( ir == 0 ) THEN   ;   llrim0 = .TRUE.
319         ELSE                 ;   llrim0 = .FALSE.
320         END IF
321         DO ib_bdy = 1, nb_bdy
322            CALL bdy_nmn( idx_bdy(ib_bdy), 1, zssh, llrim0 )   ! zssh is masked
323            llsend1(:) = llsend1(:) .OR. lsend_bdyint(ib_bdy,1,:,ir)   ! possibly every direction, T points
324            llrecv1(:) = llrecv1(:) .OR. lrecv_bdyint(ib_bdy,1,:,ir)   ! possibly every direction, T points
325         END DO
326         IF( nn_hls > 1 .AND. ir == 1 ) CYCLE   ! at least 2 halos will be corrected -> no need to correct rim 1 before rim 0
327         IF( ANY(llsend1) .OR. ANY(llrecv1) ) THEN   ! if need to send/recv in at least one direction
328            CALL lbc_lnk( 'bdydyn2d', zssh(:,:,1), 'T',  1., kfillmode=jpfillnothing ,lsend=llsend1, lrecv=llrecv1 )
329         END IF
330      END DO
331      !
332   END SUBROUTINE bdy_ssh
333
334   !!======================================================================
335END MODULE bdydyn2d
336
Note: See TracBrowser for help on using the repository browser.