source: palm/trunk/SOURCE/netcdf_data_input_mod.f90 @ 2925

Last change on this file since 2925 was 2925, checked in by suehring, 7 years ago

Check for further inconsistent settings of surface_fractions; error messages slightly rephrased and error numbers changed.

  • Property svn:keywords set to Id
File size: 194.1 KB
Line 
1!> @file netcdf_data_input_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-2018 Leibniz Universitaet Hannover
18!------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22!
23!
24! Former revisions:
25! -----------------
26! $Id: netcdf_data_input_mod.f90 2925 2018-03-23 14:54:11Z suehring $
27! Check for further inconsistent settings of surface_fractions.
28! Some messages slightly rephrased and error numbers renamed.
29!
30! 2898 2018-03-15 13:03:01Z suehring
31! Check if each building has a type. Further, check if dimensions in static
32! input file match the model dimensions.
33!
34! 2897 2018-03-15 11:47:16Z suehring
35! Relax restrictions for topography input, terrain and building heights can be
36! input separately and are not mandatory any more.
37!
38! 2874 2018-03-13 10:55:42Z knoop
39! Bugfix: wrong placement of netcdf cpp-macros fixed
40!
41! 2794 2018-02-07 14:09:43Z knoop
42! Check if 3D building input is consistent to numeric grid.
43!
44! 2773 2018-01-30 14:12:54Z suehring
45! - Enable initialization with 3D topography.
46! - Move check for correct initialization in nesting mode to check_parameters.
47!
48! 2772 2018-01-29 13:10:35Z suehring
49! Initialization of simulation independent on land-surface model.
50!
51! 2746 2018-01-15 12:06:04Z suehring
52! Read plant-canopy variables independently on land-surface model usage
53!
54! 2718 2018-01-02 08:49:38Z maronga
55! Corrected "Former revisions" section
56!
57! 2711 2017-12-20 17:04:49Z suehring
58! Rename subroutine close_file to avoid double-naming. 
59!
60! 2700 2017-12-15 14:12:35Z suehring
61!
62! 2696 2017-12-14 17:12:51Z kanani
63! Initial revision (suehring)
64!
65!
66!
67!
68! Authors:
69! --------
70! @author Matthias Suehring
71!
72! Description:
73! ------------
74!> Modulue contains routines to input data according to Palm input data       
75!> standart using dynamic and static input files.
76!>
77!> @todo - Order input alphabetically
78!> @todo - Revise error messages and error numbers
79!> @todo - Input of missing quantities (chemical species, emission rates)
80!> @todo - Defninition and input of still missing variable attributes
81!> @todo - Input of initial geostrophic wind profiles with cyclic conditions.
82!------------------------------------------------------------------------------!
83 MODULE netcdf_data_input_mod
84 
85    USE control_parameters,                                                    &
86        ONLY:  coupling_char, io_blocks, io_group
87
88    USE kinds
89
90#if defined ( __netcdf )
91    USE NETCDF
92#endif
93
94    USE pegrid
95!
96!-- Define type for dimensions.
97    TYPE dims_xy
98       INTEGER(iwp) :: nx                             !< dimension length in x
99       INTEGER(iwp) :: ny                             !< dimension length in y
100       REAL(wp), DIMENSION(:), ALLOCATABLE :: x       !< dimension array in x
101       REAL(wp), DIMENSION(:), ALLOCATABLE :: y       !< dimension array in y
102    END TYPE dims_xy
103!
104!-- Define data type for nesting in larger-scale models like COSMO.
105!-- Data type comprises u, v, w, pt, and q at lateral and top boundaries.
106    TYPE force_type
107
108       CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE ::  var_names
109
110       INTEGER(iwp) ::  nt     !< number of time levels in dynamic input file
111       INTEGER(iwp) ::  nzu    !< number of vertical levels on scalar grid in dynamic input file
112       INTEGER(iwp) ::  nzw    !< number of vertical levels on w grid in dynamic input file
113       INTEGER(iwp) ::  tind   !< time index for reference time in large-scale forcing data
114       INTEGER(iwp) ::  tind_p !< time index for following time in large-scale forcing data
115
116       LOGICAL      ::  init         = .FALSE.
117       LOGICAL      ::  interpolated = .FALSE.
118       LOGICAL      ::  from_file    = .FALSE.
119
120       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surface_pressure !< time dependent surface pressure
121       REAL(wp), DIMENSION(:), ALLOCATABLE ::  time             !< time levels in dynamic input file
122       REAL(wp), DIMENSION(:), ALLOCATABLE ::  zu_atmos         !< vertical levels at scalar grid in dynamic input file
123       REAL(wp), DIMENSION(:), ALLOCATABLE ::  zw_atmos         !< vertical levels at w grid in dynamic input file
124
125       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  u_left   !< u-component at left boundary
126       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  v_left   !< v-component at left boundary
127       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  w_left   !< w-component at left boundary
128       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  q_left   !< mixing ratio at left boundary
129       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pt_left  !< potentital temperautre at left boundary
130
131       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  u_north  !< u-component at north boundary
132       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  v_north  !< v-component at north boundary
133       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  w_north  !< w-component at north boundary
134       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  q_north  !< mixing ratio at north boundary
135       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pt_north !< potentital temperautre at north boundary
136
137       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  u_right  !< u-component at right boundary
138       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  v_right  !< v-component at right boundary
139       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  w_right  !< w-component at right boundary
140       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  q_right  !< mixing ratio at right boundary
141       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pt_right !< potentital temperautre at right boundary
142
143       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  u_south  !< u-component at south boundary
144       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  v_south  !< v-component at south boundary
145       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  w_south  !< w-component at south boundary
146       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  q_south  !< mixing ratio at south boundary
147       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pt_south !< potentital temperautre at south boundary
148
149       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  u_top    !< u-component at top boundary
150       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  v_top    !< v-component at top boundary
151       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  w_top    !< w-component at top boundary
152       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  q_top    !< mixing ratio at top boundary
153       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pt_top   !< potentital temperautre at top boundary
154
155    END TYPE force_type
156
157    TYPE init_type
158
159       INTEGER(iwp) ::  lod_msoil !< level of detail - soil moisture
160       INTEGER(iwp) ::  lod_pt    !< level of detail - pt
161       INTEGER(iwp) ::  lod_q     !< level of detail - q
162       INTEGER(iwp) ::  lod_tsoil !< level of detail - soil temperature
163       INTEGER(iwp) ::  lod_u     !< level of detail - u-component
164       INTEGER(iwp) ::  lod_v     !< level of detail - v-component
165       INTEGER(iwp) ::  lod_w     !< level of detail - w-component
166       INTEGER(iwp) ::  nx        !< number of scalar grid points along x in dynamic input file
167       INTEGER(iwp) ::  nxu       !< number of u grid points along x in dynamic input file
168       INTEGER(iwp) ::  ny        !< number of scalar grid points along y in dynamic input file
169       INTEGER(iwp) ::  nyv       !< number of v grid points along y in dynamic input file
170       INTEGER(iwp) ::  nzs       !< number of vertical soil levels in dynamic input file
171       INTEGER(iwp) ::  nzu       !< number of vertical levels on scalar grid in dynamic input file
172       INTEGER(iwp) ::  nzw       !< number of vertical levels on w grid in dynamic input file
173
174       LOGICAL ::  from_file_msoil  = .FALSE. !< flag indicating whether soil moisture is already initialized from file
175       LOGICAL ::  from_file_pt     = .FALSE. !< flag indicating whether pt is already initialized from file
176       LOGICAL ::  from_file_q      = .FALSE. !< flag indicating whether q is already initialized from file 
177       LOGICAL ::  from_file_tsoil  = .FALSE. !< flag indicating whether soil temperature is already initialized from file
178       LOGICAL ::  from_file_u      = .FALSE. !< flag indicating whether u is already initialized from file
179       LOGICAL ::  from_file_v      = .FALSE. !< flag indicating whether v is already initialized from file
180       LOGICAL ::  from_file_w      = .FALSE. !< flag indicating whether w is already initialized from file
181
182       REAL(wp) ::  fill_msoil       !< fill value for soil moisture
183       REAL(wp) ::  fill_pt          !< fill value for pt
184       REAL(wp) ::  fill_q           !< fill value for q
185       REAL(wp) ::  fill_tsoil       !< fill value for soil temperature
186       REAL(wp) ::  fill_u           !< fill value for u
187       REAL(wp) ::  fill_v           !< fill value for v
188       REAL(wp) ::  fill_w           !< fill value for w
189       REAL(wp) ::  latitude         !< latitude of the southern model boundary
190       REAL(wp) ::  longitude        !< longitude of the western model boundary
191
192       REAL(wp), DIMENSION(:), ALLOCATABLE ::  msoil_init   !< initial vertical profile of soil moisture
193       REAL(wp), DIMENSION(:), ALLOCATABLE ::  pt_init      !< initial vertical profile of pt
194       REAL(wp), DIMENSION(:), ALLOCATABLE ::  q_init       !< initial vertical profile of q
195       REAL(wp), DIMENSION(:), ALLOCATABLE ::  tsoil_init   !< initial vertical profile of soil temperature
196       REAL(wp), DIMENSION(:), ALLOCATABLE ::  u_init       !< initial vertical profile of u
197       REAL(wp), DIMENSION(:), ALLOCATABLE ::  ug_init      !< initial vertical profile of ug
198       REAL(wp), DIMENSION(:), ALLOCATABLE ::  v_init       !< initial vertical profile of v
199       REAL(wp), DIMENSION(:), ALLOCATABLE ::  vg_init      !< initial vertical profile of ug
200       REAL(wp), DIMENSION(:), ALLOCATABLE ::  w_init       !< initial vertical profile of w
201       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z_soil       !< vertical levels in soil in dynamic input file, used for interpolation
202       REAL(wp), DIMENSION(:), ALLOCATABLE ::  zu_atmos     !< vertical levels at scalar grid in dynamic input file, used for interpolation
203       REAL(wp), DIMENSION(:), ALLOCATABLE ::  zw_atmos     !< vertical levels at w grid in dynamic input file, used for interpolation
204
205
206       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  msoil        !< initial 3d soil moisture provide by Inifor and interpolated onto soil grid
207       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  tsoil        !< initial 3d soil temperature provide by Inifor and interpolated onto soil grid
208
209    END TYPE init_type
210
211!
212!-- Define data structures for different input data types.
213!-- 8-bit Integer 2D
214    TYPE int_2d_8bit
215       INTEGER(KIND=1) ::  fill = -127                      !< fill value
216       INTEGER(KIND=1), DIMENSION(:,:), ALLOCATABLE ::  var !< respective variable
217       
218       LOGICAL ::  from_file = .FALSE.  !< flag indicating whether an input variable is available and read from file or default values are used 
219    END TYPE int_2d_8bit
220!
221!-- 32-bit Integer 2D
222    TYPE int_2d_32bit
223       INTEGER(iwp) ::  fill = -9999                      !< fill value
224       INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  var  !< respective variable
225
226       LOGICAL ::  from_file = .FALSE. !< flag indicating whether an input variable is available and read from file or default values are used 
227    END TYPE int_2d_32bit
228
229!
230!-- Define data type to read 2D real variables
231    TYPE real_2d
232       LOGICAL ::  from_file = .FALSE.  !< flag indicating whether an input variable is available and read from file or default values are used 
233
234       REAL(wp) ::  fill = -9999.9_wp                !< fill value
235       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  var !< respective variable
236    END TYPE real_2d
237
238!
239!-- Define data type to read 2D real variables
240    TYPE real_3d
241       LOGICAL ::  from_file = .FALSE.  !< flag indicating whether an input variable is available and read from file or default values are used 
242
243       INTEGER(iwp) ::  nz   !< number of grid points along vertical dimension                     
244
245       REAL(wp) ::  fill = -9999.9_wp                  !< fill value
246       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  var !< respective variable
247    END TYPE real_3d
248!
249!-- Define data structure where the dimension and type of the input depends
250!-- on the given level of detail.
251!-- For buildings, the input is either 2D float, or 3d byte.
252    TYPE build_in
253       INTEGER(iwp)    ::  lod = 1                               !< level of detail                 
254       INTEGER(KIND=1) ::  fill2 = -127                          !< fill value for lod = 2
255       INTEGER(iwp)    ::  nz                                    !< number of vertical layers in file
256       INTEGER(KIND=1), DIMENSION(:,:,:), ALLOCATABLE ::  var_3d !< 3d variable (lod = 2)
257
258       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z                 !< vertical coordinate for 3D building, used for consistency check
259
260       LOGICAL ::  from_file = .FALSE.  !< flag indicating whether an input variable is available and read from file or default values are used 
261
262       REAL(wp)                              ::  fill1 = -9999.9_wp !< fill values for lod = 1
263       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  var_2d             !< 2d variable (lod = 1)
264    END TYPE build_in
265
266!
267!-- For soil_type, the input is either 2D or 3D one-byte integer.
268    TYPE soil_in
269       INTEGER(iwp)                                   ::  lod = 1      !< level of detail                 
270       INTEGER(KIND=1)                                ::  fill = -127  !< fill value for lod = 2
271       INTEGER(KIND=1), DIMENSION(:,:), ALLOCATABLE   ::  var_2d       !< 2d variable (lod = 1)
272       INTEGER(KIND=1), DIMENSION(:,:,:), ALLOCATABLE ::  var_3d       !< 3d variable (lod = 2)
273
274       LOGICAL ::  from_file = .FALSE.  !< flag indicating whether an input variable is available and read from file or default values are used 
275    END TYPE soil_in
276
277!
278!-- Define data type for fractions between surface types
279    TYPE fracs
280       INTEGER(iwp)                            ::  nf             !< total number of fractions
281       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  nfracs         !< dimension array for fraction
282
283       LOGICAL ::  from_file = .FALSE. !< flag indicating whether an input variable is available and read from file or default values are used 
284
285       REAL(wp)                                ::  fill = -9999.9_wp !< fill value
286       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  frac              !< respective fraction between different surface types
287    END TYPE fracs
288!
289!-- Data type for parameter lists, Depending on the given level of detail,
290!-- the input is 3D or 4D
291    TYPE pars
292       INTEGER(iwp)                            ::  lod = 1         !< level of detail
293       INTEGER(iwp)                            ::  np              !< total number of parameters
294       INTEGER(iwp)                            ::  nz              !< vertical dimension - number of soil layers
295       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  layers          !< dimension array for soil layers
296       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  pars            !< dimension array for parameters
297
298       LOGICAL ::  from_file = .FALSE.  !< flag indicating whether an input variable is available and read from file or default values are used 
299
300       REAL(wp)                                  ::  fill = -9999.9_wp !< fill value
301       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE   ::  pars_xy           !< respective parameters, level of detail = 1
302       REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE ::  pars_xyz          !< respective parameters, level of detail = 2
303    END TYPE pars
304!
305!-- Define variables
306    TYPE(dims_xy)    ::  dim_static !< data structure for x, y-dimension in static input file
307
308    TYPE(force_type) ::  force     !< data structure for data input at lateral and top boundaries (provided by Inifor) 
309
310    TYPE(init_type) ::  init_3d    !< data structure for the initialization of the 3D flow and soil fields
311    TYPE(init_type) ::  init_model !< data structure for the initialization of the model
312
313!
314!-- Define 2D variables of type NC_BYTE
315    TYPE(int_2d_8bit)  ::  albedo_type_f     !< input variable for albedo type
316    TYPE(int_2d_8bit)  ::  building_type_f   !< input variable for building type
317    TYPE(int_2d_8bit)  ::  pavement_type_f   !< input variable for pavenment type
318    TYPE(int_2d_8bit)  ::  street_crossing_f !< input variable for water type
319    TYPE(int_2d_8bit)  ::  street_type_f     !< input variable for water type
320    TYPE(int_2d_8bit)  ::  vegetation_type_f !< input variable for vegetation type
321    TYPE(int_2d_8bit)  ::  water_type_f      !< input variable for water type
322
323!
324!-- Define 2D variables of type NC_INT
325    TYPE(int_2d_32bit) ::  building_id_f     !< input variable for building ID
326!
327!-- Define 2D variables of type NC_FLOAT
328    TYPE(real_2d) ::  terrain_height_f       !< input variable for terrain height
329!
330!-- Define 3D variables of type NC_FLOAT
331    TYPE(real_3d) ::  basal_area_density_f    !< input variable for basal area density - resolved vegetation
332    TYPE(real_3d) ::  leaf_area_density_f     !< input variable for leaf area density - resolved vegetation
333    TYPE(real_3d) ::  root_area_density_lad_f !< input variable for root area density - resolved vegetation
334    TYPE(real_3d) ::  root_area_density_lsm_f !< input variable for root area density - parametrized vegetation
335
336!
337!-- Define input variable for buildings
338    TYPE(build_in) ::  buildings_f           !< input variable for buildings
339!
340!-- Define input variables for soil_type
341    TYPE(soil_in)  ::  soil_type_f           !< input variable for soil type
342
343    TYPE(fracs) ::  surface_fraction_f       !< input variable for surface fraction
344
345    TYPE(pars)  ::  albedo_pars_f              !< input variable for albedo parameters
346    TYPE(pars)  ::  building_pars_f            !< input variable for building parameters
347    TYPE(pars)  ::  pavement_pars_f            !< input variable for pavement parameters
348    TYPE(pars)  ::  pavement_subsurface_pars_f !< input variable for pavement parameters
349    TYPE(pars)  ::  soil_pars_f                !< input variable for soil parameters
350    TYPE(pars)  ::  vegetation_pars_f          !< input variable for vegetation parameters
351    TYPE(pars)  ::  water_pars_f               !< input variable for water parameters
352
353
354    CHARACTER(LEN=3)  ::  char_lod  = 'lod'         !< name of level-of-detail attribute in NetCDF file
355
356    CHARACTER(LEN=10) ::  char_fill = '_FillValue'  !< name of fill value attribute in NetCDF file
357    CHARACTER(LEN=10) ::  char_lon  = 'origin_lon'  !< name of global attribute for longitude in NetCDF file
358    CHARACTER(LEN=10) ::  char_lat  = 'origin_lat'  !< name of global attribute for latitude in NetCDF file
359
360    CHARACTER(LEN=100) ::  input_file_static  = 'PIDS_STATIC'  !< Name of file which comprises static input data
361    CHARACTER(LEN=100) ::  input_file_dynamic = 'PIDS_DYNAMIC' !< Name of file which comprises dynamic input data
362
363    INTEGER(iwp) ::  nc_stat         !< return value of nf90 function call
364
365    LOGICAL ::  input_pids_static  = .FALSE.   !< Flag indicating whether Palm-input-data-standard file containing static information exists
366    LOGICAL ::  input_pids_dynamic = .FALSE.   !< Flag indicating whether Palm-input-data-standard file containing dynamic information exists
367
368    SAVE
369
370    PRIVATE
371
372    INTERFACE netcdf_data_input_interpolate
373       MODULE PROCEDURE netcdf_data_input_interpolate_1d
374       MODULE PROCEDURE netcdf_data_input_interpolate_1d_soil
375       MODULE PROCEDURE netcdf_data_input_interpolate_2d
376       MODULE PROCEDURE netcdf_data_input_interpolate_3d
377    END INTERFACE netcdf_data_input_interpolate
378
379    INTERFACE netcdf_data_input_check_dynamic
380       MODULE PROCEDURE netcdf_data_input_check_dynamic
381    END INTERFACE netcdf_data_input_check_dynamic
382
383    INTERFACE netcdf_data_input_check_static
384       MODULE PROCEDURE netcdf_data_input_check_static
385    END INTERFACE netcdf_data_input_check_static
386
387    INTERFACE netcdf_data_input_inquire_file
388       MODULE PROCEDURE netcdf_data_input_inquire_file
389    END INTERFACE netcdf_data_input_inquire_file
390
391    INTERFACE netcdf_data_input_init
392       MODULE PROCEDURE netcdf_data_input_init
393    END INTERFACE netcdf_data_input_init
394
395    INTERFACE netcdf_data_input_init_3d
396       MODULE PROCEDURE netcdf_data_input_init_3d
397    END INTERFACE netcdf_data_input_init_3d
398
399    INTERFACE netcdf_data_input_lsf
400       MODULE PROCEDURE netcdf_data_input_lsf
401    END INTERFACE netcdf_data_input_lsf
402
403    INTERFACE netcdf_data_input_surface_data
404       MODULE PROCEDURE netcdf_data_input_surface_data
405    END INTERFACE netcdf_data_input_surface_data
406
407    INTERFACE netcdf_data_input_topo
408       MODULE PROCEDURE netcdf_data_input_topo
409    END INTERFACE netcdf_data_input_topo
410
411    INTERFACE get_variable
412       MODULE PROCEDURE get_variable_1d_int
413       MODULE PROCEDURE get_variable_1d_real
414       MODULE PROCEDURE get_variable_2d_int8
415       MODULE PROCEDURE get_variable_2d_int32
416       MODULE PROCEDURE get_variable_2d_real
417       MODULE PROCEDURE get_variable_3d_int8
418       MODULE PROCEDURE get_variable_3d_real
419       MODULE PROCEDURE get_variable_4d_real
420    END INTERFACE get_variable
421
422    INTERFACE get_attribute
423       MODULE PROCEDURE get_attribute_real
424       MODULE PROCEDURE get_attribute_int8
425       MODULE PROCEDURE get_attribute_int32
426       MODULE PROCEDURE get_attribute_string
427    END INTERFACE get_attribute
428
429!
430!-- Public variables
431    PUBLIC albedo_pars_f, albedo_type_f, basal_area_density_f, buildings_f,    &
432           building_id_f, building_pars_f, building_type_f, force, init_3d,    &
433           init_model, input_file_static, input_pids_static,                   &
434           input_pids_dynamic, leaf_area_density_f,                            &
435           pavement_pars_f, pavement_subsurface_pars_f, pavement_type_f,       &
436           root_area_density_lad_f, root_area_density_lsm_f, soil_pars_f,      &
437           soil_type_f, street_crossing_f, street_type_f, surface_fraction_f,  &
438           terrain_height_f, vegetation_pars_f, vegetation_type_f,             &
439           water_pars_f, water_type_f
440
441!
442!-- Public subroutines
443    PUBLIC netcdf_data_input_check_dynamic, netcdf_data_input_check_static,    &
444           netcdf_data_input_inquire_file,                                     &
445           netcdf_data_input_init, netcdf_data_input_init_3d,                  &
446           netcdf_data_input_interpolate, netcdf_data_input_lsf,               &
447           netcdf_data_input_surface_data, netcdf_data_input_topo
448
449 CONTAINS
450
451!------------------------------------------------------------------------------!
452! Description:
453! ------------
454!> Inquires whether NetCDF input files according to Palm-input-data standard
455!> exist. Moreover, basic checks are performed.
456!------------------------------------------------------------------------------!
457    SUBROUTINE netcdf_data_input_inquire_file
458
459       USE control_parameters,                                                 &
460           ONLY:  land_surface, message_string, topo_no_distinct, urban_surface
461
462       IMPLICIT NONE
463
464       LOGICAL ::  check_nest  !< flag indicating whether a check passed or not
465
466#if defined ( __netcdf )
467       INQUIRE( FILE = TRIM( input_file_static ) // TRIM( coupling_char ),     &
468                EXIST = input_pids_static  )
469       INQUIRE( FILE = TRIM( input_file_dynamic ) // TRIM( coupling_char ),    &
470                EXIST = input_pids_dynamic )
471#endif
472
473!
474!--    As long as topography can be input via ASCII format, no distinction
475!--    between building and terrain can be made. This case, classify all
476!--    surfaces as default type. Same in case land-surface and urban-surface
477!--    model are not applied.
478       IF ( .NOT. input_pids_static )  THEN
479          topo_no_distinct = .TRUE. 
480       ENDIF
481
482    END SUBROUTINE netcdf_data_input_inquire_file
483
484!------------------------------------------------------------------------------!
485! Description:
486! ------------
487!> Reads global attributes required for initialization of the model.
488!------------------------------------------------------------------------------!
489    SUBROUTINE netcdf_data_input_init
490
491       IMPLICIT NONE
492
493       INTEGER(iwp) ::  id_mod   !< NetCDF id of input file
494       INTEGER(iwp) ::  ii       !< running index for IO blocks
495
496       IF ( .NOT. input_pids_static )  RETURN 
497
498       DO  ii = 0, io_blocks-1
499          IF ( ii == io_group )  THEN
500#if defined ( __netcdf )
501!
502!--          Open file in read-only mode
503             CALL open_read_file( TRIM( input_file_static ) //                 &
504                                  TRIM( coupling_char ), id_mod )
505!
506!--          Read global attribute for latitude and longitude
507             CALL get_attribute( id_mod, char_lat,                             &
508                                 init_model%latitude, .TRUE. )
509
510             CALL get_attribute( id_mod, char_lon,                             &
511                                 init_model%longitude, .TRUE. )
512!
513!--          Finally, close input file
514             CALL close_input_file( id_mod )
515#endif
516          ENDIF
517#if defined( __parallel )
518          CALL MPI_BARRIER( comm2d, ierr )
519#endif
520       ENDDO
521
522    END SUBROUTINE netcdf_data_input_init
523
524!------------------------------------------------------------------------------!
525! Description:
526! ------------
527!> Reads surface classification data, such as vegetation and soil type, etc. .
528!------------------------------------------------------------------------------!
529    SUBROUTINE netcdf_data_input_surface_data
530
531       USE control_parameters,                                                 &
532           ONLY:  bc_lr_cyc, bc_ns_cyc, land_surface, message_string,          &
533                  plant_canopy, urban_surface
534
535       USE indices,                                                            &
536           ONLY:  nbgp, nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg
537
538
539       IMPLICIT NONE
540
541       CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE ::  var_names  !< variable names in static input file
542
543       INTEGER(iwp) ::  i         !< running index along x-direction
544       INTEGER(iwp) ::  ii        !< running index for IO blocks
545       INTEGER(iwp) ::  id_surf   !< NetCDF id of input file
546       INTEGER(iwp) ::  j         !< running index along y-direction
547       INTEGER(iwp) ::  k         !< running index along z-direction
548       INTEGER(iwp) ::  k2        !< running index
549       INTEGER(iwp) ::  num_vars  !< number of variables in input file
550       INTEGER(iwp) ::  nz_soil   !< number of soil layers in file
551
552       INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  var_exchange_int !< dummy variables used to exchange 32-bit Integer arrays
553       INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE  ::  var_dum_int_3d !< dummy variables used to exchange real arrays
554
555       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  var_exchange_real !< dummy variables used to exchange real arrays
556
557       REAL(wp), DIMENSION(:,:,:),   ALLOCATABLE ::  var_dum_real_3d !< dummy variables used to exchange real arrays
558       REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE ::  var_dum_real_4d !< dummy variables used to exchange real arrays
559
560!
561!--    If not static input file is available, skip this routine
562       IF ( .NOT. input_pids_static )  RETURN
563!
564!--    Read plant canopy variables.
565       IF ( plant_canopy )  THEN
566          DO  ii = 0, io_blocks-1
567             IF ( ii == io_group )  THEN
568#if defined ( __netcdf )
569!
570!--             Open file in read-only mode
571                CALL open_read_file( TRIM( input_file_static ) //              &
572                                     TRIM( coupling_char ) , id_surf )
573!
574!--             At first, inquire all variable names.
575!--             This will be used to check whether an optional input variable
576!--             exist or not.
577                CALL inquire_num_variables( id_surf, num_vars )
578
579                ALLOCATE( var_names(1:num_vars) )
580                CALL inquire_variable_names( id_surf, var_names )
581
582!
583!--             Read leaf area density - resolved vegetation
584                IF ( check_existence( var_names, 'leaf_area_density' ) )  THEN
585                   leaf_area_density_f%from_file = .TRUE. 
586                   CALL get_attribute( id_surf, char_fill,                     &
587                                       leaf_area_density_f%fill,               &
588                                       .FALSE., 'leaf_area_density' ) 
589!
590!--                Inquire number of vertical vegetation layer
591                   CALL get_dimension_length( id_surf, leaf_area_density_f%nz, &
592                                              'zlad' )
593!           
594!--                Allocate variable for leaf-area density
595                   ALLOCATE( leaf_area_density_f%var(                          &
596                                                   0:leaf_area_density_f%nz-1, &
597                                                   nys:nyn,nxl:nxr) )
598
599                   DO  i = nxl, nxr
600                      DO  j = nys, nyn
601                         CALL get_variable( id_surf, 'leaf_area_density',      &
602                                            i, j,                              &
603                                            leaf_area_density_f%var(:,j,i) ) 
604                      ENDDO
605                   ENDDO
606                ELSE
607                   leaf_area_density_f%from_file = .FALSE. 
608                ENDIF
609
610!
611!--             Read basal area density - resolved vegetation
612                IF ( check_existence( var_names, 'basal_area_density' ) )  THEN
613                   basal_area_density_f%from_file = .TRUE. 
614                   CALL get_attribute( id_surf, char_fill,                     &
615                                       basal_area_density_f%fill,              &
616                                       .FALSE., 'basal_area_density' ) 
617!
618!--                Inquire number of vertical vegetation layer
619                   CALL get_dimension_length( id_surf,                         &
620                                              basal_area_density_f%nz,         &
621                                              'zlad' )
622!           
623!--                Allocate variable
624                   ALLOCATE( basal_area_density_f%var(                         &
625                                                  0:basal_area_density_f%nz-1, &
626                                                  nys:nyn,nxl:nxr) )
627
628                   DO  i = nxl, nxr
629                      DO  j = nys, nyn
630                         CALL get_variable( id_surf, 'basal_area_density',     &
631                                            i, j,                              &
632                                            basal_area_density_f%var(:,j,i) ) 
633                      ENDDO
634                   ENDDO
635                ELSE
636                   basal_area_density_f%from_file = .FALSE. 
637                ENDIF
638
639!
640!--             Read root area density - resolved vegetation
641                IF ( check_existence( var_names, 'root_area_density_lad' ) )  THEN
642                   root_area_density_lad_f%from_file = .TRUE. 
643                   CALL get_attribute( id_surf, char_fill,                     &
644                                       root_area_density_lad_f%fill,           &
645                                       .FALSE., 'root_area_density_lad' ) 
646!
647!--                Inquire number of vertical soil layers
648                   CALL get_dimension_length( id_surf,                         &
649                                              root_area_density_lad_f%nz,      &
650                                              'zsoil' )
651!           
652!--                Allocate variable
653                   ALLOCATE( root_area_density_lad_f%var                       &
654                                               (0:root_area_density_lad_f%nz-1,&
655                                                nys:nyn,nxl:nxr) )
656
657                   DO  i = nxl, nxr
658                      DO  j = nys, nyn
659                         CALL get_variable( id_surf, 'root_area_density_lad',  &
660                                            i, j,                              &
661                                            root_area_density_lad_f%var(:,j,i) ) 
662                      ENDDO
663                   ENDDO
664                ELSE
665                   root_area_density_lad_f%from_file = .FALSE. 
666                ENDIF
667!
668!--             Finally, close input file
669                CALL close_input_file( id_surf )
670#endif
671             ENDIF
672#if defined( __parallel )
673             CALL MPI_BARRIER( comm2d, ierr )
674#endif
675          ENDDO
676!
677!--       Deallocate variable list. Will be re-allocated in case further
678!--       variables are read from file.         
679          IF ( ALLOCATED( var_names ) )  DEALLOCATE( var_names )
680
681       ENDIF
682!
683!--    Skip the following if no land-surface or urban-surface module are
684!--    applied. This case, no one of the following variables is used anyway. 
685       IF (  .NOT. land_surface  .OR.  .NOT. urban_surface )  RETURN
686!
687!--    Initialize dummy arrays used for ghost-point exchange
688       var_exchange_int  = 0
689       var_exchange_real = 0.0_wp
690
691       DO  ii = 0, io_blocks-1
692          IF ( ii == io_group )  THEN
693#if defined ( __netcdf )
694!
695!--          Open file in read-only mode
696             CALL open_read_file( TRIM( input_file_static ) //                 &
697                                  TRIM( coupling_char ) , id_surf )
698
699!
700!--          Inquire all variable names.
701!--          This will be used to check whether an optional input variable exist
702!--          or not.
703             CALL inquire_num_variables( id_surf, num_vars )
704
705             ALLOCATE( var_names(1:num_vars) )
706             CALL inquire_variable_names( id_surf, var_names )
707
708!
709!--          Read vegetation type and required attributes
710             IF ( check_existence( var_names, 'vegetation_type' ) )  THEN
711                vegetation_type_f%from_file = .TRUE.
712                CALL get_attribute( id_surf, char_fill,                        &
713                                    vegetation_type_f%fill,                    &
714                                    .FALSE., 'vegetation_type' )
715!
716!--             PE-wise reading of 2D vegetation type.
717                ALLOCATE ( vegetation_type_f%var(nys:nyn,nxl:nxr)  )
718
719                DO  i = nxl, nxr
720                   CALL get_variable( id_surf, 'vegetation_type',              &
721                                      i, vegetation_type_f%var(:,i) )
722                ENDDO
723             ELSE
724                vegetation_type_f%from_file = .FALSE.
725             ENDIF
726
727!
728!--          Read soil type and required attributes
729             IF ( check_existence( var_names, 'soil_type' ) )  THEN
730                   soil_type_f%from_file = .TRUE. 
731!
732!--             Note, lod is currently not on file; skip for the moment
733!                 CALL get_attribute( id_surf, char_lod,                       &
734!                                            soil_type_f%lod,                  &
735!                                            .FALSE., 'soil_type' )
736                CALL get_attribute( id_surf, char_fill,                        &
737                                    soil_type_f%fill,                          &
738                                    .FALSE., 'soil_type' ) 
739
740                IF ( soil_type_f%lod == 1 )  THEN
741!
742!--                PE-wise reading of 2D soil type.
743                   ALLOCATE ( soil_type_f%var_2d(nys:nyn,nxl:nxr)  )
744                   DO  i = nxl, nxr
745                      CALL get_variable( id_surf, 'soil_type',                 &
746                                         i, soil_type_f%var_2d(:,i) ) 
747                   ENDDO
748                ELSEIF ( soil_type_f%lod == 2 )  THEN
749!
750!--                Obtain number of soil layers from file.
751                   CALL get_dimension_length( id_surf, nz_soil, 'zsoil' )
752!
753!--                PE-wise reading of 3D soil type.
754                   ALLOCATE ( soil_type_f%var_3d(0:nz_soil,nys:nyn,nxl:nxr) )
755                   DO  i = nxl, nxr
756                      DO  j = nys, nyn
757                         CALL get_variable( id_surf, 'soil_type', i, j,        &
758                                            soil_type_f%var_3d(:,j,i) )   
759                      ENDDO
760                   ENDDO 
761                ENDIF
762             ELSE
763                soil_type_f%from_file = .FALSE.
764             ENDIF
765
766!
767!--          Read pavement type and required attributes
768             IF ( check_existence( var_names, 'pavement_type' ) )  THEN
769                pavement_type_f%from_file = .TRUE. 
770                CALL get_attribute( id_surf, char_fill,                        &
771                                    pavement_type_f%fill, .FALSE.,             &
772                                    'pavement_type' ) 
773!
774!--             PE-wise reading of 2D pavement type.
775                ALLOCATE ( pavement_type_f%var(nys:nyn,nxl:nxr)  )
776                DO  i = nxl, nxr
777                   CALL get_variable( id_surf, 'pavement_type',                &
778                                      i, pavement_type_f%var(:,i) ) 
779                ENDDO
780             ELSE
781                pavement_type_f%from_file = .FALSE.
782             ENDIF
783
784!
785!--          Read water type and required attributes
786             IF ( check_existence( var_names, 'water_type' ) )  THEN
787                water_type_f%from_file = .TRUE. 
788                CALL get_attribute( id_surf, char_fill, water_type_f%fill,     &
789                                    .FALSE., 'water_type' )
790!
791!--             PE-wise reading of 2D water type.
792                ALLOCATE ( water_type_f%var(nys:nyn,nxl:nxr)  )
793                DO  i = nxl, nxr
794                   CALL get_variable( id_surf, 'water_type', i,                &
795                                      water_type_f%var(:,i) ) 
796                ENDDO
797             ELSE
798                water_type_f%from_file = .FALSE.
799             ENDIF
800!
801!--          Read surface fractions and related information
802             IF ( check_existence( var_names, 'surface_fraction' ) )  THEN
803                surface_fraction_f%from_file = .TRUE. 
804                CALL get_attribute( id_surf, char_fill,                        &
805                                    surface_fraction_f%fill,                   &
806                                    .FALSE., 'surface_fraction' )
807!
808!--             Inquire number of surface fractions
809                CALL get_dimension_length( id_surf,                            &
810                                           surface_fraction_f%nf,              &
811                                           'nsurface_fraction' )
812!           
813!--             Allocate dimension array and input array for surface fractions
814                ALLOCATE( surface_fraction_f%nfracs(0:surface_fraction_f%nf-1) )
815                ALLOCATE( surface_fraction_f%frac(0:surface_fraction_f%nf-1,   &
816                                                  nys:nyn,nxl:nxr) )
817!
818!--             Get dimension of surface fractions
819                CALL get_variable( id_surf, 'nsurface_fraction',               &
820                                   surface_fraction_f%nfracs )
821!
822!--             Read surface fractions
823                DO  i = nxl, nxr
824                   DO  j = nys, nyn
825                      CALL get_variable( id_surf, 'surface_fraction', i, j,    &
826                                         surface_fraction_f%frac(:,j,i) ) 
827                   ENDDO
828                ENDDO
829             ELSE
830                surface_fraction_f%from_file = .FALSE. 
831             ENDIF
832!
833!--          Read building parameters and related information
834             IF ( check_existence( var_names, 'building_pars' ) )  THEN
835                building_pars_f%from_file = .TRUE. 
836                CALL get_attribute( id_surf, char_fill,                        &
837                                    building_pars_f%fill,                      &
838                                    .FALSE., 'building_pars' ) 
839!
840!--             Inquire number of building parameters
841                CALL get_dimension_length( id_surf,                            &
842                                           building_pars_f%np,                 &
843                                           'nbuilding_pars' )
844!           
845!--             Allocate dimension array and input array for building parameters
846                ALLOCATE( building_pars_f%pars(0:building_pars_f%np-1) )
847                ALLOCATE( building_pars_f%pars_xy(0:building_pars_f%np-1,      &
848                                                  nys:nyn,nxl:nxr) )
849!
850!--             Get dimension of building parameters
851                CALL get_variable( id_surf, 'nbuilding_pars',                  &
852                                   building_pars_f%pars )
853!
854!--             Read building_pars
855                DO  i = nxl, nxr
856                   DO  j = nys, nyn
857                      CALL get_variable( id_surf, 'building_pars', i, j,       &
858                                         building_pars_f%pars_xy(:,j,i) )   
859                   ENDDO
860                ENDDO
861             ELSE
862                building_pars_f%from_file = .FALSE. 
863             ENDIF
864
865!
866!--          Read albedo type and required attributes
867             IF ( check_existence( var_names, 'albedo_type' ) )  THEN
868                albedo_type_f%from_file = .TRUE. 
869                CALL get_attribute( id_surf, char_fill, albedo_type_f%fill,    &
870                                    .FALSE.,  'albedo_type' ) 
871!
872!--             PE-wise reading of 2D water type.
873                ALLOCATE ( albedo_type_f%var(nys:nyn,nxl:nxr)  )
874                DO  i = nxl, nxr
875                   CALL get_variable( id_surf, 'albedo_type',                  &
876                                      i, albedo_type_f%var(:,i) ) 
877                ENDDO
878             ELSE
879                albedo_type_f%from_file = .FALSE.
880             ENDIF
881!
882!--          Read albedo parameters and related information
883             IF ( check_existence( var_names, 'albedo_pars' ) )  THEN
884                albedo_pars_f%from_file = .TRUE. 
885                CALL get_attribute( id_surf, char_fill, albedo_pars_f%fill,    &
886                                    .FALSE., 'albedo_pars' ) 
887!
888!--             Inquire number of albedo parameters
889                CALL get_dimension_length( id_surf, albedo_pars_f%np,          &
890                                           'nalbedo_pars' )
891!           
892!--             Allocate dimension array and input array for albedo parameters
893                ALLOCATE( albedo_pars_f%pars(0:albedo_pars_f%np-1) )
894                ALLOCATE( albedo_pars_f%pars_xy(0:albedo_pars_f%np-1,          &
895                                                nys:nyn,nxl:nxr) )
896!
897!--             Get dimension of albedo parameters
898                CALL get_variable( id_surf, 'nalbedo_pars', albedo_pars_f%pars )
899
900                DO  i = nxl, nxr
901                   DO  j = nys, nyn
902                      CALL get_variable( id_surf, 'albedo_pars', i, j,         &
903                                         albedo_pars_f%pars_xy(:,j,i) )   
904                   ENDDO
905                ENDDO
906             ELSE
907                albedo_pars_f%from_file = .FALSE. 
908             ENDIF
909
910!
911!--          Read pavement parameters and related information
912             IF ( check_existence( var_names, 'pavement_pars' ) )  THEN
913                pavement_pars_f%from_file = .TRUE. 
914                CALL get_attribute( id_surf, char_fill,                        &
915                                    pavement_pars_f%fill,                      &
916                                    .FALSE., 'pavement_pars' ) 
917!
918!--             Inquire number of pavement parameters
919                CALL get_dimension_length( id_surf, pavement_pars_f%np,        &
920                                           'npavement_pars' )
921!           
922!--             Allocate dimension array and input array for pavement parameters
923                ALLOCATE( pavement_pars_f%pars(0:pavement_pars_f%np-1) )
924                ALLOCATE( pavement_pars_f%pars_xy(0:pavement_pars_f%np-1,      &
925                                                  nys:nyn,nxl:nxr) )
926!
927!--             Get dimension of pavement parameters
928                CALL get_variable( id_surf, 'npavement_pars',                  &
929                                   pavement_pars_f%pars )
930   
931                DO  i = nxl, nxr
932                   DO  j = nys, nyn
933                      CALL get_variable( id_surf, 'pavement_pars', i, j,       &
934                                         pavement_pars_f%pars_xy(:,j,i) )   
935                   ENDDO
936                ENDDO
937             ELSE
938                pavement_pars_f%from_file = .FALSE. 
939             ENDIF
940
941!
942!--          Read pavement subsurface parameters and related information
943             IF ( check_existence( var_names, 'pavement_subsurface_pars' ) )   &
944             THEN
945                pavement_subsurface_pars_f%from_file = .TRUE. 
946                CALL get_attribute( id_surf, char_fill,                        &
947                                    pavement_subsurface_pars_f%fill,           &
948                                    .FALSE., 'pavement_subsurface_pars' ) 
949!
950!--             Inquire number of parameters
951                CALL get_dimension_length( id_surf,                            &
952                                           pavement_subsurface_pars_f%np,      &
953                                           'npavement_subsurface_pars' )
954!
955!--             Inquire number of soil layers
956                CALL get_dimension_length( id_surf,                            &
957                                           pavement_subsurface_pars_f%nz,      &
958                                           'zsoil' )
959!           
960!--             Allocate dimension array and input array for pavement parameters
961                ALLOCATE( pavement_subsurface_pars_f%pars                      &
962                                  (0:pavement_subsurface_pars_f%np-1) )
963                ALLOCATE( pavement_subsurface_pars_f%pars_xyz                  &
964                                  (0:pavement_subsurface_pars_f%np-1,          &
965                                   0:pavement_subsurface_pars_f%nz-1,          &
966                                   nys:nyn,nxl:nxr) )
967!
968!--             Get dimension of pavement parameters
969                CALL get_variable( id_surf, 'npavement_subsurface_pars',       &
970                                   pavement_subsurface_pars_f%pars )
971   
972                DO  i = nxl, nxr
973                   DO  j = nys, nyn
974                      CALL get_variable(                                       &
975                                  id_surf, 'pavement_subsurface_pars',         &
976                                  i, j,                                        &
977                                  pavement_subsurface_pars_f%pars_xyz(:,:,j,i),&
978                                  pavement_subsurface_pars_f%nz,               &
979                                  pavement_subsurface_pars_f%np )   
980                   ENDDO
981                ENDDO
982             ELSE
983                pavement_subsurface_pars_f%from_file = .FALSE. 
984             ENDIF
985
986
987!
988!--          Read vegetation parameters and related information
989             IF ( check_existence( var_names, 'vegetation_pars' ) )  THEN
990                vegetation_pars_f%from_file = .TRUE. 
991                CALL get_attribute( id_surf, char_fill,                        &
992                                    vegetation_pars_f%fill,                    &
993                                    .FALSE.,  'vegetation_pars' )
994!
995!--             Inquire number of vegetation parameters
996                CALL get_dimension_length( id_surf, vegetation_pars_f%np,      &
997                                           'nvegetation_pars' )
998!           
999!--             Allocate dimension array and input array for surface fractions
1000                ALLOCATE( vegetation_pars_f%pars(0:vegetation_pars_f%np-1) )
1001                ALLOCATE( vegetation_pars_f%pars_xy(0:vegetation_pars_f%np-1,  &
1002                                                    nys:nyn,nxl:nxr) )
1003!
1004!--             Get dimension of the parameters
1005                CALL get_variable( id_surf, 'nvegetation_pars',                &
1006                                   vegetation_pars_f%pars )
1007
1008                DO  i = nxl, nxr
1009                   DO  j = nys, nyn
1010                      CALL get_variable( id_surf, 'vegetation_pars', i, j,     &
1011                                         vegetation_pars_f%pars_xy(:,j,i) ) 
1012                   ENDDO
1013                ENDDO
1014             ELSE
1015                vegetation_pars_f%from_file = .FALSE. 
1016             ENDIF
1017
1018!
1019!--          Read root parameters/distribution and related information
1020             IF ( check_existence( var_names, 'soil_pars' ) )  THEN
1021                soil_pars_f%from_file = .TRUE. 
1022                CALL get_attribute( id_surf, char_fill,                        &
1023                                    soil_pars_f%fill,                          & 
1024                                    .FALSE., 'soil_pars' ) 
1025
1026                CALL get_attribute( id_surf, char_lod,                         &
1027                                    soil_pars_f%lod,                           &
1028                                    .FALSE., 'soil_pars' ) 
1029
1030!
1031!--             Inquire number of soil parameters
1032                CALL get_dimension_length( id_surf,                            &
1033                                           soil_pars_f%np,                     &
1034                                           'nsoil_pars' )
1035!
1036!--             Read parameters array
1037                ALLOCATE( soil_pars_f%pars(0:soil_pars_f%np-1) )
1038                CALL get_variable( id_surf, 'nsoil_pars', soil_pars_f%pars )
1039
1040!
1041!--             In case of level of detail 2, also inquire number of vertical
1042!--             soil layers, allocate memory and read the respective dimension
1043                IF ( soil_pars_f%lod == 2 )  THEN
1044                   CALL get_dimension_length( id_surf, soil_pars_f%nz, 'zsoil' )
1045
1046                   ALLOCATE( soil_pars_f%layers(0:soil_pars_f%nz-1) )
1047                   CALL get_variable( id_surf, 'zsoil', soil_pars_f%layers )
1048
1049                ENDIF
1050
1051!
1052!--             Read soil parameters, depending on level of detail
1053                IF ( soil_pars_f%lod == 1 )  THEN     
1054                   ALLOCATE( soil_pars_f%pars_xy(0:soil_pars_f%np-1,           &
1055                                                 nys:nyn,nxl:nxr) )       
1056                   DO  i = nxl, nxr
1057                      DO  j = nys, nyn
1058                         CALL get_variable( id_surf, 'soil_pars', i, j,        &
1059                                            soil_pars_f%pars_xy(:,j,i) ) 
1060                      ENDDO
1061                   ENDDO
1062
1063                ELSEIF ( soil_pars_f%lod == 2 )  THEN
1064                   ALLOCATE( soil_pars_f%pars_xyz(0:soil_pars_f%np-1,          &
1065                                                  0:soil_pars_f%nz-1,          &
1066                                                  nys:nyn,nxl:nxr) )
1067                   DO  i = nxl, nxr
1068                      DO  j = nys, nyn
1069                         CALL get_variable( id_surf, 'soil_pars', i, j,        &
1070                                            soil_pars_f%pars_xyz(:,:,j,i),     &
1071                                            soil_pars_f%nz, soil_pars_f%np ) 
1072                      ENDDO
1073                   ENDDO
1074                ENDIF
1075             ELSE
1076                soil_pars_f%from_file = .FALSE. 
1077             ENDIF
1078
1079!
1080!--          Read water parameters and related information
1081             IF ( check_existence( var_names, 'water_pars' ) )  THEN
1082                water_pars_f%from_file = .TRUE. 
1083                CALL get_attribute( id_surf, char_fill,                        &
1084                                    water_pars_f%fill,                         &
1085                                    .FALSE., 'water_pars' ) 
1086!
1087!--             Inquire number of water parameters
1088                CALL get_dimension_length( id_surf,                            & 
1089                                           water_pars_f%np,                    &
1090                                           'nwater_pars' )
1091!           
1092!--             Allocate dimension array and input array for water parameters
1093                ALLOCATE( water_pars_f%pars(0:water_pars_f%np-1) )
1094                ALLOCATE( water_pars_f%pars_xy(0:water_pars_f%np-1,            &
1095                                               nys:nyn,nxl:nxr) )
1096!
1097!--             Get dimension of water parameters
1098                CALL get_variable( id_surf, 'nwater_pars', water_pars_f%pars )
1099
1100                DO  i = nxl, nxr
1101                   DO  j = nys, nyn
1102                      CALL get_variable( id_surf, 'water_pars', i, j,          &
1103                                         water_pars_f%pars_xy(:,j,i) )   
1104                   ENDDO
1105                ENDDO
1106             ELSE
1107                water_pars_f%from_file = .FALSE. 
1108             ENDIF
1109!
1110!--          Read root area density - parametrized vegetation
1111             IF ( check_existence( var_names, 'root_area_density_lsm' ) )  THEN
1112                root_area_density_lsm_f%from_file = .TRUE.
1113                CALL get_attribute( id_surf, char_fill,                        &
1114                                    root_area_density_lsm_f%fill,              &
1115                                    .FALSE., 'root_area_density_lsm' )
1116!
1117!--             Obtain number of soil layers from file and allocate variable
1118                CALL get_dimension_length( id_surf, root_area_density_lsm_f%nz,&
1119                                           'zsoil' )
1120                ALLOCATE( root_area_density_lsm_f%var                          &
1121                                              (0:root_area_density_lsm_f%nz-1, &
1122                                               nys:nyn,nxl:nxr) )
1123
1124!
1125!--             Read root-area density
1126                DO  i = nxl, nxr
1127                   DO  j = nys, nyn
1128                      CALL get_variable( id_surf, 'root_area_density_lsm',     &
1129                                         i, j,                                 &
1130                                         root_area_density_lsm_f%var(:,j,i) )   
1131                   ENDDO
1132                ENDDO
1133
1134             ELSE
1135                root_area_density_lsm_f%from_file = .FALSE.
1136             ENDIF
1137!
1138!--          Read street type and street crossing
1139             IF ( check_existence( var_names, 'street_type' ) )  THEN
1140                street_type_f%from_file = .TRUE. 
1141                CALL get_attribute( id_surf, char_fill,                        &
1142                                    street_type_f%fill, .FALSE.,               &
1143                                    'street_type' ) 
1144!
1145!--             PE-wise reading of 2D pavement type.
1146                ALLOCATE ( street_type_f%var(nys:nyn,nxl:nxr)  )
1147                DO  i = nxl, nxr
1148                   CALL get_variable( id_surf, 'street_type',                  &
1149                                      i, street_type_f%var(:,i) ) 
1150                ENDDO
1151             ELSE
1152                street_type_f%from_file = .FALSE.
1153             ENDIF
1154
1155             IF ( check_existence( var_names, 'street_crossing' ) )  THEN
1156                street_crossing_f%from_file = .TRUE. 
1157                CALL get_attribute( id_surf, char_fill,                        &
1158                                    street_crossing_f%fill, .FALSE.,           &
1159                                    'street_crossing' ) 
1160!
1161!--             PE-wise reading of 2D pavement type.
1162                ALLOCATE ( street_crossing_f%var(nys:nyn,nxl:nxr)  )
1163                DO  i = nxl, nxr
1164                   CALL get_variable( id_surf, 'street_crossing',              &
1165                                      i, street_crossing_f%var(:,i) ) 
1166                ENDDO
1167             ELSE
1168                street_crossing_f%from_file = .FALSE.
1169             ENDIF
1170!
1171!--          Still missing: root_resolved and building_surface_pars.
1172!--          Will be implemented as soon as they are available.
1173
1174!
1175!--          Finally, close input file
1176             CALL close_input_file( id_surf )
1177#endif
1178          ENDIF
1179#if defined( __parallel )
1180          CALL MPI_BARRIER( comm2d, ierr )
1181#endif
1182       ENDDO
1183!
1184!--    Exchange 1 ghost points for surface variables. Please note, ghost point
1185!--    exchange for 3D parameter lists should be revised by using additional
1186!--    MPI datatypes or rewriting exchange_horiz.
1187!--    Moreover, varialbes will be resized in the following, including ghost
1188!--    points.
1189!--    Start with 2D Integer variables. Please note, for 8-bit integer
1190!--    variables must be swapt to 32-bit integer before calling exchange_horiz.
1191       IF ( albedo_type_f%from_file )  THEN
1192          var_exchange_int                  = INT( albedo_type_f%fill, KIND = 1 )
1193          var_exchange_int(nys:nyn,nxl:nxr) =                                  &
1194                            INT( albedo_type_f%var(nys:nyn,nxl:nxr), KIND = 4 )
1195          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1196          DEALLOCATE( albedo_type_f%var )
1197          ALLOCATE( albedo_type_f%var(nysg:nyng,nxlg:nxrg) )
1198          albedo_type_f%var = INT( var_exchange_int, KIND = 1 )
1199       ENDIF
1200       IF ( pavement_type_f%from_file )  THEN
1201          var_exchange_int                  = INT( pavement_type_f%fill, KIND = 1 )
1202          var_exchange_int(nys:nyn,nxl:nxr) =                                  &
1203                          INT( pavement_type_f%var(nys:nyn,nxl:nxr), KIND = 4 )
1204          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1205          DEALLOCATE( pavement_type_f%var )
1206          ALLOCATE( pavement_type_f%var(nysg:nyng,nxlg:nxrg) )
1207          pavement_type_f%var = INT( var_exchange_int, KIND = 1 )
1208       ENDIF
1209       IF ( soil_type_f%from_file  .AND.  ALLOCATED( soil_type_f%var_2d ) )  THEN
1210          var_exchange_int                  = INT( soil_type_f%fill, KIND = 1 )
1211          var_exchange_int(nys:nyn,nxl:nxr) =                                  &
1212                            INT( soil_type_f%var_2d(nys:nyn,nxl:nxr), KIND = 4 )
1213          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1214          DEALLOCATE( soil_type_f%var_2d )
1215          ALLOCATE( soil_type_f%var_2d(nysg:nyng,nxlg:nxrg) )
1216          soil_type_f%var_2d = INT( var_exchange_int, KIND = 1 )
1217       ENDIF
1218       IF ( vegetation_type_f%from_file )  THEN
1219          var_exchange_int                  = INT( vegetation_type_f%fill, KIND = 1 )
1220          var_exchange_int(nys:nyn,nxl:nxr) =                                  &
1221                        INT( vegetation_type_f%var(nys:nyn,nxl:nxr), KIND = 4 )
1222          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1223          DEALLOCATE( vegetation_type_f%var )
1224          ALLOCATE( vegetation_type_f%var(nysg:nyng,nxlg:nxrg) )
1225          vegetation_type_f%var = INT( var_exchange_int, KIND = 1 )
1226       ENDIF
1227       IF ( water_type_f%from_file )  THEN
1228          var_exchange_int                  = INT( water_type_f%fill, KIND = 1 )
1229          var_exchange_int(nys:nyn,nxl:nxr) =                                  &
1230                         INT( water_type_f%var(nys:nyn,nxl:nxr), KIND = 4 )
1231          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1232          DEALLOCATE( water_type_f%var )
1233          ALLOCATE( water_type_f%var(nysg:nyng,nxlg:nxrg) )
1234          water_type_f%var = INT( var_exchange_int, KIND = 1 )
1235       ENDIF
1236!
1237!--    Exchange 1 ghost point for 3/4-D variables. For the sake of simplicity,
1238!--    loop further dimensions to use 2D exchange routines.
1239!--    This should be revised later by introducing new MPI datatypes.
1240       IF ( soil_type_f%from_file  .AND.  ALLOCATED( soil_type_f%var_3d ) )    &
1241       THEN
1242          ALLOCATE( var_dum_int_3d(0:nz_soil,nys:nyn,nxl:nxr) ) 
1243          var_dum_int_3d = soil_type_f%var_3d
1244          DEALLOCATE( soil_type_f%var_3d )
1245          ALLOCATE( soil_type_f%var_3d(0:nz_soil,nysg:nyng,nxlg:nxrg) )
1246          soil_type_f%var_3d = soil_type_f%fill
1247
1248          DO  k = 0, nz_soil
1249             var_exchange_int(nys:nyn,nxl:nxr) = var_dum_int_3d(k,nys:nyn,nxl:nxr)
1250             CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1251             soil_type_f%var_3d(k,:,:) = INT( var_exchange_int(:,:), KIND = 1 )
1252          ENDDO
1253          DEALLOCATE( var_dum_int_3d )
1254       ENDIF
1255
1256       IF ( surface_fraction_f%from_file )  THEN
1257          ALLOCATE( var_dum_real_3d(0:surface_fraction_f%nf-1,nys:nyn,nxl:nxr) )
1258          var_dum_real_3d = surface_fraction_f%frac
1259          DEALLOCATE( surface_fraction_f%frac )
1260          ALLOCATE( surface_fraction_f%frac(0:surface_fraction_f%nf-1,         &
1261                                            nysg:nyng,nxlg:nxrg) )
1262          surface_fraction_f%frac = surface_fraction_f%fill
1263
1264          DO  k = 0, surface_fraction_f%nf-1
1265             var_exchange_real(nys:nyn,nxl:nxr) = var_dum_real_3d(k,nys:nyn,nxl:nxr)
1266             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1267             surface_fraction_f%frac(k,:,:) = var_exchange_real(:,:)
1268          ENDDO
1269          DEALLOCATE( var_dum_real_3d )
1270       ENDIF
1271
1272       IF ( building_pars_f%from_file )  THEN
1273          ALLOCATE( var_dum_real_3d(0:building_pars_f%np-1,nys:nyn,nxl:nxr) )
1274          var_dum_real_3d = building_pars_f%pars_xy
1275          DEALLOCATE( building_pars_f%pars_xy )
1276          ALLOCATE( building_pars_f%pars_xy(0:building_pars_f%np-1,            &
1277                                            nysg:nyng,nxlg:nxrg) )
1278          building_pars_f%pars_xy = building_pars_f%fill
1279          DO  k = 0, building_pars_f%np-1
1280             var_exchange_real(nys:nyn,nxl:nxr) =                              &
1281                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1282             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1283             building_pars_f%pars_xy(k,:,:) = var_exchange_real(:,:)
1284          ENDDO
1285          DEALLOCATE( var_dum_real_3d )
1286       ENDIF
1287
1288       IF ( albedo_pars_f%from_file )  THEN
1289          ALLOCATE( var_dum_real_3d(0:albedo_pars_f%np-1,nys:nyn,nxl:nxr) )
1290          var_dum_real_3d = albedo_pars_f%pars_xy
1291          DEALLOCATE( albedo_pars_f%pars_xy )
1292          ALLOCATE( albedo_pars_f%pars_xy(0:albedo_pars_f%np-1,                &
1293                                          nysg:nyng,nxlg:nxrg) )
1294          albedo_pars_f%pars_xy = albedo_pars_f%fill
1295          DO  k = 0, albedo_pars_f%np-1
1296             var_exchange_real(nys:nyn,nxl:nxr) =                              &
1297                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1298             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1299             albedo_pars_f%pars_xy(k,:,:) = var_exchange_real(:,:)
1300          ENDDO
1301          DEALLOCATE( var_dum_real_3d )
1302       ENDIF
1303
1304       IF ( pavement_pars_f%from_file )  THEN
1305          ALLOCATE( var_dum_real_3d(0:pavement_pars_f%np-1,nys:nyn,nxl:nxr) )
1306          var_dum_real_3d = pavement_pars_f%pars_xy
1307          DEALLOCATE( pavement_pars_f%pars_xy )
1308          ALLOCATE( pavement_pars_f%pars_xy(0:pavement_pars_f%np-1,            &
1309                                            nysg:nyng,nxlg:nxrg) )
1310          pavement_pars_f%pars_xy = pavement_pars_f%fill
1311          DO  k = 0, pavement_pars_f%np-1
1312             var_exchange_real(nys:nyn,nxl:nxr) =                              &
1313                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1314             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1315             pavement_pars_f%pars_xy(k,:,:) = var_exchange_real(:,:)
1316          ENDDO
1317          DEALLOCATE( var_dum_real_3d )
1318       ENDIF
1319
1320       IF ( vegetation_pars_f%from_file )  THEN
1321          ALLOCATE( var_dum_real_3d(0:vegetation_pars_f%np-1,nys:nyn,nxl:nxr) )
1322          var_dum_real_3d = vegetation_pars_f%pars_xy
1323          DEALLOCATE( vegetation_pars_f%pars_xy )
1324          ALLOCATE( vegetation_pars_f%pars_xy(0:vegetation_pars_f%np-1,        &
1325                                            nysg:nyng,nxlg:nxrg) )
1326          vegetation_pars_f%pars_xy = vegetation_pars_f%fill
1327          DO  k = 0, vegetation_pars_f%np-1
1328             var_exchange_real(nys:nyn,nxl:nxr) =                              &
1329                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1330             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1331             vegetation_pars_f%pars_xy(k,:,:) = var_exchange_real(:,:)
1332          ENDDO
1333          DEALLOCATE( var_dum_real_3d )
1334       ENDIF
1335
1336       IF ( water_pars_f%from_file )  THEN
1337          ALLOCATE( var_dum_real_3d(0:water_pars_f%np-1,nys:nyn,nxl:nxr) )
1338          var_dum_real_3d = water_pars_f%pars_xy
1339          DEALLOCATE( water_pars_f%pars_xy )
1340          ALLOCATE( water_pars_f%pars_xy(0:water_pars_f%np-1,                  &
1341                                         nysg:nyng,nxlg:nxrg) )
1342          water_pars_f%pars_xy = water_pars_f%fill
1343          DO  k = 0, water_pars_f%np-1
1344             var_exchange_real(nys:nyn,nxl:nxr) =                              &
1345                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1346             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1347             water_pars_f%pars_xy(k,:,:) = var_exchange_real(:,:)
1348          ENDDO
1349          DEALLOCATE( var_dum_real_3d )
1350       ENDIF
1351
1352       IF ( root_area_density_lsm_f%from_file )  THEN
1353          ALLOCATE( var_dum_real_3d(0:root_area_density_lsm_f%nz-1,nys:nyn,nxl:nxr) )
1354          var_dum_real_3d = root_area_density_lsm_f%var
1355          DEALLOCATE( root_area_density_lsm_f%var )
1356          ALLOCATE( root_area_density_lsm_f%var(0:root_area_density_lsm_f%nz-1,&
1357                                                nysg:nyng,nxlg:nxrg) )
1358          root_area_density_lsm_f%var = root_area_density_lsm_f%fill
1359
1360          DO  k = 0, root_area_density_lsm_f%nz-1
1361             var_exchange_real(nys:nyn,nxl:nxr) =                              &
1362                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1363             CALL exchange_horiz_2d( var_exchange_real, nbgp )
1364             root_area_density_lsm_f%var(k,:,:) = var_exchange_real(:,:)
1365          ENDDO
1366          DEALLOCATE( var_dum_real_3d )
1367       ENDIF
1368
1369       IF ( soil_pars_f%from_file )  THEN
1370          IF ( soil_pars_f%lod == 1 )  THEN
1371
1372             ALLOCATE( var_dum_real_3d(0:soil_pars_f%np-1,nys:nyn,nxl:nxr) )
1373             var_dum_real_3d = soil_pars_f%pars_xy
1374             DEALLOCATE( soil_pars_f%pars_xy )
1375             ALLOCATE( soil_pars_f%pars_xy(0:soil_pars_f%np-1,                 &
1376                                            nysg:nyng,nxlg:nxrg) )
1377             soil_pars_f%pars_xy = soil_pars_f%fill
1378
1379             DO  k = 0, soil_pars_f%np-1
1380                var_exchange_real(nys:nyn,nxl:nxr) =                           &
1381                                              var_dum_real_3d(k,nys:nyn,nxl:nxr)
1382                CALL exchange_horiz_2d( var_exchange_real, nbgp )
1383                soil_pars_f%pars_xy(k,:,:) = var_exchange_real(:,:)
1384             ENDDO
1385             DEALLOCATE( var_dum_real_3d )
1386          ELSEIF ( soil_pars_f%lod == 2 )  THEN
1387             ALLOCATE( var_dum_real_4d(0:soil_pars_f%np-1,                     &
1388                                       0:soil_pars_f%nz-1,                     &
1389                                       nys:nyn,nxl:nxr) )
1390             var_dum_real_4d = soil_pars_f%pars_xyz
1391             DEALLOCATE( soil_pars_f%pars_xyz )
1392             ALLOCATE( soil_pars_f%pars_xyz(0:soil_pars_f%np-1,                &
1393                                            0:soil_pars_f%nz-1,                &
1394                                            nysg:nyng,nxlg:nxrg) )
1395             soil_pars_f%pars_xyz = soil_pars_f%fill
1396
1397             DO  k2 = 0, soil_pars_f%nz-1
1398                DO  k = 0, soil_pars_f%np-1
1399                   var_exchange_real(nys:nyn,nxl:nxr) =                        &
1400                                           var_dum_real_4d(k,k2,nys:nyn,nxl:nxr)
1401                   CALL exchange_horiz_2d( var_exchange_real, nbgp )
1402
1403                   soil_pars_f%pars_xyz(k,k2,:,:) = var_exchange_real(:,:)
1404                ENDDO
1405             ENDDO
1406             DEALLOCATE( var_dum_real_4d )
1407          ENDIF
1408       ENDIF
1409
1410       IF ( pavement_subsurface_pars_f%from_file )  THEN
1411          ALLOCATE( var_dum_real_4d(0:pavement_subsurface_pars_f%np-1,         &
1412                                    0:pavement_subsurface_pars_f%nz-1,         &
1413                                    nys:nyn,nxl:nxr) )
1414          var_dum_real_4d = pavement_subsurface_pars_f%pars_xyz
1415          DEALLOCATE( pavement_subsurface_pars_f%pars_xyz )
1416          ALLOCATE( pavement_subsurface_pars_f%pars_xyz                        &
1417                                          (0:pavement_subsurface_pars_f%np-1,  &
1418                                           0:pavement_subsurface_pars_f%nz-1,  &
1419                                           nysg:nyng,nxlg:nxrg) )
1420          pavement_subsurface_pars_f%pars_xyz = pavement_subsurface_pars_f%fill
1421
1422          DO  k2 = 0, pavement_subsurface_pars_f%nz-1
1423             DO  k = 0, pavement_subsurface_pars_f%np-1
1424                var_exchange_real(nys:nyn,nxl:nxr) =                           &
1425                                          var_dum_real_4d(k,k2,nys:nyn,nxl:nxr)
1426                CALL exchange_horiz_2d( var_exchange_real, nbgp )
1427                pavement_subsurface_pars_f%pars_xyz(k,k2,:,:) =                &
1428                                                        var_exchange_real(:,:)
1429             ENDDO
1430          ENDDO
1431          DEALLOCATE( var_dum_real_4d )
1432       ENDIF
1433
1434!
1435!--    In case of non-cyclic boundary conditions, set Neumann conditions at the
1436!--    lateral boundaries.
1437       IF ( .NOT. bc_ns_cyc )  THEN
1438          IF ( nys == 0  )  THEN
1439             IF ( albedo_type_f%from_file )                                    &
1440                albedo_type_f%var(-1,:) = albedo_type_f%var(0,:)
1441             IF ( pavement_type_f%from_file )                                  &
1442                pavement_type_f%var(-1,:) = pavement_type_f%var(0,:)
1443             IF ( soil_type_f%from_file )  THEN
1444                IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
1445                   soil_type_f%var_2d(-1,:) = soil_type_f%var_2d(0,:)
1446                ELSE
1447                   soil_type_f%var_3d(:,-1,:) = soil_type_f%var_3d(:,0,:)
1448                ENDIF
1449             ENDIF
1450             IF ( vegetation_type_f%from_file )                                &
1451                vegetation_type_f%var(-1,:) = vegetation_type_f%var(0,:)
1452             IF ( water_type_f%from_file )                                     &
1453                water_type_f%var(-1,:) = water_type_f%var(0,:)
1454             IF ( surface_fraction_f%from_file )                               &
1455                surface_fraction_f%frac(:,-1,:) = surface_fraction_f%frac(:,0,:)
1456             IF ( building_pars_f%from_file )                                  &
1457                building_pars_f%pars_xy(:,-1,:) = building_pars_f%pars_xy(:,0,:)
1458             IF ( albedo_pars_f%from_file )                                    &
1459                albedo_pars_f%pars_xy(:,-1,:) = albedo_pars_f%pars_xy(:,0,:)
1460             IF ( pavement_pars_f%from_file )                                  &
1461                pavement_pars_f%pars_xy(:,-1,:) = pavement_pars_f%pars_xy(:,0,:)
1462             IF ( vegetation_pars_f%from_file )                                &
1463                vegetation_pars_f%pars_xy(:,-1,:) =                            &
1464                                               vegetation_pars_f%pars_xy(:,0,:)
1465             IF ( water_pars_f%from_file )                                     &
1466                water_pars_f%pars_xy(:,-1,:) = water_pars_f%pars_xy(:,0,:)
1467             IF ( root_area_density_lsm_f%from_file )                          &
1468                root_area_density_lsm_f%var(:,-1,:) =                          &
1469                                            root_area_density_lsm_f%var(:,0,:)
1470             IF ( soil_pars_f%from_file )  THEN
1471                IF ( soil_pars_f%lod == 1 )  THEN
1472                   soil_pars_f%pars_xy(:,-1,:) = soil_pars_f%pars_xy(:,0,:)
1473                ELSE
1474                   soil_pars_f%pars_xyz(:,:,-1,:) = soil_pars_f%pars_xyz(:,:,0,:)
1475                ENDIF
1476             ENDIF
1477             IF ( pavement_subsurface_pars_f%from_file )                       &
1478                pavement_subsurface_pars_f%pars_xyz(:,:,-1,:) =                &
1479                                   pavement_subsurface_pars_f%pars_xyz(:,:,0,:)
1480          ENDIF
1481
1482          IF ( nyn == ny )  THEN
1483             IF ( albedo_type_f%from_file )                                    &
1484                albedo_type_f%var(ny+1,:) = albedo_type_f%var(ny,:)
1485             IF ( pavement_type_f%from_file )                                  &
1486                pavement_type_f%var(ny+1,:) = pavement_type_f%var(ny,:)
1487             IF ( soil_type_f%from_file )  THEN
1488                IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
1489                   soil_type_f%var_2d(ny+1,:) = soil_type_f%var_2d(ny,:)
1490                ELSE
1491                   soil_type_f%var_3d(:,ny+1,:) = soil_type_f%var_3d(:,ny,:)
1492                ENDIF
1493             ENDIF
1494             IF ( vegetation_type_f%from_file )                                &
1495                vegetation_type_f%var(ny+1,:) = vegetation_type_f%var(ny,:)
1496             IF ( water_type_f%from_file )                                     &
1497                water_type_f%var(ny+1,:) = water_type_f%var(ny,:)
1498             IF ( surface_fraction_f%from_file )                               &
1499                surface_fraction_f%frac(:,ny+1,:) =                            &
1500                                             surface_fraction_f%frac(:,ny,:)
1501             IF ( building_pars_f%from_file )                                  &
1502                building_pars_f%pars_xy(:,ny+1,:) =                            &
1503                                             building_pars_f%pars_xy(:,ny,:)
1504             IF ( albedo_pars_f%from_file )                                    &
1505                albedo_pars_f%pars_xy(:,ny+1,:) = albedo_pars_f%pars_xy(:,ny,:)
1506             IF ( pavement_pars_f%from_file )                                  &
1507                pavement_pars_f%pars_xy(:,ny+1,:) =                            &
1508                                             pavement_pars_f%pars_xy(:,ny,:)
1509             IF ( vegetation_pars_f%from_file )                                &
1510                vegetation_pars_f%pars_xy(:,ny+1,:) =                          &
1511                                               vegetation_pars_f%pars_xy(:,ny,:)
1512             IF ( water_pars_f%from_file )                                     &
1513                water_pars_f%pars_xy(:,ny+1,:) = water_pars_f%pars_xy(:,ny,:)
1514             IF ( root_area_density_lsm_f%from_file )                          &
1515                root_area_density_lsm_f%var(:,ny+1,:) =                        &
1516                                            root_area_density_lsm_f%var(:,ny,:)
1517             IF ( soil_pars_f%from_file )  THEN
1518                IF ( soil_pars_f%lod == 1 )  THEN
1519                   soil_pars_f%pars_xy(:,ny+1,:) = soil_pars_f%pars_xy(:,ny,:)
1520                ELSE
1521                   soil_pars_f%pars_xyz(:,:,ny+1,:) =                          &
1522                                              soil_pars_f%pars_xyz(:,:,ny,:)
1523                ENDIF
1524             ENDIF
1525             IF ( pavement_subsurface_pars_f%from_file )                       &
1526                pavement_subsurface_pars_f%pars_xyz(:,:,ny+1,:) =              &
1527                                   pavement_subsurface_pars_f%pars_xyz(:,:,ny,:)
1528          ENDIF
1529       ENDIF
1530
1531       IF ( .NOT. bc_lr_cyc )  THEN
1532          IF ( nxl == 0 )  THEN
1533            IF ( albedo_type_f%from_file )                                     &
1534                albedo_type_f%var(:,-1) = albedo_type_f%var(:,0)
1535             IF ( pavement_type_f%from_file )                                  &
1536                pavement_type_f%var(:,-1) = pavement_type_f%var(:,0)
1537             IF ( soil_type_f%from_file )  THEN
1538                IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
1539                   soil_type_f%var_2d(:,-1) = soil_type_f%var_2d(:,0)
1540                ELSE
1541                   soil_type_f%var_3d(:,:,-1) = soil_type_f%var_3d(:,:,0)
1542                ENDIF
1543             ENDIF
1544             IF ( vegetation_type_f%from_file )                                &
1545                vegetation_type_f%var(:,-1) = vegetation_type_f%var(:,0)
1546             IF ( water_type_f%from_file )                                     &
1547                water_type_f%var(:,-1) = water_type_f%var(:,0)
1548             IF ( surface_fraction_f%from_file )                               &
1549                surface_fraction_f%frac(:,:,-1) = surface_fraction_f%frac(:,:,0)
1550             IF ( building_pars_f%from_file )                                  &
1551                building_pars_f%pars_xy(:,:,-1) = building_pars_f%pars_xy(:,:,0)
1552             IF ( albedo_pars_f%from_file )                                    &
1553                albedo_pars_f%pars_xy(:,:,-1) = albedo_pars_f%pars_xy(:,:,0)
1554             IF ( pavement_pars_f%from_file )                                  &
1555                pavement_pars_f%pars_xy(:,:,-1) = pavement_pars_f%pars_xy(:,:,0)
1556             IF ( vegetation_pars_f%from_file )                                &
1557                vegetation_pars_f%pars_xy(:,:,-1) =                            &
1558                                               vegetation_pars_f%pars_xy(:,:,0)
1559             IF ( water_pars_f%from_file )                                     &
1560                water_pars_f%pars_xy(:,:,-1) = water_pars_f%pars_xy(:,:,0)
1561             IF ( root_area_density_lsm_f%from_file )                          &
1562                root_area_density_lsm_f%var(:,:,-1) =                          &
1563                                            root_area_density_lsm_f%var(:,:,0)
1564             IF ( soil_pars_f%from_file )  THEN
1565                IF ( soil_pars_f%lod == 1 )  THEN
1566                   soil_pars_f%pars_xy(:,:,-1) = soil_pars_f%pars_xy(:,:,0)
1567                ELSE
1568                   soil_pars_f%pars_xyz(:,:,:,-1) = soil_pars_f%pars_xyz(:,:,:,0)
1569                ENDIF
1570             ENDIF
1571             IF ( pavement_subsurface_pars_f%from_file )                       &
1572                pavement_subsurface_pars_f%pars_xyz(:,:,:,-1) =                &
1573                                    pavement_subsurface_pars_f%pars_xyz(:,:,:,0)
1574          ENDIF
1575
1576          IF ( nxr == nx )  THEN
1577             IF ( albedo_type_f%from_file )                                    &
1578                albedo_type_f%var(:,nx+1) = albedo_type_f%var(:,nx)
1579             IF ( pavement_type_f%from_file )                                  &
1580                pavement_type_f%var(:,nx+1) = pavement_type_f%var(:,nx)
1581             IF ( soil_type_f%from_file )  THEN
1582                IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
1583                   soil_type_f%var_2d(:,nx+1) = soil_type_f%var_2d(:,nx)
1584                ELSE
1585                   soil_type_f%var_3d(:,:,nx+1) = soil_type_f%var_3d(:,:,nx)
1586                ENDIF
1587             ENDIF
1588             IF ( vegetation_type_f%from_file )                                &
1589                vegetation_type_f%var(:,nx+1) = vegetation_type_f%var(:,nx)
1590             IF ( water_type_f%from_file )                                     &
1591                water_type_f%var(:,nx+1) = water_type_f%var(:,nx)
1592             IF ( surface_fraction_f%from_file )                               &
1593                surface_fraction_f%frac(:,:,nx+1) =                            &
1594                                             surface_fraction_f%frac(:,:,nx)
1595             IF ( building_pars_f%from_file )                                  &
1596                building_pars_f%pars_xy(:,:,nx+1) =                            &
1597                                             building_pars_f%pars_xy(:,:,nx)
1598             IF ( albedo_pars_f%from_file )                                    &
1599                albedo_pars_f%pars_xy(:,:,nx+1) = albedo_pars_f%pars_xy(:,:,nx)
1600             IF ( pavement_pars_f%from_file )                                  &
1601                pavement_pars_f%pars_xy(:,:,nx+1) =                            &
1602                                             pavement_pars_f%pars_xy(:,:,nx)
1603             IF ( vegetation_pars_f%from_file )                                &
1604                vegetation_pars_f%pars_xy(:,:,nx+1) =                          &
1605                                               vegetation_pars_f%pars_xy(:,:,nx)
1606             IF ( water_pars_f%from_file )                                     &
1607                water_pars_f%pars_xy(:,:,nx+1) = water_pars_f%pars_xy(:,:,nx)
1608             IF ( root_area_density_lsm_f%from_file )                          &
1609                root_area_density_lsm_f%var(:,:,nx+1) =                        &
1610                                            root_area_density_lsm_f%var(:,:,nx)
1611             IF ( soil_pars_f%from_file )  THEN
1612                IF ( soil_pars_f%lod == 1 )  THEN
1613                   soil_pars_f%pars_xy(:,:,nx+1) = soil_pars_f%pars_xy(:,:,nx)
1614                ELSE
1615                   soil_pars_f%pars_xyz(:,:,:,nx+1) =                          &
1616                                              soil_pars_f%pars_xyz(:,:,:,nx)
1617                ENDIF
1618             ENDIF
1619             IF ( pavement_subsurface_pars_f%from_file )                       &
1620                pavement_subsurface_pars_f%pars_xyz(:,:,:,nx+1) =              &
1621                                   pavement_subsurface_pars_f%pars_xyz(:,:,:,nx)
1622          ENDIF
1623       ENDIF
1624
1625    END SUBROUTINE netcdf_data_input_surface_data
1626
1627!------------------------------------------------------------------------------!
1628! Description:
1629! ------------
1630!> Reads orography and building information.
1631!------------------------------------------------------------------------------!
1632    SUBROUTINE netcdf_data_input_topo
1633
1634       USE control_parameters,                                                 &
1635           ONLY:  bc_lr_cyc, bc_ns_cyc, message_string, topography
1636
1637       USE indices,                                                            &
1638           ONLY:  nbgp, nx, nxl, nxr, ny, nyn, nys, nzb, nzt
1639                 
1640
1641       IMPLICIT NONE
1642
1643       CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE ::  var_names  !< variable names in static input file
1644
1645
1646       INTEGER(iwp) ::  i             !< running index along x-direction
1647       INTEGER(iwp) ::  ii            !< running index for IO blocks
1648       INTEGER(iwp) ::  id_topo       !< NetCDF id of topograhy input file
1649       INTEGER(iwp) ::  j             !< running index along y-direction
1650       INTEGER(iwp) ::  k             !< running index along z-direction
1651       INTEGER(iwp) ::  num_vars      !< number of variables in netcdf input file
1652       INTEGER(iwp) ::  skip_n_rows   !< counting variable to skip rows while reading topography file
1653
1654       INTEGER(iwp), DIMENSION(nys-nbgp:nyn+nbgp,nxl-nbgp:nxr+nbgp) ::  var_exchange_int !< dummy variables used to exchange 32-bit Integer arrays
1655
1656       REAL(wp) ::  dum           !< dummy variable to skip columns while reading topography file   
1657
1658       IF ( TRIM( topography ) /= 'read_from_file' )  RETURN
1659
1660       DO  ii = 0, io_blocks-1
1661          IF ( ii == io_group )  THEN
1662!
1663!--          Input via palm-input data standard
1664             IF ( input_pids_static )  THEN
1665#if defined ( __netcdf )
1666!
1667!--             Open file in read-only mode
1668                CALL open_read_file( TRIM( input_file_static ) //              &
1669                                     TRIM( coupling_char ), id_topo ) 
1670
1671!
1672!--             At first, inquire all variable names.
1673!--             This will be used to check whether an  input variable exist
1674!--             or not.
1675                CALL inquire_num_variables( id_topo, num_vars )
1676!
1677!--             Allocate memory to store variable names and inquire them.
1678                ALLOCATE( var_names(1:num_vars) )
1679                CALL inquire_variable_names( id_topo, var_names )
1680!
1681!--             Read x, y - dimensions
1682                CALL get_dimension_length( id_topo, dim_static%nx, 'x' )
1683                CALL get_dimension_length( id_topo, dim_static%ny, 'y' )
1684                ALLOCATE( dim_static%x(0:dim_static%nx-1) )
1685                ALLOCATE( dim_static%y(0:dim_static%ny-1) )
1686                CALL get_variable( id_topo, 'x', dim_static%x )
1687                CALL get_variable( id_topo, 'y', dim_static%y )
1688!
1689!--             Terrain height. First, get variable-related _FillValue attribute
1690                IF ( check_existence( var_names, 'orography_2D' ) )  THEN
1691                   terrain_height_f%from_file = .TRUE. 
1692                   CALL get_attribute( id_topo, char_fill,                     &
1693                                       terrain_height_f%fill,                  &
1694                                       .FALSE., 'orography_2D' ) 
1695!
1696!--                PE-wise reading of 2D terrain height.
1697                   ALLOCATE ( terrain_height_f%var(nys:nyn,nxl:nxr)  )
1698                   DO  i = nxl, nxr
1699                      CALL get_variable( id_topo, 'orography_2D',              &
1700                                         i, terrain_height_f%var(:,i) ) 
1701                   ENDDO
1702                ELSE
1703                   terrain_height_f%from_file = .FALSE. 
1704                ENDIF
1705
1706!
1707!--             Read building height. First, read its _FillValue attribute,
1708!--             as well as lod attribute
1709                buildings_f%from_file = .FALSE. 
1710                IF ( check_existence( var_names, 'buildings_2D' ) )  THEN
1711                   buildings_f%from_file = .TRUE. 
1712                   CALL get_attribute( id_topo, char_lod, buildings_f%lod,     &
1713                                       .FALSE., 'buildings_2D' )     
1714
1715                   CALL get_attribute( id_topo, char_fill,                     &
1716                                       buildings_f%fill1,                      &
1717                                       .FALSE., 'buildings_2D' )
1718
1719!
1720!--                Read 2D topography
1721                   IF ( buildings_f%lod == 1 )  THEN
1722                      ALLOCATE ( buildings_f%var_2d(nys:nyn,nxl:nxr) )
1723                      DO  i = nxl, nxr
1724                         CALL get_variable( id_topo, 'buildings_2D',           &
1725                                            i, buildings_f%var_2d(:,i) ) 
1726                      ENDDO
1727                   ELSE
1728                      message_string = 'NetCDF attribute lod ' //              &
1729                                       '(level of detail) is not set ' //      &
1730                                       'properly for buildings_2D.'
1731                      CALL message( 'netcdf_data_input_mod', 'NDI000',         &
1732                                     1, 2, 0, 6, 0 )
1733                   ENDIF
1734                ENDIF
1735!
1736!--             If available, also read 3D building information. If both are
1737!--             available, use 3D information.
1738                IF ( check_existence( var_names, 'buildings_3D' ) )  THEN
1739                   buildings_f%from_file = .TRUE. 
1740                   CALL get_attribute( id_topo, char_lod, buildings_f%lod,     &
1741                                       .FALSE., 'buildings_3D' )     
1742
1743                   CALL get_attribute( id_topo, char_fill,                     &
1744                                       buildings_f%fill2,                      &
1745                                       .FALSE., 'buildings_3D' )
1746
1747                   CALL get_dimension_length( id_topo, buildings_f%nz, 'z' )
1748 
1749                   IF ( buildings_f%lod == 2 )  THEN
1750                      ALLOCATE( buildings_f%z(nzb:buildings_f%nz-1) )
1751                      CALL get_variable( id_topo, 'z', buildings_f%z )
1752
1753                      ALLOCATE( buildings_f%var_3d(nzb:buildings_f%nz-1,       &
1754                                                   nys:nyn,nxl:nxr) )
1755                      buildings_f%var_3d = 0
1756!
1757!--                   Read data PE-wise. Read yz-slices.
1758                      DO  i = nxl, nxr
1759                         DO  j = nys, nyn
1760                            CALL get_variable( id_topo, 'buildings_3D',        &
1761                                               i, j,                           &
1762                                               buildings_f%var_3d(:,j,i) )
1763                         ENDDO
1764                      ENDDO
1765                   ELSE
1766                      message_string = 'NetCDF attribute lod ' //              &
1767                                       '(level of detail) is not set ' //      &
1768                                       'properly for buildings_3D.'
1769                      CALL message( 'netcdf_data_input_mod', 'NDI001',         &
1770                                     1, 2, 0, 6, 0 )
1771                   ENDIF
1772                ENDIF
1773!
1774!--             Read building IDs and its FillValue attribute. Further required
1775!--             for mapping buildings on top of orography.
1776                IF ( check_existence( var_names, 'building_id' ) )  THEN
1777                   building_id_f%from_file = .TRUE. 
1778                   CALL get_attribute( id_topo, char_fill,                     &
1779                                       building_id_f%fill, .FALSE.,            &
1780                                       'building_id' )
1781             
1782
1783                   ALLOCATE ( building_id_f%var(nys:nyn,nxl:nxr) )
1784                   DO  i = nxl, nxr
1785                      CALL get_variable( id_topo, 'building_id',               &
1786                                          i, building_id_f%var(:,i) ) 
1787                   ENDDO
1788                ELSE
1789                   building_id_f%from_file = .FALSE. 
1790                ENDIF
1791!
1792!--             Read building_type and required attributes.
1793                IF ( check_existence( var_names, 'building_type' ) )  THEN
1794                   building_type_f%from_file = .TRUE. 
1795                   CALL get_attribute( id_topo, char_fill,                     &
1796                                       building_type_f%fill, .FALSE.,          &
1797                                       'building_type' ) 
1798               
1799                   ALLOCATE ( building_type_f%var(nys:nyn,nxl:nxr) )
1800                   DO  i = nxl, nxr
1801                      CALL get_variable( id_topo, 'building_type',             &
1802                                         i, building_type_f%var(:,i) )
1803                   ENDDO
1804                ELSE
1805                   building_type_f%from_file = .FALSE.
1806                ENDIF
1807
1808!
1809!--             Close topography input file
1810                CALL close_input_file( id_topo )
1811#else
1812                CONTINUE
1813#endif
1814!
1815!--          ASCII input
1816             ELSE
1817
1818                OPEN( 90, FILE='TOPOGRAPHY_DATA'//TRIM( coupling_char ),       &
1819                      STATUS='OLD', FORM='FORMATTED', ERR=10 )
1820!
1821!--             Read topography PE-wise. Rows are read from nyn to nys, columns
1822!--             are read from nxl to nxr. At first, ny-nyn rows need to be skipped.
1823                skip_n_rows = 0
1824                DO WHILE ( skip_n_rows < ny - nyn )
1825                   READ( 90, * ) 
1826                   skip_n_rows = skip_n_rows + 1
1827                ENDDO
1828!
1829!--             Read data from nyn to nys and nxl to nxr. Therefore, skip
1830!--             column until nxl-1 is reached
1831                ALLOCATE ( buildings_f%var_2d(nys:nyn,nxl:nxr) )
1832                DO  j = nyn, nys, -1
1833                   READ( 90, *, ERR=11, END=11 )                               &
1834                                   ( dum, i = 0, nxl-1 ),                      &
1835                                   ( buildings_f%var_2d(j,i), i = nxl, nxr )
1836                ENDDO
1837
1838                GOTO 12
1839         
1840 10             message_string = 'file TOPOGRAPHY'//TRIM( coupling_char )//    &
1841                                 ' does not exist'
1842                CALL message( 'netcdf_data_input_mod', 'PA0208', 1, 2, 0, 6, 0 )
1843
1844 11             message_string = 'errors in file TOPOGRAPHY_DATA'//            &
1845                                 TRIM( coupling_char )
1846                CALL message( 'netcdf_data_input_mod', 'PA0209', 1, 2, 0, 6, 0 )
1847
1848 12             CLOSE( 90 )
1849                buildings_f%from_file = .TRUE.
1850
1851             ENDIF
1852
1853          ENDIF
1854#if defined( __parallel )
1855          CALL MPI_BARRIER( comm2d, ierr )
1856#endif
1857       ENDDO
1858!
1859!--    Check for minimum requirement to setup building topography. If buildings
1860!--    are provided, also an ID and a type are required.
1861!--    Note, doing this check in check_parameters
1862!--    will be too late (data will be used for grid inititialization before).
1863       IF ( input_pids_static )  THEN
1864          IF ( buildings_f%from_file  .AND.                                    &
1865               .NOT. building_id_f%from_file )  THEN                       
1866             message_string = 'If building heigths are prescribed in ' //      &
1867                              'static input file, also an ID is required.'
1868             CALL message( 'netcdf_data_input_mod', 'NDI002', 1, 2, 0, 6, 0 )
1869          ENDIF
1870       ENDIF
1871!
1872!--    In case no terrain height is provided by static input file, allocate
1873!--    array nevertheless and set terrain height to 0, which simplifies
1874!--    topography initialization.
1875       IF ( .NOT. terrain_height_f%from_file )  THEN
1876          ALLOCATE ( terrain_height_f%var(nys:nyn,nxl:nxr) )
1877          terrain_height_f%var = 0.0_wp
1878       ENDIF
1879!
1880!--    Finally, exchange 1 ghost point for building ID and type.
1881!--    In case of non-cyclic boundary conditions set Neumann conditions at the
1882!--    lateral boundaries.
1883       IF ( building_id_f%from_file )  THEN
1884          var_exchange_int                  = building_id_f%fill
1885          var_exchange_int(nys:nyn,nxl:nxr) = building_id_f%var(nys:nyn,nxl:nxr)
1886          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1887          DEALLOCATE( building_id_f%var )
1888          ALLOCATE( building_id_f%var(nys-nbgp:nyn+nbgp,nxl-nbgp:nxr+nbgp) )
1889          building_id_f%var = var_exchange_int
1890
1891          IF ( .NOT. bc_ns_cyc )  THEN
1892             IF ( nys == 0  )  building_id_f%var(-1,:)   = building_id_f%var(0,:)
1893             IF ( nyn == ny )  building_id_f%var(ny+1,:) = building_id_f%var(ny,:)
1894          ENDIF
1895          IF ( .NOT. bc_lr_cyc )  THEN
1896             IF ( nxl == 0  )  building_id_f%var(:,-1)   = building_id_f%var(:,0) 
1897             IF ( nxr == nx )  building_id_f%var(:,nx+1) = building_id_f%var(:,nx)       
1898          ENDIF
1899       ENDIF
1900
1901       IF ( building_type_f%from_file )  THEN
1902          var_exchange_int                  = INT( building_type_f%fill, KIND = 4 )
1903          var_exchange_int(nys:nyn,nxl:nxr) =                                  &
1904                          INT( building_type_f%var(nys:nyn,nxl:nxr), KIND = 4 )
1905          CALL exchange_horiz_2d_int( var_exchange_int, nys, nyn, nxl, nxr, nbgp )
1906          DEALLOCATE( building_type_f%var )
1907          ALLOCATE( building_type_f%var(nys-nbgp:nyn+nbgp,nxl-nbgp:nxr+nbgp) )
1908          building_type_f%var = INT( var_exchange_int, KIND = 1 )
1909
1910          IF ( .NOT. bc_ns_cyc )  THEN
1911             IF ( nys == 0  )  building_type_f%var(-1,:)   = building_type_f%var(0,:)
1912             IF ( nyn == ny )  building_type_f%var(ny+1,:) = building_type_f%var(ny,:)
1913          ENDIF
1914          IF ( .NOT. bc_lr_cyc )  THEN
1915             IF ( nxl == 0  )  building_type_f%var(:,-1)   = building_type_f%var(:,0) 
1916             IF ( nxr == nx )  building_type_f%var(:,nx+1) = building_type_f%var(:,nx)       
1917          ENDIF
1918       ENDIF
1919
1920    END SUBROUTINE netcdf_data_input_topo
1921
1922!------------------------------------------------------------------------------!
1923! Description:
1924! ------------
1925!> Reads initialization data of u, v, w, pt, q, geostrophic wind components,
1926!> as well as soil moisture and soil temperature, derived from larger-scale
1927!> model (COSMO) by Inifor.
1928!------------------------------------------------------------------------------!
1929    SUBROUTINE netcdf_data_input_init_3d
1930
1931       USE arrays_3d,                                                          &
1932           ONLY:  q, pt, u, v, w
1933
1934       USE control_parameters,                                                 &
1935           ONLY:  bc_lr_cyc, bc_ns_cyc, forcing, humidity, land_surface,       &
1936                  message_string, neutral, surface_pressure
1937
1938       USE indices,                                                            &
1939           ONLY:  nx, nxl, nxlu, nxr, ny, nyn, nys, nysv, nzb, nzt
1940
1941       IMPLICIT NONE
1942
1943       CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE ::  var_names
1944
1945       INTEGER(iwp) ::  i          !< running index along x-direction
1946       INTEGER(iwp) ::  ii         !< running index for IO blocks
1947       INTEGER(iwp) ::  id_dynamic !< NetCDF id of dynamic input file
1948       INTEGER(iwp) ::  j          !< running index along y-direction
1949       INTEGER(iwp) ::  k          !< running index along z-direction
1950       INTEGER(iwp) ::  num_vars   !< number of variables in netcdf input file
1951       INTEGER(iwp) ::  off_i      !< offset in x-direction used for reading the u-component
1952       INTEGER(iwp) ::  off_j      !< offset in y-direction used for reading the v-component
1953
1954!
1955!--    Skip routine if no input file with dynamic input data is available.
1956       IF ( .NOT. input_pids_dynamic )  RETURN
1957!
1958!--    Please note, Inifor is designed to provide initial data for u and v for
1959!--    the prognostic grid points in case of lateral Dirichlet conditions.
1960!--    This means that Inifor provides data from nxlu:nxr (for u) and
1961!--    from nysv:nyn (for v) at the left and south domain boundary, respectively.
1962!--    However, as work-around for the moment, PALM will run with cyclic
1963!--    conditions and will be initialized with data provided by Inifor
1964!--    boundaries in case of Dirichlet.
1965!--    Hence, simply set set nxlu/nysv to 1 (will be reset to its original value
1966!--    at the end of this routine.
1967       IF ( bc_lr_cyc  .AND.  nxl == 0 )  nxlu = 1 
1968       IF ( bc_ns_cyc  .AND.  nys == 0 )  nysv = 1
1969
1970       DO  ii = 0, io_blocks-1
1971          IF ( ii == io_group )  THEN
1972#if defined ( __netcdf )
1973!
1974!--          Open file in read-only mode
1975             CALL open_read_file( TRIM( input_file_dynamic ) //                &
1976                                  TRIM( coupling_char ), id_dynamic ) 
1977
1978!
1979!--          At first, inquire all variable names.
1980             CALL inquire_num_variables( id_dynamic, num_vars )
1981!
1982!--          Allocate memory to store variable names.
1983             ALLOCATE( var_names(1:num_vars) )
1984             CALL inquire_variable_names( id_dynamic, var_names )
1985!
1986!--          Read vertical dimension of scalar und w grid. Will be used for
1987!--          inter- and extrapolation in case of stretched numeric grid.
1988!--          This will be removed when Inifor is able to handle stretched grids.
1989             CALL get_dimension_length( id_dynamic, init_3d%nzu, 'z'     )
1990             CALL get_dimension_length( id_dynamic, init_3d%nzw, 'zw'    )
1991             CALL get_dimension_length( id_dynamic, init_3d%nzs, 'depth' )
1992!
1993!--          Read also the horizontal dimensions. These are used just used fo
1994!--          checking the compatibility with the PALM grid before reading.
1995             CALL get_dimension_length( id_dynamic, init_3d%nx,  'x'  )
1996             CALL get_dimension_length( id_dynamic, init_3d%nxu, 'xu' )
1997             CALL get_dimension_length( id_dynamic, init_3d%ny,  'y'  )
1998             CALL get_dimension_length( id_dynamic, init_3d%nyv, 'yv' )
1999!
2000!--          Check for correct horizontal dimension. Please note, u- and v-grid
2001!--          hase 1 grid point less on Inifor grid.
2002             IF ( init_3d%nx-1 /= nx  .OR.  init_3d%nxu-1 /= nx - 1  .OR.      &
2003                  init_3d%ny-1 /= ny  .OR.  init_3d%nyv-1 /= ny - 1 )  THEN
2004                message_string = 'Number of inifor grid points does not '  //  &
2005                                 'match the number of numeric grid points.'
2006                CALL message( 'netcdf_data_input_mod', 'NDI003', 1, 2, 0, 6, 0 )
2007             ENDIF
2008!
2009!--          Read vertical dimensions. Later, these are required for eventual
2010!--          inter- and extrapolations of the initialization data.
2011             IF ( check_existence( var_names, 'z' ) )  THEN
2012                ALLOCATE( init_3d%zu_atmos(1:init_3d%nzu) )
2013                CALL get_variable( id_dynamic, 'z', init_3d%zu_atmos )
2014             ENDIF
2015             IF ( check_existence( var_names, 'zw' ) )  THEN
2016                ALLOCATE( init_3d%zw_atmos(1:init_3d%nzw) )
2017                CALL get_variable( id_dynamic, 'zw', init_3d%zw_atmos )
2018             ENDIF
2019             IF ( check_existence( var_names, 'depth' ) )  THEN
2020                ALLOCATE( init_3d%z_soil(1:init_3d%nzs) )
2021                CALL get_variable( id_dynamic, 'depth', init_3d%z_soil )
2022             ENDIF
2023!
2024!--          Read geostrophic wind components
2025!              IF ( check_existence( var_names, 'ls_forcing_ug' ) )  THEN
2026!
2027!              ENDIF
2028!              IF ( check_existence( var_names, 'ls_forcing_vg' ) )  THEN
2029!
2030!              ENDIF
2031
2032!
2033!--          Read inital 3D data of u, v, w, pt and q,
2034!--          derived from COSMO model. Read PE-wise yz-slices.
2035!--          Please note, the u-, v- and w-component are defined on different
2036!--          grids with one element less in the x-, y-,
2037!--          and z-direction, respectively. Hence, reading is subdivided
2038!--          into separate loops. Moreover, i and j are used
2039!--          as start index in the NF90 interface.
2040!--          The passed arguments for u, and v are (i,j)-1, respectively,
2041!--          in contrast to the remaining quantities. This is because in case
2042!--          of forcing is applied, the input data for u and v has one
2043!--          element less along the x- and y-direction respectively.
2044!--          Read u-component
2045             IF ( check_existence( var_names, 'init_u' ) )  THEN
2046!
2047!--             Read attributes for the fill value and level-of-detail
2048                CALL get_attribute( id_dynamic, char_fill, init_3d%fill_u,     &
2049                                    .FALSE., 'init_u' )
2050                CALL get_attribute( id_dynamic, char_lod, init_3d%lod_u,       &
2051                                    .FALSE., 'init_u' )
2052!
2053!--             level-of-detail 1 - read initialization profile
2054                IF ( init_3d%lod_u == 1 )  THEN
2055                   ALLOCATE( init_3d%u_init(nzb:nzt+1) )
2056                   init_3d%u_init = 0.0_wp
2057
2058                   CALL get_variable( id_dynamic, 'init_u',                    &
2059                                      init_3d%u_init(nzb+1:nzt+1) )
2060!
2061!--             level-of-detail 2 - read 3D initialization data
2062                ELSEIF ( init_3d%lod_u == 2 )  THEN
2063!
2064!--                Set offset value. In case of Dirichlet conditions at the left
2065!--                domain boundary, the u component starts at nxl+1. This case,
2066!--                the passed start-index for reading the NetCDF data is shifted
2067!--                by -1. 
2068                   off_i = 1 !MERGE( 1, 0, forcing )
2069
2070                   DO  i = nxlu, nxr
2071                      DO  j = nys, nyn   
2072                         CALL get_variable( id_dynamic, 'init_u', i-off_i, j,  &
2073                                            u(nzb+1:nzt+1,j,i) )
2074                      ENDDO
2075                   ENDDO
2076
2077                ENDIF
2078                init_3d%from_file_u = .TRUE.
2079             ENDIF
2080!
2081!--          Read v-component
2082             IF ( check_existence( var_names, 'init_v' ) )  THEN
2083!
2084!--             Read attributes for the fill value and level-of-detail
2085                CALL get_attribute( id_dynamic, char_fill, init_3d%fill_v,     &
2086                                    .FALSE., 'init_v' )
2087                CALL get_attribute( id_dynamic, char_lod, init_3d%lod_v,       &
2088                                    .FALSE., 'init_v' )
2089!
2090!--             level-of-detail 1 - read initialization profile
2091                IF ( init_3d%lod_v == 1 )  THEN
2092                   ALLOCATE( init_3d%v_init(nzb:nzt+1) )
2093                   init_3d%v_init = 0.0_wp
2094
2095                   CALL get_variable( id_dynamic, 'init_v',                    &
2096                                      init_3d%v_init(nzb+1:nzt+1) )
2097
2098!
2099!--             level-of-detail 2 - read 3D initialization data
2100                ELSEIF ( init_3d%lod_v == 2 )  THEN
2101!
2102!--                Set offset value. In case of Dirichlet conditions at the south
2103!--                domain boundary, the v component starts at nys+1. This case,
2104!--                the passed start-index for reading the NetCDF data is shifted
2105!--                by -1. 
2106                   off_j = 1 !MERGE( 1, 0, forcing )
2107
2108                   DO  i = nxl, nxr
2109                      DO  j = nysv, nyn   
2110                         CALL get_variable( id_dynamic, 'init_v', i, j-off_j,  &
2111                                            v(nzb+1:nzt+1,j,i) )
2112                      ENDDO
2113                   ENDDO
2114
2115                ENDIF
2116                init_3d%from_file_v = .TRUE.
2117             ENDIF
2118!
2119!--          Read w-component
2120             IF ( check_existence( var_names, 'init_w' ) )  THEN
2121!
2122!--             Read attributes for the fill value and level-of-detail
2123                CALL get_attribute( id_dynamic, char_fill, init_3d%fill_w,     &
2124                                    .FALSE., 'init_w' )
2125                CALL get_attribute( id_dynamic, char_lod, init_3d%lod_w,       &
2126                                    .FALSE., 'init_w' )
2127!
2128!--             level-of-detail 1 - read initialization profile
2129                IF ( init_3d%lod_w == 1 )  THEN
2130                   ALLOCATE( init_3d%w_init(nzb:nzt+1) )
2131                   init_3d%w_init = 0.0_wp
2132
2133                   CALL get_variable( id_dynamic, 'init_w',                    &
2134                                      init_3d%w_init(nzb+1:nzt) )
2135
2136!
2137!--             level-of-detail 2 - read 3D initialization data
2138                ELSEIF ( init_3d%lod_w == 2 )  THEN
2139                   DO  i = nxl, nxr
2140                      DO  j = nys, nyn
2141                         CALL get_variable( id_dynamic, 'init_w', i, j,        &
2142                                            w(nzb+1:nzt,j,i) )
2143                      ENDDO
2144                   ENDDO
2145
2146                ENDIF
2147                init_3d%from_file_w = .TRUE.
2148             ENDIF
2149!
2150!--          Read potential temperature
2151             IF ( .NOT. neutral )  THEN     
2152                IF ( check_existence( var_names, 'init_pt' ) )  THEN   
2153!
2154!--                Read attributes for the fill value and level-of-detail
2155                   CALL get_attribute( id_dynamic, char_fill, init_3d%fill_pt, &
2156                                       .FALSE., 'init_pt' )
2157                   CALL get_attribute( id_dynamic, char_lod, init_3d%lod_pt,   &
2158                                       .FALSE., 'init_pt' )
2159!
2160!--                level-of-detail 1 - read initialization profile
2161                   IF ( init_3d%lod_pt == 1 )  THEN
2162                      ALLOCATE( init_3d%pt_init(nzb:nzt+1) )
2163
2164                      CALL get_variable( id_dynamic, 'init_pt',                &
2165                                         init_3d%pt_init(nzb+1:nzt+1) )
2166!
2167!--                   Set Neumann surface boundary condition for initial profil
2168                      init_3d%pt_init(nzb) = init_3d%pt_init(nzb+1)
2169!
2170!--                level-of-detail 2 - read 3D initialization data
2171                   ELSEIF ( init_3d%lod_pt == 2 )  THEN
2172                      DO  i = nxl, nxr
2173                         DO  j = nys, nyn
2174                            CALL get_variable( id_dynamic, 'init_pt', i, j,    &
2175                                               pt(nzb+1:nzt+1,j,i) )
2176                         ENDDO
2177                      ENDDO
2178
2179                   ENDIF
2180                   init_3d%from_file_pt = .TRUE.
2181                ENDIF
2182             ENDIF
2183!
2184!--          Read mixing ratio
2185             IF ( humidity )  THEN
2186                IF ( check_existence( var_names, 'init_qv' ) )  THEN
2187!
2188!--                Read attributes for the fill value and level-of-detail
2189                   CALL get_attribute( id_dynamic, char_fill, init_3d%fill_q,  &
2190                                       .FALSE., 'init_qv' )
2191                   CALL get_attribute( id_dynamic, char_lod, init_3d%lod_q,    &
2192                                       .FALSE., 'init_qv' )
2193!
2194!--                level-of-detail 1 - read initialization profile
2195                   IF ( init_3d%lod_q == 1 )  THEN
2196                      ALLOCATE( init_3d%q_init(nzb:nzt+1) )
2197
2198                      CALL get_variable( id_dynamic, 'init_qv',               &
2199                                         init_3d%q_init(nzb+1:nzt+1) )
2200!
2201!--                   Set Neumann surface boundary condition for initial profil
2202                      init_3d%q_init(nzb) = init_3d%q_init(nzb+1)
2203
2204!
2205!--                level-of-detail 2 - read 3D initialization data
2206                   ELSEIF ( init_3d%lod_q == 2 )  THEN
2207                      DO  i = nxl, nxr
2208                         DO  j = nys, nyn
2209                            CALL get_variable( id_dynamic, 'init_qv', i, j,    &
2210                                               q(nzb+1:nzt+1,j,i) )
2211                         ENDDO
2212                      ENDDO
2213
2214                   ENDIF
2215                   init_3d%from_file_q = .TRUE.
2216                ENDIF
2217             ENDIF
2218!
2219!--          Read soil moisture
2220             IF ( land_surface )  THEN
2221                IF ( check_existence( var_names, 'init_soil_m' ) )  THEN
2222!
2223!--                Read attributes for the fill value and level-of-detail
2224                   CALL get_attribute( id_dynamic, char_fill,                  &
2225                                       init_3d%fill_msoil,                     &
2226                                       .FALSE., 'init_soil_m' )
2227                   CALL get_attribute( id_dynamic, char_lod,                   &
2228                                       init_3d%lod_msoil,                      &
2229                                       .FALSE., 'init_soil_m' )
2230!
2231!--                level-of-detail 1 - read initialization profile
2232                   IF ( init_3d%lod_msoil == 1 )  THEN
2233                      ALLOCATE( init_3d%msoil_init(0:init_3d%nzs-1) )
2234
2235                      CALL get_variable( id_dynamic, 'init_soil_m',            &
2236                                         init_3d%msoil_init(0:init_3d%nzs-1) )
2237!
2238!--                level-of-detail 2 - read 3D initialization data
2239                   ELSEIF ( init_3d%lod_msoil == 2 )  THEN  ! need to be corrected
2240                      ALLOCATE ( init_3d%msoil(0:init_3d%nzs-1,nys:nyn,nxl:nxr) )
2241                      DO  i = nxl, nxr
2242                         DO  j = nys, nyn
2243                            CALL get_variable( id_dynamic, 'init_soil_m', i, j,&
2244                                               init_3d%msoil(0:init_3d%nzs-1,j,i) )
2245                         ENDDO
2246                      ENDDO
2247                   ENDIF
2248                   init_3d%from_file_msoil = .TRUE.
2249                ENDIF
2250!
2251!--             Read soil temperature
2252                IF ( check_existence( var_names, 'init_soil_t' ) )  THEN
2253!
2254!--                Read attributes for the fill value and level-of-detail
2255                   CALL get_attribute( id_dynamic, char_fill,                  &
2256                                       init_3d%fill_tsoil,                     &
2257                                       .FALSE., 'init_soil_t' )
2258                   CALL get_attribute( id_dynamic, char_lod,                   &
2259                                       init_3d%lod_tsoil,                      &
2260                                       .FALSE., 'init_soil_t' )
2261!
2262!--                level-of-detail 1 - read initialization profile
2263                   IF ( init_3d%lod_tsoil == 1 )  THEN
2264                      ALLOCATE( init_3d%tsoil_init(0:init_3d%nzs-1) )
2265
2266                      CALL get_variable( id_dynamic, 'init_soil_t',            &
2267                                         init_3d%tsoil_init(0:init_3d%nzs-1) )
2268
2269!
2270!--                level-of-detail 2 - read 3D initialization data
2271                   ELSEIF ( init_3d%lod_tsoil == 2 )  THEN  ! need to be corrected
2272                      ALLOCATE ( init_3d%tsoil(0:init_3d%nzs-1,nys:nyn,nxl:nxr) )
2273                      DO  i = nxl, nxr
2274                         DO  j = nys, nyn
2275                            CALL get_variable( id_dynamic, 'init_soil_t', i, j,&
2276                                               init_3d%tsoil(0:init_3d%nzs-1,j,i) )
2277                         ENDDO
2278                      ENDDO
2279                   ENDIF
2280                   init_3d%from_file_tsoil = .TRUE.
2281                ENDIF
2282             ENDIF
2283!
2284!--          Close input file
2285             CALL close_input_file( id_dynamic )
2286#endif
2287          ENDIF
2288#if defined( __parallel )
2289          CALL MPI_BARRIER( comm2d, ierr )
2290#endif
2291       ENDDO
2292!
2293!--    Finally, check if the input data has any fill values.
2294       IF ( init_3d%from_file_u )  THEN
2295          IF ( ANY( u(nzb+1:nzt+1,nys:nyn,nxlu:nxr) == init_3d%fill_u ) )  THEN
2296             message_string = 'NetCDF input for u_init must not contain ' //   &
2297                              'any _FillValues'
2298             CALL message( 'netcdf_data_input_mod', 'NDI004', 2, 2, 0, 6, 0 )
2299          ENDIF
2300       ENDIF
2301       IF ( init_3d%from_file_v )  THEN
2302          IF ( ANY( v(nzb+1:nzt+1,nysv:nyn,nxl:nxr) == init_3d%fill_v ) )  THEN
2303             message_string = 'NetCDF input for v_init must not contain ' //   &
2304                              'any _FillValues'
2305             CALL message( 'netcdf_data_input_mod', 'NDI005', 2, 2, 0, 6, 0 )
2306          ENDIF
2307       ENDIF
2308       IF ( init_3d%from_file_w )  THEN
2309          IF ( ANY( w(nzb+1:nzt,nys:nyn,nxl:nxr) == init_3d%fill_w ) )  THEN
2310             message_string = 'NetCDF input for w_init must not contain ' //   &
2311                              'any _FillValues'
2312             CALL message( 'netcdf_data_input_mod', 'NDI006', 2, 2, 0, 6, 0 )
2313          ENDIF
2314       ENDIF
2315       IF ( init_3d%from_file_pt )  THEN
2316          IF ( ANY( pt(nzb+1:nzt+1,nys:nyn,nxl:nxr) == init_3d%fill_pt ) )  THEN
2317             message_string = 'NetCDF input for pt_init must not contain ' //  &
2318                              'any _FillValues'
2319             CALL message( 'netcdf_data_input_mod', 'NDI007', 2, 2, 0, 6, 0 )
2320          ENDIF
2321       ENDIF
2322       IF ( init_3d%from_file_q )  THEN
2323          IF ( ANY( q(nzb+1:nzt+1,nys:nyn,nxl:nxr) == init_3d%fill_q ) )  THEN
2324             message_string = 'NetCDF input for q_init must not contain ' //   &
2325                              'any _FillValues'
2326             CALL message( 'netcdf_data_input_mod', 'NDI008', 2, 2, 0, 6, 0 )
2327          ENDIF
2328       ENDIF
2329!
2330!--    Workaround for cyclic conditions. Please see above for further explanation.
2331       IF ( bc_lr_cyc  .AND.  nxl == 0 )  nxlu = nxl 
2332       IF ( bc_ns_cyc  .AND.  nys == 0 )  nysv = nys
2333
2334    END SUBROUTINE netcdf_data_input_init_3d
2335
2336!------------------------------------------------------------------------------!
2337! Description:
2338! ------------
2339!> Reads data at lateral and top boundaries derived from larger-scale model
2340!> (COSMO) by Inifor.
2341!------------------------------------------------------------------------------!
2342    SUBROUTINE netcdf_data_input_lsf
2343
2344       USE control_parameters,                                                 &
2345           ONLY:  force_bound_l, force_bound_n, force_bound_r, force_bound_s,  &
2346                  forcing, humidity, message_string, neutral, simulated_time
2347
2348       USE indices,                                                            &
2349           ONLY:  nx, nxl, nxlu, nxr, ny, nyn, nys, nysv, nzb, nzt
2350
2351       IMPLICIT NONE
2352
2353
2354       INTEGER(iwp) ::  i          !< running index along x-direction
2355       INTEGER(iwp) ::  ii         !< running index for IO blocks
2356       INTEGER(iwp) ::  id_dynamic !< NetCDF id of dynamic input file
2357       INTEGER(iwp) ::  j          !< running index along y-direction
2358       INTEGER(iwp) ::  k          !< running index along z-direction
2359       INTEGER(iwp) ::  num_vars   !< number of variables in netcdf input file
2360       INTEGER(iwp) ::  t          !< running index time dimension
2361
2362       REAL(wp) ::  dum           !< dummy variable to skip columns while reading topography file   
2363
2364       force%from_file = MERGE( .TRUE., .FALSE., input_pids_dynamic ) 
2365!
2366!--    Skip input if no forcing from larger-scale models is applied.
2367       IF ( .NOT. forcing )  RETURN
2368
2369       DO  ii = 0, io_blocks-1
2370          IF ( ii == io_group )  THEN
2371#if defined ( __netcdf )
2372!
2373!--          Open file in read-only mode
2374             CALL open_read_file( TRIM( input_file_dynamic ) //                &
2375                                  TRIM( coupling_char ), id_dynamic ) 
2376!
2377!--          Initialize INIFOR forcing.
2378             IF ( .NOT. force%init )  THEN
2379!
2380!--             At first, inquire all variable names.
2381                CALL inquire_num_variables( id_dynamic, num_vars )
2382!
2383!--             Allocate memory to store variable names.
2384                ALLOCATE( force%var_names(1:num_vars) )
2385                CALL inquire_variable_names( id_dynamic, force%var_names )
2386!
2387!--             Read time dimension, allocate memory and finally read time array
2388                CALL get_dimension_length( id_dynamic, force%nt, 'time' )
2389
2390                IF ( check_existence( force%var_names, 'time' ) )  THEN
2391                   ALLOCATE( force%time(0:force%nt-1) )
2392                   CALL get_variable( id_dynamic, 'time', force%time )
2393                ENDIF
2394!
2395!--             Read vertical dimension of scalar und w grid
2396                CALL get_dimension_length( id_dynamic, force%nzu, 'z' )
2397                CALL get_dimension_length( id_dynamic, force%nzw, 'zw' )
2398
2399                IF ( check_existence( force%var_names, 'z' ) )  THEN
2400                   ALLOCATE( force%zu_atmos(1:force%nzu) )
2401                   CALL get_variable( id_dynamic, 'z', force%zu_atmos )
2402                ENDIF
2403                IF ( check_existence( force%var_names, 'zw' ) )  THEN
2404                   ALLOCATE( force%zw_atmos(1:force%nzw) )
2405                   CALL get_variable( id_dynamic, 'zw', force%zw_atmos )
2406                ENDIF
2407
2408!
2409!--             Read surface pressure
2410                IF ( check_existence( force%var_names,                         &
2411                                  'surface_forcing_surface_pressure' ) )  THEN
2412                   ALLOCATE( force%surface_pressure(0:force%nt-1) )
2413                   CALL get_variable( id_dynamic,                              &
2414                                      'surface_forcing_surface_pressure',      &
2415                                      force%surface_pressure )
2416                ENDIF
2417!
2418!--             Set control flag to indicate that initialization is already done
2419                force%init = .TRUE.
2420
2421             ENDIF
2422
2423!
2424!--          Obtain time index for current input starting at 0.
2425!--          @todo: At the moment time, in INIFOR and simulated time correspond
2426!--                 to each other. If required, adjust to daytime.
2427             force%tind = MINLOC( ABS( force%time - simulated_time ), DIM = 1 )&
2428                          - 1
2429             force%tind_p = force%tind + 1 
2430!
2431!--          Read data at lateral and top boundaries. Please note, at left and
2432!--          right domain boundary, yz-layers are read for u, v, w, pt and q.
2433!--          For the v-component, the data starts at nysv, while for the other
2434!--          quantities the data starts at nys. This is equivalent at the north
2435!--          and south domain boundary for the u-component.
2436!--          The function get_variable_bc assumes the start indices with respect
2437!--          to the netcdf file convention (data starts at index 1). For this
2438!--          reason, nys+1 / nxl+1 are passed instead of nys / nxl. For the
2439!--          the u- and v-component at the north/south, and left/right boundary,
2440!--          nxlu and nysv are passed, respectively, since these always starts
2441!--          at index 1 in case of forcing.
2442
2443             IF ( force_bound_l )  THEN
2444                DO  j = nys, nyn
2445                   DO  t = force%tind, force%tind_p
2446                      CALL get_variable_bc( id_dynamic, 'ls_forcing_left_u',   &
2447                                      t+1,                                     &
2448                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2449                                      j+1, 1,                                  &
2450                                      force%u_left(t-force%tind,nzb+1:nzt+1,j) )
2451                   ENDDO
2452                ENDDO
2453
2454                DO  j = nysv, nyn
2455                   DO  t = force%tind, force%tind_p
2456                      CALL get_variable_bc( id_dynamic, 'ls_forcing_left_v',   &
2457                                      t+1,                                     &
2458                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2459                                      j, 1,                                    &
2460                                      force%v_left(t-force%tind,nzb+1:nzt+1,j) )
2461                   ENDDO
2462                ENDDO
2463                DO  j = nys, nyn
2464                   DO  t = force%tind, force%tind_p
2465                      CALL get_variable_bc( id_dynamic,                        &
2466                                      'ls_forcing_left_w',                     &
2467                                      t+1,                                     &
2468                                      nzb+1, nzt-(nzb+1) + 1,                  &
2469                                      j+1, 1,                                  &
2470                                      force%w_left(t-force%tind,nzb+1:nzt,j) )
2471                   ENDDO
2472                ENDDO
2473                IF ( .NOT. neutral )  THEN
2474                   DO  j = nys, nyn
2475                      DO  t = force%tind, force%tind_p
2476                         CALL get_variable_bc( id_dynamic,                     &
2477                                      'ls_forcing_left_pt',                    &
2478                                      t+1,                                     &
2479                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2480                                      j+1, 1,                                  &
2481                                      force%pt_left(t-force%tind,nzb+1:nzt+1,j) )
2482                      ENDDO
2483                   ENDDO
2484                ENDIF
2485                IF ( humidity )  THEN
2486                   DO  j = nys, nyn
2487                      DO  t = force%tind, force%tind_p
2488                         CALL get_variable_bc( id_dynamic,                     &
2489                                      'ls_forcing_left_qv',                    &
2490                                      t+1,                                     &
2491                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2492                                      j+1, 1,                                  &
2493                                      force%q_left(t-force%tind,nzb+1:nzt+1,j) )
2494                      ENDDO
2495                   ENDDO
2496                ENDIF
2497             ENDIF
2498
2499             IF ( force_bound_r )  THEN
2500                DO  j = nys, nyn
2501                   DO  t = force%tind, force%tind_p
2502                      CALL get_variable_bc( id_dynamic, 'ls_forcing_right_u',  &
2503                                      t+1,                                     &
2504                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2505                                      j+1, 1,                                  &
2506                                      force%u_right(t-force%tind,nzb+1:nzt+1,j) )
2507                   ENDDO
2508                ENDDO
2509                DO  j = nysv, nyn
2510                   DO  t = force%tind, force%tind_p
2511                      CALL get_variable_bc( id_dynamic, 'ls_forcing_right_v',  &
2512                                      t+1,                                     &
2513                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2514                                      j, 1,                                    &
2515                                      force%v_right(t-force%tind,nzb+1:nzt+1,j) )
2516                   ENDDO
2517                ENDDO
2518                DO  j = nys, nyn
2519                   DO  t = force%tind, force%tind_p
2520                      CALL get_variable_bc( id_dynamic, 'ls_forcing_right_w',  &
2521                                      t+1,                                     &
2522                                      nzb+1, nzt-(nzb+1)+1,                    &
2523                                      j+1, 1,                                  &
2524                                      force%w_right(t-force%tind,nzb+1:nzt,j) )
2525                   ENDDO
2526                ENDDO
2527                IF ( .NOT. neutral )  THEN
2528                   DO  j = nys, nyn
2529                      DO  t = force%tind, force%tind_p
2530                         CALL get_variable_bc( id_dynamic,                     &
2531                                      'ls_forcing_right_pt',                   &
2532                                      t+1,                                     &
2533                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2534                                      j+1, 1,                                  &
2535                                      force%pt_right(t-force%tind,nzb+1:nzt+1,j) )
2536                      ENDDO
2537                   ENDDO
2538                ENDIF
2539                IF ( humidity )  THEN
2540                   DO  j = nys, nyn
2541                      DO  t = force%tind, force%tind_p
2542                         CALL get_variable_bc( id_dynamic,                     &
2543                                      'ls_forcing_right_qv',                   &
2544                                      t+1,                                     &
2545                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2546                                      j+1, 1,                                  &
2547                                      force%q_right(t-force%tind,nzb+1:nzt+1,j) )
2548                      ENDDO
2549                   ENDDO
2550                ENDIF
2551             ENDIF
2552
2553             IF ( force_bound_n )  THEN
2554                DO  i = nxlu, nxr
2555                   DO  t = force%tind, force%tind_p
2556                      CALL get_variable_bc( id_dynamic, 'ls_forcing_north_u',  &
2557                                      t+1,                                     &
2558                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2559                                      i, 1,                                    &
2560                                      force%u_north(t-force%tind,nzb+1:nzt+1,i) )
2561                   ENDDO
2562                ENDDO
2563                DO  i = nxl, nxr
2564                   DO  t = force%tind, force%tind_p
2565                      CALL get_variable_bc( id_dynamic, 'ls_forcing_north_v',  &
2566                                      t+1,                                     &
2567                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2568                                      i+1, 1,                                  &
2569                                      force%v_north(t-force%tind,nzb+1:nzt+1,i) )
2570                   ENDDO
2571                ENDDO
2572                DO  i = nxl, nxr
2573                   DO  t = force%tind, force%tind_p
2574                      CALL get_variable_bc( id_dynamic, 'ls_forcing_north_w',  &
2575                                      t+1,                                     &
2576                                      nzb+1, nzt-(nzb+1)+1,                    &
2577                                      i+1, 1,                                  &
2578                                      force%w_north(t-force%tind,nzb+1:nzt,i) )
2579                   ENDDO
2580                ENDDO
2581                IF ( .NOT. neutral )  THEN
2582                   DO  i = nxl, nxr
2583                      DO  t = force%tind, force%tind_p
2584                         CALL get_variable_bc( id_dynamic,                     &
2585                                      'ls_forcing_north_pt',                   &
2586                                      t+1,                                     &
2587                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2588                                      i+1, 1,                                  &
2589                                      force%pt_north(t-force%tind,nzb+1:nzt+1,i) )
2590                      ENDDO
2591                   ENDDO
2592                ENDIF
2593                IF ( humidity )  THEN
2594                   DO  i = nxl, nxr
2595                      DO  t = force%tind, force%tind_p
2596                         CALL get_variable_bc( id_dynamic,                     &
2597                                      'ls_forcing_north_qv',                   &
2598                                      t+1,                                     &
2599                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2600                                      i+1, 1,                                  &
2601                                      force%q_north(t-force%tind,nzb+1:nzt+1,i) )
2602                      ENDDO
2603                   ENDDO
2604                ENDIF
2605             ENDIF
2606
2607             IF ( force_bound_s )  THEN
2608                DO  i = nxlu, nxr
2609                   DO  t = force%tind, force%tind_p
2610                      CALL get_variable_bc( id_dynamic, 'ls_forcing_south_u',  &
2611                                      t+1,                                     &
2612                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2613                                      i, 1,                                    &
2614                                      force%u_south(t-force%tind,nzb+1:nzt+1,i) )
2615                   ENDDO
2616                ENDDO
2617                DO  i = nxl, nxr
2618                   DO  t = force%tind, force%tind_p
2619                      CALL get_variable_bc( id_dynamic, 'ls_forcing_south_v',  &
2620                                      t+1,                                     &
2621                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2622                                      i+1, 1,                                  &
2623                                      force%v_south(t-force%tind,nzb+1:nzt+1,i) )
2624                   ENDDO
2625                ENDDO
2626                DO  i = nxl, nxr
2627                   DO  t = force%tind, force%tind_p
2628                      CALL get_variable_bc( id_dynamic, 'ls_forcing_south_w',  &
2629                                      t+1,                                     &
2630                                      nzb+1, nzt-(nzb+1)+1,                    &
2631                                      i+1, 1,                                  &
2632                                      force%w_south(t-force%tind,nzb+1:nzt,i) )
2633                   ENDDO
2634                ENDDO
2635                IF ( .NOT. neutral )  THEN
2636                   DO  i = nxl, nxr
2637                      DO  t = force%tind, force%tind_p
2638                         CALL get_variable_bc( id_dynamic,                     &
2639                                      'ls_forcing_south_pt',                   &
2640                                      t+1,                                     &
2641                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2642                                      i+1, 1,                                  &
2643                                      force%pt_south(t-force%tind,nzb+1:nzt+1,i) )
2644                      ENDDO
2645                   ENDDO
2646                ENDIF
2647                IF ( humidity )  THEN
2648                   DO  i = nxl, nxr
2649                      DO  t = force%tind, force%tind_p
2650                         CALL get_variable_bc( id_dynamic,                     &
2651                                      'ls_forcing_south_qv',                   &
2652                                      t+1,                                     &
2653                                      nzb+1, nzt+1-(nzb+1)+1,                  &
2654                                      i+1, 1,                                  &
2655                                      force%q_south(t-force%tind,nzb+1:nzt+1,i) )
2656                      ENDDO
2657                   ENDDO
2658                ENDIF
2659             ENDIF
2660!
2661!--          Top boundary
2662             DO  i = nxlu, nxr
2663                DO  t = force%tind, force%tind_p
2664                   CALL get_variable_bc( id_dynamic, 'ls_forcing_top_u',       &
2665                                   t+1,                                        &
2666                                   nys+1, nyn-nys+1,                           &
2667                                   i, 1,                                       &
2668                                   force%u_top(t-force%tind,nys:nyn,i) )
2669                ENDDO
2670             ENDDO
2671             DO  i = nxl, nxr
2672                DO  t = force%tind, force%tind_p
2673                   CALL get_variable_bc( id_dynamic, 'ls_forcing_top_v',       &
2674                                   t+1,                                        &
2675                                   nysv, nyn-nysv+1,                           &
2676                                   i+1, 1,                                     &
2677                                   force%v_top(t-force%tind,nysv:nyn,i) )
2678                ENDDO
2679             ENDDO
2680             DO  i = nxl, nxr
2681                DO  t = force%tind, force%tind_p
2682                   CALL get_variable_bc( id_dynamic, 'ls_forcing_top_w',       &
2683                                   t+1,                                        &
2684                                   nys+1, nyn-nys+1,                           &
2685                                   i+1, 1,                                     &
2686                                   force%w_top(t-force%tind,nys:nyn,i) )
2687                ENDDO
2688             ENDDO
2689             IF ( .NOT. neutral )  THEN
2690                DO  i = nxl, nxr
2691                   DO  t = force%tind, force%tind_p
2692                      CALL get_variable_bc( id_dynamic, 'ls_forcing_top_pt',   &
2693                                      t+1,                                     &
2694                                      nys+1, nyn-nys+1,                        &
2695                                      i+1, 1,                                  &
2696                                      force%pt_top(t-force%tind,nys:nyn,i) )
2697                   ENDDO
2698                ENDDO
2699             ENDIF
2700             IF ( humidity )  THEN
2701                DO  i = nxl, nxr
2702                   DO  t = force%tind, force%tind_p
2703                      CALL get_variable_bc( id_dynamic, 'ls_forcing_top_qv',   &
2704                                      t+1,                                     &
2705                                      nys+1, nyn-nys+1,                        &
2706                                      i+1, 1,                                  &
2707                                      force%q_top(t-force%tind,nys:nyn,i) )
2708                   ENDDO
2709                ENDDO
2710             ENDIF
2711
2712!
2713!--          Close input file
2714             CALL close_input_file( id_dynamic )
2715#endif
2716          ENDIF
2717#if defined( __parallel )
2718          CALL MPI_BARRIER( comm2d, ierr )
2719#endif
2720       ENDDO
2721
2722!
2723!--    Finally, after data input set control flag indicating that vertical
2724!--    inter- and/or extrapolation is required.
2725!--    Please note, inter/extrapolation of INIFOR data is only a workaroud,
2726!--    as long as INIFOR delivers vertically equidistant data.
2727       force%interpolated = .FALSE. 
2728
2729    END SUBROUTINE netcdf_data_input_lsf
2730
2731
2732!------------------------------------------------------------------------------!
2733! Description:
2734! ------------
2735!> Checks input file for consistency and minimum requirements.
2736!------------------------------------------------------------------------------!
2737    SUBROUTINE netcdf_data_input_check_dynamic
2738
2739       USE control_parameters,                                                 &
2740           ONLY:  initializing_actions, forcing, message_string
2741
2742       IMPLICIT NONE
2743
2744!
2745!--    In case of forcing, check whether dynamic input file is present
2746       IF ( .NOT. input_pids_dynamic  .AND.  forcing )  THEN
2747          message_string = 'forcing = .TRUE. requires dynamic input file ' //  &
2748                            TRIM( input_file_dynamic ) // TRIM( coupling_char )
2749          CALL message( 'netcdf_data_input_mod', 'NDI009', 1, 2, 0, 6, 0 )
2750       ENDIF
2751!
2752!--    Dynamic input file must also be present if initialization via inifor is
2753!--    prescribed.
2754       IF ( .NOT. input_pids_dynamic  .AND.                                    &
2755            TRIM( initializing_actions ) == 'inifor' )  THEN
2756          message_string = 'initializing_actions = inifor requires dynamic ' //&
2757                           'input file ' // TRIM( input_file_dynamic ) //      &
2758                           TRIM( coupling_char )
2759          CALL message( 'netcdf_data_input_mod', 'NDI010', 1, 2, 0, 6, 0 )
2760       ENDIF
2761
2762    END SUBROUTINE netcdf_data_input_check_dynamic
2763
2764!------------------------------------------------------------------------------!
2765! Description:
2766! ------------
2767!> Checks input file for consistency and minimum requirements.
2768!------------------------------------------------------------------------------!
2769    SUBROUTINE netcdf_data_input_check_static
2770
2771       USE arrays_3d,                                                          &
2772           ONLY:  zu
2773
2774       USE control_parameters,                                                 &
2775           ONLY:  land_surface, message_string, urban_surface
2776
2777       USE grid_variables,                                                     &
2778           ONLY:  dx, dy
2779
2780       USE indices,                                                            &
2781           ONLY:  nx, nxl, nxr, ny, nyn, nys
2782
2783       IMPLICIT NONE
2784
2785       INTEGER(iwp) ::  i      !< loop index along x-direction
2786       INTEGER(iwp) ::  j      !< loop index along y-direction
2787
2788       LOGICAL      ::  check_passed !< flag indicating if a check passed
2789
2790!
2791!--    Return if no static input file is available
2792       IF ( .NOT. input_pids_static )  RETURN
2793!
2794!--    Check whether dimension size in input file matches the model dimensions
2795       IF ( dim_static%nx-1 /= nx  .OR.  dim_static%ny-1 /= ny )  THEN
2796          message_string = 'Static input file: horizontal dimension in ' //    &
2797                           'x- and/or y-direction ' //                         &
2798                           'do not match the respective model dimension'
2799          CALL message( 'netcdf_data_input_mod', 'NDI011', 1, 2, 0, 6, 0 )
2800       ENDIF
2801!
2802!--    Check if grid spacing of provided input data matches the respective
2803!--    grid spacing in the model.
2804       IF ( dim_static%x(1) - dim_static%x(0) /= dx  .OR.                      &
2805            dim_static%y(1) - dim_static%y(0) /= dy )  THEN
2806          message_string = 'Static input file: horizontal grid spacing ' //    &
2807                           'in x- and/or y-direction ' //                      &
2808                           'do not match the respective model grid spacing.'
2809          CALL message( 'netcdf_data_input_mod', 'NDI012', 1, 2, 0, 6, 0 )
2810       ENDIF
2811!
2812!--    Check orography for fill-values. For the moment, give an error message.
2813!--    More advanced methods, e.g. a nearest neighbor algorithm as used in GIS
2814!--    systems might be implemented later.
2815       IF ( ANY( terrain_height_f%var == terrain_height_f%fill ) )  THEN
2816          message_string = 'NetCDF variable orography_2D is not ' //           &
2817                           'allowed to have missing data'
2818          CALL message( 'netcdf_data_input_mod', 'NDI013', 2, 2, 0, 6, 0 )
2819       ENDIF
2820!
2821!--    If 3D buildings are read, check if building information is consistent
2822!--    to numeric grid.
2823       IF ( buildings_f%from_file )  THEN
2824          IF ( buildings_f%lod == 2 )  THEN
2825             IF ( buildings_f%nz > SIZE( zu ) )  THEN
2826                message_string = 'Reading 3D building data - too much ' //     &
2827                                 'data points along the vertical coordinate.' 
2828                CALL message( 'netcdf_data_input_mod', 'NDI014', 2, 2, 0, 6, 0 )
2829             ENDIF
2830
2831             IF ( ANY( buildings_f%z(0:buildings_f%nz-1) /=                    &
2832                       zu(0:buildings_f%nz-1) ) )  THEN
2833                message_string = 'Reading 3D building data - vertical ' //     &
2834                                 'coordinate do not match numeric grid.'
2835                CALL message( 'netcdf_data_input_mod', 'NDI015', 2, 2, 0, 6, 0 )
2836             ENDIF
2837          ENDIF
2838       ENDIF
2839
2840!
2841!--    Skip further checks concerning buildings and natural surface properties
2842!--    if no urban surface and land surface model are applied.
2843       IF (  .NOT. land_surface  .OR.  .NOT. urban_surface )  RETURN 
2844!
2845!--    Check for minimum requirement of surface-classification data in case
2846!--    static input file is used.
2847       IF ( .NOT. vegetation_type_f%from_file  .OR.                            &
2848            .NOT. pavement_type_f%from_file    .OR.                            &
2849            .NOT. building_type_f%from_file    .OR.                            &
2850            .NOT. water_type_f%from_file       .OR.                            &
2851            .NOT. soil_type_f%from_file             )  THEN
2852          message_string = 'Minimum requirement for surface classification ' //&
2853                           'is not fulfilled. At least ' //                    &
2854                           'vegetation_type, pavement_type, ' //               &
2855                           'building_type, soil_type and water_type are '//    &
2856                           'required.'
2857          CALL message( 'netcdf_data_input_mod', 'NDI016', 1, 2, 0, 6, 0 )
2858       ENDIF
2859!
2860!--    Check for general availability of input variables.
2861!--    If vegetation_type is 0 at any location, vegetation_pars as well as
2862!--    root_area_density_lsm are required.
2863       IF ( vegetation_type_f%from_file )  THEN
2864          IF ( ANY( vegetation_type_f%var == 0 ) )  THEN
2865             IF ( .NOT. vegetation_pars_f%from_file )  THEN
2866                message_string = 'If vegegation_type = 0 at any location, ' // &
2867                                 'vegetation_pars is required'
2868                CALL message( 'netcdf_data_input_mod', 'NDI017', 2, 2, 0, 6, 0 )
2869             ENDIF
2870             IF ( .NOT. root_area_density_lsm_f%from_file )  THEN
2871                message_string = 'If vegegation_type = 0 at any location, ' // &
2872                                 'root_area_density_lsm is required'
2873                CALL message( 'netcdf_data_input_mod', 'NDI018', 2, 2, 0, 6, 0 )
2874             ENDIF
2875          ENDIF
2876       ENDIF
2877!
2878!--    If soil_type is zero at any location, soil_pars is required.
2879       IF ( soil_type_f%from_file )  THEN
2880          check_passed = .TRUE. 
2881          IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
2882             IF ( ANY( soil_type_f%var_2d == 0 ) )  THEN
2883                IF ( .NOT. soil_pars_f%from_file )  check_passed = .FALSE.
2884             ENDIF
2885          ELSE
2886             IF ( ANY( soil_type_f%var_3d == 0 ) )  THEN
2887                IF ( .NOT. soil_pars_f%from_file )  check_passed = .FALSE.
2888             ENDIF
2889          ENDIF
2890          IF ( .NOT. check_passed )  THEN
2891             message_string = 'If soil_type = 0 at any location, ' //          &
2892                              'soil_pars is required'
2893             CALL message( 'netcdf_data_input_mod', 'NDI019', 2, 2, 0, 6, 0 )         
2894          ENDIF
2895       ENDIF
2896!
2897!--    If building_type is zero at any location, building_pars is required.
2898       IF ( building_type_f%from_file )  THEN
2899          IF ( ANY( building_type_f%var == 0 ) )  THEN
2900             IF ( .NOT. building_pars_f%from_file )  THEN
2901                message_string = 'If building_type = 0 at any location, ' //   &
2902                                 'building_pars is required'
2903                CALL message( 'netcdf_data_input_mod', 'NDI020', 2, 2, 0, 6, 0 )         
2904             ENDIF
2905          ENDIF
2906       ENDIF
2907!
2908!--    If albedo_type is zero at any location, albedo_pars is required.
2909       IF ( albedo_type_f%from_file )  THEN
2910          IF ( ANY( albedo_type_f%var == 0 ) )  THEN
2911             IF ( .NOT. albedo_pars_f%from_file )  THEN
2912                message_string = 'If albedo_type = 0 at any location, ' //     &
2913                                 'albedo_pars is required'
2914                CALL message( 'netcdf_data_input_mod', 'NDI021', 2, 2, 0, 6, 0 )     
2915             ENDIF     
2916          ENDIF
2917       ENDIF
2918!
2919!--    If pavement_type is zero at any location, pavement_pars is required.
2920       IF ( pavement_type_f%from_file )  THEN
2921          IF ( ANY( pavement_type_f%var == 0 ) )  THEN
2922             IF ( .NOT. pavement_pars_f%from_file )  THEN
2923                message_string = 'If pavement_type = 0 at any location, ' //   &
2924                                 'pavement_pars is required'
2925                CALL message( 'netcdf_data_input_mod', 'NDI022', 2, 2, 0, 6, 0 )     
2926             ENDIF     
2927          ENDIF
2928       ENDIF
2929!
2930!--    If pavement_type is zero at any location, also pavement_subsurface_pars
2931!--    is required.
2932       IF ( pavement_type_f%from_file )  THEN
2933          IF ( ANY( pavement_type_f%var == 0 ) )  THEN
2934             IF ( .NOT. pavement_subsurface_pars_f%from_file )  THEN
2935                message_string = 'If pavement_type = 0 at any location, ' //   &
2936                                 'pavement_subsurface_pars is required'
2937                CALL message( 'netcdf_data_input_mod', 'NDI023', 2, 2, 0, 6, 0 )     
2938             ENDIF     
2939          ENDIF
2940       ENDIF
2941!
2942!--    If water_type is zero at any location, water_pars is required.
2943       IF ( water_type_f%from_file )  THEN
2944          IF ( ANY( water_type_f%var == 0 ) )  THEN
2945             IF ( .NOT. water_pars_f%from_file )  THEN
2946                message_string = 'If water_type = 0 at any location, ' //      &
2947                                 'water_pars is required'
2948                CALL message( 'netcdf_data_input_mod', 'NDI024', 2, 2, 0, 6, 0 )     
2949             ENDIF     
2950          ENDIF
2951       ENDIF
2952!
2953!--    Check for local consistency of the input data.
2954       DO  i = nxl, nxr
2955          DO  j = nys, nyn
2956!
2957!--          For each (y,x)-location at least one of the parameters
2958!--          vegetation_type, pavement_type, building_type, or water_type
2959!--          must be set to a non­missing value.
2960             IF ( vegetation_type_f%var(j,i) == vegetation_type_f%fill  .AND.  &
2961                  pavement_type_f%var(j,i)   == pavement_type_f%fill    .AND.  &
2962                  building_type_f%var(j,i)   == building_type_f%fill    .AND.  &
2963                  water_type_f%var(j,i)      == water_type_f%fill )  THEN
2964                message_string = 'At least one of the paramters '       //     &
2965                                 'vegetation_type, pavement_type, '     //     &
2966                                 'building_type, or water_type must be set '// &
2967                                 'to a non-missing value'
2968                CALL message( 'netcdf_data_input_mod', 'NDI025', 2, 2, 0, 6, 0 )
2969             ENDIF
2970!
2971!--          Note that a soil_type is required for each location (y,x) where
2972!--          either vegetation_type or pavement_type is a non­missing value.
2973             IF ( ( vegetation_type_f%var(j,i) /= vegetation_type_f%fill  .OR. &
2974                    pavement_type_f%var(j,i)   /= pavement_type_f%fill ) )  THEN
2975                check_passed = .TRUE.
2976                IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
2977                   IF ( soil_type_f%var_2d(j,i) == soil_type_f%fill )          &
2978                      check_passed = .FALSE.
2979                ELSE
2980                   IF ( ANY( soil_type_f%var_3d(:,j,i) == soil_type_f%fill) )  &
2981                      check_passed = .FALSE.
2982                ENDIF
2983
2984                IF ( .NOT. check_passed )  THEN
2985                   message_string = 'soil_type is required for each '//        &
2986                                 'location (y,x) where vegetation_type or ' // &
2987                                 'pavement_type is a non-missing value.'
2988                   CALL message( 'netcdf_data_input_mod', 'NDI026',            &
2989                                  2, 2, 0, 6, 0 )
2990                ENDIF
2991             ENDIF
2992!
2993!--          Check for consistency of surface fraction.
2994!--          Sum of surface fractions must not exceed one.
2995             IF ( ANY ( surface_fraction_f%frac(:,j,i) ==                      &
2996                        surface_fraction_f%fill ) )  THEN
2997                message_string = 'If more than one natural surface type is ' //&
2998                              'given at a location, surface_fraction ' //      &
2999                              'must be provided.'
3000                CALL message( 'netcdf_data_input_mod', 'NDI027',               &
3001                                  2, 2, 0, 6, 0 )
3002             ENDIF
3003             IF ( SUM ( surface_fraction_f%frac(:,j,i) ) > 1.0_wp )  THEN
3004                message_string = 'surface_fraction must not exceed 1'
3005                CALL message( 'netcdf_data_input_mod', 'NDI028',               &
3006                               2, 2, 0, 6, 0 )
3007             ENDIF
3008!
3009!--          Check for further mismatches, e.g. vegetation_type is set but
3010!--          surface vegetation fraction is zero.
3011             IF ( ( vegetation_type_f%var(j,i) /= vegetation_type_f%fill  .AND.  &
3012                    surface_fraction_f%frac(0,j,i) == 0.0_wp )  .OR.             &
3013                  ( pavement_type_f%var(j,i) /= pavement_type_f%fill     .AND.   &
3014                    surface_fraction_f%frac(1,j,i) == 0.0_wp )  .OR.             &
3015                  ( water_type_f%var(j,i) /= water_type_f%fill           .AND.   &
3016                    surface_fraction_f%frac(2,j,i) == 0.0_wp ) )  THEN
3017                WRITE( message_string, * ) 'Mismatch in setting of '     //      &
3018                               'surface_fraction. Vegetation-, pavement-, or '// &
3019                               'water surface is given at (i,j) = ( ', i, j,     &
3020                               ' ), but surface fraction is 0 for the given type.'
3021                CALL message( 'netcdf_data_input_mod', 'NDI029',                 &
3022                               2, 2, 0, 6, 0 )
3023             ENDIF
3024!
3025!--          Check for further mismatches, e.g. vegetation_type is not set       
3026!--          surface vegetation fraction is non-zero.
3027             IF ( ( vegetation_type_f%var(j,i) == vegetation_type_f%fill  .AND.  &
3028                    surface_fraction_f%frac(0,j,i) /= 0.0_wp )  .OR.             &
3029                  ( pavement_type_f%var(j,i) == pavement_type_f%fill     .AND.   &
3030                    surface_fraction_f%frac(1,j,i) /= 0.0_wp )  .OR.             &
3031                  ( water_type_f%var(j,i) == water_type_f%fill           .AND.   &
3032                    surface_fraction_f%frac(2,j,i) /= 0.0_wp ) )  THEN
3033                WRITE( message_string, * ) 'Mismatch in setting of '     //      &
3034                               'surface_fraction. Vegetation-, pavement-, or '// &
3035                               'water surface is not given at (i,j) = ( ', i, j, &
3036                               ' ), but surface fraction is not 0 for the ' //   &
3037                               'given type.'
3038                CALL message( 'netcdf_data_input_mod', 'NDI030',                 &
3039                               2, 2, 0, 6, 0 )
3040             ENDIF
3041!
3042!--          Check vegetation_pars. If vegetation_type is 0, all parameters
3043!--          need to be set, otherwise, single parameters set by
3044!--          vegetation_type can be overwritten.
3045             IF ( vegetation_type_f%from_file )  THEN
3046                IF ( vegetation_type_f%var(j,i) == 0 )  THEN
3047                   IF ( ANY( vegetation_pars_f%pars_xy(:,j,i) ==               &
3048                             vegetation_pars_f%fill ) )  THEN
3049                      message_string = 'If vegetation_type(y,x) = 0, all '  // &
3050                                       'parameters of vegetation_pars at '//   & 
3051                                       'this location must be set.' 
3052                      CALL message( 'netcdf_data_input_mod', 'NDI031',         &
3053                                     2, 2, 0, 6, 0 )
3054                   ENDIF
3055                ENDIF
3056             ENDIF
3057!
3058!--          Check root distribution. If vegetation_type is 0, all levels must
3059!--          be set.
3060             IF ( vegetation_type_f%from_file )  THEN
3061                IF ( vegetation_type_f%var(j,i) == 0 )  THEN
3062                   IF ( ANY( root_area_density_lsm_f%var(:,j,i) ==             &
3063                             root_area_density_lsm_f%fill ) )  THEN
3064                      message_string = 'If vegetation_type(y,x) = 0, all ' //  &
3065                                       'levels of root_area_density_lsm ' //   &
3066                                       'must be set at this location.' 
3067                      CALL message( 'netcdf_data_input_mod', 'NDI032',         &
3068                                     2, 2, 0, 6, 0 )
3069                   ENDIF
3070                ENDIF
3071             ENDIF
3072!
3073!--          Check soil parameters. If soil_type is 0, all parameters 
3074!--          must be set.
3075             IF ( soil_type_f%from_file )  THEN
3076                check_passed = .TRUE.
3077                IF ( ALLOCATED( soil_type_f%var_2d ) )  THEN
3078                   IF ( soil_type_f%var_2d(j,i) == 0 )  THEN
3079                      IF ( ANY( soil_pars_f%pars_xy(:,j,i) ==                  &
3080                                soil_pars_f%fill ) )  check_passed = .FALSE.
3081                   ENDIF
3082                ELSE
3083                   IF ( ANY( soil_type_f%var_3d(:,j,i) == 0 ) )  THEN
3084                      IF ( ANY( soil_pars_f%pars_xy(:,j,i) ==                  &
3085                                soil_pars_f%fill ) )  check_passed = .FALSE.
3086                   ENDIF
3087                ENDIF
3088                IF ( .NOT. check_passed )  THEN
3089                   message_string = 'If soil_type(y,x) = 0, all levels of '  //& 
3090                                    'soil_pars at this location must be set.' 
3091                   CALL message( 'netcdf_data_input_mod', 'NDI033',            &
3092                                  2, 2, 0, 6, 0 )
3093                ENDIF
3094             ENDIF
3095
3096!
3097!--          Check building parameters. If building_type is 0, all parameters 
3098!--          must be set.
3099             IF ( building_type_f%from_file )  THEN
3100                IF ( building_type_f%var(j,i) == 0 )  THEN
3101                   IF ( ANY( building_pars_f%pars_xy(:,j,i) ==                 &
3102                             building_pars_f%fill ) )  THEN
3103                      message_string = 'If building_type(y,x) = 0, all ' //    &
3104                                       'parameters of building_pars at this '//&
3105                                       'location must be set.' 
3106                      CALL message( 'netcdf_data_input_mod', 'NDI034',         &
3107                                     2, 2, 0, 6, 0 )
3108                   ENDIF
3109                ENDIF
3110             ENDIF
3111!
3112!--          Check if building_type is set at each building
3113             IF ( building_type_f%from_file  .AND.  buildings_f%from_file )  THEN
3114                IF ( buildings_f%lod == 1 )  THEN
3115                   IF ( buildings_f%var_2d(j,i)  /= buildings_f%fill1  .AND.   &
3116                        building_type_f%var(j,i) == building_type_f%fill )  THEN
3117                      WRITE( message_string, * ) 'Each building requires ' //  &
3118                                                 'a type in case the ' //      &
3119                                                 'urban-surface model is ' //  &
3120                                                 'applied. i, j = ', i, j
3121                      CALL message( 'netcdf_data_input_mod', 'NDI035',         &
3122                                     2, 2, 0, 6, 0 )
3123                   ENDIF
3124                ENDIF
3125                IF ( buildings_f%lod == 2 )  THEN
3126                   IF ( ANY( buildings_f%var_3d(:,j,i) == 1 )                  &
3127                  .AND. building_type_f%var(j,i) == building_type_f%fill )  THEN
3128                      WRITE( message_string, * ) 'Each building requires ' //  &
3129                                                 'a type in case the ' //      &
3130                                                 'urban-surface model is ' //  &
3131                                                 'applied. i, j = ', i, j
3132                      CALL message( 'netcdf_data_input_mod', 'NDI036',         &
3133                                     2, 2, 0, 6, 0 )
3134                   ENDIF
3135                ENDIF
3136             ENDIF
3137!
3138!--          Check albedo parameters. If albedo_type is 0, all parameters 
3139!--          must be set.
3140             IF ( albedo_type_f%from_file )  THEN
3141                IF ( albedo_type_f%var(j,i) == 0 )  THEN
3142                   IF ( ANY( albedo_pars_f%pars_xy(:,j,i) ==                   &
3143                             albedo_pars_f%fill ) )  THEN
3144                      message_string = 'If albedo_type(y,x) = 0, all ' //      &
3145                                       'parameters of albedo_pars at this ' // &
3146                                       'location must be set.' 
3147                      CALL message( 'netcdf_data_input_mod', 'NDI037',         &
3148                                     2, 2, 0, 6, 0 )
3149                   ENDIF
3150                ENDIF
3151             ENDIF
3152
3153!
3154!--          Check pavement parameters. If pavement_type is 0, all parameters 
3155!--          of pavement_pars must be set at this location.
3156             IF ( pavement_type_f%from_file )  THEN
3157                IF ( pavement_type_f%var(j,i) == 0 )  THEN
3158                   IF ( ANY( pavement_pars_f%pars_xy(:,j,i) ==                 &
3159                             pavement_pars_f%fill ) )  THEN
3160                      message_string = 'If pavement_type(y,x) = 0, all ' //    &
3161                                       'parameters of pavement_pars at this '//&
3162                                       'location must be set.' 
3163                      CALL message( 'netcdf_data_input_mod', 'NDI038',         &
3164                                     2, 2, 0, 6, 0 )
3165                   ENDIF
3166                ENDIF
3167             ENDIF
3168!
3169!--          Check pavement-subsurface parameters. If pavement_type is 0,
3170!--          all parameters of pavement_subsurface_pars must be set  at this
3171!--          location.
3172             IF ( pavement_type_f%from_file )  THEN
3173                IF ( pavement_type_f%var(j,i) == 0 )  THEN
3174                   IF ( ANY( pavement_subsurface_pars_f%pars_xyz(:,:,j,i) ==   &
3175                             pavement_subsurface_pars_f%fill ) )  THEN
3176                      message_string = 'If pavement_type(y,x) = 0, all ' //    &
3177                                       'parameters of '                  //    &
3178                                       'pavement_subsurface_pars at this '//   &
3179                                       'location must be set.' 
3180                      CALL message( 'netcdf_data_input_mod', 'NDI039',         &
3181                                     2, 2, 0, 6, 0 )
3182                   ENDIF
3183                ENDIF
3184             ENDIF
3185
3186!
3187!--          Check water parameters. If water_type is 0, all parameters 
3188!--          must be set  at this location.
3189             IF ( water_type_f%from_file )  THEN
3190                IF ( water_type_f%var(j,i) == 0 )  THEN
3191                   IF ( ANY( water_pars_f%pars_xy(:,j,i) ==                    &
3192                             water_pars_f%fill ) )  THEN
3193                      message_string = 'If water_type(y,x) = 0, all ' //       &
3194                                       'parameters of water_pars at this ' //  &
3195                                       'location must be set.' 
3196                      CALL message( 'netcdf_data_input_mod', 'NDI040',         &
3197                                     2, 2, 0, 6, 0 )
3198                   ENDIF
3199                ENDIF
3200             ENDIF
3201
3202          ENDDO
3203       ENDDO
3204
3205    END SUBROUTINE netcdf_data_input_check_static
3206
3207!------------------------------------------------------------------------------!
3208! Description:
3209! ------------
3210!> Vertical interpolation and extrapolation of 1D variables.
3211!------------------------------------------------------------------------------!
3212    SUBROUTINE netcdf_data_input_interpolate_1d( var, z_grid, z_file)
3213
3214       IMPLICIT NONE
3215
3216       LOGICAL      ::  top     !< flag indicating extrapolation at model top
3217
3218       INTEGER(iwp) ::  k       !< running index z-direction file
3219       INTEGER(iwp) ::  kk      !< running index z-direction stretched model grid
3220       INTEGER(iwp) ::  kl      !< lower index bound along z-direction
3221       INTEGER(iwp) ::  ku      !< upper index bound along z-direction
3222       INTEGER(iwp) ::  nz_file !< number of vertical levels on file
3223
3224
3225       REAL(wp), DIMENSION(:) ::  z_grid                  !< grid levels on numeric grid
3226       REAL(wp), DIMENSION(:) ::  z_file                  !< grid levels on file grid
3227       REAL(wp), DIMENSION(:), INTENT(INOUT) ::  var      !< treated variable
3228       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  var_tmp  !< temporary variable
3229
3230
3231       kl = LBOUND(var,1)
3232       ku = UBOUND(var,1)
3233       ALLOCATE( var_tmp(kl:ku) )
3234
3235       DO  k = kl, ku
3236
3237          kk = MINLOC( ABS( z_file - z_grid(k) ), DIM = 1 )
3238
3239          IF ( kk < ku )  THEN
3240             IF ( z_file(kk) - z_grid(k) <= 0.0_wp )  THEN
3241                var_tmp(k) = var(kk) +                                         &
3242                                       ( var(kk+1)        - var(kk)    ) /     &
3243                                       ( z_file(kk+1)     - z_file(kk) ) *     &
3244                                       ( z_grid(k)        - z_file(kk) ) 
3245
3246             ELSEIF ( z_file(kk) - z_grid(k) > 0.0_wp )  THEN
3247                var_tmp(k) = var(kk-1) +                                       &
3248                                         ( var(kk)     - var(kk-1)    ) /      &
3249                                         ( z_file(kk)  - z_file(kk-1) ) *      &
3250                                         ( z_grid(k)   - z_file(kk-1) ) 
3251             ENDIF
3252!
3253!--       Extrapolate
3254          ELSE
3255     
3256             var_tmp(k) = var(ku) +   ( var(ku)    - var(ku-1)      ) /        &
3257                                      ( z_file(ku) - z_file(ku-1)   ) *        &
3258                                      ( z_grid(k)  - z_file(ku)     ) 
3259   
3260          ENDIF
3261
3262       ENDDO
3263       var(:) = var_tmp(:)
3264
3265       DEALLOCATE( var_tmp )
3266
3267
3268    END SUBROUTINE netcdf_data_input_interpolate_1d
3269
3270
3271!------------------------------------------------------------------------------!
3272! Description:
3273! ------------
3274!> Vertical interpolation and extrapolation of 1D variables from Inifor grid
3275!> onto Palm grid, where both have same dimension. Please note, the passed
3276!> paramter list in 1D version is different compared to 2D version.
3277!------------------------------------------------------------------------------!
3278    SUBROUTINE netcdf_data_input_interpolate_1d_soil( var, var_file,           &
3279                                                      z_grid, z_file,          &
3280                                                      nzb_var, nzt_var,        & 
3281                                                      nzb_file, nzt_file )
3282
3283       IMPLICIT NONE
3284
3285       INTEGER(iwp) ::  i        !< running index x-direction
3286       INTEGER(iwp) ::  j        !< running index y-direction
3287       INTEGER(iwp) ::  k        !< running index z-direction file
3288       INTEGER(iwp) ::  kk       !< running index z-direction stretched model grid
3289       INTEGER(iwp) ::  ku       !< upper index bound along z-direction for varialbe from file
3290       INTEGER(iwp) ::  nzb_var  !< lower bound of final array
3291       INTEGER(iwp) ::  nzt_var  !< upper bound of final array
3292       INTEGER(iwp) ::  nzb_file !< lower bound of file array
3293       INTEGER(iwp) ::  nzt_file !< upper bound of file array
3294
3295!        LOGICAL, OPTIONAL ::  depth !< flag indicating reverse z-axis, i.e. depth instead of height, e.g. in case of ocean or soil
3296
3297       REAL(wp), DIMENSION(nzb_var:nzt_var)   ::  z_grid   !< grid levels on numeric grid
3298       REAL(wp), DIMENSION(nzb_file:nzt_file) ::  z_file   !< grid levels on file grid
3299       REAL(wp), DIMENSION(nzb_var:nzt_var)   ::  var      !< treated variable
3300       REAL(wp), DIMENSION(nzb_file:nzt_file) ::  var_file !< temporary variable
3301
3302       ku = nzt_file
3303
3304       DO  k = nzb_var, nzt_var
3305!
3306!--       Determine index on Inifor grid which is closest to the actual height
3307          kk = MINLOC( ABS( z_file - z_grid(k) ), DIM = 1 )
3308!
3309!--       If closest index on Inifor grid is smaller than top index,
3310!--       interpolate the data
3311          IF ( kk < nzt_file )  THEN
3312             IF ( z_file(kk) - z_grid(k) <= 0.0_wp )  THEN
3313                var(k) = var_file(kk) + ( var_file(kk+1) - var_file(kk) ) /    &
3314                                        ( z_file(kk+1)   - z_file(kk)   ) *    &
3315                                        ( z_grid(k)      - z_file(kk)   ) 
3316
3317             ELSEIF ( z_file(kk) - z_grid(k) > 0.0_wp )  THEN
3318                var(k) = var_file(kk-1) + ( var_file(kk) - var_file(kk-1) ) /  &
3319                                          ( z_file(kk)   - z_file(kk-1)   ) *  &
3320                                          ( z_grid(k)    - z_file(kk-1)   ) 
3321             ENDIF
3322!
3323!--       Extrapolate if actual height is above the highest Inifor level
3324          ELSE
3325             var(k) = var_file(ku) + ( var_file(ku) - var_file(ku-1) ) /       &
3326                                     ( z_file(ku)   - z_file(ku-1)   ) *       &
3327                                     ( z_grid(k)    - z_file(ku)     ) 
3328
3329          ENDIF
3330
3331       ENDDO
3332
3333    END SUBROUTINE netcdf_data_input_interpolate_1d_soil
3334
3335!------------------------------------------------------------------------------!
3336! Description:
3337! ------------
3338!> Vertical interpolation and extrapolation of 2D variables at lateral boundaries.
3339!------------------------------------------------------------------------------!
3340    SUBROUTINE netcdf_data_input_interpolate_2d( var, z_grid, z_file)
3341
3342       IMPLICIT NONE
3343
3344       LOGICAL      ::  top     !< flag indicating extrapolation at model top
3345
3346       INTEGER(iwp) ::  i       !< running index x- or y -direction
3347       INTEGER(iwp) ::  il      !< lower index bound along x- or y-direction
3348       INTEGER(iwp) ::  iu      !< upper index bound along x- or y-direction
3349       INTEGER(iwp) ::  k       !< running index z-direction file
3350       INTEGER(iwp) ::  kk      !< running index z-direction stretched model grid
3351       INTEGER(iwp) ::  kl      !< lower index bound along z-direction
3352       INTEGER(iwp) ::  ku      !< upper index bound along z-direction
3353       INTEGER(iwp) ::  nz_file !< number of vertical levels on file
3354
3355
3356       REAL(wp), DIMENSION(:) ::  z_grid                  !< grid levels on numeric grid
3357       REAL(wp), DIMENSION(:) ::  z_file                  !< grid levels on file grid
3358       REAL(wp), DIMENSION(:,:), INTENT(INOUT) ::  var    !< treated variable
3359       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  var_tmp  !< temporary variable
3360
3361
3362       il = LBOUND(var,2)
3363       iu = UBOUND(var,2)
3364       kl = LBOUND(var,1)
3365       ku = UBOUND(var,1)
3366       ALLOCATE( var_tmp(kl:ku) )
3367
3368       DO  i = il, iu
3369          DO  k = kl, ku
3370
3371             kk = MINLOC( ABS( z_file - z_grid(k) ), DIM = 1 )
3372
3373             IF ( kk < ku )  THEN
3374                IF ( z_file(kk) - z_grid(k) <= 0.0_wp )  THEN
3375                   var_tmp(k) = var(kk,i) +                                    &
3376                                          ( var(kk+1,i)      - var(kk,i)  ) /  &
3377                                          ( z_file(kk+1)     - z_file(kk) ) *  &
3378                                          ( z_grid(k)        - z_file(kk) ) 
3379
3380                ELSEIF ( z_file(kk) - z_grid(k) > 0.0_wp )  THEN
3381                   var_tmp(k) = var(kk-1,i) +                                  &
3382                                            ( var(kk,i)   - var(kk-1,i)  ) /   &
3383                                            ( z_file(kk)  - z_file(kk-1) ) *   &
3384                                            ( z_grid(k)   - z_file(kk-1) ) 
3385                ENDIF
3386!
3387!--          Extrapolate
3388             ELSE
3389     
3390                var_tmp(k) = var(ku,i) + ( var(ku,i)  - var(ku-1,i)    ) /     &
3391                                         ( z_file(ku) - z_file(ku-1)   ) *     &
3392                                         ( z_grid(k)  - z_file(ku)     ) 
3393   
3394             ENDIF
3395
3396          ENDDO
3397          var(:,i) = var_tmp(:)
3398
3399       ENDDO
3400
3401       DEALLOCATE( var_tmp )
3402
3403
3404    END SUBROUTINE netcdf_data_input_interpolate_2d
3405
3406!------------------------------------------------------------------------------!
3407! Description:
3408! ------------
3409!> Vertical interpolation and extrapolation of 3D variables.
3410!------------------------------------------------------------------------------!
3411    SUBROUTINE netcdf_data_input_interpolate_3d( var, z_grid, z_file )
3412
3413       IMPLICIT NONE
3414
3415       INTEGER(iwp) ::  i       !< running index x-direction
3416       INTEGER(iwp) ::  il      !< lower index bound along x-direction
3417       INTEGER(iwp) ::  iu      !< upper index bound along x-direction
3418       INTEGER(iwp) ::  j       !< running index y-direction
3419       INTEGER(iwp) ::  jl      !< lower index bound along x-direction
3420       INTEGER(iwp) ::  ju      !< upper index bound along x-direction
3421       INTEGER(iwp) ::  k       !< running index z-direction file
3422       INTEGER(iwp) ::  kk      !< running index z-direction stretched model grid
3423       INTEGER(iwp) ::  kl      !< lower index bound along z-direction
3424       INTEGER(iwp) ::  ku      !< upper index bound along z-direction
3425       INTEGER(iwp) ::  nz_file !< number of vertical levels on file
3426
3427       REAL(wp), DIMENSION(:) ::  z_grid                      !< grid levels on numeric grid
3428       REAL(wp), DIMENSION(:) ::  z_file                      !< grid levels on file grid
3429       REAL(wp), DIMENSION(:,:,:), INTENT(INOUT) ::  var      !< treated variable
3430       REAL(wp), DIMENSION(:), ALLOCATABLE       ::  var_tmp  !< temporary variable
3431
3432       il = LBOUND(var,3)
3433       iu = UBOUND(var,3)
3434       jl = LBOUND(var,2)
3435       ju = UBOUND(var,2)
3436       kl = LBOUND(var,1)
3437       ku = UBOUND(var,1)
3438
3439       ALLOCATE( var_tmp(kl:ku) )
3440
3441       DO  i = il, iu
3442          DO  j = jl, ju
3443             DO  k = kl, ku
3444
3445                kk = MINLOC( ABS( z_file - z_grid(k) ), DIM = 1 ) 
3446
3447                IF ( kk < ku )  THEN
3448                   IF ( z_file(kk) - z_grid(k) <= 0.0_wp )  THEN
3449                      var_tmp(k) = var(kk,j,i) +                               &
3450                                             ( var(kk+1,j,i) - var(kk,j,i) ) / &
3451                                             ( z_file(kk+1)  - z_file(kk)  ) * &
3452                                             ( z_grid(k)     - z_file(kk)  ) 
3453
3454                   ELSEIF ( z_file(kk) - z_grid(k) > 0.0_wp )  THEN
3455                      var_tmp(k) = var(kk-1,j,i) +                             &
3456                                             ( var(kk,j,i) - var(kk-1,j,i) ) / &
3457                                             ( z_file(kk)  - z_file(kk-1)  ) * &
3458                                             ( z_grid(k)   - z_file(kk-1)  ) 
3459                   ENDIF
3460!
3461!--             Extrapolate
3462                ELSE
3463                   var_tmp(k) = var(ku,j,i) +                                  &
3464                                       ( var(ku,j,i)  - var(ku-1,j,i)   ) /    &
3465                                       ( z_file(ku)   - z_file(ku-1)    ) *    &
3466                                       ( z_grid(k)    - z_file(ku)      ) 
3467
3468                ENDIF
3469             ENDDO
3470             var(:,j,i) = var_tmp(:)
3471          ENDDO
3472       ENDDO
3473
3474       DEALLOCATE( var_tmp )
3475
3476
3477    END SUBROUTINE netcdf_data_input_interpolate_3d
3478
3479!------------------------------------------------------------------------------!
3480! Description:
3481! ------------
3482!> Checks if a given variables is on file
3483!------------------------------------------------------------------------------!
3484    FUNCTION check_existence( vars_in_file, var_name )
3485
3486       IMPLICIT NONE
3487
3488       CHARACTER(LEN=*) ::  var_name                   !< variable to be checked
3489       CHARACTER(LEN=*), DIMENSION(:) ::  vars_in_file !< list of variables in file
3490
3491       INTEGER(iwp) ::  i                              !< loop variable
3492
3493       LOGICAL ::  check_existence                     !< flag indicating whether a variable exist or not - actual return value
3494
3495       i = 1
3496       check_existence = .FALSE.
3497       DO  WHILE ( i <= SIZE( vars_in_file ) )
3498          check_existence = TRIM( vars_in_file(i) ) == TRIM( var_name )  .OR.  &
3499                            check_existence
3500          i = i + 1
3501       ENDDO
3502
3503       RETURN
3504
3505    END FUNCTION check_existence
3506
3507
3508!------------------------------------------------------------------------------!
3509! Description:
3510! ------------
3511!> Closes an existing netCDF file.
3512!------------------------------------------------------------------------------!
3513    SUBROUTINE close_input_file( id )
3514#if defined( __netcdf )
3515
3516       USE pegrid
3517
3518       IMPLICIT NONE
3519
3520       INTEGER(iwp), INTENT(INOUT)        ::  id        !< file id
3521
3522       nc_stat = NF90_CLOSE( id )
3523       CALL handle_error( 'close', 537 )
3524#endif
3525    END SUBROUTINE close_input_file
3526
3527!------------------------------------------------------------------------------!
3528! Description:
3529! ------------
3530!> Opens an existing netCDF file for reading only and returns its id.
3531!------------------------------------------------------------------------------!
3532    SUBROUTINE open_read_file( filename, id )
3533#if defined( __netcdf )
3534
3535       USE pegrid
3536
3537       IMPLICIT NONE
3538
3539       CHARACTER (LEN=*), INTENT(IN) ::  filename  !< filename
3540       INTEGER(iwp), INTENT(INOUT)   ::  id        !< file id
3541       LOGICAL                       ::  file_open = .FALSE.
3542
3543       nc_stat = NF90_OPEN( filename, NF90_NOWRITE, id )
3544
3545       CALL handle_error( 'open_read_file', 536 )
3546
3547#endif
3548    END SUBROUTINE open_read_file
3549
3550!------------------------------------------------------------------------------!
3551! Description:
3552! ------------
3553!> Reads global or variable-related attributes of type INTEGER (32-bit)
3554!------------------------------------------------------------------------------!
3555     SUBROUTINE get_attribute_int32( id, attribute_name, value, global,        &
3556                                     variable_name )
3557
3558       USE pegrid
3559
3560       IMPLICIT NONE
3561
3562       CHARACTER(LEN=*)            ::  attribute_name   !< attribute name
3563       CHARACTER(LEN=*), OPTIONAL  ::  variable_name    !< variable name
3564
3565       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3566       INTEGER(iwp)                ::  id_var           !< variable id
3567       INTEGER(iwp), INTENT(INOUT) ::  value            !< read value
3568
3569       LOGICAL, INTENT(IN) ::  global                   !< flag indicating global attribute
3570#if defined( __netcdf )
3571
3572!
3573!--    Read global attribute
3574       IF ( global )  THEN
3575          nc_stat = NF90_GET_ATT( id, NF90_GLOBAL, TRIM( attribute_name ), value )
3576          CALL handle_error( 'get_attribute_int32 global', 522 )
3577!
3578!--    Read attributes referring to a single variable. Therefore, first inquire
3579!--    variable id
3580       ELSE
3581          nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3582          CALL handle_error( 'get_attribute_int32', 522 )
3583          nc_stat = NF90_GET_ATT( id, id_var, TRIM( attribute_name ), value )
3584          CALL handle_error( 'get_attribute_int32', 522 )       
3585       ENDIF
3586#endif
3587    END SUBROUTINE get_attribute_int32
3588
3589!------------------------------------------------------------------------------!
3590! Description:
3591! ------------
3592!> Reads global or variable-related attributes of type INTEGER (8-bit)
3593!------------------------------------------------------------------------------!
3594     SUBROUTINE get_attribute_int8( id, attribute_name, value, global,         &
3595                                    variable_name )
3596
3597       USE pegrid
3598
3599       IMPLICIT NONE
3600
3601       CHARACTER(LEN=*)            ::  attribute_name   !< attribute name
3602       CHARACTER(LEN=*), OPTIONAL  ::  variable_name    !< variable name
3603
3604       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3605       INTEGER(iwp)                ::  id_var           !< variable id
3606       INTEGER(KIND=1), INTENT(INOUT) ::  value         !< read value
3607
3608       LOGICAL, INTENT(IN) ::  global                   !< flag indicating global attribute
3609#if defined( __netcdf )
3610
3611!
3612!--    Read global attribute
3613       IF ( global )  THEN
3614          nc_stat = NF90_GET_ATT( id, NF90_GLOBAL, TRIM( attribute_name ), value )
3615          CALL handle_error( 'get_attribute_int8 global', 523 )
3616!
3617!--    Read attributes referring to a single variable. Therefore, first inquire
3618!--    variable id
3619       ELSE
3620          nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3621          CALL handle_error( 'get_attribute_int8', 523 )
3622          nc_stat = NF90_GET_ATT( id, id_var, TRIM( attribute_name ), value )
3623          CALL handle_error( 'get_attribute_int8', 523 )       
3624       ENDIF
3625#endif
3626    END SUBROUTINE get_attribute_int8
3627
3628!------------------------------------------------------------------------------!
3629! Description:
3630! ------------
3631!> Reads global or variable-related attributes of type REAL
3632!------------------------------------------------------------------------------!
3633     SUBROUTINE get_attribute_real( id, attribute_name, value, global,         &
3634                                    variable_name )
3635
3636       USE pegrid
3637
3638       IMPLICIT NONE
3639
3640       CHARACTER(LEN=*)            ::  attribute_name   !< attribute name
3641       CHARACTER(LEN=*), OPTIONAL  ::  variable_name    !< variable name
3642
3643       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3644       INTEGER(iwp)                ::  id_var           !< variable id
3645
3646       LOGICAL, INTENT(IN) ::  global                   !< flag indicating global attribute
3647
3648       REAL(wp), INTENT(INOUT)     ::  value            !< read value
3649#if defined( __netcdf )
3650
3651
3652!
3653!-- Read global attribute
3654       IF ( global )  THEN
3655          nc_stat = NF90_GET_ATT( id, NF90_GLOBAL, TRIM( attribute_name ), value )
3656          CALL handle_error( 'get_attribute_real global', 524 )
3657!
3658!-- Read attributes referring to a single variable. Therefore, first inquire
3659!-- variable id
3660       ELSE
3661          nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3662          CALL handle_error( 'get_attribute_real', 524 )
3663          nc_stat = NF90_GET_ATT( id, id_var, TRIM( attribute_name ), value )
3664          CALL handle_error( 'get_attribute_real', 524 )       
3665       ENDIF
3666#endif
3667    END SUBROUTINE get_attribute_real
3668
3669!------------------------------------------------------------------------------!
3670! Description:
3671! ------------
3672!> Reads global or variable-related attributes of type CHARACTER
3673!> Remark: reading attributes of type NF_STRING return an error code 56 -
3674!> Attempt to convert between text & numbers.
3675!------------------------------------------------------------------------------!
3676     SUBROUTINE get_attribute_string( id, attribute_name, value, global,       &
3677                                      variable_name )
3678
3679       USE pegrid
3680
3681       IMPLICIT NONE
3682
3683       CHARACTER(LEN=*)                ::  attribute_name   !< attribute name
3684       CHARACTER(LEN=*), OPTIONAL      ::  variable_name    !< variable name
3685       CHARACTER(LEN=*), INTENT(INOUT) ::  value            !< read value
3686
3687       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3688       INTEGER(iwp)                ::  id_var           !< variable id
3689
3690       LOGICAL, INTENT(IN) ::  global                   !< flag indicating global attribute
3691#if defined( __netcdf )
3692
3693!
3694!--    Read global attribute
3695       IF ( global )  THEN
3696          nc_stat = NF90_GET_ATT( id, NF90_GLOBAL, TRIM( attribute_name ), value )
3697          CALL handle_error( 'get_attribute_string global', 525 )
3698!
3699!--    Read attributes referring to a single variable. Therefore, first inquire
3700!--    variable id
3701       ELSE
3702          nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3703          CALL handle_error( 'get_attribute_string', 525 )
3704
3705          nc_stat = NF90_GET_ATT( id, id_var, TRIM( attribute_name ), value )
3706          CALL handle_error( 'get_attribute_string',525 ) 
3707
3708       ENDIF
3709#endif
3710    END SUBROUTINE get_attribute_string
3711
3712
3713
3714!------------------------------------------------------------------------------!
3715! Description:
3716! ------------
3717!> Get dimension array for a given dimension
3718!------------------------------------------------------------------------------!
3719     SUBROUTINE get_dimension_length( id, dim_len, variable_name )
3720#if defined( __netcdf )
3721
3722       USE pegrid
3723
3724       IMPLICIT NONE
3725
3726       CHARACTER(LEN=*)            ::  variable_name    !< dimension name
3727       CHARACTER(LEN=100)          ::  dum              !< dummy variable to receive return character
3728
3729       INTEGER(iwp)                ::  dim_len          !< dimension size
3730       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3731       INTEGER(iwp)                ::  id_dim           !< dimension id
3732
3733!
3734!--    First, inquire dimension ID
3735       nc_stat = NF90_INQ_DIMID( id, TRIM( variable_name ), id_dim )
3736       CALL handle_error( 'get_dimension_length', 526 )
3737!
3738!--    Inquire dimension length
3739       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim, dum, LEN = dim_len )
3740       CALL handle_error( 'get_dimension_length', 526 ) 
3741
3742#endif
3743    END SUBROUTINE get_dimension_length
3744
3745!------------------------------------------------------------------------------!
3746! Description:
3747! ------------
3748!> Reads a 1D integer variable from file.
3749!------------------------------------------------------------------------------!
3750     SUBROUTINE get_variable_1d_int( id, variable_name, var )
3751
3752       USE pegrid
3753
3754       IMPLICIT NONE
3755
3756       CHARACTER(LEN=*)            ::  variable_name    !< variable name
3757
3758       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3759       INTEGER(iwp)                ::  id_var           !< dimension id
3760
3761       INTEGER(iwp), DIMENSION(:), INTENT(INOUT) ::  var  !< variable to be read
3762#if defined( __netcdf )
3763
3764!
3765!--    First, inquire variable ID
3766       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3767       CALL handle_error( 'get_variable_1d_int', 527 )
3768!
3769!--    Inquire dimension length
3770       nc_stat = NF90_GET_VAR( id, id_var, var )
3771       CALL handle_error( 'get_variable_1d_int', 527 ) 
3772
3773#endif
3774    END SUBROUTINE get_variable_1d_int
3775
3776!------------------------------------------------------------------------------!
3777! Description:
3778! ------------
3779!> Reads a 1D float variable from file.
3780!------------------------------------------------------------------------------!
3781     SUBROUTINE get_variable_1d_real( id, variable_name, var )
3782
3783       USE pegrid
3784
3785       IMPLICIT NONE
3786
3787       CHARACTER(LEN=*)            ::  variable_name    !< variable name
3788
3789       INTEGER(iwp), INTENT(IN)    ::  id               !< file id
3790       INTEGER(iwp)                ::  id_var           !< dimension id
3791
3792       REAL(wp), DIMENSION(:), INTENT(INOUT) ::  var  !< variable to be read
3793#if defined( __netcdf )
3794
3795!
3796!--    First, inquire variable ID
3797       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3798       CALL handle_error( 'get_variable_1d_real', 527 )
3799!
3800!--    Inquire dimension length
3801       nc_stat = NF90_GET_VAR( id, id_var, var )
3802       CALL handle_error( 'get_variable_1d_real', 527 ) 
3803
3804#endif
3805    END SUBROUTINE get_variable_1d_real
3806
3807!------------------------------------------------------------------------------!
3808! Description:
3809! ------------
3810!> Reads a 2D REAL variable from a file. Reading is done processor-wise,
3811!> i.e. each core reads its own domain in slices along x.
3812!------------------------------------------------------------------------------!
3813    SUBROUTINE get_variable_2d_real( id, variable_name, i, var )
3814
3815       USE indices
3816       USE pegrid
3817
3818       IMPLICIT NONE
3819
3820       CHARACTER(LEN=*)              ::  variable_name   !< variable name
3821
3822       INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
3823       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
3824       INTEGER(iwp)                  ::  id_var          !< variable id
3825
3826       REAL(wp), DIMENSION(nys:nyn), INTENT(INOUT) ::  var  !< variable to be read
3827#if defined( __netcdf )
3828!
3829!--    Inquire variable id
3830       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3831!
3832!--    Get variable
3833       nc_stat = NF90_GET_VAR( id, id_var, var(nys:nyn),                       &
3834                               start = (/ i+1, nys+1 /),                       &
3835                               count = (/ 1, nyn - nys + 1 /) )
3836
3837       CALL handle_error( 'get_variable_2d_real', 528 )
3838#endif
3839    END SUBROUTINE get_variable_2d_real
3840
3841!------------------------------------------------------------------------------!
3842! Description:
3843! ------------
3844!> Reads a 2D 32-bit INTEGER variable from file. Reading is done processor-wise,
3845!> i.e. each core reads its own domain in slices along x.
3846!------------------------------------------------------------------------------!
3847    SUBROUTINE get_variable_2d_int32( id, variable_name, i, var )
3848
3849       USE indices
3850       USE pegrid
3851
3852       IMPLICIT NONE
3853
3854       CHARACTER(LEN=*)              ::  variable_name   !< variable name
3855
3856       INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
3857       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
3858       INTEGER(iwp)                  ::  id_var          !< variable id
3859       INTEGER(iwp), DIMENSION(nys:nyn), INTENT(INOUT) ::  var  !< variable to be read
3860#if defined( __netcdf )
3861!
3862!--    Inquire variable id
3863       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3864!
3865!--    Get variable
3866       nc_stat = NF90_GET_VAR( id, id_var, var(nys:nyn),                       &
3867                               start = (/ i+1, nys+1 /),                       &
3868                               count = (/ 1, nyn - nys + 1 /) )
3869
3870       CALL handle_error( 'get_variable_2d_int32', 529 )
3871#endif
3872    END SUBROUTINE get_variable_2d_int32
3873
3874!------------------------------------------------------------------------------!
3875! Description:
3876! ------------
3877!> Reads a 2D 8-bit INTEGER variable from file. Reading is done processor-wise,
3878!> i.e. each core reads its own domain in slices along x.
3879!------------------------------------------------------------------------------!
3880    SUBROUTINE get_variable_2d_int8( id, variable_name, i, var )
3881
3882       USE indices
3883       USE pegrid
3884
3885       IMPLICIT NONE
3886
3887       CHARACTER(LEN=*)              ::  variable_name   !< variable name
3888
3889       INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
3890       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
3891       INTEGER(iwp)                  ::  id_var          !< variable id
3892       INTEGER(KIND=1), DIMENSION(nys:nyn), INTENT(INOUT) ::  var  !< variable to be read
3893#if defined( __netcdf )
3894!
3895!--    Inquire variable id
3896       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3897!
3898!--    Get variable
3899       nc_stat = NF90_GET_VAR( id, id_var, var(nys:nyn),                       &
3900                               start = (/ i+1, nys+1 /),                       &
3901                               count = (/ 1, nyn - nys + 1 /) )
3902
3903       CALL handle_error( 'get_variable_2d_int8', 530 )
3904#endif
3905    END SUBROUTINE get_variable_2d_int8
3906
3907!------------------------------------------------------------------------------!
3908! Description:
3909! ------------
3910!> Reads a 3D 8-bit INTEGER variable from file.
3911!------------------------------------------------------------------------------!
3912    SUBROUTINE get_variable_3d_int8( id, variable_name, i, j, var )
3913
3914       USE indices
3915       USE pegrid
3916
3917       IMPLICIT NONE
3918
3919       CHARACTER(LEN=*)              ::  variable_name   !< variable name
3920
3921       INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
3922       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
3923       INTEGER(iwp)                  ::  id_var          !< variable id
3924       INTEGER(iwp), INTENT(IN)      ::  j               !< index along y direction
3925       INTEGER(iwp)                  ::  n_file          !< number of data-points along 3rd dimension
3926
3927       INTEGER(iwp), DIMENSION(1:3)  ::  id_dim
3928
3929       INTEGER( KIND = 1 ), DIMENSION(nzb:nzt+1), INTENT(INOUT) ::  var  !< variable to be read
3930#if defined( __netcdf )
3931
3932!
3933!--    Inquire variable id
3934       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3935!
3936!--    Get length of first dimension, required for the count parameter.
3937!--    Therefore, first inquired dimension ids
3938       nc_stat = NF90_INQUIRE_VARIABLE( id, id_var, DIMIDS = id_dim )
3939       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim(3), LEN = n_file )
3940!
3941!--    Get variable
3942       nc_stat = NF90_GET_VAR( id, id_var, var,                  &
3943                               start = (/ i+1, j+1, 1 /),                      &
3944                               count = (/ 1, 1, n_file /) )
3945
3946       CALL handle_error( 'get_variable_3d_int8', 531 )
3947#endif
3948    END SUBROUTINE get_variable_3d_int8
3949
3950
3951!------------------------------------------------------------------------------!
3952! Description:
3953! ------------
3954!> Reads a 3D float variable from file. 
3955!------------------------------------------------------------------------------!
3956    SUBROUTINE get_variable_3d_real( id, variable_name, i, j, var )
3957
3958       USE indices
3959       USE pegrid
3960
3961       IMPLICIT NONE
3962
3963       CHARACTER(LEN=*)              ::  variable_name   !< variable name
3964
3965       INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
3966       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
3967       INTEGER(iwp)                  ::  id_var          !< variable id
3968       INTEGER(iwp), INTENT(IN)      ::  j               !< index along y direction
3969       INTEGER(iwp)                  ::  n3              !< number of data-points along 3rd dimension
3970
3971       INTEGER(iwp), DIMENSION(3)    ::  id_dim
3972
3973       REAL(wp), DIMENSION(:), INTENT(INOUT) ::  var     !< variable to be read
3974#if defined( __netcdf )
3975
3976!
3977!--    Inquire variable id
3978       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
3979!
3980!--    Get length of first dimension, required for the count parameter.
3981!--    Therefore, first inquired dimension ids
3982       nc_stat = NF90_INQUIRE_VARIABLE( id, id_var, DIMIDS = id_dim )
3983       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim(3), LEN = n3 )
3984!
3985!--    Get variable
3986       nc_stat = NF90_GET_VAR( id, id_var, var,                                &
3987                               start = (/ i+1, j+1, 1 /),                      &
3988                               count = (/ 1, 1, n3 /) )
3989
3990       CALL handle_error( 'get_variable_3d_real', 532 )
3991#endif
3992    END SUBROUTINE get_variable_3d_real
3993
3994
3995!------------------------------------------------------------------------------!
3996! Description:
3997! ------------
3998!> Reads a 4D float variable from file. Note, in constrast to 3D versions,
3999!> dimensions are already inquired and passed so that they are known here.
4000!------------------------------------------------------------------------------!
4001    SUBROUTINE get_variable_4d_real( id, variable_name, i, j, var, n3, n4 )
4002
4003       USE indices
4004       USE pegrid
4005
4006       IMPLICIT NONE
4007
4008       CHARACTER(LEN=*)              ::  variable_name   !< variable name
4009
4010       INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
4011       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
4012       INTEGER(iwp)                  ::  id_var          !< variable id
4013       INTEGER(iwp), INTENT(IN)      ::  j               !< index along y direction
4014       INTEGER(iwp), INTENT(IN)      ::  n3              !< number of data-points along 3rd dimension
4015       INTEGER(iwp), INTENT(IN)      ::  n4              !< number of data-points along 4th dimension
4016
4017       INTEGER(iwp), DIMENSION(3)    ::  id_dim
4018
4019       REAL(wp), DIMENSION(:,:), INTENT(INOUT) ::  var     !< variable to be read
4020#if defined( __netcdf )
4021
4022!
4023!--    Inquire variable id
4024       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
4025!
4026!--    Get variable
4027       nc_stat = NF90_GET_VAR( id, id_var, var,                                &
4028                               start = (/ i+1, j+1, 1, 1 /),                   &
4029                               count = (/ 1, 1, n3, n4 /) )
4030
4031       CALL handle_error( 'get_variable_4d_real', 533 )
4032#endif
4033    END SUBROUTINE get_variable_4d_real
4034
4035
4036
4037!------------------------------------------------------------------------------!
4038! Description:
4039! ------------
4040!> Reads a 3D float variable at left, right, north, south and top boundaries.
4041!------------------------------------------------------------------------------!
4042    SUBROUTINE get_variable_bc( id, variable_name, t_start,                    &
4043                                i2_s, count_2, i3_s, count_3,  var )
4044
4045       USE indices
4046       USE pegrid
4047
4048       IMPLICIT NONE
4049
4050       CHARACTER(LEN=*)              ::  variable_name   !< variable name
4051
4052       INTEGER(iwp)                  ::  count_2         !< number of elements in second dimension
4053       INTEGER(iwp)                  ::  count_3         !< number of elements in third dimension (usually 1)
4054       INTEGER(iwp)                  ::  i2_s            !< start index of second dimension
4055       INTEGER(iwp)                  ::  i3_s            !< start index of third dimension
4056       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
4057       INTEGER(iwp)                  ::  id_var          !< variable id
4058       INTEGER(iwp)                  ::  t_start         !< start index at time dimension with respect to netcdf convention
4059
4060       REAL(wp), DIMENSION(:), INTENT(INOUT) ::  var     !< input variable
4061#if defined( __netcdf )
4062
4063!
4064!--    Inquire variable id
4065       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
4066!
4067!--    Get variable
4068       nc_stat = NF90_GET_VAR( id, id_var, var,                              &
4069                               start = (/ i3_s, i2_s, t_start /),            & 
4070                               count = (/ count_3, count_2, 1 /) )       
4071
4072       CALL handle_error( 'get_variable_bc', 532 )
4073#endif
4074    END SUBROUTINE get_variable_bc
4075
4076
4077
4078!------------------------------------------------------------------------------!
4079! Description:
4080! ------------
4081!> Inquires the number of variables in a file 
4082!------------------------------------------------------------------------------!
4083    SUBROUTINE inquire_num_variables( id, num_vars )
4084
4085       USE indices
4086       USE pegrid
4087
4088       IMPLICIT NONE
4089
4090       INTEGER(iwp), INTENT(IN)      ::  id              !< file id
4091       INTEGER(iwp), INTENT(INOUT)   ::  num_vars        !< number of variables in a file
4092#if defined( __netcdf )
4093
4094       nc_stat = NF90_INQUIRE( id, NVARIABLES = num_vars )
4095       CALL handle_error( 'inquire_num_variables', 534 )
4096
4097#endif
4098    END SUBROUTINE inquire_num_variables
4099
4100
4101!------------------------------------------------------------------------------!
4102! Description:
4103! ------------
4104!> Inquires the variable names belonging to a file.
4105!------------------------------------------------------------------------------!
4106    SUBROUTINE inquire_variable_names( id, var_names )
4107
4108       USE indices
4109       USE pegrid
4110
4111       IMPLICIT NONE
4112
4113       CHARACTER(LEN=*), DIMENSION(:), INTENT(INOUT) ::  var_names   !< return variable - variable names
4114       INTEGER(iwp)                                  ::  i           !< loop variable
4115       INTEGER(iwp), INTENT(IN)                      ::  id          !< file id
4116       INTEGER(iwp)                                  ::  num_vars    !< number of variables (unused return parameter)
4117       INTEGER(iwp), DIMENSION(:), ALLOCATABLE       ::  varids      !< dummy array to strore variable ids temporarily
4118#if defined( __netcdf )
4119
4120       ALLOCATE( varids(1:SIZE(var_names)) )
4121       nc_stat = NF90_INQ_VARIDS( id, NVARS = num_vars, VARIDS = varids )
4122       CALL handle_error( 'inquire_variable_names', 535 )
4123
4124       DO  i = 1, SIZE(var_names)
4125          nc_stat = NF90_INQUIRE_VARIABLE( id, varids(i), NAME = var_names(i) )
4126          CALL handle_error( 'inquire_variable_names', 535 )
4127       ENDDO
4128
4129       DEALLOCATE( varids )
4130#endif
4131    END SUBROUTINE inquire_variable_names
4132
4133!------------------------------------------------------------------------------!
4134! Description:
4135! ------------
4136!> Prints out a text message corresponding to the current status.
4137!------------------------------------------------------------------------------!
4138    SUBROUTINE handle_error( routine_name, errno )
4139
4140       USE control_parameters,                                                 &
4141           ONLY:  message_string
4142
4143       IMPLICIT NONE
4144
4145       CHARACTER(LEN=6) ::  message_identifier
4146       CHARACTER(LEN=*) ::  routine_name
4147
4148       INTEGER(iwp) ::  errno
4149#if defined( __netcdf )
4150
4151       IF ( nc_stat /= NF90_NOERR )  THEN
4152
4153          WRITE( message_identifier, '(''NC'',I4.4)' )  errno
4154          message_string = TRIM( NF90_STRERROR( nc_stat ) )
4155
4156          CALL message( routine_name, message_identifier, 2, 2, 0, 6, 1 )
4157
4158       ENDIF
4159
4160#endif
4161    END SUBROUTINE handle_error
4162
4163
4164 END MODULE netcdf_data_input_mod
Note: See TracBrowser for help on using the repository browser.