Index: /palm/trunk/UTIL/inifor/src/inifor.f90
===================================================================
--- /palm/trunk/UTIL/inifor/src/inifor.f90	(revision 4658)
+++ /palm/trunk/UTIL/inifor/src/inifor.f90	(revision 4659)
@@ -21,9 +21,14 @@
 ! Current revisions:
 ! -----------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
 ! $Id$
+! List all warnings after successful run
+! Only define netCDF variables in enabled IO groups
+! 
+! 
+! 4523 2020-05-07 15:58:16Z eckhard
 ! respect integer working precision (iwp) specified in inifor_defs.f90
 ! 
@@ -118,5 +123,4 @@
                origin_lon,                                                     &
                output_file,                                                    &
-               output_var_table,                                               &
                p0,                                                             &
                phi_centre,                                                     &
@@ -199,12 +203,10 @@
 !-- the corresponding netCDF dimensions for each output variable
     CALL setup_variable_tables( cfg%ic_mode )
-    CALL log_runtime( 'time', 'write' )
-
-!
-!-- Add the output variables to the netCDF output file
-    CALL setup_netcdf_variables( output_file%name, output_var_table )
-
     CALL setup_io_groups
     CALL log_runtime( 'time', 'init' )
+!
+!-- Add the output variables to the netCDF output file
+    CALL setup_netcdf_variables( output_file%name, io_group_list)
+    CALL log_runtime( 'time', 'write' )
 
 !------------------------------------------------------------------------------
@@ -236,5 +238,5 @@
 !--          potential temperature is computed from the absolute temperature and
 !--          pressure.
-             CALL preprocess( group, input_buffer, cosmo_grid, iter )
+             CALL preprocess( group, input_buffer, cosmo_grid )
              CALL log_runtime( 'time', 'comp' )
 
@@ -591,16 +593,8 @@
     !CALL fini_grids
     CALL log_runtime( 'time', 'alloc' )
-    CALL log_runtime( 'report', 'void' )
-
-    message = "Finished writing dynamic driver '" // TRIM( output_file%name )
-   
-    IF ( n_wrngs > 0 )  THEN
-       message = TRIM( message ) // "' with " // TRIM( str( n_wrngs ) ) //     &
-       " warning(s). Please see logfile '" // LOG_FILE_NAME // "'."
-    ELSE
-       message = TRIM( message ) // "' successfully."
-    END IF
-
-    CALL report( 'main loop', message )
+
+    CALL report_warnings
+    CALL report_success( output_file%name )
+    CALL report_runtime
     CALL close_log
 
Index: /palm/trunk/UTIL/inifor/src/inifor_control.f90
===================================================================
--- /palm/trunk/UTIL/inifor/src/inifor_control.f90	(revision 4658)
+++ /palm/trunk/UTIL/inifor/src/inifor_control.f90	(revision 4659)
@@ -21,9 +21,15 @@
 ! Current revisions:
 ! -----------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
 ! $Id$
+! List warnings after successful run or abort
+! Produce failure exit code (1) on program abort for test automation
+! Improved code formatting
+! 
+! 
+! 4523 2020-05-07 15:58:16Z eckhard
 ! respect integer working precision (iwp) specified in inifor_defs.f90
 ! 
@@ -87,14 +93,16 @@
 
     USE inifor_defs,                                                           &
-        ONLY:  COPYRIGHT, LNAME, LOG_FILE_NAME, VERSION, iwp, wp
+        ONLY:  COPYRIGHT, LNAME, LOG_FILE_NAME, PATH, VERSION, iwp, wp
     USE inifor_util,                                                           &
-        ONLY:  real_to_str, real_to_str_f
+        ONLY:  real_to_str, real_to_str_f, str
 
     IMPLICIT NONE
 
-    CHARACTER (LEN=5000) ::  message = '' !< log message buffer
-    CHARACTER (LEN=5000) ::  tip     = '' !< optional log message buffer for tips on how to rectify encountered errors
-    INTEGER(iwp), SAVE        ::  u            !< Fortran file unit for the log file
-    INTEGER(iwp), SAVE        ::  n_wrngs = 0  !< Fortran file unit for the log file
+    INTEGER(iwp), SAVE         ::  u                     !< Fortran file unit for the log file
+    INTEGER(iwp), PARAMETER    ::  n_max_wrngs = 512     !< Fortran file unit for the log file
+    INTEGER(iwp), SAVE         ::  n_wrngs = 0           !< Fortran file unit for the log file
+    CHARACTER (LEN=5000)       ::  message = ''          !< log message buffer
+    CHARACTER (LEN=5000)       ::  tip     = ''          !< optional log message buffer for tips on how to rectify encountered errors
+    CHARACTER (LEN=5000), SAVE ::  warnings(n_max_wrngs) !< log of warnings
 
  CONTAINS
@@ -112,5 +120,5 @@
 !> to it.
 !------------------------------------------------------------------------------!
- SUBROUTINE report(routine, message, debug)
+ SUBROUTINE report( routine, message, debug )
 
     CHARACTER(LEN=*), INTENT(IN)  ::  routine !< name of calling subroutine of function
@@ -128,14 +136,31 @@
 
     suppress_message = .FALSE.
-    IF ( PRESENT(debug) )  THEN
+    IF ( PRESENT( debug ) )  THEN
        IF ( .NOT. debug )  suppress_message = .TRUE.
     ENDIF
 
     IF ( .NOT. suppress_message )  THEN
-       WRITE(*, '(A)') "inifor: " // TRIM(message) // "  [ " // TRIM(routine) // " ]"
-       WRITE(u, '(A)')  TRIM(message) // "  [ " // TRIM(routine) // " ]"
+       CALL write_to_sdtout_and_logfile(                                       &
+          TRIM( message ) // "  [ " // TRIM( routine ) // " ]"                 &
+       )
     ENDIF
 
  END SUBROUTINE report
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> This routine writes the given message to SDTOUT as well as to the INIFOR log
+!> file.
+!------------------------------------------------------------------------------!
+ SUBROUTINE write_to_sdtout_and_logfile( message )
+
+    CHARACTER(LEN=*), INTENT(IN)  ::  message
+
+    WRITE(*, '(A)') "inifor: " // TRIM( message )
+    WRITE(u, '(A)') TRIM( message )
+
+ END SUBROUTINE write_to_sdtout_and_logfile
 
 
@@ -150,13 +175,80 @@
 !> continue.
 !------------------------------------------------------------------------------!
- SUBROUTINE warn(routine, message)
+ SUBROUTINE warn( routine, message )
 
     CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
     CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
 
+    CALL cache_warning( routine, message )
+    CALL report( routine, "WARNING: " // TRIM( message ) )
+
+ END SUBROUTINE warn
+
+
+ SUBROUTINE cache_warning( routine, message )
+
+    CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
+    CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
+
     n_wrngs = n_wrngs + 1
-    CALL report(routine, "WARNING: " // TRIM(message))
-
- END SUBROUTINE warn
+    warnings(n_wrngs) = "  WARNING: " // TRIM( message ) //                      &
+                        "  [ " // TRIM( routine ) // " ]"
+
+ END SUBROUTINE cache_warning
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> 
+!> This routine writes all warnings cached with cache_warning() to STDOUT
+!> and the INIFOR log file.
+!------------------------------------------------------------------------------!
+ SUBROUTINE report_warnings()
+
+    INTEGER(iwp) ::  warning_idx
+
+    IF (n_wrngs > 0)  THEN
+       message = 'Encountered the following '// TRIM( str( n_wrngs ) ) // " warning(s) during this run:"
+       CALL report( 'report_warnings', message )
+
+       DO warning_idx = 1, n_wrngs
+          CALL write_to_sdtout_and_logfile( warnings(warning_idx) )
+       ENDDO
+    ENDIF
+
+ END SUBROUTINE report_warnings
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> 
+!> Report successful run. To be called at the end of the main loop.
+!------------------------------------------------------------------------------!
+ SUBROUTINE report_success( output_file_name )
+
+    CHARACTER(LEN=PATH), INTENT(IN) ::  output_file_name
+
+    message = "Finished writing dynamic driver '" // TRIM( output_file_name )
+    message = TRIM( message ) // "' successfully."
+    IF (n_wrngs > 0)  THEN
+       message = TRIM( message ) // " Some warnings were encountered."
+    ENDIF
+    CALL report( 'main loop', message )
+
+ END SUBROUTINE report_success
+   
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> 
+!> Report runtime statistics
+!------------------------------------------------------------------------------!
+ SUBROUTINE report_runtime()
+
+    CALL log_runtime( 'report', 'void' )
+
+ END SUBROUTINE report_runtime
 
 
@@ -171,12 +263,13 @@
 !> INIFOR from continueing.
 !------------------------------------------------------------------------------!
- SUBROUTINE inifor_abort(routine, message)
+ SUBROUTINE inifor_abort( routine , message )
 
     CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
     CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
 
-    CALL report(routine, "ERROR: " // TRIM(message) // " Stopping.")
+    CALL report( routine, "ERROR: " // TRIM( message ) // " Stopping." )
+    CALL report_warnings
     CALL close_log
-    STOP
+    CALL EXIT(1)
 
  END SUBROUTINE inifor_abort
@@ -185,5 +278,5 @@
  SUBROUTINE close_log()
 
-    CLOSE(u)
+    CLOSE( u )
 
  END SUBROUTINE close_log
@@ -209,5 +302,5 @@
 !> accumulates them in timing budgets.
 !------------------------------------------------------------------------------!
- SUBROUTINE log_runtime(mode, budget)
+ SUBROUTINE log_runtime( mode, budget )
 
     CHARACTER(LEN=*), INTENT(IN) ::  mode   !< name of the calling mode
@@ -226,32 +319,35 @@
 
 
-    SELECT CASE(TRIM(mode))
-
-    CASE('init')
+    SELECT CASE( TRIM( mode ) )
+
+    CASE( 'init' )
        CALL CPU_TIME(t0)
 
-    CASE('time')
+    CASE( 'time' )
 
        CALL CPU_TIME(t1)
 
-       SELECT CASE(TRIM(budget))
-
-          CASE('alloc')
+       SELECT CASE( TRIM( budget ) )
+
+          CASE( 'alloc' )
              t_alloc = t_alloc + t1 - t0
 
-          CASE('init')
+          CASE( 'init' )
              t_init = t_init + t1 - t0
 
-          CASE('read')
+          CASE( 'read' )
              t_read = t_read + t1 - t0
 
-          CASE('write')
+          CASE( 'write' )
              t_write = t_write + t1 - t0
 
-          CASE('comp')
+          CASE( 'comp' )
              t_comp = t_comp + t1 - t0
 
           CASE DEFAULT
-             CALL inifor_abort('log_runtime', "Time Budget '" // TRIM(mode) // "' is not supported.")
+             CALL inifor_abort(                                                &
+                'log_runtime',                                                 &
+                "Time Budget '" // TRIM( mode ) // "' is not supported."       &
+             )
 
        END SELECT
@@ -259,29 +355,29 @@
        t0 = t1
 
-    CASE('report')
+    CASE( 'report' )
         t_total = t_init + t_read + t_write + t_comp
 
-        CALL report('log_runtime', " *** CPU time ***")
-
-        CALL report('log_runtime', "Initialization:  " // TRIM( real_to_str( t_init ) ) // &
-                    " s  (" // TRIM( real_to_str( 100 * t_init / t_total, fmt ) ) // " %)" )
-
-        CALL report('log_runtime', "(De-)Allocation: " // TRIM( real_to_str( t_alloc ) ) // &
-                    " s  (" // TRIM( real_to_str( 100 * t_alloc / t_total, fmt ) ) // " %)" )
-
-        CALL report('log_runtime', "Reading data:    " // TRIM( real_to_str( t_read ) )  // &
-                    " s  (" // TRIM( real_to_str( 100 * t_read / t_total, fmt ) ) // " %)" )
-
-        CALL report('log_runtime', "Writing data:    " // TRIM( real_to_str( t_write ) ) // &
-                    " s  (" // TRIM( real_to_str( 100 * t_write / t_total, fmt ) ) // " %)" )
-
-        CALL report('log_runtime', "Computation:     " // TRIM( real_to_str( t_comp ) )  // &
-                    " s  (" // TRIM( real_to_str( 100 * t_comp / t_total, fmt) ) // " %)" )
-
-        CALL report('log_runtime', "Total:           " // TRIM( real_to_str( t_total ) ) // &
-                    " s  (" // TRIM( real_to_str( 100 * t_total / t_total, fmt ) ) // " %)")
+        CALL report( 'log_runtime', "*** CPU time ***" )
+
+        CALL report( 'log_runtime', "Initialization:  " // TRIM( real_to_str( t_init ) ) // &
+                     " s  (" // TRIM( real_to_str( 100 * t_init / t_total, fmt ) ) // " %)" )
+
+        CALL report( 'log_runtime', "(De-)Allocation: " // TRIM( real_to_str( t_alloc ) ) // &
+                     " s  (" // TRIM( real_to_str( 100 * t_alloc / t_total, fmt ) ) // " %)" )
+
+        CALL report( 'log_runtime', "Reading data:    " // TRIM( real_to_str( t_read ) )  // &
+                     " s  (" // TRIM( real_to_str( 100 * t_read / t_total, fmt ) ) // " %)" )
+
+        CALL report( 'log_runtime', "Writing data:    " // TRIM( real_to_str( t_write ) ) // &
+                     " s  (" // TRIM( real_to_str( 100 * t_write / t_total, fmt ) ) // " %)" )
+
+        CALL report( 'log_runtime', "Computation:     " // TRIM( real_to_str( t_comp ) )  // &
+                     " s  (" // TRIM( real_to_str( 100 * t_comp / t_total, fmt) ) // " %)" )
+
+        CALL report( 'log_runtime', "Total:           " // TRIM( real_to_str( t_total ) ) // &
+                     " s  (" // TRIM( real_to_str( 100 * t_total / t_total, fmt ) ) // " %)" )
 
     CASE DEFAULT
-       CALL inifor_abort('log_runtime', "Mode '" // TRIM(mode) // "' is not supported.")
+       CALL inifor_abort( 'log_runtime', "Mode '" // TRIM(mode) // "' is not supported." )
 
     END SELECT
@@ -289,3 +385,4 @@
  END SUBROUTINE log_runtime
 
+
  END MODULE inifor_control
Index: /palm/trunk/UTIL/inifor/src/inifor_defs.f90
===================================================================
--- /palm/trunk/UTIL/inifor/src/inifor_defs.f90	(revision 4658)
+++ /palm/trunk/UTIL/inifor/src/inifor_defs.f90	(revision 4659)
@@ -201,5 +201,5 @@
     ACHAR( 10 ) // ' Copyright 2017-2020 Deutscher Wetterdienst Offenbach' !< Copyright notice
  CHARACTER(LEN=*), PARAMETER ::  LOG_FILE_NAME = 'inifor.log' !< Name of INIFOR's log file
- CHARACTER(LEN=*), PARAMETER ::  VERSION = '1.4.16'           !< INIFOR version number
+ CHARACTER(LEN=*), PARAMETER ::  VERSION = '2.0.0'            !< INIFOR version number
  
  END MODULE inifor_defs
Index: /palm/trunk/UTIL/inifor/src/inifor_grid.f90
===================================================================
--- /palm/trunk/UTIL/inifor/src/inifor_grid.f90	(revision 4658)
+++ /palm/trunk/UTIL/inifor/src/inifor_grid.f90	(revision 4659)
@@ -21,9 +21,18 @@
 ! Current revisions:
 ! -----------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
 ! $Id$
+! Only define netCDF variables in enabled IO groups
+! Added cloud and precipitation quantiteis (cloud water, cloud ice, rain, snow
+!    and graupel content, as well as surface forcings of rain, snow and graupel)
+! Check for presence of precipitation files
+! Removed unused code for deaccumulation of summed up and averaged fields
+! Improved code formatting and documentation
+! 
+! 
+! 4568 2020-06-19 11:56:30Z eckhard
 ! Handle COSMO soil data with and without additional surface temperature
 ! Imporved messaging
@@ -180,7 +189,7 @@
                PIDS_ORIGIN_Z
     USE inifor_io,                                                             &
-        ONLY:  get_cosmo_grid, get_input_file_list, get_netcdf_attribute,      &
+        ONLY:  file_is_present, get_cosmo_grid, get_input_file_list, get_netcdf_attribute,      &
                get_netcdf_dim_vector, get_netcdf_variable, set_palm_origin,    &
-               parse_command_line_arguments, validate_config,                  &
+               netcdf_variable_present_in_file, parse_command_line_arguments, validate_config,                  &
                has_surface_value
     USE inifor_transform,                                                      &
@@ -287,10 +296,9 @@
     INTEGER(iwp) ::  nlev  !< number of levels in target grid (COSMO-DE)
     INTEGER(iwp) ::  ndepths !< number of COSMO-DE soil layers
-    INTEGER(iwp) ::  start_hour_flow         !< start of flow forcing in number of hours relative to start_date
-    INTEGER(iwp) ::  start_hour_soil         !< start of soil forcing in number of hours relative to start_date, typically equals start_hour_flow
-    INTEGER(iwp) ::  start_hour_radiation    !< start of radiation forcing in number of hours relative to start_date, 0 to 2 hours before start_hour_flow to reconstruct hourly averages from one- to three hourly averages of the input data
-    INTEGER(iwp) ::  start_hour_soilmoisture !< start of forcing for the soil moisture spin-up in number of hours relative to start_date, typically -672 (-4 weeks)
+    INTEGER(iwp) ::  start_hour_flow          !< start of flow forcing in number of hours relative to start_date
+    INTEGER(iwp) ::  start_hour_soil          !< start of soil forcing in number of hours relative to start_date, typically equals start_hour_flow
+    INTEGER(iwp) ::  start_hour_radiation     !< start of radiation forcing in number of hours relative to start_date, 0 to 2 hours before start_hour_flow to reconstruct hourly averages from one- to three hourly averages of the input data
+    INTEGER(iwp) ::  start_hour_precipitation !< start of forcing for precipitaiton forcing in number of hours relative to start_date
     INTEGER(iwp) ::  end_hour  !< simulation time in hours
-    INTEGER(iwp) ::  end_hour_soilmoisture  !< end of soil moisture spin-up in hours relative to start_hour_flow
     INTEGER(iwp) ::  step_hour !< number of hours between forcing time steps
 
@@ -372,18 +380,18 @@
     CHARACTER(LEN=LNAME) ::  nc_source_text = ''  !< Text describing the source of the output data, e.g. 'COSMO-DE analysis from ...'
 
-    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  flow_files          !< list of atmospheric input files (<prefix>YYYYMMDDHH-flow.nc)
-    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  soil_moisture_files !< list of precipitation input files (<prefix>YYYYMMDDHH-soilmoisture.nc) 
-    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  soil_files          !< list of soil input files (temperature, moisture, <prefix>YYYYMMDDHH-soil.nc)
-    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  radiation_files     !< list of radiation input files (<prefix>YYYYMMDDHH-rad.nc)
-
-    CHARACTER(LEN=SNAME) ::  input_prefix         !< prefix of input files, e.g. 'laf' for COSMO-DE analyses
-    CHARACTER(LEN=SNAME) ::  flow_prefix          !< prefix of flow input files, e.g. 'laf' for COSMO-DE analyses
-    CHARACTER(LEN=SNAME) ::  soil_prefix          !< prefix of soil input files, e.g. 'laf' for COSMO-DE analyses
-    CHARACTER(LEN=SNAME) ::  radiation_prefix     !< prefix of radiation input files, e.g. 'laf' for COSMO-DE analyses
-    CHARACTER(LEN=SNAME) ::  soilmoisture_prefix  !< prefix of input files for soil moisture spin-up, e.g. 'laf' for COSMO-DE analyses
-    CHARACTER(LEN=SNAME) ::  flow_suffix          !< suffix of flow input files, e.g. 'flow'
-    CHARACTER(LEN=SNAME) ::  soil_suffix          !< suffix of soil input files, e.g. 'soil'
-    CHARACTER(LEN=SNAME) ::  radiation_suffix     !< suffix of radiation input files, e.g. 'radiation'
-    CHARACTER(LEN=SNAME) ::  soilmoisture_suffix  !< suffix of input files for soil moisture spin-up, e.g. 'soilmoisture'
+    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  flow_files      !< list of atmospheric input files (<prefix>YYYYMMDDHH-flow.nc)
+    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  precip_files    !< list of precipitation input files (<prefix>YYYYMMDDHH-precip.nc) 
+    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  soil_files      !< list of soil input files (temperature, moisture, <prefix>YYYYMMDDHH-soil.nc)
+    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  radiation_files !< list of radiation input files (<prefix>YYYYMMDDHH-rad.nc)
+
+    CHARACTER(LEN=SNAME) ::  input_prefix          !< prefix of input files, e.g. 'laf' for COSMO-DE analyses
+    CHARACTER(LEN=SNAME) ::  flow_prefix           !< prefix of flow input files, e.g. 'laf' for COSMO-DE analyses
+    CHARACTER(LEN=SNAME) ::  soil_prefix           !< prefix of soil input files, e.g. 'laf' for COSMO-DE analyses
+    CHARACTER(LEN=SNAME) ::  radiation_prefix      !< prefix of radiation input files, e.g. 'laf' for COSMO-DE analyses
+    CHARACTER(LEN=SNAME) ::  precipitation_prefix  !< prefix of input files for precipitation forcing, e.g. 'laf' for COSMO-DE analyses
+    CHARACTER(LEN=SNAME) ::  flow_suffix           !< suffix of flow input files, e.g. 'flow'
+    CHARACTER(LEN=SNAME) ::  soil_suffix           !< suffix of soil input files, e.g. 'soil'
+    CHARACTER(LEN=SNAME) ::  radiation_suffix      !< suffix of radiation input files, e.g. 'radiation'
+    CHARACTER(LEN=SNAME) ::  precipitation_suffix  !< suffix of input files for precipition forcing, e.g. 'precip'
                           
     TYPE(nc_file) ::  output_file !< metadata of the dynamic driver 
@@ -408,7 +416,4 @@
 !------------------------------------------------------------------------------
     cfg%start_date = '2013072100'
-    end_hour = 2
-    start_hour_soil = -2
-    start_hour_soilmoisture = - (4 * 7 * 24) - 2
 
 !
@@ -429,6 +434,5 @@
     start_hour_soil = 0
     start_hour_radiation = 0
-    start_hour_soilmoisture = start_hour_flow - 2
-    end_hour_soilmoisture = start_hour_flow
+    start_hour_precipitation = start_hour_flow 
     step_hour = FORCING_STEP
 
@@ -438,10 +442,10 @@
     cfg%soil_prefix = input_prefix
     cfg%radiation_prefix = input_prefix
-    cfg%soilmoisture_prefix  = input_prefix
+    cfg%precipitation_prefix  = input_prefix
 
     flow_suffix = '-flow'
     soil_suffix = '-soil'
     radiation_suffix = '-rad'
-    soilmoisture_suffix = '-soilmoisture'
+    precipitation_suffix = '-precip'
 
     cfg%debug = .FALSE.
@@ -472,9 +476,9 @@
     radiation_prefix = TRIM(cfg%input_prefix)
     soil_prefix = TRIM(cfg%input_prefix)
-    soilmoisture_prefix = TRIM(cfg%input_prefix)
+    precipitation_prefix = TRIM(cfg%input_prefix)
     IF (cfg%flow_prefix_is_set)  flow_prefix = TRIM(cfg%flow_prefix)
     IF (cfg%radiation_prefix_is_set)  radiation_prefix = TRIM(cfg%radiation_prefix)
     IF (cfg%soil_prefix_is_set)  soil_prefix = TRIM(cfg%soil_prefix)
-    IF (cfg%soilmoisture_prefix_is_set)  soilmoisture_prefix = TRIM(cfg%soilmoisture_prefix)
+    IF (cfg%precipitation_prefix_is_set)  precipitation_prefix = TRIM(cfg%precipitation_prefix)
 
     output_file%name = cfg%output_file
@@ -483,5 +487,5 @@
     boundary_variables_required = TRIM( cfg%bc_mode ) == 'real'
     ls_forcing_variables_required = TRIM( cfg%bc_mode ) == 'ideal'
-    surface_forcing_required = .FALSE.
+    surface_forcing_required = .TRUE.
 
     IF ( ls_forcing_variables_required )  THEN
@@ -502,4 +506,5 @@
     CALL report('setup_parameters', "       forcing mode: " // TRIM(cfg%bc_mode))
     CALL report('setup_parameters', "     averaging mode: " // TRIM(cfg%averaging_mode))
+    CALL report('setup_parameters', "    averaging angle: " // real_to_str(cfg%averaging_angle))
     CALL report('setup_parameters', "    averaging angle: " // real_to_str(cfg%averaging_angle))
     CALL report('setup_parameters', "          data path: " // TRIM(cfg%input_path))
@@ -508,4 +513,9 @@
     CALL report('setup_parameters', "      namelist file: " // TRIM(cfg%namelist_file))
     CALL report('setup_parameters', "   output data file: " // TRIM(output_file%name))
+    IF (cfg%process_precipitation )  THEN
+        CALL report('setup_parameters', "      precipitation: enabled")
+    ELSE
+        CALL report('setup_parameters', "      precipitation: disabled")
+    ENDIF
     IF (cfg%debug )  CALL report('setup_parameters', "     debugging mode: enabled")
 
@@ -543,16 +553,16 @@
 !
 !-- Generate input file lists
-    CALL get_input_file_list(                                               &
-       cfg%start_date, start_hour_flow, end_hour, step_hour,              &
+    CALL get_input_file_list(                                                  &
+       cfg%start_date, start_hour_flow, end_hour, step_hour,                   &
        cfg%input_path, flow_prefix, flow_suffix, flow_files)
-    CALL get_input_file_list(                                               &
-       cfg%start_date, start_hour_soil, end_hour, step_hour,              &
+    CALL get_input_file_list(                                                  &
+       cfg%start_date, start_hour_soil, end_hour, step_hour,                   &
        cfg%input_path, soil_prefix, soil_suffix, soil_files)
-    CALL get_input_file_list(                                               &
-       cfg%start_date, start_hour_radiation, end_hour, step_hour,         &
-       cfg%input_path, radiation_prefix, radiation_suffix, radiation_files, nocheck=.TRUE.)
-    CALL get_input_file_list(                                               &
-       cfg%start_date, start_hour_soilmoisture, end_hour_soilmoisture, step_hour, &
-       cfg%input_path, soilmoisture_prefix, soilmoisture_suffix, soil_moisture_files, nocheck=.TRUE.)
+    CALL get_input_file_list(                                                  &
+       cfg%start_date, start_hour_radiation, end_hour, step_hour,              &
+       cfg%input_path, radiation_prefix, radiation_suffix, radiation_files)
+    CALL get_input_file_list(                                                  &
+       cfg%start_date, start_hour_flow, end_hour, step_hour,                   &
+       cfg%input_path, precipitation_prefix, precipitation_suffix, precip_files )
 
 !
@@ -2137,5 +2147,5 @@
     INTEGER(iwp) ::  ngroups
 
-    ngroups = 16
+    ngroups = 17
     ALLOCATE( io_group_list(ngroups) )
 
@@ -2214,32 +2224,32 @@
 !-- rain
     io_group_list(8) = init_io_group(                                       &
-       in_files = soil_moisture_files,                                      &
+       in_files = precip_files,                                      &
        out_vars = output_var_table(33:33),                                  &
        in_var_list = input_var_table(8:8),                                  &
-       kind = 'accumulated'                                                 &
-    )
-    io_group_list(8)%to_be_processed = .FALSE.
+       kind = 'surface'                                                     &
+    )
+    io_group_list(8)%to_be_processed = cfg%process_precipitation
 !
 !-- snow
     io_group_list(9) = init_io_group(                                       &
-       in_files = soil_moisture_files,                                      &
+       in_files = precip_files,                                      &
        out_vars = output_var_table(34:34),                                  &
        in_var_list = input_var_table(9:9),                                  &
-       kind = 'accumulated'                                                 &
-    )
-    io_group_list(9)%to_be_processed = .FALSE.
+       kind = 'surface'                                                     &
+    )
+    io_group_list(9)%to_be_processed = cfg%process_precipitation
 !
 !-- graupel
     io_group_list(10) = init_io_group(                                      &
-       in_files = soil_moisture_files,                                      &
+       in_files = precip_files,                                      &
        out_vars = output_var_table(35:35),                                  &
        in_var_list = input_var_table(10:10),                                &
-       kind = 'accumulated'                                                 &
-    )
-    io_group_list(10)%to_be_processed = .FALSE.
+       kind = 'surface'                                                     &
+    )
+    io_group_list(10)%to_be_processed = cfg%process_precipitation
 !
 !-- evapotranspiration
     io_group_list(11) = init_io_group(                                      &
-       in_files = soil_moisture_files,                                      &
+       in_files = precip_files,                                      &
        out_vars = output_var_table(37:37),                                  &
        in_var_list = input_var_table(11:11),                                &
@@ -2250,5 +2260,5 @@
 !-- 2m air temperature
     io_group_list(12) = init_io_group(                                      &
-       in_files = soil_moisture_files,                                      &
+       in_files = precip_files,                                      &
        out_vars = output_var_table(36:36),                                  &
        in_var_list = input_var_table(12:12),                                &
@@ -2293,5 +2303,100 @@
     io_group_list(16)%to_be_processed = .FALSE.
 
+!-- fog and cloud water
+    io_group_list(17) = init_io_group(                                      &
+       in_files = flow_files,                                               &
+       out_vars = output_var_table(65:94),                                  & !qc, qi, qr, qs, qg
+       in_var_list = input_var_table(11:15),                                & !QC, QI, QR, QS, QG
+       kind = 'scalar'                                                      &
+    )
+    io_group_list(17)%to_be_processed = .TRUE.
+
+    CALL validate_io_groups( io_group_list )
+
  END SUBROUTINE setup_io_groups
+
+
+ SUBROUTINE validate_io_groups( io_group_list )
+    TYPE(io_group), TARGET, INTENT(INOUT) ::  io_group_list(:)
+
+    INTEGER(iwp)                 ::  group_idx, file_idx, outvar_idx
+    TYPE(io_group), POINTER      ::  group
+    CHARACTER(LEN=PATH), POINTER ::  filename
+    TYPE(nc_var), POINTER        ::  outvar, invar
+
+    DO group_idx = 1, SIZE( io_group_list )
+       group => io_group_list(group_idx)
+
+       IF (group%to_be_processed)  THEN
+          DO file_idx = 1, SIZE( group%in_files )
+             filename => group%in_files(file_idx)
+
+             IF (.NOT. file_is_present( filename, 'input', message ))  THEN
+                IF (group%is_optional)  THEN
+
+!--                deactivate group, warn and continue
+                   group%to_be_processed = .FALSE.
+                   message = "Optional IO group '" // TRIM( group%kind ) // "' was deactivated" // &
+                      " because the required file '" // TRIM( filename ) // "' was not found."
+                   CALL warn( 'validate_io_groups', message )
+                ELSE
+!--                abort due to missing input file
+                   message = "The input file '" // TRIM( filename ) // "' of the" // &
+                      " mandatory IO group '" // TRIM( group%kind ) // "' was not found."
+                   CALL inifor_abort( 'validate_io_groups', message  )
+                ENDIF
+             ELSE
+                message = "Set up input file name '" // TRIM(filename) // "'"
+                CALL report('verify_file', message)
+             ENDIF
+
+          ENDDO
+       
+!--       deactivate all optional output variables that have missing inputs
+          DO outvar_idx = 1, SIZE(group%out_vars)
+             outvar => group%out_vars(outvar_idx)
+
+             IF (outvar%is_optional)  THEN
+
+!--             only check first input file, assuming files at later times have the
+!--             same contents
+                filename => group%in_files(LBOUND( group%in_files, 1))
+                invar => group%in_var_list(outvar%input_id)
+
+!--             if corresponding invar not present, deactivate output_var
+                IF ( .NOT.netcdf_variable_present_in_file( invar%name, filename ) )  THEN
+                      ! deactivate output variable variable, warn and continue
+                      invar%to_be_processed = .FALSE.
+                      outvar%to_be_processed = .FALSE.
+                      message = "Optional output variable '" // TRIM( outvar%name ) // "' was deactivated" // &
+                         " because the corresponding input variable was not found in file '" // TRIM( filename ) // "'."
+                      CALL warn( 'validate_io_groups', message )
+                ENDIF
+             ENDIF
+
+             !IF ( .NOT.netcdf_variable_present_in_file( invar%name, filename ) )  THEN
+!--          !      abort due to missing input variable
+             !      message = "The mandatory input variable '" // TRIM( invar%name ) // &
+             !         " was not found in the input file '" // TRIM( filename ) // "'."
+             !      CALL inifor_abort( 'validate_io_groups', message  )
+             !   ENDIF
+             !IF ( .NOT.netcdf_variable_present_in_file( invar%name, filename ) )  THEN
+!--          !      abort due to missing input variable
+             !      message = "The mandatory input variable '" // TRIM( invar%name ) // &
+             !         " was not found in the input file '" // TRIM( filename ) // "'."
+             !      CALL inifor_abort( 'validate_io_groups', message  )
+             !   ENDIF
+             !ENDIF
+!--       outvar loop
+          ENDDO
+
+!--   group%to_be_processed conditional
+      ENDIF
+
+!-- groups loop
+    ENDDO
+    
+ END SUBROUTINE validate_io_groups
+
 
 
@@ -2307,5 +2412,5 @@
 !> on the output quantity Theta.
 !------------------------------------------------------------------------------!
- FUNCTION init_io_group(in_files, out_vars, in_var_list, kind,              &
+ FUNCTION init_io_group(in_files, out_vars, in_var_list, kind,                 &
                         n_output_quantities) RESULT(group)
     CHARACTER(LEN=PATH), INTENT(IN) ::  in_files(:)
@@ -2321,12 +2426,21 @@
     group%n_inputs = SIZE(in_var_list)
     group%kind = TRIM(kind)
-!
-!-- For the 'thermodynamics' IO group, one quantity more than input variables
-!-- is needed to compute all output variables of the IO group. Concretely, in
-!-- preprocess() the density is computed from T,P or PP,QV in adddition to
-!-- the variables Theta, p, qv. In read_input_variables(),
-!-- n_output_quantities is used to allocate the correct number of input
-!-- buffers.
-    IF ( PRESENT(n_output_quantities) )  THEN
+
+!
+!-- Set the number of output quantities, which is used to allocate input buffers
+!-- in the preprocess() routine. For passive scalars, there is a one-to-one
+!-- correspondance of input and output quantities. For instance, for every water
+!-- phase input variable (e.g. cloud water QC), there is a corresponding output
+!-- quantity (qc, which lead to a number of output netCDF variables:
+!-- init_atmosphere_qc, ls_forcing_left_qc, etc.)
+!--     If more output quantities than input quantities are to be produced,
+!-- n_output_quantities can be set through the optional subroutine parameter.
+!-- For the 'thermodynamics' IO group, one quantity more than input variables is
+!-- needed to compute all output variables of the IO group.  Concretely, in
+!-- preprocess() the density is computed from T,P or PP,QV in adddition to the
+!-- variables Theta, p, qv. In read_input_variables(), n_output_quantities is
+!-- used to allocate the correct number of input buffers.
+
+    IF  ( PRESENT(n_output_quantities) )  THEN
        group%n_output_quantities = n_output_quantities
     ELSE
@@ -2393,5 +2507,5 @@
 
     n_invar = 17
-    n_outvar = 64
+    n_outvar = 94
     ALLOCATE( input_var_table(n_invar) )
     ALLOCATE( output_var_table(n_outvar) )
@@ -2461,31 +2575,31 @@
 
     var => input_var_table(11)
-    var%name = 'AEVAP_S'
+    var%name = 'QC'
     var%to_be_processed = .TRUE.
-    var%is_upside_down = .FALSE.
+    var%is_upside_down = .TRUE.
 
     var => input_var_table(12)
-    var%name = 'T_2M'
+    var%name = 'QI'
     var%to_be_processed = .TRUE.
-    var%is_upside_down = .FALSE.
+    var%is_upside_down = .TRUE.
 
     var => input_var_table(13)
-    var%name = 'ASWDIFD_S'
+    var%name = 'QR'
     var%to_be_processed = .TRUE.
-    var%is_upside_down = .FALSE.
+    var%is_upside_down = .TRUE.
 
     var => input_var_table(14)
-    var%name = 'ASWDIR_S'
+    var%name = 'QS'
     var%to_be_processed = .TRUE.
-    var%is_upside_down = .FALSE.
+    var%is_upside_down = .TRUE.
 
     var => input_var_table(15)
-    var%name = 'ASOB_S'
+    var%name = 'QG'
     var%to_be_processed = .TRUE.
-    var%is_upside_down = .FALSE.
+    var%is_upside_down = .TRUE.
 
     var => input_var_table(16)
-    var%name = 'ATHB_S'
-    var%to_be_processed = .TRUE.
+    var%name = '--'
+    var%to_be_processed = .FALSE.
     var%is_upside_down = .FALSE.
 
@@ -3332,4 +3446,414 @@
     output_var_table(64)%averaging_grid => west_averaged_scalar_profile
     output_var_table(64)%to_be_processed = .NOT. cfg%ug_defined_by_user
+
+    output_var_table(65) = init_nc_var(                                      &
+       name              = 'init_atmosphere_qc',                            &
+       std_name          = "",                                              &
+       long_name         = "initial cloud water mixture fraction",          &
+       units             = "kg/kg",                                         &
+       kind              = "init scalar",                                   &
+       input_id          = 1_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = palm_grid,                                       &
+       intermediate_grid = palm_intermediate,                               &
+       is_profile = (TRIM(ic_mode) == 'profile')                            &
+    )
+    IF (TRIM(ic_mode) == 'profile')  THEN
+       output_var_table(65)%averaging_grid => averaged_initial_scalar_profile
+    ENDIF
+    output_var_table(65)%is_optional = .TRUE.
+
+    output_var_table(66) = init_nc_var(                                     &
+       name              = 'ls_forcing_left_qc',                            &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for left model boundary for the cloud water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "left scalar",                                   &
+       input_id          = 1_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_west_grid,                               &
+       intermediate_grid = scalars_west_intermediate                        &
+    )
+    output_var_table(66)%is_optional = .TRUE.
+
+    output_var_table(67) = init_nc_var(                                     &
+       name              = 'ls_forcing_right_qc',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for right model boundary for the cloud water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "right scalar",                                  &
+       input_id          = 1_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_east_grid,                               &
+       intermediate_grid = scalars_east_intermediate                        &
+    )
+    output_var_table(67)%is_optional = .TRUE.
+
+    output_var_table(68) = init_nc_var(                                     &
+       name              = 'ls_forcing_north_qc',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for north model boundary for the cloud water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "north scalar",                                  &
+       input_id          = 1_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_north_grid,                              &
+       intermediate_grid = scalars_north_intermediate                       &
+    )
+    output_var_table(68)%is_optional = .TRUE.
+
+    output_var_table(69) = init_nc_var(                                     &
+       name              = 'ls_forcing_south_qc',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for south model boundary for the cloud water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "south scalar",                                  &
+       input_id          = 1_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_south_grid,                              &
+       intermediate_grid = scalars_south_intermediate                       &
+    )
+    output_var_table(69)%is_optional = .TRUE.
+
+    output_var_table(70) = init_nc_var(                                     &
+       name              = 'ls_forcing_top_qc',                             &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for top model boundary for the cloud water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "top scalar",                                    &
+       input_id          = 1_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_top_grid,                                &
+       intermediate_grid = scalars_top_intermediate                         &
+    )
+    output_var_table(70)%is_optional = .TRUE.
+
+    output_var_table(71) = init_nc_var(                                     &
+       name              = 'init_atmosphere_qi',                            &
+       std_name          = "",                                              &
+       long_name         = "initial cloud ice mixture fraction",            &
+       units             = "kg/kg",                                         &
+       kind              = "init scalar",                                   &
+       input_id          = 2_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = palm_grid,                                       &
+       intermediate_grid = palm_intermediate,                               &
+       is_profile = (TRIM(ic_mode) == 'profile')                            &
+    )
+    IF (TRIM(ic_mode) == 'profile')  THEN
+       output_var_table(71)%averaging_grid => averaged_initial_scalar_profile
+    ENDIF
+    output_var_table(71)%is_optional = .TRUE.
+
+    output_var_table(72) = init_nc_var(                                     &
+       name              = 'ls_forcing_left_qi',                            &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for left model boundary for the cloud ice mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "left scalar",                                   &
+       input_id          = 2_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_west_grid,                               &
+       intermediate_grid = scalars_west_intermediate                        &
+    )
+    output_var_table(72)%is_optional = .TRUE.
+
+    output_var_table(73) = init_nc_var(                                     &
+       name              = 'ls_forcing_right_qi',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for right model boundary for the cloud ice mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "right scalar",                                  &
+       input_id          = 2_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_east_grid,                               &
+       intermediate_grid = scalars_east_intermediate                        &
+    )
+    output_var_table(73)%is_optional = .TRUE.
+
+    output_var_table(74) = init_nc_var(                                     &
+       name              = 'ls_forcing_north_qi',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for north model boundary for the cloud ice mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "north scalar",                                  &
+       input_id          = 2_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_north_grid,                              &
+       intermediate_grid = scalars_north_intermediate                       &
+    )
+    output_var_table(74)%is_optional = .TRUE.
+
+    output_var_table(75) = init_nc_var(                                     &
+       name              = 'ls_forcing_south_qi',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for south model boundary for the cloud ice mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "south scalar",                                  &
+       input_id          = 2_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_south_grid,                              &
+       intermediate_grid = scalars_south_intermediate                       &
+    )
+    output_var_table(75)%is_optional = .TRUE.
+
+    output_var_table(76) = init_nc_var(                                     &
+       name              = 'ls_forcing_top_qi',                             &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for top model boundary for the cloud ice mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "top scalar",                                    &
+       input_id          = 2_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_top_grid,                                &
+       intermediate_grid = scalars_top_intermediate                         &
+    )
+    output_var_table(76)%is_optional = .TRUE.
+
+    output_var_table(77) = init_nc_var(                                     &
+       name              = 'init_atmosphere_qr',                            &
+       std_name          = "",                                              &
+       long_name         = "initial rain water mixture fraction",            &
+       units             = "kg/kg",                                         &
+       kind              = "init scalar",                                   &
+       input_id          = 3_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = palm_grid,                                       &
+       intermediate_grid = palm_intermediate,                               &
+       is_profile = (TRIM(ic_mode) == 'profile')                            &
+    )
+    IF (TRIM(ic_mode) == 'profile')  THEN
+       output_var_table(77)%averaging_grid => averaged_initial_scalar_profile
+    ENDIF
+    output_var_table(77)%is_optional = .TRUE.
+
+    output_var_table(78) = init_nc_var(                                     &
+       name              = 'ls_forcing_left_qr',                            &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for left model boundary for the rain water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "left scalar",                                   &
+       input_id          = 3_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_west_grid,                               &
+       intermediate_grid = scalars_west_intermediate                        &
+    )
+    output_var_table(78)%is_optional = .TRUE.
+
+    output_var_table(79) = init_nc_var(                                     &
+       name              = 'ls_forcing_right_qr',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for right model boundary for the rain water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "right scalar",                                  &
+       input_id          = 3_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_east_grid,                               &
+       intermediate_grid = scalars_east_intermediate                        &
+    )
+    output_var_table(79)%is_optional = .TRUE.
+
+    output_var_table(80) = init_nc_var(                                     &
+       name              = 'ls_forcing_north_qr',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for north model boundary for the rain water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "north scalar",                                  &
+       input_id          = 3_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_north_grid,                              &
+       intermediate_grid = scalars_north_intermediate                       &
+    )
+    output_var_table(80)%is_optional = .TRUE.
+
+    output_var_table(81) = init_nc_var(                                     &
+       name              = 'ls_forcing_south_qr',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for south model boundary for the rain water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "south scalar",                                  &
+       input_id          = 3_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_south_grid,                              &
+       intermediate_grid = scalars_south_intermediate                       &
+    )
+    output_var_table(81)%is_optional = .TRUE.
+
+    output_var_table(82) = init_nc_var(                                     &
+       name              = 'ls_forcing_top_qr',                             &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for top model boundary for the rain water mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "top scalar",                                    &
+       input_id          = 3_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_top_grid,                                &
+       intermediate_grid = scalars_top_intermediate                         &
+    )
+    output_var_table(82)%is_optional = .TRUE.
+
+    output_var_table(83) = init_nc_var(                                     &
+       name              = 'init_atmosphere_qs',                            &
+       std_name          = "",                                              &
+       long_name         = "initial snow mixture fraction",            &
+       units             = "kg/kg",                                         &
+       kind              = "init scalar",                                   &
+       input_id          = 4_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = palm_grid,                                       &
+       intermediate_grid = palm_intermediate,                               &
+       is_profile = (TRIM(ic_mode) == 'profile')                            &
+    )
+    IF (TRIM(ic_mode) == 'profile')  THEN
+       output_var_table(83)%averaging_grid => averaged_initial_scalar_profile
+    ENDIF
+    output_var_table(83)%is_optional = .TRUE.
+
+    output_var_table(84) = init_nc_var(                                     &
+       name              = 'ls_forcing_left_qs',                            &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for left model boundary for the snow mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "left scalar",                                   &
+       input_id          = 4_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_west_grid,                               &
+       intermediate_grid = scalars_west_intermediate                        &
+    )
+    output_var_table(84)%is_optional = .TRUE.
+
+    output_var_table(85) = init_nc_var(                                     &
+       name              = 'ls_forcing_right_qs',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for right model boundary for the snow mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "right scalar",                                  &
+       input_id          = 4_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_east_grid,                               &
+       intermediate_grid = scalars_east_intermediate                        &
+    )
+    output_var_table(85)%is_optional = .TRUE.
+
+    output_var_table(86) = init_nc_var(                                     &
+       name              = 'ls_forcing_north_qs',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for north model boundary for the snow mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "north scalar",                                  &
+       input_id          = 4_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_north_grid,                              &
+       intermediate_grid = scalars_north_intermediate                       &
+    )
+    output_var_table(86)%is_optional = .TRUE.
+
+    output_var_table(87) = init_nc_var(                                     &
+       name              = 'ls_forcing_south_qs',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for south model boundary for the snow mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "south scalar",                                  &
+       input_id          = 4_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_south_grid,                              &
+       intermediate_grid = scalars_south_intermediate                       &
+    )
+    output_var_table(87)%is_optional = .TRUE.
+
+    output_var_table(88) = init_nc_var(                                     &
+       name              = 'ls_forcing_top_qs',                             &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for top model boundary for the snow mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "top scalar",                                    &
+       input_id          = 4_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_top_grid,                                &
+       intermediate_grid = scalars_top_intermediate                         &
+    )
+    output_var_table(88)%is_optional = .TRUE.
+
+    output_var_table(89) = init_nc_var(                                     &
+       name              = 'init_atmosphere_qg',                            &
+       std_name          = "",                                              &
+       long_name         = "initial graupel mixture fraction",            &
+       units             = "kg/kg",                                         &
+       kind              = "init scalar",                                   &
+       input_id          = 5_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = palm_grid,                                       &
+       intermediate_grid = palm_intermediate,                               &
+       is_profile = (TRIM(ic_mode) == 'profile')                            &
+    )
+    IF (TRIM(ic_mode) == 'profile')  THEN
+       output_var_table(89)%averaging_grid => averaged_initial_scalar_profile
+    ENDIF
+    output_var_table(89)%is_optional = .TRUE.
+
+    output_var_table(90) = init_nc_var(                                     &
+       name              = 'ls_forcing_left_qg',                            &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for left model boundary for the graupel mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "left scalar",                                   &
+       input_id          = 5_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_west_grid,                               &
+       intermediate_grid = scalars_west_intermediate                        &
+    )
+    output_var_table(90)%is_optional = .TRUE.
+
+    output_var_table(91) = init_nc_var(                                     &
+       name              = 'ls_forcing_right_qg',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for right model boundary for the graupel mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "right scalar",                                  &
+       input_id          = 5_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_east_grid,                               &
+       intermediate_grid = scalars_east_intermediate                        &
+    )
+    output_var_table(91)%is_optional = .TRUE.
+
+    output_var_table(92) = init_nc_var(                                     &
+       name              = 'ls_forcing_north_qg',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for north model boundary for the graupel mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "north scalar",                                  &
+       input_id          = 5_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_north_grid,                              &
+       intermediate_grid = scalars_north_intermediate                       &
+    )
+    output_var_table(92)%is_optional = .TRUE.
+
+    output_var_table(93) = init_nc_var(                                     &
+       name              = 'ls_forcing_south_qg',                           &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for south model boundary for the graupel mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "south scalar",                                  &
+       input_id          = 5_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_south_grid,                              &
+       intermediate_grid = scalars_south_intermediate                       &
+    )
+    output_var_table(93)%is_optional = .TRUE.
+
+    output_var_table(94) = init_nc_var(                                     &
+       name              = 'ls_forcing_top_qg',                             &
+       std_name          = "",                                              &
+       long_name         = "large-scale forcing for top model boundary for the graupel mixture fraction", &
+       units             = "kg/kg",                                         &
+       kind              = "top scalar",                                    &
+       input_id          = 5_iwp,                                           &
+       output_file       = output_file,                                     &
+       grid              = scalars_top_grid,                                &
+       intermediate_grid = scalars_top_intermediate                         &
+    )
+    output_var_table(94)%is_optional = .TRUE.
 
 !
@@ -3711,5 +4235,5 @@
     
     CALL report('fini_file_lists', 'Deallocating file lists', cfg%debug)
-    DEALLOCATE( flow_files, soil_files, radiation_files, soil_moisture_files )
+    DEALLOCATE( flow_files, soil_files, radiation_files, precip_files )
 
  END SUBROUTINE fini_file_lists
@@ -3727,14 +4251,12 @@
 !> array will match a COSMO-DE scalar array.
 !------------------------------------------------------------------------------!
- SUBROUTINE preprocess(group, input_buffer, cosmo_grid, iter)
+ SUBROUTINE preprocess( group, input_buffer, cosmo_grid )
 
     TYPE(io_group), INTENT(INOUT), TARGET       ::  group
     TYPE(container), INTENT(INOUT), ALLOCATABLE ::  input_buffer(:)
     TYPE(grid_definition), INTENT(IN)           ::  cosmo_grid
-    INTEGER(iwp), INTENT(IN)                    ::  iter
     
     REAL(wp), ALLOCATABLE                       ::  basic_state_pressure(:)
     TYPE(container), ALLOCATABLE                ::  preprocess_buffer(:)
-    INTEGER(iwp)                                ::  hour, dt
     INTEGER(iwp)                                ::  i, j, k
     INTEGER(iwp)                                ::  nx, ny, nz
@@ -3935,94 +4457,4 @@
           input_buffer(:)%is_preprocessed = .TRUE.
 
-       CASE( 'accumulated' ) ! 
-          message = "De-accumulating '" // TRIM(group%in_var_list(1)%name) //&
-                    "' in iteration " // TRIM(str(iter)) 
-          CALL report('preprocess', message)
-
-          hour = iter - 1_iwp
-          dt = MODULO(hour, 3_iwp) + 1_iwp ! averaging period
-          SELECT CASE(dt)
-
-!
-!--          input has been accumulated over one hour. Leave as is
-!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
-             CASE(1)
-             
-!            
-!--          input has been accumulated over two hours. Subtract previous step
-!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
-!--          input_buffer(2)%array(:,:,:) carrries two-hour integral
-             CASE(2)
-                CALL deaverage(                                                   &
-                         avg_1 = input_buffer(1)%array(:,:,:), t1 = 1.0_wp,     &
-                         avg_2 = input_buffer(2)%array(:,:,:), t2 = 1.0_wp,     &
-                         avg_3 = input_buffer(1)%array(:,:,:), t3 = 1.0_wp )
-!            
-!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of second hour
-             
-!            
-!--          input has been accumulated over three hours. Subtract previous step
-!--          input_buffer(1)%array(:,:,:) carrries three-hour integral
-!--          input_buffer(2)%array(:,:,:) still carrries two-hour integral
-             CASE(3)
-                CALL deaverage(                                                   &
-                        avg_1 = input_buffer(2)%array(:,:,:), t1 = 1.0_wp,      &
-                        avg_2 = input_buffer(1)%array(:,:,:), t2 = 1.0_wp,      &
-                        avg_3 = input_buffer(1)%array(:,:,:), t3 = 1.0_wp )
-!            
-!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of third hourA
-             
-             CASE DEFAULT
-                message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
-                message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
-                CALL inifor_abort('preprocess', message)
-
-          END SELECT
-          input_buffer(:)%is_preprocessed = .TRUE.
-
-       CASE( 'running average' ) ! 
-          message = "De-averaging '" // TRIM(group%in_var_list(1)%name) //   &
-                    "' in iteration " // TRIM(str(iter)) 
-          CALL report('preprocess', message)
-
-          hour = iter - 1_iwp
-!
-!--       averaging period
-          dt = MODULO(hour, 3_iwp) + 1_iwp
-          SELECT CASE(dt)
-!
-!--          input has been accumulated over one hour. Leave as is
-!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
-             CASE(1)
-             
-!            
-!--          input has been accumulated over two hours. Subtract previous step
-!--          input_buffer(1)%array(:,:,:) carrries one-hour integral
-!--          input_buffer(2)%array(:,:,:) carrries two-hour integral
-             CASE(2)
-                CALL deaverage( input_buffer(1)%array(:,:,:), 1.0_wp,           &
-                                input_buffer(2)%array(:,:,:), 2.0_wp,           &
-                                input_buffer(1)%array(:,:,:), 1.0_wp)
-!            
-!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of second hour
-             
-!            
-!--          input has been accumulated over three hours. Subtract previous step
-!--          input_buffer(1)%array(:,:,:) carrries three-hour integral
-!--          input_buffer(2)%array(:,:,:) still carrries two-hour integral
-             CASE(3)
-                CALL deaverage( input_buffer(2)%array(:,:,:), 2.0_wp,           &
-                                input_buffer(1)%array(:,:,:), 3.0_wp,           &
-                                input_buffer(1)%array(:,:,:), 1.0_wp)
-!            
-!--             input_buffer(1)%array(:,:,:) carrries one-hour integral of third hourA
-             
-             CASE DEFAULT
-                message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
-                CALL inifor_abort('preprocess', message)
-
-          END SELECT
-          input_buffer(:)%is_preprocessed = .TRUE.
-
        CASE DEFAULT
           message = "IO group kind '" // TRIM(group%kind) // "' is not supported."
Index: /palm/trunk/UTIL/inifor/src/inifor_io.f90
===================================================================
--- /palm/trunk/UTIL/inifor/src/inifor_io.f90	(revision 4658)
+++ /palm/trunk/UTIL/inifor/src/inifor_io.f90	(revision 4659)
@@ -21,9 +21,16 @@
 ! Current revisions:
 ! -----------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
 ! $Id$
+! New command-line option '--precipitation' enables output of precipitation
+!    surface forcing
+! Only define netCDF variables in enabled IO groups
+! Improved code formatting
+! 
+! 
+! 4569 2020-06-19 12:46:17Z eckhard
 ! Removed unused variable
 ! 
@@ -450,5 +457,6 @@
     cfg%radiation_prefix_is_set = .FALSE.
     cfg%soil_prefix_is_set = .FALSE.
-    cfg%soilmoisture_prefix_is_set = .FALSE.
+    cfg%precipitation_prefix_is_set = .FALSE.
+    cfg%process_precipitation = .FALSE.
     cfg%static_driver_is_set = .FALSE.
     cfg%ug_defined_by_user = .FALSE.
@@ -538,8 +546,11 @@
                 cfg%soil_prefix_is_set = .TRUE.
    
-             CASE( '--soilmoisture-prefix')
-                CALL get_option_argument( i, arg )
-                cfg%soilmoisture_prefix = TRIM(arg)
-                cfg%soilmoisture_prefix_is_set = .TRUE.
+             CASE( '--precipitation-prefix')
+                CALL get_option_argument( i, arg )
+                cfg%precipitation_prefix = TRIM(arg)
+                cfg%precipitation_prefix_is_set = .TRUE.
+
+             CASE( '--precipitation')
+                cfg%process_precipitation = .TRUE.
 
              CASE( '-o', '--output' )
@@ -567,5 +578,5 @@
                 PRINT *, ""
                 PRINT *, &
-                   "For documentation and a list of available command-line options " // NEW_LINE(" ") // &
+                   "For documentation and a list of available command-line options " // NEW_LINE( " " ) // &
                    " please visit https://palm.muk.uni-hannover.de/trac/wiki/doc/app/iofiles/inifor."
                 STOP
@@ -628,5 +639,5 @@
  SUBROUTINE get_input_file_list( start_date_string, start_hour, end_hour,    &
                                  step_hour, input_path, prefix, suffix,      &
-                                 file_list, nocheck )
+                                 file_list )
 
     CHARACTER (LEN=DATE), INTENT(IN) ::  start_date_string
@@ -634,8 +645,4 @@
     INTEGER(iwp),         INTENT(IN) ::  start_hour, end_hour, step_hour
     CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) ::  file_list(:)
-    LOGICAL, OPTIONAL, INTENT(IN)    ::  nocheck
-
-    INTEGER(iwp) ::  i
-    LOGICAL      ::  check_files
 
     CALL get_datetime_file_list( start_date_string, start_hour, end_hour,    &
@@ -643,20 +650,4 @@
                                  file_list )
 
-    check_files = .TRUE.
-    IF ( PRESENT ( nocheck ) )  THEN
-       IF ( nocheck )  check_files = .FALSE.
-    ENDIF
-
-    IF ( check_files )  THEN
-
-       tip = "Please check if you specified the correct file prefix " //     &
-             "using the options --input-prefix, --flow-prefix, etc."
-
-       DO  i = 1, SIZE(file_list)
-           CALL verify_file(file_list(i), 'input', tip)
-       ENDDO
-
-    ENDIF
-
  END SUBROUTINE get_input_file_list
 
@@ -667,36 +658,44 @@
 !> Abort INIFOR if the given file is not present.
 !------------------------------------------------------------------------------!
- SUBROUTINE verify_file(file_name, file_kind, tip)
+LOGICAL FUNCTION file_is_present( filename, file_kind, message )
+
+    CHARACTER(LEN=*), INTENT(IN)            ::  filename, file_kind
+    CHARACTER(LEN=*), INTENT(OUT)           ::  message
+
+    file_is_present = file_present(filename)
+
+    IF (.NOT. file_is_present)  THEN
+
+       IF (LEN( TRIM( filename ) ) == 0)  THEN
+          message = "No name was given for the " // TRIM( file_kind ) // " file."
+       ELSE
+          message = "The " // TRIM( file_kind ) // " file '" //                  &
+                    TRIM( filename ) // "' was not found."
+       ENDIF
+
+    ENDIF
+
+END FUNCTION file_is_present
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Abort INIFOR if the given file is not present.
+!------------------------------------------------------------------------------!
+ SUBROUTINE verify_file( file_name, file_kind )
 
     CHARACTER(LEN=*), INTENT(IN)           ::  file_name, file_kind
-    CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  tip
-
-    IF (.NOT. file_present(file_name))  THEN
-
-       IF (LEN(TRIM(file_name)) == 0)  THEN
-
-          message = "No name was given for the " // TRIM(file_kind) // " file."
-
-       ELSE
-
-          message = "The " // TRIM(file_kind) // " file '" //                &
-                    TRIM(file_name) // "' was not found."
-
-          IF (PRESENT(tip))  THEN
-             message = TRIM(message) // " " // TRIM(tip)
-          ENDIF
-
-       ENDIF
-
-       CALL inifor_abort('verify_file', message)
-
-    ENDIF
-
-    message = "Set up input file name '" // TRIM(file_name) // "'"
-    CALL report('verify_file', message)
+
+    IF (.NOT. file_is_present( file_name, file_kind, message ))  THEN
+
+       CALL inifor_abort( 'verify_file', message )
+
+    ENDIF
+
+    message = "Set up input file name '" // TRIM( file_name ) // "'"
+    CALL report( 'verify_file', message )
 
  END SUBROUTINE verify_file
-
-
 !------------------------------------------------------------------------------!
 ! Description:
@@ -705,10 +704,10 @@
 !> i+1 of the argument list.
 !------------------------------------------------------------------------------!
- SUBROUTINE get_option_argument(i, arg)
+ SUBROUTINE get_option_argument( i, arg )
     CHARACTER(LEN=PATH), INTENT(INOUT) ::  arg
     INTEGER, INTENT(INOUT)             ::  i
 
     i = i + 1
-    CALL GET_COMMAND_ARGUMENT(i, arg)
+    CALL GET_COMMAND_ARGUMENT( i, arg )
 
  END SUBROUTINE
@@ -720,21 +719,21 @@
 !> Checks the INIFOR configuration 'cfg' for plausibility.
 !------------------------------------------------------------------------------!
- SUBROUTINE validate_config(cfg)
+ SUBROUTINE validate_config( cfg )
     TYPE(inifor_config), INTENT(IN) ::  cfg
 
-    CALL verify_file(cfg%hhl_file, 'HHL')
-    CALL verify_file(cfg%namelist_file, 'NAMELIST')
-    CALL verify_file(cfg%soiltyp_file, 'SOILTYP')
+    CALL verify_file( cfg%hhl_file, 'HHL' )
+    CALL verify_file( cfg%namelist_file, 'NAMELIST' )
+    CALL verify_file( cfg%soiltyp_file, 'SOILTYP' )
 
 !
 !-- Only check optional static driver file name, if it has been given.
-    IF (TRIM(cfg%static_driver_file) .NE. '')  THEN
-       CALL verify_file(cfg%static_driver_file, 'static driver')
-    ENDIF
-
-    SELECT CASE( TRIM(cfg%ic_mode) )
-       CASE( 'profile', 'volume')
+    IF (TRIM( cfg%static_driver_file ) .NE. '')  THEN
+       CALL verify_file( cfg%static_driver_file, 'static driver' )
+    ENDIF
+
+    SELECT CASE( TRIM( cfg%ic_mode ) )
+       CASE( 'profile', 'volume' )
        CASE DEFAULT
-          message = "Initialization mode '" // TRIM(cfg%ic_mode) //&
+          message = "Initialization mode '" // TRIM( cfg%ic_mode ) //&
                     "' is not supported. " //&
                     "Please select either 'profile' or 'volume', " //&
@@ -747,5 +746,5 @@
        CASE( 'real', 'ideal')
        CASE DEFAULT
-          message = "Forcing mode '" // TRIM(cfg%bc_mode) //& 
+          message = "Forcing mode '" // TRIM( cfg%bc_mode ) //& 
                     "' is not supported. " //&
                     "Please select either 'real' or 'ideal', " //&
@@ -755,8 +754,8 @@
     END SELECT
 
-    SELECT CASE( TRIM(cfg%averaging_mode) )
+    SELECT CASE( TRIM( cfg%averaging_mode ) )
        CASE( 'level' )
        CASE( 'height' )
-          message = "Averaging mode '" // TRIM(cfg%averaging_mode) //&
+          message = "Averaging mode '" // TRIM( cfg%averaging_mode ) //&
                     "' is currently not supported. " //&
                     "Please use level-based averaging by selecting 'level', " //&
@@ -764,5 +763,5 @@
           CALL inifor_abort( 'validate_config', message )
        CASE DEFAULT
-          message = "Averaging mode '" // TRIM(cfg%averaging_mode) //&
+          message = "Averaging mode '" // TRIM( cfg%averaging_mode ) //&
                     "' is not supported. " //&
           !          "Please select either 'height' or 'level', " //&
@@ -782,8 +781,8 @@
     IF ( .NOT. cfg%static_driver_is_set .AND. .NOT. cfg%z0_is_set )  THEN
        message =                                                               &
-          "The vertical origin of the PALM grid has not been defined. " // NEW_LINE(" ") // &
-          "Please specify the right value for your setup by either " // NEW_LINE(" ") // &
-          "  - using the command-line option --elevation <height above sea level>, or by" // NEW_LINE(" ") // &
-          "  - specifying a static driver file using --static <filename> in order to use " // NEW_LINE(" ") // &
+          "The vertical origin of the PALM grid has not been defined. " // NEW_LINE( " " ) // &
+          "Please specify the right value for your setup by either " // NEW_LINE( " " ) // &
+          "  - using the command-line option --elevation <height above sea level>, or by" // NEW_LINE( " " ) // &
+          "  - specifying a static driver file using --static <filename> in order to use " // NEW_LINE( " " ) // &
           "    use the value of origin_z (and origin_lon and origin_lat) specifed therein."
        CALL inifor_abort( 'validate_config', message )
@@ -902,5 +901,5 @@
 !>
 !------------------------------------------------------------------------------!
- SUBROUTINE get_soil_layer_thickness(depths, d_depth)
+ SUBROUTINE get_soil_layer_thickness( depths, d_depth )
 
     REAL(wp), INTENT(IN)  ::  depths(:)
@@ -916,8 +915,8 @@
 !> Check whether the given file is present on the filesystem.
 !------------------------------------------------------------------------------!
- LOGICAL FUNCTION file_present(filename)
+ LOGICAL FUNCTION file_present( filename )
     CHARACTER(LEN=PATH), INTENT(IN) ::  filename
 
-    INQUIRE(FILE=filename, EXIST=file_present)
+    INQUIRE( FILE=filename, EXIST=file_present )
 
  END FUNCTION file_present
@@ -1126,13 +1125,14 @@
 !> Defines the netCDF variables to be written to the dynamic driver file
 !------------------------------------------------------------------------------!
- SUBROUTINE setup_netcdf_variables(filename, output_variable_table)
-
-    CHARACTER (LEN=*), INTENT(IN)        ::  filename
-    TYPE(nc_var), INTENT(INOUT), TARGET  ::  output_variable_table(:)
-
-    TYPE(nc_var), POINTER                ::  var
-    INTEGER(iwp)                         ::  i
-    INTEGER                              ::  ncid
-    LOGICAL                              ::  to_be_written
+ SUBROUTINE setup_netcdf_variables(filename, io_group_list)
+
+    CHARACTER (LEN=*), INTENT(IN)       ::  filename
+    TYPE(io_group), INTENT(IN), TARGET  ::  io_group_list(:)
+
+    TYPE(io_group), POINTER             ::  group
+    TYPE(nc_var), POINTER               ::  var
+    INTEGER(iwp)                        ::  group_idx, var_idx, n_var
+    INTEGER                             ::  ncid
+    LOGICAL                             ::  to_be_written
 
     message = "Defining variables in dynamic driver '" // TRIM(filename) // "'."
@@ -1142,19 +1142,31 @@
     CALL check(nf90_redef(ncid))
 
-    DO  i = 1, SIZE(output_variable_table)
-
-       var => output_variable_table(i)
-
-       !to_be_written = ( var%to_be_processed  .AND. .NOT. var%is_internal) .OR. &
-       !                ( var%is_internal  .AND.  debug )
-       to_be_written = ( var%to_be_processed  .AND. .NOT. var%is_internal)
-
-       IF ( to_be_written )  THEN
-          message = "  variable #" // TRIM(str(i)) // " '" // TRIM(var%name) // "'."
-          CALL report('setup_netcdf_variables', message)
-
-          CALL netcdf_define_variable(var, ncid)
-          CALL netcdf_get_dimensions(var, ncid)
-       ENDIF
+    n_var = 0
+    DO  group_idx = 1, SIZE( io_group_list )
+
+       group => io_group_list(group_idx)
+       DO var_idx = 1, SIZE( group%out_vars )
+
+          to_be_written = .FALSE.
+
+          IF (ALLOCATED( group%out_vars ))  THEN
+             var => group%out_vars(var_idx)
+             n_var = n_var + 1
+
+             to_be_written = (                                                 &
+                group%to_be_processed  .AND.  var%to_be_processed              &
+                .AND. .NOT. var%is_internal                                    &
+             )
+          ENDIF
+
+          IF ( to_be_written )  THEN
+             message = "  variable #" // TRIM(str(n_var)) // " '" // TRIM(var%name) // "'."
+             CALL report('setup_netcdf_variables', message)
+
+             CALL netcdf_define_variable(var, ncid)
+             CALL netcdf_get_dimensions(var, ncid)
+          ENDIF
+
+       ENDDO
         
     ENDDO
@@ -1202,13 +1214,13 @@
 !
 !-- radiation budgets, precipitation
-    IF (group%kind == 'running average' .OR.                              &
-        group%kind == 'accumulated')  THEN
-
-       IF (SIZE(group%in_var_list) .GT. 1 ) THEN
+    IF ( group%kind == 'running average' .OR.                                  &
+         group%kind == 'accumulated' )  THEN
+
+       IF ( SIZE( group%in_var_list ) .GT. 1 ) THEN
           message = "I/O groups may not contain more than one " // & 
                     "accumulated variable. Group '" // TRIM(group%kind) //&
-                    "' contains " //                                        &
-                    TRIM( str(SIZE(group%in_var_list, kind=iwp)) ) // "."
-          CALL inifor_abort('read_input_variables | accumulation', message)
+                    "' contains " //                                           &
+                    TRIM( str( SIZE( group%in_var_list, kind=iwp ) ) ) // "."
+          CALL inifor_abort( 'read_input_variables | accumulation', message )
        ENDIF
 
@@ -1242,5 +1254,5 @@
 
 !
-!--    Allocate one input buffer per input_variable. If more quantities
+!--    Allocate one input buffer per output quantity. If more quantities
 !--    have to be computed than input variables exist in this group,
 !--    allocate more buffers. For instance, in the thermodynamics group,
@@ -1248,6 +1260,5 @@
 !--    necessart (P, Theta, Rho, qv) for the corresponding output fields
 !--    (p0, Theta, qv, ug, and vg)
-       nbuffers = MAX( group%n_inputs, group%n_output_quantities )
-       ALLOCATE( buffer(nbuffers) )
+       ALLOCATE( buffer(group%n_output_quantities) )
        CALL log_runtime('time', 'alloc')
        
@@ -1258,15 +1269,16 @@
           input_var => group%in_var_list(ivar)
 
-!
-!         Check wheather P or PP is present in input file
-          IF (input_var%name == 'P')  THEN
-             input_var%name = TRIM( get_pressure_varname(input_file) )
-          CALL log_runtime('time', 'read')
+          IF ( input_var%to_be_processed )  THEN
+!            Check wheather P or PP is present in input file
+             IF (input_var%name == 'P')  THEN
+                input_var%name = TRIM( get_pressure_varname(input_file) )
+             CALL log_runtime('time', 'read')
+             ENDIF
+
+             CALL get_netcdf_variable(input_file, input_var, buffer(ivar)%array)
+
+             IF ( input_var%is_upside_down )  CALL reverse(buffer(ivar)%array)
+             CALL log_runtime('time', 'comp')
           ENDIF
-
-          CALL get_netcdf_variable(input_file, input_var, buffer(ivar)%array)
-
-          IF ( input_var%is_upside_down )  CALL reverse(buffer(ivar)%array)
-          CALL log_runtime('time', 'comp')
 
        ENDDO
@@ -1663,4 +1675,19 @@
 
 
+ LOGICAL FUNCTION netcdf_variable_present_in_file( varname, filename )
+    CHARACTER(LEN=SNAME), INTENT(IN) ::  varname
+    CHARACTER(LEN=PATH), INTENT(IN)  ::  filename
+
+    INTEGER ::  ncid, varid
+    
+    netcdf_variable_present_in_file = (                                        &
+       nf90_open( TRIM( filename ), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
+       nf90_inq_varid( ncid, varname, varid ) .EQ. NF90_NOERR .AND.            &
+       nf90_close( ncid ) .EQ. NF90_NOERR                                      &
+    )
+ 
+ END FUNCTION netcdf_variable_present_in_file
+
+
  END MODULE inifor_io
 #endif
Index: /palm/trunk/UTIL/inifor/src/inifor_types.f90
===================================================================
--- /palm/trunk/UTIL/inifor/src/inifor_types.f90	(revision 4658)
+++ /palm/trunk/UTIL/inifor/src/inifor_types.f90	(revision 4659)
@@ -21,9 +21,14 @@
 ! Current revisions:
 ! -----------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
 ! $Id$
+! Added flag in support of new command-line option '--precipitation'
+! Improved code formatting
+! 
+! 
+! 4568 2020-06-19 11:56:30Z eckhard
 ! Handle COSMO soil data with and without additional surface temperature
 !
@@ -123,5 +128,5 @@
     CHARACTER(LEN=SNAME) ::  radiation_prefix     !< Prefix of radiation input files, e.g 'laf' for COSMO-DE analyses
     CHARACTER(LEN=SNAME) ::  soil_prefix          !< Prefix of soil input files, e.g. 'laf' for COSMO-DE analyses
-    CHARACTER(LEN=SNAME) ::  soilmoisture_prefix  !< Prefix of input files for soil moisture spin-up, e.g 'laf' for COSMO-DE analyses
+    CHARACTER(LEN=SNAME) ::  precipitation_prefix !< Prefix of input files for precipitation forcing, e.g 'laf' for COSMO-DE analyses
 
     CHARACTER(LEN=SNAME) ::  averaging_mode       !< destinguishes between level-based and heigh-based averaging
@@ -142,5 +147,6 @@
     LOGICAL              ::  radiation_prefix_is_set     !< indicates whether the radiation prefix was set manually
     LOGICAL              ::  soil_prefix_is_set          !< indicates whether the soil prefix was set manually
-    LOGICAL              ::  soilmoisture_prefix_is_set  !< indicates whether the soilmoisture prefix was set manually
+    LOGICAL              ::  precipitation_prefix_is_set !< indicates whether the precipitation prefix was set manually
+    LOGICAL              ::  process_precipitation       !< indicates whether precipitation should be processed
     LOGICAL              ::  static_driver_is_set        !< indicates whether a static driver was given
     LOGICAL              ::  ug_defined_by_user          !< indicates whether ug was set manually
@@ -247,4 +253,5 @@
     LOGICAL                               ::  to_be_processed = .FALSE. !< INIFOR flag indicating whether variable shall be processed
     LOGICAL                               ::  is_internal = .FALSE.     !< INIFOR flag indicating whether variable shall be written to netCDF file (.FALSE.) or kept for later (.TRUE.)
+    LOGICAL                               ::  is_optional = .FALSE.     !< Flag indicating whether INIFOR may continue if the the netCDF variable cannot be processed, e.g. if files are missing
     LOGICAL                               ::  is_read = .FALSE.         !< INIFOR flag indicating whether variable has been read
     LOGICAL                               ::  is_upside_down  = .FALSE. !< INIFOR flag indicating whether vertical dimension is reversed (typically the case with COSMO-DE atmospheric fields)
@@ -252,5 +259,5 @@
     TYPE(grid_definition), POINTER        ::  grid                      !< Pointer to the corresponding output grid
     TYPE(grid_definition), POINTER        ::  intermediate_grid         !< Pointer to the corresponding intermediate grid
-    TYPE(grid_definition), POINTER        ::  averaging_grid         !< Pointer to the corresponding intermediate grid
+    TYPE(grid_definition), POINTER        ::  averaging_grid            !< Pointer to the corresponding intermediate grid
  END TYPE nc_var
 
@@ -265,14 +272,16 @@
 !------------------------------------------------------------------------------!
  TYPE io_group
-    INTEGER(iwp)                          ::  nt             !< maximum number of output time steps across all output variables
-    INTEGER(iwp)                          ::  nv             !< number of netCDF output variables
-    INTEGER(iwp)                          ::  n_inputs       !< number of input variables
-    INTEGER(iwp)                          ::  n_output_quantities !< number of physical quantities required for computing netCDF output variables
-    CHARACTER(LEN=SNAME)             ::  kind           !< kind of I/O group
-    CHARACTER(LEN=PATH), ALLOCATABLE ::  in_files(:)    !< list of nt input files
-    TYPE(nc_var), ALLOCATABLE        ::  out_vars(:)    !< list of output variables 
-    TYPE(nc_var), ALLOCATABLE        ::  in_var_list(:) !< list of input variables
+    INTEGER(iwp)                     ::  nt                  !< maximum number of output time steps across all output variables
+    INTEGER(iwp)                     ::  nv                  !< number of netCDF output variables
+    INTEGER(iwp)                     ::  n_inputs            !< number of input variables
+    INTEGER(iwp)                     ::  n_output_quantities !< number of physical quantities required for computing netCDF output variables
+    CHARACTER(LEN=SNAME)             ::  name                !< name of I/O group
+    CHARACTER(LEN=SNAME)             ::  kind                !< kind of I/O group
+    CHARACTER(LEN=PATH), ALLOCATABLE ::  in_files(:)         !< list of nt input files
+    TYPE(nc_var), ALLOCATABLE        ::  out_vars(:)         !< list of output variables 
+    TYPE(nc_var), ALLOCATABLE        ::  in_var_list(:)      !< list of input variables
     LOGICAL                          ::  to_be_processed = .FALSE. !< Inifor flag indicating whether I/O group shall be processed
     LOGICAL                          ::  is_accumulated = .FALSE.  !< Flag indicating whether this I/O group contains accumulated variables
+    LOGICAL                          ::  is_optional = .FALSE.     !< Flag indicating whether INIFOR may continue if group cannot be processed, e.g. if files are missing
     LOGICAL                          ::  is_preprocessed = .FALSE. !< Inifor flag indicating whether the I/O group has been preprocessed
  END TYPE io_group 
