source: palm/trunk/SOURCE/data_output_2d.f90 @ 1308

Last change on this file since 1308 was 1308, checked in by fricke, 8 years ago

Adjustments for parallel NetCDF output for lccrayh/lccrayb (Cray XC30 systems)

  • Property svn:keywords set to Id
File size: 75.3 KB
Line 
1 SUBROUTINE data_output_2d( mode, av )
2
3!--------------------------------------------------------------------------------!
4! This file is part of PALM.
5!
6! PALM is free software: you can redistribute it and/or modify it under the terms
7! of the GNU General Public License as published by the Free Software Foundation,
8! either version 3 of the License, or (at your option) any later version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 1997-2012  Leibniz University Hannover
18!--------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22! +local_2d_sections, local_2d_sections_l, ns
23! Check, if the limit of the time dimension is exceeded for parallel output
24! To increase the performance for parallel output, the following is done:
25! - Update of time axis is only done by PE0
26! - Cross sections are first stored on a local array and are written
27!   collectively to the output file by all PEs.
28!
29! Former revisions:
30! -----------------
31! $Id: data_output_2d.f90 1308 2014-03-13 14:58:42Z fricke $
32!
33! 1115 2013-03-26 18:16:16Z hoffmann
34! ql is calculated by calc_liquid_water_content
35!
36! 1076 2012-12-05 08:30:18Z hoffmann
37! Bugfix in output of ql
38!
39! 1065 2012-11-22 17:42:36Z hoffmann
40! Bugfix: Output of cross sections of ql
41!
42! 1053 2012-11-13 17:11:03Z hoffmann
43! +qr, nr, qc and cross sections
44!
45! 1036 2012-10-22 13:43:42Z raasch
46! code put under GPL (PALM 3.9)
47!
48! 1031 2012-10-19 14:35:30Z raasch
49! netCDF4 without parallel file support implemented
50!
51! 1007 2012-09-19 14:30:36Z franke
52! Bugfix: missing calculation of ql_vp added
53!
54! 978 2012-08-09 08:28:32Z fricke
55! +z0h
56!
57! 790 2011-11-29 03:11:20Z raasch
58! bugfix: calculation of 'pr' must depend on the particle weighting factor
59!
60! 771 2011-10-27 10:56:21Z heinze
61! +lpt
62!
63! 759 2011-09-15 13:58:31Z raasch
64! Splitting of parallel I/O
65!
66! 729 2011-05-26 10:33:34Z heinze
67! Exchange ghost layers for p regardless of used pressure solver (except SOR).
68!
69! 691 2011-03-04 08:45:30Z maronga
70! Replaced simulated_time by time_since_reference_point
71!
72! 673 2011-01-18 16:19:48Z suehring
73! When using Multigrid or SOR solver an additional CALL exchange_horiz is
74! is needed for pressure output.
75!
76! 667 2010-12-23 12:06:00Z suehring/gryschka
77! nxl-1, nxr+1, nys-1, nyn+1 replaced by nxlg, nxrg, nysg, nyng in loops and
78! allocation of arrays local_2d and total_2d.
79! Calls of exchange_horiz are modiefied.
80!
81! 622 2010-12-10 08:08:13Z raasch
82! optional barriers included in order to speed up collective operations
83!
84! 493 2010-03-01 08:30:24Z raasch
85! netCDF4 support (parallel output)
86!
87! 367 2009-08-25 08:35:52Z maronga
88! simulated_time in netCDF output replaced by time_since_reference_point.
89! Output of netCDF messages with aid of message handling routine.
90! Bugfix: averaging along z is not allowed for 2d quantities (e.g. u* and z0)
91! Output of messages replaced by message handling routine.
92! Output of user defined 2D (XY) arrays at z=nzb+1 is now possible
93! Bugfix: to_be_resorted => s_av for time-averaged scalars
94! Calculation of shf* and qsws* added.
95!
96! 215 2008-11-18 09:54:31Z raasch
97! Bugfix: no output of particle concentration and radius unless particles
98! have been started
99!
100! 96 2007-06-04 08:07:41Z raasch
101! Output of density and salinity
102!
103! 75 2007-03-22 09:54:05Z raasch
104! Output of precipitation amount/rate and roughness length,
105! 2nd+3rd argument removed from exchange horiz
106!
107! RCS Log replace by Id keyword, revision history cleaned up
108!
109! Revision 1.5  2006/08/22 13:50:29  raasch
110! xz and yz cross sections now up to nzt+1
111!
112! Revision 1.2  2006/02/23 10:19:22  raasch
113! Output of time-averaged data, output of averages along x, y, or z,
114! output of user-defined quantities,
115! section data are copied from local_pf to local_2d before they are output,
116! output of particle concentration and mean radius,
117! Former subroutine plot_2d renamed data_output_2d, pl2d.. renamed do2d..,
118! anz renamed ngp, ebene renamed section, pl2d_.._anz renamed do2d_.._n
119!
120! Revision 1.1  1997/08/11 06:24:09  raasch
121! Initial revision
122!
123!
124! Description:
125! ------------
126! Data output of horizontal cross-sections in netCDF format or binary format
127! compatible to old graphic software iso2d.
128! Attention: The position of the sectional planes is still not always computed
129! ---------  correctly. (zu is used always)!
130!------------------------------------------------------------------------------!
131
132    USE arrays_3d
133    USE averaging
134    USE cloud_parameters
135    USE control_parameters
136    USE cpulog
137    USE grid_variables
138    USE indices
139    USE interfaces
140    USE netcdf_control
141    USE particle_attributes
142    USE pegrid
143
144    IMPLICIT NONE
145
146    CHARACTER (LEN=2)  ::  do2d_mode, mode
147    CHARACTER (LEN=4)  ::  grid
148    CHARACTER (LEN=25) ::  section_chr
149    CHARACTER (LEN=50) ::  rtext
150    INTEGER ::  av, ngp, file_id, i, if, is, iis, j, k, l, layer_xy, n, ns, &
151                psi, s, sender, &
152                ind(4)
153    LOGICAL ::  found, resorted, two_d
154    REAL    ::  mean_r, s_r3, s_r4
155    REAL, DIMENSION(:), ALLOCATABLE ::      level_z
156    REAL, DIMENSION(:,:), ALLOCATABLE ::    local_2d, local_2d_l
157    REAL, DIMENSION(:,:,:), ALLOCATABLE ::  local_pf, local_2d_sections, &
158                                            local_2d_sections_l
159#if defined( __parallel )
160    REAL, DIMENSION(:,:),   ALLOCATABLE ::  total_2d
161#endif
162    REAL, DIMENSION(:,:,:), POINTER ::  to_be_resorted
163
164    NAMELIST /LOCAL/  rtext
165
166!
167!-- Immediate return, if no output is requested (no respective sections
168!-- found in parameter data_output)
169    IF ( mode == 'xy'  .AND.  .NOT. data_output_xy(av) )  RETURN
170    IF ( mode == 'xz'  .AND.  .NOT. data_output_xz(av) )  RETURN
171    IF ( mode == 'yz'  .AND.  .NOT. data_output_yz(av) )  RETURN
172!
173!-- For parallel netcdf output the time axis must be limited. Return, if this
174!-- limit is exceeded. This could be the case, if the simulated time exceeds
175!-- the given end time by the length of the given output interval.
176    IF ( netcdf_data_format > 4 )  THEN
177       IF ( mode == 'xy'  .AND.  do2d_xy_time_count(av) + 1 > &
178            ntdim_2d_xy(av) )  THEN
179          WRITE ( message_string, * ) 'Output of xy cross-sections is not ', &
180                          'given at t=', simulated_time, '&because the', & 
181                          ' maximum number of output time levels is exceeded.'
182          CALL message( 'data_output_2d', 'PA0384', 0, 1, 0, 6, 0 )         
183          RETURN
184       ENDIF
185       IF ( mode == 'xz'  .AND.  do2d_xz_time_count(av) + 1 > &
186            ntdim_2d_xz(av) )  THEN
187          WRITE ( message_string, * ) 'Output of xz cross-sections is not ',  &
188                          'given at t=', simulated_time, '&because the', & 
189                          ' maximum number of output time levels is exceeded.'
190          CALL message( 'data_output_2d', 'PA0385', 0, 1, 0, 6, 0 )         
191          RETURN
192       ENDIF
193       IF ( mode == 'yz'  .AND.  do2d_yz_time_count(av) + 1 > &
194            ntdim_2d_yz(av) )  THEN
195          WRITE ( message_string, * ) 'Output of yz cross-sections is not ', &
196                          'given at t=', simulated_time, '&because the', & 
197                          ' maximum number of output time levels is exceeded.'
198          CALL message( 'data_output_2d', 'PA0386', 0, 1, 0, 6, 0 )         
199          RETURN
200       ENDIF
201    ENDIF
202
203    CALL cpu_log (log_point(3),'data_output_2d','start')
204
205    two_d = .FALSE.    ! local variable to distinguish between output of pure 2D
206                       ! arrays and cross-sections of 3D arrays.
207
208!
209!-- Depending on the orientation of the cross-section, the respective output
210!-- files have to be opened.
211    SELECT CASE ( mode )
212
213       CASE ( 'xy' )
214          s = 1
215          ALLOCATE( level_z(nzb:nzt+1), local_2d(nxlg:nxrg,nysg:nyng) )
216
217          IF ( netcdf_data_format > 4 )  THEN
218             ns = 1
219             DO WHILE ( section(ns,s) /= -9999  .AND.  ns <= 100 )
220                ns = ns + 1
221             ENDDO
222             ns = ns - 1
223             ALLOCATE( local_2d_sections(nxlg:nxrg,nysg:nyng,1:ns) )
224             local_2d_sections = 0.0
225          ENDIF
226
227!
228!--       Parallel netCDF4/HDF5 output is done on all PEs, all other on PE0 only
229          IF ( netcdf_output .AND. ( myid == 0 .OR. netcdf_data_format > 4 ) ) &
230          THEN
231             CALL check_open( 101+av*10 )
232          ENDIF
233
234          IF ( data_output_2d_on_each_pe )  THEN
235             CALL check_open( 21 )
236          ELSE
237             IF ( myid == 0 )  THEN
238                IF ( iso2d_output )  CALL check_open( 21 )
239#if defined( __parallel )
240                ALLOCATE( total_2d(-nbgp:nx+nbgp,-nbgp:ny+nbgp) )
241#endif
242             ENDIF
243          ENDIF
244
245       CASE ( 'xz' )
246          s = 2
247          ALLOCATE( local_2d(nxlg:nxrg,nzb:nzt+1) )
248
249          IF ( netcdf_data_format > 4 )  THEN
250             ns = 1
251             DO WHILE ( section(ns,s) /= -9999  .AND.  ns <= 100 )
252                ns = ns + 1
253             ENDDO
254             ns = ns - 1
255             ALLOCATE( local_2d_sections(nxlg:nxrg,1:ns,nzb:nzt+1) )
256             ALLOCATE( local_2d_sections_l(nxlg:nxrg,1:ns,nzb:nzt+1) )
257             local_2d_sections = 0.0; local_2d_sections_l = 0.0
258          ENDIF
259
260!
261!--       Parallel netCDF4/HDF5 output is done on all PEs, all other on PE0 only
262          IF ( netcdf_output .AND. ( myid == 0 .OR. netcdf_data_format > 4 ) ) &
263          THEN
264             CALL check_open( 102+av*10 )
265          ENDIF
266
267          IF ( data_output_2d_on_each_pe )  THEN
268             CALL check_open( 22 )
269          ELSE
270             IF ( myid == 0 )  THEN
271                IF ( iso2d_output )  CALL check_open( 22 )
272#if defined( __parallel )
273                ALLOCATE( total_2d(-nbgp:nx+nbgp,nzb:nzt+1) )
274#endif
275             ENDIF
276          ENDIF
277
278       CASE ( 'yz' )
279          s = 3
280          ALLOCATE( local_2d(nysg:nyng,nzb:nzt+1) )
281
282          IF ( netcdf_data_format > 4 )  THEN
283             ns = 1
284             DO WHILE ( section(ns,s) /= -9999  .AND.  ns <= 100 )
285                ns = ns + 1
286             ENDDO
287             ns = ns - 1
288             ALLOCATE( local_2d_sections(1:ns,nysg:nyng,nzb:nzt+1) )
289             ALLOCATE( local_2d_sections_l(1:ns,nysg:nyng,nzb:nzt+1) )
290             local_2d_sections = 0.0; local_2d_sections_l = 0.0
291          ENDIF
292
293!
294!--       Parallel netCDF4/HDF5 output is done on all PEs, all other on PE0 only
295          IF ( netcdf_output .AND. ( myid == 0 .OR. netcdf_data_format > 4 ) ) &
296          THEN
297             CALL check_open( 103+av*10 )
298          ENDIF
299
300          IF ( data_output_2d_on_each_pe )  THEN
301             CALL check_open( 23 )
302          ELSE
303             IF ( myid == 0 )  THEN
304                IF ( iso2d_output )  CALL check_open( 23 )
305#if defined( __parallel )
306                ALLOCATE( total_2d(-nbgp:ny+nbgp,nzb:nzt+1) )
307#endif
308             ENDIF
309          ENDIF
310
311       CASE DEFAULT
312          message_string = 'unknown cross-section: ' // TRIM( mode )
313          CALL message( 'data_output_2d', 'PA0180', 1, 2, 0, 6, 0 )
314
315    END SELECT
316
317!
318!-- Allocate a temporary array for resorting (kji -> ijk).
319    ALLOCATE( local_pf(nxlg:nxrg,nysg:nyng,nzb:nzt+1) )
320
321!
322!-- Loop of all variables to be written.
323!-- Output dimensions chosen
324    if = 1
325    l = MAX( 2, LEN_TRIM( do2d(av,if) ) )
326    do2d_mode = do2d(av,if)(l-1:l)
327
328    DO  WHILE ( do2d(av,if)(1:1) /= ' ' )
329
330       IF ( do2d_mode == mode )  THEN
331!
332!--       Store the array chosen on the temporary array.
333          resorted = .FALSE.
334          SELECT CASE ( TRIM( do2d(av,if) ) )
335
336             CASE ( 'e_xy', 'e_xz', 'e_yz' )
337                IF ( av == 0 )  THEN
338                   to_be_resorted => e
339                ELSE
340                   to_be_resorted => e_av
341                ENDIF
342                IF ( mode == 'xy' )  level_z = zu
343
344             CASE ( 'lpt_xy', 'lpt_xz', 'lpt_yz' )
345                IF ( av == 0 )  THEN
346                   to_be_resorted => pt
347                ELSE
348                   to_be_resorted => lpt_av
349                ENDIF
350                IF ( mode == 'xy' )  level_z = zu
351
352             CASE ( 'lwp*_xy' )        ! 2d-array
353                IF ( av == 0 )  THEN
354                   DO  i = nxlg, nxrg
355                      DO  j = nysg, nyng
356                         local_pf(i,j,nzb+1) = SUM( ql(nzb:nzt,j,i) * &
357                                                    dzw(1:nzt+1) )
358                      ENDDO
359                   ENDDO
360                ELSE
361                   DO  i = nxlg, nxrg
362                      DO  j = nysg, nyng
363                         local_pf(i,j,nzb+1) = lwp_av(j,i)
364                      ENDDO
365                   ENDDO
366                ENDIF
367                resorted = .TRUE.
368                two_d = .TRUE.
369                level_z(nzb+1) = zu(nzb+1)
370
371             CASE ( 'nr_xy', 'nr_xz', 'nr_yz' )
372                IF ( av == 0 )  THEN
373                   to_be_resorted => nr
374                ELSE
375                   to_be_resorted => nr_av
376                ENDIF
377                IF ( mode == 'xy' )  level_z = zu
378
379             CASE ( 'p_xy', 'p_xz', 'p_yz' )
380                IF ( av == 0 )  THEN
381                   IF ( psolver /= 'sor' )  CALL exchange_horiz( p, nbgp )
382                   to_be_resorted => p
383                ELSE
384                   IF ( psolver /= 'sor' )  CALL exchange_horiz( p_av, nbgp )
385                   to_be_resorted => p_av
386                ENDIF
387                IF ( mode == 'xy' )  level_z = zu
388
389             CASE ( 'pc_xy', 'pc_xz', 'pc_yz' )  ! particle concentration
390                IF ( av == 0 )  THEN
391                   IF ( simulated_time >= particle_advection_start )  THEN
392                      tend = prt_count
393                      CALL exchange_horiz( tend, nbgp )
394                   ELSE
395                      tend = 0.0
396                   ENDIF
397                   DO  i = nxlg, nxrg
398                      DO  j = nysg, nyng
399                         DO  k = nzb, nzt+1
400                            local_pf(i,j,k) = tend(k,j,i)
401                         ENDDO
402                      ENDDO
403                   ENDDO
404                   resorted = .TRUE.
405                ELSE
406                   CALL exchange_horiz( pc_av, nbgp )
407                   to_be_resorted => pc_av
408                ENDIF
409
410             CASE ( 'pr_xy', 'pr_xz', 'pr_yz' )  ! mean particle radius
411                IF ( av == 0 )  THEN
412                   IF ( simulated_time >= particle_advection_start )  THEN
413                      DO  i = nxl, nxr
414                         DO  j = nys, nyn
415                            DO  k = nzb, nzt+1
416                               psi = prt_start_index(k,j,i)
417                               s_r3 = 0.0
418                               s_r4 = 0.0
419                               DO  n = psi, psi+prt_count(k,j,i)-1
420                                  s_r3 = s_r3 + particles(n)%radius**3 * &
421                                                particles(n)%weight_factor
422                                  s_r4 = s_r4 + particles(n)%radius**4 * &
423                                                particles(n)%weight_factor
424                               ENDDO
425                               IF ( s_r3 /= 0.0 )  THEN
426                                  mean_r = s_r4 / s_r3
427                               ELSE
428                                  mean_r = 0.0
429                               ENDIF
430                               tend(k,j,i) = mean_r
431                            ENDDO
432                         ENDDO
433                      ENDDO
434                      CALL exchange_horiz( tend, nbgp )
435                   ELSE
436                      tend = 0.0
437                   END IF
438                   DO  i = nxlg, nxrg
439                      DO  j = nysg, nyng
440                         DO  k = nzb, nzt+1
441                            local_pf(i,j,k) = tend(k,j,i)
442                         ENDDO
443                      ENDDO
444                   ENDDO
445                   resorted = .TRUE.
446                ELSE
447                   CALL exchange_horiz( pr_av, nbgp )
448                   to_be_resorted => pr_av
449                ENDIF
450
451             CASE ( 'pra*_xy' )        ! 2d-array / integral quantity => no av
452                CALL exchange_horiz_2d( precipitation_amount )
453                   DO  i = nxlg, nxrg
454                      DO  j = nysg, nyng
455                      local_pf(i,j,nzb+1) =  precipitation_amount(j,i)
456                   ENDDO
457                ENDDO
458                precipitation_amount = 0.0   ! reset for next integ. interval
459                resorted = .TRUE.
460                two_d = .TRUE.
461                level_z(nzb+1) = zu(nzb+1)
462
463             CASE ( 'prr*_xy' )        ! 2d-array
464                IF ( icloud_scheme == 1 )  THEN
465                   IF ( av == 0 )  THEN
466                      CALL exchange_horiz_2d( precipitation_rate )
467                      DO  i = nxlg, nxrg
468                         DO  j = nysg, nyng
469                            local_pf(i,j,nzb+1) =  precipitation_rate(j,i)
470                         ENDDO
471                      ENDDO
472                   ELSE
473                      CALL exchange_horiz_2d( precipitation_rate_av )
474                      DO  i = nxlg, nxrg
475                         DO  j = nysg, nyng
476                            local_pf(i,j,nzb+1) =  precipitation_rate_av(j,i)
477                         ENDDO
478                      ENDDO
479                   ENDIF
480                ELSE
481                   IF ( av == 0 )  THEN
482                      CALL exchange_horiz_2d( prr(nzb+1,:,:) )
483                      DO  i = nxlg, nxrg
484                         DO  j = nysg, nyng
485                            local_pf(i,j,nzb+1) = prr(nzb+1,j,i) * hyrho(nzb+1)
486                         ENDDO
487                      ENDDO
488                   ELSE
489                      CALL exchange_horiz_2d( prr_av(nzb+1,:,:) )
490                      DO  i = nxlg, nxrg
491                         DO  j = nysg, nyng
492                            local_pf(i,j,nzb+1) = prr_av(nzb+1,j,i) * hyrho(nzb+1)
493                         ENDDO
494                      ENDDO
495                   ENDIF
496                ENDIF
497                resorted = .TRUE.
498                two_d = .TRUE.
499                level_z(nzb+1) = zu(nzb+1)
500
501             CASE ( 'prr_xy', 'prr_xz', 'prr_yz' )
502                IF ( av == 0 )  THEN
503                   CALL exchange_horiz( prr, nbgp )
504                   DO  i = nxlg, nxrg
505                      DO  j = nysg, nyng
506                         DO  k = nzb, nzt+1
507                            local_pf(i,j,k) = prr(k,j,i)
508                         ENDDO
509                      ENDDO
510                   ENDDO
511                ELSE
512                   CALL exchange_horiz( prr_av, nbgp )
513                   DO  i = nxlg, nxrg
514                      DO  j = nysg, nyng
515                         DO  k = nzb, nzt+1
516                            local_pf(i,j,k) = prr_av(k,j,i)
517                         ENDDO
518                      ENDDO
519                   ENDDO
520                ENDIF
521                resorted = .TRUE.
522                IF ( mode == 'xy' )  level_z = zu
523
524             CASE ( 'pt_xy', 'pt_xz', 'pt_yz' )
525                IF ( av == 0 )  THEN
526                   IF ( .NOT. cloud_physics ) THEN
527                      to_be_resorted => pt
528                   ELSE
529                   DO  i = nxlg, nxrg
530                      DO  j = nysg, nyng
531                            DO  k = nzb, nzt+1
532                               local_pf(i,j,k) = pt(k,j,i) + l_d_cp *    &
533                                                             pt_d_t(k) * &
534                                                             ql(k,j,i)
535                            ENDDO
536                         ENDDO
537                      ENDDO
538                      resorted = .TRUE.
539                   ENDIF
540                ELSE
541                   to_be_resorted => pt_av
542                ENDIF
543                IF ( mode == 'xy' )  level_z = zu
544
545             CASE ( 'q_xy', 'q_xz', 'q_yz' )
546                IF ( av == 0 )  THEN
547                   to_be_resorted => q
548                ELSE
549                   to_be_resorted => q_av
550                ENDIF
551                IF ( mode == 'xy' )  level_z = zu
552
553             CASE ( 'qc_xy', 'qc_xz', 'qc_yz' )
554                IF ( av == 0 )  THEN
555                   to_be_resorted => qc
556                ELSE
557                   to_be_resorted => qc_av
558                ENDIF
559                IF ( mode == 'xy' )  level_z = zu
560
561             CASE ( 'ql_xy', 'ql_xz', 'ql_yz' )
562                IF ( av == 0 )  THEN
563                   to_be_resorted => ql
564                ELSE
565                   to_be_resorted => ql_av
566                ENDIF
567                IF ( mode == 'xy' )  level_z = zu
568
569             CASE ( 'ql_c_xy', 'ql_c_xz', 'ql_c_yz' )
570                IF ( av == 0 )  THEN
571                   to_be_resorted => ql_c
572                ELSE
573                   to_be_resorted => ql_c_av
574                ENDIF
575                IF ( mode == 'xy' )  level_z = zu
576
577             CASE ( 'ql_v_xy', 'ql_v_xz', 'ql_v_yz' )
578                IF ( av == 0 )  THEN
579                   to_be_resorted => ql_v
580                ELSE
581                   to_be_resorted => ql_v_av
582                ENDIF
583                IF ( mode == 'xy' )  level_z = zu
584
585             CASE ( 'ql_vp_xy', 'ql_vp_xz', 'ql_vp_yz' )
586                IF ( av == 0 )  THEN
587                   IF ( simulated_time >= particle_advection_start )  THEN
588                      DO  i = nxl, nxr
589                         DO  j = nys, nyn
590                            DO  k = nzb, nzt+1
591                               psi = prt_start_index(k,j,i)
592                               DO  n = psi, psi+prt_count(k,j,i)-1
593                                  tend(k,j,i) =  tend(k,j,i) + &
594                                                 particles(n)%weight_factor / &
595                                                 prt_count(k,j,i)
596                               ENDDO
597                            ENDDO
598                         ENDDO
599                      ENDDO
600                      CALL exchange_horiz( tend, nbgp )
601                   ELSE
602                      tend = 0.0
603                   END IF
604                   DO  i = nxlg, nxrg
605                      DO  j = nysg, nyng
606                         DO  k = nzb, nzt+1
607                            local_pf(i,j,k) = tend(k,j,i)
608                         ENDDO
609                      ENDDO
610                   ENDDO
611                   resorted = .TRUE.
612                ELSE
613                   CALL exchange_horiz( ql_vp_av, nbgp )
614                   to_be_resorted => ql_vp
615                ENDIF
616                IF ( mode == 'xy' )  level_z = zu
617
618             CASE ( 'qr_xy', 'qr_xz', 'qr_yz' )
619                IF ( av == 0 )  THEN
620                   to_be_resorted => qr
621                ELSE
622                   to_be_resorted => qr_av
623                ENDIF
624                IF ( mode == 'xy' )  level_z = zu
625
626             CASE ( 'qsws*_xy' )        ! 2d-array
627                IF ( av == 0 ) THEN
628                   DO  i = nxlg, nxrg
629                      DO  j = nysg, nyng
630                         local_pf(i,j,nzb+1) =  qsws(j,i)
631                      ENDDO
632                   ENDDO
633                ELSE
634                   DO  i = nxlg, nxrg
635                      DO  j = nysg, nyng
636                         local_pf(i,j,nzb+1) =  qsws_av(j,i)
637                      ENDDO
638                   ENDDO
639                ENDIF
640                resorted = .TRUE.
641                two_d = .TRUE.
642                level_z(nzb+1) = zu(nzb+1)
643
644             CASE ( 'qv_xy', 'qv_xz', 'qv_yz' )
645                IF ( av == 0 )  THEN
646                   DO  i = nxlg, nxrg
647                      DO  j = nysg, nyng
648                         DO  k = nzb, nzt+1
649                            local_pf(i,j,k) = q(k,j,i) - ql(k,j,i)
650                         ENDDO
651                      ENDDO
652                   ENDDO
653                   resorted = .TRUE.
654                ELSE
655                   to_be_resorted => qv_av
656                ENDIF
657                IF ( mode == 'xy' )  level_z = zu
658
659             CASE ( 'rho_xy', 'rho_xz', 'rho_yz' )
660                IF ( av == 0 )  THEN
661                   to_be_resorted => rho
662                ELSE
663                   to_be_resorted => rho_av
664                ENDIF
665
666             CASE ( 's_xy', 's_xz', 's_yz' )
667                IF ( av == 0 )  THEN
668                   to_be_resorted => q
669                ELSE
670                   to_be_resorted => s_av
671                ENDIF
672
673             CASE ( 'sa_xy', 'sa_xz', 'sa_yz' )
674                IF ( av == 0 )  THEN
675                   to_be_resorted => sa
676                ELSE
677                   to_be_resorted => sa_av
678                ENDIF
679
680             CASE ( 'shf*_xy' )        ! 2d-array
681                IF ( av == 0 ) THEN
682                   DO  i = nxlg, nxrg
683                      DO  j = nysg, nyng
684                         local_pf(i,j,nzb+1) =  shf(j,i)
685                      ENDDO
686                   ENDDO
687                ELSE
688                   DO  i = nxlg, nxrg
689                      DO  j = nysg, nyng
690                         local_pf(i,j,nzb+1) =  shf_av(j,i)
691                      ENDDO
692                   ENDDO
693                ENDIF
694                resorted = .TRUE.
695                two_d = .TRUE.
696                level_z(nzb+1) = zu(nzb+1)
697
698             CASE ( 't*_xy' )        ! 2d-array
699                IF ( av == 0 )  THEN
700                   DO  i = nxlg, nxrg
701                      DO  j = nysg, nyng
702                         local_pf(i,j,nzb+1) = ts(j,i)
703                      ENDDO
704                   ENDDO
705                ELSE
706                   DO  i = nxlg, nxrg
707                      DO  j = nysg, nyng
708                         local_pf(i,j,nzb+1) = ts_av(j,i)
709                      ENDDO
710                   ENDDO
711                ENDIF
712                resorted = .TRUE.
713                two_d = .TRUE.
714                level_z(nzb+1) = zu(nzb+1)
715
716             CASE ( 'u_xy', 'u_xz', 'u_yz' )
717                IF ( av == 0 )  THEN
718                   to_be_resorted => u
719                ELSE
720                   to_be_resorted => u_av
721                ENDIF
722                IF ( mode == 'xy' )  level_z = zu
723!
724!--             Substitute the values generated by "mirror" boundary condition
725!--             at the bottom boundary by the real surface values.
726                IF ( do2d(av,if) == 'u_xz'  .OR.  do2d(av,if) == 'u_yz' )  THEN
727                   IF ( ibc_uv_b == 0 )  local_pf(:,:,nzb) = 0.0
728                ENDIF
729
730             CASE ( 'u*_xy' )        ! 2d-array
731                IF ( av == 0 )  THEN
732                   DO  i = nxlg, nxrg
733                      DO  j = nysg, nyng
734                         local_pf(i,j,nzb+1) = us(j,i)
735                      ENDDO
736                   ENDDO
737                ELSE
738                   DO  i = nxlg, nxrg
739                      DO  j = nysg, nyng
740                         local_pf(i,j,nzb+1) = us_av(j,i)
741                      ENDDO
742                   ENDDO
743                ENDIF
744                resorted = .TRUE.
745                two_d = .TRUE.
746                level_z(nzb+1) = zu(nzb+1)
747
748             CASE ( 'v_xy', 'v_xz', 'v_yz' )
749                IF ( av == 0 )  THEN
750                   to_be_resorted => v
751                ELSE
752                   to_be_resorted => v_av
753                ENDIF
754                IF ( mode == 'xy' )  level_z = zu
755!
756!--             Substitute the values generated by "mirror" boundary condition
757!--             at the bottom boundary by the real surface values.
758                IF ( do2d(av,if) == 'v_xz'  .OR.  do2d(av,if) == 'v_yz' )  THEN
759                   IF ( ibc_uv_b == 0 )  local_pf(:,:,nzb) = 0.0
760                ENDIF
761
762             CASE ( 'vpt_xy', 'vpt_xz', 'vpt_yz' )
763                IF ( av == 0 )  THEN
764                   to_be_resorted => vpt
765                ELSE
766                   to_be_resorted => vpt_av
767                ENDIF
768                IF ( mode == 'xy' )  level_z = zu
769
770             CASE ( 'w_xy', 'w_xz', 'w_yz' )
771                IF ( av == 0 )  THEN
772                   to_be_resorted => w
773                ELSE
774                   to_be_resorted => w_av
775                ENDIF
776                IF ( mode == 'xy' )  level_z = zw
777
778             CASE ( 'z0*_xy' )        ! 2d-array
779                IF ( av == 0 ) THEN
780                   DO  i = nxlg, nxrg
781                      DO  j = nysg, nyng
782                         local_pf(i,j,nzb+1) =  z0(j,i)
783                      ENDDO
784                   ENDDO
785                ELSE
786                   DO  i = nxlg, nxrg
787                      DO  j = nysg, nyng
788                         local_pf(i,j,nzb+1) =  z0_av(j,i)
789                      ENDDO
790                   ENDDO
791                ENDIF
792                resorted = .TRUE.
793                two_d = .TRUE.
794                level_z(nzb+1) = zu(nzb+1)
795
796             CASE ( 'z0h*_xy' )        ! 2d-array
797                IF ( av == 0 ) THEN
798                   DO  i = nxlg, nxrg
799                      DO  j = nysg, nyng
800                         local_pf(i,j,nzb+1) =  z0h(j,i)
801                      ENDDO
802                   ENDDO
803                ELSE
804                   DO  i = nxlg, nxrg
805                      DO  j = nysg, nyng
806                         local_pf(i,j,nzb+1) =  z0h_av(j,i)
807                      ENDDO
808                   ENDDO
809                ENDIF
810                resorted = .TRUE.
811                two_d = .TRUE.
812                level_z(nzb+1) = zu(nzb+1)
813
814             CASE DEFAULT
815!
816!--             User defined quantity
817                CALL user_data_output_2d( av, do2d(av,if), found, grid, &
818                                          local_pf, two_d )
819                resorted = .TRUE.
820
821                IF ( grid == 'zu' )  THEN
822                   IF ( mode == 'xy' )  level_z = zu
823                ELSEIF ( grid == 'zw' )  THEN
824                   IF ( mode == 'xy' )  level_z = zw
825                ELSEIF ( grid == 'zu1' ) THEN
826                   IF ( mode == 'xy' )  level_z(nzb+1) = zu(nzb+1)
827                ENDIF
828
829                IF ( .NOT. found )  THEN
830                   message_string = 'no output provided for: ' //    &
831                                    TRIM( do2d(av,if) )
832                   CALL message( 'data_output_2d', 'PA0181', 0, 0, 0, 6, 0 )
833                ENDIF
834
835          END SELECT
836
837!
838!--       Resort the array to be output, if not done above
839          IF ( .NOT. resorted )  THEN
840             DO  i = nxlg, nxrg
841                DO  j = nysg, nyng
842                   DO  k = nzb, nzt+1
843                      local_pf(i,j,k) = to_be_resorted(k,j,i)
844                   ENDDO
845                ENDDO
846             ENDDO
847          ENDIF
848
849!
850!--       Output of the individual cross-sections, depending on the cross-
851!--       section mode chosen.
852          is = 1
853   loop1: DO  WHILE ( section(is,s) /= -9999  .OR.  two_d )
854
855             SELECT CASE ( mode )
856
857                CASE ( 'xy' )
858!
859!--                Determine the cross section index
860                   IF ( two_d )  THEN
861                      layer_xy = nzb+1
862                   ELSE
863                      layer_xy = section(is,s)
864                   ENDIF
865
866!
867!--                Update the netCDF xy cross section time axis.
868!--                In case of parallel output, this is only done by PE0
869!--                to increase the performance.
870                   IF ( simulated_time /= do2d_xy_last_time(av) )  THEN
871                      do2d_xy_time_count(av) = do2d_xy_time_count(av) + 1
872                      do2d_xy_last_time(av)  = simulated_time
873                      IF ( myid == 0 )  THEN
874                         IF ( ( .NOT. data_output_2d_on_each_pe  .AND. &
875                              netcdf_output )  .OR.  netcdf_data_format > 4 ) &
876                         THEN
877#if defined( __netcdf )
878                            nc_stat = NF90_PUT_VAR( id_set_xy(av),             &
879                                                    id_var_time_xy(av),        &
880                                             (/ time_since_reference_point /), &
881                                         start = (/ do2d_xy_time_count(av) /), &
882                                                    count = (/ 1 /) )
883                            CALL handle_netcdf_error( 'data_output_2d', 53 )
884#endif
885                         ENDIF
886                      ENDIF
887                   ENDIF
888!
889!--                If required, carry out averaging along z
890                   IF ( section(is,s) == -1  .AND.  .NOT. two_d )  THEN
891
892                      local_2d = 0.0
893!
894!--                   Carry out the averaging (all data are on the PE)
895                      DO  k = nzb, nzt+1
896                         DO  j = nysg, nyng
897                            DO  i = nxlg, nxrg
898                               local_2d(i,j) = local_2d(i,j) + local_pf(i,j,k)
899                            ENDDO
900                         ENDDO
901                      ENDDO
902
903                      local_2d = local_2d / ( nzt -nzb + 2.0)
904
905                   ELSE
906!
907!--                   Just store the respective section on the local array
908                      local_2d = local_pf(:,:,layer_xy)
909
910                   ENDIF
911
912#if defined( __parallel )
913                   IF ( netcdf_output  .AND.  netcdf_data_format > 4 )  THEN
914!
915!--                   Parallel output in netCDF4/HDF5 format.
916                      IF ( two_d ) THEN
917                         iis = 1
918                      ELSE
919                         iis = is
920                      ENDIF
921
922#if defined( __netcdf )
923!
924!--                   For parallel output, all cross sections are first stored
925!--                   here on a local array and will be written to the output
926!--                   file afterwards to increase the performance.
927                      DO  i = nxlg, nxrg
928                         DO  j = nysg, nyng
929                            local_2d_sections(i,j,iis) = local_2d(i,j)
930                         ENDDO
931                      ENDDO
932#endif
933                   ELSE
934
935                      IF ( data_output_2d_on_each_pe )  THEN
936!
937!--                      Output of partial arrays on each PE
938#if defined( __netcdf )
939                         IF ( netcdf_output  .AND.  myid == 0 )  THEN
940                            WRITE ( 21 )  time_since_reference_point, &
941                                          do2d_xy_time_count(av), av
942                         ENDIF
943#endif
944                         DO  i = 0, io_blocks-1
945                            IF ( i == io_group )  THEN
946                               WRITE ( 21 )  nxlg, nxrg, nysg, nyng
947                               WRITE ( 21 )  local_2d
948                            ENDIF
949#if defined( __parallel )
950                            CALL MPI_BARRIER( comm2d, ierr )
951#endif
952                         ENDDO
953
954                      ELSE
955!
956!--                      PE0 receives partial arrays from all processors and
957!--                      then outputs them. Here a barrier has to be set,
958!--                      because otherwise "-MPI- FATAL: Remote protocol queue
959!--                      full" may occur.
960                         CALL MPI_BARRIER( comm2d, ierr )
961
962                         ngp = ( nxrg-nxlg+1 ) * ( nyng-nysg+1 )
963                         IF ( myid == 0 )  THEN
964!
965!--                         Local array can be relocated directly.
966                            total_2d(nxlg:nxrg,nysg:nyng) = local_2d
967!
968!--                         Receive data from all other PEs.
969                            DO  n = 1, numprocs-1
970!
971!--                            Receive index limits first, then array.
972!--                            Index limits are received in arbitrary order from
973!--                            the PEs.
974                               CALL MPI_RECV( ind(1), 4, MPI_INTEGER,    &
975                                              MPI_ANY_SOURCE, 0, comm2d, &
976                                              status, ierr )
977                               sender = status(MPI_SOURCE)
978                               DEALLOCATE( local_2d )
979                               ALLOCATE( local_2d(ind(1):ind(2),ind(3):ind(4)) )
980                               CALL MPI_RECV( local_2d(ind(1),ind(3)), ngp,  &
981                                              MPI_REAL, sender, 1, comm2d,   &
982                                              status, ierr )
983                               total_2d(ind(1):ind(2),ind(3):ind(4)) = local_2d
984                            ENDDO
985!
986!--                         Output of the total cross-section.
987                            IF ( iso2d_output )  THEN
988                               WRITE (21)  total_2d(-nbgp:nx+nbgp,-nbgp:ny+nbgp)
989                            ENDIF
990!
991!--                         Relocate the local array for the next loop increment
992                            DEALLOCATE( local_2d )
993                            ALLOCATE( local_2d(nxlg:nxrg,nysg:nyng) )
994
995#if defined( __netcdf )
996                            IF ( netcdf_output )  THEN
997                               IF ( two_d ) THEN
998                                  nc_stat = NF90_PUT_VAR( id_set_xy(av),       &
999                                                          id_var_do2d(av,if),  &
1000                                                      total_2d(0:nx+1,0:ny+1), &
1001                                start = (/ 1, 1, 1, do2d_xy_time_count(av) /), &
1002                                                count = (/ nx+2, ny+2, 1, 1 /) )
1003                               ELSE
1004                                  nc_stat = NF90_PUT_VAR( id_set_xy(av),       &
1005                                                          id_var_do2d(av,if),  &
1006                                                      total_2d(0:nx+1,0:ny+1), &
1007                               start = (/ 1, 1, is, do2d_xy_time_count(av) /), &
1008                                                count = (/ nx+2, ny+2, 1, 1 /) )
1009                               ENDIF
1010                               CALL handle_netcdf_error( 'data_output_2d', 54 )
1011                            ENDIF
1012#endif
1013
1014                         ELSE
1015!
1016!--                         First send the local index limits to PE0
1017                            ind(1) = nxlg; ind(2) = nxrg
1018                            ind(3) = nysg; ind(4) = nyng
1019                            CALL MPI_SEND( ind(1), 4, MPI_INTEGER, 0, 0, &
1020                                           comm2d, ierr )
1021!
1022!--                         Send data to PE0
1023                            CALL MPI_SEND( local_2d(nxlg,nysg), ngp, &
1024                                           MPI_REAL, 0, 1, comm2d, ierr )
1025                         ENDIF
1026!
1027!--                      A barrier has to be set, because otherwise some PEs may
1028!--                      proceed too fast so that PE0 may receive wrong data on
1029!--                      tag 0
1030                         CALL MPI_BARRIER( comm2d, ierr )
1031                      ENDIF
1032
1033                   ENDIF
1034#else
1035                   IF ( iso2d_output )  THEN
1036                      WRITE (21)  local_2d(nxl:nxr+1,nys:nyn+1)
1037                   ENDIF
1038#if defined( __netcdf )
1039                   IF ( netcdf_output )  THEN
1040                      IF ( two_d ) THEN
1041                         nc_stat = NF90_PUT_VAR( id_set_xy(av),                &
1042                                                 id_var_do2d(av,if),           &
1043                                                local_2d(nxl:nxr+1,nys:nyn+1), &
1044                                start = (/ 1, 1, 1, do2d_xy_time_count(av) /), &
1045                                              count = (/ nx+2, ny+2, 1, 1 /) )
1046                      ELSE
1047                         nc_stat = NF90_PUT_VAR( id_set_xy(av),                &
1048                                                 id_var_do2d(av,if),           &
1049                                                local_2d(nxl:nxr+1,nys:nyn+1), &
1050                               start = (/ 1, 1, is, do2d_xy_time_count(av) /), &
1051                                              count = (/ nx+2, ny+2, 1, 1 /) )
1052                      ENDIF
1053                      CALL handle_netcdf_error( 'data_output_2d', 447 )
1054                   ENDIF
1055#endif
1056#endif
1057                   do2d_xy_n = do2d_xy_n + 1
1058!
1059!--                Write LOCAL parameter set for ISO2D.
1060                   IF ( myid == 0  .AND.  iso2d_output )  THEN
1061                      IF ( section(is,s) /= -1 )  THEN
1062                         WRITE ( section_chr, '(''z = '',F7.2,'' m  (GP '',I3, &
1063                                               &'')'')'                        &
1064                               )  level_z(layer_xy), layer_xy
1065                      ELSE
1066                         section_chr = 'averaged along z'
1067                      ENDIF
1068                      IF ( av == 0 )  THEN
1069                         rtext = TRIM( do2d(av,if) ) // '  t = ' //    &
1070                                 TRIM( simulated_time_chr ) // '  ' // &
1071                                 TRIM( section_chr )
1072                      ELSE
1073                         rtext = TRIM( do2d(av,if) ) // '  averaged t = ' // &
1074                                 TRIM( simulated_time_chr ) // '  ' //       &
1075                                 TRIM( section_chr )
1076                      ENDIF
1077                      WRITE (27,LOCAL)
1078                   ENDIF
1079!
1080!--                For 2D-arrays (e.g. u*) only one cross-section is available.
1081!--                Hence exit loop of output levels.
1082                   IF ( two_d )  THEN
1083                      two_d = .FALSE.
1084                      EXIT loop1
1085                   ENDIF
1086
1087                CASE ( 'xz' )
1088!
1089!--                Update the netCDF xz cross section time axis.
1090!--                In case of parallel output, this is only done by PE0
1091!--                to increase the performance.
1092                   IF ( simulated_time /= do2d_xz_last_time(av) )  THEN
1093                      do2d_xz_time_count(av) = do2d_xz_time_count(av) + 1
1094                      do2d_xz_last_time(av)  = simulated_time
1095                      IF ( myid == 0 )  THEN
1096                         IF ( ( .NOT. data_output_2d_on_each_pe  .AND.        &
1097                              netcdf_output )  .OR.  netcdf_data_format > 4 ) &
1098                         THEN
1099#if defined( __netcdf )
1100                            nc_stat = NF90_PUT_VAR( id_set_xz(av),             &
1101                                                    id_var_time_xz(av),        &
1102                                             (/ time_since_reference_point /), &
1103                                         start = (/ do2d_xz_time_count(av) /), &
1104                                                    count = (/ 1 /) )
1105                            CALL handle_netcdf_error( 'data_output_2d', 56 )
1106#endif
1107                         ENDIF
1108                      ENDIF
1109                   ENDIF
1110
1111!
1112!--                If required, carry out averaging along y
1113                   IF ( section(is,s) == -1 )  THEN
1114
1115                      ALLOCATE( local_2d_l(nxlg:nxrg,nzb:nzt+1) )
1116                      local_2d_l = 0.0
1117                      ngp = ( nxrg-nxlg+1 ) * ( nzt-nzb+2 )
1118!
1119!--                   First local averaging on the PE
1120                      DO  k = nzb, nzt+1
1121                         DO  j = nys, nyn
1122                            DO  i = nxlg, nxrg
1123                               local_2d_l(i,k) = local_2d_l(i,k) + &
1124                                                 local_pf(i,j,k)
1125                            ENDDO
1126                         ENDDO
1127                      ENDDO
1128#if defined( __parallel )
1129!
1130!--                   Now do the averaging over all PEs along y
1131                      IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
1132                      CALL MPI_ALLREDUCE( local_2d_l(nxlg,nzb),              &
1133                                          local_2d(nxlg,nzb), ngp, MPI_REAL, &
1134                                          MPI_SUM, comm1dy, ierr )
1135#else
1136                      local_2d = local_2d_l
1137#endif
1138                      local_2d = local_2d / ( ny + 1.0 )
1139
1140                      DEALLOCATE( local_2d_l )
1141
1142                   ELSE
1143!
1144!--                   Just store the respective section on the local array
1145!--                   (but only if it is available on this PE!)
1146                      IF ( section(is,s) >= nys  .AND.  section(is,s) <= nyn ) &
1147                      THEN
1148                         local_2d = local_pf(:,section(is,s),nzb:nzt+1)
1149                      ENDIF
1150
1151                   ENDIF
1152
1153#if defined( __parallel )
1154                   IF ( netcdf_output  .AND.  netcdf_data_format > 4 )  THEN
1155!
1156!--                   Output in netCDF4/HDF5 format.
1157!--                   Output only on those PEs where the respective cross
1158!--                   sections reside. Cross sections averaged along y are
1159!--                   output on the respective first PE along y (myidy=0).
1160                      IF ( ( section(is,s) >= nys  .AND.  &
1161                             section(is,s) <= nyn )  .OR.  &
1162                           ( section(is,s) == -1  .AND.  myidy == 0 ) )  THEN
1163#if defined( __netcdf )
1164!
1165!--                      For parallel output, all cross sections are first
1166!--                      stored here on a local array and will be written to the
1167!--                      output file afterwards to increase the performance.
1168                         DO  i = nxlg, nxrg
1169                            DO  k = nzb, nzt+1
1170                               local_2d_sections_l(i,is,k) = local_2d(i,k)
1171                            ENDDO
1172                         ENDDO
1173#endif
1174                      ENDIF
1175
1176                   ELSE
1177
1178                      IF ( data_output_2d_on_each_pe )  THEN
1179!
1180!--                      Output of partial arrays on each PE. If the cross
1181!--                      section does not reside on the PE, output special
1182!--                      index values.
1183#if defined( __netcdf )
1184                         IF ( netcdf_output  .AND.  myid == 0 )  THEN
1185                            WRITE ( 22 )  time_since_reference_point, &
1186                                          do2d_xz_time_count(av), av
1187                         ENDIF
1188#endif
1189                         DO  i = 0, io_blocks-1
1190                            IF ( i == io_group )  THEN
1191                               IF ( ( section(is,s) >= nys  .AND.   &
1192                                      section(is,s) <= nyn )  .OR.  &
1193                                    ( section(is,s) == -1  .AND.    &
1194                                      nys-1 == -1 ) )               &
1195                               THEN
1196                                  WRITE (22)  nxlg, nxrg, nzb, nzt+1
1197                                  WRITE (22)  local_2d
1198                               ELSE
1199                                  WRITE (22)  -1, -1, -1, -1
1200                               ENDIF
1201                            ENDIF
1202#if defined( __parallel )
1203                            CALL MPI_BARRIER( comm2d, ierr )
1204#endif
1205                         ENDDO
1206
1207                      ELSE
1208!
1209!--                      PE0 receives partial arrays from all processors of the
1210!--                      respective cross section and outputs them. Here a
1211!--                      barrier has to be set, because otherwise
1212!--                      "-MPI- FATAL: Remote protocol queue full" may occur.
1213                         CALL MPI_BARRIER( comm2d, ierr )
1214
1215                         ngp = ( nxrg-nxlg+1 ) * ( nzt-nzb+2 )
1216                         IF ( myid == 0 )  THEN
1217!
1218!--                         Local array can be relocated directly.
1219                            IF ( ( section(is,s) >= nys  .AND.                 &
1220                                   section(is,s) <= nyn )  .OR.                &
1221                                 ( section(is,s) == -1  .AND.  nys-1 == -1 ) ) &
1222                            THEN
1223                               total_2d(nxlg:nxrg,nzb:nzt+1) = local_2d
1224                            ENDIF
1225!
1226!--                         Receive data from all other PEs.
1227                            DO  n = 1, numprocs-1
1228!
1229!--                            Receive index limits first, then array.
1230!--                            Index limits are received in arbitrary order from
1231!--                            the PEs.
1232                               CALL MPI_RECV( ind(1), 4, MPI_INTEGER,     &
1233                                              MPI_ANY_SOURCE, 0, comm2d,  &
1234                                              status, ierr )
1235!
1236!--                            Not all PEs have data for XZ-cross-section.
1237                               IF ( ind(1) /= -9999 )  THEN
1238                                  sender = status(MPI_SOURCE)
1239                                  DEALLOCATE( local_2d )
1240                                  ALLOCATE( local_2d(ind(1):ind(2), &
1241                                                     ind(3):ind(4)) )
1242                                  CALL MPI_RECV( local_2d(ind(1),ind(3)), ngp, &
1243                                                 MPI_REAL, sender, 1, comm2d,  &
1244                                                 status, ierr )
1245                                  total_2d(ind(1):ind(2),ind(3):ind(4)) = &
1246                                                                        local_2d
1247                               ENDIF
1248                            ENDDO
1249!
1250!--                         Output of the total cross-section.
1251                            IF ( iso2d_output )  THEN
1252                               WRITE (22)  total_2d(-nbgp:nx+nbgp,nzb:nzt+1)
1253                            ENDIF
1254!
1255!--                         Relocate the local array for the next loop increment
1256                            DEALLOCATE( local_2d )
1257                            ALLOCATE( local_2d(nxlg:nxrg,nzb:nzt+1) )
1258
1259#if defined( __netcdf )
1260                            IF ( netcdf_output )  THEN
1261                               nc_stat = NF90_PUT_VAR( id_set_xz(av),          &
1262                                                    id_var_do2d(av,if),        &
1263                                                    total_2d(0:nx+1,nzb:nzt+1),&
1264                               start = (/ 1, is, 1, do2d_xz_time_count(av) /), &
1265                                                count = (/ nx+2, 1, nz+2, 1 /) )
1266                               CALL handle_netcdf_error( 'data_output_2d', 58 )
1267                            ENDIF
1268#endif
1269
1270                         ELSE
1271!
1272!--                         If the cross section resides on the PE, send the
1273!--                         local index limits, otherwise send -9999 to PE0.
1274                            IF ( ( section(is,s) >= nys  .AND.                 &
1275                                   section(is,s) <= nyn )  .OR.                &
1276                                 ( section(is,s) == -1  .AND.  nys-1 == -1 ) ) &
1277                            THEN
1278                               ind(1) = nxlg; ind(2) = nxrg
1279                               ind(3) = nzb;   ind(4) = nzt+1
1280                            ELSE
1281                               ind(1) = -9999; ind(2) = -9999
1282                               ind(3) = -9999; ind(4) = -9999
1283                            ENDIF
1284                            CALL MPI_SEND( ind(1), 4, MPI_INTEGER, 0, 0, &
1285                                           comm2d, ierr )
1286!
1287!--                         If applicable, send data to PE0.
1288                            IF ( ind(1) /= -9999 )  THEN
1289                               CALL MPI_SEND( local_2d(nxlg,nzb), ngp, &
1290                                              MPI_REAL, 0, 1, comm2d, ierr )
1291                            ENDIF
1292                         ENDIF
1293!
1294!--                      A barrier has to be set, because otherwise some PEs may
1295!--                      proceed too fast so that PE0 may receive wrong data on
1296!--                      tag 0
1297                         CALL MPI_BARRIER( comm2d, ierr )
1298                      ENDIF
1299
1300                   ENDIF
1301#else
1302                   IF ( iso2d_output )  THEN
1303                      WRITE (22)  local_2d(nxl:nxr+1,nzb:nzt+1)
1304                   ENDIF
1305#if defined( __netcdf )
1306                   IF ( netcdf_output )  THEN
1307                      nc_stat = NF90_PUT_VAR( id_set_xz(av),                   &
1308                                              id_var_do2d(av,if),              &
1309                                              local_2d(nxl:nxr+1,nzb:nzt+1),   &
1310                               start = (/ 1, is, 1, do2d_xz_time_count(av) /), &
1311                                              count = (/ nx+2, 1, nz+2, 1 /) )
1312                      CALL handle_netcdf_error( 'data_output_2d', 451 )
1313                   ENDIF
1314#endif
1315#endif
1316                   do2d_xz_n = do2d_xz_n + 1
1317!
1318!--                Write LOCAL-parameter set for ISO2D.
1319                   IF ( myid == 0  .AND.  iso2d_output )  THEN
1320                      IF ( section(is,s) /= -1 )  THEN
1321                         WRITE ( section_chr, '(''y = '',F8.2,'' m  (GP '',I3, &
1322                                               &'')'')'                        &
1323                               )  section(is,s)*dy, section(is,s)
1324                      ELSE
1325                         section_chr = 'averaged along y'
1326                      ENDIF
1327                      IF ( av == 0 )  THEN
1328                         rtext = TRIM( do2d(av,if) ) // '  t = ' //    &
1329                                 TRIM( simulated_time_chr ) // '  ' // &
1330                                 TRIM( section_chr )
1331                      ELSE
1332                         rtext = TRIM( do2d(av,if) ) // '  averaged t = ' // &
1333                                 TRIM( simulated_time_chr ) // '  ' //       &
1334                                 TRIM( section_chr )
1335                      ENDIF
1336                      WRITE (28,LOCAL)
1337                   ENDIF
1338
1339                CASE ( 'yz' )
1340!
1341!--                Update the netCDF yz cross section time axis.
1342!--                In case of parallel output, this is only done by PE0
1343!--                to increase the performance.
1344                   IF ( simulated_time /= do2d_yz_last_time(av) )  THEN
1345                      do2d_yz_time_count(av) = do2d_yz_time_count(av) + 1
1346                      do2d_yz_last_time(av)  = simulated_time
1347                      IF ( myid == 0 )  THEN
1348                         IF ( ( .NOT. data_output_2d_on_each_pe  .AND.        &
1349                              netcdf_output )  .OR.  netcdf_data_format > 4 ) &
1350                         THEN
1351#if defined( __netcdf )
1352                            nc_stat = NF90_PUT_VAR( id_set_yz(av),             &
1353                                                    id_var_time_yz(av),        &
1354                                             (/ time_since_reference_point /), &
1355                                         start = (/ do2d_yz_time_count(av) /), &
1356                                                    count = (/ 1 /) )
1357                            CALL handle_netcdf_error( 'data_output_2d', 59 )
1358#endif
1359                         ENDIF
1360                      ENDIF
1361                   ENDIF
1362
1363!
1364!--                If required, carry out averaging along x
1365                   IF ( section(is,s) == -1 )  THEN
1366
1367                      ALLOCATE( local_2d_l(nysg:nyng,nzb:nzt+1) )
1368                      local_2d_l = 0.0
1369                      ngp = ( nyng-nysg+1 ) * ( nzt-nzb+2 )
1370!
1371!--                   First local averaging on the PE
1372                      DO  k = nzb, nzt+1
1373                         DO  j = nysg, nyng
1374                            DO  i = nxl, nxr
1375                               local_2d_l(j,k) = local_2d_l(j,k) + &
1376                                                 local_pf(i,j,k)
1377                            ENDDO
1378                         ENDDO
1379                      ENDDO
1380#if defined( __parallel )
1381!
1382!--                   Now do the averaging over all PEs along x
1383                      IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
1384                      CALL MPI_ALLREDUCE( local_2d_l(nysg,nzb),              &
1385                                          local_2d(nysg,nzb), ngp, MPI_REAL, &
1386                                          MPI_SUM, comm1dx, ierr )
1387#else
1388                      local_2d = local_2d_l
1389#endif
1390                      local_2d = local_2d / ( nx + 1.0 )
1391
1392                      DEALLOCATE( local_2d_l )
1393
1394                   ELSE
1395!
1396!--                   Just store the respective section on the local array
1397!--                   (but only if it is available on this PE!)
1398                      IF ( section(is,s) >= nxl  .AND.  section(is,s) <= nxr ) &
1399                      THEN
1400                         local_2d = local_pf(section(is,s),:,nzb:nzt+1)
1401                      ENDIF
1402
1403                   ENDIF
1404
1405#if defined( __parallel )
1406                   IF ( netcdf_output  .AND.  netcdf_data_format > 4 )  THEN
1407!
1408!--                   Output in netCDF4/HDF5 format.
1409!--                   Output only on those PEs where the respective cross
1410!--                   sections reside. Cross sections averaged along x are
1411!--                   output on the respective first PE along x (myidx=0).
1412                      IF ( ( section(is,s) >= nxl  .AND.  &
1413                             section(is,s) <= nxr )  .OR.  &
1414                           ( section(is,s) == -1  .AND.  myidx == 0 ) )  THEN
1415#if defined( __netcdf )
1416!
1417!--                      For parallel output, all cross sections are first
1418!--                      stored here on a local array and will be written to the
1419!--                      output file afterwards to increase the performance.
1420                         DO  j = nysg, nyng
1421                            DO  k = nzb, nzt+1
1422                               local_2d_sections_l(is,j,k) = local_2d(j,k)
1423                            ENDDO
1424                         ENDDO
1425#endif
1426                      ENDIF
1427
1428                   ELSE
1429
1430                      IF ( data_output_2d_on_each_pe )  THEN
1431!
1432!--                      Output of partial arrays on each PE. If the cross
1433!--                      section does not reside on the PE, output special
1434!--                      index values.
1435#if defined( __netcdf )
1436                         IF ( netcdf_output  .AND.  myid == 0 )  THEN
1437                            WRITE ( 23 )  time_since_reference_point, &
1438                                          do2d_yz_time_count(av), av
1439                         ENDIF
1440#endif
1441                         DO  i = 0, io_blocks-1
1442                            IF ( i == io_group )  THEN
1443                               IF ( ( section(is,s) >= nxl  .AND.   &
1444                                      section(is,s) <= nxr )  .OR.  &
1445                                    ( section(is,s) == -1  .AND.    &
1446                                      nxl-1 == -1 ) )               &
1447                               THEN
1448                                  WRITE (23)  nysg, nyng, nzb, nzt+1
1449                                  WRITE (23)  local_2d
1450                               ELSE
1451                                  WRITE (23)  -1, -1, -1, -1
1452                               ENDIF
1453                            ENDIF
1454#if defined( __parallel )
1455                            CALL MPI_BARRIER( comm2d, ierr )
1456#endif
1457                         ENDDO
1458
1459                      ELSE
1460!
1461!--                      PE0 receives partial arrays from all processors of the
1462!--                      respective cross section and outputs them. Here a
1463!--                      barrier has to be set, because otherwise
1464!--                      "-MPI- FATAL: Remote protocol queue full" may occur.
1465                         CALL MPI_BARRIER( comm2d, ierr )
1466
1467                         ngp = ( nyng-nysg+1 ) * ( nzt-nzb+2 )
1468                         IF ( myid == 0 )  THEN
1469!
1470!--                         Local array can be relocated directly.
1471                            IF ( ( section(is,s) >= nxl  .AND.                 &
1472                                   section(is,s) <= nxr )   .OR.               &
1473                                 ( section(is,s) == -1  .AND.  nxl-1 == -1 ) ) &
1474                            THEN
1475                               total_2d(nysg:nyng,nzb:nzt+1) = local_2d
1476                            ENDIF
1477!
1478!--                         Receive data from all other PEs.
1479                            DO  n = 1, numprocs-1
1480!
1481!--                            Receive index limits first, then array.
1482!--                            Index limits are received in arbitrary order from
1483!--                            the PEs.
1484                               CALL MPI_RECV( ind(1), 4, MPI_INTEGER,     &
1485                                              MPI_ANY_SOURCE, 0, comm2d,  &
1486                                              status, ierr )
1487!
1488!--                            Not all PEs have data for YZ-cross-section.
1489                               IF ( ind(1) /= -9999 )  THEN
1490                                  sender = status(MPI_SOURCE)
1491                                  DEALLOCATE( local_2d )
1492                                  ALLOCATE( local_2d(ind(1):ind(2), &
1493                                                     ind(3):ind(4)) )
1494                                  CALL MPI_RECV( local_2d(ind(1),ind(3)), ngp, &
1495                                                 MPI_REAL, sender, 1, comm2d,  &
1496                                                 status, ierr )
1497                                  total_2d(ind(1):ind(2),ind(3):ind(4)) = &
1498                                                                        local_2d
1499                               ENDIF
1500                            ENDDO
1501!
1502!--                         Output of the total cross-section.
1503                            IF ( iso2d_output )  THEN
1504                               WRITE (23)  total_2d(0:ny+1,nzb:nzt+1)
1505                            ENDIF
1506!
1507!--                         Relocate the local array for the next loop increment
1508                            DEALLOCATE( local_2d )
1509                            ALLOCATE( local_2d(nysg:nyng,nzb:nzt+1) )
1510
1511#if defined( __netcdf )
1512                            IF ( netcdf_output )  THEN
1513                               nc_stat = NF90_PUT_VAR( id_set_yz(av),          &
1514                                                    id_var_do2d(av,if),        &
1515                                                    total_2d(0:ny+1,nzb:nzt+1),&
1516                               start = (/ is, 1, 1, do2d_yz_time_count(av) /), &
1517                                                count = (/ 1, ny+2, nz+2, 1 /) )
1518                               CALL handle_netcdf_error( 'data_output_2d', 61 )
1519                            ENDIF
1520#endif
1521
1522                         ELSE
1523!
1524!--                         If the cross section resides on the PE, send the
1525!--                         local index limits, otherwise send -9999 to PE0.
1526                            IF ( ( section(is,s) >= nxl  .AND.                 &
1527                                   section(is,s) <= nxr )  .OR.                &
1528                                 ( section(is,s) == -1  .AND.  nxl-1 == -1 ) ) &
1529                            THEN
1530                               ind(1) = nysg; ind(2) = nyng
1531                               ind(3) = nzb;   ind(4) = nzt+1
1532                            ELSE
1533                               ind(1) = -9999; ind(2) = -9999
1534                               ind(3) = -9999; ind(4) = -9999
1535                            ENDIF
1536                            CALL MPI_SEND( ind(1), 4, MPI_INTEGER, 0, 0, &
1537                                           comm2d, ierr )
1538!
1539!--                         If applicable, send data to PE0.
1540                            IF ( ind(1) /= -9999 )  THEN
1541                               CALL MPI_SEND( local_2d(nysg,nzb), ngp, &
1542                                              MPI_REAL, 0, 1, comm2d, ierr )
1543                            ENDIF
1544                         ENDIF
1545!
1546!--                      A barrier has to be set, because otherwise some PEs may
1547!--                      proceed too fast so that PE0 may receive wrong data on
1548!--                      tag 0
1549                         CALL MPI_BARRIER( comm2d, ierr )
1550                      ENDIF
1551
1552                   ENDIF
1553#else
1554                   IF ( iso2d_output )  THEN
1555                      WRITE (23)  local_2d(nys:nyn+1,nzb:nzt+1)
1556                   ENDIF
1557#if defined( __netcdf )
1558                   IF ( netcdf_output )  THEN
1559                      nc_stat = NF90_PUT_VAR( id_set_yz(av),                   &
1560                                              id_var_do2d(av,if),              &
1561                                              local_2d(nys:nyn+1,nzb:nzt+1),   &
1562                               start = (/ is, 1, 1, do2d_xz_time_count(av) /), &
1563                                              count = (/ 1, ny+2, nz+2, 1 /) )
1564                      CALL handle_netcdf_error( 'data_output_2d', 452 )
1565                   ENDIF
1566#endif
1567#endif
1568                   do2d_yz_n = do2d_yz_n + 1
1569!
1570!--                Write LOCAL-parameter set for ISO2D.
1571                   IF ( myid == 0  .AND.  iso2d_output )  THEN
1572                      IF ( section(is,s) /= -1 )  THEN
1573                         WRITE ( section_chr, '(''x = '',F8.2,'' m  (GP '',I3, &
1574                                               &'')'')'                        &
1575                               )  section(is,s)*dx, section(is,s)
1576                      ELSE
1577                         section_chr = 'averaged along x'
1578                      ENDIF
1579                      IF ( av == 0 )  THEN
1580                         rtext = TRIM( do2d(av,if) ) // '  t = ' //    &
1581                                 TRIM( simulated_time_chr ) // '  ' // &
1582                                 TRIM( section_chr )
1583                      ELSE
1584                         rtext = TRIM( do2d(av,if) ) // '  averaged t = ' // &
1585                                 TRIM( simulated_time_chr ) // '  ' //       &
1586                                 TRIM( section_chr )
1587                      ENDIF
1588                      WRITE (29,LOCAL)
1589                   ENDIF
1590
1591             END SELECT
1592
1593             is = is + 1
1594          ENDDO loop1
1595
1596!
1597!--       For parallel output, all data were collected before on a local array
1598!--       and are written now to the netcdf file. This must be done to increase
1599!--       the performance of the parallel output.
1600#if defined( __netcdf )
1601          IF ( netcdf_output .AND. netcdf_data_format > 4 )  THEN
1602
1603                SELECT CASE ( mode )
1604
1605                   CASE ( 'xy' )
1606                      IF ( two_d ) THEN
1607                         iis = 1
1608                      ELSE
1609                         iis = is-1
1610                      ENDIF
1611!
1612!--                   Do not output redundant ghost point data except for the
1613!--                   boundaries of the total domain.
1614                      IF ( nxr == nx  .AND.  nyn /= ny )  THEN
1615                         nc_stat = NF90_PUT_VAR( id_set_xy(av),                &
1616                                                 id_var_do2d(av,if),           &
1617                                                 local_2d_sections(nxl:nxr+1,  &
1618                                                    nys:nyn,1:ns),             &
1619                                                 start = (/ nxl+1, nys+1, 1,   &
1620                                                    do2d_xy_time_count(av) /), &
1621                                                 count = (/ nxr-nxl+2,         &
1622                                                            nyn-nys+1, ns, 1   &
1623                                                          /) )
1624                      ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
1625                         nc_stat = NF90_PUT_VAR( id_set_xy(av),                &
1626                                                 id_var_do2d(av,if),           &
1627                                                 local_2d_sections(nxl:nxr,    &
1628                                                    nys:nyn+1,1:ns),           &
1629                                                 start = (/ nxl+1, nys+1, 1,   &
1630                                                    do2d_xy_time_count(av) /), &
1631                                                 count = (/ nxr-nxl+1,         &
1632                                                            nyn-nys+2, ns, 1   &
1633                                                          /) )
1634                      ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
1635                         nc_stat = NF90_PUT_VAR( id_set_xy(av),                &
1636                                                 id_var_do2d(av,if),           &
1637                                                 local_2d_sections(nxl:nxr+1,  &
1638                                                    nys:nyn+1,1:ns),           &
1639                                                 start = (/ nxl+1, nys+1, 1,   &
1640                                                    do2d_xy_time_count(av) /), &
1641                                                 count = (/ nxr-nxl+2,         &
1642                                                            nyn-nys+2, ns, 1   &
1643                                                          /) )
1644                      ELSE
1645                         nc_stat = NF90_PUT_VAR( id_set_xy(av),                &
1646                                                 id_var_do2d(av,if),           &
1647                                                 local_2d_sections(nxl:nxr,    &
1648                                                    nys:nyn,1:ns),             &
1649                                                 start = (/ nxl+1, nys+1, 1,   &
1650                                                    do2d_xy_time_count(av) /), &
1651                                                 count = (/ nxr-nxl+1,         &
1652                                                            nyn-nys+1, ns, 1   &
1653                                                          /) )
1654                      ENDIF   
1655
1656                      CALL handle_netcdf_error( 'data_output_2d', 55 ) 
1657
1658                   CASE ( 'xz' )
1659!
1660!--                   First, all PEs get the information of all cross-sections.
1661!--                   Then the data are written to the output file by all PEs
1662!--                   while NF90_COLLECTIVE is set in subroutine
1663!--                   define_netcdf_header. Although redundant information are
1664!--                   written to the output file in that case, the performance
1665!--                   is significantly better compared to the case where only
1666!--                   the first row of PEs in x-direction (myidx = 0) is given
1667!--                   the output while NF90_INDEPENDENT is set.
1668                      IF ( npey /= 1 )  THEN
1669                         
1670#if defined( __parallel )
1671!
1672!--                      Distribute data over all PEs along y
1673                         ngp = ( nxrg-nxlg+1 ) * ( nzt-nzb+2 ) * ns
1674                         IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr )
1675                         CALL MPI_ALLREDUCE( local_2d_sections_l(nxlg,1,nzb),  &
1676                                             local_2d_sections(nxlg,1,nzb),    &
1677                                             ngp, MPI_REAL, MPI_SUM, comm1dy,  &
1678                                             ierr )
1679#else
1680                         local_2d_sections = local_2d_sections_l
1681#endif
1682                      ENDIF
1683!
1684!--                   Do not output redundant ghost point data except for the
1685!--                   boundaries of the total domain.
1686                      IF ( nxr == nx )  THEN
1687                         nc_stat = NF90_PUT_VAR( id_set_xz(av),                &
1688                                             id_var_do2d(av,if),               & 
1689                                             local_2d_sections(nxl:nxr+1,1:ns, &
1690                                                nzb:nzt+1),                    &
1691                                             start = (/ nxl+1, 1, 1,           &
1692                                                do2d_xz_time_count(av) /),     &
1693                                             count = (/ nxr-nxl+2, ns, nzt+2,  &
1694                                                        1 /) )
1695                      ELSE
1696                         nc_stat = NF90_PUT_VAR( id_set_xz(av),                &
1697                                             id_var_do2d(av,if),               &
1698                                             local_2d_sections(nxl:nxr,1:ns,   &
1699                                                nzb:nzt+1),                    &
1700                                             start = (/ nxl+1, 1, 1,           &
1701                                                do2d_xz_time_count(av) /),     &
1702                                             count = (/ nxr-nxl+1, ns, nzt+2,  &
1703                                                1 /) )
1704                      ENDIF
1705
1706                      CALL handle_netcdf_error( 'data_output_2d', 57 )
1707
1708                   CASE ( 'yz' )
1709!
1710!--                   First, all PEs get the information of all cross-sections.
1711!--                   Then the data are written to the output file by all PEs
1712!--                   while NF90_COLLECTIVE is set in subroutine
1713!--                   define_netcdf_header. Although redundant information are
1714!--                   written to the output file in that case, the performance
1715!--                   is significantly better compared to the case where only
1716!--                   the first row of PEs in y-direction (myidy = 0) is given
1717!--                   the output while NF90_INDEPENDENT is set.
1718                      IF ( npex /= 1 )  THEN
1719
1720#if defined( __parallel )
1721!
1722!--                      Distribute data over all PEs along x
1723                         ngp = ( nyng-nysg+1 ) * ( nzt-nzb + 2 ) * ns
1724                         IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr )
1725                         CALL MPI_ALLREDUCE( local_2d_sections_l(1,nysg,nzb),  &
1726                                             local_2d_sections(1,nysg,nzb),    &
1727                                             ngp, MPI_REAL, MPI_SUM, comm1dx,  &
1728                                             ierr )
1729#else
1730                         local_2d_sections = local_2d_sections_l
1731#endif
1732                      ENDIF
1733!
1734!--                   Do not output redundant ghost point data except for the
1735!--                   boundaries of the total domain.
1736                      IF ( nyn == ny )  THEN
1737                         nc_stat = NF90_PUT_VAR( id_set_yz(av),                &
1738                                             id_var_do2d(av,if),               &
1739                                             local_2d_sections(1:ns,           &
1740                                                nys:nyn+1,nzb:nzt+1),          &
1741                                             start = (/ 1, nys+1, 1,           &
1742                                                do2d_yz_time_count(av) /),     &
1743                                             count = (/ ns, nyn-nys+2,         &
1744                                                        nzt+2, 1 /) )
1745                      ELSE
1746                         nc_stat = NF90_PUT_VAR( id_set_yz(av),                &
1747                                             id_var_do2d(av,if),               &
1748                                             local_2d_sections(1:ns,nys:nyn,   &
1749                                                nzb:nzt+1),                    &
1750                                             start = (/ 1, nys+1, 1,           &
1751                                                do2d_yz_time_count(av) /),     &
1752                                             count = (/ ns, nyn-nys+1,         &
1753                                                        nzt+2, 1 /) )
1754                      ENDIF
1755
1756                      CALL handle_netcdf_error( 'data_output_2d', 60 )
1757
1758                   CASE DEFAULT
1759                      message_string = 'unknown cross-section: ' // TRIM( mode )
1760                      CALL message( 'data_output_2d', 'PA0180', 1, 2, 0, 6, 0 )
1761
1762                END SELECT                     
1763
1764          ENDIF
1765
1766       ENDIF
1767
1768       if = if + 1
1769       l = MAX( 2, LEN_TRIM( do2d(av,if) ) )
1770       do2d_mode = do2d(av,if)(l-1:l)
1771
1772    ENDDO
1773
1774!
1775!-- Deallocate temporary arrays.
1776    IF ( ALLOCATED( level_z ) )  DEALLOCATE( level_z )
1777    IF ( netcdf_data_format > 4 )  THEN
1778       DEALLOCATE( local_pf, local_2d, local_2d_sections )
1779       IF( mode == 'xz' .OR. mode == 'yz' ) DEALLOCATE( local_2d_sections_l )
1780    ENDIF
1781#if defined( __parallel )
1782    IF ( .NOT.  data_output_2d_on_each_pe  .AND.  myid == 0 )  THEN
1783       DEALLOCATE( total_2d )
1784    ENDIF
1785#endif
1786
1787!
1788!-- Close plot output file.
1789    file_id = 20 + s
1790
1791    IF ( data_output_2d_on_each_pe )  THEN
1792       DO  i = 0, io_blocks-1
1793          IF ( i == io_group )  THEN
1794             CALL close_file( file_id )
1795          ENDIF
1796#if defined( __parallel )
1797          CALL MPI_BARRIER( comm2d, ierr )
1798#endif
1799       ENDDO
1800    ELSE
1801       IF ( myid == 0 )  CALL close_file( file_id )
1802    ENDIF
1803
1804    CALL cpu_log (log_point(3),'data_output_2d','stop','nobarrier')
1805
1806 END SUBROUTINE data_output_2d
Note: See TracBrowser for help on using the repository browser.