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.
domain.F90 in branches/2016/dev_merge_2016/NEMOGCM/NEMO/OPA_SRC/DOM – NEMO

source: branches/2016/dev_merge_2016/NEMOGCM/NEMO/OPA_SRC/DOM/domain.F90 @ 7485

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

Remove CPP key key_offline and replace it with a logical l_offline

  • Property svn:keywords set to Id
File size: 35.3 KB
Line 
1MODULE domain
2   !!==============================================================================
3   !!                       ***  MODULE domain   ***
4   !! Ocean initialization : domain initialization
5   !!==============================================================================
6   !! History :  OPA  !  1990-10  (C. Levy - G. Madec)  Original code
7   !!                 !  1992-01  (M. Imbard) insert time step initialization
8   !!                 !  1996-06  (G. Madec) generalized vertical coordinate
9   !!                 !  1997-02  (G. Madec) creation of domwri.F
10   !!                 !  2001-05  (E.Durand - G. Madec) insert closed sea
11   !!   NEMO     1.0  !  2002-08  (G. Madec)  F90: Free form and module
12   !!            2.0  !  2005-11  (V. Garnier) Surface pressure gradient organization
13   !!            3.3  !  2010-11  (G. Madec)  initialisation in C1D configuration
14   !!            3.6  !  2013     ( J. Simeon, C. Calone, G. Madec, C. Ethe ) Online coarsening of outputs
15   !!            3.7  !  2015-11  (G. Madec, A. Coward)  time varying zgr by default
16   !!            4.0  !  2016-10  (G. Madec, S. Flavoni)  domain configuration / user defined interface
17   !!----------------------------------------------------------------------
18   
19   !!----------------------------------------------------------------------
20   !!   dom_init      : initialize the space and time domain
21   !!   dom_glo       : initialize global domain <--> local domain indices
22   !!   dom_nam       : read and contral domain namelists
23   !!   dom_ctl       : control print for the ocean domain
24   !!   domain_cfg    : read the global domain size in domain configuration file
25   !!   cfg_write     : create the domain configuration file
26   !!----------------------------------------------------------------------
27   USE oce            ! ocean variables
28   USE dom_oce        ! domain: ocean
29   USE sbc_oce        ! surface boundary condition: ocean
30   USE trc_oce        ! shared ocean & passive tracers variab
31   USE phycst         ! physical constants
32   USE usrdef_closea  ! closed seas
33   USE domhgr         ! domain: set the horizontal mesh
34   USE domzgr         ! domain: set the vertical mesh
35   USE dommsk         ! domain: set the mask system
36   USE domwri         ! domain: write the meshmask file
37   USE domvvl         ! variable volume
38   USE c1d            ! 1D configuration
39   USE domc1d         ! 1D configuration: column location
40   USE dyncor_c1d     ! 1D configuration: Coriolis term    (cor_c1d routine)
41   !
42   USE trc_oce , ONLY :   l_offline    ! passive tracers offline flag
43   !
44   USE in_out_manager ! I/O manager
45   USE iom            ! I/O library
46   USE lbclnk         ! ocean lateral boundary condition (or mpp link)
47   USE lib_mpp        ! distributed memory computing library
48   USE wrk_nemo       ! Memory Allocation
49   USE timing         ! Timing
50
51   IMPLICIT NONE
52   PRIVATE
53
54   PUBLIC   dom_init     ! called by nemogcm.F90
55   PUBLIC   domain_cfg   ! called by nemogcm.F90
56
57   !!-------------------------------------------------------------------------
58   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
59   !! $Id$
60   !! Software governed by the CeCILL licence        (NEMOGCM/NEMO_CeCILL.txt)
61   !!-------------------------------------------------------------------------
62CONTAINS
63
64   SUBROUTINE dom_init
65      !!----------------------------------------------------------------------
66      !!                  ***  ROUTINE dom_init  ***
67      !!                   
68      !! ** Purpose :   Domain initialization. Call the routines that are
69      !!              required to create the arrays which define the space
70      !!              and time domain of the ocean model.
71      !!
72      !! ** Method  : - dom_msk: compute the masks from the bathymetry file
73      !!              - dom_hgr: compute or read the horizontal grid-point position
74      !!                         and scale factors, and the coriolis factor
75      !!              - dom_zgr: define the vertical coordinate and the bathymetry
76      !!              - dom_wri: create the meshmask file if nn_msh=1
77      !!              - 1D configuration, move Coriolis, u and v at T-point
78      !!----------------------------------------------------------------------
79      INTEGER ::   ji, jj, jk, ik   ! dummy loop indices
80      INTEGER ::   iconf = 0    ! local integers
81      CHARACTER (len=64) ::   cform = "(A12, 3(A13, I7))" 
82      INTEGER , DIMENSION(jpi,jpj) ::   ik_top , ik_bot       ! top and bottom ocean level
83      REAL(wp), DIMENSION(jpi,jpj) ::   z1_hu_0, z1_hv_0
84      !!----------------------------------------------------------------------
85      !
86      IF( nn_timing == 1 )   CALL timing_start('dom_init')
87      !
88      IF(lwp) THEN         ! Ocean domain Parameters (control print)
89         WRITE(numout,*)
90         WRITE(numout,*) 'dom_init : domain initialization'
91         WRITE(numout,*) '~~~~~~~~'
92         !
93         WRITE(numout,*)     '   Domain info'
94         WRITE(numout,*)     '      dimension of model:'
95         WRITE(numout,*)     '             Local domain      Global domain       Data domain '
96         WRITE(numout,cform) '        ','   jpi     : ', jpi, '   jpiglo  : ', jpiglo
97         WRITE(numout,cform) '        ','   jpj     : ', jpj, '   jpjglo  : ', jpjglo
98         WRITE(numout,cform) '        ','   jpk     : ', jpk, '   jpkglo  : ', jpkglo
99         WRITE(numout,cform) '       ' ,'   jpij    : ', jpij
100         WRITE(numout,*)     '      mpp local domain info (mpp):'
101         WRITE(numout,*)     '              jpni    : ', jpni, '   jpreci  : ', jpreci
102         WRITE(numout,*)     '              jpnj    : ', jpnj, '   jprecj  : ', jprecj
103         WRITE(numout,*)     '              jpnij   : ', jpnij
104         WRITE(numout,*)     '      lateral boundary of the Global domain : jperio  = ', jperio
105         SELECT CASE ( jperio )
106         CASE( 0 )   ;   WRITE(numout,*) '         (i.e. closed)'
107         CASE( 1 )   ;   WRITE(numout,*) '         (i.e. cyclic east-west)'
108         CASE( 2 )   ;   WRITE(numout,*) '         (i.e. equatorial symmetric)'
109         CASE( 3 )   ;   WRITE(numout,*) '         (i.e. north fold with T-point pivot)'
110         CASE( 4 )   ;   WRITE(numout,*) '         (i.e. cyclic east-west and north fold with T-point pivot)'
111         CASE( 5 )   ;   WRITE(numout,*) '         (i.e. north fold with F-point pivot)'
112         CASE( 6 )   ;   WRITE(numout,*) '         (i.e. cyclic east-west and north fold with F-point pivot)'
113         CASE DEFAULT
114            CALL ctl_stop( 'jperio is out of range' )
115         END SELECT
116         WRITE(numout,*)     '      Ocean model configuration used:'
117         WRITE(numout,*)     '              cn_cfg = ', cn_cfg
118         WRITE(numout,*)     '              nn_cfg = ', nn_cfg
119      ENDIF
120      !
121      !     
122!!gm  This should be removed with the new configuration interface
123      IF( lk_c1d .AND. ln_c1d_locpt )  CALL dom_c1d( rn_lat1d, rn_lon1d )
124!!gm end
125      !
126      !           !==  Reference coordinate system  ==!
127      !
128      CALL dom_glo                     ! global domain versus local domain
129      CALL dom_nam                     ! read namelist ( namrun, namdom )
130      CALL dom_clo( cn_cfg, nn_cfg )   ! Closed seas and lake
131      CALL dom_hgr                     ! Horizontal mesh
132      CALL dom_zgr( ik_top, ik_bot )   ! Vertical mesh and bathymetry
133      IF( nn_closea == 0 )   CALL clo_bat( ik_top, ik_bot )    !==  remove closed seas or lakes  ==!
134      CALL dom_msk( ik_top, ik_bot )   ! Masks
135      !
136      DO jj = 1, jpj                   ! depth of the iceshelves
137         DO ji = 1, jpi
138            ik = mikt(ji,jj)
139            risfdep(ji,jj) = gdepw_0(ji,jj,ik)
140         END DO
141      END DO
142      !
143      ht_0(:,:) = 0._wp  ! Reference ocean thickness
144      hu_0(:,:) = 0._wp
145      hv_0(:,:) = 0._wp
146      DO jk = 1, jpk
147         ht_0(:,:) = ht_0(:,:) + e3t_0(:,:,jk) * tmask(:,:,jk)
148         hu_0(:,:) = hu_0(:,:) + e3u_0(:,:,jk) * umask(:,:,jk)
149         hv_0(:,:) = hv_0(:,:) + e3v_0(:,:,jk) * vmask(:,:,jk)
150      END DO
151      !
152      !           !==  time varying part of coordinate system  ==!
153      !
154      IF( ln_linssh ) THEN       != Fix in time : set to the reference one for all
155      !
156         !       before        !          now          !       after         !
157            gdept_b = gdept_0  ;   gdept_n = gdept_0   !        ---          ! depth of grid-points
158            gdepw_b = gdepw_0  ;   gdepw_n = gdepw_0   !        ---          !
159                                   gde3w_n = gde3w_0   !        ---          !
160         !                                                                 
161              e3t_b =   e3t_0  ;     e3t_n =   e3t_0   ;   e3t_a =  e3t_0    ! scale factors
162              e3u_b =   e3u_0  ;     e3u_n =   e3u_0   ;   e3u_a =  e3u_0    !
163              e3v_b =   e3v_0  ;     e3v_n =   e3v_0   ;   e3v_a =  e3v_0    !
164                                     e3f_n =   e3f_0   !        ---          !
165              e3w_b =   e3w_0  ;     e3w_n =   e3w_0   !        ---          !
166             e3uw_b =  e3uw_0  ;    e3uw_n =  e3uw_0   !        ---          !
167             e3vw_b =  e3vw_0  ;    e3vw_n =  e3vw_0   !        ---          !
168         !
169         z1_hu_0(:,:) = ssumask(:,:) / ( hu_0(:,:) + 1._wp - ssumask(:,:) )     ! _i mask due to ISF
170         z1_hv_0(:,:) = ssvmask(:,:) / ( hv_0(:,:) + 1._wp - ssvmask(:,:) )
171         !
172         !        before       !          now          !       after         !
173                                      ht_n =    ht_0   !                     ! water column thickness
174               hu_b =    hu_0  ;      hu_n =    hu_0   ;    hu_a =    hu_0   !
175               hv_b =    hv_0  ;      hv_n =    hv_0   ;    hv_a =    hv_0   !
176            r1_hu_b = z1_hu_0  ;   r1_hu_n = z1_hu_0   ; r1_hu_a = z1_hu_0   ! inverse of water column thickness
177            r1_hv_b = z1_hv_0  ;   r1_hv_n = z1_hv_0   ; r1_hv_a = z1_hv_0   !
178         !
179         !
180      ELSE                       != time varying : initialize before/now/after variables
181         !
182         IF( .NOT.l_offline )  CALL dom_vvl_init 
183         !
184      ENDIF
185      !
186      IF( lk_c1d         )   CALL cor_c1d       ! 1D configuration: Coriolis set at T-point
187      !
188      IF( nn_msh > 0 .AND. .NOT. ln_iscpl )                         CALL dom_wri      ! Create a domain file
189      IF( nn_msh > 0 .AND.       ln_iscpl .AND. .NOT. ln_rstart )   CALL dom_wri      ! Create a domain file
190      IF( .NOT.ln_rstart )   CALL dom_ctl       ! Domain control
191      !
192     
193      IF(lwp) THEN
194         WRITE(numout,*)
195         WRITE(numout,*) 'dom_init : end of domain initialization nn_msh=', nn_msh
196         WRITE(numout,*) 
197      ENDIF
198      !
199      IF( ln_write_cfg )   CALL cfg_write         ! create the configuration file
200      !
201      IF( nn_timing == 1 )   CALL timing_stop('dom_init')
202      !
203   END SUBROUTINE dom_init
204
205
206   SUBROUTINE dom_glo
207      !!----------------------------------------------------------------------
208      !!                     ***  ROUTINE dom_glo  ***
209      !!
210      !! ** Purpose :   initialization of global domain <--> local domain indices
211      !!
212      !! ** Method  :   
213      !!
214      !! ** Action  : - mig , mjg : local  domain indices ==> global domain indices
215      !!              - mi0 , mi1 : global domain indices ==> local  domain indices
216      !!              - mj0,, mj1   (global point not in the local domain ==> mi0>mi1 and/or mj0>mj1)
217      !!----------------------------------------------------------------------
218      INTEGER ::   ji, jj   ! dummy loop argument
219      !!----------------------------------------------------------------------
220      !
221      DO ji = 1, jpi                 ! local domain indices ==> global domain indices
222        mig(ji) = ji + nimpp - 1
223      END DO
224      DO jj = 1, jpj
225        mjg(jj) = jj + njmpp - 1
226      END DO
227      !                              ! global domain indices ==> local domain indices
228      !                                   ! (return (m.0,m.1)=(1,0) if data domain gridpoint is to the west/south of the
229      !                                   ! local domain, or (m.0,m.1)=(jp.+1,jp.) to the east/north of local domain.
230      DO ji = 1, jpiglo
231        mi0(ji) = MAX( 1 , MIN( ji - nimpp + 1, jpi+1 ) )
232        mi1(ji) = MAX( 0 , MIN( ji - nimpp + 1, jpi   ) )
233      END DO
234      DO jj = 1, jpjglo
235        mj0(jj) = MAX( 1 , MIN( jj - njmpp + 1, jpj+1 ) )
236        mj1(jj) = MAX( 0 , MIN( jj - njmpp + 1, jpj   ) )
237      END DO
238      IF(lwp) THEN                   ! control print
239         WRITE(numout,*)
240         WRITE(numout,*) 'dom_glo : domain: global <<==>> local '
241         WRITE(numout,*) '~~~~~~~ '
242         WRITE(numout,*) '   global domain:   jpiglo = ', jpiglo, ' jpjglo = ', jpjglo, ' jpkglo = ', jpkglo
243         WRITE(numout,*) '   local  domain:   jpi    = ', jpi   , ' jpj    = ', jpj   , ' jpk    = ', jpk
244         WRITE(numout,*)
245         WRITE(numout,*) '   conversion from local to global domain indices (and vise versa) done'
246         IF( nn_print >= 1 ) THEN
247            WRITE(numout,*)
248            WRITE(numout,*) '          conversion local  ==> global i-index domain'
249            WRITE(numout,25)              (mig(ji),ji = 1,jpi)
250            WRITE(numout,*)
251            WRITE(numout,*) '          conversion global ==> local  i-index domain'
252            WRITE(numout,*) '             starting index'
253            WRITE(numout,25)              (mi0(ji),ji = 1,jpiglo)
254            WRITE(numout,*) '             ending index'
255            WRITE(numout,25)              (mi1(ji),ji = 1,jpiglo)
256            WRITE(numout,*)
257            WRITE(numout,*) '          conversion local  ==> global j-index domain'
258            WRITE(numout,25)              (mjg(jj),jj = 1,jpj)
259            WRITE(numout,*)
260            WRITE(numout,*) '          conversion global ==> local  j-index domain'
261            WRITE(numout,*) '             starting index'
262            WRITE(numout,25)              (mj0(jj),jj = 1,jpjglo)
263            WRITE(numout,*) '             ending index'
264            WRITE(numout,25)              (mj1(jj),jj = 1,jpjglo)
265         ENDIF
266      ENDIF
267 25   FORMAT( 100(10x,19i4,/) )
268      !
269   END SUBROUTINE dom_glo
270
271
272   SUBROUTINE dom_nam
273      !!----------------------------------------------------------------------
274      !!                     ***  ROUTINE dom_nam  ***
275      !!                   
276      !! ** Purpose :   read domaine namelists and print the variables.
277      !!
278      !! ** input   : - namrun namelist
279      !!              - namdom namelist
280      !!              - namnc4 namelist   ! "key_netcdf4" only
281      !!----------------------------------------------------------------------
282      USE ioipsl
283      NAMELIST/namrun/ cn_ocerst_indir, cn_ocerst_outdir, nn_stocklist, ln_rst_list,                 &
284         &             nn_no   , cn_exp   , cn_ocerst_in, cn_ocerst_out, ln_rstart , nn_rstctl ,     &
285         &             nn_it000, nn_itend , nn_date0    , nn_time0     , nn_leapy  , nn_istate ,     &
286         &             nn_stock, nn_write , ln_mskland  , ln_clobber   , nn_chunksz, nn_euler  ,     &
287         &             ln_cfmeta, ln_iscpl
288      NAMELIST/namdom/ ln_linssh, nn_closea, nn_msh, rn_isfhmin, rn_rdt, rn_atfp, ln_crs
289#if defined key_netcdf4
290      NAMELIST/namnc4/ nn_nchunks_i, nn_nchunks_j, nn_nchunks_k, ln_nc4zip
291#endif
292      INTEGER  ::   ios                 ! Local integer output status for namelist read
293      !!----------------------------------------------------------------------
294      !
295      REWIND( numnam_ref )              ! Namelist namrun in reference namelist : Parameters of the run
296      READ  ( numnam_ref, namrun, IOSTAT = ios, ERR = 901)
297901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namrun in reference namelist', lwp )
298      !
299      REWIND( numnam_cfg )              ! Namelist namrun in configuration namelist : Parameters of the run
300      READ  ( numnam_cfg, namrun, IOSTAT = ios, ERR = 902 )
301902   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namrun in configuration namelist', lwp )
302      IF(lwm) WRITE ( numond, namrun )
303      !
304      IF(lwp) THEN                  ! control print
305         WRITE(numout,*)
306         WRITE(numout,*) 'dom_nam  : domain initialization through namelist read'
307         WRITE(numout,*) '~~~~~~~ '
308         WRITE(numout,*) '   Namelist namrun'
309         WRITE(numout,*) '      job number                      nn_no      = ', nn_no
310         WRITE(numout,*) '      experiment name for output      cn_exp     = ', cn_exp
311         WRITE(numout,*) '      file prefix restart input       cn_ocerst_in= ', cn_ocerst_in
312         WRITE(numout,*) '      restart input directory         cn_ocerst_indir= ', cn_ocerst_indir
313         WRITE(numout,*) '      file prefix restart output      cn_ocerst_out= ', cn_ocerst_out
314         WRITE(numout,*) '      restart output directory        cn_ocerst_outdir= ', cn_ocerst_outdir
315         WRITE(numout,*) '      restart logical                 ln_rstart  = ', ln_rstart
316         WRITE(numout,*) '      start with forward time step    nn_euler   = ', nn_euler
317         WRITE(numout,*) '      control of time step            nn_rstctl  = ', nn_rstctl
318         WRITE(numout,*) '      number of the first time step   nn_it000   = ', nn_it000
319         WRITE(numout,*) '      number of the last time step    nn_itend   = ', nn_itend
320         WRITE(numout,*) '      initial calendar date aammjj    nn_date0   = ', nn_date0
321         WRITE(numout,*) '      initial time of day in hhmm     nn_time0   = ', nn_time0
322         WRITE(numout,*) '      leap year calendar (0/1)        nn_leapy   = ', nn_leapy
323         WRITE(numout,*) '      initial state output            nn_istate  = ', nn_istate
324         IF( ln_rst_list ) THEN
325            WRITE(numout,*) '      list of restart dump times      nn_stocklist   =', nn_stocklist
326         ELSE
327            WRITE(numout,*) '      frequency of restart file       nn_stock   = ', nn_stock
328         ENDIF
329         WRITE(numout,*) '      frequency of output file        nn_write   = ', nn_write
330         WRITE(numout,*) '      mask land points                ln_mskland = ', ln_mskland
331         WRITE(numout,*) '      additional CF standard metadata ln_cfmeta  = ', ln_cfmeta
332         WRITE(numout,*) '      overwrite an existing file      ln_clobber = ', ln_clobber
333         WRITE(numout,*) '      NetCDF chunksize (bytes)        nn_chunksz = ', nn_chunksz
334         WRITE(numout,*) '      IS coupling at the restart step ln_iscpl   = ', ln_iscpl
335      ENDIF
336
337      no = nn_no                    ! conversion DOCTOR names into model names (this should disappear soon)
338      cexper = cn_exp
339      nrstdt = nn_rstctl
340      nit000 = nn_it000
341      nitend = nn_itend
342      ndate0 = nn_date0
343      nleapy = nn_leapy
344      ninist = nn_istate
345      nstock = nn_stock
346      nstocklist = nn_stocklist
347      nwrite = nn_write
348      neuler = nn_euler
349      IF ( neuler == 1 .AND. .NOT. ln_rstart ) THEN
350         WRITE(ctmp1,*) 'ln_rstart =.FALSE., nn_euler is forced to 0 '
351         CALL ctl_warn( ctmp1 )
352         neuler = 0
353      ENDIF
354      !                             ! control of output frequency
355      IF ( nstock == 0 .OR. nstock > nitend ) THEN
356         WRITE(ctmp1,*) 'nstock = ', nstock, ' it is forced to ', nitend
357         CALL ctl_warn( ctmp1 )
358         nstock = nitend
359      ENDIF
360      IF ( nwrite == 0 ) THEN
361         WRITE(ctmp1,*) 'nwrite = ', nwrite, ' it is forced to ', nitend
362         CALL ctl_warn( ctmp1 )
363         nwrite = nitend
364      ENDIF
365
366#if defined key_agrif
367      IF( Agrif_Root() ) THEN
368#endif
369      SELECT CASE ( nleapy )        ! Choose calendar for IOIPSL
370      CASE (  1 ) 
371         CALL ioconf_calendar('gregorian')
372         IF(lwp) WRITE(numout,*) '   The IOIPSL calendar is "gregorian", i.e. leap year'
373      CASE (  0 )
374         CALL ioconf_calendar('noleap')
375         IF(lwp) WRITE(numout,*) '   The IOIPSL calendar is "noleap", i.e. no leap year'
376      CASE ( 30 )
377         CALL ioconf_calendar('360d')
378         IF(lwp) WRITE(numout,*) '   The IOIPSL calendar is "360d", i.e. 360 days in a year'
379      END SELECT
380#if defined key_agrif
381      ENDIF
382#endif
383
384      REWIND( numnam_ref )              ! Namelist namdom in reference namelist : space & time domain (bathymetry, mesh, timestep)
385      READ  ( numnam_ref, namdom, IOSTAT = ios, ERR = 903)
386903   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in reference namelist', lwp )
387      !
388      REWIND( numnam_cfg )              ! Namelist namdom in configuration namelist : space & time domain (bathymetry, mesh, timestep)
389      READ  ( numnam_cfg, namdom, IOSTAT = ios, ERR = 904 )
390904   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in configuration namelist', lwp )
391      IF(lwm) WRITE ( numond, namdom )
392      !
393      IF(lwp) THEN
394         WRITE(numout,*)
395         WRITE(numout,*) '   Namelist namdom : space & time domain'
396         WRITE(numout,*) '      linear free surface (=T)              ln_linssh  = ', ln_linssh
397         WRITE(numout,*) '      suppression of closed seas (=0)       nn_closea  = ', nn_closea
398         WRITE(numout,*) '      create mesh/mask file(s)              nn_msh     = ', nn_msh
399         WRITE(numout,*) '           = 0   no file created           '
400         WRITE(numout,*) '           = 1   mesh_mask                 '
401         WRITE(numout,*) '           = 2   mesh and mask             '
402         WRITE(numout,*) '           = 3   mesh_hgr, msh_zgr and mask'
403         WRITE(numout,*) '      treshold to open the isf cavity       rn_isfhmin = ', rn_isfhmin, ' (m)'
404         WRITE(numout,*) '      ocean time step                       rn_rdt     = ', rn_rdt
405         WRITE(numout,*) '      asselin time filter parameter         rn_atfp    = ', rn_atfp
406         WRITE(numout,*) '      online coarsening of dynamical fields ln_crs     = ', ln_crs
407      ENDIF
408     
409      call flush( numout )
410      !
411!     !          ! conversion DOCTOR names into model names (this should disappear soon)
412      atfp      = rn_atfp
413      rdt       = rn_rdt
414
415#if defined key_netcdf4
416      !                             ! NetCDF 4 case   ("key_netcdf4" defined)
417      REWIND( numnam_ref )              ! Namelist namnc4 in reference namelist : NETCDF
418      READ  ( numnam_ref, namnc4, IOSTAT = ios, ERR = 907)
419907   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namnc4 in reference namelist', lwp )
420      !
421      REWIND( numnam_cfg )              ! Namelist namnc4 in configuration namelist : NETCDF
422      READ  ( numnam_cfg, namnc4, IOSTAT = ios, ERR = 908 )
423908   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namnc4 in configuration namelist', lwp )
424      IF(lwm) WRITE( numond, namnc4 )
425
426      IF(lwp) THEN                        ! control print
427         WRITE(numout,*)
428         WRITE(numout,*) '   Namelist namnc4 - Netcdf4 chunking parameters'
429         WRITE(numout,*) '      number of chunks in i-dimension      nn_nchunks_i   = ', nn_nchunks_i
430         WRITE(numout,*) '      number of chunks in j-dimension      nn_nchunks_j   = ', nn_nchunks_j
431         WRITE(numout,*) '      number of chunks in k-dimension      nn_nchunks_k   = ', nn_nchunks_k
432         WRITE(numout,*) '      apply netcdf4/hdf5 chunking & compression ln_nc4zip = ', ln_nc4zip
433      ENDIF
434
435      ! Put the netcdf4 settings into a simple structure (snc4set, defined in in_out_manager module)
436      ! Note the chunk size in the unlimited (time) dimension will be fixed at 1
437      snc4set%ni   = nn_nchunks_i
438      snc4set%nj   = nn_nchunks_j
439      snc4set%nk   = nn_nchunks_k
440      snc4set%luse = ln_nc4zip
441#else
442      snc4set%luse = .FALSE.        ! No NetCDF 4 case
443#endif
444      !
445   END SUBROUTINE dom_nam
446
447
448   SUBROUTINE dom_ctl
449      !!----------------------------------------------------------------------
450      !!                     ***  ROUTINE dom_ctl  ***
451      !!
452      !! ** Purpose :   Domain control.
453      !!
454      !! ** Method  :   compute and print extrema of masked scale factors
455      !!----------------------------------------------------------------------
456      INTEGER ::   iimi1, ijmi1, iimi2, ijmi2, iima1, ijma1, iima2, ijma2
457      INTEGER, DIMENSION(2) ::   iloc   !
458      REAL(wp) ::   ze1min, ze1max, ze2min, ze2max
459      !!----------------------------------------------------------------------
460      !
461      IF(lk_mpp) THEN
462         CALL mpp_minloc( e1t(:,:), tmask_i(:,:), ze1min, iimi1,ijmi1 )
463         CALL mpp_minloc( e2t(:,:), tmask_i(:,:), ze2min, iimi2,ijmi2 )
464         CALL mpp_maxloc( e1t(:,:), tmask_i(:,:), ze1max, iima1,ijma1 )
465         CALL mpp_maxloc( e2t(:,:), tmask_i(:,:), ze2max, iima2,ijma2 )
466      ELSE
467         ze1min = MINVAL( e1t(:,:), mask = tmask_i(:,:) == 1._wp )   
468         ze2min = MINVAL( e2t(:,:), mask = tmask_i(:,:) == 1._wp )   
469         ze1max = MAXVAL( e1t(:,:), mask = tmask_i(:,:) == 1._wp )   
470         ze2max = MAXVAL( e2t(:,:), mask = tmask_i(:,:) == 1._wp )   
471         !
472         iloc  = MINLOC( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
473         iimi1 = iloc(1) + nimpp - 1
474         ijmi1 = iloc(2) + njmpp - 1
475         iloc  = MINLOC( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
476         iimi2 = iloc(1) + nimpp - 1
477         ijmi2 = iloc(2) + njmpp - 1
478         iloc  = MAXLOC( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
479         iima1 = iloc(1) + nimpp - 1
480         ijma1 = iloc(2) + njmpp - 1
481         iloc  = MAXLOC( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
482         iima2 = iloc(1) + nimpp - 1
483         ijma2 = iloc(2) + njmpp - 1
484      ENDIF
485      IF(lwp) THEN
486         WRITE(numout,*)
487         WRITE(numout,*) 'dom_ctl : extrema of the masked scale factors'
488         WRITE(numout,*) '~~~~~~~'
489         WRITE(numout,"(14x,'e1t maxi: ',1f10.2,' at i = ',i5,' j= ',i5)") ze1max, iima1, ijma1
490         WRITE(numout,"(14x,'e1t mini: ',1f10.2,' at i = ',i5,' j= ',i5)") ze1min, iimi1, ijmi1
491         WRITE(numout,"(14x,'e2t maxi: ',1f10.2,' at i = ',i5,' j= ',i5)") ze2max, iima2, ijma2
492         WRITE(numout,"(14x,'e2t mini: ',1f10.2,' at i = ',i5,' j= ',i5)") ze2min, iimi2, ijmi2
493      ENDIF
494      !
495   END SUBROUTINE dom_ctl
496
497
498   SUBROUTINE domain_cfg( ldtxt, cd_cfg, kk_cfg, kpi, kpj, kpk, kperio )
499      !!----------------------------------------------------------------------
500      !!                     ***  ROUTINE dom_nam  ***
501      !!                   
502      !! ** Purpose :   read the domain size in domain configuration file
503      !!
504      !! ** Method  :   
505      !!
506      !!----------------------------------------------------------------------
507      CHARACTER(len=*), DIMENSION(:), INTENT(out) ::   ldtxt           ! stored print information
508      CHARACTER(len=*)              , INTENT(out) ::   cd_cfg          ! configuration name
509      INTEGER                       , INTENT(out) ::   kk_cfg          ! configuration resolution
510      INTEGER                       , INTENT(out) ::   kpi, kpj, kpk   ! global domain sizes
511      INTEGER                       , INTENT(out) ::   kperio          ! lateral global domain b.c.
512      !
513      INTEGER ::   inum, ii   ! local integer
514      REAL(wp) ::   zorca_res                     ! local scalars
515      REAL(wp) ::   ziglo, zjglo, zkglo, zperio   !   -      -
516      !!----------------------------------------------------------------------
517      !
518      ii = 1
519      WRITE(ldtxt(ii),*) '           '                                                    ;   ii = ii+1
520      WRITE(ldtxt(ii),*) 'domain_cfg : domain size read in', TRIM( cn_domcfg ), ' file'   ;   ii = ii+1
521      WRITE(ldtxt(ii),*) '~~~~~~~~~~ '                                                    ;   ii = ii+1
522      !
523      CALL iom_open( cn_domcfg, inum )
524      !
525      !                                   !- ORCA family specificity
526      IF(  iom_varid( inum, 'ORCA'       , ldstop = .FALSE. ) > 0  .AND.  &
527         & iom_varid( inum, 'ORCA_index' , ldstop = .FALSE. ) > 0    ) THEN
528         !
529         cd_cfg = 'ORCA'
530         CALL iom_get( inum, 'ORCA_index', zorca_res )   ;   kk_cfg = INT( zorca_res )
531         !
532         WRITE(ldtxt(ii),*) '       '                                                    ;   ii = ii+1
533         WRITE(ldtxt(ii),*) '       ==>>>   ORCA configuration '                         ;   ii = ii+1
534         WRITE(ldtxt(ii),*) '       '                                                    ;   ii = ii+1
535         !
536      ELSE                                !- cd_cfg & k_cfg are not used
537         cd_cfg = 'UNKNOWN'
538         kk_cfg = -9999999
539      ENDIF
540      !
541      CALL iom_get( inum, 'jpiglo', ziglo  )   ;   kpi = INT( ziglo )
542      CALL iom_get( inum, 'jpjglo', zjglo  )   ;   kpj = INT( zjglo )
543      CALL iom_get( inum, 'jpkglo', zkglo  )   ;   kpk = INT( zkglo )
544      CALL iom_get( inum, 'jperio', zperio )   ;   kperio = INT( zperio )
545      CALL iom_close( inum )
546      !
547      WRITE(ldtxt(ii),*) '   cn_cfg = ', TRIM(cd_cfg), '   nn_cfg = ', kk_cfg             ;   ii = ii+1
548      WRITE(ldtxt(ii),*) '   jpiglo = ', kpi                                              ;   ii = ii+1
549      WRITE(ldtxt(ii),*) '   jpjglo = ', kpj                                              ;   ii = ii+1
550      WRITE(ldtxt(ii),*) '   jpkglo = ', kpk                                              ;   ii = ii+1
551      WRITE(ldtxt(ii),*) '   type of global domain lateral boundary   jperio = ', kperio  ;   ii = ii+1
552      !       
553   END SUBROUTINE domain_cfg
554   
555   
556   SUBROUTINE cfg_write
557      !!----------------------------------------------------------------------
558      !!                  ***  ROUTINE cfg_write  ***
559      !!                   
560      !! ** Purpose :   Create the "cn_domcfg_out" file, a NetCDF file which
561      !!              contains all the ocean domain informations required to
562      !!              define an ocean configuration.
563      !!
564      !! ** Method  :   Write in a file all the arrays required to set up an
565      !!              ocean configuration.
566      !!
567      !! ** output file :   domcfg_out.nc : domain size, characteristics, horizontal
568      !!                       mesh, Coriolis parameter, and vertical scale factors
569      !!                    NB: also contain ORCA family information
570      !!----------------------------------------------------------------------
571      INTEGER           ::   ji, jj, jk   ! dummy loop indices
572      INTEGER           ::   izco, izps, isco, icav
573      INTEGER           ::   inum     ! local units
574      CHARACTER(len=21) ::   clnam    ! filename (mesh and mask informations)
575      REAL(wp), DIMENSION(jpi,jpj) ::   z2d   ! workspace
576      !!----------------------------------------------------------------------
577      !
578      IF(lwp) WRITE(numout,*)
579      IF(lwp) WRITE(numout,*) 'cfg_write : create the domain configuration file (', TRIM(cn_domcfg_out),'.nc)'
580      IF(lwp) WRITE(numout,*) '~~~~~~~~~'
581      !
582      !                       ! ============================= !
583      !                       !  create 'domcfg_out.nc' file  !
584      !                       ! ============================= !
585      !         
586      clnam = 'domcfg_out'  ! filename (configuration information)
587      CALL iom_open( TRIM(clnam), inum, ldwrt = .TRUE., kiolib = jprstlib )
588     
589      !
590      !                             !==  ORCA family specificities  ==!
591      IF( cn_cfg == "ORCA" ) THEN
592         CALL iom_rstput( 0, 0, inum, 'ORCA'      , 1._wp            , ktype = jp_i4 )
593         CALL iom_rstput( 0, 0, inum, 'ORCA_index', REAL( nn_cfg, wp), ktype = jp_i4 )         
594      ENDIF
595      !
596      !                             !==  global domain size  ==!
597      !
598      CALL iom_rstput( 0, 0, inum, 'jpiglo', REAL( jpiglo, wp), ktype = jp_i4 )
599      CALL iom_rstput( 0, 0, inum, 'jpjglo', REAL( jpjglo, wp), ktype = jp_i4 )
600      CALL iom_rstput( 0, 0, inum, 'jpkglo', REAL( jpk   , wp), ktype = jp_i4 )
601      !
602      !                             !==  domain characteristics  ==!
603      !
604      !                                   ! lateral boundary of the global domain
605      CALL iom_rstput( 0, 0, inum, 'jperio', REAL( jperio, wp), ktype = jp_i4 )
606      !
607      !                                   ! type of vertical coordinate
608      IF( ln_zco    ) THEN   ;   izco = 1   ;   ELSE   ;   izco = 0   ;   ENDIF
609      IF( ln_zps    ) THEN   ;   izps = 1   ;   ELSE   ;   izps = 0   ;   ENDIF
610      IF( ln_sco    ) THEN   ;   isco = 1   ;   ELSE   ;   isco = 0   ;   ENDIF
611      CALL iom_rstput( 0, 0, inum, 'ln_zco'   , REAL( izco, wp), ktype = jp_i4 )
612      CALL iom_rstput( 0, 0, inum, 'ln_zps'   , REAL( izps, wp), ktype = jp_i4 )
613      CALL iom_rstput( 0, 0, inum, 'ln_sco'   , REAL( isco, wp), ktype = jp_i4 )
614      !
615      !                                   ! ocean cavities under iceshelves
616      IF( ln_isfcav ) THEN   ;   icav = 1   ;   ELSE   ;   icav = 0   ;   ENDIF
617      CALL iom_rstput( 0, 0, inum, 'ln_isfcav', REAL( icav, wp), ktype = jp_i4 )
618      !
619      !                             !==  horizontal mesh  !
620      !
621      CALL iom_rstput( 0, 0, inum, 'glamt', glamt, ktype = jp_r8 )   ! latitude
622      CALL iom_rstput( 0, 0, inum, 'glamu', glamu, ktype = jp_r8 )
623      CALL iom_rstput( 0, 0, inum, 'glamv', glamv, ktype = jp_r8 )
624      CALL iom_rstput( 0, 0, inum, 'glamf', glamf, ktype = jp_r8 )
625      !                               
626      CALL iom_rstput( 0, 0, inum, 'gphit', gphit, ktype = jp_r8 )   ! longitude
627      CALL iom_rstput( 0, 0, inum, 'gphiu', gphiu, ktype = jp_r8 )
628      CALL iom_rstput( 0, 0, inum, 'gphiv', gphiv, ktype = jp_r8 )
629      CALL iom_rstput( 0, 0, inum, 'gphif', gphif, ktype = jp_r8 )
630      !                               
631      CALL iom_rstput( 0, 0, inum, 'e1t'  , e1t  , ktype = jp_r8 )   ! i-scale factors (e1.)
632      CALL iom_rstput( 0, 0, inum, 'e1u'  , e1u  , ktype = jp_r8 )
633      CALL iom_rstput( 0, 0, inum, 'e1v'  , e1v  , ktype = jp_r8 )
634      CALL iom_rstput( 0, 0, inum, 'e1f'  , e1f  , ktype = jp_r8 )
635      !
636      CALL iom_rstput( 0, 0, inum, 'e2t'  , e2t  , ktype = jp_r8 )   ! j-scale factors (e2.)
637      CALL iom_rstput( 0, 0, inum, 'e2u'  , e2u  , ktype = jp_r8 )
638      CALL iom_rstput( 0, 0, inum, 'e2v'  , e2v  , ktype = jp_r8 )
639      CALL iom_rstput( 0, 0, inum, 'e2f'  , e2f  , ktype = jp_r8 )
640      !
641      CALL iom_rstput( 0, 0, inum, 'ff_f' , ff_f , ktype = jp_r8 )   ! coriolis factor
642      CALL iom_rstput( 0, 0, inum, 'ff_t' , ff_t , ktype = jp_r8 )
643      !
644      !                             !==  vertical mesh  ==!
645      !                                                     
646      CALL iom_rstput( 0, 0, inum, 'e3t_1d'  , e3t_1d , ktype = jp_r8 )   ! reference 1D-coordinate
647      CALL iom_rstput( 0, 0, inum, 'e3w_1d'  , e3w_1d , ktype = jp_r8 )
648      !
649      CALL iom_rstput( 0, 0, inum, 'e3t_0'   , e3t_0  , ktype = jp_r8 )   ! vertical scale factors
650      CALL iom_rstput( 0, 0, inum, 'e3u_0'   , e3u_0  , ktype = jp_r8 )
651      CALL iom_rstput( 0, 0, inum, 'e3v_0'   , e3v_0  , ktype = jp_r8 )
652      CALL iom_rstput( 0, 0, inum, 'e3f_0'   , e3f_0  , ktype = jp_r8 )
653      CALL iom_rstput( 0, 0, inum, 'e3w_0'   , e3w_0  , ktype = jp_r8 )
654      CALL iom_rstput( 0, 0, inum, 'e3uw_0'  , e3uw_0 , ktype = jp_r8 )
655      CALL iom_rstput( 0, 0, inum, 'e3vw_0'  , e3vw_0 , ktype = jp_r8 )
656      !                                         
657      !                             !==  wet top and bottom level  ==!   (caution: multiplied by ssmask)
658      !
659      CALL iom_rstput( 0, 0, inum, 'top_level'    , REAL( mikt, wp )*ssmask , ktype = jp_i4 )   ! nb of ocean T-points (ISF)
660      CALL iom_rstput( 0, 0, inum, 'bottom_level' , REAL( mbkt, wp )*ssmask , ktype = jp_i4 )   ! nb of ocean T-points
661      !
662      IF( ln_sco ) THEN             ! s-coordinate: store grid stiffness ratio  (Not required anyway)
663         CALL dom_stiff( z2d )
664         CALL iom_rstput( 0, 0, inum, 'stiffness', z2d )        !    ! Max. grid stiffness ratio
665      ENDIF
666      !
667      !                                ! ============================
668      !                                !        close the files
669      !                                ! ============================
670      CALL iom_close( inum )
671      !
672   END SUBROUTINE cfg_write
673
674   !!======================================================================
675END MODULE domain
Note: See TracBrowser for help on using the repository browser.