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

source: branches/2017/dev_merge_2017/NEMOGCM/NEMO/OPA_SRC/USR/usrdef_closea.F90 @ 9124

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

dev_merge_2017: ln_timing instead of nn_timing + restricted timing to nemo_init and routine called by step in OPA_SRC

  • Property svn:keywords set to Id
File size: 18.2 KB
Line 
1MODULE usrdef_closea
2   !!======================================================================
3   !!                   ***  MODULE  usrdef_closea  ***
4   !!
5   !!                      ===  ORCA configuration  ===
6   !!                         (2, 1 and 1/4 degrees)
7   !!
8   !! User define : specific treatments associated with closed seas
9   !!======================================================================
10   !! History :   8.2  !  2000-05  (O. Marti)  Original code
11   !!   NEMO      1.0  !  2002-06  (E. Durand, G. Madec)  F90
12   !!             3.0  !  2006-07  (G. Madec)  add clo_rnf, clo_ups, clo_bat
13   !!             3.4  !  2014-12  (P.G. Fogli) sbc_clo bug fix & mpp reproducibility
14   !!             4.0  !  2016-06  (G. Madec)  move to usrdef_closea, remove clo_ups
15   !!----------------------------------------------------------------------
16
17   !!----------------------------------------------------------------------
18   !!   dom_clo    : modification of the ocean domain for closed seas cases
19   !!   sbc_clo    : Special handling of closed seas
20   !!   clo_rnf    : set close sea outflows as river mouths (see sbcrnf)
21   !!   clo_bat    : set to zero a field over closed sea (see domzrg)
22   !!----------------------------------------------------------------------
23   USE oce             ! dynamics and tracers
24   USE dom_oce         ! ocean space and time domain
25   USE phycst          ! physical constants
26   USE sbc_oce         ! ocean surface boundary conditions
27   !
28   USE in_out_manager  ! I/O manager
29   USE lib_fortran,    ONLY: glob_sum, DDPDD
30   USE lbclnk          ! lateral boundary condition - MPP exchanges
31   USE lib_mpp         ! MPP library
32
33   IMPLICIT NONE
34   PRIVATE
35
36   PUBLIC dom_clo      ! called by domain module
37   PUBLIC sbc_clo      ! called by step module
38   PUBLIC clo_rnf      ! called by sbcrnf module
39   PUBLIC clo_bat      ! called in domzgr module
40
41   INTEGER, PUBLIC, PARAMETER          ::   jpncs   = 4      !: number of closed sea
42   INTEGER, PUBLIC, DIMENSION(jpncs)   ::   ncstt            !: Type of closed sea
43   INTEGER, PUBLIC, DIMENSION(jpncs)   ::   ncsi1, ncsj1     !: south-west closed sea limits (i,j)
44   INTEGER, PUBLIC, DIMENSION(jpncs)   ::   ncsi2, ncsj2     !: north-east closed sea limits (i,j)
45   INTEGER, PUBLIC, DIMENSION(jpncs)   ::   ncsnr            !: number of point where run-off pours
46   INTEGER, PUBLIC, DIMENSION(jpncs,4) ::   ncsir, ncsjr     !: Location of runoff
47
48   REAL(wp), DIMENSION (jpncs+1)       ::   surf             ! closed sea surface
49
50   !! * Substitutions
51#  include "vectopt_loop_substitute.h90"
52   !!----------------------------------------------------------------------
53   !! NEMO/OPA 4.0 , NEMO Consortium (2016)
54   !! $Id$
55   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
56   !!----------------------------------------------------------------------
57CONTAINS
58
59   SUBROUTINE dom_clo( cd_cfg, kcfg )
60      !!---------------------------------------------------------------------
61      !!                  ***  ROUTINE dom_clo  ***
62      !!       
63      !! ** Purpose :   Closed sea domain initialization
64      !!
65      !! ** Method  :   if a closed sea is located only in a model grid point
66      !!                just the thermodynamic processes are applied.
67      !!
68      !! ** Action  :   ncsi1(), ncsj1() : south-west closed sea limits (i,j)
69      !!                ncsi2(), ncsj2() : north-east Closed sea limits (i,j)
70      !!                ncsir(), ncsjr() : Location of runoff
71      !!                ncsnr            : number of point where run-off pours
72      !!                ncstt            : Type of closed sea
73      !!                                   =0 spread over the world ocean
74      !!                                   =2 put at location runoff
75      !!----------------------------------------------------------------------
76      CHARACTER(len=*), INTENT(in   ) ::   cd_cfg   ! configuration name
77      INTEGER         , INTENT(in   ) ::   kcfg     ! configuration identifier
78      !
79      INTEGER ::   jc      ! dummy loop indices
80      INTEGER ::   isrow   ! local index
81      !!----------------------------------------------------------------------
82      !
83      IF(lwp) WRITE(numout,*)
84      IF(lwp) WRITE(numout,*)'dom_clo : closed seas '
85      IF(lwp) WRITE(numout,*)'~~~~~~~'
86      !
87      ! initial values
88      ncsnr(:) = 1  ;  ncsi1(:) = 1  ;  ncsi2(:) = 1  ;  ncsir(:,:) = 1
89      ncstt(:) = 0  ;  ncsj1(:) = 1  ;  ncsj2(:) = 1  ;  ncsjr(:,:) = 1
90      !
91      ! set the closed seas (in data domain indices)
92      ! -------------------
93      !
94      IF( cd_cfg == "orca" ) THEN      !==  ORCA configuration  ==!
95         !
96         SELECT CASE ( kcfg )
97         !                                           ! =======================
98         CASE ( 1 )                                  !  ORCA_R1 configuration
99            !                                        ! =======================
100            IF(lwp) WRITE(numout,*)'   ORCA_R1 closed seas :  only the Caspian Sea'
101            ! This dirty section will be suppressed by simplification process:
102            ! all this will come back in input files
103            ! Currently these hard-wired indices relate to configuration with
104            ! extend grid (jpjglo=332)
105            isrow = 332 - jpjglo
106            !
107            ncsnr(1)   = 1    ; ncstt(1)   = 0           ! Caspian Sea  (spread over the globe)
108            ncsi1(1)   = 332  ; ncsj1(1)   = 243 - isrow
109            ncsi2(1)   = 344  ; ncsj2(1)   = 275 - isrow
110            ncsir(1,1) = 1    ; ncsjr(1,1) = 1
111            !                                       
112            !                                        ! =======================
113         CASE ( 2 )                                  !  ORCA_R2 configuration
114            !                                        ! =======================
115            IF(lwp) WRITE(numout,*)'   ORCA_R2 closed seas and lakes : '
116            !                                            ! Caspian Sea
117            IF(lwp) WRITE(numout,*)'      Caspian Sea  '
118            ncsnr(1)   =   1  ;  ncstt(1)   =   0           ! spread over the globe
119            ncsi1(1)   =  11  ;  ncsj1(1)   = 103
120            ncsi2(1)   =  17  ;  ncsj2(1)   = 112
121            ncsir(1,1) =   1  ;  ncsjr(1,1) =   1 
122            !                                            ! Great North American Lakes
123            IF(lwp) WRITE(numout,*)'      Great North American Lakes  '
124            ncsnr(2)   =   1  ;  ncstt(2)   =   2           ! put at St Laurent mouth
125            ncsi1(2)   =  97  ;  ncsj1(2)   = 107
126            ncsi2(2)   = 103  ;  ncsj2(2)   = 111
127            ncsir(2,1) = 110  ;  ncsjr(2,1) = 111           
128            !                                            ! Black Sea (crossed by the cyclic boundary condition)
129            IF(lwp) WRITE(numout,*)'      Black Sea  '
130            ncsnr(3:4) =   4  ;  ncstt(3:4) =   2           ! put in Med Sea (north of Aegean Sea)
131            ncsir(3:4,1) = 171;  ncsjr(3:4,1) = 106         !
132            ncsir(3:4,2) = 170;  ncsjr(3:4,2) = 106 
133            ncsir(3:4,3) = 171;  ncsjr(3:4,3) = 105 
134            ncsir(3:4,4) = 170;  ncsjr(3:4,4) = 105 
135            ncsi1(3)   = 174  ;  ncsj1(3)   = 107           ! 1 : west part of the Black Sea     
136            ncsi2(3)   = 181  ;  ncsj2(3)   = 112           !            (ie west of the cyclic b.c.)
137            ncsi1(4)   =   2  ;  ncsj1(4)   = 107           ! 2 : east part of the Black Sea
138            ncsi2(4)   =   6  ;  ncsj2(4)   = 112           !           (ie east of the cyclic b.c.)
139            !
140            !                                        ! =========================
141         CASE ( 025 )                                !  ORCA_R025 configuration
142            !                                        ! =========================
143            IF(lwp) WRITE(numout,*)'   ORCA_R025 closed seas : '
144            !                                            ! Caspian Sea
145            IF(lwp) WRITE(numout,*)'      Caspian Sea  '
146            ncsnr(1)   = 1    ; ncstt(1)   = 0               ! Caspian + Aral sea
147            ncsi1(1)   = 1330 ; ncsj1(1)   = 645
148            ncsi2(1)   = 1400 ; ncsj2(1)   = 795
149            ncsir(1,1) = 1    ; ncsjr(1,1) = 1
150            !                                       
151            IF(lwp) WRITE(numout,*)'      Azov Sea  '
152            ncsnr(2)   = 1    ; ncstt(2)   = 0               ! Azov Sea
153            ncsi1(2)   = 1284 ; ncsj1(2)   = 722
154            ncsi2(2)   = 1304 ; ncsj2(2)   = 747
155            ncsir(2,1) = 1    ; ncsjr(2,1) = 1
156            !
157         END SELECT
158         !
159      ELSE                             !==  No closed sea in the configuration  ==!
160         !
161         IF(lwp) WRITE(numout,*)'   No closed seas or lakes in the configuration '
162         !
163      ENDIF
164
165      ! convert the position in local domain indices
166      ! --------------------------------------------
167      DO jc = 1, jpncs
168         ncsi1(jc)   = mi0( ncsi1(jc) )
169         ncsj1(jc)   = mj0( ncsj1(jc) )
170         !
171         ncsi2(jc)   = mi1( ncsi2(jc) )   
172         ncsj2(jc)   = mj1( ncsj2(jc) ) 
173      END DO
174      !
175   END SUBROUTINE dom_clo
176
177
178   SUBROUTINE sbc_clo( kt, cd_cfg, kcfg )
179      !!---------------------------------------------------------------------
180      !!                  ***  ROUTINE sbc_clo  ***
181      !!                   
182      !! ** Purpose :   Special handling of closed seas
183      !!
184      !! ** Method  :   Water flux is forced to zero over closed sea
185      !!      Excess is shared between remaining ocean, or
186      !!      put as run-off in open ocean.
187      !!
188      !! ** Action  :   emp updated surface freshwater fluxes and associated heat content at kt
189      !!----------------------------------------------------------------------
190      INTEGER         , INTENT(in   ) ::   kt       ! ocean model time step
191      CHARACTER(len=*), INTENT(in   ) ::   cd_cfg   ! configuration name
192      INTEGER         , INTENT(in   ) ::   kcfg     ! configuration identifier
193      !
194      INTEGER             ::   ji, jj, jc, jn   ! dummy loop indices
195      REAL(wp), PARAMETER ::   rsmall = 1.e-20_wp    ! Closed sea correction epsilon
196      REAL(wp)            ::   zze2, ztmp, zcorr     !
197      REAL(wp)            ::   zcoef, zcoef1         !
198      COMPLEX(wp)         ::   ctmp 
199      REAL(wp), DIMENSION(jpncs) ::   zfwf   ! 1D workspace
200      !!----------------------------------------------------------------------
201      !
202      !                                                   !------------------!
203      IF( kt == nit000 ) THEN                             !  Initialisation  !
204         !                                                !------------------!
205         IF(lwp) WRITE(numout,*)
206         IF(lwp) WRITE(numout,*)'sbc_clo : closed seas '
207         IF(lwp) WRITE(numout,*)'~~~~~~~'
208
209         surf(:) = 0._wp
210         !
211         surf(jpncs+1) = glob_sum( e1e2t(:,:) )   ! surface of the global ocean
212         !
213         !                                        ! surface of closed seas
214         DO jc = 1, jpncs
215            ctmp = CMPLX( 0.e0, 0.e0, wp )
216            DO jj = ncsj1(jc), ncsj2(jc)
217               DO ji = ncsi1(jc), ncsi2(jc)
218                  ztmp = e1e2t(ji,jj) * tmask_i(ji,jj)
219                  CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
220               END DO
221            END DO
222            IF( lk_mpp )   CALL mpp_sum( ctmp )
223            surf(jc) = REAL(ctmp,wp)
224         END DO
225
226         IF(lwp) WRITE(numout,*)'     Closed sea surfaces'
227         DO jc = 1, jpncs
228            IF(lwp)WRITE(numout,FMT='(1I3,4I4,5X,F16.2)') jc, ncsi1(jc), ncsi2(jc), ncsj1(jc), ncsj2(jc), surf(jc)
229         END DO
230
231         ! jpncs+1 : surface of sea, closed seas excluded
232         DO jc = 1, jpncs
233            surf(jpncs+1) = surf(jpncs+1) - surf(jc)
234         END DO           
235         !
236      ENDIF
237      !                                                   !--------------------!
238      !                                                   !  update emp        !
239      zfwf = 0.e0_wp                                      !--------------------!
240      DO jc = 1, jpncs
241         ctmp = CMPLX( 0.e0, 0.e0, wp )
242         DO jj = ncsj1(jc), ncsj2(jc)
243            DO ji = ncsi1(jc), ncsi2(jc)
244               ztmp = e1e2t(ji,jj) * ( emp(ji,jj)-rnf(ji,jj) ) * tmask_i(ji,jj)
245               CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
246            END DO 
247         END DO
248         IF( lk_mpp )   CALL mpp_sum( ctmp )
249         zfwf(jc) = REAL(ctmp,wp)
250      END DO
251
252      IF( cd_cfg == "orca" .AND. kcfg == 2 ) THEN      ! Black Sea case for ORCA_R2 configuration
253         zze2    = ( zfwf(3) + zfwf(4) ) * 0.5_wp
254         zfwf(3) = zze2
255         zfwf(4) = zze2
256      ENDIF
257
258      zcorr = 0._wp
259
260      DO jc = 1, jpncs
261         !
262         ! The following if avoids the redistribution of the round off
263         IF ( ABS(zfwf(jc) / surf(jpncs+1) ) > rsmall) THEN
264            !
265            IF( ncstt(jc) == 0 ) THEN           ! water/evap excess is shared by all open ocean
266               zcoef    = zfwf(jc) / surf(jpncs+1)
267               zcoef1   = rcp * zcoef
268               emp(:,:) = emp(:,:) + zcoef
269               qns(:,:) = qns(:,:) - zcoef1 * sst_m(:,:)
270               ! accumulate closed seas correction
271               zcorr    = zcorr    + zcoef
272               !
273            ELSEIF( ncstt(jc) == 1 ) THEN       ! Excess water in open sea, at outflow location, excess evap shared
274               IF ( zfwf(jc) <= 0.e0_wp ) THEN
275                   DO jn = 1, ncsnr(jc)
276                     ji = mi0(ncsir(jc,jn))
277                     jj = mj0(ncsjr(jc,jn)) ! Location of outflow in open ocean
278                     IF (      ji > 1 .AND. ji < jpi   &
279                         .AND. jj > 1 .AND. jj < jpj ) THEN
280                         zcoef      = zfwf(jc) / ( REAL(ncsnr(jc)) * e1e2t(ji,jj) )
281                         zcoef1     = rcp * zcoef
282                         emp(ji,jj) = emp(ji,jj) + zcoef
283                         qns(ji,jj) = qns(ji,jj) - zcoef1 * sst_m(ji,jj)
284                     ENDIF
285                   END DO
286               ELSE
287                   zcoef    = zfwf(jc) / surf(jpncs+1)
288                   zcoef1   = rcp * zcoef
289                   emp(:,:) = emp(:,:) + zcoef
290                   qns(:,:) = qns(:,:) - zcoef1 * sst_m(:,:)
291                   ! accumulate closed seas correction
292                   zcorr    = zcorr    + zcoef
293               ENDIF
294            ELSEIF( ncstt(jc) == 2 ) THEN       ! Excess e-p-r (either sign) goes to open ocean, at outflow location
295               DO jn = 1, ncsnr(jc)
296                  ji = mi0(ncsir(jc,jn))
297                  jj = mj0(ncsjr(jc,jn)) ! Location of outflow in open ocean
298                  IF(      ji > 1 .AND. ji < jpi    &
299                     .AND. jj > 1 .AND. jj < jpj ) THEN
300                     zcoef      = zfwf(jc) / ( REAL(ncsnr(jc)) *  e1e2t(ji,jj) )
301                     zcoef1     = rcp * zcoef
302                     emp(ji,jj) = emp(ji,jj) + zcoef
303                     qns(ji,jj) = qns(ji,jj) - zcoef1 * sst_m(ji,jj)
304                  ENDIF
305               END DO
306            ENDIF 
307            !
308            DO jj = ncsj1(jc), ncsj2(jc)
309               DO ji = ncsi1(jc), ncsi2(jc)
310                  zcoef      = zfwf(jc) / surf(jc)
311                  zcoef1     = rcp * zcoef
312                  emp(ji,jj) = emp(ji,jj) - zcoef
313                  qns(ji,jj) = qns(ji,jj) + zcoef1 * sst_m(ji,jj)
314               END DO 
315            END DO 
316            !
317         END IF
318      END DO
319
320      IF ( ABS(zcorr) > rsmall ) THEN      ! remove the global correction from the closed seas
321         DO jc = 1, jpncs                  ! only if it is large enough
322            DO jj = ncsj1(jc), ncsj2(jc)
323               DO ji = ncsi1(jc), ncsi2(jc)
324                  emp(ji,jj) = emp(ji,jj) - zcorr
325                  qns(ji,jj) = qns(ji,jj) + rcp * zcorr * sst_m(ji,jj)
326               END DO 
327             END DO
328          END DO
329      ENDIF
330      !
331      emp (:,:) = emp (:,:) * tmask(:,:,1)
332      !
333      CALL lbc_lnk( emp , 'T', 1._wp )
334      !
335   END SUBROUTINE sbc_clo
336
337
338   SUBROUTINE clo_rnf( p_rnfmsk )
339      !!---------------------------------------------------------------------
340      !!                  ***  ROUTINE sbc_rnf  ***
341      !!                   
342      !! ** Purpose :   allow the treatment of closed sea outflow grid-points
343      !!                to be the same as river mouth grid-points
344      !!
345      !! ** Method  :   set to 1 the runoff mask (mskrnf, see sbcrnf module)
346      !!                at the closed sea outflow grid-point.
347      !!
348      !! ** Action  :   update (p_)mskrnf (set 1 at closed sea outflow)
349      !!----------------------------------------------------------------------
350      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) ::   p_rnfmsk   ! river runoff mask (rnfmsk array)
351      !
352      INTEGER  ::   jc, jn, ji, jj      ! dummy loop indices
353      !!----------------------------------------------------------------------
354      !
355      DO jc = 1, jpncs
356         IF( ncstt(jc) >= 1 ) THEN            ! runoff mask set to 1 at closed sea outflows
357             DO jn = 1, 4
358                DO jj =    mj0( ncsjr(jc,jn) ), mj1( ncsjr(jc,jn) )
359                   DO ji = mi0( ncsir(jc,jn) ), mi1( ncsir(jc,jn) )
360                      p_rnfmsk(ji,jj) = MAX( p_rnfmsk(ji,jj), 1.0_wp )
361                   END DO
362                END DO
363            END DO
364         ENDIF
365      END DO 
366      !
367   END SUBROUTINE clo_rnf
368   
369     
370   SUBROUTINE clo_bat( k_top, k_bot )
371      !!---------------------------------------------------------------------
372      !!                  ***  ROUTINE clo_bat  ***
373      !!                   
374      !! ** Purpose :   suppress closed sea from the domain
375      !!
376      !! ** Method  :   set first and last ocean level to 0 over the closed seas.
377      !!
378      !! ** Action  :   set pbat=0 and kbat=0 over closed seas
379      !!----------------------------------------------------------------------
380      INTEGER, DIMENSION(:,:), INTENT(inout) ::   k_top, k_bot   ! ocean first and last level indices
381      !
382      INTEGER  ::   jc, ji, jj      ! dummy loop indices
383      !!----------------------------------------------------------------------
384      !
385      DO jc = 1, jpncs
386         DO jj = ncsj1(jc), ncsj2(jc)
387            DO ji = ncsi1(jc), ncsi2(jc)
388               k_top(ji,jj) = 0   
389               k_bot(ji,jj) = 0   
390            END DO
391         END DO
392       END DO 
393       !
394   END SUBROUTINE clo_bat
395
396   !!======================================================================
397END MODULE usrdef_closea
398
Note: See TracBrowser for help on using the repository browser.