Changeset 3866


Ignore:
Timestamp:
Apr 5, 2019 2:25:01 PM (6 years ago)
Author:
eckhard
Message:

inifor: Use PALM's working precision; improved error handling, coding style, and comments

Location:
palm/trunk/UTIL
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified palm/trunk/UTIL/Makefile_utilities

    r3795 r3866  
    2323# -----------------
    2424# $Id$
     25# Use PALM's kinds module in inifor
     26#
     27#
     28# 3795 2019-03-15 09:40:05Z eckhard
    2529# Upated inifor build dependencies
    2630#
     
    141145        inifor_defs.o \
    142146        inifor_util.o
     147inifor_defs.o: \
     148        mod_kinds.o
    143149inifor_grid.o: \
    144150        inifor_control.o \
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor.f90

    r3785 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29! Show error message if compiled without netCDF support
     30! Renamed run_control -> log_runtime
     31! Improved coding style added comments
     32!
     33!
     34! 3785 2019-03-06 10:41:14Z eckhard
    2835! Average geostrophic wind components on coarse COSMO levels instead of fine PALM levels
    2936! Remove --debug netCDF output of internal pressure profiles
     
    8188!------------------------------------------------------------------------------!
    8289 PROGRAM inifor
     90
    8391#if defined ( __netcdf )
    8492
     
    8694    USE inifor_defs
    8795    USE inifor_grid,                                                           &
    88         ONLY:  setup_parameters, setup_grids, setup_variable_tables,           &
    89                setup_io_groups, fini_grids, fini_variables, fini_io_groups,    &
    90                fini_file_lists, preprocess, origin_lon, origin_lat,            &
    91                output_file, io_group_list, output_var_table,                   &
    92                cosmo_grid, palm_grid, nx, ny, nz, p0, cfg, f3,                 &
    93                averaging_width_ns, averaging_width_ew, phi_n, lambda_n,        &
    94                lam_centre, phi_centre
     96        ONLY:  averaging_width_ns,                                             &
     97               averaging_width_ew,                                             &
     98               cfg,                                                            &   
     99               cosmo_grid,                                                     &
     100               f3,                                                             &
     101               fini_grids,                                                     &
     102               fini_io_groups,                                                 &
     103               fini_variables,                                                 &
     104               fini_file_lists,                                                &
     105               io_group_list,                                                  &
     106               lam_centre,                                                     &
     107               lambda_n,                                                       &
     108               nx, ny, nz,                                                     &
     109               origin_lat,                                                     &
     110               origin_lon,                                                     &
     111               output_file,                                                    &
     112               output_var_table,                                               &
     113               p0,                                                             &
     114               phi_centre,                                                     &
     115               phi_n,                                                          &
     116               preprocess,                                                     &
     117               palm_grid,                                                      &
     118               setup_grids,                                                    &
     119               setup_parameters,                                               &
     120               setup_variable_tables,                                          &
     121               setup_io_groups
    95122    USE inifor_io
    96123    USE inifor_transform,                                                      &
    97         ONLY:  average_pressure_perturbation, average_profile, interpolate_1d, &
    98                interpolate_1d_arr, interpolate_2d, interpolate_3d,             &
    99                interp_average_profile, geostrophic_winds, extrapolate_density, &
    100                extrapolate_pressure, get_surface_pressure
     124        ONLY:  average_pressure_perturbation,                                  &
     125               average_profile,                                                &
     126               extrapolate_density,                                            &
     127               extrapolate_pressure,                                           &
     128               geostrophic_winds,                                              &
     129               get_surface_pressure,                                           &
     130               interp_average_profile,                                         &
     131               interpolate_1d,                                                 &
     132               interpolate_1d_arr,                                             &
     133               interpolate_2d,                                                 &
     134               interpolate_3d
    101135    USE inifor_types
    102136   
     
    107141    INTEGER ::  iter   !< loop index for time steps
    108142
    109     REAL(dp), ALLOCATABLE, DIMENSION(:,:,:)     ::  output_arr !< array buffer for interpolated quantities
    110     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_centre !< density profile of the centre averaging domain
    111     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  ug_cosmo   !< profile of the geostrophic wind in x direction on COSMO levels
    112     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  vg_cosmo   !< profile of the geostrophic wind in y direction on COSMO levels
    113     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  ug_palm    !< profile of the geostrophic wind in x direction interpolated onto PALM levels
    114     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  vg_palm    !< profile of the geostrophic wind in y direction interpolated onto PALM levels
    115     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_north  !< density profile of the northern averaging domain
    116     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_south  !< density profile of the southern averaging domain
    117     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_east   !< density profile of the eastern averaging domain
    118     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_west   !< density profile of the western averaging domain
    119     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_north    !< pressure profile of the northern averaging domain
    120     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_south    !< pressure profile of the southern averaging domain
    121     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_east     !< pressure profile of the eastern averaging domain
    122     REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_west     !< pressure profile of the western averaging domain
    123 
    124     REAL(dp), POINTER, DIMENSION(:) ::  internal_arr !< pointer to the currently processed internal array (density, pressure)
    125     REAL(dp), POINTER, DIMENSION(:) ::  ug_vg_palm   !< pointer to the currently processed geostrophic wind component
     143    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:)     ::  output_arr !< array buffer for interpolated quantities
     144    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_centre !< density profile of the centre averaging domain
     145    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  ug_cosmo   !< profile of the geostrophic wind in x direction on COSMO levels
     146    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  vg_cosmo   !< profile of the geostrophic wind in y direction on COSMO levels
     147    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  ug_palm    !< profile of the geostrophic wind in x direction interpolated onto PALM levels
     148    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  vg_palm    !< profile of the geostrophic wind in y direction interpolated onto PALM levels
     149    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_north  !< density profile of the northern averaging domain
     150    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_south  !< density profile of the southern averaging domain
     151    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_east   !< density profile of the eastern averaging domain
     152    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  rho_west   !< density profile of the western averaging domain
     153    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_north    !< pressure profile of the northern averaging domain
     154    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_south    !< pressure profile of the southern averaging domain
     155    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_east     !< pressure profile of the eastern averaging domain
     156    REAL(wp), ALLOCATABLE, DIMENSION(:), TARGET ::  p_west     !< pressure profile of the western averaging domain
     157
     158    REAL(wp), POINTER, DIMENSION(:) ::  internal_arr !< pointer to the currently processed internal array (density, pressure)
     159    REAL(wp), POINTER, DIMENSION(:) ::  ug_vg_palm   !< pointer to the currently processed geostrophic wind component
    126160
    127161    TYPE(nc_var), POINTER        ::  output_var      !< pointer to the currently processed output variable
     
    138172!- Section 1: Initialization
    139173!------------------------------------------------------------------------------
    140  CALL run_control('init', 'void')
     174    CALL log_runtime( 'init', 'void' )
    141175
    142176!
    143177!-- Initialize INIFOR's parameters from command-line interface and namelists
    144     CALL setup_parameters()
     178    CALL setup_parameters
    145179
    146180!
    147181!-- Initialize all grids, including interpolation neighbours and weights
    148     CALL setup_grids()
    149  CALL run_control('time', 'init')
     182    CALL setup_grids
     183    CALL log_runtime( 'time', 'init' )
    150184
    151185!
    152186!-- Initialize the netCDF output file and define dimensions
    153     CALL setup_netcdf_dimensions(output_file, palm_grid, cfg % start_date,    &
     187    CALL setup_netcdf_dimensions(output_file, palm_grid, cfg%start_date,    &
    154188                                 origin_lon, origin_lat)
    155  CALL run_control('time', 'write')
     189    CALL log_runtime( 'time', 'write' )
    156190
    157191!
    158192!-- Set up the tables containing the input and output variables and set
    159193!-- the corresponding netCDF dimensions for each output variable
    160     CALL setup_variable_tables(cfg % ic_mode)
    161  CALL run_control('time', 'write')
     194    CALL setup_variable_tables( cfg%ic_mode )
     195    CALL log_runtime( 'time', 'write' )
    162196
    163197!
    164198!-- Add the output variables to the netCDF output file
    165     CALL setup_netcdf_variables(output_file % name, output_var_table)
    166 
    167     CALL setup_io_groups()
    168  CALL run_control('time', 'init')
    169 
    170 !------------------------------------------------------------------------------
    171 !- Section 2: Main loop
    172 !------------------------------------------------------------------------------
    173     DO igroup = 1, SIZE(io_group_list)
     199    CALL setup_netcdf_variables( output_file%name, output_var_table )
     200
     201    CALL setup_io_groups
     202    CALL log_runtime( 'time', 'init' )
     203
     204!------------------------------------------------------------------------------
     205!-- Section 2: Main loop
     206!------------------------------------------------------------------------------
     207!
     208!-- Input and output variables are organized into IO groups. For instance, the
     209!-- 'thermodynamics' IO group bundles the input variaebls T, P, QV and the
     210!-- output variables p, theta, rho, and qv.
     211!-- An IO group bunldes variables that are physically dependent on each other.
     212!-- In case of the 'thermodynamics' group, theta = f(P,T), rho = f(P,T,QV).
     213    DO  igroup = 1, SIZE( io_group_list )
    174214
    175215       group => io_group_list(igroup)
    176        IF ( group % to_be_processed )  THEN
     216       IF ( group%to_be_processed )  THEN
    177217         
    178           DO iter = 1, group % nt
    179 
    180 !------------------------------------------------------------------------------
    181 !- Section 2.1: Read and preprocess input data
    182 !------------------------------------------------------------------------------
    183              CALL read_input_variables(group, iter, input_buffer)
    184  CALL run_control('time', 'read')
    185 
    186              CALL preprocess(group, input_buffer, cosmo_grid, iter)
    187  CALL run_control('time', 'comp')
     218!--       Loop over all output time steps for the current group.
     219          DO  iter = 1, group%nt
     220
     221!------------------------------------------------------------------------------
     222!-- Section 2.1: Read and preprocess input data
     223!------------------------------------------------------------------------------
     224             CALL read_input_variables( group, iter, input_buffer )
     225             CALL log_runtime( 'time', 'read' )
     226
     227!--          Carry out all required physical conversion of the input variables
     228!--          of the current IO group on the input (COSMO) grid. For instance,
     229!--          horizontal velocities are rotated to the PALM coordinate system and
     230!--          potential temperature is computed from the absolute temperature and
     231!--          pressure.
     232             CALL preprocess( group, input_buffer, cosmo_grid, iter )
     233             CALL log_runtime( 'time', 'comp' )
    188234
    189235             !TODO: move this assertion into 'preprocess'.
    190              IF ( .NOT. ALL(input_buffer(:) % is_preprocessed .AND. .TRUE.) )  THEN
    191                 message = "Input buffers for group '" // TRIM(group % kind) // &
    192                    "' could not be preprocessed sucessfully."
    193                 CALL inifor_abort('main loop', message)
     236             IF ( .NOT. ALL(input_buffer(:)%is_preprocessed .AND. .TRUE.) )  THEN
     237                message = "Input buffers for group '" // TRIM( group%kind ) // &
     238                          "' could not be preprocessed sucessfully."
     239                CALL inifor_abort( 'main loop', message )
    194240             ENDIF
    195241
    196242!------------------------------------------------------------------------------
    197 !- Section 2.2: Interpolate each output variable of the group
    198 !------------------------------------------------------------------------------
    199              DO ivar = 1, group % nv
    200 
    201                 output_var => group % out_vars( ivar )
    202 
    203                 IF ( output_var % to_be_processed .AND.                        &
    204                      iter .LE. output_var % nt )  THEN
    205 
    206                    message = "Processing '" // TRIM(output_var % name) //      &
    207                              "' (" // TRIM(output_var % kind) //               &
    208                              "), iteration " // TRIM(str(iter)) //" of " //    &
    209                              TRIM(str(output_var % nt))
    210                    CALL report('main loop', message)
    211 
    212                    SELECT CASE( TRIM(output_var % task) )
    213 
    214                    CASE( 'interpolate_2d' )
    215                    
    216                       SELECT CASE( TRIM(output_var % kind) )
    217                        
    218                       CASE( 'init soil' )
    219 
    220                          ALLOCATE( output_arr( 0:output_var % grid % nx,       &
    221                                                0:output_var % grid % ny,       &
    222                                                SIZE(output_var % grid % depths) ) )
    223 
    224                       CASE ( 'surface forcing' )
    225 
    226                          ALLOCATE( output_arr( 0:output_var % grid % nx,       &
    227                                                0:output_var % grid % ny, 1 ) )
    228 
    229                       CASE DEFAULT
    230 
    231                           message = "'" // TRIM(output_var % kind) // "' is not a soil variable"
    232                           CALL inifor_abort("main loop", message)
    233 
    234                       END SELECT
    235  CALL run_control('time', 'alloc')
    236 
    237                       CALL interpolate_2d(input_buffer(output_var % input_id) % array(:,:,:), &
    238                               output_arr(:,:,:), output_var % intermediate_grid, output_var)
    239  CALL run_control('time', 'comp')
    240 
    241 
    242                    CASE ( 'interpolate_3d' )
    243 
    244                       ALLOCATE( output_arr( 0:output_var % grid % nx,          &
    245                                             0:output_var % grid % ny,          &
    246                                             1:output_var % grid % nz ) )
    247 
    248  CALL run_control('time', 'alloc')
    249                       CALL interpolate_3d(                                     &
    250                          input_buffer(output_var % input_id) % array(:,:,:),   &
    251                          output_arr(:,:,:),                                    &
    252                          output_var % intermediate_grid,                       &
    253                          output_var % grid)
    254  CALL run_control('time', 'comp')
    255 
    256                    CASE ( 'average profile' )
    257 
    258                       ALLOCATE( output_arr( 0:output_var % grid % nx,          &
    259                                             0:output_var % grid % ny,          &
    260                                             1:output_var % grid % nz ) )
    261  CALL run_control('time', 'alloc')
     243!-- Section 2.2: Interpolate each output variable of the group
     244!------------------------------------------------------------------------------
     245             DO  ivar = 1, group%nv
     246
     247                output_var => group%out_vars(ivar)
     248
     249                IF ( output_var%to_be_processed .AND.                          &
     250                     iter .LE. output_var%nt )  THEN
     251
     252                   message = "Processing '" // TRIM( output_var%name ) //      &
     253                             "' (" // TRIM( output_var%kind ) //               &
     254                             "), iteration " // TRIM( str( iter ) ) //" of " //&
     255                             TRIM( str( output_var%nt ) )
     256                   CALL report( 'main loop', message )
     257
     258                   SELECT CASE( TRIM( output_var%task ) )
     259
     260!--                   2D horizontal interpolation
     261                      CASE( 'interpolate_2d' )
    262262                     
    263                       CALL interp_average_profile(                             &
    264                          input_buffer(output_var % input_id) % array(:,:,:),   &
    265                          output_arr(0,0,:),                                    &
    266                          output_var % averaging_grid)
    267 
    268                       IF ( TRIM(output_var % name) ==                          &
    269                            'surface_forcing_surface_pressure' )  THEN
    270 
    271                          IF ( cfg % p0_is_set )  THEN
    272                             output_arr(0,0,1) = p0
    273                          ELSE
    274                             CALL get_surface_pressure(                         &
    275                                output_arr(0,0,:), rho_centre,                  &
    276                                output_var % averaging_grid)
     263                         SELECT CASE( TRIM( output_var%kind ) )
     264                         
     265                         CASE( 'init soil' )
     266   
     267                            ALLOCATE( output_arr(0:output_var%grid%nx,            &
     268                                                 0:output_var%grid%ny,            &
     269                                                 SIZE( output_var%grid%depths )) )
     270   
     271                         CASE ( 'surface forcing' )
     272   
     273                            ALLOCATE( output_arr(0:output_var%grid%nx,            &
     274                                                 0:output_var%grid%ny, 1) )
     275   
     276                         CASE DEFAULT
     277   
     278                             message = "'" // TRIM( output_var%kind ) // "' is not a soil variable"
     279                             CALL inifor_abort( "main loop", message )
     280   
     281                         END SELECT
     282                         CALL log_runtime( 'time', 'alloc' )
     283   
     284                         CALL interpolate_2d( input_buffer(output_var%input_id)%array(:,:,:), &
     285                                 output_arr(:,:,:), output_var%intermediate_grid, output_var )
     286                         CALL log_runtime( 'time', 'comp' )
     287   
     288   
     289!--                   Interpolation in 3D, used for atmospheric initial and
     290!--                   boundary conditions.
     291                      CASE ( 'interpolate_3d' )
     292   
     293                         ALLOCATE( output_arr(0:output_var%grid % nx,           &
     294                                              0:output_var%grid % ny,           &
     295                                              1:output_var%grid % nz) )
     296   
     297                         CALL log_runtime( 'time', 'alloc' )
     298                         CALL interpolate_3d(                                     &
     299                            input_buffer(output_var%input_id)%array(:,:,:),       &
     300                            output_arr(:,:,:),                                    &
     301                            output_var%intermediate_grid,                         &
     302                            output_var%grid)
     303                         CALL log_runtime( 'time', 'comp' )
     304   
     305!--                   Compute initial avaerage profiles (if --init-mode profile
     306!--                   is used)
     307                      CASE ( 'average profile' )
     308   
     309                         ALLOCATE( output_arr(0:output_var%grid%nx,               &
     310                                              0:output_var%grid%ny,               &
     311                                              1:output_var%grid%nz) )
     312                         CALL log_runtime( 'time', 'alloc' )
     313                         
     314                         CALL interp_average_profile(                             &
     315                            input_buffer(output_var%input_id)%array(:,:,:),     &
     316                            output_arr(0,0,:),                                    &
     317                            output_var%averaging_grid )
     318   
     319                         IF ( TRIM( output_var%name ) ==                          &
     320                              'surface_forcing_surface_pressure' )  THEN
     321   
     322                            IF ( cfg%p0_is_set )  THEN
     323                               output_arr(0,0,1) = p0
     324                            ELSE
     325                               CALL get_surface_pressure(                         &
     326                                  output_arr(0,0,:), rho_centre,                  &
     327                                  output_var%averaging_grid )
     328                            ENDIF
     329   
    277330                         ENDIF
    278 
    279                       ENDIF
    280  CALL run_control('time', 'comp')
    281 
    282                    CASE ( 'internal profile' )
    283 
    284                       message = "Averaging of internal profile for variable '" //&
    285                          TRIM(output_var % name) // "' is not supported."
    286 
    287                       SELECT CASE (TRIM(output_var % name))
    288 
    289                       CASE('internal_density_centre')
    290                          ALLOCATE( rho_centre( 1:cosmo_grid % nz) )
    291                          internal_arr => rho_centre
    292 
    293                       CASE('internal_density_north')
    294                          ALLOCATE( rho_north( 1:cosmo_grid % nz) )
    295                          internal_arr => rho_north
    296 
    297                       CASE('internal_density_south')
    298                          ALLOCATE( rho_south( 1:cosmo_grid % nz) )
    299                          internal_arr => rho_south
    300 
    301                       CASE('internal_density_east')
    302                          ALLOCATE( rho_east( 1:cosmo_grid % nz) )
    303                          internal_arr => rho_east
    304 
    305                       CASE('internal_density_west')
    306                          ALLOCATE( rho_west( 1:cosmo_grid % nz) )
    307                          internal_arr => rho_west
    308 
    309                       CASE('internal_pressure_north')
    310                          ALLOCATE( p_north( 1:cosmo_grid % nz) )
    311                          internal_arr => p_north
    312 
    313                       CASE('internal_pressure_south')
    314                          ALLOCATE( p_south( 1:cosmo_grid % nz) )
    315                          internal_arr => p_south
    316 
    317                       CASE('internal_pressure_east')
    318                          ALLOCATE( p_east( 1:cosmo_grid % nz) )
    319                          internal_arr => p_east
    320 
    321                       CASE('internal_pressure_west')
    322                          ALLOCATE( p_west( 1:cosmo_grid % nz) )
    323                          internal_arr => p_west
    324 
    325                       CASE DEFAULT
    326                          CALL inifor_abort('main loop', message)
    327 
    328                       END SELECT
    329  CALL run_control('time', 'alloc')
    330 
    331 
    332                       SELECT CASE( TRIM( output_var % name ) )
    333 
    334                       CASE( 'internal_pressure_north',                         &
    335                             'internal_pressure_south',                         &
    336                             'internal_pressure_east',                          &
    337                             'internal_pressure_west' )
    338 
    339                          CALL average_pressure_perturbation(                   &
    340                             input_buffer(output_var % input_id) % array(:,:,:),&
    341                             internal_arr(:),                                   &
    342                             cosmo_grid, output_var % averaging_grid            &
    343                          )
    344 
    345                       CASE DEFAULT
    346 
    347                          CALL average_profile(                                 &
    348                             input_buffer(output_var % input_id) % array(:,:,:),&
    349                             internal_arr(:),                                   &
    350                             output_var % averaging_grid                        &
    351                          )
     331                         CALL log_runtime( 'time', 'comp' )
     332   
     333!--                   Compute internal profiles, required for differentiation of
     334!--                   geostrophic wind
     335                      CASE ( 'internal profile' )
     336   
     337                         message = "Averaging of internal profile for variable '" //&
     338                            TRIM( output_var%name ) // "' is not supported."
     339   
     340                         SELECT CASE ( TRIM( output_var%name ) )
     341   
     342                         CASE( 'internal_density_centre' )
     343                            ALLOCATE( rho_centre(1:cosmo_grid%nz) )
     344                            internal_arr => rho_centre
     345   
     346                         CASE( 'internal_density_north' )
     347                            ALLOCATE( rho_north(1:cosmo_grid%nz) )
     348                            internal_arr => rho_north
     349   
     350                         CASE( 'internal_density_south' )
     351                            ALLOCATE( rho_south(1:cosmo_grid%nz) )
     352                            internal_arr => rho_south
     353   
     354                         CASE( 'internal_density_east' )
     355                            ALLOCATE( rho_east(1:cosmo_grid%nz) )
     356                            internal_arr => rho_east
     357   
     358                         CASE( 'internal_density_west' )
     359                            ALLOCATE( rho_west(1:cosmo_grid%nz) )
     360                            internal_arr => rho_west
     361   
     362                         CASE( 'internal_pressure_north' )
     363                            ALLOCATE( p_north(1:cosmo_grid%nz) )
     364                            internal_arr => p_north
     365   
     366                         CASE( 'internal_pressure_south' )
     367                            ALLOCATE( p_south(1:cosmo_grid%nz) )
     368                            internal_arr => p_south
     369   
     370                         CASE( 'internal_pressure_east' )
     371                            ALLOCATE( p_east(1:cosmo_grid%nz) )
     372                            internal_arr => p_east
     373   
     374                         CASE( 'internal_pressure_west' )
     375                            ALLOCATE( p_west(1:cosmo_grid%nz) )
     376                            internal_arr => p_west
     377   
     378                         CASE DEFAULT
     379                            CALL inifor_abort( 'main loop', message )
     380   
     381                         END SELECT
     382                         CALL log_runtime( 'time', 'alloc' )
     383   
     384   
     385                         SELECT CASE( TRIM( output_var%name ) )
     386   
     387                         CASE( 'internal_pressure_north',                         &
     388                               'internal_pressure_south',                         &
     389                               'internal_pressure_east',                          &
     390                               'internal_pressure_west' )
     391   
     392                            CALL average_pressure_perturbation(                   &
     393                               input_buffer(output_var%input_id) % array(:,:,:),&
     394                               internal_arr(:),                                   &
     395                               cosmo_grid, output_var%averaging_grid            &
     396                            )
     397   
     398                         CASE DEFAULT
     399   
     400                            CALL average_profile(                                 &
     401                               input_buffer(output_var%input_id) % array(:,:,:),&
     402                               internal_arr(:),                                   &
     403                               output_var%averaging_grid                        &
     404                            )
    352405
    353406                      END SELECT
     
    360413!--                   (requires definiton of COSMO levels in netCDF output.)
    361414                      !IF (.TRUE.)  THEN
    362                       !   ALLOCATE( output_arr(1,1,1:output_var % grid % nz) )
     415                      !   ALLOCATE( output_arr(1,1,1:output_var%grid % nz) )
    363416                      !   output_arr(1,1,:) = internal_arr(:)
    364417                      !ENDIF
    365  CALL run_control('time', 'comp')
     418                      CALL log_runtime( 'time', 'comp' )
    366419
    367420!
     
    372425
    373426                      IF (.NOT. ug_vg_have_been_computed )  THEN
    374                          ALLOCATE( ug_palm(output_var % grid % nz) )
    375                          ALLOCATE( vg_palm(output_var % grid % nz) )
    376                          ALLOCATE( ug_cosmo(cosmo_grid % nz) )
    377                          ALLOCATE( vg_cosmo(cosmo_grid % nz) )
    378 
    379                          IF ( cfg % ug_defined_by_user )  THEN
    380                             ug_palm = cfg % ug
    381                             vg_palm = cfg % vg
     427                         ALLOCATE( ug_palm(output_var%grid%nz) )
     428                         ALLOCATE( vg_palm(output_var%grid%nz) )
     429                         ALLOCATE( ug_cosmo(cosmo_grid%nz) )
     430                         ALLOCATE( vg_cosmo(cosmo_grid%nz) )
     431
     432                         IF ( cfg%ug_defined_by_user )  THEN
     433                            ug_palm = cfg%ug
     434                            vg_palm = cfg%vg
    382435                         ELSE
    383436                            CALL geostrophic_winds( p_north, p_south, p_east,  &
     
    390443
    391444                            CALL interpolate_1d( ug_cosmo, ug_palm,             &
    392                                                  output_var % grid )
     445                                                 output_var%grid )
    393446
    394447                            CALL interpolate_1d( vg_cosmo, vg_palm,             &
    395                                                  output_var % grid )
     448                                                 output_var%grid )
    396449                         ENDIF
    397450
     
    402455!
    403456!--                   Select output array of current geostrophic wind component
    404                       SELECT CASE(TRIM(output_var % name))
    405                       CASE ('ls_forcing_ug')
     457                      SELECT CASE( TRIM( output_var%name ) )
     458                      CASE ( 'ls_forcing_ug' )
    406459                         ug_vg_palm => ug_palm
    407                       CASE ('ls_forcing_vg')
     460                      CASE ( 'ls_forcing_vg' )
    408461                         ug_vg_palm => vg_palm
    409462                      END SELECT
    410463
    411                       ALLOCATE( output_arr(1,1,output_var % grid % nz) )
     464                      ALLOCATE( output_arr(1,1,output_var%grid%nz) )
    412465                      output_arr(1,1,:) = ug_vg_palm(:)
    413466
    414                    CASE ( 'average scalar' )
    415 
    416                       ALLOCATE( output_arr(1,1,1) )
    417  CALL run_control('time', 'alloc')
    418                       output_arr(1,1,1) = p0
    419  CALL run_control('time', 'comp')
    420 
     467!--                User defined constant profiles
    421468                   CASE ( 'set profile' )
    422469                     
    423                       ALLOCATE( output_arr( 1, 1, 1:nz ) )
    424  CALL run_control('time', 'alloc')
    425 
    426                       SELECT CASE (TRIM(output_var % name))
    427 
    428                       CASE('nudging_tau')
     470                      ALLOCATE( output_arr(1,1,1:nz) )
     471                      CALL log_runtime( 'time', 'alloc' )
     472
     473                      SELECT CASE ( TRIM( output_var%name ) )
     474
     475                      CASE ( 'nudging_tau' )
    429476                          output_arr(1, 1, :) = NUDGING_TAU
    430477
    431478                      CASE DEFAULT
    432                           message = "'" // TRIM(output_var % name) //          &
    433                              "' is not a valid '" // TRIM(output_var % kind) //&
     479                          message = "'" // TRIM( output_var%name ) //          &
     480                             "' is not a valid '" // TRIM( output_var%kind ) //&
    434481                             "' variable kind."
    435                           CALL inifor_abort('main loop', message)
     482                          CALL inifor_abort( 'main loop', message )
    436483                      END SELECT
    437  CALL run_control('time', 'comp')
    438 
    439                    CASE('average large-scale profile')
    440                       message = "Averaging of large-scale forcing profiles " //&
    441                                 "has not been implemented, yet."
    442                       CALL inifor_abort('main loop', message)
     484                      CALL log_runtime( 'time', 'comp' )
    443485
    444486                   CASE DEFAULT
    445                       message = "Processing task '" // TRIM(output_var % task) //&
     487                      message = "Processing task '" // TRIM( output_var%task ) //&
    446488                               "' not recognized."
    447                       CALL inifor_abort('', message)
     489                      CALL inifor_abort( '', message )
    448490
    449491                   END SELECT
    450  CALL run_control('time', 'comp')
     492                   CALL log_runtime( 'time', 'comp' )
    451493
    452494!------------------------------------------------------------------------------
     
    458500!--                defined on averaged COSMO levels instead of PALM levels
    459501!--                (requires definiton of COSMO levels in netCDF output.)
    460                    !IF (.NOT. output_var % is_internal .OR. debugging_output)  THEN
    461 
    462                    IF (.NOT. output_var % is_internal)  THEN
    463                       message = "Writing variable '" // TRIM(output_var%name) // "'."
    464                       CALL report('main loop', message)
    465                       CALL update_output(output_var, output_arr, iter,         &
    466                                          output_file, cfg)
    467  CALL run_control('time', 'write')
     502                   !IF (.NOT. output_var%is_internal .OR. debugging_output)  THEN
     503
     504                   IF ( .NOT. output_var%is_internal )  THEN
     505                      message = "Writing variable '" // TRIM( output_var%name ) // "'."
     506                      CALL report( 'main loop', message )
     507                      CALL update_output( output_var, output_arr, iter,        &
     508                                          output_file, cfg )
     509                      CALL log_runtime( 'time', 'write' )
    468510                   ENDIF
    469511
    470                    IF (ALLOCATED(output_arr))  DEALLOCATE(output_arr)
    471  CALL run_control('time', 'alloc')
     512                   IF ( ALLOCATED( output_arr ) )  DEALLOCATE( output_arr )
     513                   CALL log_runtime( 'time', 'alloc' )
    472514
    473515                ENDIF
     
    478520
    479521             ug_vg_have_been_computed = .FALSE.
    480              IF ( group % kind == 'thermodynamics' )  THEN
     522             IF ( group%kind == 'thermodynamics' )  THEN
    481523                DEALLOCATE( rho_centre )
    482524                DEALLOCATE( ug_palm )
     
    484526                DEALLOCATE( ug_cosmo )
    485527                DEALLOCATE( vg_cosmo )
    486                 IF ( .NOT. cfg % ug_defined_by_user )  THEN
     528                IF ( .NOT. cfg%ug_defined_by_user )  THEN
    487529                   DEALLOCATE( rho_north )
    488530                   DEALLOCATE( rho_south )
     
    499541!--          Keep input buffer around for averaged (radiation) and
    500542!--          accumulated COSMO quantities (precipitation).
    501              IF ( group % kind == 'running average' .OR. &
    502                   group % kind == 'accumulated' )  THEN
     543             IF ( group%kind == 'running average' .OR. &
     544                  group%kind == 'accumulated' )  THEN
    503545             ELSE
    504                 CALL report('main loop', 'Deallocating input buffer', cfg % debug)
    505                 DEALLOCATE(input_buffer)
     546                CALL report( 'main loop', 'Deallocating input buffer', cfg%debug )
     547                DEALLOCATE( input_buffer )
    506548             ENDIF
    507  CALL run_control('time', 'alloc')
     549             CALL log_runtime( 'time', 'alloc' )
    508550
    509551!
     
    511553          ENDDO
    512554
    513           IF (ALLOCATED(input_buffer))  THEN
    514              CALL report('main loop', 'Deallocating input buffer', cfg % debug)
    515              DEALLOCATE(input_buffer)
     555          IF ( ALLOCATED( input_buffer ) )  THEN
     556             CALL report( 'main loop', 'Deallocating input buffer', cfg%debug )
     557             DEALLOCATE( input_buffer )
    516558          ENDIF
    517  CALL run_control('time', 'alloc')
     559          CALL log_runtime( 'time', 'alloc' )
    518560
    519561       ELSE
    520562
    521           message = "Skipping IO group " // TRIM(str(igroup)) // " '" // TRIM(group % kind) // "'"
    522           IF ( ALLOCATED(group % in_var_list) )  THEN
    523               message = TRIM(message) // " with input variable '" //           &
    524               TRIM(group % in_var_list(1) % name) // "'."
     563          message = "Skipping IO group " // TRIM( str( igroup ) ) // " '" // TRIM( group%kind ) // "'"
     564          IF ( ALLOCATED( group%in_var_list ) )  THEN
     565              message = TRIM( message ) // " with input variable '" //         &
     566              TRIM( group%in_var_list(1)%name ) // "'."
    525567          ENDIF
    526568
    527           CALL report('main loop', message, cfg % debug)
    528 
    529 !
    530 !--    IO group % to_be_processed conditional
     569          CALL report( 'main loop', message, cfg%debug )
     570
     571!
     572!--    IO group%to_be_processed conditional
    531573       ENDIF
    532574
     
    538580!- Section 3: Clean up.
    539581!------------------------------------------------------------------------------
    540     CALL fini_file_lists()
    541     CALL fini_io_groups()
    542     CALL fini_variables()
    543     !CALL fini_grids()
    544  CALL run_control('time', 'alloc')
    545  CALL run_control('report', 'void')
    546 
    547     message = "Finished writing dynamic driver '" // TRIM(output_file % name) // &
     582    CALL fini_file_lists
     583    CALL fini_io_groups
     584    CALL fini_variables
     585    !CALL fini_grids
     586    CALL log_runtime( 'time', 'alloc' )
     587    CALL log_runtime( 'report', 'void' )
     588
     589    message = "Finished writing dynamic driver '" // TRIM( output_file%name ) // &
    548590              "' successfully."
    549     CALL report('main loop', message)
    550 
    551 
     591    CALL report( 'main loop', message )
     592    CALL close_log
     593
     594#else
     595
     596    USE inifor_control
     597    IMPLICIT NONE
     598   
     599    message = "INIFOR was compiled without netCDF support, which is required for it to run. "  //     &
     600              "To use INIFOR, recompile PALM with netCDF support by adding the -D__netcdf " //        &
     601              "precompiler flag to your .palm.config file."
     602    CALL inifor_abort( 'main loop', message )
     603 
    552604#endif
     605
    553606 END PROGRAM inifor
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_control.f90

    r3785 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29! Renamed run_control -> log_runtime
     30! Open log file only once
     31! Improved coding style
     32!
     33!
     34! 3785 2019-03-06 10:41:14Z eckhard
    2835! Added message buffer for displaying tips to rectify encountered errors
    2936!
     
    6673!> feedback to the terminal and a log file.
    6774!------------------------------------------------------------------------------!
    68 #if defined ( __netcdf )
    6975 MODULE inifor_control
    7076
    7177    USE inifor_defs,                                                           &
    72         ONLY:  LNAME, dp, VERSION, COPYRIGHT
    73 
     78        ONLY:  COPYRIGHT, LNAME, LOG_FILE_NAME, VERSION, wp
    7479    USE inifor_util,                                                           &
    7580        ONLY:  real_to_str, real_to_str_f
     
    7984    CHARACTER (LEN=5000) ::  message = '' !< log message buffer
    8085    CHARACTER (LEN=5000) ::  tip     = '' !< optional log message buffer for tips on how to rectify encountered errors
     86    INTEGER, SAVE        ::  u            !< Fortran file unit for the log file
    8187
    8288 CONTAINS
     
    94100!> to it.
    95101!------------------------------------------------------------------------------!
    96     SUBROUTINE report(routine, message, debug)
    97 
    98        CHARACTER(LEN=*), INTENT(IN)  ::  routine !< name of calling subroutine of function
    99        CHARACTER(LEN=*), INTENT(IN)  ::  message !< log message
    100        LOGICAL, OPTIONAL, INTENT(IN) ::  debug   !< flag the current message as debugging message
    101 
    102        INTEGER                       ::  u                     !< Fortran file unit for the log file
    103        LOGICAL, SAVE                 ::  is_first_run = .TRUE. !< control flag for file opening mode
    104        LOGICAL                       ::  suppress_message      !< control falg for additional debugging log
    105 
    106 
    107        IF ( is_first_run )  THEN
    108           OPEN( NEWUNIT=u, FILE='inifor.log', STATUS='replace' )
    109           is_first_run = .FALSE.
    110        ELSE
    111           OPEN( NEWUNIT=u, FILE='inifor.log', POSITION='append', STATUS='old' )
    112        ENDIF
    113          
    114 
    115        suppress_message = .FALSE.
    116        IF ( PRESENT(debug) )  THEN
    117           IF ( .NOT. debug )  suppress_message = .TRUE.
    118        ENDIF
    119 
    120        IF ( .NOT. suppress_message )  THEN
    121           PRINT *, "inifor: " // TRIM(message) // "  [ " // TRIM(routine) // " ]"
    122           WRITE(u, *)  TRIM(message) // "  [ " // TRIM(routine) // " ]"
    123        ENDIF
    124 
    125        CLOSE(u)
    126 
    127     END SUBROUTINE report
     102 SUBROUTINE report(routine, message, debug)
     103
     104    CHARACTER(LEN=*), INTENT(IN)  ::  routine !< name of calling subroutine of function
     105    CHARACTER(LEN=*), INTENT(IN)  ::  message !< log message
     106    LOGICAL, OPTIONAL, INTENT(IN) ::  debug   !< flag the current message as debugging message
     107
     108    LOGICAL, SAVE                 ::  is_first_run = .TRUE. !< control flag for file opening mode
     109    LOGICAL                       ::  suppress_message      !< control falg for additional debugging log
     110
     111    IF ( is_first_run )  THEN
     112       OPEN( NEWUNIT=u, FILE=LOG_FILE_NAME, STATUS='replace' )
     113       is_first_run = .FALSE.
     114    ENDIF
     115       
     116
     117    suppress_message = .FALSE.
     118    IF ( PRESENT(debug) )  THEN
     119       IF ( .NOT. debug )  suppress_message = .TRUE.
     120    ENDIF
     121
     122    IF ( .NOT. suppress_message )  THEN
     123       PRINT *, "inifor: " // TRIM(message) // "  [ " // TRIM(routine) // " ]"
     124       WRITE(u, *)  TRIM(message) // "  [ " // TRIM(routine) // " ]"
     125    ENDIF
     126
     127 END SUBROUTINE report
    128128
    129129
     
    138138!> continue.
    139139!------------------------------------------------------------------------------!
    140     SUBROUTINE warn(routine, message)
    141 
    142        CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
    143        CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
    144 
    145        CALL report(routine, "WARNING: " // TRIM(message))
    146 
    147     END SUBROUTINE warn
     140 SUBROUTINE warn(routine, message)
     141
     142    CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
     143    CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
     144
     145    CALL report(routine, "WARNING: " // TRIM(message))
     146
     147 END SUBROUTINE warn
    148148
    149149
     
    158158!> INIFOR from continueing.
    159159!------------------------------------------------------------------------------!
    160     SUBROUTINE inifor_abort(routine, message)
    161 
    162        CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
    163        CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
    164 
    165        CALL report(routine, "ERROR: " // TRIM(message) // " Stopping.")
    166        STOP
    167 
    168     END SUBROUTINE inifor_abort
     160 SUBROUTINE inifor_abort(routine, message)
     161
     162    CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
     163    CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
     164
     165    CALL report(routine, "ERROR: " // TRIM(message) // " Stopping.")
     166    CALL close_log
     167    STOP
     168
     169 END SUBROUTINE inifor_abort
     170
     171
     172 SUBROUTINE close_log()
     173
     174    CLOSE(u)
     175
     176 END SUBROUTINE close_log
    169177
    170178
     
    175183!> print_version() prints the INIFOR version number and copyright notice.
    176184!------------------------------------------------------------------------------!
    177     SUBROUTINE print_version()
    178        PRINT *, "INIFOR " // VERSION
    179        PRINT *, COPYRIGHT
    180     END SUBROUTINE print_version
    181 
    182 
    183 !------------------------------------------------------------------------------!
    184 ! Description:
    185 ! ------------
    186 !>
    187 !> run_control() measures the run times of various parts of INIFOR and
     185 SUBROUTINE print_version()
     186    PRINT *, "INIFOR " // VERSION
     187    PRINT *, COPYRIGHT
     188 END SUBROUTINE print_version
     189
     190
     191!------------------------------------------------------------------------------!
     192! Description:
     193! ------------
     194!>
     195!> log_runtime() measures the run times of various parts of INIFOR and
    188196!> accumulates them in timing budgets.
    189197!------------------------------------------------------------------------------!
    190     SUBROUTINE run_control(mode, budget)
    191 
    192        CHARACTER(LEN=*), INTENT(IN) ::  mode   !< name of the calling mode
    193        CHARACTER(LEN=*), INTENT(IN) ::  budget !< name of the timing budget
    194 
    195        REAL(dp), SAVE ::  t0               !< begin of timing interval
    196        REAL(dp), SAVE ::  t1               !< end of timing interval
    197        REAL(dp), SAVE ::  t_comp  = 0.0_dp !< computation timing budget
    198        REAL(dp), SAVE ::  t_alloc = 0.0_dp !< allocation timing budget
    199        REAL(dp), SAVE ::  t_init  = 0.0_dp !< initialization timing budget
    200        REAL(dp), SAVE ::  t_read  = 0.0_dp !< reading timing budget
    201        REAL(dp), SAVE ::  t_total = 0.0_dp !< total time
    202        REAL(dp), SAVE ::  t_write = 0.0_dp !< writing timing budget
    203 
    204        CHARACTER(LEN=*), PARAMETER  ::  fmt='(F6.2)' !< floating-point output format
    205 
    206 
    207        SELECT CASE(TRIM(mode))
    208 
    209        CASE('init')
    210           CALL CPU_TIME(t0)
    211 
    212        CASE('time')
    213 
    214           CALL CPU_TIME(t1)
    215 
    216           SELECT CASE(TRIM(budget))
    217 
    218              CASE('alloc')
    219                 t_alloc = t_alloc + t1 - t0
    220 
    221              CASE('init')
    222                 t_init = t_init + t1 - t0
    223 
    224              CASE('read')
    225                 t_read = t_read + t1 - t0
    226 
    227              CASE('write')
    228                 t_write = t_write + t1 - t0
    229 
    230              CASE('comp')
    231                 t_comp = t_comp + t1 - t0
    232 
    233              CASE DEFAULT
    234                 CALL inifor_abort('run_control', "Time Budget '" // TRIM(mode) // "' is not supported.")
    235 
    236           END SELECT
    237 
    238           t0 = t1
    239 
    240        CASE('report')
    241            t_total = t_init + t_read + t_write + t_comp
    242 
    243            CALL report('run_control', " *** CPU time ***")
    244 
    245            CALL report('run_control', "Initialization: " // real_to_str(t_init)  // &
    246                        " s (" // TRIM(real_to_str(100*t_init/t_total, fmt))      // " %)")
    247 
    248            CALL report('run_control', "(De-)Allocation:" // real_to_str(t_alloc)  // &
    249                        " s (" // TRIM(real_to_str(100*t_alloc/t_total, fmt))      // " %)")
    250 
    251            CALL report('run_control', "Reading data:   " // real_to_str(t_read)  // &
    252                        " s (" // TRIM(real_to_str(100*t_read/t_total, fmt))      // " %)")
    253 
    254            CALL report('run_control', "Writing data:   " // real_to_str(t_write) // &
    255                        " s (" // TRIM(real_to_str(100*t_write/t_total, fmt))     // " %)")
    256 
    257            CALL report('run_control', "Computation:    " // real_to_str(t_comp)  // &
    258                        " s (" // TRIM(real_to_str(100*t_comp/t_total, fmt))      // " %)")
    259 
    260            CALL report('run_control', "Total:          " // real_to_str(t_total) // &
    261                        " s (" // TRIM(real_to_str(100*t_total/t_total, fmt))     // " %)")
    262 
    263        CASE DEFAULT
    264           CALL inifor_abort('run_control', "Mode '" // TRIM(mode) // "' is not supported.")
     198 SUBROUTINE log_runtime(mode, budget)
     199
     200    CHARACTER(LEN=*), INTENT(IN) ::  mode   !< name of the calling mode
     201    CHARACTER(LEN=*), INTENT(IN) ::  budget !< name of the timing budget
     202
     203    REAL(wp), SAVE ::  t0               !< begin of timing interval
     204    REAL(wp), SAVE ::  t1               !< end of timing interval
     205    REAL(wp), SAVE ::  t_comp  = 0.0_wp !< computation timing budget
     206    REAL(wp), SAVE ::  t_alloc = 0.0_wp !< allocation timing budget
     207    REAL(wp), SAVE ::  t_init  = 0.0_wp !< initialization timing budget
     208    REAL(wp), SAVE ::  t_read  = 0.0_wp !< reading timing budget
     209    REAL(wp), SAVE ::  t_total = 0.0_wp !< total time
     210    REAL(wp), SAVE ::  t_write = 0.0_wp !< writing timing budget
     211
     212    CHARACTER(LEN=*), PARAMETER  ::  fmt='(F6.2)' !< floating-point output format
     213
     214
     215    SELECT CASE(TRIM(mode))
     216
     217    CASE('init')
     218       CALL CPU_TIME(t0)
     219
     220    CASE('time')
     221
     222       CALL CPU_TIME(t1)
     223
     224       SELECT CASE(TRIM(budget))
     225
     226          CASE('alloc')
     227             t_alloc = t_alloc + t1 - t0
     228
     229          CASE('init')
     230             t_init = t_init + t1 - t0
     231
     232          CASE('read')
     233             t_read = t_read + t1 - t0
     234
     235          CASE('write')
     236             t_write = t_write + t1 - t0
     237
     238          CASE('comp')
     239             t_comp = t_comp + t1 - t0
     240
     241          CASE DEFAULT
     242             CALL inifor_abort('log_runtime', "Time Budget '" // TRIM(mode) // "' is not supported.")
    265243
    266244       END SELECT
    267245
    268     END SUBROUTINE run_control
     246       t0 = t1
     247
     248    CASE('report')
     249        t_total = t_init + t_read + t_write + t_comp
     250
     251        CALL report('log_runtime', " *** CPU time ***")
     252
     253        CALL report('log_runtime', "Initialization:  " // TRIM( real_to_str( t_init ) ) // &
     254                    " s  (" // TRIM( real_to_str( 100 * t_init / t_total, fmt ) ) // " %)" )
     255
     256        CALL report('log_runtime', "(De-)Allocation: " // TRIM( real_to_str( t_alloc ) ) // &
     257                    " s  (" // TRIM( real_to_str( 100 * t_alloc / t_total, fmt ) ) // " %)" )
     258
     259        CALL report('log_runtime', "Reading data:    " // TRIM( real_to_str( t_read ) )  // &
     260                    " s  (" // TRIM( real_to_str( 100 * t_read / t_total, fmt ) ) // " %)" )
     261
     262        CALL report('log_runtime', "Writing data:    " // TRIM( real_to_str( t_write ) ) // &
     263                    " s  (" // TRIM( real_to_str( 100 * t_write / t_total, fmt ) ) // " %)" )
     264
     265        CALL report('log_runtime', "Computation:     " // TRIM( real_to_str( t_comp ) )  // &
     266                    " s  (" // TRIM( real_to_str( 100 * t_comp / t_total, fmt) ) // " %)" )
     267
     268        CALL report('log_runtime', "Total:           " // TRIM( real_to_str( t_total ) ) // &
     269                    " s  (" // TRIM( real_to_str( 100 * t_total / t_total, fmt ) ) // " %)")
     270
     271    CASE DEFAULT
     272       CALL inifor_abort('log_runtime', "Mode '" // TRIM(mode) // "' is not supported.")
     273
     274    END SELECT
     275
     276 END SUBROUTINE log_runtime
    269277
    270278 END MODULE inifor_control
    271 #endif
    272 
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_defs.f90

    r3801 r3866  
    2626! -----------------
    2727! $Id$
     28! Added parameter for INIFOR's log file name
     29! Use PALM's working precision
     30!
     31!
     32! 3801 2019-03-15 17:14:25Z eckhard
    2833! Defined netCDF variable names for COSMO grid
    2934! Bumped version number
     
    9499!> The defs module provides global constants used in INIFOR.
    95100!------------------------------------------------------------------------------!
    96 #if defined ( __netcdf )
    97101 MODULE inifor_defs
    98102 
     103 USE kinds,                                                                    &
     104     ONLY :  wp, iwp
     105
    99106 IMPLICIT NONE
    100107
    101108!
    102109!-- Parameters for type definitions
    103  INTEGER, PARAMETER  ::  dp    = 8   !< double precision (8 bytes = 64 bits)
    104  INTEGER, PARAMETER  ::  sp    = 4   !< single precision (4 bytes = 32 bits)
    105  INTEGER, PARAMETER  ::  hp    = 2   !< half precision (2 bytes = 16 bits)
    106110 INTEGER, PARAMETER  ::  PATH  = 140 !< length of file path strings
    107111 INTEGER, PARAMETER  ::  LNAME = 150 !< length of long name strings
     
    111115!
    112116!-- Trigonomentry
    113  REAL(dp), PARAMETER ::  PI = 3.14159265358979323846264338_dp !< Ratio of a circle's circumference to its diamter [-]
    114  REAL(dp), PARAMETER ::  TO_RADIANS = PI / 180.0_dp           !< Conversion factor from degrees to radiant [-]
    115  REAL(dp), PARAMETER ::  TO_DEGREES = 180.0_dp / PI           !< Conversion factor from radians to degrees [-]
     117 REAL(wp), PARAMETER ::  PI = 3.14159265358979323846264338_wp !< Ratio of a circle's circumference to its diamter [-]
     118 REAL(wp), PARAMETER ::  TO_RADIANS = PI / 180.0_wp           !< Conversion factor from degrees to radiant [-]
     119 REAL(wp), PARAMETER ::  TO_DEGREES = 180.0_wp / PI           !< Conversion factor from radians to degrees [-]
    116120
    117121!
    118122!-- COSMO parameters
    119123 INTEGER, PARAMETER  ::  WATER_ID = 9                !< Integer corresponding to the water soil type in COSMO-DE [-]
    120  REAL(dp), PARAMETER ::  EARTH_RADIUS = 6371229.0_dp !< Earth radius used in COSMO-DE [m]
    121  REAL(dp), PARAMETER ::  P_SL = 1e5_dp               !< Reference pressure for computation of COSMO-DE's basic state pressure [Pa]
    122  REAL(dp), PARAMETER ::  T_SL = 288.15_dp            !< Reference temperature for computation of COSMO-DE's basic state pressure [K]
    123  REAL(dp), PARAMETER ::  BETA = 42.0_dp              !< logarithmic lapse rate, dT / d ln(p), for computation of COSMO-DE's basic
     124 REAL(wp), PARAMETER ::  EARTH_RADIUS = 6371229.0_wp !< Earth radius used in COSMO-DE [m]
     125 REAL(wp), PARAMETER ::  P_SL = 1e5_wp               !< Reference pressure for computation of COSMO-DE's basic state pressure [Pa]
     126 REAL(wp), PARAMETER ::  T_SL = 288.15_wp            !< Reference temperature for computation of COSMO-DE's basic state pressure [K]
     127 REAL(wp), PARAMETER ::  BETA = 42.0_wp              !< logarithmic lapse rate, dT / d ln(p), for computation of COSMO-DE's basic
    124128                                                     !< state pressure [K]
    125  REAL(dp), PARAMETER ::  RD   = 287.05_dp            !< specific gas constant of dry air, used in computation of COSMO-DE's basic
     129 REAL(wp), PARAMETER ::  RD   = 287.05_wp            !< specific gas constant of dry air, used in computation of COSMO-DE's basic
    126130                                                     !< state [J/kg/K]
    127  REAL(dp), PARAMETER ::  RV   = 461.51_dp            !< specific gas constant of water vapor [J/kg/K]
    128  REAL(dp), PARAMETER ::  G    = 9.80665_dp           !< acceleration of Earth's gravity, used in computation of COSMO-DE's basic
     131 REAL(wp), PARAMETER ::  RV   = 461.51_wp            !< specific gas constant of water vapor [J/kg/K]
     132 REAL(wp), PARAMETER ::  G    = 9.80665_wp           !< acceleration of Earth's gravity, used in computation of COSMO-DE's basic
    129133                                                     !< state [m/s/s]
    130  REAL(dp), PARAMETER ::  RHO_L = 1e3_dp              !< density of liquid water, used to convert W_SO from [kg/m^2] to [m^3/m^3],
     134 REAL(wp), PARAMETER ::  RHO_L = 1e3_wp              !< density of liquid water, used to convert W_SO from [kg/m^2] to [m^3/m^3],
    131135                                                     !< in [kg/m^3]
    132  REAL(dp), PARAMETER ::  HECTO = 100_dp              !< unit conversion factor from hPa to Pa
     136 REAL(wp), PARAMETER ::  HECTO = 100_wp              !< unit conversion factor from hPa to Pa
    133137
    134138!
    135139!-- PALM-4U parameters
    136  REAL(dp), PARAMETER ::  OMEGA   = 7.29e-5_dp !< angular velocity of Earth's rotation [s^-1]
    137  REAL(dp), PARAMETER ::  P_REF   = 1e5_dp     !< Reference pressure for potential temperature [Pa]
    138  REAL(dp), PARAMETER ::  RD_PALM = 287.0_dp   !< specific gas constant of dry air, used in computation of PALM-4U's potential temperature [J/kg/K]
    139  REAL(dp), PARAMETER ::  CP_PALM = 1005.0_dp  !< heat capacity of dry air at constant pressure, used in computation of PALM-4U's potential temperature [J/kg/K]
     140 REAL(wp), PARAMETER ::  OMEGA   = 7.29e-5_wp !< angular velocity of Earth's rotation [s^-1]
     141 REAL(wp), PARAMETER ::  P_REF   = 1e5_wp     !< Reference pressure for potential temperature [Pa]
     142 REAL(wp), PARAMETER ::  RD_PALM = 287.0_wp   !< specific gas constant of dry air, used in computation of PALM-4U's potential temperature [J/kg/K]
     143 REAL(wp), PARAMETER ::  CP_PALM = 1005.0_wp  !< heat capacity of dry air at constant pressure, used in computation of PALM-4U's potential temperature [J/kg/K]
    140144
    141145!
     
    154158                                                              !< water cells [-]
    155159 INTEGER, PARAMETER          ::  FORCING_STEP = 1             !< Number of hours between forcing time steps [h]
    156  REAL(dp), PARAMETER         ::  NUDGING_TAU = 21600.0_dp     !< Nudging relaxation time scale [s]
    157  CHARACTER(LEN=*), PARAMETER ::  VERSION = '1.4.8'            !< INIFOR version number
     160 REAL(wp), PARAMETER         ::  NUDGING_TAU = 21600.0_wp     !< Nudging relaxation time scale [s]
    158161 CHARACTER(LEN=*), PARAMETER ::  COPYRIGHT = 'Copyright 2017-2019 Leibniz Universitaet Hannover' // &
    159      ACHAR( 10 ) // ' Copyright 2017-2019 Deutscher Wetterdienst Offenbach' !< Copyright notice
    160 
     162    ACHAR( 10 ) // ' Copyright 2017-2019 Deutscher Wetterdienst Offenbach' !< Copyright notice
     163 CHARACTER(LEN=*), PARAMETER ::  LOG_FILE_NAME = 'inifor.log' !< Name of INIFOR's log file
     164 CHARACTER(LEN=*), PARAMETER ::  VERSION = '1.4.9rc'          !< INIFOR version number
     165 
    161166 END MODULE inifor_defs
    162 #endif
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_grid.f90

    r3802 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29! Catch errors while reading namelists
     30! Improved coding style
     31!
     32!
     33! 3802 2019-03-17 13:33:42Z raasch
    2834! unused variable removed
    2935!
     
    131137    USE inifor_control
    132138    USE inifor_defs,                                                           &
    133         ONLY:  DATE, EARTH_RADIUS, TO_RADIANS, TO_DEGREES, PI, dp, hp, sp,     &
     139        ONLY:  DATE, EARTH_RADIUS, TO_RADIANS, TO_DEGREES, PI,                 &
    134140               SNAME, LNAME, PATH, FORCING_STEP, WATER_ID, FILL_ITERATIONS,    &
    135141               BETA, P_SL, T_SL, BETA, RD, RV, G, P_REF, RD_PALM, CP_PALM,     &
    136                RHO_L, OMEGA, HECTO
     142               RHO_L, OMEGA, HECTO, wp, iwp
    137143    USE inifor_io,                                                             &
    138144        ONLY:  get_cosmo_grid, get_netcdf_attribute, get_netcdf_dim_vector,    &
     
    140146               get_input_file_list, validate_config
    141147    USE inifor_transform,                                                      &
    142         ONLY:  average_2d, rotate_to_cosmo, find_horizontal_neighbours,&
     148        ONLY:  average_2d, rotate_to_cosmo, find_horizontal_neighbours,        &
    143149               compute_horizontal_interp_weights,                              &
    144150               find_vertical_neighbours_and_weights_interp,                    &
     
    156162    SAVE
    157163   
    158     REAL(dp) ::  averaging_angle   = 0.0_dp       !< latitudal and longitudal width of averaging regions [rad]
    159     REAL(dp) ::  averaging_width_ns = 0.0_dp       !< longitudal width of averaging regions [m]
    160     REAL(dp) ::  averaging_width_ew = 0.0_dp       !< latitudal width of averaging regions [m]
    161     REAL(dp) ::  phi_equat         = 0.0_dp       !< latitude of rotated equator of COSMO-DE grid [rad]
    162     REAL(dp) ::  phi_n             = 0.0_dp       !< latitude of rotated pole of COSMO-DE grid [rad]
    163     REAL(dp) ::  lambda_n          = 0.0_dp       !< longitude of rotaded pole of COSMO-DE grid [rad]
    164     REAL(dp) ::  phi_c             = 0.0_dp       !< rotated-grid latitude of the center of the PALM domain [rad]
    165     REAL(dp) ::  lambda_c          = 0.0_dp       !< rotated-grid longitude of the centre of the PALM domain [rad]
    166     REAL(dp) ::  phi_cn            = 0.0_dp       !< latitude of the rotated pole relative to the COSMO-DE grid [rad]
    167     REAL(dp) ::  lambda_cn         = 0.0_dp       !< longitude of the rotated pole relative to the COSMO-DE grid [rad]
    168     REAL(dp) ::  lam_centre        = 0.0_dp       !< longitude of the PLAM domain centre in the source (COSMO rotated-pole) system [rad]
    169     REAL(dp) ::  phi_centre        = 0.0_dp       !< latitude of the PLAM domain centre in the source (COSMO rotated-pole) system [rad]
    170     REAL(dp) ::  lam_east          = 0.0_dp       !< longitude of the east central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
    171     REAL(dp) ::  lam_west          = 0.0_dp       !< longitude of the west central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
    172     REAL(dp) ::  phi_north         = 0.0_dp       !< latitude of the north central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
    173     REAL(dp) ::  phi_south         = 0.0_dp       !< latitude of the south central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
    174     REAL(dp) ::  gam               = 0.0_dp       !< angle for working around phirot2phi/rlarot2rla bug
    175     REAL(dp) ::  dx                = 0.0_dp       !< PALM-4U grid spacing in x direction [m]
    176     REAL(dp) ::  dy                = 0.0_dp       !< PALM-4U grid spacing in y direction [m]
    177     REAL(dp) ::  dz(10)            = -1.0_dp      !< PALM-4U grid spacing in z direction [m]
    178     REAL(dp) ::  dz_max            = 1000.0_dp    !< maximum vertical grid spacing [m]
    179     REAL(dp) ::  dz_stretch_factor = 1.08_dp      !< factor for vertical grid stretching [m]
    180     REAL(dp) ::  dz_stretch_level  = -9999999.9_dp!< height above which the vertical grid will be stretched [m]
    181     REAL(dp) ::  dz_stretch_level_start(9) = -9999999.9_dp !< namelist parameter
    182     REAL(dp) ::  dz_stretch_level_end(9) = 9999999.9_dp !< namelist parameter
    183     REAL(dp) ::  dz_stretch_factor_array(9) = 1.08_dp !< namelist parameter
    184     REAL(dp) ::  dxi               = 0.0_dp       !< inverse PALM-4U grid spacing in x direction [m^-1]
    185     REAL(dp) ::  dyi               = 0.0_dp       !< inverse PALM-4U grid spacing in y direction [m^-1]
    186     REAL(dp) ::  dzi               = 0.0_dp       !< inverse PALM-4U grid spacing in z direction [m^-1]
    187     REAL(dp) ::  f3                = 0.0_dp       !< Coriolis parameter
    188     REAL(dp) ::  lx                = 0.0_dp       !< PALM-4U domain size in x direction [m]
    189     REAL(dp) ::  ly                = 0.0_dp       !< PALM-4U domain size in y direction [m]
    190     REAL(dp) ::  p0                = 0.0_dp       !< PALM-4U surface pressure, at z0 [Pa]
    191     REAL(dp) ::  x0                = 0.0_dp       !< x coordinate of PALM-4U Earth tangent [m]
    192     REAL(dp) ::  y0                = 0.0_dp       !< y coordinate of PALM-4U Earth tangent [m]
    193     REAL(dp) ::  z0                = 0.0_dp       !< Elevation of the PALM-4U domain above sea level [m]
    194     REAL(dp) ::  z_top             = 0.0_dp       !< height of the scalar top boundary [m]
    195     REAL(dp) ::  zw_top            = 0.0_dp       !< height of the vertical velocity top boundary [m]
    196     REAL(dp) ::  lonmin_cosmo      = 0.0_dp       !< Minimunm longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    197     REAL(dp) ::  lonmax_cosmo      = 0.0_dp       !< Maximum longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    198     REAL(dp) ::  latmin_cosmo      = 0.0_dp       !< Minimunm latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    199     REAL(dp) ::  latmax_cosmo      = 0.0_dp       !< Maximum latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    200     REAL(dp) ::  lonmin_palm       = 0.0_dp       !< Minimunm longitude of PALM grid [COSMO rotated-pole rad]
    201     REAL(dp) ::  lonmax_palm       = 0.0_dp       !< Maximum longitude of PALM grid [COSMO rotated-pole rad]
    202     REAL(dp) ::  latmin_palm       = 0.0_dp       !< Minimunm latitude of PALM grid [COSMO rotated-pole rad]
    203     REAL(dp) ::  latmax_palm       = 0.0_dp       !< Maximum latitude of PALM grid [COSMO rotated-pole rad]
    204     REAL(dp) ::  lonmin_tot        = 0.0_dp       !< Minimunm longitude of required COSMO data [COSMO rotated-pole rad]
    205     REAL(dp) ::  lonmax_tot        = 0.0_dp       !< Maximum longitude of required COSMO data [COSMO rotated-pole rad]
    206     REAL(dp) ::  latmin_tot        = 0.0_dp       !< Minimunm latitude of required COSMO data [COSMO rotated-pole rad]
    207     REAL(dp) ::  latmax_tot        = 0.0_dp       !< Maximum latitude of required COSMO data [COSMO rotated-pole rad]
    208     REAL(dp) ::  latitude          = 0.0_dp       !< geographical latitude of the PALM-4U origin, from inipar namelist [deg]
    209     REAL(dp) ::  longitude         = 0.0_dp       !< geographical longitude of the PALM-4U origin, from inipar namelist [deg]
    210     REAL(dp) ::  origin_lat        = 0.0_dp       !< geographical latitude of the PALM-4U origin, from static driver netCDF file [deg]
    211     REAL(dp) ::  origin_lon        = 0.0_dp       !< geographical longitude of the PALM-4U origin, from static driver netCDF file [deg]
    212     REAL(dp) ::  rotation_angle    = 0.0_dp       !< clockwise angle the PALM-4U north is rotated away from geographical north [deg]
    213     REAL(dp) ::  end_time          = 0.0_dp       !< PALM-4U simulation time [s]
    214 
    215     REAL(dp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  hhl             !< heights of half layers (cell faces) above sea level in COSMO-DE, read in from external file
    216     REAL(dp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  hfl             !< heights of full layers (cell centres) above sea level in COSMO-DE, computed as arithmetic average of hhl
    217     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  depths          !< COSMO-DE's TERRA-ML soil layer depths
    218     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  d_depth         !< COSMO-DE's TERRA-ML soil layer thicknesses
    219     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  d_depth_rho_inv !< inverted soil water mass
    220     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  rlon            !< longitudes of COSMO-DE's rotated-pole grid
    221     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  rlat            !< latitudes of COSMO-DE's rotated-pole grid
    222     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  time            !< output times
    223     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  x               !< base palm grid x coordinate vector pointed to by grid_definitions
    224     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  xu              !< base palm grid xu coordinate vector pointed to by grid_definitions
    225     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  y               !< base palm grid y coordinate vector pointed to by grid_definitions
    226     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  yv              !< base palm grid yv coordinate vector pointed to by grid_definitions
    227     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  z_column        !< base palm grid z coordinate vector including the top boundary coordinate (entire column)
    228     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  zw_column       !< base palm grid zw coordinate vector including the top boundary coordinate (entire column)
    229     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  z               !< base palm grid z coordinate vector pointed to by grid_definitions
    230     REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET     ::  zw              !< base palm grid zw coordinate vector pointed to by grid_definitions
    231 
    232     INTEGER(hp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  soiltyp      !< COSMO-DE soil type map
     164    REAL(wp) ::  averaging_angle   = 0.0_wp       !< latitudal and longitudal width of averaging regions [rad]
     165    REAL(wp) ::  averaging_width_ns = 0.0_wp       !< longitudal width of averaging regions [m]
     166    REAL(wp) ::  averaging_width_ew = 0.0_wp       !< latitudal width of averaging regions [m]
     167    REAL(wp) ::  phi_equat         = 0.0_wp       !< latitude of rotated equator of COSMO-DE grid [rad]
     168    REAL(wp) ::  phi_n             = 0.0_wp       !< latitude of rotated pole of COSMO-DE grid [rad]
     169    REAL(wp) ::  lambda_n          = 0.0_wp       !< longitude of rotaded pole of COSMO-DE grid [rad]
     170    REAL(wp) ::  phi_c             = 0.0_wp       !< rotated-grid latitude of the center of the PALM domain [rad]
     171    REAL(wp) ::  lambda_c          = 0.0_wp       !< rotated-grid longitude of the centre of the PALM domain [rad]
     172    REAL(wp) ::  phi_cn            = 0.0_wp       !< latitude of the rotated pole relative to the COSMO-DE grid [rad]
     173    REAL(wp) ::  lambda_cn         = 0.0_wp       !< longitude of the rotated pole relative to the COSMO-DE grid [rad]
     174    REAL(wp) ::  lam_centre        = 0.0_wp       !< longitude of the PLAM domain centre in the source (COSMO rotated-pole) system [rad]
     175    REAL(wp) ::  phi_centre        = 0.0_wp       !< latitude of the PLAM domain centre in the source (COSMO rotated-pole) system [rad]
     176    REAL(wp) ::  lam_east          = 0.0_wp       !< longitude of the east central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
     177    REAL(wp) ::  lam_west          = 0.0_wp       !< longitude of the west central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
     178    REAL(wp) ::  phi_north         = 0.0_wp       !< latitude of the north central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
     179    REAL(wp) ::  phi_south         = 0.0_wp       !< latitude of the south central-averaging-domain boundary in the source (COSMO rotated-pole) system [rad]
     180    REAL(wp) ::  gam               = 0.0_wp       !< angle for working around phirot2phi/rlarot2rla bug
     181    REAL(wp) ::  dx                = 0.0_wp       !< PALM-4U grid spacing in x direction [m]
     182    REAL(wp) ::  dy                = 0.0_wp       !< PALM-4U grid spacing in y direction [m]
     183    REAL(wp) ::  dz(10)            = -1.0_wp      !< PALM-4U grid spacing in z direction [m]
     184    REAL(wp) ::  dz_max            = 1000.0_wp    !< maximum vertical grid spacing [m]
     185    REAL(wp) ::  dz_stretch_factor = 1.08_wp      !< factor for vertical grid stretching [m]
     186    REAL(wp) ::  dz_stretch_level  = -9999999.9_wp!< height above which the vertical grid will be stretched [m]
     187    REAL(wp) ::  dz_stretch_level_start(9) = -9999999.9_wp !< namelist parameter
     188    REAL(wp) ::  dz_stretch_level_end(9) = 9999999.9_wp !< namelist parameter
     189    REAL(wp) ::  dz_stretch_factor_array(9) = 1.08_wp !< namelist parameter
     190    REAL(wp) ::  dxi               = 0.0_wp       !< inverse PALM-4U grid spacing in x direction [m^-1]
     191    REAL(wp) ::  dyi               = 0.0_wp       !< inverse PALM-4U grid spacing in y direction [m^-1]
     192    REAL(wp) ::  dzi               = 0.0_wp       !< inverse PALM-4U grid spacing in z direction [m^-1]
     193    REAL(wp) ::  f3                = 0.0_wp       !< Coriolis parameter
     194    REAL(wp) ::  lx                = 0.0_wp       !< PALM-4U domain size in x direction [m]
     195    REAL(wp) ::  ly                = 0.0_wp       !< PALM-4U domain size in y direction [m]
     196    REAL(wp) ::  p0                = 0.0_wp       !< PALM-4U surface pressure, at z0 [Pa]
     197    REAL(wp) ::  x0                = 0.0_wp       !< x coordinate of PALM-4U Earth tangent [m]
     198    REAL(wp) ::  y0                = 0.0_wp       !< y coordinate of PALM-4U Earth tangent [m]
     199    REAL(wp) ::  z0                = 0.0_wp       !< Elevation of the PALM-4U domain above sea level [m]
     200    REAL(wp) ::  z_top             = 0.0_wp       !< height of the scalar top boundary [m]
     201    REAL(wp) ::  zw_top            = 0.0_wp       !< height of the vertical velocity top boundary [m]
     202    REAL(wp) ::  lonmin_cosmo      = 0.0_wp       !< Minimunm longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     203    REAL(wp) ::  lonmax_cosmo      = 0.0_wp       !< Maximum longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     204    REAL(wp) ::  latmin_cosmo      = 0.0_wp       !< Minimunm latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     205    REAL(wp) ::  latmax_cosmo      = 0.0_wp       !< Maximum latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     206    REAL(wp) ::  lonmin_palm       = 0.0_wp       !< Minimunm longitude of PALM grid [COSMO rotated-pole rad]
     207    REAL(wp) ::  lonmax_palm       = 0.0_wp       !< Maximum longitude of PALM grid [COSMO rotated-pole rad]
     208    REAL(wp) ::  latmin_palm       = 0.0_wp       !< Minimunm latitude of PALM grid [COSMO rotated-pole rad]
     209    REAL(wp) ::  latmax_palm       = 0.0_wp       !< Maximum latitude of PALM grid [COSMO rotated-pole rad]
     210    REAL(wp) ::  lonmin_tot        = 0.0_wp       !< Minimunm longitude of required COSMO data [COSMO rotated-pole rad]
     211    REAL(wp) ::  lonmax_tot        = 0.0_wp       !< Maximum longitude of required COSMO data [COSMO rotated-pole rad]
     212    REAL(wp) ::  latmin_tot        = 0.0_wp       !< Minimunm latitude of required COSMO data [COSMO rotated-pole rad]
     213    REAL(wp) ::  latmax_tot        = 0.0_wp       !< Maximum latitude of required COSMO data [COSMO rotated-pole rad]
     214    REAL(wp) ::  latitude          = 0.0_wp       !< geographical latitude of the PALM-4U origin, from inipar namelist [deg]
     215    REAL(wp) ::  longitude         = 0.0_wp       !< geographical longitude of the PALM-4U origin, from inipar namelist [deg]
     216    REAL(wp) ::  origin_lat        = 0.0_wp       !< geographical latitude of the PALM-4U origin, from static driver netCDF file [deg]
     217    REAL(wp) ::  origin_lon        = 0.0_wp       !< geographical longitude of the PALM-4U origin, from static driver netCDF file [deg]
     218    REAL(wp) ::  rotation_angle    = 0.0_wp       !< clockwise angle the PALM-4U north is rotated away from geographical north [deg]
     219    REAL(wp) ::  end_time          = 0.0_wp       !< PALM-4U simulation time [s]
     220
     221    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  hhl             !< heights of half layers (cell faces) above sea level in COSMO-DE, read in from external file
     222    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  hfl             !< heights of full layers (cell centres) above sea level in COSMO-DE, computed as arithmetic average of hhl
     223    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  depths          !< COSMO-DE's TERRA-ML soil layer depths
     224    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  d_depth         !< COSMO-DE's TERRA-ML soil layer thicknesses
     225    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  d_depth_rho_inv !< inverted soil water mass
     226    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  rlon            !< longitudes of COSMO-DE's rotated-pole grid
     227    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  rlat            !< latitudes of COSMO-DE's rotated-pole grid
     228    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  time            !< output times
     229    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  x               !< base palm grid x coordinate vector pointed to by grid_definitions
     230    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  xu              !< base palm grid xu coordinate vector pointed to by grid_definitions
     231    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  y               !< base palm grid y coordinate vector pointed to by grid_definitions
     232    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  yv              !< base palm grid yv coordinate vector pointed to by grid_definitions
     233    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  z_column        !< base palm grid z coordinate vector including the top boundary coordinate (entire column)
     234    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  zw_column       !< base palm grid zw coordinate vector including the top boundary coordinate (entire column)
     235    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  z               !< base palm grid z coordinate vector pointed to by grid_definitions
     236    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET     ::  zw              !< base palm grid zw coordinate vector pointed to by grid_definitions
     237
     238    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  soiltyp     !< COSMO-DE soil type map
    233239    INTEGER ::  dz_stretch_level_end_index(9)               !< vertical grid level index until which the vertical grid spacing is stretched
    234240    INTEGER ::  dz_stretch_level_start_index(9)             !< vertical grid level index above which the vertical grid spacing is stretched
     241    INTEGER ::  iostat !< return status of READ statement
    235242    INTEGER ::  nt    !< number of output time steps
    236243    INTEGER ::  nx    !< number of PALM-4U grid points in x direction
     
    355362!> interplation grids later in setup_grids().
    356363!------------------------------------------------------------------------------!
    357     SUBROUTINE setup_parameters()
     364 SUBROUTINE setup_parameters()
    358365
    359366!
     
    361368! Section 1: Define default parameters
    362369!------------------------------------------------------------------------------
    363        cfg % start_date = '2013072100'
    364        end_hour = 2
    365        start_hour_soil = -2
    366        start_hour_soilmoisture = - (4 * 7 * 24) - 2
    367 
    368 !
    369 !--    Defaultmain centre (_c) of the PALM-4U grid in the geographical system (_g)
    370        origin_lat = 52.325079_dp * TO_RADIANS ! south-west of Berlin, origin used for the Dec 2017 showcase simulation
    371        origin_lon = 13.082744_dp * TO_RADIANS
    372        cfg % z0 = 35.0_dp
    373 
    374 !
    375 !--    Default atmospheric parameters
    376        cfg % ug = 0.0_dp
    377        cfg % vg = 0.0_dp
    378        cfg % p0 = P_SL
    379 
    380 !
    381 !--    Parameters for file names
    382        start_hour_flow = 0
    383        start_hour_soil = 0
    384        start_hour_radiation = 0
    385        start_hour_soilmoisture = start_hour_flow - 2
    386        end_hour_soilmoisture = start_hour_flow
    387        step_hour = FORCING_STEP
    388 
    389        input_prefix = 'laf'
    390        cfg % flow_prefix = input_prefix
    391        cfg % input_prefix = input_prefix
    392        cfg % soil_prefix = input_prefix
    393        cfg % radiation_prefix = input_prefix
    394        cfg % soilmoisture_prefix  = input_prefix
    395 
    396        flow_suffix = '-flow'
    397        soil_suffix = '-soil'
    398        radiation_suffix = '-rad'
    399        soilmoisture_suffix = '-soilmoisture'
    400 
    401        cfg % debug = .FALSE.
    402        cfg % averaging_angle = 2.0_dp
     370    cfg%start_date = '2013072100'
     371    end_hour = 2
     372    start_hour_soil = -2
     373    start_hour_soilmoisture = - (4 * 7 * 24) - 2
     374
     375!
     376!-- Defaultmain centre (_c) of the PALM-4U grid in the geographical system (_g)
     377    origin_lat = 52.325079_wp * TO_RADIANS ! south-west of Berlin, origin used for the Dec 2017 showcase simulation
     378    origin_lon = 13.082744_wp * TO_RADIANS
     379    cfg%z0 = 35.0_wp
     380
     381!
     382!-- Default atmospheric parameters
     383    cfg%ug = 0.0_wp
     384    cfg%vg = 0.0_wp
     385    cfg%p0 = P_SL
     386
     387!
     388!-- Parameters for file names
     389    start_hour_flow = 0
     390    start_hour_soil = 0
     391    start_hour_radiation = 0
     392    start_hour_soilmoisture = start_hour_flow - 2
     393    end_hour_soilmoisture = start_hour_flow
     394    step_hour = FORCING_STEP
     395
     396    input_prefix = 'laf'
     397    cfg%flow_prefix = input_prefix
     398    cfg%input_prefix = input_prefix
     399    cfg%soil_prefix = input_prefix
     400    cfg%radiation_prefix = input_prefix
     401    cfg%soilmoisture_prefix  = input_prefix
     402
     403    flow_suffix = '-flow'
     404    soil_suffix = '-soil'
     405    radiation_suffix = '-rad'
     406    soilmoisture_suffix = '-soilmoisture'
     407
     408    cfg%debug = .FALSE.
     409    cfg%averaging_angle = 2.0_wp
    403410!
    404411!------------------------------------------------------------------------------
     
    407414
    408415!
    409 !--    Set default paths and modes
    410        cfg % input_path         = './'
    411        cfg % hhl_file           = ''
    412        cfg % soiltyp_file       = ''
    413        cfg % namelist_file      = './namelist'
    414        cfg % static_driver_file = ''
    415        cfg % output_file = './palm-4u-input.nc'
    416        cfg % ic_mode = 'volume'
    417        cfg % bc_mode = 'real'
    418        cfg % averaging_mode = 'level'
    419 
    420 !
    421 !--    Overwrite defaults with user configuration
    422        CALL parse_command_line_arguments( cfg )
    423        CALL report('main_loop', 'Running INIFOR version ' // VERSION)
    424 
    425        flow_prefix = TRIM(cfg % input_prefix)
    426        radiation_prefix = TRIM(cfg % input_prefix)
    427        soil_prefix = TRIM(cfg % input_prefix)
    428        soilmoisture_prefix = TRIM(cfg % input_prefix)
    429        IF (cfg % flow_prefix_is_set)  flow_prefix = TRIM(cfg % flow_prefix)
    430        IF (cfg % radiation_prefix_is_set)  radiation_prefix = TRIM(cfg % radiation_prefix)
    431        IF (cfg % soil_prefix_is_set)  soil_prefix = TRIM(cfg % soil_prefix)
    432        IF (cfg % soilmoisture_prefix_is_set)  soilmoisture_prefix = TRIM(cfg % soilmoisture_prefix)
    433 
    434        output_file % name = cfg % output_file
    435        z0 = cfg % z0
    436        p0 = cfg % p0
    437 
    438        init_variables_required = .TRUE.
    439        boundary_variables_required = TRIM( cfg % bc_mode ) == 'real'
    440        ls_forcing_variables_required = TRIM( cfg % bc_mode ) == 'ideal'
    441        surface_forcing_required = .FALSE.
    442 
    443        IF ( ls_forcing_variables_required )  THEN
    444           message = "Averaging of large-scale forcing profiles " //            &
    445                     "has not been implemented, yet."
    446           CALL inifor_abort('setup_parameters', message)
    447        ENDIF
    448 
    449 !
    450 !--    Set default file paths, if not specified by user.
    451        CALL normalize_path(cfg % input_path)
    452        IF (TRIM(cfg % hhl_file) == '')  cfg % hhl_file = TRIM(cfg % input_path) // 'hhl.nc'
    453        IF (TRIM(cfg % soiltyp_file) == '')  cfg % soiltyp_file = TRIM(cfg % input_path) // 'soil.nc'
    454 
    455        CALL validate_config( cfg )
    456 
    457        CALL report('setup_parameters', "initialization mode: " // TRIM(cfg % ic_mode))
    458        CALL report('setup_parameters', "       forcing mode: " // TRIM(cfg % bc_mode))
    459        CALL report('setup_parameters', "     averaging mode: " // TRIM(cfg % averaging_mode))
    460        CALL report('setup_parameters', "    averaging angle: " // real_to_str(cfg % averaging_angle))
    461        CALL report('setup_parameters', "          data path: " // TRIM(cfg % input_path))
    462        CALL report('setup_parameters', "           hhl file: " // TRIM(cfg % hhl_file))
    463        CALL report('setup_parameters', "       soiltyp file: " // TRIM(cfg % soiltyp_file))
    464        CALL report('setup_parameters', "      namelist file: " // TRIM(cfg % namelist_file))
    465        CALL report('setup_parameters', "   output data file: " // TRIM(output_file % name))
    466        IF (cfg % debug )  CALL report('setup_parameters', "     debugging mode: enabled")
    467 
    468  CALL run_control('time', 'init')
    469  !
    470  !--   Read in namelist parameters
    471        OPEN(10, FILE=cfg % namelist_file)
    472        READ(10, NML=inipar) ! nx, ny, nz, dx, dy, dz
    473        READ(10, NML=d3par)  ! end_time
     416!-- Set default paths and modes
     417    cfg%input_path         = './'
     418    cfg%hhl_file           = ''
     419    cfg%soiltyp_file       = ''
     420    cfg%namelist_file      = './namelist'
     421    cfg%static_driver_file = ''
     422    cfg%output_file = './palm-4u-input.nc'
     423    cfg%ic_mode = 'volume'
     424    cfg%bc_mode = 'real'
     425    cfg%averaging_mode = 'level'
     426
     427!
     428!-- Overwrite defaults with user configuration
     429    CALL parse_command_line_arguments( cfg )
     430    CALL report('main_loop', 'Running INIFOR version ' // VERSION)
     431
     432    flow_prefix = TRIM(cfg%input_prefix)
     433    radiation_prefix = TRIM(cfg%input_prefix)
     434    soil_prefix = TRIM(cfg%input_prefix)
     435    soilmoisture_prefix = TRIM(cfg%input_prefix)
     436    IF (cfg%flow_prefix_is_set)  flow_prefix = TRIM(cfg%flow_prefix)
     437    IF (cfg%radiation_prefix_is_set)  radiation_prefix = TRIM(cfg%radiation_prefix)
     438    IF (cfg%soil_prefix_is_set)  soil_prefix = TRIM(cfg%soil_prefix)
     439    IF (cfg%soilmoisture_prefix_is_set)  soilmoisture_prefix = TRIM(cfg%soilmoisture_prefix)
     440
     441    output_file%name = cfg%output_file
     442    z0 = cfg%z0
     443    p0 = cfg%p0
     444
     445    init_variables_required = .TRUE.
     446    boundary_variables_required = TRIM( cfg%bc_mode ) == 'real'
     447    ls_forcing_variables_required = TRIM( cfg%bc_mode ) == 'ideal'
     448    surface_forcing_required = .FALSE.
     449
     450    IF ( ls_forcing_variables_required )  THEN
     451       message = "Averaging of large-scale forcing profiles " //            &
     452                 "has not been implemented, yet."
     453       CALL inifor_abort('setup_parameters', message)
     454    ENDIF
     455
     456!
     457!-- Set default file paths, if not specified by user.
     458    CALL normalize_path(cfg%input_path)
     459    IF (TRIM(cfg%hhl_file) == '')  cfg%hhl_file = TRIM(cfg%input_path) // 'hhl.nc'
     460    IF (TRIM(cfg%soiltyp_file) == '')  cfg%soiltyp_file = TRIM(cfg%input_path) // 'soil.nc'
     461
     462    CALL validate_config( cfg )
     463
     464    CALL report('setup_parameters', "initialization mode: " // TRIM(cfg%ic_mode))
     465    CALL report('setup_parameters', "       forcing mode: " // TRIM(cfg%bc_mode))
     466    CALL report('setup_parameters', "     averaging mode: " // TRIM(cfg%averaging_mode))
     467    CALL report('setup_parameters', "    averaging angle: " // real_to_str(cfg%averaging_angle))
     468    CALL report('setup_parameters', "          data path: " // TRIM(cfg%input_path))
     469    CALL report('setup_parameters', "           hhl file: " // TRIM(cfg%hhl_file))
     470    CALL report('setup_parameters', "       soiltyp file: " // TRIM(cfg%soiltyp_file))
     471    CALL report('setup_parameters', "      namelist file: " // TRIM(cfg%namelist_file))
     472    CALL report('setup_parameters', "   output data file: " // TRIM(output_file%name))
     473    IF (cfg%debug )  CALL report('setup_parameters', "     debugging mode: enabled")
     474
     475    CALL log_runtime('time', 'init')
     476!
     477!-- Read in namelist parameters
     478    OPEN(10, FILE=cfg%namelist_file, STATUS='old')
     479    READ(10, NML=inipar, IOSTAT=iostat) ! nx, ny, nz, dx, dy, dz   
     480    IF ( iostat > 0 )  THEN     
     481       message = "Failed to read namelist 'inipar' from file '" //             &
     482                 TRIM( cfg%namelist_file ) // "'. "
     483       CALL inifor_abort( 'setup_parameters', message )
    474484       CLOSE(10)
    475  CALL run_control('time', 'read')
    476 
    477        end_hour = CEILING( end_time / 3600.0 * step_hour )
    478 
    479 !
    480 !--    Generate input file lists
    481        CALL get_input_file_list(                                               &
    482           cfg % start_date, start_hour_flow, end_hour, step_hour,              &
    483           cfg % input_path, flow_prefix, flow_suffix, flow_files)
    484        CALL get_input_file_list(                                               &
    485           cfg % start_date, start_hour_soil, end_hour, step_hour,              &
    486           cfg % input_path, soil_prefix, soil_suffix, soil_files)
    487        CALL get_input_file_list(                                               &
    488           cfg % start_date, start_hour_radiation, end_hour, step_hour,         &
    489           cfg % input_path, radiation_prefix, radiation_suffix, radiation_files, nocheck=.TRUE.)
    490        CALL get_input_file_list(                                               &
    491           cfg % start_date, start_hour_soilmoisture, end_hour_soilmoisture, step_hour, &
    492           cfg % input_path, soilmoisture_prefix, soilmoisture_suffix, soil_moisture_files, nocheck=.TRUE.)
     485    ENDIF
     486
     487    READ(10, NML=d3par, IOSTAT=iostat)  ! end_time
     488    IF ( iostat > 0 )  THEN
     489       message = "Failed to read namelist 'd3par' from file '" //              &
     490                 TRIM( cfg%namelist_file ) // "'. "
     491       CALL inifor_abort( 'setup_parameters', message )
     492       CLOSE(10)
     493    ENDIF
     494    CLOSE(10)
     495   
     496    CALL log_runtime('time', 'read')
     497
     498    end_hour = CEILING( end_time / 3600.0 * step_hour )
     499
     500!
     501!-- Generate input file lists
     502    CALL get_input_file_list(                                               &
     503       cfg%start_date, start_hour_flow, end_hour, step_hour,              &
     504       cfg%input_path, flow_prefix, flow_suffix, flow_files)
     505    CALL get_input_file_list(                                               &
     506       cfg%start_date, start_hour_soil, end_hour, step_hour,              &
     507       cfg%input_path, soil_prefix, soil_suffix, soil_files)
     508    CALL get_input_file_list(                                               &
     509       cfg%start_date, start_hour_radiation, end_hour, step_hour,         &
     510       cfg%input_path, radiation_prefix, radiation_suffix, radiation_files, nocheck=.TRUE.)
     511    CALL get_input_file_list(                                               &
     512       cfg%start_date, start_hour_soilmoisture, end_hour_soilmoisture, step_hour, &
     513       cfg%input_path, soilmoisture_prefix, soilmoisture_suffix, soil_moisture_files, nocheck=.TRUE.)
    493514
    494515!
     
    506527
    507528
    508  CALL run_control('time', 'init')
    509 !
    510 !--    Read COSMO soil type map
    511        cosmo_var % name = 'SOILTYP'
    512        CALL get_netcdf_variable(cfg % soiltyp_file, cosmo_var, soiltyp)
    513 
    514        message = 'Reading PALM-4U origin from'
    515        IF (TRIM(cfg % static_driver_file) .NE. '')  THEN
    516 
    517           origin_lon = get_netcdf_attribute(cfg % static_driver_file, 'origin_lon')
    518           origin_lat = get_netcdf_attribute(cfg % static_driver_file, 'origin_lat')
    519 
    520           message = TRIM(message) // " static driver file '"                   &
    521                                   // TRIM(cfg % static_driver_file) // "'"
    522 
    523 
    524        ELSE
    525 
    526           origin_lon = longitude
    527           origin_lat = latitude
    528 
    529           message = TRIM(message) // " namlist file '"                         &
    530                                   // TRIM(cfg % namelist_file) // "'"
    531 
    532        ENDIF
    533        origin_lon = origin_lon * TO_RADIANS
    534        origin_lat = origin_lat * TO_RADIANS
    535 
    536        CALL report('setup_parameters', message)
    537 
    538  CALL run_control('time', 'read')
    539 
    540        CALL get_cosmo_grid( cfg, soil_files(1), rlon, rlat, hhl, hfl, depths,  &
    541                             d_depth, d_depth_rho_inv, phi_n, lambda_n,         &
    542                             phi_equat,                                         &
    543                             lonmin_cosmo, lonmax_cosmo,                        &
    544                             latmin_cosmo, latmax_cosmo,                        &
    545                             nlon, nlat, nlev, ndepths )
     529    CALL log_runtime('time', 'init')
     530!
     531!-- Read COSMO soil type map
     532    cosmo_var%name = 'SOILTYP'
     533    CALL get_netcdf_variable(cfg%soiltyp_file, cosmo_var, soiltyp)
     534
     535    message = 'Reading PALM-4U origin from'
     536    IF (TRIM(cfg%static_driver_file) .NE. '')  THEN
     537
     538       origin_lon = get_netcdf_attribute(cfg%static_driver_file, 'origin_lon')
     539       origin_lat = get_netcdf_attribute(cfg%static_driver_file, 'origin_lat')
     540
     541       message = TRIM(message) // " static driver file '"                   &
     542                               // TRIM(cfg%static_driver_file) // "'"
     543
     544
     545    ELSE
     546
     547       origin_lon = longitude
     548       origin_lat = latitude
     549
     550       message = TRIM(message) // " namlist file '"                         &
     551                               // TRIM(cfg%namelist_file) // "'"
     552
     553    ENDIF
     554    origin_lon = origin_lon * TO_RADIANS
     555    origin_lat = origin_lat * TO_RADIANS
     556
     557    CALL report('setup_parameters', message)
     558
     559    CALL log_runtime('time', 'read')
     560
     561    CALL get_cosmo_grid( cfg, soil_files(1), rlon, rlat, hhl, hfl, depths,  &
     562                         d_depth, d_depth_rho_inv, phi_n, lambda_n,         &
     563                         phi_equat,                                         &
     564                         lonmin_cosmo, lonmax_cosmo,                        &
     565                         latmin_cosmo, latmax_cosmo,                        &
     566                         nlon, nlat, nlev, ndepths )
    546567
    547568
     
    550571!------------------------------------------------------------------------------
    551572!
    552 !--    PALM-4U domain extents
    553        lx = (nx+1) * dx
    554        ly = (ny+1) * dy
    555        
    556 !
    557 !--    PALM-4U point of Earth tangency
    558        x0 = 0.0_dp
    559        y0 = 0.0_dp
    560 
    561 !
    562 !--    time vector
    563        nt = CEILING(end_time / (step_hour * 3600.0_dp)) + 1
    564        ALLOCATE( time(nt) )
    565        CALL linspace(0.0_dp, 3600.0_dp * (nt-1), time)
    566        output_file % time => time
    567  CALL run_control('time', 'init')
    568 
    569 !
    570 !--    Convert the PALM-4U origin coordinates to COSMO's rotated-pole grid
    571        phi_c    = TO_RADIANS *                                                 &
    572                   phi2phirot( origin_lat * TO_DEGREES, origin_lon * TO_DEGREES,&
    573                               phi_n * TO_DEGREES, lambda_n * TO_DEGREES )
    574        lambda_c = TO_RADIANS *                                                 &
    575                   rla2rlarot( origin_lat * TO_DEGREES, origin_lon * TO_DEGREES,&
    576                               phi_n * TO_DEGREES, lambda_n * TO_DEGREES,     &
    577                               0.0_dp )
    578 
    579 !
    580 !--    Set gamma according to whether PALM domain is in the northern or southern
    581 !--    hemisphere of the COSMO rotated-pole system. Gamma assumes either the
    582 !--    value 0 or PI and is needed to work around around a bug in the
    583 !--    rotated-pole coordinate transformations.
    584        gam = gamma_from_hemisphere(origin_lat, phi_equat)
    585 
    586 !
    587 !--    Compute the north pole of the rotated-pole grid centred at the PALM-4U
    588 !--    domain centre. The resulting (phi_cn, lambda_cn) are coordinates in
    589 !--    COSMO-DE's rotated-pole grid.
    590        phi_cn    = phic_to_phin(phi_c)
    591        lambda_cn = lamc_to_lamn(phi_c, lambda_c)
    592 
    593        message =   "PALM-4U origin:" // NEW_LINE('') // &
    594           "           lon (lambda) = " // &
    595           TRIM(real_to_str_f(origin_lon * TO_DEGREES)) // " deg"// NEW_LINE(' ') //&
    596           "           lat (phi   ) = " // &
    597           TRIM(real_to_str_f(origin_lat * TO_DEGREES)) // " deg (geographical)" // NEW_LINE(' ') //&
    598           "           lon (lambda) = " // &
    599           TRIM(real_to_str_f(lambda_c * TO_DEGREES)) // " deg" // NEW_LINE(' ') // &
    600           "           lat (phi   ) = " // &
    601           TRIM(real_to_str_f(phi_c * TO_DEGREES)) // " deg (COSMO-DE rotated-pole)"
    602       CALL report ('setup_parameters', message)
    603 
    604        message = "North pole of the rotated COSMO-DE system:" // NEW_LINE(' ') // &
    605           "           lon (lambda) = " // &
    606           TRIM(real_to_str_f(lambda_n * TO_DEGREES)) // " deg" // NEW_LINE(' ') //&
    607           "           lat (phi   ) = " // &
    608           TRIM(real_to_str_f(phi_n * TO_DEGREES)) // " deg (geographical)"
    609        CALL report ('setup_parameters', message)
    610           
    611        message = "North pole of the rotated palm system:" // NEW_LINE(' ') // &
    612           "           lon (lambda) = " // &
    613           TRIM(real_to_str_f(lambda_cn * TO_DEGREES)) // " deg" // NEW_LINE(' ') // &
    614           "           lat (phi   ) = " // &
    615           TRIM(real_to_str_f(phi_cn * TO_DEGREES)) // " deg (COSMO-DE rotated-pole)"
    616        CALL report ('setup_parameters', message)
    617 
    618  CALL run_control('time', 'comp')
     573!-- PALM-4U domain extents
     574    lx = (nx+1) * dx
     575    ly = (ny+1) * dy
     576   
     577!
     578!-- PALM-4U point of Earth tangency
     579    x0 = 0.0_wp
     580    y0 = 0.0_wp
     581
     582!
     583!-- time vector
     584    nt = CEILING(end_time / (step_hour * 3600.0_wp)) + 1
     585    ALLOCATE( time(nt) )
     586    CALL linspace(0.0_wp, 3600.0_wp * (nt-1), time)
     587    output_file%time => time
     588    CALL log_runtime('time', 'init')
     589
     590!
     591!-- Convert the PALM-4U origin coordinates to COSMO's rotated-pole grid
     592    phi_c    = TO_RADIANS *                                                 &
     593               phi2phirot( origin_lat * TO_DEGREES, origin_lon * TO_DEGREES,&
     594                           phi_n * TO_DEGREES, lambda_n * TO_DEGREES )
     595    lambda_c = TO_RADIANS *                                                 &
     596               rla2rlarot( origin_lat * TO_DEGREES, origin_lon * TO_DEGREES,&
     597                           phi_n * TO_DEGREES, lambda_n * TO_DEGREES,     &
     598                           0.0_wp )
     599
     600!
     601!-- Set gamma according to whether PALM domain is in the northern or southern
     602!-- hemisphere of the COSMO rotated-pole system. Gamma assumes either the
     603!-- value 0 or PI and is needed to work around around a bug in the
     604!-- rotated-pole coordinate transformations.
     605    gam = gamma_from_hemisphere(origin_lat, phi_equat)
     606
     607!
     608!-- Compute the north pole of the rotated-pole grid centred at the PALM-4U
     609!-- domain centre. The resulting (phi_cn, lambda_cn) are coordinates in
     610!-- COSMO-DE's rotated-pole grid.
     611    phi_cn    = phic_to_phin(phi_c)
     612    lambda_cn = lamc_to_lamn(phi_c, lambda_c)
     613
     614    message =   "PALM-4U origin:" // NEW_LINE('') // &
     615       "           lon (lambda) = " // &
     616       TRIM(real_to_str_f(origin_lon * TO_DEGREES)) // " deg"// NEW_LINE(' ') //&
     617       "           lat (phi   ) = " // &
     618       TRIM(real_to_str_f(origin_lat * TO_DEGREES)) // " deg (geographical)" // NEW_LINE(' ') //&
     619       "           lon (lambda) = " // &
     620       TRIM(real_to_str_f(lambda_c * TO_DEGREES)) // " deg" // NEW_LINE(' ') // &
     621       "           lat (phi   ) = " // &
     622       TRIM(real_to_str_f(phi_c * TO_DEGREES)) // " deg (COSMO-DE rotated-pole)"
     623    CALL report ('setup_parameters', message)
     624
     625    message = "North pole of the rotated COSMO-DE system:" // NEW_LINE(' ') // &
     626       "           lon (lambda) = " // &
     627       TRIM(real_to_str_f(lambda_n * TO_DEGREES)) // " deg" // NEW_LINE(' ') //&
     628       "           lat (phi   ) = " // &
     629       TRIM(real_to_str_f(phi_n * TO_DEGREES)) // " deg (geographical)"
     630    CALL report ('setup_parameters', message)
     631       
     632    message = "North pole of the rotated palm system:" // NEW_LINE(' ') // &
     633       "           lon (lambda) = " // &
     634       TRIM(real_to_str_f(lambda_cn * TO_DEGREES)) // " deg" // NEW_LINE(' ') // &
     635       "           lat (phi   ) = " // &
     636       TRIM(real_to_str_f(phi_cn * TO_DEGREES)) // " deg (COSMO-DE rotated-pole)"
     637    CALL report ('setup_parameters', message)
     638
     639    CALL log_runtime('time', 'comp')
    619640
    620641!------------------------------------------------------------------------------
     
    625646!-- Compute coordiantes of the PALM centre in the source (COSMO) system
    626647    phi_centre = phirot2phi(                                                   &
    627        phirot = project(0.5_dp*ly, y0, EARTH_RADIUS) * TO_DEGREES,             &
    628        rlarot = project(0.5_dp*lx, x0, EARTH_RADIUS) * TO_DEGREES,             &
     648       phirot = project(0.5_wp*ly, y0, EARTH_RADIUS) * TO_DEGREES,             &
     649       rlarot = project(0.5_wp*lx, x0, EARTH_RADIUS) * TO_DEGREES,             &
    629650       polphi = phi_cn * TO_DEGREES,                                           &
    630651       polgam = gam * TO_DEGREES                                               &
     
    632653
    633654    lam_centre = rlarot2rla(                                                   &
    634        phirot = project(0.5_dp*ly, y0, EARTH_RADIUS) * TO_DEGREES,             &
    635        rlarot = project(0.5_dp*lx, x0, EARTH_RADIUS) * TO_DEGREES,             &
     655       phirot = project(0.5_wp*ly, y0, EARTH_RADIUS) * TO_DEGREES,             &
     656       rlarot = project(0.5_wp*lx, x0, EARTH_RADIUS) * TO_DEGREES,             &
    636657       polphi = phi_cn * TO_DEGREES, pollam = lambda_cn * TO_DEGREES,          &
    637658       polgam = gam * TO_DEGREES                                               &
     
    647668!
    648669!-- Compute boundaries of the central averaging box
    649     averaging_angle = cfg % averaging_angle * TO_RADIANS
    650     lam_east = lam_centre + 0.5_dp * averaging_angle
    651     lam_west = lam_centre - 0.5_dp * averaging_angle
    652     phi_north = phi_centre + 0.5_dp * averaging_angle
    653     phi_south = phi_centre - 0.5_dp * averaging_angle
     670    averaging_angle = cfg%averaging_angle * TO_RADIANS
     671    lam_east = lam_centre + 0.5_wp * averaging_angle
     672    lam_west = lam_centre - 0.5_wp * averaging_angle
     673    phi_north = phi_centre + 0.5_wp * averaging_angle
     674    phi_south = phi_centre - 0.5_wp * averaging_angle
    654675    averaging_width_ew = averaging_angle * COS(phi_centre) * EARTH_RADIUS
    655676    averaging_width_ns = averaging_angle * EARTH_RADIUS
     
    674695!
    675696!-- Coriolis parameter
    676     f3 = 2.0_dp * OMEGA * SIN(                                                 &
     697    f3 = 2.0_wp * OMEGA * SIN(                                                 &
    677698       TO_RADIANS*phirot2phi( phi_centre * TO_DEGREES, lam_centre * TO_DEGREES,&
    678699                              phi_n * TO_DEGREES,                              &
     
    680701    )
    681702
    682     END SUBROUTINE setup_parameters
     703 END SUBROUTINE setup_parameters
    683704
    684705
     
    689710!> coordinates and interpolation weights
    690711!------------------------------------------------------------------------------!
    691     SUBROUTINE setup_grids()
    692        CHARACTER ::  interp_mode
     712 SUBROUTINE setup_grids()
     713    CHARACTER ::  interp_mode
    693714
    694715!------------------------------------------------------------------------------
     
    696717!------------------------------------------------------------------------------
    697718!
    698 !--    palm x y z, we allocate the column to nz+1 in order to include the top
    699 !--    scalar boundary. The interpolation grids will be associated with
    700 !--    a shorter column that omits the top element.
    701        ALLOCATE( x(0:nx), y(0:ny), z(1:nz), z_column(1:nz+1) )
    702        CALL linspace(0.5_dp * dx, lx - 0.5_dp * dx, x)
    703        CALL linspace(0.5_dp * dy, ly - 0.5_dp * dy, y)
    704        CALL stretched_z(z_column, dz, dz_max=dz_max,                           &
    705                         dz_stretch_factor=dz_stretch_factor,                   &
    706                         dz_stretch_level=dz_stretch_level,                     &
    707                         dz_stretch_level_start=dz_stretch_level_start,         &
    708                         dz_stretch_level_end=dz_stretch_level_end,             &
    709                         dz_stretch_factor_array=dz_stretch_factor_array)
    710        z(1:nz) = z_column(1:nz)
    711        z_top = z_column(nz+1)
    712 
    713 !
    714 !--    palm xu yv zw, compared to the scalar grid, velocity coordinates
    715 !--    contain one element less.
    716        ALLOCATE( xu(1:nx),  yv(1:ny), zw(1:nz-1), zw_column(1:nz))
    717        CALL linspace(dx, lx - dx, xu)
    718        CALL linspace(dy, ly - dy, yv)
    719        CALL midpoints(z_column, zw_column)
    720        zw(1:nz-1) = zw_column(1:nz-1)
    721        zw_top     = zw_column(nz)
     719!-- palm x y z, we allocate the column to nz+1 in order to include the top
     720!-- scalar boundary. The interpolation grids will be associated with
     721!-- a shorter column that omits the top element.
     722    ALLOCATE( x(0:nx), y(0:ny), z(1:nz), z_column(1:nz+1) )
     723    CALL linspace(0.5_wp * dx, lx - 0.5_wp * dx, x)
     724    CALL linspace(0.5_wp * dy, ly - 0.5_wp * dy, y)
     725    CALL stretched_z(z_column, dz, dz_max=dz_max,                           &
     726                     dz_stretch_factor=dz_stretch_factor,                   &
     727                     dz_stretch_level=dz_stretch_level,                     &
     728                     dz_stretch_level_start=dz_stretch_level_start,         &
     729                     dz_stretch_level_end=dz_stretch_level_end,             &
     730                     dz_stretch_factor_array=dz_stretch_factor_array)
     731    z(1:nz) = z_column(1:nz)
     732    z_top = z_column(nz+1)
     733
     734!
     735!-- palm xu yv zw, compared to the scalar grid, velocity coordinates
     736!-- contain one element less.
     737    ALLOCATE( xu(1:nx),  yv(1:ny), zw(1:nz-1), zw_column(1:nz))
     738    CALL linspace(dx, lx - dx, xu)
     739    CALL linspace(dy, ly - dy, yv)
     740    CALL midpoints(z_column, zw_column)
     741    zw(1:nz-1) = zw_column(1:nz-1)
     742    zw_top     = zw_column(nz)
    722743
    723744
     
    725746! Section 1: Define initialization and boundary grids
    726747!------------------------------------------------------------------------------
    727        CALL init_grid_definition('palm', grid=palm_grid,                       &
    728                xmin=0.0_dp, xmax=lx,                                           &
    729                ymin=0.0_dp, ymax=ly,                                           &
    730                x0=x0, y0=y0, z0=z0,                                            &
    731                nx=nx, ny=ny, nz=nz, z=z, zw=zw, ic_mode=cfg % ic_mode)
    732 
    733 !
    734 !--    Subtracting 1 because arrays will be allocated with nlon + 1 elements.
    735        CALL init_grid_definition('cosmo-de', grid=cosmo_grid,                  &
    736                xmin=lonmin_cosmo, xmax=lonmax_cosmo,                           &
    737                ymin=latmin_cosmo, ymax=latmax_cosmo,                           &
    738                x0=x0, y0=y0, z0=0.0_dp,                                        &
    739                nx=nlon-1, ny=nlat-1, nz=nlev-1)
    740 
    741 !
    742 !--    Define intermediate grid. This is the same as palm_grid except with a
    743 !--    much coarser vertical grid. The vertical levels are interpolated in each
    744 !--    PALM column from COSMO's secondary levels. The main levels are then
    745 !--    computed as the averages of the bounding secondary levels.
    746        CALL init_grid_definition('palm intermediate', grid=palm_intermediate,  &
    747                xmin=0.0_dp, xmax=lx,                                           &
    748                ymin=0.0_dp, ymax=ly,                                           &
    749                x0=x0, y0=y0, z0=z0,                                            &
    750                nx=nx, ny=ny, nz=nlev-2)
    751 
    752        CALL init_grid_definition('boundary', grid=u_initial_grid,              &
     748    CALL init_grid_definition('palm', grid=palm_grid,                       &
     749            xmin=0.0_wp, xmax=lx,                                           &
     750            ymin=0.0_wp, ymax=ly,                                           &
     751            x0=x0, y0=y0, z0=z0,                                            &
     752            nx=nx, ny=ny, nz=nz, z=z, zw=zw, ic_mode=cfg%ic_mode)
     753
     754!
     755!-- Subtracting 1 because arrays will be allocated with nlon + 1 elements.
     756    CALL init_grid_definition('cosmo-de', grid=cosmo_grid,                  &
     757            xmin=lonmin_cosmo, xmax=lonmax_cosmo,                           &
     758            ymin=latmin_cosmo, ymax=latmax_cosmo,                           &
     759            x0=x0, y0=y0, z0=0.0_wp,                                        &
     760            nx=nlon-1, ny=nlat-1, nz=nlev-1)
     761
     762!
     763!-- Define intermediate grid. This is the same as palm_grid except with a
     764!-- much coarser vertical grid. The vertical levels are interpolated in each
     765!-- PALM column from COSMO's secondary levels. The main levels are then
     766!-- computed as the averages of the bounding secondary levels.
     767    CALL init_grid_definition('palm intermediate', grid=palm_intermediate,  &
     768            xmin=0.0_wp, xmax=lx,                                           &
     769            ymin=0.0_wp, ymax=ly,                                           &
     770            x0=x0, y0=y0, z0=z0,                                            &
     771            nx=nx, ny=ny, nz=nlev-2)
     772
     773    CALL init_grid_definition('boundary', grid=u_initial_grid,              &
     774            xmin = dx, xmax = lx - dx,                                      &
     775            ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     776            x0=x0, y0=y0, z0 = z0,                                          &
     777            nx = nx-1, ny = ny, nz = nz,                                    &
     778            z=z, ic_mode=cfg%ic_mode)
     779
     780    CALL init_grid_definition('boundary', grid=v_initial_grid,              &
     781            xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     782            ymin = dy, ymax = ly - dy,                                      &
     783            x0=x0, y0=y0, z0 = z0,                                          &
     784            nx = nx, ny = ny-1, nz = nz,                                    &
     785            z=z, ic_mode=cfg%ic_mode)
     786
     787    CALL init_grid_definition('boundary', grid=w_initial_grid,              &
     788            xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     789            ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     790            x0=x0, y0=y0, z0 = z0,                                          &
     791            nx = nx, ny = ny, nz = nz-1,                                    &
     792            z=zw, ic_mode=cfg%ic_mode)
     793
     794    CALL init_grid_definition('boundary intermediate', grid=u_initial_intermediate,      &
     795            xmin = dx, xmax = lx - dx,                                      &
     796            ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     797            x0=x0, y0=y0, z0 = z0,                                          &
     798            nx = nx-1, ny = ny, nz = nlev - 2)
     799
     800    CALL init_grid_definition('boundary intermediate', grid=v_initial_intermediate,      &
     801            xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     802            ymin = dy, ymax = ly - dy,                                      &
     803            x0=x0, y0=y0, z0 = z0,                                          &
     804            nx = nx, ny = ny-1, nz = nlev - 2)
     805
     806    CALL init_grid_definition('boundary intermediate', grid=w_initial_intermediate,      &
     807            xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     808            ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     809            x0=x0, y0=y0, z0 = z0,                                          &
     810            nx = nx, ny = ny, nz = nlev - 1)
     811
     812    IF (boundary_variables_required)  THEN
     813!
     814!------------------------------------------------------------------------------
     815! Section 2: Define PALM-4U boundary grids
     816!------------------------------------------------------------------------------
     817       CALL init_grid_definition('boundary', grid=scalars_east_grid,           &
     818               xmin = lx + 0.5_wp * dx, xmax = lx + 0.5_wp * dx,               &
     819               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     820               x0=x0, y0=y0, z0 = z0,                                          &
     821               nx = 0, ny = ny, nz = nz, z=z)
     822
     823       CALL init_grid_definition('boundary', grid=scalars_west_grid,           &
     824               xmin = -0.5_wp * dx, xmax = -0.5_wp * dx,                       &
     825               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     826               x0=x0, y0=y0, z0 = z0,                                          &
     827               nx = 0, ny = ny, nz = nz, z=z)
     828
     829       CALL init_grid_definition('boundary', grid=scalars_north_grid,          &
     830               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     831               ymin = ly + 0.5_wp * dy, ymax = ly + 0.5_wp * dy,               &
     832               x0=x0, y0=y0, z0 = z0,                                          &
     833               nx = nx, ny = 0, nz = nz, z=z)
     834
     835       CALL init_grid_definition('boundary', grid=scalars_south_grid,          &
     836               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     837               ymin = -0.5_wp * dy, ymax = -0.5_wp * dy,                       &
     838               x0=x0, y0=y0, z0 = z0,                                          &
     839               nx = nx, ny = 0, nz = nz, z=z)
     840
     841       CALL init_grid_definition('boundary', grid=scalars_top_grid,            &
     842               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     843               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     844               x0=x0, y0=y0, z0 = z0,                                          &
     845               nx = nx, ny = ny, nz = 1, z=(/z_top/))
     846
     847       CALL init_grid_definition('boundary', grid=u_east_grid,                 &
     848               xmin = lx, xmax = lx,                                           &
     849               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     850               x0=x0, y0=y0, z0 = z0,                                          &
     851               nx = 0, ny = ny, nz = nz, z=z)
     852
     853       CALL init_grid_definition('boundary', grid=u_west_grid,                 &
     854               xmin = 0.0_wp, xmax = 0.0_wp,                                   &
     855               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     856               x0=x0, y0=y0, z0 = z0,                                          &
     857               nx = 0, ny = ny, nz = nz, z=z)
     858
     859       CALL init_grid_definition('boundary', grid=u_north_grid,                &
    753860               xmin = dx, xmax = lx - dx,                                      &
    754                ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
     861               ymin = ly + 0.5_wp * dy, ymax = ly + 0.5_wp * dy,               &
    755862               x0=x0, y0=y0, z0 = z0,                                          &
    756                nx = nx-1, ny = ny, nz = nz,                                    &
    757                z=z, ic_mode=cfg % ic_mode)
    758 
    759        CALL init_grid_definition('boundary', grid=v_initial_grid,              &
    760                xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
     863               nx = nx-1, ny = 0, nz = nz, z=z)
     864   
     865       CALL init_grid_definition('boundary', grid=u_south_grid,                &
     866               xmin = dx, xmax = lx - dx,                                      &
     867               ymin = -0.5_wp * dy, ymax = -0.5_wp * dy,                       &
     868               x0=x0, y0=y0, z0 = z0,                                          &
     869               nx = nx-1, ny = 0, nz = nz, z=z)
     870
     871       CALL init_grid_definition('boundary', grid=u_top_grid,                  &
     872               xmin = dx, xmax = lx - dx,                                      &
     873               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     874               x0=x0, y0=y0, z0 = z0,                                          &
     875               nx = nx-1, ny = ny, nz = 1, z=(/z_top/))
     876
     877       CALL init_grid_definition('boundary', grid=v_east_grid,                 &
     878               xmin = lx + 0.5_wp * dx, xmax = lx + 0.5_wp * dx,               &
    761879               ymin = dy, ymax = ly - dy,                                      &
    762880               x0=x0, y0=y0, z0 = z0,                                          &
    763                nx = nx, ny = ny-1, nz = nz,                                    &
    764                z=z, ic_mode=cfg % ic_mode)
    765 
    766        CALL init_grid_definition('boundary', grid=w_initial_grid,              &
    767                xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    768                ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
     881               nx = 0, ny = ny-1, nz = nz, z=z)
     882
     883       CALL init_grid_definition('boundary', grid=v_west_grid,                 &
     884               xmin = -0.5_wp * dx, xmax = -0.5_wp * dx,                       &
     885               ymin = dy, ymax = ly - dy,                                      &
    769886               x0=x0, y0=y0, z0 = z0,                                          &
    770                nx = nx, ny = ny, nz = nz-1,                                    &
    771                z=zw, ic_mode=cfg % ic_mode)
    772 
    773        CALL init_grid_definition('boundary intermediate', grid=u_initial_intermediate,      &
     887               nx = 0, ny = ny-1, nz = nz, z=z)
     888
     889       CALL init_grid_definition('boundary', grid=v_north_grid,                &
     890               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     891               ymin = ly, ymax = ly,                                           &
     892               x0=x0, y0=y0, z0 = z0,                                          &
     893               nx = nx, ny = 0, nz = nz, z=z)
     894
     895       CALL init_grid_definition('boundary', grid=v_south_grid,                &
     896               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     897               ymin = 0.0_wp, ymax = 0.0_wp,                                   &
     898               x0=x0, y0=y0, z0 = z0,                                          &
     899               nx = nx, ny = 0, nz = nz, z=z)
     900
     901       CALL init_grid_definition('boundary', grid=v_top_grid,                  &
     902               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     903               ymin = dy, ymax = ly - dy,                                      &
     904               x0=x0, y0=y0, z0 = z0,                                          &
     905               nx = nx, ny = ny-1, nz = 1, z=(/z_top/))
     906
     907       CALL init_grid_definition('boundary', grid=w_east_grid,                 &
     908               xmin = lx + 0.5_wp * dx, xmax = lx + 0.5_wp * dx,               &
     909               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     910               x0=x0, y0=y0, z0 = z0,                                          &
     911               nx = 0, ny = ny, nz = nz - 1, z=zw)
     912
     913       CALL init_grid_definition('boundary', grid=w_west_grid,                 &
     914               xmin = -0.5_wp * dx, xmax = -0.5_wp * dx,                       &
     915               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     916               x0=x0, y0=y0, z0 = z0,                                          &
     917               nx = 0, ny = ny, nz = nz - 1, z=zw)
     918
     919       CALL init_grid_definition('boundary', grid=w_north_grid,                &
     920               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     921               ymin = ly + 0.5_wp * dy, ymax = ly + 0.5_wp * dy,               &
     922               x0=x0, y0=y0, z0 = z0,                                          &
     923               nx = nx, ny = 0, nz = nz - 1, z=zw)
     924
     925       CALL init_grid_definition('boundary', grid=w_south_grid,                &
     926               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     927               ymin = -0.5_wp * dy, ymax = -0.5_wp * dy,                       &
     928               x0=x0, y0=y0, z0 = z0,                                          &
     929               nx = nx, ny = 0, nz = nz - 1, z=zw)
     930
     931       CALL init_grid_definition('boundary', grid=w_top_grid,                  &
     932               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     933               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     934               x0=x0, y0=y0, z0 = z0,                                          &
     935               nx = nx, ny = ny, nz = 1, z=(/zw_top/))
     936
     937       CALL init_grid_definition('boundary intermediate', grid=scalars_east_intermediate,   &
     938               xmin = lx + 0.5_wp * dx, xmax = lx + 0.5_wp * dx,               &
     939               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     940               x0=x0, y0=y0, z0 = z0,                                          &
     941               nx = 0, ny = ny, nz = nlev - 2)
     942
     943       CALL init_grid_definition('boundary intermediate', grid=scalars_west_intermediate,   &
     944               xmin = -0.5_wp * dx, xmax = -0.5_wp * dx,                       &
     945               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     946               x0=x0, y0=y0, z0 = z0,                                          &
     947               nx = 0, ny = ny, nz = nlev - 2)
     948
     949       CALL init_grid_definition('boundary intermediate', grid=scalars_north_intermediate,  &
     950               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     951               ymin = ly + 0.5_wp * dy, ymax = ly + 0.5_wp * dy,               &
     952               x0=x0, y0=y0, z0 = z0,                                          &
     953               nx = nx, ny = 0, nz = nlev - 2)
     954
     955       CALL init_grid_definition('boundary intermediate', grid=scalars_south_intermediate,  &
     956               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     957               ymin = -0.5_wp * dy, ymax = -0.5_wp * dy,                       &
     958               x0=x0, y0=y0, z0 = z0,                                          &
     959               nx = nx, ny = 0, nz = nlev - 2)
     960
     961       CALL init_grid_definition('boundary intermediate', grid=scalars_top_intermediate,    &
     962               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     963               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     964               x0=x0, y0=y0, z0 = z0,                                          &
     965               nx = nx, ny = ny, nz = nlev - 2)
     966
     967       CALL init_grid_definition('boundary intermediate', grid=u_east_intermediate,         &
     968               xmin = lx, xmax = lx,                                           &
     969               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     970               x0=x0, y0=y0, z0 = z0,                                          &
     971               nx = 0, ny = ny, nz = nlev - 2)
     972
     973       CALL init_grid_definition('boundary intermediate', grid=u_west_intermediate,         &
     974               xmin = 0.0_wp, xmax = 0.0_wp,                                   &
     975               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
     976               x0=x0, y0=y0, z0 = z0,                                          &
     977               nx = 0, ny = ny, nz = nlev - 2)
     978
     979       CALL init_grid_definition('boundary intermediate', grid=u_north_intermediate,        &
    774980               xmin = dx, xmax = lx - dx,                                      &
    775                ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
     981               ymin = ly + 0.5_wp * dy, ymax = ly + 0.5_wp * dy,               &
     982               x0=x0, y0=y0, z0 = z0,                                          &
     983               nx = nx-1, ny = 0, nz = nlev - 2)
     984
     985       CALL init_grid_definition('boundary intermediate', grid=u_south_intermediate,        &
     986               xmin = dx, xmax = lx - dx,                                      &
     987               ymin = -0.5_wp * dy, ymax = -0.5_wp * dy,                       &
     988               x0=x0, y0=y0, z0 = z0,                                          &
     989               nx = nx-1, ny = 0, nz = nlev - 2)
     990
     991       CALL init_grid_definition('boundary intermediate', grid=u_top_intermediate,          &
     992               xmin = dx, xmax = lx - dx,                                      &
     993               ymin = 0.5_wp * dy, ymax = ly - 0.5_wp * dy,                    &
    776994               x0=x0, y0=y0, z0 = z0,                                          &
    777995               nx = nx-1, ny = ny, nz = nlev - 2)
    778996
    779        CALL init_grid_definition('boundary intermediate', grid=v_initial_intermediate,      &
    780                xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
     997       CALL init_grid_definition('boundary intermediate', grid=v_east_intermediate,         &
     998               xmin = lx + 0.5_wp * dx, xmax = lx + 0.5_wp * dx,               &
     999               ymin = dy, ymax = ly - dy,                                      &
     1000               x0=x0, y0=y0, z0 = z0,                                          &
     1001               nx = 0, ny = ny-1, nz = nlev - 2)
     1002
     1003       CALL init_grid_definition('boundary intermediate', grid=v_west_intermediate,         &
     1004               xmin = -0.5_wp * dx, xmax = -0.5_wp * dx,                       &
     1005               ymin = dy, ymax = ly - dy,                                      &
     1006               x0=x0, y0=y0, z0 = z0,                                          &
     1007               nx = 0, ny = ny-1, nz = nlev - 2)
     1008
     1009       CALL init_grid_definition('boundary intermediate', grid=v_north_intermediate,        &
     1010               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     1011               ymin = ly, ymax = ly,                                           &
     1012               x0=x0, y0=y0, z0 = z0,                                          &
     1013               nx = nx, ny = 0, nz = nlev - 2)
     1014
     1015       CALL init_grid_definition('boundary intermediate', grid=v_south_intermediate,        &
     1016               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     1017               ymin = 0.0_wp, ymax = 0.0_wp,                                   &
     1018               x0=x0, y0=y0, z0 = z0,                                          &
     1019               nx = nx, ny = 0, nz = nlev - 2)
     1020
     1021       CALL init_grid_definition('boundary intermediate', grid=v_top_intermediate,          &
     1022               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
    7811023               ymin = dy, ymax = ly - dy,                                      &
    7821024               x0=x0, y0=y0, z0 = z0,                                          &
    7831025               nx = nx, ny = ny-1, nz = nlev - 2)
    7841026
    785        CALL init_grid_definition('boundary intermediate', grid=w_initial_intermediate,      &
    786                xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    787                ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
     1027       CALL init_grid_definition('boundary intermediate', grid=w_east_intermediate,         &
     1028               xmin = lx + 0.5_wp * dx, xmax = lx + 0.5_wp * dx,               &
     1029               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     1030               x0=x0, y0=y0, z0 = z0,                                          &
     1031               nx = 0, ny = ny, nz = nlev - 1)
     1032
     1033       CALL init_grid_definition('boundary intermediate', grid=w_west_intermediate,         &
     1034               xmin = -0.5_wp * dx, xmax = -0.5_wp * dx,                       &
     1035               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
     1036               x0=x0, y0=y0, z0 = z0,                                          &
     1037               nx = 0, ny = ny, nz = nlev - 1)
     1038
     1039       CALL init_grid_definition('boundary intermediate', grid=w_north_intermediate,        &
     1040               xmin = 0.5_wp * dx, xmax = lx - 0.5_wp * dx,                    &
     1041               ymin = ly + 0.5_wp * dy, ymax = ly + 0.5_wp * dy,               &
     1042               x0=x0, y0=y0, z0 = z0,                                          &
     1043               nx = nx, ny = 0, nz = nlev - 1)
     1044
     1045       CALL init_grid_definition('boundary intermediate', grid=w_south_intermediate,        &
     1046               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     1047               ymin = -0.5_wp * dy, ymax = -0.5_wp * dy,                       &
     1048               x0=x0, y0=y0, z0 = z0,                                          &
     1049               nx = nx, ny = 0, nz = nlev - 1)
     1050
     1051       CALL init_grid_definition('boundary intermediate', grid=w_top_intermediate,          &
     1052               xmin =  0.5_wp * dx, xmax = lx - 0.5_wp * dx,                   &
     1053               ymin =  0.5_wp * dy, ymax = ly - 0.5_wp * dy,                   &
    7881054               x0=x0, y0=y0, z0 = z0,                                          &
    7891055               nx = nx, ny = ny, nz = nlev - 1)
    790 
    791       IF (boundary_variables_required)  THEN
    792 !
    793 !------------------------------------------------------------------------------
    794 ! Section 2: Define PALM-4U boundary grids
    795 !------------------------------------------------------------------------------
    796           CALL init_grid_definition('boundary', grid=scalars_east_grid,           &
    797                   xmin = lx + 0.5_dp * dx, xmax = lx + 0.5_dp * dx,               &
    798                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    799                   x0=x0, y0=y0, z0 = z0,                                          &
    800                   nx = 0, ny = ny, nz = nz, z=z)
    801 
    802           CALL init_grid_definition('boundary', grid=scalars_west_grid,           &
    803                   xmin = -0.5_dp * dx, xmax = -0.5_dp * dx,                       &
    804                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    805                   x0=x0, y0=y0, z0 = z0,                                          &
    806                   nx = 0, ny = ny, nz = nz, z=z)
    807 
    808           CALL init_grid_definition('boundary', grid=scalars_north_grid,          &
    809                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    810                   ymin = ly + 0.5_dp * dy, ymax = ly + 0.5_dp * dy,               &
    811                   x0=x0, y0=y0, z0 = z0,                                          &
    812                   nx = nx, ny = 0, nz = nz, z=z)
    813 
    814           CALL init_grid_definition('boundary', grid=scalars_south_grid,          &
    815                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    816                   ymin = -0.5_dp * dy, ymax = -0.5_dp * dy,                       &
    817                   x0=x0, y0=y0, z0 = z0,                                          &
    818                   nx = nx, ny = 0, nz = nz, z=z)
    819 
    820           CALL init_grid_definition('boundary', grid=scalars_top_grid,            &
    821                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    822                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    823                   x0=x0, y0=y0, z0 = z0,                                          &
    824                   nx = nx, ny = ny, nz = 1, z=(/z_top/))
    825 
    826           CALL init_grid_definition('boundary', grid=u_east_grid,                 &
    827                   xmin = lx, xmax = lx,                                           &
    828                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    829                   x0=x0, y0=y0, z0 = z0,                                          &
    830                   nx = 0, ny = ny, nz = nz, z=z)
    831 
    832           CALL init_grid_definition('boundary', grid=u_west_grid,                 &
    833                   xmin = 0.0_dp, xmax = 0.0_dp,                                   &
    834                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    835                   x0=x0, y0=y0, z0 = z0,                                          &
    836                   nx = 0, ny = ny, nz = nz, z=z)
    837 
    838           CALL init_grid_definition('boundary', grid=u_north_grid,                &
    839                   xmin = dx, xmax = lx - dx,                                      &
    840                   ymin = ly + 0.5_dp * dy, ymax = ly + 0.5_dp * dy,               &
    841                   x0=x0, y0=y0, z0 = z0,                                          &
    842                   nx = nx-1, ny = 0, nz = nz, z=z)
    843    
    844           CALL init_grid_definition('boundary', grid=u_south_grid,                &
    845                   xmin = dx, xmax = lx - dx,                                      &
    846                   ymin = -0.5_dp * dy, ymax = -0.5_dp * dy,                       &
    847                   x0=x0, y0=y0, z0 = z0,                                          &
    848                   nx = nx-1, ny = 0, nz = nz, z=z)
    849 
    850           CALL init_grid_definition('boundary', grid=u_top_grid,                  &
    851                   xmin = dx, xmax = lx - dx,                                      &
    852                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    853                   x0=x0, y0=y0, z0 = z0,                                          &
    854                   nx = nx-1, ny = ny, nz = 1, z=(/z_top/))
    855 
    856           CALL init_grid_definition('boundary', grid=v_east_grid,                 &
    857                   xmin = lx + 0.5_dp * dx, xmax = lx + 0.5_dp * dx,               &
    858                   ymin = dy, ymax = ly - dy,                                      &
    859                   x0=x0, y0=y0, z0 = z0,                                          &
    860                   nx = 0, ny = ny-1, nz = nz, z=z)
    861 
    862           CALL init_grid_definition('boundary', grid=v_west_grid,                 &
    863                   xmin = -0.5_dp * dx, xmax = -0.5_dp * dx,                       &
    864                   ymin = dy, ymax = ly - dy,                                      &
    865                   x0=x0, y0=y0, z0 = z0,                                          &
    866                   nx = 0, ny = ny-1, nz = nz, z=z)
    867 
    868           CALL init_grid_definition('boundary', grid=v_north_grid,                &
    869                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    870                   ymin = ly, ymax = ly,                                           &
    871                   x0=x0, y0=y0, z0 = z0,                                          &
    872                   nx = nx, ny = 0, nz = nz, z=z)
    873 
    874           CALL init_grid_definition('boundary', grid=v_south_grid,                &
    875                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    876                   ymin = 0.0_dp, ymax = 0.0_dp,                                   &
    877                   x0=x0, y0=y0, z0 = z0,                                          &
    878                   nx = nx, ny = 0, nz = nz, z=z)
    879 
    880           CALL init_grid_definition('boundary', grid=v_top_grid,                  &
    881                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    882                   ymin = dy, ymax = ly - dy,                                      &
    883                   x0=x0, y0=y0, z0 = z0,                                          &
    884                   nx = nx, ny = ny-1, nz = 1, z=(/z_top/))
    885 
    886           CALL init_grid_definition('boundary', grid=w_east_grid,                 &
    887                   xmin = lx + 0.5_dp * dx, xmax = lx + 0.5_dp * dx,               &
    888                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    889                   x0=x0, y0=y0, z0 = z0,                                          &
    890                   nx = 0, ny = ny, nz = nz - 1, z=zw)
    891 
    892           CALL init_grid_definition('boundary', grid=w_west_grid,                 &
    893                   xmin = -0.5_dp * dx, xmax = -0.5_dp * dx,                       &
    894                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    895                   x0=x0, y0=y0, z0 = z0,                                          &
    896                   nx = 0, ny = ny, nz = nz - 1, z=zw)
    897 
    898           CALL init_grid_definition('boundary', grid=w_north_grid,                &
    899                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    900                   ymin = ly + 0.5_dp * dy, ymax = ly + 0.5_dp * dy,               &
    901                   x0=x0, y0=y0, z0 = z0,                                          &
    902                   nx = nx, ny = 0, nz = nz - 1, z=zw)
    903 
    904           CALL init_grid_definition('boundary', grid=w_south_grid,                &
    905                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    906                   ymin = -0.5_dp * dy, ymax = -0.5_dp * dy,                       &
    907                   x0=x0, y0=y0, z0 = z0,                                          &
    908                   nx = nx, ny = 0, nz = nz - 1, z=zw)
    909 
    910           CALL init_grid_definition('boundary', grid=w_top_grid,                  &
    911                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    912                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    913                   x0=x0, y0=y0, z0 = z0,                                          &
    914                   nx = nx, ny = ny, nz = 1, z=(/zw_top/))
    915 
    916           CALL init_grid_definition('boundary intermediate', grid=scalars_east_intermediate,   &
    917                   xmin = lx + 0.5_dp * dx, xmax = lx + 0.5_dp * dx,               &
    918                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    919                   x0=x0, y0=y0, z0 = z0,                                          &
    920                   nx = 0, ny = ny, nz = nlev - 2)
    921 
    922           CALL init_grid_definition('boundary intermediate', grid=scalars_west_intermediate,   &
    923                   xmin = -0.5_dp * dx, xmax = -0.5_dp * dx,                       &
    924                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    925                   x0=x0, y0=y0, z0 = z0,                                          &
    926                   nx = 0, ny = ny, nz = nlev - 2)
    927 
    928           CALL init_grid_definition('boundary intermediate', grid=scalars_north_intermediate,  &
    929                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    930                   ymin = ly + 0.5_dp * dy, ymax = ly + 0.5_dp * dy,               &
    931                   x0=x0, y0=y0, z0 = z0,                                          &
    932                   nx = nx, ny = 0, nz = nlev - 2)
    933 
    934           CALL init_grid_definition('boundary intermediate', grid=scalars_south_intermediate,  &
    935                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    936                   ymin = -0.5_dp * dy, ymax = -0.5_dp * dy,                       &
    937                   x0=x0, y0=y0, z0 = z0,                                          &
    938                   nx = nx, ny = 0, nz = nlev - 2)
    939 
    940           CALL init_grid_definition('boundary intermediate', grid=scalars_top_intermediate,    &
    941                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    942                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    943                   x0=x0, y0=y0, z0 = z0,                                          &
    944                   nx = nx, ny = ny, nz = nlev - 2)
    945 
    946           CALL init_grid_definition('boundary intermediate', grid=u_east_intermediate,         &
    947                   xmin = lx, xmax = lx,                                           &
    948                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    949                   x0=x0, y0=y0, z0 = z0,                                          &
    950                   nx = 0, ny = ny, nz = nlev - 2)
    951 
    952           CALL init_grid_definition('boundary intermediate', grid=u_west_intermediate,         &
    953                   xmin = 0.0_dp, xmax = 0.0_dp,                                   &
    954                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    955                   x0=x0, y0=y0, z0 = z0,                                          &
    956                   nx = 0, ny = ny, nz = nlev - 2)
    957 
    958           CALL init_grid_definition('boundary intermediate', grid=u_north_intermediate,        &
    959                   xmin = dx, xmax = lx - dx,                                      &
    960                   ymin = ly + 0.5_dp * dy, ymax = ly + 0.5_dp * dy,               &
    961                   x0=x0, y0=y0, z0 = z0,                                          &
    962                   nx = nx-1, ny = 0, nz = nlev - 2)
    963 
    964           CALL init_grid_definition('boundary intermediate', grid=u_south_intermediate,        &
    965                   xmin = dx, xmax = lx - dx,                                      &
    966                   ymin = -0.5_dp * dy, ymax = -0.5_dp * dy,                       &
    967                   x0=x0, y0=y0, z0 = z0,                                          &
    968                   nx = nx-1, ny = 0, nz = nlev - 2)
    969 
    970           CALL init_grid_definition('boundary intermediate', grid=u_top_intermediate,          &
    971                   xmin = dx, xmax = lx - dx,                                      &
    972                   ymin = 0.5_dp * dy, ymax = ly - 0.5_dp * dy,                    &
    973                   x0=x0, y0=y0, z0 = z0,                                          &
    974                   nx = nx-1, ny = ny, nz = nlev - 2)
    975 
    976           CALL init_grid_definition('boundary intermediate', grid=v_east_intermediate,         &
    977                   xmin = lx + 0.5_dp * dx, xmax = lx + 0.5_dp * dx,               &
    978                   ymin = dy, ymax = ly - dy,                                      &
    979                   x0=x0, y0=y0, z0 = z0,                                          &
    980                   nx = 0, ny = ny-1, nz = nlev - 2)
    981 
    982           CALL init_grid_definition('boundary intermediate', grid=v_west_intermediate,         &
    983                   xmin = -0.5_dp * dx, xmax = -0.5_dp * dx,                       &
    984                   ymin = dy, ymax = ly - dy,                                      &
    985                   x0=x0, y0=y0, z0 = z0,                                          &
    986                   nx = 0, ny = ny-1, nz = nlev - 2)
    987 
    988           CALL init_grid_definition('boundary intermediate', grid=v_north_intermediate,        &
    989                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    990                   ymin = ly, ymax = ly,                                           &
    991                   x0=x0, y0=y0, z0 = z0,                                          &
    992                   nx = nx, ny = 0, nz = nlev - 2)
    993 
    994           CALL init_grid_definition('boundary intermediate', grid=v_south_intermediate,        &
    995                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    996                   ymin = 0.0_dp, ymax = 0.0_dp,                                   &
    997                   x0=x0, y0=y0, z0 = z0,                                          &
    998                   nx = nx, ny = 0, nz = nlev - 2)
    999 
    1000           CALL init_grid_definition('boundary intermediate', grid=v_top_intermediate,          &
    1001                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    1002                   ymin = dy, ymax = ly - dy,                                      &
    1003                   x0=x0, y0=y0, z0 = z0,                                          &
    1004                   nx = nx, ny = ny-1, nz = nlev - 2)
    1005 
    1006           CALL init_grid_definition('boundary intermediate', grid=w_east_intermediate,         &
    1007                   xmin = lx + 0.5_dp * dx, xmax = lx + 0.5_dp * dx,               &
    1008                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    1009                   x0=x0, y0=y0, z0 = z0,                                          &
    1010                   nx = 0, ny = ny, nz = nlev - 1)
    1011 
    1012           CALL init_grid_definition('boundary intermediate', grid=w_west_intermediate,         &
    1013                   xmin = -0.5_dp * dx, xmax = -0.5_dp * dx,                       &
    1014                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    1015                   x0=x0, y0=y0, z0 = z0,                                          &
    1016                   nx = 0, ny = ny, nz = nlev - 1)
    1017 
    1018           CALL init_grid_definition('boundary intermediate', grid=w_north_intermediate,        &
    1019                   xmin = 0.5_dp * dx, xmax = lx - 0.5_dp * dx,                    &
    1020                   ymin = ly + 0.5_dp * dy, ymax = ly + 0.5_dp * dy,               &
    1021                   x0=x0, y0=y0, z0 = z0,                                          &
    1022                   nx = nx, ny = 0, nz = nlev - 1)
    1023 
    1024           CALL init_grid_definition('boundary intermediate', grid=w_south_intermediate,        &
    1025                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    1026                   ymin = -0.5_dp * dy, ymax = -0.5_dp * dy,                       &
    1027                   x0=x0, y0=y0, z0 = z0,                                          &
    1028                   nx = nx, ny = 0, nz = nlev - 1)
    1029 
    1030           CALL init_grid_definition('boundary intermediate', grid=w_top_intermediate,          &
    1031                   xmin =  0.5_dp * dx, xmax = lx - 0.5_dp * dx,                   &
    1032                   ymin =  0.5_dp * dy, ymax = ly - 0.5_dp * dy,                   &
    1033                   x0=x0, y0=y0, z0 = z0,                                          &
    1034                   nx = nx, ny = ny, nz = nlev - 1)
    1035        ENDIF
     1056    ENDIF
    10361057
    10371058!                                                                             
     
    10401061!------------------------------------------------------------------------------
    10411062
    1042        lonmin_palm = MINVAL(palm_intermediate % clon)
    1043        lonmax_palm = MAXVAL(palm_intermediate % clon)
    1044        latmin_palm = MINVAL(palm_intermediate % clat)
    1045        latmax_palm = MAXVAL(palm_intermediate % clat)
    1046 
    1047        CALL init_averaging_grid(averaged_initial_scalar_profile, cosmo_grid,   &
    1048                x = 0.5_dp * lx, y = 0.5_dp * ly, z = z, z0 = z0,               &
    1049                lonmin = lonmin_palm, lonmax = lonmax_palm,                     &
    1050                latmin = latmin_palm, latmax = latmax_palm,                     &
    1051                kind='scalar', name='averaged initial scalar')
    1052 
    1053        CALL init_averaging_grid(averaged_initial_w_profile, cosmo_grid,        &
    1054                x = 0.5_dp * lx, y = 0.5_dp * ly, z = zw, z0 = z0,              &
    1055                lonmin = lonmin_palm, lonmax = lonmax_palm,                     &
    1056                latmin = latmin_palm, latmax = latmax_palm,                     &
    1057                kind='w', name='averaged initial w')
    1058 
    1059        CALL init_averaging_grid(averaged_scalar_profile, cosmo_grid,           &
    1060                x = 0.5_dp * lx, y = 0.5_dp * ly, z = z, z0 = z0,               &
    1061                lonmin = lam_west, lonmax = lam_east,                           &
    1062                latmin = phi_south, latmax = phi_north,                         &
    1063                kind='scalar', name='centre geostrophic scalar')
    1064 
    1065        CALL init_averaging_grid(averaged_w_profile, cosmo_grid,                &
    1066                x = 0.5_dp * lx, y = 0.5_dp * ly, z = zw, z0 = z0,              &
    1067                lonmin = lam_west, lonmax = lam_east,                           &
    1068                latmin = phi_south, latmax = phi_north,                         &
    1069                kind='w', name='centre geostrophic w')
    1070 
    1071        CALL init_averaging_grid(south_averaged_scalar_profile, cosmo_grid,     &
    1072                x = 0.5_dp * lx, y = 0.5_dp * ly, z = z, z0 = z0,               &
    1073                lonmin = lam_west, lonmax = lam_east,                           &
    1074                latmin = phi_centre - averaging_angle,                          &
    1075                latmax = phi_centre,                                            &
    1076                kind='scalar', name='south geostrophic scalar')
    1077 
    1078        CALL init_averaging_grid(north_averaged_scalar_profile, cosmo_grid,     &
    1079                x = 0.5_dp * lx, y = 0.5_dp * ly, z = z, z0 = z0,               &
    1080                lonmin = lam_west, lonmax = lam_east,                           &
    1081                latmin = phi_centre,                                            &
    1082                latmax = phi_centre + averaging_angle,                          &
    1083                kind='scalar', name='north geostrophic scalar')
    1084 
    1085        CALL init_averaging_grid(west_averaged_scalar_profile, cosmo_grid,      &
    1086                x = 0.5_dp * lx, y = 0.5_dp * ly, z = z, z0 = z0,               &
    1087                lonmin = lam_centre - averaging_angle,                          &
    1088                lonmax = lam_centre,                                            &
    1089                latmin = phi_south, latmax = phi_north,                         &
    1090                kind='scalar', name='west geostrophic scalar')
    1091 
    1092        CALL init_averaging_grid(east_averaged_scalar_profile, cosmo_grid,      &
    1093                x = 0.5_dp * lx, y = 0.5_dp * ly, z = z, z0 = z0,               &
    1094                lonmin = lam_centre,                                            &
    1095                lonmax = lam_centre + averaging_angle,                          &
    1096                latmin = phi_south, latmax = phi_north,                         &
    1097                kind='scalar', name='east geostrophic scalar')
     1063    lonmin_palm = MINVAL(palm_intermediate%clon)
     1064    lonmax_palm = MAXVAL(palm_intermediate%clon)
     1065    latmin_palm = MINVAL(palm_intermediate%clat)
     1066    latmax_palm = MAXVAL(palm_intermediate%clat)
     1067
     1068    CALL init_averaging_grid(averaged_initial_scalar_profile, cosmo_grid,   &
     1069            x = 0.5_wp * lx, y = 0.5_wp * ly, z = z, z0 = z0,               &
     1070            lonmin = lonmin_palm, lonmax = lonmax_palm,                     &
     1071            latmin = latmin_palm, latmax = latmax_palm,                     &
     1072            kind='scalar', name='averaged initial scalar')
     1073
     1074    CALL init_averaging_grid(averaged_initial_w_profile, cosmo_grid,        &
     1075            x = 0.5_wp * lx, y = 0.5_wp * ly, z = zw, z0 = z0,              &
     1076            lonmin = lonmin_palm, lonmax = lonmax_palm,                     &
     1077            latmin = latmin_palm, latmax = latmax_palm,                     &
     1078            kind='w', name='averaged initial w')
     1079
     1080    CALL init_averaging_grid(averaged_scalar_profile, cosmo_grid,           &
     1081            x = 0.5_wp * lx, y = 0.5_wp * ly, z = z, z0 = z0,               &
     1082            lonmin = lam_west, lonmax = lam_east,                           &
     1083            latmin = phi_south, latmax = phi_north,                         &
     1084            kind='scalar', name='centre geostrophic scalar')
     1085
     1086    CALL init_averaging_grid(averaged_w_profile, cosmo_grid,                &
     1087            x = 0.5_wp * lx, y = 0.5_wp * ly, z = zw, z0 = z0,              &
     1088            lonmin = lam_west, lonmax = lam_east,                           &
     1089            latmin = phi_south, latmax = phi_north,                         &
     1090            kind='w', name='centre geostrophic w')
     1091
     1092    CALL init_averaging_grid(south_averaged_scalar_profile, cosmo_grid,     &
     1093            x = 0.5_wp * lx, y = 0.5_wp * ly, z = z, z0 = z0,               &
     1094            lonmin = lam_west, lonmax = lam_east,                           &
     1095            latmin = phi_centre - averaging_angle,                          &
     1096            latmax = phi_centre,                                            &
     1097            kind='scalar', name='south geostrophic scalar')
     1098
     1099    CALL init_averaging_grid(north_averaged_scalar_profile, cosmo_grid,     &
     1100            x = 0.5_wp * lx, y = 0.5_wp * ly, z = z, z0 = z0,               &
     1101            lonmin = lam_west, lonmax = lam_east,                           &
     1102            latmin = phi_centre,                                            &
     1103            latmax = phi_centre + averaging_angle,                          &
     1104            kind='scalar', name='north geostrophic scalar')
     1105
     1106    CALL init_averaging_grid(west_averaged_scalar_profile, cosmo_grid,      &
     1107            x = 0.5_wp * lx, y = 0.5_wp * ly, z = z, z0 = z0,               &
     1108            lonmin = lam_centre - averaging_angle,                          &
     1109            lonmax = lam_centre,                                            &
     1110            latmin = phi_south, latmax = phi_north,                         &
     1111            kind='scalar', name='west geostrophic scalar')
     1112
     1113    CALL init_averaging_grid(east_averaged_scalar_profile, cosmo_grid,      &
     1114            x = 0.5_wp * lx, y = 0.5_wp * ly, z = z, z0 = z0,               &
     1115            lonmin = lam_centre,                                            &
     1116            lonmax = lam_centre + averaging_angle,                          &
     1117            latmin = phi_south, latmax = phi_north,                         &
     1118            kind='scalar', name='east geostrophic scalar')
    10981119
    10991120
     
    11021123! Section 4: Precompute neighbours and weights for interpolation             
    11031124!------------------------------------------------------------------------------
    1104        interp_mode = 's'
    1105        CALL setup_interpolation(cosmo_grid, palm_grid, palm_intermediate, interp_mode, ic_mode=cfg % ic_mode)
    1106        IF (boundary_variables_required)  THEN
    1107           CALL setup_interpolation(cosmo_grid, scalars_east_grid, scalars_east_intermediate, interp_mode)
    1108           CALL setup_interpolation(cosmo_grid, scalars_west_grid, scalars_west_intermediate, interp_mode)
    1109           CALL setup_interpolation(cosmo_grid, scalars_north_grid, scalars_north_intermediate, interp_mode)
    1110           CALL setup_interpolation(cosmo_grid, scalars_south_grid, scalars_south_intermediate, interp_mode)
    1111           CALL setup_interpolation(cosmo_grid, scalars_top_grid, scalars_top_intermediate, interp_mode)
    1112        ENDIF
    1113 
    1114        interp_mode = 'u'
    1115        CALL setup_interpolation(cosmo_grid, u_initial_grid, u_initial_intermediate, interp_mode, ic_mode=cfg % ic_mode)
    1116        IF (boundary_variables_required)  THEN
    1117           CALL setup_interpolation(cosmo_grid, u_east_grid, u_east_intermediate, interp_mode)
    1118           CALL setup_interpolation(cosmo_grid, u_west_grid, u_west_intermediate, interp_mode)
    1119           CALL setup_interpolation(cosmo_grid, u_north_grid, u_north_intermediate, interp_mode)
    1120           CALL setup_interpolation(cosmo_grid, u_south_grid, u_south_intermediate, interp_mode)
    1121           CALL setup_interpolation(cosmo_grid, u_top_grid, u_top_intermediate, interp_mode)
    1122        ENDIF
    1123 
    1124        interp_mode = 'v'
    1125        CALL setup_interpolation(cosmo_grid, v_initial_grid, v_initial_intermediate, interp_mode, ic_mode=cfg % ic_mode)
    1126        IF (boundary_variables_required)  THEN
    1127           CALL setup_interpolation(cosmo_grid, v_east_grid, v_east_intermediate, interp_mode)
    1128           CALL setup_interpolation(cosmo_grid, v_west_grid, v_west_intermediate, interp_mode)
    1129           CALL setup_interpolation(cosmo_grid, v_north_grid, v_north_intermediate, interp_mode)
    1130           CALL setup_interpolation(cosmo_grid, v_south_grid, v_south_intermediate, interp_mode)
    1131           CALL setup_interpolation(cosmo_grid, v_top_grid, v_top_intermediate, interp_mode)
    1132        ENDIF
    1133 
    1134        interp_mode = 'w'
    1135        CALL setup_interpolation(cosmo_grid, w_initial_grid, w_initial_intermediate, interp_mode, ic_mode=cfg % ic_mode)
    1136        IF (boundary_variables_required)  THEN
    1137           CALL setup_interpolation(cosmo_grid, w_east_grid, w_east_intermediate, interp_mode)
    1138           CALL setup_interpolation(cosmo_grid, w_west_grid, w_west_intermediate, interp_mode)
    1139           CALL setup_interpolation(cosmo_grid, w_north_grid, w_north_intermediate, interp_mode)
    1140           CALL setup_interpolation(cosmo_grid, w_south_grid, w_south_intermediate, interp_mode)
    1141           CALL setup_interpolation(cosmo_grid, w_top_grid, w_top_intermediate, interp_mode)
    1142        ENDIF
    1143 
    1144        IF (TRIM(cfg % ic_mode) == 'profile')  THEN
    1145            !TODO: remove this conditional if not needed.
    1146        ENDIF
    1147        
    1148 
    1149     END SUBROUTINE setup_grids
     1125    interp_mode = 's'
     1126    CALL setup_interpolation(cosmo_grid, palm_grid, palm_intermediate, interp_mode, ic_mode=cfg%ic_mode)
     1127    IF (boundary_variables_required)  THEN
     1128       CALL setup_interpolation(cosmo_grid, scalars_east_grid, scalars_east_intermediate, interp_mode)
     1129       CALL setup_interpolation(cosmo_grid, scalars_west_grid, scalars_west_intermediate, interp_mode)
     1130       CALL setup_interpolation(cosmo_grid, scalars_north_grid, scalars_north_intermediate, interp_mode)
     1131       CALL setup_interpolation(cosmo_grid, scalars_south_grid, scalars_south_intermediate, interp_mode)
     1132       CALL setup_interpolation(cosmo_grid, scalars_top_grid, scalars_top_intermediate, interp_mode)
     1133    ENDIF
     1134
     1135    interp_mode = 'u'
     1136    CALL setup_interpolation(cosmo_grid, u_initial_grid, u_initial_intermediate, interp_mode, ic_mode=cfg%ic_mode)
     1137    IF (boundary_variables_required)  THEN
     1138       CALL setup_interpolation(cosmo_grid, u_east_grid, u_east_intermediate, interp_mode)
     1139       CALL setup_interpolation(cosmo_grid, u_west_grid, u_west_intermediate, interp_mode)
     1140       CALL setup_interpolation(cosmo_grid, u_north_grid, u_north_intermediate, interp_mode)
     1141       CALL setup_interpolation(cosmo_grid, u_south_grid, u_south_intermediate, interp_mode)
     1142       CALL setup_interpolation(cosmo_grid, u_top_grid, u_top_intermediate, interp_mode)
     1143    ENDIF
     1144
     1145    interp_mode = 'v'
     1146    CALL setup_interpolation(cosmo_grid, v_initial_grid, v_initial_intermediate, interp_mode, ic_mode=cfg%ic_mode)
     1147    IF (boundary_variables_required)  THEN
     1148       CALL setup_interpolation(cosmo_grid, v_east_grid, v_east_intermediate, interp_mode)
     1149       CALL setup_interpolation(cosmo_grid, v_west_grid, v_west_intermediate, interp_mode)
     1150       CALL setup_interpolation(cosmo_grid, v_north_grid, v_north_intermediate, interp_mode)
     1151       CALL setup_interpolation(cosmo_grid, v_south_grid, v_south_intermediate, interp_mode)
     1152       CALL setup_interpolation(cosmo_grid, v_top_grid, v_top_intermediate, interp_mode)
     1153    ENDIF
     1154
     1155    interp_mode = 'w'
     1156    CALL setup_interpolation(cosmo_grid, w_initial_grid, w_initial_intermediate, interp_mode, ic_mode=cfg%ic_mode)
     1157    IF (boundary_variables_required)  THEN
     1158       CALL setup_interpolation(cosmo_grid, w_east_grid, w_east_intermediate, interp_mode)
     1159       CALL setup_interpolation(cosmo_grid, w_west_grid, w_west_intermediate, interp_mode)
     1160       CALL setup_interpolation(cosmo_grid, w_north_grid, w_north_intermediate, interp_mode)
     1161       CALL setup_interpolation(cosmo_grid, w_south_grid, w_south_intermediate, interp_mode)
     1162       CALL setup_interpolation(cosmo_grid, w_top_grid, w_top_intermediate, interp_mode)
     1163    ENDIF
     1164
     1165    IF (TRIM(cfg%ic_mode) == 'profile')  THEN
     1166        !TODO: remove this conditional if not needed.
     1167    ENDIF
     1168
     1169 END SUBROUTINE setup_grids
    11501170
    11511171
     
    11561176!> vertical interpolation.
    11571177!------------------------------------------------------------------------------!
    1158     SUBROUTINE setup_interpolation(cosmo_grid, grid, intermediate_grid, kind, ic_mode)
    1159 
    1160        TYPE(grid_definition), INTENT(IN), TARGET    ::  cosmo_grid
    1161        TYPE(grid_definition), INTENT(INOUT), TARGET ::  grid, intermediate_grid
    1162        CHARACTER, INTENT(IN)                        ::  kind
    1163        CHARACTER(LEN=*), INTENT(IN), OPTIONAL       ::  ic_mode
    1164 
    1165        REAL(dp), DIMENSION(:), POINTER     ::  cosmo_lat, cosmo_lon
    1166        REAL(dp), DIMENSION(:,:,:), POINTER ::  cosmo_h
    1167 
    1168        LOGICAL :: setup_volumetric
     1178 SUBROUTINE setup_interpolation(cosmo_grid, grid, intermediate_grid, kind, ic_mode)
     1179
     1180    TYPE(grid_definition), INTENT(IN), TARGET    ::  cosmo_grid
     1181    TYPE(grid_definition), INTENT(INOUT), TARGET ::  grid, intermediate_grid
     1182    CHARACTER, INTENT(IN)                        ::  kind
     1183    CHARACTER(LEN=*), INTENT(IN), OPTIONAL       ::  ic_mode
     1184
     1185    REAL(wp), DIMENSION(:), POINTER     ::  cosmo_lat, cosmo_lon
     1186    REAL(wp), DIMENSION(:,:,:), POINTER ::  cosmo_h
     1187
     1188    LOGICAL :: setup_volumetric
    11691189
    11701190!------------------------------------------------------------------------------
     
    11721192!------------------------------------------------------------------------------
    11731193!
    1174 !--    Select horizontal coordinates according to kind of points (s/w, u, v)
    1175        SELECT CASE(kind)
    1176 
    1177 !
    1178 !--    scalars
    1179        CASE('s')
    1180 
    1181           cosmo_lat => cosmo_grid % lat
    1182           cosmo_lon => cosmo_grid % lon
    1183           cosmo_h   => cosmo_grid % hfl
    1184 !
    1185 !--    vertical velocity
    1186        CASE('w')
    1187 
    1188           cosmo_lat => cosmo_grid % lat
    1189           cosmo_lon => cosmo_grid % lon
    1190           cosmo_h   => cosmo_grid % hhl
    1191 !
    1192 !--    x velocity
    1193        CASE('u')
    1194 
    1195           cosmo_lat => cosmo_grid % lat
    1196           cosmo_lon => cosmo_grid % lonu
    1197           cosmo_h   => cosmo_grid % hfl
    1198 
    1199 !
    1200 !--    y velocity
    1201        CASE('v')
    1202 
    1203           cosmo_lat => cosmo_grid % latv
    1204           cosmo_lon => cosmo_grid % lon
    1205           cosmo_h   => cosmo_grid % hfl
    1206 
    1207        CASE DEFAULT
    1208 
    1209           message = "Interpolation quantity '" // kind // "' is not supported."
    1210           CALL inifor_abort('setup_interpolation', message)
    1211 
    1212        END SELECT
    1213 
    1214        CALL find_horizontal_neighbours(cosmo_lat, cosmo_lon,                   &
    1215           intermediate_grid % clat, intermediate_grid % clon,                  &
    1216           intermediate_grid % ii, intermediate_grid % jj)
    1217 
    1218        CALL compute_horizontal_interp_weights(cosmo_lat, cosmo_lon,            &
    1219           intermediate_grid % clat, intermediate_grid % clon,                  &
    1220           intermediate_grid % ii, intermediate_grid % jj,                      &
    1221           intermediate_grid % w_horiz)
     1194!-- Select horizontal coordinates according to kind of points (s/w, u, v)
     1195    SELECT CASE(kind)
     1196
     1197!
     1198!-- scalars
     1199    CASE('s')
     1200
     1201       cosmo_lat => cosmo_grid%lat
     1202       cosmo_lon => cosmo_grid%lon
     1203       cosmo_h   => cosmo_grid%hfl
     1204!
     1205!-- vertical velocity
     1206    CASE('w')
     1207
     1208       cosmo_lat => cosmo_grid%lat
     1209       cosmo_lon => cosmo_grid%lon
     1210       cosmo_h   => cosmo_grid%hhl
     1211!
     1212!-- x velocity
     1213    CASE('u')
     1214
     1215       cosmo_lat => cosmo_grid%lat
     1216       cosmo_lon => cosmo_grid%lonu
     1217       cosmo_h   => cosmo_grid%hfl
     1218
     1219!
     1220!-- y velocity
     1221    CASE('v')
     1222
     1223       cosmo_lat => cosmo_grid%latv
     1224       cosmo_lon => cosmo_grid%lon
     1225       cosmo_h   => cosmo_grid%hfl
     1226
     1227    CASE DEFAULT
     1228
     1229       message = "Interpolation quantity '" // kind // "' is not supported."
     1230       CALL inifor_abort('setup_interpolation', message)
     1231
     1232    END SELECT
     1233
     1234    CALL find_horizontal_neighbours(cosmo_lat, cosmo_lon,                   &
     1235       intermediate_grid%clat, intermediate_grid%clon,                  &
     1236       intermediate_grid%ii, intermediate_grid%jj)
     1237
     1238    CALL compute_horizontal_interp_weights(cosmo_lat, cosmo_lon,            &
     1239       intermediate_grid%clat, intermediate_grid%clon,                  &
     1240       intermediate_grid%ii, intermediate_grid%jj,                      &
     1241       intermediate_grid%w_horiz)
    12221242
    12231243!------------------------------------------------------------------------------
     
    12261246
    12271247!
    1228 !--    If profile initialization is chosen, we--somewhat counterintuitively--
    1229 !--    don't need to compute vertical interpolation weights. At least, we
    1230 !--    don't need them on the intermediate grid, which fills the entire PALM
    1231 !--    domain volume. Instead we need vertical weights for the intermediate
    1232 !--    profile grids, which get computed in setup_averaging().
    1233        setup_volumetric = .TRUE.
    1234        IF (PRESENT(ic_mode))  THEN
    1235           IF (TRIM(ic_mode) == 'profile')  setup_volumetric = .FALSE.
    1236        ENDIF
    1237 
    1238        IF (setup_volumetric)  THEN
    1239           ALLOCATE( intermediate_grid % h(0:intermediate_grid % nx,            &
    1240                                           0:intermediate_grid % ny,            &
    1241                                           0:intermediate_grid % nz) )
    1242           intermediate_grid % h(:,:,:) = - EARTH_RADIUS
    1243 
    1244 !
    1245 !--       For w points, use hhl, for scalars use hfl
    1246 !--       compute the full heights for the intermediate grids
    1247           CALL interpolate_2d(cosmo_h, intermediate_grid % h, intermediate_grid)
    1248           CALL find_vertical_neighbours_and_weights_interp(grid, intermediate_grid)
    1249        ENDIF
    1250        
    1251     END SUBROUTINE setup_interpolation
     1248!-- If profile initialization is chosen, we--somewhat counterintuitively--
     1249!-- don't need to compute vertical interpolation weights. At least, we
     1250!-- don't need them on the intermediate grid, which fills the entire PALM
     1251!-- domain volume. Instead we need vertical weights for the intermediate
     1252!-- profile grids, which get computed in setup_averaging().
     1253    setup_volumetric = .TRUE.
     1254    IF (PRESENT(ic_mode))  THEN
     1255       IF (TRIM(ic_mode) == 'profile')  setup_volumetric = .FALSE.
     1256    ENDIF
     1257
     1258    IF (setup_volumetric)  THEN
     1259       ALLOCATE( intermediate_grid%h(0:intermediate_grid%nx,            &
     1260                                     0:intermediate_grid%ny,            &
     1261                                     0:intermediate_grid%nz) )
     1262       intermediate_grid%h(:,:,:) = - EARTH_RADIUS
     1263
     1264!
     1265!--    For w points, use hhl, for scalars use hfl
     1266!--    compute the full heights for the intermediate grids
     1267       CALL interpolate_2d(cosmo_h, intermediate_grid%h, intermediate_grid)
     1268       CALL find_vertical_neighbours_and_weights_interp(grid, intermediate_grid)
     1269    ENDIF
     1270       
     1271 END SUBROUTINE setup_interpolation
    12521272
    12531273!------------------------------------------------------------------------------!
     
    12811301!> grid : Grid variable to be initialized.
    12821302!------------------------------------------------------------------------------!
    1283     SUBROUTINE init_grid_definition(kind, xmin, xmax, ymin, ymax,              &
    1284                                     x0, y0, z0, nx, ny, nz, z, zw, grid, ic_mode)
    1285         CHARACTER(LEN=*), INTENT(IN)           ::  kind
    1286         CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  ic_mode
    1287         INTEGER, INTENT(IN)                    ::  nx, ny, nz
    1288         REAL(dp), INTENT(IN)                   ::  xmin, xmax, ymin, ymax
    1289         REAL(dp), INTENT(IN)                   ::  x0, y0, z0
    1290         REAL(dp), INTENT(IN), TARGET, OPTIONAL ::  z(:)
    1291         REAL(dp), INTENT(IN), TARGET, OPTIONAL ::  zw(:)
    1292         TYPE(grid_definition), INTENT(INOUT)   ::  grid
    1293 
    1294         grid % nx = nx
    1295         grid % ny = ny
    1296         grid % nz = nz
    1297 
    1298         grid % lx = xmax - xmin
    1299         grid % ly = ymax - ymin
    1300 
    1301         grid % x0 = x0
    1302         grid % y0 = y0
    1303         grid % z0 = z0
    1304 
    1305         SELECT CASE( TRIM(kind) )
    1306 
    1307         CASE('boundary')
    1308 
    1309            IF (.NOT.PRESENT(z))  THEN
    1310               message = "z has not been passed but is required for 'boundary' grids"
    1311               CALL inifor_abort('init_grid_definition', message)
    1312            ENDIF
    1313 
    1314            ALLOCATE( grid % x(0:nx) )
    1315            CALL linspace(xmin, xmax, grid % x)
    1316 
    1317            ALLOCATE( grid % y(0:ny) )
    1318            CALL linspace(ymin, ymax, grid % y)
    1319 
    1320            grid % z => z
    1321 
    1322 !
    1323 !--        Allocate neighbour indices and weights
    1324            IF (TRIM(ic_mode) .NE. 'profile')  THEN
    1325               ALLOCATE( grid % kk(0:nx, 0:ny, 1:nz, 2) )
    1326               grid % kk(:,:,:,:) = -1
    1327 
    1328               ALLOCATE( grid % w_verti(0:nx, 0:ny, 1:nz, 2) )
    1329               grid % w_verti(:,:,:,:) = 0.0_dp
    1330            ENDIF
    1331         
    1332         CASE('boundary intermediate')
    1333 
    1334            ALLOCATE( grid % x(0:nx) )
    1335            CALL linspace(xmin, xmax, grid % x)
    1336 
    1337            ALLOCATE( grid % y(0:ny) )
    1338            CALL linspace(ymin, ymax, grid % y)
    1339 
    1340            ALLOCATE( grid % clon(0:nx, 0:ny), grid % clat(0:nx, 0:ny)  )
    1341 
    1342            CALL rotate_to_cosmo(                                               &
    1343               phir = project( grid % y, y0, EARTH_RADIUS ) ,                   & ! = plate-carree latitude
    1344               lamr = project( grid % x, x0, EARTH_RADIUS ) ,                   & ! = plate-carree longitude
    1345               phip = phi_cn, lamp = lambda_cn,                                 &
    1346               phi  = grid % clat,                                              &
    1347               lam  = grid % clon,                                              &
    1348               gam  = gam                                                       &
    1349            )
    1350 
    1351 !
    1352 !--        Allocate neighbour indices and weights
    1353            ALLOCATE( grid % ii(0:nx, 0:ny, 4),                                 &
    1354                      grid % jj(0:nx, 0:ny, 4) )
    1355            grid % ii(:,:,:)   = -1
    1356            grid % jj(:,:,:)   = -1
    1357 
    1358            ALLOCATE( grid % w_horiz(0:nx, 0:ny, 4) )
    1359            grid % w_horiz(:,:,:)   = 0.0_dp
    1360         
    1361 !
    1362 !--     This mode initializes a Cartesian PALM-4U grid and adds the
    1363 !--     corresponding latitudes and longitudes of the rotated pole grid.
    1364         CASE('palm')
    1365 
    1366            IF (.NOT.PRESENT(z))  THEN
    1367               message = "z has not been passed but is required for 'palm' grids"
    1368               CALL inifor_abort('init_grid_definition', message)
    1369            ENDIF
    1370 
    1371            IF (.NOT.PRESENT(zw))  THEN
    1372               message = "zw has not been passed but is required for 'palm' grids"
    1373               CALL inifor_abort('init_grid_definition', message)
    1374            ENDIF
    1375 
    1376            grid % name(1) = 'x and lon'
    1377            grid % name(2) = 'y and lat'
    1378            grid % name(3) = 'z'
    1379 
    1380 !
    1381 !--        TODO: Remove use of global dx, dy, dz variables. Consider
    1382 !--        TODO: associating global x,y, and z arrays.
    1383            ALLOCATE( grid % x(0:nx),   grid % y(0:ny) )
    1384            ALLOCATE( grid % xu(1:nx),  grid % yv(1:ny) )
    1385            CALL linspace(xmin + 0.5_dp* dx, xmax - 0.5_dp* dx, grid % x)
    1386            CALL linspace(ymin + 0.5_dp* dy, ymax - 0.5_dp* dy, grid % y)
    1387            grid % z => z
    1388            CALL linspace(xmin +  dx, xmax -  dx, grid % xu)
    1389            CALL linspace(ymin +  dy, ymax -  dy, grid % yv)
    1390            grid % zw => zw
    1391 
    1392            grid % depths => depths
    1393 
    1394 !
    1395 !--        Allocate neighbour indices and weights
    1396            IF (TRIM(ic_mode) .NE. 'profile')  THEN
    1397               ALLOCATE( grid % kk(0:nx, 0:ny, 1:nz, 2) )
    1398               grid % kk(:,:,:,:) = -1
    1399 
    1400               ALLOCATE( grid % w_verti(0:nx, 0:ny, 1:nz, 2) )
    1401               grid % w_verti(:,:,:,:) = 0.0_dp
    1402            ENDIF
    1403 
    1404         CASE('palm intermediate')
    1405 
    1406            grid % name(1) = 'x and lon'
    1407            grid % name(2) = 'y and lat'
    1408            grid % name(3) = 'interpolated hhl or hfl'
    1409 
    1410 !
    1411 !--        TODO: Remove use of global dx, dy, dz variables. Consider
    1412 !--        TODO: associating global x,y, and z arrays.
    1413            ALLOCATE( grid % x(0:nx),   grid % y(0:ny) )
    1414            ALLOCATE( grid % xu(1:nx),  grid % yv(1:ny) )
    1415            CALL linspace(xmin + 0.5_dp*dx, xmax - 0.5_dp*dx, grid % x)
    1416            CALL linspace(ymin + 0.5_dp*dy, ymax - 0.5_dp*dy, grid % y)
    1417            CALL linspace(xmin + dx, xmax - dx, grid % xu)
    1418            CALL linspace(ymin + dy, ymax - dy, grid % yv)
    1419 
    1420            grid % depths => depths
    1421 
    1422 !
    1423 !--        Allocate rotated-pole coordinates, clon is for (c)osmo-de (lon)gitude
    1424            ALLOCATE( grid % clon(0:nx, 0:ny),   grid % clat(0:nx, 0:ny)  )
    1425            ALLOCATE( grid % clonu(1:nx, 0:ny),  grid % clatu(1:nx, 0:ny) )
    1426            ALLOCATE( grid % clonv(0:nx, 1:ny),  grid % clatv(0:nx, 1:ny) )
    1427 
    1428 !
    1429 !--        Compute rotated-pole coordinates of...
    1430 !--        ... PALM-4U centres
    1431            CALL rotate_to_cosmo(                                               &
    1432               phir = project( grid % y, y0, EARTH_RADIUS ) , & ! = plate-carree latitude
    1433               lamr = project( grid % x, x0, EARTH_RADIUS ) , & ! = plate-carree longitude
    1434               phip = phi_cn, lamp = lambda_cn,                                 &
    1435               phi  = grid % clat,                                              &
    1436               lam  = grid % clon,                                              &
    1437               gam  = gam                                                       &
    1438            )
    1439 
    1440 !
    1441 !--        ... PALM-4U u winds
    1442            CALL rotate_to_cosmo(                                               &
    1443               phir = project( grid % y,  y0, EARTH_RADIUS ), & ! = plate-carree latitude
    1444               lamr = project( grid % xu, x0, EARTH_RADIUS ), & ! = plate-carree longitude
    1445               phip = phi_cn, lamp = lambda_cn,                                 &
    1446               phi  = grid % clatu,                                             &
    1447               lam  = grid % clonu,                                             &
    1448               gam  = gam                                                       &
    1449            )
    1450 
    1451 !
    1452 !--        ... PALM-4U v winds
    1453            CALL rotate_to_cosmo(                                               &
    1454               phir = project( grid % yv, y0, EARTH_RADIUS ), & ! = plate-carree latitude
    1455               lamr = project( grid % x,  x0, EARTH_RADIUS ), & ! = plate-carree longitude
    1456               phip = phi_cn, lamp = lambda_cn,                                 &
    1457               phi  = grid % clatv,                                             &
    1458               lam  = grid % clonv,                                             &
    1459               gam  = gam                                                       &
    1460            )
    1461 
    1462 !
    1463 !--        Allocate neighbour indices and weights
    1464            ALLOCATE( grid % ii(0:nx, 0:ny, 4),                                 &
    1465                      grid % jj(0:nx, 0:ny, 4) )
    1466            grid % ii(:,:,:)   = -1
    1467            grid % jj(:,:,:)   = -1
    1468 
    1469            ALLOCATE( grid % w_horiz(0:nx, 0:ny, 4) )
    1470            grid % w_horiz(:,:,:)   = 0.0_dp
    1471 
    1472         CASE('cosmo-de')
    1473            grid % name(1) = 'rlon'         ! of COMSO-DE cell centres (scalars)
    1474            grid % name(2) = 'rlat'         ! of COMSO-DE cell centres (scalars)
    1475            grid % name(3) = 'height'
    1476 
    1477            ALLOCATE( grid % lon(0:nx),   grid % lat(0:ny)  )
    1478            ALLOCATE( grid % lonu(0:nx),  grid % latv(0:ny) )
    1479 
    1480            CALL linspace(xmin, xmax, grid % lon)
    1481            CALL linspace(ymin, ymax, grid % lat)
    1482            grid % lonu(:) = grid % lon + 0.5_dp * (grid % lx / grid % nx)
    1483            grid % latv(:) = grid % lat + 0.5_dp * (grid % ly / grid % ny)
    1484 
    1485 !
    1486 !--        Point to heights of half levels (hhl) and compute heights of full
    1487 !--        levels (hfl) as arithmetic averages
    1488            grid % hhl => hhl
    1489            grid % hfl => hfl
    1490            grid % depths => depths
    1491 
    1492         CASE DEFAULT
    1493             message = "Grid kind '" // TRIM(kind) // "' is not recognized."
    1494             CALL inifor_abort('init_grid_definition', message)
    1495 
    1496         END SELECT
    1497 
    1498     END SUBROUTINE init_grid_definition
     1303 SUBROUTINE init_grid_definition(kind, xmin, xmax, ymin, ymax,              &
     1304                                 x0, y0, z0, nx, ny, nz, z, zw, grid, ic_mode)
     1305    CHARACTER(LEN=*), INTENT(IN)           ::  kind
     1306    CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  ic_mode
     1307    INTEGER, INTENT(IN)                    ::  nx, ny, nz
     1308    REAL(wp), INTENT(IN)                   ::  xmin, xmax, ymin, ymax
     1309    REAL(wp), INTENT(IN)                   ::  x0, y0, z0
     1310    REAL(wp), INTENT(IN), TARGET, OPTIONAL ::  z(:)
     1311    REAL(wp), INTENT(IN), TARGET, OPTIONAL ::  zw(:)
     1312    TYPE(grid_definition), INTENT(INOUT)   ::  grid
     1313
     1314    grid%nx = nx
     1315    grid%ny = ny
     1316    grid%nz = nz
     1317
     1318    grid%lx = xmax - xmin
     1319    grid%ly = ymax - ymin
     1320
     1321    grid%x0 = x0
     1322    grid%y0 = y0
     1323    grid%z0 = z0
     1324
     1325    SELECT CASE( TRIM(kind) )
     1326
     1327       CASE('boundary')
     1328       
     1329          IF (.NOT.PRESENT(z))  THEN
     1330             message = "z has not been passed but is required for 'boundary' grids"
     1331             CALL inifor_abort('init_grid_definition', message)
     1332          ENDIF
     1333       
     1334          ALLOCATE( grid%x(0:nx) )
     1335          CALL linspace(xmin, xmax, grid%x)
     1336       
     1337          ALLOCATE( grid%y(0:ny) )
     1338          CALL linspace(ymin, ymax, grid%y)
     1339       
     1340          grid%z => z
     1341       
     1342!     
     1343!--       Allocate neighbour indices and weights
     1344          IF (TRIM(ic_mode) .NE. 'profile')  THEN
     1345             ALLOCATE( grid%kk(0:nx, 0:ny, 1:nz, 2) )
     1346             grid%kk(:,:,:,:) = -1
     1347       
     1348             ALLOCATE( grid%w_verti(0:nx, 0:ny, 1:nz, 2) )
     1349             grid%w_verti(:,:,:,:) = 0.0_wp
     1350          ENDIF
     1351       
     1352       CASE('boundary intermediate')
     1353       
     1354          ALLOCATE( grid%x(0:nx) )
     1355          CALL linspace(xmin, xmax, grid%x)
     1356       
     1357          ALLOCATE( grid%y(0:ny) )
     1358          CALL linspace(ymin, ymax, grid%y)
     1359       
     1360          ALLOCATE( grid%clon(0:nx, 0:ny), grid%clat(0:nx, 0:ny)  )
     1361       
     1362          CALL rotate_to_cosmo(                                               &
     1363             phir = project( grid%y, y0, EARTH_RADIUS ) ,                   & ! = plate-carree latitude
     1364             lamr = project( grid%x, x0, EARTH_RADIUS ) ,                   & ! = plate-carree longitude
     1365             phip = phi_cn, lamp = lambda_cn,                                 &
     1366             phi  = grid%clat,                                              &
     1367             lam  = grid%clon,                                              &
     1368             gam  = gam                                                       &
     1369          )
     1370       
     1371!     
     1372!--       Allocate neighbour indices and weights
     1373          ALLOCATE( grid%ii(0:nx, 0:ny, 4),                                 &
     1374                    grid%jj(0:nx, 0:ny, 4) )
     1375          grid%ii(:,:,:)   = -1
     1376          grid%jj(:,:,:)   = -1
     1377       
     1378          ALLOCATE( grid%w_horiz(0:nx, 0:ny, 4) )
     1379          grid%w_horiz(:,:,:)   = 0.0_wp
     1380       
     1381!     
     1382!--    This mode initializes a Cartesian PALM-4U grid and adds the
     1383!--    corresponding latitudes and longitudes of the rotated pole grid.
     1384       CASE('palm')
     1385       
     1386          IF (.NOT.PRESENT(z))  THEN
     1387             message = "z has not been passed but is required for 'palm' grids"
     1388             CALL inifor_abort('init_grid_definition', message)
     1389          ENDIF
     1390       
     1391          IF (.NOT.PRESENT(zw))  THEN
     1392             message = "zw has not been passed but is required for 'palm' grids"
     1393             CALL inifor_abort('init_grid_definition', message)
     1394          ENDIF
     1395       
     1396          grid%name(1) = 'x and lon'
     1397          grid%name(2) = 'y and lat'
     1398          grid%name(3) = 'z'
     1399       
     1400!     
     1401!--       TODO: Remove use of global dx, dy, dz variables. Consider
     1402!--       TODO: associating global x,y, and z arrays.
     1403          ALLOCATE( grid%x(0:nx),   grid%y(0:ny) )
     1404          ALLOCATE( grid%xu(1:nx),  grid%yv(1:ny) )
     1405          CALL linspace(xmin + 0.5_wp* dx, xmax - 0.5_wp* dx, grid%x)
     1406          CALL linspace(ymin + 0.5_wp* dy, ymax - 0.5_wp* dy, grid%y)
     1407          grid%z => z
     1408          CALL linspace(xmin +  dx, xmax -  dx, grid%xu)
     1409          CALL linspace(ymin +  dy, ymax -  dy, grid%yv)
     1410          grid%zw => zw
     1411       
     1412          grid%depths => depths
     1413       
     1414!     
     1415!--       Allocate neighbour indices and weights
     1416          IF (TRIM(ic_mode) .NE. 'profile')  THEN
     1417             ALLOCATE( grid%kk(0:nx, 0:ny, 1:nz, 2) )
     1418             grid%kk(:,:,:,:) = -1
     1419       
     1420             ALLOCATE( grid%w_verti(0:nx, 0:ny, 1:nz, 2) )
     1421             grid%w_verti(:,:,:,:) = 0.0_wp
     1422          ENDIF
     1423       
     1424       CASE('palm intermediate')
     1425       
     1426          grid%name(1) = 'x and lon'
     1427          grid%name(2) = 'y and lat'
     1428          grid%name(3) = 'interpolated hhl or hfl'
     1429       
     1430!     
     1431!--       TODO: Remove use of global dx, dy, dz variables. Consider
     1432!--       TODO: associating global x,y, and z arrays.
     1433          ALLOCATE( grid%x(0:nx),   grid%y(0:ny) )
     1434          ALLOCATE( grid%xu(1:nx),  grid%yv(1:ny) )
     1435          CALL linspace(xmin + 0.5_wp*dx, xmax - 0.5_wp*dx, grid%x)
     1436          CALL linspace(ymin + 0.5_wp*dy, ymax - 0.5_wp*dy, grid%y)
     1437          CALL linspace(xmin + dx, xmax - dx, grid%xu)
     1438          CALL linspace(ymin + dy, ymax - dy, grid%yv)
     1439       
     1440          grid%depths => depths
     1441       
     1442!     
     1443!--       Allocate rotated-pole coordinates, clon is for (c)osmo-de (lon)gitude
     1444          ALLOCATE( grid%clon(0:nx, 0:ny),   grid%clat(0:nx, 0:ny)  )
     1445          ALLOCATE( grid%clonu(1:nx, 0:ny),  grid%clatu(1:nx, 0:ny) )
     1446          ALLOCATE( grid%clonv(0:nx, 1:ny),  grid%clatv(0:nx, 1:ny) )
     1447       
     1448!     
     1449!--       Compute rotated-pole coordinates of...
     1450!--       ... PALM-4U centres
     1451          CALL rotate_to_cosmo(                                               &
     1452             phir = project( grid%y, y0, EARTH_RADIUS ) , & ! = plate-carree latitude
     1453             lamr = project( grid%x, x0, EARTH_RADIUS ) , & ! = plate-carree longitude
     1454             phip = phi_cn, lamp = lambda_cn,                                 &
     1455             phi  = grid%clat,                                              &
     1456             lam  = grid%clon,                                              &
     1457             gam  = gam                                                       &
     1458          )
     1459       
     1460!     
     1461!--       ... PALM-4U u winds
     1462          CALL rotate_to_cosmo(                                               &
     1463             phir = project( grid%y,  y0, EARTH_RADIUS ), & ! = plate-carree latitude
     1464             lamr = project( grid%xu, x0, EARTH_RADIUS ), & ! = plate-carree longitude
     1465             phip = phi_cn, lamp = lambda_cn,                                 &
     1466             phi  = grid%clatu,                                             &
     1467             lam  = grid%clonu,                                             &
     1468             gam  = gam                                                       &
     1469          )
     1470       
     1471!     
     1472!--       ... PALM-4U v winds
     1473          CALL rotate_to_cosmo(                                               &
     1474             phir = project( grid%yv, y0, EARTH_RADIUS ), & ! = plate-carree latitude
     1475             lamr = project( grid%x,  x0, EARTH_RADIUS ), & ! = plate-carree longitude
     1476             phip = phi_cn, lamp = lambda_cn,                                 &
     1477             phi  = grid%clatv,                                             &
     1478             lam  = grid%clonv,                                             &
     1479             gam  = gam                                                       &
     1480          )
     1481       
     1482!     
     1483!--       Allocate neighbour indices and weights
     1484          ALLOCATE( grid%ii(0:nx, 0:ny, 4),                                 &
     1485                    grid%jj(0:nx, 0:ny, 4) )
     1486          grid%ii(:,:,:)   = -1
     1487          grid%jj(:,:,:)   = -1
     1488       
     1489          ALLOCATE( grid%w_horiz(0:nx, 0:ny, 4) )
     1490          grid%w_horiz(:,:,:)   = 0.0_wp
     1491       
     1492       CASE('cosmo-de')
     1493          grid%name(1) = 'rlon'         ! of COMSO-DE cell centres (scalars)
     1494          grid%name(2) = 'rlat'         ! of COMSO-DE cell centres (scalars)
     1495          grid%name(3) = 'height'
     1496       
     1497          ALLOCATE( grid%lon(0:nx),   grid%lat(0:ny)  )
     1498          ALLOCATE( grid%lonu(0:nx),  grid%latv(0:ny) )
     1499       
     1500          CALL linspace(xmin, xmax, grid%lon)
     1501          CALL linspace(ymin, ymax, grid%lat)
     1502          grid%lonu(:) = grid%lon + 0.5_wp * (grid%lx / grid%nx)
     1503          grid%latv(:) = grid%lat + 0.5_wp * (grid%ly / grid%ny)
     1504       
     1505!     
     1506!--       Point to heights of half levels (hhl) and compute heights of full
     1507!--       levels (hfl) as arithmetic averages
     1508          grid%hhl => hhl
     1509          grid%hfl => hfl
     1510          grid%depths => depths
     1511       
     1512       CASE DEFAULT
     1513           message = "Grid kind '" // TRIM(kind) // "' is not recognized."
     1514           CALL inifor_abort('init_grid_definition', message)
     1515
     1516    END SELECT
     1517
     1518 END SUBROUTINE init_grid_definition
    14991519
    15001520
     
    15271547!> avg_grid : averagin grid to be initialized
    15281548!------------------------------------------------------------------------------!
    1529     SUBROUTINE init_averaging_grid(avg_grid, cosmo_grid, x, y, z, z0,          &
    1530        lonmin, lonmax, latmin, latmax, kind, name)
    1531 
    1532        TYPE(grid_definition), INTENT(INOUT) ::  avg_grid
    1533        TYPE(grid_definition), INTENT(IN)    ::  cosmo_grid
    1534        REAL(dp), INTENT(IN)                 ::  x, y, z0
    1535        REAL(dp), INTENT(IN), TARGET         ::  z(:)
    1536        REAL(dp), INTENT(IN)                 ::  lonmin !< lower longitude bound of the averaging grid region [COSMO rotated-pole rad]
    1537        REAL(dp), INTENT(IN)                 ::  lonmax !< upper longitude bound of the averaging grid region [COSMO rotated-pole rad]
    1538        REAL(dp), INTENT(IN)                 ::  latmin !< lower latitude bound of the averaging grid region [COSMO rotated-pole rad]
    1539        REAL(dp), INTENT(IN)                 ::  latmax !< lower latitude bound of the averaging grid region [COSMO rotated-pole rad]
    1540 
    1541        CHARACTER(LEN=*), INTENT(IN)         ::  kind
    1542        CHARACTER(LEN=*), INTENT(IN)         ::  name
    1543 
    1544        LOGICAL                              ::  level_based_averaging
    1545 
    1546        ALLOCATE( avg_grid % x(1) )
    1547        ALLOCATE( avg_grid % y(1) )
    1548        avg_grid % x(1) = x
    1549        avg_grid % y(1) = y
    1550        avg_grid % z => z
    1551        avg_grid % z0 = z0
    1552 
    1553        avg_grid % nz = SIZE(z, 1)
    1554 
    1555        ALLOCATE( avg_grid % lon(2) )
    1556        ALLOCATE( avg_grid % lat(2) )
    1557        avg_grid % lon(1:2) = (/lonmin, lonmax/)
    1558        avg_grid % lat(1:2) = (/latmin, latmax/)
    1559 
    1560        avg_grid % kind = TRIM(kind)
    1561        avg_grid % name(1) = TRIM(name)
    1562 
    1563 !
    1564 !--    Find and store COSMO columns that fall into the coordinate range
    1565 !--    given by avg_grid % clon, % clat
    1566        CALL get_cosmo_averaging_region(avg_grid, cosmo_grid)
    1567 
    1568        ALLOCATE (avg_grid % kkk(avg_grid % n_columns, avg_grid % nz, 2) )
    1569        ALLOCATE (avg_grid % w(avg_grid % n_columns, avg_grid % nz, 2) )
    1570 !
    1571 !--    Compute average COSMO levels in the averaging region
    1572        SELECT CASE(avg_grid % kind)
     1549 SUBROUTINE init_averaging_grid(avg_grid, cosmo_grid, x, y, z, z0,          &
     1550    lonmin, lonmax, latmin, latmax, kind, name)
     1551
     1552    TYPE(grid_definition), INTENT(INOUT) ::  avg_grid
     1553    TYPE(grid_definition), INTENT(IN)    ::  cosmo_grid
     1554    REAL(wp), INTENT(IN)                 ::  x, y, z0
     1555    REAL(wp), INTENT(IN), TARGET         ::  z(:)
     1556    REAL(wp), INTENT(IN)                 ::  lonmin !< lower longitude bound of the averaging grid region [COSMO rotated-pole rad]
     1557    REAL(wp), INTENT(IN)                 ::  lonmax !< upper longitude bound of the averaging grid region [COSMO rotated-pole rad]
     1558    REAL(wp), INTENT(IN)                 ::  latmin !< lower latitude bound of the averaging grid region [COSMO rotated-pole rad]
     1559    REAL(wp), INTENT(IN)                 ::  latmax !< lower latitude bound of the averaging grid region [COSMO rotated-pole rad]
     1560
     1561    CHARACTER(LEN=*), INTENT(IN)         ::  kind
     1562    CHARACTER(LEN=*), INTENT(IN)         ::  name
     1563
     1564    LOGICAL                              ::  level_based_averaging
     1565
     1566    ALLOCATE( avg_grid%x(1) )
     1567    ALLOCATE( avg_grid%y(1) )
     1568    avg_grid%x(1) = x
     1569    avg_grid%y(1) = y
     1570    avg_grid%z => z
     1571    avg_grid%z0 = z0
     1572
     1573    avg_grid%nz = SIZE(z, 1)
     1574
     1575    ALLOCATE( avg_grid%lon(2) )
     1576    ALLOCATE( avg_grid%lat(2) )
     1577    avg_grid%lon(1:2) = (/lonmin, lonmax/)
     1578    avg_grid%lat(1:2) = (/latmin, latmax/)
     1579
     1580    avg_grid%kind = TRIM(kind)
     1581    avg_grid%name(1) = TRIM(name)
     1582
     1583!
     1584!-- Find and store COSMO columns that fall into the coordinate range
     1585!-- given by avg_grid%clon, %clat
     1586    CALL get_cosmo_averaging_region(avg_grid, cosmo_grid)
     1587
     1588    ALLOCATE (avg_grid%kkk(avg_grid%n_columns, avg_grid%nz, 2) )
     1589    ALLOCATE (avg_grid%w(avg_grid%n_columns, avg_grid%nz, 2) )
     1590!
     1591!-- Compute average COSMO levels in the averaging region
     1592    SELECT CASE(avg_grid%kind)
    15731593
    15741594       CASE('scalar', 'u', 'v')
    1575           avg_grid % cosmo_h => cosmo_grid % hfl
     1595          avg_grid%cosmo_h => cosmo_grid%hfl
    15761596
    15771597       CASE('w')
    1578           avg_grid % cosmo_h => cosmo_grid % hhl
     1598          avg_grid%cosmo_h => cosmo_grid%hhl
    15791599
    15801600       CASE DEFAULT
    1581           message = "Averaging grid kind '" // TRIM(avg_grid % kind) // &
     1601          message = "Averaging grid kind '" // TRIM(avg_grid%kind) // &
    15821602                    "' is not supported. Use 'scalar', 'u', or 'v'."
    15831603          CALL inifor_abort('get_cosmo_averaging_region', message)
    15841604
    1585        END SELECT
    1586 
    1587 !
    1588 !--    For level-besed averaging, compute average heights
    1589        !level_based_averaging = ( TRIM(mode) == 'level' )
    1590        level_based_averaging = ( TRIM(cfg % averaging_mode) == 'level' )
    1591        IF (level_based_averaging)  THEN
    1592           ALLOCATE(avg_grid % h(1,1,SIZE(avg_grid % cosmo_h, 3)) )
     1605    END SELECT
     1606
     1607!
     1608!-- For level-besed averaging, compute average heights
     1609    level_based_averaging = ( TRIM(cfg%averaging_mode) == 'level' )
     1610    IF (level_based_averaging)  THEN
     1611       ALLOCATE(avg_grid%h(1,1,SIZE(avg_grid%cosmo_h, 3)) )
    15931612 
    1594           CALL average_2d(avg_grid % cosmo_h, avg_grid % h(1,1,:),             &
    1595                           avg_grid % iii, avg_grid % jjj)
    1596 
    1597        ENDIF
    1598 
    1599 !
    1600 !--    Compute vertical weights and neighbours
    1601        CALL find_vertical_neighbours_and_weights_average(                      &
    1602           avg_grid, level_based_averaging                                      &
    1603        )
    1604 
    1605     END SUBROUTINE init_averaging_grid
    1606 
    1607 
    1608     SUBROUTINE get_cosmo_averaging_region(avg_grid, cosmo_grid)
    1609        TYPE(grid_definition), INTENT(INOUT)         ::  avg_grid
    1610        TYPE(grid_definition), TARGET, INTENT(IN)    ::  cosmo_grid
    1611 
    1612        REAL(dp), DIMENSION(:), POINTER              ::  cosmo_lon, cosmo_lat
    1613        REAL(dp)                                     ::  dlon, dlat
    1614 
    1615        INTEGER ::  i, j, imin, imax, jmin, jmax, l, nx, ny
    1616 
    1617 
    1618        SELECT CASE( TRIM(avg_grid % kind) )
     1613       CALL average_2d(avg_grid%cosmo_h, avg_grid%h(1,1,:),             &
     1614                       avg_grid%iii, avg_grid%jjj)
     1615
     1616    ENDIF
     1617
     1618!
     1619!-- Compute vertical weights and neighbours
     1620    CALL find_vertical_neighbours_and_weights_average(                      &
     1621       avg_grid, level_based_averaging                                      &
     1622    )
     1623
     1624 END SUBROUTINE init_averaging_grid
     1625
     1626
     1627 SUBROUTINE get_cosmo_averaging_region(avg_grid, cosmo_grid)
     1628    TYPE(grid_definition), INTENT(INOUT)         ::  avg_grid
     1629    TYPE(grid_definition), TARGET, INTENT(IN)    ::  cosmo_grid
     1630
     1631    REAL(wp), DIMENSION(:), POINTER              ::  cosmo_lon, cosmo_lat
     1632    REAL(wp)                                     ::  dlon, dlat
     1633
     1634    INTEGER ::  i, j, imin, imax, jmin, jmax, l, nx, ny
     1635
     1636
     1637    SELECT CASE( TRIM(avg_grid%kind) )
    16191638
    16201639       CASE('scalar', 'w')
    1621           cosmo_lon => cosmo_grid % lon
    1622           cosmo_lat => cosmo_grid % lat
     1640          cosmo_lon => cosmo_grid%lon
     1641          cosmo_lat => cosmo_grid%lat
    16231642
    16241643       CASE('u')
    1625           cosmo_lon => cosmo_grid % lonu
    1626           cosmo_lat => cosmo_grid % lat
     1644          cosmo_lon => cosmo_grid%lonu
     1645          cosmo_lat => cosmo_grid%lat
    16271646
    16281647       CASE('v')
    1629           cosmo_lon => cosmo_grid % lon
    1630           cosmo_lat => cosmo_grid % latv
     1648          cosmo_lon => cosmo_grid%lon
     1649          cosmo_lat => cosmo_grid%latv
    16311650
    16321651       CASE DEFAULT
    1633           message = "Averaging grid kind '" // TRIM(avg_grid % kind) // &
     1652          message = "Averaging grid kind '" // TRIM(avg_grid%kind) // &
    16341653                    "' is not supported. Use 'scalar', 'u', or 'v'."
    16351654          CALL inifor_abort('get_cosmo_averaging_region', message)
    16361655
    1637        END SELECT
    1638 
    1639 !
    1640 !--    FIXME: make dlon, dlat parameters of the grid_defintion type
    1641        dlon = cosmo_lon(1) - cosmo_lon(0)
    1642        dlat = cosmo_lat(1) - cosmo_lat(0)
    1643 
    1644        imin = FLOOR  ( (avg_grid % lon(1) - cosmo_lon(0)) / dlon )
    1645        imax = CEILING( (avg_grid % lon(2) - cosmo_lon(0)) / dlon )
    1646 
    1647        jmin = FLOOR  ( (avg_grid % lat(1) - cosmo_lat(0)) / dlat )
    1648        jmax = CEILING( (avg_grid % lat(2) - cosmo_lat(0)) / dlat )
    1649        
    1650        message = "Grid " // TRIM(avg_grid % name(1)) // " averages over " // &
    1651                  TRIM(str(imin)) // " <= i <= " // TRIM(str(imax)) //          &
    1652                  " and " //                                                    &
    1653                  TRIM(str(jmin)) // " <= j <= " // TRIM(str(jmax))
    1654        CALL report( 'get_cosmo_averaging_region', message )
    1655 
    1656        nx = imax - imin + 1
    1657        ny = jmax - jmin + 1
    1658        avg_grid % n_columns = nx * ny
    1659 
    1660        ALLOCATE( avg_grid % iii(avg_grid % n_columns),                         &
    1661                  avg_grid % jjj(avg_grid % n_columns) )
    1662 
    1663        l = 0
    1664        DO j = jmin, jmax
    1665        DO i = imin, imax
    1666           l = l + 1
    1667           avg_grid % iii(l) = i
    1668           avg_grid % jjj(l) = j
    1669        ENDDO
    1670        ENDDO
    1671 
    1672     END SUBROUTINE get_cosmo_averaging_region
     1656    END SELECT
     1657
     1658!
     1659!-- FIXME: make dlon, dlat parameters of the grid_defintion type
     1660    dlon = cosmo_lon(1) - cosmo_lon(0)
     1661    dlat = cosmo_lat(1) - cosmo_lat(0)
     1662
     1663    imin = FLOOR  ( (avg_grid%lon(1) - cosmo_lon(0)) / dlon )
     1664    imax = CEILING( (avg_grid%lon(2) - cosmo_lon(0)) / dlon )
     1665
     1666    jmin = FLOOR  ( (avg_grid%lat(1) - cosmo_lat(0)) / dlat )
     1667    jmax = CEILING( (avg_grid%lat(2) - cosmo_lat(0)) / dlat )
     1668   
     1669    message = "Grid " // TRIM(avg_grid%name(1)) // " averages over " // &
     1670              TRIM(str(imin)) // " <= i <= " // TRIM(str(imax)) //          &
     1671              " and " //                                                    &
     1672              TRIM(str(jmin)) // " <= j <= " // TRIM(str(jmax))
     1673    CALL report( 'get_cosmo_averaging_region', message )
     1674
     1675    nx = imax - imin + 1
     1676    ny = jmax - jmin + 1
     1677    avg_grid%n_columns = nx * ny
     1678
     1679    ALLOCATE( avg_grid%iii(avg_grid%n_columns),                         &
     1680              avg_grid%jjj(avg_grid%n_columns) )
     1681
     1682    l = 0
     1683    DO j = jmin, jmax
     1684    DO i = imin, imax
     1685       l = l + 1
     1686       avg_grid%iii(l) = i
     1687       avg_grid%jjj(l) = j
     1688    ENDDO
     1689    ENDDO
     1690
     1691 END SUBROUTINE get_cosmo_averaging_region
    16731692
    16741693
     
    16831702!> 'modpoints'.
    16841703!------------------------------------------------------------------------------!
    1685     SUBROUTINE stretched_z(z, dz, dz_max, dz_stretch_factor, dz_stretch_level, &
    1686                            dz_stretch_level_start, dz_stretch_level_end,       &
    1687                            dz_stretch_factor_array)
    1688 
    1689        REAL(dp), DIMENSION(:), INTENT(INOUT) ::  z, dz, dz_stretch_factor_array
    1690        REAL(dp), DIMENSION(:), INTENT(INOUT) ::  dz_stretch_level_start, dz_stretch_level_end
    1691        REAL(dp), INTENT(IN) ::  dz_max, dz_stretch_factor, dz_stretch_level
    1692 
    1693        INTEGER ::  number_stretch_level_start        !< number of user-specified start levels for stretching
    1694        INTEGER ::  number_stretch_level_end          !< number of user-specified end levels for stretching
    1695 
    1696        REAL(dp), DIMENSION(:), ALLOCATABLE ::  min_dz_stretch_level_end
    1697        REAL(dp) ::  dz_level_end, dz_stretched
    1698 
    1699        INTEGER ::  dz_stretch_level_end_index(9)      !< vertical grid level index until which the vertical grid spacing is stretched
    1700        INTEGER ::  dz_stretch_level_start_index(9)    !< vertical grid level index above which the vertical grid spacing is stretched
    1701        INTEGER ::  dz_stretch_level_index = 0
    1702        INTEGER ::  k, n, number_dz
     1704 SUBROUTINE stretched_z(z, dz, dz_max, dz_stretch_factor, dz_stretch_level, &
     1705                        dz_stretch_level_start, dz_stretch_level_end,       &
     1706                        dz_stretch_factor_array)
     1707
     1708    REAL(wp), DIMENSION(:), INTENT(INOUT) ::  z, dz, dz_stretch_factor_array
     1709    REAL(wp), DIMENSION(:), INTENT(INOUT) ::  dz_stretch_level_start, dz_stretch_level_end
     1710    REAL(wp), INTENT(IN) ::  dz_max, dz_stretch_factor, dz_stretch_level
     1711
     1712    INTEGER ::  number_stretch_level_start        !< number of user-specified start levels for stretching
     1713    INTEGER ::  number_stretch_level_end          !< number of user-specified end levels for stretching
     1714
     1715    REAL(wp), DIMENSION(:), ALLOCATABLE ::  min_dz_stretch_level_end
     1716    REAL(wp) ::  dz_level_end, dz_stretched
     1717
     1718    INTEGER ::  dz_stretch_level_end_index(9)      !< vertical grid level index until which the vertical grid spacing is stretched
     1719    INTEGER ::  dz_stretch_level_start_index(9)    !< vertical grid level index above which the vertical grid spacing is stretched
     1720    INTEGER ::  dz_stretch_level_index = 0
     1721    INTEGER ::  k, n, number_dz
    17031722
    17041723!
    17051724!-- Compute height of u-levels from constant grid length and dz stretch factors
    1706        IF ( dz(1) == -1.0_dp )  THEN
    1707           message = 'missing dz'
    1708           CALL inifor_abort( 'stretched_z', message)
    1709        ELSEIF ( dz(1) <= 0.0_dp )  THEN
    1710           WRITE( message, * ) 'dz=', dz(1),' <= 0.0'
    1711           CALL inifor_abort( 'stretched_z', message)
    1712        ENDIF
     1725    IF ( dz(1) == -1.0_wp )  THEN
     1726       message = 'missing dz'
     1727       CALL inifor_abort( 'stretched_z', message)
     1728    ELSEIF ( dz(1) <= 0.0_wp )  THEN
     1729       WRITE( message, * ) 'dz=', dz(1),' <= 0.0'
     1730       CALL inifor_abort( 'stretched_z', message)
     1731    ENDIF
    17131732
    17141733!
    17151734!-- Initialize dz_stretch_level_start with the value of dz_stretch_level
    17161735!-- if it was set by the user
    1717        IF ( dz_stretch_level /= -9999999.9_dp ) THEN
    1718           dz_stretch_level_start(1) = dz_stretch_level
    1719        ENDIF
     1736    IF ( dz_stretch_level /= -9999999.9_wp ) THEN
     1737       dz_stretch_level_start(1) = dz_stretch_level
     1738    ENDIF
    17201739       
    17211740!
     
    17271746!-- is used (Attention: The user is not allowed to specify a dz value equal
    17281747!-- to the default of dz_max = 999.0).
    1729        number_dz = COUNT( dz /= -1.0_dp .AND. dz /= dz_max )
    1730        number_stretch_level_start = COUNT( dz_stretch_level_start /=           &
    1731                                            -9999999.9_dp )
    1732        number_stretch_level_end = COUNT( dz_stretch_level_end /=               &
    1733                                          9999999.9_dp )
     1748    number_dz = COUNT( dz /= -1.0_wp .AND. dz /= dz_max )
     1749    number_stretch_level_start = COUNT( dz_stretch_level_start /=           &
     1750                                        -9999999.9_wp )
     1751    number_stretch_level_end = COUNT( dz_stretch_level_end /=               &
     1752                                      9999999.9_wp )
    17341753
    17351754!
    17361755!-- The number of specified end levels +1 has to be the same than the number
    17371756!-- of specified dz values
    1738        IF ( number_dz /= number_stretch_level_end + 1 ) THEN
    1739           WRITE( message, * ) 'The number of values for dz = ',                &
    1740                               number_dz, 'has to be the same than ',           &
    1741                               'the number of values for ',                     &
    1742                               'dz_stretch_level_end + 1 = ',                   &
    1743                               number_stretch_level_end+1
    1744           CALL inifor_abort( 'stretched_z', message)
    1745        ENDIF
     1757    IF ( number_dz /= number_stretch_level_end + 1 ) THEN
     1758       WRITE( message, * ) 'The number of values for dz = ',                &
     1759                           number_dz, 'has to be the same than ',           &
     1760                           'the number of values for ',                     &
     1761                           'dz_stretch_level_end + 1 = ',                   &
     1762                           number_stretch_level_end+1
     1763       CALL inifor_abort( 'stretched_z', message)
     1764    ENDIF
    17461765   
    17471766!
    1748 !--    The number of specified start levels has to be the same or one less than
    1749 !--    the number of specified dz values
    1750        IF ( number_dz /= number_stretch_level_start + 1 .AND.                  &
    1751             number_dz /= number_stretch_level_start ) THEN
    1752           WRITE( message, * ) 'The number of values for dz = ',         &
    1753                               number_dz, 'has to be the same or one ', &
    1754                               'more than& the number of values for ',  &
    1755                               'dz_stretch_level_start = ',             &
    1756                               number_stretch_level_start
    1757           CALL inifor_abort( 'stretched_z', message)
    1758        ENDIF
     1767!-- The number of specified start levels has to be the same or one less than
     1768!-- the number of specified dz values
     1769    IF ( number_dz /= number_stretch_level_start + 1 .AND.                  &
     1770         number_dz /= number_stretch_level_start ) THEN
     1771       WRITE( message, * ) 'The number of values for dz = ',         &
     1772                           number_dz, 'has to be the same or one ', &
     1773                           'more than& the number of values for ',  &
     1774                           'dz_stretch_level_start = ',             &
     1775                           number_stretch_level_start
     1776       CALL inifor_abort( 'stretched_z', message)
     1777    ENDIF
    17591778   
    1760 !--    The number of specified start levels has to be the same or one more than
    1761 !--    the number of specified end levels
    1762        IF ( number_stretch_level_start /= number_stretch_level_end + 1 .AND.   &
    1763             number_stretch_level_start /= number_stretch_level_end ) THEN
    1764           WRITE( message, * ) 'The number of values for ',              &
    1765                               'dz_stretch_level_start = ',              &
    1766                               dz_stretch_level_start, 'has to be the ',&
    1767                               'same or one more than& the number of ', &
    1768                               'values for dz_stretch_level_end = ',    &
    1769                               number_stretch_level_end
    1770           CALL inifor_abort( 'stretched_z', message)
    1771        ENDIF
     1779!-- The number of specified start levels has to be the same or one more than
     1780!-- the number of specified end levels
     1781    IF ( number_stretch_level_start /= number_stretch_level_end + 1 .AND.   &
     1782         number_stretch_level_start /= number_stretch_level_end ) THEN
     1783       WRITE( message, * ) 'The number of values for ',              &
     1784                           'dz_stretch_level_start = ',              &
     1785                           dz_stretch_level_start, 'has to be the ',&
     1786                           'same or one more than& the number of ', &
     1787                           'values for dz_stretch_level_end = ',    &
     1788                           number_stretch_level_end
     1789       CALL inifor_abort( 'stretched_z', message)
     1790    ENDIF
    17721791
    17731792!
    17741793!-- Initialize dz for the free atmosphere with the value of dz_max
    1775        IF ( dz(number_stretch_level_start+1) == -1.0_dp .AND.                     &
    1776             number_stretch_level_start /= 0 ) THEN
    1777           dz(number_stretch_level_start+1) = dz_max
    1778        ENDIF
     1794    IF ( dz(number_stretch_level_start+1) == -1.0_wp .AND.                     &
     1795         number_stretch_level_start /= 0 ) THEN
     1796       dz(number_stretch_level_start+1) = dz_max
     1797    ENDIF
    17791798       
    17801799!
     
    17821801!-- atmosphere is desired (dz_stretch_level_end was not specified for the
    17831802!-- free atmosphere)
    1784        IF ( number_stretch_level_start == number_stretch_level_end + 1 ) THEN
    1785           dz_stretch_factor_array(number_stretch_level_start) =                   &
    1786           dz_stretch_factor
     1803    IF ( number_stretch_level_start == number_stretch_level_end + 1 )  THEN
     1804       dz_stretch_factor_array(number_stretch_level_start) =                   &
     1805       dz_stretch_factor
     1806    ENDIF
     1807
     1808!-- Allocation of arrays for stretching
     1809    ALLOCATE( min_dz_stretch_level_end(number_stretch_level_start) )
     1810
     1811!
     1812!-- The stretching region has to be large enough to allow for a smooth
     1813!-- transition between two different grid spacings
     1814    DO  n = 1, number_stretch_level_start
     1815       min_dz_stretch_level_end(n) = dz_stretch_level_start(n) +            &
     1816                                     4 * MAX( dz(n),dz(n+1) )
     1817    ENDDO
     1818
     1819    IF ( ANY( min_dz_stretch_level_end(1:number_stretch_level_start) >      &
     1820              dz_stretch_level_end(1:number_stretch_level_start) ) )  THEN
     1821    !IF ( ANY( min_dz_stretch_level_end >      &
     1822    !          dz_stretch_level_end ) ) THEN
     1823          message = 'Each dz_stretch_level_end has to be larger '  // &
     1824                    'than its corresponding value for ' //            &
     1825                    'dz_stretch_level_start + 4*MAX(dz(n),dz(n+1)) '//&
     1826                    'to allow for smooth grid stretching'
     1827          CALL inifor_abort('stretched_z', message)
     1828    ENDIF
     1829   
     1830!
     1831!-- Stretching must not be applied within the prandtl_layer
     1832!-- (first two grid points). For the default case dz_stretch_level_start
     1833!-- is negative. Therefore the absolut value is checked here.
     1834    IF ( ANY( ABS( dz_stretch_level_start ) < dz(1) * 1.5_wp ) )  THEN
     1835       WRITE( message, * ) 'Eeach dz_stretch_level_start has to be ',&
     1836                           'larger than ', dz(1) * 1.5
     1837          CALL inifor_abort( 'stretched_z', message)
     1838    ENDIF
     1839
     1840!
     1841!-- The stretching has to start and end on a grid level. Therefore
     1842!-- user-specified values have to ''interpolate'' to the next lowest level
     1843    IF ( number_stretch_level_start /= 0 )  THEN
     1844       dz_stretch_level_start(1) = INT( (dz_stretch_level_start(1) -        &
     1845                                         dz(1)/2.0) / dz(1) )               &
     1846                                   * dz(1) + dz(1)/2.0
     1847    ENDIF
     1848   
     1849    IF ( number_stretch_level_start > 1 )  THEN
     1850       DO  n = 2, number_stretch_level_start
     1851          dz_stretch_level_start(n) = INT( dz_stretch_level_start(n) /      &
     1852                                           dz(n) ) * dz(n)
     1853       ENDDO
     1854    ENDIF
     1855   
     1856    IF ( number_stretch_level_end /= 0 )  THEN
     1857       DO  n = 1, number_stretch_level_end
     1858          dz_stretch_level_end(n) = INT( dz_stretch_level_end(n) /          &
     1859                                         dz(n+1) ) * dz(n+1)
     1860       ENDDO
     1861    ENDIF
     1862 
     1863!
     1864!-- Determine stretching factor if necessary
     1865    IF ( number_stretch_level_end >= 1 )  THEN
     1866       CALL calculate_stretching_factor( number_stretch_level_end, dz,      &
     1867                                         dz_stretch_factor_array,           &   
     1868                                         dz_stretch_level_end,              &
     1869                                         dz_stretch_level_start )
     1870    ENDIF
     1871
     1872    z(1) = dz(1) * 0.5_wp
     1873!
     1874    dz_stretch_level_index = n
     1875    dz_stretched = dz(1)
     1876    DO  k = 2, n
     1877
     1878       IF ( dz_stretch_level <= z(k-1)  .AND.  dz_stretched < dz_max )  THEN
     1879
     1880          dz_stretched = dz_stretched * dz_stretch_factor
     1881          dz_stretched = MIN( dz_stretched, dz_max )
     1882
     1883          IF ( dz_stretch_level_index == n )  dz_stretch_level_index = k-1
     1884
    17871885       ENDIF
    17881886
    1789 !-- Allocation of arrays for stretching
    1790        ALLOCATE( min_dz_stretch_level_end(number_stretch_level_start) )
    1791 
    1792 !
    1793 !--    The stretching region has to be large enough to allow for a smooth
    1794 !--    transition between two different grid spacings
    1795        DO n = 1, number_stretch_level_start
    1796           min_dz_stretch_level_end(n) = dz_stretch_level_start(n) +            &
    1797                                         4 * MAX( dz(n),dz(n+1) )
    1798        ENDDO
    1799 
    1800        IF ( ANY( min_dz_stretch_level_end(1:number_stretch_level_start) >      &
    1801                  dz_stretch_level_end(1:number_stretch_level_start) ) ) THEN
    1802        !IF ( ANY( min_dz_stretch_level_end >      &
    1803        !          dz_stretch_level_end ) ) THEN
    1804              message = 'Each dz_stretch_level_end has to be larger '  // &
    1805                        'than its corresponding value for ' //            &
    1806                        'dz_stretch_level_start + 4*MAX(dz(n),dz(n+1)) '//&
    1807                        'to allow for smooth grid stretching'
    1808              CALL inifor_abort('stretched_z', message)
    1809        ENDIF
    1810        
    1811 !
    1812 !--    Stretching must not be applied within the prandtl_layer
    1813 !--    (first two grid points). For the default case dz_stretch_level_start
    1814 !--    is negative. Therefore the absolut value is checked here.
    1815        IF ( ANY( ABS( dz_stretch_level_start ) < dz(1) * 1.5_dp ) ) THEN
    1816           WRITE( message, * ) 'Eeach dz_stretch_level_start has to be ',&
    1817                               'larger than ', dz(1) * 1.5
    1818              CALL inifor_abort( 'stretched_z', message)
    1819        ENDIF
    1820 
    1821 !
    1822 !--    The stretching has to start and end on a grid level. Therefore
    1823 !--    user-specified values have to ''interpolate'' to the next lowest level
    1824        IF ( number_stretch_level_start /= 0 ) THEN
    1825           dz_stretch_level_start(1) = INT( (dz_stretch_level_start(1) -        &
    1826                                             dz(1)/2.0) / dz(1) )               &
    1827                                       * dz(1) + dz(1)/2.0
    1828        ENDIF
    1829        
    1830        IF ( number_stretch_level_start > 1 ) THEN
    1831           DO n = 2, number_stretch_level_start
    1832              dz_stretch_level_start(n) = INT( dz_stretch_level_start(n) /      &
    1833                                               dz(n) ) * dz(n)
    1834           ENDDO
    1835        ENDIF
    1836        
    1837        IF ( number_stretch_level_end /= 0 ) THEN
    1838           DO n = 1, number_stretch_level_end
    1839              dz_stretch_level_end(n) = INT( dz_stretch_level_end(n) /          &
    1840                                             dz(n+1) ) * dz(n+1)
    1841           ENDDO
    1842        ENDIF
    1843  
    1844 !
    1845 !--    Determine stretching factor if necessary
    1846        IF ( number_stretch_level_end >= 1 ) THEN
    1847           CALL calculate_stretching_factor( number_stretch_level_end, dz,      &
    1848                                             dz_stretch_factor_array,           &   
    1849                                             dz_stretch_level_end,              &
    1850                                             dz_stretch_level_start )
    1851        ENDIF
    1852 
    1853        z(1) = dz(1) * 0.5_dp
    1854 !
    1855        dz_stretch_level_index = n
    1856        dz_stretched = dz(1)
    1857        DO  k = 2, n
    1858 
    1859           IF ( dz_stretch_level <= z(k-1)  .AND.  dz_stretched < dz_max )  THEN
    1860 
    1861              dz_stretched = dz_stretched * dz_stretch_factor
    1862              dz_stretched = MIN( dz_stretched, dz_max )
    1863 
    1864              IF ( dz_stretch_level_index == n ) dz_stretch_level_index = k-1
    1865 
    1866           ENDIF
    1867 
    1868           z(k) = z(k-1) + dz_stretched
    1869 
    1870        ENDDO
    1871 !--    Determine u and v height levels considering the possibility of grid
    1872 !--    stretching in several heights.
    1873        n = 1
    1874        dz_stretch_level_start_index(:) = UBOUND(z, 1)
    1875        dz_stretch_level_end_index(:) = UBOUND(z, 1)
    1876        dz_stretched = dz(1)
    1877 
    1878 !--    The default value of dz_stretch_level_start is negative, thus the first
    1879 !--    condition is always true. Hence, the second condition is necessary.
    1880        DO  k = 2, UBOUND(z, 1)
    1881           IF ( dz_stretch_level_start(n) <= z(k-1) .AND.                      &
    1882                dz_stretch_level_start(n) /= -9999999.9_dp ) THEN
    1883              dz_stretched = dz_stretched * dz_stretch_factor_array(n)
    1884              
    1885              IF ( dz(n) > dz(n+1) ) THEN
    1886                 dz_stretched = MAX( dz_stretched, dz(n+1) ) !Restrict dz_stretched to the user-specified (higher) dz
    1887              ELSE
    1888                 dz_stretched = MIN( dz_stretched, dz(n+1) ) !Restrict dz_stretched to the user-specified (lower) dz
    1889              ENDIF
    1890              
    1891              IF ( dz_stretch_level_start_index(n) == UBOUND(z, 1) )            &
    1892              dz_stretch_level_start_index(n) = k-1
    1893              
     1887       z(k) = z(k-1) + dz_stretched
     1888
     1889    ENDDO
     1890!-- Determine u and v height levels considering the possibility of grid
     1891!-- stretching in several heights.
     1892    n = 1
     1893    dz_stretch_level_start_index(:) = UBOUND(z, 1)
     1894    dz_stretch_level_end_index(:) = UBOUND(z, 1)
     1895    dz_stretched = dz(1)
     1896
     1897!-- The default value of dz_stretch_level_start is negative, thus the first
     1898!-- condition is always true. Hence, the second condition is necessary.
     1899    DO  k = 2, UBOUND(z, 1)
     1900       IF ( dz_stretch_level_start(n) <= z(k-1) .AND.                      &
     1901            dz_stretch_level_start(n) /= -9999999.9_wp )  THEN
     1902          dz_stretched = dz_stretched * dz_stretch_factor_array(n)
     1903         
     1904          IF ( dz(n) > dz(n+1) )  THEN
     1905             dz_stretched = MAX( dz_stretched, dz(n+1) ) !Restrict dz_stretched to the user-specified (higher) dz
     1906          ELSE
     1907             dz_stretched = MIN( dz_stretched, dz(n+1) ) !Restrict dz_stretched to the user-specified (lower) dz
    18941908          ENDIF
    18951909         
    1896           z(k) = z(k-1) + dz_stretched
     1910          IF ( dz_stretch_level_start_index(n) == UBOUND(z, 1) )            &
     1911          dz_stretch_level_start_index(n) = k-1
    18971912         
    1898 !
    1899 !--       Make sure that the stretching ends exactly at dz_stretch_level_end
    1900           dz_level_end = ABS( z(k) - dz_stretch_level_end(n) )
    1901          
    1902           IF ( dz_level_end < dz(n+1)/3.0 ) THEN
    1903              z(k) = dz_stretch_level_end(n)
    1904              dz_stretched = dz(n+1)
    1905              dz_stretch_level_end_index(n) = k
    1906              n = n + 1             
    1907           ENDIF
    1908        ENDDO
    1909 
    1910        DEALLOCATE( min_dz_stretch_level_end )
    1911 
    1912     END SUBROUTINE stretched_z
     1913       ENDIF
     1914       
     1915       z(k) = z(k-1) + dz_stretched
     1916       
     1917!
     1918!--    Make sure that the stretching ends exactly at dz_stretch_level_end
     1919       dz_level_end = ABS( z(k) - dz_stretch_level_end(n) )
     1920       
     1921       IF ( dz_level_end < dz(n+1)/3.0 )  THEN
     1922          z(k) = dz_stretch_level_end(n)
     1923          dz_stretched = dz(n+1)
     1924          dz_stretch_level_end_index(n) = k
     1925          n = n + 1             
     1926       ENDIF
     1927    ENDDO
     1928
     1929    DEALLOCATE( min_dz_stretch_level_end )
     1930
     1931 END SUBROUTINE stretched_z
    19131932
    19141933
     
    19281947                                         dz_stretch_level_start )
    19291948 
    1930     REAL(dp), DIMENSION(:), INTENT(IN)    ::  dz
    1931     REAL(dp), DIMENSION(:), INTENT(INOUT) ::  dz_stretch_factor_array
    1932     REAL(dp), DIMENSION(:), INTENT(IN)    ::  dz_stretch_level_end, dz_stretch_level_start
     1949    REAL(wp), DIMENSION(:), INTENT(IN)    ::  dz
     1950    REAL(wp), DIMENSION(:), INTENT(INOUT) ::  dz_stretch_factor_array
     1951    REAL(wp), DIMENSION(:), INTENT(IN)    ::  dz_stretch_level_end, dz_stretch_level_start
    19331952 
    19341953    INTEGER ::  iterations  !< number of iterations until stretch_factor_lower/upper_limit is reached 
     
    19381957    INTEGER, INTENT(IN) ::  number_end !< number of user-specified end levels for stretching
    19391958       
    1940     REAL(dp) ::  delta_l               !< absolute difference between l and l_rounded
    1941     REAL(dp) ::  delta_stretch_factor  !< absolute difference between stretch_factor_1 and stretch_factor_2
    1942     REAL(dp) ::  delta_total_new       !< sum of delta_l and delta_stretch_factor for the next iteration (should be as small as possible)
    1943     REAL(dp) ::  delta_total_old       !< sum of delta_l and delta_stretch_factor for the last iteration
    1944     REAL(dp) ::  distance              !< distance between dz_stretch_level_start and dz_stretch_level_end (stretching region)
    1945     REAL(dp) ::  l                     !< value that fulfil Eq. (5) in the paper mentioned above together with stretch_factor_1 exactly
    1946     REAL(dp) ::  numerator             !< numerator of the quotient
    1947     REAL(dp) ::  stretch_factor_1      !< stretching factor that fulfil Eq. (5) togehter with l exactly
    1948     REAL(dp) ::  stretch_factor_2      !< stretching factor that fulfil Eq. (6) togehter with l_rounded exactly
     1959    REAL(wp) ::  delta_l               !< absolute difference between l and l_rounded
     1960    REAL(wp) ::  delta_stretch_factor  !< absolute difference between stretch_factor_1 and stretch_factor_2
     1961    REAL(wp) ::  delta_total_new       !< sum of delta_l and delta_stretch_factor for the next iteration (should be as small as possible)
     1962    REAL(wp) ::  delta_total_old       !< sum of delta_l and delta_stretch_factor for the last iteration
     1963    REAL(wp) ::  distance              !< distance between dz_stretch_level_start and dz_stretch_level_end (stretching region)
     1964    REAL(wp) ::  l                     !< value that fulfil Eq. (5) in the paper mentioned above together with stretch_factor_1 exactly
     1965    REAL(wp) ::  numerator             !< numerator of the quotient
     1966    REAL(wp) ::  stretch_factor_1      !< stretching factor that fulfil Eq. (5) togehter with l exactly
     1967    REAL(wp) ::  stretch_factor_2      !< stretching factor that fulfil Eq. (6) togehter with l_rounded exactly
    19491968   
    1950     REAL(dp) ::  dz_stretch_factor_array_2(9) = 1.08_dp  !< Array that contains all stretch_factor_2 that belongs to stretch_factor_1
     1969    REAL(wp) ::  dz_stretch_factor_array_2(9) = 1.08_wp  !< Array that contains all stretch_factor_2 that belongs to stretch_factor_1
    19511970   
    1952     REAL(dp), PARAMETER ::  stretch_factor_interval = 1.0E-06  !< interval for sampling possible stretching factors
    1953     REAL(dp), PARAMETER ::  stretch_factor_lower_limit = 0.88  !< lowest possible stretching factor
    1954     REAL(dp), PARAMETER ::  stretch_factor_upper_limit = 1.12  !< highest possible stretching factor
     1971    REAL(wp), PARAMETER ::  stretch_factor_interval = 1.0E-06  !< interval for sampling possible stretching factors
     1972    REAL(wp), PARAMETER ::  stretch_factor_lower_limit = 0.88  !< lowest possible stretching factor
     1973    REAL(wp), PARAMETER ::  stretch_factor_upper_limit = 1.12  !< highest possible stretching factor
    19551974 
    19561975 
     
    19631982       delta_total_old = 1.0
    19641983       
    1965        IF ( dz(n) > dz(n+1) ) THEN
    1966           DO WHILE ( stretch_factor_1 >= stretch_factor_lower_limit )
     1984       IF ( dz(n) > dz(n+1) )  THEN
     1985          DO  WHILE ( stretch_factor_1 >= stretch_factor_lower_limit )
    19671986             
    19681987             stretch_factor_1 = 1.0 - iterations * stretch_factor_interval
     
    19721991                         stretch_factor_1 - distance/dz(n)
    19731992             
    1974              IF ( numerator > 0.0 ) THEN
     1993             IF ( numerator > 0.0 )  THEN
    19751994                l = LOG( numerator ) / LOG( stretch_factor_1 ) - 1.0
    19761995                l_rounded = NINT( l )
     
    19912010!--                stretch_factor_2 would guarantee that the stretched dz(n) is
    19922011!--                equal to dz(n+1) after l_rounded grid levels.
    1993              IF (delta_total_new < delta_total_old) THEN
     2012             IF (delta_total_new < delta_total_old)  THEN
    19942013                dz_stretch_factor_array(n) = stretch_factor_1
    19952014                dz_stretch_factor_array_2(n) = stretch_factor_2
     
    20012020          ENDDO
    20022021             
    2003        ELSEIF ( dz(n) < dz(n+1) ) THEN
    2004           DO WHILE ( stretch_factor_1 <= stretch_factor_upper_limit )
     2022       ELSEIF ( dz(n) < dz(n+1) )  THEN
     2023          DO  WHILE ( stretch_factor_1 <= stretch_factor_upper_limit )
    20052024                     
    20062025             stretch_factor_1 = 1.0 + iterations * stretch_factor_interval
     
    20272046!--          stretch_factor_2 would guarantee that the stretched dz(n) is
    20282047!--          equal to dz(n+1) after l_rounded grid levels.
    2029              IF (delta_total_new < delta_total_old) THEN
     2048             IF (delta_total_new < delta_total_old)  THEN
    20302049                dz_stretch_factor_array(n) = stretch_factor_1
    20312050                dz_stretch_factor_array_2(n) = stretch_factor_2
     
    20452064!--    interval. If not, print a warning for the user.
    20462065       IF ( dz_stretch_factor_array_2(n) < stretch_factor_lower_limit .OR.     &
    2047             dz_stretch_factor_array_2(n) > stretch_factor_upper_limit ) THEN
    2048           WRITE( message, * ) 'stretch_factor_2 = ',                    &
     2066            dz_stretch_factor_array_2(n) > stretch_factor_upper_limit )  THEN
     2067          WRITE( message, * ) 'stretch_factor_2 = ',                           &
    20492068                                     dz_stretch_factor_array_2(n), ' which is',&
    20502069                                     ' responsible for exactly reaching& dz =',&
     
    20672086!> coordinate vector 'z' and stores it in 'zw'.
    20682087!------------------------------------------------------------------------------!
    2069     SUBROUTINE midpoints(z, zw)
    2070 
    2071         REAL(dp), INTENT(IN)  ::  z(0:)
    2072         REAL(dp), INTENT(OUT) ::  zw(1:)
    2073 
    2074         INTEGER ::  k
    2075 
    2076         DO k = 1, UBOUND(zw, 1)
    2077            zw(k) = 0.5_dp * (z(k-1) + z(k))
    2078         ENDDO
    2079 
    2080     END SUBROUTINE midpoints
     2088 SUBROUTINE midpoints(z, zw)
     2089
     2090     REAL(wp), INTENT(IN)  ::  z(0:)
     2091     REAL(wp), INTENT(OUT) ::  zw(1:)
     2092
     2093     INTEGER ::  k
     2094
     2095     DO k = 1, UBOUND(zw, 1)
     2096        zw(k) = 0.5_wp * (z(k-1) + z(k))
     2097     ENDDO
     2098
     2099 END SUBROUTINE midpoints
    20812100
    20822101!------------------------------------------------------------------------------!
     
    20852104!> Defines INFOR's IO groups.
    20862105!------------------------------------------------------------------------------!
    2087     SUBROUTINE setup_io_groups()
    2088 
    2089        INTEGER ::  ngroups
    2090 
    2091        ngroups = 16
    2092        ALLOCATE( io_group_list(ngroups) )
    2093 
    2094 !
    2095 !--    soil temp
    2096        io_group_list(1) = init_io_group(                                       &
    2097           in_files = soil_files,                                               &
    2098           out_vars = output_var_table(1:1),                                    &
    2099           in_var_list = input_var_table(1:1),                                  &
    2100           kind = 'soil-temperature'                                            &
    2101        )
    2102 
    2103 !
    2104 !--    soil water
    2105        io_group_list(2) = init_io_group(                                       &
    2106           in_files = soil_files,                                               &
    2107           out_vars = output_var_table(2:2),                                    &
    2108           in_var_list = input_var_table(2:2),                                  &
    2109           kind = 'soil-water'                                                  &
    2110        )
    2111 
    2112 !
    2113 !--    potential temperature, surface pressure, specific humidity including
    2114 !--    nudging and subsidence, and geostrophic winds ug, vg
    2115        io_group_list(3) = init_io_group(                                       &
    2116           in_files = flow_files,                                               &
    2117           out_vars = [output_var_table(56:64),                                 & ! internal averaged density and pressure profiles
    2118                       output_var_table(3:8), output_var_table(9:14),           &
    2119                       output_var_table(42:42), output_var_table(43:44),        &
    2120                       output_var_table(49:51), output_var_table(52:54)],       &
    2121           in_var_list = (/input_var_table(3), input_var_table(17),             & ! T, P, QV
    2122                           input_var_table(4) /),                               &
    2123           kind = 'thermodynamics',                                             &
    2124           n_output_quantities = 4                                              & ! P, Theta, Rho, qv
    2125        )
    2126 
    2127 !
    2128 !--    Moved to therodynamic io_group
    2129        !io_group_list(4) = init_io_group(                                       &
    2130        !   in_files = flow_files,                                               &
    2131        !   out_vars = [output_var_table(9:14), output_var_table(52:54)],        &
    2132        !   in_var_list = input_var_table(4:4),                                  &
    2133        !   kind = 'scalar'                                                      &
    2134        !)
    2135 
    2136 !
    2137 !--    u and v velocity
    2138        io_group_list(5) = init_io_group(                                       &
    2139           in_files = flow_files,                                               &
    2140           out_vars = [output_var_table(15:26), output_var_table(45:46)],       &
    2141           !out_vars = output_var_table(15:20),                                  &
    2142           in_var_list = input_var_table(5:6),                                  &
    2143           !in_var_list = input_var_table(5:5),                                  &
    2144           kind = 'velocities'                                                  &
    2145        )
     2106 SUBROUTINE setup_io_groups()
     2107
     2108    INTEGER ::  ngroups
     2109
     2110    ngroups = 16
     2111    ALLOCATE( io_group_list(ngroups) )
     2112
     2113!
     2114!-- soil temp
     2115    io_group_list(1) = init_io_group(                                       &
     2116       in_files = soil_files,                                               &
     2117       out_vars = output_var_table(1:1),                                    &
     2118       in_var_list = input_var_table(1:1),                                  &
     2119       kind = 'soil-temperature'                                            &
     2120    )
     2121
     2122!
     2123!-- soil water
     2124    io_group_list(2) = init_io_group(                                       &
     2125       in_files = soil_files,                                               &
     2126       out_vars = output_var_table(2:2),                                    &
     2127       in_var_list = input_var_table(2:2),                                  &
     2128       kind = 'soil-water'                                                  &
     2129    )
     2130
     2131!
     2132!-- potential temperature, surface pressure, specific humidity including
     2133!-- nudging and subsidence, and geostrophic winds ug, vg
     2134    io_group_list(3) = init_io_group(                                       &
     2135       in_files = flow_files,                                               &
     2136       out_vars = [output_var_table(56:64),                                 & ! internal averaged density and pressure profiles
     2137                   output_var_table(3:8), output_var_table(9:14),           &
     2138                   output_var_table(42:42), output_var_table(43:44),        &
     2139                   output_var_table(49:51), output_var_table(52:54)],       &
     2140       in_var_list = (/input_var_table(3), input_var_table(17),             & ! T, P, QV
     2141                       input_var_table(4) /),                               &
     2142       kind = 'thermodynamics',                                             &
     2143       n_output_quantities = 4                                              & ! P, Theta, Rho, qv
     2144    )
     2145
     2146!
     2147!-- Moved to therodynamic io_group
     2148    !io_group_list(4) = init_io_group(                                       &
     2149    !   in_files = flow_files,                                               &
     2150    !   out_vars = [output_var_table(9:14), output_var_table(52:54)],        &
     2151    !   in_var_list = input_var_table(4:4),                                  &
     2152    !   kind = 'scalar'                                                      &
     2153    !)
     2154
     2155!
     2156!-- u and v velocity
     2157    io_group_list(5) = init_io_group(                                       &
     2158       in_files = flow_files,                                               &
     2159       out_vars = [output_var_table(15:26), output_var_table(45:46)],       &
     2160       !out_vars = output_var_table(15:20),                                  &
     2161       in_var_list = input_var_table(5:6),                                  &
     2162       !in_var_list = input_var_table(5:5),                                  &
     2163       kind = 'velocities'                                                  &
     2164    )
    21462165   
    21472166!
    2148 !--    v velocity, deprecated!
    2149        !io_group_list(6) = init_io_group(                                       &
    2150        !   in_files = flow_files,                                               &
    2151        !   out_vars = output_var_table(21:26),                                  &
    2152        !   in_var_list = input_var_table(6:6),                                  &
    2153        !   kind = 'horizontal velocity'                                         &
    2154        !)
    2155        !io_group_list(6) % to_be_processed = .FALSE.
     2167!-- v velocity, deprecated!
     2168    !io_group_list(6) = init_io_group(                                       &
     2169    !   in_files = flow_files,                                               &
     2170    !   out_vars = output_var_table(21:26),                                  &
     2171    !   in_var_list = input_var_table(6:6),                                  &
     2172    !   kind = 'horizontal velocity'                                         &
     2173    !)
     2174    !io_group_list(6)%to_be_processed = .FALSE.
    21562175   
    21572176!
    2158 !--    w velocity and subsidence and w nudging
    2159        io_group_list(7) = init_io_group(                                       &
    2160           in_files = flow_files,                                               &
    2161           out_vars = [output_var_table(27:32), output_var_table(47:48)],       &
    2162           in_var_list = input_var_table(7:7),                                  &
    2163           kind = 'scalar'                                                      &
    2164        )
    2165 !
    2166 !--    rain
    2167        io_group_list(8) = init_io_group(                                       &
    2168           in_files = soil_moisture_files,                                      &
    2169           out_vars = output_var_table(33:33),                                  &
    2170           in_var_list = input_var_table(8:8),                                  &
    2171           kind = 'accumulated'                                                 &
    2172        )
    2173        io_group_list(8) % to_be_processed = .FALSE.
    2174 !
    2175 !--    snow
    2176        io_group_list(9) = init_io_group(                                       &
    2177           in_files = soil_moisture_files,                                      &
    2178           out_vars = output_var_table(34:34),                                  &
    2179           in_var_list = input_var_table(9:9),                                  &
    2180           kind = 'accumulated'                                                 &
    2181        )
    2182        io_group_list(9) % to_be_processed = .FALSE.
    2183 !
    2184 !--    graupel
    2185        io_group_list(10) = init_io_group(                                      &
    2186           in_files = soil_moisture_files,                                      &
    2187           out_vars = output_var_table(35:35),                                  &
    2188           in_var_list = input_var_table(10:10),                                &
    2189           kind = 'accumulated'                                                 &
    2190        )
    2191        io_group_list(10) % to_be_processed = .FALSE.
    2192 !
    2193 !--    evapotranspiration
    2194        io_group_list(11) = init_io_group(                                      &
    2195           in_files = soil_moisture_files,                                      &
    2196           out_vars = output_var_table(37:37),                                  &
    2197           in_var_list = input_var_table(11:11),                                &
    2198           kind = 'accumulated'                                                 &
    2199        )
    2200        io_group_list(11) % to_be_processed = .FALSE.
    2201 !
    2202 !--    2m air temperature
    2203        io_group_list(12) = init_io_group(                                      &
    2204           in_files = soil_moisture_files,                                      &
    2205           out_vars = output_var_table(36:36),                                  &
    2206           in_var_list = input_var_table(12:12),                                &
    2207           kind = 'surface'                                                     &
    2208        )
    2209        io_group_list(12) % to_be_processed = .FALSE.
    2210 !
    2211 !--    incoming diffusive sw flux
    2212        io_group_list(13) = init_io_group(                                      &
    2213           in_files = radiation_files,                                          &
    2214           out_vars = output_var_table(38:38),                                  &
    2215           in_var_list = input_var_table(13:13),                                &
    2216           kind = 'running average'                                             &
    2217        )
    2218        io_group_list(13) % to_be_processed = .FALSE.
    2219 !
    2220 !--    incoming direct sw flux
    2221        io_group_list(14) = init_io_group(                                      &
    2222           in_files = radiation_files,                                          &
    2223           out_vars = output_var_table(39:39),                                  &
    2224           in_var_list = input_var_table(14:14),                                &
    2225           kind = 'running average'                                             &
    2226        )
    2227        io_group_list(14) % to_be_processed = .FALSE.
    2228 !
    2229 !--    sw radiation balance
    2230        io_group_list(15) = init_io_group(                                      &
    2231           in_files = radiation_files,                                          &
    2232           out_vars = output_var_table(40:40),                                  &
    2233           in_var_list = input_var_table(15:15),                                &
    2234           kind = 'running average'                                             &
    2235        )
    2236        io_group_list(15) % to_be_processed = .FALSE.
    2237 !
    2238 !--    lw radiation balance
    2239        io_group_list(16) = init_io_group(                                      &
    2240           in_files = radiation_files,                                          &
    2241           out_vars = output_var_table(41:41),                                  &
    2242           in_var_list = input_var_table(16:16),                                &
    2243           kind = 'running average'                                             &
    2244        )
    2245        io_group_list(16) % to_be_processed = .FALSE.
    2246 
    2247     END SUBROUTINE setup_io_groups
     2177!-- w velocity and subsidence and w nudging
     2178    io_group_list(7) = init_io_group(                                       &
     2179       in_files = flow_files,                                               &
     2180       out_vars = [output_var_table(27:32), output_var_table(47:48)],       &
     2181       in_var_list = input_var_table(7:7),                                  &
     2182       kind = 'scalar'                                                      &
     2183    )
     2184!
     2185!-- rain
     2186    io_group_list(8) = init_io_group(                                       &
     2187       in_files = soil_moisture_files,                                      &
     2188       out_vars = output_var_table(33:33),                                  &
     2189       in_var_list = input_var_table(8:8),                                  &
     2190       kind = 'accumulated'                                                 &
     2191    )
     2192    io_group_list(8)%to_be_processed = .FALSE.
     2193!
     2194!-- snow
     2195    io_group_list(9) = init_io_group(                                       &
     2196       in_files = soil_moisture_files,                                      &
     2197       out_vars = output_var_table(34:34),                                  &
     2198       in_var_list = input_var_table(9:9),                                  &
     2199       kind = 'accumulated'                                                 &
     2200    )
     2201    io_group_list(9)%to_be_processed = .FALSE.
     2202!
     2203!-- graupel
     2204    io_group_list(10) = init_io_group(                                      &
     2205       in_files = soil_moisture_files,                                      &
     2206       out_vars = output_var_table(35:35),                                  &
     2207       in_var_list = input_var_table(10:10),                                &
     2208       kind = 'accumulated'                                                 &
     2209    )
     2210    io_group_list(10)%to_be_processed = .FALSE.
     2211!
     2212!-- evapotranspiration
     2213    io_group_list(11) = init_io_group(                                      &
     2214       in_files = soil_moisture_files,                                      &
     2215       out_vars = output_var_table(37:37),                                  &
     2216       in_var_list = input_var_table(11:11),                                &
     2217       kind = 'accumulated'                                                 &
     2218    )
     2219    io_group_list(11)%to_be_processed = .FALSE.
     2220!
     2221!-- 2m air temperature
     2222    io_group_list(12) = init_io_group(                                      &
     2223       in_files = soil_moisture_files,                                      &
     2224       out_vars = output_var_table(36:36),                                  &
     2225       in_var_list = input_var_table(12:12),                                &
     2226       kind = 'surface'                                                     &
     2227    )
     2228    io_group_list(12)%to_be_processed = .FALSE.
     2229!
     2230!-- incoming diffusive sw flux
     2231    io_group_list(13) = init_io_group(                                      &
     2232       in_files = radiation_files,                                          &
     2233       out_vars = output_var_table(38:38),                                  &
     2234       in_var_list = input_var_table(13:13),                                &
     2235       kind = 'running average'                                             &
     2236    )
     2237    io_group_list(13)%to_be_processed = .FALSE.
     2238!
     2239!-- incoming direct sw flux
     2240    io_group_list(14) = init_io_group(                                      &
     2241       in_files = radiation_files,                                          &
     2242       out_vars = output_var_table(39:39),                                  &
     2243       in_var_list = input_var_table(14:14),                                &
     2244       kind = 'running average'                                             &
     2245    )
     2246    io_group_list(14)%to_be_processed = .FALSE.
     2247!
     2248!-- sw radiation balance
     2249    io_group_list(15) = init_io_group(                                      &
     2250       in_files = radiation_files,                                          &
     2251       out_vars = output_var_table(40:40),                                  &
     2252       in_var_list = input_var_table(15:15),                                &
     2253       kind = 'running average'                                             &
     2254    )
     2255    io_group_list(15)%to_be_processed = .FALSE.
     2256!
     2257!-- lw radiation balance
     2258    io_group_list(16) = init_io_group(                                      &
     2259       in_files = radiation_files,                                          &
     2260       out_vars = output_var_table(41:41),                                  &
     2261       in_var_list = input_var_table(16:16),                                &
     2262       kind = 'running average'                                             &
     2263    )
     2264    io_group_list(16)%to_be_processed = .FALSE.
     2265
     2266 END SUBROUTINE setup_io_groups
    22482267
    22492268
     
    22592278!> on the output quantity Theta.
    22602279!------------------------------------------------------------------------------!
    2261     FUNCTION init_io_group(in_files, out_vars, in_var_list, kind,              &
    2262                            n_output_quantities) RESULT(group)
    2263        CHARACTER(LEN=PATH), INTENT(IN) ::  in_files(:)
    2264        CHARACTER(LEN=*), INTENT(IN)    ::  kind
    2265        TYPE(nc_var), INTENT(IN)        ::  out_vars(:)
    2266        TYPE(nc_var), INTENT(IN)        ::  in_var_list(:)
    2267        INTEGER, OPTIONAL               ::  n_output_quantities
    2268 
    2269        TYPE(io_group)                  ::  group
    2270 
    2271        group % nt = SIZE(in_files)
    2272        group % nv = SIZE(out_vars)
    2273        group % n_inputs = SIZE(in_var_list)
    2274        group % kind = TRIM(kind)
    2275 !
    2276 !--    For the 'thermodynamics' IO group, one quantity more than input variables
    2277 !--    is needed to compute all output variables of the IO group. Concretely, in
    2278 !--    preprocess() the density is computed from T,P or PP,QV in adddition to
    2279 !--    the variables Theta, p, qv. In read_input_variables(),
    2280 !--    n_output_quantities is used to allocate the correct number of input
    2281 !--    buffers.
    2282        IF ( PRESENT(n_output_quantities) )  THEN
    2283           group % n_output_quantities = n_output_quantities
    2284        ELSE
    2285           group % n_output_quantities = group % n_inputs
    2286        ENDIF
    2287 
    2288        ALLOCATE(group % in_var_list(group % n_inputs))
    2289        ALLOCATE(group % in_files(group % nt))
    2290        ALLOCATE(group % out_vars(group % nv))
    2291 
    2292        group % in_var_list = in_var_list
    2293        group % in_files = in_files
    2294        group % out_vars = out_vars
    2295        group % to_be_processed = .TRUE.
    2296 
    2297     END FUNCTION init_io_group
     2280 FUNCTION init_io_group(in_files, out_vars, in_var_list, kind,              &
     2281                        n_output_quantities) RESULT(group)
     2282    CHARACTER(LEN=PATH), INTENT(IN) ::  in_files(:)
     2283    CHARACTER(LEN=*), INTENT(IN)    ::  kind
     2284    TYPE(nc_var), INTENT(IN)        ::  out_vars(:)
     2285    TYPE(nc_var), INTENT(IN)        ::  in_var_list(:)
     2286    INTEGER, OPTIONAL               ::  n_output_quantities
     2287
     2288    TYPE(io_group)                  ::  group
     2289
     2290    group%nt = SIZE(in_files)
     2291    group%nv = SIZE(out_vars)
     2292    group%n_inputs = SIZE(in_var_list)
     2293    group%kind = TRIM(kind)
     2294!
     2295!-- For the 'thermodynamics' IO group, one quantity more than input variables
     2296!-- is needed to compute all output variables of the IO group. Concretely, in
     2297!-- preprocess() the density is computed from T,P or PP,QV in adddition to
     2298!-- the variables Theta, p, qv. In read_input_variables(),
     2299!-- n_output_quantities is used to allocate the correct number of input
     2300!-- buffers.
     2301    IF ( PRESENT(n_output_quantities) )  THEN
     2302       group%n_output_quantities = n_output_quantities
     2303    ELSE
     2304       group%n_output_quantities = group%n_inputs
     2305    ENDIF
     2306
     2307    ALLOCATE(group%in_var_list(group%n_inputs))
     2308    ALLOCATE(group%in_files(group%nt))
     2309    ALLOCATE(group%out_vars(group%nv))
     2310
     2311    group%in_var_list = in_var_list
     2312    group%in_files = in_files
     2313    group%out_vars = out_vars
     2314    group%to_be_processed = .TRUE.
     2315
     2316 END FUNCTION init_io_group
    22982317
    22992318
     
    23032322!> Deallocates all allocated variables.
    23042323!------------------------------------------------------------------------------!
    2305     SUBROUTINE fini_grids()
    2306 
    2307        CALL report('fini_grids', 'Deallocating grids', cfg % debug)
    2308        
    2309        DEALLOCATE(x, y, z, xu, yv, zw, z_column, zw_column)
    2310 
    2311        DEALLOCATE(palm_grid%x,  palm_grid%y,  palm_grid%z,                     &
    2312                   palm_grid%xu, palm_grid%yv, palm_grid%zw,                    &
    2313                   palm_grid%clon,  palm_grid%clat,                             &
    2314                   palm_grid%clonu, palm_grid%clatu)
    2315 
    2316        DEALLOCATE(palm_intermediate%x,  palm_intermediate%y,  palm_intermediate%z, &
    2317                   palm_intermediate%xu, palm_intermediate%yv, palm_intermediate%zw,&
    2318                   palm_intermediate%clon,  palm_intermediate%clat,             & 
    2319                   palm_intermediate%clonu, palm_intermediate%clatu)
    2320 
    2321        DEALLOCATE(cosmo_grid%lon,  cosmo_grid%lat,                             &
    2322                   cosmo_grid%lonu, cosmo_grid%latv,                            &
    2323                   cosmo_grid%hfl)
    2324 
    2325     END SUBROUTINE fini_grids
     2324 SUBROUTINE fini_grids()
     2325
     2326    CALL report('fini_grids', 'Deallocating grids', cfg%debug)
     2327   
     2328    DEALLOCATE(x, y, z, xu, yv, zw, z_column, zw_column)
     2329
     2330    DEALLOCATE(palm_grid%x,  palm_grid%y,  palm_grid%z,                        &
     2331               palm_grid%xu, palm_grid%yv, palm_grid%zw,                       &
     2332               palm_grid%clon,  palm_grid%clat,                                &
     2333               palm_grid%clonu, palm_grid%clatu)
     2334
     2335    DEALLOCATE(palm_intermediate%x,  palm_intermediate%y,  palm_intermediate%z, &
     2336               palm_intermediate%xu, palm_intermediate%yv, palm_intermediate%zw,&
     2337               palm_intermediate%clon,  palm_intermediate%clat,                & 
     2338               palm_intermediate%clonu, palm_intermediate%clatu)
     2339
     2340    DEALLOCATE(cosmo_grid%lon,  cosmo_grid%lat,                                &
     2341               cosmo_grid%lonu, cosmo_grid%latv,                               &
     2342               cosmo_grid%hfl)
     2343
     2344 END SUBROUTINE fini_grids
    23262345
    23272346
     
    23312350!> Initializes the variable list.
    23322351!------------------------------------------------------------------------------!
    2333     SUBROUTINE setup_variable_tables(ic_mode)
    2334        CHARACTER(LEN=*), INTENT(IN) ::  ic_mode
    2335        INTEGER                      ::  n_invar = 0  !< number of variables in the input variable table
    2336        INTEGER                      ::  n_outvar = 0 !< number of variables in the output variable table
    2337        TYPE(nc_var), POINTER        ::  var
    2338 
    2339        IF (TRIM(cfg % start_date) == '')  THEN
    2340           message = 'Simulation start date has not been set.'
    2341           CALL inifor_abort('setup_variable_tables', message)
    2342        ENDIF
    2343 
    2344        nc_source_text = 'COSMO-DE analysis from ' // TRIM(cfg % start_date)
    2345 
    2346        n_invar = 17
    2347        n_outvar = 64
    2348        ALLOCATE( input_var_table(n_invar) )
    2349        ALLOCATE( output_var_table(n_outvar) )
     2352 SUBROUTINE setup_variable_tables(ic_mode)
     2353    CHARACTER(LEN=*), INTENT(IN) ::  ic_mode
     2354    INTEGER                      ::  n_invar = 0  !< number of variables in the input variable table
     2355    INTEGER                      ::  n_outvar = 0 !< number of variables in the output variable table
     2356    TYPE(nc_var), POINTER        ::  var
     2357
     2358    IF (TRIM(cfg%start_date) == '')  THEN
     2359       message = 'Simulation start date has not been set.'
     2360       CALL inifor_abort('setup_variable_tables', message)
     2361    ENDIF
     2362
     2363    nc_source_text = 'COSMO-DE analysis from ' // TRIM(cfg%start_date)
     2364
     2365    n_invar = 17
     2366    n_outvar = 64
     2367    ALLOCATE( input_var_table(n_invar) )
     2368    ALLOCATE( output_var_table(n_outvar) )
    23502369
    23512370!
     
    23532372!- Section 1: NetCDF input variables
    23542373!------------------------------------------------------------------------------
    2355        var => input_var_table(1)
    2356        var % name = 'T_SO'
    2357        var % to_be_processed = .TRUE.
    2358        var % is_upside_down = .FALSE.
    2359 
    2360        var => input_var_table(2)
    2361        var % name = 'W_SO'
    2362        var % to_be_processed = .TRUE.
    2363        var % is_upside_down = .FALSE.
    2364 
    2365        var => input_var_table(3)
    2366        var % name = 'T'
    2367        var % to_be_processed = .TRUE.
    2368        var % is_upside_down = .TRUE.
    2369 
    2370        var => input_var_table(4)
    2371        var % name = 'QV'
    2372        var % to_be_processed = .TRUE.
    2373        var % is_upside_down = .TRUE.
    2374 
    2375        var => input_var_table(5)
    2376        var % name = 'U'
    2377        var % to_be_processed = .TRUE.
    2378        var % is_upside_down = .TRUE.
    2379 
    2380        var => input_var_table(6)
    2381        var % name = 'V'
    2382        var % to_be_processed = .TRUE.
    2383        var % is_upside_down = .TRUE.
    2384 
    2385        var => input_var_table(7)
    2386        var % name = 'W'
    2387        var % to_be_processed = .TRUE.
    2388        var % is_upside_down = .TRUE.
    2389 
    2390        var => input_var_table(8)
    2391        var % name = 'RAIN_GSP'
    2392        var % to_be_processed = .TRUE.
    2393        var % is_upside_down = .FALSE.
    2394 
    2395        var => input_var_table(9)
    2396        var % name = 'SNOW_GSP'
    2397        var % to_be_processed = .TRUE.
    2398        var % is_upside_down = .FALSE.
    2399 
    2400        var => input_var_table(10)
    2401        var % name = 'GRAU_GSP'
    2402        var % to_be_processed = .TRUE.
    2403        var % is_upside_down = .FALSE.
    2404 
    2405        var => input_var_table(11)
    2406        var % name = 'AEVAP_S'
    2407        var % to_be_processed = .TRUE.
    2408        var % is_upside_down = .FALSE.
    2409 
    2410        var => input_var_table(12)
    2411        var % name = 'T_2M'
    2412        var % to_be_processed = .TRUE.
    2413        var % is_upside_down = .FALSE.
    2414 
    2415        var => input_var_table(13)
    2416        var % name = 'ASWDIFD_S'
    2417        var % to_be_processed = .TRUE.
    2418        var % is_upside_down = .FALSE.
    2419 
    2420        var => input_var_table(14)
    2421        var % name = 'ASWDIR_S'
    2422        var % to_be_processed = .TRUE.
    2423        var % is_upside_down = .FALSE.
    2424 
    2425        var => input_var_table(15)
    2426        var % name = 'ASOB_S'
    2427        var % to_be_processed = .TRUE.
    2428        var % is_upside_down = .FALSE.
    2429 
    2430        var => input_var_table(16)
    2431        var % name = 'ATHB_S'
    2432        var % to_be_processed = .TRUE.
    2433        var % is_upside_down = .FALSE.
    2434 
    2435        var => input_var_table(17)
    2436        var % name = 'P'
    2437        var % to_be_processed = .TRUE.
    2438        var % is_upside_down = .TRUE.
     2374    var => input_var_table(1)
     2375    var%name = 'T_SO'
     2376    var%to_be_processed = .TRUE.
     2377    var%is_upside_down = .FALSE.
     2378
     2379    var => input_var_table(2)
     2380    var%name = 'W_SO'
     2381    var%to_be_processed = .TRUE.
     2382    var%is_upside_down = .FALSE.
     2383
     2384    var => input_var_table(3)
     2385    var%name = 'T'
     2386    var%to_be_processed = .TRUE.
     2387    var%is_upside_down = .TRUE.
     2388
     2389    var => input_var_table(4)
     2390    var%name = 'QV'
     2391    var%to_be_processed = .TRUE.
     2392    var%is_upside_down = .TRUE.
     2393
     2394    var => input_var_table(5)
     2395    var%name = 'U'
     2396    var%to_be_processed = .TRUE.
     2397    var%is_upside_down = .TRUE.
     2398
     2399    var => input_var_table(6)
     2400    var%name = 'V'
     2401    var%to_be_processed = .TRUE.
     2402    var%is_upside_down = .TRUE.
     2403
     2404    var => input_var_table(7)
     2405    var%name = 'W'
     2406    var%to_be_processed = .TRUE.
     2407    var%is_upside_down = .TRUE.
     2408
     2409    var => input_var_table(8)
     2410    var%name = 'RAIN_GSP'
     2411    var%to_be_processed = .TRUE.
     2412    var%is_upside_down = .FALSE.
     2413
     2414    var => input_var_table(9)
     2415    var%name = 'SNOW_GSP'
     2416    var%to_be_processed = .TRUE.
     2417    var%is_upside_down = .FALSE.
     2418
     2419    var => input_var_table(10)
     2420    var%name = 'GRAU_GSP'
     2421    var%to_be_processed = .TRUE.
     2422    var%is_upside_down = .FALSE.
     2423
     2424    var => input_var_table(11)
     2425    var%name = 'AEVAP_S'
     2426    var%to_be_processed = .TRUE.
     2427    var%is_upside_down = .FALSE.
     2428
     2429    var => input_var_table(12)
     2430    var%name = 'T_2M'
     2431    var%to_be_processed = .TRUE.
     2432    var%is_upside_down = .FALSE.
     2433
     2434    var => input_var_table(13)
     2435    var%name = 'ASWDIFD_S'
     2436    var%to_be_processed = .TRUE.
     2437    var%is_upside_down = .FALSE.
     2438
     2439    var => input_var_table(14)
     2440    var%name = 'ASWDIR_S'
     2441    var%to_be_processed = .TRUE.
     2442    var%is_upside_down = .FALSE.
     2443
     2444    var => input_var_table(15)
     2445    var%name = 'ASOB_S'
     2446    var%to_be_processed = .TRUE.
     2447    var%is_upside_down = .FALSE.
     2448
     2449    var => input_var_table(16)
     2450    var%name = 'ATHB_S'
     2451    var%to_be_processed = .TRUE.
     2452    var%is_upside_down = .FALSE.
     2453
     2454    var => input_var_table(17)
     2455    var%name = 'P'
     2456    var%to_be_processed = .TRUE.
     2457    var%is_upside_down = .TRUE.
    24392458
    24402459!
     
    24462465! Section 2.1: Realistic forcings, i.e. 3D initial and boundary conditions
    24472466!------------------------------------------------------------------------------
    2448        output_var_table(1) = init_nc_var(                                      &
    2449           name              = 'init_soil_t',                                   &
    2450           std_name          = "",                                              &
    2451           long_name         = "initial soil temperature",                      &
    2452           units             = "K",                                             &
    2453           kind              = "init soil",                                     &
    2454           input_id          = 1,                                               &
    2455           output_file       = output_file,                                     &
    2456           grid              = palm_grid,                                       &
    2457           intermediate_grid = palm_intermediate                                &
    2458        )
    2459 
    2460        output_var_table(2) = init_nc_var(                                      &
    2461           name              = 'init_soil_m',                                   &
    2462           std_name          = "",                                              &
    2463           long_name         = "initial soil moisture",                         &
    2464           units             = "m^3/m^3",                                       &
    2465           kind              = "init soil",                                     &
    2466           input_id          = 1,                                               &
    2467           output_file       = output_file,                                     &
    2468           grid              = palm_grid,                                       &
    2469           intermediate_grid = palm_intermediate                                &
    2470        )
    2471 
    2472        output_var_table(3) = init_nc_var(                                      &
    2473           name              = 'init_atmosphere_pt',                            &
    2474           std_name          = "",                                              &
    2475           long_name         = "initial potential temperature",                 &
    2476           units             = "K",                                             &
    2477           kind              = "init scalar",                                   &
    2478           input_id          = 1,                                               & ! first in (T, p) IO group
    2479           output_file       = output_file,                                     &
    2480           grid              = palm_grid,                                       &
    2481           intermediate_grid = palm_intermediate,                               &
    2482           is_profile = (TRIM(ic_mode) == 'profile')                            &
    2483        )
    2484        IF (TRIM(ic_mode) == 'profile')  THEN
    2485           output_var_table(3) % averaging_grid => averaged_initial_scalar_profile
    2486        ENDIF
    2487 
    2488        output_var_table(4) = init_nc_var(                                      &
    2489           name              = 'ls_forcing_left_pt',                            &
    2490           std_name          = "",                                              &
    2491           long_name         = "large-scale forcing for left model boundary for the potential temperature", &
    2492           units             = "K",                                             &
    2493           kind              = "left scalar",                                   &
    2494           input_id          = 1,                                               &
    2495           grid              = scalars_west_grid,                               &
    2496           intermediate_grid = scalars_west_intermediate,                       &
    2497           output_file = output_file                                            &
    2498        )
    2499 
    2500        output_var_table(5) = init_nc_var(                                      &
    2501           name              = 'ls_forcing_right_pt',                           &
    2502           std_name          = "",                                              &
    2503           long_name         = "large-scale forcing for right model boundary for the potential temperature", &
    2504           units             = "K",                                             &
    2505           kind              = "right scalar",                                  &
    2506           input_id          = 1,                                               &
    2507           grid              = scalars_east_grid,                               &
    2508           intermediate_grid = scalars_east_intermediate,                       &
    2509           output_file = output_file                                            &
    2510        )
    2511 
    2512        output_var_table(6) = init_nc_var(                                      &
    2513           name              = 'ls_forcing_north_pt',                           &
    2514           std_name          = "",                                              &
    2515           long_name         = "large-scale forcing for north model boundary for the potential temperature", &
    2516           units             = "K",                                             &
    2517           kind              = "north scalar",                                  &
    2518           input_id          = 1,                                               &
    2519           grid              = scalars_north_grid,                              &
    2520           intermediate_grid = scalars_north_intermediate,                      &
    2521           output_file = output_file                                            &
    2522        )
    2523 
    2524        output_var_table(7) = init_nc_var(                                      &
    2525           name              = 'ls_forcing_south_pt',                           &
    2526           std_name          = "",                                              &
    2527           long_name         = "large-scale forcing for south model boundary for the potential temperature", &
    2528           units             = "K",                                             &
    2529           kind              = "south scalar",                                  &
    2530           input_id          = 1,                                               &
    2531           grid              = scalars_south_grid,                              &
    2532           intermediate_grid = scalars_south_intermediate,                      &
    2533           output_file = output_file                                            &
    2534        )
    2535 
    2536        output_var_table(8) = init_nc_var(                                      &
    2537           name              = 'ls_forcing_top_pt',                             &
    2538           std_name          = "",                                              &
    2539           long_name         = "large-scale forcing for top model boundary for the potential temperature", &
    2540           units             = "K",                                             &
    2541           kind              = "top scalar",                                    &
    2542           input_id          = 1,                                               &
    2543           grid              = scalars_top_grid,                                &
    2544           intermediate_grid = scalars_top_intermediate,                        &
    2545           output_file = output_file                                            &
    2546        )
    2547 
    2548        output_var_table(9) = init_nc_var(                                      &
    2549           name              = 'init_atmosphere_qv',                            &
    2550           std_name          = "",                                              &
    2551           long_name         = "initial specific humidity",                     &
    2552           units             = "kg/kg",                                         &
    2553           kind              = "init scalar",                                   &
    2554           input_id          = 3,                                               &
    2555           output_file       = output_file,                                     &
    2556           grid              = palm_grid,                                       &
    2557           intermediate_grid = palm_intermediate,                               &
    2558           is_profile = (TRIM(ic_mode) == 'profile')                            &
    2559        )
    2560        IF (TRIM(ic_mode) == 'profile')  THEN
    2561           output_var_table(9) % averaging_grid => averaged_initial_scalar_profile
    2562        ENDIF
    2563 
    2564        output_var_table(10) = init_nc_var(                                     &
    2565           name              = 'ls_forcing_left_qv',                            &
    2566           std_name          = "",                                              &
    2567           long_name         = "large-scale forcing for left model boundary for the specific humidity", &
    2568           units             = "kg/kg",                                         &
    2569           kind              = "left scalar",                                   &
    2570           input_id          = 3,                                               &
    2571           output_file       = output_file,                                     &
    2572           grid              = scalars_west_grid,                               &
    2573           intermediate_grid = scalars_west_intermediate                        &
    2574        )
    2575 
    2576        output_var_table(11) = init_nc_var(                                     &
    2577           name              = 'ls_forcing_right_qv',                           &
    2578           std_name          = "",                                              &
    2579           long_name         = "large-scale forcing for right model boundary for the specific humidity", &
    2580           units             = "kg/kg",                                         &
    2581           kind              = "right scalar",                                  &
    2582           input_id          = 3,                                               &
    2583           output_file       = output_file,                                     &
    2584           grid              = scalars_east_grid,                               &
    2585           intermediate_grid = scalars_east_intermediate                        &
    2586        )
    2587 
    2588        output_var_table(12) = init_nc_var(                                     &
    2589           name              = 'ls_forcing_north_qv',                           &
    2590           std_name          = "",                                              &
    2591           long_name         = "large-scale forcing for north model boundary for the specific humidity", &
    2592           units             = "kg/kg",                                         &
    2593           kind              = "north scalar",                                  &
    2594           input_id          = 3,                                               &
    2595           output_file       = output_file,                                     &
    2596           grid              = scalars_north_grid,                              &
    2597           intermediate_grid = scalars_north_intermediate                       &
    2598        )
    2599 
    2600        output_var_table(13) = init_nc_var(                                     &
    2601           name              = 'ls_forcing_south_qv',                           &
    2602           std_name          = "",                                              &
    2603           long_name         = "large-scale forcing for south model boundary for the specific humidity", &
    2604           units             = "kg/kg",                                         &
    2605           kind              = "south scalar",                                  &
    2606           input_id          = 3,                                               &
    2607           output_file       = output_file,                                     &
    2608           grid              = scalars_south_grid,                              &
    2609           intermediate_grid = scalars_south_intermediate                       &
    2610        )
    2611 
    2612        output_var_table(14) = init_nc_var(                                     &
    2613           name              = 'ls_forcing_top_qv',                             &
    2614           std_name          = "",                                              &
    2615           long_name         = "large-scale forcing for top model boundary for the specific humidity", &
    2616           units             = "kg/kg",                                         &
    2617           kind              = "top scalar",                                    &
    2618           input_id          = 3,                                               &
    2619           output_file       = output_file,                                     &
    2620           grid              = scalars_top_grid,                                &
    2621           intermediate_grid = scalars_top_intermediate                         &
    2622        )
    2623 
    2624        output_var_table(15) = init_nc_var(                                     &
    2625           name              = 'init_atmosphere_u',                             &
    2626           std_name          = "",                                              &
    2627           long_name         = "initial wind component in x direction",         &
    2628           units             = "m/s",                                           &
    2629           kind              = "init u",                                        &
    2630           input_id          = 1,                                               & ! first in (U, V) I/O group
    2631           output_file       = output_file,                                     &
    2632           grid              = u_initial_grid,                                  &
    2633           intermediate_grid = u_initial_intermediate,                          &
    2634           is_profile = (TRIM(ic_mode) == 'profile')                            &
    2635        )
    2636        IF (TRIM(ic_mode) == 'profile')  THEN
    2637           output_var_table(15) % averaging_grid => averaged_initial_scalar_profile
    2638        ENDIF
    2639 
    2640        output_var_table(16) = init_nc_var(                                     &
    2641           name              = 'ls_forcing_left_u',                             &
    2642           std_name          = "",                                              &
    2643           long_name         = "large-scale forcing for left model boundary for the wind component in x direction", &
    2644           units             = "m/s",                                           &
    2645           kind              = "left u",                                        &
    2646           input_id          = 1,                                               & ! first in (U, V) I/O group
    2647           output_file       = output_file,                                     &
    2648           grid              = u_west_grid,                                     &
    2649           intermediate_grid = u_west_intermediate                              &
    2650        )
    2651 
    2652        output_var_table(17) = init_nc_var(                                     &
    2653           name              = 'ls_forcing_right_u',                            &
    2654           std_name          = "",                                              &
    2655           long_name         = "large-scale forcing for right model boundary for the wind component in x direction", &
    2656           units             = "m/s",                                           &
    2657           kind              = "right u",                                       &
    2658           input_id          = 1,                                               & ! first in (U, V) I/O group
    2659           output_file       = output_file,                                     &
    2660           grid              = u_east_grid,                                     &
    2661           intermediate_grid = u_east_intermediate                              &
    2662        )
    2663 
    2664        output_var_table(18) = init_nc_var(                                     &
    2665           name              = 'ls_forcing_north_u',                            &
    2666           std_name          = "",                                              &
    2667           long_name         = "large-scale forcing for north model boundary for the wind component in x direction", &
    2668           units             = "m/s",                                           &
    2669           kind              = "north u",                                       &
    2670           input_id          = 1,                                               & ! first in (U, V) I/O group
    2671           output_file       = output_file,                                     &
    2672           grid              = u_north_grid,                                    &
    2673           intermediate_grid = u_north_intermediate                             &
    2674        )
    2675 
    2676        output_var_table(19) = init_nc_var(                                     &
    2677           name              = 'ls_forcing_south_u',                            &
    2678           std_name          = "",                                              &
    2679           long_name         = "large-scale forcing for south model boundary for the wind component in x direction", &
    2680           units             = "m/s",                                           &
    2681           kind              = "south u",                                       &
    2682           input_id          = 1,                                               & ! first in (U, V) I/O group
    2683           output_file       = output_file,                                     &
    2684           grid              = u_south_grid,                                    &
    2685           intermediate_grid = u_south_intermediate                             &
    2686        )
    2687 
    2688        output_var_table(20) = init_nc_var(                                     &
    2689           name              = 'ls_forcing_top_u',                              &
    2690           std_name          = "",                                              &
    2691           long_name         = "large-scale forcing for top model boundary for the wind component in x direction", &
    2692           units             = "m/s",                                           &
    2693           kind              = "top u",                                         &
    2694           input_id          = 1,                                               & ! first in (U, V) I/O group
    2695           output_file       = output_file,                                     &
    2696           grid              = u_top_grid,                                      &
    2697           intermediate_grid = u_top_intermediate                               &
    2698        )
    2699 
    2700        output_var_table(21) = init_nc_var(                                     &
    2701           name              = 'init_atmosphere_v',                             &
    2702           std_name          = "",                                              &
    2703           long_name         = "initial wind component in y direction",         &
    2704           units             = "m/s",                                           &
    2705           kind              = "init v",                                        &
    2706           input_id          = 2,                                               & ! second in (U, V) I/O group
    2707           output_file       = output_file,                                     &
    2708           grid              = v_initial_grid,                                  &
    2709           intermediate_grid = v_initial_intermediate,                          &
    2710           is_profile = (TRIM(ic_mode) == 'profile')                            &
    2711        )
    2712        IF (TRIM(ic_mode) == 'profile')  THEN
    2713           output_var_table(21) % averaging_grid => averaged_initial_scalar_profile
    2714        ENDIF
    2715 
    2716        output_var_table(22) = init_nc_var(                                     &
    2717           name              = 'ls_forcing_left_v',                             &
    2718           std_name          = "",                                              &
    2719           long_name         = "large-scale forcing for left model boundary for the wind component in y direction", &
    2720           units             = "m/s",                                           &
    2721           kind              = "right v",                                       &
    2722           input_id          = 2,                                               & ! second in (U, V) I/O group
    2723           output_file       = output_file,                                     &
    2724           grid              = v_west_grid,                                     &
    2725           intermediate_grid = v_west_intermediate                              &
    2726        )
    2727 
    2728        output_var_table(23) = init_nc_var(                                     &
    2729           name              = 'ls_forcing_right_v',                            &
    2730           std_name          = "",                                              &
    2731           long_name         = "large-scale forcing for right model boundary for the wind component in y direction", &
    2732           units             = "m/s",                                           &
    2733           kind              = "right v",                                       &
    2734           input_id          = 2,                                               & ! second in (U, V) I/O group
    2735           output_file       = output_file,                                     &
    2736           grid              = v_east_grid,                                     &
    2737           intermediate_grid = v_east_intermediate                              &
    2738        )
    2739 
    2740        output_var_table(24) = init_nc_var(                                     &
    2741           name              = 'ls_forcing_north_v',                            &
    2742           std_name          = "",                                              &
    2743           long_name         = "large-scale forcing for north model boundary for the wind component in y direction", &
    2744           units             = "m/s",                                           &
    2745           kind              = "north v",                                       &
    2746           input_id          = 2,                                               & ! second in (U, V) I/O group
    2747           output_file       = output_file,                                     &
    2748           grid              = v_north_grid,                                    &
    2749           intermediate_grid = v_north_intermediate                             &
    2750        )
    2751 
    2752        output_var_table(25) = init_nc_var(                                     &
    2753           name              = 'ls_forcing_south_v',                            &
    2754           std_name          = "",                                              &
    2755           long_name         = "large-scale forcing for south model boundary for the wind component in y direction", &
    2756           units             = "m/s",                                           &
    2757           kind              = "south v",                                       &
    2758           input_id          = 2,                                               & ! second in (U, V) I/O group
    2759           output_file       = output_file,                                     &
    2760           grid              = v_south_grid,                                    &
    2761           intermediate_grid = v_south_intermediate                             &
    2762        )
    2763 
    2764        output_var_table(26) = init_nc_var(                                     &
    2765           name              = 'ls_forcing_top_v',                              &
    2766           std_name          = "",                                              &
    2767           long_name         = "large-scale forcing for top model boundary for the wind component in y direction", &
    2768           units             = "m/s",                                           &
    2769           kind              = "top v",                                         &
    2770           input_id          = 2,                                               & ! second in (U, V) I/O group
    2771           output_file       = output_file,                                     &
    2772           grid              = v_top_grid,                                      &
    2773           intermediate_grid = v_top_intermediate                               &
    2774        )
    2775 
    2776        output_var_table(27) = init_nc_var(                                     &
    2777           name              = 'init_atmosphere_w',                             &
    2778           std_name          = "",                                              &
    2779           long_name         = "initial wind component in z direction",         &
    2780           units             = "m/s",                                           &
    2781           kind              = "init w",                                        &
    2782           input_id          = 1,                                               &
    2783           output_file       = output_file,                                     &
    2784           grid              = w_initial_grid,                                  &
    2785           intermediate_grid = w_initial_intermediate,                          &
    2786           is_profile = (TRIM(ic_mode) == 'profile')                            &
    2787        )
    2788        IF (TRIM(ic_mode) == 'profile')  THEN
    2789           output_var_table(27) % averaging_grid => averaged_initial_w_profile
    2790        ENDIF
    2791 
    2792        output_var_table(28) = init_nc_var(                                     &
    2793           name              = 'ls_forcing_left_w',                             &
    2794           std_name          = "",                                              &
    2795           long_name         = "large-scale forcing for left model boundary for the wind component in z direction", &
    2796           units             = "m/s",                                           &
    2797           kind              = "left w",                                        &
    2798           input_id          = 1,                                               &
    2799           output_file       = output_file,                                     &
    2800           grid              = w_west_grid,                                     &
    2801           intermediate_grid = w_west_intermediate                              &
    2802        )
    2803 
    2804        output_var_table(29) = init_nc_var(                                     &
    2805           name              = 'ls_forcing_right_w',                            &
    2806           std_name          = "",                                              &
    2807           long_name         = "large-scale forcing for right model boundary for the wind component in z direction", &
    2808           units             = "m/s",                                           &
    2809           kind              = "right w",                                       &
    2810           input_id          = 1,                                               &
    2811           output_file       = output_file,                                     &
    2812           grid              = w_east_grid,                                     &
    2813           intermediate_grid = w_east_intermediate                              &
    2814        )
    2815 
    2816        output_var_table(30) = init_nc_var(                                     &
    2817           name              = 'ls_forcing_north_w',                            &
    2818           std_name          = "",                                              &
    2819           long_name         = "large-scale forcing for north model boundary for the wind component in z direction", &
    2820           units             = "m/s",                                           &
    2821           kind              = "north w",                                       &
    2822           input_id          = 1,                                               &
    2823           output_file       = output_file,                                     &
    2824           grid              = w_north_grid,                                    &
    2825           intermediate_grid = w_north_intermediate                             &
    2826        )
    2827 
    2828        output_var_table(31) = init_nc_var(                                     &
    2829           name              = 'ls_forcing_south_w',                            &
    2830           std_name          = "",                                              &
    2831           long_name         = "large-scale forcing for south model boundary for the wind component in z direction", &
    2832           units             = "m/s",                                           &
    2833           kind              = "south w",                                       &
    2834           input_id          = 1,                                               &
    2835           output_file       = output_file,                                     &
    2836           grid              = w_south_grid,                                    &
    2837           intermediate_grid = w_south_intermediate                             &
    2838        )
    2839 
    2840        output_var_table(32) = init_nc_var(                                     &
    2841           name              = 'ls_forcing_top_w',                              &
    2842           std_name          = "",                                              &
    2843           long_name         = "large-scale forcing for top model boundary for the wind component in z direction", &
    2844           units             = "m/s",                                           &
    2845           kind              = "top w",                                         &
    2846           input_id          = 1,                                               &
    2847           output_file       = output_file,                                     &
    2848           grid              = w_top_grid,                                      &
    2849           intermediate_grid = w_top_intermediate                               &
    2850        )
    2851 
    2852        output_var_table(33) = init_nc_var(                                     &
    2853           name              = 'ls_forcing_soil_rain',                          &
    2854           std_name          = "",                                              &
    2855           long_name         = "large-scale forcing rain",                      &
    2856           units             = "kg/m2",                                         &
    2857           kind              = "surface forcing",                               &
    2858           input_id          = 1,                                               &
    2859           output_file       = output_file,                                     &
    2860           grid              = palm_grid,                                       &
    2861           intermediate_grid = palm_intermediate                                &
    2862        )
    2863 
    2864        output_var_table(34) = init_nc_var(                                     &
    2865           name              = 'ls_forcing_soil_snow',                          &
    2866           std_name          = "",                                              &
    2867           long_name         = "large-scale forcing snow",                      &
    2868           units             = "kg/m2",                                         &
    2869           kind              = "surface forcing",                               &
    2870           input_id          = 1,                                               &
    2871           output_file       = output_file,                                     &
    2872           grid              = palm_grid,                                       &
    2873           intermediate_grid = palm_intermediate                                &
    2874        )
    2875 
    2876        output_var_table(35) = init_nc_var(                                     &
    2877           name              = 'ls_forcing_soil_graupel',                       &
    2878           std_name          = "",                                              &
    2879           long_name         = "large-scale forcing graupel",                   &
    2880           units             = "kg/m2",                                         &
    2881           kind              = "surface forcing",                               &
    2882           input_id          = 1,                                               &
    2883           output_file       = output_file,                                     &
    2884           grid              = palm_grid,                                       &
    2885           intermediate_grid = palm_intermediate                                &
    2886        )
    2887 
    2888        output_var_table(36) = init_nc_var(                                     &
    2889           name              = 'ls_forcing_soil_t_2m',                          &
    2890           std_name          = "",                                              &
    2891           long_name         = "large-scale forcing 2m air temperature",        &
    2892           units             = "kg/m2",                                         &
    2893           kind              = "surface forcing",                               &
    2894           input_id          = 1,                                               &
    2895           output_file       = output_file,                                     &
    2896           grid              = palm_grid,                                       &
    2897           intermediate_grid = palm_intermediate                                &
    2898        )
    2899 
    2900        output_var_table(37) = init_nc_var(                                     &
    2901           name              = 'ls_forcing_soil_evap',                          &
    2902           std_name          = "",                                              &
    2903           long_name         = "large-scale forcing evapo-transpiration",       &
    2904           units             = "kg/m2",                                         &
    2905           kind              = "surface forcing",                               &
    2906           input_id          = 1,                                               &
    2907           output_file       = output_file,                                     &
    2908           grid              = palm_grid,                                       &
    2909           intermediate_grid = palm_intermediate                                &
    2910        )
    2911 
    2912        output_var_table(38) = init_nc_var(                                     &
    2913           name              = 'rad_swd_dif_0',                                 &
    2914           std_name          = "",                                              &
    2915           long_name         = "incoming diffuse shortwave radiative flux at the surface", &
    2916           units             = "W/m2",                                          &
    2917           kind              = "surface forcing",                               &
    2918           input_id          = 1,                                               &
    2919           output_file       = output_file,                                     &
    2920           grid              = palm_grid,                                       &
    2921           intermediate_grid = palm_intermediate                                &
    2922        )
    2923 
    2924        output_var_table(39) = init_nc_var(                                     &
    2925           name              = 'rad_swd_dir_0',                                 &
    2926           std_name          = "",                                              &
    2927           long_name         = "incoming direct shortwave radiative flux at the surface", &
    2928           units             = "W/m2",                                          &
    2929           kind              = "surface forcing",                               &
    2930           input_id          = 1,                                               &
    2931           output_file       = output_file,                                     &
    2932           grid              = palm_grid,                                       &
    2933           intermediate_grid = palm_intermediate                                &
    2934        )
    2935 
    2936        output_var_table(40) = init_nc_var(                                     &
    2937           name              = 'rad_sw_bal_0',                                  &
    2938           std_name          = "",                                              &
    2939           long_name         = "shortwave radiation balance at the surface",    &
    2940           units             = "W/m2",                                          &
    2941           kind              = "surface forcing",                               &
    2942           input_id          = 1,                                               &
    2943           output_file       = output_file,                                     &
    2944           grid              = palm_grid,                                       &
    2945           intermediate_grid = palm_intermediate                                &
    2946        )
    2947 
    2948        output_var_table(41) = init_nc_var(                                     &
    2949           name              = 'rad_lw_bal_0',                                  &
    2950           std_name          = "",                                              &
    2951           long_name         = "longwave radiation balance at the surface",     &
    2952           units             = "W/m2",                                          &
    2953           kind              = "surface forcing",                               &
    2954           input_id          = 1,                                               &
    2955           output_file       = output_file,                                     &
    2956           grid              = palm_grid,                                       &
    2957           intermediate_grid = palm_intermediate                                &
    2958        )
     2467    output_var_table(1) = init_nc_var(                                      &
     2468       name              = 'init_soil_t',                                   &
     2469       std_name          = "",                                              &
     2470       long_name         = "initial soil temperature",                      &
     2471       units             = "K",                                             &
     2472       kind              = "init soil",                                     &
     2473       input_id          = 1,                                               &
     2474       output_file       = output_file,                                     &
     2475       grid              = palm_grid,                                       &
     2476       intermediate_grid = palm_intermediate                                &
     2477    )
     2478
     2479    output_var_table(2) = init_nc_var(                                      &
     2480       name              = 'init_soil_m',                                   &
     2481       std_name          = "",                                              &
     2482       long_name         = "initial soil moisture",                         &
     2483       units             = "m^3/m^3",                                       &
     2484       kind              = "init soil",                                     &
     2485       input_id          = 1,                                               &
     2486       output_file       = output_file,                                     &
     2487       grid              = palm_grid,                                       &
     2488       intermediate_grid = palm_intermediate                                &
     2489    )
     2490
     2491    output_var_table(3) = init_nc_var(                                      &
     2492       name              = 'init_atmosphere_pt',                            &
     2493       std_name          = "",                                              &
     2494       long_name         = "initial potential temperature",                 &
     2495       units             = "K",                                             &
     2496       kind              = "init scalar",                                   &
     2497       input_id          = 1,                                               & ! first in (T, p) IO group
     2498       output_file       = output_file,                                     &
     2499       grid              = palm_grid,                                       &
     2500       intermediate_grid = palm_intermediate,                               &
     2501       is_profile = (TRIM(ic_mode) == 'profile')                            &
     2502    )
     2503    IF (TRIM(ic_mode) == 'profile')  THEN
     2504       output_var_table(3)%averaging_grid => averaged_initial_scalar_profile
     2505    ENDIF
     2506
     2507    output_var_table(4) = init_nc_var(                                      &
     2508       name              = 'ls_forcing_left_pt',                            &
     2509       std_name          = "",                                              &
     2510       long_name         = "large-scale forcing for left model boundary for the potential temperature", &
     2511       units             = "K",                                             &
     2512       kind              = "left scalar",                                   &
     2513       input_id          = 1,                                               &
     2514       grid              = scalars_west_grid,                               &
     2515       intermediate_grid = scalars_west_intermediate,                       &
     2516       output_file = output_file                                            &
     2517    )
     2518
     2519    output_var_table(5) = init_nc_var(                                      &
     2520       name              = 'ls_forcing_right_pt',                           &
     2521       std_name          = "",                                              &
     2522       long_name         = "large-scale forcing for right model boundary for the potential temperature", &
     2523       units             = "K",                                             &
     2524       kind              = "right scalar",                                  &
     2525       input_id          = 1,                                               &
     2526       grid              = scalars_east_grid,                               &
     2527       intermediate_grid = scalars_east_intermediate,                       &
     2528       output_file = output_file                                            &
     2529    )
     2530
     2531    output_var_table(6) = init_nc_var(                                      &
     2532       name              = 'ls_forcing_north_pt',                           &
     2533       std_name          = "",                                              &
     2534       long_name         = "large-scale forcing for north model boundary for the potential temperature", &
     2535       units             = "K",                                             &
     2536       kind              = "north scalar",                                  &
     2537       input_id          = 1,                                               &
     2538       grid              = scalars_north_grid,                              &
     2539       intermediate_grid = scalars_north_intermediate,                      &
     2540       output_file = output_file                                            &
     2541    )
     2542
     2543    output_var_table(7) = init_nc_var(                                      &
     2544       name              = 'ls_forcing_south_pt',                           &
     2545       std_name          = "",                                              &
     2546       long_name         = "large-scale forcing for south model boundary for the potential temperature", &
     2547       units             = "K",                                             &
     2548       kind              = "south scalar",                                  &
     2549       input_id          = 1,                                               &
     2550       grid              = scalars_south_grid,                              &
     2551       intermediate_grid = scalars_south_intermediate,                      &
     2552       output_file = output_file                                            &
     2553    )
     2554
     2555    output_var_table(8) = init_nc_var(                                      &
     2556       name              = 'ls_forcing_top_pt',                             &
     2557       std_name          = "",                                              &
     2558       long_name         = "large-scale forcing for top model boundary for the potential temperature", &
     2559       units             = "K",                                             &
     2560       kind              = "top scalar",                                    &
     2561       input_id          = 1,                                               &
     2562       grid              = scalars_top_grid,                                &
     2563       intermediate_grid = scalars_top_intermediate,                        &
     2564       output_file = output_file                                            &
     2565    )
     2566
     2567    output_var_table(9) = init_nc_var(                                      &
     2568       name              = 'init_atmosphere_qv',                            &
     2569       std_name          = "",                                              &
     2570       long_name         = "initial specific humidity",                     &
     2571       units             = "kg/kg",                                         &
     2572       kind              = "init scalar",                                   &
     2573       input_id          = 3,                                               &
     2574       output_file       = output_file,                                     &
     2575       grid              = palm_grid,                                       &
     2576       intermediate_grid = palm_intermediate,                               &
     2577       is_profile = (TRIM(ic_mode) == 'profile')                            &
     2578    )
     2579    IF (TRIM(ic_mode) == 'profile')  THEN
     2580       output_var_table(9)%averaging_grid => averaged_initial_scalar_profile
     2581    ENDIF
     2582
     2583    output_var_table(10) = init_nc_var(                                     &
     2584       name              = 'ls_forcing_left_qv',                            &
     2585       std_name          = "",                                              &
     2586       long_name         = "large-scale forcing for left model boundary for the specific humidity", &
     2587       units             = "kg/kg",                                         &
     2588       kind              = "left scalar",                                   &
     2589       input_id          = 3,                                               &
     2590       output_file       = output_file,                                     &
     2591       grid              = scalars_west_grid,                               &
     2592       intermediate_grid = scalars_west_intermediate                        &
     2593    )
     2594
     2595    output_var_table(11) = init_nc_var(                                     &
     2596       name              = 'ls_forcing_right_qv',                           &
     2597       std_name          = "",                                              &
     2598       long_name         = "large-scale forcing for right model boundary for the specific humidity", &
     2599       units             = "kg/kg",                                         &
     2600       kind              = "right scalar",                                  &
     2601       input_id          = 3,                                               &
     2602       output_file       = output_file,                                     &
     2603       grid              = scalars_east_grid,                               &
     2604       intermediate_grid = scalars_east_intermediate                        &
     2605    )
     2606
     2607    output_var_table(12) = init_nc_var(                                     &
     2608       name              = 'ls_forcing_north_qv',                           &
     2609       std_name          = "",                                              &
     2610       long_name         = "large-scale forcing for north model boundary for the specific humidity", &
     2611       units             = "kg/kg",                                         &
     2612       kind              = "north scalar",                                  &
     2613       input_id          = 3,                                               &
     2614       output_file       = output_file,                                     &
     2615       grid              = scalars_north_grid,                              &
     2616       intermediate_grid = scalars_north_intermediate                       &
     2617    )
     2618
     2619    output_var_table(13) = init_nc_var(                                     &
     2620       name              = 'ls_forcing_south_qv',                           &
     2621       std_name          = "",                                              &
     2622       long_name         = "large-scale forcing for south model boundary for the specific humidity", &
     2623       units             = "kg/kg",                                         &
     2624       kind              = "south scalar",                                  &
     2625       input_id          = 3,                                               &
     2626       output_file       = output_file,                                     &
     2627       grid              = scalars_south_grid,                              &
     2628       intermediate_grid = scalars_south_intermediate                       &
     2629    )
     2630
     2631    output_var_table(14) = init_nc_var(                                     &
     2632       name              = 'ls_forcing_top_qv',                             &
     2633       std_name          = "",                                              &
     2634       long_name         = "large-scale forcing for top model boundary for the specific humidity", &
     2635       units             = "kg/kg",                                         &
     2636       kind              = "top scalar",                                    &
     2637       input_id          = 3,                                               &
     2638       output_file       = output_file,                                     &
     2639       grid              = scalars_top_grid,                                &
     2640       intermediate_grid = scalars_top_intermediate                         &
     2641    )
     2642
     2643    output_var_table(15) = init_nc_var(                                     &
     2644       name              = 'init_atmosphere_u',                             &
     2645       std_name          = "",                                              &
     2646       long_name         = "initial wind component in x direction",         &
     2647       units             = "m/s",                                           &
     2648       kind              = "init u",                                        &
     2649       input_id          = 1,                                               & ! first in (U, V) I/O group
     2650       output_file       = output_file,                                     &
     2651       grid              = u_initial_grid,                                  &
     2652       intermediate_grid = u_initial_intermediate,                          &
     2653       is_profile = (TRIM(ic_mode) == 'profile')                            &
     2654    )
     2655    IF (TRIM(ic_mode) == 'profile')  THEN
     2656       output_var_table(15)%averaging_grid => averaged_initial_scalar_profile
     2657    ENDIF
     2658
     2659    output_var_table(16) = init_nc_var(                                     &
     2660       name              = 'ls_forcing_left_u',                             &
     2661       std_name          = "",                                              &
     2662       long_name         = "large-scale forcing for left model boundary for the wind component in x direction", &
     2663       units             = "m/s",                                           &
     2664       kind              = "left u",                                        &
     2665       input_id          = 1,                                               & ! first in (U, V) I/O group
     2666       output_file       = output_file,                                     &
     2667       grid              = u_west_grid,                                     &
     2668       intermediate_grid = u_west_intermediate                              &
     2669    )
     2670
     2671    output_var_table(17) = init_nc_var(                                     &
     2672       name              = 'ls_forcing_right_u',                            &
     2673       std_name          = "",                                              &
     2674       long_name         = "large-scale forcing for right model boundary for the wind component in x direction", &
     2675       units             = "m/s",                                           &
     2676       kind              = "right u",                                       &
     2677       input_id          = 1,                                               & ! first in (U, V) I/O group
     2678       output_file       = output_file,                                     &
     2679       grid              = u_east_grid,                                     &
     2680       intermediate_grid = u_east_intermediate                              &
     2681    )
     2682
     2683    output_var_table(18) = init_nc_var(                                     &
     2684       name              = 'ls_forcing_north_u',                            &
     2685       std_name          = "",                                              &
     2686       long_name         = "large-scale forcing for north model boundary for the wind component in x direction", &
     2687       units             = "m/s",                                           &
     2688       kind              = "north u",                                       &
     2689       input_id          = 1,                                               & ! first in (U, V) I/O group
     2690       output_file       = output_file,                                     &
     2691       grid              = u_north_grid,                                    &
     2692       intermediate_grid = u_north_intermediate                             &
     2693    )
     2694
     2695    output_var_table(19) = init_nc_var(                                     &
     2696       name              = 'ls_forcing_south_u',                            &
     2697       std_name          = "",                                              &
     2698       long_name         = "large-scale forcing for south model boundary for the wind component in x direction", &
     2699       units             = "m/s",                                           &
     2700       kind              = "south u",                                       &
     2701       input_id          = 1,                                               & ! first in (U, V) I/O group
     2702       output_file       = output_file,                                     &
     2703       grid              = u_south_grid,                                    &
     2704       intermediate_grid = u_south_intermediate                             &
     2705    )
     2706
     2707    output_var_table(20) = init_nc_var(                                     &
     2708       name              = 'ls_forcing_top_u',                              &
     2709       std_name          = "",                                              &
     2710       long_name         = "large-scale forcing for top model boundary for the wind component in x direction", &
     2711       units             = "m/s",                                           &
     2712       kind              = "top u",                                         &
     2713       input_id          = 1,                                               & ! first in (U, V) I/O group
     2714       output_file       = output_file,                                     &
     2715       grid              = u_top_grid,                                      &
     2716       intermediate_grid = u_top_intermediate                               &
     2717    )
     2718
     2719    output_var_table(21) = init_nc_var(                                     &
     2720       name              = 'init_atmosphere_v',                             &
     2721       std_name          = "",                                              &
     2722       long_name         = "initial wind component in y direction",         &
     2723       units             = "m/s",                                           &
     2724       kind              = "init v",                                        &
     2725       input_id          = 2,                                               & ! second in (U, V) I/O group
     2726       output_file       = output_file,                                     &
     2727       grid              = v_initial_grid,                                  &
     2728       intermediate_grid = v_initial_intermediate,                          &
     2729       is_profile = (TRIM(ic_mode) == 'profile')                            &
     2730    )
     2731    IF (TRIM(ic_mode) == 'profile')  THEN
     2732       output_var_table(21)%averaging_grid => averaged_initial_scalar_profile
     2733    ENDIF
     2734
     2735    output_var_table(22) = init_nc_var(                                     &
     2736       name              = 'ls_forcing_left_v',                             &
     2737       std_name          = "",                                              &
     2738       long_name         = "large-scale forcing for left model boundary for the wind component in y direction", &
     2739       units             = "m/s",                                           &
     2740       kind              = "right v",                                       &
     2741       input_id          = 2,                                               & ! second in (U, V) I/O group
     2742       output_file       = output_file,                                     &
     2743       grid              = v_west_grid,                                     &
     2744       intermediate_grid = v_west_intermediate                              &
     2745    )
     2746
     2747    output_var_table(23) = init_nc_var(                                     &
     2748       name              = 'ls_forcing_right_v',                            &
     2749       std_name          = "",                                              &
     2750       long_name         = "large-scale forcing for right model boundary for the wind component in y direction", &
     2751       units             = "m/s",                                           &
     2752       kind              = "right v",                                       &
     2753       input_id          = 2,                                               & ! second in (U, V) I/O group
     2754       output_file       = output_file,                                     &
     2755       grid              = v_east_grid,                                     &
     2756       intermediate_grid = v_east_intermediate                              &
     2757    )
     2758
     2759    output_var_table(24) = init_nc_var(                                     &
     2760       name              = 'ls_forcing_north_v',                            &
     2761       std_name          = "",                                              &
     2762       long_name         = "large-scale forcing for north model boundary for the wind component in y direction", &
     2763       units             = "m/s",                                           &
     2764       kind              = "north v",                                       &
     2765       input_id          = 2,                                               & ! second in (U, V) I/O group
     2766       output_file       = output_file,                                     &
     2767       grid              = v_north_grid,                                    &
     2768       intermediate_grid = v_north_intermediate                             &
     2769    )
     2770
     2771    output_var_table(25) = init_nc_var(                                     &
     2772       name              = 'ls_forcing_south_v',                            &
     2773       std_name          = "",                                              &
     2774       long_name         = "large-scale forcing for south model boundary for the wind component in y direction", &
     2775       units             = "m/s",                                           &
     2776       kind              = "south v",                                       &
     2777       input_id          = 2,                                               & ! second in (U, V) I/O group
     2778       output_file       = output_file,                                     &
     2779       grid              = v_south_grid,                                    &
     2780       intermediate_grid = v_south_intermediate                             &
     2781    )
     2782
     2783    output_var_table(26) = init_nc_var(                                     &
     2784       name              = 'ls_forcing_top_v',                              &
     2785       std_name          = "",                                              &
     2786       long_name         = "large-scale forcing for top model boundary for the wind component in y direction", &
     2787       units             = "m/s",                                           &
     2788       kind              = "top v",                                         &
     2789       input_id          = 2,                                               & ! second in (U, V) I/O group
     2790       output_file       = output_file,                                     &
     2791       grid              = v_top_grid,                                      &
     2792       intermediate_grid = v_top_intermediate                               &
     2793    )
     2794
     2795    output_var_table(27) = init_nc_var(                                     &
     2796       name              = 'init_atmosphere_w',                             &
     2797       std_name          = "",                                              &
     2798       long_name         = "initial wind component in z direction",         &
     2799       units             = "m/s",                                           &
     2800       kind              = "init w",                                        &
     2801       input_id          = 1,                                               &
     2802       output_file       = output_file,                                     &
     2803       grid              = w_initial_grid,                                  &
     2804       intermediate_grid = w_initial_intermediate,                          &
     2805       is_profile = (TRIM(ic_mode) == 'profile')                            &
     2806    )
     2807    IF (TRIM(ic_mode) == 'profile')  THEN
     2808       output_var_table(27)%averaging_grid => averaged_initial_w_profile
     2809    ENDIF
     2810
     2811    output_var_table(28) = init_nc_var(                                     &
     2812       name              = 'ls_forcing_left_w',                             &
     2813       std_name          = "",                                              &
     2814       long_name         = "large-scale forcing for left model boundary for the wind component in z direction", &
     2815       units             = "m/s",                                           &
     2816       kind              = "left w",                                        &
     2817       input_id          = 1,                                               &
     2818       output_file       = output_file,                                     &
     2819       grid              = w_west_grid,                                     &
     2820       intermediate_grid = w_west_intermediate                              &
     2821    )
     2822
     2823    output_var_table(29) = init_nc_var(                                     &
     2824       name              = 'ls_forcing_right_w',                            &
     2825       std_name          = "",                                              &
     2826       long_name         = "large-scale forcing for right model boundary for the wind component in z direction", &
     2827       units             = "m/s",                                           &
     2828       kind              = "right w",                                       &
     2829       input_id          = 1,                                               &
     2830       output_file       = output_file,                                     &
     2831       grid              = w_east_grid,                                     &
     2832       intermediate_grid = w_east_intermediate                              &
     2833    )
     2834
     2835    output_var_table(30) = init_nc_var(                                     &
     2836       name              = 'ls_forcing_north_w',                            &
     2837       std_name          = "",                                              &
     2838       long_name         = "large-scale forcing for north model boundary for the wind component in z direction", &
     2839       units             = "m/s",                                           &
     2840       kind              = "north w",                                       &
     2841       input_id          = 1,                                               &
     2842       output_file       = output_file,                                     &
     2843       grid              = w_north_grid,                                    &
     2844       intermediate_grid = w_north_intermediate                             &
     2845    )
     2846
     2847    output_var_table(31) = init_nc_var(                                     &
     2848       name              = 'ls_forcing_south_w',                            &
     2849       std_name          = "",                                              &
     2850       long_name         = "large-scale forcing for south model boundary for the wind component in z direction", &
     2851       units             = "m/s",                                           &
     2852       kind              = "south w",                                       &
     2853       input_id          = 1,                                               &
     2854       output_file       = output_file,                                     &
     2855       grid              = w_south_grid,                                    &
     2856       intermediate_grid = w_south_intermediate                             &
     2857    )
     2858
     2859    output_var_table(32) = init_nc_var(                                     &
     2860       name              = 'ls_forcing_top_w',                              &
     2861       std_name          = "",                                              &
     2862       long_name         = "large-scale forcing for top model boundary for the wind component in z direction", &
     2863       units             = "m/s",                                           &
     2864       kind              = "top w",                                         &
     2865       input_id          = 1,                                               &
     2866       output_file       = output_file,                                     &
     2867       grid              = w_top_grid,                                      &
     2868       intermediate_grid = w_top_intermediate                               &
     2869    )
     2870
     2871    output_var_table(33) = init_nc_var(                                     &
     2872       name              = 'ls_forcing_soil_rain',                          &
     2873       std_name          = "",                                              &
     2874       long_name         = "large-scale forcing rain",                      &
     2875       units             = "kg/m2",                                         &
     2876       kind              = "surface forcing",                               &
     2877       input_id          = 1,                                               &
     2878       output_file       = output_file,                                     &
     2879       grid              = palm_grid,                                       &
     2880       intermediate_grid = palm_intermediate                                &
     2881    )
     2882
     2883    output_var_table(34) = init_nc_var(                                     &
     2884       name              = 'ls_forcing_soil_snow',                          &
     2885       std_name          = "",                                              &
     2886       long_name         = "large-scale forcing snow",                      &
     2887       units             = "kg/m2",                                         &
     2888       kind              = "surface forcing",                               &
     2889       input_id          = 1,                                               &
     2890       output_file       = output_file,                                     &
     2891       grid              = palm_grid,                                       &
     2892       intermediate_grid = palm_intermediate                                &
     2893    )
     2894
     2895    output_var_table(35) = init_nc_var(                                     &
     2896       name              = 'ls_forcing_soil_graupel',                       &
     2897       std_name          = "",                                              &
     2898       long_name         = "large-scale forcing graupel",                   &
     2899       units             = "kg/m2",                                         &
     2900       kind              = "surface forcing",                               &
     2901       input_id          = 1,                                               &
     2902       output_file       = output_file,                                     &
     2903       grid              = palm_grid,                                       &
     2904       intermediate_grid = palm_intermediate                                &
     2905    )
     2906
     2907    output_var_table(36) = init_nc_var(                                     &
     2908       name              = 'ls_forcing_soil_t_2m',                          &
     2909       std_name          = "",                                              &
     2910       long_name         = "large-scale forcing 2m air temperature",        &
     2911       units             = "kg/m2",                                         &
     2912       kind              = "surface forcing",                               &
     2913       input_id          = 1,                                               &
     2914       output_file       = output_file,                                     &
     2915       grid              = palm_grid,                                       &
     2916       intermediate_grid = palm_intermediate                                &
     2917    )
     2918
     2919    output_var_table(37) = init_nc_var(                                     &
     2920       name              = 'ls_forcing_soil_evap',                          &
     2921       std_name          = "",                                              &
     2922       long_name         = "large-scale forcing evapo-transpiration",       &
     2923       units             = "kg/m2",                                         &
     2924       kind              = "surface forcing",                               &
     2925       input_id          = 1,                                               &
     2926       output_file       = output_file,                                     &
     2927       grid              = palm_grid,                                       &
     2928       intermediate_grid = palm_intermediate                                &
     2929    )
     2930
     2931    output_var_table(38) = init_nc_var(                                     &
     2932       name              = 'rad_swd_dif_0',                                 &
     2933       std_name          = "",                                              &
     2934       long_name         = "incoming diffuse shortwave radiative flux at the surface", &
     2935       units             = "W/m2",                                          &
     2936       kind              = "surface forcing",                               &
     2937       input_id          = 1,                                               &
     2938       output_file       = output_file,                                     &
     2939       grid              = palm_grid,                                       &
     2940       intermediate_grid = palm_intermediate                                &
     2941    )
     2942
     2943    output_var_table(39) = init_nc_var(                                     &
     2944       name              = 'rad_swd_dir_0',                                 &
     2945       std_name          = "",                                              &
     2946       long_name         = "incoming direct shortwave radiative flux at the surface", &
     2947       units             = "W/m2",                                          &
     2948       kind              = "surface forcing",                               &
     2949       input_id          = 1,                                               &
     2950       output_file       = output_file,                                     &
     2951       grid              = palm_grid,                                       &
     2952       intermediate_grid = palm_intermediate                                &
     2953    )
     2954
     2955    output_var_table(40) = init_nc_var(                                     &
     2956       name              = 'rad_sw_bal_0',                                  &
     2957       std_name          = "",                                              &
     2958       long_name         = "shortwave radiation balance at the surface",    &
     2959       units             = "W/m2",                                          &
     2960       kind              = "surface forcing",                               &
     2961       input_id          = 1,                                               &
     2962       output_file       = output_file,                                     &
     2963       grid              = palm_grid,                                       &
     2964       intermediate_grid = palm_intermediate                                &
     2965    )
     2966
     2967    output_var_table(41) = init_nc_var(                                     &
     2968       name              = 'rad_lw_bal_0',                                  &
     2969       std_name          = "",                                              &
     2970       long_name         = "longwave radiation balance at the surface",     &
     2971       units             = "W/m2",                                          &
     2972       kind              = "surface forcing",                               &
     2973       input_id          = 1,                                               &
     2974       output_file       = output_file,                                     &
     2975       grid              = palm_grid,                                       &
     2976       intermediate_grid = palm_intermediate                                &
     2977    )
    29592978!
    29602979!------------------------------------------------------------------------------
    29612980! Section 2.2: Idealized large-scale forcings
    29622981!------------------------------------------------------------------------------
    2963        output_var_table(42) = init_nc_var(                                     &
    2964           name              = 'surface_forcing_surface_pressure',              &
    2965           std_name          = "",                                              &
    2966           long_name         = "surface pressure",                              &
    2967           units             = "Pa",                                            &
    2968           kind              = "time series",                                   &
    2969           input_id          = 2,                                               & ! second in (T, p) I/O group
    2970           output_file       = output_file,                                     &
    2971           grid              = palm_grid,                                       &
    2972           intermediate_grid = palm_intermediate                                &
    2973        )
    2974        output_var_table(42) % averaging_grid => averaged_scalar_profile
    2975 
    2976        output_var_table(43) = init_nc_var(                                     &
    2977           name              = 'ls_forcing_ug',                                 &
    2978           std_name          = "",                                              &
    2979           long_name         = "geostrophic wind (u component)",                &
    2980           units             = "m/s",                                           &
    2981           kind              = "geostrophic",                                   &
    2982           input_id          = 1,                                               &
    2983           output_file       = output_file,                                     &
    2984           grid              = averaged_scalar_profile,                         &
    2985           intermediate_grid = averaged_scalar_profile                          &
    2986        )
    2987 
    2988        output_var_table(44) = init_nc_var(                                     &
    2989           name              = 'ls_forcing_vg',                                 &
    2990           std_name          = "",                                              &
    2991           long_name         = "geostrophic wind (v component)",                &
    2992           units             = "m/s",                                           &
    2993           kind              = "geostrophic",                                   &
    2994           input_id          = 1,                                               &
    2995           output_file       = output_file,                                     &
    2996           grid              = averaged_scalar_profile,                         &
    2997           intermediate_grid = averaged_scalar_profile                          &
    2998        )
    2999 
    3000        output_var_table(45) = init_nc_var(                                     &
    3001           name              = 'nudging_u',                                     &
    3002           std_name          = "",                                              &
    3003           long_name         = "wind component in x direction",                 &
    3004           units             = "m/s",                                           &
    3005           kind              = "geostrophic",                                   &
    3006           input_id          = 1,                                               &
    3007           output_file       = output_file,                                     &
    3008           grid              = averaged_scalar_profile,                         &
    3009           intermediate_grid = averaged_scalar_profile                          &
    3010        )
    3011        output_var_table(45) % to_be_processed = ls_forcing_variables_required
    3012 
    3013        output_var_table(46) = init_nc_var(                                     &
    3014           name              = 'nudging_v',                                     &
    3015           std_name          = "",                                              &
    3016           long_name         = "wind component in y direction",                 &
    3017           units             = "m/s",                                           &
    3018           kind              = "large-scale scalar forcing",                    &
    3019           input_id          = 1,                                               &
    3020           output_file       = output_file,                                     &
    3021           grid              = averaged_scalar_profile,                         &
    3022           intermediate_grid = averaged_scalar_profile                          &
    3023        )
    3024        output_var_table(46) % to_be_processed = ls_forcing_variables_required
    3025 
    3026        output_var_table(47) = init_nc_var(                                     &
    3027           name              = 'ls_forcing_sub_w',                              &
    3028           std_name          = "",                                              &
    3029           long_name         = "subsidence velocity of w",                      &
    3030           units             = "m/s",                                           &
    3031           kind              = "large-scale w forcing",                         &
    3032           input_id          = 1,                                               &
    3033           output_file       = output_file,                                     &
    3034           grid              = averaged_scalar_profile,                         &
    3035           intermediate_grid = averaged_scalar_profile                          &
    3036        )
    3037        output_var_table(47) % to_be_processed = ls_forcing_variables_required
    3038 
    3039        output_var_table(48) = init_nc_var(                                     &
    3040           name              = 'nudging_w',                                     &
    3041           std_name          = "",                                              &
    3042           long_name         = "wind component in w direction",                 &
    3043           units             = "m/s",                                           &
    3044           kind              = "large-scale w forcing",                         &
    3045           input_id          = 1,                                               &
    3046           output_file       = output_file,                                     &
    3047           grid              = averaged_w_profile,                              &
    3048           intermediate_grid = averaged_w_profile                               &
    3049        )
    3050        output_var_table(48) % to_be_processed = ls_forcing_variables_required
    3051 
    3052 
    3053        output_var_table(49) = init_nc_var(                                     &
    3054           name              = 'ls_forcing_adv_pt',                             &
    3055           std_name          = "",                                              &
    3056           long_name         = "advection of potential temperature",            &
    3057           units             = "K/s",                                           &
    3058           kind              = "large-scale scalar forcing",                    &
    3059           input_id          = 1,                                               &
    3060           output_file       = output_file,                                     &
    3061           grid              = averaged_scalar_profile,                         &
    3062           intermediate_grid = averaged_scalar_profile                          &
    3063        )
    3064        output_var_table(49) % to_be_processed = ls_forcing_variables_required
    3065 
    3066        output_var_table(50) = init_nc_var(                                     &
    3067           name              = 'ls_forcing_sub_pt',                             &
    3068           std_name          = "",                                              &
    3069           long_name         = "subsidence velocity of potential temperature",  &
    3070           units             = "K/s",                                           &
    3071           kind              = "large-scale scalar forcing",                    &
    3072           input_id          = 1,                                               &
    3073           output_file       = output_file,                                     &
    3074           grid              = averaged_scalar_profile,                         &
    3075           intermediate_grid = averaged_scalar_profile                          &
    3076        )
    3077        output_var_table(50) % to_be_processed = ls_forcing_variables_required
    3078 
    3079        output_var_table(51) = init_nc_var(                                     &
    3080           name              = 'nudging_pt',                                    &
    3081           std_name          = "",                                              &
    3082           long_name         = "potential temperature",                         &
    3083           units             = "K",                                             &
    3084           kind              = "large-scale scalar forcing",                    &
    3085           input_id          = 1,                                               &
    3086           output_file       = output_file,                                     &
    3087           grid              = averaged_scalar_profile,                         &
    3088           intermediate_grid = averaged_scalar_profile                          &
    3089        )
    3090        output_var_table(51) % to_be_processed = ls_forcing_variables_required
    3091 
    3092        output_var_table(52) = init_nc_var(                                     &
    3093           name              = 'ls_forcing_adv_qv',                             &
    3094           std_name          = "",                                              &
    3095           long_name         = "advection of specific humidity",                &
    3096           units             = "kg/kg/s",                                       &
    3097           kind              = "large-scale scalar forcing",                    &
    3098           input_id          = 3,                                               &
    3099           output_file       = output_file,                                     &
    3100           grid              = averaged_scalar_profile,                         &
    3101           intermediate_grid = averaged_scalar_profile                          &
    3102        )
    3103        output_var_table(52) % to_be_processed = ls_forcing_variables_required
    3104 
    3105 
    3106        output_var_table(53) = init_nc_var(                                     &
    3107           name              = 'ls_forcing_sub_qv',                             &
    3108           std_name          = "",                                              &
    3109           long_name         = "subsidence velocity of specific humidity",      &
    3110           units             = "kg/kg/s",                                       &
    3111           kind              = "large-scale scalar forcing",                    &
    3112           input_id          = 3,                                               &
    3113           output_file       = output_file,                                     &
    3114           grid              = averaged_scalar_profile,                         &
    3115           intermediate_grid = averaged_scalar_profile                          &
    3116        )
    3117        output_var_table(53) % to_be_processed = ls_forcing_variables_required
    3118 
    3119        output_var_table(54) = init_nc_var(                                     &
    3120           name              = 'nudging_qv',                                    &
    3121           std_name          = "",                                              &
    3122           long_name         = "specific humidity",                             &
    3123           units             = "kg/kg",                                         &
    3124           kind              = "large-scale scalar forcing",                    &
    3125           input_id          = 3,                                               &
    3126           output_file       = output_file,                                     &
    3127           grid              = averaged_scalar_profile,                         &
    3128           intermediate_grid = averaged_scalar_profile                          &
    3129        )
    3130        output_var_table(54) % to_be_processed = ls_forcing_variables_required
    3131 
    3132        output_var_table(55) = init_nc_var(                                     &
    3133           name              = 'nudging_tau',                                   &
    3134           std_name          = "",                                              &
    3135           long_name         = "nudging relaxation time scale",                 &
    3136           units             = "s",                                             &
    3137           kind              = "constant scalar profile",                       &
    3138           input_id          = 1,                                               &
    3139           output_file       = output_file,                                     &
    3140           grid              = averaged_scalar_profile,                         &
    3141           intermediate_grid = averaged_scalar_profile                          &
    3142        )
    3143        output_var_table(55) % to_be_processed = ls_forcing_variables_required
    3144 
    3145 
    3146        output_var_table(56) = init_nc_var(                                     &
    3147           name              = 'internal_density_centre',                              &
    3148           std_name          = "",                                              &
    3149           long_name         = "",                                              &
    3150           units             = "",                                              &
    3151           kind              = "internal profile",                              &
    3152           input_id          = 4,                                               &
    3153           output_file       = output_file,                                     &
    3154           grid              = averaged_scalar_profile,                         &
    3155           intermediate_grid = averaged_scalar_profile                          &
    3156        )
    3157        output_var_table(56) % averaging_grid => averaged_scalar_profile
    3158 
    3159 
    3160        output_var_table(57) = init_nc_var(                                     &
    3161           name              = 'internal_density_north',                       &
    3162           std_name          = "",                                              &
    3163           long_name         = "",                                              &
    3164           units             = "",                                              &
    3165           kind              = "internal profile",                              &
    3166           input_id          = 4,                                               &
    3167           output_file       = output_file,                                     &
    3168           grid              = north_averaged_scalar_profile,                   &
    3169           intermediate_grid = north_averaged_scalar_profile                    &
    3170        )
    3171        output_var_table(57) % averaging_grid => north_averaged_scalar_profile
    3172        output_var_table(57) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3173 
    3174 
    3175        output_var_table(58) = init_nc_var(                                     &
    3176           name              = 'internal_density_south',                       &
    3177           std_name          = "",                                              &
    3178           long_name         = "",                                              &
    3179           units             = "",                                              &
    3180           kind              = "internal profile",                              &
    3181           input_id          = 4,                                               &
    3182           output_file       = output_file,                                     &
    3183           grid              = south_averaged_scalar_profile,                   &
    3184           intermediate_grid = south_averaged_scalar_profile                    &
    3185        )
    3186        output_var_table(58) % averaging_grid => south_averaged_scalar_profile
    3187        output_var_table(58) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3188 
    3189 
    3190        output_var_table(59) = init_nc_var(                                     &
    3191           name              = 'internal_density_east',                        &
    3192           std_name          = "",                                              &
    3193           long_name         = "",                                              &
    3194           units             = "",                                              &
    3195           kind              = "internal profile",                              &
    3196           input_id          = 4,                                               &
    3197           output_file       = output_file,                                     &
    3198           grid              = east_averaged_scalar_profile,                    &
    3199           intermediate_grid = east_averaged_scalar_profile                     &
    3200        )
    3201        output_var_table(59) % averaging_grid => east_averaged_scalar_profile
    3202        output_var_table(59) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3203 
    3204 
    3205        output_var_table(60) = init_nc_var(                                     &
    3206           name              = 'internal_density_west',                        &
    3207           std_name          = "",                                              &
    3208           long_name         = "",                                              &
    3209           units             = "",                                              &
    3210           kind              = "internal profile",                              &
    3211           input_id          = 4,                                               &
    3212           output_file       = output_file,                                     &
    3213           grid              = west_averaged_scalar_profile,                    &
    3214           intermediate_grid = west_averaged_scalar_profile                     &
    3215        )
    3216        output_var_table(60) % averaging_grid => west_averaged_scalar_profile
    3217        output_var_table(60) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3218 
    3219        output_var_table(61) = init_nc_var(                                     &
    3220           name              = 'internal_pressure_north',                       &
    3221           std_name          = "",                                              &
    3222           long_name         = "",                                              &
    3223           units             = "",                                              &
    3224           kind              = "internal profile",                              &
    3225           input_id          = 2,                                               &
    3226           output_file       = output_file,                                     &
    3227           grid              = north_averaged_scalar_profile,                   &
    3228           intermediate_grid = north_averaged_scalar_profile                    &
    3229        )
    3230        output_var_table(61) % averaging_grid => north_averaged_scalar_profile
    3231        output_var_table(61) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3232 
    3233 
    3234        output_var_table(62) = init_nc_var(                                     &
    3235           name              = 'internal_pressure_south',                       &
    3236           std_name          = "",                                              &
    3237           long_name         = "",                                              &
    3238           units             = "",                                              &
    3239           kind              = "internal profile",                              &
    3240           input_id          = 2,                                               &
    3241           output_file       = output_file,                                     &
    3242           grid              = south_averaged_scalar_profile,                   &
    3243           intermediate_grid = south_averaged_scalar_profile                    &
    3244        )
    3245        output_var_table(62) % averaging_grid => south_averaged_scalar_profile
    3246        output_var_table(62) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3247 
    3248 
    3249        output_var_table(63) = init_nc_var(                                     &
    3250           name              = 'internal_pressure_east',                        &
    3251           std_name          = "",                                              &
    3252           long_name         = "",                                              &
    3253           units             = "",                                              &
    3254           kind              = "internal profile",                              &
    3255           input_id          = 2,                                               &
    3256           output_file       = output_file,                                     &
    3257           grid              = east_averaged_scalar_profile,                    &
    3258           intermediate_grid = east_averaged_scalar_profile                     &
    3259        )
    3260        output_var_table(63) % averaging_grid => east_averaged_scalar_profile
    3261        output_var_table(63) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3262 
    3263 
    3264        output_var_table(64) = init_nc_var(                                     &
    3265           name              = 'internal_pressure_west',                        &
    3266           std_name          = "",                                              &
    3267           long_name         = "",                                              &
    3268           units             = "",                                              &
    3269           kind              = "internal profile",                              &
    3270           input_id          = 2,                                               &
    3271           output_file       = output_file,                                     &
    3272           grid              = west_averaged_scalar_profile,                    &
    3273           intermediate_grid = west_averaged_scalar_profile                     &
    3274        )
    3275        output_var_table(64) % averaging_grid => west_averaged_scalar_profile
    3276        output_var_table(64) % to_be_processed = .NOT. cfg % ug_defined_by_user
    3277 
    3278 !
    3279 !--    Attributes shared among all variables
    3280        output_var_table(:) % source = nc_source_text
    3281 
    3282 
    3283     END SUBROUTINE setup_variable_tables
     2982    output_var_table(42) = init_nc_var(                                     &
     2983       name              = 'surface_forcing_surface_pressure',              &
     2984       std_name          = "",                                              &
     2985       long_name         = "surface pressure",                              &
     2986       units             = "Pa",                                            &
     2987       kind              = "time series",                                   &
     2988       input_id          = 2,                                               & ! second in (T, p) I/O group
     2989       output_file       = output_file,                                     &
     2990       grid              = palm_grid,                                       &
     2991       intermediate_grid = palm_intermediate                                &
     2992    )
     2993    output_var_table(42)%averaging_grid => averaged_scalar_profile
     2994
     2995    output_var_table(43) = init_nc_var(                                     &
     2996       name              = 'ls_forcing_ug',                                 &
     2997       std_name          = "",                                              &
     2998       long_name         = "geostrophic wind (u component)",                &
     2999       units             = "m/s",                                           &
     3000       kind              = "geostrophic",                                   &
     3001       input_id          = 1,                                               &
     3002       output_file       = output_file,                                     &
     3003       grid              = averaged_scalar_profile,                         &
     3004       intermediate_grid = averaged_scalar_profile                          &
     3005    )
     3006
     3007    output_var_table(44) = init_nc_var(                                     &
     3008       name              = 'ls_forcing_vg',                                 &
     3009       std_name          = "",                                              &
     3010       long_name         = "geostrophic wind (v component)",                &
     3011       units             = "m/s",                                           &
     3012       kind              = "geostrophic",                                   &
     3013       input_id          = 1,                                               &
     3014       output_file       = output_file,                                     &
     3015       grid              = averaged_scalar_profile,                         &
     3016       intermediate_grid = averaged_scalar_profile                          &
     3017    )
     3018
     3019    output_var_table(45) = init_nc_var(                                     &
     3020       name              = 'nudging_u',                                     &
     3021       std_name          = "",                                              &
     3022       long_name         = "wind component in x direction",                 &
     3023       units             = "m/s",                                           &
     3024       kind              = "geostrophic",                                   &
     3025       input_id          = 1,                                               &
     3026       output_file       = output_file,                                     &
     3027       grid              = averaged_scalar_profile,                         &
     3028       intermediate_grid = averaged_scalar_profile                          &
     3029    )
     3030    output_var_table(45)%to_be_processed = ls_forcing_variables_required
     3031
     3032    output_var_table(46) = init_nc_var(                                     &
     3033       name              = 'nudging_v',                                     &
     3034       std_name          = "",                                              &
     3035       long_name         = "wind component in y direction",                 &
     3036       units             = "m/s",                                           &
     3037       kind              = "large-scale scalar forcing",                    &
     3038       input_id          = 1,                                               &
     3039       output_file       = output_file,                                     &
     3040       grid              = averaged_scalar_profile,                         &
     3041       intermediate_grid = averaged_scalar_profile                          &
     3042    )
     3043    output_var_table(46)%to_be_processed = ls_forcing_variables_required
     3044
     3045    output_var_table(47) = init_nc_var(                                     &
     3046       name              = 'ls_forcing_sub_w',                              &
     3047       std_name          = "",                                              &
     3048       long_name         = "subsidence velocity of w",                      &
     3049       units             = "m/s",                                           &
     3050       kind              = "large-scale w forcing",                         &
     3051       input_id          = 1,                                               &
     3052       output_file       = output_file,                                     &
     3053       grid              = averaged_scalar_profile,                         &
     3054       intermediate_grid = averaged_scalar_profile                          &
     3055    )
     3056    output_var_table(47)%to_be_processed = ls_forcing_variables_required
     3057
     3058    output_var_table(48) = init_nc_var(                                     &
     3059       name              = 'nudging_w',                                     &
     3060       std_name          = "",                                              &
     3061       long_name         = "wind component in w direction",                 &
     3062       units             = "m/s",                                           &
     3063       kind              = "large-scale w forcing",                         &
     3064       input_id          = 1,                                               &
     3065       output_file       = output_file,                                     &
     3066       grid              = averaged_w_profile,                              &
     3067       intermediate_grid = averaged_w_profile                               &
     3068    )
     3069    output_var_table(48)%to_be_processed = ls_forcing_variables_required
     3070
     3071
     3072    output_var_table(49) = init_nc_var(                                     &
     3073       name              = 'ls_forcing_adv_pt',                             &
     3074       std_name          = "",                                              &
     3075       long_name         = "advection of potential temperature",            &
     3076       units             = "K/s",                                           &
     3077       kind              = "large-scale scalar forcing",                    &
     3078       input_id          = 1,                                               &
     3079       output_file       = output_file,                                     &
     3080       grid              = averaged_scalar_profile,                         &
     3081       intermediate_grid = averaged_scalar_profile                          &
     3082    )
     3083    output_var_table(49)%to_be_processed = ls_forcing_variables_required
     3084
     3085    output_var_table(50) = init_nc_var(                                     &
     3086       name              = 'ls_forcing_sub_pt',                             &
     3087       std_name          = "",                                              &
     3088       long_name         = "subsidence velocity of potential temperature",  &
     3089       units             = "K/s",                                           &
     3090       kind              = "large-scale scalar forcing",                    &
     3091       input_id          = 1,                                               &
     3092       output_file       = output_file,                                     &
     3093       grid              = averaged_scalar_profile,                         &
     3094       intermediate_grid = averaged_scalar_profile                          &
     3095    )
     3096    output_var_table(50)%to_be_processed = ls_forcing_variables_required
     3097
     3098    output_var_table(51) = init_nc_var(                                     &
     3099       name              = 'nudging_pt',                                    &
     3100       std_name          = "",                                              &
     3101       long_name         = "potential temperature",                         &
     3102       units             = "K",                                             &
     3103       kind              = "large-scale scalar forcing",                    &
     3104       input_id          = 1,                                               &
     3105       output_file       = output_file,                                     &
     3106       grid              = averaged_scalar_profile,                         &
     3107       intermediate_grid = averaged_scalar_profile                          &
     3108    )
     3109    output_var_table(51)%to_be_processed = ls_forcing_variables_required
     3110
     3111    output_var_table(52) = init_nc_var(                                     &
     3112       name              = 'ls_forcing_adv_qv',                             &
     3113       std_name          = "",                                              &
     3114       long_name         = "advection of specific humidity",                &
     3115       units             = "kg/kg/s",                                       &
     3116       kind              = "large-scale scalar forcing",                    &
     3117       input_id          = 3,                                               &
     3118       output_file       = output_file,                                     &
     3119       grid              = averaged_scalar_profile,                         &
     3120       intermediate_grid = averaged_scalar_profile                          &
     3121    )
     3122    output_var_table(52)%to_be_processed = ls_forcing_variables_required
     3123
     3124
     3125    output_var_table(53) = init_nc_var(                                     &
     3126       name              = 'ls_forcing_sub_qv',                             &
     3127       std_name          = "",                                              &
     3128       long_name         = "subsidence velocity of specific humidity",      &
     3129       units             = "kg/kg/s",                                       &
     3130       kind              = "large-scale scalar forcing",                    &
     3131       input_id          = 3,                                               &
     3132       output_file       = output_file,                                     &
     3133       grid              = averaged_scalar_profile,                         &
     3134       intermediate_grid = averaged_scalar_profile                          &
     3135    )
     3136    output_var_table(53)%to_be_processed = ls_forcing_variables_required
     3137
     3138    output_var_table(54) = init_nc_var(                                     &
     3139       name              = 'nudging_qv',                                    &
     3140       std_name          = "",                                              &
     3141       long_name         = "specific humidity",                             &
     3142       units             = "kg/kg",                                         &
     3143       kind              = "large-scale scalar forcing",                    &
     3144       input_id          = 3,                                               &
     3145       output_file       = output_file,                                     &
     3146       grid              = averaged_scalar_profile,                         &
     3147       intermediate_grid = averaged_scalar_profile                          &
     3148    )
     3149    output_var_table(54)%to_be_processed = ls_forcing_variables_required
     3150
     3151    output_var_table(55) = init_nc_var(                                     &
     3152       name              = 'nudging_tau',                                   &
     3153       std_name          = "",                                              &
     3154       long_name         = "nudging relaxation time scale",                 &
     3155       units             = "s",                                             &
     3156       kind              = "constant scalar profile",                       &
     3157       input_id          = 1,                                               &
     3158       output_file       = output_file,                                     &
     3159       grid              = averaged_scalar_profile,                         &
     3160       intermediate_grid = averaged_scalar_profile                          &
     3161    )
     3162    output_var_table(55)%to_be_processed = ls_forcing_variables_required
     3163
     3164
     3165    output_var_table(56) = init_nc_var(                                     &
     3166       name              = 'internal_density_centre',                              &
     3167       std_name          = "",                                              &
     3168       long_name         = "",                                              &
     3169       units             = "",                                              &
     3170       kind              = "internal profile",                              &
     3171       input_id          = 4,                                               &
     3172       output_file       = output_file,                                     &
     3173       grid              = averaged_scalar_profile,                         &
     3174       intermediate_grid = averaged_scalar_profile                          &
     3175    )
     3176    output_var_table(56)%averaging_grid => averaged_scalar_profile
     3177
     3178
     3179    output_var_table(57) = init_nc_var(                                     &
     3180       name              = 'internal_density_north',                       &
     3181       std_name          = "",                                              &
     3182       long_name         = "",                                              &
     3183       units             = "",                                              &
     3184       kind              = "internal profile",                              &
     3185       input_id          = 4,                                               &
     3186       output_file       = output_file,                                     &
     3187       grid              = north_averaged_scalar_profile,                   &
     3188       intermediate_grid = north_averaged_scalar_profile                    &
     3189    )
     3190    output_var_table(57)%averaging_grid => north_averaged_scalar_profile
     3191    output_var_table(57)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3192
     3193
     3194    output_var_table(58) = init_nc_var(                                     &
     3195       name              = 'internal_density_south',                       &
     3196       std_name          = "",                                              &
     3197       long_name         = "",                                              &
     3198       units             = "",                                              &
     3199       kind              = "internal profile",                              &
     3200       input_id          = 4,                                               &
     3201       output_file       = output_file,                                     &
     3202       grid              = south_averaged_scalar_profile,                   &
     3203       intermediate_grid = south_averaged_scalar_profile                    &
     3204    )
     3205    output_var_table(58)%averaging_grid => south_averaged_scalar_profile
     3206    output_var_table(58)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3207
     3208
     3209    output_var_table(59) = init_nc_var(                                     &
     3210       name              = 'internal_density_east',                        &
     3211       std_name          = "",                                              &
     3212       long_name         = "",                                              &
     3213       units             = "",                                              &
     3214       kind              = "internal profile",                              &
     3215       input_id          = 4,                                               &
     3216       output_file       = output_file,                                     &
     3217       grid              = east_averaged_scalar_profile,                    &
     3218       intermediate_grid = east_averaged_scalar_profile                     &
     3219    )
     3220    output_var_table(59)%averaging_grid => east_averaged_scalar_profile
     3221    output_var_table(59)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3222
     3223
     3224    output_var_table(60) = init_nc_var(                                     &
     3225       name              = 'internal_density_west',                        &
     3226       std_name          = "",                                              &
     3227       long_name         = "",                                              &
     3228       units             = "",                                              &
     3229       kind              = "internal profile",                              &
     3230       input_id          = 4,                                               &
     3231       output_file       = output_file,                                     &
     3232       grid              = west_averaged_scalar_profile,                    &
     3233       intermediate_grid = west_averaged_scalar_profile                     &
     3234    )
     3235    output_var_table(60)%averaging_grid => west_averaged_scalar_profile
     3236    output_var_table(60)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3237
     3238    output_var_table(61) = init_nc_var(                                     &
     3239       name              = 'internal_pressure_north',                       &
     3240       std_name          = "",                                              &
     3241       long_name         = "",                                              &
     3242       units             = "",                                              &
     3243       kind              = "internal profile",                              &
     3244       input_id          = 2,                                               &
     3245       output_file       = output_file,                                     &
     3246       grid              = north_averaged_scalar_profile,                   &
     3247       intermediate_grid = north_averaged_scalar_profile                    &
     3248    )
     3249    output_var_table(61)%averaging_grid => north_averaged_scalar_profile
     3250    output_var_table(61)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3251
     3252
     3253    output_var_table(62) = init_nc_var(                                     &
     3254       name              = 'internal_pressure_south',                       &
     3255       std_name          = "",                                              &
     3256       long_name         = "",                                              &
     3257       units             = "",                                              &
     3258       kind              = "internal profile",                              &
     3259       input_id          = 2,                                               &
     3260       output_file       = output_file,                                     &
     3261       grid              = south_averaged_scalar_profile,                   &
     3262       intermediate_grid = south_averaged_scalar_profile                    &
     3263    )
     3264    output_var_table(62)%averaging_grid => south_averaged_scalar_profile
     3265    output_var_table(62)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3266
     3267
     3268    output_var_table(63) = init_nc_var(                                     &
     3269       name              = 'internal_pressure_east',                        &
     3270       std_name          = "",                                              &
     3271       long_name         = "",                                              &
     3272       units             = "",                                              &
     3273       kind              = "internal profile",                              &
     3274       input_id          = 2,                                               &
     3275       output_file       = output_file,                                     &
     3276       grid              = east_averaged_scalar_profile,                    &
     3277       intermediate_grid = east_averaged_scalar_profile                     &
     3278    )
     3279    output_var_table(63)%averaging_grid => east_averaged_scalar_profile
     3280    output_var_table(63)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3281
     3282
     3283    output_var_table(64) = init_nc_var(                                     &
     3284       name              = 'internal_pressure_west',                        &
     3285       std_name          = "",                                              &
     3286       long_name         = "",                                              &
     3287       units             = "",                                              &
     3288       kind              = "internal profile",                              &
     3289       input_id          = 2,                                               &
     3290       output_file       = output_file,                                     &
     3291       grid              = west_averaged_scalar_profile,                    &
     3292       intermediate_grid = west_averaged_scalar_profile                     &
     3293    )
     3294    output_var_table(64)%averaging_grid => west_averaged_scalar_profile
     3295    output_var_table(64)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3296
     3297!
     3298!-- Attributes shared among all variables
     3299    output_var_table(:)%source = nc_source_text
     3300
     3301
     3302 END SUBROUTINE setup_variable_tables
    32843303
    32853304
     
    32913310!> 'lod', as defined by the PALM-4U input data standard.
    32923311!------------------------------------------------------------------------------!
    3293     FUNCTION init_nc_var(name, std_name, long_name, units, kind, input_id,     &
    3294                          grid, intermediate_grid, output_file, is_profile)     &
    3295        RESULT(var)
    3296 
    3297        CHARACTER(LEN=*), INTENT(IN)      ::  name, std_name, long_name, units, kind
    3298        INTEGER, INTENT(IN)               ::  input_id
    3299        TYPE(grid_definition), INTENT(IN), TARGET ::  grid, intermediate_grid
    3300        TYPE(nc_file), INTENT(IN)         ::  output_file
    3301        LOGICAL, INTENT(IN), OPTIONAL     ::  is_profile
    3302 
    3303        CHARACTER(LEN=LNAME)              ::  out_var_kind
    3304        TYPE(nc_var)                      ::  var
    3305 
    3306        out_var_kind = TRIM(kind)
    3307 
    3308        IF (PRESENT(is_profile))  THEN
    3309           IF (is_profile)  out_var_kind = TRIM(kind) // ' profile'
    3310        ENDIF
    3311 
    3312        var % name              = name
    3313        var % standard_name     = std_name
    3314        var % long_name         = long_name
    3315        var % units             = units
    3316        var % kind              = TRIM(out_var_kind)
    3317        var % input_id          = input_id
    3318        var % nt                = SIZE (output_file % time)
    3319        var % grid              => grid
    3320        var % intermediate_grid => intermediate_grid
    3321 
    3322        SELECT CASE( TRIM(out_var_kind) )
     3312 FUNCTION init_nc_var(name, std_name, long_name, units, kind, input_id,     &
     3313                      grid, intermediate_grid, output_file, is_profile)     &
     3314    RESULT(var)
     3315
     3316    CHARACTER(LEN=*), INTENT(IN)      ::  name, std_name, long_name, units, kind
     3317    INTEGER, INTENT(IN)               ::  input_id
     3318    TYPE(grid_definition), INTENT(IN), TARGET ::  grid, intermediate_grid
     3319    TYPE(nc_file), INTENT(IN)         ::  output_file
     3320    LOGICAL, INTENT(IN), OPTIONAL     ::  is_profile
     3321
     3322    CHARACTER(LEN=LNAME)              ::  out_var_kind
     3323    TYPE(nc_var)                      ::  var
     3324
     3325    out_var_kind = TRIM(kind)
     3326
     3327    IF (PRESENT(is_profile))  THEN
     3328       IF (is_profile)  out_var_kind = TRIM(kind) // ' profile'
     3329    ENDIF
     3330
     3331    var%name              = name
     3332    var%standard_name     = std_name
     3333    var%long_name         = long_name
     3334    var%units             = units
     3335    var%kind              = TRIM(out_var_kind)
     3336    var%input_id          = input_id
     3337    var%nt                = SIZE (output_file%time)
     3338    var%grid              => grid
     3339    var%intermediate_grid => intermediate_grid
     3340
     3341    SELECT CASE( TRIM(out_var_kind) )
    33233342
    33243343!
     
    33273346!--    TODO: and pass into init_nc_var.
    33283347       CASE( 'init soil' )
    3329           var % nt              = 1
    3330           var % lod             = 2
    3331           var % ndim            = 3
    3332           var % dimids(1:3)     = output_file % dimids_soil
    3333           var % dimvarids(1:3)  = output_file % dimvarids_soil
    3334           var % to_be_processed = init_variables_required
    3335           var % is_internal     = .FALSE.
    3336           var % task            = "interpolate_2d"
     3348          var%nt              = 1
     3349          var%lod             = 2
     3350          var%ndim            = 3
     3351          var%dimids(1:3)     = output_file%dimids_soil
     3352          var%dimvarids(1:3)  = output_file%dimvarids_soil
     3353          var%to_be_processed = init_variables_required
     3354          var%is_internal     = .FALSE.
     3355          var%task            = "interpolate_2d"
    33373356
    33383357       CASE( 'init scalar' )
    3339           var % nt              = 1
    3340           var % lod             = 2
    3341           var % ndim            = 3
    3342           var % dimids(1:3)     = output_file % dimids_scl
    3343           var % dimvarids(1:3)  = output_file % dimvarids_scl
    3344           var % to_be_processed = init_variables_required
    3345           var % is_internal     = .FALSE.
    3346           var % task            = "interpolate_3d"
     3358          var%nt              = 1
     3359          var%lod             = 2
     3360          var%ndim            = 3
     3361          var%dimids(1:3)     = output_file%dimids_scl
     3362          var%dimvarids(1:3)  = output_file%dimvarids_scl
     3363          var%to_be_processed = init_variables_required
     3364          var%is_internal     = .FALSE.
     3365          var%task            = "interpolate_3d"
    33473366
    33483367       CASE( 'init u' )
    3349           var % nt              = 1
    3350           var % lod             = 2
    3351           var % ndim            = 3
    3352           var % dimids(1)       = output_file % dimids_vel(1)
    3353           var % dimids(2)       = output_file % dimids_scl(2)
    3354           var % dimids(3)       = output_file % dimids_scl(3)
    3355           var % dimvarids(1)    = output_file % dimvarids_vel(1)
    3356           var % dimvarids(2)    = output_file % dimvarids_scl(2)
    3357           var % dimvarids(3)    = output_file % dimvarids_scl(3)
    3358           var % to_be_processed = init_variables_required
    3359           var % is_internal     = .FALSE.
    3360           var % task            = "interpolate_3d"
     3368          var%nt              = 1
     3369          var%lod             = 2
     3370          var%ndim            = 3
     3371          var%dimids(1)       = output_file%dimids_vel(1)
     3372          var%dimids(2)       = output_file%dimids_scl(2)
     3373          var%dimids(3)       = output_file%dimids_scl(3)
     3374          var%dimvarids(1)    = output_file%dimvarids_vel(1)
     3375          var%dimvarids(2)    = output_file%dimvarids_scl(2)
     3376          var%dimvarids(3)    = output_file%dimvarids_scl(3)
     3377          var%to_be_processed = init_variables_required
     3378          var%is_internal     = .FALSE.
     3379          var%task            = "interpolate_3d"
    33613380
    33623381       CASE( 'init v' )
    3363           var % nt              = 1
    3364           var % lod             = 2
    3365           var % ndim            = 3
    3366           var % dimids(1)       = output_file % dimids_scl(1)
    3367           var % dimids(2)       = output_file % dimids_vel(2)
    3368           var % dimids(3)       = output_file % dimids_scl(3)
    3369           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3370           var % dimvarids(2)    = output_file % dimvarids_vel(2)
    3371           var % dimvarids(3)    = output_file % dimvarids_scl(3)
    3372           var % to_be_processed = init_variables_required
    3373           var % is_internal     = .FALSE.
    3374           var % task            = "interpolate_3d"
     3382          var%nt              = 1
     3383          var%lod             = 2
     3384          var%ndim            = 3
     3385          var%dimids(1)       = output_file%dimids_scl(1)
     3386          var%dimids(2)       = output_file%dimids_vel(2)
     3387          var%dimids(3)       = output_file%dimids_scl(3)
     3388          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3389          var%dimvarids(2)    = output_file%dimvarids_vel(2)
     3390          var%dimvarids(3)    = output_file%dimvarids_scl(3)
     3391          var%to_be_processed = init_variables_required
     3392          var%is_internal     = .FALSE.
     3393          var%task            = "interpolate_3d"
    33753394
    33763395       CASE( 'init w' )
    3377           var % nt              = 1
    3378           var % lod             = 2
    3379           var % ndim            = 3
    3380           var % dimids(1)       = output_file % dimids_scl(1)
    3381           var % dimids(2)       = output_file % dimids_scl(2)
    3382           var % dimids(3)       = output_file % dimids_vel(3)
    3383           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3384           var % dimvarids(2)    = output_file % dimvarids_scl(2)
    3385           var % dimvarids(3)    = output_file % dimvarids_vel(3)
    3386           var % to_be_processed = init_variables_required
    3387           var % is_internal     = .FALSE.
    3388           var % task            = "interpolate_3d"
     3396          var%nt              = 1
     3397          var%lod             = 2
     3398          var%ndim            = 3
     3399          var%dimids(1)       = output_file%dimids_scl(1)
     3400          var%dimids(2)       = output_file%dimids_scl(2)
     3401          var%dimids(3)       = output_file%dimids_vel(3)
     3402          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3403          var%dimvarids(2)    = output_file%dimvarids_scl(2)
     3404          var%dimvarids(3)    = output_file%dimvarids_vel(3)
     3405          var%to_be_processed = init_variables_required
     3406          var%is_internal     = .FALSE.
     3407          var%task            = "interpolate_3d"
    33893408
    33903409       CASE( 'init scalar profile', 'init u profile', 'init v profile')
    3391           var % nt              = 1
    3392           var % lod             = 1
    3393           var % ndim            = 1
    3394           var % dimids(1)       = output_file % dimids_scl(3)    !z
    3395           var % dimvarids(1)    = output_file % dimvarids_scl(3) !z
    3396           var % to_be_processed = init_variables_required
    3397           var % is_internal     = .FALSE.
    3398           var % task            = "average profile"
     3410          var%nt              = 1
     3411          var%lod             = 1
     3412          var%ndim            = 1
     3413          var%dimids(1)       = output_file%dimids_scl(3)    !z
     3414          var%dimvarids(1)    = output_file%dimvarids_scl(3) !z
     3415          var%to_be_processed = init_variables_required
     3416          var%is_internal     = .FALSE.
     3417          var%task            = "average profile"
    33993418
    34003419       CASE( 'init w profile')
    3401           var % nt              = 1
    3402           var % lod             = 1
    3403           var % ndim            = 1
    3404           var % dimids(1)       = output_file % dimids_vel(3)    !z
    3405           var % dimvarids(1)    = output_file % dimvarids_vel(3) !z
    3406           var % to_be_processed = init_variables_required
    3407           var % is_internal     = .FALSE.
    3408           var % task            = "average profile"
     3420          var%nt              = 1
     3421          var%lod             = 1
     3422          var%ndim            = 1
     3423          var%dimids(1)       = output_file%dimids_vel(3)    !z
     3424          var%dimvarids(1)    = output_file%dimvarids_vel(3) !z
     3425          var%to_be_processed = init_variables_required
     3426          var%is_internal     = .FALSE.
     3427          var%task            = "average profile"
    34093428
    34103429       CASE( 'surface forcing' )
    3411           var % lod             = -1
    3412           var % ndim            = 3
    3413           var % dimids(3)       = output_file % dimid_time
    3414           var % dimids(1:2)     = output_file % dimids_soil(1:2)
    3415           var % dimvarids(3)    = output_file % dimvarid_time
    3416           var % dimvarids(1:2)  = output_file % dimvarids_soil(1:2)
    3417           var % to_be_processed = surface_forcing_required
    3418           var % is_internal     = .FALSE.
    3419           var % task            = "interpolate_2d"
     3430          var%lod             = -1
     3431          var%ndim            = 3
     3432          var%dimids(3)       = output_file%dimid_time
     3433          var%dimids(1:2)     = output_file%dimids_soil(1:2)
     3434          var%dimvarids(3)    = output_file%dimvarid_time
     3435          var%dimvarids(1:2)  = output_file%dimvarids_soil(1:2)
     3436          var%to_be_processed = surface_forcing_required
     3437          var%is_internal     = .FALSE.
     3438          var%task            = "interpolate_2d"
    34203439
    34213440       CASE( 'left scalar', 'right scalar')
    3422           var % lod             = -1
    3423           var % ndim            = 3
    3424           var % dimids(3)       = output_file % dimid_time
    3425           var % dimids(1)       = output_file % dimids_scl(2)
    3426           var % dimids(2)       = output_file % dimids_scl(3)
    3427           var % dimvarids(3)    = output_file % dimvarid_time
    3428           var % dimvarids(1)    = output_file % dimvarids_scl(2)
    3429           var % dimvarids(2)    = output_file % dimvarids_scl(3)
    3430           var % to_be_processed = boundary_variables_required
    3431           var % is_internal     = .FALSE.
    3432           var % task            = "interpolate_3d"
     3441          var%lod             = -1
     3442          var%ndim            = 3
     3443          var%dimids(3)       = output_file%dimid_time
     3444          var%dimids(1)       = output_file%dimids_scl(2)
     3445          var%dimids(2)       = output_file%dimids_scl(3)
     3446          var%dimvarids(3)    = output_file%dimvarid_time
     3447          var%dimvarids(1)    = output_file%dimvarids_scl(2)
     3448          var%dimvarids(2)    = output_file%dimvarids_scl(3)
     3449          var%to_be_processed = boundary_variables_required
     3450          var%is_internal     = .FALSE.
     3451          var%task            = "interpolate_3d"
    34333452
    34343453       CASE( 'north scalar', 'south scalar')
    3435           var % lod             = -1
    3436           var % ndim            = 3
    3437           var % dimids(3)       = output_file % dimid_time
    3438           var % dimids(1)       = output_file % dimids_scl(1)
    3439           var % dimids(2)       = output_file % dimids_scl(3)
    3440           var % dimvarids(3)    = output_file % dimvarid_time
    3441           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3442           var % dimvarids(2)    = output_file % dimvarids_scl(3)
    3443           var % to_be_processed = boundary_variables_required
    3444           var % is_internal     = .FALSE.
    3445           var % task            = "interpolate_3d"
     3454          var%lod             = -1
     3455          var%ndim            = 3
     3456          var%dimids(3)       = output_file%dimid_time
     3457          var%dimids(1)       = output_file%dimids_scl(1)
     3458          var%dimids(2)       = output_file%dimids_scl(3)
     3459          var%dimvarids(3)    = output_file%dimvarid_time
     3460          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3461          var%dimvarids(2)    = output_file%dimvarids_scl(3)
     3462          var%to_be_processed = boundary_variables_required
     3463          var%is_internal     = .FALSE.
     3464          var%task            = "interpolate_3d"
    34463465
    34473466       CASE( 'top scalar', 'top w' )
    3448           var % lod             = -1
    3449           var % ndim            = 3
    3450           var % dimids(3)       = output_file % dimid_time
    3451           var % dimids(1)       = output_file % dimids_scl(1)
    3452           var % dimids(2)       = output_file % dimids_scl(2)
    3453           var % dimvarids(3)    = output_file % dimvarid_time
    3454           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3455           var % dimvarids(2)    = output_file % dimvarids_scl(2)
    3456           var % to_be_processed = boundary_variables_required
    3457           var % is_internal     = .FALSE.
    3458           var % task            = "interpolate_3d"
     3467          var%lod             = -1
     3468          var%ndim            = 3
     3469          var%dimids(3)       = output_file%dimid_time
     3470          var%dimids(1)       = output_file%dimids_scl(1)
     3471          var%dimids(2)       = output_file%dimids_scl(2)
     3472          var%dimvarids(3)    = output_file%dimvarid_time
     3473          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3474          var%dimvarids(2)    = output_file%dimvarids_scl(2)
     3475          var%to_be_processed = boundary_variables_required
     3476          var%is_internal     = .FALSE.
     3477          var%task            = "interpolate_3d"
    34593478
    34603479       CASE( 'left u', 'right u' )
    3461           var % lod             = -1
    3462           var % ndim            = 3
    3463           var % dimids(3)       = output_file % dimid_time
    3464           var % dimids(1)       = output_file % dimids_scl(2)
    3465           var % dimids(2)       = output_file % dimids_scl(3)
    3466           var % dimvarids(3)    = output_file % dimvarid_time
    3467           var % dimvarids(1)    = output_file % dimvarids_scl(2)
    3468           var % dimvarids(2)    = output_file % dimvarids_scl(3)
    3469           var % to_be_processed = boundary_variables_required
    3470           var % is_internal     = .FALSE.
    3471           var % task            = "interpolate_3d"
     3480          var%lod             = -1
     3481          var%ndim            = 3
     3482          var%dimids(3)       = output_file%dimid_time
     3483          var%dimids(1)       = output_file%dimids_scl(2)
     3484          var%dimids(2)       = output_file%dimids_scl(3)
     3485          var%dimvarids(3)    = output_file%dimvarid_time
     3486          var%dimvarids(1)    = output_file%dimvarids_scl(2)
     3487          var%dimvarids(2)    = output_file%dimvarids_scl(3)
     3488          var%to_be_processed = boundary_variables_required
     3489          var%is_internal     = .FALSE.
     3490          var%task            = "interpolate_3d"
    34723491
    34733492       CASE( 'north u', 'south u' )
    3474           var % lod             = -1
    3475           var % ndim            = 3
    3476           var % dimids(3)       = output_file % dimid_time    !t
    3477           var % dimids(1)       = output_file % dimids_vel(1) !x
    3478           var % dimids(2)       = output_file % dimids_scl(3) !z
    3479           var % dimvarids(3)    = output_file % dimvarid_time
    3480           var % dimvarids(1)    = output_file % dimvarids_vel(1)
    3481           var % dimvarids(2)    = output_file % dimvarids_scl(3)
    3482           var % to_be_processed = boundary_variables_required
    3483           var % is_internal     = .FALSE.
    3484           var % task            = "interpolate_3d"
     3493          var%lod             = -1
     3494          var%ndim            = 3
     3495          var%dimids(3)       = output_file%dimid_time    !t
     3496          var%dimids(1)       = output_file%dimids_vel(1) !x
     3497          var%dimids(2)       = output_file%dimids_scl(3) !z
     3498          var%dimvarids(3)    = output_file%dimvarid_time
     3499          var%dimvarids(1)    = output_file%dimvarids_vel(1)
     3500          var%dimvarids(2)    = output_file%dimvarids_scl(3)
     3501          var%to_be_processed = boundary_variables_required
     3502          var%is_internal     = .FALSE.
     3503          var%task            = "interpolate_3d"
    34853504
    34863505       CASE( 'top u' )
    3487           var % lod             = -1
    3488           var % ndim            = 3
    3489           var % dimids(3)       = output_file % dimid_time    !t
    3490           var % dimids(1)       = output_file % dimids_vel(1) !x
    3491           var % dimids(2)       = output_file % dimids_scl(2) !z
    3492           var % dimvarids(3)    = output_file % dimvarid_time
    3493           var % dimvarids(1)    = output_file % dimvarids_vel(1)
    3494           var % dimvarids(2)    = output_file % dimvarids_scl(2)
    3495           var % to_be_processed = boundary_variables_required
    3496           var % is_internal     = .FALSE.
    3497           var % task            = "interpolate_3d"
     3506          var%lod             = -1
     3507          var%ndim            = 3
     3508          var%dimids(3)       = output_file%dimid_time    !t
     3509          var%dimids(1)       = output_file%dimids_vel(1) !x
     3510          var%dimids(2)       = output_file%dimids_scl(2) !z
     3511          var%dimvarids(3)    = output_file%dimvarid_time
     3512          var%dimvarids(1)    = output_file%dimvarids_vel(1)
     3513          var%dimvarids(2)    = output_file%dimvarids_scl(2)
     3514          var%to_be_processed = boundary_variables_required
     3515          var%is_internal     = .FALSE.
     3516          var%task            = "interpolate_3d"
    34983517
    34993518       CASE( 'left v', 'right v' )
    3500           var % lod             = -1
    3501           var % ndim            = 3
    3502           var % dimids(3)       = output_file % dimid_time
    3503           var % dimids(1)       = output_file % dimids_vel(2)
    3504           var % dimids(2)       = output_file % dimids_scl(3)
    3505           var % dimvarids(3)    = output_file % dimvarid_time
    3506           var % dimvarids(1)    = output_file % dimvarids_vel(2)
    3507           var % dimvarids(2)    = output_file % dimvarids_scl(3)
    3508           var % to_be_processed = boundary_variables_required
    3509           var % is_internal     = .FALSE.
    3510           var % task            = "interpolate_3d"
     3519          var%lod             = -1
     3520          var%ndim            = 3
     3521          var%dimids(3)       = output_file%dimid_time
     3522          var%dimids(1)       = output_file%dimids_vel(2)
     3523          var%dimids(2)       = output_file%dimids_scl(3)
     3524          var%dimvarids(3)    = output_file%dimvarid_time
     3525          var%dimvarids(1)    = output_file%dimvarids_vel(2)
     3526          var%dimvarids(2)    = output_file%dimvarids_scl(3)
     3527          var%to_be_processed = boundary_variables_required
     3528          var%is_internal     = .FALSE.
     3529          var%task            = "interpolate_3d"
    35113530
    35123531       CASE( 'north v', 'south v' )
    3513           var % lod             = -1
    3514           var % ndim            = 3
    3515           var % dimids(3)       = output_file % dimid_time    !t
    3516           var % dimids(1)       = output_file % dimids_scl(1) !x
    3517           var % dimids(2)       = output_file % dimids_scl(3) !z
    3518           var % dimvarids(3)    = output_file % dimvarid_time
    3519           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3520           var % dimvarids(2)    = output_file % dimvarids_scl(3)
    3521           var % to_be_processed = boundary_variables_required
    3522           var % is_internal     = .FALSE.
    3523           var % task            = "interpolate_3d"
     3532          var%lod             = -1
     3533          var%ndim            = 3
     3534          var%dimids(3)       = output_file%dimid_time    !t
     3535          var%dimids(1)       = output_file%dimids_scl(1) !x
     3536          var%dimids(2)       = output_file%dimids_scl(3) !z
     3537          var%dimvarids(3)    = output_file%dimvarid_time
     3538          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3539          var%dimvarids(2)    = output_file%dimvarids_scl(3)
     3540          var%to_be_processed = boundary_variables_required
     3541          var%is_internal     = .FALSE.
     3542          var%task            = "interpolate_3d"
    35243543
    35253544       CASE( 'top v' )
    3526           var % lod             = -1
    3527           var % ndim            = 3
    3528           var % dimids(3)       = output_file % dimid_time    !t
    3529           var % dimids(1)       = output_file % dimids_scl(1) !x
    3530           var % dimids(2)       = output_file % dimids_vel(2) !z
    3531           var % dimvarids(3)    = output_file % dimvarid_time
    3532           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3533           var % dimvarids(2)    = output_file % dimvarids_vel(2)
    3534           var % to_be_processed = boundary_variables_required
    3535           var % is_internal     = .FALSE.
    3536           var % task            = "interpolate_3d"
     3545          var%lod             = -1
     3546          var%ndim            = 3
     3547          var%dimids(3)       = output_file%dimid_time    !t
     3548          var%dimids(1)       = output_file%dimids_scl(1) !x
     3549          var%dimids(2)       = output_file%dimids_vel(2) !z
     3550          var%dimvarids(3)    = output_file%dimvarid_time
     3551          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3552          var%dimvarids(2)    = output_file%dimvarids_vel(2)
     3553          var%to_be_processed = boundary_variables_required
     3554          var%is_internal     = .FALSE.
     3555          var%task            = "interpolate_3d"
    35373556
    35383557       CASE( 'left w', 'right w')
    3539           var % lod             = -1
    3540           var % ndim            = 3
    3541           var % dimids(3)       = output_file % dimid_time
    3542           var % dimids(1)       = output_file % dimids_scl(2)
    3543           var % dimids(2)       = output_file % dimids_vel(3)
    3544           var % dimvarids(3)    = output_file % dimvarid_time
    3545           var % dimvarids(1)    = output_file % dimvarids_scl(2)
    3546           var % dimvarids(2)    = output_file % dimvarids_vel(3)
    3547           var % to_be_processed = boundary_variables_required
    3548           var % is_internal     = .FALSE.
    3549           var % task            = "interpolate_3d"
     3558          var%lod             = -1
     3559          var%ndim            = 3
     3560          var%dimids(3)       = output_file%dimid_time
     3561          var%dimids(1)       = output_file%dimids_scl(2)
     3562          var%dimids(2)       = output_file%dimids_vel(3)
     3563          var%dimvarids(3)    = output_file%dimvarid_time
     3564          var%dimvarids(1)    = output_file%dimvarids_scl(2)
     3565          var%dimvarids(2)    = output_file%dimvarids_vel(3)
     3566          var%to_be_processed = boundary_variables_required
     3567          var%is_internal     = .FALSE.
     3568          var%task            = "interpolate_3d"
    35503569
    35513570       CASE( 'north w', 'south w' )
    3552           var % lod             = -1
    3553           var % ndim            = 3
    3554           var % dimids(3)       = output_file % dimid_time    !t
    3555           var % dimids(1)       = output_file % dimids_scl(1) !x
    3556           var % dimids(2)       = output_file % dimids_vel(3) !z
    3557           var % dimvarids(3)    = output_file % dimvarid_time
    3558           var % dimvarids(1)    = output_file % dimvarids_scl(1)
    3559           var % dimvarids(2)    = output_file % dimvarids_vel(3)
    3560           var % to_be_processed = boundary_variables_required
    3561           var % is_internal     = .FALSE.
    3562           var % task            = "interpolate_3d"
     3571          var%lod             = -1
     3572          var%ndim            = 3
     3573          var%dimids(3)       = output_file%dimid_time    !t
     3574          var%dimids(1)       = output_file%dimids_scl(1) !x
     3575          var%dimids(2)       = output_file%dimids_vel(3) !z
     3576          var%dimvarids(3)    = output_file%dimvarid_time
     3577          var%dimvarids(1)    = output_file%dimvarids_scl(1)
     3578          var%dimvarids(2)    = output_file%dimvarids_vel(3)
     3579          var%to_be_processed = boundary_variables_required
     3580          var%is_internal     = .FALSE.
     3581          var%task            = "interpolate_3d"
    35633582
    35643583       CASE( 'time series' )
    3565           var % lod             = 0
    3566           var % ndim            = 1
    3567           var % dimids(1)       = output_file % dimid_time    !t
    3568           var % dimvarids(1)    = output_file % dimvarid_time
    3569           var % to_be_processed = .TRUE.
    3570           var % is_internal     = .FALSE.
    3571           var % task            = "average profile"
     3584          var%lod             = 0
     3585          var%ndim            = 1
     3586          var%dimids(1)       = output_file%dimid_time    !t
     3587          var%dimvarids(1)    = output_file%dimvarid_time
     3588          var%to_be_processed = .TRUE.
     3589          var%is_internal     = .FALSE.
     3590          var%task            = "average profile"
    35723591
    35733592       CASE( 'constant scalar profile' )
    3574           var % lod             = -1
    3575           var % ndim            = 2
    3576           var % dimids(2)       = output_file % dimid_time    !t
    3577           var % dimids(1)       = output_file % dimids_scl(3) !z
    3578           var % dimvarids(2)    = output_file % dimvarid_time
    3579           var % dimvarids(1)    = output_file % dimvarids_scl(3)
    3580           var % to_be_processed = .TRUE.
    3581           var % is_internal     = .FALSE.
    3582           var % task            = "set profile"
     3593          var%lod             = -1
     3594          var%ndim            = 2
     3595          var%dimids(2)       = output_file%dimid_time    !t
     3596          var%dimids(1)       = output_file%dimids_scl(3) !z
     3597          var%dimvarids(2)    = output_file%dimvarid_time
     3598          var%dimvarids(1)    = output_file%dimvarids_scl(3)
     3599          var%to_be_processed = .TRUE.
     3600          var%is_internal     = .FALSE.
     3601          var%task            = "set profile"
    35833602
    35843603       CASE( 'large-scale scalar forcing' )
    3585           var % lod             = -1
    3586           var % ndim            = 2
    3587           var % dimids(2)       = output_file % dimid_time    !t
    3588           var % dimids(1)       = output_file % dimids_scl(3) !z
    3589           var % dimvarids(2)    = output_file % dimvarid_time
    3590           var % dimvarids(1)    = output_file % dimvarids_scl(3)
    3591           var % to_be_processed = ls_forcing_variables_required
    3592           var % is_internal     = .FALSE.
    3593           var % task            = "average large-scale profile"
     3604          var%lod             = -1
     3605          var%ndim            = 2
     3606          var%dimids(2)       = output_file%dimid_time    !t
     3607          var%dimids(1)       = output_file%dimids_scl(3) !z
     3608          var%dimvarids(2)    = output_file%dimvarid_time
     3609          var%dimvarids(1)    = output_file%dimvarids_scl(3)
     3610          var%to_be_processed = ls_forcing_variables_required
     3611          var%is_internal     = .FALSE.
     3612          var%task            = "average large-scale profile"
    35943613
    35953614       CASE( 'geostrophic' )
    3596           var % lod             = -1
    3597           var % ndim            = 2
    3598           var % dimids(2)       = output_file % dimid_time    !t
    3599           var % dimids(1)       = output_file % dimids_scl(3) !z
    3600           var % dimvarids(2)    = output_file % dimvarid_time
    3601           var % dimvarids(1)    = output_file % dimvarids_scl(3)
    3602           var % to_be_processed = .TRUE.
    3603           var % is_internal     = .FALSE.
    3604           var % task            = "geostrophic winds"
     3615          var%lod             = -1
     3616          var%ndim            = 2
     3617          var%dimids(2)       = output_file%dimid_time    !t
     3618          var%dimids(1)       = output_file%dimids_scl(3) !z
     3619          var%dimvarids(2)    = output_file%dimvarid_time
     3620          var%dimvarids(1)    = output_file%dimvarids_scl(3)
     3621          var%to_be_processed = .TRUE.
     3622          var%is_internal     = .FALSE.
     3623          var%task            = "geostrophic winds"
    36053624
    36063625       CASE( 'large-scale w forcing' )
    3607           var % lod             = -1
    3608           var % ndim            = 2
    3609           var % dimids(2)       = output_file % dimid_time    !t
    3610           var % dimids(1)       = output_file % dimids_vel(3) !z
    3611           var % dimvarids(2)    = output_file % dimvarid_time
    3612           var % dimvarids(1)    = output_file % dimvarids_vel(3)
    3613           var % to_be_processed = ls_forcing_variables_required
    3614           var % is_internal     = .FALSE.
    3615           var % task            = "average large-scale profile"
     3626          var%lod             = -1
     3627          var%ndim            = 2
     3628          var%dimids(2)       = output_file%dimid_time    !t
     3629          var%dimids(1)       = output_file%dimids_vel(3) !z
     3630          var%dimvarids(2)    = output_file%dimvarid_time
     3631          var%dimvarids(1)    = output_file%dimvarids_vel(3)
     3632          var%to_be_processed = ls_forcing_variables_required
     3633          var%is_internal     = .FALSE.
     3634          var%task            = "average large-scale profile"
    36163635
    36173636       CASE( 'internal profile' )
    3618           var % lod             = -1
    3619           var % ndim            = 2
    3620           var % dimids(2)       = output_file % dimid_time    !t
    3621           var % dimids(1)       = output_file % dimids_scl(3) !z
    3622           var % dimvarids(2)    = output_file % dimvarid_time
    3623           var % dimvarids(1)    = output_file % dimvarids_scl(3)
    3624           var % to_be_processed = .TRUE.
    3625           var % is_internal     = .TRUE.
    3626           var % task            = "internal profile"
     3637          var%lod             = -1
     3638          var%ndim            = 2
     3639          var%dimids(2)       = output_file%dimid_time    !t
     3640          var%dimids(1)       = output_file%dimids_scl(3) !z
     3641          var%dimvarids(2)    = output_file%dimvarid_time
     3642          var%dimvarids(1)    = output_file%dimvarids_scl(3)
     3643          var%to_be_processed = .TRUE.
     3644          var%is_internal     = .TRUE.
     3645          var%task            = "internal profile"
    36273646
    36283647       CASE DEFAULT
     
    36303649           CALL inifor_abort ('init_nc_var', message)
    36313650
    3632        END SELECT
    3633 
    3634     END FUNCTION init_nc_var
    3635 
    3636 
    3637     SUBROUTINE fini_variables()
    3638 
    3639        CALL report('fini_variables', 'Deallocating variable table', cfg % debug)
    3640        DEALLOCATE( input_var_table )
    3641 
    3642     END SUBROUTINE fini_variables
    3643 
    3644 
    3645     SUBROUTINE fini_io_groups()
    3646 
    3647        CALL report('fini_io_groups', 'Deallocating IO groups', cfg % debug)
    3648        DEALLOCATE( io_group_list )
    3649 
    3650     END SUBROUTINE fini_io_groups
    3651 
    3652 
    3653     SUBROUTINE fini_file_lists()
    3654        
    3655        CALL report('fini_file_lists', 'Deallocating file lists', cfg % debug)
    3656        DEALLOCATE( flow_files, soil_files, radiation_files, soil_moisture_files )
    3657 
    3658     END SUBROUTINE fini_file_lists
     3651    END SELECT
     3652
     3653 END FUNCTION init_nc_var
     3654
     3655
     3656 SUBROUTINE fini_variables()
     3657
     3658    CALL report('fini_variables', 'Deallocating variable table', cfg%debug)
     3659    DEALLOCATE( input_var_table )
     3660
     3661 END SUBROUTINE fini_variables
     3662
     3663
     3664 SUBROUTINE fini_io_groups()
     3665
     3666    CALL report('fini_io_groups', 'Deallocating IO groups', cfg%debug)
     3667    DEALLOCATE( io_group_list )
     3668
     3669 END SUBROUTINE fini_io_groups
     3670
     3671
     3672 SUBROUTINE fini_file_lists()
     3673   
     3674    CALL report('fini_file_lists', 'Deallocating file lists', cfg%debug)
     3675    DEALLOCATE( flow_files, soil_files, radiation_files, soil_moisture_files )
     3676
     3677 END SUBROUTINE fini_file_lists
    36593678
    36603679
     
    36703689!> array will match a COSMO-DE scalar array.
    36713690!------------------------------------------------------------------------------!
    3672     SUBROUTINE preprocess(group, input_buffer, cosmo_grid, iter)
    3673 
    3674        TYPE(io_group), INTENT(INOUT), TARGET       ::  group
    3675        TYPE(container), INTENT(INOUT), ALLOCATABLE ::  input_buffer(:)
    3676        TYPE(grid_definition), INTENT(IN)           ::  cosmo_grid
    3677        INTEGER, INTENT(IN)                         ::  iter
    3678        
    3679        REAL(dp), ALLOCATABLE                       ::  basic_state_pressure(:)
    3680        TYPE(container), ALLOCATABLE                ::  preprocess_buffer(:)
    3681        INTEGER                                     ::  hour, dt
    3682        INTEGER                                     ::  i, j, k
    3683        INTEGER                                     ::  nx, ny, nz
    3684        
    3685        input_buffer(:) % is_preprocessed = .FALSE.
    3686         
    3687        SELECT CASE( group % kind )
     3691 SUBROUTINE preprocess(group, input_buffer, cosmo_grid, iter)
     3692
     3693    TYPE(io_group), INTENT(INOUT), TARGET       ::  group
     3694    TYPE(container), INTENT(INOUT), ALLOCATABLE ::  input_buffer(:)
     3695    TYPE(grid_definition), INTENT(IN)           ::  cosmo_grid
     3696    INTEGER, INTENT(IN)                         ::  iter
     3697   
     3698    REAL(wp), ALLOCATABLE                       ::  basic_state_pressure(:)
     3699    TYPE(container), ALLOCATABLE                ::  preprocess_buffer(:)
     3700    INTEGER                                     ::  hour, dt
     3701    INTEGER                                     ::  i, j, k
     3702    INTEGER                                     ::  nx, ny, nz
     3703   
     3704    input_buffer(:)%is_preprocessed = .FALSE.
     3705     
     3706    SELECT CASE( group%kind )
    36883707       
    36893708       CASE( 'velocities' )
     
    36943713!
    36953714!--       Allocate u and v arrays with scalar dimensions
    3696           nx = SIZE(input_buffer(1) % array, 1)
    3697           ny = SIZE(input_buffer(1) % array, 2)
    3698           nz = SIZE(input_buffer(1) % array, 3)
    3699           ALLOCATE( preprocess_buffer(1) % array(nx, ny, nz) ) ! u buffer
    3700           ALLOCATE( preprocess_buffer(2) % array(nx, ny, nz) ) ! v buffer
    3701 
    3702  CALL run_control('time', 'alloc')
     3715          nx = SIZE(input_buffer(1)%array, 1)
     3716          ny = SIZE(input_buffer(1)%array, 2)
     3717          nz = SIZE(input_buffer(1)%array, 3)
     3718          ALLOCATE( preprocess_buffer(1)%array(nx, ny, nz) ) ! u buffer
     3719          ALLOCATE( preprocess_buffer(2)%array(nx, ny, nz) ) ! v buffer
     3720
     3721          CALL log_runtime('time', 'alloc')
    37033722
    37043723!
    37053724!--       interpolate U and V to centres
    3706           CALL centre_velocities( u_face = input_buffer(1) % array,            &
    3707                                   v_face = input_buffer(2) % array,            &
    3708                                   u_centre = preprocess_buffer(1) % array,     &
    3709                                   v_centre = preprocess_buffer(2) % array )
     3725          CALL centre_velocities( u_face = input_buffer(1)%array,            &
     3726                                  v_face = input_buffer(2)%array,            &
     3727                                  u_centre = preprocess_buffer(1)%array,     &
     3728                                  v_centre = preprocess_buffer(2)%array )
    37103729         
    3711           cfg % rotation_method = 'rotated-pole'
    3712           SELECT CASE(cfg % rotation_method)
    3713 
    3714           CASE('rotated-pole')
    3715 !
    3716 !--          rotate U and V to PALM-4U orientation and overwrite U and V with
    3717 !--          rotated velocities
    3718              DO k = 1, nz
    3719              DO j = 1, ny
    3720              DO i = 1, nx
    3721                 CALL uv2uvrot( urot = preprocess_buffer(1) % array(i,j,k),     &
    3722                                vrot = preprocess_buffer(2) % array(i,j,k),     &
    3723                                rlat = cosmo_grid % lat(j-1),                   &
    3724                                rlon = cosmo_grid % lon(i-1),                   &
    3725                                pollat = phi_cn,                                &
    3726                                pollon = lambda_cn,                             &
    3727                                u = input_buffer(1) % array(i,j,k),             &
    3728                                v = input_buffer(2) % array(i,j,k) )
    3729              ENDDO
    3730              ENDDO
    3731              ENDDO
    3732 
    3733           CASE DEFAULT
    3734              message = "Rotation method '" // TRIM(cfg % rotation_method) //   &
    3735                 "' not recognized."
    3736              CALL inifor_abort('preprocess', message)
     3730          cfg%rotation_method = 'rotated-pole'
     3731          SELECT CASE(cfg%rotation_method)
     3732
     3733             CASE('rotated-pole')
     3734!           
     3735!--             rotate U and V to PALM-4U orientation and overwrite U and V with
     3736!--             rotated velocities
     3737                DO k = 1, nz
     3738                DO j = 1, ny
     3739                DO i = 1, nx
     3740                   CALL uv2uvrot( urot = preprocess_buffer(1)%array(i,j,k),     &
     3741                                  vrot = preprocess_buffer(2)%array(i,j,k),     &
     3742                                  rlat = cosmo_grid%lat(j-1),                   &
     3743                                  rlon = cosmo_grid%lon(i-1),                   &
     3744                                  pollat = phi_cn,                                &
     3745                                  pollon = lambda_cn,                             &
     3746                                  u = input_buffer(1)%array(i,j,k),             &
     3747                                  v = input_buffer(2)%array(i,j,k) )
     3748                ENDDO
     3749                ENDDO
     3750                ENDDO
     3751             
     3752             CASE DEFAULT
     3753                message = "Rotation method '" // TRIM(cfg%rotation_method) //   &
     3754                   "' not recognized."
     3755                CALL inifor_abort('preprocess', message)
    37373756
    37383757          END SELECT
    37393758
    3740           input_buffer(1) % array(1,:,:) = 0.0_dp
    3741           input_buffer(2) % array(1,:,:) = 0.0_dp
    3742           input_buffer(1) % array(:,1,:) = 0.0_dp
    3743           input_buffer(2) % array(:,1,:) = 0.0_dp
    3744 
    3745           input_buffer(1:2) % is_preprocessed = .TRUE.
    3746  CALL run_control('time', 'comp')
     3759          input_buffer(1)%array(1,:,:) = 0.0_wp
     3760          input_buffer(2)%array(1,:,:) = 0.0_wp
     3761          input_buffer(1)%array(:,1,:) = 0.0_wp
     3762          input_buffer(2)%array(:,1,:) = 0.0_wp
     3763
     3764          input_buffer(1:2)%is_preprocessed = .TRUE.
     3765          CALL log_runtime('time', 'comp')
    37473766
    37483767          DEALLOCATE( preprocess_buffer )
    3749  CALL run_control('time', 'alloc')
    3750 
    3751           message = "Input buffers for group '" // TRIM(group % kind) // "'"//&
     3768          CALL log_runtime('time', 'alloc')
     3769
     3770          message = "Input buffers for group '" // TRIM(group%kind) // "'"//&
    37523771             " preprocessed sucessfully."
    37533772          CALL report('preprocess', message)
    37543773       
    37553774       CASE( 'thermodynamics' ) ! T, P, QV
    3756           nx = SIZE(input_buffer(1) % array, 1)
    3757           ny = SIZE(input_buffer(1) % array, 2)
    3758           nz = SIZE(input_buffer(1) % array, 3)
     3775          nx = SIZE(input_buffer(1)%array, 1)
     3776          ny = SIZE(input_buffer(1)%array, 2)
     3777          nz = SIZE(input_buffer(1)%array, 3)
    37593778
    37603779!
    37613780!--       Compute absolute pressure if presure perturbation has been read in.
    3762           IF ( TRIM(group % in_var_list(2) % name) == 'PP' )  THEN
     3781          IF ( TRIM(group%in_var_list(2)%name) == 'PP' )  THEN
    37633782             message = "Absolute pressure, P, not available, " //              &
    37643783                       "computing from pressure preturbation PP."
     
    37663785
    37673786             ALLOCATE( basic_state_pressure(1:nz) )
    3768  CALL run_control('time', 'alloc')
    3769 
    3770              DO j = 1, ny
    3771              DO i = 1, nx
    3772 
    3773                 CALL get_basic_state(cosmo_grid % hfl(i,j,:), BETA, P_SL, T_SL,&
     3787             CALL log_runtime('time', 'alloc')
     3788
     3789             DO  j = 1, ny
     3790             DO  i = 1, nx
     3791
     3792                CALL get_basic_state(cosmo_grid%hfl(i,j,:), BETA, P_SL, T_SL,&
    37743793                                     RD, G, basic_state_pressure)
    37753794
     
    37773796!--             Overwrite pressure perturbation with absolute pressure. HECTO
    37783797!--             converts pressure perturbation from hPa to Pa.
    3779                 input_buffer (2) % array(i,j,:) =                              &
    3780                    HECTO * input_buffer (2) % array(i,j,:) +                   &
     3798                input_buffer (2)%array(i,j,:) =                              &
     3799                   HECTO * input_buffer (2)%array(i,j,:) +                   &
    37813800                   basic_state_pressure(:)
    37823801
    37833802             ENDDO
    37843803             ENDDO
    3785  CALL run_control('time', 'comp')
     3804             CALL log_runtime('time', 'comp')
    37863805
    37873806             DEALLOCATE( basic_state_pressure )
    3788  CALL run_control('time', 'alloc')
    3789 
    3790              group % in_var_list(2) % name = 'P'
     3807             CALL log_runtime('time', 'alloc')
     3808
     3809             group%in_var_list(2)%name = 'P'
    37913810
    37923811          ENDIF
    37933812!
    37943813!--       mark pressure as preprocessed
    3795           input_buffer(2) % is_preprocessed = .TRUE.
     3814          input_buffer(2)%is_preprocessed = .TRUE.
    37963815
    37973816!
    37983817!--       Copy temperature to the last input buffer array
    37993818          ALLOCATE(                                                            &
    3800               input_buffer( group % n_output_quantities ) % array (nx, ny, nz) &
     3819              input_buffer( group%n_output_quantities )%array (nx, ny, nz) &
    38013820          )
    3802           input_buffer(group % n_output_quantities) % array(:,:,:) =           &
    3803               input_buffer(1) % array(:,:,:)
     3821          CALL log_runtime('time', 'alloc')
     3822          input_buffer(group%n_output_quantities)%array(:,:,:) =           &
     3823              input_buffer(1)%array(:,:,:)
    38043824
    38053825!
    38063826!--       Convert absolute in place to potential temperature
    38073827          CALL potential_temperature(                                          &
    3808              t = input_buffer(1) % array(:,:,:),                               &
    3809              p = input_buffer(2) % array(:,:,:),                               &
     3828             t = input_buffer(1)%array(:,:,:),                               &
     3829             p = input_buffer(2)%array(:,:,:),                               &
    38103830             p_ref = P_REF,                                                    &
    38113831             r = RD_PALM,                                                      &
     
    38153835!
    38163836!--       mark potential temperature as preprocessed
    3817           input_buffer(1) % is_preprocessed = .TRUE.
     3837          input_buffer(1)%is_preprocessed = .TRUE.
    38183838
    38193839!
    38203840!--       Convert temperature copy to density
    38213841          CALL moist_density(                                                  &
    3822              t_rho = input_buffer(group % n_output_quantities) % array(:,:,:), &
    3823              p = input_buffer(2) % array(:,:,:),                               &
    3824              qv = input_buffer(3) % array(:,:,:),                              &
     3842             t_rho = input_buffer(group%n_output_quantities)%array(:,:,:), &
     3843             p = input_buffer(2)%array(:,:,:),                               &
     3844             qv = input_buffer(3)%array(:,:,:),                              &
    38253845             rd = RD,                                                          &
    38263846             rv = RV                                                           &
     
    38293849!
    38303850!--       mark qv as preprocessed
    3831           input_buffer(3) % is_preprocessed = .TRUE.
     3851          input_buffer(3)%is_preprocessed = .TRUE.
    38323852
    38333853!
    38343854!--       mark density as preprocessed
    3835           input_buffer(group % n_output_quantities) % is_preprocessed = .TRUE.
    3836 
    3837 
    3838           message = "Input buffers for group '" // TRIM(group % kind) // "'"//&
     3855          input_buffer(group%n_output_quantities)%is_preprocessed = .TRUE.
     3856
     3857
     3858          message = "Input buffers for group '" // TRIM(group%kind) // "'"//&
    38393859             " preprocessed sucessfully."
    38403860          CALL report('preprocess', message)
    3841  CALL run_control('time', 'comp')
    38423861       
    38433862       CASE( 'scalar' ) ! S or W
    3844           input_buffer(:) % is_preprocessed = .TRUE.
    3845  CALL run_control('time', 'comp')
     3863          input_buffer(:)%is_preprocessed = .TRUE.
    38463864
    38473865       CASE( 'soil-temperature' ) !
    38483866         
    3849           CALL fill_water_cells(soiltyp, input_buffer(1) % array, &
    3850                                 SIZE(input_buffer(1) % array, 3), &
     3867          CALL fill_water_cells(soiltyp, input_buffer(1)%array, &
     3868                                SIZE(input_buffer(1)%array, 3), &
    38513869                                FILL_ITERATIONS)
    3852           input_buffer(:) % is_preprocessed = .TRUE.
    3853  CALL run_control('time', 'comp')
     3870          input_buffer(:)%is_preprocessed = .TRUE.
    38543871
    38553872       CASE( 'soil-water' ) !
    38563873
    3857           CALL fill_water_cells(soiltyp, input_buffer(1) % array, &
    3858                                 SIZE(input_buffer(1) % array, 3), &
     3874          CALL fill_water_cells(soiltyp, input_buffer(1)%array, &
     3875                                SIZE(input_buffer(1)%array, 3), &
    38593876                                FILL_ITERATIONS)
    38603877
    3861           nx = SIZE(input_buffer(1) % array, 1)
    3862           ny = SIZE(input_buffer(1) % array, 2)
    3863           nz = SIZE(input_buffer(1) % array, 3)
    3864 
    3865           DO k = 1, nz
    3866           DO j = 1, ny
    3867           DO i = 1, nx
    3868              input_buffer(1) % array(i,j,k) =                                  &
    3869                  input_buffer(1) % array(i,j,k) * d_depth_rho_inv(k)
     3878          nx = SIZE(input_buffer(1)%array, 1)
     3879          ny = SIZE(input_buffer(1)%array, 2)
     3880          nz = SIZE(input_buffer(1)%array, 3)
     3881
     3882          DO  k = 1, nz
     3883          DO  j = 1, ny
     3884          DO  i = 1, nx
     3885             input_buffer(1)%array(i,j,k) =                                  &
     3886                 input_buffer(1)%array(i,j,k) * d_depth_rho_inv(k)
    38703887          ENDDO
    38713888          ENDDO
     
    38753892          CALL report('preprocess', message)
    38763893
    3877           input_buffer(:) % is_preprocessed = .TRUE.
    3878  CALL run_control('time', 'comp')
     3894          input_buffer(:)%is_preprocessed = .TRUE.
    38793895
    38803896       CASE( 'surface' ) !
    3881           input_buffer(:) % is_preprocessed = .TRUE.
    3882  CALL run_control('time', 'comp')
     3897          input_buffer(:)%is_preprocessed = .TRUE.
    38833898
    38843899       CASE( 'accumulated' ) !
    3885           message = "De-accumulating '" // TRIM(group % in_var_list(1) % name) //&
     3900          message = "De-accumulating '" // TRIM(group%in_var_list(1)%name) //&
    38863901                    "' in iteration " // TRIM(str(iter))
    38873902          CALL report('preprocess', message)
     
    38923907
    38933908!
    3894 !--       input has been accumulated over one hour. Leave as is
    3895 !--       input_buffer(1) % array(:,:,:) carrries one-hour integral
    3896           CASE(1)
    3897 
    3898 !
    3899 !--       input has been accumulated over two hours. Subtract previous step
    3900 !--       input_buffer(1) % array(:,:,:) carrries one-hour integral
    3901 !--       input_buffer(2) % array(:,:,:) carrries two-hour integral
    3902           CASE(2)
    3903              CALL deaverage(                                                   &
    3904                       avg_1 = input_buffer(1) % array(:,:,:), t1 = 1.0_dp,     &
    3905                       avg_2 = input_buffer(2) % array(:,:,:), t2 = 1.0_dp,     &
    3906                       avg_3 = input_buffer(1) % array(:,:,:), t3 = 1.0_dp )
    3907 !
    3908 !--          input_buffer(1) % array(:,:,:) carrries one-hour integral of second hour
    3909 
    3910 !
    3911 !--       input has been accumulated over three hours. Subtract previous step
    3912 !--       input_buffer(1) % array(:,:,:) carrries three-hour integral
    3913 !--       input_buffer(2) % array(:,:,:) still carrries two-hour integral
    3914           CASE(3)
    3915              CALL deaverage(                                                   &
    3916                      avg_1 = input_buffer(2) % array(:,:,:), t1 = 1.0_dp,      &
    3917                      avg_2 = input_buffer(1) % array(:,:,:), t2 = 1.0_dp,      &
    3918                      avg_3 = input_buffer(1) % array(:,:,:), t3 = 1.0_dp )
    3919 !
    3920 !--          input_buffer(1) % array(:,:,:) carrries one-hour integral of third hourA
    3921 
    3922           CASE DEFAULT
    3923              message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
    3924              CALL inifor_abort('preprocess', message)
     3909!--          input has been accumulated over one hour. Leave as is
     3910!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
     3911             CASE(1)
     3912             
     3913!           
     3914!--          input has been accumulated over two hours. Subtract previous step
     3915!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
     3916!--          input_buffer(2)%array(:,:,:) carrries two-hour integral
     3917             CASE(2)
     3918                CALL deaverage(                                                   &
     3919                         avg_1 = input_buffer(1)%array(:,:,:), t1 = 1.0_wp,     &
     3920                         avg_2 = input_buffer(2)%array(:,:,:), t2 = 1.0_wp,     &
     3921                         avg_3 = input_buffer(1)%array(:,:,:), t3 = 1.0_wp )
     3922!           
     3923!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of second hour
     3924             
     3925!           
     3926!--          input has been accumulated over three hours. Subtract previous step
     3927!--          input_buffer(1)%array(:,:,:) carrries three-hour integral
     3928!--          input_buffer(2)%array(:,:,:) still carrries two-hour integral
     3929             CASE(3)
     3930                CALL deaverage(                                                   &
     3931                        avg_1 = input_buffer(2)%array(:,:,:), t1 = 1.0_wp,      &
     3932                        avg_2 = input_buffer(1)%array(:,:,:), t2 = 1.0_wp,      &
     3933                        avg_3 = input_buffer(1)%array(:,:,:), t3 = 1.0_wp )
     3934!           
     3935!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of third hourA
     3936             
     3937             CASE DEFAULT
     3938                message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
     3939                CALL inifor_abort('preprocess', message)
    39253940
    39263941          END SELECT
    3927           input_buffer(:) % is_preprocessed = .TRUE.
    3928  CALL run_control('time', 'comp')
     3942          input_buffer(:)%is_preprocessed = .TRUE.
    39293943
    39303944       CASE( 'running average' ) !
    3931           message = "De-averaging '" // TRIM(group % in_var_list(1) % name) //   &
     3945          message = "De-averaging '" // TRIM(group%in_var_list(1)%name) //   &
    39323946                    "' in iteration " // TRIM(str(iter))
    39333947          CALL report('preprocess', message)
     
    39393953          SELECT CASE(dt)
    39403954!
    3941 !--       input has been accumulated over one hour. Leave as is
    3942 !--       input_buffer(1) % array(:,:,:) carrries one-hour integral
    3943           CASE(1)
    3944 
    3945 !
    3946 !--       input has been accumulated over two hours. Subtract previous step
    3947 !--       input_buffer(1) % array(:,:,:) carrries one-hour integral
    3948 !--       input_buffer(2) % array(:,:,:) carrries two-hour integral
    3949           CASE(2)
    3950              CALL deaverage( input_buffer(1) % array(:,:,:), 1.0_dp,           &
    3951                              input_buffer(2) % array(:,:,:), 2.0_dp,           &
    3952                              input_buffer(1) % array(:,:,:), 1.0_dp)
    3953 !
    3954 !--          input_buffer(1) % array(:,:,:) carrries one-hour integral of second hour
    3955 
    3956 !
    3957 !--       input has been accumulated over three hours. Subtract previous step
    3958 !--       input_buffer(1) % array(:,:,:) carrries three-hour integral
    3959 !--       input_buffer(2) % array(:,:,:) still carrries two-hour integral
    3960           CASE(3)
    3961              CALL deaverage( input_buffer(2) % array(:,:,:), 2.0_dp,           &
    3962                              input_buffer(1) % array(:,:,:), 3.0_dp,           &
    3963                              input_buffer(1) % array(:,:,:), 1.0_dp)
    3964 !
    3965 !--          input_buffer(1) % array(:,:,:) carrries one-hour integral of third hourA
    3966 
    3967           CASE DEFAULT
    3968              message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
    3969              CALL inifor_abort('preprocess', message)
     3955!--          input has been accumulated over one hour. Leave as is
     3956!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
     3957             CASE(1)
     3958             
     3959!           
     3960!--          input has been accumulated over two hours. Subtract previous step
     3961!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
     3962!--          input_buffer(2)%array(:,:,:) carrries two-hour integral
     3963             CASE(2)
     3964                CALL deaverage( input_buffer(1)%array(:,:,:), 1.0_wp,           &
     3965                                input_buffer(2)%array(:,:,:), 2.0_wp,           &
     3966                                input_buffer(1)%array(:,:,:), 1.0_wp)
     3967!           
     3968!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of second hour
     3969             
     3970!           
     3971!--          input has been accumulated over three hours. Subtract previous step
     3972!--          input_buffer(1)%array(:,:,:) carrries three-hour integral
     3973!--          input_buffer(2)%array(:,:,:) still carrries two-hour integral
     3974             CASE(3)
     3975                CALL deaverage( input_buffer(2)%array(:,:,:), 2.0_wp,           &
     3976                                input_buffer(1)%array(:,:,:), 3.0_wp,           &
     3977                                input_buffer(1)%array(:,:,:), 1.0_wp)
     3978!           
     3979!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of third hourA
     3980             
     3981             CASE DEFAULT
     3982                message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
     3983                CALL inifor_abort('preprocess', message)
    39703984
    39713985          END SELECT
    3972           input_buffer(:) % is_preprocessed = .TRUE.
     3986          input_buffer(:)%is_preprocessed = .TRUE.
    39733987
    39743988       CASE DEFAULT
    3975           message = "IO group kind '" // TRIM(group % kind) // "' is not supported."
     3989          message = "IO group kind '" // TRIM(group%kind) // "' is not supported."
    39763990          CALL inifor_abort('prerpocess', message)
    39773991
    3978        END SELECT
    3979  CALL run_control('time', 'comp')
    3980 
    3981     END SUBROUTINE preprocess
     3992    END SELECT
     3993    CALL log_runtime('time', 'comp')
     3994
     3995 END SUBROUTINE preprocess
    39823996
    39833997
     
    40064020!> array : the soil array (i.e. water content or temperature)
    40074021!------------------------------------------------------------------------------!
    4008     SUBROUTINE fill_water_cells(soiltyp, array, nz, niter)
    4009        INTEGER(hp), DIMENSION(:,:,:), INTENT(IN) :: soiltyp
    4010        REAL(dp), DIMENSION(:,:,:), INTENT(INOUT) :: array
    4011        INTEGER, INTENT(IN)                       :: nz, niter
    4012 
    4013        REAL(dp), DIMENSION(nz)                   :: column
    4014        INTEGER(hp), DIMENSION(:,:), ALLOCATABLE  :: old_soiltyp, new_soiltyp
    4015        INTEGER                                   :: l, i, j, nx, ny, n_cells, ii, jj, iter
    4016        INTEGER, DIMENSION(8)                     :: di, dj
    4017 
    4018        nx = SIZE(array, 1)
    4019        ny = SIZE(array, 2)
    4020        di = (/ -1, -1, -1, 0,  0,  1, 1, 1 /)
    4021        dj = (/ -1,  0,  1, -1, 1, -1, 0, 1 /)
    4022 
    4023        ALLOCATE(old_soiltyp(SIZE(soiltyp,1), &
    4024                             SIZE(soiltyp,2) ))
    4025 
    4026        ALLOCATE(new_soiltyp(SIZE(soiltyp,1), &
    4027                             SIZE(soiltyp,2) ))
    4028 
    4029        old_soiltyp(:,:) = soiltyp(:,:,1)
    4030        new_soiltyp(:,:) = soiltyp(:,:,1)
    4031 
    4032        DO iter = 1, niter
    4033 
    4034           DO j = 1, ny
    4035           DO i = 1, nx
    4036          
    4037              IF (old_soiltyp(i,j) == WATER_ID)  THEN
    4038 
    4039                 n_cells = 0
    4040                 column(:) = 0.0_dp
    4041                 DO l = 1, SIZE(di)
    4042 
    4043                    ii = MIN(nx, MAX(1, i + di(l)))
    4044                    jj = MIN(ny, MAX(1, j + dj(l)))
    4045 
    4046                    IF (old_soiltyp(ii,jj) .NE. WATER_ID)  THEN
    4047                       n_cells = n_cells + 1
    4048                       column(:) = column(:) + array(ii,jj,:)
    4049                    ENDIF
    4050 
    4051                 ENDDO
    4052 
    4053 !
    4054 !--             Overwrite if at least one non-water neighbour cell is available
    4055                 IF (n_cells > 0)  THEN
    4056                    array(i,j,:) = column(:) / n_cells
    4057                    new_soiltyp(i,j) = 0
     4022 SUBROUTINE fill_water_cells(soiltyp, array, nz, niter)
     4023    INTEGER(iwp), DIMENSION(:,:,:), INTENT(IN) :: soiltyp
     4024    REAL(wp), DIMENSION(:,:,:), INTENT(INOUT)  :: array
     4025    INTEGER, INTENT(IN)                        :: nz, niter
     4026
     4027    REAL(wp), DIMENSION(nz)                    :: column
     4028    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE  :: old_soiltyp, new_soiltyp
     4029    INTEGER                                    :: l, i, j, nx, ny, n_cells, ii, jj, iter
     4030    INTEGER, DIMENSION(8)                      :: di, dj
     4031
     4032    nx = SIZE(array, 1)
     4033    ny = SIZE(array, 2)
     4034    di = (/ -1, -1, -1, 0,  0,  1, 1, 1 /)
     4035    dj = (/ -1,  0,  1, -1, 1, -1, 0, 1 /)
     4036
     4037    ALLOCATE(old_soiltyp(SIZE(soiltyp,1), &
     4038                         SIZE(soiltyp,2) ))
     4039
     4040    ALLOCATE(new_soiltyp(SIZE(soiltyp,1), &
     4041                         SIZE(soiltyp,2) ))
     4042
     4043    old_soiltyp(:,:) = soiltyp(:,:,1)
     4044    new_soiltyp(:,:) = soiltyp(:,:,1)
     4045
     4046    DO  iter = 1, niter
     4047
     4048       DO  j = 1, ny
     4049       DO  i = 1, nx
     4050       
     4051          IF (old_soiltyp(i,j) == WATER_ID)  THEN
     4052
     4053             n_cells = 0
     4054             column(:) = 0.0_wp
     4055             DO  l = 1, SIZE(di)
     4056
     4057                ii = MIN(nx, MAX(1, i + di(l)))
     4058                jj = MIN(ny, MAX(1, j + dj(l)))
     4059
     4060                IF (old_soiltyp(ii,jj) .NE. WATER_ID)  THEN
     4061                   n_cells = n_cells + 1
     4062                   column(:) = column(:) + array(ii,jj,:)
    40584063                ENDIF
    40594064
     4065             ENDDO
     4066
     4067!
     4068!--          Overwrite if at least one non-water neighbour cell is available
     4069             IF (n_cells > 0)  THEN
     4070                array(i,j,:) = column(:) / n_cells
     4071                new_soiltyp(i,j) = 0
    40604072             ENDIF
    40614073
    4062           ENDDO
    4063           ENDDO
    4064 
    4065           old_soiltyp(:,:) = new_soiltyp(:,:)
     4074          ENDIF
    40664075
    40674076       ENDDO
    4068 
    4069        DEALLOCATE(old_soiltyp, new_soiltyp)
    4070 
    4071     END SUBROUTINE fill_water_cells
     4077       ENDDO
     4078
     4079       old_soiltyp(:,:) = new_soiltyp(:,:)
     4080
     4081    ENDDO
     4082
     4083    DEALLOCATE(old_soiltyp, new_soiltyp)
     4084
     4085 END SUBROUTINE fill_water_cells
    40724086
    40734087
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_io.f90

    r3801 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29! Improved coding style
     30!
     31!
     32! 3801 2019-03-15 17:14:25Z eckhard
    2833! Added routine get_cosmo_grid() to read in COSMO rotated pole from COSMO domain
    2934! Moved get_soil_layer_thickness() here from inifor_grid
     
    118123    USE inifor_control
    119124    USE inifor_defs,                                                           &
    120         ONLY:  DATE, SNAME, PATH, PI, dp, hp, TO_RADIANS, TO_DEGREES, VERSION, &
     125        ONLY:  DATE, SNAME, PATH, PI, TO_RADIANS, TO_DEGREES, VERSION,        &
    121126               NC_DEPTH_NAME, NC_HHL_NAME, NC_RLAT_NAME, NC_RLON_NAME,         &
    122127               NC_ROTATED_POLE_NAME, NC_POLE_LATITUDE_NAME,                    &
    123                NC_POLE_LONGITUDE_NAME, RHO_L
     128               NC_POLE_LONGITUDE_NAME, RHO_L, wp, iwp
    124129    USE inifor_types
    125130    USE inifor_util,                                                           &
     
    133138! ------------
    134139!> get_netcdf_variable() reads the netCDF data and metadate for the netCDF
    135 !> variable 'in_var % name' from the file 'in_file'. The netCDF data array is
     140!> variable 'in_var%name' from the file 'in_file'. The netCDF data array is
    136141!> stored in the 'buffer' array and metadata added to the respective members of
    137142!> the given 'in_var'.
     
    152157!> get_netcdf_variable interface.
    153158!------------------------------------------------------------------------------!
    154     SUBROUTINE get_netcdf_variable_int(in_file, in_var, buffer)
    155 
    156        CHARACTER(LEN=PATH), INTENT(IN)         ::  in_file
    157        TYPE(nc_var), INTENT(INOUT)             ::  in_var
    158        INTEGER(hp), ALLOCATABLE, INTENT(INOUT) ::  buffer(:,:,:)
    159 
    160        INTEGER               ::  ncid
    161        INTEGER, DIMENSION(3) ::  start, count
    162 
    163        IF ( nf90_open( TRIM(in_file), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
    164             nf90_inq_varid( ncid, in_var % name, in_var % varid ) .EQ. NF90_NOERR )  THEN
    165 
    166           CALL get_input_dimensions(in_var, ncid)
    167 
    168           CALL get_netcdf_start_and_count(in_var, start, count)
    169  CALL run_control('time', 'read')
    170 
    171           ALLOCATE( buffer( count(1), count(2), count(3) ) )
    172  CALL run_control('time', 'alloc')
    173 
    174           CALL check(nf90_get_var( ncid, in_var % varid, buffer,                  &
    175                                    start = start,                                 &
    176                                    count = count ))
    177 
    178        ELSE
    179 
    180           message = "Failed to read '" // TRIM(in_var % name) // &
    181              "' from file '" // TRIM(in_file) // "'."
    182           CALL inifor_abort('get_netcdf_variable', message)
    183 
    184        ENDIF
    185 
    186        CALL check(nf90_close(ncid))
    187  CALL run_control('time', 'read')
    188 
    189     END SUBROUTINE get_netcdf_variable_int
     159 SUBROUTINE get_netcdf_variable_int(in_file, in_var, buffer)
     160
     161    CHARACTER(LEN=PATH), INTENT(IN)          ::  in_file
     162    TYPE(nc_var), INTENT(INOUT)              ::  in_var
     163    INTEGER(iwp), ALLOCATABLE, INTENT(INOUT) ::  buffer(:,:,:)
     164
     165    INTEGER               ::  ncid
     166    INTEGER, DIMENSION(3) ::  start, count
     167
     168    IF ( nf90_open( TRIM(in_file), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
     169         nf90_inq_varid( ncid, in_var%name, in_var%varid ) .EQ. NF90_NOERR )  THEN
     170
     171       CALL get_input_dimensions(in_var, ncid)
     172
     173       CALL get_netcdf_start_and_count(in_var, start, count)
     174       CALL log_runtime('time', 'read')
     175
     176       ALLOCATE( buffer( count(1), count(2), count(3) ) )
     177       CALL log_runtime('time', 'alloc')
     178
     179       CALL check(nf90_get_var( ncid, in_var%varid, buffer,                  &
     180                                start = start,                                 &
     181                                count = count ))
     182
     183    ELSE
     184
     185       message = "Failed to read '" // TRIM(in_var%name) // &
     186          "' from file '" // TRIM(in_file) // "'."
     187       CALL inifor_abort('get_netcdf_variable', message)
     188
     189    ENDIF
     190
     191    CALL check(nf90_close(ncid))
     192    CALL log_runtime('time', 'read')
     193
     194 END SUBROUTINE get_netcdf_variable_int
    190195
    191196
     
    196201!> get_netcdf_variable interface.
    197202!------------------------------------------------------------------------------!
    198     SUBROUTINE get_netcdf_variable_real(in_file, in_var, buffer)
    199 
    200        CHARACTER(LEN=PATH), INTENT(IN)      ::  in_file
    201        TYPE(nc_var), INTENT(INOUT)          ::  in_var
    202        REAL(dp), ALLOCATABLE, INTENT(INOUT) ::  buffer(:,:,:)
    203 
    204        INTEGER               ::  ncid
    205        INTEGER, DIMENSION(3) ::  start, count
    206 
    207        IF ( nf90_open( TRIM(in_file), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
    208             nf90_inq_varid( ncid, in_var % name, in_var % varid ) .EQ. NF90_NOERR )  THEN
    209 
    210           CALL get_input_dimensions(in_var, ncid)
    211 
    212           CALL get_netcdf_start_and_count(in_var, start, count)
    213  CALL run_control('time', 'read')
    214 
    215           ALLOCATE( buffer( count(1), count(2), count(3) ) )
    216  CALL run_control('time', 'alloc')
    217 
    218           CALL check(nf90_get_var( ncid, in_var % varid, buffer,                  &
    219                                    start = start,                                 &
    220                                    count = count ))
    221 
    222        ELSE
    223 
    224           message = "Failed to read '" // TRIM(in_var % name) // &
    225              "' from file '" // TRIM(in_file) // "'."
    226           CALL inifor_abort('get_netcdf_variable', message)
    227 
    228        ENDIF
    229 
    230        CALL check(nf90_close(ncid))
    231  CALL run_control('time', 'read')
    232 
    233     END SUBROUTINE get_netcdf_variable_real
     203 SUBROUTINE get_netcdf_variable_real(in_file, in_var, buffer)
     204
     205    CHARACTER(LEN=PATH), INTENT(IN)      ::  in_file
     206    TYPE(nc_var), INTENT(INOUT)          ::  in_var
     207    REAL(wp), ALLOCATABLE, INTENT(INOUT) ::  buffer(:,:,:)
     208
     209    INTEGER               ::  ncid
     210    INTEGER, DIMENSION(3) ::  start, count
     211
     212    IF ( nf90_open( TRIM(in_file), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
     213         nf90_inq_varid( ncid, in_var%name, in_var%varid ) .EQ. NF90_NOERR )  THEN
     214
     215       CALL get_input_dimensions(in_var, ncid)
     216
     217       CALL get_netcdf_start_and_count(in_var, start, count)
     218       CALL log_runtime('time', 'read')
     219
     220       ALLOCATE( buffer( count(1), count(2), count(3) ) )
     221       CALL log_runtime('time', 'alloc')
     222
     223       CALL check(nf90_get_var( ncid, in_var%varid, buffer,                  &
     224                                start = start,                                 &
     225                                count = count ))
     226
     227    ELSE
     228
     229       message = "Failed to read '" // TRIM(in_var%name) // &
     230          "' from file '" // TRIM(in_file) // "'."
     231       CALL inifor_abort('get_netcdf_variable', message)
     232
     233    ENDIF
     234
     235    CALL check(nf90_close(ncid))
     236    CALL log_runtime('time', 'read')
     237
     238 END SUBROUTINE get_netcdf_variable_real
    234239
    235240
     
    240245!> netCDF file 'filename'.
    241246!------------------------------------------------------------------------------!
    242     SUBROUTINE get_netcdf_dim_vector(filename, coordname, coords)
    243 
    244        CHARACTER(LEN=*), INTENT(IN)         ::  filename
    245        CHARACTER(LEN=*), INTENT(IN)         ::  coordname
    246        REAL(dp), ALLOCATABLE, INTENT(INOUT) ::  coords(:)
    247 
    248        INTEGER ::  ncid, varid, dimlen
    249        INTEGER ::  dimids(NF90_MAX_VAR_DIMS)
    250 
    251        IF ( nf90_open( TRIM(filename), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
    252             nf90_inq_varid( ncid, coordname, varid ) .EQ. NF90_NOERR )  THEN
    253 
    254           CALL check(nf90_inquire_variable( ncid, varid, dimids = dimids ))
    255           CALL check(nf90_inquire_dimension( ncid, dimids(1), len = dimlen ))
    256 
    257           ALLOCATE(coords(dimlen))
    258           CALL check(nf90_get_var( ncid, varid, coords))
    259 
    260        ELSE
    261 
    262           message = "Failed to read '" // TRIM(coordname) // &
    263              "' from file '" // TRIM(filename) // "'."
    264           CALL inifor_abort('get_netcdf_dim_vector', message)
    265 
    266        ENDIF
    267 
    268     END SUBROUTINE get_netcdf_dim_vector
     247 SUBROUTINE get_netcdf_dim_vector(filename, coordname, coords)
     248
     249    CHARACTER(LEN=*), INTENT(IN)         ::  filename
     250    CHARACTER(LEN=*), INTENT(IN)         ::  coordname
     251    REAL(wp), ALLOCATABLE, INTENT(INOUT) ::  coords(:)
     252
     253    INTEGER ::  ncid, varid, dimlen
     254    INTEGER ::  dimids(NF90_MAX_VAR_DIMS)
     255
     256    IF ( nf90_open( TRIM(filename), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
     257         nf90_inq_varid( ncid, coordname, varid ) .EQ. NF90_NOERR )  THEN
     258
     259       CALL check(nf90_inquire_variable( ncid, varid, dimids = dimids ))
     260       CALL check(nf90_inquire_dimension( ncid, dimids(1), len = dimlen ))
     261
     262       ALLOCATE(coords(dimlen))
     263       CALL check(nf90_get_var( ncid, varid, coords))
     264
     265    ELSE
     266
     267       message = "Failed to read '" // TRIM(coordname) // &
     268          "' from file '" // TRIM(filename) // "'."
     269       CALL inifor_abort('get_netcdf_dim_vector', message)
     270
     271    ENDIF
     272
     273 END SUBROUTINE get_netcdf_dim_vector
    269274
    270275
     
    273278! ------------
    274279!> get_input_dimensions() reads dimensions metadata of the netCDF variable given
    275 !> by 'in_var % name' into 'in_var' data structure.
    276 !------------------------------------------------------------------------------!
    277     SUBROUTINE get_input_dimensions(in_var, ncid)
    278 
    279        TYPE(nc_var), INTENT(INOUT) ::  in_var
    280        INTEGER, INTENT(IN)         ::  ncid
    281 
    282        INTEGER ::  i
    283 
    284        CALL check(nf90_get_att( ncid, in_var % varid, "long_name",             &
    285                                 in_var % long_name))
    286 
    287        CALL check(nf90_get_att( ncid, in_var % varid, "units",                 &
    288                                 in_var % units ))
    289 
    290        CALL check(nf90_inquire_variable( ncid, in_var % varid,                 &
    291                                          ndims  = in_var % ndim,               &
    292                                          dimids = in_var % dimids ))
    293 
    294        DO i = 1, in_var % ndim
    295           CALL check(nf90_inquire_dimension( ncid, in_var % dimids(i),         &
    296                                              name = in_var % dimname(i),       &
    297                                              len  = in_var % dimlen(i) ))
    298        ENDDO
    299 
    300     END SUBROUTINE get_input_dimensions
     280!> by 'in_var%name' into 'in_var' data structure.
     281!------------------------------------------------------------------------------!
     282 SUBROUTINE get_input_dimensions(in_var, ncid)
     283
     284    TYPE(nc_var), INTENT(INOUT) ::  in_var
     285    INTEGER, INTENT(IN)         ::  ncid
     286
     287    INTEGER ::  i
     288
     289    CALL check(nf90_get_att( ncid, in_var%varid, "long_name",             &
     290                             in_var%long_name))
     291
     292    CALL check(nf90_get_att( ncid, in_var%varid, "units",                 &
     293                             in_var%units ))
     294
     295    CALL check(nf90_inquire_variable( ncid, in_var%varid,                 &
     296                                      ndims  = in_var%ndim,               &
     297                                      dimids = in_var%dimids ))
     298
     299    DO  i = 1, in_var%ndim
     300       CALL check(nf90_inquire_dimension( ncid, in_var%dimids(i),         &
     301                                          name = in_var%dimname(i),       &
     302                                          len  = in_var%dimlen(i) ))
     303    ENDDO
     304
     305 END SUBROUTINE get_input_dimensions
    301306
    302307
     
    308313!> and _real() for reading input variables..
    309314!------------------------------------------------------------------------------!
    310     SUBROUTINE get_netcdf_start_and_count(in_var, start, count)
    311 
    312        TYPE(nc_var), INTENT(INOUT)        ::  in_var
    313        INTEGER, DIMENSION(3), INTENT(OUT) ::  start, count
    314 
    315        INTEGER ::  ndim
    316 
    317        IF ( in_var % ndim .LT. 2  .OR.  in_var % ndim .GT. 4 )  THEN
    318 
    319           message = "Failed reading NetCDF variable " //                       &
    320              TRIM(in_var % name) // " with " // TRIM(str(in_var % ndim)) //    &
    321              " dimensions because only two- and and three-dimensional" //      &
    322              " variables are supported."
    323           CALL inifor_abort('get_netcdf_start_and_count', message)
    324 
    325        ENDIF
    326 
    327        start = (/ 1, 1, 1 /)
    328        IF ( TRIM(in_var % name) .EQ. 'T_SO' )  THEN
    329 !
    330 !--       Skip depth = 0.0 for T_SO and reduce number of depths from 9 to 8
    331           in_var % dimlen(3) = in_var % dimlen(3) - 1
    332 
    333 !
    334 !--       Start reading from second level, e.g. depth = 0.005 instead of 0.0
    335           start(3) = 2
    336        ENDIF
    337 
    338        IF (in_var % ndim .EQ. 2)  THEN
    339           in_var % dimlen(3) = 1
    340        ENDIF
    341 
    342        ndim = MIN(in_var % ndim, 3)
    343        count = (/ 1, 1, 1 /)
    344        count(1:ndim) = in_var % dimlen(1:ndim)
    345 
    346     END SUBROUTINE get_netcdf_start_and_count
     315 SUBROUTINE get_netcdf_start_and_count(in_var, start, count)
     316
     317    TYPE(nc_var), INTENT(INOUT)        ::  in_var
     318    INTEGER, DIMENSION(3), INTENT(OUT) ::  start, count
     319
     320    INTEGER ::  ndim
     321
     322    IF ( in_var%ndim .LT. 2  .OR.  in_var%ndim .GT. 4 )  THEN
     323
     324       message = "Failed reading NetCDF variable " //                       &
     325          TRIM(in_var%name) // " with " // TRIM(str(in_var%ndim)) //    &
     326          " dimensions because only two- and and three-dimensional" //      &
     327          " variables are supported."
     328       CALL inifor_abort('get_netcdf_start_and_count', message)
     329
     330    ENDIF
     331
     332    start = (/ 1, 1, 1 /)
     333    IF ( TRIM(in_var%name) .EQ. 'T_SO' )  THEN
     334!
     335!--    Skip depth = 0.0 for T_SO and reduce number of depths from 9 to 8
     336       in_var%dimlen(3) = in_var%dimlen(3) - 1
     337
     338!
     339!--    Start reading from second level, e.g. depth = 0.005 instead of 0.0
     340       start(3) = 2
     341    ENDIF
     342
     343    IF (in_var%ndim .EQ. 2)  THEN
     344       in_var%dimlen(3) = 1
     345    ENDIF
     346
     347    ndim = MIN(in_var%ndim, 3)
     348    count = (/ 1, 1, 1 /)
     349    count(1:ndim) = in_var%dimlen(1:ndim)
     350
     351 END SUBROUTINE get_netcdf_start_and_count
    347352
    348353
     
    353358!> output.
    354359!------------------------------------------------------------------------------!
    355     SUBROUTINE netcdf_define_variable(var, ncid)
    356 
    357         TYPE(nc_var), INTENT(INOUT) ::  var
    358         INTEGER, INTENT(IN)         ::  ncid
    359 
    360         CALL check(nf90_def_var(ncid, var % name, NF90_FLOAT,       var % dimids(1:var % ndim), var % varid))
    361         CALL check(nf90_put_att(ncid, var % varid, "long_name",     var % long_name))
    362         CALL check(nf90_put_att(ncid, var % varid, "units",         var % units))
    363         IF ( var % lod .GE. 0 )  THEN
    364            CALL check(nf90_put_att(ncid, var % varid, "lod",           var % lod))
    365         ENDIF
    366         CALL check(nf90_put_att(ncid, var % varid, "source",        var % source))
    367         CALL check(nf90_put_att(ncid, var % varid, "_FillValue",    NF90_FILL_REAL))
    368 
    369     END SUBROUTINE netcdf_define_variable
     360 SUBROUTINE netcdf_define_variable(var, ncid)
     361
     362     TYPE(nc_var), INTENT(INOUT) ::  var
     363     INTEGER, INTENT(IN)         ::  ncid
     364
     365     CALL check(nf90_def_var(ncid, var%name, NF90_FLOAT,       var%dimids(1:var%ndim), var%varid))
     366     CALL check(nf90_put_att(ncid, var%varid, "long_name",     var%long_name))
     367     CALL check(nf90_put_att(ncid, var%varid, "units",         var%units))
     368     IF ( var%lod .GE. 0 )  THEN
     369        CALL check(nf90_put_att(ncid, var%varid, "lod",           var%lod))
     370     ENDIF
     371     CALL check(nf90_put_att(ncid, var%varid, "source",        var%source))
     372     CALL check(nf90_put_att(ncid, var%varid, "_FillValue",    NF90_FILL_REAL))
     373
     374 END SUBROUTINE netcdf_define_variable
    370375   
    371376
     
    377382!> for writing output variables in update_output().
    378383!------------------------------------------------------------------------------!
    379     SUBROUTINE netcdf_get_dimensions(var, ncid)
    380 
    381         TYPE(nc_var), INTENT(INOUT) ::  var
    382         INTEGER, INTENT(IN)         ::  ncid
    383         INTEGER                     ::  i
    384         CHARACTER(SNAME)            ::  null
    385 
    386         DO i = 1, var % ndim
    387            CALL check(nf90_inquire_dimension(ncid, var % dimids(i), &
    388                                              name = null, &
    389                                              len  = var % dimlen(i)  ) )
    390         ENDDO
    391 
    392     END SUBROUTINE netcdf_get_dimensions
     384 SUBROUTINE netcdf_get_dimensions(var, ncid)
     385
     386     TYPE(nc_var), INTENT(INOUT) ::  var
     387     INTEGER, INTENT(IN)         ::  ncid
     388     INTEGER                     ::  i
     389     CHARACTER(SNAME)            ::  null
     390
     391     DO  i = 1, var%ndim
     392        CALL check(nf90_inquire_dimension(ncid, var%dimids(i), &
     393                                          name = null, &
     394                                          len  = var%dimlen(i)  ) )
     395     ENDDO
     396
     397 END SUBROUTINE netcdf_get_dimensions
    393398
    394399
     
    399404!> resulting settings in the 'cfg' data structure.
    400405!------------------------------------------------------------------------------!
    401     SUBROUTINE parse_command_line_arguments( cfg )
    402 
    403        TYPE(inifor_config), INTENT(INOUT) ::  cfg
    404 
    405        CHARACTER(LEN=PATH)                ::  option, arg
    406        INTEGER                            ::  arg_count, i
    407 
    408        cfg % p0_is_set = .FALSE.
    409        cfg % ug_defined_by_user = .FALSE.
    410        cfg % vg_defined_by_user = .FALSE.
    411        cfg % flow_prefix_is_set = .FALSE.
    412        cfg % input_prefix_is_set = .FALSE.
    413        cfg % radiation_prefix_is_set = .FALSE.
    414        cfg % soil_prefix_is_set = .FALSE.
    415        cfg % soilmoisture_prefix_is_set = .FALSE.
    416 
    417        arg_count = COMMAND_ARGUMENT_COUNT()
    418        IF (arg_count .GT. 0)  THEN
    419 
    420           message = "The -clon and -clat command line options are depricated. " // &
    421              "Please remove them form your inifor command and specify the " // &
    422              "location of the PALM-4U origin either" // NEW_LINE(' ') // &
    423              "   - by setting the namelist parameters 'longitude' and 'latitude', or" // NEW_LINE(' ') // &
    424              "   - by providing a static driver netCDF file via the -static command-line option."
    425 
    426           i = 1
    427           DO WHILE (i .LE. arg_count)
    428 
    429              CALL GET_COMMAND_ARGUMENT( i, option )
    430 
    431              SELECT CASE( TRIM(option) )
     406 SUBROUTINE parse_command_line_arguments( cfg )
     407
     408    TYPE(inifor_config), INTENT(INOUT) ::  cfg
     409
     410    CHARACTER(LEN=PATH)                ::  option, arg
     411    INTEGER                            ::  arg_count, i
     412
     413    cfg%p0_is_set = .FALSE.
     414    cfg%ug_defined_by_user = .FALSE.
     415    cfg%vg_defined_by_user = .FALSE.
     416    cfg%flow_prefix_is_set = .FALSE.
     417    cfg%input_prefix_is_set = .FALSE.
     418    cfg%radiation_prefix_is_set = .FALSE.
     419    cfg%soil_prefix_is_set = .FALSE.
     420    cfg%soilmoisture_prefix_is_set = .FALSE.
     421
     422    arg_count = COMMAND_ARGUMENT_COUNT()
     423    IF (arg_count .GT. 0)  THEN
     424
     425       message = "The -clon and -clat command line options are depricated. " // &
     426          "Please remove them form your inifor command and specify the " // &
     427          "location of the PALM-4U origin either" // NEW_LINE(' ') // &
     428          "   - by setting the namelist parameters 'longitude' and 'latitude', or" // NEW_LINE(' ') // &
     429          "   - by providing a static driver netCDF file via the -static command-line option."
     430
     431       i = 1
     432       DO WHILE (i .LE. arg_count)
     433
     434          CALL GET_COMMAND_ARGUMENT( i, option )
     435
     436          SELECT CASE( TRIM(option) )
    432437
    433438             CASE( '--averaging-mode' )
    434439                CALL get_option_argument( i, arg )
    435                 cfg % averaging_mode = TRIM(arg)
     440                cfg%averaging_mode = TRIM(arg)
    436441
    437442             CASE( '-date', '-d', '--date' )
    438443                CALL get_option_argument( i, arg )
    439                 cfg % start_date = TRIM(arg)
     444                cfg%start_date = TRIM(arg)
    440445
    441446             CASE( '--debug' )
    442                 cfg % debug = .TRUE.
     447                cfg%debug = .TRUE.
    443448
    444449             CASE( '-z0', '-z', '--elevation' )
    445450                CALL get_option_argument( i, arg )
    446                 READ(arg, *) cfg % z0
     451                READ(arg, *) cfg%z0
    447452
    448453             CASE( '-p0', '-r', '--surface-pressure' )
    449                 cfg % p0_is_set = .TRUE.
    450                 CALL get_option_argument( i, arg )
    451                 READ(arg, *) cfg % p0
     454                cfg%p0_is_set = .TRUE.
     455                CALL get_option_argument( i, arg )
     456                READ(arg, *) cfg%p0
    452457
    453458             CASE( '-ug', '-u', '--geostrophic-u' )
    454                 cfg % ug_defined_by_user = .TRUE.
    455                 CALL get_option_argument( i, arg )
    456                 READ(arg, *) cfg % ug
     459                cfg%ug_defined_by_user = .TRUE.
     460                CALL get_option_argument( i, arg )
     461                READ(arg, *) cfg%ug
    457462
    458463             CASE( '-vg', '-v', '--geostrophic-v' )
    459                 cfg % vg_defined_by_user = .TRUE.
    460                 CALL get_option_argument( i, arg )
    461                 READ(arg, *) cfg % vg
     464                cfg%vg_defined_by_user = .TRUE.
     465                CALL get_option_argument( i, arg )
     466                READ(arg, *) cfg%vg
    462467
    463468             CASE( '-clon', '-clat' )
     
    466471             CASE( '-path', '-p', '--path' )
    467472                CALL get_option_argument( i, arg )
    468                  cfg % input_path = TRIM(arg)
     473                 cfg%input_path = TRIM(arg)
    469474
    470475             CASE( '-hhl', '-l', '--hhl-file' )
    471476                CALL get_option_argument( i, arg )
    472                 cfg % hhl_file = TRIM(arg)
     477                cfg%hhl_file = TRIM(arg)
    473478
    474479             CASE( '--input-prefix')
    475480                CALL get_option_argument( i, arg )
    476                 cfg % input_prefix = TRIM(arg)
    477                 cfg % input_prefix_is_set = .TRUE.
     481                cfg%input_prefix = TRIM(arg)
     482                cfg%input_prefix_is_set = .TRUE.
    478483   
    479484             CASE( '-a', '--averaging-angle' )
    480485                CALL get_option_argument( i, arg )
    481                 READ(arg, *) cfg % averaging_angle
     486                READ(arg, *) cfg%averaging_angle
    482487
    483488             CASE( '-static', '-t', '--static-driver' )
    484489                CALL get_option_argument( i, arg )
    485                 cfg % static_driver_file = TRIM(arg)
     490                cfg%static_driver_file = TRIM(arg)
    486491
    487492             CASE( '-soil', '-s', '--soil-file')
    488493                CALL get_option_argument( i, arg )
    489                 cfg % soiltyp_file = TRIM(arg)
     494                cfg%soiltyp_file = TRIM(arg)
    490495
    491496             CASE( '--flow-prefix')
    492497                CALL get_option_argument( i, arg )
    493                 cfg % flow_prefix = TRIM(arg)
    494                 cfg % flow_prefix_is_set = .TRUE.
     498                cfg%flow_prefix = TRIM(arg)
     499                cfg%flow_prefix_is_set = .TRUE.
    495500   
    496501             CASE( '--radiation-prefix')
    497502                CALL get_option_argument( i, arg )
    498                 cfg % radiation_prefix = TRIM(arg)
    499                 cfg % radiation_prefix_is_set = .TRUE.
     503                cfg%radiation_prefix = TRIM(arg)
     504                cfg%radiation_prefix_is_set = .TRUE.
    500505   
    501506             CASE( '--soil-prefix')
    502507                CALL get_option_argument( i, arg )
    503                 cfg % soil_prefix = TRIM(arg)
    504                 cfg % soil_prefix_is_set = .TRUE.
     508                cfg%soil_prefix = TRIM(arg)
     509                cfg%soil_prefix_is_set = .TRUE.
    505510   
    506511             CASE( '--soilmoisture-prefix')
    507512                CALL get_option_argument( i, arg )
    508                 cfg % soilmoisture_prefix = TRIM(arg)
    509                 cfg % soilmoisture_prefix_is_set = .TRUE.
     513                cfg%soilmoisture_prefix = TRIM(arg)
     514                cfg%soilmoisture_prefix_is_set = .TRUE.
    510515
    511516             CASE( '-o', '--output' )
    512517                CALL get_option_argument( i, arg )
    513                 cfg % output_file = TRIM(arg)
     518                cfg%output_file = TRIM(arg)
    514519
    515520             CASE( '-n', '--namelist' )
    516521                CALL get_option_argument( i, arg )
    517                 cfg % namelist_file = TRIM(arg)
     522                cfg%namelist_file = TRIM(arg)
    518523
    519524             CASE( '-mode', '-i', '--init-mode' )
    520525                CALL get_option_argument( i, arg )
    521                 cfg % ic_mode = TRIM(arg)
     526                cfg%ic_mode = TRIM(arg)
    522527
    523528             CASE( '-f', '--forcing-mode' )
    524529                CALL get_option_argument( i, arg )
    525                 cfg % bc_mode = TRIM(arg)
     530                cfg%bc_mode = TRIM(arg)
    526531
    527532             CASE( '--version' )
    528                 CALL print_version()
     533                CALL print_version
    529534                STOP
    530535
    531536             CASE( '--help' )
    532                 CALL print_version()
     537                CALL print_version
    533538                PRINT *, ""
    534539                PRINT *, "For a list of command-line options have a look at the README file."
     
    539544                CALL inifor_abort('parse_command_line_arguments', message)
    540545
    541              END SELECT
    542 
    543              i = i + 1
    544 
    545           ENDDO
    546 
    547        ELSE
    548             
    549           message = "No arguments present, using default input and output files"
    550           CALL report('parse_command_line_arguments', message)
    551 
    552        ENDIF
    553 
    554    END SUBROUTINE parse_command_line_arguments
     546          END SELECT
     547
     548          i = i + 1
     549
     550       ENDDO
     551
     552    ELSE
     553         
     554       message = "No arguments present, using default input and output files"
     555       CALL report('parse_command_line_arguments', message)
     556
     557    ENDIF
     558
     559 END SUBROUTINE parse_command_line_arguments
    555560
    556561   
    557562
    558    SUBROUTINE get_datetime_file_list( start_date_string, start_hour, end_hour, &
    559                                       step_hour, input_path, prefix, suffix,   &
    560                                       file_list )
    561 
    562       CHARACTER (LEN=DATE), INTENT(IN) ::  start_date_string
    563       CHARACTER (LEN=*),    INTENT(IN) ::  prefix, suffix, input_path
    564       INTEGER,              INTENT(IN) ::  start_hour, end_hour, step_hour
    565       CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) ::  file_list(:)
    566 
    567       INTEGER             ::  number_of_intervals, hour, i
    568       CHARACTER(LEN=DATE) ::  date_string
    569 
    570       number_of_intervals = CEILING( REAL(end_hour - start_hour) / step_hour )
    571       ALLOCATE( file_list(number_of_intervals + 1) )
    572 
    573       DO i = 0, number_of_intervals
    574 
    575          hour = start_hour + i * step_hour
    576          date_string = add_hours_to(start_date_string, hour)
    577 
    578          file_list(i+1) = TRIM(input_path) // TRIM(prefix) //                  &
    579                           TRIM(date_string) // TRIM(suffix) // '.nc'
    580 
    581       ENDDO
    582 
    583    END SUBROUTINE get_datetime_file_list
     563 SUBROUTINE get_datetime_file_list( start_date_string, start_hour, end_hour, &
     564                                    step_hour, input_path, prefix, suffix,   &
     565                                    file_list )
     566
     567    CHARACTER (LEN=DATE), INTENT(IN) ::  start_date_string
     568    CHARACTER (LEN=*),    INTENT(IN) ::  prefix, suffix, input_path
     569    INTEGER,              INTENT(IN) ::  start_hour, end_hour, step_hour
     570    CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) ::  file_list(:)
     571
     572    INTEGER             ::  number_of_intervals, hour, i
     573    CHARACTER(LEN=DATE) ::  date_string
     574
     575    number_of_intervals = CEILING( REAL(end_hour - start_hour) / step_hour )
     576    ALLOCATE( file_list(number_of_intervals + 1) )
     577
     578    DO i = 0, number_of_intervals
     579
     580       hour = start_hour + i * step_hour
     581       date_string = add_hours_to(start_date_string, hour)
     582
     583       file_list(i+1) = TRIM(input_path) // TRIM(prefix) //                  &
     584                        TRIM(date_string) // TRIM(suffix) // '.nc'
     585
     586    ENDDO
     587
     588 END SUBROUTINE get_datetime_file_list
    584589
    585590!------------------------------------------------------------------------------!
     
    589594!> prefixes and suffixes.
    590595!------------------------------------------------------------------------------!
    591    SUBROUTINE get_input_file_list( start_date_string, start_hour, end_hour,    &
    592                                    step_hour, input_path, prefix, suffix,      &
    593                                    file_list, nocheck )
    594 
    595       CHARACTER (LEN=DATE), INTENT(IN) ::  start_date_string
    596       CHARACTER (LEN=*),    INTENT(IN) ::  prefix, suffix, input_path
    597       INTEGER,              INTENT(IN) ::  start_hour, end_hour, step_hour
    598       CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) ::  file_list(:)
    599       LOGICAL, OPTIONAL, INTENT(IN)    ::  nocheck
    600 
    601       INTEGER ::  i
    602       LOGICAL ::  check_files
    603 
    604       CALL get_datetime_file_list( start_date_string, start_hour, end_hour,    &
    605                                    step_hour, input_path, prefix, suffix,      &
    606                                    file_list )
    607 
    608       check_files = .TRUE.
    609       IF ( PRESENT ( nocheck ) )  THEN
    610          IF ( nocheck )  check_files = .FALSE.
    611       ENDIF
    612 
    613       IF ( check_files )  THEN
    614 
    615          tip = "Please check if you specified the correct file prefix " //     &
    616                "using the options --input-prefix, --flow-prefix, etc."
    617 
    618          DO i = 1, SIZE(file_list)
    619              CALL verify_file(file_list(i), 'input', tip)
    620          ENDDO
    621 
    622       ENDIF
    623 
    624    END SUBROUTINE get_input_file_list
     596 SUBROUTINE get_input_file_list( start_date_string, start_hour, end_hour,    &
     597                                 step_hour, input_path, prefix, suffix,      &
     598                                 file_list, nocheck )
     599
     600    CHARACTER (LEN=DATE), INTENT(IN) ::  start_date_string
     601    CHARACTER (LEN=*),    INTENT(IN) ::  prefix, suffix, input_path
     602    INTEGER,              INTENT(IN) ::  start_hour, end_hour, step_hour
     603    CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) ::  file_list(:)
     604    LOGICAL, OPTIONAL, INTENT(IN)    ::  nocheck
     605
     606    INTEGER ::  i
     607    LOGICAL ::  check_files
     608
     609    CALL get_datetime_file_list( start_date_string, start_hour, end_hour,    &
     610                                 step_hour, input_path, prefix, suffix,      &
     611                                 file_list )
     612
     613    check_files = .TRUE.
     614    IF ( PRESENT ( nocheck ) )  THEN
     615       IF ( nocheck )  check_files = .FALSE.
     616    ENDIF
     617
     618    IF ( check_files )  THEN
     619
     620       tip = "Please check if you specified the correct file prefix " //     &
     621             "using the options --input-prefix, --flow-prefix, etc."
     622
     623       DO i = 1, SIZE(file_list)
     624           CALL verify_file(file_list(i), 'input', tip)
     625       ENDDO
     626
     627    ENDIF
     628
     629 END SUBROUTINE get_input_file_list
    625630
    626631
     
    630635!> Abort INIFOR if the given file is not present.
    631636!------------------------------------------------------------------------------!
    632    SUBROUTINE verify_file(file_name, file_kind, tip)
    633 
    634       CHARACTER(LEN=*), INTENT(IN)           ::  file_name, file_kind
    635       CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  tip
    636 
    637       IF (.NOT. file_present(file_name))  THEN
    638 
    639          IF (LEN(TRIM(file_name)) == 0)  THEN
    640 
    641             message = "No name was given for the " // TRIM(file_kind) // " file."
    642 
    643          ELSE
    644 
    645             message = "The " // TRIM(file_kind) // " file '" //                &
    646                       TRIM(file_name) // "' was not found."
    647 
    648             IF (PRESENT(tip))  THEN
    649                message = TRIM(message) // " " // TRIM(tip)
    650             ENDIF
    651 
    652          ENDIF
    653 
    654          CALL inifor_abort('verify_file', message)
    655 
    656       ENDIF
    657 
    658       message = "Set up input file name '" // TRIM(file_name) // "'"
    659       CALL report('verify_file', message)
    660 
    661    END SUBROUTINE verify_file
     637 SUBROUTINE verify_file(file_name, file_kind, tip)
     638
     639    CHARACTER(LEN=*), INTENT(IN)           ::  file_name, file_kind
     640    CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  tip
     641
     642    IF (.NOT. file_present(file_name))  THEN
     643
     644       IF (LEN(TRIM(file_name)) == 0)  THEN
     645
     646          message = "No name was given for the " // TRIM(file_kind) // " file."
     647
     648       ELSE
     649
     650          message = "The " // TRIM(file_kind) // " file '" //                &
     651                    TRIM(file_name) // "' was not found."
     652
     653          IF (PRESENT(tip))  THEN
     654             message = TRIM(message) // " " // TRIM(tip)
     655          ENDIF
     656
     657       ENDIF
     658
     659       CALL inifor_abort('verify_file', message)
     660
     661    ENDIF
     662
     663    message = "Set up input file name '" // TRIM(file_name) // "'"
     664    CALL report('verify_file', message)
     665
     666 END SUBROUTINE verify_file
    662667
    663668
     
    668673!> i+1 of the argument list.
    669674!------------------------------------------------------------------------------!
    670    SUBROUTINE get_option_argument(i, arg)
    671       CHARACTER(LEN=PATH), INTENT(INOUT) ::  arg
    672       INTEGER, INTENT(INOUT)             ::  i
    673 
    674       i = i + 1
    675       CALL GET_COMMAND_ARGUMENT(i, arg)
    676 
    677    END SUBROUTINE
     675 SUBROUTINE get_option_argument(i, arg)
     676    CHARACTER(LEN=PATH), INTENT(INOUT) ::  arg
     677    INTEGER, INTENT(INOUT)             ::  i
     678
     679    i = i + 1
     680    CALL GET_COMMAND_ARGUMENT(i, arg)
     681
     682 END SUBROUTINE
    678683
    679684
     
    683688!> Checks the INIFOR configuration 'cfg' for plausibility.
    684689!------------------------------------------------------------------------------!
    685    SUBROUTINE validate_config(cfg)
    686       TYPE(inifor_config), INTENT(IN) ::  cfg
    687 
    688       CALL verify_file(cfg % hhl_file, 'HHL')
    689       CALL verify_file(cfg % namelist_file, 'NAMELIST')
    690       CALL verify_file(cfg % soiltyp_file, 'SOILTYP')
    691 
    692 !
    693 !--   Only check optional static driver file name, if it has been given.
    694       IF (TRIM(cfg % static_driver_file) .NE. '')  THEN
    695          CALL verify_file(cfg % static_driver_file, 'static driver')
    696       ENDIF
    697 
    698       SELECT CASE( TRIM(cfg % ic_mode) )
    699       CASE( 'profile', 'volume')
    700       CASE DEFAULT
    701          message = "Initialization mode '" // TRIM(cfg % ic_mode) //&
    702                    "' is not supported. " //&
    703                    "Please select either 'profile' or 'volume', " //&
    704                    "or omit the -i/--init-mode/-mode option entirely, which corresponds "//&
    705                    "to the latter."
    706          CALL inifor_abort( 'validate_config', message )
    707       END SELECT
    708 
    709 
    710       SELECT CASE( TRIM(cfg % bc_mode) )
    711       CASE( 'real', 'ideal')
    712       CASE DEFAULT
    713          message = "Forcing mode '" // TRIM(cfg % bc_mode) //&
    714                    "' is not supported. " //&
    715                    "Please select either 'real' or 'ideal', " //&
    716                    "or omit the -f/--forcing-mode option entirely, which corresponds "//&
    717                    "to the latter."
    718          CALL inifor_abort( 'validate_config', message )
    719       END SELECT
    720 
    721       SELECT CASE( TRIM(cfg % averaging_mode) )
    722       CASE( 'level' )
    723       CASE( 'height' )
    724          message = "Averaging mode '" // TRIM(cfg % averaging_mode) //&
    725                    "' is currently not supported. " //&
    726                    "Please use level-based averaging by selecting 'level', " //&
    727                    "or by omitting the --averaging-mode option entirely."
    728          CALL inifor_abort( 'validate_config', message )
    729       CASE DEFAULT
    730          message = "Averaging mode '" // TRIM(cfg % averaging_mode) //&
    731                    "' is not supported. " //&
    732          !          "Please select either 'height' or 'level', " //&
    733          !          "or omit the --averaging-mode option entirely, which corresponds "//&
    734          !          "to the latter."
    735                    "Please use level-based averaging by selecting 'level', " //&
    736                    "or by omitting the --averaging-mode option entirely."
    737          CALL inifor_abort( 'validate_config', message )
    738       END SELECT
    739 
    740       IF ( cfg % ug_defined_by_user .NEQV. cfg % vg_defined_by_user )  THEN
    741          message = "You specified only one component of the geostrophic " // &
    742                    "wind. Please specify either both or none."
    743          CALL inifor_abort( 'validate_config', message )
    744       ENDIF
    745 
    746    END SUBROUTINE validate_config
    747 
    748 
    749    SUBROUTINE get_cosmo_grid( cfg, soil_file, rlon, rlat, hhl, hfl, depths, &
    750                               d_depth, d_depth_rho_inv, phi_n, lambda_n,       &
    751                               phi_equat,                                       &
    752                               lonmin_cosmo, lonmax_cosmo,                      &
    753                               latmin_cosmo, latmax_cosmo,                      &
    754                               nlon, nlat, nlev, ndepths )
    755 
    756       TYPE(inifor_config), INTENT(IN)                      ::  cfg
    757       CHARACTER(LEN=PATH), INTENT(IN)                      ::  soil_file !< list of soil input files (temperature, moisture, <prefix>YYYYMMDDHH-soil.nc)
    758       REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  rlon      !< longitudes of COSMO-DE's rotated-pole grid
    759       REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  rlat      !< latitudes of COSMO-DE's rotated-pole grid
    760       REAL(dp), DIMENSION(:,:,:), ALLOCATABLE, INTENT(OUT) ::  hhl       !< heights of half layers (cell faces) above sea level in COSMO-DE, read in from external file
    761       REAL(dp), DIMENSION(:,:,:), ALLOCATABLE, INTENT(OUT) ::  hfl       !< heights of full layers (cell centres) above sea level in COSMO-DE, computed as arithmetic average of hhl
    762       REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  depths    !< COSMO-DE's TERRA-ML soil layer depths
    763       REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  d_depth
    764       REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  d_depth_rho_inv
    765       REAL(dp), INTENT(OUT)                                ::  phi_n
    766       REAL(dp), INTENT(OUT)                                ::  phi_equat
    767       REAL(dp), INTENT(OUT)                                ::  lambda_n
    768       REAL(dp), INTENT(OUT)                                ::  lonmin_cosmo !< Minimunm longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    769       REAL(dp), INTENT(OUT)                                ::  lonmax_cosmo !< Maximum longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    770       REAL(dp), INTENT(OUT)                                ::  latmin_cosmo !< Minimunm latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    771       REAL(dp), INTENT(OUT)                                ::  latmax_cosmo !< Maximum latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
    772       INTEGER, INTENt(OUT)                                 ::  nlon, nlat, nlev, ndepths
    773 
    774       TYPE(nc_var) ::  cosmo_var !< COSMO dummy variable, used for reading HHL, rlon, rlat
    775       INTEGER      ::  k
    776 
    777 !
    778 !--   Read in COSMO's heights of half layers (vertical cell faces)
    779       cosmo_var % name = NC_HHL_NAME
    780       CALL get_netcdf_variable( cfg % hhl_file, cosmo_var, hhl )
    781       CALL get_netcdf_dim_vector( cfg % hhl_file, NC_RLON_NAME, rlon )
    782       CALL get_netcdf_dim_vector( cfg % hhl_file, NC_RLAT_NAME, rlat )
    783       CALL get_netcdf_dim_vector( soil_file, NC_DEPTH_NAME, depths)
    784  CALL run_control( 'time', 'read' )
    785 
    786       CALL reverse( hhl )
    787       nlon = SIZE( hhl, 1 )
    788       nlat = SIZE( hhl, 2 )
    789       nlev = SIZE( hhl, 3 )
    790       ndepths = SIZE( depths )
    791 
    792  CALL run_control( 'time', 'comp' )
    793 
    794       ALLOCATE( hfl( nlon, nlat, nlev-1 ) )
    795       ALLOCATE( d_depth( ndepths ), d_depth_rho_inv( ndepths ) )
    796  CALL run_control('time', 'alloc')
    797 
    798       CALL get_soil_layer_thickness( depths, d_depth )
    799       d_depth_rho_inv = 1.0_dp / ( d_depth * RHO_L )
    800 
    801 !
    802 !--   Compute COSMO's heights of full layers (cell centres)
    803       DO k = 1, nlev-1
    804          hfl(:,:,k) = 0.5_dp * ( hhl(:,:,k) +                                  &
    805                                  hhl(:,:,k+1) )
    806       ENDDO
    807 !
    808 !--   COSMO rotated pole coordinates
    809       phi_n = TO_RADIANS                                                       &
    810             * get_netcdf_variable_attribute( cfg % hhl_file,                   &
    811                                              NC_ROTATED_POLE_NAME,             &
    812                                              NC_POLE_LATITUDE_NAME )
    813 
    814       lambda_n = TO_RADIANS                                                    &
    815                * get_netcdf_variable_attribute( cfg % hhl_file,                &
    816                                                 NC_ROTATED_POLE_NAME,          &
    817                                                 NC_POLE_LONGITUDE_NAME )
    818 
    819       phi_equat = 90.0_dp * TO_RADIANS - phi_n
    820 
    821       lonmin_cosmo = MINVAL( rlon ) * TO_RADIANS
    822       lonmax_cosmo = MAXVAL( rlon ) * TO_RADIANS
    823       latmin_cosmo = MINVAL( rlat ) * TO_RADIANS
    824       latmax_cosmo = MAXVAL( rlat ) * TO_RADIANS
    825  CALL run_control('time', 'comp')
    826 
    827    END SUBROUTINE get_cosmo_grid
     690 SUBROUTINE validate_config(cfg)
     691    TYPE(inifor_config), INTENT(IN) ::  cfg
     692
     693    CALL verify_file(cfg%hhl_file, 'HHL')
     694    CALL verify_file(cfg%namelist_file, 'NAMELIST')
     695    CALL verify_file(cfg%soiltyp_file, 'SOILTYP')
     696
     697!
     698!-- Only check optional static driver file name, if it has been given.
     699    IF (TRIM(cfg%static_driver_file) .NE. '')  THEN
     700       CALL verify_file(cfg%static_driver_file, 'static driver')
     701    ENDIF
     702
     703    SELECT CASE( TRIM(cfg%ic_mode) )
     704       CASE( 'profile', 'volume')
     705       CASE DEFAULT
     706          message = "Initialization mode '" // TRIM(cfg%ic_mode) //&
     707                    "' is not supported. " //&
     708                    "Please select either 'profile' or 'volume', " //&
     709                    "or omit the -i/--init-mode/-mode option entirely, which corresponds "//&
     710                    "to the latter."
     711          CALL inifor_abort( 'validate_config', message )
     712    END SELECT
     713
     714    SELECT CASE( TRIM(cfg%bc_mode) )
     715       CASE( 'real', 'ideal')
     716       CASE DEFAULT
     717          message = "Forcing mode '" // TRIM(cfg%bc_mode) //&
     718                    "' is not supported. " //&
     719                    "Please select either 'real' or 'ideal', " //&
     720                    "or omit the -f/--forcing-mode option entirely, which corresponds "//&
     721                    "to the latter."
     722          CALL inifor_abort( 'validate_config', message )
     723    END SELECT
     724
     725    SELECT CASE( TRIM(cfg%averaging_mode) )
     726       CASE( 'level' )
     727       CASE( 'height' )
     728          message = "Averaging mode '" // TRIM(cfg%averaging_mode) //&
     729                    "' is currently not supported. " //&
     730                    "Please use level-based averaging by selecting 'level', " //&
     731                    "or by omitting the --averaging-mode option entirely."
     732          CALL inifor_abort( 'validate_config', message )
     733       CASE DEFAULT
     734          message = "Averaging mode '" // TRIM(cfg%averaging_mode) //&
     735                    "' is not supported. " //&
     736          !          "Please select either 'height' or 'level', " //&
     737          !          "or omit the --averaging-mode option entirely, which corresponds "//&
     738          !          "to the latter."
     739                    "Please use level-based averaging by selecting 'level', " //&
     740                    "or by omitting the --averaging-mode option entirely."
     741          CALL inifor_abort( 'validate_config', message )
     742    END SELECT
     743
     744    IF ( cfg%ug_defined_by_user .NEQV. cfg%vg_defined_by_user )  THEN
     745       message = "You specified only one component of the geostrophic " // &
     746                 "wind. Please specify either both or none."
     747       CALL inifor_abort( 'validate_config', message )
     748    ENDIF
     749
     750 END SUBROUTINE validate_config
     751
     752
     753 SUBROUTINE get_cosmo_grid( cfg, soil_file, rlon, rlat, hhl, hfl, depths, &
     754                            d_depth, d_depth_rho_inv, phi_n, lambda_n,       &
     755                            phi_equat,                                       &
     756                            lonmin_cosmo, lonmax_cosmo,                      &
     757                            latmin_cosmo, latmax_cosmo,                      &
     758                            nlon, nlat, nlev, ndepths )
     759
     760    TYPE(inifor_config), INTENT(IN)                      ::  cfg
     761    CHARACTER(LEN=PATH), INTENT(IN)                      ::  soil_file !< list of soil input files (temperature, moisture, <prefix>YYYYMMDDHH-soil.nc)
     762    REAL(wp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  rlon      !< longitudes of COSMO-DE's rotated-pole grid
     763    REAL(wp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  rlat      !< latitudes of COSMO-DE's rotated-pole grid
     764    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, INTENT(OUT) ::  hhl       !< heights of half layers (cell faces) above sea level in COSMO-DE, read in from external file
     765    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, INTENT(OUT) ::  hfl       !< heights of full layers (cell centres) above sea level in COSMO-DE, computed as arithmetic average of hhl
     766    REAL(wp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  depths    !< COSMO-DE's TERRA-ML soil layer depths
     767    REAL(wp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  d_depth
     768    REAL(wp), DIMENSION(:), ALLOCATABLE, INTENT(OUT)     ::  d_depth_rho_inv
     769    REAL(wp), INTENT(OUT)                                ::  phi_n
     770    REAL(wp), INTENT(OUT)                                ::  phi_equat
     771    REAL(wp), INTENT(OUT)                                ::  lambda_n
     772    REAL(wp), INTENT(OUT)                                ::  lonmin_cosmo !< Minimunm longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     773    REAL(wp), INTENT(OUT)                                ::  lonmax_cosmo !< Maximum longitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     774    REAL(wp), INTENT(OUT)                                ::  latmin_cosmo !< Minimunm latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     775    REAL(wp), INTENT(OUT)                                ::  latmax_cosmo !< Maximum latitude of COSMO-DE's rotated-pole grid [COSMO rotated-pole rad]
     776    INTEGER, INTENt(OUT)                                 ::  nlon, nlat, nlev, ndepths
     777
     778    TYPE(nc_var) ::  cosmo_var !< COSMO dummy variable, used for reading HHL, rlon, rlat
     779    INTEGER      ::  k
     780
     781!
     782!-- Read in COSMO's heights of half layers (vertical cell faces)
     783    cosmo_var%name = NC_HHL_NAME
     784    CALL get_netcdf_variable( cfg%hhl_file, cosmo_var, hhl )
     785    CALL get_netcdf_dim_vector( cfg%hhl_file, NC_RLON_NAME, rlon )
     786    CALL get_netcdf_dim_vector( cfg%hhl_file, NC_RLAT_NAME, rlat )
     787    CALL get_netcdf_dim_vector( soil_file, NC_DEPTH_NAME, depths)
     788    CALL log_runtime( 'time', 'read' )
     789
     790    CALL reverse( hhl )
     791    nlon = SIZE( hhl, 1 )
     792    nlat = SIZE( hhl, 2 )
     793    nlev = SIZE( hhl, 3 )
     794    ndepths = SIZE( depths )
     795
     796    CALL log_runtime( 'time', 'comp' )
     797
     798    ALLOCATE( hfl( nlon, nlat, nlev-1 ) )
     799    ALLOCATE( d_depth( ndepths ), d_depth_rho_inv( ndepths ) )
     800    CALL log_runtime('time', 'alloc')
     801
     802    CALL get_soil_layer_thickness( depths, d_depth )
     803    d_depth_rho_inv = 1.0_wp / ( d_depth * RHO_L )
     804
     805!
     806!-- Compute COSMO's heights of full layers (cell centres)
     807    DO  k = 1, nlev-1
     808       hfl(:,:,k) = 0.5_wp * ( hhl(:,:,k) +                                  &
     809                               hhl(:,:,k+1) )
     810    ENDDO
     811!
     812!-- COSMO rotated pole coordinates
     813    phi_n = TO_RADIANS                                                       &
     814          * get_netcdf_variable_attribute( cfg%hhl_file,                   &
     815                                           NC_ROTATED_POLE_NAME,             &
     816                                           NC_POLE_LATITUDE_NAME )
     817
     818    lambda_n = TO_RADIANS                                                    &
     819             * get_netcdf_variable_attribute( cfg%hhl_file,                &
     820                                              NC_ROTATED_POLE_NAME,          &
     821                                              NC_POLE_LONGITUDE_NAME )
     822
     823    phi_equat = 90.0_wp * TO_RADIANS - phi_n
     824
     825    lonmin_cosmo = MINVAL( rlon ) * TO_RADIANS
     826    lonmax_cosmo = MAXVAL( rlon ) * TO_RADIANS
     827    latmin_cosmo = MINVAL( rlat ) * TO_RADIANS
     828    latmax_cosmo = MAXVAL( rlat ) * TO_RADIANS
     829    CALL log_runtime('time', 'comp')
     830
     831 END SUBROUTINE get_cosmo_grid
    828832
    829833
     
    856860!>
    857861!------------------------------------------------------------------------------!
    858     SUBROUTINE get_soil_layer_thickness(depths, d_depth)
    859 
    860        REAL(dp), INTENT(IN)  ::  depths(:)
    861        REAL(dp), INTENT(OUT) ::  d_depth(:)
    862 
    863        d_depth(:) = depths(:)
    864        d_depth(1) = 2.0_dp * depths(1)
    865 
    866     END SUBROUTINE get_soil_layer_thickness
     862 SUBROUTINE get_soil_layer_thickness(depths, d_depth)
     863
     864    REAL(wp), INTENT(IN)  ::  depths(:)
     865    REAL(wp), INTENT(OUT) ::  d_depth(:)
     866
     867    d_depth(:) = depths(:)
     868    d_depth(1) = 2.0_wp * depths(1)
     869
     870 END SUBROUTINE get_soil_layer_thickness
    867871!------------------------------------------------------------------------------!
    868872! Description:
     
    870874!> Check whether the given file is present on the filesystem.
    871875!------------------------------------------------------------------------------!
    872    LOGICAL FUNCTION file_present(filename)
    873       CHARACTER(LEN=PATH), INTENT(IN) ::  filename
    874 
    875       INQUIRE(FILE=filename, EXIST=file_present)
    876 
    877    END FUNCTION file_present
     876 LOGICAL FUNCTION file_present(filename)
     877    CHARACTER(LEN=PATH), INTENT(IN) ::  filename
     878
     879    INQUIRE(FILE=filename, EXIST=file_present)
     880
     881 END FUNCTION file_present
    878882
    879883
     
    888892!> writes the actual data.
    889893!------------------------------------------------------------------------------!
    890    SUBROUTINE setup_netcdf_dimensions(output_file, palm_grid,                  &
    891                                       start_date_string, origin_lon, origin_lat)
    892 
    893        TYPE(nc_file), INTENT(INOUT)      ::  output_file
    894        TYPE(grid_definition), INTENT(IN) ::  palm_grid
    895        CHARACTER (LEN=DATE), INTENT(IN)  ::  start_date_string
    896        REAL(dp), INTENT(IN)              ::  origin_lon, origin_lat
    897 
    898        CHARACTER (LEN=8)     ::  date_string
    899        CHARACTER (LEN=10)    ::  time_string
    900        CHARACTER (LEN=5)     ::  zone_string
    901        CHARACTER (LEN=SNAME) ::  history_string
    902        INTEGER               ::  ncid, nx, ny, nz, nt, dimids(3), dimvarids(3)
    903        REAL(dp)              ::  z0
    904 
    905        message = "Initializing PALM-4U dynamic driver file '" //               &
    906                  TRIM(output_file % name) // "' and setting up dimensions."
    907        CALL report('setup_netcdf_dimensions', message)
    908 
    909 !
    910 !--    Create the netCDF file as in netCDF-4/HDF5 format if __netcdf4 preprocessor flag is given
     894 SUBROUTINE setup_netcdf_dimensions( output_file, palm_grid,                  &
     895                                     start_date_string, origin_lon, origin_lat )
     896
     897    TYPE(nc_file), INTENT(INOUT)      ::  output_file
     898    TYPE(grid_definition), INTENT(IN) ::  palm_grid
     899    CHARACTER (LEN=DATE), INTENT(IN)  ::  start_date_string
     900    REAL(wp), INTENT(IN)              ::  origin_lon, origin_lat
     901
     902    CHARACTER (LEN=8)     ::  date_string
     903    CHARACTER (LEN=10)    ::  time_string
     904    CHARACTER (LEN=5)     ::  zone_string
     905    CHARACTER (LEN=SNAME) ::  history_string
     906    INTEGER               ::  ncid, nx, ny, nz, nt, dimids(3), dimvarids(3)
     907    REAL(wp)              ::  z0
     908
     909    message = "Initializing PALM-4U dynamic driver file '" //               &
     910              TRIM(output_file%name) // "' and setting up dimensions."
     911    CALL report('setup_netcdf_dimensions', message)
     912
     913!
     914!-- Create the netCDF file as in netCDF-4/HDF5 format if __netcdf4 preprocessor flag is given
    911915#if defined( __netcdf4 )
    912        CALL check(nf90_create(TRIM(output_file % name), OR(NF90_CLOBBER, NF90_HDF5), ncid))
     916    CALL check(nf90_create(TRIM(output_file%name), OR(NF90_CLOBBER, NF90_HDF5), ncid))
    913917#else
    914        CALL check(nf90_create(TRIM(output_file % name), NF90_CLOBBER, ncid))
     918    CALL check(nf90_create(TRIM(output_file%name), NF90_CLOBBER, ncid))
    915919#endif
    916920
     
    918922!- Section 1: Define NetCDF dimensions and coordinates
    919923!------------------------------------------------------------------------------
    920        nt = SIZE(output_file % time)
    921        nx = palm_grid % nx
    922        ny = palm_grid % ny
    923        nz = palm_grid % nz
    924        z0 = palm_grid % z0
     924    nt = SIZE(output_file%time)
     925    nx = palm_grid%nx
     926    ny = palm_grid%ny
     927    nz = palm_grid%nz
     928    z0 = palm_grid%z0
    925929
    926930
     
    929933!- Section 2: Write global NetCDF attributes
    930934!------------------------------------------------------------------------------
    931        CALL date_and_time(DATE=date_string, TIME=time_string, ZONE=zone_string)
    932        history_string =                                                        &
    933            'Created on '// date_string      //                                 &
    934            ' at '       // time_string(1:2) // ':' // time_string(3:4) //      &
    935            ' (UTC'      // zone_string // ')'
    936 
    937        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'title',          'PALM input file for scenario ...'))
    938        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'institution',    'Deutscher Wetterdienst, Offenbach'))
    939        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'author',         'Eckhard Kadasch, eckhard.kadasch@dwd.de'))
    940        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'history',        TRIM(history_string)))
    941        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'references',     '--'))
    942        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'comment',        '--'))
    943        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'origin_lat',     TRIM(real_to_str(origin_lat*TO_DEGREES, '(F18.13)'))))
    944        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'origin_lon',     TRIM(real_to_str(origin_lon*TO_DEGREES, '(F18.13)'))))
    945 !
    946 !--    FIXME: This is the elevation relative to COSMO-DE/D2 sea level and does
    947 !--    FIXME: not necessarily comply with DHHN2016 (c.f. PALM Input Data
    948 !--    FIXME: Standard v1.9., origin_z)
    949        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'origin_z',       TRIM(real_to_str(z0, '(F18.13)'))))
    950        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'inifor_version', TRIM(VERSION)))
    951        CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'palm_version',   '--'))
     935    CALL date_and_time(DATE=date_string, TIME=time_string, ZONE=zone_string)
     936    history_string =                                                        &
     937        'Created on '// date_string      //                                 &
     938        ' at '       // time_string(1:2) // ':' // time_string(3:4) //      &
     939        ' (UTC'      // zone_string // ')'
     940
     941    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'title',          'PALM input file for scenario ...'))
     942    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'institution',    'Deutscher Wetterdienst, Offenbach'))
     943    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'author',         'Eckhard Kadasch, eckhard.kadasch@dwd.de'))
     944    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'history',        TRIM(history_string)))
     945    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'references',     '--'))
     946    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'comment',        '--'))
     947    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'origin_lat',     TRIM(real_to_str(origin_lat*TO_DEGREES, '(F18.13)'))))
     948    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'origin_lon',     TRIM(real_to_str(origin_lon*TO_DEGREES, '(F18.13)'))))
     949!
     950!-- FIXME: This is the elevation relative to COSMO-DE/D2 sea level and does
     951!-- FIXME: not necessarily comply with DHHN2016 (c.f. PALM Input Data
     952!-- FIXME: Standard v1.9., origin_z)
     953    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'origin_z',       TRIM(real_to_str(z0, '(F18.13)'))))
     954    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'inifor_version', TRIM(VERSION)))
     955    CALL check(nf90_put_att(ncid, NF90_GLOBAL, 'palm_version',   '--'))
    952956
    953957!
     
    957961!------------------------------------------------------------------------------
    958962!
    959 !--    reset dimids first
    960        dimids = (/0, 0, 0/)
    961        CALL check( nf90_def_dim(ncid, "x", nx+1, dimids(1)) )
    962        CALL check( nf90_def_dim(ncid, "y", ny+1, dimids(2)) )
    963        CALL check( nf90_def_dim(ncid, "z", nz, dimids(3)) )
    964 !
    965 !--    save dimids for later
    966        output_file % dimids_scl = dimids
    967 
    968 !
    969 !--    reset dimvarids first
    970        dimvarids = (/0, 0, 0/)
    971        CALL check(nf90_def_var(ncid, "x", NF90_FLOAT, dimids(1), dimvarids(1)))
    972        CALL check(nf90_put_att(ncid, dimvarids(1), "standard_name", "x coordinate of cell centers"))
    973        CALL check(nf90_put_att(ncid, dimvarids(1), "units", "m"))
    974 
    975        CALL check(nf90_def_var(ncid, "y", NF90_FLOAT, dimids(2), dimvarids(2)))
    976        CALL check(nf90_put_att(ncid, dimvarids(2), "standard_name", "y coordinate of cell centers"))
    977        CALL check(nf90_put_att(ncid, dimvarids(2), "units", "m"))
    978 
    979        CALL check(nf90_def_var(ncid, "z", NF90_FLOAT, dimids(3), dimvarids(3)))
    980        CALL check(nf90_put_att(ncid, dimvarids(3), "standard_name", "z coordinate of cell centers"))
    981        CALL check(nf90_put_att(ncid, dimvarids(3), "units", "m"))
    982 !
    983 !--    save dimvarids for later
    984        output_file % dimvarids_scl = dimvarids
    985 
    986 !
    987 !--    overwrite third dimid with the one of depth
    988        CALL check(nf90_def_dim(ncid, "zsoil", SIZE(palm_grid % depths), dimids(3)) )
    989 !
    990 !--    save dimids for later
    991        output_file % dimids_soil = dimids
    992 
    993 !
    994 !--    overwrite third dimvarid with the one of depth
    995        CALL check(nf90_def_var(ncid, "zsoil", NF90_FLOAT, output_file % dimids_soil(3), dimvarids(3)))
    996        CALL check(nf90_put_att(ncid, dimvarids(3), "standard_name", "depth_below_land"))
    997        CALL check(nf90_put_att(ncid, dimvarids(3), "positive", "down"))
    998        CALL check(nf90_put_att(ncid, dimvarids(3), "units", "m"))
    999 !
    1000 !--    save dimvarids for later
    1001        output_file % dimvarids_soil = dimvarids
     963!-- reset dimids first
     964    dimids = (/0, 0, 0/)
     965    CALL check( nf90_def_dim(ncid, "x", nx+1, dimids(1)) )
     966    CALL check( nf90_def_dim(ncid, "y", ny+1, dimids(2)) )
     967    CALL check( nf90_def_dim(ncid, "z", nz, dimids(3)) )
     968!
     969!-- save dimids for later
     970    output_file%dimids_scl = dimids
     971
     972!
     973!-- reset dimvarids first
     974    dimvarids = (/0, 0, 0/)
     975    CALL check(nf90_def_var(ncid, "x", NF90_FLOAT, dimids(1), dimvarids(1)))
     976    CALL check(nf90_put_att(ncid, dimvarids(1), "standard_name", "x coordinate of cell centers"))
     977    CALL check(nf90_put_att(ncid, dimvarids(1), "units", "m"))
     978
     979    CALL check(nf90_def_var(ncid, "y", NF90_FLOAT, dimids(2), dimvarids(2)))
     980    CALL check(nf90_put_att(ncid, dimvarids(2), "standard_name", "y coordinate of cell centers"))
     981    CALL check(nf90_put_att(ncid, dimvarids(2), "units", "m"))
     982
     983    CALL check(nf90_def_var(ncid, "z", NF90_FLOAT, dimids(3), dimvarids(3)))
     984    CALL check(nf90_put_att(ncid, dimvarids(3), "standard_name", "z coordinate of cell centers"))
     985    CALL check(nf90_put_att(ncid, dimvarids(3), "units", "m"))
     986!
     987!-- save dimvarids for later
     988    output_file%dimvarids_scl = dimvarids
     989
     990!
     991!-- overwrite third dimid with the one of depth
     992    CALL check(nf90_def_dim(ncid, "zsoil", SIZE(palm_grid%depths), dimids(3)) )
     993!
     994!-- save dimids for later
     995    output_file%dimids_soil = dimids
     996
     997!
     998!-- overwrite third dimvarid with the one of depth
     999    CALL check(nf90_def_var(ncid, "zsoil", NF90_FLOAT, output_file%dimids_soil(3), dimvarids(3)))
     1000    CALL check(nf90_put_att(ncid, dimvarids(3), "standard_name", "depth_below_land"))
     1001    CALL check(nf90_put_att(ncid, dimvarids(3), "positive", "down"))
     1002    CALL check(nf90_put_att(ncid, dimvarids(3), "units", "m"))
     1003!
     1004!-- save dimvarids for later
     1005    output_file%dimvarids_soil = dimvarids
    10021006!
    10031007!------------------------------------------------------------------------------
     
    10051009!------------------------------------------------------------------------------
    10061010!
    1007 !--    reset dimids first
    1008        dimids = (/0, 0, 0/)
    1009        CALL check(nf90_def_dim(ncid, "xu", nx, dimids(1)) )
    1010        CALL check(nf90_def_dim(ncid, "yv", ny, dimids(2)) )
    1011        CALL check(nf90_def_dim(ncid, "zw", nz-1, dimids(3)) )
    1012 !
    1013 !--    save dimids for later
    1014        output_file % dimids_vel = dimids
    1015 
    1016 !
    1017 !--    reset dimvarids first
    1018        dimvarids = (/0, 0, 0/)
    1019        CALL check(nf90_def_var(ncid, "xu", NF90_FLOAT, dimids(1), dimvarids(1)))
    1020        CALL check(nf90_put_att(ncid, dimvarids(1), "standard_name", "x coordinate of cell faces"))
    1021        CALL check(nf90_put_att(ncid, dimvarids(1), "units", "m"))
    1022 
    1023        CALL check(nf90_def_var(ncid, "yv", NF90_FLOAT, dimids(2), dimvarids(2)))
    1024        CALL check(nf90_put_att(ncid, dimvarids(2), "standard_name", "y coordinate of cell faces"))
    1025        CALL check(nf90_put_att(ncid, dimvarids(2), "units", "m"))
    1026 
    1027        CALL check(nf90_def_var(ncid, "zw", NF90_FLOAT, dimids(3), dimvarids(3)))
    1028        CALL check(nf90_put_att(ncid, dimvarids(3), "standard_name", "z coordinate of cell faces"))
    1029        CALL check(nf90_put_att(ncid, dimvarids(3), "units", "m"))
    1030 !
    1031 !--    save dimvarids for later
    1032        output_file % dimvarids_vel = dimvarids
     1011!-- reset dimids first
     1012    dimids = (/0, 0, 0/)
     1013    CALL check(nf90_def_dim(ncid, "xu", nx, dimids(1)) )
     1014    CALL check(nf90_def_dim(ncid, "yv", ny, dimids(2)) )
     1015    CALL check(nf90_def_dim(ncid, "zw", nz-1, dimids(3)) )
     1016!
     1017!-- save dimids for later
     1018    output_file%dimids_vel = dimids
     1019
     1020!
     1021!-- reset dimvarids first
     1022    dimvarids = (/0, 0, 0/)
     1023    CALL check(nf90_def_var(ncid, "xu", NF90_FLOAT, dimids(1), dimvarids(1)))
     1024    CALL check(nf90_put_att(ncid, dimvarids(1), "standard_name", "x coordinate of cell faces"))
     1025    CALL check(nf90_put_att(ncid, dimvarids(1), "units", "m"))
     1026
     1027    CALL check(nf90_def_var(ncid, "yv", NF90_FLOAT, dimids(2), dimvarids(2)))
     1028    CALL check(nf90_put_att(ncid, dimvarids(2), "standard_name", "y coordinate of cell faces"))
     1029    CALL check(nf90_put_att(ncid, dimvarids(2), "units", "m"))
     1030
     1031    CALL check(nf90_def_var(ncid, "zw", NF90_FLOAT, dimids(3), dimvarids(3)))
     1032    CALL check(nf90_put_att(ncid, dimvarids(3), "standard_name", "z coordinate of cell faces"))
     1033    CALL check(nf90_put_att(ncid, dimvarids(3), "units", "m"))
     1034!
     1035!-- save dimvarids for later
     1036    output_file%dimvarids_vel = dimvarids
    10331037
    10341038!
     
    10361040!- Section 2c: Define time dimension
    10371041!------------------------------------------------------------------------------
    1038        CALL check(nf90_def_dim(ncid, "time", nt, output_file % dimid_time) )
    1039        CALL check(nf90_def_var(ncid, "time", NF90_FLOAT, &
    1040                                              output_file % dimid_time, &
    1041                                              output_file % dimvarid_time))
    1042        CALL check(nf90_put_att(ncid, output_file % dimvarid_time, "standard_name", "time"))
    1043        CALL check(nf90_put_att(ncid, output_file % dimvarid_time, "long_name", "time"))
    1044        CALL check(nf90_put_att(ncid, output_file % dimvarid_time, "units",     &
    1045                                "seconds since " // start_date_string // " UTC"))
    1046 
    1047        CALL check(nf90_enddef(ncid))
     1042    CALL check(nf90_def_dim(ncid, "time", nt, output_file%dimid_time) )
     1043    CALL check(nf90_def_var(ncid, "time", NF90_FLOAT, &
     1044                                          output_file%dimid_time, &
     1045                                          output_file%dimvarid_time))
     1046    CALL check(nf90_put_att(ncid, output_file%dimvarid_time, "standard_name", "time"))
     1047    CALL check(nf90_put_att(ncid, output_file%dimvarid_time, "long_name", "time"))
     1048    CALL check(nf90_put_att(ncid, output_file%dimvarid_time, "units",     &
     1049                            "seconds since " // start_date_string // " UTC"))
     1050
     1051    CALL check(nf90_enddef(ncid))
    10481052
    10491053!
     
    10511055!- Section 3: Write grid coordinates
    10521056!------------------------------------------------------------------------------
    1053        CALL check(nf90_put_var(ncid, output_file % dimvarids_scl(1), palm_grid%x))
    1054        CALL check(nf90_put_var(ncid, output_file % dimvarids_scl(2), palm_grid%y))
    1055        CALL check(nf90_put_var(ncid, output_file % dimvarids_scl(3), palm_grid%z))
    1056 
    1057        CALL check(nf90_put_var(ncid, output_file % dimvarids_vel(1), palm_grid%xu))
    1058        CALL check(nf90_put_var(ncid, output_file % dimvarids_vel(2), palm_grid%yv))
    1059        CALL check(nf90_put_var(ncid, output_file % dimvarids_vel(3), palm_grid%zw))
    1060 
    1061 !
    1062 !--    TODO Read in soil depths from input file before this.
    1063        CALL check(nf90_put_var(ncid, output_file % dimvarids_soil(3), palm_grid%depths))
    1064 
    1065 !
    1066 !--    Write time vector
    1067        CALL check(nf90_put_var(ncid, output_file % dimvarid_time, output_file % time))
    1068 
    1069 !
    1070 !--    Close the file
    1071        CALL check(nf90_close(ncid))
    1072 
    1073     END SUBROUTINE setup_netcdf_dimensions
     1057    CALL check(nf90_put_var(ncid, output_file%dimvarids_scl(1), palm_grid%x))
     1058    CALL check(nf90_put_var(ncid, output_file%dimvarids_scl(2), palm_grid%y))
     1059    CALL check(nf90_put_var(ncid, output_file%dimvarids_scl(3), palm_grid%z))
     1060
     1061    CALL check(nf90_put_var(ncid, output_file%dimvarids_vel(1), palm_grid%xu))
     1062    CALL check(nf90_put_var(ncid, output_file%dimvarids_vel(2), palm_grid%yv))
     1063    CALL check(nf90_put_var(ncid, output_file%dimvarids_vel(3), palm_grid%zw))
     1064
     1065!
     1066!-- TODO Read in soil depths from input file before this.
     1067    CALL check(nf90_put_var(ncid, output_file%dimvarids_soil(3), palm_grid%depths))
     1068
     1069!
     1070!-- Write time vector
     1071    CALL check(nf90_put_var(ncid, output_file%dimvarid_time, output_file%time))
     1072
     1073!
     1074!-- Close the file
     1075    CALL check(nf90_close(ncid))
     1076
     1077 END SUBROUTINE setup_netcdf_dimensions
    10741078
    10751079
     
    10791083!> Defines the netCDF variables to be written to the dynamic driver file
    10801084!------------------------------------------------------------------------------!
    1081     SUBROUTINE setup_netcdf_variables(filename, output_variable_table)
    1082 
    1083        CHARACTER (LEN=*), INTENT(IN)        ::  filename
    1084        TYPE(nc_var), INTENT(INOUT), TARGET  ::  output_variable_table(:)
    1085 
    1086        TYPE(nc_var), POINTER                ::  var
    1087        INTEGER                              ::  i, ncid
    1088        LOGICAL                              ::  to_be_written
    1089 
    1090        message = "Defining variables in dynamic driver '" // TRIM(filename) // "'."
    1091        CALL report('setup_netcdf_variables', message)
    1092 
    1093        CALL check(nf90_open(TRIM(filename), NF90_WRITE, ncid))
    1094        CALL check(nf90_redef(ncid))
    1095 
    1096        DO i = 1, SIZE(output_variable_table)
    1097 
    1098           var => output_variable_table(i)
    1099 
    1100           !to_be_written = ( var % to_be_processed  .AND. .NOT. var % is_internal) .OR. &
    1101           !                ( var % is_internal  .AND.  debug )
    1102           to_be_written = ( var % to_be_processed  .AND. .NOT. var % is_internal)
    1103 
    1104           IF ( to_be_written )  THEN
    1105              message = "  variable #" // TRIM(str(i)) // " '" // TRIM(var%name) // "'."
    1106              CALL report('setup_netcdf_variables', message)
    1107 
    1108              CALL netcdf_define_variable(var, ncid)
    1109              CALL netcdf_get_dimensions(var, ncid)
    1110           ENDIF
    1111            
    1112        ENDDO
    1113 
    1114        CALL check(nf90_enddef(ncid))
    1115        CALL check(nf90_close(ncid))
    1116 
    1117        message = "Dynamic driver '" // TRIM(filename) // "' initialized successfully."
    1118        CALL report('setup_netcdf_variables', message)
    1119 
    1120     END SUBROUTINE setup_netcdf_variables
     1085 SUBROUTINE setup_netcdf_variables(filename, output_variable_table)
     1086
     1087    CHARACTER (LEN=*), INTENT(IN)        ::  filename
     1088    TYPE(nc_var), INTENT(INOUT), TARGET  ::  output_variable_table(:)
     1089
     1090    TYPE(nc_var), POINTER                ::  var
     1091    INTEGER                              ::  i, ncid
     1092    LOGICAL                              ::  to_be_written
     1093
     1094    message = "Defining variables in dynamic driver '" // TRIM(filename) // "'."
     1095    CALL report('setup_netcdf_variables', message)
     1096
     1097    CALL check(nf90_open(TRIM(filename), NF90_WRITE, ncid))
     1098    CALL check(nf90_redef(ncid))
     1099
     1100    DO i = 1, SIZE(output_variable_table)
     1101
     1102       var => output_variable_table(i)
     1103
     1104       !to_be_written = ( var%to_be_processed  .AND. .NOT. var%is_internal) .OR. &
     1105       !                ( var%is_internal  .AND.  debug )
     1106       to_be_written = ( var%to_be_processed  .AND. .NOT. var%is_internal)
     1107
     1108       IF ( to_be_written )  THEN
     1109          message = "  variable #" // TRIM(str(i)) // " '" // TRIM(var%name) // "'."
     1110          CALL report('setup_netcdf_variables', message)
     1111
     1112          CALL netcdf_define_variable(var, ncid)
     1113          CALL netcdf_get_dimensions(var, ncid)
     1114       ENDIF
     1115       
     1116    ENDDO
     1117
     1118    CALL check(nf90_enddef(ncid))
     1119    CALL check(nf90_close(ncid))
     1120
     1121    message = "Dynamic driver '" // TRIM(filename) // "' initialized successfully."
     1122    CALL report('setup_netcdf_variables', message)
     1123
     1124 END SUBROUTINE setup_netcdf_variables
    11211125
    11221126
     
    11341138!> record netCDF IDs in the 'in_var_list()' member variable.
    11351139!------------------------------------------------------------------------------!
    1136     SUBROUTINE read_input_variables(group, iter, buffer)
    1137        TYPE(io_group), INTENT(INOUT), TARGET       ::  group
    1138        INTEGER, INTENT(IN)                         ::  iter
    1139        TYPE(container), ALLOCATABLE, INTENT(INOUT) ::  buffer(:)
    1140        INTEGER                                     ::  hour, buf_id
    1141        TYPE(nc_var), POINTER                       ::  input_var
    1142        CHARACTER(LEN=PATH), POINTER                ::  input_file
    1143        INTEGER                                     ::  ivar, nbuffers
    1144 
    1145        message = "Reading data for I/O group '" // TRIM(group % in_var_list(1) % name) // "'."
    1146        CALL report('read_input_variables', message)
    1147 
    1148        input_file => group % in_files(iter)
     1140 SUBROUTINE read_input_variables(group, iter, buffer)
     1141    TYPE(io_group), INTENT(INOUT), TARGET       ::  group
     1142    INTEGER, INTENT(IN)                         ::  iter
     1143    TYPE(container), ALLOCATABLE, INTENT(INOUT) ::  buffer(:)
     1144    INTEGER                                     ::  hour, buf_id
     1145    TYPE(nc_var), POINTER                       ::  input_var
     1146    CHARACTER(LEN=PATH), POINTER                ::  input_file
     1147    INTEGER                                     ::  ivar, nbuffers
     1148
     1149    message = "Reading data for I/O group '" // TRIM(group%in_var_list(1)%name) // "'."
     1150    CALL report('read_input_variables', message)
     1151
     1152    input_file => group%in_files(iter)
    11491153
    11501154!
     
    11531157!------------------------------------------------------------------------------
    11541158!
    1155 !--    radiation budgets, precipitation
    1156        IF (group % kind == 'running average' .OR.                              &
    1157            group % kind == 'accumulated')  THEN
    1158 
    1159           IF (SIZE(group % in_var_list) .GT. 1 ) THEN
    1160              message = "I/O groups may not contain more than one " // &
    1161                        "accumulated variable. Group '" // TRIM(group % kind) //&
    1162                        "' contains " //                                        &
    1163                        TRIM( str(SIZE(group % in_var_list)) ) // "."
    1164              CALL inifor_abort('read_input_variables | accumulation', message)
     1159!-- radiation budgets, precipitation
     1160    IF (group%kind == 'running average' .OR.                              &
     1161        group%kind == 'accumulated')  THEN
     1162
     1163       IF (SIZE(group%in_var_list) .GT. 1 ) THEN
     1164          message = "I/O groups may not contain more than one " // &
     1165                    "accumulated variable. Group '" // TRIM(group%kind) //&
     1166                    "' contains " //                                        &
     1167                    TRIM( str(SIZE(group%in_var_list)) ) // "."
     1168          CALL inifor_abort('read_input_variables | accumulation', message)
     1169       ENDIF
     1170
     1171!
     1172!--    use two buffer arrays
     1173       nbuffers = 2
     1174       IF ( .NOT. ALLOCATED( buffer ) )  ALLOCATE( buffer(nbuffers) )
     1175
     1176!
     1177!--    hour of the day
     1178       hour = iter - 1
     1179!
     1180!--    chose correct buffer array
     1181       buf_id = select_buffer(hour)
     1182
     1183       CALL log_runtime('time', 'read')
     1184       IF ( ALLOCATED(buffer(buf_id)%array) )  DEALLOCATE(buffer(buf_id)%array)
     1185       CALL log_runtime('time', 'alloc')
     1186
     1187       input_var => group%in_var_list(1)
     1188       CALL get_netcdf_variable(input_file, input_var, buffer(buf_id)%array)
     1189       CALL report('read_input_variables', "Read accumulated " // TRIM(group%in_var_list(1)%name))
     1190
     1191       IF ( input_var%is_upside_down )  CALL reverse(buffer(buf_id)%array)
     1192       CALL log_runtime('time', 'comp')
     1193         
     1194!------------------------------------------------------------------------------
     1195!- Section 2: Load input buffers for normal I/O groups
     1196!------------------------------------------------------------------------------
     1197    ELSE
     1198
     1199!
     1200!--    Allocate one input buffer per input_variable. If more quantities
     1201!--    have to be computed than input variables exist in this group,
     1202!--    allocate more buffers. For instance, in the thermodynamics group,
     1203!--    there are three input variabels (PP, T, Qv) and four quantities
     1204!--    necessart (P, Theta, Rho, qv) for the corresponding output fields
     1205!--    (p0, Theta, qv, ug, and vg)
     1206       nbuffers = MAX( group%n_inputs, group%n_output_quantities )
     1207       ALLOCATE( buffer(nbuffers) )
     1208       CALL log_runtime('time', 'alloc')
     1209       
     1210!
     1211!--    Read in all input variables, leave extra buffers-if any-untouched.
     1212       DO  ivar = 1, group%n_inputs
     1213
     1214          input_var => group%in_var_list(ivar)
     1215
     1216!
     1217!         Check wheather P or PP is present in input file
     1218          IF (input_var%name == 'P')  THEN
     1219             input_var%name = TRIM( get_pressure_varname(input_file) )
     1220          CALL log_runtime('time', 'read')
    11651221          ENDIF
    11661222
    1167 !
    1168 !--       use two buffer arrays
    1169           nbuffers = 2
    1170           IF ( .NOT. ALLOCATED( buffer ) )  ALLOCATE( buffer(nbuffers) )
    1171 
    1172 !
    1173 !--       hour of the day
    1174           hour = iter - 1
    1175 !
    1176 !--       chose correct buffer array
    1177           buf_id = select_buffer(hour)
    1178 
    1179  CALL run_control('time', 'read')
    1180           IF ( ALLOCATED(buffer(buf_id) % array) )  DEALLOCATE(buffer(buf_id) % array)
    1181  CALL run_control('time', 'alloc')
    1182 
    1183           input_var => group % in_var_list(1)
    1184           CALL get_netcdf_variable(input_file, input_var, buffer(buf_id) % array)
    1185           CALL report('read_input_variables', "Read accumulated " // TRIM(group % in_var_list(1) % name))
    1186 
    1187           IF ( input_var % is_upside_down )  CALL reverse(buffer(buf_id) % array)
    1188  CALL run_control('time', 'comp')
    1189          
    1190 !------------------------------------------------------------------------------
    1191 !- Section 2: Load input buffers for normal I/O groups
    1192 !------------------------------------------------------------------------------
    1193        ELSE
    1194 
    1195 !
    1196 !--       Allocate one input buffer per input_variable. If more quantities
    1197 !--       have to be computed than input variables exist in this group,
    1198 !--       allocate more buffers. For instance, in the thermodynamics group,
    1199 !--       there are three input variabels (PP, T, Qv) and four quantities
    1200 !--       necessart (P, Theta, Rho, qv) for the corresponding output fields
    1201 !--       (p0, Theta, qv, ug, and vg)
    1202           nbuffers = MAX( group % n_inputs, group % n_output_quantities )
    1203           ALLOCATE( buffer(nbuffers) )
    1204  CALL run_control('time', 'alloc')
    1205          
    1206 !
    1207 !--       Read in all input variables, leave extra buffers-if any-untouched.
    1208           DO ivar = 1, group % n_inputs
    1209 
    1210              input_var => group % in_var_list(ivar)
    1211 
    1212 !
    1213 !            Check wheather P or PP is present in input file
    1214              IF (input_var % name == 'P')  THEN
    1215                 input_var % name = TRIM( get_pressure_varname(input_file) )
    1216  CALL run_control('time', 'read')
    1217              ENDIF
    1218 
    1219              CALL get_netcdf_variable(input_file, input_var, buffer(ivar) % array)
    1220 
    1221              IF ( input_var % is_upside_down )  CALL reverse(buffer(ivar) % array)
    1222  CALL run_control('time', 'comp')
    1223 
    1224           ENDDO
    1225        ENDIF
    1226 
    1227     END SUBROUTINE read_input_variables
     1223          CALL get_netcdf_variable(input_file, input_var, buffer(ivar)%array)
     1224
     1225          IF ( input_var%is_upside_down )  CALL reverse(buffer(ivar)%array)
     1226          CALL log_runtime('time', 'comp')
     1227
     1228       ENDDO
     1229    ENDIF
     1230
     1231 END SUBROUTINE read_input_variables
    12281232
    12291233
     
    12341238!> depending on the current hour.
    12351239!------------------------------------------------------------------------------!
    1236     INTEGER FUNCTION select_buffer(hour)
    1237        INTEGER, INTENT(IN) ::  hour
    1238        INTEGER             ::  step
    1239 
    1240        select_buffer = 0
    1241        step = MODULO(hour, 3) + 1
    1242 
    1243        SELECT CASE(step)
     1240 INTEGER FUNCTION select_buffer(hour)
     1241    INTEGER, INTENT(IN) ::  hour
     1242    INTEGER             ::  step
     1243
     1244    select_buffer = 0
     1245    step = MODULO(hour, 3) + 1
     1246
     1247    SELECT CASE(step)
    12441248       CASE(1, 3)
    12451249           select_buffer = 1
     
    12491253           message = "Invalid step '" // TRIM(str(step))
    12501254           CALL inifor_abort('select_buffer', message)
    1251        END SELECT
    1252     END FUNCTION select_buffer
     1255    END SELECT
     1256 END FUNCTION select_buffer
    12531257
    12541258
     
    12591263!> perturbation, 'PP', and returns the appropriate string.
    12601264!------------------------------------------------------------------------------!
    1261     CHARACTER(LEN=2) FUNCTION get_pressure_varname(input_file) RESULT(var)
    1262        CHARACTER(LEN=*) ::  input_file
    1263        INTEGER          ::  ncid, varid
    1264 
    1265        CALL check(nf90_open( TRIM(input_file), NF90_NOWRITE, ncid ))
    1266        IF ( nf90_inq_varid( ncid, 'P', varid ) .EQ. NF90_NOERR )  THEN
    1267 
    1268           var = 'P'
    1269 
    1270        ELSE IF ( nf90_inq_varid( ncid, 'PP', varid ) .EQ. NF90_NOERR )  THEN
    1271 
    1272           var = 'PP'
    1273           CALL report('get_pressure_var', 'Using PP instead of P')
    1274 
    1275        ELSE
    1276 
    1277           message = "Failed to read '" // TRIM(var) // &
    1278                     "' from file '" // TRIM(input_file) // "'."
    1279           CALL inifor_abort('get_pressure_var', message)
    1280 
    1281        ENDIF
    1282 
     1265 CHARACTER(LEN=2) FUNCTION get_pressure_varname(input_file) RESULT(var)
     1266    CHARACTER(LEN=*) ::  input_file
     1267    INTEGER          ::  ncid, varid
     1268
     1269    CALL check(nf90_open( TRIM(input_file), NF90_NOWRITE, ncid ))
     1270    IF ( nf90_inq_varid( ncid, 'P', varid ) .EQ. NF90_NOERR )  THEN
     1271
     1272       var = 'P'
     1273
     1274    ELSE IF ( nf90_inq_varid( ncid, 'PP', varid ) .EQ. NF90_NOERR )  THEN
     1275
     1276       var = 'PP'
     1277       CALL report('get_pressure_var', 'Using PP instead of P')
     1278
     1279    ELSE
     1280
     1281       message = "Failed to read '" // TRIM(var) // &
     1282                 "' from file '" // TRIM(input_file) // "'."
     1283       CALL inifor_abort('get_pressure_var', message)
     1284
     1285    ENDIF
     1286
     1287    CALL check(nf90_close(ncid))
     1288
     1289 END FUNCTION get_pressure_varname
     1290
     1291
     1292!------------------------------------------------------------------------------!
     1293! Description:
     1294! ------------
     1295!> Read the given global attribute form the given netCDF file.
     1296!------------------------------------------------------------------------------!
     1297 FUNCTION get_netcdf_attribute(filename, attribute) RESULT(attribute_value)
     1298
     1299    CHARACTER(LEN=*), INTENT(IN) ::  filename, attribute
     1300    REAL(wp)                     ::  attribute_value
     1301
     1302    INTEGER                      ::  ncid
     1303
     1304    IF ( nf90_open( TRIM(filename), NF90_NOWRITE, ncid ) == NF90_NOERR )  THEN
     1305
     1306       CALL check(nf90_get_att(ncid, NF90_GLOBAL, TRIM(attribute), attribute_value))
    12831307       CALL check(nf90_close(ncid))
    12841308
    1285     END FUNCTION get_pressure_varname
    1286 
    1287 
    1288 !------------------------------------------------------------------------------!
    1289 ! Description:
    1290 ! ------------
    1291 !> Read the given global attribute form the given netCDF file.
    1292 !------------------------------------------------------------------------------!
    1293     FUNCTION get_netcdf_attribute(filename, attribute) RESULT(attribute_value)
    1294 
    1295        CHARACTER(LEN=*), INTENT(IN) ::  filename, attribute
    1296        REAL(dp)                     ::  attribute_value
    1297 
    1298        INTEGER                      ::  ncid
    1299 
    1300        IF ( nf90_open( TRIM(filename), NF90_NOWRITE, ncid ) == NF90_NOERR )  THEN
    1301 
    1302           CALL check(nf90_get_att(ncid, NF90_GLOBAL, TRIM(attribute), attribute_value))
    1303           CALL check(nf90_close(ncid))
    1304 
    1305        ELSE
    1306 
    1307           message = "Failed to read '" // TRIM(attribute) // &
    1308                     "' from file '" // TRIM(filename) // "'."
    1309           CALL inifor_abort('get_netcdf_attribute', message)
    1310 
    1311        ENDIF
    1312 
    1313     END FUNCTION get_netcdf_attribute
     1309    ELSE
     1310
     1311       message = "Failed to read '" // TRIM(attribute) // &
     1312                 "' from file '" // TRIM(filename) // "'."
     1313       CALL inifor_abort('get_netcdf_attribute', message)
     1314
     1315    ENDIF
     1316
     1317 END FUNCTION get_netcdf_attribute
    13141318
    13151319
     
    13191323!> Read the attribute of the given variable form the given netCDF file.
    13201324!------------------------------------------------------------------------------!
    1321     FUNCTION get_netcdf_variable_attribute(filename, varname, attribute)       &
    1322        RESULT(attribute_value)
    1323 
    1324        CHARACTER(LEN=*), INTENT(IN) ::  filename, varname, attribute
    1325        REAL(dp)                     ::  attribute_value
    1326 
    1327        INTEGER                      ::  ncid, varid
    1328 
    1329        IF ( nf90_open( TRIM(filename), NF90_NOWRITE, ncid ) == NF90_NOERR )  THEN
    1330 
    1331           CALL check( nf90_inq_varid( ncid, TRIM( varname ), varid ) )
    1332           CALL check( nf90_get_att( ncid, varid, TRIM( attribute ),            &
    1333                       attribute_value ) )
    1334           CALL check( nf90_close( ncid ) )
    1335 
    1336        ELSE
    1337 
    1338           message = "Failed to read '" // TRIM( varname ) // ":" //            &
    1339                     TRIM( attribute ) // "' from file '" // TRIM(filename) // "'."
    1340           CALL inifor_abort('get_netcdf_variable_attribute', message)
    1341 
    1342        ENDIF
    1343 
    1344     END FUNCTION get_netcdf_variable_attribute
     1325 FUNCTION get_netcdf_variable_attribute(filename, varname, attribute)       &
     1326    RESULT(attribute_value)
     1327
     1328    CHARACTER(LEN=*), INTENT(IN) ::  filename, varname, attribute
     1329    REAL(wp)                     ::  attribute_value
     1330
     1331    INTEGER                      ::  ncid, varid
     1332
     1333    IF ( nf90_open( TRIM(filename), NF90_NOWRITE, ncid ) == NF90_NOERR )  THEN
     1334
     1335       CALL check( nf90_inq_varid( ncid, TRIM( varname ), varid ) )
     1336       CALL check( nf90_get_att( ncid, varid, TRIM( attribute ),            &
     1337                   attribute_value ) )
     1338       CALL check( nf90_close( ncid ) )
     1339
     1340    ELSE
     1341
     1342       message = "Failed to read '" // TRIM( varname ) // ":" //            &
     1343                 TRIM( attribute ) // "' from file '" // TRIM(filename) // "'."
     1344       CALL inifor_abort('get_netcdf_variable_attribute', message)
     1345
     1346    ENDIF
     1347
     1348 END FUNCTION get_netcdf_variable_attribute
    13451349
    13461350!------------------------------------------------------------------------------!
     
    13501354!> variable at the current time step.
    13511355!------------------------------------------------------------------------------!
    1352     SUBROUTINE update_output(var, array, iter, output_file, cfg)
    1353        TYPE(nc_var), INTENT(IN)  ::  var
    1354        REAL(dp), INTENT(IN)      ::  array(:,:,:)
    1355        INTEGER, INTENT(IN)       ::  iter
    1356        TYPE(nc_file), INTENT(IN) ::  output_file
    1357        TYPE(inifor_config)       ::  cfg
    1358 
    1359        INTEGER ::  ncid, ndim, start(4), count(4)
    1360        LOGICAL ::  var_is_time_dependent
    1361 
    1362        var_is_time_dependent = (                                               &
    1363           var % dimids( var % ndim ) == output_file % dimid_time               &
    1364        )
    1365 
    1366 !
    1367 !--    Skip time dimension for output
    1368        ndim = var % ndim
    1369        IF ( var_is_time_dependent )  ndim = var % ndim - 1
    1370 
    1371        start(:)      = (/1,1,1,1/)
    1372        start(ndim+1) = iter
    1373        count(1:ndim) = var%dimlen(1:ndim)
    1374 
    1375        CALL check(nf90_open(output_file % name, NF90_WRITE, ncid))
    1376 
    1377 !
    1378 !--    Reduce dimension of output array according to variable kind
    1379        SELECT CASE (TRIM(var % kind))
     1356 SUBROUTINE update_output(var, array, iter, output_file, cfg)
     1357    TYPE(nc_var), INTENT(IN)  ::  var
     1358    REAL(wp), INTENT(IN)      ::  array(:,:,:)
     1359    INTEGER, INTENT(IN)       ::  iter
     1360    TYPE(nc_file), INTENT(IN) ::  output_file
     1361    TYPE(inifor_config)       ::  cfg
     1362
     1363    INTEGER ::  ncid, ndim, start(4), count(4)
     1364    LOGICAL ::  var_is_time_dependent
     1365
     1366    var_is_time_dependent = (                                               &
     1367       var%dimids( var%ndim ) == output_file%dimid_time               &
     1368    )
     1369
     1370!
     1371!-- Skip time dimension for output
     1372    ndim = var%ndim
     1373    IF ( var_is_time_dependent )  ndim = var%ndim - 1
     1374
     1375    start(:)      = (/1,1,1,1/)
     1376    start(ndim+1) = iter
     1377    count(1:ndim) = var%dimlen(1:ndim)
     1378
     1379    CALL check(nf90_open(output_file%name, NF90_WRITE, ncid))
     1380
     1381!
     1382!-- Reduce dimension of output array according to variable kind
     1383    SELECT CASE (TRIM(var%kind))
    13801384       
    13811385       CASE ( 'init scalar profile', 'init u profile', 'init v profile',       &
     
    13951399         
    13961400
    1397           IF (.NOT. SIZE(array, 2) .EQ. var % dimlen(1))  THEN
     1401          IF (.NOT. SIZE(array, 2) .EQ. var%dimlen(1))  THEN
    13981402             PRINT *, "inifor: update_output: Dimension ", 1, " of variable ", &
    1399                  TRIM(var % name), " (", var % dimlen(1),                      &
     1403                 TRIM(var%name), " (", var%dimlen(1),                      &
    14001404                 ") does not match the dimension of the output array (",       &
    14011405                 SIZE(array, 2), ")."
     
    14481452       CASE ( 'internal profile' )
    14491453
    1450           IF ( cfg % debug )  THEN
     1454          IF ( cfg%debug )  THEN
    14511455             CALL check(nf90_put_var( ncid, var%varid, array(1,1,:),           &
    14521456                                      start=start(1:ndim+1),                   &
     
    14611465       CASE DEFAULT
    14621466
    1463            message = "Variable kind '" // TRIM(var % kind) //                  &
     1467           message = "Variable kind '" // TRIM(var%kind) //                  &
    14641468                    "' not recognized."
    14651469           CALL inifor_abort('update_output', message)
    14661470
    1467        END SELECT
    1468 
    1469        CALL check(nf90_close(ncid))
    1470 
    1471     END SUBROUTINE update_output
     1471    END SELECT
     1472
     1473    CALL check(nf90_close(ncid))
     1474
     1475 END SUBROUTINE update_output
    14721476
    14731477
     
    14771481!> Checks the status of a netCDF API call and aborts if an error occured
    14781482!------------------------------------------------------------------------------!
    1479     SUBROUTINE check(status)
    1480 
    1481        INTEGER, INTENT(IN) ::  status
    1482 
    1483        IF (status /= nf90_noerr)  THEN
    1484           message = "NetCDF API call failed with error: " //                     &
    1485                     TRIM( nf90_strerror(status) )
    1486           CALL inifor_abort('io.check', message)
    1487        ENDIF
    1488 
    1489     END SUBROUTINE check
     1483 SUBROUTINE check(status)
     1484
     1485    INTEGER, INTENT(IN) ::  status
     1486
     1487    IF (status /= nf90_noerr)  THEN
     1488       message = "NetCDF API call failed with error: " //                     &
     1489                 TRIM( nf90_strerror(status) )
     1490       CALL inifor_abort('io.check', message)
     1491    ENDIF
     1492
     1493 END SUBROUTINE check
    14901494
    14911495 END MODULE inifor_io
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_transform.f90

    r3785 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29! Improved coding style
     30!
     31!
     32! 3785 2019-03-06 10:41:14Z eckhard
    2833! Remove basic state pressure before computing geostrophic wind
    2934!  - Introduced new level-based profile averaging routine that does not rely on
     
    106111    USE inifor_control
    107112    USE inifor_defs,                                                           &
    108         ONLY: BETA, dp, G, P_SL, PI, RD, T_SL, TO_DEGREES, TO_RADIANS
     113        ONLY: BETA, G, P_SL, PI, RD, T_SL, TO_DEGREES, TO_RADIANS, wp
    109114    USE inifor_types
    110115    USE inifor_util,                                                           &
     
    116121
    117122
    118     SUBROUTINE interpolate_1d(in_arr, out_arr, outgrid)
    119        TYPE(grid_definition), INTENT(IN) ::  outgrid
    120        REAL(dp), INTENT(IN)              ::  in_arr(:)
    121        REAL(dp), INTENT(OUT)             ::  out_arr(:)
    122 
    123        INTEGER :: k, l, nz
    124 
    125        nz = UBOUND(out_arr, 1)
    126 
    127        DO k = nz, LBOUND(out_arr, 1), -1
    128 
    129 !
    130 !--       TODO: Remove IF clause and extrapolate based on a critical vertical
    131 !--       TODO: index marking the lower bound of COSMO-DE data coverage.
    132 !--       Check for negative interpolation weights indicating grid points
    133 !--       below COSMO-DE domain and extrapolate from the top in such cells.
    134           IF (outgrid % w(1,k,1) < -1.0_dp .AND. k < nz)  THEN
    135              out_arr(k) = out_arr(k+1)
    136           ELSE
    137              out_arr(k) = 0.0_dp
    138              DO l = 1, 2
    139                 out_arr(k) = out_arr(k) +                                      &
    140                     outgrid % w(1,k,l) * in_arr(outgrid % kkk(1,k,l) )
    141              ENDDO
    142           ENDIF
    143        ENDDO
    144 
    145     END SUBROUTINE interpolate_1d
     123 SUBROUTINE interpolate_1d(in_arr, out_arr, outgrid)
     124    TYPE(grid_definition), INTENT(IN) ::  outgrid
     125    REAL(wp), INTENT(IN)              ::  in_arr(:)
     126    REAL(wp), INTENT(OUT)             ::  out_arr(:)
     127
     128    INTEGER :: k, l, nz
     129
     130    nz = UBOUND(out_arr, 1)
     131
     132    DO k = nz, LBOUND(out_arr, 1), -1
     133
     134!
     135!--    TODO: Remove IF clause and extrapolate based on a critical vertical
     136!--    TODO: index marking the lower bound of COSMO-DE data coverage.
     137!--    Check for negative interpolation weights indicating grid points
     138!--    below COSMO-DE domain and extrapolate from the top in such cells.
     139       IF (outgrid%w(1,k,1) < -1.0_wp .AND. k < nz)  THEN
     140          out_arr(k) = out_arr(k+1)
     141       ELSE
     142          out_arr(k) = 0.0_wp
     143          DO l = 1, 2
     144             out_arr(k) = out_arr(k) +                                      &
     145                 outgrid%w(1,k,l) * in_arr(outgrid%kkk(1,k,l) )
     146          ENDDO
     147       ENDIF
     148    ENDDO
     149
     150 END SUBROUTINE interpolate_1d
    146151
    147152
     
    158163!> invar : Array of source data
    159164!>
    160 !> outgrid % kk : Array of vertical neighbour indices. kk(i,j,k,:) contain the
     165!> outgrid%kk : Array of vertical neighbour indices. kk(i,j,k,:) contain the
    161166!>     indices of the two vertical neighbors of PALM-4U point (i,j,k) on the
    162167!>     input grid corresponding to the source data invar.
    163168!>
    164 !> outgrid % w_verti : Array of weights for vertical linear interpolation
     169!> outgrid%w_verti : Array of weights for vertical linear interpolation
    165170!>     corresponding to neighbour points indexed by kk.
    166171!>
     
    169174!> outvar : Array of interpolated data
    170175!------------------------------------------------------------------------------!
    171     SUBROUTINE interpolate_1d_arr(in_arr, out_arr, outgrid)
    172        TYPE(grid_definition), INTENT(IN) ::  outgrid
    173        REAL(dp), INTENT(IN)              ::  in_arr(0:,0:,0:)
    174        REAL(dp), INTENT(OUT)             ::  out_arr(0:,0:,:)
    175 
    176        INTEGER :: i, j, k, l, nz
    177 
    178        nz = UBOUND(out_arr, 3)
    179 
    180        DO j = LBOUND(out_arr, 2), UBOUND(out_arr, 2)
    181        DO i = LBOUND(out_arr, 1), UBOUND(out_arr, 1)
    182        DO k = nz, LBOUND(out_arr, 3), -1
    183 
    184 !
    185 !--       TODO: Remove IF clause and extrapolate based on a critical vertical
    186 !--       TODO: index marking the lower bound of COSMO-DE data coverage.
    187 !--       Check for negative interpolation weights indicating grid points
    188 !--       below COSMO-DE domain and extrapolate from the top in such cells.
    189           IF (outgrid % w_verti(i,j,k,1) < -1.0_dp .AND. k < nz)  THEN
    190              out_arr(i,j,k) = out_arr(i,j,k+1)
    191           ELSE
    192              out_arr(i,j,k) = 0.0_dp
    193              DO l = 1, 2
    194                 out_arr(i,j,k) = out_arr(i,j,k) +                              &
    195                     outgrid % w_verti(i,j,k,l) *                               &
    196                     in_arr(i,j,outgrid % kk(i,j,k, l) )
    197              ENDDO
    198           ENDIF
    199        ENDDO
    200        ENDDO
    201        ENDDO
    202     END SUBROUTINE interpolate_1d_arr
     176 SUBROUTINE interpolate_1d_arr(in_arr, out_arr, outgrid)
     177    TYPE(grid_definition), INTENT(IN) ::  outgrid
     178    REAL(wp), INTENT(IN)              ::  in_arr(0:,0:,0:)
     179    REAL(wp), INTENT(OUT)             ::  out_arr(0:,0:,:)
     180
     181    INTEGER :: i, j, k, l, nz
     182
     183    nz = UBOUND(out_arr, 3)
     184
     185    DO j = LBOUND(out_arr, 2), UBOUND(out_arr, 2)
     186    DO i = LBOUND(out_arr, 1), UBOUND(out_arr, 1)
     187    DO k = nz, LBOUND(out_arr, 3), -1
     188
     189!
     190!--    TODO: Remove IF clause and extrapolate based on a critical vertical
     191!--    TODO: index marking the lower bound of COSMO-DE data coverage.
     192!--    Check for negative interpolation weights indicating grid points
     193!--    below COSMO-DE domain and extrapolate from the top in such cells.
     194       IF (outgrid%w_verti(i,j,k,1) < -1.0_wp .AND. k < nz)  THEN
     195          out_arr(i,j,k) = out_arr(i,j,k+1)
     196       ELSE
     197          out_arr(i,j,k) = 0.0_wp
     198          DO l = 1, 2
     199             out_arr(i,j,k) = out_arr(i,j,k) +                              &
     200                 outgrid%w_verti(i,j,k,l) *                               &
     201                 in_arr(i,j,outgrid%kk(i,j,k, l) )
     202          ENDDO
     203       ENDIF
     204    ENDDO
     205    ENDDO
     206    ENDDO
     207 END SUBROUTINE interpolate_1d_arr
    203208
    204209
     
    214219!> invar : Array of source data
    215220!>
    216 !> outgrid % ii, % jj : Array of neighbour indices in x and y direction.
     221!> outgrid%ii,%jj : Array of neighbour indices in x and y direction.
    217222!>     ii(i,j,k,:), and jj(i,j,k,:) contain the four horizontal neighbour points
    218223!>     of PALM-4U point (i,j,k) on the input grid corresponding to the source
     
    220225!      form of the interpolation weights.)
    221226!>
    222 !> outgrid % w_horiz: Array of weights for horizontal bi-linear interpolation
     227!> outgrid%w_horiz: Array of weights for horizontal bi-linear interpolation
    223228!>     corresponding to neighbour points indexed by ii and jj.
    224229!>
     
    227232!> outvar : Array of interpolated data
    228233!------------------------------------------------------------------------------!
    229     SUBROUTINE interpolate_2d(invar, outvar, outgrid, ncvar)
    230 !
    231 !--    I index 0-based for the indices of the outvar to be consistent with the
    232 !--    outgrid indices and interpolation weights.
    233        TYPE(grid_definition), INTENT(IN)  ::  outgrid
    234        REAL(dp), INTENT(IN)               ::  invar(0:,0:,0:)
    235        REAL(dp), INTENT(OUT)              ::  outvar(0:,0:,0:)
    236        TYPE(nc_var), INTENT(IN), OPTIONAL ::  ncvar
    237 
    238        INTEGER ::  i, j, k, l
    239 
    240 !
    241 !--    TODO: check if input dimensions are consistent, i.e. ranges are correct
    242        IF ( UBOUND(outvar, 3) .GT. UBOUND(invar, 3) )  THEN
    243            message = "Output array for '" // TRIM(ncvar % name) // "' has ' more levels (" // &
    244               TRIM(str(UBOUND(outvar, 3))) // ") than input variable ("//&
    245               TRIM(str(UBOUND(invar, 3))) // ")."
    246            CALL inifor_abort('interpolate_2d', message)
    247        ENDIF
    248 
    249        DO k = 0, UBOUND(outvar, 3)
    250        DO j = 0, UBOUND(outvar, 2)
    251        DO i = 0, UBOUND(outvar, 1)
    252           outvar(i,j,k) = 0.0_dp
    253           DO l = 1, 4
    254              
    255              outvar(i,j,k) = outvar(i,j,k) +                                   &
    256                 outgrid % w_horiz(i,j,l) * invar( outgrid % ii(i,j,l),         &
    257                                                   outgrid % jj(i,j,l),         &
    258                                                   k )
    259           ENDDO
     234 SUBROUTINE interpolate_2d(invar, outvar, outgrid, ncvar)
     235!
     236!-- I index 0-based for the indices of the outvar to be consistent with the
     237!-- outgrid indices and interpolation weights.
     238    TYPE(grid_definition), INTENT(IN)  ::  outgrid
     239    REAL(wp), INTENT(IN)               ::  invar(0:,0:,0:)
     240    REAL(wp), INTENT(OUT)              ::  outvar(0:,0:,0:)
     241    TYPE(nc_var), INTENT(IN), OPTIONAL ::  ncvar
     242
     243    INTEGER ::  i, j, k, l
     244
     245!
     246!-- TODO: check if input dimensions are consistent, i.e. ranges are correct
     247    IF ( UBOUND(outvar, 3) .GT. UBOUND(invar, 3) )  THEN
     248        message = "Output array for '" // TRIM(ncvar%name) // "' has ' more levels (" // &
     249           TRIM(str(UBOUND(outvar, 3))) // ") than input variable ("//&
     250           TRIM(str(UBOUND(invar, 3))) // ")."
     251        CALL inifor_abort('interpolate_2d', message)
     252    ENDIF
     253
     254    DO  k = 0, UBOUND(outvar, 3)
     255    DO  j = 0, UBOUND(outvar, 2)
     256    DO  i = 0, UBOUND(outvar, 1)
     257       outvar(i,j,k) = 0.0_wp
     258       DO  l = 1, 4
     259         
     260          outvar(i,j,k) = outvar(i,j,k) +                                   &
     261             outgrid%w_horiz(i,j,l) * invar( outgrid%ii(i,j,l),         &
     262                                               outgrid%jj(i,j,l),         &
     263                                               k )
    260264       ENDDO
    261        ENDDO
    262        ENDDO
     265    ENDDO
     266    ENDDO
     267    ENDDO
    263268       
    264     END SUBROUTINE interpolate_2d
     269 END SUBROUTINE interpolate_2d
    265270
    266271
     
    271276!> out_arr(:)
    272277!------------------------------------------------------------------------------!
    273     SUBROUTINE average_2d(in_arr, out_arr, ii, jj)
    274        REAL(dp), INTENT(IN)              ::  in_arr(0:,0:,0:)
    275        REAL(dp), INTENT(OUT)             ::  out_arr(0:)
    276        INTEGER, INTENT(IN), DIMENSION(:) ::  ii, jj
    277 
    278        INTEGER  ::  i, j, k, l
    279        REAL(dp) ::  ni
    280 
    281        IF (SIZE(ii) /= SIZE(jj))  THEN
    282           message = "Length of 'ii' and 'jj' index lists do not match." //     &
    283              NEW_LINE(' ') // "ii has " // str(SIZE(ii)) // " elements, " //   &
    284              NEW_LINE(' ') // "jj has " // str(SIZE(jj)) // "."
    285           CALL inifor_abort('average_2d', message)
    286        ENDIF
    287 
    288        IF (SIZE(ii) == 0)  THEN
    289           message = "No columns to average over; " //                          &
    290                     "size of index lists 'ii' and 'jj' is zero."
    291           CALL inifor_abort('average_2d', message)
    292        ENDIF
    293 
    294        DO k = 0, UBOUND(out_arr, 1)
    295 
    296           out_arr(k) = 0.0_dp
    297           DO l = 1, UBOUND(ii, 1)
    298              i = ii(l)
    299              j = jj(l)
    300              out_arr(k) = out_arr(k) + in_arr(i, j, k)
    301           ENDDO
    302 
     278 SUBROUTINE average_2d(in_arr, out_arr, ii, jj)
     279    REAL(wp), INTENT(IN)              ::  in_arr(0:,0:,0:)
     280    REAL(wp), INTENT(OUT)             ::  out_arr(0:)
     281    INTEGER, INTENT(IN), DIMENSION(:) ::  ii, jj
     282
     283    INTEGER  ::  i, j, k, l
     284    REAL(wp) ::  ni
     285
     286    IF (SIZE(ii) /= SIZE(jj))  THEN
     287       message = "Length of 'ii' and 'jj' index lists do not match." //     &
     288          NEW_LINE(' ') // "ii has " // str(SIZE(ii)) // " elements, " //   &
     289          NEW_LINE(' ') // "jj has " // str(SIZE(jj)) // "."
     290       CALL inifor_abort('average_2d', message)
     291    ENDIF
     292
     293    IF (SIZE(ii) == 0)  THEN
     294       message = "No columns to average over; " //                          &
     295                 "size of index lists 'ii' and 'jj' is zero."
     296       CALL inifor_abort('average_2d', message)
     297    ENDIF
     298
     299    DO  k = 0, UBOUND(out_arr, 1)
     300
     301       out_arr(k) = 0.0_wp
     302       DO  l = 1, UBOUND(ii, 1)
     303          i = ii(l)
     304          j = jj(l)
     305          out_arr(k) = out_arr(k) + in_arr(i, j, k)
    303306       ENDDO
    304307
    305        ni = 1.0_dp / SIZE(ii)
    306        out_arr(:) = out_arr(:) * ni
    307 
    308     END SUBROUTINE average_2d
     308    ENDDO
     309
     310    ni = 1.0_wp / SIZE(ii)
     311    out_arr(:) = out_arr(:) * ni
     312
     313 END SUBROUTINE average_2d
    309314
    310315
     
    320325!> as coarse as COSMO, horizontally as fine as PALM).
    321326!------------------------------------------------------------------------------!
    322     SUBROUTINE interpolate_3d(source_array, palm_array, palm_intermediate, palm_grid)
    323        TYPE(grid_definition), INTENT(IN) ::  palm_intermediate, palm_grid
    324        REAL(dp), DIMENSION(:,:,:), INTENT(IN)  ::  source_array
    325        REAL(dp), DIMENSION(:,:,:), INTENT(OUT) ::  palm_array
    326        REAL(dp), DIMENSION(:,:,:), ALLOCATABLE ::  intermediate_array
    327        INTEGER ::  nx, ny, nlev
    328 
    329        nx = palm_intermediate % nx
    330        ny = palm_intermediate % ny
    331        nlev = palm_intermediate % nz
    332 
    333 !
    334 !--    Interpolate from COSMO to intermediate grid. Allocating with one
    335 !--    less point in the vertical, since scalars like T have 50 instead of 51
    336 !--    points in COSMO.
    337        ALLOCATE(intermediate_array(0:nx, 0:ny, 0:nlev-1)) !
    338 
    339        CALL interpolate_2d(source_array, intermediate_array, palm_intermediate)
    340 
    341 !
    342 !--    Interpolate from intermediate grid to palm_grid grid, includes
    343 !--    extrapolation for cells below COSMO domain.
    344        CALL interpolate_1d_arr(intermediate_array, palm_array, palm_grid)
    345 
    346        DEALLOCATE(intermediate_array)
    347 
    348     END SUBROUTINE interpolate_3d
     327 SUBROUTINE interpolate_3d(source_array, palm_array, palm_intermediate, palm_grid)
     328    TYPE(grid_definition), INTENT(IN) ::  palm_intermediate, palm_grid
     329    REAL(wp), DIMENSION(:,:,:), INTENT(IN)  ::  source_array
     330    REAL(wp), DIMENSION(:,:,:), INTENT(OUT) ::  palm_array
     331    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  intermediate_array
     332    INTEGER ::  nx, ny, nlev
     333
     334    nx = palm_intermediate%nx
     335    ny = palm_intermediate%ny
     336    nlev = palm_intermediate%nz
     337
     338!
     339!-- Interpolate from COSMO to intermediate grid. Allocating with one
     340!-- less point in the vertical, since scalars like T have 50 instead of 51
     341!-- points in COSMO.
     342    ALLOCATE(intermediate_array(0:nx, 0:ny, 0:nlev-1)) !
     343
     344    CALL interpolate_2d(source_array, intermediate_array, palm_intermediate)
     345
     346!
     347!-- Interpolate from intermediate grid to palm_grid grid, includes
     348!-- extrapolation for cells below COSMO domain.
     349    CALL interpolate_1d_arr(intermediate_array, palm_array, palm_grid)
     350
     351    DEALLOCATE(intermediate_array)
     352
     353 END SUBROUTINE interpolate_3d
    349354
    350355
     
    355360!> averaging grid 'avg_grid' and store the result in 'profile_array'.
    356361!------------------------------------------------------------------------------!
    357     SUBROUTINE interp_average_profile(source_array, profile_array, avg_grid)
    358        TYPE(grid_definition), INTENT(IN)          ::  avg_grid
    359        REAL(dp), DIMENSION(:,:,:), INTENT(IN)     ::  source_array
    360        REAL(dp), DIMENSION(:), INTENT(OUT)        ::  profile_array
    361 
    362        INTEGER ::  i_source, j_source, k_profile, k_source, l, m
    363 
    364        REAL ::  ni_columns
    365 
    366        profile_array(:) = 0.0_dp
    367 
    368        DO l = 1, avg_grid % n_columns
    369           i_source = avg_grid % iii(l)
    370           j_source = avg_grid % jjj(l)
    371 
    372 !
    373 !--       Loop over PALM levels
    374           DO k_profile = avg_grid % k_min, UBOUND(profile_array, 1)
    375 
    376 !
    377 !--          Loop over vertical interpolation neighbours
    378              DO m = 1, 2
    379 
    380                 k_source = avg_grid % kkk(l, k_profile, m)
    381 
    382                 profile_array(k_profile) = profile_array(k_profile)            &
    383                    + avg_grid % w(l, k_profile, m)                             &
    384                    * source_array(i_source, j_source, k_source)
    385 !
    386 !--          Loop over vertical interpolation neighbours m
    387              ENDDO
    388 
    389 !
    390 !--       Loop over PALM levels k_profile
     362 SUBROUTINE interp_average_profile(source_array, profile_array, avg_grid)
     363    TYPE(grid_definition), INTENT(IN)          ::  avg_grid
     364    REAL(wp), DIMENSION(:,:,:), INTENT(IN)     ::  source_array
     365    REAL(wp), DIMENSION(:), INTENT(OUT)        ::  profile_array
     366
     367    INTEGER ::  i_source, j_source, k_profile, k_source, l, m
     368
     369    REAL ::  ni_columns
     370
     371    profile_array(:) = 0.0_wp
     372
     373    DO  l = 1, avg_grid%n_columns
     374       i_source = avg_grid%iii(l)
     375       j_source = avg_grid%jjj(l)
     376
     377!
     378!--    Loop over PALM levels
     379       DO  k_profile = avg_grid%k_min, UBOUND(profile_array, 1)
     380
     381!
     382!--       Loop over vertical interpolation neighbours
     383          DO  m = 1, 2
     384
     385             k_source = avg_grid%kkk(l, k_profile, m)
     386
     387             profile_array(k_profile) = profile_array(k_profile)            &
     388                + avg_grid%w(l, k_profile, m)                             &
     389                * source_array(i_source, j_source, k_source)
     390!
     391!--       Loop over vertical interpolation neighbours m
    391392          ENDDO
    392393
    393394!
    394 !--    Loop over horizontal neighbours l
     395!--    Loop over PALM levels k_profile
    395396       ENDDO
    396397
    397        ni_columns = 1.0_dp / avg_grid % n_columns
    398        profile_array(:) = profile_array(:) * ni_columns
    399 
    400 !
    401 !--    Constant extrapolation to the bottom
    402        profile_array(1:avg_grid % k_min-1) = profile_array(avg_grid % k_min)
    403 
    404     END SUBROUTINE interp_average_profile
     398!
     399!-- Loop over horizontal neighbours l
     400    ENDDO
     401
     402    ni_columns = 1.0_wp / avg_grid%n_columns
     403    profile_array(:) = profile_array(:) * ni_columns
     404
     405!
     406!-- Constant extrapolation to the bottom
     407    profile_array(1:avg_grid%k_min-1) = profile_array(avg_grid%k_min)
     408
     409 END SUBROUTINE interp_average_profile
    405410
    406411
     
    411416!> averaging grid 'avg_grid' and store the result in 'profile_array'.
    412417!------------------------------------------------------------------------------!
    413     SUBROUTINE average_profile( source_array, profile_array, avg_grid )
    414 
    415        TYPE(grid_definition), INTENT(IN)          ::  avg_grid
    416        REAL(dp), DIMENSION(:,:,:), INTENT(IN)     ::  source_array
    417        REAL(dp), DIMENSION(:), INTENT(OUT)        ::  profile_array
    418 
    419        INTEGER ::  i_source, j_source, l, nz, nlev
    420 
    421        REAL(dp) ::  ni_columns
    422 
    423        nlev = SIZE( source_array, 3 )
    424        nz   = SIZE( profile_array, 1 )
    425 
    426        IF ( nlev /= nz )  THEN
    427           message = "Lengths of input and output profiles do not match: " //   &
    428                     "cosmo_pressure(" // TRIM( str( nlev ) ) //                &
    429                     "), profile_array(" // TRIM( str( nz ) )  // ")."
    430           CALL inifor_abort('average_pressure_perturbation', message)
    431        ENDIF
    432      
    433        profile_array(:) = 0.0_dp
    434 
    435        DO l = 1, avg_grid % n_columns
    436 
    437           i_source = avg_grid % iii(l)
    438           j_source = avg_grid % jjj(l)
    439 
    440           profile_array(:) = profile_array(:)                                  &
    441                            + source_array(i_source, j_source, :)
    442 
    443        ENDDO
    444 
    445        ni_columns = 1.0_dp / avg_grid % n_columns
    446        profile_array(:) = profile_array(:) * ni_columns
    447 
    448     END SUBROUTINE average_profile
     418 SUBROUTINE average_profile( source_array, profile_array, avg_grid )
     419
     420    TYPE(grid_definition), INTENT(IN)          ::  avg_grid
     421    REAL(wp), DIMENSION(:,:,:), INTENT(IN)     ::  source_array
     422    REAL(wp), DIMENSION(:), INTENT(OUT)        ::  profile_array
     423
     424    INTEGER ::  i_source, j_source, l, nz, nlev
     425
     426    REAL(wp) ::  ni_columns
     427
     428    nlev = SIZE( source_array, 3 )
     429    nz   = SIZE( profile_array, 1 )
     430
     431    IF ( nlev /= nz )  THEN
     432       message = "Lengths of input and output profiles do not match: " //   &
     433                 "cosmo_pressure(" // TRIM( str( nlev ) ) //                &
     434                 "), profile_array(" // TRIM( str( nz ) )  // ")."
     435       CALL inifor_abort('average_pressure_perturbation', message)
     436    ENDIF
     437   
     438    profile_array(:) = 0.0_wp
     439
     440    DO  l = 1, avg_grid%n_columns
     441
     442       i_source = avg_grid%iii(l)
     443       j_source = avg_grid%jjj(l)
     444
     445       profile_array(:) = profile_array(:)                                  &
     446                        + source_array(i_source, j_source, :)
     447
     448    ENDDO
     449
     450    ni_columns = 1.0_wp / avg_grid%n_columns
     451    profile_array(:) = profile_array(:) * ni_columns
     452
     453 END SUBROUTINE average_profile
    449454
    450455
     
    456461!> averaging.
    457462!------------------------------------------------------------------------------!
    458     SUBROUTINE average_pressure_perturbation( cosmo_pressure, profile_array,   &
    459                                               cosmo_grid, avg_grid )
    460 
    461        TYPE(grid_definition), INTENT(IN)          ::  cosmo_grid, avg_grid
    462        REAL(dp), DIMENSION(:,:,:), INTENT(IN)     ::  cosmo_pressure
    463        REAL(dp), DIMENSION(:), INTENT(OUT)        ::  profile_array
    464 
    465        INTEGER ::  i_source, j_source, l, nz, nlev
    466 
    467        REAL(dp)                            ::  ni_columns
    468        REAL(dp), DIMENSION(:), ALLOCATABLE ::  basic_state_pressure
    469 
    470        nlev = SIZE( cosmo_pressure, 3 )
    471        nz   = SIZE( profile_array, 1 )
    472 
    473        IF ( nlev /= nz )  THEN
    474           message = "Lengths of input and output profiles do not match: " //   &
    475                     "cosmo_pressure(" // TRIM( str( nlev ) ) //                &
    476                     "), profile_array(" // TRIM( str( nz ) )  // ")."
    477           CALL inifor_abort('average_pressure_perturbation', message)
    478        ENDIF
    479 
    480        ALLOCATE( basic_state_pressure(nz) )
    481        profile_array(:) = 0.0_dp
    482 
    483        DO l = 1, avg_grid % n_columns
    484           i_source = avg_grid % iii(l)
    485           j_source = avg_grid % jjj(l)
    486 
    487 !
    488 !--       Compute pressure perturbation by removing COSMO basic state pressure
    489           CALL get_basic_state( cosmo_grid % hfl(i_source,j_source,:), BETA,   &
    490                                 P_SL, T_SL, RD, G, basic_state_pressure )
    491 
    492           profile_array(:) = profile_array(:)                                  &
    493                            + cosmo_pressure(i_source, j_source, :)             &
    494                            - basic_state_pressure(:)
    495 
    496 !
    497 !--    Loop over horizontal neighbours l
    498        ENDDO
    499 
    500        DEALLOCATE( basic_state_pressure )
    501 
    502        ni_columns = 1.0_dp / avg_grid % n_columns
    503        profile_array(:) = profile_array(:) * ni_columns
    504 
    505     END SUBROUTINE average_pressure_perturbation
     463 SUBROUTINE average_pressure_perturbation( cosmo_pressure, profile_array,   &
     464                                           cosmo_grid, avg_grid )
     465
     466    TYPE(grid_definition), INTENT(IN)          ::  cosmo_grid, avg_grid
     467    REAL(wp), DIMENSION(:,:,:), INTENT(IN)     ::  cosmo_pressure
     468    REAL(wp), DIMENSION(:), INTENT(OUT)        ::  profile_array
     469
     470    INTEGER ::  i_source, j_source, l, nz, nlev
     471
     472    REAL(wp)                            ::  ni_columns
     473    REAL(wp), DIMENSION(:), ALLOCATABLE ::  basic_state_pressure
     474
     475    nlev = SIZE( cosmo_pressure, 3 )
     476    nz   = SIZE( profile_array, 1 )
     477
     478    IF ( nlev /= nz )  THEN
     479       message = "Lengths of input and output profiles do not match: " //   &
     480                 "cosmo_pressure(" // TRIM( str( nlev ) ) //                &
     481                 "), profile_array(" // TRIM( str( nz ) )  // ")."
     482       CALL inifor_abort('average_pressure_perturbation', message)
     483    ENDIF
     484
     485    ALLOCATE( basic_state_pressure(nz) )
     486    profile_array(:) = 0.0_wp
     487
     488    DO  l = 1, avg_grid%n_columns
     489       i_source = avg_grid%iii(l)
     490       j_source = avg_grid%jjj(l)
     491
     492!
     493!--    Compute pressure perturbation by removing COSMO basic state pressure
     494       CALL get_basic_state( cosmo_grid%hfl(i_source,j_source,:), BETA,   &
     495                             P_SL, T_SL, RD, G, basic_state_pressure )
     496
     497       profile_array(:) = profile_array(:)                                  &
     498                        + cosmo_pressure(i_source, j_source, :)             &
     499                        - basic_state_pressure(:)
     500
     501!
     502!-- Loop over horizontal neighbours l
     503    ENDDO
     504
     505    DEALLOCATE( basic_state_pressure )
     506
     507    ni_columns = 1.0_wp / avg_grid%n_columns
     508    profile_array(:) = profile_array(:) * ni_columns
     509
     510 END SUBROUTINE average_pressure_perturbation
    506511
    507512
     
    513518!> Extrapolates density linearly from the level 'k_min' downwards.
    514519!------------------------------------------------------------------------------!
    515     SUBROUTINE extrapolate_density(rho, avg_grid)
    516        REAL(dp), DIMENSION(:), INTENT(INOUT) ::  rho
    517        TYPE(grid_definition), INTENT(IN)     ::  avg_grid
    518 
    519        REAL(dp) ::  drhodz, dz, zk, rhok
    520        INTEGER  ::  k_min
    521 
    522        k_min  = avg_grid % k_min
    523        zk     = avg_grid % z(k_min)
    524        rhok   = rho(k_min)
    525        dz     = avg_grid % z(k_min + 1) - avg_grid % z(k_min)
    526        drhodz = (rho(k_min + 1) - rho(k_min)) / dz
    527 
    528        rho(1:k_min-1) = rhok + drhodz * (avg_grid % z(1:k_min-1) - zk)
    529 
    530     END SUBROUTINE extrapolate_density
     520 SUBROUTINE extrapolate_density(rho, avg_grid)
     521    REAL(wp), DIMENSION(:), INTENT(INOUT) ::  rho
     522    TYPE(grid_definition), INTENT(IN)     ::  avg_grid
     523
     524    REAL(wp) ::  drhodz, dz, zk, rhok
     525    INTEGER  ::  k_min
     526
     527    k_min  = avg_grid%k_min
     528    zk     = avg_grid%z(k_min)
     529    rhok   = rho(k_min)
     530    dz     = avg_grid%z(k_min + 1) - avg_grid%z(k_min)
     531    drhodz = (rho(k_min + 1) - rho(k_min)) / dz
     532
     533    rho(1:k_min-1) = rhok + drhodz * (avg_grid%z(1:k_min-1) - zk)
     534
     535 END SUBROUTINE extrapolate_density
    531536
    532537
     
    536541!> Driver for extrapolating pressure from PALM level k_min downwards
    537542!------------------------------------------------------------------------------!
    538     SUBROUTINE extrapolate_pressure(p, rho, avg_grid)
    539        REAL(dp), DIMENSION(:), INTENT(IN)    ::  rho
    540        REAL(dp), DIMENSION(:), INTENT(INOUT) ::  p
    541        TYPE(grid_definition), INTENT(IN)     ::  avg_grid
    542 
    543        REAL(dp) ::  drhodz, dz, zk, rhok
    544        INTEGER  ::  k, k_min
    545 
    546        k_min = avg_grid % k_min
    547        zk    = avg_grid % z(k_min)
    548        rhok  = rho(k_min)
    549        dz    = avg_grid % z(k_min + 1) - avg_grid % z(k_min)
    550        drhodz = 0.5_dp * (rho(k_min + 1) - rho(k_min)) / dz
    551 
    552        DO k = 1, k_min-1
    553           p(k) = constant_density_pressure(p(k_min), zk, rhok, drhodz,         &
    554                                            avg_grid % z(k), G)
    555        ENDDO
    556 
    557     END SUBROUTINE extrapolate_pressure
     543 SUBROUTINE extrapolate_pressure(p, rho, avg_grid)
     544    REAL(wp), DIMENSION(:), INTENT(IN)    ::  rho
     545    REAL(wp), DIMENSION(:), INTENT(INOUT) ::  p
     546    TYPE(grid_definition), INTENT(IN)     ::  avg_grid
     547
     548    REAL(wp) ::  drhodz, dz, zk, rhok
     549    INTEGER  ::  k, k_min
     550
     551    k_min = avg_grid%k_min
     552    zk    = avg_grid%z(k_min)
     553    rhok  = rho(k_min)
     554    dz    = avg_grid%z(k_min + 1) - avg_grid%z(k_min)
     555    drhodz = 0.5_wp * (rho(k_min + 1) - rho(k_min)) / dz
     556
     557    DO k = 1, k_min-1
     558       p(k) = constant_density_pressure(p(k_min), zk, rhok, drhodz,         &
     559                                        avg_grid%z(k), G)
     560    ENDDO
     561
     562 END SUBROUTINE extrapolate_pressure
    558563
    559564
     
    564569!> extrapolated pressure at the surface.
    565570!------------------------------------------------------------------------------!
    566     SUBROUTINE get_surface_pressure(p, rho, avg_grid)
    567        REAL(dp), DIMENSION(:), INTENT(IN)    ::  rho
    568        REAL(dp), DIMENSION(:), INTENT(INOUT) ::  p
    569        TYPE(grid_definition), INTENT(IN)     ::  avg_grid
    570 
    571        REAL(dp) ::  drhodz, dz, zk, rhok
    572        INTEGER  ::  k_min
    573 
    574        k_min = avg_grid % k_min
    575        zk    = avg_grid % z(k_min)
    576        rhok  = rho(k_min)
    577        dz    = avg_grid % z(k_min + 1) - avg_grid % z(k_min)
    578        drhodz = 0.5_dp * (rho(k_min + 1) - rho(k_min)) / dz
    579 
    580        p(1) = constant_density_pressure(p(k_min), zk, rhok, drhodz,            &
    581                                         0.0_dp, G)
    582 
    583     END SUBROUTINE get_surface_pressure
    584 
    585 
    586     FUNCTION constant_density_pressure(pk, zk, rhok, drhodz, z, g)  RESULT(p)
    587 
    588        REAL(dp), INTENT(IN)  ::  pk, zk, rhok, drhodz, g, z
    589        REAL(dp) ::  p
    590 
    591        p = pk + ( zk - z ) * g * ( rhok + 0.5*drhodz * (zk - z) )
    592 
    593     END FUNCTION constant_density_pressure
     571 SUBROUTINE get_surface_pressure(p, rho, avg_grid)
     572    REAL(wp), DIMENSION(:), INTENT(IN)    ::  rho
     573    REAL(wp), DIMENSION(:), INTENT(INOUT) ::  p
     574    TYPE(grid_definition), INTENT(IN)     ::  avg_grid
     575
     576    REAL(wp) ::  drhodz, dz, zk, rhok
     577    INTEGER  ::  k_min
     578
     579    k_min = avg_grid%k_min
     580    zk    = avg_grid%z(k_min)
     581    rhok  = rho(k_min)
     582    dz    = avg_grid%z(k_min + 1) - avg_grid%z(k_min)
     583    drhodz = 0.5_wp * (rho(k_min + 1) - rho(k_min)) / dz
     584
     585    p(1) = constant_density_pressure(p(k_min), zk, rhok, drhodz,            &
     586                                     0.0_wp, G)
     587
     588 END SUBROUTINE get_surface_pressure
     589
     590
     591 FUNCTION constant_density_pressure(pk, zk, rhok, drhodz, z, g)  RESULT(p)
     592
     593    REAL(wp), INTENT(IN)  ::  pk, zk, rhok, drhodz, g, z
     594    REAL(wp) ::  p
     595
     596    p = pk + ( zk - z ) * g * ( rhok + 0.5*drhodz * (zk - z) )
     597
     598 END FUNCTION constant_density_pressure
    594599
    595600!-----------------------------------------------------------------------------!
     
    599604!> vg.
    600605!-----------------------------------------------------------------------------!
    601     SUBROUTINE geostrophic_winds(p_north, p_south, p_east, p_west, rho, f3,    &
    602                                  Lx, Ly, phi_n, lam_n, phi_g, lam_g, ug, vg)
    603 
    604     REAL(dp), DIMENSION(:), INTENT(IN)  ::  p_north, p_south, p_east, p_west,  &
     606 SUBROUTINE geostrophic_winds(p_north, p_south, p_east, p_west, rho, f3,    &
     607                              Lx, Ly, phi_n, lam_n, phi_g, lam_g, ug, vg)
     608
     609    REAL(wp), DIMENSION(:), INTENT(IN)  ::  p_north, p_south, p_east, p_west,  &
    605610                                            rho
    606     REAL(dp), INTENT(IN)                ::  f3, Lx, Ly, phi_n, lam_n, phi_g, lam_g
    607     REAL(dp), DIMENSION(:), INTENT(OUT) ::  ug, vg
    608     REAL(dp)                            ::  facx, facy
    609 
    610     facx = 1.0_dp / (Lx * f3)
    611     facy = 1.0_dp / (Ly * f3)
     611    REAL(wp), INTENT(IN)                ::  f3, Lx, Ly, phi_n, lam_n, phi_g, lam_g
     612    REAL(wp), DIMENSION(:), INTENT(OUT) ::  ug, vg
     613    REAL(wp)                            ::  facx, facy
     614
     615    facx = 1.0_wp / (Lx * f3)
     616    facy = 1.0_wp / (Ly * f3)
    612617    ug(:) = - facy / rho(:) * (p_north(:) - p_south(:))
    613618    vg(:) =   facx / rho(:) * (p_east(:) - p_west(:))
     
    617622    )
    618623
    619     END SUBROUTINE geostrophic_winds
     624 END SUBROUTINE geostrophic_winds
    620625
    621626
     
    627632!> lngitude of a geographical system centered at x0 and y0.
    628633!-----------------------------------------------------------------------------!
    629     SUBROUTINE inv_plate_carree(x, y, x0, y0, r, lat, lon)
    630        REAL(dp), INTENT(IN)  ::  x(:), y(:), x0, y0, r
    631        REAL(dp), INTENT(OUT) ::  lat(:), lon(:)
    632        
    633        REAL(dp) :: ri
    634 
    635 !
    636 !--    TODO check dimensions of lat/lon and y/x match
    637 
    638        ri = 1.0_dp / r
    639        
    640        lat(:) = (y(:) - y0) * ri
    641        lon(:) = (x(:) - x0) * ri
    642     END SUBROUTINE
     634 SUBROUTINE inv_plate_carree(x, y, x0, y0, r, lat, lon)
     635    REAL(wp), INTENT(IN)  ::  x(:), y(:), x0, y0, r
     636    REAL(wp), INTENT(OUT) ::  lat(:), lon(:)
     637   
     638    REAL(wp) :: ri
     639
     640!
     641!-- TODO check dimensions of lat/lon and y/x match
     642
     643    ri = 1.0_wp / r
     644   
     645    lat(:) = (y(:) - y0) * ri
     646    lon(:) = (x(:) - x0) * ri
     647 END SUBROUTINE
    643648
    644649
     
    663668!>     coordinate xy.
    664669!------------------------------------------------------------------------------!
    665     ELEMENTAL REAL(dp) FUNCTION project(xy, xy0, r)
    666        REAL(dp), INTENT(IN)  ::  xy, xy0, r
    667        REAL(dp) :: ri
    668 
    669 !
    670 !--    If this elemental function is called with a large array as xy, it is
    671 !--    computationally more efficient to precompute the inverse radius and
    672 !--    then muliply.
    673        ri = 1.0_dp / r
    674 
    675        project = (xy - xy0) * ri
    676 
    677     END FUNCTION project
     670 ELEMENTAL REAL(wp) FUNCTION project(xy, xy0, r)
     671    REAL(wp), INTENT(IN)  ::  xy, xy0, r
     672    REAL(wp) :: ri
     673
     674!
     675!-- If this elemental function is called with a large array as xy, it is
     676!-- computationally more efficient to precompute the inverse radius and
     677!-- then muliply.
     678    ri = 1.0_wp / r
     679
     680    project = (xy - xy0) * ri
     681
     682 END FUNCTION project
    678683
    679684
     
    684689!> compute the geographical latitude of its rotated north pole.
    685690!------------------------------------------------------------------------------!
    686     REAL(dp) FUNCTION phic_to_phin(phi_c)
    687         REAL(dp), INTENT(IN) ::  phi_c
    688 
    689         phic_to_phin = 0.5_dp * PI - ABS(phi_c)
    690 
    691     END FUNCTION phic_to_phin
     691 REAL(wp) FUNCTION phic_to_phin(phi_c)
     692     REAL(wp), INTENT(IN) ::  phi_c
     693
     694     phic_to_phin = 0.5_wp * PI - ABS(phi_c)
     695
     696 END FUNCTION phic_to_phin
    692697
    693698   
     
    699704!> north pole.
    700705!------------------------------------------------------------------------------!
    701     REAL(dp) FUNCTION lamc_to_lamn(phi_c, lam_c)
    702        REAL(dp), INTENT(IN) ::  phi_c, lam_c
    703         
    704        lamc_to_lamn = lam_c
    705        IF (phi_c > 0.0_dp)  THEN
    706           lamc_to_lamn = lam_c - SIGN(PI, lam_c)
    707        ENDIF
    708 
    709     END FUNCTION lamc_to_lamn
     706 REAL(wp) FUNCTION lamc_to_lamn(phi_c, lam_c)
     707    REAL(wp), INTENT(IN) ::  phi_c, lam_c
     708     
     709    lamc_to_lamn = lam_c
     710    IF (phi_c > 0.0_wp)  THEN
     711       lamc_to_lamn = lam_c - SIGN(PI, lam_c)
     712    ENDIF
     713
     714 END FUNCTION lamc_to_lamn
    710715
    711716
     
    718723!> rotated-pole coordinate transformations.
    719724!------------------------------------------------------------------------------!
    720     REAL(dp) FUNCTION gamma_from_hemisphere(phi_cg, phi_ref)
    721        REAL(dp), INTENT(IN) ::  phi_cg
    722        REAL(dp), INTENT(IN) ::  phi_ref
    723 
    724        LOGICAL ::  palm_origin_is_south_of_cosmo_origin
    725        
    726        palm_origin_is_south_of_cosmo_origin = (phi_cg < phi_ref)
    727 
    728        IF (palm_origin_is_south_of_cosmo_origin)  THEN
    729            gamma_from_hemisphere = PI
    730        ELSE
    731            gamma_from_hemisphere = 0.0_dp
    732        ENDIF
    733     END FUNCTION gamma_from_hemisphere
     725 REAL(wp) FUNCTION gamma_from_hemisphere(phi_cg, phi_ref)
     726    REAL(wp), INTENT(IN) ::  phi_cg
     727    REAL(wp), INTENT(IN) ::  phi_ref
     728
     729    LOGICAL ::  palm_origin_is_south_of_cosmo_origin
     730   
     731    palm_origin_is_south_of_cosmo_origin = (phi_cg < phi_ref)
     732
     733    IF (palm_origin_is_south_of_cosmo_origin)  THEN
     734        gamma_from_hemisphere = PI
     735    ELSE
     736        gamma_from_hemisphere = 0.0_wp
     737    ENDIF
     738 END FUNCTION gamma_from_hemisphere
    734739
    735740
     
    760765!> phi(:,:), lam(:,:): geographical latitudes and logitudes
    761766!------------------------------------------------------------------------------!
    762     SUBROUTINE rotate_to_cosmo(phir, lamr, phip, lamp, phi, lam, gam)
    763        REAL(dp), INTENT(IN)  ::  phir(0:), lamr(0:), phip, lamp, gam
    764        REAL(dp), INTENT(OUT) ::  phi(0:,0:), lam(0:,0:)
    765 
    766        INTEGER ::  i, j
     767 SUBROUTINE rotate_to_cosmo(phir, lamr, phip, lamp, phi, lam, gam)
     768    REAL(wp), INTENT(IN)  ::  phir(0:), lamr(0:), phip, lamp, gam
     769    REAL(wp), INTENT(OUT) ::  phi(0:,0:), lam(0:,0:)
     770
     771    INTEGER ::  i, j
     772   
     773    IF ( SIZE(phi, 1) .NE. SIZE(lam, 1) .OR. &
     774         SIZE(phi, 2) .NE. SIZE(lam, 2) )  THEN
     775       PRINT *, "inifor: rotate_to_cosmo: Dimensions of phi and lambda do not match. Dimensions are:"
     776       PRINT *, "inifor: rotate_to_cosmo: phi: ", SIZE(phi, 1), SIZE(phi, 2)
     777       PRINT *, "inifor: rotate_to_cosmo: lam: ", SIZE(lam, 1), SIZE(lam, 2)
     778       STOP
     779    ENDIF
     780
     781    IF ( SIZE(phir) .NE. SIZE(phi, 2) .OR. &
     782         SIZE(lamr) .NE. SIZE(phi, 1) )  THEN
     783       PRINT *, "inifor: rotate_to_cosmo: Dimensions of phir and lamr do not match. Dimensions are:"
     784       PRINT *, "inifor: rotate_to_cosmo: phir: ", SIZE(phir), SIZE(phi, 2)
     785       PRINT *, "inifor: rotate_to_cosmo: lamr: ", SIZE(lamr), SIZE(phi, 1)
     786       STOP
     787    ENDIF
     788   
     789    DO  j = 0, UBOUND(phir, 1)
     790       DO  i = 0, UBOUND(lamr, 1)
     791
     792          phi(i,j) = phirot2phi(phir(j) * TO_DEGREES,                       &
     793                                lamr(i) * TO_DEGREES,                       &
     794                                phip * TO_DEGREES,                          &
     795                                gam  * TO_DEGREES) * TO_RADIANS
     796
     797          lam(i,j) = rlarot2rla(phir(j) * TO_DEGREES,                       &
     798                                lamr(i) * TO_DEGREES,                       &
     799                                phip * TO_DEGREES,                          &
     800                                lamp * TO_DEGREES,                          &
     801                                gam  * TO_DEGREES) * TO_RADIANS
     802
     803       ENDDO
     804    ENDDO
     805
     806 END SUBROUTINE rotate_to_cosmo
    767807       
    768        IF ( SIZE(phi, 1) .NE. SIZE(lam, 1) .OR. &
    769             SIZE(phi, 2) .NE. SIZE(lam, 2) )  THEN
    770           PRINT *, "inifor: rotate_to_cosmo: Dimensions of phi and lambda do not match. Dimensions are:"
    771           PRINT *, "inifor: rotate_to_cosmo: phi: ", SIZE(phi, 1), SIZE(phi, 2)
    772           PRINT *, "inifor: rotate_to_cosmo: lam: ", SIZE(lam, 1), SIZE(lam, 2)
    773           STOP
    774        ENDIF
    775 
    776        IF ( SIZE(phir) .NE. SIZE(phi, 2) .OR. &
    777             SIZE(lamr) .NE. SIZE(phi, 1) )  THEN
    778           PRINT *, "inifor: rotate_to_cosmo: Dimensions of phir and lamr do not match. Dimensions are:"
    779           PRINT *, "inifor: rotate_to_cosmo: phir: ", SIZE(phir), SIZE(phi, 2)
    780           PRINT *, "inifor: rotate_to_cosmo: lamr: ", SIZE(lamr), SIZE(phi, 1)
    781           STOP
    782        ENDIF
    783        
    784        DO j = 0, UBOUND(phir, 1)
    785           DO i = 0, UBOUND(lamr, 1)
    786 
    787              phi(i,j) = phirot2phi(phir(j) * TO_DEGREES,                       &
    788                                    lamr(i) * TO_DEGREES,                       &
    789                                    phip * TO_DEGREES,                          &
    790                                    gam  * TO_DEGREES) * TO_RADIANS
    791 
    792              lam(i,j) = rlarot2rla(phir(j) * TO_DEGREES,                       &
    793                                    lamr(i) * TO_DEGREES,                       &
    794                                    phip * TO_DEGREES,                          &
    795                                    lamp * TO_DEGREES,                          &
    796                                    gam  * TO_DEGREES) * TO_RADIANS
    797 
    798           ENDDO
    799        ENDDO
    800 
    801     END SUBROUTINE rotate_to_cosmo
    802        
    803808
    804809!------------------------------------------------------------------------------!
     
    807812!> Rotate the given vector field (x(:), y(:)) by the given 'angle'.
    808813!------------------------------------------------------------------------------!
    809     SUBROUTINE rotate_vector_field(x, y, angle)
    810        REAL(dp), DIMENSION(:), INTENT(INOUT) :: x, y  !< x and y coodrinate in arbitrary units
    811        REAL(dp), INTENT(IN)                  :: angle !< rotation angle [deg]
    812 
    813        INTEGER  :: i
    814        REAL(dp) :: sine, cosine, v_rot(2), rotation(2,2)
    815 
    816        sine = SIN(angle * TO_RADIANS)
    817        cosine = COS(angle * TO_RADIANS)
    818 !
    819 !--    RESAHPE() fills columns first, so the rotation matrix becomes
    820 !--    
    821 !--    rotation = [ cosine   -sine  ]
    822 !--               [  sine    cosine ]
    823        rotation = RESHAPE( (/cosine, sine, -sine, cosine/), (/2, 2/) )
    824 
    825        DO i = LBOUND(x, 1), UBOUND(x, 1)
    826 
    827           v_rot(:) = MATMUL(rotation, (/x(i), y(i)/))
    828 
    829           x(i) = v_rot(1)
    830           y(i) = v_rot(2)
    831 
    832        ENDDO
    833 
    834     END SUBROUTINE rotate_vector_field
     814 SUBROUTINE rotate_vector_field(x, y, angle)
     815    REAL(wp), DIMENSION(:), INTENT(INOUT) :: x, y  !< x and y coodrinate in arbitrary units
     816    REAL(wp), INTENT(IN)                  :: angle !< rotation angle [deg]
     817
     818    INTEGER  :: i
     819    REAL(wp) :: sine, cosine, v_rot(2), rotation(2,2)
     820
     821    sine = SIN(angle * TO_RADIANS)
     822    cosine = COS(angle * TO_RADIANS)
     823!
     824!-- RESAHPE() fills columns first, so the rotation matrix becomes
     825!--
     826!-- rotation = [ cosine   -sine  ]
     827!--            [  sine    cosine ]
     828    rotation = RESHAPE( (/cosine, sine, -sine, cosine/), (/2, 2/) )
     829
     830    DO i = LBOUND(x, 1), UBOUND(x, 1)
     831
     832       v_rot(:) = MATMUL(rotation, (/x(i), y(i)/))
     833
     834       x(i) = v_rot(1)
     835       y(i) = v_rot(2)
     836
     837    ENDDO
     838
     839 END SUBROUTINE rotate_vector_field
    835840
    836841
     
    847852!>    https://www.dwd.de/SharedDocs/downloads/DE/modelldokumentationen/nwv/cosmo_d2/cosmo_d2_dbbeschr_aktuell.pdf?__blob=publicationFile&v=2
    848853!------------------------------------------------------------------------------!
    849     FUNCTION meridian_convergence_rotated(phi_n, lam_n, phi_g, lam_g)          &
    850        RESULT(delta)
    851 
    852        REAL(dp), INTENT(IN) ::  phi_n, lam_n, phi_g, lam_g
    853        REAL(dp)             ::  delta
    854 
    855        delta = atan2( COS(phi_n) * SIN(lam_n - lam_g),                         &
    856                       COS(phi_g) * SIN(phi_n) -                                &
    857                       SIN(phi_g) * COS(phi_n) * COS(lam_n - lam_g) )
    858 
    859     END FUNCTION meridian_convergence_rotated
     854 FUNCTION meridian_convergence_rotated(phi_n, lam_n, phi_g, lam_g)          &
     855    RESULT(delta)
     856
     857    REAL(wp), INTENT(IN) ::  phi_n, lam_n, phi_g, lam_g
     858    REAL(wp)             ::  delta
     859
     860    delta = atan2( COS(phi_n) * SIN(lam_n - lam_g),                         &
     861                   COS(phi_g) * SIN(phi_n) -                                &
     862                   SIN(phi_g) * COS(phi_n) * COS(lam_n - lam_g) )
     863
     864 END FUNCTION meridian_convergence_rotated
    860865
    861866!------------------------------------------------------------------------------!
     
    903908!>
    904909!------------------------------------------------------------------------------!
    905     SUBROUTINE find_horizontal_neighbours(cosmo_lat, cosmo_lon,                &
    906                                           palm_clat, palm_clon,                &
    907                                           palm_ii, palm_jj)
    908 
    909        REAL(dp), DIMENSION(0:), INTENT(IN)        ::  cosmo_lat, cosmo_lon
    910        REAL(dp), DIMENSION(0:,0:), INTENT(IN)     ::  palm_clat, palm_clon
    911        REAL(dp)                                   ::  cosmo_dxi, cosmo_dyi
    912        INTEGER, DIMENSION(0:,0:,1:), INTENT(OUT)  ::  palm_ii, palm_jj
    913 
    914        REAL(dp) ::  lonpos, latpos, lon0, lat0
    915        INTEGER  ::  i, j
    916 
    917        lon0 = cosmo_lon(0)
    918        lat0 = cosmo_lat(0)
    919        cosmo_dxi = 1.0_dp / (cosmo_lon(1) - cosmo_lon(0))
    920        cosmo_dyi = 1.0_dp / (cosmo_lat(1) - cosmo_lat(0))
    921 
    922        DO j = 0, UBOUND(palm_clon, 2)!palm_grid % ny
    923        DO i = 0, UBOUND(palm_clon, 1)!palm_grid % nx
    924 !
    925 !--       Compute the floating point index corrseponding to PALM-4U grid point
    926 !--       location along target grid (COSMO-DE) axes.
    927           lonpos = (palm_clon(i,j) - lon0) * cosmo_dxi
    928           latpos = (palm_clat(i,j) - lat0) * cosmo_dyi
    929 
    930           IF (lonpos < 0.0_dp .OR. latpos < 0.0_dp)  THEN
    931              message = "lonpos or latpos out of bounds " //                    &
    932                 "while finding interpolation neighbours!" // NEW_LINE(' ') //  &
    933                 "          (i,j) = (" //                                       &
    934                 TRIM(str(i)) // ", " // TRIM(str(j)) // ")" // NEW_LINE(' ') //&
    935                 "          lonpos " // TRIM(real_to_str(lonpos*TO_DEGREES)) // &
    936                 ", latpos " // TRIM(real_to_str(latpos*TO_DEGREES)) // NEW_LINE(' ') // &
    937                 "          lon0 " // TRIM(real_to_str(lon0  *TO_DEGREES)) //   &
    938                 ", lat0   " // TRIM(real_to_str(lat0*TO_DEGREES)) // NEW_LINE(' ') // &
    939                 "          PALM lon " // TRIM(real_to_str(palm_clon(i,j)*TO_DEGREES)) // &
    940                 ", PALM lat " // TRIM(real_to_str(palm_clat(i,j)*TO_DEGREES))
    941              CALL inifor_abort('find_horizontal_neighbours', message)
    942           ENDIF
    943 
    944           palm_ii(i,j,1) = FLOOR(lonpos)
    945           palm_ii(i,j,2) = FLOOR(lonpos)
    946           palm_ii(i,j,3) = CEILING(lonpos)
    947           palm_ii(i,j,4) = CEILING(lonpos)
    948 
    949           palm_jj(i,j,1) = FLOOR(latpos)
    950           palm_jj(i,j,2) = CEILING(latpos)
    951           palm_jj(i,j,3) = CEILING(latpos)
    952           palm_jj(i,j,4) = FLOOR(latpos)
    953        ENDDO
    954        ENDDO
    955 
    956     END SUBROUTINE find_horizontal_neighbours
     910 SUBROUTINE find_horizontal_neighbours(cosmo_lat, cosmo_lon,                &
     911                                       palm_clat, palm_clon,                &
     912                                       palm_ii, palm_jj)
     913
     914    REAL(wp), DIMENSION(0:), INTENT(IN)        ::  cosmo_lat, cosmo_lon
     915    REAL(wp), DIMENSION(0:,0:), INTENT(IN)     ::  palm_clat, palm_clon
     916    REAL(wp)                                   ::  cosmo_dxi, cosmo_dyi
     917    INTEGER, DIMENSION(0:,0:,1:), INTENT(OUT)  ::  palm_ii, palm_jj
     918
     919    REAL(wp) ::  lonpos, latpos, lon0, lat0
     920    INTEGER  ::  i, j
     921
     922    lon0 = cosmo_lon(0)
     923    lat0 = cosmo_lat(0)
     924    cosmo_dxi = 1.0_wp / (cosmo_lon(1) - cosmo_lon(0))
     925    cosmo_dyi = 1.0_wp / (cosmo_lat(1) - cosmo_lat(0))
     926
     927    DO  j = 0, UBOUND(palm_clon, 2)!palm_grid%ny
     928    DO  i = 0, UBOUND(palm_clon, 1)!palm_grid%nx
     929!
     930!--    Compute the floating point index corrseponding to PALM-4U grid point
     931!--    location along target grid (COSMO-DE) axes.
     932       lonpos = (palm_clon(i,j) - lon0) * cosmo_dxi
     933       latpos = (palm_clat(i,j) - lat0) * cosmo_dyi
     934
     935       IF (lonpos < 0.0_wp .OR. latpos < 0.0_wp)  THEN
     936          message = "lonpos or latpos out of bounds " //                    &
     937             "while finding interpolation neighbours!" // NEW_LINE(' ') //  &
     938             "          (i,j) = (" //                                       &
     939             TRIM(str(i)) // ", " // TRIM(str(j)) // ")" // NEW_LINE(' ') //&
     940             "          lonpos " // TRIM(real_to_str(lonpos*TO_DEGREES)) // &
     941             ", latpos " // TRIM(real_to_str(latpos*TO_DEGREES)) // NEW_LINE(' ') // &
     942             "          lon0 " // TRIM(real_to_str(lon0  *TO_DEGREES)) //   &
     943             ", lat0   " // TRIM(real_to_str(lat0*TO_DEGREES)) // NEW_LINE(' ') // &
     944             "          PALM lon " // TRIM(real_to_str(palm_clon(i,j)*TO_DEGREES)) // &
     945             ", PALM lat " // TRIM(real_to_str(palm_clat(i,j)*TO_DEGREES))
     946          CALL inifor_abort('find_horizontal_neighbours', message)
     947       ENDIF
     948
     949       palm_ii(i,j,1) = FLOOR(lonpos)
     950       palm_ii(i,j,2) = FLOOR(lonpos)
     951       palm_ii(i,j,3) = CEILING(lonpos)
     952       palm_ii(i,j,4) = CEILING(lonpos)
     953
     954       palm_jj(i,j,1) = FLOOR(latpos)
     955       palm_jj(i,j,2) = CEILING(latpos)
     956       palm_jj(i,j,3) = CEILING(latpos)
     957       palm_jj(i,j,4) = FLOOR(latpos)
     958    ENDDO
     959    ENDDO
     960
     961 END SUBROUTINE find_horizontal_neighbours
    957962
    958963   
     
    963968!> column of the given palm grid.
    964969!------------------------------------------------------------------------------!
    965     SUBROUTINE find_vertical_neighbours_and_weights_interp( palm_grid,         &
     970 SUBROUTINE find_vertical_neighbours_and_weights_interp( palm_grid,         &
    966971                                                            palm_intermediate )
    967        TYPE(grid_definition), INTENT(INOUT) ::  palm_grid
    968        TYPE(grid_definition), INTENT(IN)    ::  palm_intermediate
    969 
    970        INTEGER  ::  i, j, k, nx, ny, nz, nlev, k_intermediate
    971        LOGICAL  ::  point_is_below_grid, point_is_above_grid,                  &
    972                     point_is_in_current_cell
    973        REAL(dp) ::  current_height, column_base, column_top, h_top, h_bottom,  &
    974                     weight
    975 
    976        nx   = palm_grid % nx
    977        ny   = palm_grid % ny
    978        nz   = palm_grid % nz
    979        nlev = palm_intermediate % nz
    980 
    981 !
    982 !--    in each column of the fine grid, find vertical neighbours of every cell
    983        DO j = 0, ny
    984        DO i = 0, nx
    985 
    986           k_intermediate = 0
    987 
    988           column_base = palm_intermediate % h(i,j,0)
    989           column_top  = palm_intermediate % h(i,j,nlev)
    990 
    991 !
    992 !--       scan through palm_grid column and set neighbour indices in
    993 !--       case current_height is either below column_base, in the current
    994 !--       cell, or above column_top. Keep increasing current cell index until
    995 !--       the current cell overlaps with the current_height.
    996           DO k = 1, nz
    997 
    998 !
    999 !--          Memorize the top and bottom boundaries of the coarse cell and the
    1000 !--          current height within it
    1001              current_height = palm_grid % z(k) + palm_grid % z0
    1002              h_top    = palm_intermediate % h(i,j,k_intermediate+1)
    1003              h_bottom = palm_intermediate % h(i,j,k_intermediate)
    1004 
    1005              point_is_above_grid = (current_height > column_top) !22000m, very unlikely
    1006              point_is_below_grid = (current_height < column_base)
    1007 
    1008              point_is_in_current_cell = (                                      &
    1009                 current_height >= h_bottom .AND.                               &
    1010                 current_height <  h_top                                        &
    1011              )
    1012 
    1013 !
    1014 !--          set default weights
    1015              palm_grid % w_verti(i,j,k,1:2) = 0.0_dp
    1016 
    1017              IF (point_is_above_grid)  THEN
    1018 
    1019                 palm_grid % kk(i,j,k,1:2) = nlev
    1020                 palm_grid % w_verti(i,j,k,1:2) = - 2.0_dp
    1021 
    1022                 message = "PALM-4U grid extends above COSMO-DE model top."
    1023                 CALL inifor_abort('find_vertical_neighbours_and_weights', message)
    1024 
    1025              ELSE IF (point_is_below_grid)  THEN
    1026 
    1027                 palm_grid % kk(i,j,k,1:2) = 0
    1028                 palm_grid % w_verti(i,j,k,1:2) = - 2.0_dp
    1029 
    1030              ELSE
    1031 !
    1032 !--             cycle through intermediate levels until current
    1033 !--             intermediate-grid cell overlaps with current_height
    1034                 DO WHILE (.NOT. point_is_in_current_cell .AND. k_intermediate <= nlev-1)
    1035                    k_intermediate = k_intermediate + 1
    1036 
    1037                    h_top    = palm_intermediate % h(i,j,k_intermediate+1)
    1038                    h_bottom = palm_intermediate % h(i,j,k_intermediate)
    1039                    point_is_in_current_cell = (                                &
    1040                       current_height >= h_bottom .AND.                         &
    1041                       current_height <  h_top                                  &
    1042                    )
    1043                 ENDDO
    1044 
    1045                 IF (k_intermediate > nlev-1)  THEN
    1046                    message = "Index " // TRIM(str(k_intermediate)) //          &
    1047                              " is above intermediate grid range."
    1048                    CALL inifor_abort('find_vertical_neighbours', message)
    1049                 ENDIF
     972    TYPE(grid_definition), INTENT(INOUT) ::  palm_grid
     973    TYPE(grid_definition), INTENT(IN)    ::  palm_intermediate
     974
     975    INTEGER  ::  i, j, k, nx, ny, nz, nlev, k_intermediate
     976    LOGICAL  ::  point_is_below_grid, point_is_above_grid,                  &
     977                 point_is_in_current_cell
     978    REAL(wp) ::  current_height, column_base, column_top, h_top, h_bottom,  &
     979                 weight
     980
     981    nx   = palm_grid%nx
     982    ny   = palm_grid%ny
     983    nz   = palm_grid%nz
     984    nlev = palm_intermediate%nz
     985
     986!
     987!-- in each column of the fine grid, find vertical neighbours of every cell
     988    DO j = 0, ny
     989    DO i = 0, nx
     990
     991       k_intermediate = 0
     992
     993       column_base = palm_intermediate%h(i,j,0)
     994       column_top  = palm_intermediate%h(i,j,nlev)
     995
     996!
     997!--    scan through palm_grid column and set neighbour indices in
     998!--    case current_height is either below column_base, in the current
     999!--    cell, or above column_top. Keep increasing current cell index until
     1000!--    the current cell overlaps with the current_height.
     1001       DO k = 1, nz
     1002
     1003!
     1004!--       Memorize the top and bottom boundaries of the coarse cell and the
     1005!--       current height within it
     1006          current_height = palm_grid%z(k) + palm_grid%z0
     1007          h_top    = palm_intermediate%h(i,j,k_intermediate+1)
     1008          h_bottom = palm_intermediate%h(i,j,k_intermediate)
     1009
     1010          point_is_above_grid = (current_height > column_top) !22000m, very unlikely
     1011          point_is_below_grid = (current_height < column_base)
     1012
     1013          point_is_in_current_cell = (                                      &
     1014             current_height >= h_bottom .AND.                               &
     1015             current_height <  h_top                                        &
     1016          )
     1017
     1018!
     1019!--       set default weights
     1020          palm_grid%w_verti(i,j,k,1:2) = 0.0_wp
     1021
     1022          IF (point_is_above_grid)  THEN
     1023
     1024             palm_grid%kk(i,j,k,1:2) = nlev
     1025             palm_grid%w_verti(i,j,k,1:2) = - 2.0_wp
     1026
     1027             message = "PALM-4U grid extends above COSMO-DE model top."
     1028             CALL inifor_abort('find_vertical_neighbours_and_weights', message)
     1029
     1030          ELSE IF (point_is_below_grid)  THEN
     1031
     1032             palm_grid%kk(i,j,k,1:2) = 0
     1033             palm_grid%w_verti(i,j,k,1:2) = - 2.0_wp
     1034
     1035          ELSE
     1036!
     1037!--          cycle through intermediate levels until current
     1038!--          intermediate-grid cell overlaps with current_height
     1039             DO WHILE (.NOT. point_is_in_current_cell .AND. k_intermediate <= nlev-1)
     1040                k_intermediate = k_intermediate + 1
     1041
     1042                h_top    = palm_intermediate%h(i,j,k_intermediate+1)
     1043                h_bottom = palm_intermediate%h(i,j,k_intermediate)
     1044                point_is_in_current_cell = (                                &
     1045                   current_height >= h_bottom .AND.                         &
     1046                   current_height <  h_top                                  &
     1047                )
     1048             ENDDO
     1049
     1050             IF (k_intermediate > nlev-1)  THEN
     1051                message = "Index " // TRIM(str(k_intermediate)) //          &
     1052                          " is above intermediate grid range."
     1053                CALL inifor_abort('find_vertical_neighbours', message)
     1054             ENDIF
    10501055   
    1051                 palm_grid % kk(i,j,k,1) = k_intermediate
    1052                 palm_grid % kk(i,j,k,2) = k_intermediate + 1
    1053 
    1054 !
    1055 !--             compute vertical weights
    1056                 weight = (h_top - current_height) / (h_top - h_bottom)
    1057                 palm_grid % w_verti(i,j,k,1) = weight
    1058                 palm_grid % w_verti(i,j,k,2) = 1.0_dp - weight
    1059              ENDIF
    1060 
    1061           ENDDO
     1056             palm_grid%kk(i,j,k,1) = k_intermediate
     1057             palm_grid%kk(i,j,k,2) = k_intermediate + 1
     1058
     1059!
     1060!--          compute vertical weights
     1061             weight = (h_top - current_height) / (h_top - h_bottom)
     1062             palm_grid%w_verti(i,j,k,1) = weight
     1063             palm_grid%w_verti(i,j,k,2) = 1.0_wp - weight
     1064          ENDIF
    10621065
    10631066       ENDDO
    1064        ENDDO
    1065 
    1066     END SUBROUTINE find_vertical_neighbours_and_weights_interp
     1067
     1068    ENDDO
     1069    ENDDO
     1070
     1071 END SUBROUTINE find_vertical_neighbours_and_weights_interp
    10671072
    10681073
     
    10791084!> iii(:) and jjj(:).
    10801085!------------------------------------------------------------------------------!
    1081     SUBROUTINE find_vertical_neighbours_and_weights_average(                   &
    1082        avg_grid, level_based_averaging                                         &
    1083     )
    1084 
    1085        TYPE(grid_definition), INTENT(INOUT), TARGET ::  avg_grid
    1086        LOGICAL                                      ::  level_based_averaging
    1087 
    1088        INTEGER           ::  i, j, k_palm, k_intermediate, l, nlev
    1089        LOGICAL           ::  point_is_below_grid, point_is_above_grid,         &
    1090                              point_is_in_current_cell
    1091        REAL(dp)          ::  current_height, column_base, column_top, h_top,   &
    1092                              h_bottom, weight
    1093        REAL(dp), POINTER ::  cosmo_h(:,:,:)
    1094 
    1095 
    1096        avg_grid % k_min = LBOUND(avg_grid % z, 1)
    1097 
    1098        nlev = SIZE(avg_grid % cosmo_h, 3)
     1086 SUBROUTINE find_vertical_neighbours_and_weights_average(                   &
     1087    avg_grid, level_based_averaging                                         &
     1088 )
     1089
     1090    TYPE(grid_definition), INTENT(INOUT), TARGET ::  avg_grid
     1091    LOGICAL                                      ::  level_based_averaging
     1092
     1093    INTEGER           ::  i, j, k_palm, k_intermediate, l, nlev
     1094    LOGICAL           ::  point_is_below_grid, point_is_above_grid,         &
     1095                          point_is_in_current_cell
     1096    REAL(wp)          ::  current_height, column_base, column_top, h_top,   &
     1097                          h_bottom, weight
     1098    REAL(wp), POINTER ::  cosmo_h(:,:,:)
     1099
     1100
     1101    avg_grid%k_min = LBOUND(avg_grid%z, 1)
     1102
     1103    nlev = SIZE(avg_grid%cosmo_h, 3)
     1104
     1105    IF (level_based_averaging)  THEN
     1106       cosmo_h => avg_grid%h
     1107    ELSE
     1108       cosmo_h => avg_grid%cosmo_h
     1109    ENDIF
     1110
     1111!
     1112!-- in each column of the fine grid, find vertical neighbours of every cell
     1113    DO  l = 1, avg_grid%n_columns
    10991114
    11001115       IF (level_based_averaging)  THEN
    1101           cosmo_h => avg_grid % h
     1116          i = 1
     1117          j = 1
    11021118       ELSE
    1103           cosmo_h => avg_grid % cosmo_h
     1119          i = avg_grid%iii(l)
     1120          j = avg_grid%jjj(l)
    11041121       ENDIF
    11051122
    1106 !
    1107 !--    in each column of the fine grid, find vertical neighbours of every cell
    1108        DO l = 1, avg_grid % n_columns
    1109 
    1110           IF (level_based_averaging)  THEN
    1111              i = 1
    1112              j = 1
     1123       column_base = cosmo_h(i,j,1)
     1124       column_top  = cosmo_h(i,j,nlev)
     1125
     1126!
     1127!--    scan through avg_grid column until and set neighbour indices in
     1128!--    case current_height is either below column_base, in the current
     1129!--    cell, or above column_top. Keep increasing current cell index until
     1130!--    the current cell overlaps with the current_height.
     1131       k_intermediate = 1 !avg_grid%cosmo_h is indezed 1-based.
     1132       DO  k_palm = 1, avg_grid%nz
     1133
     1134!
     1135!--       Memorize the top and bottom boundaries of the coarse cell and the
     1136!--       current height within it
     1137          current_height = avg_grid%z(k_palm) + avg_grid%z0
     1138          h_top    = cosmo_h(i,j,k_intermediate+1)
     1139          h_bottom = cosmo_h(i,j,k_intermediate)
     1140
     1141!
     1142!--       COSMO column top is located at 22000m, point_is_above_grid is very
     1143!--       unlikely.
     1144          point_is_above_grid = (current_height > column_top)
     1145          point_is_below_grid = (current_height < column_base)
     1146
     1147          point_is_in_current_cell = (                                      &
     1148             current_height >= h_bottom .AND.                               &
     1149             current_height <  h_top                                        &
     1150          )
     1151
     1152!
     1153!--       set default weights
     1154          avg_grid%w(l,k_palm,1:2) = 0.0_wp
     1155
     1156          IF (point_is_above_grid)  THEN
     1157
     1158             avg_grid%kkk(l,k_palm,1:2) = nlev
     1159             avg_grid%w(l,k_palm,1:2) = - 2.0_wp
     1160
     1161             message = "PALM-4U grid extends above COSMO-DE model top."
     1162             CALL inifor_abort('find_vertical_neighbours_and_weights_average', message)
     1163
     1164          ELSE IF (point_is_below_grid)  THEN
     1165
     1166             avg_grid%kkk(l,k_palm,1:2) = 0
     1167             avg_grid%w(l,k_palm,1:2) = - 2.0_wp
     1168             avg_grid%k_min = MAX(k_palm + 1, avg_grid%k_min)
    11131169          ELSE
    1114              i = avg_grid % iii(l)
    1115              j = avg_grid % jjj(l)
     1170!
     1171!--          cycle through intermediate levels until current
     1172!--          intermediate-grid cell overlaps with current_height
     1173             DO  WHILE (.NOT. point_is_in_current_cell .AND. k_intermediate <= nlev-1)
     1174                k_intermediate = k_intermediate + 1
     1175
     1176                h_top    = cosmo_h(i,j,k_intermediate+1)
     1177                h_bottom = cosmo_h(i,j,k_intermediate)
     1178                point_is_in_current_cell = (                                &
     1179                   current_height >= h_bottom .AND.                         &
     1180                   current_height <  h_top                                  &
     1181                )
     1182             ENDDO
     1183
     1184!
     1185!--          k_intermediate = 48 indicates the last section (indices 48 and 49), i.e.
     1186!--          k_intermediate = 49 is not the beginning of a valid cell.
     1187             IF (k_intermediate > nlev-1)  THEN
     1188                message = "Index " // TRIM(str(k_intermediate)) //          &
     1189                          " is above intermediate grid range."
     1190                CALL inifor_abort('find_vertical_neighbours', message)
     1191             ENDIF
     1192   
     1193             avg_grid%kkk(l,k_palm,1) = k_intermediate
     1194             avg_grid%kkk(l,k_palm,2) = k_intermediate + 1
     1195
     1196!
     1197!--          compute vertical weights
     1198             weight = (h_top - current_height) / (h_top - h_bottom)
     1199             avg_grid%w(l,k_palm,1) = weight
     1200             avg_grid%w(l,k_palm,2) = 1.0_wp - weight
    11161201          ENDIF
    11171202
    1118           column_base = cosmo_h(i,j,1)
    1119           column_top  = cosmo_h(i,j,nlev)
    1120 
    1121 !
    1122 !--       scan through avg_grid column until and set neighbour indices in
    1123 !--       case current_height is either below column_base, in the current
    1124 !--       cell, or above column_top. Keep increasing current cell index until
    1125 !--       the current cell overlaps with the current_height.
    1126           k_intermediate = 1 !avg_grid % cosmo_h is indezed 1-based.
    1127           DO k_palm = 1, avg_grid % nz
    1128 
    1129 !
    1130 !--          Memorize the top and bottom boundaries of the coarse cell and the
    1131 !--          current height within it
    1132              current_height = avg_grid % z(k_palm) + avg_grid % z0
    1133              h_top    = cosmo_h(i,j,k_intermediate+1)
    1134              h_bottom = cosmo_h(i,j,k_intermediate)
    1135 
    1136 !
    1137 !--          COSMO column top is located at 22000m, point_is_above_grid is very
    1138 !--          unlikely.
    1139              point_is_above_grid = (current_height > column_top)
    1140              point_is_below_grid = (current_height < column_base)
    1141 
    1142              point_is_in_current_cell = (                                      &
    1143                 current_height >= h_bottom .AND.                               &
    1144                 current_height <  h_top                                        &
    1145              )
    1146 
    1147 !
    1148 !--          set default weights
    1149              avg_grid % w(l,k_palm,1:2) = 0.0_dp
    1150 
    1151              IF (point_is_above_grid)  THEN
    1152 
    1153                 avg_grid % kkk(l,k_palm,1:2) = nlev
    1154                 avg_grid % w(l,k_palm,1:2) = - 2.0_dp
    1155 
    1156                 message = "PALM-4U grid extends above COSMO-DE model top."
    1157                 CALL inifor_abort('find_vertical_neighbours_and_weights_average', message)
    1158 
    1159              ELSE IF (point_is_below_grid)  THEN
    1160 
    1161                 avg_grid % kkk(l,k_palm,1:2) = 0
    1162                 avg_grid % w(l,k_palm,1:2) = - 2.0_dp
    1163                 avg_grid % k_min = MAX(k_palm + 1, avg_grid % k_min)
    1164              ELSE
    1165 !
    1166 !--             cycle through intermediate levels until current
    1167 !--             intermediate-grid cell overlaps with current_height
    1168                 DO WHILE (.NOT. point_is_in_current_cell .AND. k_intermediate <= nlev-1)
    1169                    k_intermediate = k_intermediate + 1
    1170 
    1171                    h_top    = cosmo_h(i,j,k_intermediate+1)
    1172                    h_bottom = cosmo_h(i,j,k_intermediate)
    1173                    point_is_in_current_cell = (                                &
    1174                       current_height >= h_bottom .AND.                         &
    1175                       current_height <  h_top                                  &
    1176                    )
    1177                 ENDDO
    1178 
    1179 !
    1180 !--             k_intermediate = 48 indicates the last section (indices 48 and 49), i.e.
    1181 !--             k_intermediate = 49 is not the beginning of a valid cell.
    1182                 IF (k_intermediate > nlev-1)  THEN
    1183                    message = "Index " // TRIM(str(k_intermediate)) //          &
    1184                              " is above intermediate grid range."
    1185                    CALL inifor_abort('find_vertical_neighbours', message)
    1186                 ENDIF
    1187    
    1188                 avg_grid % kkk(l,k_palm,1) = k_intermediate
    1189                 avg_grid % kkk(l,k_palm,2) = k_intermediate + 1
    1190 
    1191 !
    1192 !--             compute vertical weights
    1193                 weight = (h_top - current_height) / (h_top - h_bottom)
    1194                 avg_grid % w(l,k_palm,1) = weight
    1195                 avg_grid % w(l,k_palm,2) = 1.0_dp - weight
    1196              ENDIF
    1197 
    1198 !
    1199 !--       Loop over PALM levels k
    1200           ENDDO
    1201 
    1202 !
    1203 !--       Loop over averaging columns l
     1203!
     1204!--    Loop over PALM levels k
    12041205       ENDDO
     1206
     1207!
     1208!--    Loop over averaging columns l
     1209    ENDDO
    12051210 
    1206     END SUBROUTINE find_vertical_neighbours_and_weights_average
     1211 END SUBROUTINE find_vertical_neighbours_and_weights_average
    12071212
    12081213!------------------------------------------------------------------------------!
     
    12151220!> Input parameters:
    12161221!> -----------------
    1217 !> palm_grid % clon : longitudes of PALM-4U scalars (cell centres) in COSMO-DE's rotated-pole grid [rad]
    1218 !>
    1219 !> palm_grid % clat : latitudes of PALM-4U cell centres in COSMO-DE's rotated-pole grid [rad]
    1220 !>
    1221 !> cosmo_grid % lon : rotated-pole longitudes of scalars (cell centres) of the COSMO-DE grid [rad]
    1222 !>
    1223 !> cosmo_grid % lat : rotated-pole latitudes of scalars (cell centers) of the COSMO-DE grid [rad]
    1224 !>
    1225 !> cosmo_grid % dxi : inverse grid spacing in the first dimension [m^-1]
    1226 !>
    1227 !> cosmo_grid % dyi : inverse grid spacing in the second dimension [m^-1]
     1222!> palm_grid%clon : longitudes of PALM-4U scalars (cell centres) in COSMO-DE's rotated-pole grid [rad]
     1223!>
     1224!> palm_grid%clat : latitudes of PALM-4U cell centres in COSMO-DE's rotated-pole grid [rad]
     1225!>
     1226!> cosmo_grid%lon : rotated-pole longitudes of scalars (cell centres) of the COSMO-DE grid [rad]
     1227!>
     1228!> cosmo_grid%lat : rotated-pole latitudes of scalars (cell centers) of the COSMO-DE grid [rad]
     1229!>
     1230!> cosmo_grid%dxi : inverse grid spacing in the first dimension [m^-1]
     1231!>
     1232!> cosmo_grid%dyi : inverse grid spacing in the second dimension [m^-1]
    12281233!>
    12291234!> Output parameters:
    12301235!> ------------------
    1231 !> palm_grid % w_horiz(:,:,1-4) : weights for bilinear horizontal interpolation
     1236!> palm_grid%w_horiz(:,:,1-4) : weights for bilinear horizontal interpolation
    12321237!
    12331238!                               COSMO-DE grid
     
    12511256!         
    12521257!------------------------------------------------------------------------------!
    1253     SUBROUTINE compute_horizontal_interp_weights(cosmo_lat, cosmo_lon,         &
    1254        palm_clat, palm_clon, palm_ii, palm_jj, palm_w_horiz)
     1258 SUBROUTINE compute_horizontal_interp_weights(cosmo_lat, cosmo_lon,         &
     1259    palm_clat, palm_clon, palm_ii, palm_jj, palm_w_horiz)
    12551260       
    1256        REAL(dp), DIMENSION(0:), INTENT(IN)        ::  cosmo_lat, cosmo_lon
    1257        REAL(dp)                                   ::  cosmo_dxi, cosmo_dyi
    1258        REAL(dp), DIMENSION(0:,0:), INTENT(IN)     ::  palm_clat, palm_clon
    1259        INTEGER, DIMENSION(0:,0:,1:), INTENT(IN)   ::  palm_ii, palm_jj
    1260 
    1261        REAL(dp), DIMENSION(0:,0:,1:), INTENT(OUT) ::  palm_w_horiz
    1262 
    1263        REAL(dp) ::  wl, wp
    1264        INTEGER  ::  i, j
    1265 
    1266        cosmo_dxi = 1.0_dp / (cosmo_lon(1) - cosmo_lon(0))
    1267        cosmo_dyi = 1.0_dp / (cosmo_lat(1) - cosmo_lat(0))
    1268 
    1269        DO j = 0, UBOUND(palm_clon, 2)
    1270        DO i = 0, UBOUND(palm_clon, 1)
    1271      
    1272 !
    1273 !--       weight in lambda direction
    1274           wl = ( cosmo_lon(palm_ii(i,j,4)) - palm_clon(i,j) ) * cosmo_dxi
    1275 
    1276 !
    1277 !--       weight in phi direction
    1278           wp = ( cosmo_lat(palm_jj(i,j,2)) - palm_clat(i,j) ) * cosmo_dyi
    1279 
    1280           IF (wl > 1.0_dp .OR. wl < 0.0_dp)  THEN
    1281               message = "Horizontal weight wl = " // TRIM(real_to_str(wl)) //   &
    1282                         " is out bounds."
    1283               CALL inifor_abort('compute_horizontal_interp_weights', message)
    1284           ENDIF
    1285           IF (wp > 1.0_dp .OR. wp < 0.0_dp)  THEN
    1286               message = "Horizontal weight wp = " // TRIM(real_to_str(wp)) //   &
    1287                         " is out bounds."
    1288               CALL inifor_abort('compute_horizontal_interp_weights', message)
    1289           ENDIF
    1290 
    1291           palm_w_horiz(i,j,1) = wl * wp
    1292           palm_w_horiz(i,j,2) = wl * (1.0_dp - wp)
    1293           palm_w_horiz(i,j,3) = (1.0_dp - wl) * (1.0_dp - wp)
    1294           palm_w_horiz(i,j,4) = 1.0_dp - SUM( palm_w_horiz(i,j,1:3) )
    1295 
    1296        ENDDO
    1297        ENDDO
     1261    REAL(wp), DIMENSION(0:), INTENT(IN)        ::  cosmo_lat, cosmo_lon
     1262    REAL(wp)                                   ::  cosmo_dxi, cosmo_dyi
     1263    REAL(wp), DIMENSION(0:,0:), INTENT(IN)     ::  palm_clat, palm_clon
     1264    INTEGER, DIMENSION(0:,0:,1:), INTENT(IN)   ::  palm_ii, palm_jj
     1265
     1266    REAL(wp), DIMENSION(0:,0:,1:), INTENT(OUT) ::  palm_w_horiz
     1267
     1268    REAL(wp) ::  wlambda, wphi
     1269    INTEGER  ::  i, j
     1270
     1271    cosmo_dxi = 1.0_wp / (cosmo_lon(1) - cosmo_lon(0))
     1272    cosmo_dyi = 1.0_wp / (cosmo_lat(1) - cosmo_lat(0))
     1273
     1274    DO j = 0, UBOUND(palm_clon, 2)
     1275    DO i = 0, UBOUND(palm_clon, 1)
     1276   
     1277!
     1278!--    weight in lambda direction
     1279       wlambda = ( cosmo_lon(palm_ii(i,j,4)) - palm_clon(i,j) ) * cosmo_dxi
     1280
     1281!
     1282!--    weight in phi direction
     1283       wphi = ( cosmo_lat(palm_jj(i,j,2)) - palm_clat(i,j) ) * cosmo_dyi
     1284
     1285       IF (wlambda > 1.0_wp .OR. wlambda < 0.0_wp)  THEN
     1286           message = "Horizontal weight wlambda = " // TRIM(real_to_str(wlambda)) //   &
     1287                     " is out bounds."
     1288           CALL inifor_abort('compute_horizontal_interp_weights', message)
     1289       ENDIF
     1290       IF (wphi > 1.0_wp .OR. wphi < 0.0_wp)  THEN
     1291           message = "Horizontal weight wphi = " // TRIM(real_to_str(wphi)) //   &
     1292                     " is out bounds."
     1293           CALL inifor_abort('compute_horizontal_interp_weights', message)
     1294       ENDIF
     1295
     1296       palm_w_horiz(i,j,1) = wlambda * wphi
     1297       palm_w_horiz(i,j,2) = wlambda * (1.0_wp - wphi)
     1298       palm_w_horiz(i,j,3) = (1.0_wp - wlambda) * (1.0_wp - wphi)
     1299       palm_w_horiz(i,j,4) = 1.0_wp - SUM( palm_w_horiz(i,j,1:3) )
     1300
     1301    ENDDO
     1302    ENDDO
    12981303       
    1299     END SUBROUTINE compute_horizontal_interp_weights
     1304 END SUBROUTINE compute_horizontal_interp_weights
    13001305
    13011306
     
    13111316!> which means the first centre point has to be omitted and is set to zero.
    13121317!------------------------------------------------------------------------------!
    1313     SUBROUTINE centre_velocities(u_face, v_face, u_centre, v_centre)
    1314        REAL(dp), DIMENSION(0:,0:,0:), INTENT(IN)  ::  u_face, v_face
    1315        REAL(dp), DIMENSION(0:,0:,0:), INTENT(OUT) ::  u_centre, v_centre
    1316        INTEGER ::  nx, ny
    1317 
    1318        nx = UBOUND(u_face, 1)
    1319        ny = UBOUND(u_face, 2)
    1320 
    1321        u_centre(0,:,:)  = 0.0_dp
    1322        u_centre(1:,:,:) = 0.5_dp * ( u_face(0:nx-1,:,:) + u_face(1:,:,:) )
    1323 
    1324        v_centre(:,0,:)  = 0.0_dp
    1325        v_centre(:,1:,:) = 0.5_dp * ( v_face(:,0:ny-1,:) + v_face(:,1:,:) )
    1326     END SUBROUTINE centre_velocities
     1318 SUBROUTINE centre_velocities(u_face, v_face, u_centre, v_centre)
     1319    REAL(wp), DIMENSION(0:,0:,0:), INTENT(IN)  ::  u_face, v_face
     1320    REAL(wp), DIMENSION(0:,0:,0:), INTENT(OUT) ::  u_centre, v_centre
     1321    INTEGER ::  nx, ny
     1322
     1323    nx = UBOUND(u_face, 1)
     1324    ny = UBOUND(u_face, 2)
     1325
     1326    u_centre(0,:,:)  = 0.0_wp
     1327    u_centre(1:,:,:) = 0.5_wp * ( u_face(0:nx-1,:,:) + u_face(1:,:,:) )
     1328
     1329    v_centre(:,0,:)  = 0.0_wp
     1330    v_centre(:,1:,:) = 0.5_wp * ( v_face(:,0:ny-1,:) + v_face(:,1:,:) )
     1331 END SUBROUTINE centre_velocities
    13271332
    13281333
     
    13321337!> Compute the geographical latitude of a point given in rotated-pole cordinates
    13331338!------------------------------------------------------------------------------!
    1334     FUNCTION phirot2phi (phirot, rlarot, polphi, polgam)
    1335    
    1336        REAL(dp), INTENT (IN) ::  polphi      !< latitude of the rotated north pole
    1337        REAL(dp), INTENT (IN) ::  phirot      !< latitude in the rotated system
    1338        REAL(dp), INTENT (IN) ::  rlarot      !< longitude in the rotated system
    1339        REAL(dp), INTENT (IN) ::  polgam      !< angle between the north poles of the systems
    1340 
    1341        REAL(dp)              ::  phirot2phi  !< latitude in the geographical system
    1342        
    1343        REAL(dp)              ::  zsinpol, zcospol, zphis, zrlas, zarg, zgam
    1344    
    1345        zsinpol = SIN(polphi * TO_RADIANS)
    1346        zcospol = COS(polphi * TO_RADIANS)
    1347        zphis   = phirot * TO_RADIANS
    1348 
    1349        IF (rlarot > 180.0_dp)  THEN
    1350           zrlas = rlarot - 360.0_dp
    1351        ELSE
    1352           zrlas = rlarot
    1353        ENDIF
    1354        zrlas = zrlas * TO_RADIANS
     1339 FUNCTION phirot2phi (phirot, rlarot, polphi, polgam)
     1340 
     1341    REAL(wp), INTENT (IN) ::  polphi      !< latitude of the rotated north pole
     1342    REAL(wp), INTENT (IN) ::  phirot      !< latitude in the rotated system
     1343    REAL(wp), INTENT (IN) ::  rlarot      !< longitude in the rotated system
     1344    REAL(wp), INTENT (IN) ::  polgam      !< angle between the north poles of the systems
     1345
     1346    REAL(wp)              ::  phirot2phi  !< latitude in the geographical system
     1347   
     1348    REAL(wp)              ::  zsinpol, zcospol, zphis, zrlas, zarg, zgam
     1349 
     1350    zsinpol = SIN(polphi * TO_RADIANS)
     1351    zcospol = COS(polphi * TO_RADIANS)
     1352    zphis   = phirot * TO_RADIANS
     1353
     1354    IF (rlarot > 180.0_wp)  THEN
     1355       zrlas = rlarot - 360.0_wp
     1356    ELSE
     1357       zrlas = rlarot
     1358    ENDIF
     1359    zrlas = zrlas * TO_RADIANS
     1360 
     1361    IF (polgam /= 0.0_wp)  THEN
     1362       zgam = polgam * TO_RADIANS
     1363       zarg = zsinpol * SIN (zphis) +                                       &
     1364              zcospol * COS(zphis) * ( COS(zrlas) * COS(zgam) -             &
     1365                                       SIN(zgam)  * SIN(zrlas) )
     1366    ELSE
     1367       zarg = zcospol * COS (zphis) * COS (zrlas) + zsinpol * SIN (zphis)
     1368    ENDIF
     1369   
     1370    phirot2phi = ASIN (zarg) * TO_DEGREES
     1371 
     1372 END FUNCTION phirot2phi
     1373
     1374
     1375!------------------------------------------------------------------------------!
     1376! Description:
     1377! ------------
     1378!> Compute the geographical latitude of a point given in rotated-pole cordinates
     1379!------------------------------------------------------------------------------!
     1380 FUNCTION phi2phirot (phi, rla, polphi, pollam)
     1381 
     1382    REAL(wp), INTENT (IN) ::  polphi !< latitude of the rotated north pole
     1383    REAL(wp), INTENT (IN) ::  pollam !< longitude of the rotated north pole
     1384    REAL(wp), INTENT (IN) ::  phi    !< latitude in the geographical system
     1385    REAL(wp), INTENT (IN) ::  rla    !< longitude in the geographical system
     1386   
     1387    REAL(wp) ::  phi2phirot          !< longitude in the rotated system
     1388   
     1389    REAL(wp) ::  zsinpol, zcospol, zlampol, zphi, zrla, zarg1, zarg2, zrla1
     1390   
     1391    zsinpol = SIN(polphi * TO_RADIANS)
     1392    zcospol = COS(polphi * TO_RADIANS)
     1393    zlampol = pollam * TO_RADIANS
     1394    zphi    = phi * TO_RADIANS
     1395
     1396    IF (rla > 180.0_wp)  THEN
     1397       zrla1 = rla - 360.0_wp
     1398    ELSE
     1399       zrla1 = rla
     1400    ENDIF
     1401    zrla = zrla1 * TO_RADIANS
     1402   
     1403    zarg1 = SIN(zphi) * zsinpol
     1404    zarg2 = COS(zphi) * zcospol * COS(zrla - zlampol)
     1405   
     1406    phi2phirot = ASIN(zarg1 + zarg2) * TO_DEGREES
     1407 
     1408 END FUNCTION phi2phirot
     1409
     1410
     1411!------------------------------------------------------------------------------!
     1412! Description:
     1413! ------------
     1414!> Compute the geographical longitude of a point given in rotated-pole cordinates
     1415!------------------------------------------------------------------------------!
     1416 FUNCTION rlarot2rla(phirot, rlarot, polphi, pollam, polgam)
     1417 
     1418    REAL(wp), INTENT (IN) ::  polphi !< latitude of the rotated north pole
     1419    REAL(wp), INTENT (IN) ::  pollam !< longitude of the rotated north pole
     1420    REAL(wp), INTENT (IN) ::  phirot !< latitude in the rotated system
     1421    REAL(wp), INTENT (IN) ::  rlarot !< longitude in the rotated system
     1422    REAL(wp), INTENT (IN) ::  polgam !< angle between the north poles of the systems
     1423   
     1424    REAL(wp) ::  rlarot2rla          !< latitude in the geographical system
     1425   
     1426    REAL(wp) ::  zsinpol, zcospol, zlampol, zphis, zrlas, zarg1, zarg2, zgam
     1427   
     1428    zsinpol = SIN(TO_RADIANS * polphi)
     1429    zcospol = COS(TO_RADIANS * polphi)
     1430    zlampol = TO_RADIANS * pollam
     1431    zphis   = TO_RADIANS * phirot
     1432
     1433    IF (rlarot > 180.0_wp)  THEN
     1434       zrlas = rlarot - 360.0_wp
     1435    ELSE
     1436       zrlas = rlarot
     1437    ENDIF
     1438    zrlas   = TO_RADIANS * zrlas
     1439   
     1440    IF (polgam /= 0.0_wp)  THEN
     1441       zgam  = TO_RADIANS * polgam
     1442       zarg1 = SIN(zlampol) * (zcospol * SIN(zphis) - zsinpol*COS(zphis) *  &
     1443               (COS(zrlas) * COS(zgam) - SIN(zrlas) * SIN(zgam)) ) -        &
     1444               COS(zlampol) * COS(zphis) * ( SIN(zrlas) * COS(zgam) +       &
     1445                                             COS(zrlas) * SIN(zgam) )
     1446   
     1447       zarg2 = COS (zlampol) * (zcospol * SIN(zphis) - zsinpol*COS(zphis) * &
     1448               (COS(zrlas) * COS(zgam) - SIN(zrlas) * SIN(zgam)) ) +        &
     1449               SIN(zlampol) * COS(zphis) * ( SIN(zrlas) * COS(zgam) +       &
     1450                                             COS(zrlas) * SIN(zgam) )
     1451    ELSE
     1452       zarg1   = SIN (zlampol) * (-zsinpol * COS(zrlas) * COS(zphis)  +     &
     1453                                   zcospol *              SIN(zphis)) -     &
     1454                 COS (zlampol) *             SIN(zrlas) * COS(zphis)
     1455       zarg2   = COS (zlampol) * (-zsinpol * COS(zrlas) * COS(zphis)  +     &
     1456                                   zcospol *              SIN(zphis)) +     &
     1457                 SIN (zlampol) *             SIN(zrlas) * COS(zphis)
     1458    ENDIF
     1459   
     1460    IF (zarg2 == 0.0_wp)  zarg2 = 1.0E-20_wp
     1461   
     1462    rlarot2rla = ATAN2(zarg1,zarg2) * TO_DEGREES
    13551463     
    1356        IF (polgam /= 0.0_dp)  THEN
    1357           zgam = polgam * TO_RADIANS
    1358           zarg = zsinpol * SIN (zphis) +                                       &
    1359                  zcospol * COS(zphis) * ( COS(zrlas) * COS(zgam) -             &
    1360                                           SIN(zgam)  * SIN(zrlas) )
    1361        ELSE
    1362           zarg = zcospol * COS (zphis) * COS (zrlas) + zsinpol * SIN (zphis)
    1363        ENDIF
    1364      
    1365        phirot2phi = ASIN (zarg) * TO_DEGREES
    1366    
    1367     END FUNCTION phirot2phi
    1368 
    1369 
    1370 !------------------------------------------------------------------------------!
    1371 ! Description:
    1372 ! ------------
    1373 !> Compute the geographical latitude of a point given in rotated-pole cordinates
    1374 !------------------------------------------------------------------------------!
    1375     FUNCTION phi2phirot (phi, rla, polphi, pollam)
    1376    
    1377        REAL(dp), INTENT (IN) ::  polphi !< latitude of the rotated north pole
    1378        REAL(dp), INTENT (IN) ::  pollam !< longitude of the rotated north pole
    1379        REAL(dp), INTENT (IN) ::  phi    !< latitude in the geographical system
    1380        REAL(dp), INTENT (IN) ::  rla    !< longitude in the geographical system
    1381        
    1382        REAL(dp) ::  phi2phirot          !< longitude in the rotated system
    1383        
    1384        REAL(dp) ::  zsinpol, zcospol, zlampol, zphi, zrla, zarg1, zarg2, zrla1
    1385        
    1386        zsinpol = SIN(polphi * TO_RADIANS)
    1387        zcospol = COS(polphi * TO_RADIANS)
    1388        zlampol = pollam * TO_RADIANS
    1389        zphi    = phi * TO_RADIANS
    1390 
    1391        IF (rla > 180.0_dp)  THEN
    1392           zrla1 = rla - 360.0_dp
    1393        ELSE
    1394           zrla1 = rla
    1395        ENDIF
    1396        zrla = zrla1 * TO_RADIANS
    1397        
    1398        zarg1 = SIN(zphi) * zsinpol
    1399        zarg2 = COS(zphi) * zcospol * COS(zrla - zlampol)
    1400        
    1401        phi2phirot = ASIN(zarg1 + zarg2) * TO_DEGREES
    1402    
    1403     END FUNCTION phi2phirot
    1404 
    1405 
    1406 !------------------------------------------------------------------------------!
    1407 ! Description:
    1408 ! ------------
    1409 !> Compute the geographical longitude of a point given in rotated-pole cordinates
    1410 !------------------------------------------------------------------------------!
    1411     FUNCTION rlarot2rla(phirot, rlarot, polphi, pollam, polgam)
    1412    
    1413        REAL(dp), INTENT (IN) ::  polphi !< latitude of the rotated north pole
    1414        REAL(dp), INTENT (IN) ::  pollam !< longitude of the rotated north pole
    1415        REAL(dp), INTENT (IN) ::  phirot !< latitude in the rotated system
    1416        REAL(dp), INTENT (IN) ::  rlarot !< longitude in the rotated system
    1417        REAL(dp), INTENT (IN) ::  polgam !< angle between the north poles of the systems
    1418        
    1419        REAL(dp) ::  rlarot2rla          !< latitude in the geographical system
    1420        
    1421        REAL(dp) ::  zsinpol, zcospol, zlampol, zphis, zrlas, zarg1, zarg2, zgam
    1422        
    1423        zsinpol = SIN(TO_RADIANS * polphi)
    1424        zcospol = COS(TO_RADIANS * polphi)
    1425        zlampol = TO_RADIANS * pollam
    1426        zphis   = TO_RADIANS * phirot
    1427 
    1428        IF (rlarot > 180.0_dp)  THEN
    1429           zrlas = rlarot - 360.0_dp
    1430        ELSE
    1431           zrlas = rlarot
    1432        ENDIF
    1433        zrlas   = TO_RADIANS * zrlas
    1434      
    1435        IF (polgam /= 0.0_dp)  THEN
    1436           zgam  = TO_RADIANS * polgam
    1437           zarg1 = SIN(zlampol) * (zcospol * SIN(zphis) - zsinpol*COS(zphis) *  &
    1438                   (COS(zrlas) * COS(zgam) - SIN(zrlas) * SIN(zgam)) ) -        &
    1439                   COS(zlampol) * COS(zphis) * ( SIN(zrlas) * COS(zgam) +       &
    1440                                                 COS(zrlas) * SIN(zgam) )
    1441        
    1442           zarg2 = COS (zlampol) * (zcospol * SIN(zphis) - zsinpol*COS(zphis) * &
    1443                   (COS(zrlas) * COS(zgam) - SIN(zrlas) * SIN(zgam)) ) +        &
    1444                   SIN(zlampol) * COS(zphis) * ( SIN(zrlas) * COS(zgam) +       &
    1445                                                 COS(zrlas) * SIN(zgam) )
    1446        ELSE
    1447           zarg1   = SIN (zlampol) * (-zsinpol * COS(zrlas) * COS(zphis)  +     &
    1448                                       zcospol *              SIN(zphis)) -     &
    1449                     COS (zlampol) *             SIN(zrlas) * COS(zphis)
    1450           zarg2   = COS (zlampol) * (-zsinpol * COS(zrlas) * COS(zphis)  +     &
    1451                                       zcospol *              SIN(zphis)) +     &
    1452                     SIN (zlampol) *             SIN(zrlas) * COS(zphis)
    1453        ENDIF
    1454      
    1455        IF (zarg2 == 0.0_dp)  zarg2 = 1.0E-20_dp
    1456      
    1457        rlarot2rla = ATAN2(zarg1,zarg2) * TO_DEGREES
    1458        
    1459     END FUNCTION rlarot2rla
     1464 END FUNCTION rlarot2rla
    14601465
    14611466
     
    14651470!> Compute the rotated-pole longitude of a point given in geographical cordinates
    14661471!------------------------------------------------------------------------------!
    1467     FUNCTION rla2rlarot ( phi, rla, polphi, pollam, polgam )
    1468 
    1469        REAL(dp), INTENT (IN) ::  polphi !< latitude of the rotated north pole
    1470        REAL(dp), INTENT (IN) ::  pollam !< longitude of the rotated north pole
    1471        REAL(dp), INTENT (IN) ::  phi    !< latitude in geographical system
    1472        REAL(dp), INTENT (IN) ::  rla    !< longitude in geographical system
    1473        REAL(dp), INTENT (IN) ::  polgam !< angle between the north poles of the systems
    1474        
    1475        REAL (KIND=dp) ::  rla2rlarot    !< latitude in the the rotated system
    1476        
    1477        REAL (KIND=dp) ::  zsinpol, zcospol, zlampol, zphi, zrla, zarg1, zarg2, zrla1
    1478        
    1479        zsinpol = SIN(polphi * TO_RADIANS)
    1480        zcospol = COS(polphi * TO_RADIANS)
    1481        zlampol = pollam * TO_RADIANS
    1482        zphi    = phi * TO_RADIANS
    1483 
    1484        IF (rla > 180.0_dp)  THEN
    1485           zrla1 = rla - 360.0_dp
    1486        ELSE
    1487           zrla1 = rla
    1488        ENDIF
    1489        zrla = zrla1 * TO_RADIANS
    1490        
    1491        zarg1 = - SIN (zrla-zlampol) * COS(zphi)
    1492        zarg2 = - zsinpol * COS(zphi) * COS(zrla-zlampol) + zcospol * SIN(zphi)
    1493        
    1494        IF (zarg2 == 0.0_dp)  zarg2 = 1.0E-20_dp
    1495        
    1496        rla2rlarot = ATAN2 (zarg1,zarg2) * TO_DEGREES
    1497        
    1498        IF (polgam /= 0.0_dp )  THEN
    1499           rla2rlarot = polgam + rla2rlarot
    1500           IF (rla2rlarot > 180._dp)  rla2rlarot = rla2rlarot - 360.0_dp
    1501        ENDIF
    1502        
    1503     END FUNCTION rla2rlarot
     1472 FUNCTION rla2rlarot ( phi, rla, polphi, pollam, polgam )
     1473
     1474    REAL(wp), INTENT (IN) ::  polphi !< latitude of the rotated north pole
     1475    REAL(wp), INTENT (IN) ::  pollam !< longitude of the rotated north pole
     1476    REAL(wp), INTENT (IN) ::  phi    !< latitude in geographical system
     1477    REAL(wp), INTENT (IN) ::  rla    !< longitude in geographical system
     1478    REAL(wp), INTENT (IN) ::  polgam !< angle between the north poles of the systems
     1479   
     1480    REAL(wp) ::  rla2rlarot    !< latitude in the the rotated system
     1481   
     1482    REAL(wp) ::  zsinpol, zcospol, zlampol, zphi, zrla, zarg1, zarg2, zrla1
     1483   
     1484    zsinpol = SIN(polphi * TO_RADIANS)
     1485    zcospol = COS(polphi * TO_RADIANS)
     1486    zlampol = pollam * TO_RADIANS
     1487    zphi    = phi * TO_RADIANS
     1488
     1489    IF (rla > 180.0_wp)  THEN
     1490       zrla1 = rla - 360.0_wp
     1491    ELSE
     1492       zrla1 = rla
     1493    ENDIF
     1494    zrla = zrla1 * TO_RADIANS
     1495   
     1496    zarg1 = - SIN (zrla-zlampol) * COS(zphi)
     1497    zarg2 = - zsinpol * COS(zphi) * COS(zrla-zlampol) + zcospol * SIN(zphi)
     1498   
     1499    IF (zarg2 == 0.0_wp)  zarg2 = 1.0E-20_wp
     1500   
     1501    rla2rlarot = ATAN2 (zarg1,zarg2) * TO_DEGREES
     1502   
     1503    IF (polgam /= 0.0_wp )  THEN
     1504       rla2rlarot = polgam + rla2rlarot
     1505       IF (rla2rlarot > 180._wp)  rla2rlarot = rla2rlarot - 360.0_wp
     1506    ENDIF
     1507   
     1508 END FUNCTION rla2rlarot
    15041509
    15051510
     
    15101515!> rotated-pole system
    15111516!------------------------------------------------------------------------------!
    1512     SUBROUTINE uv2uvrot(u, v, rlat, rlon, pollat, pollon, urot, vrot)
    1513     
    1514        REAL(dp), INTENT (IN)  ::  u, v           !< wind components in the true geographical system
    1515        REAL(dp), INTENT (IN)  ::  rlat, rlon     !< coordinates in the true geographical system
    1516        REAL(dp), INTENT (IN)  ::  pollat, pollon !< latitude and longitude of the north pole of the rotated grid
    1517        
    1518        REAL(dp), INTENT (OUT) ::  urot, vrot     !< wind components in the rotated grid             
    1519        
    1520        REAL (dp) ::  zsinpol, zcospol, zlonp, zlat, zarg1, zarg2, znorm
    1521        
    1522        zsinpol = SIN(pollat * TO_RADIANS)
    1523        zcospol = COS(pollat * TO_RADIANS)
    1524        zlonp   = (pollon-rlon) * TO_RADIANS
    1525        zlat    = rlat * TO_RADIANS
    1526        
    1527        zarg1 = zcospol * SIN(zlonp)
    1528        zarg2 = zsinpol * COS(zlat) - zcospol * SIN(zlat) * COS(zlonp)
    1529        znorm = 1.0_dp / SQRT(zarg1*zarg1 + zarg2*zarg2)
    1530        
    1531        urot = u * zarg2 * znorm - v * zarg1 * znorm
    1532        vrot = u * zarg1 * znorm + v * zarg2 * znorm
    1533     
    1534     END SUBROUTINE uv2uvrot
     1517 SUBROUTINE uv2uvrot(u, v, rlat, rlon, pollat, pollon, urot, vrot)
     1518 
     1519    REAL(wp), INTENT (IN)  ::  u, v           !< wind components in the true geographical system
     1520    REAL(wp), INTENT (IN)  ::  rlat, rlon     !< coordinates in the true geographical system
     1521    REAL(wp), INTENT (IN)  ::  pollat, pollon !< latitude and longitude of the north pole of the rotated grid
     1522   
     1523    REAL(wp), INTENT (OUT) ::  urot, vrot     !< wind components in the rotated grid             
     1524   
     1525    REAL (wp) ::  zsinpol, zcospol, zlonp, zlat, zarg1, zarg2, znorm
     1526   
     1527    zsinpol = SIN(pollat * TO_RADIANS)
     1528    zcospol = COS(pollat * TO_RADIANS)
     1529    zlonp   = (pollon-rlon) * TO_RADIANS
     1530    zlat    = rlat * TO_RADIANS
     1531   
     1532    zarg1 = zcospol * SIN(zlonp)
     1533    zarg2 = zsinpol * COS(zlat) - zcospol * SIN(zlat) * COS(zlonp)
     1534    znorm = 1.0_wp / SQRT(zarg1*zarg1 + zarg2*zarg2)
     1535   
     1536    urot = u * zarg2 * znorm - v * zarg1 * znorm
     1537    vrot = u * zarg1 * znorm + v * zarg2 * znorm
     1538 
     1539 END SUBROUTINE uv2uvrot
    15351540
    15361541
     
    15411546!> geographical system
    15421547!------------------------------------------------------------------------------!
    1543     SUBROUTINE uvrot2uv (urot, vrot, rlat, rlon, pollat, pollon, u, v)
    1544     
    1545        REAL(dp), INTENT(IN) ::  urot, vrot     !< wind components in the rotated grid
    1546        REAL(dp), INTENT(IN) ::  rlat, rlon     !< latitude and longitude in the true geographical system
    1547        REAL(dp), INTENT(IN) ::  pollat, pollon !< latitude and longitude of the north pole of the rotated grid
    1548        
    1549        REAL(dp), INTENT(OUT) ::  u, v          !< wind components in the true geographical system
    1550        
    1551        REAL(dp) ::  zsinpol, zcospol, zlonp, zlat, zarg1, zarg2, znorm
    1552      
    1553        zsinpol = SIN(pollat * TO_RADIANS)
    1554        zcospol = COS(pollat * TO_RADIANS)
    1555        zlonp   = (pollon-rlon) * TO_RADIANS
    1556        zlat    = rlat * TO_RADIANS
    1557      
    1558        zarg1 = zcospol * SIN(zlonp)
    1559        zarg2 = zsinpol * COS(zlat) - zcospol * SIN(zlat) * COS(zlonp)
    1560        znorm = 1.0_dp / SQRT(zarg1*zarg1 + zarg2*zarg2)
    1561      
    1562        u =   urot * zarg2 * znorm + vrot * zarg1 * znorm
    1563        v = - urot * zarg1 * znorm + vrot * zarg2 * znorm
    1564     
    1565     END SUBROUTINE uvrot2uv
     1548 SUBROUTINE uvrot2uv (urot, vrot, rlat, rlon, pollat, pollon, u, v)
     1549 
     1550    REAL(wp), INTENT(IN) ::  urot, vrot     !< wind components in the rotated grid
     1551    REAL(wp), INTENT(IN) ::  rlat, rlon     !< latitude and longitude in the true geographical system
     1552    REAL(wp), INTENT(IN) ::  pollat, pollon !< latitude and longitude of the north pole of the rotated grid
     1553   
     1554    REAL(wp), INTENT(OUT) ::  u, v          !< wind components in the true geographical system
     1555   
     1556    REAL(wp) ::  zsinpol, zcospol, zlonp, zlat, zarg1, zarg2, znorm
     1557 
     1558    zsinpol = SIN(pollat * TO_RADIANS)
     1559    zcospol = COS(pollat * TO_RADIANS)
     1560    zlonp   = (pollon-rlon) * TO_RADIANS
     1561    zlat    = rlat * TO_RADIANS
     1562 
     1563    zarg1 = zcospol * SIN(zlonp)
     1564    zarg2 = zsinpol * COS(zlat) - zcospol * SIN(zlat) * COS(zlonp)
     1565    znorm = 1.0_wp / SQRT(zarg1*zarg1 + zarg2*zarg2)
     1566 
     1567    u =   urot * zarg2 * znorm + vrot * zarg1 * znorm
     1568    v = - urot * zarg1 * znorm + vrot * zarg2 * znorm
     1569 
     1570 END SUBROUTINE uvrot2uv
    15661571
    15671572 END MODULE inifor_transform
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_types.f90

    r3779 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29!
     30!
     31! 3779 2019-03-05 11:13:35Z eckhard
    2832! Improved variable naming
    2933!
     
    6872!> The types module provides derived data types used in INIFOR.
    6973!------------------------------------------------------------------------------!
    70 #if defined ( __netcdf )
    7174 MODULE inifor_types
    7275 
    7376 USE inifor_defs,                                                              &
    74     ONLY:  dp, DATE, PATH, SNAME, LNAME
     77    ONLY:  DATE, PATH, SNAME, LNAME, wp
     78
     79#if defined ( __netcdf )
    7580 USE netcdf,                                                                   &
    7681    ONLY:  NF90_MAX_VAR_DIMS, NF90_MAX_NAME
     82#endif
    7783
    7884 IMPLICIT NONE
     
    104110    CHARACTER(LEN=SNAME) ::  rotation_method      !< selects method for velocity rotation
    105111
    106     REAL(dp)             ::  p0                   !< manually specified surface pressure [Pa]
    107     REAL(dp)             ::  ug                   !< manually spefied geostrophic wind component in x direction [m/s]
    108     REAL(dp)             ::  vg                   !< manually spefied geostrophic wind component in y direction [m/s]
    109     REAL(dp)             ::  z0                   !< elevation of the PALM-4U domain above sea level [m]
    110     REAL(dp)             ::  averaging_angle      !< latitudal and longitudal width of averaging regions [deg]
     112    REAL(wp)             ::  p0                   !< manually specified surface pressure [Pa]
     113    REAL(wp)             ::  ug                   !< manually spefied geostrophic wind component in x direction [m/s]
     114    REAL(wp)             ::  vg                   !< manually spefied geostrophic wind component in y direction [m/s]
     115    REAL(wp)             ::  z0                   !< elevation of the PALM-4U domain above sea level [m]
     116    REAL(wp)             ::  averaging_angle      !< latitudal and longitudal width of averaging regions [deg]
    111117   
    112118    LOGICAL              ::  debug                       !< indicates whether --debug option was given
     
    143149    INTEGER, ALLOCATABLE  ::  jjj(:)        !< profile averaging neighbour indices
    144150    INTEGER, ALLOCATABLE  ::  kkk(:,:,:)    !< indices of vertical interpolation neightbours, kkk(<source column>, <PALM k level>, <neighbour index>)
    145     REAL(dp)              ::  lx            !< domain length in the first dimension [m]
    146     REAL(dp)              ::  ly            !< domain length in the second dimension [m]
    147     REAL(dp)              ::  x0            !< x coordinate of PALM-4U domain projection centre, i.e. location of zero distortion
    148     REAL(dp)              ::  y0            !< y coordinate of PALM-4U domain projection centre, i.e. location of zwro distortion
    149     REAL(dp)              ::  z0            !< displacement of the coordinate origin above sea level [m]
    150     REAL(dp), ALLOCATABLE ::  x(:)          !< coordinates of cell centers in x direction [m]
    151     REAL(dp), ALLOCATABLE ::  y(:)          !< coordinates of cell centers in y direction [m]
    152     REAL(dp), POINTER     ::  z(:)          !< coordinates of cell centers in z direction [m]
    153     REAL(dp), ALLOCATABLE ::  h(:,:,:)      !< heights grid point for intermediate grids [m]
    154     REAL(dp), POINTER     ::  cosmo_h(:,:,:)!< pointer to appropriate COSMO level heights (scalar/w) [m]
    155     REAL(dp), POINTER     ::  hhl(:,:,:)    !< heights of half layers (cell faces) above sea level in COSMO-DE, read in from
    156     REAL(dp), POINTER     ::  hfl(:,:,:)    !< heights of full layers (cell centres) above sea level in COSMO-DE, computed as arithmetic average of hhl
    157     REAL(dp), POINTER     ::  depths(:)     !< depths of output soil layers, equal the depths of the source model (e.g. COSMO-DE)
    158     REAL(dp), ALLOCATABLE ::  xu(:)         !< coordinates of cell faces in x direction [m]
    159     REAL(dp), ALLOCATABLE ::  yv(:)         !< coordinates of cell faces in y direction [m]
    160     REAL(dp), POINTER     ::  zw(:)         !< coordinates of cell faces in z direction [m]
    161     REAL(dp), ALLOCATABLE ::  lat(:)        !< rotated-pole latitudes of scalars (cell centers) of the COSMO-DE grid [rad]
    162     REAL(dp), ALLOCATABLE ::  lon(:)        !< rotated-pole longitudes of scalars (cell centres) of the COSMO-DE grid [rad]
    163     REAL(dp), ALLOCATABLE ::  latv(:)       !< rotated-pole latitudes of v winds (face centres in latitudal/y direction) [rad]
    164     REAL(dp), ALLOCATABLE ::  lonu(:)       !< rotated-pole latitudes of u winds (face centres in longitudal/x direction) [rad]
    165     REAL(dp), ALLOCATABLE ::  clat(:,:)     !< latitudes of PALM-4U cell centres in COSMO-DE's rotated-pole grid [rad]
    166     REAL(dp), ALLOCATABLE ::  clon(:,:)     !< longitudes of PALM-4U scalars (cell centres) in COSMO-DE's rotated-pole grid [rad]
    167     REAL(dp), ALLOCATABLE ::  clatu(:,:)    !< latitudes of PALM-4U u winds (cell faces in u direction) in COSMO-DE's rotated-pole grid [rad]
    168     REAL(dp), ALLOCATABLE ::  clonu(:,:)    !< longitudes of PALM-4U u winds (cell faces in u direction) in COSMO-DE's rotated-pole grid [rad]
    169     REAL(dp), ALLOCATABLE ::  clatv(:,:)    !< latitudes of PALM-4U v winds (cell faces in v direction) in COSMO-DE's rotated-pole grid [rad]
    170     REAL(dp), ALLOCATABLE ::  clonv(:,:)    !< longitudes of PALM-4U v winds (cell faces in v direction) in COSMO-DE's rotated-pole grid [rad]
    171     REAL(dp), ALLOCATABLE ::  w_horiz(:,:,:)   !< weights for bilinear horizontal interpolation
    172     REAL(dp), ALLOCATABLE ::  w_verti(:,:,:,:) !< weights for linear vertical interpolation
    173     REAL(dp), ALLOCATABLE ::  w(:,:,:)      !< vertical interpolation weights, w(<source_column>, <PALM k level>, <neighbour index>) [-]
     151    REAL(wp)              ::  lx            !< domain length in the first dimension [m]
     152    REAL(wp)              ::  ly            !< domain length in the second dimension [m]
     153    REAL(wp)              ::  x0            !< x coordinate of PALM-4U domain projection centre, i.e. location of zero distortion
     154    REAL(wp)              ::  y0            !< y coordinate of PALM-4U domain projection centre, i.e. location of zwro distortion
     155    REAL(wp)              ::  z0            !< displacement of the coordinate origin above sea level [m]
     156    REAL(wp), ALLOCATABLE ::  x(:)          !< coordinates of cell centers in x direction [m]
     157    REAL(wp), ALLOCATABLE ::  y(:)          !< coordinates of cell centers in y direction [m]
     158    REAL(wp), POINTER     ::  z(:)          !< coordinates of cell centers in z direction [m]
     159    REAL(wp), ALLOCATABLE ::  h(:,:,:)      !< heights grid point for intermediate grids [m]
     160    REAL(wp), POINTER     ::  cosmo_h(:,:,:)!< pointer to appropriate COSMO level heights (scalar/w) [m]
     161    REAL(wp), POINTER     ::  hhl(:,:,:)    !< heights of half layers (cell faces) above sea level in COSMO-DE, read in from
     162    REAL(wp), POINTER     ::  hfl(:,:,:)    !< heights of full layers (cell centres) above sea level in COSMO-DE, computed as arithmetic average of hhl
     163    REAL(wp), POINTER     ::  depths(:)     !< depths of output soil layers, equal the depths of the source model (e.g. COSMO-DE)
     164    REAL(wp), ALLOCATABLE ::  xu(:)         !< coordinates of cell faces in x direction [m]
     165    REAL(wp), ALLOCATABLE ::  yv(:)         !< coordinates of cell faces in y direction [m]
     166    REAL(wp), POINTER     ::  zw(:)         !< coordinates of cell faces in z direction [m]
     167    REAL(wp), ALLOCATABLE ::  lat(:)        !< rotated-pole latitudes of scalars (cell centers) of the COSMO-DE grid [rad]
     168    REAL(wp), ALLOCATABLE ::  lon(:)        !< rotated-pole longitudes of scalars (cell centres) of the COSMO-DE grid [rad]
     169    REAL(wp), ALLOCATABLE ::  latv(:)       !< rotated-pole latitudes of v winds (face centres in latitudal/y direction) [rad]
     170    REAL(wp), ALLOCATABLE ::  lonu(:)       !< rotated-pole latitudes of u winds (face centres in longitudal/x direction) [rad]
     171    REAL(wp), ALLOCATABLE ::  clat(:,:)     !< latitudes of PALM-4U cell centres in COSMO-DE's rotated-pole grid [rad]
     172    REAL(wp), ALLOCATABLE ::  clon(:,:)     !< longitudes of PALM-4U scalars (cell centres) in COSMO-DE's rotated-pole grid [rad]
     173    REAL(wp), ALLOCATABLE ::  clatu(:,:)    !< latitudes of PALM-4U u winds (cell faces in u direction) in COSMO-DE's rotated-pole grid [rad]
     174    REAL(wp), ALLOCATABLE ::  clonu(:,:)    !< longitudes of PALM-4U u winds (cell faces in u direction) in COSMO-DE's rotated-pole grid [rad]
     175    REAL(wp), ALLOCATABLE ::  clatv(:,:)    !< latitudes of PALM-4U v winds (cell faces in v direction) in COSMO-DE's rotated-pole grid [rad]
     176    REAL(wp), ALLOCATABLE ::  clonv(:,:)    !< longitudes of PALM-4U v winds (cell faces in v direction) in COSMO-DE's rotated-pole grid [rad]
     177    REAL(wp), ALLOCATABLE ::  w_horiz(:,:,:)   !< weights for bilinear horizontal interpolation
     178    REAL(wp), ALLOCATABLE ::  w_verti(:,:,:,:) !< weights for linear vertical interpolation
     179    REAL(wp), ALLOCATABLE ::  w(:,:,:)      !< vertical interpolation weights, w(<source_column>, <PALM k level>, <neighbour index>) [-]
    174180 END TYPE grid_definition
    175181
     
    190196    INTEGER               ::  dimvarids_vel(3)  !< NetCDF IDs of the grid coordinates of velocities xu, yu, zu. Note that velocities are located at mix of both coordinates, e.g. u(xu, y, z).
    191197    INTEGER               ::  dimvarids_soil(3) !< NetCDF IDs of the grid coordinates for soil points x, y, depth
    192     REAL(dp), POINTER     ::  time(:)           !< vector of output time steps
     198    REAL(wp), POINTER     ::  time(:)           !< vector of output time steps
    193199 END TYPE nc_file
    194200
     
    199205!> Metadata container for netCDF variables
    200206!------------------------------------------------------------------------------!
     207#if defined ( __netcdf )
    201208 TYPE nc_var
    202209    INTEGER                               ::  varid     !< NetCDF ID of the variable
     
    247254    LOGICAL                          ::  is_preprocessed = .FALSE. !< Inifor flag indicating whether the I/O group has been preprocessed
    248255 END TYPE io_group
    249 
     256#endif
    250257
    251258!------------------------------------------------------------------------------!
     
    257264!------------------------------------------------------------------------------!
    258265 TYPE container
    259    REAL(dp), ALLOCATABLE ::  array(:,:,:)               !< generic data array
     266   REAL(wp), ALLOCATABLE ::  array(:,:,:)               !< generic data array
    260267   LOGICAL               ::  is_preprocessed = .FALSE.  !< flag indicating whether input array has been preprocessed
    261268 END TYPE container
    262269
    263270 END MODULE inifor_types
    264 #endif
    265 
  • TabularUnified palm/trunk/UTIL/inifor/src/inifor_util.f90

    r3785 r3866  
    2626! -----------------
    2727! $Id$
     28! Use PALM's working precision
     29! Improved coding style
     30!
     31!
     32! 3785 2019-03-06 10:41:14Z eckhard
    2833! Prefixed all INIFOR modules with inifor_
    2934!
     
    5863!> The util module provides miscellaneous utility routines for INIFOR.
    5964!------------------------------------------------------------------------------!
    60 #if defined ( __netcdf )
    6165 MODULE inifor_util
    6266
    6367    USE inifor_defs,                                                           &
    64         ONLY :  dp, PI, DATE, SNAME
     68        ONLY :  PI, DATE, SNAME, wp
    6569    USE inifor_types,                                                          &
    6670        ONLY :  grid_definition
     
    8791    END TYPE
    8892
    89     INTERFACE
     93 INTERFACE
    9094
    9195!------------------------------------------------------------------------------!
     
    9599!> structure.
    96100!------------------------------------------------------------------------------!
    97        FUNCTION strptime(string, format, timeinfo) BIND(c, NAME='strptime')
    98           IMPORT :: C_CHAR, C_SIZE_T, tm_struct
    99 
    100           IMPLICIT NONE
    101 
    102           CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) ::  string, format
    103           TYPE(tm_struct), INTENT(OUT)                     ::  timeinfo
    104 
    105           INTEGER(C_SIZE_T)                                ::  strptime
    106        END FUNCTION
     101    FUNCTION strptime(string, format, timeinfo) BIND(c, NAME='strptime')
     102       IMPORT :: C_CHAR, C_SIZE_T, tm_struct
     103
     104       IMPLICIT NONE
     105
     106       CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) ::  string, format
     107       TYPE(tm_struct), INTENT(OUT)                     ::  timeinfo
     108
     109       INTEGER(C_SIZE_T)                                ::  strptime
     110    END FUNCTION
    107111
    108112
     
    113117!> structure to a string in the given 'format'.
    114118!------------------------------------------------------------------------------!
    115        FUNCTION strftime(string, string_len, format, timeinfo) BIND(c, NAME='strftime')
    116           IMPORT :: C_CHAR, C_SIZE_T, tm_struct
    117 
    118           IMPLICIT NONE
    119 
    120           CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(OUT) ::  string
    121           CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN)  ::  format
    122           INTEGER(C_SIZE_T), INTENT(IN)                     ::  string_len
    123           TYPE(tm_struct), INTENT(IN)                       ::  timeinfo
    124 
    125           INTEGER(C_SIZE_T)                                 ::  strftime
    126        END FUNCTION
     119    FUNCTION strftime(string, string_len, format, timeinfo) BIND(c, NAME='strftime')
     120       IMPORT :: C_CHAR, C_SIZE_T, tm_struct
     121
     122       IMPLICIT NONE
     123
     124       CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(OUT) ::  string
     125       CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN)  ::  format
     126       INTEGER(C_SIZE_T), INTENT(IN)                     ::  string_len
     127       TYPE(tm_struct), INTENT(IN)                       ::  timeinfo
     128
     129       INTEGER(C_SIZE_T)                                 ::  strftime
     130    END FUNCTION
    127131
    128132
     
    135139!> e.g. increments the date if hours overfow 24.
    136140!------------------------------------------------------------------------------!
    137        FUNCTION mktime(timeinfo) BIND(c, NAME='mktime')
    138           IMPORT :: C_PTR, tm_struct
    139 
    140           IMPLICIT NONE
    141 
    142           TYPE(tm_struct), INTENT(IN) ::  timeinfo
    143 
    144           TYPE(C_PTR)                 ::  mktime
    145        END FUNCTION
    146 
    147     END INTERFACE
     141    FUNCTION mktime(timeinfo) BIND(c, NAME='mktime')
     142       IMPORT :: C_PTR, tm_struct
     143
     144       IMPLICIT NONE
     145
     146       TYPE(tm_struct), INTENT(IN) ::  timeinfo
     147
     148       TYPE(C_PTR)                 ::  mktime
     149    END FUNCTION
     150
     151 END INTERFACE
    148152
    149153 CONTAINS
     
    156160!> format
    157161!------------------------------------------------------------------------------!
    158     CHARACTER(LEN=DATE) FUNCTION add_hours_to(date_string, hours)
    159        CHARACTER(LEN=DATE), INTENT(IN)          ::  date_string
    160        INTEGER, INTENT(IN)                      ::  hours
    161 
    162        CHARACTER(KIND=C_CHAR, LEN=*), PARAMETER ::  format_string = "%Y%m%d%H"
    163        CHARACTER(KIND=C_CHAR, LEN=DATE)         ::  c_date_string
    164        TYPE(C_PTR)                              ::  c_pointer
    165        TYPE(tm_struct)                          ::  time_info
    166        INTEGER                                  ::  err
    167 
    168        c_date_string = date_string
    169 
    170        ! Convert C string to C tm struct
    171        CALL init_tm(time_info)
    172        err = strptime(c_date_string, format_string, time_info)
     162 CHARACTER(LEN=DATE) FUNCTION add_hours_to(date_string, hours)
     163    CHARACTER(LEN=DATE), INTENT(IN)          ::  date_string
     164    INTEGER, INTENT(IN)                      ::  hours
     165
     166    CHARACTER(KIND=C_CHAR, LEN=*), PARAMETER ::  format_string = "%Y%m%d%H"
     167    CHARACTER(KIND=C_CHAR, LEN=DATE)         ::  c_date_string
     168    TYPE(C_PTR)                              ::  c_pointer
     169    TYPE(tm_struct)                          ::  time_info
     170    INTEGER                                  ::  err
     171
     172    c_date_string = date_string
     173
     174    ! Convert C string to C tm struct
     175    CALL init_tm(time_info)
     176    err = strptime(c_date_string, format_string, time_info)
     177 
     178    ! Manipulate and normalize C tm struct
     179    time_info%tm_hour = time_info%tm_hour + hours
     180    c_pointer = mktime(time_info)
     181
     182    ! Convert back to C string
     183    err = strftime(c_date_string, INT(DATE, KIND=C_SIZE_T),                 &
     184                   format_string, time_info)
     185
     186    add_hours_to = c_date_string
     187 END FUNCTION
     188
     189
     190!------------------------------------------------------------------------------!
     191! Description:
     192! ------------
     193!> Print all members of the given tm structure
     194!------------------------------------------------------------------------------!
     195 SUBROUTINE print_tm(timeinfo)
     196    TYPE(tm_struct), INTENT(IN) :: timeinfo
     197
     198    PRINT *, "sec: ", timeinfo%tm_sec,  &  !< seconds after the minute [0, 61]
     199             "min: ", timeinfo%tm_min,  &  !< minutes after the hour [0, 59]
     200             "hr:  ", timeinfo%tm_hour, &  !< hours since midnight [0, 23]
     201             "day: ", timeinfo%tm_mday, &  !< day of the month [1, 31]
     202             "mon: ", timeinfo%tm_mon,  &  !< month since January [0, 11]
     203             "yr:  ", timeinfo%tm_year, &  !< years since 1900
     204             "wday:", timeinfo%tm_wday, &  !< days since Sunday [0, 6]
     205             "yday:", timeinfo%tm_yday, &  !< days since January 1st [0, 356]
     206             "dst: ", timeinfo%tm_isdst    !< Daylight Saving time flag
     207 END SUBROUTINE print_tm
     208
    173209   
    174        ! Manipulate and normalize C tm struct
    175        time_info % tm_hour = time_info % tm_hour + hours
    176        c_pointer = mktime(time_info)
    177 
    178        ! Convert back to C string
    179        err = strftime(c_date_string, INT(DATE, KIND=C_SIZE_T),                 &
    180                       format_string, time_info)
    181 
    182        add_hours_to = c_date_string
    183     END FUNCTION
    184 
    185 
    186 !------------------------------------------------------------------------------!
    187 ! Description:
    188 ! ------------
    189 !> Print all members of the given tm structure
    190 !------------------------------------------------------------------------------!
    191     SUBROUTINE print_tm(timeinfo)
    192        TYPE(tm_struct), INTENT(IN) :: timeinfo
    193 
    194        PRINT *, "sec: ", timeinfo % tm_sec,  &  !< seconds after the minute [0, 61]
    195                 "min: ", timeinfo % tm_min,  &  !< minutes after the hour [0, 59]
    196                 "hr:  ", timeinfo % tm_hour, &  !< hours since midnight [0, 23]
    197                 "day: ", timeinfo % tm_mday, &  !< day of the month [1, 31]
    198                 "mon: ", timeinfo % tm_mon,  &  !< month since January [0, 11]
    199                 "yr:  ", timeinfo % tm_year, &  !< years since 1900
    200                 "wday:", timeinfo % tm_wday, &  !< days since Sunday [0, 6]
    201                 "yday:", timeinfo % tm_yday, &  !< days since January 1st [0, 356]
    202                 "dst: ", timeinfo % tm_isdst    !< Daylight Saving time flag
    203     END SUBROUTINE print_tm
    204 
    205    
    206210!------------------------------------------------------------------------------!
    207211! Description:
     
    209213!> Initialize the given tm structure with zero values
    210214!------------------------------------------------------------------------------!
    211     SUBROUTINE init_tm(timeinfo)
    212        TYPE(tm_struct), INTENT(INOUT) :: timeinfo
    213 
    214        timeinfo % tm_sec   = 0
    215        timeinfo % tm_min   = 0
    216        timeinfo % tm_hour  = 0
    217        timeinfo % tm_mday  = 0
    218        timeinfo % tm_mon   = 0
    219        timeinfo % tm_year  = 0
    220        timeinfo % tm_wday  = 0
    221        timeinfo % tm_yday  = 0
    222 
    223        ! We use UTC times, so marking Daylight Saving Time (DST) 'not available'
    224        ! (< 0). If this is set to 0, mktime will convert the timeinfo to DST and
    225        ! add one hour.
    226        timeinfo % tm_isdst = -1
    227     END SUBROUTINE init_tm
     215 SUBROUTINE init_tm(timeinfo)
     216    TYPE(tm_struct), INTENT(INOUT) :: timeinfo
     217
     218    timeinfo%tm_sec   = 0
     219    timeinfo%tm_min   = 0
     220    timeinfo%tm_hour  = 0
     221    timeinfo%tm_mday  = 0
     222    timeinfo%tm_mon   = 0
     223    timeinfo%tm_year  = 0
     224    timeinfo%tm_wday  = 0
     225    timeinfo%tm_yday  = 0
     226
     227    ! We use UTC times, so marking Daylight Saving Time (DST) 'not available'
     228    ! (< 0). If this is set to 0, mktime will convert the timeinfo to DST and
     229    ! add one hour.
     230    timeinfo%tm_isdst = -1
     231 END SUBROUTINE init_tm
    228232
    229233
     
    234238!> and stop
    235239!------------------------------------------------------------------------------!
    236     SUBROUTINE linspace(start, stop, array)
    237 
    238        REAL(dp), INTENT(IN)    ::  start, stop
    239        REAL(dp), INTENT(INOUT) ::  array(0:)
    240        INTEGER                 ::  i, n
    241 
    242        n = UBOUND(array, 1)
    243 
    244        IF (n .EQ. 0)  THEN
    245 
    246           array(0) = start
    247 
    248        ELSE
    249 
    250           DO i = 0, n
    251              array(i) = start + REAL(i, dp) / n * (stop - start)
    252           ENDDO
    253 
    254        ENDIF
    255        
    256     END SUBROUTINE linspace
     240 SUBROUTINE linspace(start, stop, array)
     241
     242    REAL(wp), INTENT(IN)    ::  start, stop
     243    REAL(wp), INTENT(INOUT) ::  array(0:)
     244    INTEGER                 ::  i, n
     245
     246    n = UBOUND(array, 1)
     247
     248    IF (n .EQ. 0)  THEN
     249
     250       array(0) = start
     251
     252    ELSE
     253
     254       DO i = 0, n
     255          array(i) = start + REAL(i, wp) / n * (stop - start)
     256       ENDDO
     257
     258    ENDIF
     259   
     260 END SUBROUTINE linspace
    257261
    258262
     
    263267!> (COSMO) to bottom-up (PALM)
    264268!------------------------------------------------------------------------------!
    265     SUBROUTINE reverse(input_arr)
    266 
    267        REAL(dp), INTENT(INOUT) ::  input_arr(:,:,:)
    268 
    269        input_arr = input_arr(:,:,size(input_arr, 3):1:-1)
    270 
    271     END SUBROUTINE reverse
     269 SUBROUTINE reverse(input_arr)
     270
     271    REAL(wp), INTENT(INOUT) ::  input_arr(:,:,:)
     272
     273    input_arr = input_arr(:,:,size(input_arr, 3):1:-1)
     274
     275 END SUBROUTINE reverse
    272276
    273277
     
    277281!>
    278282!------------------------------------------------------------------------------!
    279     SUBROUTINE deaverage(avg_1, t1, avg_2, t2, avg_3, t3)
    280 
    281        REAL(dp), DIMENSION(:,:,:), INTENT(IN)  ::  avg_1, avg_2
    282        REAL(dp), INTENT(IN)                    ::  t1, t2, t3
    283        REAL(dp), DIMENSION(:,:,:), INTENT(OUT) ::  avg_3
    284 
    285        REAL(dp)                                ::  ti
     283 SUBROUTINE deaverage(avg_1, t1, avg_2, t2, avg_3, t3)
     284
     285    REAL(wp), DIMENSION(:,:,:), INTENT(IN)  ::  avg_1, avg_2
     286    REAL(wp), INTENT(IN)                    ::  t1, t2, t3
     287    REAL(wp), DIMENSION(:,:,:), INTENT(OUT) ::  avg_3
     288
     289    REAL(wp)                                ::  ti
    286290 
    287        ti = 1.0_dp / t3
    288 
    289        avg_3(:,:,:) = ti * ( t2 * avg_2(:,:,:) - t1 * avg_1(:,:,:) )
    290 
    291     END SUBROUTINE deaverage
     291    ti = 1.0_wp / t3
     292
     293    avg_3(:,:,:) = ti * ( t2 * avg_2(:,:,:) - t1 * avg_1(:,:,:) )
     294
     295 END SUBROUTINE deaverage
    292296
    293297
     
    297301!> Compute the COSMO-DE/-D2 basic state pressure profile
    298302!------------------------------------------------------------------------------!
    299     SUBROUTINE get_basic_state(z, beta, p_sl, t_sl, rd, g, p0)
    300 
    301        REAL(dp), INTENT(IN)  ::  z(1:)  !< height [m]
    302        REAL(dp), INTENT(IN)  ::  beta   !< logarithmic lapse rate, dT / d ln(p) [K]
    303        REAL(dp), INTENT(IN)  ::  p_sl   !< reference pressure [Pa]
    304        REAL(dp), INTENT(IN)  ::  t_sl   !< reference tempereature [K]
    305        REAL(dp), INTENT(IN)  ::  rd     !< ideal gas constant of dry air [J/kg/K]
    306        REAL(dp), INTENT(IN)  ::  g      !< acceleration of Earth's gravity [m/s^2]
    307        REAL(dp), INTENT(OUT) ::  p0(1:) !< COSMO basic state pressure [Pa]
    308        REAL(dp) ::  root_frac, factor   !< precomputed factors
    309 
    310        factor = - t_sl / beta
    311        root_frac = (2.0_dp * beta * g) / (rd * t_sl*t_sl)
    312 
    313        p0(:) = p_sl * EXP(                                                     &
    314                   factor * ( 1.0_dp - SQRT( 1.0_dp - root_frac * z(:) ) )      &
    315        )
    316 
    317     END SUBROUTINE get_basic_state
     303 SUBROUTINE get_basic_state(z, beta, p_sl, t_sl, rd, g, p0)
     304
     305    REAL(wp), INTENT(IN)  ::  z(1:)  !< height [m]
     306    REAL(wp), INTENT(IN)  ::  beta   !< logarithmic lapse rate, dT / d ln(p) [K]
     307    REAL(wp), INTENT(IN)  ::  p_sl   !< reference pressure [Pa]
     308    REAL(wp), INTENT(IN)  ::  t_sl   !< reference tempereature [K]
     309    REAL(wp), INTENT(IN)  ::  rd     !< ideal gas constant of dry air [J/kg/K]
     310    REAL(wp), INTENT(IN)  ::  g      !< acceleration of Earth's gravity [m/s^2]
     311    REAL(wp), INTENT(OUT) ::  p0(1:) !< COSMO basic state pressure [Pa]
     312    REAL(wp) ::  root_frac, factor   !< precomputed factors
     313
     314    factor = - t_sl / beta
     315    root_frac = (2.0_wp * beta * g) / (rd * t_sl*t_sl)
     316
     317    p0(:) = p_sl * EXP(                                                     &
     318               factor * ( 1.0_wp - SQRT( 1.0_wp - root_frac * z(:) ) )      &
     319    )
     320
     321 END SUBROUTINE get_basic_state
    318322
    319323
     
    326330!>     theta = T * (p_ref/p)^(R/c_p) = T * e^( R/c_p * ln(p_ref/p) )
    327331!------------------------------------------------------------------------------!
    328     SUBROUTINE potential_temperature(t, p, p_ref, r, cp)
    329        REAL(dp), DIMENSION(:,:,:), INTENT(INOUT) ::  t
    330        REAL(dp), DIMENSION(:,:,:), INTENT(IN)    ::  p
    331        REAL(dp), INTENT(IN)                      ::  p_ref, r, cp
    332        REAL(dp)                                  ::  rcp
    333 
    334        rcp = r/cp
    335        t(:,:,:) =  t(:,:,:) * EXP( rcp * LOG(p_ref / p(:,:,:)) )
    336 
    337     END SUBROUTINE potential_temperature
     332 SUBROUTINE potential_temperature(t, p, p_ref, r, cp)
     333    REAL(wp), DIMENSION(:,:,:), INTENT(INOUT) ::  t
     334    REAL(wp), DIMENSION(:,:,:), INTENT(IN)    ::  p
     335    REAL(wp), INTENT(IN)                      ::  p_ref, r, cp
     336    REAL(wp)                                  ::  rcp
     337
     338    rcp = r/cp
     339    t(:,:,:) =  t(:,:,:) * EXP( rcp * LOG(p_ref / p(:,:,:)) )
     340
     341 END SUBROUTINE potential_temperature
    338342
    339343
     
    343347!> Compute the density in place of the given temperature (t_rho).
    344348!------------------------------------------------------------------------------!
    345    SUBROUTINE moist_density(t_rho, p, qv, rd, rv)
    346        REAL(dp), DIMENSION(:,:,:), INTENT(INOUT) ::  t_rho
    347        REAL(dp), DIMENSION(:,:,:), INTENT(IN)    ::  p, qv
    348        REAL(dp), INTENT(IN)                      ::  rd, rv
    349 
    350        t_rho(:,:,:) = p(:,:,:) / (                                             &
    351           (rv * qv(:,:,:) + rd * (1.0_dp - qv(:,:,:))) * t_rho(:,:,:)          &
    352        )
    353 
    354     END SUBROUTINE moist_density
    355 
    356 
    357     ! Convert a real number to a string in scientific notation
    358     ! showing four significant digits.
    359     CHARACTER(LEN=SNAME) FUNCTION real_to_str(val, format)
    360 
    361         REAL(dp), INTENT(IN)                   ::  val
    362         CHARACTER(LEN=*), OPTIONAL, INTENT(IN) ::  format
    363 
    364         IF (PRESENT(format))  THEN
    365            WRITE(real_to_str, format) val
    366         ELSE
    367            WRITE(real_to_str, '(E11.4)') val
    368         ENDIF
    369         real_to_str = ADJUSTL(real_to_str)
    370 
    371     END FUNCTION real_to_str
     349 SUBROUTINE moist_density(t_rho, p, qv, rd, rv)
     350    REAL(wp), DIMENSION(:,:,:), INTENT(INOUT) ::  t_rho
     351    REAL(wp), DIMENSION(:,:,:), INTENT(IN)    ::  p, qv
     352    REAL(wp), INTENT(IN)                      ::  rd, rv
     353
     354    t_rho(:,:,:) = p(:,:,:) / (                                             &
     355       (rv * qv(:,:,:) + rd * (1.0_wp - qv(:,:,:))) * t_rho(:,:,:)          &
     356    )
     357
     358 END SUBROUTINE moist_density
     359
     360!------------------------------------------------------------------------------!
     361! Description:
     362! ------------
     363! Convert a real number to a string in scientific notation showing four
     364! significant digits.
     365!------------------------------------------------------------------------------!
     366 CHARACTER(LEN=SNAME) FUNCTION real_to_str(val, format)
     367
     368    REAL(wp), INTENT(IN)                   ::  val
     369    CHARACTER(LEN=*), OPTIONAL, INTENT(IN) ::  format
     370
     371    IF (PRESENT( format ) )  THEN
     372       WRITE( real_to_str, format ) val
     373    ELSE
     374       WRITE( real_to_str, '(E11.4)' ) val
     375    ENDIF
     376    real_to_str = ADJUSTL( real_to_str )
     377
     378 END FUNCTION real_to_str
    372379
    373380
     
    377384!> Converts the given real value to a string
    378385!------------------------------------------------------------------------------!
    379     CHARACTER(LEN=16) FUNCTION real_to_str_f(val)
    380 
    381         REAL(dp), INTENT(IN) ::  val
    382 
    383         WRITE(real_to_str_f, '(F16.8)') val
    384         real_to_str_f = ADJUSTL(real_to_str_f)
    385 
    386     END FUNCTION real_to_str_f
     386 CHARACTER(LEN=16) FUNCTION real_to_str_f(val)
     387
     388     REAL(wp), INTENT(IN) ::  val
     389
     390     WRITE(real_to_str_f, '(F16.8)') val
     391     real_to_str_f = ADJUSTL(real_to_str_f)
     392
     393 END FUNCTION real_to_str_f
    387394
    388395
     
    392399!> Converts the given integer value to a string
    393400!------------------------------------------------------------------------------!
    394     CHARACTER(LEN=10) FUNCTION str(val)
    395 
    396         INTEGER, INTENT(IN) ::  val
    397 
    398         WRITE(str, '(i10)') val
    399         str = ADJUSTL(str)
    400 
    401     END FUNCTION str
     401 CHARACTER(LEN=10) FUNCTION str(val)
     402
     403     INTEGER, INTENT(IN) ::  val
     404
     405     WRITE(str, '(i10)') val
     406     str = ADJUSTL(str)
     407
     408 END FUNCTION str
    402409
    403410
     
    407414!> If the given path is not conlcuded by a slash, add one.
    408415!------------------------------------------------------------------------------!
    409     SUBROUTINE normalize_path(path)
    410         
    411         CHARACTER(LEN=*), INTENT(INOUT) ::  path
    412         INTEGER ::  n
    413 
    414         n = LEN_TRIM(path)
    415 
    416         IF (path(n:n) .NE. '/')  THEN
    417            path = TRIM(path) // '/'
    418         ENDIF
    419 
    420     END SUBROUTINE
     416 SUBROUTINE normalize_path(path)
     417     
     418     CHARACTER(LEN=*), INTENT(INOUT) ::  path
     419     INTEGER ::  n
     420
     421     n = LEN_TRIM(path)
     422
     423     IF (path(n:n) .NE. '/')  THEN
     424        path = TRIM(path) // '/'
     425     ENDIF
     426
     427 END SUBROUTINE
    421428
    422429 END MODULE inifor_util
    423 #endif
    424 
Note: See TracChangeset for help on using the changeset viewer.