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

source: branches/UKMO/CCRS_NUS_MC_STABLE/NEMOGCM/NEMO/OPA_SRC/DOM/domwri.F90 @ 10064

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

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

File size: 18.5 KB
Line 
1MODULE domwri
2   !!======================================================================
3   !!                       ***  MODULE domwri  ***
4   !! Ocean initialization : write the ocean domain mesh file(s)
5   !!======================================================================
6   !! History :  OPA  ! 1997-02  (G. Madec)  Original code
7   !!            8.1  ! 1999-11  (M. Imbard)  NetCDF FORMAT with IOIPSL
8   !!   NEMO     1.0  ! 2002-08  (G. Madec)  F90 and several file
9   !!            3.0  ! 2008-01  (S. Masson) add dom_uniq
10   !!            4.0  ! 2011-01  (A. R. Porter, STFC Daresbury) dynamical allocation
11   !!----------------------------------------------------------------------
12
13   !!----------------------------------------------------------------------
14   !!   dom_wri        : create and write mesh and mask file(s)
15   !!   dom_uniq       :
16   !!----------------------------------------------------------------------
17   USE dom_oce         ! ocean space and time domain
18   USE in_out_manager  ! I/O manager
19   USE iom             ! I/O library
20   USE lbclnk          ! lateral boundary conditions - mpp exchanges
21   USE lib_mpp         ! MPP library
22   USE wrk_nemo        ! Memory allocation
23   USE timing          ! Timing
24
25   IMPLICIT NONE
26   PRIVATE
27
28   PUBLIC dom_wri        ! routine called by inidom.F90
29
30   !! * Substitutions
31#  include "vectopt_loop_substitute.h90"
32   !!----------------------------------------------------------------------
33   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
34   !! $Id$
35   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
36   !!----------------------------------------------------------------------
37CONTAINS
38
39   SUBROUTINE dom_wri
40      !!----------------------------------------------------------------------
41      !!                  ***  ROUTINE dom_wri  ***
42      !!                   
43      !! ** Purpose :   Create the NetCDF file(s) which contain(s) all the
44      !!      ocean domain informations (mesh and mask arrays). This (these)
45      !!      file(s) is (are) used for visualisation (SAXO software) and
46      !!      diagnostic computation.
47      !!
48      !! ** Method  :   Write in a file all the arrays generated in routines
49      !!      domhgr, domzgr, and dommsk. Note: the file contain depends on
50      !!      the vertical coord. used (z-coord, partial steps, s-coord)
51      !!            MOD(nmsh, 3) = 1  :   'mesh_mask.nc' file
52      !!                         = 2  :   'mesh.nc' and mask.nc' files
53      !!                         = 0  :   'mesh_hgr.nc', 'mesh_zgr.nc' and
54      !!                                  'mask.nc' files
55      !!      For huge size domain, use option 2 or 3 depending on your
56      !!      vertical coordinate.
57      !!
58      !!      if     nmsh <= 3: write full 3D arrays for e3[tuvw] and gdep[tuvw]
59      !!      if 3 < nmsh <= 6: write full 3D arrays for e3[tuvw] and 2D arrays
60      !!                        corresponding to the depth of the bottom t- and w-points
61      !!      if 6 < nmsh <= 9: write 2D arrays corresponding to the depth and the
62      !!                        thickness (e3[tw]_ps) of the bottom points
63      !!
64      !! ** output file :   meshmask.nc  : domain size, horizontal grid-point position,
65      !!                                   masks, depth and vertical scale factors
66      !!----------------------------------------------------------------------
67      !!
68      INTEGER           ::   inum0    ! temprary units for 'mesh_mask.nc' file
69      INTEGER           ::   inum1    ! temprary units for 'mesh.nc'      file
70      INTEGER           ::   inum2    ! temprary units for 'mask.nc'      file
71      INTEGER           ::   inum3    ! temprary units for 'mesh_hgr.nc'  file
72      INTEGER           ::   inum4    ! temprary units for 'mesh_zgr.nc'  file
73      CHARACTER(len=21) ::   clnam0   ! filename (mesh and mask informations)
74      CHARACTER(len=21) ::   clnam1   ! filename (mesh informations)
75      CHARACTER(len=21) ::   clnam2   ! filename (mask informations)
76      CHARACTER(len=21) ::   clnam3   ! filename (horizontal mesh informations)
77      CHARACTER(len=21) ::   clnam4   ! filename (vertical   mesh informations)
78      INTEGER           ::   ji, jj, jk   ! dummy loop indices
79      !                                   !  workspaces
80      REAL(wp), POINTER, DIMENSION(:,:  ) :: zprt, zprw 
81      REAL(wp), POINTER, DIMENSION(:,:,:) :: zdepu, zdepv, zdepf  !CEOD
82      !!----------------------------------------------------------------------
83      !
84      IF( nn_timing == 1 )  CALL timing_start('dom_wri')
85      !
86      CALL wrk_alloc( jpi, jpj, zprt, zprw )
87      CALL wrk_alloc( jpi, jpj, jpk, zdepu, zdepv, zdepf ) !CEOD
88      !
89      IF(lwp) WRITE(numout,*)
90      IF(lwp) WRITE(numout,*) 'dom_wri : create NetCDF mesh and mask information file(s)'
91      IF(lwp) WRITE(numout,*) '~~~~~~~'
92     
93      clnam0 = 'mesh_mask'  ! filename (mesh and mask informations)
94      clnam1 = 'mesh'       ! filename (mesh informations)
95      clnam2 = 'mask'       ! filename (mask informations)
96      clnam3 = 'mesh_hgr'   ! filename (horizontal mesh informations)
97      clnam4 = 'mesh_zgr'   ! filename (vertical   mesh informations)
98     
99      SELECT CASE ( MOD(nmsh, 3) )
100         !                                  ! ============================
101      CASE ( 1 )                            !  create 'mesh_mask.nc' file
102         !                                  ! ============================
103         CALL iom_open( TRIM(clnam0), inum0, ldwrt = .TRUE., kiolib = jprstlib )
104         inum2 = inum0                                            ! put all the informations
105         inum3 = inum0                                            ! in unit inum0
106         inum4 = inum0
107         
108         !                                  ! ============================
109      CASE ( 2 )                            !  create 'mesh.nc' and
110         !                                  !         'mask.nc' files
111         !                                  ! ============================
112         CALL iom_open( TRIM(clnam1), inum1, ldwrt = .TRUE., kiolib = jprstlib )
113         CALL iom_open( TRIM(clnam2), inum2, ldwrt = .TRUE., kiolib = jprstlib )
114         inum3 = inum1                                            ! put mesh informations
115         inum4 = inum1                                            ! in unit inum1
116         !                                  ! ============================
117      CASE ( 0 )                            !  create 'mesh_hgr.nc'
118         !                                  !         'mesh_zgr.nc' and
119         !                                  !         'mask.nc'     files
120         !                                  ! ============================
121         CALL iom_open( TRIM(clnam2), inum2, ldwrt = .TRUE., kiolib = jprstlib )
122         CALL iom_open( TRIM(clnam3), inum3, ldwrt = .TRUE., kiolib = jprstlib )
123         CALL iom_open( TRIM(clnam4), inum4, ldwrt = .TRUE., kiolib = jprstlib )
124         !
125      END SELECT
126     
127      !                                                         ! masks (inum2)
128      CALL iom_rstput( 0, 0, inum2, 'tmask', tmask, ktype = jp_i1 )     !    ! land-sea mask
129      CALL iom_rstput( 0, 0, inum2, 'umask', umask, ktype = jp_i1 )
130      CALL iom_rstput( 0, 0, inum2, 'vmask', vmask, ktype = jp_i1 )
131      CALL iom_rstput( 0, 0, inum2, 'fmask', fmask, ktype = jp_i1 )
132     
133      CALL dom_uniq( zprw, 'T' )
134      DO jj = 1, jpj
135         DO ji = 1, jpi
136            jk=mikt(ji,jj) 
137            zprt(ji,jj) = tmask(ji,jj,jk) * zprw(ji,jj)                        !    ! unique point mask
138         END DO
139      END DO                             !    ! unique point mask
140      CALL iom_rstput( 0, 0, inum2, 'tmaskutil', zprt, ktype = jp_i1 ) 
141      CALL dom_uniq( zprw, 'U' )
142      DO jj = 1, jpj
143         DO ji = 1, jpi
144            jk=miku(ji,jj) 
145            zprt(ji,jj) = umask(ji,jj,jk) * zprw(ji,jj)                        !    ! unique point mask
146         END DO
147      END DO
148      CALL iom_rstput( 0, 0, inum2, 'umaskutil', zprt, ktype = jp_i1 ) 
149      CALL dom_uniq( zprw, 'V' )
150      DO jj = 1, jpj
151         DO ji = 1, jpi
152            jk=mikv(ji,jj) 
153            zprt(ji,jj) = vmask(ji,jj,jk) * zprw(ji,jj)                        !    ! unique point mask
154         END DO
155      END DO
156      CALL iom_rstput( 0, 0, inum2, 'vmaskutil', zprt, ktype = jp_i1 ) 
157      CALL dom_uniq( zprw, 'F' )
158      DO jj = 1, jpj
159         DO ji = 1, jpi
160            jk=mikf(ji,jj) 
161            zprt(ji,jj) = fmask(ji,jj,jk) * zprw(ji,jj)                        !    ! unique point mask
162         END DO
163      END DO
164      CALL iom_rstput( 0, 0, inum2, 'fmaskutil', zprt, ktype = jp_i1 ) 
165
166      !                                                         ! horizontal mesh (inum3)
167      CALL iom_rstput( 0, 0, inum3, 'glamt', glamt, ktype = jp_r4 )     !    ! latitude
168      CALL iom_rstput( 0, 0, inum3, 'glamu', glamu, ktype = jp_r4 )
169      CALL iom_rstput( 0, 0, inum3, 'glamv', glamv, ktype = jp_r4 )
170      CALL iom_rstput( 0, 0, inum3, 'glamf', glamf, ktype = jp_r4 )
171     
172      CALL iom_rstput( 0, 0, inum3, 'gphit', gphit, ktype = jp_r4 )     !    ! longitude
173      CALL iom_rstput( 0, 0, inum3, 'gphiu', gphiu, ktype = jp_r4 )
174      CALL iom_rstput( 0, 0, inum3, 'gphiv', gphiv, ktype = jp_r4 )
175      CALL iom_rstput( 0, 0, inum3, 'gphif', gphif, ktype = jp_r4 )
176     
177      CALL iom_rstput( 0, 0, inum3, 'e1t', e1t, ktype = jp_r8 )         !    ! e1 scale factors
178      CALL iom_rstput( 0, 0, inum3, 'e1u', e1u, ktype = jp_r8 )
179      CALL iom_rstput( 0, 0, inum3, 'e1v', e1v, ktype = jp_r8 )
180      CALL iom_rstput( 0, 0, inum3, 'e1f', e1f, ktype = jp_r8 )
181     
182      CALL iom_rstput( 0, 0, inum3, 'e2t', e2t, ktype = jp_r8 )         !    ! e2 scale factors
183      CALL iom_rstput( 0, 0, inum3, 'e2u', e2u, ktype = jp_r8 )
184      CALL iom_rstput( 0, 0, inum3, 'e2v', e2v, ktype = jp_r8 )
185      CALL iom_rstput( 0, 0, inum3, 'e2f', e2f, ktype = jp_r8 )
186     
187      CALL iom_rstput( 0, 0, inum3, 'ff', ff, ktype = jp_r8 )           !    ! coriolis factor
188     
189      ! note that mbkt is set to 1 over land ==> use surface tmask
190      zprt(:,:) = ssmask(:,:) * REAL( mbkt(:,:) , wp )
191      CALL iom_rstput( 0, 0, inum4, 'mbathy', zprt, ktype = jp_i2 )     !    ! nb of ocean T-points
192      zprt(:,:) = ssmask(:,:) * REAL( mikt(:,:) , wp )
193      CALL iom_rstput( 0, 0, inum4, 'misf', zprt, ktype = jp_i2 )       !    ! nb of ocean T-points
194      zprt(:,:) = ssmask(:,:) * REAL( risfdep(:,:) , wp )
195      CALL iom_rstput( 0, 0, inum4, 'isfdraft', zprt, ktype = jp_r4 )       !    ! nb of ocean T-points
196           
197      IF( ln_sco ) THEN                                         ! s-coordinate
198         CALL iom_rstput( 0, 0, inum4, 'hbatt', hbatt )
199         CALL iom_rstput( 0, 0, inum4, 'hbatu', hbatu )
200         CALL iom_rstput( 0, 0, inum4, 'hbatv', hbatv )
201         CALL iom_rstput( 0, 0, inum4, 'hbatf', hbatf )
202         !
203         CALL iom_rstput( 0, 0, inum4, 'gsigt', gsigt )         !    ! scaling coef.
204         CALL iom_rstput( 0, 0, inum4, 'gsigw', gsigw ) 
205         CALL iom_rstput( 0, 0, inum4, 'gsi3w', gsi3w )
206         CALL iom_rstput( 0, 0, inum4, 'esigt', esigt )
207         CALL iom_rstput( 0, 0, inum4, 'esigw', esigw )
208         !
209         CALL iom_rstput( 0, 0, inum4, 'e3t_0', e3t_0 )         !    ! scale factors
210         CALL iom_rstput( 0, 0, inum4, 'e3u_0', e3u_0 )
211         CALL iom_rstput( 0, 0, inum4, 'e3v_0', e3v_0 )
212         CALL iom_rstput( 0, 0, inum4, 'e3w_0', e3w_0 )
213         CALL iom_rstput( 0, 0, inum4, 'rx1', rx1 )             !    ! Max. grid stiffness ratio
214         !
215         CALL iom_rstput( 0, 0, inum4, 'gdept_1d' , gdept_1d )  !    ! stretched system
216         CALL iom_rstput( 0, 0, inum4, 'gdepw_1d' , gdepw_1d )
217         CALL iom_rstput( 0, 0, inum4, 'gdept_0', gdept_0, ktype = jp_r4 )     
218         CALL iom_rstput( 0, 0, inum4, 'gdepw_0', gdepw_0, ktype = jp_r4 )     
219      ENDIF
220            !CEOD Added for gdep uvf
221      IF( ln_sco ) THEN                                         ! s-coordinate
222
223         DO jk = 1,jpk
224            DO jj = 1, jpjm1
225               DO ji = 1, fs_jpim1   ! vector opt.
226                  zdepu(ji,jj,jk) = 0.5*(gdept_0(ji,jj,jk) + gdept_0(ji+1,jj,jk) )
227                  zdepv(ji,jj,jk) = 0.5*(gdept_0(ji,jj,jk) + gdept_0(ji,jj+1,jk) )
228
229                  zdepf(ji,jj,jk) = 0.25*(gdept_0(ji,jj,jk) + gdept_0(ji+1,jj+1,jk) +gdept_0(ji+1,jj  ,jk)  + gdept_0(ji  ,jj+1,jk) )
230               END DO
231            END DO
232         END DO
233
234         CALL lbc_lnk( zdepu, 'U', 1. )   ;   CALL lbc_lnk( zdepv, 'V', 1. )
235         CALL iom_rstput( 0, 0, inum4, 'gdepu', zdepu, ktype = jp_r4 )
236         CALL iom_rstput( 0, 0, inum4, 'gdepv', zdepv, ktype = jp_r4 )
237         CALL iom_rstput( 0, 0, inum4, 'gdepf', zdepf, ktype = jp_r4 )
238         CALL iom_rstput( 0, 0, inum4, 'gdepw_0', gdepw_0, ktype = jp_r4 )
239
240      END IF
241
242      IF( ln_zps ) THEN                                         ! z-coordinate - partial steps
243         !
244         IF( nmsh <= 6 ) THEN                                   !    ! 3D vertical scale factors
245            CALL iom_rstput( 0, 0, inum4, 'e3t_0', e3t_0 )         
246            CALL iom_rstput( 0, 0, inum4, 'e3u_0', e3u_0 )
247            CALL iom_rstput( 0, 0, inum4, 'e3v_0', e3v_0 )
248            CALL iom_rstput( 0, 0, inum4, 'e3w_0', e3w_0 )
249         ELSE                                                   !    ! 2D masked bottom ocean scale factors
250            DO jj = 1,jpj   
251               DO ji = 1,jpi
252                  e3tp(ji,jj) = e3t_0(ji,jj,mbkt(ji,jj)) * ssmask(ji,jj)
253                  e3wp(ji,jj) = e3w_0(ji,jj,mbkt(ji,jj)) * ssmask(ji,jj)
254               END DO
255            END DO
256            CALL iom_rstput( 0, 0, inum4, 'e3t_ps', e3tp )     
257            CALL iom_rstput( 0, 0, inum4, 'e3w_ps', e3wp )
258         END IF
259         !
260         IF( nmsh <= 3 ) THEN                                   !    ! 3D depth
261            CALL iom_rstput( 0, 0, inum4, 'gdept_0', gdept_0, ktype = jp_r4 )     
262            DO jk = 1,jpk   
263               DO jj = 1, jpjm1   
264                  DO ji = 1, fs_jpim1   ! vector opt.
265                     zdepu(ji,jj,jk) = MIN( gdept_0(ji,jj,jk) , gdept_0(ji+1,jj  ,jk) )
266                     zdepv(ji,jj,jk) = MIN( gdept_0(ji,jj,jk) , gdept_0(ji  ,jj+1,jk) )
267                  END DO   
268               END DO   
269            END DO
270            CALL lbc_lnk( zdepu, 'U', 1. )   ;   CALL lbc_lnk( zdepv, 'V', 1. ) 
271            CALL iom_rstput( 0, 0, inum4, 'gdepu', zdepu, ktype = jp_r4 )
272            CALL iom_rstput( 0, 0, inum4, 'gdepv', zdepv, ktype = jp_r4 )
273            CALL iom_rstput( 0, 0, inum4, 'gdepw_0', gdepw_0, ktype = jp_r4 )
274         ELSE                                                   !    ! 2D bottom depth
275            DO jj = 1,jpj   
276               DO ji = 1,jpi
277                  zprt(ji,jj) = gdept_0(ji,jj,mbkt(ji,jj)  ) * ssmask(ji,jj)
278                  zprw(ji,jj) = gdepw_0(ji,jj,mbkt(ji,jj)+1) * ssmask(ji,jj)
279               END DO
280            END DO
281            CALL iom_rstput( 0, 0, inum4, 'hdept', zprt, ktype = jp_r4 )     
282            CALL iom_rstput( 0, 0, inum4, 'hdepw', zprw, ktype = jp_r4 ) 
283         ENDIF
284         !
285         CALL iom_rstput( 0, 0, inum4, 'gdept_1d', gdept_1d )   !    ! reference z-coord.
286         CALL iom_rstput( 0, 0, inum4, 'gdepw_1d', gdepw_1d )
287         CALL iom_rstput( 0, 0, inum4, 'e3t_1d'  , e3t_1d   )
288         CALL iom_rstput( 0, 0, inum4, 'e3w_1d'  , e3w_1d   )
289      ENDIF
290     
291      IF( ln_zco ) THEN
292         !                                                      ! z-coordinate - full steps
293         CALL iom_rstput( 0, 0, inum4, 'gdept_1d', gdept_1d )   !    ! depth
294         CALL iom_rstput( 0, 0, inum4, 'gdepw_1d', gdepw_1d )
295         CALL iom_rstput( 0, 0, inum4, 'e3t_1d'  , e3t_1d   )   !    ! scale factors
296         CALL iom_rstput( 0, 0, inum4, 'e3w_1d'  , e3w_1d   )
297      ENDIF
298      !                                     ! ============================
299      !                                     !        close the files
300      !                                     ! ============================
301      SELECT CASE ( MOD(nmsh, 3) )
302      CASE ( 1 )               
303         CALL iom_close( inum0 )
304      CASE ( 2 )
305         CALL iom_close( inum1 )
306         CALL iom_close( inum2 )
307      CASE ( 0 )
308         CALL iom_close( inum2 )
309         CALL iom_close( inum3 )
310         CALL iom_close( inum4 )
311      END SELECT
312      !
313      CALL wrk_dealloc( jpi, jpj, zprt, zprw )
314      CALL wrk_dealloc( jpi, jpj, jpk, zdepu, zdepv )
315      !
316      IF( nn_timing == 1 )  CALL timing_stop('dom_wri')
317      !
318   END SUBROUTINE dom_wri
319
320
321   SUBROUTINE dom_uniq( puniq, cdgrd )
322      !!----------------------------------------------------------------------
323      !!                  ***  ROUTINE dom_uniq  ***
324      !!                   
325      !! ** Purpose :   identify unique point of a grid (TUVF)
326      !!
327      !! ** Method  :   1) aplly lbc_lnk on an array with different values for each element
328      !!                2) check which elements have been changed
329      !!----------------------------------------------------------------------
330      !
331      CHARACTER(len=1)        , INTENT(in   ) ::   cdgrd   !
332      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   puniq   !
333      !
334      REAL(wp) ::  zshift   ! shift value link to the process number
335      INTEGER  ::  ji       ! dummy loop indices
336      LOGICAL, DIMENSION(SIZE(puniq,1),SIZE(puniq,2),1) ::  lldbl  ! store whether each point is unique or not
337      REAL(wp), POINTER, DIMENSION(:,:) :: ztstref
338      !!----------------------------------------------------------------------
339      !
340      IF( nn_timing == 1 )  CALL timing_start('dom_uniq')
341      !
342      CALL wrk_alloc( jpi, jpj, ztstref )
343      !
344      ! build an array with different values for each element
345      ! in mpp: make sure that these values are different even between process
346      ! -> apply a shift value according to the process number
347      zshift = jpi * jpj * ( narea - 1 )
348      ztstref(:,:) = RESHAPE( (/ (zshift + REAL(ji,wp), ji = 1, jpi*jpj) /), (/ jpi, jpj /) )
349      !
350      puniq(:,:) = ztstref(:,:)                   ! default definition
351      CALL lbc_lnk( puniq, cdgrd, 1. )            ! apply boundary conditions
352      lldbl(:,:,1) = puniq(:,:) == ztstref(:,:)   ! check which values have been changed
353      !
354      puniq(:,:) = 1.                             ! default definition
355      ! fill only the inner part of the cpu with llbl converted into real
356      puniq(nldi:nlei,nldj:nlej) = REAL( COUNT( lldbl(nldi:nlei,nldj:nlej,:), dim = 3 ) , wp )
357      !
358      CALL wrk_dealloc( jpi, jpj, ztstref )
359      !
360      IF( nn_timing == 1 )  CALL timing_stop('dom_uniq')
361      !
362   END SUBROUTINE dom_uniq
363
364   !!======================================================================
365END MODULE domwri
Note: See TracBrowser for help on using the repository browser.