source: palm/trunk/SOURCE/netcdf_interface_mod.f90 @ 3655

Last change on this file since 3655 was 3655, checked in by knoop, 6 years ago

Bugfix: made "unit" and "found" intend INOUT in module interface subroutines + automatic copyright update

  • Property svn:keywords set to Id
File size: 323.0 KB
Line 
1!> @file netcdf_interface_mod.f90
2!------------------------------------------------------------------------------!
3! This file is part of the PALM model system.
4!
5! PALM is free software: you can redistribute it and/or modify it under the
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! 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-2019 Leibniz Universitaet Hannover
18!------------------------------------------------------------------------------!
19!
20! Current revisions:
21! ------------------
22!
23!
24! Former revisions:
25! -----------------
26! $Id: netcdf_interface_mod.f90 3655 2019-01-07 16:51:22Z knoop $
27! Move the control parameter "salsa" from salsa_mod to control_parameters
28! (M. Kurppa)
29!
30! 3582 2018-11-29 19:16:36Z suehring
31! dom_dwd_user, Schrempf:
32! Remove uv exposure model code, this is now part of biometeorology_mod
33!
34! 3529 2018-11-15 21:03:15Z gronemeier
35! - set time units
36! - add additional global attributes,
37! - add additinal variable attributes
38! - move definition of UTM and geographic coordinates into subroutine
39! - change fill_value
40!
41! 3525 2018-11-14 16:06:14Z kanani
42! Changes related to clean-up of biometeorology (dom_dwd_user)
43!
44! 3485 2018-11-03 17:09:40Z gronemeier
45! Write geographic coordinates as global attributes to file.
46!
47! 3467 2018-10-30 19:05:21Z suehring
48! - Salsa implemented
49! - Bugfix convert_utm_to...
50!
51! 3464 2018-10-30 18:08:55Z kanani
52! - Add variable crs to output files
53! - Add long_name to UTM coordinates
54! - Add latitude/longitude coordinates. For 3d and xy output, lon and lat are
55!   only written if parallel output is used.
56!
57! 3459 2018-10-30 15:04:11Z gronemeier
58! Adjustment of biometeorology calls
59!
60! 3435 2018-10-26 18:25:44Z gronemeier
61! Bugfix: corrected order of calls to define_netcdf_grid for masked output
62! Add vertical dimensions to masked output in case of terrain-following output
63!
64! 3421 2018-10-24 18:39:32Z gronemeier
65! Bugfix: move ocean output variables to ocean_mod
66! Renamed output variables
67! Add UTM coordinates to mask, 3d, xy, xz, yz output
68!
69! 3337 2018-10-12 15:17:09Z kanani
70! (from branch resler)
71! Add biometeorology
72!
73! 3294 2018-10-01 02:37:10Z raasch
74! changes concerning modularization of ocean option
75!
76! 3274 2018-09-24 15:42:55Z knoop
77! Modularization of all bulk cloud physics code components
78!
79! 3241 2018-09-12 15:02:00Z raasch
80! unused variables removed
81!
82! 3235 2018-09-07 14:06:15Z sward
83! Changed MAS output dimension id_dim_agtnum to be of defined size and no longer
84! unlimited. Also changed some MAS output variables to be of type float
85!
86! 3198 2018-08-15 09:23:10Z sward
87! Redefined MAS limited time dimension to fit usage of multi_agent_system_end
88!
89! 3187 2018-07-31 10:32:34Z sward
90! Changed agent output to precision NF90_DOUBLE
91!
92! 3165 2018-07-24 13:12:42Z sward
93! Added agent ID output
94!
95! 3159 2018-07-20 11:20:01Z sward
96! Added multi agent system
97!
98! 3049 2018-05-29 13:52:36Z Giersch
99! Error messages revised
100!
101! 3045 2018-05-28 07:55:41Z Giersch
102! Error messages revised, code adjusted to PALMs coding standards, CASE pt_ext
103! pt_new disabled, comment revised
104!
105! 3004 2018-04-27 12:33:25Z Giersch
106! .NOT. found in if-query added to account for variables found in tcm
107!
108! 2964 2018-04-12 16:04:03Z Giersch
109! Calculation of fixed number of output time levels for parallel netcdf output
110! has been moved completely to check_parameters
111!
112! 2932 2018-03-26 09:39:22Z maronga
113! Renamed inipar to initialization_parameters.
114!
115! 2817 2018-02-19 16:32:21Z knoop
116! Preliminary gust module interface implemented
117!
118! 2769 2018-01-25 09:22:24Z raasch
119! bugfix for calculating number of required output time levels in case of output
120! at the beginning of a restart run
121!
122! 2766 2018-01-22 17:17:47Z kanani
123! Removed preprocessor directive __chem
124!
125! 2746 2018-01-15 12:06:04Z suehring
126! Move flag plant canopy to modules
127!
128! 2718 2018-01-02 08:49:38Z maronga
129! Corrected "Former revisions" section
130!
131! 2696 2017-12-14 17:12:51Z kanani
132! Change in file header (GPL part)
133! Implementation of uv exposure model (FK)
134! Implemented checks for turbulence_closure_mod (TG)
135! Implementation of chemistry module (FK)
136! Bugfix in setting netcdf grids for LSM variables
137! Enable setting of _FillValue attribute in output files (MS)
138!
139! 2512 2017-10-04 08:26:59Z raasch
140! upper bounds of cross section and 3d output changed from nx+1,ny+1 to nx,ny
141! no output of ghost layer data any more
142!
143! 2302 2017-07-03 14:07:20Z suehring
144! Reading of 3D topography using NetCDF data type NC_BYTE
145!
146! 2292 2017-06-20 09:51:42Z schwenkel
147! Implementation of new microphysic scheme: cloud_scheme = 'morrison'
148! includes two more prognostic equations for cloud drop concentration (nc) 
149! and cloud water content (qc).
150!
151! 2270 2017-06-09 12:18:47Z maronga
152! Removed 2 timeseries (shf_eb + qsws_eb). Removed _eb suffixes
153!
154! 2265 2017-06-08 16:58:28Z schwenkel
155! Unused variables removed.
156!
157! 2239 2017-06-01 12:04:51Z suehring
158! Bugfix xy-output of land-surface variables
159!
160! 2233 2017-05-30 18:08:54Z suehring
161!
162! 2232 2017-05-30 17:47:52Z suehring
163! Adjustments to new topography and surface concept
164!
165! Topograpyh height arrays (zu_s_inner, zw_w_inner) are defined locally, output
166! only if parallel netcdf.
167!
168! Build interface for topography input:
169! - open file in read-only mode
170! - read global attributes
171! - read variables
172!
173! Bugfix in xy output (land-surface case)
174!
175! 2209 2017-04-19 09:34:46Z kanani
176! Added support for plant canopy model output
177!
178! 2189 2017-03-21 09:29:52Z raasch
179! bugfix: rho renamed rho_ocean for the cross section output
180!
181! 2109 2017-01-10 12:18:08Z raasch
182! bugfix: length of character string netcdf_var_name extended to avoid problems
183!         which appeared in restart runs due to truncation
184!
185! 2040 2016-10-26 16:58:09Z gronemeier
186! Increased number of possible statistic_regions to 99
187!
188! 2037 2016-10-26 11:15:40Z knoop
189! Anelastic approximation implemented
190!
191! 2031 2016-10-21 15:11:58Z knoop
192! renamed variable rho to rho_ocean
193!
194! 2011 2016-09-19 17:29:57Z kanani
195! Flag urban_surface is now defined in module control_parameters,
196! changed prefix for urban surface model output to "usm_",
197! introduced control parameter varnamelength for LEN of trimvar.
198!
199! 2007 2016-08-24 15:47:17Z kanani
200! Added support for new urban surface model (temporary modifications of
201! SELECT CASE ( ) necessary, see variable trimvar),
202! increased DIMENSION of do2d_unit, do3d_unit, id_var_do2d, id_var_do3d,
203! increased LEN of char_cross_profiles, var_list, var_list_old
204!
205! 2000 2016-08-20 18:09:15Z knoop
206! Forced header and separation lines into 80 columns
207!
208! 1990 2016-08-12 09:54:36Z gronemeier
209! Bugfix: variable list was not written for time series output
210!
211! 1980 2016-07-29 15:51:57Z suehring
212! Bugfix, in order to steer user-defined output, setting flag found explicitly
213! to .F.
214!
215! 1976 2016-07-27 13:28:04Z maronga
216! Removed remaining 2D land surface quantities. Definition of radiation
217! quantities is now done directly in the respective module
218!
219! 1972 2016-07-26 07:52:02Z maronga
220! Bugfix: wrong units for lsm quantities.
221! Definition of grids for land surface quantities is now done directly in the
222! respective module.
223!
224! 1960 2016-07-12 16:34:24Z suehring
225! Additional labels and units for timeseries output of passive scalar-related
226! quantities
227!
228! 1957 2016-07-07 10:43:48Z suehring
229! flight module added
230!
231! 1850 2016-04-08 13:29:27Z maronga
232! Module renamed
233!
234!
235! 1833 2016-04-07 14:23:03Z raasch
236! spectrum renamed spectra_mod
237!
238! 1786 2016-03-08 05:49:27Z raasch
239! Bugfix: id_var_time_sp made public
240!
241! 1783 2016-03-06 18:36:17Z raasch
242! netcdf interface has been modularized, former file netcdf renamed to
243! netcdf_interface, creation of netcdf-dimensions and -variables moved to
244! specific new subroutines create_netcdf_dim and create_netcdf_var,
245! compression (deflation) of variables implemented,
246! ibmy special cpp directive removed
247!
248! 1745 2016-02-05 13:06:51Z gronemeier
249! Bugfix: recalculating ntdim_3d, ntdim_2d_xy/xz/yz when checking the
250!         extensibility of an existing file (only when using parallel NetCDF).
251!
252! 1691 2015-10-26 16:17:44Z maronga
253! Added output of radiative heating rates for RRTMG. Corrected output of
254! radiative fluxes
255!
256! 1682 2015-10-07 23:56:08Z knoop
257! Code annotations made doxygen readable
258!
259! 1596 2015-05-21 09:34:28Z gronemeier
260! Bugfix in masked data output. Read 'zu_3d' when trying to extend masked data
261!
262! 1551 2015-03-03 14:18:16Z maronga
263! Added support for land surface model and radiation model output. In the course
264! of this action a new vertical grid zs (soil) was introduced.
265!
266! 1353 2014-04-08 15:21:23Z heinze
267! REAL constants provided with KIND-attribute
268!
269! 1322 2014-03-20 16:38:49Z raasch
270! Forgotten ONLY-attribute added to USE-statements
271!
272! 1320 2014-03-20 08:40:49Z raasch
273! ONLY-attribute added to USE-statements,
274! kind-parameters added to all INTEGER and REAL declaration statements,
275! kinds are defined in new module kinds,
276! revision history before 2012 removed,
277! comment fields (!:) to be used for variable explanations added to
278! all variable declaration statements
279!
280! 1308 2014-03-13 14:58:42Z fricke
281! +ntime_count, oldmode
282! Adjust NF90_CREATE and NF90_OPEN statement for parallel output
283! To increase the performance for parallel output, the following is done:
284! - Limit time dimension
285! - Values of axis data are only written by PE0
286! - No fill is set for all variables
287! Check the number of output time levels for restart jobs
288!
289! 1206 2013-07-18 12:49:16Z witha
290! Bugfix: typo in preprocessor directive in subroutine open_write_netcdf_file
291!
292! 1092 2013-02-02 11:24:22Z raasch
293! unused variables removed
294!
295! 1053 2012-11-13 17:11:03Z hoffmann
296! +qr, nr, prr
297!
298! 1036 2012-10-22 13:43:42Z raasch
299! code put under GPL (PALM 3.9)
300!
301! 1031 2012-10-19 14:35:30Z raasch
302! netCDF4 without parallel file support implemented, new routines
303! create_netcdf_file and open_write_netcdf_file at end
304!
305! 992 2012-09-05 15:08:26Z hoffmann
306! Removal of the informative messages PA0352 and PA0353.
307
308! 983 2012-08-21 14:17:57Z hoffmann
309! Bugfix in cross_profiles.
310!
311! 964 2012-07-26 09:14:24Z raasch
312! rev 951 and 959 reformatted
313!
314! 959 2012-07-24 13:13:41Z hoffmann
315! Bugfix in cross_profiles. It is not allowed to arrange more than 100
316! profiles with cross_profiles.
317!
318! 951 2012-07-19 14:22:52Z hoffmann
319! cross_profiles, profile_rows, profile_columns are written to netCDF header
320!
321! Revision 1.1  2005/05/18 15:37:16  raasch
322! Initial revision
323!
324!
325! Description:
326! ------------
327!> In case of extend = .FALSE.:
328!> Define all necessary dimensions, axes and variables for the different
329!> netCDF datasets. This subroutine is called from check_open after a new
330!> dataset is created. It leaves the open netCDF files ready to write.
331!>
332!> In case of extend = .TRUE.:
333!> Find out if dimensions and variables of an existing file match the values
334!> of the actual run. If so, get all necessary information (ids, etc.) from
335!> this file.
336!>
337!> Parameter av can assume values 0 (non-averaged data) and 1 (time averaged
338!> data)
339!>
340!> @todo calculation of output time levels for parallel NetCDF still does not
341!>       cover every exception (change of dt_do, end_time in restart)
342!> @todo timeseries and profile output still needs to be rewritten to allow
343!>       modularization
344!> @todo output 2d UTM coordinates without global arrays
345!> @todo output longitude/latitude also with non-parallel output (3d and xy)
346!------------------------------------------------------------------------------!
347 MODULE netcdf_interface
348
349    USE control_parameters,                                                    &
350        ONLY:  biometeorology, fl_max,                                         &
351               max_masks, multi_agent_system_end,                              &
352               multi_agent_system_start, var_fl_max, varnamelength
353    USE kinds
354#if defined( __netcdf )
355    USE NETCDF
356#endif
357    USE mas_global_attributes,                                                 &
358        ONLY:  dim_size_agtnum
359
360    USE netcdf_data_input_mod,                                                 &
361        ONLY: coord_ref_sys, init_model
362
363    PRIVATE
364
365    CHARACTER (LEN=16), DIMENSION(13) ::  agt_var_names =                      &
366          (/ 'ag_id           ', 'ag_x            ', 'ag_y            ',       &
367             'ag_wind         ', 'ag_temp         ', 'ag_group        ',       &
368             'PM10            ', 'PM25            ', 'ag_iPT          ',       &
369             'ag_uv           ', 'not_used        ', 'not_used        ',       &
370             'not_used        ' /)
371
372    CHARACTER (LEN=16), DIMENSION(13) ::  agt_var_units = &
373          (/ 'dim_less        ', 'meters          ', 'meters          ',       &
374             'm/s             ', 'K               ', 'dim_less        ',       &
375             'tbd             ', 'tbd             ', 'tbd             ',       &
376             'tbd             ', 'not_used        ', 'not_used        ',       &
377             'not_used        ' /)
378
379    INTEGER(iwp), PARAMETER ::  dopr_norm_num = 7, dopts_num = 29, dots_max = 100
380
381    CHARACTER (LEN=7), DIMENSION(dopr_norm_num) ::  dopr_norm_names =          &
382         (/ 'wtheta0', 'ws2    ', 'tsw2   ', 'ws3    ', 'ws2tsw ', 'wstsw2 ',  &
383            'z_i    ' /)
384
385    CHARACTER (LEN=7), DIMENSION(dopr_norm_num) ::  dopr_norm_longnames =      &
386         (/ 'wtheta0', 'w*2    ', 't*w2   ', 'w*3    ', 'w*2t*w ', 'w*t*w2 ',  &
387            'z_i    ' /)
388
389    CHARACTER (LEN=7), DIMENSION(dopts_num) :: dopts_label =                   &
390          (/ 'tnpt   ', 'x_     ', 'y_     ', 'z_     ', 'z_abs  ', 'u      ', &
391             'v      ', 'w      ', 'u"     ', 'v"     ', 'w"     ', 'npt_up ', &
392             'w_up   ', 'w_down ', 'radius ', 'r_min  ', 'r_max  ', 'npt_max', &
393             'npt_min', 'x*2    ', 'y*2    ', 'z*2    ', 'u*2    ', 'v*2    ', &
394             'w*2    ', 'u"2    ', 'v"2    ', 'w"2    ', 'npt*2  ' /)
395
396    CHARACTER (LEN=7), DIMENSION(dopts_num) :: dopts_unit =                    &
397          (/ 'number ', 'm      ', 'm      ', 'm      ', 'm      ', 'm/s    ', &
398             'm/s    ', 'm/s    ', 'm/s    ', 'm/s    ', 'm/s    ', 'number ', &
399             'm/s    ', 'm/s    ', 'm      ', 'm      ', 'm      ', 'number ', &
400             'number ', 'm2     ', 'm2     ', 'm2     ', 'm2/s2  ', 'm2/s2  ', &
401             'm2/s2  ', 'm2/s2  ', 'm2/s2  ', 'm2/s2  ', 'number2' /)
402
403    INTEGER(iwp) ::  dots_num  = 25  !< number of timeseries defined by default
404    INTEGER(iwp) ::  dots_soil = 26  !< starting index for soil-timeseries
405    INTEGER(iwp) ::  dots_rad  = 32  !< starting index for radiation-timeseries
406
407    CHARACTER (LEN=13), DIMENSION(dots_max) :: dots_label =                    &
408          (/ 'E            ', 'E*           ', 'dt           ',                &
409             'us*          ', 'th*          ', 'umax         ',                &
410             'vmax         ', 'wmax         ', 'div_new      ',                &
411             'div_old      ', 'zi_wtheta    ', 'zi_theta     ',                &
412             'w*           ', 'w"theta"0    ', 'w"theta"     ',                &
413             'wtheta       ', 'theta(0)     ', 'theta(z_mo)  ',                &
414             'w"u"0        ', 'w"v"0        ', 'w"q"0        ',                &
415             'ol           ', 'q*           ', 'w"s"         ',                &
416             's*           ', 'ghf          ', 'qsws_liq     ',                &
417             'qsws_soil    ', 'qsws_veg     ', 'r_a          ',                &
418             'r_s          ',                                                  &
419             'rad_net      ', 'rad_lw_in    ', 'rad_lw_out   ',                &
420             'rad_sw_in    ', 'rad_sw_out   ', 'rrtm_aldif   ',                &
421             'rrtm_aldir   ', 'rrtm_asdif   ', 'rrtm_asdir   ',                &                                               
422             ( 'unknown      ', i9 = 1, dots_max-40 ) /)
423
424    CHARACTER (LEN=13), DIMENSION(dots_max) :: dots_unit =                     &
425          (/ 'm2/s2        ', 'm2/s2        ', 's            ',                &
426             'm/s          ', 'K            ', 'm/s          ',                &
427             'm/s          ', 'm/s          ', 's-1          ',                &
428             's-1          ', 'm            ', 'm            ',                &
429             'm/s          ', 'K m/s        ', 'K m/s        ',                &
430             'K m/s        ', 'K            ', 'K            ',                &
431             'm2/s2        ', 'm2/s2        ', 'kg m/s       ',                &
432             'm            ', 'kg/kg        ', 'kg m/(kg s)  ',                &
433             'kg/kg        ', 'W/m2         ', 'W/m2         ',                &
434             'W/m2         ', 'W/m2         ', 's/m          ',                &
435             's/m          ',                                                  &
436             'W/m2         ', 'W/m2         ', 'W/m2         ',                &
437             'W/m2         ', 'W/m2         ', '             ',                &
438             '             ', '             ', '             ',                &
439             ( 'unknown      ', i9 = 1, dots_max-40 ) /)
440
441    CHARACTER (LEN=16) :: heatflux_output_unit     !< unit for heatflux output
442    CHARACTER (LEN=16) :: waterflux_output_unit    !< unit for waterflux output
443    CHARACTER (LEN=16) :: momentumflux_output_unit !< unit for momentumflux output
444
445    CHARACTER (LEN=9), DIMENSION(300) ::  dopr_unit = 'unknown'
446
447    CHARACTER (LEN=7), DIMENSION(0:1,500) ::  do2d_unit, do3d_unit
448
449!    CHARACTER (LEN=16), DIMENSION(25) ::  prt_var_names = &
450!          (/ 'pt_age          ', 'pt_dvrp_size    ', 'pt_origin_x     ', &
451!             'pt_origin_y     ', 'pt_origin_z     ', 'pt_radius       ', &
452!             'pt_speed_x      ', 'pt_speed_y      ', 'pt_speed_z      ', &
453!             'pt_weight_factor', 'pt_x            ', 'pt_y            ', &
454!             'pt_z            ', 'pt_color        ', 'pt_group        ', &
455!             'pt_tailpoints   ', 'pt_tail_id      ', 'pt_density_ratio', &
456!             'pt_exp_arg      ', 'pt_exp_term     ', 'not_used        ', &
457!             'not_used        ', 'not_used        ', 'not_used        ', &
458!             'not_used        ' /)
459
460!    CHARACTER (LEN=16), DIMENSION(25) ::  prt_var_units = &
461!          (/ 'seconds         ', 'meters          ', 'meters          ', &
462!             'meters          ', 'meters          ', 'meters          ', &
463!             'm/s             ', 'm/s             ', 'm/s             ', &
464!             'factor          ', 'meters          ', 'meters          ', &
465!             'meters          ', 'none            ', 'none            ', &
466!             'none            ', 'none            ', 'ratio           ', &
467!             'none            ', 'none            ', 'not_used        ', &
468!             'not_used        ', 'not_used        ', 'not_used        ', &
469!             'not_used        ' /)
470
471    CHARACTER(LEN=20), DIMENSION(11) ::  netcdf_precision = ' '
472    CHARACTER(LEN=40) ::  netcdf_data_format_string
473
474    INTEGER(iwp) ::  id_dim_agtnum, id_dim_time_agt,                           &
475                     id_dim_time_fl, id_dim_time_pr,                           &
476                     id_dim_time_pts, id_dim_time_sp, id_dim_time_ts,          &
477                     id_dim_x_sp, id_dim_y_sp, id_dim_zu_sp, id_dim_zw_sp,     &
478                     id_set_agt, id_set_fl, id_set_pr, id_set_prt, id_set_pts, &
479                     id_set_sp, id_set_ts, id_var_agtnum, id_var_time_agt,     &
480                     id_var_time_fl, id_var_rnoa_agt, id_var_time_pr,          &
481                     id_var_time_pts, id_var_time_sp, id_var_time_ts,          &
482                     id_var_x_sp, id_var_y_sp, id_var_zu_sp, id_var_zw_sp,     &
483                     nc_stat
484
485
486    INTEGER(iwp), DIMENSION(0:1) ::  id_dim_time_xy, id_dim_time_xz, &
487                    id_dim_time_yz, id_dim_time_3d, id_dim_x_xy, id_dim_xu_xy, &
488                    id_dim_x_xz, id_dim_xu_xz, id_dim_x_yz, id_dim_xu_yz, &
489                    id_dim_x_3d, id_dim_xu_3d, id_dim_y_xy, id_dim_yv_xy, &
490                    id_dim_y_xz, id_dim_yv_xz, id_dim_y_yz, id_dim_yv_yz, &
491                    id_dim_y_3d, id_dim_yv_3d, id_dim_zs_xy, id_dim_zs_xz, &
492                    id_dim_zs_yz, id_dim_zs_3d, id_dim_zu_xy, id_dim_zu1_xy, &
493                    id_dim_zu_xz, id_dim_zu_yz, id_dim_zu_3d, id_dim_zw_xy, &
494                    id_dim_zw_xz, id_dim_zw_yz, id_dim_zw_3d, id_set_xy, &
495                    id_set_xz, id_set_yz, id_set_3d, id_var_ind_x_yz, &
496                    id_var_ind_y_xz, id_var_ind_z_xy, id_var_time_xy, &
497                    id_var_time_xz, id_var_time_yz, id_var_time_3d, id_var_x_xy, &
498                    id_var_xu_xy, id_var_x_xz, id_var_xu_xz, id_var_x_yz, &
499                    id_var_xu_yz, id_var_x_3d, id_var_xu_3d, id_var_y_xy, &
500                    id_var_yv_xy, id_var_y_xz, id_var_yv_xz, id_var_y_yz, &
501                    id_var_yv_yz, id_var_y_3d, id_var_yv_3d, id_var_zs_xy, &
502                    id_var_zs_xz, id_var_zs_yz, id_var_zs_3d, id_var_zusi_xy, &
503                    id_var_zusi_3d, id_var_zu_xy, id_var_zu1_xy, id_var_zu_xz, &
504                    id_var_zu_yz, id_var_zu_3d, id_var_zwwi_xy, id_var_zwwi_3d, &
505                    id_var_zw_xy, id_var_zw_xz, id_var_zw_yz, id_var_zw_3d
506
507    INTEGER(iwp), DIMENSION(0:1,0:2) ::  id_var_eutm_3d, id_var_nutm_3d, &
508                                         id_var_eutm_xy, id_var_nutm_xy, &
509                                         id_var_eutm_xz, id_var_nutm_xz, &
510                                         id_var_eutm_yz, id_var_nutm_yz
511
512    INTEGER(iwp), DIMENSION(0:1,0:2) ::  id_var_lat_3d, id_var_lon_3d, &
513                                         id_var_lat_xy, id_var_lon_xy, &
514                                         id_var_lat_xz, id_var_lon_xz, &
515                                         id_var_lat_yz, id_var_lon_yz
516
517    INTEGER ::  netcdf_data_format = 2  !< NetCDF3 64bit offset format
518    INTEGER ::  netcdf_deflate = 0      !< NetCDF compression, default: no
519                                        !< compression
520
521    INTEGER(iwp)                 ::  dofl_time_count
522    INTEGER(iwp), DIMENSION(10)  ::  id_var_dospx, id_var_dospy
523    INTEGER(iwp), DIMENSION(20)  ::  id_var_agt
524!    INTEGER(iwp), DIMENSION(20)  ::  id_var_prt
525    INTEGER(iwp), DIMENSION(11)  ::  nc_precision
526    INTEGER(iwp), DIMENSION(dopr_norm_num) ::  id_var_norm_dopr
527   
528    INTEGER(iwp), DIMENSION(fl_max) ::  id_dim_x_fl, id_dim_y_fl, id_dim_z_fl
529    INTEGER(iwp), DIMENSION(fl_max) ::  id_var_x_fl, id_var_y_fl, id_var_z_fl
530   
531    CHARACTER (LEN=20), DIMENSION(fl_max*var_fl_max) :: dofl_label
532    CHARACTER (LEN=20), DIMENSION(fl_max*var_fl_max) :: dofl_unit 
533    CHARACTER (LEN=20), DIMENSION(fl_max) :: dofl_dim_label_x
534    CHARACTER (LEN=20), DIMENSION(fl_max) :: dofl_dim_label_y
535    CHARACTER (LEN=20), DIMENSION(fl_max) :: dofl_dim_label_z
536
537    INTEGER(iwp), DIMENSION(fl_max*var_fl_max) :: id_var_dofl   
538
539    INTEGER(iwp), DIMENSION(dopts_num,0:10) ::  id_var_dopts
540    INTEGER(iwp), DIMENSION(0:1,500)        ::  id_var_do2d, id_var_do3d
541    INTEGER(iwp), DIMENSION(100,0:99)       ::  id_dim_z_pr, id_var_dopr, &
542                                                id_var_z_pr
543    INTEGER(iwp), DIMENSION(dots_max,0:99)  ::  id_var_dots
544
545!
546!-- Masked output
547    CHARACTER (LEN=7), DIMENSION(max_masks,0:1,100) ::  domask_unit
548
549    LOGICAL ::  output_for_t0 = .FALSE.
550
551    INTEGER(iwp), DIMENSION(1:max_masks,0:1) ::  id_dim_time_mask, id_dim_x_mask, &
552                   id_dim_xu_mask, id_dim_y_mask, id_dim_yv_mask, id_dim_zs_mask, &
553                   id_dim_zu_mask, id_dim_zw_mask, &
554                   id_set_mask, &
555                   id_var_time_mask, id_var_x_mask, id_var_xu_mask, &
556                   id_var_y_mask, id_var_yv_mask, id_var_zs_mask, &
557                   id_var_zu_mask, id_var_zw_mask, &
558                   id_var_zusi_mask, id_var_zwwi_mask
559
560    INTEGER(iwp), DIMENSION(1:max_masks,0:1,0:2) ::  id_var_eutm_mask, &
561                                                     id_var_nutm_mask
562
563    INTEGER(iwp), DIMENSION(1:max_masks,0:1,0:2) ::  id_var_lat_mask, &
564                                                     id_var_lon_mask
565
566    INTEGER(iwp), DIMENSION(1:max_masks,0:1,100) ::  id_var_domask
567
568    REAL(wp) ::  fill_value = -9999.0_wp    !< value for the _FillValue attribute
569
570
571    PUBLIC  dofl_dim_label_x, dofl_dim_label_y, dofl_dim_label_z, dofl_label,  &
572            dofl_time_count, dofl_unit, domask_unit, dopr_unit, dopts_num,     &
573            dots_label, dots_max, dots_num, dots_rad, dots_soil, dots_unit,    &
574            do2d_unit, do3d_unit, fill_value, id_set_agt, id_set_fl,           &
575            id_set_mask, id_set_pr, id_set_prt, id_set_pts, id_set_sp,         &
576            id_set_ts, id_set_xy, id_set_xz, id_set_yz, id_set_3d, id_var_agt, &
577            id_var_domask, id_var_dofl, id_var_dopr, id_var_dopts,             &
578            id_var_dospx, id_var_dospy, id_var_dots, id_var_do2d, id_var_do3d, &
579            id_var_norm_dopr, id_var_time_agt, id_var_time_fl,                 &
580            id_var_time_mask, id_var_time_pr, id_var_rnoa_agt, id_var_time_pts,&
581            id_var_time_sp, id_var_time_ts,                                    &
582            id_var_time_xy, id_var_time_xz, id_var_time_yz, id_var_time_3d,    &
583            id_var_x_fl, id_var_y_fl, id_var_z_fl,  nc_stat,                   &
584            netcdf_data_format, netcdf_data_format_string, netcdf_deflate,     &
585            netcdf_precision, output_for_t0, heatflux_output_unit,             &
586            waterflux_output_unit, momentumflux_output_unit
587
588    SAVE
589
590    INTERFACE netcdf_create_dim
591       MODULE PROCEDURE netcdf_create_dim
592    END INTERFACE netcdf_create_dim
593
594    INTERFACE netcdf_create_file
595       MODULE PROCEDURE netcdf_create_file
596    END INTERFACE netcdf_create_file
597
598    INTERFACE netcdf_create_var
599       MODULE PROCEDURE netcdf_create_var
600    END INTERFACE netcdf_create_var
601
602    INTERFACE netcdf_create_att
603       MODULE PROCEDURE netcdf_create_att_string
604    END INTERFACE netcdf_create_att
605
606    INTERFACE netcdf_define_header
607       MODULE PROCEDURE netcdf_define_header
608    END INTERFACE netcdf_define_header
609
610    INTERFACE netcdf_handle_error
611       MODULE PROCEDURE netcdf_handle_error
612    END INTERFACE netcdf_handle_error
613
614    INTERFACE netcdf_open_write_file
615       MODULE PROCEDURE netcdf_open_write_file
616    END INTERFACE netcdf_open_write_file
617
618    PUBLIC netcdf_create_file, netcdf_define_header,                           &
619           netcdf_handle_error, netcdf_open_write_file
620
621 CONTAINS
622
623 SUBROUTINE netcdf_define_header( callmode, extend, av )
624 
625#if defined( __netcdf )
626
627    USE arrays_3d,                                                             &
628        ONLY:  zu, zw
629
630    USE biometeorology_mod,                                                    &
631        ONLY:  bio_define_netcdf_grid
632
633    USE chemistry_model_mod,                                                   &
634        ONLY:  chem_define_netcdf_grid 
635
636    USE basic_constants_and_equations_mod,                                     &
637        ONLY:  pi
638
639    USE control_parameters,                                                    &
640        ONLY:  agent_time_unlimited, air_chemistry, averaging_interval,        &
641               averaging_interval_pr, data_output_pr, domask, dopr_n,          &
642               dopr_time_count, dopts_time_count, dots_time_count,             &
643               do2d, do2d_at_begin, do2d_xz_time_count, do3d, do3d_at_begin,   &
644               do2d_yz_time_count, dt_data_output_av, dt_do2d_xy, dt_do2d_xz,  &
645               dt_do2d_yz, dt_do3d, dt_write_agent_data, mask_size,            &
646               do2d_xy_time_count,                                             &
647               do3d_time_count, domask_time_count, end_time, land_surface,     &
648               mask_size_l, mask_i, mask_i_global, mask_j, mask_j_global,      &
649               mask_k_global, mask_surface,                                    &
650               message_string, mid, ntdim_2d_xy, ntdim_2d_xz,                  &
651               ntdim_2d_yz, ntdim_3d, nz_do3d, ocean_mode, plant_canopy,       &
652               run_description_header, salsa, section, simulated_time,         &
653               simulated_time_at_begin, skip_time_data_output_av,              &
654               skip_time_do2d_xy, skip_time_do2d_xz, skip_time_do2d_yz,        &
655               skip_time_do3d, topography, num_leg, num_var_fl,                &
656               urban_surface
657
658    USE grid_variables,                                                        &
659        ONLY:  dx, dy, zu_s_inner, zw_w_inner
660
661    USE gust_mod,                                                              &
662        ONLY: gust_define_netcdf_grid, gust_module_enabled
663
664    USE indices,                                                               &
665        ONLY:  nx, nxl, nxr, ny, nys, nyn, nz ,nzb, nzt
666
667    USE kinds
668
669    USE land_surface_model_mod,                                                &
670        ONLY: lsm_define_netcdf_grid, nzb_soil, nzt_soil, nzs, zs
671
672    USE ocean_mod,                                                             &
673        ONLY:  ocean_define_netcdf_grid
674
675    USE pegrid
676
677    USE particle_attributes,                                                   &
678        ONLY:  number_of_particle_groups
679
680    USE plant_canopy_model_mod,                                                &
681        ONLY:  pcm_define_netcdf_grid
682
683    USE profil_parameter,                                                      &
684        ONLY:  crmax, cross_profiles, dopr_index, profile_columns, profile_rows
685
686    USE radiation_model_mod,                                                   &
687        ONLY: radiation, radiation_define_netcdf_grid     
688     
689    USE salsa_mod,                                                             &
690        ONLY:  salsa_define_netcdf_grid           
691
692    USE spectra_mod,                                                           &
693        ONLY:  averaging_interval_sp, comp_spectra_level, data_output_sp, dosp_time_count, spectra_direction
694
695    USE statistics,                                                            &
696        ONLY:  hom, statistic_regions
697
698    USE turbulence_closure_mod,                                                &
699        ONLY:  tcm_define_netcdf_grid
700
701    USE urban_surface_mod,                                                     &
702        ONLY:  usm_define_netcdf_grid
703
704
705
706    IMPLICIT NONE
707
708    CHARACTER (LEN=3)              ::  suffix                !<
709    CHARACTER (LEN=2), INTENT (IN) ::  callmode              !<
710    CHARACTER (LEN=4)              ::  grid_x                !<
711    CHARACTER (LEN=4)              ::  grid_y                !<
712    CHARACTER (LEN=4)              ::  grid_z                !<
713    CHARACTER (LEN=6)              ::  mode                  !<
714    CHARACTER (LEN=10)             ::  precision             !<
715    CHARACTER (LEN=10)             ::  var                   !<
716    CHARACTER (LEN=20)             ::  netcdf_var_name       !<
717    CHARACTER (LEN=varnamelength)  ::  trimvar               !< TRIM of output-variable string
718    CHARACTER (LEN=80)             ::  time_average_text     !<
719    CHARACTER (LEN=4000)           ::  char_cross_profiles   !<
720    CHARACTER (LEN=4000)           ::  var_list              !<
721    CHARACTER (LEN=4000)           ::  var_list_old          !<
722
723    CHARACTER (LEN=100), DIMENSION(1:crmax) ::  cross_profiles_adj   !<
724    CHARACTER (LEN=100), DIMENSION(1:crmax) ::  cross_profiles_char  !<
725
726    INTEGER(iwp) ::  av                                      !<
727    INTEGER(iwp) ::  cross_profiles_count                    !<
728    INTEGER(iwp) ::  cross_profiles_maxi                     !<
729    INTEGER(iwp) ::  delim                                   !<
730    INTEGER(iwp) ::  delim_old                               !<
731    INTEGER(iwp) ::  file_id                                 !<
732    INTEGER(iwp) ::  i                                       !<
733    INTEGER(iwp) ::  id_last                                 !<
734    INTEGER(iwp) ::  id_x                                    !<
735    INTEGER(iwp) ::  id_y                                    !<
736    INTEGER(iwp) ::  id_z                                    !<
737    INTEGER(iwp) ::  j                                       !<
738    INTEGER(iwp) ::  k                                       !<
739    INTEGER(iwp) ::  kk                                      !<
740    INTEGER(iwp) ::  ns                                      !<
741    INTEGER(iwp) ::  ns_do                                   !< actual value of ns for soil model data
742    INTEGER(iwp) ::  ns_old                                  !<
743    INTEGER(iwp) ::  ntime_count                             !< number of time levels found in file
744    INTEGER(iwp) ::  nz_old                                  !<
745    INTEGER(iwp) ::  l                                       !<
746
747    INTEGER(iwp), SAVE ::  oldmode                           !<
748
749    INTEGER(iwp), DIMENSION(1) ::  id_dim_time_old           !<
750    INTEGER(iwp), DIMENSION(1) ::  id_dim_x_yz_old           !<
751    INTEGER(iwp), DIMENSION(1) ::  id_dim_y_xz_old           !<
752    INTEGER(iwp), DIMENSION(1) ::  id_dim_zu_sp_old          !<
753    INTEGER(iwp), DIMENSION(1) ::  id_dim_zu_xy_old          !<
754    INTEGER(iwp), DIMENSION(1) ::  id_dim_zu_3d_old          !<
755    INTEGER(iwp), DIMENSION(1) ::  id_dim_zu_mask_old        !<
756
757
758    INTEGER(iwp), DIMENSION(1:crmax) ::  cross_profiles_numb !<
759
760    LOGICAL ::  found                                        !<
761
762    LOGICAL, INTENT (INOUT) ::  extend                       !<
763
764    LOGICAL, SAVE ::  init_netcdf = .FALSE.                  !<
765
766    REAL(wp) ::  cos_ra                                      !< cosine of rotation_angle
767    REAL(wp) ::  eutm                                        !< easting (UTM)
768    REAL(wp) ::  nutm                                        !< northing (UTM)
769    REAL(wp) ::  shift_x                                     !< shift of x coordinate
770    REAL(wp) ::  shift_y                                     !< shift of y coordinate
771    REAL(wp) ::  sin_ra                                      !< sine of rotation_angle
772
773    REAL(wp), DIMENSION(1) ::  last_time_coordinate          !< last time value in file
774    REAL(wp), DIMENSION(8) ::  crs_list                      !< list of coord_ref_sys values
775
776    REAL(wp), DIMENSION(:), ALLOCATABLE   ::  netcdf_data    !<
777    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  netcdf_data_2d !<
778    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  lat            !< latitude
779    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  lon            !< longitude
780
781
782!
783!-- Initializing actions
784    IF ( .NOT. init_netcdf )  THEN
785!
786!--    Check and set accuracy for netCDF output. First set default value
787       nc_precision = NF90_REAL4
788
789       i = 1
790       DO  WHILE ( netcdf_precision(i) /= ' ' )
791          j = INDEX( netcdf_precision(i), '_' )
792          IF ( j == 0 )  THEN
793             WRITE ( message_string, * ) 'netcdf_precision must contain a ', &
794                                         '"_"netcdf_precision(', i, ')="',   &
795                                         TRIM( netcdf_precision(i) ),'"'
796             CALL message( 'netcdf_define_header', 'PA0241', 2, 2, 0, 6, 0 )
797          ENDIF
798
799          var       = netcdf_precision(i)(1:j-1)
800          precision = netcdf_precision(i)(j+1:)
801
802          IF ( precision == 'NF90_REAL4' )  THEN
803             j = NF90_REAL4
804          ELSEIF ( precision == 'NF90_REAL8' )  THEN
805             j = NF90_REAL8
806          ELSE
807             WRITE ( message_string, * ) 'illegal netcdf precision: ',  &
808                                         'netcdf_precision(', i, ')="', &
809                                         TRIM( netcdf_precision(i) ),'"'
810             CALL message( 'netcdf_define_header', 'PA0242', 1, 2, 0, 6, 0 )
811          ENDIF
812
813          SELECT CASE ( var )
814             CASE ( 'xy' )
815                nc_precision(1) = j
816             CASE ( 'xz' )
817                nc_precision(2) = j
818             CASE ( 'yz' )
819                nc_precision(3) = j
820             CASE ( '2d' )
821                nc_precision(1:3) = j
822             CASE ( '3d' )
823                nc_precision(4) = j
824             CASE ( 'pr' )
825                nc_precision(5) = j
826             CASE ( 'ts' )
827                nc_precision(6) = j
828             CASE ( 'sp' )
829                nc_precision(7) = j
830             CASE ( 'prt' )
831                nc_precision(8) = j
832             CASE ( 'masks' )
833                nc_precision(11) = j
834             CASE ( 'fl' )
835                nc_precision(9) = j
836             CASE ( 'all' )
837                nc_precision    = j
838
839             CASE DEFAULT
840                WRITE ( message_string, * ) 'unknown variable in ' //          &
841                                  'initialization_parameters ',                & 
842                                  'assignment: netcdf_precision(', i, ')="',   &
843                                            TRIM( netcdf_precision(i) ),'"'
844                CALL message( 'netcdf_define_header', 'PA0243', 1, 2, 0, 6, 0 )
845
846          END SELECT
847
848          i = i + 1
849          IF ( i > 50 )  EXIT
850       ENDDO
851
852!
853!--    Check for allowed parameter range
854       IF ( netcdf_deflate < 0  .OR.  netcdf_deflate > 9 )  THEN
855          WRITE ( message_string, '(A,I3,A)' ) 'netcdf_deflate out of ' //     &
856                                      'range & given value: ', netcdf_deflate, &
857                                      ', allowed range: 0-9'
858          CALL message( 'netcdf_define_header', 'PA0355', 2, 2, 0, 6, 0 )
859       ENDIF
860!
861!--    Data compression does not work with parallel NetCDF/HDF5
862       IF ( netcdf_deflate > 0  .AND.  netcdf_data_format /= 3 )  THEN
863          message_string = 'netcdf_deflate reset to 0'
864          CALL message( 'netcdf_define_header', 'PA0356', 0, 1, 0, 6, 0 )
865
866          netcdf_deflate = 0
867       ENDIF
868
869       init_netcdf = .TRUE.
870
871    ENDIF
872
873!
874!-- Convert coord_ref_sys into vector (used for lat/lon calculation)
875    crs_list = (/ coord_ref_sys%semi_major_axis,                  &
876                  coord_ref_sys%inverse_flattening,               &
877                  coord_ref_sys%longitude_of_prime_meridian,      &
878                  coord_ref_sys%longitude_of_central_meridian,    &
879                  coord_ref_sys%scale_factor_at_central_meridian, &
880                  coord_ref_sys%latitude_of_projection_origin,    &
881                  coord_ref_sys%false_easting,                    &
882                  coord_ref_sys%false_northing /)
883
884!
885!-- Determine the mode to be processed
886    IF ( extend )  THEN
887       mode = callmode // '_ext'
888    ELSE
889       mode = callmode // '_new'
890    ENDIF
891
892!
893!-- Select the mode to be processed. Possibilities are 3d, ma (mask), xy, xz,
894!-- yz, pr (profiles), ps (particle timeseries), fl (flight data), ts
895!-- (timeseries) or sp (spectra)
896    SELECT CASE ( mode )
897
898       CASE ( 'ma_new' )
899
900!
901!--       decompose actual parameter file_id (=formal parameter av) into
902!--       mid and av
903          file_id = av
904          IF ( file_id <= 200+max_masks )  THEN
905             mid = file_id - 200
906             av = 0
907          ELSE
908             mid = file_id - (200+max_masks)
909             av = 1
910          ENDIF
911
912!
913!--       Define some global attributes of the dataset
914          IF ( av == 0 )  THEN
915             CALL netcdf_create_global_atts( id_set_mask(mid,av), 'podsmasked', TRIM( run_description_header ), 464 )
916             time_average_text = ' '
917          ELSE
918             CALL netcdf_create_global_atts( id_set_mask(mid,av), 'podsmasked', TRIM( run_description_header ), 464 )
919             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval
920             nc_stat = NF90_PUT_ATT( id_set_mask(mid,av), NF90_GLOBAL, 'time_avg',   &
921                                     TRIM( time_average_text ) )
922             CALL netcdf_handle_error( 'netcdf_define_header', 466 )
923          ENDIF
924
925!
926!--       Define time coordinate for volume data (unlimited dimension)
927          CALL netcdf_create_dim( id_set_mask(mid,av), 'time', NF90_UNLIMITED, &
928                                  id_dim_time_mask(mid,av), 467 )
929          CALL netcdf_create_var( id_set_mask(mid,av),                         &
930                                  (/ id_dim_time_mask(mid,av) /), 'time',      &
931                                  NF90_DOUBLE, id_var_time_mask(mid,av),       &
932                                 'seconds since '//TRIM(init_model%origin_time), 'time', 468, 469, 000 )
933          CALL netcdf_create_att( id_set_mask(mid,av), id_var_time_mask(mid,av), 'standard_name', 'time', 000)
934          CALL netcdf_create_att( id_set_mask(mid,av), id_var_time_mask(mid,av), 'axis', 'T', 000)
935
936!
937!--       Define spatial dimensions and coordinates:
938          IF ( mask_surface(mid) )  THEN
939!
940!--          In case of terrain-following output, the vertical dimensions are
941!--          indices, not meters
942             CALL netcdf_create_dim( id_set_mask(mid,av), 'ku_above_surf',     &
943                                     mask_size(mid,3), id_dim_zu_mask(mid,av), &
944                                     470 )
945             CALL netcdf_create_var( id_set_mask(mid,av),                      &
946                                     (/ id_dim_zu_mask(mid,av) /),             &
947                                     'ku_above_surf',                          &
948                                     NF90_DOUBLE, id_var_zu_mask(mid,av),      &
949                                     '1', 'grid point above terrain',          &
950                                     471, 472, 000 )
951             CALL netcdf_create_dim( id_set_mask(mid,av), 'kw_above_surf',     &
952                                     mask_size(mid,3), id_dim_zw_mask(mid,av), &
953                                     473 )
954             CALL netcdf_create_var( id_set_mask(mid,av),                      &
955                                     (/ id_dim_zw_mask(mid,av) /),             &
956                                     'kw_above_surf',                          &
957                                     NF90_DOUBLE, id_var_zw_mask(mid,av),      &
958                                    '1', 'grid point above terrain',           &
959                                    474, 475, 000 )
960          ELSE
961!
962!--          Define vertical coordinate grid (zu grid)
963             CALL netcdf_create_dim( id_set_mask(mid,av), 'zu_3d',             &
964                                     mask_size(mid,3), id_dim_zu_mask(mid,av), &
965                                     470 )
966             CALL netcdf_create_var( id_set_mask(mid,av),                      &
967                                     (/ id_dim_zu_mask(mid,av) /), 'zu_3d',    &
968                                     NF90_DOUBLE, id_var_zu_mask(mid,av),      &
969                                     'meters', '', 471, 472, 000 )
970!
971!--          Define vertical coordinate grid (zw grid)
972             CALL netcdf_create_dim( id_set_mask(mid,av), 'zw_3d',             &
973                                     mask_size(mid,3), id_dim_zw_mask(mid,av), &
974                                     473 )
975             CALL netcdf_create_var( id_set_mask(mid,av),                      &
976                                     (/ id_dim_zw_mask(mid,av) /), 'zw_3d',    &
977                                     NF90_DOUBLE, id_var_zw_mask(mid,av),      &
978                                    'meters', '', 474, 475, 000 )
979          ENDIF
980!
981!--       Define x-axis (for scalar position)
982          CALL netcdf_create_dim( id_set_mask(mid,av), 'x', mask_size(mid,1),  &
983                                  id_dim_x_mask(mid,av), 476 )
984          CALL netcdf_create_var( id_set_mask(mid,av),                         &
985                                  (/ id_dim_x_mask(mid,av) /), 'x',            &
986                                  NF90_DOUBLE, id_var_x_mask(mid,av),          &
987                                  'meters', '', 477, 478, 000 )
988!
989!--       Define x-axis (for u position)
990          CALL netcdf_create_dim( id_set_mask(mid,av), 'xu', mask_size(mid,1), &
991                                  id_dim_xu_mask(mid,av), 479 )
992          CALL netcdf_create_var( id_set_mask(mid,av),                         &
993                                  (/ id_dim_xu_mask(mid,av) /), 'xu',          &
994                                  NF90_DOUBLE, id_var_xu_mask(mid,av),         &
995                                  'meters', '', 480, 481, 000 )
996!
997!--       Define y-axis (for scalar position)
998          CALL netcdf_create_dim( id_set_mask(mid,av), 'y', mask_size(mid,2),  &
999                                  id_dim_y_mask(mid,av), 482 )
1000          CALL netcdf_create_var( id_set_mask(mid,av),                         &
1001                                  (/ id_dim_y_mask(mid,av) /), 'y',            &
1002                                  NF90_DOUBLE, id_var_y_mask(mid,av),          &
1003                                  'meters', '', 483, 484, 000 )
1004!
1005!--       Define y-axis (for v position)
1006          CALL netcdf_create_dim( id_set_mask(mid,av), 'yv', mask_size(mid,2), &
1007                                  id_dim_yv_mask(mid,av), 485 )
1008          CALL netcdf_create_var( id_set_mask(mid,av),                         &
1009                                  (/ id_dim_yv_mask(mid,av) /),                &
1010                                  'yv', NF90_DOUBLE, id_var_yv_mask(mid,av),   &
1011                                  'meters', '', 486, 487, 000 )
1012!
1013!--       Define UTM and geographic coordinates
1014          CALL define_geo_coordinates( id_set_mask(mid,av),               &
1015                  (/ id_dim_x_mask(mid,av), id_dim_xu_mask(mid,av) /),    &
1016                  (/ id_dim_y_mask(mid,av), id_dim_yv_mask(mid,av) /),    &
1017                  id_var_eutm_mask(mid,av,:), id_var_nutm_mask(mid,av,:), &
1018                  id_var_lat_mask(mid,av,:), id_var_lon_mask(mid,av,:)    )
1019!
1020!--       Define coordinate-reference system
1021          CALL netcdf_create_crs( id_set_mask(mid,av), 000 )
1022!
1023!--       In case of non-flat topography define 2d-arrays containing the height
1024!--       information. Only for parallel netcdf output.
1025          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
1026               netcdf_data_format > 4 )  THEN
1027!
1028!--          Define zusi = zu(nzb_s_inner)
1029             CALL netcdf_create_var( id_set_mask(mid,av),                      &
1030                                     (/ id_dim_x_mask(mid,av),                 &
1031                                        id_dim_y_mask(mid,av) /), 'zusi',      &
1032                                     NF90_DOUBLE, id_var_zusi_mask(mid,av),    &
1033                                     'meters', 'zu(nzb_s_inner)', 488, 489,    &
1034                                     490 )
1035!             
1036!--          Define zwwi = zw(nzb_w_inner)
1037             CALL netcdf_create_var( id_set_mask(mid,av),                      &
1038                                     (/ id_dim_x_mask(mid,av),                 &
1039                                        id_dim_y_mask(mid,av) /), 'zwwi',      &
1040                                     NF90_DOUBLE, id_var_zwwi_mask(mid,av),    &
1041                                     'meters', 'zw(nzb_w_inner)', 491, 492,    &
1042                                     493 )
1043          ENDIF             
1044 
1045          IF ( land_surface )  THEN
1046!
1047!--          Define vertical coordinate grid (zw grid)
1048             CALL netcdf_create_dim( id_set_mask(mid,av), 'zs_3d',             &
1049                                     mask_size(mid,3), id_dim_zs_mask(mid,av), &
1050                                     536 )
1051             CALL netcdf_create_var( id_set_mask(mid,av),                      &
1052                                     (/ id_dim_zs_mask(mid,av) /), 'zs_3d',    &
1053                                     NF90_DOUBLE, id_var_zs_mask(mid,av),      &
1054                                     'meters', '', 537, 555, 000 )
1055          ENDIF
1056
1057!
1058!--       Define the variables
1059          var_list = ';'
1060          i = 1
1061
1062          DO WHILE ( domask(mid,av,i)(1:1) /= ' ' )
1063!
1064!--          Temporary solution to account for data output within the new urban
1065!--          surface model (urban_surface_mod.f90), see also SELECT CASE ( trimvar )
1066             trimvar = TRIM( domask(mid,av,i) )
1067             IF ( urban_surface  .AND.  trimvar(1:4) == 'usm_' )  THEN
1068                trimvar = 'usm_output'
1069             ENDIF
1070!
1071!--          Check for the grid
1072             found = .FALSE.
1073             SELECT CASE ( trimvar )
1074!
1075!--             Most variables are defined on the scalar grid
1076                CASE ( 'e', 'nc', 'nr', 'p', 'pc', 'pr', 'prr',                &
1077                       'q', 'qc', 'ql', 'ql_c', 'ql_v', 'ql_vp', 'qr', 'qv',   &
1078                       's', 'theta', 'thetal', 'thetav' )
1079
1080                   grid_x = 'x'
1081                   grid_y = 'y'
1082                   grid_z = 'zu'
1083!
1084!--             u grid
1085                CASE ( 'u' )
1086
1087                   grid_x = 'xu'
1088                   grid_y = 'y'
1089                   grid_z = 'zu'
1090!
1091!--             v grid
1092                CASE ( 'v' )
1093
1094                   grid_x = 'x'
1095                   grid_y = 'yv'
1096                   grid_z = 'zu'
1097!
1098!--             w grid
1099                CASE ( 'w' )
1100
1101                   grid_x = 'x'
1102                   grid_y = 'y'
1103                   grid_z = 'zw'
1104
1105!             
1106!--             Block of urban surface model outputs
1107                CASE ( 'usm_output' )
1108
1109                   CALL usm_define_netcdf_grid( domask( mid,av,i), found,      &
1110                                                        grid_x, grid_y, grid_z )
1111
1112                CASE DEFAULT
1113!
1114!--                Check for quantities defined in other modules                                                       
1115                   CALL tcm_define_netcdf_grid( domask( mid,av,i), found,      &
1116                                                        grid_x, grid_y, grid_z )
1117
1118                   IF ( .NOT. found  .AND.  air_chemistry )  THEN
1119                      CALL chem_define_netcdf_grid( domask(mid,av,i), found,   &
1120                                                    grid_x, grid_y, grid_z )
1121                   ENDIF
1122
1123                   IF ( .NOT. found  .AND.  gust_module_enabled )  THEN
1124                      CALL gust_define_netcdf_grid( domask(mid,av,i), found,   &
1125                                                    grid_x, grid_y, grid_z )
1126                   ENDIF
1127
1128                   IF ( land_surface )  THEN
1129                      CALL lsm_define_netcdf_grid( domask(mid,av,i), found,    &
1130                                                   grid_x, grid_y, grid_z )
1131                   ENDIF
1132
1133                   IF ( .NOT. found  .AND.  ocean_mode )  THEN
1134                      CALL ocean_define_netcdf_grid( domask(mid,av,i), found,  &
1135                                                     grid_x, grid_y, grid_z )
1136                   ENDIF
1137
1138                   IF ( .NOT. found  .AND.  plant_canopy )  THEN
1139                      CALL pcm_define_netcdf_grid( domask(mid,av,i), found,    &
1140                                                   grid_x, grid_y, grid_z )
1141                   ENDIF
1142
1143                   IF ( .NOT. found  .AND.  radiation )  THEN
1144                      CALL radiation_define_netcdf_grid( domask(mid,av,i),     &
1145                                                         found, grid_x, grid_y,&
1146                                                         grid_z )
1147                   ENDIF
1148!
1149!--                Check for SALSA quantities
1150                   IF ( .NOT. found  .AND.  salsa )  THEN
1151                      CALL salsa_define_netcdf_grid( domask(mid,av,i), found,  &
1152                                                     grid_x, grid_y, grid_z )
1153                   ENDIF                                   
1154!
1155!--                Now check for user-defined quantities
1156                   IF ( .NOT. found )  THEN
1157                      CALL user_define_netcdf_grid( domask(mid,av,i), found,   &
1158                                                    grid_x, grid_y, grid_z )
1159                   ENDIF
1160                                                 
1161                   IF ( .NOT. found )  THEN
1162                      WRITE ( message_string, * ) 'no grid defined for',       &
1163                           ' variable ', TRIM( domask(mid,av,i) )
1164                      CALL message( 'define_netcdf_header', 'PA0244', 0, 1, 0, &
1165                                    6, 0 )
1166                   ENDIF
1167
1168             END SELECT
1169
1170!
1171!--          Select the respective dimension ids
1172             IF ( grid_x == 'x' )  THEN
1173                id_x = id_dim_x_mask(mid,av)
1174             ELSEIF ( grid_x == 'xu' )  THEN
1175                id_x = id_dim_xu_mask(mid,av)
1176             ENDIF
1177
1178             IF ( grid_y == 'y' )  THEN
1179                id_y = id_dim_y_mask(mid,av)
1180             ELSEIF ( grid_y == 'yv' )  THEN
1181                id_y = id_dim_yv_mask(mid,av)
1182             ENDIF
1183
1184             IF ( grid_z == 'zu' )  THEN
1185                id_z = id_dim_zu_mask(mid,av)
1186             ELSEIF ( grid_z == 'zw' )  THEN
1187                id_z = id_dim_zw_mask(mid,av)
1188             ELSEIF ( grid_z == "zs" )  THEN
1189                id_z = id_dim_zs_mask(mid,av)
1190             ENDIF
1191
1192!
1193!--          Define the grid
1194             CALL netcdf_create_var( id_set_mask(mid,av), (/ id_x, id_y, id_z, &
1195                                     id_dim_time_mask(mid,av) /),              &
1196                                     domask(mid,av,i), nc_precision(11),       &
1197                                     id_var_domask(mid,av,i),                  &
1198                                     TRIM( domask_unit(mid,av,i) ),            &
1199                                     domask(mid,av,i), 494, 495, 496, .TRUE. )
1200
1201             var_list = TRIM( var_list ) // TRIM( domask(mid,av,i) ) // ';'
1202
1203             i = i + 1
1204
1205          ENDDO
1206
1207!
1208!--       No arrays to output
1209          IF ( i == 1 )  RETURN
1210
1211!
1212!--       Write the list of variables as global attribute (this is used by
1213!--       restart runs and by combine_plot_fields)
1214          nc_stat = NF90_PUT_ATT( id_set_mask(mid,av), NF90_GLOBAL, &
1215                                  'VAR_LIST', var_list )
1216          CALL netcdf_handle_error( 'netcdf_define_header', 497 )
1217
1218!
1219!--       Leave netCDF define mode
1220          nc_stat = NF90_ENDDEF( id_set_mask(mid,av) )
1221          CALL netcdf_handle_error( 'netcdf_define_header', 498 )
1222
1223!
1224!--       Write data for x (shifted by +dx/2) and xu axis
1225          ALLOCATE( netcdf_data(mask_size(mid,1)) )
1226
1227          netcdf_data = ( mask_i_global(mid,:mask_size(mid,1)) + 0.5_wp ) * dx
1228
1229          nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_x_mask(mid,av), &
1230                                  netcdf_data, start = (/ 1 /),               &
1231                                  count = (/ mask_size(mid,1) /) )
1232          CALL netcdf_handle_error( 'netcdf_define_header', 499 )
1233
1234          netcdf_data = mask_i_global(mid,:mask_size(mid,1)) * dx
1235
1236          nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_xu_mask(mid,av),&
1237                                  netcdf_data, start = (/ 1 /),               &
1238                                  count = (/ mask_size(mid,1) /) )
1239          CALL netcdf_handle_error( 'netcdf_define_header', 500 )
1240
1241          DEALLOCATE( netcdf_data )
1242
1243!
1244!--       Write data for y (shifted by +dy/2) and yv axis
1245          ALLOCATE( netcdf_data(mask_size(mid,2)) )
1246
1247          netcdf_data = ( mask_j_global(mid,:mask_size(mid,2)) + 0.5_wp ) * dy
1248
1249          nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_y_mask(mid,av), &
1250                                  netcdf_data, start = (/ 1 /),               &
1251                                  count = (/ mask_size(mid,2) /))
1252          CALL netcdf_handle_error( 'netcdf_define_header', 501 )
1253
1254          netcdf_data = mask_j_global(mid,:mask_size(mid,2)) * dy
1255
1256          nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_yv_mask(mid,av), &
1257                                  netcdf_data, start = (/ 1 /),    &
1258                                  count = (/ mask_size(mid,2) /))
1259          CALL netcdf_handle_error( 'netcdf_define_header', 502 )
1260
1261          DEALLOCATE( netcdf_data )
1262
1263!
1264!--       Write UTM coordinates
1265          IF ( init_model%rotation_angle == 0.0_wp )  THEN
1266!
1267!--          1D in case of no rotation
1268             cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
1269!
1270!--          x coordinates
1271             ALLOCATE( netcdf_data(mask_size(mid,1)) )
1272             DO  k = 0, 2
1273!           
1274!--             Scalar grid points
1275                IF ( k == 0 )  THEN
1276                   shift_x = 0.5
1277!           
1278!--             u grid points
1279                ELSEIF ( k == 1 )  THEN
1280                   shift_x = 0.0
1281!           
1282!--             v grid points
1283                ELSEIF ( k == 2 )  THEN
1284                   shift_x = 0.5
1285                ENDIF
1286
1287                netcdf_data = init_model%origin_x + cos_ra                     &
1288                       * ( mask_i_global(mid,:mask_size(mid,1)) + shift_x ) * dx
1289
1290                nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), &
1291                                        id_var_eutm_mask(mid,av,k), &
1292                                        netcdf_data, start = (/ 1 /), &
1293                                        count = (/ mask_size(mid,1) /) )
1294                CALL netcdf_handle_error( 'netcdf_define_header', 555 )
1295
1296             ENDDO
1297             DEALLOCATE( netcdf_data )
1298!
1299!--          y coordinates
1300             ALLOCATE( netcdf_data(mask_size(mid,2)) )
1301             DO  k = 0, 2
1302!
1303!--             Scalar grid points
1304                IF ( k == 0 )  THEN
1305                   shift_y = 0.5
1306!
1307!--             u grid points
1308                ELSEIF ( k == 1 )  THEN
1309                   shift_y = 0.5
1310!
1311!--             v grid points
1312                ELSEIF ( k == 2 )  THEN
1313                   shift_y = 0.0
1314                ENDIF
1315
1316                netcdf_data = init_model%origin_y + cos_ra                     &
1317                       * ( mask_j_global(mid,:mask_size(mid,2)) + shift_y ) * dy
1318
1319                nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), &
1320                                        id_var_nutm_mask(mid,av,k), &
1321                                        netcdf_data, start = (/ 1 /), &
1322                                        count = (/ mask_size(mid,2) /) )
1323                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
1324
1325             ENDDO
1326             DEALLOCATE( netcdf_data )
1327
1328          ELSE
1329!
1330!--          2D in case of rotation
1331             ALLOCATE( netcdf_data_2d(mask_size(mid,1),mask_size(mid,2)) )
1332             cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
1333             sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
1334
1335             DO  k = 0, 2
1336!           
1337!--            Scalar grid points
1338               IF ( k == 0 )  THEN
1339                  shift_x = 0.5 ; shift_y = 0.5
1340!           
1341!--            u grid points
1342               ELSEIF ( k == 1 )  THEN
1343                  shift_x = 0.0 ; shift_y = 0.5
1344!           
1345!--            v grid points
1346               ELSEIF ( k == 2 )  THEN
1347                  shift_x = 0.5 ; shift_y = 0.0
1348               ENDIF
1349
1350               DO  j = 1, mask_size(mid,2)
1351                  DO  i = 1, mask_size(mid,1)
1352                     netcdf_data_2d(i,j) = init_model%origin_x                 &
1353                           + cos_ra * ( mask_i_global(mid,i) + shift_x ) * dx  &
1354                           + sin_ra * ( mask_j_global(mid,j) + shift_y ) * dy
1355                  ENDDO
1356               ENDDO
1357
1358               nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), &
1359                                       id_var_eutm_mask(mid,av,k), &
1360                                       netcdf_data_2d, start = (/ 1, 1 /), &
1361                                       count = (/ mask_size(mid,1), &
1362                                                  mask_size(mid,2) /) )
1363               CALL netcdf_handle_error( 'netcdf_define_header', 555 )
1364
1365               DO  j = 1, mask_size(mid,2)
1366                  DO  i = 1, mask_size(mid,1)
1367                     netcdf_data_2d(i,j) = init_model%origin_y                 &
1368                           - sin_ra * ( mask_i_global(mid,i) + shift_x ) * dx  &
1369                           + cos_ra * ( mask_j_global(mid,j) + shift_y ) * dy
1370                  ENDDO
1371               ENDDO
1372             
1373               nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), &
1374                                       id_var_nutm_mask(mid,av,k), &
1375                                       netcdf_data_2d, start = (/ 1, 1 /), &
1376                                       count = (/ mask_size(mid,1), &
1377                                                  mask_size(mid,2) /) )
1378               CALL netcdf_handle_error( 'netcdf_define_header', 556 )
1379             
1380             ENDDO
1381             DEALLOCATE( netcdf_data_2d )
1382          ENDIF
1383!
1384!--       Write lon and lat data.
1385          ALLOCATE( lat(mask_size(mid,1),mask_size(mid,2)) )
1386          ALLOCATE( lon(mask_size(mid,1),mask_size(mid,2)) )
1387          cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
1388          sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
1389
1390          DO  k = 0, 2
1391!               
1392!--          Scalar grid points
1393             IF ( k == 0 )  THEN
1394                shift_x = 0.5 ; shift_y = 0.5
1395!               
1396!--          u grid points
1397             ELSEIF ( k == 1 )  THEN
1398                shift_x = 0.0 ; shift_y = 0.5
1399!               
1400!--          v grid points
1401             ELSEIF ( k == 2 )  THEN
1402                shift_x = 0.5 ; shift_y = 0.0
1403             ENDIF
1404
1405             DO  j = 1, mask_size(mid,2)
1406                DO  i = 1, mask_size(mid,1)
1407                   eutm = init_model%origin_x                               &
1408                        + cos_ra * ( mask_i_global(mid,i) + shift_x ) * dx  &
1409                        + sin_ra * ( mask_j_global(mid,j) + shift_y ) * dy
1410                   nutm = init_model%origin_y                               &
1411                        - sin_ra * ( mask_i_global(mid,i) + shift_x ) * dx  &
1412                        + cos_ra * ( mask_j_global(mid,j) + shift_y ) * dy
1413
1414                   CALL  convert_utm_to_geographic( crs_list,          &
1415                                                    eutm, nutm,        &
1416                                                    lon(i,j), lat(i,j) )
1417                ENDDO
1418             ENDDO
1419
1420             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),           &
1421                                     id_var_lon_mask(mid,av,k),     &
1422                                     lon, start = (/ 1, 1 /),       &
1423                                     count = (/ mask_size(mid,1),   &
1424                                                mask_size(mid,2) /) )
1425             CALL netcdf_handle_error( 'netcdf_define_header', 556 )
1426
1427             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),           &
1428                                     id_var_lat_mask(mid,av,k),     &
1429                                     lat, start = (/ 1, 1 /),       &
1430                                     count = (/ mask_size(mid,1),   &
1431                                                mask_size(mid,2) /) )
1432             CALL netcdf_handle_error( 'netcdf_define_header', 556 )
1433          ENDDO
1434
1435          DEALLOCATE( lat )
1436          DEALLOCATE( lon )
1437!
1438!--       Write zu and zw data (vertical axes)
1439          ALLOCATE( netcdf_data(mask_size(mid,3)) )
1440
1441          IF ( mask_surface(mid) )  THEN
1442
1443             netcdf_data = mask_k_global(mid,:mask_size(mid,3))
1444
1445             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_zu_mask(mid,av), &
1446                                     netcdf_data, start = (/ 1 /), &
1447                                     count = (/ mask_size(mid,3) /) )
1448             CALL netcdf_handle_error( 'netcdf_define_header', 503 )
1449
1450             netcdf_data = mask_k_global(mid,:mask_size(mid,3))
1451
1452             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_zw_mask(mid,av), &
1453                                     netcdf_data, start = (/ 1 /), &
1454                                     count = (/ mask_size(mid,3) /) )
1455             CALL netcdf_handle_error( 'netcdf_define_header', 504 )
1456
1457          ELSE
1458
1459             netcdf_data = zu( mask_k_global(mid,:mask_size(mid,3)) )
1460
1461             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_zu_mask(mid,av), &
1462                                     netcdf_data, start = (/ 1 /), &
1463                                     count = (/ mask_size(mid,3) /) )
1464             CALL netcdf_handle_error( 'netcdf_define_header', 503 )
1465
1466             netcdf_data = zw( mask_k_global(mid,:mask_size(mid,3)) )
1467
1468             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_zw_mask(mid,av), &
1469                                     netcdf_data, start = (/ 1 /), &
1470                                     count = (/ mask_size(mid,3) /) )
1471             CALL netcdf_handle_error( 'netcdf_define_header', 504 )
1472
1473          ENDIF
1474
1475          DEALLOCATE( netcdf_data )
1476
1477!
1478!--       In case of non-flat topography write height information
1479          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
1480               netcdf_data_format > 4 )  THEN
1481
1482             ALLOCATE( netcdf_data_2d(mask_size_l(mid,1),mask_size_l(mid,2)) )
1483             netcdf_data_2d = zu_s_inner( mask_i(mid,:mask_size_l(mid,1)),     &
1484                                          mask_j(mid,:mask_size_l(mid,2)) )
1485
1486             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),                      &
1487                                     id_var_zusi_mask(mid,av),                 &
1488                                     netcdf_data_2d,                           &
1489                                     start = (/ 1, 1 /),                       &
1490                                     count = (/ mask_size_l(mid,1),            &
1491                                                mask_size_l(mid,2) /) )
1492             CALL netcdf_handle_error( 'netcdf_define_header', 505 )
1493
1494             netcdf_data_2d = zw_w_inner( mask_i(mid,:mask_size_l(mid,1)),     &
1495                                          mask_j(mid,:mask_size_l(mid,2)) )
1496
1497             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),                      &
1498                                     id_var_zwwi_mask(mid,av),                 &
1499                                     netcdf_data_2d,                           &
1500                                     start = (/ 1, 1 /),                       &
1501                                     count = (/ mask_size_l(mid,1),            &
1502                                                mask_size_l(mid,2) /) )
1503             CALL netcdf_handle_error( 'netcdf_define_header', 506 )
1504
1505             DEALLOCATE( netcdf_data_2d )
1506
1507          ENDIF
1508
1509          IF ( land_surface )  THEN
1510!
1511!--          Write zs data (vertical axes for soil model), use negative values
1512!--          to indicate soil depth
1513             ALLOCATE( netcdf_data(mask_size(mid,3)) )
1514
1515             netcdf_data = zs( mask_k_global(mid,:mask_size(mid,3)) )
1516
1517             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av), id_var_zs_mask(mid,av), &
1518                                     netcdf_data, start = (/ 1 /), &
1519                                     count = (/ mask_size(mid,3) /) )
1520             CALL netcdf_handle_error( 'netcdf_define_header', 538 )
1521
1522             DEALLOCATE( netcdf_data )
1523
1524          ENDIF
1525
1526!
1527!--       restore original parameter file_id (=formal parameter av) into av
1528          av = file_id
1529
1530
1531       CASE ( 'ma_ext' )
1532
1533!
1534!--       decompose actual parameter file_id (=formal parameter av) into
1535!--       mid and av
1536          file_id = av
1537          IF ( file_id <= 200+max_masks )  THEN
1538             mid = file_id - 200
1539             av = 0
1540          ELSE
1541             mid = file_id - (200+max_masks)
1542             av = 1
1543          ENDIF
1544
1545!
1546!--       Get the list of variables and compare with the actual run.
1547!--       First var_list_old has to be reset, since GET_ATT does not assign
1548!--       trailing blanks.
1549          var_list_old = ' '
1550          nc_stat = NF90_GET_ATT( id_set_mask(mid,av), NF90_GLOBAL, 'VAR_LIST',&
1551                                  var_list_old )
1552          CALL netcdf_handle_error( 'netcdf_define_header', 507 )
1553
1554          var_list = ';'
1555          i = 1
1556          DO WHILE ( domask(mid,av,i)(1:1) /= ' ' )
1557             var_list = TRIM(var_list) // TRIM( domask(mid,av,i) ) // ';'
1558             i = i + 1
1559          ENDDO
1560
1561          IF ( av == 0 )  THEN
1562             var = '(mask)'
1563          ELSE
1564             var = '(mask_av)'
1565          ENDIF
1566
1567          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
1568             WRITE ( message_string, * ) 'netCDF file for ', TRIM( var ),       &
1569                  ' data for mask', mid, ' from previous run found,',           &
1570                  '&but this file cannot be extended due to variable ',         &
1571                  'mismatch.&New file is created instead.'
1572             CALL message( 'define_netcdf_header', 'PA0335', 0, 1, 0, 6, 0 )
1573             extend = .FALSE.
1574             RETURN
1575          ENDIF
1576
1577!
1578!--       Get and compare the number of vertical gridpoints
1579          nc_stat = NF90_INQ_VARID( id_set_mask(mid,av), 'zu_3d', &
1580                                    id_var_zu_mask(mid,av) )
1581          CALL netcdf_handle_error( 'netcdf_define_header', 508 )
1582
1583          nc_stat = NF90_INQUIRE_VARIABLE( id_set_mask(mid,av),     &
1584                                           id_var_zu_mask(mid,av),  &
1585                                           dimids = id_dim_zu_mask_old )
1586          CALL netcdf_handle_error( 'netcdf_define_header', 509 )
1587          id_dim_zu_mask(mid,av) = id_dim_zu_mask_old(1)
1588
1589          nc_stat = NF90_INQUIRE_DIMENSION( id_set_mask(mid,av),               &
1590                                            id_dim_zu_mask(mid,av),            &
1591                                            len = nz_old )
1592          CALL netcdf_handle_error( 'netcdf_define_header', 510 )
1593
1594          IF ( mask_size(mid,3) /= nz_old )  THEN
1595             WRITE ( message_string, * ) 'netCDF file for ', TRIM( var ),      &
1596                  '&data for mask', mid, ' from previous run found,',          &
1597                  ' but this file cannot be extended due to mismatch in ',     &
1598                  ' number of vertical grid points.',                          &
1599                  '&New file is created instead.'
1600             CALL message( 'define_netcdf_header', 'PA0336', 0, 1, 0, 6, 0 )
1601             extend = .FALSE.
1602             RETURN
1603          ENDIF
1604
1605!
1606!--       Get the id of the time coordinate (unlimited coordinate) and its
1607!--       last index on the file. The next time level is plmask..count+1.
1608!--       The current time must be larger than the last output time
1609!--       on the file.
1610          nc_stat = NF90_INQ_VARID( id_set_mask(mid,av), 'time',               &
1611                                    id_var_time_mask(mid,av) )
1612          CALL netcdf_handle_error( 'netcdf_define_header', 511 )
1613
1614          nc_stat = NF90_INQUIRE_VARIABLE( id_set_mask(mid,av),                &
1615                                           id_var_time_mask(mid,av),           &
1616                                           dimids = id_dim_time_old )
1617          CALL netcdf_handle_error( 'netcdf_define_header', 512 )
1618          id_dim_time_mask(mid,av) = id_dim_time_old(1)
1619
1620          nc_stat = NF90_INQUIRE_DIMENSION( id_set_mask(mid,av),               &
1621                                            id_dim_time_mask(mid,av),          &
1622                                            len = domask_time_count(mid,av) )
1623          CALL netcdf_handle_error( 'netcdf_define_header', 513 )
1624
1625          nc_stat = NF90_GET_VAR( id_set_mask(mid,av),                         &
1626                                  id_var_time_mask(mid,av),                    &
1627                                  last_time_coordinate,                        &
1628                                  start = (/ domask_time_count(mid,av) /),     &
1629                                  count = (/ 1 /) )
1630          CALL netcdf_handle_error( 'netcdf_define_header', 514 )
1631
1632          IF ( last_time_coordinate(1) >= simulated_time )  THEN
1633             WRITE ( message_string, * ) 'netCDF file for ', TRIM( var ),      &
1634                  ' data for mask', mid, ' from previous run found,',          &
1635                  '&but this file cannot be extended because the current ',    &
1636                  'output time is less or equal than the last output time ',   &
1637                  'on this file.&New file is created instead.'
1638             CALL message( 'define_netcdf_header', 'PA0337', 0, 1, 0, 6, 0 )
1639             domask_time_count(mid,av) = 0
1640             extend = .FALSE.
1641             RETURN
1642          ENDIF
1643
1644!
1645!--       Dataset seems to be extendable.
1646!--       Now get the variable ids.
1647          i = 1
1648          DO WHILE ( domask(mid,av,i)(1:1) /= ' ' )
1649             nc_stat = NF90_INQ_VARID( id_set_mask(mid,av), &
1650                                       TRIM( domask(mid,av,i) ), &
1651                                       id_var_domask(mid,av,i) )
1652             CALL netcdf_handle_error( 'netcdf_define_header', 515 )
1653             i = i + 1
1654          ENDDO
1655
1656!
1657!--       Update the title attribute on file
1658!--       In order to avoid 'data mode' errors if updated attributes are larger
1659!--       than their original size, NF90_PUT_ATT is called in 'define mode'
1660!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
1661!--       performance loss due to data copying; an alternative strategy would be
1662!--       to ensure equal attribute size in a job chain. Maybe revise later.
1663          IF ( av == 0 )  THEN
1664             time_average_text = ' '
1665          ELSE
1666             WRITE (time_average_text, '('', '',F7.1,'' s average'')')         &
1667                                                            averaging_interval
1668          ENDIF
1669          nc_stat = NF90_REDEF( id_set_mask(mid,av) )
1670          CALL netcdf_handle_error( 'netcdf_define_header', 516 )
1671          nc_stat = NF90_PUT_ATT( id_set_mask(mid,av), NF90_GLOBAL, 'title',   &
1672                                  TRIM( run_description_header ) //            &
1673                                  TRIM( time_average_text ) )
1674          CALL netcdf_handle_error( 'netcdf_define_header', 517 )
1675          nc_stat = NF90_ENDDEF( id_set_mask(mid,av) )
1676          CALL netcdf_handle_error( 'netcdf_define_header', 518 )
1677          WRITE ( message_string, * ) 'netCDF file for ', TRIM( var ),         &
1678               ' data for mask', mid, ' from previous run found.',             &
1679               ' &This file will be extended.'
1680          CALL message( 'define_netcdf_header', 'PA0338', 0, 0, 0, 6, 0 )
1681!
1682!--       restore original parameter file_id (=formal parameter av) into av
1683          av = file_id
1684
1685
1686       CASE ( '3d_new' )
1687
1688!
1689!--       Define some global attributes of the dataset
1690          IF ( av == 0 )  THEN
1691             CALL netcdf_create_global_atts( id_set_3d(av), '3d', TRIM( run_description_header ), 62 )
1692             time_average_text = ' '
1693          ELSE
1694             CALL netcdf_create_global_atts( id_set_3d(av), '3d_av', TRIM( run_description_header ), 62 )
1695             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval
1696             nc_stat = NF90_PUT_ATT( id_set_3d(av), NF90_GLOBAL, 'time_avg',   &
1697                                     TRIM( time_average_text ) )
1698             CALL netcdf_handle_error( 'netcdf_define_header', 63 )
1699          ENDIF
1700
1701!
1702!--       Define time coordinate for volume data.
1703!--       For parallel output the time dimensions has to be limited, otherwise
1704!--       the performance drops significantly.
1705          IF ( netcdf_data_format < 5 )  THEN
1706             CALL netcdf_create_dim( id_set_3d(av), 'time', NF90_UNLIMITED,    &
1707                                     id_dim_time_3d(av), 64 )
1708          ELSE
1709             CALL netcdf_create_dim( id_set_3d(av), 'time', ntdim_3d(av),      &
1710                                     id_dim_time_3d(av), 523 )
1711          ENDIF
1712
1713          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_time_3d(av) /),     &
1714                                  'time', NF90_DOUBLE, id_var_time_3d(av),     &
1715                                  'seconds since '//TRIM(init_model%origin_time), 'time', 65, 66, 00 )
1716          CALL netcdf_create_att( id_set_3d(av), id_var_time_3d(av), 'standard_name', 'time', 000)
1717          CALL netcdf_create_att( id_set_3d(av), id_var_time_3d(av), 'axis', 'T', 000)
1718!
1719!--       Define spatial dimensions and coordinates:
1720!--       Define vertical coordinate grid (zu grid)
1721          CALL netcdf_create_dim( id_set_3d(av), 'zu_3d', nz_do3d-nzb+1,       &
1722                                  id_dim_zu_3d(av), 67 )
1723          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_zu_3d(av) /),       &
1724                                  'zu_3d', NF90_DOUBLE, id_var_zu_3d(av),      &
1725                                  'meters', '', 68, 69, 00 )
1726!
1727!--       Define vertical coordinate grid (zw grid)
1728          CALL netcdf_create_dim( id_set_3d(av), 'zw_3d', nz_do3d-nzb+1,       &
1729                                  id_dim_zw_3d(av), 70 )
1730          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_zw_3d(av) /),       &
1731                                  'zw_3d', NF90_DOUBLE, id_var_zw_3d(av),      &
1732                                  'meters', '', 71, 72, 00 )
1733!
1734!--       Define x-axis (for scalar position)
1735          CALL netcdf_create_dim( id_set_3d(av), 'x', nx+1, id_dim_x_3d(av),   &
1736                                  73 )
1737          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_x_3d(av) /), 'x',   &
1738                                  NF90_DOUBLE, id_var_x_3d(av), 'meters', '',  &
1739                                  74, 75, 00 )
1740!
1741!--       Define x-axis (for u position)
1742          CALL netcdf_create_dim( id_set_3d(av), 'xu', nx+1, id_dim_xu_3d(av), &
1743                                  358 )
1744          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_xu_3d(av) /), 'xu', &
1745                                  NF90_DOUBLE, id_var_xu_3d(av), 'meters', '', &
1746                                  359, 360, 000 )
1747!
1748!--       Define y-axis (for scalar position)
1749          CALL netcdf_create_dim( id_set_3d(av), 'y', ny+1, id_dim_y_3d(av),   &
1750                                  76 )
1751          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_y_3d(av) /), 'y',   &
1752                                  NF90_DOUBLE, id_var_y_3d(av), 'meters', '',  &
1753                                  77, 78, 00 )
1754!
1755!--       Define y-axis (for v position)
1756          CALL netcdf_create_dim( id_set_3d(av), 'yv', ny+1, id_dim_yv_3d(av), &
1757                                  361 )
1758          CALL netcdf_create_var( id_set_3d(av), (/ id_dim_yv_3d(av) /), 'yv', &
1759                                  NF90_DOUBLE, id_var_yv_3d(av), 'meters', '', &
1760                                  362, 363, 000 )
1761!
1762!--       Define UTM and geographic coordinates
1763          CALL define_geo_coordinates( id_set_3d(av),         &
1764                  (/ id_dim_x_3d(av), id_dim_xu_3d(av) /),    &
1765                  (/ id_dim_y_3d(av), id_dim_yv_3d(av) /),    &
1766                  id_var_eutm_3d(av,:), id_var_nutm_3d(av,:), &
1767                  id_var_lat_3d(av,:), id_var_lon_3d(av,:)    )
1768!
1769!--       Define coordinate-reference system
1770          CALL netcdf_create_crs( id_set_3d(av), 000 )
1771!
1772!--       In case of non-flat topography define 2d-arrays containing the height
1773!--       information. Only output 2d topography information in case of parallel
1774!--       output.
1775          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
1776               netcdf_data_format > 4 )  THEN
1777!
1778!--          Define zusi = zu(nzb_s_inner)
1779             CALL netcdf_create_var( id_set_3d(av), (/ id_dim_x_3d(av),        &
1780                                     id_dim_y_3d(av) /), 'zusi', NF90_DOUBLE,  &
1781                                     id_var_zusi_3d(av), 'meters',             &
1782                                     'zu(nzb_s_inner)', 413, 414, 415 )
1783!             
1784!--          Define zwwi = zw(nzb_w_inner)
1785             CALL netcdf_create_var( id_set_3d(av), (/ id_dim_x_3d(av),        &
1786                                     id_dim_y_3d(av) /), 'zwwi', NF90_DOUBLE,  &
1787                                     id_var_zwwi_3d(av), 'meters',             &
1788                                     'zw(nzb_w_inner)', 416, 417, 418 )
1789
1790          ENDIF             
1791
1792          IF ( land_surface )  THEN
1793!
1794!--          Define vertical coordinate grid (zs grid)
1795             CALL netcdf_create_dim( id_set_3d(av), 'zs_3d',                   &
1796                                     nzt_soil-nzb_soil+1, id_dim_zs_3d(av), 70 )
1797             CALL netcdf_create_var( id_set_3d(av), (/ id_dim_zs_3d(av) /),    &
1798                                     'zs_3d', NF90_DOUBLE, id_var_zs_3d(av),   &
1799                                     'meters', '', 71, 72, 00 )
1800
1801          ENDIF
1802
1803!
1804!--       Define the variables
1805          var_list = ';'
1806          i = 1
1807
1808          DO WHILE ( do3d(av,i)(1:1) /= ' ' )
1809!
1810!--          Temporary solution to account for data output within the new urban
1811!--          surface model (urban_surface_mod.f90), see also SELECT CASE ( trimvar )
1812             trimvar = TRIM( do3d(av,i) )
1813             IF ( urban_surface  .AND.  trimvar(1:4) == 'usm_' )  THEN
1814                trimvar = 'usm_output'
1815             ENDIF
1816!
1817!--          Check for the grid
1818             found = .FALSE.
1819             SELECT CASE ( trimvar )
1820!
1821!--             Most variables are defined on the scalar grid
1822                CASE ( 'e', 'nc', 'nr', 'p', 'pc', 'pr', 'prr',   &
1823                       'q', 'qc', 'ql', 'ql_c', 'ql_v', 'ql_vp', 'qr', 'qv',   &
1824                       's', 'theta', 'thetal', 'thetav' )
1825
1826                   grid_x = 'x'
1827                   grid_y = 'y'
1828                   grid_z = 'zu'
1829!
1830!--             u grid
1831                CASE ( 'u' )
1832
1833                   grid_x = 'xu'
1834                   grid_y = 'y'
1835                   grid_z = 'zu'
1836!
1837!--             v grid
1838                CASE ( 'v' )
1839
1840                   grid_x = 'x'
1841                   grid_y = 'yv'
1842                   grid_z = 'zu'
1843!
1844!--             w grid
1845                CASE ( 'w' )
1846
1847                   grid_x = 'x'
1848                   grid_y = 'y'
1849                   grid_z = 'zw'
1850
1851!             
1852!--             Block of urban surface model outputs   
1853                CASE ( 'usm_output' )
1854                   CALL usm_define_netcdf_grid( do3d(av,i), found, &
1855                                                   grid_x, grid_y, grid_z )
1856
1857                CASE DEFAULT
1858
1859                   CALL tcm_define_netcdf_grid( do3d(av,i), found, &
1860                                                   grid_x, grid_y, grid_z )
1861
1862!
1863!--                Check for land surface quantities
1864                   IF ( .NOT. found .AND. land_surface )  THEN
1865                      CALL lsm_define_netcdf_grid( do3d(av,i), found, grid_x,  &
1866                                                   grid_y, grid_z )
1867                   ENDIF
1868!
1869!--                Check for ocean quantities
1870                   IF ( .NOT. found  .AND.  ocean_mode )  THEN
1871                      CALL ocean_define_netcdf_grid( do3d(av,i), found,  &
1872                                                     grid_x, grid_y, grid_z )
1873                   ENDIF
1874
1875!
1876!--                Check for plant canopy quantities
1877                   IF ( .NOT. found  .AND.  plant_canopy )  THEN
1878                      CALL pcm_define_netcdf_grid( do3d(av,i), found, grid_x,  &
1879                                                   grid_y, grid_z )
1880                   ENDIF
1881
1882!
1883!--                Check for radiation quantities
1884                   IF ( .NOT. found  .AND.  radiation )  THEN
1885                      CALL radiation_define_netcdf_grid( do3d(av,i), found,    &
1886                                                         grid_x, grid_y,       &
1887                                                         grid_z )
1888                   ENDIF
1889
1890!--                Check for gust module quantities
1891                   IF ( .NOT. found  .AND.  gust_module_enabled )  THEN
1892                      CALL gust_define_netcdf_grid( do3d(av,i), found, grid_x, &
1893                                                    grid_y, grid_z )
1894                   ENDIF
1895
1896!
1897!--                Check for biometeorology quantities
1898                   IF ( .NOT. found  .AND.  biometeorology )  THEN
1899                      CALL bio_define_netcdf_grid( do3d(av,i), found,          &
1900                                                   grid_x, grid_y, grid_z )
1901                   ENDIF
1902
1903!
1904!--                Check for chemistry quantities                   
1905                   IF ( .NOT. found  .AND.  air_chemistry )  THEN
1906                      CALL chem_define_netcdf_grid( do3d(av,i), found,         &
1907                                                    grid_x, grid_y, grid_z )
1908                   ENDIF
1909
1910!
1911!--                Check for SALSA quantities
1912                   IF ( .NOT. found  .AND.  salsa )  THEN
1913                      CALL salsa_define_netcdf_grid( do3d(av,i), found, grid_x,&
1914                                                     grid_y, grid_z )
1915                   ENDIF                 
1916!                   
1917!--                Check for user-defined quantities
1918                   IF ( .NOT. found )  THEN
1919                      CALL user_define_netcdf_grid( do3d(av,i), found, grid_x, &
1920                                                    grid_y, grid_z )
1921                   ENDIF
1922                                                 
1923                   IF ( .NOT. found )  THEN
1924                      WRITE ( message_string, * ) 'no grid defined for varia', &
1925                                                  'ble ', TRIM( do3d(av,i) )
1926                      CALL message( 'define_netcdf_header', 'PA0244', 0, 1, 0, &
1927                                    6, 0 )
1928                   ENDIF
1929
1930             END SELECT
1931
1932!
1933!--          Select the respective dimension ids
1934             IF ( grid_x == 'x' )  THEN
1935                id_x = id_dim_x_3d(av)
1936             ELSEIF ( grid_x == 'xu' )  THEN
1937                id_x = id_dim_xu_3d(av)
1938             ENDIF
1939
1940             IF ( grid_y == 'y' )  THEN
1941                id_y = id_dim_y_3d(av)
1942             ELSEIF ( grid_y == 'yv' )  THEN
1943                id_y = id_dim_yv_3d(av)
1944             ENDIF
1945
1946             IF ( grid_z == 'zu' )  THEN
1947                id_z = id_dim_zu_3d(av)
1948             ELSEIF ( grid_z == 'zw' )  THEN
1949                id_z = id_dim_zw_3d(av)
1950             ELSEIF ( grid_z == 'zs' )  THEN
1951                id_z = id_dim_zs_3d(av)
1952             ENDIF
1953
1954!
1955!--          Define the grid
1956             CALL netcdf_create_var( id_set_3d(av),(/ id_x, id_y, id_z,        &
1957                                     id_dim_time_3d(av) /), do3d(av,i),        &
1958                                     nc_precision(4), id_var_do3d(av,i),       &
1959                                     TRIM( do3d_unit(av,i) ), do3d(av,i), 79,  &
1960                                     80, 357, .TRUE. )
1961#if defined( __netcdf4_parallel )
1962             IF ( netcdf_data_format > 4 )  THEN
1963!
1964!--             Set no fill for every variable to increase performance.
1965                nc_stat = NF90_DEF_VAR_FILL( id_set_3d(av),     &
1966                                             id_var_do3d(av,i), &
1967                                             1, 0 )
1968                CALL netcdf_handle_error( 'netcdf_define_header', 532 )
1969!
1970!--             Set collective io operations for parallel io
1971                nc_stat = NF90_VAR_PAR_ACCESS( id_set_3d(av),     &
1972                                               id_var_do3d(av,i), &
1973                                               NF90_COLLECTIVE )
1974                CALL netcdf_handle_error( 'netcdf_define_header', 445 )
1975             ENDIF
1976#endif
1977             var_list = TRIM( var_list ) // TRIM( do3d(av,i) ) // ';'
1978
1979             i = i + 1
1980
1981          ENDDO
1982
1983!
1984!--       No arrays to output
1985          IF ( i == 1 )  RETURN
1986
1987!
1988!--       Write the list of variables as global attribute (this is used by
1989!--       restart runs and by combine_plot_fields)
1990          nc_stat = NF90_PUT_ATT( id_set_3d(av), NF90_GLOBAL, 'VAR_LIST', &
1991                                  var_list )
1992          CALL netcdf_handle_error( 'netcdf_define_header', 81 )
1993
1994!
1995!--       Set general no fill, otherwise the performance drops significantly for
1996!--       parallel output.
1997          nc_stat = NF90_SET_FILL( id_set_3d(av), NF90_NOFILL, oldmode )
1998          CALL netcdf_handle_error( 'netcdf_define_header', 528 )
1999
2000!
2001!--       Leave netCDF define mode
2002          nc_stat = NF90_ENDDEF( id_set_3d(av) )
2003          CALL netcdf_handle_error( 'netcdf_define_header', 82 )
2004
2005!
2006!--       These data are only written by PE0 for parallel output to increase
2007!--       the performance.
2008          IF ( myid == 0  .OR.  netcdf_data_format < 5 )  THEN
2009!
2010!--          Write data for x (shifted by +dx/2) and xu axis
2011             ALLOCATE( netcdf_data(0:nx) )
2012
2013             DO  i = 0, nx
2014                netcdf_data(i) = ( i + 0.5 ) * dx
2015             ENDDO
2016
2017             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_x_3d(av),  &
2018                                     netcdf_data, start = (/ 1 /),    &
2019                                     count = (/ nx+1 /) )
2020             CALL netcdf_handle_error( 'netcdf_define_header', 83 )
2021
2022             DO  i = 0, nx
2023                netcdf_data(i) = i * dx
2024             ENDDO
2025
2026             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_xu_3d(av), &
2027                                     netcdf_data, start = (/ 1 /),    &
2028                                     count = (/ nx+1 /) )
2029             CALL netcdf_handle_error( 'netcdf_define_header', 385 )
2030
2031             DEALLOCATE( netcdf_data )
2032
2033!
2034!--          Write data for y (shifted by +dy/2) and yv axis
2035             ALLOCATE( netcdf_data(0:ny) )
2036
2037             DO  i = 0, ny
2038                netcdf_data(i) = ( i + 0.5_wp ) * dy
2039             ENDDO
2040
2041             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_y_3d(av),  &
2042                                     netcdf_data, start = (/ 1 /),    &
2043                                     count = (/ ny+1 /) )
2044             CALL netcdf_handle_error( 'netcdf_define_header', 84 )
2045
2046             DO  i = 0, ny
2047                netcdf_data(i) = i * dy
2048             ENDDO
2049
2050             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_yv_3d(av), &
2051                                     netcdf_data, start = (/ 1 /),    &
2052                                     count = (/ ny+1 /))
2053             CALL netcdf_handle_error( 'netcdf_define_header', 387 )
2054
2055             DEALLOCATE( netcdf_data )
2056
2057!
2058!--          Write UTM coordinates
2059             IF ( init_model%rotation_angle == 0.0_wp )  THEN
2060!
2061!--             1D in case of no rotation
2062                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
2063!
2064!--             x coordinates
2065                ALLOCATE( netcdf_data(0:nx) )
2066                DO  k = 0, 2
2067!               
2068!--                Scalar grid points
2069                   IF ( k == 0 )  THEN
2070                      shift_x = 0.5
2071!               
2072!--                u grid points
2073                   ELSEIF ( k == 1 )  THEN
2074                      shift_x = 0.0
2075!               
2076!--                v grid points
2077                   ELSEIF ( k == 2 )  THEN
2078                      shift_x = 0.5
2079                   ENDIF
2080               
2081                   DO  i = 0, nx
2082                     netcdf_data(i) = init_model%origin_x            &
2083                                    + cos_ra * ( i + shift_x ) * dx
2084                   ENDDO
2085               
2086                   nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_eutm_3d(av,k),&
2087                                           netcdf_data, start = (/ 1 /),   &
2088                                           count = (/ nx+1 /) )
2089                   CALL netcdf_handle_error( 'netcdf_define_header', 555 )
2090
2091                ENDDO
2092                DEALLOCATE( netcdf_data )
2093!
2094!--             y coordinates
2095                ALLOCATE( netcdf_data(0:ny) )
2096                DO  k = 0, 2
2097!
2098!--                Scalar grid points
2099                   IF ( k == 0 )  THEN
2100                      shift_y = 0.5
2101!
2102!--                u grid points
2103                   ELSEIF ( k == 1 )  THEN
2104                      shift_y = 0.5
2105!
2106!--                v grid points
2107                   ELSEIF ( k == 2 )  THEN
2108                      shift_y = 0.0
2109                   ENDIF
2110
2111                   DO  j = 0, ny
2112                      netcdf_data(j) = init_model%origin_y            &
2113                                     + cos_ra * ( j + shift_y ) * dy
2114                   ENDDO
2115
2116                   nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_nutm_3d(av,k),&
2117                                           netcdf_data, start = (/ 1 /),   &
2118                                           count = (/ ny+1 /) )
2119                   CALL netcdf_handle_error( 'netcdf_define_header', 556 )
2120
2121                ENDDO
2122                DEALLOCATE( netcdf_data )
2123
2124             ELSE
2125!
2126!--             2D in case of rotation
2127                ALLOCATE( netcdf_data_2d(0:nx,0:ny) )
2128                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
2129                sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
2130               
2131                DO  k = 0, 2
2132!               
2133!--               Scalar grid points
2134                  IF ( k == 0 )  THEN
2135                     shift_x = 0.5 ; shift_y = 0.5
2136!               
2137!--               u grid points
2138                  ELSEIF ( k == 1 )  THEN
2139                     shift_x = 0.0 ; shift_y = 0.5
2140!               
2141!--               v grid points
2142                  ELSEIF ( k == 2 )  THEN
2143                     shift_x = 0.5 ; shift_y = 0.0
2144                  ENDIF
2145               
2146                  DO  j = 0, ny
2147                     DO  i = 0, nx
2148                        netcdf_data_2d(i,j) = init_model%origin_x            &
2149                                            + cos_ra * ( i + shift_x ) * dx  &
2150                                            + sin_ra * ( j + shift_y ) * dy
2151                     ENDDO
2152                  ENDDO
2153               
2154                  nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_eutm_3d(av,k),  &
2155                                          netcdf_data_2d, start = (/ 1, 1 /),   &
2156                                          count = (/ nx+1, ny+1 /) )
2157                  CALL netcdf_handle_error( 'netcdf_define_header', 555 )
2158               
2159                  DO  j = 0, ny
2160                     DO  i = 0, nx
2161                        netcdf_data_2d(i,j) = init_model%origin_y            &
2162                                            - sin_ra * ( i + shift_x ) * dx  &
2163                                            + cos_ra * ( j + shift_y ) * dy
2164                     ENDDO
2165                  ENDDO
2166               
2167                  nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_nutm_3d(av,k),  &
2168                                          netcdf_data_2d, start = (/ 1, 1 /),   &
2169                                          count = (/ nx+1, ny+1 /) )
2170                  CALL netcdf_handle_error( 'netcdf_define_header', 556 )
2171               
2172                ENDDO
2173                DEALLOCATE( netcdf_data_2d )
2174             ENDIF
2175!
2176!--          Write zu and zw data (vertical axes)
2177             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zu_3d(av),  &
2178                                     zu(nzb:nz_do3d), start = (/ 1 /), &
2179                                     count = (/ nz_do3d-nzb+1 /) )
2180             CALL netcdf_handle_error( 'netcdf_define_header', 85 )
2181
2182
2183             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zw_3d(av),  &
2184                                     zw(nzb:nz_do3d), start = (/ 1 /), &
2185                                     count = (/ nz_do3d-nzb+1 /) )
2186             CALL netcdf_handle_error( 'netcdf_define_header', 86 )
2187
2188             IF ( land_surface )  THEN
2189!
2190!--             Write zs grid
2191                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zs_3d(av),  &
2192                                        - zs(nzb_soil:nzt_soil), start = (/ 1 /), &
2193                                        count = (/ nzt_soil-nzb_soil+1 /) )
2194                CALL netcdf_handle_error( 'netcdf_define_header', 86 )
2195             ENDIF
2196
2197          ENDIF
2198!
2199!--       Write lon and lat data. Only for parallel output.
2200          IF ( netcdf_data_format > 4 )  THEN
2201
2202             ALLOCATE( lat(nxl:nxr,nys:nyn) )
2203             ALLOCATE( lon(nxl:nxr,nys:nyn) )
2204             cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
2205             sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
2206
2207             DO  k = 0, 2
2208!               
2209!--             Scalar grid points
2210                IF ( k == 0 )  THEN
2211                   shift_x = 0.5 ; shift_y = 0.5
2212!               
2213!--             u grid points
2214                ELSEIF ( k == 1 )  THEN
2215                   shift_x = 0.0 ; shift_y = 0.5
2216!               
2217!--             v grid points
2218                ELSEIF ( k == 2 )  THEN
2219                   shift_x = 0.5 ; shift_y = 0.0
2220                ENDIF
2221
2222                DO  j = nys, nyn
2223                   DO  i = nxl, nxr
2224                      eutm = init_model%origin_x            &
2225                           + cos_ra * ( i + shift_x ) * dx  &
2226                           + sin_ra * ( j + shift_y ) * dy
2227                      nutm = init_model%origin_y            &
2228                           - sin_ra * ( i + shift_x ) * dx  &
2229                           + cos_ra * ( j + shift_y ) * dy
2230
2231                      CALL  convert_utm_to_geographic( crs_list,          &
2232                                                       eutm, nutm,        &
2233                                                       lon(i,j), lat(i,j) )
2234                   ENDDO
2235                ENDDO
2236
2237                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_lon_3d(av,k), &
2238                                     lon, start = (/ nxl+1, nys+1 /),       &
2239                                     count = (/ nxr-nxl+1, nyn-nys+1 /) )
2240                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
2241
2242                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_lat_3d(av,k), &
2243                                     lat, start = (/ nxl+1, nys+1 /),       &
2244                                     count = (/ nxr-nxl+1, nyn-nys+1 /) )
2245                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
2246             ENDDO
2247
2248             DEALLOCATE( lat )
2249             DEALLOCATE( lon )
2250
2251          ENDIF
2252!
2253!--       In case of non-flat topography write height information. Only for
2254!--       parallel netcdf output.
2255          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
2256               netcdf_data_format > 4 )  THEN
2257
2258!             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
2259!                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
2260!                                        zu_s_inner(nxl:nxr+1,nys:nyn),         &
2261!                                        start = (/ nxl+1, nys+1 /),            &
2262!                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
2263!             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
2264!                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
2265!                                        zu_s_inner(nxl:nxr,nys:nyn+1),         &
2266!                                        start = (/ nxl+1, nys+1 /),            &
2267!                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
2268!             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
2269!                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
2270!                                        zu_s_inner(nxl:nxr+1,nys:nyn+1),       &
2271!                                        start = (/ nxl+1, nys+1 /),            &
2272!                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
2273!             ELSE
2274                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
2275                                        zu_s_inner(nxl:nxr,nys:nyn),           &
2276                                        start = (/ nxl+1, nys+1 /),            &
2277                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
2278!             ENDIF
2279             CALL netcdf_handle_error( 'netcdf_define_header', 419 )
2280
2281!             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
2282!                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
2283!                                        zw_w_inner(nxl:nxr+1,nys:nyn),         &
2284!                                        start = (/ nxl+1, nys+1 /),            &
2285!                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
2286!             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
2287!                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
2288!                                        zw_w_inner(nxl:nxr,nys:nyn+1),         &
2289!                                        start = (/ nxl+1, nys+1 /),            &
2290!                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
2291!             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
2292!                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
2293!                                        zw_w_inner(nxl:nxr+1,nys:nyn+1),       &
2294!                                        start = (/ nxl+1, nys+1 /),            &
2295!                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
2296!             ELSE
2297                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
2298                                        zw_w_inner(nxl:nxr,nys:nyn),           &
2299                                        start = (/ nxl+1, nys+1 /),            &
2300                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
2301!             ENDIF
2302             CALL netcdf_handle_error( 'netcdf_define_header', 420 )
2303
2304          ENDIF
2305
2306       CASE ( '3d_ext' )
2307
2308!
2309!--       Get the list of variables and compare with the actual run.
2310!--       First var_list_old has to be reset, since GET_ATT does not assign
2311!--       trailing blanks.
2312          var_list_old = ' '
2313          nc_stat = NF90_GET_ATT( id_set_3d(av), NF90_GLOBAL, 'VAR_LIST', &
2314                                  var_list_old )
2315          CALL netcdf_handle_error( 'netcdf_define_header', 87 )
2316
2317          var_list = ';'
2318          i = 1
2319          DO WHILE ( do3d(av,i)(1:1) /= ' ' )
2320             var_list = TRIM(var_list) // TRIM( do3d(av,i) ) // ';'
2321             i = i + 1
2322          ENDDO
2323
2324          IF ( av == 0 )  THEN
2325             var = '(3d)'
2326          ELSE
2327             var = '(3d_av)'
2328          ENDIF
2329
2330          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
2331             message_string = 'netCDF file for volume data ' //             &
2332                              TRIM( var ) // ' from previous run found,' // &
2333                              '&but this file cannot be extended due to' // &
2334                              ' variable mismatch.' //                      &
2335                              '&New file is created instead.'
2336             CALL message( 'define_netcdf_header', 'PA0245', 0, 1, 0, 6, 0 )
2337             extend = .FALSE.
2338             RETURN
2339          ENDIF
2340
2341!
2342!--       Get and compare the number of vertical gridpoints
2343          nc_stat = NF90_INQ_VARID( id_set_3d(av), 'zu_3d', id_var_zu_3d(av) )
2344          CALL netcdf_handle_error( 'netcdf_define_header', 88 )
2345
2346          nc_stat = NF90_INQUIRE_VARIABLE( id_set_3d(av), id_var_zu_3d(av), &
2347                                           dimids = id_dim_zu_3d_old )
2348          CALL netcdf_handle_error( 'netcdf_define_header', 89 )
2349          id_dim_zu_3d(av) = id_dim_zu_3d_old(1)
2350
2351          nc_stat = NF90_INQUIRE_DIMENSION( id_set_3d(av), id_dim_zu_3d(av), &
2352                                            len = nz_old )
2353          CALL netcdf_handle_error( 'netcdf_define_header', 90 )
2354
2355          IF ( nz_do3d-nzb+1 /= nz_old )  THEN
2356              message_string = 'netCDF file for volume data ' //             &
2357                               TRIM( var ) // ' from previous run found,' // &
2358                               '&but this file cannot be extended due to' // &
2359                               ' mismatch in number of' //                   &
2360                               ' vertical grid points (nz_do3d).' //         &
2361                               '&New file is created instead.'
2362             CALL message( 'define_netcdf_header', 'PA0246', 0, 1, 0, 6, 0 )
2363             extend = .FALSE.
2364             RETURN
2365          ENDIF
2366
2367!
2368!--       Get the id of the time coordinate (unlimited coordinate) and its
2369!--       last index on the file. The next time level is pl3d..count+1.
2370!--       The current time must be larger than the last output time
2371!--       on the file.
2372          nc_stat = NF90_INQ_VARID( id_set_3d(av), 'time', id_var_time_3d(av) )
2373          CALL netcdf_handle_error( 'netcdf_define_header', 91 )
2374
2375          nc_stat = NF90_INQUIRE_VARIABLE( id_set_3d(av), id_var_time_3d(av), &
2376                                           dimids = id_dim_time_old )
2377          CALL netcdf_handle_error( 'netcdf_define_header', 92 )
2378
2379          id_dim_time_3d(av) = id_dim_time_old(1)
2380
2381          nc_stat = NF90_INQUIRE_DIMENSION( id_set_3d(av), id_dim_time_3d(av), &
2382                                            len = ntime_count )
2383          CALL netcdf_handle_error( 'netcdf_define_header', 93 )
2384
2385!
2386!--       For non-parallel output use the last output time level of the netcdf
2387!--       file because the time dimension is unlimited. In case of parallel
2388!--       output the variable ntime_count could get the value of 9*10E36 because
2389!--       the time dimension is limited.
2390          IF ( netcdf_data_format < 5 ) do3d_time_count(av) = ntime_count
2391
2392          nc_stat = NF90_GET_VAR( id_set_3d(av), id_var_time_3d(av), &
2393                                  last_time_coordinate,              &
2394                                  start = (/ do3d_time_count(av) /), &
2395                                  count = (/ 1 /) )
2396          CALL netcdf_handle_error( 'netcdf_define_header', 94 )
2397
2398          IF ( last_time_coordinate(1) >= simulated_time )  THEN
2399             message_string = 'netCDF file for volume data ' //             &
2400                              TRIM( var ) // ' from previous run found,' // &
2401                              '&but this file cannot be extended becaus' // &
2402                              'e the current output time' //                &
2403                              '&is less or equal than the last output t' // &
2404                              'ime on this file.' //                        &
2405                              '&New file is created instead.'
2406             CALL message( 'define_netcdf_header', 'PA0247', 0, 1, 0, 6, 0 )
2407             do3d_time_count(av) = 0
2408             extend = .FALSE.
2409             RETURN
2410          ENDIF
2411
2412          IF ( netcdf_data_format > 4 )  THEN
2413!
2414!--          Check if the needed number of output time levels is increased
2415!--          compared to the number of time levels in the existing file.
2416             IF ( ntdim_3d(av) > ntime_count )  THEN
2417                message_string = 'netCDF file for volume data ' // &
2418                                 TRIM( var ) // ' from previous run found,' // &
2419                                 '&but this file cannot be extended becaus' // &
2420                                 'e the number of output time levels has b' // &
2421                                 'een increased compared to the previous s' // &
2422                                 'imulation.' //                               &
2423                                 '&New file is created instead.'
2424                CALL message( 'define_netcdf_header', 'PA0388', 0, 1, 0, 6, 0 )
2425                do3d_time_count(av) = 0
2426                extend = .FALSE.
2427!
2428!--             Recalculate the needed time levels for the new file.
2429                IF ( av == 0 )  THEN
2430                   ntdim_3d(0) = CEILING(                               &
2431                           ( end_time - MAX( skip_time_do3d,            &
2432                                             simulated_time_at_begin )  &
2433                           ) / dt_do3d )
2434                   IF ( do3d_at_begin )  ntdim_3d(0) = ntdim_3d(0) + 1
2435                ELSE
2436                   ntdim_3d(1) = CEILING(                               &
2437                           ( end_time - MAX( skip_time_data_output_av,  &
2438                                             simulated_time_at_begin )  &
2439                           ) / dt_data_output_av )
2440                ENDIF
2441                RETURN
2442             ENDIF
2443          ENDIF
2444
2445!
2446!--       Dataset seems to be extendable.
2447!--       Now get the variable ids.
2448          i = 1
2449          DO WHILE ( do3d(av,i)(1:1) /= ' ' )
2450             nc_stat = NF90_INQ_VARID( id_set_3d(av), TRIM( do3d(av,i) ), &
2451                                       id_var_do3d(av,i) )
2452             CALL netcdf_handle_error( 'netcdf_define_header', 95 )
2453#if defined( __netcdf4_parallel )
2454!
2455!--          Set collective io operations for parallel io
2456             IF ( netcdf_data_format > 4 )  THEN
2457                nc_stat = NF90_VAR_PAR_ACCESS( id_set_3d(av),     &
2458                                               id_var_do3d(av,i), &
2459                                               NF90_COLLECTIVE )
2460                CALL netcdf_handle_error( 'netcdf_define_header', 453 )
2461             ENDIF
2462#endif
2463             i = i + 1
2464          ENDDO
2465
2466!
2467!--       Update the title attribute on file
2468!--       In order to avoid 'data mode' errors if updated attributes are larger
2469!--       than their original size, NF90_PUT_ATT is called in 'define mode'
2470!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
2471!--       performance loss due to data copying; an alternative strategy would be
2472!--       to ensure equal attribute size. Maybe revise later.
2473          IF ( av == 0 )  THEN
2474             time_average_text = ' '
2475          ELSE
2476             WRITE (time_average_text, '('', '',F7.1,'' s average'')') &
2477                                                            averaging_interval
2478          ENDIF
2479          nc_stat = NF90_REDEF( id_set_3d(av) )
2480          CALL netcdf_handle_error( 'netcdf_define_header', 429 )
2481          nc_stat = NF90_PUT_ATT( id_set_3d(av), NF90_GLOBAL, 'title', &
2482                                  TRIM( run_description_header ) //    &
2483                                  TRIM( time_average_text ) )
2484          CALL netcdf_handle_error( 'netcdf_define_header', 96 )
2485          nc_stat = NF90_ENDDEF( id_set_3d(av) )
2486          CALL netcdf_handle_error( 'netcdf_define_header', 430 )
2487          message_string = 'netCDF file for volume data ' //             &
2488                           TRIM( var ) // ' from previous run found.' // &
2489                           '&This file will be extended.'
2490          CALL message( 'define_netcdf_header', 'PA0248', 0, 0, 0, 6, 0 )
2491
2492
2493       CASE ( 'ag_new' )
2494
2495!
2496!--       Define some global attributes of the dataset
2497          nc_stat = NF90_PUT_ATT( id_set_agt, NF90_GLOBAL, 'title', &
2498                                  TRIM( run_description_header ) )
2499          CALL netcdf_handle_error( 'netcdf_define_header', 330 )
2500!
2501!--       Switch for unlimited time dimension
2502          IF ( agent_time_unlimited ) THEN
2503             CALL netcdf_create_dim( id_set_agt, 'time', NF90_UNLIMITED,       &
2504                                     id_dim_time_agt, 331 )
2505          ELSE
2506             CALL netcdf_create_dim( id_set_agt, 'time',                       &
2507                                     INT( ( MIN( multi_agent_system_end,       &
2508                                                 end_time ) -                  &
2509                                            multi_agent_system_start ) /       &
2510                                            dt_write_agent_data * 1.1 ),       &
2511                                     id_dim_time_agt, 331 )
2512          ENDIF
2513
2514          CALL netcdf_create_var( id_set_agt, (/ id_dim_time_agt /), 'time',   &
2515                                  NF90_REAL4, id_var_time_agt, 'seconds since '//TRIM(init_model%origin_time), 'time',  &
2516                                  332, 333, 000 )
2517          CALL netcdf_create_att( id_set_agt, id_var_time_agt, 'standard_name', 'time', 000)
2518          CALL netcdf_create_att( id_set_agt, id_var_time_agt, 'axis', 'T', 000)
2519
2520          CALL netcdf_create_dim( id_set_agt, 'agent_number',                  &
2521                                  dim_size_agtnum, id_dim_agtnum, 334 )
2522
2523          CALL netcdf_create_var( id_set_agt, (/ id_dim_agtnum /),             &
2524                                  'agent_number', NF90_REAL4,                  &
2525                                  id_var_agtnum, 'agent number', '', 335,      &
2526                                  336, 000 )
2527!
2528!--       Define variable which contains the real number of agents in use
2529          CALL netcdf_create_var( id_set_agt, (/ id_dim_time_agt /),           &
2530                                  'real_num_of_agt', NF90_REAL4,               &
2531                                  id_var_rnoa_agt, 'agent number', '', 337,    &
2532                                  338, 000 )
2533          i = 1
2534          CALL netcdf_create_var( id_set_agt, (/ id_dim_agtnum,                &
2535                                  id_dim_time_agt /), agt_var_names(i),        &
2536                                  NF90_DOUBLE, id_var_agt(i),                  &
2537                                  TRIM( agt_var_units(i) ),                    &
2538                                  TRIM( agt_var_names(i) ), 339, 340, 341 )
2539!
2540!--       Define the variables
2541          DO  i = 2, 6
2542             CALL netcdf_create_var( id_set_agt, (/ id_dim_agtnum,             &
2543                                     id_dim_time_agt /), agt_var_names(i),     &
2544                                     NF90_REAL4, id_var_agt(i),                &
2545                                     TRIM( agt_var_units(i) ),                 &
2546                                     TRIM( agt_var_names(i) ), 339, 340, 341 )
2547
2548          ENDDO
2549!
2550!--       Define vars for biometeorology
2551          CALL netcdf_create_var( id_set_agt, (/ id_dim_agtnum,                &
2552                                  id_dim_time_agt /), agt_var_names(9),        &
2553                                  nc_precision(8), id_var_agt(9),              &
2554                                  TRIM( agt_var_units(9) ),                    &
2555                                  TRIM( agt_var_names(9) ), 339, 340, 341 )
2556
2557!
2558!--       Leave netCDF define mode
2559          nc_stat = NF90_ENDDEF( id_set_agt )
2560          CALL netcdf_handle_error( 'netcdf_define_header', 342 )
2561
2562
2563!        CASE ( 'ag_ext' )
2564! !+?agent extend output for restart runs has to be adapted
2565!
2566! !
2567! !--       Get the id of the time coordinate (unlimited coordinate) and its
2568! !--       last index on the file. The next time level is prt..count+1.
2569! !--       The current time must be larger than the last output time
2570! !--       on the file.
2571!           nc_stat = NF90_INQ_VARID( id_set_agt, 'time', id_var_time_agt )
2572!           CALL netcdf_handle_error( 'netcdf_define_header', 343 )
2573!
2574!           nc_stat = NF90_INQUIRE_VARIABLE( id_set_agt, id_var_time_agt, &
2575!                                            dimids = id_dim_time_old )
2576!           CALL netcdf_handle_error( 'netcdf_define_header', 344 )
2577!           id_dim_time_agt = id_dim_time_old(1)
2578!
2579!           nc_stat = NF90_INQUIRE_DIMENSION( id_set_agt, id_dim_time_agt, &
2580!                                             len = agt_time_count )
2581!           CALL netcdf_handle_error( 'netcdf_define_header', 345 )
2582!
2583!           nc_stat = NF90_GET_VAR( id_set_agt, id_var_time_agt,  &
2584!                                   last_time_coordinate,         &
2585!                                   start = (/ agt_time_count /), &
2586!                                   count = (/ 1 /) )
2587!           CALL netcdf_handle_error( 'netcdf_define_header', 346 )
2588!
2589!           IF ( last_time_coordinate(1) >= simulated_time )  THEN
2590!              message_string = 'netCDF file for agents ' //                  &
2591!                               'from previous run found,' //                 &
2592!                               '&but this file cannot be extended becaus' // &
2593!                               'e the current output time' //                &
2594!                               '&is less or equal than the last output t' // &
2595!                               'ime on this file.' //                        &
2596!                               '&New file is created instead.'
2597!              CALL message( 'define_netcdf_header', 'PA0265', 0, 1, 0, 6, 0 )
2598!              agt_time_count = 0
2599!              extend = .FALSE.
2600!              RETURN
2601!           ENDIF
2602!
2603! !
2604! !--       Dataset seems to be extendable.
2605! !--       Now get the variable ids.
2606!           nc_stat = NF90_INQ_VARID( id_set_agt, 'real_num_of_agt', &
2607!                                     id_var_rnoa_agt )
2608!           CALL netcdf_handle_error( 'netcdf_define_header', 347 )
2609!
2610!           DO  i = 1, 17
2611!
2612!              nc_stat = NF90_INQ_VARID( id_set_agt, agt_var_names(i), &
2613!                                        id_var_prt(i) )
2614!              CALL netcdf_handle_error( 'netcdf_define_header', 348 )
2615!
2616!           ENDDO
2617!
2618!           message_string = 'netCDF file for particles ' // &
2619!                            'from previous run found.' //   &
2620!                            '&This file will be extended.'
2621!           CALL message( 'define_netcdf_header', 'PA0266', 0, 0, 0, 6, 0 )
2622         
2623
2624       CASE ( 'xy_new' )
2625
2626!
2627!--       Define some global attributes of the dataset
2628          IF ( av == 0 )  THEN
2629             CALL netcdf_create_global_atts( id_set_xy(av), 'xy', TRIM( run_description_header ), 97 )
2630             time_average_text = ' '
2631          ELSE
2632             CALL netcdf_create_global_atts( id_set_xy(av), 'xy_av', TRIM( run_description_header ), 97 )
2633             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval
2634             nc_stat = NF90_PUT_ATT( id_set_xy(av), NF90_GLOBAL, 'time_avg',   &
2635                                     TRIM( time_average_text ) )
2636             CALL netcdf_handle_error( 'netcdf_define_header', 98 )
2637          ENDIF
2638
2639!
2640!--       Define time coordinate for xy sections.
2641!--       For parallel output the time dimensions has to be limited, otherwise
2642!--       the performance drops significantly.
2643          IF ( netcdf_data_format < 5 )  THEN
2644             CALL netcdf_create_dim( id_set_xy(av), 'time', NF90_UNLIMITED,    &
2645                                     id_dim_time_xy(av), 99 )
2646          ELSE
2647             CALL netcdf_create_dim( id_set_xy(av), 'time', ntdim_2d_xy(av),   &
2648                                     id_dim_time_xy(av), 524 )
2649          ENDIF
2650
2651          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_time_xy(av) /),     &
2652                                  'time', NF90_DOUBLE, id_var_time_xy(av),     &
2653                                  'seconds since '//TRIM(init_model%origin_time), 'time', 100, 101, 000 )
2654          CALL netcdf_create_att( id_set_xy(av), id_var_time_xy(av), 'standard_name', 'time', 000)
2655          CALL netcdf_create_att( id_set_xy(av), id_var_time_xy(av), 'axis', 'T', 000)
2656!
2657!--       Define the spatial dimensions and coordinates for xy-sections.
2658!--       First, determine the number of horizontal sections to be written.
2659          IF ( section(1,1) == -9999 )  THEN
2660             RETURN
2661          ELSE
2662             ns = 1
2663             DO WHILE ( section(ns,1) /= -9999  .AND.  ns <= 100 )
2664                ns = ns + 1
2665             ENDDO
2666             ns = ns - 1
2667          ENDIF
2668
2669!
2670!--       Define vertical coordinate grid (zu grid)
2671          CALL netcdf_create_dim( id_set_xy(av), 'zu_xy', ns,                  &
2672                                  id_dim_zu_xy(av), 102 )
2673          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_zu_xy(av) /),       &
2674                                  'zu_xy', NF90_DOUBLE, id_var_zu_xy(av),      &
2675                                  'meters', '', 103, 104, 000 )
2676!
2677!--       Define vertical coordinate grid (zw grid)
2678          CALL netcdf_create_dim( id_set_xy(av), 'zw_xy', ns,                  &
2679                                  id_dim_zw_xy(av), 105 )
2680          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_zw_xy(av) /),       &
2681                                  'zw_xy', NF90_DOUBLE, id_var_zw_xy(av),      &
2682                                  'meters', '', 106, 107, 000 )
2683
2684          IF ( land_surface )  THEN
2685
2686             ns_do = 1
2687             DO WHILE ( section(ns_do,1) /= -9999  .AND.  ns_do < nzs )
2688                ns_do = ns_do + 1
2689             ENDDO
2690!
2691!--          Define vertical coordinate grid (zs grid)
2692             CALL netcdf_create_dim( id_set_xy(av), 'zs_xy', ns_do,            &
2693                                     id_dim_zs_xy(av), 539 )
2694             CALL netcdf_create_var( id_set_xy(av), (/ id_dim_zs_xy(av) /),    &
2695                                     'zs_xy', NF90_DOUBLE, id_var_zs_xy(av),   &
2696                                     'meters', '', 540, 541, 000 )
2697
2698          ENDIF
2699
2700!
2701!--       Define a pseudo vertical coordinate grid for the surface variables
2702!--       u* and t* to store their height level
2703          CALL netcdf_create_dim( id_set_xy(av), 'zu1_xy', 1,                  &
2704                                  id_dim_zu1_xy(av), 108 )
2705          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_zu1_xy(av) /),      &
2706                                  'zu1_xy', NF90_DOUBLE, id_var_zu1_xy(av),    &
2707                                  'meters', '', 109, 110, 000 )
2708!
2709!--       Define a variable to store the layer indices of the horizontal cross
2710!--       sections, too
2711          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_zu_xy(av) /),       &
2712                                  'ind_z_xy', NF90_DOUBLE,                     &
2713                                  id_var_ind_z_xy(av), 'gridpoints', '', 111,  &
2714                                  112, 000 )
2715!
2716!--       Define x-axis (for scalar position)
2717          CALL netcdf_create_dim( id_set_xy(av), 'x', nx+1, id_dim_x_xy(av),   &
2718                                  113 )
2719          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_x_xy(av) /), 'x',   &
2720                                  NF90_DOUBLE, id_var_x_xy(av), 'meters', '',  &
2721                                  114, 115, 000 )
2722!
2723!--       Define x-axis (for u position)
2724          CALL netcdf_create_dim( id_set_xy(av), 'xu', nx+1,                   &
2725                                  id_dim_xu_xy(av), 388 )
2726          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_xu_xy(av) /), 'xu', &
2727                                  NF90_DOUBLE, id_var_xu_xy(av), 'meters', '', &
2728                                  389, 390, 000 )
2729!
2730!--       Define y-axis (for scalar position)
2731          CALL netcdf_create_dim( id_set_xy(av), 'y', ny+1, id_dim_y_xy(av),   &
2732                                  116 )
2733          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_y_xy(av) /), 'y',   &
2734                                  NF90_DOUBLE, id_var_y_xy(av), 'meters', '',  &
2735                                  117, 118, 000 )
2736!
2737!--       Define y-axis (for scalar position)
2738          CALL netcdf_create_dim( id_set_xy(av), 'yv', ny+1,                   &
2739                                  id_dim_yv_xy(av), 364 )
2740          CALL netcdf_create_var( id_set_xy(av), (/ id_dim_yv_xy(av) /), 'yv', &
2741                                  NF90_DOUBLE, id_var_yv_xy(av), 'meters', '', &
2742                                  365, 366, 000 )
2743!
2744!--       Define UTM and geographic coordinates
2745          CALL define_geo_coordinates( id_set_xy(av),         &
2746                  (/ id_dim_x_xy(av), id_dim_xu_xy(av) /),    &
2747                  (/ id_dim_y_xy(av), id_dim_yv_xy(av) /),    &
2748                  id_var_eutm_xy(av,:), id_var_nutm_xy(av,:), &
2749                  id_var_lat_xy(av,:), id_var_lon_xy(av,:)    )
2750!
2751!--       Define coordinate-reference system
2752          CALL netcdf_create_crs( id_set_xy(av), 000 )
2753!
2754!--       In case of non-flat topography define 2d-arrays containing the height
2755!--       information. Only for parallel netcdf output.
2756          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
2757               netcdf_data_format > 4  )  THEN
2758!
2759!--          Define zusi = zu(nzb_s_inner)
2760             CALL netcdf_create_var( id_set_xy(av), (/ id_dim_x_xy(av),        &
2761                                     id_dim_y_xy(av) /), 'zusi', NF90_DOUBLE,  &
2762                                     id_var_zusi_xy(av), 'meters',             &
2763                                     'zu(nzb_s_inner)', 421, 422, 423 )
2764!             
2765!--          Define zwwi = zw(nzb_w_inner)
2766             CALL netcdf_create_var( id_set_xy(av), (/ id_dim_x_xy(av),        &
2767                                     id_dim_y_xy(av) /), 'zwwi', NF90_DOUBLE,  &
2768                                     id_var_zwwi_xy(av), 'meters',             &
2769                                     'zw(nzb_w_inner)', 424, 425, 426 )
2770
2771          ENDIF
2772
2773!
2774!--       Define the variables
2775          var_list = ';'
2776          i = 1
2777
2778          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
2779
2780             IF ( INDEX( do2d(av,i), 'xy' ) /= 0 )  THEN
2781!
2782!--             If there is a star in the variable name (u* or t*), it is a
2783!--             surface variable. Define it with id_dim_zu1_xy.
2784                IF ( INDEX( do2d(av,i), '*' ) /= 0 )  THEN
2785
2786                   CALL netcdf_create_var( id_set_xy(av), (/ id_dim_x_xy(av),  &
2787                                           id_dim_y_xy(av), id_dim_zu1_xy(av), &
2788                                           id_dim_time_xy(av) /), do2d(av,i),  &
2789                                           nc_precision(1), id_var_do2d(av,i), &
2790                                           TRIM( do2d_unit(av,i) ),            &
2791                                           do2d(av,i), 119, 120, 354, .TRUE. )
2792
2793                ELSE
2794
2795!
2796!--                Check for the grid
2797                   found = .FALSE.
2798                   SELECT CASE ( do2d(av,i) )
2799!
2800!--                   Most variables are defined on the zu grid
2801                      CASE ( 'e_xy', 'nc_xy', 'nr_xy', 'p_xy',                 &
2802                             'pc_xy', 'pr_xy', 'prr_xy', 'q_xy',               &
2803                             'qc_xy', 'ql_xy', 'ql_c_xy', 'ql_v_xy',           &
2804                             'ql_vp_xy', 'qr_xy', 'qv_xy',                     &
2805                             's_xy',                                           &
2806                             'theta_xy', 'thetal_xy', 'thetav_xy' )
2807
2808                         grid_x = 'x'
2809                         grid_y = 'y'
2810                         grid_z = 'zu'
2811!
2812!--                   u grid
2813                      CASE ( 'u_xy' )
2814
2815                         grid_x = 'xu'
2816                         grid_y = 'y'
2817                         grid_z = 'zu'
2818!
2819!--                   v grid
2820                      CASE ( 'v_xy' )
2821
2822                         grid_x = 'x'
2823                         grid_y = 'yv'
2824                         grid_z = 'zu'
2825!
2826!--                   w grid
2827                      CASE ( 'w_xy' )
2828
2829                         grid_x = 'x'
2830                         grid_y = 'y'
2831                         grid_z = 'zw'
2832
2833
2834                      CASE DEFAULT
2835!
2836!--                      Check for land surface quantities
2837                         IF ( land_surface )  THEN
2838                            CALL lsm_define_netcdf_grid( do2d(av,i), found,    &
2839                                                   grid_x, grid_y, grid_z )
2840                         ENDIF
2841
2842                         IF ( .NOT. found )  THEN
2843                            CALL tcm_define_netcdf_grid( do2d(av,i), found,    &
2844                                                         grid_x, grid_y,       &
2845                                                         grid_z )
2846                         ENDIF
2847
2848!
2849!--                      Check for ocean quantities
2850                         IF ( .NOT. found  .AND.  ocean_mode )  THEN
2851                            CALL ocean_define_netcdf_grid( do2d(av,i), found,  &
2852                                                           grid_x, grid_y,     &
2853                                                           grid_z )
2854                         ENDIF
2855!
2856!--                      Check for radiation quantities
2857                         IF ( .NOT. found  .AND.  radiation )  THEN
2858                            CALL radiation_define_netcdf_grid( do2d(av,i),     &
2859                                                         found, grid_x, grid_y,&
2860                                                         grid_z )
2861                         ENDIF
2862
2863!
2864!--                      Check for SALSA quantities
2865                         IF ( .NOT. found  .AND.  salsa )  THEN
2866                            CALL salsa_define_netcdf_grid( do2d(av,i), found,  &
2867                                                           grid_x, grid_y,     &
2868                                                           grid_z )
2869                         ENDIF                       
2870
2871!
2872!--                      Check for gust module quantities
2873                         IF ( .NOT. found  .AND.  gust_module_enabled )  THEN
2874                            CALL gust_define_netcdf_grid( do2d(av,i), found,   &
2875                                                          grid_x, grid_y,      &
2876                                                          grid_z )
2877                         ENDIF
2878!
2879!--                      Check for biometeorology quantities
2880                         IF ( .NOT. found  .AND.  biometeorology )  THEN
2881                            CALL bio_define_netcdf_grid( do2d( av, i), found,  &
2882                                                         grid_x, grid_y,       &
2883                                                         grid_z )
2884                         ENDIF
2885!
2886!--                      Check for chemistry quantities
2887                         IF ( .NOT. found  .AND.  air_chemistry )  THEN
2888                            CALL chem_define_netcdf_grid( do2d(av,i), found,   &
2889                                                          grid_x, grid_y,      &
2890                                                          grid_z )
2891                         ENDIF
2892
2893
2894!
2895!--                      Check for user-defined quantities
2896                         IF ( .NOT. found )  THEN
2897                            CALL user_define_netcdf_grid( do2d(av,i), found,   &
2898                                                          grid_x, grid_y,      &
2899                                                          grid_z )
2900                         ENDIF
2901
2902                         IF ( .NOT. found )  THEN
2903                            WRITE ( message_string, * ) 'no grid defined for', &
2904                                                ' variable ', TRIM( do2d(av,i) )
2905                            CALL message( 'define_netcdf_header', 'PA0244',    &
2906                                          0, 1, 0, 6, 0 )
2907                         ENDIF
2908
2909                   END SELECT
2910
2911!
2912!--                Select the respective dimension ids
2913                   IF ( grid_x == 'x' )  THEN
2914                      id_x = id_dim_x_xy(av)
2915                   ELSEIF ( grid_x == 'xu' )  THEN
2916                      id_x = id_dim_xu_xy(av)
2917                   ENDIF
2918
2919                   IF ( grid_y == 'y' )  THEN
2920                      id_y = id_dim_y_xy(av)
2921                   ELSEIF ( grid_y == 'yv' )  THEN
2922                      id_y = id_dim_yv_xy(av)
2923                   ENDIF
2924
2925                   IF ( grid_z == 'zu' )  THEN
2926                      id_z = id_dim_zu_xy(av)
2927                   ELSEIF ( grid_z == 'zw' )  THEN
2928                      id_z = id_dim_zw_xy(av)
2929                   ELSEIF ( grid_z == 'zs' )  THEN
2930                      id_z = id_dim_zs_xy(av)
2931                   ELSEIF ( grid_z == 'zu1' )  THEN
2932                      id_z = id_dim_zu1_xy(av)
2933                   ENDIF
2934
2935!
2936!--                Define the grid
2937                   CALL netcdf_create_var( id_set_xy(av), (/ id_x, id_y, id_z, &
2938                                           id_dim_time_xy(av) /), do2d(av,i),  &
2939                                           nc_precision(1), id_var_do2d(av,i), &
2940                                           TRIM( do2d_unit(av,i) ),            &
2941                                           do2d(av,i), 119, 120, 354, .TRUE. )
2942
2943                ENDIF
2944
2945#if defined( __netcdf4_parallel )
2946                IF ( netcdf_data_format > 4 )  THEN
2947!
2948!--                Set no fill for every variable to increase performance.
2949                   nc_stat = NF90_DEF_VAR_FILL( id_set_xy(av),     &
2950                                                id_var_do2d(av,i), &
2951                                                1, 0 )
2952                   CALL netcdf_handle_error( 'netcdf_define_header', 533 )
2953!
2954!--                Set collective io operations for parallel io
2955                   nc_stat = NF90_VAR_PAR_ACCESS( id_set_xy(av),     &
2956                                                  id_var_do2d(av,i), &
2957                                                  NF90_COLLECTIVE )
2958                   CALL netcdf_handle_error( 'netcdf_define_header', 448 )
2959                ENDIF
2960#endif
2961                var_list = TRIM( var_list) // TRIM( do2d(av,i) ) // ';'
2962
2963             ENDIF
2964
2965             i = i + 1
2966
2967          ENDDO
2968
2969!
2970!--       No arrays to output. Close the netcdf file and return.
2971          IF ( i == 1 )  RETURN
2972
2973!
2974!--       Write the list of variables as global attribute (this is used by
2975!--       restart runs and by combine_plot_fields)
2976          nc_stat = NF90_PUT_ATT( id_set_xy(av), NF90_GLOBAL, 'VAR_LIST', &
2977                                  var_list )
2978          CALL netcdf_handle_error( 'netcdf_define_header', 121 )
2979
2980!
2981!--       Set general no fill, otherwise the performance drops significantly for
2982!--       parallel output.
2983          nc_stat = NF90_SET_FILL( id_set_xy(av), NF90_NOFILL, oldmode )
2984          CALL netcdf_handle_error( 'netcdf_define_header', 529 )
2985
2986!
2987!--       Leave netCDF define mode
2988          nc_stat = NF90_ENDDEF( id_set_xy(av) )
2989          CALL netcdf_handle_error( 'netcdf_define_header', 122 )
2990
2991!
2992!--       These data are only written by PE0 for parallel output to increase
2993!--       the performance.
2994          IF ( myid == 0  .OR.  netcdf_data_format < 5 )  THEN
2995
2996!
2997!--          Write axis data: z_xy, x, y
2998             ALLOCATE( netcdf_data(1:ns) )
2999
3000!
3001!--          Write zu data
3002             DO  i = 1, ns
3003                IF( section(i,1) == -1 )  THEN
3004                   netcdf_data(i) = -1.0_wp  ! section averaged along z
3005                ELSE
3006                   netcdf_data(i) = zu( section(i,1) )
3007                ENDIF
3008             ENDDO
3009             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zu_xy(av), &
3010                                     netcdf_data, start = (/ 1 /),    &
3011                                     count = (/ ns /) )
3012             CALL netcdf_handle_error( 'netcdf_define_header', 123 )
3013
3014!
3015!--          Write zw data
3016             DO  i = 1, ns
3017                IF( section(i,1) == -1 )  THEN
3018                   netcdf_data(i) = -1.0_wp  ! section averaged along z
3019                ELSE
3020                   netcdf_data(i) = zw( section(i,1) )
3021                ENDIF
3022             ENDDO
3023             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zw_xy(av), &
3024                                     netcdf_data, start = (/ 1 /),    &
3025                                     count = (/ ns /) )
3026             CALL netcdf_handle_error( 'netcdf_define_header', 124 )
3027
3028!
3029!--          Write zs data
3030             IF ( land_surface )  THEN
3031                ns_do = 0
3032                DO  i = 1, ns
3033                   IF( section(i,1) == -1 )  THEN
3034                      netcdf_data(i) = 1.0_wp  ! section averaged along z
3035                      ns_do = ns_do + 1
3036                   ELSEIF ( section(i,1) < nzs )  THEN
3037                      netcdf_data(i) = - zs( section(i,1) )
3038                      ns_do = ns_do + 1
3039                   ENDIF
3040                ENDDO
3041
3042                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zs_xy(av), &
3043                                        netcdf_data(1:ns_do), start = (/ 1 /),    &
3044                                        count = (/ ns_do /) )
3045                CALL netcdf_handle_error( 'netcdf_define_header', 124 )
3046
3047             ENDIF
3048
3049!
3050!--          Write gridpoint number data
3051             netcdf_data(1:ns) = section(1:ns,1)
3052             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_ind_z_xy(av), &
3053                                     netcdf_data, start = (/ 1 /),       &
3054                                     count = (/ ns /) )
3055             CALL netcdf_handle_error( 'netcdf_define_header', 125 )
3056
3057             DEALLOCATE( netcdf_data )
3058
3059!
3060!--          Write the cross section height u*, t*
3061             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zu1_xy(av), &
3062                                     (/ zu(nzb+1) /), start = (/ 1 /), &
3063                                     count = (/ 1 /) )
3064             CALL netcdf_handle_error( 'netcdf_define_header', 126 )
3065
3066!
3067!--          Write data for x (shifted by +dx/2) and xu axis
3068             ALLOCATE( netcdf_data(0:nx) )
3069
3070             DO  i = 0, nx
3071                netcdf_data(i) = ( i + 0.5_wp ) * dx
3072             ENDDO
3073
3074             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_x_xy(av), &
3075                                     netcdf_data, start = (/ 1 /),   &
3076                                     count = (/ nx+1 /) )
3077             CALL netcdf_handle_error( 'netcdf_define_header', 127 )
3078
3079             DO  i = 0, nx
3080                netcdf_data(i) = i * dx
3081             ENDDO
3082
3083             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_xu_xy(av), &
3084                                     netcdf_data, start = (/ 1 /),    &
3085                                     count = (/ nx+1 /) )
3086             CALL netcdf_handle_error( 'netcdf_define_header', 367 )
3087
3088             DEALLOCATE( netcdf_data )
3089
3090!
3091!--          Write data for y (shifted by +dy/2) and yv axis
3092             ALLOCATE( netcdf_data(0:ny+1) )
3093
3094             DO  i = 0, ny
3095                netcdf_data(i) = ( i + 0.5_wp ) * dy
3096             ENDDO
3097
3098             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_y_xy(av), &
3099                                     netcdf_data, start = (/ 1 /),   &
3100                                     count = (/ ny+1 /))
3101             CALL netcdf_handle_error( 'netcdf_define_header', 128 )
3102
3103             DO  i = 0, ny
3104                netcdf_data(i) = i * dy
3105             ENDDO
3106
3107             nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_yv_xy(av), &
3108                                     netcdf_data, start = (/ 1 /),    &
3109                                     count = (/ ny+1 /))
3110             CALL netcdf_handle_error( 'netcdf_define_header', 368 )
3111
3112             DEALLOCATE( netcdf_data )
3113!
3114!--          Write UTM coordinates
3115             IF ( init_model%rotation_angle == 0.0_wp )  THEN
3116!
3117!--             1D in case of no rotation
3118                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
3119!
3120!--             x coordinates
3121                ALLOCATE( netcdf_data(0:nx) )
3122                DO  k = 0, 2
3123!               
3124!--                Scalar grid points
3125                   IF ( k == 0 )  THEN
3126                      shift_x = 0.5
3127!               
3128!--                u grid points
3129                   ELSEIF ( k == 1 )  THEN
3130                      shift_x = 0.0
3131!               
3132!--                v grid points
3133                   ELSEIF ( k == 2 )  THEN
3134                      shift_x = 0.5
3135                   ENDIF
3136               
3137                   DO  i = 0, nx
3138                     netcdf_data(i) = init_model%origin_x            &
3139                                    + cos_ra * ( i + shift_x ) * dx
3140                   ENDDO
3141               
3142                   nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_eutm_xy(av,k),&
3143                                           netcdf_data, start = (/ 1 /),   &
3144                                           count = (/ nx+1 /) )
3145                   CALL netcdf_handle_error( 'netcdf_define_header', 555 )
3146
3147                ENDDO
3148                DEALLOCATE( netcdf_data )
3149!
3150!--             y coordinates
3151                ALLOCATE( netcdf_data(0:ny) )
3152                DO  k = 0, 2
3153!
3154!--                Scalar grid points
3155                   IF ( k == 0 )  THEN
3156                      shift_y = 0.5
3157!
3158!--                u grid points
3159                   ELSEIF ( k == 1 )  THEN
3160                      shift_y = 0.5
3161!
3162!--                v grid points
3163                   ELSEIF ( k == 2 )  THEN
3164                      shift_y = 0.0
3165                   ENDIF
3166
3167                   DO  j = 0, ny
3168                      netcdf_data(j) = init_model%origin_y            &
3169                                     + cos_ra * ( j + shift_y ) * dy
3170                   ENDDO
3171
3172                   nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_nutm_xy(av,k),&
3173                                           netcdf_data, start = (/ 1 /),   &
3174                                           count = (/ ny+1 /) )
3175                   CALL netcdf_handle_error( 'netcdf_define_header', 556 )
3176
3177                ENDDO
3178                DEALLOCATE( netcdf_data )
3179
3180             ELSE
3181!
3182!--             2D in case of rotation
3183                ALLOCATE( netcdf_data_2d(0:nx,0:ny) )
3184                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
3185                sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
3186               
3187                DO  k = 0, 2
3188!               
3189!--               Scalar grid points
3190                  IF ( k == 0 )  THEN
3191                     shift_x = 0.5 ; shift_y = 0.5
3192!               
3193!--               u grid points
3194                  ELSEIF ( k == 1 )  THEN
3195                     shift_x = 0.0 ; shift_y = 0.5
3196!               
3197!--               v grid points
3198                  ELSEIF ( k == 2 )  THEN
3199                     shift_x = 0.5 ; shift_y = 0.0
3200                  ENDIF
3201               
3202                  DO  j = 0, ny
3203                     DO  i = 0, nx
3204                        netcdf_data_2d(i,j) = init_model%origin_x            &
3205                                            + cos_ra * ( i + shift_x ) * dx  &
3206                                            + sin_ra * ( j + shift_y ) * dy
3207                     ENDDO
3208                  ENDDO
3209               
3210                  nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_eutm_xy(av,k),  &
3211                                          netcdf_data_2d, start = (/ 1, 1 /),   &
3212                                          count = (/ nx+1, ny+1 /) )
3213                  CALL netcdf_handle_error( 'netcdf_define_header', 555 )
3214               
3215                  DO  j = 0, ny
3216                     DO  i = 0, nx
3217                        netcdf_data_2d(i,j) = init_model%origin_y            &
3218                                            - sin_ra * ( i + shift_x ) * dx  &
3219                                            + cos_ra * ( j + shift_y ) * dy
3220                     ENDDO
3221                  ENDDO
3222               
3223                  nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_nutm_xy(av,k),  &
3224                                          netcdf_data_2d, start = (/ 1, 1 /),   &
3225                                          count = (/ nx+1, ny+1 /) )
3226                  CALL netcdf_handle_error( 'netcdf_define_header', 556 )
3227
3228                ENDDO
3229                DEALLOCATE( netcdf_data_2d )
3230             ENDIF
3231
3232          ENDIF
3233!
3234!--       Write lon and lat data. Only for parallel output.
3235          IF ( netcdf_data_format > 4 )  THEN
3236
3237             ALLOCATE( lat(nxl:nxr,nys:nyn) )
3238             ALLOCATE( lon(nxl:nxr,nys:nyn) )
3239             cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
3240             sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
3241
3242             DO  k = 0, 2
3243!               
3244!--             Scalar grid points
3245                IF ( k == 0 )  THEN
3246                   shift_x = 0.5 ; shift_y = 0.5
3247!               
3248!--             u grid points
3249                ELSEIF ( k == 1 )  THEN
3250                   shift_x = 0.0 ; shift_y = 0.5
3251!               
3252!--             v grid points
3253                ELSEIF ( k == 2 )  THEN
3254                   shift_x = 0.5 ; shift_y = 0.0
3255                ENDIF
3256
3257                DO  j = nys, nyn
3258                   DO  i = nxl, nxr
3259                      eutm = init_model%origin_x            &
3260                           + cos_ra * ( i + shift_x ) * dx  &
3261                           + sin_ra * ( j + shift_y ) * dy
3262                      nutm = init_model%origin_y            &
3263                           - sin_ra * ( i + shift_x ) * dx  &
3264                           + cos_ra * ( j + shift_y ) * dy
3265
3266                      CALL  convert_utm_to_geographic( crs_list,          &
3267                                                       eutm, nutm,        &
3268                                                       lon(i,j), lat(i,j) )
3269                   ENDDO
3270                ENDDO
3271
3272                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_lon_xy(av,k), &
3273                                     lon, start = (/ nxl+1, nys+1 /),       &
3274                                     count = (/ nxr-nxl+1, nyn-nys+1 /) )
3275                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
3276
3277                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_lat_xy(av,k), &
3278                                     lat, start = (/ nxl+1, nys+1 /),       &
3279                                     count = (/ nxr-nxl+1, nyn-nys+1 /) )
3280                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
3281             ENDDO
3282
3283             DEALLOCATE( lat )
3284             DEALLOCATE( lon )
3285
3286          ENDIF
3287!
3288!--       In case of non-flat topography write height information. Only for
3289!--       parallel netcdf output.
3290          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
3291               netcdf_data_format > 4  )  THEN
3292
3293!             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
3294!                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
3295!                                        zu_s_inner(nxl:nxr+1,nys:nyn),         &
3296!                                        start = (/ nxl+1, nys+1 /),            &
3297!                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
3298!             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
3299!                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
3300!                                        zu_s_inner(nxl:nxr,nys:nyn+1),         &
3301!                                        start = (/ nxl+1, nys+1 /),            &
3302!                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
3303!             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
3304!                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
3305!                                        zu_s_inner(nxl:nxr+1,nys:nyn+1),       &
3306!                                        start = (/ nxl+1, nys+1 /),            &
3307!                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
3308!             ELSE
3309                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
3310                                        zu_s_inner(nxl:nxr,nys:nyn),           &
3311                                        start = (/ nxl+1, nys+1 /),            &
3312                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
3313!             ENDIF
3314             CALL netcdf_handle_error( 'netcdf_define_header', 427 )
3315
3316!             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
3317!                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
3318!                                        zw_w_inner(nxl:nxr+1,nys:nyn),         &
3319!                                        start = (/ nxl+1, nys+1 /),            &
3320!                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
3321!             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
3322!                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
3323!                                        zw_w_inner(nxl:nxr,nys:nyn+1),         &
3324!                                        start = (/ nxl+1, nys+1 /),            &
3325!                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
3326!             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
3327!                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
3328!                                        zw_w_inner(nxl:nxr+1,nys:nyn+1),       &
3329!                                        start = (/ nxl+1, nys+1 /),            &
3330!                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
3331!             ELSE
3332                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
3333                                        zw_w_inner(nxl:nxr,nys:nyn),           &
3334                                        start = (/ nxl+1, nys+1 /),            &
3335                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
3336!             ENDIF
3337             CALL netcdf_handle_error( 'netcdf_define_header', 428 )
3338
3339          ENDIF
3340
3341       CASE ( 'xy_ext' )
3342
3343!
3344!--       Get the list of variables and compare with the actual run.
3345!--       First var_list_old has to be reset, since GET_ATT does not assign
3346!--       trailing blanks.
3347          var_list_old = ' '
3348          nc_stat = NF90_GET_ATT( id_set_xy(av), NF90_GLOBAL, 'VAR_LIST', &
3349                                  var_list_old )
3350          CALL netcdf_handle_error( 'netcdf_define_header', 129 )
3351
3352          var_list = ';'
3353          i = 1
3354          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
3355             IF ( INDEX( do2d(av,i), 'xy' ) /= 0 )  THEN
3356                var_list = TRIM( var_list ) // TRIM( do2d(av,i) ) // ';'
3357             ENDIF
3358             i = i + 1
3359          ENDDO
3360
3361          IF ( av == 0 )  THEN
3362             var = '(xy)'
3363          ELSE
3364             var = '(xy_av)'
3365          ENDIF
3366
3367          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
3368             message_string = 'netCDF file for cross-sections ' //           &
3369                              TRIM( var ) // ' from previous run found,' //  &
3370                              '&but this file cannot be extended due to' //  &
3371                              ' variable mismatch.' //                       &
3372                              '&New file is created instead.'
3373             CALL message( 'define_netcdf_header', 'PA0249', 0, 1, 0, 6, 0 )
3374             extend = .FALSE.
3375             RETURN
3376          ENDIF
3377
3378!
3379!--       Calculate the number of current sections
3380          ns = 1
3381          DO WHILE ( section(ns,1) /= -9999  .AND.  ns <= 100 )
3382             ns = ns + 1
3383          ENDDO
3384          ns = ns - 1
3385
3386!
3387!--       Get and compare the number of horizontal cross sections
3388          nc_stat = NF90_INQ_VARID( id_set_xy(av), 'zu_xy', id_var_zu_xy(av) )
3389          CALL netcdf_handle_error( 'netcdf_define_header', 130 )
3390
3391          nc_stat = NF90_INQUIRE_VARIABLE( id_set_xy(av), id_var_zu_xy(av), &
3392                                           dimids = id_dim_zu_xy_old )
3393          CALL netcdf_handle_error( 'netcdf_define_header', 131 )
3394          id_dim_zu_xy(av) = id_dim_zu_xy_old(1)
3395
3396          nc_stat = NF90_INQUIRE_DIMENSION( id_set_xy(av), id_dim_zu_xy(av), &
3397                                            len = ns_old )
3398          CALL netcdf_handle_error( 'netcdf_define_header', 132 )
3399
3400          IF ( ns /= ns_old )  THEN
3401             message_string = 'netCDF file for cross-sections ' //          &
3402                              TRIM( var ) // ' from previous run found,' // &
3403                              '&but this file cannot be extended due to' // &
3404                              ' mismatch in number of' //                   &
3405                              ' cross sections.' //                         &
3406                              '&New file is created instead.'
3407             CALL message( 'define_netcdf_header', 'PA0250', 0, 1, 0, 6, 0 )
3408             extend = .FALSE.
3409             RETURN
3410          ENDIF
3411
3412!
3413!--       Get and compare the heights of the cross sections
3414          ALLOCATE( netcdf_data(1:ns_old) )
3415
3416          nc_stat = NF90_GET_VAR( id_set_xy(av), id_var_zu_xy(av), netcdf_data )
3417          CALL netcdf_handle_error( 'netcdf_define_header', 133 )
3418
3419          DO  i = 1, ns
3420             IF ( section(i,1) /= -1 )  THEN
3421                IF ( zu(section(i,1)) /= netcdf_data(i) )  THEN
3422                   message_string = 'netCDF file for cross-sections ' //       &
3423                               TRIM( var ) // ' from previous run found,' //   &
3424                               ' but this file cannot be extended' //          &
3425                               ' due to mismatch in cross' //                  &
3426                               ' section levels.' //                           &
3427                               ' New file is created instead.'
3428                   CALL message( 'define_netcdf_header', 'PA0251',             &
3429                                                                 0, 1, 0, 6, 0 )
3430                   extend = .FALSE.
3431                   RETURN
3432                ENDIF
3433             ELSE
3434                IF ( -1.0_wp /= netcdf_data(i) )  THEN
3435                   message_string = 'netCDF file for cross-sections ' //       &
3436                               TRIM( var ) // ' from previous run found,' //   &
3437                               ' but this file cannot be extended' //          &
3438                               ' due to mismatch in cross' //                  &
3439                               ' section levels.' //                           &
3440                               ' New file is created instead.'
3441                   CALL message( 'define_netcdf_header', 'PA0251',             &
3442                                                                 0, 1, 0, 6, 0 )
3443                   extend = .FALSE.
3444                   RETURN
3445                ENDIF
3446             ENDIF
3447          ENDDO
3448
3449          DEALLOCATE( netcdf_data )
3450
3451!
3452!--       Get the id of the time coordinate (unlimited coordinate) and its
3453!--       last index on the file. The next time level is do2d..count+1.
3454!--       The current time must be larger than the last output time
3455!--       on the file.
3456          nc_stat = NF90_INQ_VARID( id_set_xy(av), 'time', id_var_time_xy(av) )
3457          CALL netcdf_handle_error( 'netcdf_define_header', 134 )
3458
3459          nc_stat = NF90_INQUIRE_VARIABLE( id_set_xy(av), id_var_time_xy(av), &
3460                                           dimids = id_dim_time_old )
3461          CALL netcdf_handle_error( 'netcdf_define_header', 135 )
3462          id_dim_time_xy(av) = id_dim_time_old(1)
3463
3464          nc_stat = NF90_INQUIRE_DIMENSION( id_set_xy(av), id_dim_time_xy(av), &
3465                                            len = ntime_count )
3466          CALL netcdf_handle_error( 'netcdf_define_header', 136 )
3467
3468!
3469!--       For non-parallel output use the last output time level of the netcdf
3470!--       file because the time dimension is unlimited. In case of parallel
3471!--       output the variable ntime_count could get the value of 9*10E36 because
3472!--       the time dimension is limited.
3473          IF ( netcdf_data_format < 5 ) do2d_xy_time_count(av) = ntime_count
3474
3475          nc_stat = NF90_GET_VAR( id_set_xy(av), id_var_time_xy(av),           &
3476                                  last_time_coordinate,                        &
3477                                  start = (/ do2d_xy_time_count(av) /),        &
3478                                  count = (/ 1 /) )
3479          CALL netcdf_handle_error( 'netcdf_define_header', 137 )
3480
3481          IF ( last_time_coordinate(1) >= simulated_time )  THEN
3482             message_string = 'netCDF file for cross sections ' //             &
3483                              TRIM( var ) // ' from previous run found,' //    &
3484                              '&but this file cannot be extended becaus' //    &
3485                              'e the current output time' //                   &
3486                              '&is less or equal than the last output t' //    &
3487                              'ime on this file.' //                           &
3488                              '&New file is created instead.'
3489             CALL message( 'define_netcdf_header', 'PA0252', 0, 1, 0, 6, 0 )
3490             do2d_xy_time_count(av) = 0
3491             extend = .FALSE.
3492             RETURN
3493          ENDIF
3494
3495          IF ( netcdf_data_format > 4 )  THEN
3496!
3497!--          Check if the needed number of output time levels is increased
3498!--          compared to the number of time levels in the existing file.
3499             IF ( ntdim_2d_xy(av) > ntime_count )  THEN
3500                message_string = 'netCDF file for cross sections ' //          &
3501                                 TRIM( var ) // ' from previous run found,' // &
3502                                 '&but this file cannot be extended becaus' // &
3503                                 'e the number of output time levels has b' // &
3504                                 'een increased compared to the previous s' // &
3505                                 'imulation.' //                               &
3506                                 '&New file is created instead.'
3507                CALL message( 'define_netcdf_header', 'PA0389', 0, 1, 0, 6, 0 )
3508                do2d_xy_time_count(av) = 0
3509                extend = .FALSE.
3510!
3511!--             Recalculate the needed time levels for the new file.
3512                IF ( av == 0 )  THEN
3513                   ntdim_2d_xy(0) = CEILING(                            &
3514                           ( end_time - MAX( skip_time_do2d_xy,         &
3515                                             simulated_time_at_begin )  &
3516                           ) / dt_do2d_xy )
3517                   IF ( do2d_at_begin )  ntdim_2d_xy(0) = ntdim_2d_xy(0) + 1
3518                ELSE
3519                   ntdim_2d_xy(1) = CEILING(                            &
3520                           ( end_time - MAX( skip_time_data_output_av,  &
3521                                             simulated_time_at_begin )  &
3522                           ) / dt_data_output_av )
3523                ENDIF
3524                RETURN
3525             ENDIF
3526          ENDIF
3527
3528!
3529!--       Dataset seems to be extendable.
3530!--       Now get the variable ids.
3531          i = 1
3532          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
3533             IF ( INDEX( do2d(av,i), 'xy' ) /= 0 )  THEN
3534                nc_stat = NF90_INQ_VARID( id_set_xy(av), do2d(av,i), &
3535                                          id_var_do2d(av,i) )
3536                CALL netcdf_handle_error( 'netcdf_define_header', 138 )
3537#if defined( __netcdf4_parallel )
3538!
3539!--             Set collective io operations for parallel io
3540                IF ( netcdf_data_format > 4 )  THEN
3541                   nc_stat = NF90_VAR_PAR_ACCESS( id_set_xy(av),     &
3542                                                  id_var_do2d(av,i), &
3543                                                  NF90_COLLECTIVE )
3544                   CALL netcdf_handle_error( 'netcdf_define_header', 454 )
3545                ENDIF
3546#endif
3547             ENDIF
3548             i = i + 1
3549          ENDDO
3550
3551!
3552!--       Update the title attribute on file
3553!--       In order to avoid 'data mode' errors if updated attributes are larger
3554!--       than their original size, NF90_PUT_ATT is called in 'define mode'
3555!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
3556!--       performance loss due to data copying; an alternative strategy would be
3557!--       to ensure equal attribute size in a job chain. Maybe revise later.
3558          IF ( av == 0 )  THEN
3559             time_average_text = ' '
3560          ELSE
3561             WRITE (time_average_text, '('', '',F7.1,'' s average'')') &
3562                                                            averaging_interval
3563          ENDIF
3564          nc_stat = NF90_REDEF( id_set_xy(av) )
3565          CALL netcdf_handle_error( 'netcdf_define_header', 431 )
3566          nc_stat = NF90_PUT_ATT( id_set_xy(av), NF90_GLOBAL, 'title',         &
3567                                  TRIM( run_description_header ) //            &
3568                                  TRIM( time_average_text ) )
3569          CALL netcdf_handle_error( 'netcdf_define_header', 139 )
3570          nc_stat = NF90_ENDDEF( id_set_xy(av) )
3571          CALL netcdf_handle_error( 'netcdf_define_header', 432 )
3572          message_string = 'netCDF file for cross-sections ' //                &
3573                            TRIM( var ) // ' from previous run found.' //      &
3574                           '&This file will be extended.'
3575          CALL message( 'define_netcdf_header', 'PA0253', 0, 0, 0, 6, 0 )
3576         
3577
3578       CASE ( 'xz_new' )
3579
3580!
3581!--       Define some global attributes of the dataset
3582          IF ( av == 0 )  THEN
3583             CALL netcdf_create_global_atts( id_set_xz(av), 'xz', TRIM( run_description_header ), 140 )
3584             time_average_text = ' '
3585          ELSE
3586             CALL netcdf_create_global_atts( id_set_xz(av), 'xz_av', TRIM( run_description_header ), 140 )
3587             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval
3588             nc_stat = NF90_PUT_ATT( id_set_xz(av), NF90_GLOBAL, 'time_avg',   &
3589                                     TRIM( time_average_text ) )
3590             CALL netcdf_handle_error( 'netcdf_define_header', 141 )
3591          ENDIF
3592
3593!
3594!--       Define time coordinate for xz sections.
3595!--       For parallel output the time dimensions has to be limited, otherwise
3596!--       the performance drops significantly.
3597          IF ( netcdf_data_format < 5 )  THEN
3598             CALL netcdf_create_dim( id_set_xz(av), 'time', NF90_UNLIMITED,    &
3599                                     id_dim_time_xz(av), 142 )
3600          ELSE
3601             CALL netcdf_create_dim( id_set_xz(av), 'time', ntdim_2d_xz(av),   &
3602                                     id_dim_time_xz(av), 525 )
3603          ENDIF
3604
3605          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_time_xz(av) /),     &
3606                                  'time', NF90_DOUBLE, id_var_time_xz(av),     &
3607                                  'seconds since '//TRIM(init_model%origin_time), 'time', 143, 144, 000 )
3608          CALL netcdf_create_att( id_set_xz(av), id_var_time_xz(av), 'standard_name', 'time', 000)
3609          CALL netcdf_create_att( id_set_xz(av), id_var_time_xz(av), 'axis', 'T', 000)
3610!
3611!--       Define the spatial dimensions and coordinates for xz-sections.
3612!--       First, determine the number of vertical sections to be written.
3613          IF ( section(1,2) == -9999 )  THEN
3614             RETURN
3615          ELSE
3616             ns = 1
3617             DO WHILE ( section(ns,2) /= -9999  .AND.  ns <= 100 )
3618                ns = ns + 1
3619             ENDDO
3620             ns = ns - 1
3621          ENDIF
3622
3623!
3624!--       Define y-axis (for scalar position)
3625          CALL netcdf_create_dim( id_set_xz(av), 'y_xz', ns, id_dim_y_xz(av),  &
3626                                  145 )
3627          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_y_xz(av) /),        &
3628                                  'y_xz', NF90_DOUBLE, id_var_y_xz(av),        &
3629                                  'meters', '', 146, 147, 000 )
3630!
3631!--       Define y-axis (for v position)
3632          CALL netcdf_create_dim( id_set_xz(av), 'yv_xz', ns,                  &
3633                                  id_dim_yv_xz(av), 369 )
3634          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_yv_xz(av) /),       &
3635                                  'yv_xz', NF90_DOUBLE, id_var_yv_xz(av),      &
3636                                  'meters', '', 370, 371, 000 )
3637!
3638!--       Define a variable to store the layer indices of the vertical cross
3639!--       sections
3640          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_y_xz(av) /),        &
3641                                  'ind_y_xz', NF90_DOUBLE,                     &
3642                                  id_var_ind_y_xz(av), 'gridpoints', '', 148,  &
3643                                  149, 000 )
3644!
3645!--       Define x-axis (for scalar position)
3646          CALL netcdf_create_dim( id_set_xz(av), 'x', nx+1, id_dim_x_xz(av),   &
3647                                  150 )
3648          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_x_xz(av) /), 'x',   &
3649                                  NF90_DOUBLE, id_var_x_xz(av), 'meters', '',  &
3650                                  151, 152, 000 )
3651!
3652!--       Define x-axis (for u position)
3653          CALL netcdf_create_dim( id_set_xz(av), 'xu', nx+1, id_dim_xu_xz(av), &
3654                                  372 )
3655          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_xu_xz(av) /), 'xu', &
3656                                  NF90_DOUBLE, id_var_xu_xz(av), 'meters', '', &
3657                                  373, 374, 000 )
3658!
3659!--       Define the three z-axes (zu, zw, and zs)
3660          CALL netcdf_create_dim( id_set_xz(av), 'zu', nz+2, id_dim_zu_xz(av), &
3661                                  153 )
3662          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_zu_xz(av) /), 'zu', &
3663                                  NF90_DOUBLE, id_var_zu_xz(av), 'meters', '', &
3664                                  154, 155, 000 )
3665          CALL netcdf_create_dim( id_set_xz(av), 'zw', nz+2, id_dim_zw_xz(av), &
3666                                  156 )
3667          CALL netcdf_create_var( id_set_xz(av), (/ id_dim_zw_xz(av) /), 'zw', &
3668                                  NF90_DOUBLE, id_var_zw_xz(av), 'meters', '', &
3669                                  157, 158, 000 )
3670!
3671!--       Define UTM and geographic coordinates
3672          CALL define_geo_coordinates( id_set_xz(av),         &
3673                  (/ id_dim_x_xz(av), id_dim_xu_xz(av) /),    &
3674                  (/ id_dim_y_xz(av), id_dim_yv_xz(av) /),    &
3675                  id_var_eutm_xz(av,:), id_var_nutm_xz(av,:), &
3676                  id_var_lat_xz(av,:), id_var_lon_xz(av,:)    )
3677!
3678!--       Define coordinate-reference system
3679          CALL netcdf_create_crs( id_set_xz(av), 000 )
3680
3681          IF ( land_surface )  THEN
3682
3683             CALL netcdf_create_dim( id_set_xz(av), 'zs', nzs,                 &
3684                                     id_dim_zs_xz(av), 542 )
3685             CALL netcdf_create_var( id_set_xz(av), (/ id_dim_zs_xz(av) /),    &
3686                                     'zs', NF90_DOUBLE, id_var_zs_xz(av),      &
3687                                     'meters', '', 543, 544, 000 )
3688
3689          ENDIF
3690
3691!
3692!--       Define the variables
3693          var_list = ';'
3694          i = 1
3695
3696          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
3697
3698             IF ( INDEX( do2d(av,i), 'xz' ) /= 0 )  THEN
3699
3700!
3701!--             Check for the grid
3702                found = .FALSE.
3703                SELECT CASE ( do2d(av,i) )
3704!
3705!--                Most variables are defined on the zu grid
3706                   CASE ( 'e_xz', 'nc_xz', 'nr_xz', 'p_xz', 'pc_xz',           &
3707                          'pr_xz', 'prr_xz', 'q_xz', 'qc_xz',                  &
3708                          'ql_xz', 'ql_c_xz', 'ql_v_xz', 'ql_vp_xz', 'qr_xz',  &
3709                          'qv_xz', 's_xz',                                     &
3710                          'theta_xz', 'thetal_xz', 'thetav_xz'                 )
3711
3712                      grid_x = 'x'
3713                      grid_y = 'y'
3714                      grid_z = 'zu'
3715!
3716!--                u grid
3717                   CASE ( 'u_xz' )
3718
3719                      grid_x = 'xu'
3720                      grid_y = 'y'
3721                      grid_z = 'zu'
3722!
3723!--                v grid
3724                   CASE ( 'v_xz' )
3725
3726                      grid_x = 'x'
3727                      grid_y = 'yv'
3728                      grid_z = 'zu'
3729!
3730!--                w grid
3731                   CASE ( 'w_xz' )
3732
3733                      grid_x = 'x'
3734                      grid_y = 'y'
3735                      grid_z = 'zw'
3736
3737                   CASE DEFAULT
3738
3739!
3740!--                   Check for land surface quantities
3741                      IF ( land_surface )  THEN
3742                         CALL lsm_define_netcdf_grid( do2d(av,i), found,       &
3743                                                      grid_x, grid_y, grid_z )
3744                      ENDIF
3745
3746                      IF ( .NOT. found )  THEN
3747                         CALL tcm_define_netcdf_grid( do2d(av,i), found,       &
3748                                                      grid_x, grid_y, grid_z )
3749                      ENDIF
3750
3751!
3752!--                   Check for ocean quantities
3753                      IF ( .NOT. found  .AND.  ocean_mode )  THEN
3754                         CALL ocean_define_netcdf_grid( do2d(av,i), found,  &
3755                                                        grid_x, grid_y, grid_z )
3756                      ENDIF
3757!
3758!--                   Check for radiation quantities
3759                      IF ( .NOT. found  .AND.  radiation )  THEN
3760                         CALL radiation_define_netcdf_grid( do2d(av,i), found, &
3761                                                            grid_x, grid_y,    &
3762                                                            grid_z )
3763                      ENDIF
3764!
3765!--                   Check for SALSA quantities
3766                      IF ( .NOT. found  .AND.  salsa )  THEN
3767                         CALL salsa_define_netcdf_grid( do2d(av,i), found,     &
3768                                                        grid_x, grid_y, grid_z )
3769                      ENDIF                         
3770
3771!
3772!--                   Check for gust module quantities
3773                      IF ( .NOT. found  .AND.  gust_module_enabled )  THEN
3774                         CALL gust_define_netcdf_grid( do2d(av,i), found,      &
3775                                                       grid_x, grid_y, grid_z )
3776                      ENDIF
3777
3778!
3779!--                   Check for chemistry quantities
3780                      IF ( .NOT. found  .AND.  air_chemistry )  THEN
3781                         CALL chem_define_netcdf_grid( do2d(av,i), found,      &
3782                                                       grid_x, grid_y,         &
3783                                                       grid_z )
3784                      ENDIF
3785
3786!
3787!--                   Check for user-defined quantities
3788                      IF ( .NOT. found )  THEN
3789                         CALL user_define_netcdf_grid( do2d(av,i), found,      &
3790                                                       grid_x, grid_y, grid_z )
3791                      ENDIF
3792
3793                      IF ( .NOT. found )  THEN
3794                         WRITE ( message_string, * ) 'no grid defined for',    &
3795                                                ' variable ', TRIM( do2d(av,i) )
3796                         CALL message( 'define_netcdf_header', 'PA0244',       &
3797                                       0, 1, 0, 6, 0 )
3798                      ENDIF
3799
3800                END SELECT
3801
3802!
3803!--             Select the respective dimension ids
3804                IF ( grid_x == 'x' )  THEN
3805                   id_x = id_dim_x_xz(av)
3806                ELSEIF ( grid_x == 'xu' )  THEN
3807                   id_x = id_dim_xu_xz(av)
3808                ENDIF
3809
3810                IF ( grid_y == 'y' )  THEN
3811                   id_y = id_dim_y_xz(av)
3812                ELSEIF ( grid_y == 'yv' )  THEN
3813                   id_y = id_dim_yv_xz(av)
3814                ENDIF
3815
3816                IF ( grid_z == 'zu' )  THEN
3817                   id_z = id_dim_zu_xz(av)
3818                ELSEIF ( grid_z == 'zw' )  THEN
3819                   id_z = id_dim_zw_xz(av)
3820                ELSEIF ( grid_z == 'zs' )  THEN
3821                   id_z = id_dim_zs_xz(av)
3822                ENDIF
3823
3824!
3825!--             Define the grid
3826                CALL netcdf_create_var( id_set_xz(av), (/ id_x, id_y, id_z,    &
3827                                        id_dim_time_xz(av) /), do2d(av,i),     &
3828                                        nc_precision(2), id_var_do2d(av,i),    &
3829                                        TRIM( do2d_unit(av,i) ), do2d(av,i),   &
3830                                        159, 160, 355, .TRUE. )
3831
3832#if defined( __netcdf4_parallel )
3833
3834                IF ( netcdf_data_format > 4 )  THEN
3835!
3836!--                Set no fill for every variable to increase performance.
3837                   nc_stat = NF90_DEF_VAR_FILL( id_set_xz(av),     &
3838                                                id_var_do2d(av,i), &
3839                                                1, 0 )
3840                   CALL netcdf_handle_error( 'netcdf_define_header', 534 )
3841!
3842!--                Set independent io operations for parallel io. Collective io
3843!--                is only allowed in case of a 1d-decomposition along x,
3844!--                because otherwise, not all PEs have output data.
3845                   IF ( npey == 1 )  THEN
3846                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_xz(av),     &
3847                                                     id_var_do2d(av,i), &
3848                                                     NF90_COLLECTIVE )
3849                   ELSE
3850!
3851!--                   Test simulations showed that the output of cross sections
3852!--                   by all PEs in data_output_2d using NF90_COLLECTIVE is
3853!--                   faster than the output by the first row of PEs in
3854!--                   x-direction using NF90_INDEPENDENT.
3855                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_xz(av),    & 
3856                                                    id_var_do2d(av,i), &
3857                                                    NF90_COLLECTIVE )
3858!                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_xz(av),     &
3859!                                                     id_var_do2d(av,i), &
3860!                                                     NF90_INDEPENDENT )
3861                   ENDIF
3862                   CALL netcdf_handle_error( 'netcdf_define_header', 449 )
3863                ENDIF
3864#endif
3865                var_list = TRIM( var_list ) // TRIM( do2d(av,i) ) // ';'
3866
3867             ENDIF
3868
3869             i = i + 1
3870
3871          ENDDO
3872
3873!
3874!--       No arrays to output. Close the netcdf file and return.
3875          IF ( i == 1 )  RETURN
3876
3877!
3878!--       Write the list of variables as global attribute (this is used by
3879!--       restart runs and by combine_plot_fields)
3880          nc_stat = NF90_PUT_ATT( id_set_xz(av), NF90_GLOBAL, 'VAR_LIST', &
3881                                  var_list )
3882          CALL netcdf_handle_error( 'netcdf_define_header', 161 )
3883
3884!
3885!--       Set general no fill, otherwise the performance drops significantly for
3886!--       parallel output.
3887          nc_stat = NF90_SET_FILL( id_set_xz(av), NF90_NOFILL, oldmode )
3888          CALL netcdf_handle_error( 'netcdf_define_header', 530 )
3889
3890!
3891!--       Leave netCDF define mode
3892          nc_stat = NF90_ENDDEF( id_set_xz(av) )
3893          CALL netcdf_handle_error( 'netcdf_define_header', 162 )
3894
3895!
3896!--       These data are only written by PE0 for parallel output to increase
3897!--       the performance.
3898          IF ( myid == 0  .OR.  netcdf_data_format < 5 )  THEN
3899
3900!
3901!--          Write axis data: y_xz, x, zu, zw
3902             ALLOCATE( netcdf_data(1:ns) )
3903
3904!
3905!--          Write y_xz data (shifted by +dy/2)
3906             DO  i = 1, ns
3907                IF( section(i,2) == -1 )  THEN
3908                   netcdf_data(i) = -1.0_wp  ! section averaged along y
3909                ELSE
3910                   netcdf_data(i) = ( section(i,2) + 0.5_wp ) * dy
3911                ENDIF
3912             ENDDO
3913             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_y_xz(av), &
3914                                     netcdf_data, start = (/ 1 /),   &
3915                                     count = (/ ns /) )
3916             CALL netcdf_handle_error( 'netcdf_define_header', 163 )
3917
3918!
3919!--          Write yv_xz data
3920             DO  i = 1, ns
3921                IF( section(i,2) == -1 )  THEN
3922                   netcdf_data(i) = -1.0_wp  ! section averaged along y
3923                ELSE
3924                   netcdf_data(i) = section(i,2) * dy
3925                ENDIF
3926             ENDDO
3927             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_yv_xz(av), &
3928                                     netcdf_data, start = (/ 1 /),    &
3929                                     count = (/ ns /) )
3930             CALL netcdf_handle_error( 'netcdf_define_header', 375 )
3931
3932!
3933!--          Write gridpoint number data
3934             netcdf_data(1:ns) = section(1:ns,2)
3935             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_ind_y_xz(av), &
3936                                     netcdf_data, start = (/ 1 /),       &
3937                                     count = (/ ns /) )
3938             CALL netcdf_handle_error( 'netcdf_define_header', 164 )
3939
3940
3941             DEALLOCATE( netcdf_data )
3942
3943!
3944!--          Write data for x (shifted by +dx/2) and xu axis
3945             ALLOCATE( netcdf_data(0:nx) )
3946
3947             DO  i = 0, nx
3948                netcdf_data(i) = ( i + 0.5_wp ) * dx
3949             ENDDO
3950
3951             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_x_xz(av), &
3952                                     netcdf_data, start = (/ 1 /),   &
3953                                     count = (/ nx+1 /) )
3954             CALL netcdf_handle_error( 'netcdf_define_header', 165 )
3955
3956             DO  i = 0, nx
3957                netcdf_data(i) = i * dx
3958             ENDDO
3959
3960             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_xu_xz(av), &
3961                                     netcdf_data, start = (/ 1 /),    &
3962                                     count = (/ nx+1 /) )
3963             CALL netcdf_handle_error( 'netcdf_define_header', 377 )
3964
3965             DEALLOCATE( netcdf_data )
3966
3967!
3968!--          Write zu and zw data (vertical axes)
3969             ALLOCATE( netcdf_data(0:nz+1) )
3970
3971             netcdf_data(0:nz+1) = zu(nzb:nzt+1)
3972             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_zu_xz(av), &
3973                                     netcdf_data, start = (/ 1 /),    &
3974                                     count = (/ nz+2 /) )
3975             CALL netcdf_handle_error( 'netcdf_define_header', 166 )
3976
3977             netcdf_data(0:nz+1) = zw(nzb:nzt+1)
3978             nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_zw_xz(av), &
3979                                     netcdf_data, start = (/ 1 /),    &
3980                                     count = (/ nz+2 /) )
3981             CALL netcdf_handle_error( 'netcdf_define_header', 167 )
3982
3983!
3984!--          Write zs data
3985             IF ( land_surface )  THEN
3986                netcdf_data(0:nzs-1) = - zs(nzb_soil:nzt_soil)
3987                nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_zs_xz(av), &
3988                                        netcdf_data(0:nzs), start = (/ 1 /),    &
3989                                        count = (/ nzt_soil-nzb_soil+1 /) )
3990               CALL netcdf_handle_error( 'netcdf_define_header', 548 )
3991             ENDIF
3992
3993             DEALLOCATE( netcdf_data )
3994!
3995!--          Write UTM coordinates
3996             IF ( init_model%rotation_angle == 0.0_wp )  THEN
3997!
3998!--             1D in case of no rotation
3999                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
4000!
4001!--             x coordinates
4002                ALLOCATE( netcdf_data(0:nx) )
4003                DO  k = 0, 2
4004!               
4005!--                Scalar grid points
4006                   IF ( k == 0 )  THEN
4007                      shift_x = 0.5
4008!               
4009!--                u grid points
4010                   ELSEIF ( k == 1 )  THEN
4011                      shift_x = 0.0
4012!               
4013!--                v grid points
4014                   ELSEIF ( k == 2 )  THEN
4015                      shift_x = 0.5
4016                   ENDIF
4017               
4018                   DO  i = 0, nx
4019                     netcdf_data(i) = init_model%origin_x            &
4020                                    + cos_ra * ( i + shift_x ) * dx
4021                   ENDDO
4022               
4023                   nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_eutm_xz(av,k),&
4024                                           netcdf_data, start = (/ 1 /),   &
4025                                           count = (/ nx+1 /) )
4026                   CALL netcdf_handle_error( 'netcdf_define_header', 555 )
4027
4028                ENDDO
4029                DEALLOCATE( netcdf_data )
4030!
4031!--             y coordinates
4032                ALLOCATE( netcdf_data(1:ns) )
4033                DO  k = 0, 2
4034!
4035!--                Scalar grid points
4036                   IF ( k == 0 )  THEN
4037                      shift_y = 0.5
4038!
4039!--                u grid points
4040                   ELSEIF ( k == 1 )  THEN
4041                      shift_y = 0.5
4042!
4043!--                v grid points
4044                   ELSEIF ( k == 2 )  THEN
4045                      shift_y = 0.0
4046                   ENDIF
4047
4048                   DO  i = 1, ns
4049                      IF( section(i,2) == -1 )  THEN
4050                         netcdf_data(i) = -1.0_wp  ! section averaged along y
4051                      ELSE
4052                         netcdf_data(i) = init_model%origin_y &
4053                                     + cos_ra * ( section(i,2) + shift_y ) * dy
4054                      ENDIF
4055                   ENDDO
4056
4057                   nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_nutm_xz(av,k),&
4058                                           netcdf_data, start = (/ 1 /),   &
4059                                           count = (/ ns /) )
4060                   CALL netcdf_handle_error( 'netcdf_define_header', 556 )
4061
4062                ENDDO
4063                DEALLOCATE( netcdf_data )
4064
4065             ELSE
4066!
4067!--             2D in case of rotation
4068                ALLOCATE( netcdf_data_2d(0:nx,1:ns) )
4069                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
4070                sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
4071               
4072                DO  k = 0, 2
4073!               
4074!--                Scalar grid points
4075                   IF ( k == 0 )  THEN
4076                      shift_x = 0.5 ; shift_y = 0.5
4077!                 
4078!--                u grid points
4079                   ELSEIF ( k == 1 )  THEN
4080                      shift_x = 0.0 ; shift_y = 0.5
4081!                 
4082!--                v grid points
4083                   ELSEIF ( k == 2 )  THEN
4084                      shift_x = 0.5 ; shift_y = 0.0
4085                   ENDIF
4086
4087                   DO  j = 1, ns
4088                      IF( section(j,2) == -1 )  THEN
4089                         netcdf_data_2d(:,j) = -1.0_wp  ! section averaged along y
4090                      ELSE
4091                         DO  i = 0, nx
4092                            netcdf_data_2d(i,j) = init_model%origin_x          &
4093                                    + cos_ra * ( i + shift_x ) * dx            &
4094                                    + sin_ra * ( section(j,2) + shift_y ) * dy
4095                         ENDDO
4096                      ENDIF
4097                   ENDDO
4098                   
4099                   nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_eutm_xz(av,k),  &
4100                                           netcdf_data_2d, start = (/ 1, 1 /),   &
4101                                           count = (/ nx+1, ns /) )
4102                   CALL netcdf_handle_error( 'netcdf_define_header', 555 )
4103                   
4104                   DO  j = 1, ns
4105                      IF( section(j,2) == -1 )  THEN
4106                         netcdf_data_2d(:,j) = -1.0_wp  ! section averaged along y
4107                      ELSE
4108                         DO  i = 0, nx
4109                            netcdf_data_2d(i,j) = init_model%origin_y          &
4110                                    - sin_ra * ( i + shift_x ) * dx            &
4111                                    + cos_ra * ( section(j,2) + shift_y ) * dy
4112                         ENDDO
4113                      ENDIF
4114                   ENDDO
4115                   
4116                   nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_nutm_xz(av,k),  &
4117                                           netcdf_data_2d, start = (/ 1, 1 /),   &
4118                                           count = (/ nx+1, ns /) )
4119                   CALL netcdf_handle_error( 'netcdf_define_header', 556 )
4120               
4121                ENDDO
4122                DEALLOCATE( netcdf_data_2d )
4123             ENDIF
4124!
4125!--          Write lon and lat data
4126             ALLOCATE( lat(0:nx,1:ns) )
4127             ALLOCATE( lon(0:nx,1:ns) )
4128             cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
4129             sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
4130
4131             DO  k = 0, 2
4132!               
4133!--             Scalar grid points
4134                IF ( k == 0 )  THEN
4135                   shift_x = 0.5 ; shift_y = 0.5
4136!               
4137!--             u grid points
4138                ELSEIF ( k == 1 )  THEN
4139                   shift_x = 0.0 ; shift_y = 0.5
4140!               
4141!--             v grid points
4142                ELSEIF ( k == 2 )  THEN
4143                   shift_x = 0.5 ; shift_y = 0.0
4144                ENDIF
4145
4146                DO  j = 1, ns
4147                   IF( section(j,2) == -1 )  THEN
4148                      lat(:,j) = -90.0_wp  ! section averaged along y
4149                      lon(:,j) = -180.0_wp  ! section averaged along y
4150                   ELSE
4151                      DO  i = 0, nx
4152                         eutm = init_model%origin_x            &
4153                              + cos_ra * ( i + shift_x ) * dx  &
4154                              + sin_ra * ( section(j,2) + shift_y ) * dy
4155                         nutm = init_model%origin_y            &
4156                              - sin_ra * ( i + shift_x ) * dx  &
4157                              + cos_ra * ( section(j,2) + shift_y ) * dy
4158
4159                         CALL  convert_utm_to_geographic( crs_list,          &
4160                                                          eutm, nutm,        &
4161                                                          lon(i,j), lat(i,j) )
4162                      ENDDO
4163                   ENDIF
4164                ENDDO
4165
4166                nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_lon_xz(av,k), &
4167                                     lon, start = (/ 1, 1 /),       &
4168                                     count = (/ nx+1, ns /) )
4169                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
4170
4171                nc_stat = NF90_PUT_VAR( id_set_xz(av), id_var_lat_xz(av,k), &
4172                                     lat, start = (/ 1, 1 /),       &
4173                                     count = (/ nx+1, ns /) )
4174                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
4175             ENDDO
4176
4177             DEALLOCATE( lat )
4178             DEALLOCATE( lon )
4179
4180          ENDIF
4181
4182
4183       CASE ( 'xz_ext' )
4184
4185!
4186!--       Get the list of variables and compare with the actual run.
4187!--       First var_list_old has to be reset, since GET_ATT does not assign
4188!--       trailing blanks.
4189          var_list_old = ' '
4190          nc_stat = NF90_GET_ATT( id_set_xz(av), NF90_GLOBAL, 'VAR_LIST', &
4191                                  var_list_old )
4192          CALL netcdf_handle_error( 'netcdf_define_header', 168 )
4193
4194          var_list = ';'
4195          i = 1
4196          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
4197             IF ( INDEX( do2d(av,i), 'xz' ) /= 0 )  THEN
4198                var_list = TRIM( var_list ) // TRIM( do2d(av,i) ) // ';'
4199             ENDIF
4200             i = i + 1
4201          ENDDO
4202
4203          IF ( av == 0 )  THEN
4204             var = '(xz)'
4205          ELSE
4206             var = '(xz_av)'
4207          ENDIF
4208
4209          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
4210             message_string = 'netCDF file for cross-sections ' //           &
4211                              TRIM( var ) // ' from previous run found,' //  &
4212                              '&but this file cannot be extended due to' //  &
4213                              ' variable mismatch.' //                       &
4214                              '&New file is created instead.'
4215             CALL message( 'define_netcdf_header', 'PA0249', 0, 1, 0, 6, 0 )
4216             extend = .FALSE.
4217             RETURN
4218          ENDIF
4219
4220!
4221!--       Calculate the number of current sections
4222          ns = 1
4223          DO WHILE ( section(ns,2) /= -9999  .AND.  ns <= 100 )
4224             ns = ns + 1
4225          ENDDO
4226          ns = ns - 1
4227
4228!
4229!--       Get and compare the number of vertical cross sections
4230          nc_stat = NF90_INQ_VARID( id_set_xz(av), 'y_xz', id_var_y_xz(av) )
4231          CALL netcdf_handle_error( 'netcdf_define_header', 169 )
4232
4233          nc_stat = NF90_INQUIRE_VARIABLE( id_set_xz(av), id_var_y_xz(av), &
4234                                           dimids = id_dim_y_xz_old )
4235          CALL netcdf_handle_error( 'netcdf_define_header', 170 )
4236          id_dim_y_xz(av) = id_dim_y_xz_old(1)
4237
4238          nc_stat = NF90_INQUIRE_DIMENSION( id_set_xz(av), id_dim_y_xz(av), &
4239                                            len = ns_old )
4240          CALL netcdf_handle_error( 'netcdf_define_header', 171 )
4241
4242          IF ( ns /= ns_old )  THEN
4243             message_string = 'netCDF file for cross-sections ' //          &
4244                              TRIM( var ) // ' from previous run found,' // &
4245                              '&but this file cannot be extended due to' // &
4246                              ' mismatch in number of' //                   & 
4247                              ' cross sections.' //                         &
4248                              '&New file is created instead.'
4249             CALL message( 'define_netcdf_header', 'PA0250', 0, 1, 0, 6, 0 )
4250             extend = .FALSE.
4251             RETURN
4252          ENDIF
4253
4254!
4255!--       Get and compare the heights of the cross sections
4256          ALLOCATE( netcdf_data(1:ns_old) )
4257
4258          nc_stat = NF90_GET_VAR( id_set_xz(av), id_var_y_xz(av), netcdf_data )
4259          CALL netcdf_handle_error( 'netcdf_define_header', 172 )
4260
4261          DO  i = 1, ns
4262             IF ( section(i,2) /= -1 )  THEN
4263                IF ( ( ( section(i,2) + 0.5 ) * dy ) /= netcdf_data(i) )  THEN
4264                   message_string = 'netCDF file for cross-sections ' //       &
4265                               TRIM( var ) // ' from previous run found,' //   &
4266                               ' but this file cannot be extended' //          &
4267                               ' due to mismatch in cross' //                  &
4268                               ' section levels.' //                           &
4269                               ' New file is created instead.'
4270                   CALL message( 'define_netcdf_header', 'PA0251',             &
4271                                                                 0, 1, 0, 6, 0 )
4272                   extend = .FALSE.
4273                   RETURN
4274                ENDIF
4275             ELSE
4276                IF ( -1.0_wp /= netcdf_data(i) )  THEN
4277                   message_string = 'netCDF file for cross-sections ' //       &
4278                               TRIM( var ) // ' from previous run found,' //   &
4279                               ' but this file cannot be extended' //          &
4280                               ' due to mismatch in cross' //                  &
4281                               ' section levels.' //                           &
4282                               ' New file is created instead.'
4283                   CALL message( 'define_netcdf_header', 'PA0251',             &
4284                                                                 0, 1, 0, 6, 0 )
4285                   extend = .FALSE.
4286                   RETURN
4287                ENDIF
4288             ENDIF
4289          ENDDO
4290
4291          DEALLOCATE( netcdf_data )
4292
4293!
4294!--       Get the id of the time coordinate (unlimited coordinate) and its
4295!--       last index on the file. The next time level is do2d..count+1.
4296!--       The current time must be larger than the last output time
4297!--       on the file.
4298          nc_stat = NF90_INQ_VARID( id_set_xz(av), 'time', id_var_time_xz(av) )
4299          CALL netcdf_handle_error( 'netcdf_define_header', 173 )
4300
4301          nc_stat = NF90_INQUIRE_VARIABLE( id_set_xz(av), id_var_time_xz(av), &
4302                                           dimids = id_dim_time_old )
4303          CALL netcdf_handle_error( 'netcdf_define_header', 174 )
4304          id_dim_time_xz(av) = id_dim_time_old(1)
4305
4306          nc_stat = NF90_INQUIRE_DIMENSION( id_set_xz(av), id_dim_time_xz(av), &
4307                                            len = ntime_count )
4308          CALL netcdf_handle_error( 'netcdf_define_header', 175 )
4309
4310!
4311!--       For non-parallel output use the last output time level of the netcdf
4312!--       file because the time dimension is unlimited. In case of parallel
4313!--       output the variable ntime_count could get the value of 9*10E36 because
4314!--       the time dimension is limited.
4315          IF ( netcdf_data_format < 5 ) do2d_xz_time_count(av) = ntime_count
4316
4317          nc_stat = NF90_GET_VAR( id_set_xz(av), id_var_time_xz(av),           &
4318                                  last_time_coordinate,                        &
4319                                  start = (/ do2d_xz_time_count(av) /),        &
4320                                  count = (/ 1 /) )
4321          CALL netcdf_handle_error( 'netcdf_define_header', 176 )
4322
4323          IF ( last_time_coordinate(1) >= simulated_time )  THEN
4324             message_string = 'netCDF file for cross sections ' //             &
4325                              TRIM( var ) // ' from previous run found,' //    &
4326                              '&but this file cannot be extended becaus' //    &
4327                              'e the current output time' //                   &
4328                              '&is less or equal than the last output t' //    &
4329                              'ime on this file.' //                           &
4330                              '&New file is created instead.'
4331             CALL message( 'define_netcdf_header', 'PA0252', 0, 1, 0, 6, 0 )
4332             do2d_xz_time_count(av) = 0
4333             extend = .FALSE.
4334             RETURN
4335          ENDIF
4336
4337          IF ( netcdf_data_format > 4 )  THEN
4338!
4339!--          Check if the needed number of output time levels is increased
4340!--          compared to the number of time levels in the existing file.
4341             IF ( ntdim_2d_xz(av) > ntime_count )  THEN
4342                message_string = 'netCDF file for cross sections ' // &
4343                                 TRIM( var ) // ' from previous run found,' // &
4344                                 '&but this file cannot be extended becaus' // &
4345                                 'e the number of output time levels has b' // &
4346                                 'een increased compared to the previous s' // &
4347                                 'imulation.' //                               &
4348                                 '&New file is created instead.'
4349                CALL message( 'define_netcdf_header', 'PA0390', 0, 1, 0, 6, 0 )
4350                do2d_xz_time_count(av) = 0
4351                extend = .FALSE.
4352!
4353!--             Recalculate the needed time levels for the new file.
4354                IF ( av == 0 )  THEN
4355                   ntdim_2d_xz(0) = CEILING(                            &
4356                           ( end_time - MAX( skip_time_do2d_xz,         &
4357                                             simulated_time_at_begin )  &
4358                           ) / dt_do2d_xz )
4359                   IF ( do2d_at_begin )  ntdim_2d_xz(0) = ntdim_2d_xz(0) + 1
4360                ELSE
4361                   ntdim_2d_xz(1) = CEILING(                            &
4362                           ( end_time - MAX( skip_time_data_output_av,  &
4363                                             simulated_time_at_begin )  &
4364                           ) / dt_data_output_av )
4365                ENDIF
4366                RETURN
4367             ENDIF
4368          ENDIF
4369
4370!
4371!--       Dataset seems to be extendable.
4372!--       Now get the variable ids.
4373          i = 1
4374          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
4375             IF ( INDEX( do2d(av,i), 'xz' ) /= 0 )  THEN
4376                nc_stat = NF90_INQ_VARID( id_set_xz(av), do2d(av,i), &
4377                                          id_var_do2d(av,i) )
4378                CALL netcdf_handle_error( 'netcdf_define_header', 177 )
4379#if defined( __netcdf4_parallel )
4380!
4381!--             Set independent io operations for parallel io. Collective io
4382!--             is only allowed in case of a 1d-decomposition along x, because
4383!--             otherwise, not all PEs have output data.
4384                IF ( netcdf_data_format > 4 )  THEN
4385                   IF ( npey == 1 )  THEN
4386                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_xz(av),     &
4387                                                     id_var_do2d(av,i), &
4388                                                     NF90_COLLECTIVE )
4389                   ELSE
4390!
4391!--                   Test simulations showed that the output of cross sections
4392!--                   by all PEs in data_output_2d using NF90_COLLECTIVE is
4393!--                   faster than the output by the first row of PEs in
4394!--                   x-direction using NF90_INDEPENDENT.
4395                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_xz(av),     &
4396                                                     id_var_do2d(av,i), &
4397                                                     NF90_COLLECTIVE )
4398!                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_xz(av),     &
4399!                                                     id_var_do2d(av,i), &
4400!                                                     NF90_INDEPENDENT )
4401                   ENDIF
4402                   CALL netcdf_handle_error( 'netcdf_define_header', 455 )
4403                ENDIF
4404#endif
4405             ENDIF
4406             i = i + 1
4407          ENDDO
4408
4409!
4410!--       Update the title attribute on file
4411!--       In order to avoid 'data mode' errors if updated attributes are larger
4412!--       than their original size, NF90_PUT_ATT is called in 'define mode'
4413!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
4414!--       performance loss due to data copying; an alternative strategy would be
4415!--       to ensure equal attribute size in a job chain. Maybe revise later.
4416          IF ( av == 0 )  THEN
4417             time_average_text = ' '
4418          ELSE
4419             WRITE (time_average_text, '('', '',F7.1,'' s average'')') &
4420                                                            averaging_interval
4421          ENDIF
4422          nc_stat = NF90_REDEF( id_set_xz(av) )
4423          CALL netcdf_handle_error( 'netcdf_define_header', 433 )
4424          nc_stat = NF90_PUT_ATT( id_set_xz(av), NF90_GLOBAL, 'title',         &
4425                                  TRIM( run_description_header ) //            &
4426                                  TRIM( time_average_text ) )
4427          CALL netcdf_handle_error( 'netcdf_define_header', 178 )
4428          nc_stat = NF90_ENDDEF( id_set_xz(av) )
4429          CALL netcdf_handle_error( 'netcdf_define_header', 434 )
4430          message_string = 'netCDF file for cross-sections ' //                &
4431                            TRIM( var ) // ' from previous run found.' //      &
4432                           '&This file will be extended.'
4433          CALL message( 'define_netcdf_header', 'PA0253', 0, 0, 0, 6, 0 )
4434
4435
4436       CASE ( 'yz_new' )
4437
4438!
4439!--       Define some global attributes of the dataset
4440          IF ( av == 0 )  THEN
4441             CALL netcdf_create_global_atts( id_set_yz(av), 'yz', TRIM( run_description_header ), 179 )
4442             time_average_text = ' '
4443          ELSE
4444             CALL netcdf_create_global_atts( id_set_yz(av), 'yz_av', TRIM( run_description_header ), 179 )
4445             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval
4446             nc_stat = NF90_PUT_ATT( id_set_yz(av), NF90_GLOBAL, 'time_avg',   &
4447                                     TRIM( time_average_text ) )
4448             CALL netcdf_handle_error( 'netcdf_define_header', 180 )
4449          ENDIF
4450
4451!
4452!--       Define time coordinate for yz sections.
4453!--       For parallel output the time dimensions has to be limited, otherwise
4454!--       the performance drops significantly.
4455          IF ( netcdf_data_format < 5 )  THEN
4456             CALL netcdf_create_dim( id_set_yz(av), 'time', NF90_UNLIMITED,    &
4457                                     id_dim_time_yz(av), 181 )
4458          ELSE
4459             CALL netcdf_create_dim( id_set_yz(av), 'time', ntdim_2d_yz(av),   &
4460                                     id_dim_time_yz(av), 526 )
4461          ENDIF
4462
4463          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_time_yz(av) /),     &
4464                                  'time', NF90_DOUBLE, id_var_time_yz(av),     &
4465                                  'seconds since '//TRIM(init_model%origin_time), 'time', 182, 183, 000 )
4466          CALL netcdf_create_att( id_set_yz(av), id_var_time_yz(av), 'standard_name', 'time', 000)
4467          CALL netcdf_create_att( id_set_yz(av), id_var_time_yz(av), 'axis', 'T', 000)
4468!
4469!--       Define the spatial dimensions and coordinates for yz-sections.
4470!--       First, determine the number of vertical sections to be written.
4471          IF ( section(1,3) == -9999 )  THEN
4472             RETURN
4473          ELSE
4474             ns = 1
4475             DO WHILE ( section(ns,3) /= -9999  .AND.  ns <= 100 )
4476                ns = ns + 1
4477             ENDDO
4478             ns = ns - 1
4479          ENDIF
4480
4481!
4482!--       Define x axis (for scalar position)
4483          CALL netcdf_create_dim( id_set_yz(av), 'x_yz', ns, id_dim_x_yz(av),  &
4484                                  184 )
4485          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_x_yz(av) /),        &
4486                                  'x_yz', NF90_DOUBLE, id_var_x_yz(av),        &
4487                                  'meters', '', 185, 186, 000 )
4488!
4489!--       Define x axis (for u position)
4490          CALL netcdf_create_dim( id_set_yz(av), 'xu_yz', ns,                  &
4491                                  id_dim_xu_yz(av), 377 )
4492          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_xu_yz(av) /),       &
4493                                  'xu_yz', NF90_DOUBLE, id_var_xu_yz(av),      &
4494                                  'meters', '', 378, 379, 000 )
4495!
4496!--       Define a variable to store the layer indices of the vertical cross
4497!--       sections
4498          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_x_yz(av) /),        &
4499                                  'ind_x_yz', NF90_DOUBLE,                     &
4500                                  id_var_ind_x_yz(av), 'gridpoints', '', 187,  &
4501                                  188, 000 )
4502!
4503!--       Define y-axis (for scalar position)
4504          CALL netcdf_create_dim( id_set_yz(av), 'y', ny+1, id_dim_y_yz(av),   &
4505                                  189 )
4506          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_y_yz(av) /), 'y',   &
4507                                  NF90_DOUBLE, id_var_y_yz(av), 'meters', '',  &
4508                                  190, 191, 000 )
4509!
4510!--       Define y-axis (for v position)
4511          CALL netcdf_create_dim( id_set_yz(av), 'yv', ny+1, id_dim_yv_yz(av), &
4512                                  380 )
4513          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_yv_yz(av) /), 'yv', &
4514                                  NF90_DOUBLE, id_var_yv_yz(av), 'meters', '', &
4515                                  381, 382, 000 )
4516!
4517!--       Define the two z-axes (zu and zw)
4518          CALL netcdf_create_dim( id_set_yz(av), 'zu', nz+2, id_dim_zu_yz(av), &
4519                                  192 )
4520          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_zu_yz(av) /), 'zu', &
4521                                  NF90_DOUBLE, id_var_zu_yz(av), 'meters', '', &
4522                                  193, 194, 000 )
4523
4524          CALL netcdf_create_dim( id_set_yz(av), 'zw', nz+2, id_dim_zw_yz(av), &
4525                                  195 )
4526          CALL netcdf_create_var( id_set_yz(av), (/ id_dim_zw_yz(av) /), 'zw', &
4527                                  NF90_DOUBLE, id_var_zw_yz(av), 'meters', '', &
4528                                  196, 197, 000 )
4529!
4530!--       Define UTM and geographic coordinates
4531          CALL define_geo_coordinates( id_set_yz(av),         &
4532                  (/ id_dim_x_yz(av), id_dim_xu_yz(av) /),    &
4533                  (/ id_dim_y_yz(av), id_dim_yv_yz(av) /),    &
4534                  id_var_eutm_yz(av,:), id_var_nutm_yz(av,:), &
4535                  id_var_lat_yz(av,:), id_var_lon_yz(av,:)    )
4536!
4537!--       Define coordinate-reference system
4538          CALL netcdf_create_crs( id_set_yz(av), 000 )
4539
4540          IF ( land_surface )  THEN
4541
4542             CALL netcdf_create_dim( id_set_yz(av), 'zs', nzs,                 &
4543                                     id_dim_zs_yz(av), 545 )
4544             CALL netcdf_create_var( id_set_yz(av), (/ id_dim_zs_yz(av) /),    &
4545                                     'zs', NF90_DOUBLE, id_var_zs_yz(av),      &
4546                                     'meters', '', 546, 547, 000 )
4547
4548          ENDIF
4549
4550!
4551!--       Define the variables
4552          var_list = ';'
4553          i = 1
4554
4555          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
4556
4557             IF ( INDEX( do2d(av,i), 'yz' ) /= 0 )  THEN
4558
4559!
4560!--             Check for the grid
4561                found = .FALSE.
4562                SELECT CASE ( do2d(av,i) )
4563!
4564!--                Most variables are defined on the zu grid
4565                   CASE ( 'e_yz', 'nc_yz', 'nr_yz', 'p_yz', 'pc_yz',           &
4566                          'pr_yz','prr_yz', 'q_yz', 'qc_yz', 'ql_yz',          &
4567                          'ql_c_yz', 'ql_v_yz', 'ql_vp_yz', 'qr_yz', 'qv_yz',  &
4568                          's_yz',                                              &
4569                          'theta_yz', 'thetal_yz', 'thetav_yz' )
4570
4571                      grid_x = 'x'
4572                      grid_y = 'y'
4573                      grid_z = 'zu'
4574!
4575!--                u grid
4576                   CASE ( 'u_yz' )
4577
4578                      grid_x = 'xu'
4579                      grid_y = 'y'
4580                      grid_z = 'zu'
4581!
4582!--                v grid
4583                   CASE ( 'v_yz' )
4584
4585                      grid_x = 'x'
4586                      grid_y = 'yv'
4587                      grid_z = 'zu'
4588!
4589!--                w grid
4590                   CASE ( 'w_yz' )
4591
4592                      grid_x = 'x'
4593                      grid_y = 'y'
4594                      grid_z = 'zw'
4595
4596
4597                   CASE DEFAULT
4598!
4599!--                   Check for land surface quantities
4600                      IF ( land_surface )  THEN
4601                         CALL lsm_define_netcdf_grid( do2d(av,i), found,       &
4602                                                      grid_x, grid_y, grid_z )
4603                      ENDIF
4604
4605                      IF ( .NOT. found )  THEN
4606                         CALL tcm_define_netcdf_grid( do2d(av,i), found,       &
4607                                                      grid_x, grid_y, grid_z )
4608                      ENDIF
4609
4610!
4611!--                   Check for ocean quantities
4612                      IF ( .NOT. found  .AND.  ocean_mode )  THEN
4613                         CALL ocean_define_netcdf_grid( do2d(av,i), found,     &
4614                                                       grid_x, grid_y, grid_z )
4615                      ENDIF
4616!
4617!--                   Check for radiation quantities
4618                      IF ( .NOT. found  .AND.  radiation )  THEN
4619                         CALL radiation_define_netcdf_grid( do2d(av,i), found, &
4620                                                            grid_x, grid_y,    &
4621                                                            grid_z )
4622                      ENDIF
4623!
4624!--                   Check for SALSA quantities
4625                      IF ( .NOT. found  .AND.  salsa )  THEN
4626                         CALL salsa_define_netcdf_grid( do2d(av,i), found,     &
4627                                                        grid_x, grid_y, grid_z )
4628                      ENDIF                           
4629!
4630!--                   Check for gust module quantities
4631                      IF ( .NOT. found  .AND.  gust_module_enabled )  THEN
4632                         CALL gust_define_netcdf_grid( do2d(av,i), found,      &
4633                                                       grid_x, grid_y, grid_z )
4634                      ENDIF
4635
4636!
4637!--                   Check for chemistry quantities
4638                      IF ( .NOT. found  .AND.  air_chemistry )  THEN
4639                         CALL chem_define_netcdf_grid( do2d(av,i), found,      &
4640                                                       grid_x, grid_y,         &
4641                                                       grid_z )
4642                      ENDIF
4643!
4644!--                   Check for user-defined quantities
4645                      IF ( .NOT. found )  THEN
4646                         CALL user_define_netcdf_grid( do2d(av,i), found,      &
4647                                                       grid_x, grid_y, grid_z )
4648                      ENDIF
4649
4650                      IF ( .NOT. found )  THEN
4651                         WRITE ( message_string, * ) 'no grid defined for',    &
4652                                                ' variable ', TRIM( do2d(av,i) )
4653                         CALL message( 'define_netcdf_header', 'PA0244',       &
4654                                       0, 1, 0, 6, 0 )
4655                      ENDIF
4656
4657                END SELECT
4658
4659!
4660!--             Select the respective dimension ids
4661                IF ( grid_x == 'x' )  THEN
4662                   id_x = id_dim_x_yz(av)
4663                ELSEIF ( grid_x == 'xu' )  THEN
4664                   id_x = id_dim_xu_yz(av)
4665                ENDIF
4666
4667                IF ( grid_y == 'y' )  THEN
4668                   id_y = id_dim_y_yz(av)
4669                ELSEIF ( grid_y == 'yv' )  THEN
4670                   id_y = id_dim_yv_yz(av)
4671                ENDIF
4672
4673                IF ( grid_z == 'zu' )  THEN
4674                   id_z = id_dim_zu_yz(av)
4675                ELSEIF ( grid_z == 'zw' )  THEN
4676                   id_z = id_dim_zw_yz(av)
4677                ELSEIF ( grid_z == 'zs' )  THEN
4678                   id_z = id_dim_zs_yz(av)
4679                ENDIF
4680
4681!
4682!--             Define the grid
4683                CALL netcdf_create_var( id_set_yz(av),  (/ id_x, id_y, id_z,   &
4684                                        id_dim_time_yz(av) /), do2d(av,i),     &
4685                                        nc_precision(3), id_var_do2d(av,i),    &
4686                                        TRIM( do2d_unit(av,i) ), do2d(av,i),   &
4687                                        198, 199, 356, .TRUE. )
4688
4689#if defined( __netcdf4_parallel )
4690                IF ( netcdf_data_format > 4 )  THEN
4691!
4692!--                Set no fill for every variable to increase performance.
4693                   nc_stat = NF90_DEF_VAR_FILL( id_set_yz(av),     &
4694                                                id_var_do2d(av,i), &
4695                                                1, 0 )
4696                   CALL netcdf_handle_error( 'netcdf_define_header', 535 )
4697!
4698!--                Set independent io operations for parallel io. Collective io
4699!--                is only allowed in case of a 1d-decomposition along y,
4700!--                because otherwise, not all PEs have output data.
4701                   IF ( npex == 1 )  THEN
4702                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_yz(av),     &
4703                                                     id_var_do2d(av,i), &
4704                                                     NF90_COLLECTIVE )
4705                   ELSE
4706!
4707!--                   Test simulations showed that the output of cross sections
4708!--                   by all PEs in data_output_2d using NF90_COLLECTIVE is
4709!--                   faster than the output by the first row of PEs in
4710!--                   y-direction using NF90_INDEPENDENT.
4711                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_yz(av),     &
4712                                                     id_var_do2d(av,i), &
4713                                                     NF90_COLLECTIVE )
4714!                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_yz(av),     &
4715!                                                     id_var_do2d(av,i), &
4716!                                                     NF90_INDEPENDENT )
4717                   ENDIF
4718                   CALL netcdf_handle_error( 'netcdf_define_header', 450 )
4719                ENDIF
4720#endif
4721                var_list = TRIM( var_list ) // TRIM( do2d(av,i) ) // ';'
4722
4723             ENDIF
4724
4725             i = i + 1
4726
4727          ENDDO
4728
4729!
4730!--       No arrays to output. Close the netcdf file and return.
4731          IF ( i == 1 )  RETURN
4732
4733!
4734!--       Write the list of variables as global attribute (this is used by
4735!--       restart runs and by combine_plot_fields)
4736          nc_stat = NF90_PUT_ATT( id_set_yz(av), NF90_GLOBAL, 'VAR_LIST', &
4737                                  var_list )
4738          CALL netcdf_handle_error( 'netcdf_define_header', 200 )
4739
4740!
4741!--       Set general no fill, otherwise the performance drops significantly for
4742!--       parallel output.
4743          nc_stat = NF90_SET_FILL( id_set_yz(av), NF90_NOFILL, oldmode )
4744          CALL netcdf_handle_error( 'netcdf_define_header', 531 )
4745
4746!
4747!--       Leave netCDF define mode
4748          nc_stat = NF90_ENDDEF( id_set_yz(av) )
4749          CALL netcdf_handle_error( 'netcdf_define_header', 201 )
4750
4751!
4752!--       These data are only written by PE0 for parallel output to increase
4753!--       the performance.
4754          IF ( myid == 0  .OR.  netcdf_data_format < 5 )  THEN
4755
4756!
4757!--          Write axis data: x_yz, y, zu, zw
4758             ALLOCATE( netcdf_data(1:ns) )
4759
4760!
4761!--          Write x_yz data (shifted by +dx/2)
4762             DO  i = 1, ns
4763                IF( section(i,3) == -1 )  THEN
4764                   netcdf_data(i) = -1.0_wp  ! section averaged along x
4765                ELSE
4766                   netcdf_data(i) = ( section(i,3) + 0.5_wp ) * dx
4767                ENDIF
4768             ENDDO
4769             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_x_yz(av), &
4770                                     netcdf_data, start = (/ 1 /),   &
4771                                     count = (/ ns /) )
4772             CALL netcdf_handle_error( 'netcdf_define_header', 202 )
4773
4774!
4775!--          Write x_yz data (xu grid)
4776             DO  i = 1, ns
4777                IF( section(i,3) == -1 )  THEN
4778                   netcdf_data(i) = -1.0_wp  ! section averaged along x
4779                ELSE
4780                   netcdf_data(i) = section(i,3) * dx
4781                ENDIF
4782             ENDDO
4783             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_xu_yz(av), &
4784                                     netcdf_data, start = (/ 1 /),    &
4785                                     count = (/ ns /) )
4786             CALL netcdf_handle_error( 'netcdf_define_header', 383 )
4787
4788!
4789!--          Write gridpoint number data
4790             netcdf_data(1:ns) = section(1:ns,3)
4791             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_ind_x_yz(av), &
4792                                     netcdf_data, start = (/ 1 /),       &
4793                                     count = (/ ns /) )
4794             CALL netcdf_handle_error( 'netcdf_define_header', 203 )
4795
4796             DEALLOCATE( netcdf_data )
4797
4798!
4799!--          Write data for y (shifted by +dy/2) and yv axis
4800             ALLOCATE( netcdf_data(0:ny) )
4801
4802             DO  j = 0, ny
4803                netcdf_data(j) = ( j + 0.5_wp ) * dy
4804             ENDDO
4805
4806             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_y_yz(av), &
4807                                     netcdf_data, start = (/ 1 /),   &
4808                                     count = (/ ny+1 /) )
4809             CALL netcdf_handle_error( 'netcdf_define_header', 204 )
4810
4811             DO  j = 0, ny
4812                netcdf_data(j) = j * dy
4813             ENDDO
4814
4815             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_yv_yz(av), &
4816                                     netcdf_data, start = (/ 1 /),    &
4817                                     count = (/ ny+1 /) )
4818             CALL netcdf_handle_error( 'netcdf_define_header', 384 )
4819
4820             DEALLOCATE( netcdf_data )
4821
4822!
4823!--          Write zu and zw data (vertical axes)
4824             ALLOCATE( netcdf_data(0:nz+1) )
4825
4826             netcdf_data(0:nz+1) = zu(nzb:nzt+1)
4827             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_zu_yz(av), &
4828                                     netcdf_data, start = (/ 1 /),    &
4829                                     count = (/ nz+2 /) )
4830             CALL netcdf_handle_error( 'netcdf_define_header', 205 )
4831
4832             netcdf_data(0:nz+1) = zw(nzb:nzt+1)
4833             nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_zw_yz(av), &
4834                                     netcdf_data, start = (/ 1 /),    &
4835                                     count = (/ nz+2 /) )
4836             CALL netcdf_handle_error( 'netcdf_define_header', 206 )
4837
4838             DEALLOCATE( netcdf_data )
4839!
4840!--          Write UTM coordinates
4841             IF ( init_model%rotation_angle == 0.0_wp )  THEN
4842!
4843!--             1D in case of no rotation
4844                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
4845!
4846!--             x coordinates
4847                ALLOCATE( netcdf_data(1:ns) )
4848                DO  k = 0, 2
4849!               
4850!--                Scalar grid points
4851                   IF ( k == 0 )  THEN
4852                      shift_x = 0.5
4853!               
4854!--                u grid points
4855                   ELSEIF ( k == 1 )  THEN
4856                      shift_x = 0.0
4857!               
4858!--                v grid points
4859                   ELSEIF ( k == 2 )  THEN
4860                      shift_x = 0.5
4861                   ENDIF
4862               
4863                   DO  i = 1, ns
4864                      IF( section(i,3) == -1 )  THEN
4865                         netcdf_data(i) = -1.0_wp  ! section averaged along x
4866                      ELSE
4867                         netcdf_data(i) = init_model%origin_x &
4868                                     + cos_ra * ( section(i,3) + shift_x ) * dx
4869                      ENDIF
4870                   ENDDO
4871               
4872                   nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_eutm_yz(av,k),&
4873                                           netcdf_data, start = (/ 1 /),   &
4874                                           count = (/ ns /) )
4875                   CALL netcdf_handle_error( 'netcdf_define_header', 555 )
4876
4877                ENDDO
4878                DEALLOCATE( netcdf_data )
4879!
4880!--             y coordinates
4881                ALLOCATE( netcdf_data(0:ny) )
4882                DO  k = 0, 2
4883!
4884!--                Scalar grid points
4885                   IF ( k == 0 )  THEN
4886                      shift_y = 0.5
4887!
4888!--                u grid points
4889                   ELSEIF ( k == 1 )  THEN
4890                      shift_y = 0.5
4891!
4892!--                v grid points
4893                   ELSEIF ( k == 2 )  THEN
4894                      shift_y = 0.0
4895                   ENDIF
4896
4897                   DO  i = 0, ny
4898                     netcdf_data(i) = init_model%origin_y            &
4899                                    + cos_ra * ( i + shift_y ) * dy
4900                   ENDDO
4901
4902                   nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_nutm_yz(av,k),&
4903                                           netcdf_data, start = (/ 1 /),   &
4904                                           count = (/ ny+1 /) )
4905                   CALL netcdf_handle_error( 'netcdf_define_header', 556 )
4906
4907                ENDDO
4908                DEALLOCATE( netcdf_data )
4909
4910             ELSE
4911!
4912!--             2D in case of rotation
4913                ALLOCATE( netcdf_data_2d(1:ns,0:ny) )
4914                cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
4915                sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
4916
4917                DO  k = 0, 2
4918!               
4919!--                Scalar grid points
4920                   IF ( k == 0 )  THEN
4921                      shift_x = 0.5 ; shift_y = 0.5
4922!                 
4923!--                u grid points
4924                   ELSEIF ( k == 1 )  THEN
4925                      shift_x = 0.0 ; shift_y = 0.5
4926!                 
4927!--                v grid points
4928                   ELSEIF ( k == 2 )  THEN
4929                      shift_x = 0.5 ; shift_y = 0.0
4930                   ENDIF
4931
4932                   DO  j = 0, ny
4933                      DO  i = 1, ns
4934                         IF( section(i,3) == -1 )  THEN
4935                            netcdf_data_2d(i,:) = -1.0_wp !section averaged along x
4936                         ELSE
4937                            netcdf_data_2d(i,j) = init_model%origin_x          &
4938                                    + cos_ra * ( section(i,3) + shift_x ) * dx &
4939                                    + sin_ra * ( j + shift_y ) * dy
4940                         ENDIF
4941                      ENDDO
4942                   ENDDO
4943                   
4944                   nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_eutm_yz(av,k),  &
4945                                           netcdf_data_2d, start = (/ 1, 1 /),   &
4946                                           count = (/ ns, ny+1 /) )
4947                   CALL netcdf_handle_error( 'netcdf_define_header', 555 )
4948                   
4949                   DO  j = 0, ny
4950                      DO  i = 1, ns
4951                         IF( section(i,3) == -1 )  THEN
4952                            netcdf_data_2d(i,:) = -1.0_wp !section averaged along x
4953                         ELSE
4954                            netcdf_data_2d(i,j) = init_model%origin_y          &
4955                                    - sin_ra * ( section(i,3) + shift_x ) * dx &
4956                                    + cos_ra * ( j + shift_y ) * dy
4957                         ENDIF
4958                      ENDDO
4959                   ENDDO
4960
4961                   nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_nutm_yz(av,k),  &
4962                                           netcdf_data_2d, start = (/ 1, 1 /),   &
4963                                           count = (/ ns, ny+1 /) )
4964                   CALL netcdf_handle_error( 'netcdf_define_header', 556 )
4965               
4966                ENDDO
4967                DEALLOCATE( netcdf_data_2d )
4968             ENDIF
4969!
4970!--          Write lon and lat data
4971             ALLOCATE( lat(1:ns,0:ny) )
4972             ALLOCATE( lon(1:ns,0:ny) )
4973             cos_ra = COS( init_model%rotation_angle * pi / 180.0_wp )
4974             sin_ra = SIN( init_model%rotation_angle * pi / 180.0_wp )
4975
4976             DO  k = 0, 2
4977!               
4978!--             Scalar grid points
4979                IF ( k == 0 )  THEN
4980                   shift_x = 0.5 ; shift_y = 0.5
4981!               
4982!--             u grid points
4983                ELSEIF ( k == 1 )  THEN
4984                   shift_x = 0.0 ; shift_y = 0.5
4985!               
4986!--             v grid points
4987                ELSEIF ( k == 2 )  THEN
4988                   shift_x = 0.5 ; shift_y = 0.0
4989                ENDIF
4990
4991                DO  j = 0, ny
4992                   DO  i = 1, ns
4993                      IF( section(i,3) == -1 )  THEN
4994                         lat(i,:) = -90.0_wp   ! section averaged along x
4995                         lon(i,:) = -180.0_wp  ! section averaged along x
4996                      ELSE
4997                         eutm = init_model%origin_x            &
4998                              + cos_ra * ( section(i,3) + shift_x ) * dx  &
4999                              + sin_ra * ( j + shift_y ) * dy
5000                         nutm = init_model%origin_y            &
5001                              - sin_ra * ( section(i,3) + shift_x ) * dx  &
5002                              + cos_ra * ( j + shift_y ) * dy
5003
5004                         CALL  convert_utm_to_geographic( crs_list,          &
5005                                                          eutm, nutm,        &
5006                                                          lon(i,j), lat(i,j) )
5007                      ENDIF
5008                   ENDDO
5009                ENDDO
5010
5011                nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_lon_yz(av,k), &
5012                                     lon, start = (/ 1, 1 /),       &
5013                                     count = (/ ns, ny+1 /) )
5014                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
5015
5016                nc_stat = NF90_PUT_VAR( id_set_yz(av), id_var_lat_yz(av,k), &
5017                                     lat, start = (/ 1, 1 /),       &
5018                                     count = (/ ns, ny+1 /) )
5019                CALL netcdf_handle_error( 'netcdf_define_header', 556 )
5020             ENDDO
5021
5022             DEALLOCATE( lat )
5023             DEALLOCATE( lon )
5024
5025          ENDIF
5026
5027
5028       CASE ( 'yz_ext' )
5029
5030!
5031!--       Get the list of variables and compare with the actual run.
5032!--       First var_list_old has to be reset, since GET_ATT does not assign
5033!--       trailing blanks.
5034          var_list_old = ' '
5035          nc_stat = NF90_GET_ATT( id_set_yz(av), NF90_GLOBAL, 'VAR_LIST', &
5036                                  var_list_old )
5037          CALL netcdf_handle_error( 'netcdf_define_header', 207 )
5038
5039          var_list = ';'
5040          i = 1
5041          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
5042             IF ( INDEX( do2d(av,i), 'yz' ) /= 0 )  THEN
5043                var_list = TRIM( var_list ) // TRIM( do2d(av,i) ) // ';'
5044             ENDIF
5045             i = i + 1
5046          ENDDO
5047
5048          IF ( av == 0 )  THEN
5049             var = '(yz)'
5050          ELSE
5051             var = '(yz_av)'
5052          ENDIF
5053
5054          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
5055             message_string = 'netCDF file for cross-sections ' //           &
5056                              TRIM( var ) // ' from previous run found,' //  &
5057                              '&but this file cannot be extended due to' //  &
5058                              ' variable mismatch.' //                       & 
5059                              '&New file is created instead.'
5060             CALL message( 'define_netcdf_header', 'PA0249', 0, 1, 0, 6, 0 )
5061             extend = .FALSE.
5062             RETURN
5063          ENDIF
5064
5065!
5066!--       Calculate the number of current sections
5067          ns = 1
5068          DO WHILE ( section(ns,3) /= -9999  .AND.  ns <= 100 )
5069             ns = ns + 1
5070          ENDDO
5071          ns = ns - 1
5072
5073!
5074!--       Get and compare the number of vertical cross sections
5075          nc_stat = NF90_INQ_VARID( id_set_yz(av), 'x_yz', id_var_x_yz(av) )
5076          CALL netcdf_handle_error( 'netcdf_define_header', 208 )
5077
5078          nc_stat = NF90_INQUIRE_VARIABLE( id_set_yz(av), id_var_x_yz(av), &
5079                                           dimids = id_dim_x_yz_old )
5080          CALL netcdf_handle_error( 'netcdf_define_header', 209 )
5081          id_dim_x_yz(av) = id_dim_x_yz_old(1)
5082
5083          nc_stat = NF90_INQUIRE_DIMENSION( id_set_yz(av), id_dim_x_yz(av), &
5084                                            len = ns_old )
5085          CALL netcdf_handle_error( 'netcdf_define_header', 210 )
5086
5087          IF ( ns /= ns_old )  THEN
5088             message_string = 'netCDF file for cross-sections ' //          &
5089                              TRIM( var ) // ' from previous run found,' // &
5090                              '&but this file cannot be extended due to' // &
5091                              ' mismatch in number of' //                   &
5092                              ' cross sections.' //                         &
5093                              '&New file is created instead.'
5094             CALL message( 'define_netcdf_header', 'PA0250', 0, 1, 0, 6, 0 )
5095             extend = .FALSE.
5096             RETURN
5097          ENDIF
5098
5099!
5100!--       Get and compare the heights of the cross sections
5101          ALLOCATE( netcdf_data(1:ns_old) )
5102
5103          nc_stat = NF90_GET_VAR( id_set_yz(av), id_var_x_yz(av), netcdf_data )
5104          CALL netcdf_handle_error( 'netcdf_define_header', 211 )
5105
5106          DO  i = 1, ns
5107             IF ( section(i,3) /= -1 )  THEN
5108                IF ( ( ( section(i,3) + 0.5 ) * dx ) /= netcdf_data(i) )  THEN
5109                   message_string = 'netCDF file for cross-sections ' //       &
5110                              TRIM( var ) // ' from previous run found,' //    &
5111                              ' but this file cannot be extended' //           &
5112                              ' due to mismatch in cross' //                   &
5113                              ' section levels.' //                            &
5114                              ' New file is created instead.'
5115                   CALL message( 'define_netcdf_header', 'PA0251',             &
5116                                                                 0, 1, 0, 6, 0 )
5117                   extend = .FALSE.
5118                   RETURN
5119                ENDIF
5120             ELSE
5121                IF ( -1.0_wp /= netcdf_data(i) )  THEN
5122                   message_string = 'netCDF file for cross-sections ' //       &
5123                              TRIM( var ) // ' from previous run found,' //    &
5124                              ' but this file cannot be extended' //           &
5125                              ' due to mismatch in cross' //                   &
5126                              ' section levels.' //                            &
5127                              ' New file is created instead.'
5128                   CALL message( 'define_netcdf_header', 'PA0251',             &
5129                                                                 0, 1, 0, 6, 0 )
5130                   extend = .FALSE.
5131                   RETURN
5132                ENDIF
5133             ENDIF
5134          ENDDO
5135
5136          DEALLOCATE( netcdf_data )
5137
5138!
5139!--       Get the id of the time coordinate (unlimited coordinate) and its
5140!--       last index on the file. The next time level is pl2d..count+1.
5141!--       The current time must be larger than the last output time
5142!--       on the file.
5143          nc_stat = NF90_INQ_VARID( id_set_yz(av), 'time', id_var_time_yz(av) )
5144          CALL netcdf_handle_error( 'netcdf_define_header', 212 )
5145
5146          nc_stat = NF90_INQUIRE_VARIABLE( id_set_yz(av), id_var_time_yz(av), &
5147                                           dimids = id_dim_time_old )
5148          CALL netcdf_handle_error( 'netcdf_define_header', 213 )
5149          id_dim_time_yz(av) = id_dim_time_old(1)
5150
5151          nc_stat = NF90_INQUIRE_DIMENSION( id_set_yz(av), id_dim_time_yz(av), &
5152                                            len = ntime_count )
5153          CALL netcdf_handle_error( 'netcdf_define_header', 214 )
5154
5155!
5156!--       For non-parallel output use the last output time level of the netcdf
5157!--       file because the time dimension is unlimited. In case of parallel
5158!--       output the variable ntime_count could get the value of 9*10E36 because
5159!--       the time dimension is limited.
5160          IF ( netcdf_data_format < 5 ) do2d_yz_time_count(av) = ntime_count
5161
5162          nc_stat = NF90_GET_VAR( id_set_yz(av), id_var_time_yz(av),           &
5163                                  last_time_coordinate,                        &
5164                                  start = (/ do2d_yz_time_count(av) /),        &
5165                                  count = (/ 1 /) )
5166          CALL netcdf_handle_error( 'netcdf_define_header', 215 )
5167
5168          IF ( last_time_coordinate(1) >= simulated_time )  THEN
5169             message_string = 'netCDF file for cross sections ' //             &
5170                              TRIM( var ) // ' from previous run found,' //    &
5171                              '&but this file cannot be extended becaus' //    &
5172                              'e the current output time' //                   &
5173                              '&is less or equal than the last output t' //    &
5174                              'ime on this file.' //                           &
5175                              '&New file is created instead.'
5176             CALL message( 'define_netcdf_header', 'PA0252', 0, 1, 0, 6, 0 )
5177             do2d_yz_time_count(av) = 0
5178             extend = .FALSE.
5179             RETURN
5180          ENDIF
5181
5182          IF ( netcdf_data_format > 4 )  THEN
5183!
5184!--          Check if the needed number of output time levels is increased
5185!--          compared to the number of time levels in the existing file.
5186             IF ( ntdim_2d_yz(av) > ntime_count )  THEN
5187                message_string = 'netCDF file for cross sections ' //          &
5188                                 TRIM( var ) // ' from previous run found,' // &
5189                                 '&but this file cannot be extended becaus' // &
5190                                 'e the number of output time levels has b' // &
5191                                 'een increased compared to the previous s' // &
5192                                 'imulation.' //                               &
5193                                 '&New file is created instead.'
5194                CALL message( 'define_netcdf_header', 'PA0391', 0, 1, 0, 6, 0 )
5195                do2d_yz_time_count(av) = 0
5196                extend = .FALSE.
5197!
5198!--             Recalculate the needed time levels for the new file.
5199                IF ( av == 0 )  THEN
5200                   ntdim_2d_yz(0) = CEILING(                            &
5201                           ( end_time - MAX( skip_time_do2d_yz,         &
5202                                             simulated_time_at_begin )  &
5203                           ) / dt_do2d_yz )
5204                   IF ( do2d_at_begin )  ntdim_2d_yz(0) = ntdim_2d_yz(0) + 1
5205                ELSE
5206                   ntdim_2d_yz(1) = CEILING(                            &
5207                           ( end_time - MAX( skip_time_data_output_av,  &
5208                                             simulated_time_at_begin )  &
5209                           ) / dt_data_output_av )
5210                ENDIF
5211                RETURN
5212             ENDIF
5213          ENDIF
5214
5215!
5216!--       Dataset seems to be extendable.
5217!--       Now get the variable ids.
5218          i = 1
5219          DO WHILE ( do2d(av,i)(1:1) /= ' ' )
5220             IF ( INDEX( do2d(av,i), 'yz' ) /= 0 )  THEN
5221                nc_stat = NF90_INQ_VARID( id_set_yz(av), do2d(av,i), &
5222                                          id_var_do2d(av,i) )
5223                CALL netcdf_handle_error( 'netcdf_define_header', 216 )
5224#if defined( __netcdf4_parallel )
5225!
5226!--             Set independent io operations for parallel io. Collective io
5227!--             is only allowed in case of a 1d-decomposition along y, because
5228!--             otherwise, not all PEs have output data.
5229                IF ( netcdf_data_format > 4 )  THEN
5230                   IF ( npex == 1 )  THEN
5231                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_yz(av),     &
5232                                                     id_var_do2d(av,i), &
5233                                                     NF90_COLLECTIVE )
5234                   ELSE
5235!
5236!--                   Test simulations showed that the output of cross sections
5237!--                   by all PEs in data_output_2d using NF90_COLLECTIVE is
5238!--                   faster than the output by the first row of PEs in
5239!--                   y-direction using NF90_INDEPENDENT.
5240                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_yz(av),     &
5241                                                     id_var_do2d(av,i), &
5242                                                     NF90_COLLECTIVE )
5243!                      nc_stat = NF90_VAR_PAR_ACCESS( id_set_yz(av),     &
5244!                                                     id_var_do2d(av,i), &
5245!                                                     NF90_INDEPENDENT )
5246                   ENDIF
5247                   CALL netcdf_handle_error( 'netcdf_define_header', 450 )
5248                ENDIF
5249#endif
5250             ENDIF
5251             i = i + 1
5252          ENDDO
5253
5254!
5255!--       Update the title attribute on file
5256!--       In order to avoid 'data mode' errors if updated attributes are larger
5257!--       than their original size, NF90_PUT_ATT is called in 'define mode'
5258!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
5259!--       performance loss due to data copying; an alternative strategy would be
5260!--       to ensure equal attribute size in a job chain. Maybe revise later.
5261          IF ( av == 0 )  THEN
5262             time_average_text = ' '
5263          ELSE
5264             WRITE (time_average_text, '('', '',F7.1,'' s average'')') &
5265                                                            averaging_interval
5266          ENDIF
5267          nc_stat = NF90_REDEF( id_set_yz(av) )
5268          CALL netcdf_handle_error( 'netcdf_define_header', 435 )
5269          nc_stat = NF90_PUT_ATT( id_set_yz(av), NF90_GLOBAL, 'title',         &
5270                                  TRIM( run_description_header ) //            &
5271                                  TRIM( time_average_text ) )
5272          CALL netcdf_handle_error( 'netcdf_define_header', 217 )
5273          nc_stat = NF90_ENDDEF( id_set_yz(av) )
5274          CALL netcdf_handle_error( 'netcdf_define_header', 436 )
5275          message_string = 'netCDF file for cross-sections ' //                &
5276                            TRIM( var ) // ' from previous run found.' //      &
5277                           '&This file will be extended.'
5278          CALL message( 'define_netcdf_header', 'PA0253', 0, 0, 0, 6, 0 )
5279
5280
5281       CASE ( 'pr_new' )
5282
5283!
5284!--       Define some global attributes of the dataset
5285
5286          IF ( averaging_interval_pr /= 0.0_wp )  THEN
5287             CALL netcdf_create_global_atts( id_set_pr, 'podsprav', TRIM( run_description_header ), 451 )
5288             WRITE ( time_average_text,'(F7.1,'' s avg'')' ) averaging_interval_pr
5289             nc_stat = NF90_PUT_ATT( id_set_pr, NF90_GLOBAL, 'time_avg',       &
5290                                     TRIM( time_average_text ) )
5291          ELSE
5292             CALL netcdf_create_global_atts( id_set_pr, 'podspr', TRIM( run_description_header ), 451 )
5293          ENDIF
5294          CALL netcdf_handle_error( 'netcdf_define_header', 219 )
5295!
5296!--       Write number of columns and rows of coordinate systems to be plotted
5297!--       on one page to the netcdf header.
5298!--       This information can be used by palmplot.
5299          nc_stat = NF90_PUT_ATT( id_set_pr, NF90_GLOBAL,                     &
5300                                  'no_rows',                                  & 
5301                                  profile_rows ) 
5302          CALL netcdf_handle_error( 'netcdf_define_header', 519 )
5303
5304          nc_stat = NF90_PUT_ATT( id_set_pr, NF90_GLOBAL,                     &
5305                                  'no_columns',                               & 
5306                                  profile_columns ) 
5307          CALL netcdf_handle_error( 'netcdf_define_header', 520 )
5308
5309
5310          cross_profiles_adj  = ADJUSTL( cross_profiles )
5311          cross_profiles_numb = 999999
5312          cross_profiles_char = ''
5313
5314!
5315!--       Each profile defined in cross_profiles is written to an array
5316!--       (cross_profiles_char). The number of the respective coordinate
5317!--       system is assigned in a second array (cross_profiles_numb).
5318          k = 1
5319
5320          DO  i = 1, crmax
5321
5322             IF ( TRIM( cross_profiles_adj(i) ) == ' ' )  EXIT
5323             delim_old = 0
5324
5325             DO   j = 1, crmax
5326                delim = INDEX( cross_profiles_adj(i)(delim_old+1:), ' ' )
5327                IF ( delim == 1 )  EXIT
5328                kk = MIN( crmax, k )
5329                cross_profiles_char(kk) = cross_profiles_adj(i)(delim_old+1: &
5330                                                              delim_old+delim-1)
5331                cross_profiles_numb(kk) = i
5332                k = k + 1
5333                cross_profiles_maxi  = i
5334                delim_old = delim_old + delim
5335             ENDDO
5336
5337          ENDDO
5338
5339          cross_profiles_count = MIN( crmax, k-1 )
5340!
5341!--       Check if all profiles defined in cross_profiles are defined in
5342!--       data_output_pr. If not, they will be skipped.
5343          DO  i = 1, cross_profiles_count
5344             DO  j = 1, dopr_n
5345
5346                IF ( TRIM(cross_profiles_char(i)) == TRIM(data_output_pr(j)) ) &
5347                THEN
5348                   EXIT
5349                ENDIF
5350
5351                IF ( j == dopr_n )  THEN
5352                   cross_profiles_numb(i) = 999999
5353                ENDIF
5354
5355             ENDDO
5356          ENDDO
5357
5358          DO i = 1, crmax
5359             IF ( cross_profiles_numb(i) == 999999 ) THEN
5360                DO j = i + 1, crmax
5361                   IF ( cross_profiles_numb(j) /= 999999 ) THEN
5362                      cross_profiles_char(i) = cross_profiles_char(j)
5363                      cross_profiles_numb(i) = cross_profiles_numb(j)
5364                      cross_profiles_numb(j) = 999999
5365                      EXIT
5366                   ENDIF
5367                ENDDO
5368             ENDIF
5369          ENDDO
5370
5371          DO i = 1, crmax-1
5372             IF ( cross_profiles_numb(i + 1) == 999999 ) THEN
5373                cross_profiles_count = i
5374                EXIT
5375             ENDIF
5376          ENDDO
5377!
5378!--       Check if all profiles defined in data_output_pr are defined in
5379!--       cross_profiles. If not, they will be added to cross_profiles.
5380          DO  i = 1, dopr_n
5381             DO  j = 1, cross_profiles_count
5382
5383                IF ( TRIM(cross_profiles_char(j)) == TRIM(data_output_pr(i)))  &
5384                THEN
5385                   EXIT
5386                ENDIF
5387
5388                IF (( j == cross_profiles_count ) .AND.                        &
5389                    ( cross_profiles_count <= crmax - 1))  THEN
5390                   cross_profiles_count = cross_profiles_count + 1
5391                   cross_profiles_maxi  = cross_profiles_maxi  + 1
5392                   cross_profiles_char(MIN( crmax, cross_profiles_count )) =   &
5393                                                      TRIM( data_output_pr(i) )
5394                   cross_profiles_numb(MIN( crmax, cross_profiles_count )) =   &
5395                                                      cross_profiles_maxi
5396                ENDIF
5397
5398             ENDDO
5399          ENDDO
5400
5401          IF ( cross_profiles_count >= crmax )  THEN
5402             message_string = 'It is not allowed to arrange more than '        &
5403                              // '100 profiles with & cross_profiles. Apart'   &
5404                              // ' from that, all profiles are saved & to '    &
5405                              // 'the netCDF file.'
5406             CALL message( 'define_netcdf_header', 'PA0354', 0, 0, 0, 6, 0 )
5407          ENDIF
5408
5409!
5410!--       Writing cross_profiles to netcdf header. This information can be
5411!--       used by palmplot. Each profile is separated by ",", each cross is
5412!--       separated by ";".
5413          char_cross_profiles = ';'
5414          id_last = 1
5415          cross_profiles_count = MIN( cross_profiles_count, crmax )
5416
5417          DO  i = 1, cross_profiles_count
5418
5419             IF ( cross_profiles_numb(i) /= 999999 )  THEN
5420                IF ( TRIM( char_cross_profiles ) == ';' )  THEN
5421                   char_cross_profiles = TRIM( char_cross_profiles ) // &
5422                                         TRIM( cross_profiles_char(i) )
5423                ELSEIF ( id_last == cross_profiles_numb(i) )  THEN
5424                   char_cross_profiles = TRIM( char_cross_profiles ) // &
5425                                         ',' // TRIM( cross_profiles_char(i) )
5426                ELSE
5427                   char_cross_profiles = TRIM( char_cross_profiles ) // &
5428                                         ';' // TRIM( cross_profiles_char(i) )
5429                ENDIF
5430                id_last = cross_profiles_numb(i)
5431             ENDIF
5432
5433          ENDDO
5434
5435          char_cross_profiles = TRIM( char_cross_profiles ) // ';'
5436
5437          nc_stat = NF90_PUT_ATT( id_set_pr, NF90_GLOBAL, 'cross_profiles',   &
5438                                  TRIM( char_cross_profiles ) )
5439          CALL netcdf_handle_error( 'netcdf_define_header', 521 )
5440
5441!
5442!--       Define time coordinate for profiles (unlimited dimension)
5443          CALL netcdf_create_dim( id_set_pr, 'time', NF90_UNLIMITED,           &
5444                                  id_dim_time_pr, 220 )
5445          CALL netcdf_create_var( id_set_pr, (/ id_dim_time_pr /), 'time',     &
5446                                  NF90_DOUBLE, id_var_time_pr, 'seconds since '//TRIM(init_model%origin_time), 'time',  &
5447                                  221, 222, 000 )
5448          CALL netcdf_create_att( id_set_pr, id_var_time_pr, 'standard_name', 'time', 000)
5449          CALL netcdf_create_att( id_set_pr, id_var_time_pr, 'axis', 'T', 000)
5450!
5451!--       Define the variables
5452          var_list = ';'
5453          DO  i = 1, dopr_n
5454
5455             IF ( statistic_regions == 0 )  THEN
5456
5457!
5458!--             Define the z-axes (each variable gets its own z-axis)
5459                CALL netcdf_create_dim( id_set_pr,                             &
5460                                        'z' // TRIM( data_output_pr(i) ),      &
5461                                        nzt+2-nzb, id_dim_z_pr(i,0), 223 )
5462                CALL netcdf_create_var( id_set_pr, (/ id_dim_z_pr(i,0) /),     &
5463                                        'z' // TRIM( data_output_pr(i) ),      &
5464                                       NF90_DOUBLE, id_var_z_pr(i,0),          &
5465                                       'meters', '', 224, 225, 000 )
5466!
5467!--             Define the variable
5468                CALL netcdf_create_var( id_set_pr, (/ id_dim_z_pr(i,0),        &
5469                                        id_dim_time_pr /), data_output_pr(i),  &
5470                                        nc_precision(5), id_var_dopr(i,0),     &
5471                                        TRIM( dopr_unit(i) ),                  &
5472                                        TRIM( data_output_pr(i) ), 226, 227,   &
5473                                        228 )
5474
5475                var_list = TRIM( var_list ) // TRIM( data_output_pr(i) ) //  ';'
5476
5477             ELSE
5478!
5479!--             If statistic regions are defined, add suffix _SR+#SR to the
5480!--             names
5481                DO  j = 0, statistic_regions
5482                   WRITE ( suffix, '(''_'',I2.2)' )  j
5483
5484!
5485!--                Define the z-axes (each variable gets it own z-axis)
5486                   CALL netcdf_create_dim( id_set_pr, 'z' //                   &
5487                                           TRIM(data_output_pr(i)) // suffix,  &
5488                                           nzt+2-nzb, id_dim_z_pr(i,j), 229 )
5489                   CALL netcdf_create_var( id_set_pr, (/ id_dim_z_pr(i,j) /),  &
5490                                           'z' // TRIM(data_output_pr(i)) //   &
5491                                           suffix, NF90_DOUBLE,                &
5492                                           id_var_z_pr(i,j), 'meters', '',     &
5493                                           230, 231, 000 )
5494!
5495!--                Define the variable
5496                   CALL netcdf_create_var( id_set_pr, (/ id_dim_z_pr(i,j),     &
5497                                           id_dim_time_pr /),                  &
5498                                           TRIM(data_output_pr(i)) // suffix,  &
5499                                           nc_precision(5), id_var_dopr(i,j),  &
5500                                           TRIM( dopr_unit(i) ),               &
5501                                           TRIM( data_output_pr(i) ) //        &
5502                                           ' SR ', 232, 233, 234 )
5503
5504                   var_list = TRIM( var_list ) // TRIM( data_output_pr(i) ) // &
5505                              suffix // ';'
5506
5507                ENDDO
5508
5509             ENDIF
5510
5511          ENDDO
5512
5513!
5514!--       Write the list of variables as global attribute (this is used by
5515!--       restart runs)
5516          nc_stat = NF90_PUT_ATT( id_set_pr, NF90_GLOBAL, 'VAR_LIST', var_list )
5517          CALL netcdf_handle_error( 'netcdf_define_header', 235 )
5518
5519!
5520!--       Define normalization variables (as time series)
5521          DO  i = 1, dopr_norm_num
5522
5523             CALL netcdf_create_var( id_set_pr, (/ id_dim_time_pr /),          &
5524                                     'NORM_' // TRIM( dopr_norm_names(i) ),    &
5525                                     nc_precision(5), id_var_norm_dopr(i),     &
5526                                     '', TRIM( dopr_norm_longnames(i) ), 236,  &
5527                                     000, 237 )
5528
5529          ENDDO
5530
5531!
5532!--       Leave netCDF define mode
5533          nc_stat = NF90_ENDDEF( id_set_pr )
5534          CALL netcdf_handle_error( 'netcdf_define_header', 238 )
5535
5536!
5537!--       Write z-axes data
5538          DO  i = 1, dopr_n
5539             DO  j = 0, statistic_regions
5540
5541                nc_stat = NF90_PUT_VAR( id_set_pr, id_var_z_pr(i,j),      &
5542                                        hom(nzb:nzt+1,2,dopr_index(i),0), &
5543                                        start = (/ 1 /),                  &
5544                                        count = (/ nzt-nzb+2 /) )
5545                CALL netcdf_handle_error( 'netcdf_define_header', 239 )
5546
5547             ENDDO
5548          ENDDO
5549
5550
5551       CASE ( 'pr_ext' )
5552
5553!
5554!--       Get the list of variables and compare with the actual run.
5555!--       First var_list_old has to be reset, since GET_ATT does not assign
5556!--       trailing blanks.
5557          var_list_old = ' '
5558          nc_stat = NF90_GET_ATT( id_set_pr, NF90_GLOBAL, 'VAR_LIST', &
5559                                  var_list_old )
5560          CALL netcdf_handle_error( 'netcdf_define_header', 240 )
5561
5562          var_list = ';'
5563          DO  i = 1, dopr_n
5564
5565             IF ( statistic_regions == 0 )  THEN
5566                var_list = TRIM( var_list ) // TRIM( data_output_pr(i) ) // ';'
5567             ELSE
5568                DO  j = 0, statistic_regions
5569                   WRITE ( suffix, '(''_'',I2.2)' )  j
5570                   var_list = TRIM( var_list ) // TRIM( data_output_pr(i) ) // &
5571                              suffix // ';'
5572                ENDDO
5573             ENDIF
5574
5575          ENDDO
5576
5577          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
5578             message_string = 'netCDF file for vertical profiles ' //          &
5579                              'from previous run found,' //                    &
5580                              '&but this file cannot be extended due to' //    &
5581                              ' variable mismatch.' //                         &
5582                              '&New file is created instead.'
5583             CALL message( 'define_netcdf_header', 'PA0254', 0, 1, 0, 6, 0 )
5584             extend = .FALSE.
5585             RETURN
5586          ENDIF
5587
5588!
5589!--       Get the id of the time coordinate (unlimited coordinate) and its
5590!--       last index on the file. The next time level is dopr..count+1.
5591!--       The current time must be larger than the last output time
5592!--       on the file.
5593          nc_stat = NF90_INQ_VARID( id_set_pr, 'time', id_var_time_pr )
5594          CALL netcdf_handle_error( 'netcdf_define_header', 241 )
5595
5596          nc_stat = NF90_INQUIRE_VARIABLE( id_set_pr, id_var_time_pr, &
5597                                           dimids = id_dim_time_old )
5598          CALL netcdf_handle_error( 'netcdf_define_header', 242 )
5599          id_dim_time_pr = id_dim_time_old(1)
5600
5601          nc_stat = NF90_INQUIRE_DIMENSION( id_set_pr, id_dim_time_pr, &
5602                                            len = dopr_time_count )
5603          CALL netcdf_handle_error( 'netcdf_define_header', 243 )
5604
5605          nc_stat = NF90_GET_VAR( id_set_pr, id_var_time_pr,        &
5606                                  last_time_coordinate,             &
5607                                  start = (/ dopr_time_count /), &
5608                                  count = (/ 1 /) )
5609          CALL netcdf_handle_error( 'netcdf_define_header', 244 )
5610
5611          IF ( last_time_coordinate(1) >= simulated_time )  THEN
5612             message_string = 'netCDF file for vertical profiles ' //          &
5613                              'from previous run found,' //                    &
5614                              '&but this file cannot be extended becaus' //    &
5615                              'e the current output time' //                   &
5616                              '&is less or equal than the last output t' //    &
5617                              'ime on this file.' //                           &
5618                              '&New file is created instead.'
5619             CALL message( 'define_netcdf_header', 'PA0255', 0, 1, 0, 6, 0 )
5620             dopr_time_count = 0
5621             extend = .FALSE.
5622             RETURN
5623          ENDIF
5624
5625!
5626!--       Dataset seems to be extendable.
5627!--       Now get the variable ids.
5628          i = 1
5629          DO  i = 1, dopr_n
5630 
5631             IF ( statistic_regions == 0 )  THEN
5632                nc_stat = NF90_INQ_VARID( id_set_pr, data_output_pr(i),        &
5633                                          id_var_dopr(i,0) )
5634                CALL netcdf_handle_error( 'netcdf_define_header', 245 )
5635             ELSE
5636                DO  j = 0, statistic_regions
5637                   WRITE ( suffix, '(''_'',I2.2)' )  j
5638                   netcdf_var_name = TRIM( data_output_pr(i) ) // suffix
5639                   nc_stat = NF90_INQ_VARID( id_set_pr, netcdf_var_name,       &
5640                                             id_var_dopr(i,j) )
5641                   CALL netcdf_handle_error( 'netcdf_define_header', 246 )
5642                ENDDO
5643             ENDIF
5644
5645          ENDDO
5646
5647!
5648!--       Get ids of the normalization variables
5649          DO  i = 1, dopr_norm_num
5650             nc_stat = NF90_INQ_VARID( id_set_pr,                             &
5651                                       'NORM_' // TRIM( dopr_norm_names(i) ), &
5652                                       id_var_norm_dopr(i) )
5653             CALL netcdf_handle_error( 'netcdf_define_header', 247 )
5654          ENDDO
5655
5656!
5657!--       Update the title attribute on file
5658!--       In order to avoid 'data mode' errors if updated attributes are larger
5659!--       than their original size, NF90_PUT_ATT is called in 'define mode'
5660!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
5661!--       performance loss due to data copying; an alternative strategy would be
5662!--       to ensure equal attribute size in a job chain. Maybe revise later.
5663          IF ( averaging_interval_pr == 0.0_wp )  THEN
5664             time_average_text = ' '
5665          ELSE
5666             WRITE (time_average_text, '('', '',F7.1,'' s average'')') &
5667                                                            averaging_interval_pr
5668          ENDIF
5669          nc_stat = NF90_REDEF( id_set_pr )
5670          CALL netcdf_handle_error( 'netcdf_define_header', 437 )
5671          nc_stat = NF90_PUT_ATT( id_set_pr, NF90_GLOBAL, 'title',             &
5672                                  TRIM( run_description_header ) //            &
5673                                  TRIM( time_average_text ) )
5674          CALL netcdf_handle_error( 'netcdf_define_header', 248 )
5675
5676          nc_stat = NF90_ENDDEF( id_set_pr )
5677          CALL netcdf_handle_error( 'netcdf_define_header', 438 )
5678          message_string = 'netCDF file for vertical profiles ' //             &
5679                           'from previous run found.' //                       &
5680                           '&This file will be extended.'
5681          CALL message( 'define_netcdf_header', 'PA0256', 0, 0, 0, 6, 0 )
5682
5683
5684       CASE ( 'ts_new' )
5685
5686!
5687!--       Define some global attributes of the dataset
5688          CALL netcdf_create_global_atts( id_set_ts, 'podsts', TRIM(run_description_header), 329 )
5689
5690          ! nc_stat = NF90_PUT_ATT( id_set_ts, NF90_GLOBAL, 'title',             &
5691          !                         TRIM( run_description_header ) )
5692          ! CALL netcdf_handle_error( 'netcdf_define_header', 249 )
5693
5694!
5695!--       Define time coordinate for time series (unlimited dimension)
5696          CALL netcdf_create_dim( id_set_ts, 'time', NF90_UNLIMITED,           &
5697                                  id_dim_time_ts, 250 )
5698          CALL netcdf_create_var( id_set_ts, (/ id_dim_time_ts /), 'time',     &
5699                                  NF90_DOUBLE, id_var_time_ts, 'seconds since '//TRIM(init_model%origin_time), 'time',  &
5700                                  251, 252, 000 )
5701          CALL netcdf_create_att( id_set_ts, id_var_time_ts, 'standard_name', 'time', 000)
5702          CALL netcdf_create_att( id_set_ts, id_var_time_ts, 'axis', 'T', 000)
5703!
5704!--       Define the variables
5705          var_list = ';'
5706          DO  i = 1, dots_num
5707
5708             IF ( statistic_regions == 0 )  THEN
5709
5710                CALL netcdf_create_var( id_set_ts, (/ id_dim_time_ts /),       &
5711                                        dots_label(i), nc_precision(6),        &
5712                                        id_var_dots(i,0),                      &
5713                                        TRIM( dots_unit(i) ),                  &
5714                                        TRIM( dots_label(i) ), 253, 254, 255 )
5715
5716                var_list = TRIM( var_list ) // TRIM( dots_label(i) ) // ';'
5717
5718             ELSE
5719!
5720!--             If statistic regions are defined, add suffix _SR+#SR to the
5721!--             names
5722                DO  j = 0, statistic_regions
5723                   WRITE ( suffix, '(''_'',I2.2)' )  j
5724
5725                   CALL netcdf_create_var( id_set_ts, (/ id_dim_time_ts /),    &
5726                                           TRIM( dots_label(i) ) // suffix,    &
5727                                           nc_precision(6), id_var_dots(i,j),  &
5728                                           TRIM( dots_unit(i) ),               &
5729                                           TRIM( dots_label(i) ) // ' SR ' //  &
5730                                           suffix(2:2), 256, 257, 347)
5731
5732                   var_list = TRIM( var_list ) // TRIM( dots_label(i) ) // &
5733                              suffix // ';'
5734
5735                ENDDO
5736
5737             ENDIF
5738
5739          ENDDO
5740
5741!
5742!--       Write the list of variables as global attribute (this is used by
5743!--       restart runs)
5744          nc_stat = NF90_PUT_ATT( id_set_ts, NF90_GLOBAL, 'VAR_LIST', var_list )
5745          CALL netcdf_handle_error( 'netcdf_define_header', 258 )
5746
5747!
5748!--       Leave netCDF define mode
5749          nc_stat = NF90_ENDDEF( id_set_ts )
5750          CALL netcdf_handle_error( 'netcdf_define_header', 259 )
5751
5752
5753       CASE ( 'ts_ext' )
5754
5755!
5756!--       Get the list of variables and compare with the actual run.
5757!--       First var_list_old has to be reset, since GET_ATT does not assign
5758!--       trailing blanks.
5759          var_list_old = ' '
5760          nc_stat = NF90_GET_ATT( id_set_ts, NF90_GLOBAL, 'VAR_LIST', &
5761                                  var_list_old )
5762          CALL netcdf_handle_error( 'netcdf_define_header', 260 )
5763
5764          var_list = ';'
5765          i = 1
5766          DO  i = 1, dots_num
5767
5768             IF ( statistic_regions == 0 )  THEN
5769                var_list = TRIM( var_list ) // TRIM( dots_label(i) ) // ';'
5770             ELSE
5771                DO  j = 0, statistic_regions
5772                   WRITE ( suffix, '(''_'',I2.2)' )  j
5773                   var_list = TRIM( var_list ) // TRIM( dots_label(i) ) //     &
5774                              suffix // ';'
5775                ENDDO
5776             ENDIF
5777
5778          ENDDO
5779
5780          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
5781             message_string = 'netCDF file for time series ' //                &
5782                              'from previous run found,' //                    &
5783                              '&but this file cannot be extended due to' //    &
5784                              ' variable mismatch.' //                         &
5785                              '&New file is created instead.'
5786             CALL message( 'define_netcdf_header', 'PA0257', 0, 1, 0, 6, 0 )
5787             extend = .FALSE.
5788             RETURN
5789          ENDIF
5790
5791!
5792!--       Get the id of the time coordinate (unlimited coordinate) and its
5793!--       last index on the file. The next time level is dots..count+1.
5794!--       The current time must be larger than the last output time
5795!--       on the file.
5796          nc_stat = NF90_INQ_VARID( id_set_ts, 'time', id_var_time_ts )
5797          CALL netcdf_handle_error( 'netcdf_define_header', 261 )
5798
5799          nc_stat = NF90_INQUIRE_VARIABLE( id_set_ts, id_var_time_ts,          &
5800                                           dimids = id_dim_time_old )
5801          CALL netcdf_handle_error( 'netcdf_define_header', 262 )
5802          id_dim_time_ts = id_dim_time_old(1)
5803
5804          nc_stat = NF90_INQUIRE_DIMENSION( id_set_ts, id_dim_time_ts,         &
5805                                            len = dots_time_count )
5806          CALL netcdf_handle_error( 'netcdf_define_header', 263 )
5807
5808          nc_stat = NF90_GET_VAR( id_set_ts, id_var_time_ts,                   &
5809                                  last_time_coordinate,                        &
5810                                  start = (/ dots_time_count /),               &
5811                                  count = (/ 1 /) )
5812          CALL netcdf_handle_error( 'netcdf_define_header', 264 )
5813
5814          IF ( last_time_coordinate(1) >= simulated_time )  THEN
5815             message_string = 'netCDF file for time series ' //                &
5816                              'from previous run found,' //                    &
5817                              '&but this file cannot be extended becaus' //    &
5818                              'e the current output time' //                   &
5819                              '&is less or equal than the last output t' //    &
5820                              'ime on this file.' //                           &
5821                              '&New file is created instead.'
5822             CALL message( 'define_netcdf_header', 'PA0258', 0, 1, 0, 6, 0 )
5823             dots_time_count = 0
5824             extend = .FALSE.
5825             RETURN
5826          ENDIF
5827
5828!
5829!--       Dataset seems to be extendable.
5830!--       Now get the variable ids
5831          i = 1
5832          DO  i = 1, dots_num
5833 
5834             IF ( statistic_regions == 0 )  THEN
5835                nc_stat = NF90_INQ_VARID( id_set_ts, dots_label(i), &
5836                                          id_var_dots(i,0) )
5837                CALL netcdf_handle_error( 'netcdf_define_header', 265 )
5838             ELSE
5839                DO  j = 0, statistic_regions
5840                   WRITE ( suffix, '(''_'',I2.2)' )  j
5841                   netcdf_var_name = TRIM( dots_label(i) ) // suffix
5842                   nc_stat = NF90_INQ_VARID( id_set_ts, netcdf_var_name, &
5843                                             id_var_dots(i,j) )
5844                   CALL netcdf_handle_error( 'netcdf_define_header', 266 )
5845                ENDDO
5846             ENDIF
5847
5848          ENDDO
5849
5850!
5851!--       Update the title attribute on file
5852!--       In order to avoid 'data mode' errors if updated attributes are larger
5853!--       than their original size, NF90_PUT_ATT is called in 'define mode'
5854!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
5855!--       performance loss due to data copying; an alternative strategy would be
5856!--       to ensure equal attribute size in a job chain. Maybe revise later.
5857          nc_stat = NF90_REDEF( id_set_ts )
5858          CALL netcdf_handle_error( 'netcdf_define_header', 439 )
5859          nc_stat = NF90_PUT_ATT( id_set_ts, NF90_GLOBAL, 'title',             &
5860                                  TRIM( run_description_header ) )
5861          CALL netcdf_handle_error( 'netcdf_define_header', 267 )
5862          nc_stat = NF90_ENDDEF( id_set_ts )
5863          CALL netcdf_handle_error( 'netcdf_define_header', 440 )
5864          message_string = 'netCDF file for time series ' //                   &
5865                           'from previous run found.' //                       &
5866                           '&This file will be extended.'
5867          CALL message( 'define_netcdf_header', 'PA0259', 0, 0, 0, 6, 0 )
5868
5869
5870       CASE ( 'sp_new' )
5871
5872!
5873!--       Define some global attributes of the dataset
5874          IF ( averaging_interval_sp /= 0.0_wp )  THEN
5875             WRITE (time_average_text,'('', '',F7.1,'' s average'')')          &
5876                                                            averaging_interval_sp
5877             nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'title',          &
5878                                     TRIM( run_description_header ) //         &
5879                                     TRIM( time_average_text ) )
5880             CALL netcdf_handle_error( 'netcdf_define_header', 268 )
5881
5882             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval_sp
5883             nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'time_avg', &
5884                                     TRIM( time_average_text ) )
5885          ELSE
5886             nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'title', &
5887                                     TRIM( run_description_header ) )
5888          ENDIF
5889          CALL netcdf_handle_error( 'netcdf_define_header', 269 )
5890
5891!
5892!--       Define time coordinate for spectra (unlimited dimension)
5893          CALL netcdf_create_dim( id_set_sp, 'time', NF90_UNLIMITED,           &
5894                                  id_dim_time_sp, 270 )
5895          CALL netcdf_create_var( id_set_sp, (/ id_dim_time_sp /), 'time',     &
5896                                  NF90_DOUBLE, id_var_time_sp, 'seconds since '//TRIM(init_model%origin_time), 'time',  &
5897                                  271, 272, 000 )
5898          CALL netcdf_create_att( id_set_sp, id_var_time_sp, 'standard_name', 'time', 000)
5899          CALL netcdf_create_att( id_set_sp, id_var_time_sp, 'axis', 'T', 000)
5900!
5901!--       Define the spatial dimensions and coordinates for spectra.
5902!--       First, determine the number of vertical levels for which spectra
5903!--       are to be output.
5904          ns = 1
5905          DO WHILE ( comp_spectra_level(ns) /= 999999  .AND.  ns <= 100 )
5906             ns = ns + 1
5907          ENDDO
5908          ns = ns - 1
5909
5910!
5911!--       Define vertical coordinate grid (zu grid)
5912          CALL netcdf_create_dim( id_set_sp, 'zu_sp', ns, id_dim_zu_sp, 273 )
5913          CALL netcdf_create_var( id_set_sp, (/ id_dim_zu_sp /), 'zu_sp',      &
5914                                  NF90_DOUBLE, id_var_zu_sp, 'meters', '',     &
5915                                  274, 275, 000 )
5916!
5917!--       Define vertical coordinate grid (zw grid)
5918          CALL netcdf_create_dim( id_set_sp, 'zw_sp', ns, id_dim_zw_sp, 276 )
5919          CALL netcdf_create_var( id_set_sp, (/ id_dim_zw_sp /), 'zw_sp',      &
5920                                  NF90_DOUBLE, id_var_zw_sp, 'meters', '',     &
5921                                  277, 278, 000 )
5922!
5923!--       Define x-axis
5924          CALL netcdf_create_dim( id_set_sp, 'k_x', nx/2, id_dim_x_sp, 279 )
5925          CALL netcdf_create_var( id_set_sp, (/ id_dim_x_sp /), 'k_x',         &
5926                                  NF90_DOUBLE, id_var_x_sp, 'm-1', '', 280,    &
5927                                  281, 000 )
5928!
5929!--       Define y-axis
5930          CALL netcdf_create_dim( id_set_sp, 'k_y', ny/2, id_dim_y_sp, 282 )
5931          CALL netcdf_create_var( id_set_sp, (/ id_dim_y_sp /), 'k_y',         &
5932                                  NF90_DOUBLE, id_var_y_sp, 'm-1', '', 283,    &
5933                                  284, 000 )
5934!
5935!--       Define the variables
5936          var_list = ';'
5937          i = 1
5938          DO WHILE ( data_output_sp(i) /= ' '  .AND.  i <= 10 )
5939!
5940!--          First check for the vertical grid
5941             found = .FALSE.
5942             SELECT CASE ( data_output_sp(i) )
5943!
5944!--             Most variables are defined on the zu levels
5945                CASE ( 'e', 'nc', 'nr', 'p', 'pc', 'pr', 'prr',   &
5946                       'q', 'qc', 'ql', 'ql_c', 'ql_v', 'ql_vp', 'qr', 'qv',   &
5947                       'rho_sea_water', 's', 'sa', &
5948                       'theta', 'thetal', 'thetav', 'u', 'v' )
5949
5950                   grid_z = 'zu'
5951!
5952!--             zw levels
5953                CASE ( 'w' )
5954
5955                   grid_z = 'zw'
5956
5957                CASE DEFAULT
5958!
5959!--                Check for user-defined quantities (found, grid_x and grid_y
5960!--                are dummies)
5961                   CALL user_define_netcdf_grid( data_output_sp(i), found,     &
5962                                                 grid_x, grid_y, grid_z )
5963
5964             END SELECT
5965
5966             IF ( INDEX( spectra_direction(i), 'x' ) /= 0 )  THEN
5967
5968!
5969!--             Define the variable
5970                netcdf_var_name = TRIM( data_output_sp(i) ) // '_x'
5971                IF ( TRIM( grid_z ) == 'zw' )  THEN
5972                   CALL netcdf_create_var( id_set_sp, (/ id_dim_x_sp,          &
5973                                           id_dim_zw_sp, id_dim_time_sp /),    &
5974                                           netcdf_var_name, nc_precision(7),   &
5975                                           id_var_dospx(i), 'unknown',         &
5976                                           netcdf_var_name, 285, 286, 287 )
5977                ELSE
5978                   CALL netcdf_create_var( id_set_sp, (/ id_dim_x_sp,          &
5979                                           id_dim_zu_sp, id_dim_time_sp /),    &
5980                                           netcdf_var_name, nc_precision(7),   &
5981                                           id_var_dospx(i), 'unknown',         &
5982                                           netcdf_var_name, 285, 286, 287 )
5983                ENDIF
5984
5985                var_list = TRIM( var_list ) // TRIM( netcdf_var_name ) // ';'
5986
5987             ENDIF
5988
5989             IF ( INDEX( spectra_direction(i), 'y' ) /= 0 )  THEN
5990
5991!
5992!--             Define the variable
5993                netcdf_var_name = TRIM( data_output_sp(i) ) // '_y'
5994                IF ( TRIM( grid_z ) == 'zw' )  THEN
5995                   CALL netcdf_create_var( id_set_sp, (/ id_dim_y_sp,          &
5996                                           id_dim_zw_sp, id_dim_time_sp /),    &
5997                                           netcdf_var_name, nc_precision(7),   &
5998                                           id_var_dospy(i), 'unknown',         &
5999                                           netcdf_var_name, 288, 289, 290 )
6000                ELSE
6001                   CALL netcdf_create_var( id_set_sp, (/ id_dim_y_sp,          &
6002                                           id_dim_zu_sp, id_dim_time_sp /),    &
6003                                           netcdf_var_name, nc_precision(7),   &
6004                                           id_var_dospy(i), 'unknown',         &
6005                                           netcdf_var_name, 288, 289, 290 )
6006                ENDIF
6007
6008                var_list = TRIM( var_list ) // TRIM( netcdf_var_name ) // ';'
6009
6010             ENDIF
6011
6012             i = i + 1
6013
6014          ENDDO
6015
6016!
6017!--       Write the list of variables as global attribute (this is used by
6018!--       restart runs)
6019          nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'VAR_LIST', var_list )
6020          CALL netcdf_handle_error( 'netcdf_define_header', 291 )
6021
6022!
6023!--       Leave netCDF define mode
6024          nc_stat = NF90_ENDDEF( id_set_sp )
6025          CALL netcdf_handle_error( 'netcdf_define_header', 292 )
6026
6027!
6028!--       Write axis data: zu_sp, zw_sp, k_x, k_y
6029          ALLOCATE( netcdf_data(1:ns) )
6030
6031!
6032!--       Write zu data
6033          netcdf_data(1:ns) = zu( comp_spectra_level(1:ns) )
6034          nc_stat = NF90_PUT_VAR( id_set_sp, id_var_zu_sp, netcdf_data, &
6035                                  start = (/ 1 /), count = (/ ns /) )
6036          CALL netcdf_handle_error( 'netcdf_define_header', 293 )
6037
6038!
6039!--       Write zw data
6040          netcdf_data(1:ns) = zw( comp_spectra_level(1:ns) )
6041          nc_stat = NF90_PUT_VAR( id_set_sp, id_var_zw_sp, netcdf_data, &
6042                                  start = (/ 1 /), count = (/ ns /) )
6043          CALL netcdf_handle_error( 'netcdf_define_header', 294 )
6044
6045          DEALLOCATE( netcdf_data )
6046
6047!
6048!--       Write data for x and y axis (wavenumbers)
6049          ALLOCATE( netcdf_data(nx/2) )
6050          DO  i = 1, nx/2
6051             netcdf_data(i) = 2.0_wp * pi * i / ( dx * ( nx + 1 ) )
6052          ENDDO
6053
6054          nc_stat = NF90_PUT_VAR( id_set_sp, id_var_x_sp, netcdf_data, &
6055                                  start = (/ 1 /), count = (/ nx/2 /) )
6056          CALL netcdf_handle_error( 'netcdf_define_header', 295 )
6057
6058          DEALLOCATE( netcdf_data )
6059
6060          ALLOCATE( netcdf_data(ny/2) )
6061          DO  i = 1, ny/2
6062             netcdf_data(i) = 2.0_wp * pi * i / ( dy * ( ny + 1 ) )
6063          ENDDO
6064
6065          nc_stat = NF90_PUT_VAR( id_set_sp, id_var_y_sp, netcdf_data, &
6066                                  start = (/ 1 /), count = (/ ny/2 /) )
6067          CALL netcdf_handle_error( 'netcdf_define_header', 296 )
6068
6069          DEALLOCATE( netcdf_data )
6070
6071
6072       CASE ( 'sp_ext' )
6073
6074!
6075!--       Get the list of variables and compare with the actual run.
6076!--       First var_list_old has to be reset, since GET_ATT does not assign
6077!--       trailing blanks.
6078          var_list_old = ' '
6079          nc_stat = NF90_GET_ATT( id_set_sp, NF90_GLOBAL, 'VAR_LIST', &
6080                                  var_list_old )
6081          CALL netcdf_handle_error( 'netcdf_define_header', 297 )
6082          var_list = ';'
6083          i = 1
6084          DO WHILE ( data_output_sp(i) /= ' '  .AND.  i <= 10 )
6085
6086             IF ( INDEX( spectra_direction(i), 'x' ) /= 0 )  THEN
6087                netcdf_var_name = TRIM( data_output_sp(i) ) // '_x'
6088                var_list = TRIM( var_list ) // TRIM( netcdf_var_name ) // ';'
6089             ENDIF
6090
6091             IF ( INDEX( spectra_direction(i), 'y' ) /= 0 )  THEN
6092                netcdf_var_name = TRIM( data_output_sp(i) ) // '_y'
6093                var_list = TRIM( var_list ) // TRIM( netcdf_var_name ) // ';'
6094             ENDIF
6095
6096             i = i + 1
6097
6098          ENDDO
6099
6100          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
6101             message_string = 'netCDF file for spectra  ' //                   &
6102                              'from previous run found,' //                    &
6103                              '&but this file cannot be extended due to' //    &
6104                              ' variable mismatch.' //                         &
6105                              '&New file is created instead.'
6106             CALL message( 'define_netcdf_header', 'PA0260', 0, 1, 0, 6, 0 )
6107             extend = .FALSE.
6108             RETURN
6109          ENDIF
6110
6111!
6112!--       Determine the number of current vertical levels for which spectra
6113!--       shall be output
6114          ns = 1
6115          DO WHILE ( comp_spectra_level(ns) /= 999999  .AND.  ns <= 100 )
6116             ns = ns + 1
6117          ENDDO
6118          ns = ns - 1
6119
6120!
6121!--       Get and compare the number of vertical levels
6122          nc_stat = NF90_INQ_VARID( id_set_sp, 'zu_sp', id_var_zu_sp )
6123          CALL netcdf_handle_error( 'netcdf_define_header', 298 )
6124
6125          nc_stat = NF90_INQUIRE_VARIABLE( id_set_sp, id_var_zu_sp, &
6126                                           dimids = id_dim_zu_sp_old )
6127          CALL netcdf_handle_error( 'netcdf_define_header', 299 )
6128          id_dim_zu_sp = id_dim_zu_sp_old(1)
6129
6130          nc_stat = NF90_INQUIRE_DIMENSION( id_set_sp, id_dim_zu_sp, &
6131                                            len = ns_old )
6132          CALL netcdf_handle_error( 'netcdf_define_header', 300 )
6133
6134          IF ( ns /= ns_old )  THEN
6135             message_string = 'netCDF file for spectra ' //                    &
6136                              ' from previous run found,' //                   &
6137                              '&but this file cannot be extended due to' //    &
6138                              ' mismatch in number of' //                      &
6139                              ' vertical levels.' //                           &
6140                              '&New file is created instead.'
6141             CALL message( 'define_netcdf_header', 'PA0261', 0, 1, 0, 6, 0 )
6142             extend = .FALSE.
6143             RETURN
6144          ENDIF
6145
6146!
6147!--       Get and compare the heights of the cross sections
6148          ALLOCATE( netcdf_data(1:ns_old) )
6149
6150          nc_stat = NF90_GET_VAR( id_set_sp, id_var_zu_sp, netcdf_data )
6151          CALL netcdf_handle_error( 'netcdf_define_header', 301 )
6152
6153          DO  i = 1, ns
6154             IF ( zu(comp_spectra_level(i)) /= netcdf_data(i) )  THEN
6155                message_string = 'netCDF file for spectra ' //                 &
6156                                 ' from previous run found,' //                &
6157                                 '&but this file cannot be extended due to' // &
6158                                 ' mismatch in heights of' //                  &
6159                                 ' vertical levels.' //                        &
6160                                 '&New file is created instead.'
6161                CALL message( 'define_netcdf_header', 'PA0262', 0, 1, 0, 6, 0 )
6162                extend = .FALSE.
6163                RETURN
6164             ENDIF
6165          ENDDO
6166
6167          DEALLOCATE( netcdf_data )
6168
6169!
6170!--       Get the id of the time coordinate (unlimited coordinate) and its
6171!--       last index on the file. The next time level is plsp..count+1.
6172!--       The current time must be larger than the last output time
6173!--       on the file.
6174          nc_stat = NF90_INQ_VARID( id_set_sp, 'time', id_var_time_sp )
6175          CALL netcdf_handle_error( 'netcdf_define_header', 302 )
6176
6177          nc_stat = NF90_INQUIRE_VARIABLE( id_set_sp, id_var_time_sp, &
6178                                           dimids = id_dim_time_old )
6179          CALL netcdf_handle_error( 'netcdf_define_header', 303 )
6180          id_dim_time_sp = id_dim_time_old(1)
6181
6182          nc_stat = NF90_INQUIRE_DIMENSION( id_set_sp, id_dim_time_sp, &
6183                                            len = dosp_time_count )
6184          CALL netcdf_handle_error( 'netcdf_define_header', 304 )
6185
6186          nc_stat = NF90_GET_VAR( id_set_sp, id_var_time_sp,        &
6187                                  last_time_coordinate,             &
6188                                  start = (/ dosp_time_count /), &
6189                                  count = (/ 1 /) )
6190          CALL netcdf_handle_error( 'netcdf_define_header', 305 )
6191
6192          IF ( last_time_coordinate(1) >= simulated_time )  THEN
6193             message_string = 'netCDF file for spectra ' //                    &
6194                              'from previous run found,' //                    &
6195                              '&but this file cannot be extended becaus' //    &
6196                              'e the current output time' //                   & 
6197                              '&is less or equal than the last output t' //    &
6198                              'ime on this file.' //                           &
6199                              '&New file is created instead.'
6200             CALL message( 'define_netcdf_header', 'PA0263', 0, 1, 0, 6, 0 )
6201             dosp_time_count = 0
6202             extend = .FALSE.
6203             RETURN
6204          ENDIF
6205
6206!
6207!--       Dataset seems to be extendable.
6208!--       Now get the variable ids.
6209          i = 1
6210          DO WHILE ( data_output_sp(i) /= ' '  .AND.  i <= 10 )
6211
6212             IF ( INDEX( spectra_direction(i), 'x' ) /= 0 )  THEN
6213                netcdf_var_name = TRIM( data_output_sp(i) ) // '_x'
6214                nc_stat = NF90_INQ_VARID( id_set_sp, netcdf_var_name, &
6215                                          id_var_dospx(i) )
6216                CALL netcdf_handle_error( 'netcdf_define_header', 306 )
6217             ENDIF
6218
6219             IF ( INDEX( spectra_direction(i), 'y' ) /= 0 )  THEN
6220                netcdf_var_name = TRIM( data_output_sp(i) ) // '_y'
6221                nc_stat = NF90_INQ_VARID( id_set_sp, netcdf_var_name, &
6222                                          id_var_dospy(i) )
6223                CALL netcdf_handle_error( 'netcdf_define_header', 307 )
6224             ENDIF
6225
6226             i = i + 1
6227
6228          ENDDO
6229
6230!
6231!--       Update the title attribute on file
6232!--       In order to avoid 'data mode' errors if updated attributes are larger
6233!--       than their original size, NF90_PUT_ATT is called in 'define mode'
6234!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
6235!--       performance loss due to data copying; an alternative strategy would be
6236!--       to ensure equal attribute size in a job chain. Maybe revise later.
6237          nc_stat = NF90_REDEF( id_set_sp )
6238          CALL netcdf_handle_error( 'netcdf_define_header', 441 )
6239          IF ( averaging_interval_sp /= 0.0_wp )  THEN
6240             WRITE (time_average_text,'('', '',F7.1,'' s average'')') &
6241                                                           averaging_interval_sp
6242             nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'title',  &
6243                                     TRIM( run_description_header ) // &
6244                                     TRIM( time_average_text ) )
6245             CALL netcdf_handle_error( 'netcdf_define_header', 308 )
6246
6247             WRITE ( time_average_text,'(F7.1,'' s avg'')' )  averaging_interval_sp
6248             nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'time_avg',       &
6249                                     TRIM( time_average_text ) )
6250          ELSE
6251             nc_stat = NF90_PUT_ATT( id_set_sp, NF90_GLOBAL, 'title',          &
6252                                     TRIM( run_description_header ) )
6253          ENDIF
6254          CALL netcdf_handle_error( 'netcdf_define_header', 309 )
6255          nc_stat = NF90_ENDDEF( id_set_sp )
6256          CALL netcdf_handle_error( 'netcdf_define_header', 442 )
6257          message_string = 'netCDF file for spectra ' //                       &
6258                           'from previous run found.' //                       &
6259                           '&This file will be extended.'
6260          CALL message( 'define_netcdf_header', 'PA0264', 0, 0, 0, 6, 0 )
6261
6262!
6263!--     Currently disabled (DATA_PRT_NETCDF)
6264!       CASE ( 'pt_new' )
6265
6266!
6267!--       Define some global attributes of the dataset
6268!          nc_stat = NF90_PUT_ATT( id_set_prt, NF90_GLOBAL, 'title',            &
6269!                                  TRIM( run_description_header ) )
6270!          CALL netcdf_handle_error( 'netcdf_define_header', 310 )
6271
6272!
6273!--       Define time coordinate for particles (unlimited dimension)
6274!          CALL netcdf_create_dim( id_set_prt, 'time', NF90_UNLIMITED,          &
6275!                                  id_dim_time_prt, 311 )
6276!          CALL netcdf_create_var( id_set_prt, (/ id_dim_time_prt /), 'time',   &
6277!                                  NF90_DOUBLE, id_var_time_prt, 'seconds', '', &
6278!                                  312, 313, 000 )
6279!
6280!--       netCDF4 allows more than one unlimited dimension
6281!          CALL netcdf_create_dim( id_set_prt, 'particle_number',            &
6282!                                  NF90_UNLIMITED, id_dim_prtnum, 314 )
6283
6284!          CALL netcdf_create_var( id_set_prt, (/ id_dim_prtnum /),             &
6285!                                  'particle_number', NF90_DOUBLE,              &
6286!                                  id_var_prtnum, 'particle number', '', 315,   &
6287!                                  316, 000 )
6288!
6289!--       Define variable which contains the real number of particles in use
6290!          CALL netcdf_create_var( id_set_prt, (/ id_dim_time_prt /),           &
6291!                                  'real_num_of_prt', NF90_DOUBLE,              &
6292!                                  id_var_rnop_prt, 'particle number', '', 317, &
6293!                                  318, 000 )
6294!
6295!--       Define the variables
6296!          DO  i = 1, 17
6297
6298!             CALL netcdf_create_var( id_set_prt, (/ id_dim_prtnum,             &
6299!                                     id_dim_time_prt /), prt_var_names(i),     &
6300!                                     nc_precision(8), id_var_prt(i),           &
6301!                                     TRIM( prt_var_units(i) ),                 &
6302!                                     TRIM( prt_var_names(i) ), 319, 320, 321 )
6303
6304!          ENDDO
6305
6306!
6307!--       Leave netCDF define mode
6308!          nc_stat = NF90_ENDDEF( id_set_prt )
6309!          CALL netcdf_handle_error( 'netcdf_define_header', 322 )
6310
6311!
6312!--     Currently disabled (DATA_PRT_NETCDF)
6313!       CASE ( 'pt_ext' )
6314
6315!
6316!--       Get the id of the time coordinate (unlimited coordinate) and its
6317!--       last index on the file. The next time level is prt..count+1.
6318!--       The current time must be larger than the last output time
6319!--       on the file.
6320!          nc_stat = NF90_INQ_VARID( id_set_prt, 'time', id_var_time_prt )
6321!          CALL netcdf_handle_error( 'netcdf_define_header', 323 )
6322
6323!          nc_stat = NF90_INQUIRE_VARIABLE( id_set_prt, id_var_time_prt, &
6324!                                           dimids = id_dim_time_old )
6325!          CALL netcdf_handle_error( 'netcdf_define_header', 324 )
6326!          id_dim_time_prt = id_dim_time_old(1)
6327
6328!          nc_stat = NF90_INQUIRE_DIMENSION( id_set_prt, id_dim_time_prt, &
6329!                                            len = prt_time_count )
6330!          CALL netcdf_handle_error( 'netcdf_define_header', 325 )
6331
6332!          nc_stat = NF90_GET_VAR( id_set_prt, id_var_time_prt,  &
6333!                                  last_time_coordinate,         &
6334!                                  start = (/ prt_time_count /), &
6335!                                  count = (/ 1 /) )
6336!          CALL netcdf_handle_error( 'netcdf_define_header', 326 )
6337
6338!          IF ( last_time_coordinate(1) >= simulated_time )  THEN
6339!             message_string = 'netCDF file for particles ' //                  &
6340!                              'from previous run found,' //                    &
6341!                              '&but this file cannot be extended becaus' //    &
6342!                              'e the current output time' //                   &
6343!                              '&is less or equal than the last output t' //    &
6344!                              'ime on this file.' //                           &
6345!                              '&New file is created instead.'
6346!             CALL message( 'define_netcdf_header', 'PA0265', 0, 1, 0, 6, 0 )
6347!             prt_time_count = 0
6348!             extend = .FALSE.
6349!             RETURN
6350!          ENDIF
6351
6352!
6353!--       Dataset seems to be extendable.
6354!--       Now get the variable ids.
6355!         nc_stat = NF90_INQ_VARID( id_set_prt, 'real_num_of_prt',             &
6356!                                   id_var_rnop_prt )
6357!         CALL netcdf_handle_error( 'netcdf_define_header', 327 )
6358
6359!          DO  i = 1, 17
6360
6361!             nc_stat = NF90_INQ_VARID( id_set_prt, prt_var_names(i),           &
6362!                                       id_var_prt(i) )
6363!             CALL netcdf_handle_error( 'netcdf_define_header', 328 )
6364
6365!          ENDDO
6366
6367!          message_string = 'netCDF file for particles ' //                     &
6368!                           'from previous run found.' //                       &
6369!                           '&This file will be extended.'
6370!          CALL message( 'define_netcdf_header', 'PA0266', 0, 0, 0, 6, 0 )
6371       
6372
6373
6374       CASE ( 'ps_new' )
6375
6376!
6377!--       Define some global attributes of the dataset
6378          nc_stat = NF90_PUT_ATT( id_set_pts, NF90_GLOBAL, 'title',            &
6379                                  TRIM( run_description_header ) )
6380          CALL netcdf_handle_error( 'netcdf_define_header', 396 )
6381
6382!
6383!--       Define time coordinate for particle time series (unlimited dimension)
6384          CALL netcdf_create_dim( id_set_pts, 'time', NF90_UNLIMITED,          &
6385                                  id_dim_time_pts, 397 )
6386          CALL netcdf_create_var( id_set_pts, (/ id_dim_time_pts /), 'time',   &
6387                                  NF90_DOUBLE, id_var_time_pts, 'seconds since '//TRIM(init_model%origin_time), 'time', &
6388                                  398, 399, 000 )
6389          CALL netcdf_create_att( id_set_pts, id_var_time_pts, 'standard_name', 'time', 000)
6390          CALL netcdf_create_att( id_set_pts, id_var_time_pts, 'axis', 'T', 000)
6391!
6392!--       Define the variables. If more than one particle group is defined,
6393!--       define seperate variables for each group
6394          var_list = ';'
6395          DO  i = 1, dopts_num
6396
6397             DO  j = 0, number_of_particle_groups
6398
6399                IF ( j == 0 )  THEN
6400                   suffix = ''
6401                ELSE
6402                   WRITE ( suffix, '(''_'',I2.2)' )  j
6403                ENDIF
6404
6405                IF ( j == 0 )  THEN
6406                   CALL netcdf_create_var( id_set_pts, (/ id_dim_time_pts /),  &
6407                                           TRIM( dopts_label(i) ) // suffix,  &
6408                                           nc_precision(6), id_var_dopts(i,j), &
6409                                           TRIM( dopts_unit(i) ),              &
6410                                           TRIM( dopts_label(i) ), 400, 401,   &
6411                                           402 )
6412                ELSE
6413                   CALL netcdf_create_var( id_set_pts, (/ id_dim_time_pts /),  &
6414                                           TRIM( dopts_label(i) ) // suffix,  &
6415                                           nc_precision(6), id_var_dopts(i,j), &
6416                                           TRIM( dopts_unit(i) ),              &
6417                                           TRIM( dopts_label(i) ) // ' PG ' // &
6418                                           suffix(2:3), 400, 401, 402 )
6419                ENDIF
6420
6421                var_list = TRIM( var_list ) // TRIM( dopts_label(i) ) // &
6422                           suffix // ';'
6423
6424                IF ( number_of_particle_groups == 1 )  EXIT
6425
6426             ENDDO
6427
6428          ENDDO
6429
6430!
6431!--       Write the list of variables as global attribute (this is used by
6432!--       restart runs)
6433          nc_stat = NF90_PUT_ATT( id_set_pts, NF90_GLOBAL, 'VAR_LIST', &
6434                                  var_list )
6435          CALL netcdf_handle_error( 'netcdf_define_header', 403 )
6436
6437
6438!
6439!--       Leave netCDF define mode
6440          nc_stat = NF90_ENDDEF( id_set_pts )
6441          CALL netcdf_handle_error( 'netcdf_define_header', 404 )
6442
6443
6444       CASE ( 'ps_ext' )
6445
6446!
6447!--       Get the list of variables and compare with the actual run.
6448!--       First var_list_old has to be reset, since GET_ATT does not assign
6449!--       trailing blanks.
6450          var_list_old = ' '
6451          nc_stat = NF90_GET_ATT( id_set_pts, NF90_GLOBAL, 'VAR_LIST', &
6452                                  var_list_old )
6453          CALL netcdf_handle_error( 'netcdf_define_header', 405 )
6454
6455          var_list = ';'
6456          i = 1
6457          DO  i = 1, dopts_num
6458
6459             DO  j = 0, number_of_particle_groups
6460
6461                IF ( j == 0 )  THEN
6462                   suffix = ''
6463                ELSE
6464                   WRITE ( suffix, '(''_'',I2.2)' )  j
6465                ENDIF
6466
6467                var_list = TRIM( var_list ) // TRIM( dopts_label(i) ) // &
6468                           suffix // ';'
6469
6470                IF ( number_of_particle_groups == 1 )  EXIT
6471
6472             ENDDO
6473
6474          ENDDO
6475
6476          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
6477             message_string = 'netCDF file for particle time series ' //       &
6478                              'from previous run found,' //                    &
6479                              '&but this file cannot be extended due to' //    &
6480                              ' variable mismatch.' //                         &
6481                              '&New file is created instead.'
6482             CALL message( 'define_netcdf_header', 'PA0267', 0, 1, 0, 6, 0 )
6483             extend = .FALSE.
6484             RETURN
6485          ENDIF
6486
6487!
6488!--       Get the id of the time coordinate (unlimited coordinate) and its
6489!--       last index on the file. The next time level is dots..count+1.
6490!--       The current time must be larger than the last output time
6491!--       on the file.
6492          nc_stat = NF90_INQ_VARID( id_set_pts, 'time', id_var_time_pts )
6493          CALL netcdf_handle_error( 'netcdf_define_header', 406 )
6494
6495          nc_stat = NF90_INQUIRE_VARIABLE( id_set_pts, id_var_time_pts, &
6496                                           dimids = id_dim_time_old )
6497          CALL netcdf_handle_error( 'netcdf_define_header', 407 )
6498          id_dim_time_pts = id_dim_time_old(1)
6499
6500          nc_stat = NF90_INQUIRE_DIMENSION( id_set_pts, id_dim_time_pts, &
6501                                            len = dopts_time_count )
6502          CALL netcdf_handle_error( 'netcdf_define_header', 408 )
6503
6504          nc_stat = NF90_GET_VAR( id_set_pts, id_var_time_pts,    &
6505                                  last_time_coordinate,           &
6506                                  start = (/ dopts_time_count /), &
6507                                  count = (/ 1 /) )
6508          CALL netcdf_handle_error( 'netcdf_define_header', 409 )
6509
6510          IF ( last_time_coordinate(1) >= simulated_time )  THEN
6511             message_string = 'netCDF file for particle time series ' //       &
6512                              'from previous run found,' //                    &
6513                              '&but this file cannot be extended becaus' //    &
6514                              'e the current output time' //                   &
6515                              '&is less or equal than the last output t' //    &
6516                              'ime on this file.' //                           &
6517                              '&New file is created instead.'
6518             CALL message( 'define_netcdf_header', 'PA0268', 0, 1, 0, 6, 0 )
6519             dopts_time_count = 0
6520             extend = .FALSE.
6521             RETURN
6522          ENDIF
6523
6524!
6525!--       Dataset seems to be extendable.
6526!--       Now get the variable ids
6527          i = 1
6528          DO  i = 1, dopts_num
6529 
6530             DO  j = 0, number_of_particle_groups
6531
6532                IF ( j == 0 )  THEN
6533                   suffix = ''
6534                ELSE
6535                   WRITE ( suffix, '(''_'',I2.2)' )  j
6536                ENDIF
6537
6538                netcdf_var_name = TRIM( dopts_label(i) ) // suffix
6539
6540                nc_stat = NF90_INQ_VARID( id_set_pts, netcdf_var_name, &
6541                                          id_var_dopts(i,j) )
6542                CALL netcdf_handle_error( 'netcdf_define_header', 410 )
6543
6544                IF ( number_of_particle_groups == 1 )  EXIT
6545
6546             ENDDO
6547
6548          ENDDO
6549
6550!
6551!--       Update the title attribute on file
6552!--       In order to avoid 'data mode' errors if updated attributes are larger
6553!--       than their original size, NF90_PUT_ATT is called in 'define mode'
6554!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
6555!--       performance loss due to data copying; an alternative strategy would be
6556!--       to ensure equal attribute size in a job chain. Maybe revise later.
6557          nc_stat = NF90_REDEF( id_set_pts )
6558          CALL netcdf_handle_error( 'netcdf_define_header', 443 )
6559          nc_stat = NF90_PUT_ATT( id_set_pts, NF90_GLOBAL, 'title',            &
6560                                  TRIM( run_description_header ) )
6561          CALL netcdf_handle_error( 'netcdf_define_header', 411 )
6562          nc_stat = NF90_ENDDEF( id_set_pts )
6563          CALL netcdf_handle_error( 'netcdf_define_header', 444 )
6564          message_string = 'netCDF file for particle time series ' //          &
6565                           'from previous run found.' //                       &
6566                           '&This file will be extended.'
6567          CALL message( 'netcdf_define_header', 'PA0269', 0, 0, 0, 6, 0 )
6568
6569!
6570!--    Flight data
6571       CASE ( 'fl_new' )
6572!
6573!--       Define some global attributes of the dataset
6574          nc_stat = NF90_PUT_ATT( id_set_fl, NF90_GLOBAL, 'title',             &
6575                                  TRIM( run_description_header ) )
6576          CALL netcdf_handle_error( 'netcdf_define_header', 249 )
6577
6578!
6579!--       Define time and location coordinates for flight space-time series
6580!--       (unlimited dimension)
6581!--       Error number must still be set appropriately.
6582          CALL netcdf_create_dim( id_set_fl, 'time', NF90_UNLIMITED,           &
6583                                  id_dim_time_fl, 250 )
6584          CALL netcdf_create_var( id_set_fl, (/ id_dim_time_fl /), 'time',     &
6585                                  NF90_DOUBLE, id_var_time_fl, 'seconds since '//TRIM(init_model%origin_time), 'time',  &
6586                                  251, 252, 000 )
6587          CALL netcdf_create_att( id_set_fl, id_var_time_fl, 'standard_name', 'time', 000)
6588          CALL netcdf_create_att( id_set_fl, id_var_time_fl, 'axis', 'T', 000)
6589
6590          DO l = 1, num_leg
6591             CALL netcdf_create_dim( id_set_fl, dofl_dim_label_x(l),           &
6592                                     NF90_UNLIMITED, id_dim_x_fl(l), 250 )
6593             CALL netcdf_create_dim( id_set_fl, dofl_dim_label_y(l),           &
6594                                     NF90_UNLIMITED, id_dim_y_fl(l), 250 )
6595             CALL netcdf_create_dim( id_set_fl, dofl_dim_label_z(l),           &
6596                                     NF90_UNLIMITED, id_dim_z_fl(l), 250 )
6597
6598             CALL netcdf_create_var( id_set_fl, (/ id_dim_x_fl(l) /),          &
6599                                     dofl_dim_label_x(l), NF90_DOUBLE,         &
6600                                     id_var_x_fl(l), 'm', '', 251, 252, 000 )
6601             CALL netcdf_create_var( id_set_fl, (/ id_dim_y_fl(l) /),          &
6602                                     dofl_dim_label_y(l), NF90_DOUBLE,         &
6603                                     id_var_y_fl(l), 'm', '', 251, 252, 000 )
6604             CALL netcdf_create_var( id_set_fl, (/ id_dim_z_fl(l) /),          &
6605                                     dofl_dim_label_z(l), NF90_DOUBLE,         &
6606                                     id_var_z_fl(l), 'm', '', 251, 252, 000 )
6607          ENDDO
6608!
6609!--       Define the variables
6610          var_list = ';'
6611          k = 1
6612          DO  l = 1, num_leg
6613             DO i = 1, num_var_fl
6614
6615                CALL netcdf_create_var( id_set_fl, (/ id_dim_time_fl /),       &
6616                                        dofl_label(k), nc_precision(9),        &
6617                                        id_var_dofl(k),                        &
6618                                        TRIM( dofl_unit(k) ),                  &
6619                                        TRIM( dofl_label(k) ), 253, 254, 255 )
6620
6621                k = k + 1
6622               
6623             ENDDO
6624
6625          ENDDO
6626
6627!
6628!--       Write the list of variables as global attribute (this is used by
6629!--       restart runs)
6630          nc_stat = NF90_PUT_ATT( id_set_fl, NF90_GLOBAL, 'VAR_LIST', var_list )
6631          CALL netcdf_handle_error( 'netcdf_define_header', 258 )
6632
6633!
6634!--       Leave netCDF define mode
6635          nc_stat = NF90_ENDDEF( id_set_fl )
6636          CALL netcdf_handle_error( 'netcdf_define_header', 259 )
6637
6638
6639       CASE ( 'fl_ext' )
6640
6641!
6642!--       Get the list of variables and compare with the actual run.
6643!--       First var_list_old has to be reset, since GET_ATT does not assign
6644!--       trailing blanks.
6645          var_list_old = ' '
6646          nc_stat = NF90_GET_ATT( id_set_fl, NF90_GLOBAL, 'VAR_LIST',          &
6647                                  var_list_old )
6648          CALL netcdf_handle_error( 'netcdf_define_header', 260 )
6649
6650          var_list = ';'
6651          i = 1
6652          DO  i = 1, num_leg * num_var_fl
6653
6654             var_list = TRIM( var_list ) // TRIM( dofl_label(i) ) // ';'
6655
6656          ENDDO
6657
6658          IF ( TRIM( var_list ) /= TRIM( var_list_old ) )  THEN
6659             message_string = 'netCDF file for flight time series ' //         &
6660                              'from previous run found,' //                    &
6661                              '&but this file cannot be extended due to' //    &
6662                              ' variable mismatch.' //                         &
6663                              '&New file is created instead.'
6664             CALL message( 'define_netcdf_header', 'PA0257', 0, 1, 0, 6, 0 )
6665             extend = .FALSE.
6666             RETURN
6667          ENDIF
6668
6669!
6670!--       Get the id of the time coordinate (unlimited coordinate) and its
6671!--       last index on the file. The next time level is dofl_time_count+1.
6672!--       The current time must be larger than the last output time
6673!--       on the file.
6674          nc_stat = NF90_INQ_VARID( id_set_fl, 'time', id_var_time_fl )
6675          CALL netcdf_handle_error( 'netcdf_define_header', 261 )
6676
6677          nc_stat = NF90_INQUIRE_VARIABLE( id_set_fl, id_var_time_fl,          &
6678                                           dimids = id_dim_time_old )
6679          CALL netcdf_handle_error( 'netcdf_define_header', 262 )
6680          id_dim_time_fl = id_dim_time_old(1)
6681
6682          nc_stat = NF90_INQUIRE_DIMENSION( id_set_fl, id_dim_time_fl,         &
6683                                            len = dofl_time_count )
6684          CALL netcdf_handle_error( 'netcdf_define_header', 263 )
6685
6686          nc_stat = NF90_GET_VAR( id_set_fl, id_var_time_fl,        &
6687                                  last_time_coordinate,             &
6688                                  start = (/ dofl_time_count /), &
6689                                  count = (/ 1 /) )
6690          CALL netcdf_handle_error( 'netcdf_define_header', 264 )
6691
6692          IF ( last_time_coordinate(1) >= simulated_time )  THEN
6693             message_string = 'netCDF file for flight-time series ' //         &
6694                              'from previous run found,' //                    &
6695                              '&but this file cannot be extended becaus' //    &
6696                              'e the current output time' //                   &
6697                              '&is less or equal than the last output t' //    &
6698                              'ime on this file.' //                           &
6699                              '&New file is created instead.'
6700             CALL message( 'define_netcdf_header', 'PA0258', 0, 1, 0, 6, 0 )
6701             dofl_time_count = 0
6702             extend = .FALSE.
6703             RETURN
6704          ENDIF
6705
6706!
6707!--       Dataset seems to be extendable.
6708!--       Now get the remaining dimension and variable ids
6709          DO l = 1, num_leg
6710             nc_stat = NF90_INQ_VARID( id_set_fl, dofl_dim_label_x(l),         &
6711                                       id_var_x_fl(l) )
6712             CALL netcdf_handle_error( 'netcdf_define_header', 265 )
6713             nc_stat = NF90_INQ_VARID( id_set_fl, dofl_dim_label_y(l),         &
6714                                       id_var_y_fl(l) )
6715             CALL netcdf_handle_error( 'netcdf_define_header', 265 )
6716             nc_stat = NF90_INQ_VARID( id_set_fl, dofl_dim_label_z(l),         &
6717                                       id_var_z_fl(l) )
6718             CALL netcdf_handle_error( 'netcdf_define_header', 265 )
6719
6720          ENDDO
6721
6722
6723          DO  i = 1, num_leg * num_var_fl
6724 
6725            nc_stat = NF90_INQ_VARID( id_set_fl, dofl_label(i), &
6726                                       id_var_dofl(i) )
6727            CALL netcdf_handle_error( 'netcdf_define_header', 265 )
6728
6729          ENDDO
6730
6731!
6732!--       Update the title attribute on file
6733!--       In order to avoid 'data mode' errors if updated attributes are larger
6734!--       than their original size, NF90_PUT_ATT is called in 'define mode'
6735!--       enclosed by NF90_REDEF and NF90_ENDDEF calls. This implies a possible
6736!--       performance loss due to data copying; an alternative strategy would be
6737!--       to ensure equal attribute size in a job chain. Maybe revise later.
6738          nc_stat = NF90_REDEF( id_set_fl )
6739          CALL netcdf_handle_error( 'netcdf_define_header', 439 )
6740          nc_stat = NF90_PUT_ATT( id_set_fl, NF90_GLOBAL, 'title',             &
6741                                  TRIM( run_description_header ) )
6742          CALL netcdf_handle_error( 'netcdf_define_header', 267 )
6743          nc_stat = NF90_ENDDEF( id_set_fl )
6744          CALL netcdf_handle_error( 'netcdf_define_header', 440 )
6745          message_string = 'netCDF file for flight-time series ' //            &
6746                           'from previous run found.' //                       &
6747                           '&This file will be extended.'
6748          CALL message( 'define_netcdf_header', 'PA0259', 0, 0, 0, 6, 0 )
6749
6750         
6751       CASE DEFAULT
6752
6753          message_string = 'mode "' // TRIM( mode) // '" not supported'
6754          CALL message( 'netcdf_define_header', 'PA0270', 0, 0, 0, 6, 0 )
6755
6756    END SELECT
6757
6758#endif
6759 END SUBROUTINE netcdf_define_header
6760
6761
6762!------------------------------------------------------------------------------!
6763! Description:
6764! ------------
6765!> Creates a netCDF file and give back the id. The parallel flag has to be TRUE
6766!> for parallel netCDF output support.
6767!------------------------------------------------------------------------------!
6768 
6769 SUBROUTINE netcdf_create_file( filename , id, parallel, errno )
6770#if defined( __netcdf )
6771
6772    USE pegrid
6773
6774    IMPLICIT NONE
6775
6776    CHARACTER (LEN=*), INTENT(IN) :: filename
6777    INTEGER, INTENT(IN)           :: errno
6778    INTEGER, INTENT(OUT)          :: id
6779    LOGICAL, INTENT(IN)           :: parallel
6780
6781
6782!
6783!-- Create a new netCDF output file with requested netCDF format
6784    IF ( netcdf_data_format == 1 )  THEN
6785!
6786!--    Classic netCDF format
6787       nc_stat = NF90_CREATE( filename, NF90_NOCLOBBER, id )
6788
6789    ELSEIF ( netcdf_data_format == 2 )  THEN
6790!
6791!--    64bit-offset format
6792       nc_stat = NF90_CREATE( filename,                                        &
6793                              IOR( NF90_NOCLOBBER, NF90_64BIT_OFFSET ), id )
6794
6795#if defined( __netcdf4 )
6796    ELSEIF ( netcdf_data_format == 3  .OR.                                     &
6797             ( .NOT. parallel  .AND.  netcdf_data_format == 5 ) )  THEN
6798!
6799!--    netCDF4/HDF5 format
6800       nc_stat = NF90_CREATE( filename, IOR( NF90_NOCLOBBER, NF90_NETCDF4 ), id )
6801
6802    ELSEIF ( netcdf_data_format == 4  .OR.                                     &
6803             ( .NOT. parallel  .AND.  netcdf_data_format == 6 ) )  THEN
6804!
6805!--    netCDF4/HDF5 format with classic model flag
6806       nc_stat = NF90_CREATE( filename,                                        &
6807                              IOR( NF90_NOCLOBBER,                             &
6808                              IOR( NF90_CLASSIC_MODEL, NF90_HDF5 ) ), id )
6809
6810#if defined( __netcdf4_parallel )
6811    ELSEIF ( netcdf_data_format == 5  .AND.  parallel )  THEN
6812!
6813!--    netCDF4/HDF5 format, parallel
6814       nc_stat = NF90_CREATE( filename,                                        &
6815                              IOR( NF90_NOCLOBBER,                             &
6816                              IOR( NF90_NETCDF4, NF90_MPIIO ) ),               &
6817                              id, COMM = comm2d, INFO = MPI_INFO_NULL )
6818
6819    ELSEIF ( netcdf_data_format == 6  .AND.  parallel )  THEN
6820!
6821!--    netCDF4/HDF5 format with classic model flag, parallel
6822       nc_stat = NF90_CREATE( filename,                                        &
6823                              IOR( NF90_NOCLOBBER,                             &
6824                              IOR( NF90_MPIIO,                                 &
6825                              IOR( NF90_CLASSIC_MODEL, NF90_HDF5 ) ) ),        &
6826                              id, COMM = comm2d, INFO = MPI_INFO_NULL )
6827
6828#endif
6829#endif
6830    ENDIF
6831
6832    CALL netcdf_handle_error( 'netcdf_create_file', errno )
6833#endif
6834 END SUBROUTINE netcdf_create_file
6835
6836!------------------------------------------------------------------------------!
6837! Description:
6838! ------------
6839!> Opens an existing netCDF file for writing and gives back the id.
6840!> The parallel flag has to be TRUE for parallel netCDF output support.
6841!------------------------------------------------------------------------------!
6842 SUBROUTINE netcdf_open_write_file( filename, id, parallel, errno )
6843#if defined( __netcdf )
6844
6845    USE pegrid
6846
6847    IMPLICIT NONE
6848
6849    CHARACTER (LEN=*), INTENT(IN) :: filename
6850    INTEGER, INTENT(IN)           :: errno
6851    INTEGER, INTENT(OUT)          :: id
6852    LOGICAL, INTENT(IN)           :: parallel
6853
6854
6855    IF ( netcdf_data_format < 5  .OR.  .NOT. parallel )  THEN
6856       nc_stat = NF90_OPEN( filename, NF90_WRITE, id )
6857#if defined( __netcdf4 )
6858#if defined( __netcdf4_parallel )
6859    ELSEIF ( netcdf_data_format > 4  .AND.  parallel )  THEN
6860       nc_stat = NF90_OPEN( filename, IOR( NF90_WRITE, NF90_MPIIO ), id,  &
6861                            COMM = comm2d, INFO = MPI_INFO_NULL )
6862#endif
6863#endif
6864    ENDIF
6865
6866    CALL netcdf_handle_error( 'netcdf_open_write_file', errno )
6867#endif
6868 END SUBROUTINE netcdf_open_write_file
6869
6870
6871!------------------------------------------------------------------------------!
6872! Description:
6873! ------------
6874!> Prints out a text message corresponding to the current status.
6875!------------------------------------------------------------------------------!
6876 
6877 SUBROUTINE netcdf_handle_error( routine_name, errno )
6878#if defined( __netcdf )
6879
6880
6881    USE control_parameters,                                                    &
6882        ONLY:  message_string
6883
6884    IMPLICIT NONE
6885
6886    CHARACTER(LEN=6) ::  message_identifier
6887    CHARACTER(LEN=*) ::  routine_name
6888
6889    INTEGER(iwp) ::  errno
6890
6891    IF ( nc_stat /= NF90_NOERR )  THEN
6892
6893       WRITE( message_identifier, '(''NC'',I4.4)' )  errno
6894
6895       message_string = TRIM( NF90_STRERROR( nc_stat ) )
6896
6897       CALL message( routine_name, message_identifier, 2, 2, 0, 6, 1 )
6898
6899    ENDIF
6900
6901#endif
6902 END SUBROUTINE netcdf_handle_error
6903
6904
6905!------------------------------------------------------------------------------!
6906! Description:
6907! ------------
6908!> Create a dimension in NetCDF file
6909!------------------------------------------------------------------------------!
6910
6911 SUBROUTINE netcdf_create_dim(ncid, dim_name, ncdim_type, ncdim_id, error_no)
6912
6913#if defined( __netcdf )
6914
6915    USE kinds
6916
6917    IMPLICIT NONE
6918
6919    CHARACTER(LEN=*), INTENT(IN) ::  dim_name
6920
6921    INTEGER, INTENT(IN)  ::  error_no
6922    INTEGER, INTENT(IN)  ::  ncid
6923    INTEGER, INTENT(OUT) ::  ncdim_id
6924    INTEGER, INTENT(IN)  ::  ncdim_type
6925
6926!
6927!-- Define time coordinate for volume data (unlimited dimension)
6928    nc_stat = NF90_DEF_DIM( ncid, dim_name, ncdim_type, ncdim_id )
6929    CALL netcdf_handle_error( 'netcdf_create_dim', error_no )
6930
6931#endif
6932
6933 END SUBROUTINE netcdf_create_dim
6934
6935
6936!------------------------------------------------------------------------------!
6937! Description:
6938! ------------
6939!> Create a one dimensional variable in specific units in NetCDF file
6940!------------------------------------------------------------------------------!
6941
6942 SUBROUTINE netcdf_create_var( ncid, dim_id, var_name, var_type, var_id,       &
6943                               unit_name, long_name, error_no1, error_no2,     &
6944                               error_no3, fill )
6945
6946#if defined( __netcdf )
6947    IMPLICIT NONE
6948
6949    CHARACTER(LEN=*), INTENT(IN) ::  long_name
6950    CHARACTER(LEN=*), INTENT(IN) ::  unit_name
6951    CHARACTER(LEN=*), INTENT(IN) ::  var_name
6952
6953    LOGICAL, OPTIONAL ::  fill  !< indicates setting of _FillValue attribute
6954
6955    INTEGER, INTENT(IN)  ::  error_no1
6956    INTEGER, INTENT(IN)  ::  error_no2
6957    INTEGER, INTENT(IN)  ::  error_no3
6958    INTEGER, INTENT(IN)  ::  ncid
6959    INTEGER, INTENT(OUT) ::  var_id
6960    INTEGER, INTENT(IN)  ::  var_type
6961
6962    INTEGER, DIMENSION(:), INTENT(IN) ::  dim_id
6963
6964!
6965!-- Define variable
6966    nc_stat = NF90_DEF_VAR( ncid, var_name, var_type, dim_id, var_id )
6967    CALL netcdf_handle_error( 'netcdf_create_var', error_no1 )
6968
6969#if defined( __netcdf4 )
6970!
6971!-- Check if variable should be deflate (including shuffling)
6972!-- and if it is possible (only NetCDF4 with HDF5 supports compression)
6973    IF ( netcdf_data_format > 2  .AND.  netcdf_deflate > 0 )  THEN
6974       nc_stat = NF90_DEF_VAR_DEFLATE( ncid, var_id, 1, 1, netcdf_deflate )
6975       CALL netcdf_handle_error( 'netcdf_create_var_deflate', error_no1 )
6976    ENDIF
6977#endif
6978!
6979!-- Set unit name if set
6980    IF ( unit_name /= '' )  THEN
6981       nc_stat = NF90_PUT_ATT( ncid, var_id, 'units', unit_name )
6982       CALL netcdf_handle_error( 'netcdf_create_var', error_no2 )
6983    ENDIF
6984
6985!
6986!-- Set long name if set
6987    IF ( long_name /= '' )  THEN
6988       nc_stat = NF90_PUT_ATT( ncid, var_id, 'long_name', long_name )
6989       CALL netcdf_handle_error( 'netcdf_create_var', error_no3 )
6990    ENDIF
6991
6992!
6993!-- Set _FillValue for all variables, except for dimension variables.
6994!-- Set the fill values accordingly to the corresponding output precision.
6995    IF ( PRESENT( fill ) )  THEN
6996       IF ( var_type == NF90_REAL4 )  THEN
6997          nc_stat = NF90_PUT_ATT( ncid, var_id, '_FillValue',                  &
6998                                  REAL( fill_value, KIND = 4 ) )
6999          CALL netcdf_handle_error( 'netcdf_create_var', 0 )
7000       ELSE
7001          nc_stat = NF90_PUT_ATT( ncid, var_id, '_FillValue',                  &
7002                                  REAL( fill_value, KIND = 8 ) )
7003          CALL netcdf_handle_error( 'netcdf_create_var', 0 )
7004       ENDIF
7005    ENDIF
7006
7007#endif
7008 END SUBROUTINE netcdf_create_var
7009
7010
7011!------------------------------------------------------------------------------!
7012! Description:
7013! ------------
7014!> Write attributes to file.
7015!------------------------------------------------------------------------------!
7016 SUBROUTINE netcdf_create_att_string( ncid, varid, name, value, err )
7017
7018    IMPLICIT NONE
7019
7020    CHARACTER(LEN=*), INTENT(IN) ::  name    !< attribute name
7021    CHARACTER(LEN=*), INTENT(IN) ::  value   !< attribute value
7022
7023    INTEGER, INTENT(IN) ::  err              !< error id
7024    INTEGER, INTENT(IN) ::  ncid             !< file id
7025
7026    INTEGER, INTENT(IN), OPTIONAL ::  varid  !< variable id
7027
7028#if defined( __netcdf )
7029    IF ( PRESENT( varid ) )  THEN
7030       nc_stat = NF90_PUT_ATT( ncid, varid, TRIM( name ), TRIM( value ) )
7031    ELSE
7032       nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( name ), TRIM( value ) )
7033    ENDIF
7034    CALL netcdf_handle_error( 'netcdf_create_att_string', err )
7035#endif
7036
7037 END SUBROUTINE netcdf_create_att_string
7038
7039
7040!------------------------------------------------------------------------------!
7041! Description:
7042! ------------
7043!> Write a set of global attributes to file.
7044!------------------------------------------------------------------------------!
7045 SUBROUTINE netcdf_create_global_atts( ncid, data_content, title, error_no )
7046
7047    USE control_parameters,  &
7048        ONLY:  revision, run_date, run_time, run_zone, runnr, version
7049       
7050    USE netcdf_data_input_mod,  &
7051        ONLY:  input_file_atts
7052
7053    IMPLICIT NONE
7054
7055    CHARACTER(LEN=*), INTENT(IN)  ::  data_content  !< describes the type of data in file
7056    CHARACTER(LEN=*), INTENT(IN)  ::  title         !< file title
7057
7058    INTEGER, INTENT(IN)  ::  error_no  !< error number
7059    INTEGER, INTENT(IN)  ::  ncid      !< file id
7060
7061#if defined( __netcdf )
7062    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'title', TRIM( title ) )
7063    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7064    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'Conventions', 'CF-1.7' )
7065    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7066    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'creation_time', TRIM( run_date )//' '//TRIM( run_time )//' '//run_zone(1:3) )
7067    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7068    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'data_content', TRIM(data_content) )
7069    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7070    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'version', runnr+1 )
7071    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7072
7073    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'origin_time', init_model%origin_time )
7074    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7075    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'origin_lat', init_model%latitude )
7076    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7077    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'origin_lon', init_model%longitude )
7078    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7079    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'origin_x', init_model%origin_x )
7080    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7081    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'origin_y', init_model%origin_y )
7082    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7083    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'origin_z', init_model%origin_z )
7084    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7085    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'rotation_angle', init_model%rotation_angle )
7086    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7087
7088    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'dependencies', '' )
7089    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7090    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'history', '' )
7091    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7092
7093    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%author_char ), TRIM( input_file_atts%author ) )
7094    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7095    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%contact_person_char ), TRIM( input_file_atts%contact_person ) )
7096    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7097    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%institution_char ), TRIM( input_file_atts%institution ) )
7098    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7099    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%acronym_char ), TRIM( input_file_atts%acronym ) )
7100    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7101
7102    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%campaign_char ), TRIM( input_file_atts%campaign ) )
7103    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7104    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%location_char ), TRIM( input_file_atts%location ) )
7105    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7106    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%site_char ), TRIM( input_file_atts%site ) )
7107    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7108
7109    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, 'source', TRIM( version )//' '//TRIM( revision ) )
7110    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7111    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%references_char ), TRIM( input_file_atts%references ) )
7112    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7113    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%keywords_char ), TRIM( input_file_atts%keywords ) )
7114    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7115    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%licence_char ), TRIM( input_file_atts%licence ) )
7116    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7117    nc_stat = NF90_PUT_ATT( ncid, NF90_GLOBAL, TRIM( input_file_atts%comment_char ), TRIM( input_file_atts%comment ) )
7118    CALL netcdf_handle_error( 'netcdf_create_global_atts', error_no )
7119
7120#endif
7121
7122 END SUBROUTINE netcdf_create_global_atts
7123
7124!------------------------------------------------------------------------------!
7125! Description:
7126! ------------
7127!> Create a variable holding the coordinate-reference-system information.
7128!------------------------------------------------------------------------------!
7129 SUBROUTINE netcdf_create_crs( ncid, error_no )
7130
7131    IMPLICIT NONE
7132
7133    INTEGER, INTENT(IN)  ::  error_no  !< error number
7134    INTEGER, INTENT(IN)  ::  ncid      !< file id
7135    INTEGER              ::  var_id    !< variable id
7136
7137#if defined( __netcdf )
7138!
7139!-- Define variable
7140    nc_stat = NF90_DEF_VAR( ncid, 'crs', NF90_INT, VARID = var_id )
7141    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7142!
7143!-- Set attributes
7144    nc_stat = NF90_PUT_ATT( ncid, var_id, 'epsg_code', &
7145                            coord_ref_sys%epsg_code )
7146    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7147
7148    nc_stat = NF90_PUT_ATT( ncid, var_id, 'false_easting', &
7149                            coord_ref_sys%false_easting )
7150    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7151
7152    nc_stat = NF90_PUT_ATT( ncid, var_id, 'false_northing', &
7153                            coord_ref_sys%false_northing )
7154    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7155
7156    nc_stat = NF90_PUT_ATT( ncid, var_id, 'grid_mapping_name', &
7157                            coord_ref_sys%grid_mapping_name )
7158    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7159
7160    nc_stat = NF90_PUT_ATT( ncid, var_id, 'inverse_flattening', &
7161                            coord_ref_sys%inverse_flattening )
7162    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7163
7164    nc_stat = NF90_PUT_ATT( ncid, var_id, 'latitude_of_projection_origin', &
7165                            coord_ref_sys%latitude_of_projection_origin )
7166    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7167
7168    nc_stat = NF90_PUT_ATT( ncid, var_id, 'long_name', &
7169                            coord_ref_sys%long_name )
7170    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7171
7172    nc_stat = NF90_PUT_ATT( ncid, var_id, 'longitude_of_central_meridian', &
7173                            coord_ref_sys%longitude_of_central_meridian )
7174    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7175
7176    nc_stat = NF90_PUT_ATT( ncid, var_id, 'longitude_of_prime_meridian', &
7177                            coord_ref_sys%longitude_of_prime_meridian )
7178    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7179
7180    nc_stat = NF90_PUT_ATT( ncid, var_id, 'scale_factor_at_central_meridian', &
7181                            coord_ref_sys%scale_factor_at_central_meridian )
7182    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7183
7184    nc_stat = NF90_PUT_ATT( ncid, var_id, 'semi_major_axis', &
7185                            coord_ref_sys%semi_major_axis )
7186    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7187
7188    nc_stat = NF90_PUT_ATT( ncid, var_id, 'units', &
7189                            coord_ref_sys%units )
7190    CALL netcdf_handle_error( 'netcdf_create_crs', error_no )
7191
7192#endif
7193 END SUBROUTINE netcdf_create_crs
7194
7195
7196!------------------------------------------------------------------------------!
7197! Description:
7198! ------------
7199!> Define UTM coordinates and longitude and latitude in file.
7200!------------------------------------------------------------------------------!
7201 SUBROUTINE define_geo_coordinates( id_set, id_dim_x, id_dim_y, id_var_eutm, id_var_nutm, id_var_lat, id_var_lon )
7202
7203    IMPLICIT NONE
7204
7205    INTEGER ::  i                    !< loop index
7206    INTEGER, INTENT(IN)  ::  id_set  !< file id
7207
7208    INTEGER(iwp), DIMENSION(0:1), INTENT(IN) ::  id_dim_x  !< dimension id of x and xu
7209    INTEGER(iwp), DIMENSION(0:1), INTENT(IN) ::  id_dim_y  !< dimension id of y and yv
7210
7211    INTEGER(iwp), DIMENSION(0:2), INTENT(OUT) ::  id_var_eutm  !< variable id for E_UTM coordinates
7212    INTEGER(iwp), DIMENSION(0:2), INTENT(OUT) ::  id_var_lat   !< variable id for latitude coordinates
7213    INTEGER(iwp), DIMENSION(0:2), INTENT(OUT) ::  id_var_lon   !< variable id for longitude coordinates
7214    INTEGER(iwp), DIMENSION(0:2), INTENT(OUT) ::  id_var_nutm  !< variable id for N_UTM coordinates
7215
7216#if defined( __netcdf )
7217
7218!
7219!-- Define UTM coordinates
7220    IF ( init_model%rotation_angle == 0.0_wp )  THEN
7221       CALL netcdf_create_var( id_set, (/ id_dim_x(0) /), 'E_UTM', NF90_DOUBLE, id_var_eutm(0), 'm', 'easting', 000, 000, 000 )
7222       CALL netcdf_create_var( id_set, (/ id_dim_y(0) /), 'N_UTM', NF90_DOUBLE, id_var_nutm(0), 'm', 'northing', 000, 000, 000 )
7223       CALL netcdf_create_var( id_set, (/ id_dim_x(1) /), 'Eu_UTM', NF90_DOUBLE, id_var_eutm(1), 'm', 'easting', 000, 000, 000 )
7224       CALL netcdf_create_var( id_set, (/ id_dim_y(0) /), 'Nu_UTM', NF90_DOUBLE, id_var_nutm(1), 'm', 'northing', 000, 000, 000 )
7225       CALL netcdf_create_var( id_set, (/ id_dim_x(0) /), 'Ev_UTM', NF90_DOUBLE, id_var_eutm(2), 'm', 'easting', 000, 000, 000 )
7226       CALL netcdf_create_var( id_set, (/ id_dim_y(1) /), 'Nv_UTM', NF90_DOUBLE, id_var_nutm(2), 'm', 'northing', 000, 000, 000 )
7227    ELSE
7228       CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(0) /), &
7229                               'E_UTM', NF90_DOUBLE, id_var_eutm(0), 'm', 'easting', 000, 000, 000 )
7230       CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(0) /), &
7231                               'N_UTM', NF90_DOUBLE, id_var_nutm(0), 'm', 'northing', 000, 000, 000 )
7232       CALL netcdf_create_var( id_set, (/ id_dim_x(1), id_dim_y(0) /), &
7233                               'Eu_UTM', NF90_DOUBLE, id_var_eutm(1), 'm', 'easting', 000, 000, 000 )
7234       CALL netcdf_create_var( id_set, (/ id_dim_x(1), id_dim_y(0) /), &
7235                               'Nu_UTM', NF90_DOUBLE, id_var_nutm(1), 'm', 'northing', 000, 000, 000 )
7236       CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(1) /), &
7237                               'Ev_UTM', NF90_DOUBLE, id_var_eutm(2), 'm', 'easting', 000, 000, 000 )
7238       CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(1) /), &
7239                               'Nv_UTM', NF90_DOUBLE, id_var_nutm(2), 'm', 'northing', 000, 000, 000 )
7240    ENDIF
7241!
7242!-- Define geographic coordinates
7243    CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(0) /), 'lon', NF90_DOUBLE, id_var_lon(0), &
7244                            'degrees_east', 'longitude', 000, 000, 000 )
7245    CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(0) /), 'lat', NF90_DOUBLE, id_var_lat(0), &
7246                            'degrees_north', 'latitude', 000, 000, 000 )
7247    CALL netcdf_create_var( id_set, (/ id_dim_x(1), id_dim_y(0) /), 'lonu', NF90_DOUBLE, id_var_lon(1), &
7248                            'degrees_east', 'longitude', 000, 000, 000 )
7249    CALL netcdf_create_var( id_set, (/ id_dim_x(1), id_dim_y(0) /), 'latu', NF90_DOUBLE, id_var_lat(1), &
7250                            'degrees_north', 'latitude', 000, 000, 000 )
7251    CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(1) /), 'lonv', NF90_DOUBLE, id_var_lon(2), &
7252                            'degrees_east', 'longitude', 000, 000, 000 )
7253    CALL netcdf_create_var( id_set, (/ id_dim_x(0), id_dim_y(1) /), 'latv', NF90_DOUBLE, id_var_lat(2), &
7254                            'degrees_north', 'latitude', 000, 000, 000 )
7255
7256    DO  i = 0, 2
7257       CALL netcdf_create_att( id_set, id_var_eutm(i), 'standard_name', 'projection_x_coordinate', 000)
7258       CALL netcdf_create_att( id_set, id_var_nutm(i), 'standard_name', 'projection_y_coordinate', 000)
7259
7260       CALL netcdf_create_att( id_set, id_var_lat(i), 'standard_name', 'latitude', 000)
7261       CALL netcdf_create_att( id_set, id_var_lon(i), 'standard_name', 'longitude', 000)
7262    ENDDO
7263
7264#endif
7265 END SUBROUTINE define_geo_coordinates
7266
7267
7268!------------------------------------------------------------------------------!
7269! Description:
7270! ------------
7271!> Convert UTM coordinates into geographic latitude and longitude. Conversion
7272!> is based on the work of KrÃŒger (1912) DOI: 10.2312/GFZ.b103-krueger28
7273!> and Karney (2013) DOI: 10.1007/s00190-012-0578-z
7274!> Based on a JavaScript of the geodesy function library written by chrisveness
7275!> https://github.com/chrisveness/geodesy
7276!------------------------------------------------------------------------------!
7277 SUBROUTINE convert_utm_to_geographic( crs, eutm, nutm, lon, lat )
7278
7279    USE basic_constants_and_equations_mod,                                     &
7280        ONLY:  pi
7281
7282    IMPLICIT NONE
7283
7284    INTEGER(iwp) ::  j   !< loop index
7285   
7286    REAL(wp), INTENT(in)  ::  eutm !< easting (UTM)
7287    REAL(wp), INTENT(out) ::  lat  !< geographic latitude in degree
7288    REAL(wp), INTENT(out) ::  lon  !< geographic longitude in degree
7289    REAL(wp), INTENT(in)  ::  nutm !< northing (UTM)
7290
7291    REAL(wp) ::  a           !< 2*pi*a is the circumference of a meridian
7292    REAL(wp) ::  cos_eta_s   !< cos(eta_s)
7293    REAL(wp) ::  delta_i     !<
7294    REAL(wp) ::  delta_tau_i !<
7295    REAL(wp) ::  e           !< eccentricity
7296    REAL(wp) ::  eta         !<
7297    REAL(wp) ::  eta_s       !<
7298    REAL(wp) ::  n           !< 3rd flattening
7299    REAL(wp) ::  n2          !< n^2
7300    REAL(wp) ::  n3          !< n^3
7301    REAL(wp) ::  n4          !< n^4
7302    REAL(wp) ::  n5          !< n^5
7303    REAL(wp) ::  n6          !< n^6
7304    REAL(wp) ::  nu          !<
7305    REAL(wp) ::  nu_s        !<
7306    REAL(wp) ::  sin_eta_s   !< sin(eta_s)
7307    REAL(wp) ::  sinh_nu_s   !< sinush(nu_s)
7308    REAL(wp) ::  tau_i       !<
7309    REAL(wp) ::  tau_i_s     !<
7310    REAL(wp) ::  tau_s       !<
7311    REAL(wp) ::  x           !< adjusted easting
7312    REAL(wp) ::  y           !< adjusted northing
7313
7314    REAL(wp), DIMENSION(6) ::  beta !< 6th order KrÃŒger expressions
7315
7316    REAL(wp), DIMENSION(8), INTENT(in) ::  crs !< coordinate reference system, consists of
7317                                               !< (/semi_major_axis,
7318                                               !<   inverse_flattening,
7319                                               !<   longitude_of_prime_meridian,
7320                                               !<   longitude_of_central_meridian,
7321                                               !<   scale_factor_at_central_meridian,
7322                                               !<   latitude_of_projection_origin,
7323                                               !<   false_easting,
7324                                               !<   false_northing /)
7325
7326    x = eutm - crs(7)  ! remove false easting
7327    y = nutm - crs(8)  ! remove false northing
7328
7329!-- from Karney 2011 Eq 15-22, 36:
7330    e = SQRT( 1.0_wp / crs(2) * ( 2.0_wp - 1.0_wp / crs(2) ) )
7331    n = 1.0_wp / crs(2) / ( 2.0_wp - 1.0_wp / crs(2) )
7332    n2 = n * n
7333    n3 = n * n2
7334    n4 = n * n3
7335    n5 = n * n4
7336    n6 = n * n5
7337
7338    a = crs(1) / ( 1.0_wp + n ) * ( 1.0_wp + 0.25_wp * n2       &
7339                                           + 0.015625_wp * n4   &
7340                                           + 3.90625E-3_wp * n6 )
7341
7342    nu  = x / ( crs(5) * a )
7343    eta = y / ( crs(5) * a )
7344
7345!-- According to KrÃŒger (1912), eq. 26*
7346    beta(1) =        0.5_wp                  * n  &
7347            -        2.0_wp /         3.0_wp * n2 &
7348            +       37.0_wp /        96.0_wp * n3 &
7349            -        1.0_wp /       360.0_wp * n4 &
7350            -       81.0_wp /       512.0_wp * n5 &
7351            +    96199.0_wp /    604800.0_wp * n6
7352
7353    beta(2) =        1.0_wp /        48.0_wp * n2 &
7354            +        1.0_wp /        15.0_wp * n3 &
7355            -      437.0_wp /      1440.0_wp * n4 &
7356            +       46.0_wp /       105.0_wp * n5 &
7357            -  1118711.0_wp /   3870720.0_wp * n6
7358
7359    beta(3) =       17.0_wp /       480.0_wp * n3 &
7360            -       37.0_wp /       840.0_wp * n4 &
7361            -      209.0_wp /      4480.0_wp * n5 &
7362            +     5569.0_wp /     90720.0_wp * n6
7363
7364    beta(4) =     4397.0_wp /    161280.0_wp * n4 &
7365            -       11.0_wp /       504.0_wp * n5 &
7366            -   830251.0_wp /   7257600.0_wp * n6
7367
7368    beta(5) =     4583.0_wp /    161280.0_wp * n5 &
7369            -   108847.0_wp /   3991680.0_wp * n6
7370
7371    beta(6) = 20648693.0_wp / 638668800.0_wp * n6
7372
7373    eta_s = eta
7374    nu_s  = nu
7375    DO  j = 1, 6
7376      eta_s = eta_s - beta(j) * SIN(2.0_wp * j * eta) * COSH(2.0_wp * j * nu)
7377      nu_s  = nu_s  - beta(j) * COS(2.0_wp * j * eta) * SINH(2.0_wp * j * nu)
7378    ENDDO
7379
7380    sinh_nu_s = SINH( nu_s )
7381    sin_eta_s = SIN( eta_s )
7382    cos_eta_s = COS( eta_s )
7383
7384    tau_s = sin_eta_s / SQRT( sinh_nu_s**2 + cos_eta_s**2 )
7385
7386    tau_i = tau_s
7387    delta_tau_i = 1.0_wp
7388
7389    DO WHILE ( ABS( delta_tau_i ) > 1.0E-12_wp )
7390
7391      delta_i = SINH( e * ATANH( e * tau_i / SQRT( 1.0_wp + tau_i**2 ) ) )
7392
7393      tau_i_s = tau_i   * SQRT( 1.0_wp + delta_i**2 )  &
7394               - delta_i * SQRT( 1.0_wp + tau_i**2 )
7395
7396      delta_tau_i = ( tau_s - tau_i_s ) / SQRT( 1.0_wp + tau_i_s**2 )  &
7397                   * ( 1.0_wp + ( 1.0_wp - e**2 ) * tau_i**2 )          &
7398                   / ( ( 1.0_wp - e**2 ) * SQRT( 1.0_wp + tau_i**2 ) )
7399
7400      tau_i = tau_i + delta_tau_i
7401
7402    ENDDO
7403
7404    lat = ATAN( tau_i ) / pi * 180.0_wp
7405    lon = ATAN2( sinh_nu_s, cos_eta_s ) / pi * 180.0_wp + crs(4)
7406
7407 END SUBROUTINE convert_utm_to_geographic
7408
7409 END MODULE netcdf_interface
Note: See TracBrowser for help on using the repository browser.