source: NEMO/trunk/src/OCE/ICB/icbini.F90 @ 10570

Last change on this file since 10570 was 10570, checked in by acc, 19 months ago

Trunk update to implement finer control over the choice of text report files generated. See ticket: #2167

  • Property svn:keywords set to Id
File size: 22.8 KB
Line 
1MODULE icbini
2   !!======================================================================
3   !!                       ***  MODULE  icbini  ***
4   !! Icebergs:  initialise variables for iceberg tracking
5   !!======================================================================
6   !! History :   -   !  2010-01  (T. Martin & A. Adcroft)  Original code
7   !!            3.3  !  2011-03  (G. Madec)  Part conversion to NEMO form ; Removal of mapping from another grid
8   !!             -   !  2011-04  (S. Alderson)  Split into separate modules ; Restore restart routines
9   !!             -   !  2011-05  (S. Alderson)  generate_test_icebergs restored ; new forcing arrays with extra halo ;
10   !!             -   !                          north fold exchange arrays added
11   !!----------------------------------------------------------------------
12   !!----------------------------------------------------------------------
13   !!   icb_init     : initialise icebergs
14   !!   icb_ini_gen  : generate test icebergs
15   !!   icb_nam      : read iceberg namelist
16   !!----------------------------------------------------------------------
17   USE dom_oce        ! ocean domain
18   USE in_out_manager ! IO routines and numout in particular
19   USE lib_mpp        ! mpi library and lk_mpp in particular
20   USE sbc_oce        ! ocean  : surface boundary condition
21   USE sbc_ice        ! sea-ice: surface boundary condition
22   USE iom            ! IOM library
23   USE fldread        ! field read
24   USE lbclnk         ! lateral boundary condition - MPP link
25   !
26   USE icb_oce        ! define iceberg arrays
27   USE icbutl         ! iceberg utility routines
28   USE icbrst         ! iceberg restart routines
29   USE icbtrj         ! iceberg trajectory I/O routines
30   USE icbdia         ! iceberg budget routines
31
32   IMPLICIT NONE
33   PRIVATE
34
35   PUBLIC   icb_init  ! routine called in nemogcm.F90 module
36
37   CHARACTER(len=100)                                 ::   cn_dir = './'   !: Root directory for location of icb files
38   TYPE(FLD_N)                                        ::   sn_icb          !: information about the calving file to be read
39   TYPE(FLD), PUBLIC, ALLOCATABLE     , DIMENSION(:)  ::   sf_icb          !: structure: file information, fields read
40                                                                           !: used in icbini and icbstp
41   !!----------------------------------------------------------------------
42   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
43   !! $Id$
44   !! Software governed by the CeCILL license (see ./LICENSE)
45   !!----------------------------------------------------------------------
46CONTAINS
47
48   SUBROUTINE icb_init( pdt, kt )
49      !!----------------------------------------------------------------------
50      !!                  ***  ROUTINE dom_init  ***
51      !!
52      !! ** Purpose :   iceberg initialization.
53      !!
54      !! ** Method  : - read the iceberg namelist
55      !!              - find non-overlapping processor interior since we can only
56      !!                have one instance of a particular iceberg
57      !!              - calculate the destinations for north fold exchanges
58      !!              - setup either test icebergs or calving file
59      !!----------------------------------------------------------------------
60      REAL(wp), INTENT(in) ::   pdt   ! iceberg time-step (rdt*nn_fsbc)
61      INTEGER , INTENT(in) ::   kt    ! time step number
62      !
63      INTEGER ::   ji, jj, jn               ! dummy loop indices
64      INTEGER ::   i1, i2, i3               ! local integers
65      INTEGER ::   ii, inum, ivar           !   -       -
66      INTEGER ::   istat1, istat2, istat3   !   -       -
67      CHARACTER(len=300) ::   cl_sdist      ! local character
68      !!----------------------------------------------------------------------
69      !
70      CALL icb_nam               ! Read and print namelist parameters
71      !
72      IF( .NOT. ln_icebergs )   RETURN
73
74      !                          ! allocate gridded fields
75      IF( icb_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'icb_alloc : unable to allocate arrays' )
76
77      !                          ! open ascii output file or files for iceberg status information
78      !                          ! note that we choose to do this on all processors since we cannot
79      !                          ! predict where icebergs will be ahead of time
80      IF( nn_verbose_level > 0) THEN
81         CALL ctl_opn( numicb, 'icebergs.stat', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, numout, lwp, narea )
82      ENDIF
83
84      ! set parameters (mostly from namelist)
85      !
86      berg_dt         = pdt
87      first_width (:) = SQRT(  rn_initial_mass(:) / ( rn_LoW_ratio * rn_rho_bergs * rn_initial_thickness(:) )  )
88      first_length(:) = rn_LoW_ratio * first_width(:)
89
90      berg_grid%calving      (:,:)   = 0._wp
91      berg_grid%calving_hflx (:,:)   = 0._wp
92      berg_grid%stored_heat  (:,:)   = 0._wp
93      berg_grid%floating_melt(:,:)   = 0._wp
94      berg_grid%maxclass     (:,:)   = nclasses
95      berg_grid%stored_ice   (:,:,:) = 0._wp
96      berg_grid%tmp          (:,:)   = 0._wp
97      src_calving            (:,:)   = 0._wp
98      src_calving_hflx       (:,:)   = 0._wp
99
100      !                          ! domain for icebergs
101      IF( lk_mpp .AND. jpni == 1 )   CALL ctl_stop( 'icbinit: having ONE processor in x currently does not work' )
102      ! NB: the issue here is simply that cyclic east-west boundary condition have not been coded in mpp case
103      ! for the north fold we work out which points communicate by asking
104      ! lbc_lnk to pass processor number (valid even in single processor case)
105      ! borrow src_calving arrays for this
106      !
107      ! pack i and j together using a scaling of a power of 10
108      nicbpack = 10000
109      IF( jpiglo >= nicbpack )   CALL ctl_stop( 'icbini: processor index packing failure' )
110      nicbfldproc(:) = -1
111
112      DO jj = 1, jpj
113         DO ji = 1, jpi
114            src_calving_hflx(ji,jj) = narea
115            src_calving     (ji,jj) = nicbpack * mjg(jj) + mig(ji)
116         END DO
117      END DO
118      CALL lbc_lnk( 'icbini', src_calving_hflx, 'T', 1._wp )
119      CALL lbc_lnk( 'icbini', src_calving     , 'T', 1._wp )
120
121      ! work out interior of processor from exchange array
122      ! first entry with narea for this processor is left hand interior index
123      ! last  entry                               is right hand interior index
124      jj = nlcj/2
125      nicbdi = -1
126      nicbei = -1
127      DO ji = 1, jpi
128         i3 = INT( src_calving(ji,jj) )
129         i2 = INT( i3/nicbpack )
130         i1 = i3 - i2*nicbpack
131         i3 = INT( src_calving_hflx(ji,jj) )
132         IF( i1 == mig(ji) .AND. i3 == narea ) THEN
133            IF( nicbdi < 0 ) THEN   ;   nicbdi = ji
134            ELSE                    ;   nicbei = ji
135            ENDIF
136         ENDIF
137      END DO
138      !
139      ! repeat for j direction
140      ji = nlci/2
141      nicbdj = -1
142      nicbej = -1
143      DO jj = 1, jpj
144         i3 = INT( src_calving(ji,jj) )
145         i2 = INT( i3/nicbpack )
146         i1 = i3 - i2*nicbpack
147         i3 = INT( src_calving_hflx(ji,jj) )
148         IF( i2 == mjg(jj) .AND. i3 == narea ) THEN
149            IF( nicbdj < 0 ) THEN   ;   nicbdj = jj
150            ELSE                    ;   nicbej = jj
151            ENDIF
152         ENDIF
153      END DO
154      !   
155      ! special for east-west boundary exchange we save the destination index
156      i1 = MAX( nicbdi-1, 1)
157      i3 = INT( src_calving(i1,nlcj/2) )
158      jj = INT( i3/nicbpack )
159      ricb_left = REAL( i3 - nicbpack*jj, wp )
160      i1 = MIN( nicbei+1, jpi )
161      i3 = INT( src_calving(i1,nlcj/2) )
162      jj = INT( i3/nicbpack )
163      ricb_right = REAL( i3 - nicbpack*jj, wp )
164     
165      ! north fold
166      IF( npolj > 0 ) THEN
167         !
168         ! icebergs in row nicbej+1 get passed across fold
169         nicbfldpts(:)  = INT( src_calving(:,nicbej+1) )
170         nicbflddest(:) = INT( src_calving_hflx(:,nicbej+1) )
171         !
172         ! work out list of unique processors to talk to
173         ! pack them into a fixed size array where empty slots are marked by a -1
174         DO ji = nicbdi, nicbei
175            ii = nicbflddest(ji)
176            IF( ii .GT. 0 ) THEN     ! Needed because land suppression can mean
177                                     ! that unused points are not set in edge haloes
178               DO jn = 1, jpni
179                  ! work along array until we find an empty slot
180                  IF( nicbfldproc(jn) == -1 ) THEN
181                     nicbfldproc(jn) = ii
182                     EXIT                             !!gm EXIT should be avoided: use DO WHILE expression instead
183                  ENDIF
184                  ! before we find an empty slot, we may find processor number is already here so we exit
185                  IF( nicbfldproc(jn) == ii ) EXIT
186               END DO
187            ENDIF
188         END DO
189      ENDIF
190      !
191      IF( nn_verbose_level > 0) THEN
192         WRITE(numicb,*) 'processor ', narea
193         WRITE(numicb,*) 'jpi, jpj   ', jpi, jpj
194         WRITE(numicb,*) 'nldi, nlei ', nldi, nlei
195         WRITE(numicb,*) 'nldj, nlej ', nldj, nlej
196         WRITE(numicb,*) 'berg i interior ', nicbdi, nicbei
197         WRITE(numicb,*) 'berg j interior ', nicbdj, nicbej
198         WRITE(numicb,*) 'berg left       ', ricb_left
199         WRITE(numicb,*) 'berg right      ', ricb_right
200         jj = nlcj/2
201         WRITE(numicb,*) "central j line:"
202         WRITE(numicb,*) "i processor"
203         WRITE(numicb,*) (INT(src_calving_hflx(ji,jj)), ji=1,jpi)
204         WRITE(numicb,*) "i point"
205         WRITE(numicb,*) (INT(src_calving(ji,jj)), ji=1,jpi)
206         ji = nlci/2
207         WRITE(numicb,*) "central i line:"
208         WRITE(numicb,*) "j processor"
209         WRITE(numicb,*) (INT(src_calving_hflx(ji,jj)), jj=1,jpj)
210         WRITE(numicb,*) "j point"
211         WRITE(numicb,*) (INT(src_calving(ji,jj)), jj=1,jpj)
212         IF( npolj > 0 ) THEN
213            WRITE(numicb,*) 'north fold destination points '
214            WRITE(numicb,*) nicbfldpts
215            WRITE(numicb,*) 'north fold destination procs  '
216            WRITE(numicb,*) nicbflddest
217            WRITE(numicb,*) 'north fold destination proclist  '
218            WRITE(numicb,*) nicbfldproc
219         ENDIF
220         CALL flush(numicb)
221      ENDIF
222     
223      src_calving     (:,:) = 0._wp
224      src_calving_hflx(:,:) = 0._wp
225
226      ! assign each new iceberg with a unique number constructed from the processor number
227      ! and incremented by the total number of processors
228      num_bergs(:) = 0
229      num_bergs(1) = narea - jpnij
230
231      ! when not generating test icebergs we need to setup calving file
232      IF( nn_test_icebergs < 0 .OR. ln_use_calving ) THEN
233         !
234         ! maximum distribution class array does not change in time so read it once
235         cl_sdist = TRIM( cn_dir )//TRIM( sn_icb%clname )
236         CALL iom_open ( cl_sdist, inum )                              ! open file
237         ivar = iom_varid( inum, 'maxclass', ldstop=.FALSE. )
238         IF( ivar > 0 ) THEN
239            CALL iom_get  ( inum, jpdom_data, 'maxclass', src_calving )   ! read the max distribution array
240            berg_grid%maxclass(:,:) = INT( src_calving )
241            src_calving(:,:) = 0._wp
242         ENDIF
243         CALL iom_close( inum )                                     ! close file
244         !
245         IF( nn_verbose_level > 0) THEN
246            WRITE(numicb,*)
247            WRITE(numicb,*) '          calving read in a file'
248         ENDIF
249         ALLOCATE( sf_icb(1), STAT=istat1 )         ! Create sf_icb structure (calving)
250         ALLOCATE( sf_icb(1)%fnow(jpi,jpj,1), STAT=istat2 )
251         ALLOCATE( sf_icb(1)%fdta(jpi,jpj,1,2), STAT=istat3 )
252         IF( istat1+istat2+istat3 > 0 ) THEN
253            CALL ctl_stop( 'sbc_icb: unable to allocate sf_icb structure' )   ;   RETURN
254         ENDIF
255         !                                          ! fill sf_icb with the namelist (sn_icb) and control print
256         CALL fld_fill( sf_icb, (/ sn_icb /), cn_dir, 'icb_init', 'read calving data', 'namicb' )
257         !
258      ENDIF
259
260      IF( .NOT.ln_rstart ) THEN
261         IF( nn_test_icebergs > 0 )   CALL icb_ini_gen()
262      ELSE
263         IF( nn_test_icebergs > 0 ) THEN
264            CALL icb_ini_gen()
265         ELSE
266            CALL icb_rst_read()
267            l_restarted_bergs = .TRUE.
268         ENDIF
269      ENDIF
270      !
271      IF( nn_sample_rate .GT. 0 ) CALL icb_trj_init( nitend )
272      !
273      CALL icb_dia_init()
274      !
275      IF( nn_verbose_level >= 2 )   CALL icb_utl_print('icb_init, initial status', nit000-1)
276      !
277   END SUBROUTINE icb_init
278
279
280   SUBROUTINE icb_ini_gen()
281      !!----------------------------------------------------------------------
282      !!                  ***  ROUTINE icb_ini_gen  ***
283      !!
284      !! ** Purpose :   iceberg generation
285      !!
286      !! ** Method  : - at each grid point of the test box supplied in the namelist
287      !!                generate an iceberg in one class determined by the value of
288      !!                parameter nn_test_icebergs
289      !!----------------------------------------------------------------------
290      INTEGER                         ::   ji, jj, ibergs
291      TYPE(iceberg)                   ::   localberg ! NOT a pointer but an actual local variable
292      TYPE(point)                     ::   localpt
293      INTEGER                         ::   iyr, imon, iday, ihr, imin, isec
294      INTEGER                         ::   iberg
295      !!----------------------------------------------------------------------
296
297      ! For convenience
298      iberg = nn_test_icebergs
299
300      ! call get_date(Time, iyr, imon, iday, ihr, imin, isec)
301      ! Convert nemo time variables from dom_oce into local versions
302      iyr  = nyear
303      imon = nmonth
304      iday = nday
305      ihr = INT(nsec_day/3600)
306      imin = INT((nsec_day-ihr*3600)/60)
307      isec = nsec_day - ihr*3600 - imin*60
308
309      ! no overlap for icebergs since we want only one instance of each across the whole domain
310      ! so restrict area of interest
311      ! use tmask here because tmask_i has been doctored on one side of the north fold line
312
313      DO jj = nicbdj, nicbej
314         DO ji = nicbdi, nicbei
315            IF( tmask(ji,jj,1) > 0._wp        .AND.                                       &
316                rn_test_box(1) < glamt(ji,jj) .AND. glamt(ji,jj) < rn_test_box(2) .AND.   &
317                rn_test_box(3) < gphit(ji,jj) .AND. gphit(ji,jj) < rn_test_box(4) ) THEN
318               localberg%mass_scaling = rn_mass_scaling(iberg)
319               localpt%xi = REAL( mig(ji), wp )
320               localpt%yj = REAL( mjg(jj), wp )
321               localpt%lon = icb_utl_bilin(glamt, localpt%xi, localpt%yj, 'T' )
322               localpt%lat = icb_utl_bilin(gphit, localpt%xi, localpt%yj, 'T' )
323               localpt%mass      = rn_initial_mass     (iberg)
324               localpt%thickness = rn_initial_thickness(iberg)
325               localpt%width  = first_width (iberg)
326               localpt%length = first_length(iberg)
327               localpt%year = iyr
328               localpt%day = REAL(iday,wp)+(REAL(ihr,wp)+REAL(imin,wp)/60._wp)/24._wp
329               localpt%mass_of_bits = 0._wp
330               localpt%heat_density = 0._wp
331               localpt%uvel = 0._wp
332               localpt%vvel = 0._wp
333               CALL icb_utl_incr()
334               localberg%number(:) = num_bergs(:)
335               call icb_utl_add(localberg, localpt)
336            ENDIF
337         END DO
338      END DO
339      !
340      ibergs = icb_utl_count()
341      CALL mpp_sum('icbini', ibergs)
342      IF( nn_verbose_level > 0) THEN
343         WRITE(numicb,'(a,i6,a)') 'diamonds, icb_ini_gen: ',ibergs,' were generated'
344      ENDIF
345      !
346   END SUBROUTINE icb_ini_gen
347
348
349   SUBROUTINE icb_nam
350      !!----------------------------------------------------------------------
351      !!                     ***  ROUTINE icb_nam  ***
352      !!
353      !! ** Purpose :   read iceberg namelist and print the variables.
354      !!
355      !! ** input   : - namberg namelist
356      !!----------------------------------------------------------------------
357      INTEGER  ::   jn      ! dummy loop indices
358      INTEGER  ::   ios     ! Local integer output status for namelist read
359      REAL(wp) ::   zfact   ! local scalar
360      !
361      NAMELIST/namberg/ ln_icebergs    , ln_bergdia     , nn_sample_rate      , rn_initial_mass      ,   &
362         &              rn_distribution, rn_mass_scaling, rn_initial_thickness, nn_verbose_write     ,   &
363         &              rn_rho_bergs   , rn_LoW_ratio   , nn_verbose_level    , ln_operator_splitting,   &
364         &              rn_bits_erosion_fraction        , rn_sicn_shift       , ln_passive_mode      ,   &
365         &              ln_time_average_weight          , nn_test_icebergs    , rn_test_box          ,   &
366         &              ln_use_calving , rn_speed_limit , cn_dir, sn_icb
367      !!----------------------------------------------------------------------
368
369#if defined key_agrif
370      IF(lwp) THEN
371         WRITE(numout,*)
372         WRITE(numout,*) 'icb_nam : AGRIF is not compatible with namelist namberg :  '
373         WRITE(numout,*) '~~~~~~~   definition of rn_initial_mass(nclasses) with nclasses as PARAMETER '
374         WRITE(numout,*)
375         WRITE(numout,*) '   ==>>>   force  NO icebergs used. The namelist namberg is not read'
376      ENDIF
377      ln_icebergs = .false.     
378      RETURN
379#else
380      IF(lwp) THEN
381         WRITE(numout,*)
382         WRITE(numout,*) 'icb_nam : iceberg initialization through namberg namelist read'
383         WRITE(numout,*) '~~~~~~~~ '
384      ENDIF
385#endif   
386      !                             !==  read namelist  ==!
387      REWIND( numnam_ref )              ! Namelist namberg in reference namelist : Iceberg parameters
388      READ  ( numnam_ref, namberg, IOSTAT = ios, ERR = 901)
389901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namberg in reference namelist', lwp )
390      REWIND( numnam_cfg )              ! Namelist namberg in configuration namelist : Iceberg parameters
391      READ  ( numnam_cfg, namberg, IOSTAT = ios, ERR = 902 )
392902   IF( ios >  0 ) CALL ctl_nam ( ios , 'namberg in configuration namelist', lwp )
393      IF(lwm) WRITE ( numond, namberg )
394      !
395      IF(lwp) WRITE(numout,*)
396      IF( ln_icebergs ) THEN
397         IF(lwp) WRITE(numout,*) '   ==>>>   icebergs are used'
398      ELSE
399         IF(lwp) WRITE(numout,*) '   ==>>>   No icebergs used'
400         RETURN
401      ENDIF
402      !
403      IF( nn_test_icebergs > nclasses ) THEN
404         IF(lwp) WRITE(numout,*)
405         IF(lwp) WRITE(numout,*) '   ==>>>   Resetting of nn_test_icebergs to ', nclasses
406         nn_test_icebergs = nclasses
407      ENDIF
408      !
409      IF( nn_test_icebergs < 0 .AND. .NOT. ln_use_calving ) THEN
410         IF(lwp) WRITE(numout,*)
411         IF(lwp) WRITE(numout,*) '   ==>>>   Resetting ln_use_calving to .true. since we are not using test icebergs'
412         ln_use_calving = .true.
413      ENDIF
414      !
415      IF(lwp) THEN                  ! control print
416         WRITE(numout,*)
417         WRITE(numout,*) 'icb_nam : iceberg initialization through namberg namelist read'
418         WRITE(numout,*) '~~~~~~~~ '
419         WRITE(numout,*) '   Calculate budgets                                            ln_bergdia       = ', ln_bergdia
420         WRITE(numout,*) '   Period between sampling of position for trajectory storage   nn_sample_rate = ', nn_sample_rate
421         WRITE(numout,*) '   Mass thresholds between iceberg classes (kg)                 rn_initial_mass     ='
422         DO jn = 1, nclasses
423            WRITE(numout,'(a,f15.2)') '                                                                ', rn_initial_mass(jn)
424         ENDDO
425         WRITE(numout,*) '   Fraction of calving to apply to this class (non-dim)         rn_distribution     ='
426         DO jn = 1, nclasses
427            WRITE(numout,'(a,f10.4)') '                                                                ', rn_distribution(jn)
428         END DO
429         WRITE(numout,*) '   Ratio between effective and real iceberg mass (non-dim)      rn_mass_scaling     = '
430         DO jn = 1, nclasses
431            WRITE(numout,'(a,f10.2)') '                                                                ', rn_mass_scaling(jn)
432         END DO
433         WRITE(numout,*) '   Total thickness of newly calved bergs (m)                    rn_initial_thickness = '
434         DO jn = 1, nclasses
435            WRITE(numout,'(a,f10.2)') '                                                                ', rn_initial_thickness(jn)
436         END DO
437         WRITE(numout,*) '   Timesteps between verbose messages                           nn_verbose_write    = ', nn_verbose_write
438
439         WRITE(numout,*) '   Density of icebergs                           rn_rho_bergs  = ', rn_rho_bergs
440         WRITE(numout,*) '   Initial ratio L/W for newly calved icebergs   rn_LoW_ratio  = ', rn_LoW_ratio
441         WRITE(numout,*) '   Turn on more verbose output                          level  = ', nn_verbose_level
442         WRITE(numout,*) '   Use first order operator splitting for thermodynamics    ',   &
443            &                    'use_operator_splitting = ', ln_operator_splitting
444         WRITE(numout,*) '   Fraction of erosion melt flux to divert to bergy bits    ',   &
445            &                    'bits_erosion_fraction = ', rn_bits_erosion_fraction
446
447         WRITE(numout,*) '   Shift of sea-ice concentration in erosion flux modulation ',   &
448            &                    '(0<sicn_shift<1)    rn_sicn_shift  = ', rn_sicn_shift
449         WRITE(numout,*) '   Do not add freshwater flux from icebergs to ocean                ',   &
450            &                    '                  passive_mode            = ', ln_passive_mode
451         WRITE(numout,*) '   Time average the weight on the ocean   time_average_weight       = ', ln_time_average_weight
452         WRITE(numout,*) '   Create icebergs in absence of a restart file   nn_test_icebergs  = ', nn_test_icebergs
453         WRITE(numout,*) '                   in lon/lat box                                   = ', rn_test_box
454         WRITE(numout,*) '   Use calving data even if nn_test_icebergs > 0    ln_use_calving  = ', ln_use_calving
455         WRITE(numout,*) '   CFL speed limit for a berg            speed_limit                = ', rn_speed_limit
456         WRITE(numout,*) '   Writing Iceberg status information to icebergs.stat file        '
457      ENDIF
458      !
459      ! ensure that the sum of berg input distribution is equal to one
460      zfact = SUM( rn_distribution )
461      IF( zfact /= 1._wp .AND. 0_wp /= zfact ) THEN
462         rn_distribution(:) = rn_distribution(:) / zfact
463         IF(lwp) THEN
464            WRITE(numout,*)
465            WRITE(numout,*) '      ==>>> CAUTION:    sum of berg input distribution = ', zfact
466            WRITE(numout,*) '            *******     redistribution has been rescaled'
467            WRITE(numout,*) '                        updated berg distribution is :'
468            DO jn = 1, nclasses
469               WRITE(numout,'(a,f10.4)') '                                   ',rn_distribution(jn)
470            END DO
471         ENDIF
472      ENDIF
473      IF( MINVAL( rn_distribution(:) ) < 0._wp ) THEN
474         CALL ctl_stop( 'icb_nam: a negative rn_distribution value encountered ==>> change your namelist namberg' )
475      ENDIF
476      !
477   END SUBROUTINE icb_nam
478
479   !!======================================================================
480END MODULE icbini
Note: See TracBrowser for help on using the repository browser.