source: NEMO/branches/UKMO/NEMO_4.0_GO8_package_text_diagnostics/src/OCE/ICB/icbrst.F90 @ 10948

Last change on this file since 10948 was 10948, checked in by andmirek, 19 months ago

GMED 462 iceberg model

File size: 22.6 KB
Line 
1MODULE icbrst
2   !!======================================================================
3   !!                       ***  MODULE  icbrst  ***
4   !! Ocean physics:  read and write iceberg restart files
5   !!======================================================================
6   !! History : 3.3.1 !  2010-01  (Martin&Adcroft) Original code
7   !!            -    !  2011-03  (Madec)          Part conversion to NEMO form
8   !!            -    !                            Removal of mapping from another grid
9   !!            -    !  2011-04  (Alderson)       Split into separate modules
10   !!            -    !  2011-04  (Alderson)       Restore restart routine
11   !!            -    !                            Currently needs a fixed processor
12   !!            -    !                            layout between restarts
13   !!            -    !  2015-11  Dave Storkey     Convert icb_rst_read to use IOM so can
14   !!                                              read single restart files
15   !!----------------------------------------------------------------------
16
17   !!----------------------------------------------------------------------
18   !!   icb_rst_read    : read restart file
19   !!   icb_rst_write   : write restart file
20   !!----------------------------------------------------------------------
21   USE par_oce        ! NEMO parameters
22   USE dom_oce        ! NEMO domain
23   USE in_out_manager ! NEMO IO routines
24   USE lib_mpp        ! NEMO MPI library, lk_mpp in particular
25   USE netcdf         ! netcdf routines for IO
26   USE iom
27   USE ioipsl, ONLY : ju2ymds    ! for calendar
28   USE icb_oce        ! define iceberg arrays
29   USE icbutl         ! iceberg utility routines
30
31   IMPLICIT NONE
32   PRIVATE
33
34   PUBLIC   icb_rst_read    ! routine called in icbini.F90 module
35   PUBLIC   icb_rst_write   ! routine called in icbstp.F90 module
36   
37   INTEGER ::   nlonid, nlatid, nxid, nyid, nuvelid, nvvelid
38   INTEGER ::   nmassid, nthicknessid, nwidthid, nlengthid
39   INTEGER ::   nyearid, ndayid
40   INTEGER ::   nscaling_id, nmass_of_bits_id, nheat_density_id, numberid
41   INTEGER ::   nsiceid, nsheatid, ncalvid, ncalvhid, nkountid
42   INTEGER ::   nret, ncid, nc_dim
43   
44   INTEGER,  DIMENSION(3)                  :: nstrt3, nlngth3
45
46   !!----------------------------------------------------------------------
47   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
48   !! $Id$
49   !! Software governed by the CeCILL license (see ./LICENSE)
50   !!----------------------------------------------------------------------
51CONTAINS
52
53   SUBROUTINE icb_rst_read()
54      !!----------------------------------------------------------------------
55      !!                 ***  SUBROUTINE icb_rst_read  ***
56      !!
57      !! ** Purpose :   read a iceberg restart file
58      !!      NB: for this version, we just read back in the restart for this processor
59      !!      so we cannot change the processor layout currently with iceberg code
60      !!----------------------------------------------------------------------
61      INTEGER                      ::   idim, ivar, iatt
62      INTEGER                      ::   jn, iunlim_dim, ibergs_in_file
63      INTEGER                      ::   ii, ij, iclass, ibase_err, imax_icb
64      REAL(wp), DIMENSION(nkounts) ::   zdata     
65      LOGICAL                      ::   ll_found_restart
66      CHARACTER(len=256)           ::   cl_path
67      CHARACTER(len=256)           ::   cl_filename
68      CHARACTER(len=NF90_MAX_NAME) ::   cl_dname
69      TYPE(iceberg)                ::   localberg ! NOT a pointer but an actual local variable
70      TYPE(point)                  ::   localpt   ! NOT a pointer but an actual local variable
71      !!----------------------------------------------------------------------
72
73      ! Find a restart file. Assume iceberg restarts in same directory as ocean restarts
74      ! and are called TRIM(cn_ocerst)//'_icebergs'
75      cl_path = TRIM(cn_ocerst_indir)
76      IF( cl_path(LEN_TRIM(cl_path):) /= '/' ) cl_path = TRIM(cl_path) // '/'
77      cl_filename = TRIM(cn_ocerst_in)//'_icebergs'
78      CALL iom_open( TRIM(cl_path)//cl_filename, ncid )
79
80      imax_icb = 0
81      IF( iom_file(ncid)%iduld .GE. 0) THEN
82
83         ibergs_in_file = iom_file(ncid)%lenuld
84         DO jn = 1,ibergs_in_file
85
86            ! iom_get treats the unlimited dimension as time. Here the unlimited dimension
87            ! is the iceberg index, but we can still use the ktime keyword to get the iceberg we want.
88
89            CALL iom_get( ncid, 'xi'     ,localpt%xi  , ktime=jn )
90            CALL iom_get( ncid, 'yj'     ,localpt%yj  , ktime=jn )
91
92            ii = INT( localpt%xi + 0.5 )
93            ij = INT( localpt%yj + 0.5 )
94            ! Only proceed if this iceberg is on the local processor (excluding halos).
95            IF ( ii .GE. nldi+nimpp-1 .AND. ii .LE. nlei+nimpp-1 .AND. &
96           &     ij .GE. nldj+njmpp-1 .AND. ij .LE. nlej+njmpp-1 ) THEN           
97
98               CALL iom_get( ncid, jpdom_unknown, 'number'       , zdata(:) , ktime=jn, kstart=(/1/), kcount=(/nkounts/) )
99               localberg%number(:) = INT(zdata(:))
100               imax_icb = MAX( imax_icb, INT(zdata(1)) )
101               CALL iom_get( ncid, 'mass_scaling' , localberg%mass_scaling, ktime=jn )
102               CALL iom_get( ncid, 'lon'          , localpt%lon           , ktime=jn )
103               CALL iom_get( ncid, 'lat'          , localpt%lat           , ktime=jn )
104               CALL iom_get( ncid, 'uvel'         , localpt%uvel          , ktime=jn )
105               CALL iom_get( ncid, 'vvel'         , localpt%vvel          , ktime=jn )
106               CALL iom_get( ncid, 'mass'         , localpt%mass          , ktime=jn )
107               CALL iom_get( ncid, 'thickness'    , localpt%thickness     , ktime=jn )
108               CALL iom_get( ncid, 'width'        , localpt%width         , ktime=jn )
109               CALL iom_get( ncid, 'length'       , localpt%length        , ktime=jn )
110               CALL iom_get( ncid, 'year'         , zdata(1)              , ktime=jn )
111               localpt%year = INT(zdata(1))
112               CALL iom_get( ncid, 'day'          , localpt%day           , ktime=jn )
113               CALL iom_get( ncid, 'mass_of_bits' , localpt%mass_of_bits  , ktime=jn )
114               CALL iom_get( ncid, 'heat_density' , localpt%heat_density  , ktime=jn )
115               !
116               CALL icb_utl_add( localberg, localpt )
117               !
118            ENDIF
119            !
120         END DO
121         !
122      ELSE
123         ibergs_in_file = 0
124      ENDIF 
125
126      ! Gridded variables
127      CALL iom_get( ncid, jpdom_autoglo,    'calving'     , src_calving  )
128      CALL iom_get( ncid, jpdom_autoglo,    'calving_hflx', src_calving_hflx  )
129      CALL iom_get( ncid, jpdom_autoglo,    'stored_heat' , berg_grid%stored_heat  )
130      CALL iom_get( ncid, jpdom_autoglo_xy, 'stored_ice'  , berg_grid%stored_ice, kstart=(/1,1,1/), kcount=(/1,1,nclasses/) )
131     
132      CALL iom_get( ncid, jpdom_unknown, 'kount' , zdata(:) )
133      num_bergs(:) = INT(zdata(:))
134      ! Close file
135      CALL iom_close( ncid )
136      !
137
138      ! Sanity checks
139      jn = icb_utl_count()
140      IF ( lwp .AND. nprint > 0 )   &
141         WRITE(numout,'(2(a,i5))') 'icebergs, read_restart_bergs: # bergs =',jn,' on PE',narea-1
142      IF( lk_mpp ) THEN
143         ! Only mpp_sum ibergs_in_file if we are reading from multiple restart files.
144         IF( INDEX(iom_file(ncid)%name,'icebergs.nc' ) .EQ. 0 ) CALL mpp_sum('icbrst', ibergs_in_file)
145         CALL mpp_sum('icbrst', jn)
146      ENDIF
147      IF( lwp .AND. nprint > 0 )   &
148          WRITE(numout,'(a,i5,a,i5,a)') 'icebergs, icb_rst_read: there were',ibergs_in_file,   &
149         &                              ' bergs in the restart file and', jn,' bergs have been read'
150      !
151      ! Confirm that all areas have a suitable base for assigning new iceberg
152      ! numbers. This will not be the case if restarting from a collated dataset
153      ! (even if using the same processor decomposition)
154      !
155      ibase_err = 0
156      IF( num_bergs(1) < 0 .AND. num_bergs(1) /= narea - jpnij ) THEN
157         ! If this area has never calved a new berg then the base should be
158         ! set to narea - jpnij. If it is negative but something else then
159         ! a new base will be needed to guarantee unique, future iceberg numbers
160         ibase_err = 1
161      ELSEIF( MOD( num_bergs(1) - narea , jpnij ) /= 0 ) THEN
162         ! If this area has a base which is not in the set {narea + N*jpnij}
163         ! for positive integers N then a new base will be needed to guarantee
164         ! unique, future iceberg numbers
165         ibase_err = 1
166      ENDIF
167      IF( lk_mpp ) THEN
168         CALL mpp_sum('icbrst', ibase_err)
169      ENDIF
170      IF( ibase_err > 0 ) THEN
171         !
172         ! A new base is needed. The only secure solution is to set bases such that
173         ! all future icebergs numbers will be greater than the current global maximum
174         IF( lk_mpp ) THEN
175            CALL mpp_max('icbrst', imax_icb)
176         ENDIF
177         num_bergs(1) = imax_icb - jpnij + narea
178      ENDIF
179      !
180      IF( lwp .AND. nprint >= 0 )  WRITE(numout,'(a)') 'icebergs, icb_rst_read: completed'
181      !
182   END SUBROUTINE icb_rst_read
183
184
185   SUBROUTINE icb_rst_write( kt )
186      !!----------------------------------------------------------------------
187      !!                 ***  SUBROUTINE icb_rst_write  ***
188      !!
189      !!----------------------------------------------------------------------
190      INTEGER, INTENT( in ) :: kt
191      !
192      INTEGER ::   jn   ! dummy loop index
193      INTEGER ::   ix_dim, iy_dim, ik_dim, in_dim
194      INTEGER             ::   iyear, imonth, iday
195      REAL (wp)           ::   zsec
196      REAL (wp)           ::   zfjulday
197      CHARACTER(len=256)  :: cl_path
198      CHARACTER(len=256)  :: cl_filename
199      CHARACTER(LEN=20)   ::   clkt     ! ocean time-step deine as a character
200      TYPE(iceberg), POINTER :: this
201      TYPE(point)  , POINTER :: pt
202      !!----------------------------------------------------------------------
203
204      ! Following the normal restart procedure, this routine will be called
205      ! the timestep before a restart stage as well as the restart timestep.
206      ! This is a performance step enabling the file to be opened and contents
207      ! defined in advance of the write. This is not possible with icebergs
208      ! since the number of bergs to be written could change between timesteps
209      IF( kt == nitrst ) THEN
210         ! Only operate on the restart timestep itself.
211         ! Assume we write iceberg restarts to same directory as ocean restarts.
212         cl_path = TRIM(cn_ocerst_outdir)
213         IF( cl_path(LEN_TRIM(cl_path):) /= '/' ) cl_path = TRIM(cl_path) // '/'
214         IF ( ln_rstdate ) THEN
215            zfjulday = fjulday + rdt / rday
216            IF( ABS(zfjulday - REAL(NINT(zfjulday),wp)) < 0.1 / rday )   zfjulday = REAL(NINT(zfjulday),wp)   ! avoid truncation error
217            CALL ju2ymds( zfjulday, iyear, imonth, iday, zsec )           
218            WRITE(clkt, '(i4.4,2i2.2)') iyear, imonth, iday
219         ELSE
220            IF( kt > 999999999 ) THEN   ;   WRITE(clkt, *       ) kt
221            ELSE                        ;   WRITE(clkt, '(i8.8)') kt
222            ENDIF
223         ENDIF
224         IF( lk_mpp ) THEN
225            WRITE(cl_filename,'(A,"_icebergs_",A,"_restart_",I4.4,".nc")') TRIM(cexper), TRIM(ADJUSTL(clkt)), narea-1
226         ELSE
227            WRITE(cl_filename,'(A,"_icebergs_",A,"_restart.nc")') TRIM(cexper), TRIM(ADJUSTL(clkt))
228         ENDIF
229         IF ( lwp .AND. nprint > 0) WRITE(numout,'(2a)') 'icebergs, write_restart: creating ',  &
230           &                                                         TRIM(cl_path)//TRIM(cl_filename)
231   
232         nret = NF90_CREATE(TRIM(cl_path)//TRIM(cl_filename), NF90_CLOBBER, ncid)
233         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_create failed')
234   
235         ! Dimensions
236         nret = NF90_DEF_DIM(ncid, 'x', jpi, ix_dim)
237         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_def_dim x failed')
238   
239         nret = NF90_DEF_DIM(ncid, 'y', jpj, iy_dim)
240         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_def_dim y failed')
241   
242         nret = NF90_DEF_DIM(ncid, 'c', nclasses, nc_dim)
243         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_def_dim c failed')
244   
245         nret = NF90_DEF_DIM(ncid, 'k', nkounts, ik_dim)
246         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_def_dim k failed')
247   
248         ! global attributes
249         IF( lk_mpp ) THEN
250            ! Set domain parameters (assume jpdom_local_full)
251            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_number_total'   , jpnij              )
252            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_number'         , narea-1            )
253            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_dimensions_ids' , (/1     , 2     /) )
254            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_size_global'    , (/jpiglo, jpjglo/) )
255            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_size_local'     , (/jpi   , jpj   /) )
256            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_position_first' , (/nimpp , njmpp /) )
257            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_position_last'  , (/nimpp + jpi - 1 , njmpp + jpj - 1  /) )
258            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_halo_size_start', (/nldi - 1        , nldj - 1         /) )
259            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_halo_size_end'  , (/jpi - nlei      , jpj - nlej       /) )
260            nret = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'DOMAIN_type'           , 'BOX'              )
261         ENDIF
262         
263         IF (associated(first_berg)) then
264            nret = NF90_DEF_DIM(ncid, 'n', NF90_UNLIMITED, in_dim)
265            IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_def_dim n failed')
266         ENDIF
267   
268         ! Variables
269         nret = NF90_DEF_VAR(ncid, 'kount'       , NF90_INT   , (/ ik_dim /), nkountid)
270         nret = NF90_DEF_VAR(ncid, 'calving'     , NF90_DOUBLE, (/ ix_dim, iy_dim /), ncalvid)
271         nret = NF90_DEF_VAR(ncid, 'calving_hflx', NF90_DOUBLE, (/ ix_dim, iy_dim /), ncalvhid)
272         nret = NF90_DEF_VAR(ncid, 'stored_ice'  , NF90_DOUBLE, (/ ix_dim, iy_dim, nc_dim /), nsiceid)
273         nret = NF90_DEF_VAR(ncid, 'stored_heat' , NF90_DOUBLE, (/ ix_dim, iy_dim /), nsheatid)
274   
275         ! Attributes
276         nret = NF90_PUT_ATT(ncid, ncalvid , 'long_name', 'iceberg calving')
277         nret = NF90_PUT_ATT(ncid, ncalvid , 'units', 'some')
278         nret = NF90_PUT_ATT(ncid, ncalvhid, 'long_name', 'heat flux associated with iceberg calving')
279         nret = NF90_PUT_ATT(ncid, ncalvhid, 'units', 'some')
280         nret = NF90_PUT_ATT(ncid, nsiceid , 'long_name', 'stored ice used to calve icebergs')
281         nret = NF90_PUT_ATT(ncid, nsiceid , 'units', 'kg/s')
282         nret = NF90_PUT_ATT(ncid, nsheatid, 'long_name', 'heat in stored ice used to calve icebergs')
283         nret = NF90_PUT_ATT(ncid, nsheatid, 'units', 'J/kg/s')
284   
285         IF ( ASSOCIATED(first_berg) ) THEN
286   
287            ! Only add berg variables for this PE if we have anything to say
288   
289            ! Variables
290            nret = NF90_DEF_VAR(ncid, 'lon', NF90_DOUBLE, in_dim, nlonid)
291            nret = NF90_DEF_VAR(ncid, 'lat', NF90_DOUBLE, in_dim, nlatid)
292            nret = NF90_DEF_VAR(ncid, 'xi', NF90_DOUBLE, in_dim, nxid)
293            nret = NF90_DEF_VAR(ncid, 'yj', NF90_DOUBLE, in_dim, nyid)
294            nret = NF90_DEF_VAR(ncid, 'uvel', NF90_DOUBLE, in_dim, nuvelid)
295            nret = NF90_DEF_VAR(ncid, 'vvel', NF90_DOUBLE, in_dim, nvvelid)
296            nret = NF90_DEF_VAR(ncid, 'mass', NF90_DOUBLE, in_dim, nmassid)
297            nret = NF90_DEF_VAR(ncid, 'thickness', NF90_DOUBLE, in_dim, nthicknessid)
298            nret = NF90_DEF_VAR(ncid, 'width', NF90_DOUBLE, in_dim, nwidthid)
299            nret = NF90_DEF_VAR(ncid, 'length', NF90_DOUBLE, in_dim, nlengthid)
300            nret = NF90_DEF_VAR(ncid, 'number', NF90_INT, (/ik_dim,in_dim/), numberid)
301            nret = NF90_DEF_VAR(ncid, 'year', NF90_INT, in_dim, nyearid)
302            nret = NF90_DEF_VAR(ncid, 'day', NF90_DOUBLE, in_dim, ndayid)
303            nret = NF90_DEF_VAR(ncid, 'mass_scaling', NF90_DOUBLE, in_dim, nscaling_id)
304            nret = NF90_DEF_VAR(ncid, 'mass_of_bits', NF90_DOUBLE, in_dim, nmass_of_bits_id)
305            nret = NF90_DEF_VAR(ncid, 'heat_density', NF90_DOUBLE, in_dim, nheat_density_id)
306   
307            ! Attributes
308            nret = NF90_PUT_ATT(ncid, nlonid, 'long_name', 'longitude')
309            nret = NF90_PUT_ATT(ncid, nlonid, 'units', 'degrees_E')
310            nret = NF90_PUT_ATT(ncid, nlatid, 'long_name', 'latitude')
311            nret = NF90_PUT_ATT(ncid, nlatid, 'units', 'degrees_N')
312            nret = NF90_PUT_ATT(ncid, nxid, 'long_name', 'x grid box position')
313            nret = NF90_PUT_ATT(ncid, nxid, 'units', 'fractional')
314            nret = NF90_PUT_ATT(ncid, nyid, 'long_name', 'y grid box position')
315            nret = NF90_PUT_ATT(ncid, nyid, 'units', 'fractional')
316            nret = NF90_PUT_ATT(ncid, nuvelid, 'long_name', 'zonal velocity')
317            nret = NF90_PUT_ATT(ncid, nuvelid, 'units', 'm/s')
318            nret = NF90_PUT_ATT(ncid, nvvelid, 'long_name', 'meridional velocity')
319            nret = NF90_PUT_ATT(ncid, nvvelid, 'units', 'm/s')
320            nret = NF90_PUT_ATT(ncid, nmassid, 'long_name', 'mass')
321            nret = NF90_PUT_ATT(ncid, nmassid, 'units', 'kg')
322            nret = NF90_PUT_ATT(ncid, nthicknessid, 'long_name', 'thickness')
323            nret = NF90_PUT_ATT(ncid, nthicknessid, 'units', 'm')
324            nret = NF90_PUT_ATT(ncid, nwidthid, 'long_name', 'width')
325            nret = NF90_PUT_ATT(ncid, nwidthid, 'units', 'm')
326            nret = NF90_PUT_ATT(ncid, nlengthid, 'long_name', 'length')
327            nret = NF90_PUT_ATT(ncid, nlengthid, 'units', 'm')
328            nret = NF90_PUT_ATT(ncid, numberid, 'long_name', 'iceberg number on this processor')
329            nret = NF90_PUT_ATT(ncid, numberid, 'units', 'count')
330            nret = NF90_PUT_ATT(ncid, nyearid, 'long_name', 'calendar year of calving event')
331            nret = NF90_PUT_ATT(ncid, nyearid, 'units', 'years')
332            nret = NF90_PUT_ATT(ncid, ndayid, 'long_name', 'year day of calving event')
333            nret = NF90_PUT_ATT(ncid, ndayid, 'units', 'days')
334            nret = NF90_PUT_ATT(ncid, nscaling_id, 'long_name', 'scaling factor for mass of calving berg')
335            nret = NF90_PUT_ATT(ncid, nscaling_id, 'units', 'none')
336            nret = NF90_PUT_ATT(ncid, nmass_of_bits_id, 'long_name', 'mass of bergy bits')
337            nret = NF90_PUT_ATT(ncid, nmass_of_bits_id, 'units', 'kg')
338            nret = NF90_PUT_ATT(ncid, nheat_density_id, 'long_name', 'heat density')
339            nret = NF90_PUT_ATT(ncid, nheat_density_id, 'units', 'J/kg')
340   
341         ENDIF ! associated(first_berg)
342   
343         ! End define mode
344         nret = NF90_ENDDEF(ncid)
345   
346         ! --------------------------------
347         ! now write some data
348   
349         nstrt3(1) = 1
350         nstrt3(2) = 1
351         nlngth3(1) = jpi
352         nlngth3(2) = jpj
353         nlngth3(3) = 1
354   
355         DO jn=1,nclasses
356            griddata(:,:,1) = berg_grid%stored_ice(:,:,jn)
357            nstrt3(3) = jn
358            nret = NF90_PUT_VAR( ncid, nsiceid, griddata, nstrt3, nlngth3 )
359            IF (nret .ne. NF90_NOERR) THEN
360               IF( lwp ) WRITE(numout,*) TRIM(NF90_STRERROR( nret ))
361               CALL ctl_stop('icebergs, write_restart: nf_put_var stored_ice failed')
362            ENDIF
363         ENDDO
364         IF( lwp .AND. nprint > 1 ) WRITE(numout,*) 'file: ',TRIM(cl_path)//TRIM(cl_filename),' var: stored_ice  written'
365   
366         nret = NF90_PUT_VAR( ncid, nkountid, num_bergs(:) )
367         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_put_var kount failed')
368   
369         nret = NF90_PUT_VAR( ncid, nsheatid, berg_grid%stored_heat(:,:) )
370         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_put_var stored_heat failed')
371         IF( lwp .AND. nprint > 1 ) WRITE(numout,*) 'file: ',TRIM(cl_path)//TRIM(cl_filename),' var: stored_heat written'
372   
373         nret = NF90_PUT_VAR( ncid, ncalvid , src_calving(:,:) )
374         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_put_var calving failed')
375         nret = NF90_PUT_VAR( ncid, ncalvhid, src_calving_hflx(:,:) )
376         IF (nret .ne. NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_put_var calving_hflx failed')
377         IF( lwp .AND. nprint > 1 ) WRITE(numout,*) 'file: ',TRIM(cl_path)//TRIM(cl_filename),' var: calving written'
378   
379         IF ( ASSOCIATED(first_berg) ) THEN
380   
381            ! Write variables
382            ! just write out the current point of the trajectory
383   
384            this => first_berg
385            jn = 0
386            DO WHILE (ASSOCIATED(this))
387               pt => this%current_point
388               jn=jn+1
389   
390               nret = NF90_PUT_VAR(ncid, numberid, this%number, (/1,jn/), (/nkounts,1/) )
391               nret = NF90_PUT_VAR(ncid, nscaling_id, this%mass_scaling, (/ jn /) )
392   
393               nret = NF90_PUT_VAR(ncid, nlonid, pt%lon, (/ jn /) )
394               nret = NF90_PUT_VAR(ncid, nlatid, pt%lat, (/ jn /) )
395               nret = NF90_PUT_VAR(ncid, nxid, pt%xi, (/ jn /) )
396               nret = NF90_PUT_VAR(ncid, nyid, pt%yj, (/ jn /) )
397               nret = NF90_PUT_VAR(ncid, nuvelid, pt%uvel, (/ jn /) )
398               nret = NF90_PUT_VAR(ncid, nvvelid, pt%vvel, (/ jn /) )
399               nret = NF90_PUT_VAR(ncid, nmassid, pt%mass, (/ jn /) )
400               nret = NF90_PUT_VAR(ncid, nthicknessid, pt%thickness, (/ jn /) )
401               nret = NF90_PUT_VAR(ncid, nwidthid, pt%width, (/ jn /) )
402               nret = NF90_PUT_VAR(ncid, nlengthid, pt%length, (/ jn /) )
403               nret = NF90_PUT_VAR(ncid, nyearid, pt%year, (/ jn /) )
404               nret = NF90_PUT_VAR(ncid, ndayid, pt%day, (/ jn /) )
405               nret = NF90_PUT_VAR(ncid, nmass_of_bits_id, pt%mass_of_bits, (/ jn /) )
406               nret = NF90_PUT_VAR(ncid, nheat_density_id, pt%heat_density, (/ jn /) )
407   
408               this=>this%next
409            END DO
410            !
411         ENDIF ! associated(first_berg)
412   
413         ! Finish up
414         nret = NF90_CLOSE(ncid)
415         IF (nret /= NF90_NOERR) CALL ctl_stop('icebergs, write_restart: nf_close failed')
416   
417         ! Sanity check
418         jn = icb_utl_count()
419         IF ( lwp .AND. nprint > 0)   &
420            WRITE(numout,'(2(a,i5))') 'icebergs, icb_rst_write: # bergs =',jn,' on PE',narea-1
421         IF( lk_mpp ) THEN
422            CALL mpp_sum('icbrst', jn)
423         ENDIF
424         IF(lwp .AND. nprint >= 0 )   WRITE(numout,'(a,i5,a,i5,a)') 'icebergs, icb_rst_write: ', jn,   &
425            &                                    ' bergs in total have been written at timestep ', kt
426         !
427         ! Finish up
428         !
429      ENDIF
430   END SUBROUTINE icb_rst_write
431   !
432   !!======================================================================
433END MODULE icbrst
Note: See TracBrowser for help on using the repository browser.