Changeset 4659 for palm/trunk/UTIL


Ignore:
Timestamp:
Aug 31, 2020 11:21:17 AM (4 years ago)
Author:
eckhard
Message:

inifor: Support for COSMO cloud water and precipitation

Location:
palm/trunk/UTIL/inifor/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • palm/trunk/UTIL/inifor/src/inifor.f90

    r4523 r4659  
    2121! Current revisions:
    2222! -----------------
    23 ! 
    24 ! 
     23!
     24!
    2525! Former revisions:
    2626! -----------------
    2727! $Id$
     28! List all warnings after successful run
     29! Only define netCDF variables in enabled IO groups
     30!
     31!
     32! 4523 2020-05-07 15:58:16Z eckhard
    2833! respect integer working precision (iwp) specified in inifor_defs.f90
    2934!
     
    118123               origin_lon,                                                     &
    119124               output_file,                                                    &
    120                output_var_table,                                               &
    121125               p0,                                                             &
    122126               phi_centre,                                                     &
     
    199203!-- the corresponding netCDF dimensions for each output variable
    200204    CALL setup_variable_tables( cfg%ic_mode )
    201     CALL log_runtime( 'time', 'write' )
    202 
    203 !
    204 !-- Add the output variables to the netCDF output file
    205     CALL setup_netcdf_variables( output_file%name, output_var_table )
    206 
    207205    CALL setup_io_groups
    208206    CALL log_runtime( 'time', 'init' )
     207!
     208!-- Add the output variables to the netCDF output file
     209    CALL setup_netcdf_variables( output_file%name, io_group_list)
     210    CALL log_runtime( 'time', 'write' )
    209211
    210212!------------------------------------------------------------------------------
     
    236238!--          potential temperature is computed from the absolute temperature and
    237239!--          pressure.
    238              CALL preprocess( group, input_buffer, cosmo_grid, iter )
     240             CALL preprocess( group, input_buffer, cosmo_grid )
    239241             CALL log_runtime( 'time', 'comp' )
    240242
     
    591593    !CALL fini_grids
    592594    CALL log_runtime( 'time', 'alloc' )
    593     CALL log_runtime( 'report', 'void' )
    594 
    595     message = "Finished writing dynamic driver '" // TRIM( output_file%name )
    596    
    597     IF ( n_wrngs > 0 )  THEN
    598        message = TRIM( message ) // "' with " // TRIM( str( n_wrngs ) ) //     &
    599        " warning(s). Please see logfile '" // LOG_FILE_NAME // "'."
    600     ELSE
    601        message = TRIM( message ) // "' successfully."
    602     END IF
    603 
    604     CALL report( 'main loop', message )
     595
     596    CALL report_warnings
     597    CALL report_success( output_file%name )
     598    CALL report_runtime
    605599    CALL close_log
    606600
  • palm/trunk/UTIL/inifor/src/inifor_control.f90

    r4523 r4659  
    2121! Current revisions:
    2222! -----------------
    23 ! 
    24 ! 
     23!
     24!
    2525! Former revisions:
    2626! -----------------
    2727! $Id$
     28! List warnings after successful run or abort
     29! Produce failure exit code (1) on program abort for test automation
     30! Improved code formatting
     31!
     32!
     33! 4523 2020-05-07 15:58:16Z eckhard
    2834! respect integer working precision (iwp) specified in inifor_defs.f90
    2935!
     
    8793
    8894    USE inifor_defs,                                                           &
    89         ONLY:  COPYRIGHT, LNAME, LOG_FILE_NAME, VERSION, iwp, wp
     95        ONLY:  COPYRIGHT, LNAME, LOG_FILE_NAME, PATH, VERSION, iwp, wp
    9096    USE inifor_util,                                                           &
    91         ONLY:  real_to_str, real_to_str_f
     97        ONLY:  real_to_str, real_to_str_f, str
    9298
    9399    IMPLICIT NONE
    94100
    95     CHARACTER (LEN=5000) ::  message = '' !< log message buffer
    96     CHARACTER (LEN=5000) ::  tip     = '' !< optional log message buffer for tips on how to rectify encountered errors
    97     INTEGER(iwp), SAVE        ::  u            !< Fortran file unit for the log file
    98     INTEGER(iwp), SAVE        ::  n_wrngs = 0  !< Fortran file unit for the log file
     101    INTEGER(iwp), SAVE         ::  u                     !< Fortran file unit for the log file
     102    INTEGER(iwp), PARAMETER    ::  n_max_wrngs = 512     !< Fortran file unit for the log file
     103    INTEGER(iwp), SAVE         ::  n_wrngs = 0           !< Fortran file unit for the log file
     104    CHARACTER (LEN=5000)       ::  message = ''          !< log message buffer
     105    CHARACTER (LEN=5000)       ::  tip     = ''          !< optional log message buffer for tips on how to rectify encountered errors
     106    CHARACTER (LEN=5000), SAVE ::  warnings(n_max_wrngs) !< log of warnings
    99107
    100108 CONTAINS
     
    112120!> to it.
    113121!------------------------------------------------------------------------------!
    114  SUBROUTINE report(routine, message, debug)
     122 SUBROUTINE report( routine, message, debug )
    115123
    116124    CHARACTER(LEN=*), INTENT(IN)  ::  routine !< name of calling subroutine of function
     
    128136
    129137    suppress_message = .FALSE.
    130     IF ( PRESENT(debug) )  THEN
     138    IF ( PRESENT( debug ) )  THEN
    131139       IF ( .NOT. debug )  suppress_message = .TRUE.
    132140    ENDIF
    133141
    134142    IF ( .NOT. suppress_message )  THEN
    135        WRITE(*, '(A)') "inifor: " // TRIM(message) // "  [ " // TRIM(routine) // " ]"
    136        WRITE(u, '(A)')  TRIM(message) // "  [ " // TRIM(routine) // " ]"
     143       CALL write_to_sdtout_and_logfile(                                       &
     144          TRIM( message ) // "  [ " // TRIM( routine ) // " ]"                 &
     145       )
    137146    ENDIF
    138147
    139148 END SUBROUTINE report
     149
     150
     151!------------------------------------------------------------------------------!
     152! Description:
     153! ------------
     154!> This routine writes the given message to SDTOUT as well as to the INIFOR log
     155!> file.
     156!------------------------------------------------------------------------------!
     157 SUBROUTINE write_to_sdtout_and_logfile( message )
     158
     159    CHARACTER(LEN=*), INTENT(IN)  ::  message
     160
     161    WRITE(*, '(A)') "inifor: " // TRIM( message )
     162    WRITE(u, '(A)') TRIM( message )
     163
     164 END SUBROUTINE write_to_sdtout_and_logfile
    140165
    141166
     
    150175!> continue.
    151176!------------------------------------------------------------------------------!
    152  SUBROUTINE warn(routine, message)
     177 SUBROUTINE warn( routine, message )
    153178
    154179    CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
    155180    CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
    156181
     182    CALL cache_warning( routine, message )
     183    CALL report( routine, "WARNING: " // TRIM( message ) )
     184
     185 END SUBROUTINE warn
     186
     187
     188 SUBROUTINE cache_warning( routine, message )
     189
     190    CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
     191    CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
     192
    157193    n_wrngs = n_wrngs + 1
    158     CALL report(routine, "WARNING: " // TRIM(message))
    159 
    160  END SUBROUTINE warn
     194    warnings(n_wrngs) = "  WARNING: " // TRIM( message ) //                      &
     195                        "  [ " // TRIM( routine ) // " ]"
     196
     197 END SUBROUTINE cache_warning
     198
     199
     200!------------------------------------------------------------------------------!
     201! Description:
     202! ------------
     203!>
     204!> This routine writes all warnings cached with cache_warning() to STDOUT
     205!> and the INIFOR log file.
     206!------------------------------------------------------------------------------!
     207 SUBROUTINE report_warnings()
     208
     209    INTEGER(iwp) ::  warning_idx
     210
     211    IF (n_wrngs > 0)  THEN
     212       message = 'Encountered the following '// TRIM( str( n_wrngs ) ) // " warning(s) during this run:"
     213       CALL report( 'report_warnings', message )
     214
     215       DO warning_idx = 1, n_wrngs
     216          CALL write_to_sdtout_and_logfile( warnings(warning_idx) )
     217       ENDDO
     218    ENDIF
     219
     220 END SUBROUTINE report_warnings
     221
     222!------------------------------------------------------------------------------!
     223! Description:
     224! ------------
     225!>
     226!> Report successful run. To be called at the end of the main loop.
     227!------------------------------------------------------------------------------!
     228 SUBROUTINE report_success( output_file_name )
     229
     230    CHARACTER(LEN=PATH), INTENT(IN) ::  output_file_name
     231
     232    message = "Finished writing dynamic driver '" // TRIM( output_file_name )
     233    message = TRIM( message ) // "' successfully."
     234    IF (n_wrngs > 0)  THEN
     235       message = TRIM( message ) // " Some warnings were encountered."
     236    ENDIF
     237    CALL report( 'main loop', message )
     238
     239 END SUBROUTINE report_success
     240   
     241
     242!------------------------------------------------------------------------------!
     243! Description:
     244! ------------
     245!>
     246!> Report runtime statistics
     247!------------------------------------------------------------------------------!
     248 SUBROUTINE report_runtime()
     249
     250    CALL log_runtime( 'report', 'void' )
     251
     252 END SUBROUTINE report_runtime
    161253
    162254
     
    171263!> INIFOR from continueing.
    172264!------------------------------------------------------------------------------!
    173  SUBROUTINE inifor_abort(routine, message)
     265 SUBROUTINE inifor_abort( routine , message )
    174266
    175267    CHARACTER(LEN=*), INTENT(IN) ::  routine !< name of calling subroutine or function
    176268    CHARACTER(LEN=*), INTENT(IN) ::  message !< log message
    177269
    178     CALL report(routine, "ERROR: " // TRIM(message) // " Stopping.")
     270    CALL report( routine, "ERROR: " // TRIM( message ) // " Stopping." )
     271    CALL report_warnings
    179272    CALL close_log
    180     STOP
     273    CALL EXIT(1)
    181274
    182275 END SUBROUTINE inifor_abort
     
    185278 SUBROUTINE close_log()
    186279
    187     CLOSE(u)
     280    CLOSE( u )
    188281
    189282 END SUBROUTINE close_log
     
    209302!> accumulates them in timing budgets.
    210303!------------------------------------------------------------------------------!
    211  SUBROUTINE log_runtime(mode, budget)
     304 SUBROUTINE log_runtime( mode, budget )
    212305
    213306    CHARACTER(LEN=*), INTENT(IN) ::  mode   !< name of the calling mode
     
    226319
    227320
    228     SELECT CASE(TRIM(mode))
    229 
    230     CASE('init')
     321    SELECT CASE( TRIM( mode ) )
     322
     323    CASE( 'init' )
    231324       CALL CPU_TIME(t0)
    232325
    233     CASE('time')
     326    CASE( 'time' )
    234327
    235328       CALL CPU_TIME(t1)
    236329
    237        SELECT CASE(TRIM(budget))
    238 
    239           CASE('alloc')
     330       SELECT CASE( TRIM( budget ) )
     331
     332          CASE( 'alloc' )
    240333             t_alloc = t_alloc + t1 - t0
    241334
    242           CASE('init')
     335          CASE( 'init' )
    243336             t_init = t_init + t1 - t0
    244337
    245           CASE('read')
     338          CASE( 'read' )
    246339             t_read = t_read + t1 - t0
    247340
    248           CASE('write')
     341          CASE( 'write' )
    249342             t_write = t_write + t1 - t0
    250343
    251           CASE('comp')
     344          CASE( 'comp' )
    252345             t_comp = t_comp + t1 - t0
    253346
    254347          CASE DEFAULT
    255              CALL inifor_abort('log_runtime', "Time Budget '" // TRIM(mode) // "' is not supported.")
     348             CALL inifor_abort(                                                &
     349                'log_runtime',                                                 &
     350                "Time Budget '" // TRIM( mode ) // "' is not supported."       &
     351             )
    256352
    257353       END SELECT
     
    259355       t0 = t1
    260356
    261     CASE('report')
     357    CASE( 'report' )
    262358        t_total = t_init + t_read + t_write + t_comp
    263359
    264         CALL report('log_runtime', " *** CPU time ***")
    265 
    266         CALL report('log_runtime', "Initialization:  " // TRIM( real_to_str( t_init ) ) // &
    267                     " s  (" // TRIM( real_to_str( 100 * t_init / t_total, fmt ) ) // " %)" )
    268 
    269         CALL report('log_runtime', "(De-)Allocation: " // TRIM( real_to_str( t_alloc ) ) // &
    270                     " s  (" // TRIM( real_to_str( 100 * t_alloc / t_total, fmt ) ) // " %)" )
    271 
    272         CALL report('log_runtime', "Reading data:    " // TRIM( real_to_str( t_read ) )  // &
    273                     " s  (" // TRIM( real_to_str( 100 * t_read / t_total, fmt ) ) // " %)" )
    274 
    275         CALL report('log_runtime', "Writing data:    " // TRIM( real_to_str( t_write ) ) // &
    276                     " s  (" // TRIM( real_to_str( 100 * t_write / t_total, fmt ) ) // " %)" )
    277 
    278         CALL report('log_runtime', "Computation:     " // TRIM( real_to_str( t_comp ) )  // &
    279                     " s  (" // TRIM( real_to_str( 100 * t_comp / t_total, fmt) ) // " %)" )
    280 
    281         CALL report('log_runtime', "Total:           " // TRIM( real_to_str( t_total ) ) // &
    282                     " s  (" // TRIM( real_to_str( 100 * t_total / t_total, fmt ) ) // " %)")
     360        CALL report( 'log_runtime', "*** CPU time ***" )
     361
     362        CALL report( 'log_runtime', "Initialization:  " // TRIM( real_to_str( t_init ) ) // &
     363                     " s  (" // TRIM( real_to_str( 100 * t_init / t_total, fmt ) ) // " %)" )
     364
     365        CALL report( 'log_runtime', "(De-)Allocation: " // TRIM( real_to_str( t_alloc ) ) // &
     366                     " s  (" // TRIM( real_to_str( 100 * t_alloc / t_total, fmt ) ) // " %)" )
     367
     368        CALL report( 'log_runtime', "Reading data:    " // TRIM( real_to_str( t_read ) )  // &
     369                     " s  (" // TRIM( real_to_str( 100 * t_read / t_total, fmt ) ) // " %)" )
     370
     371        CALL report( 'log_runtime', "Writing data:    " // TRIM( real_to_str( t_write ) ) // &
     372                     " s  (" // TRIM( real_to_str( 100 * t_write / t_total, fmt ) ) // " %)" )
     373
     374        CALL report( 'log_runtime', "Computation:     " // TRIM( real_to_str( t_comp ) )  // &
     375                     " s  (" // TRIM( real_to_str( 100 * t_comp / t_total, fmt) ) // " %)" )
     376
     377        CALL report( 'log_runtime', "Total:           " // TRIM( real_to_str( t_total ) ) // &
     378                     " s  (" // TRIM( real_to_str( 100 * t_total / t_total, fmt ) ) // " %)" )
    283379
    284380    CASE DEFAULT
    285        CALL inifor_abort('log_runtime', "Mode '" // TRIM(mode) // "' is not supported.")
     381       CALL inifor_abort( 'log_runtime', "Mode '" // TRIM(mode) // "' is not supported." )
    286382
    287383    END SELECT
     
    289385 END SUBROUTINE log_runtime
    290386
     387
    291388 END MODULE inifor_control
  • palm/trunk/UTIL/inifor/src/inifor_defs.f90

    r4568 r4659  
    201201    ACHAR( 10 ) // ' Copyright 2017-2020 Deutscher Wetterdienst Offenbach' !< Copyright notice
    202202 CHARACTER(LEN=*), PARAMETER ::  LOG_FILE_NAME = 'inifor.log' !< Name of INIFOR's log file
    203  CHARACTER(LEN=*), PARAMETER ::  VERSION = '1.4.16'           !< INIFOR version number
     203 CHARACTER(LEN=*), PARAMETER ::  VERSION = '2.0.0'            !< INIFOR version number
    204204 
    205205 END MODULE inifor_defs
  • palm/trunk/UTIL/inifor/src/inifor_grid.f90

    r4568 r4659  
    2121! Current revisions:
    2222! -----------------
    23 ! 
    24 ! 
     23!
     24!
    2525! Former revisions:
    2626! -----------------
    2727! $Id$
     28! Only define netCDF variables in enabled IO groups
     29! Added cloud and precipitation quantiteis (cloud water, cloud ice, rain, snow
     30!    and graupel content, as well as surface forcings of rain, snow and graupel)
     31! Check for presence of precipitation files
     32! Removed unused code for deaccumulation of summed up and averaged fields
     33! Improved code formatting and documentation
     34!
     35!
     36! 4568 2020-06-19 11:56:30Z eckhard
    2837! Handle COSMO soil data with and without additional surface temperature
    2938! Imporved messaging
     
    180189               PIDS_ORIGIN_Z
    181190    USE inifor_io,                                                             &
    182         ONLY:  get_cosmo_grid, get_input_file_list, get_netcdf_attribute,      &
     191        ONLY:  file_is_present, get_cosmo_grid, get_input_file_list, get_netcdf_attribute,      &
    183192               get_netcdf_dim_vector, get_netcdf_variable, set_palm_origin,    &
    184                parse_command_line_arguments, validate_config,                  &
     193               netcdf_variable_present_in_file, parse_command_line_arguments, validate_config,                  &
    185194               has_surface_value
    186195    USE inifor_transform,                                                      &
     
    287296    INTEGER(iwp) ::  nlev  !< number of levels in target grid (COSMO-DE)
    288297    INTEGER(iwp) ::  ndepths !< number of COSMO-DE soil layers
    289     INTEGER(iwp) ::  start_hour_flow         !< start of flow forcing in number of hours relative to start_date
    290     INTEGER(iwp) ::  start_hour_soil         !< start of soil forcing in number of hours relative to start_date, typically equals start_hour_flow
    291     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
    292     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)
     298    INTEGER(iwp) ::  start_hour_flow          !< start of flow forcing in number of hours relative to start_date
     299    INTEGER(iwp) ::  start_hour_soil          !< start of soil forcing in number of hours relative to start_date, typically equals start_hour_flow
     300    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
     301    INTEGER(iwp) ::  start_hour_precipitation !< start of forcing for precipitaiton forcing in number of hours relative to start_date
    293302    INTEGER(iwp) ::  end_hour  !< simulation time in hours
    294     INTEGER(iwp) ::  end_hour_soilmoisture  !< end of soil moisture spin-up in hours relative to start_hour_flow
    295303    INTEGER(iwp) ::  step_hour !< number of hours between forcing time steps
    296304
     
    372380    CHARACTER(LEN=LNAME) ::  nc_source_text = ''  !< Text describing the source of the output data, e.g. 'COSMO-DE analysis from ...'
    373381
    374     CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  flow_files          !< list of atmospheric input files (<prefix>YYYYMMDDHH-flow.nc)
    375     CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  soil_moisture_files !< list of precipitation input files (<prefix>YYYYMMDDHH-soilmoisture.nc)
    376     CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  soil_files          !< list of soil input files (temperature, moisture, <prefix>YYYYMMDDHH-soil.nc)
    377     CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  radiation_files     !< list of radiation input files (<prefix>YYYYMMDDHH-rad.nc)
    378 
    379     CHARACTER(LEN=SNAME) ::  input_prefix         !< prefix of input files, e.g. 'laf' for COSMO-DE analyses
    380     CHARACTER(LEN=SNAME) ::  flow_prefix          !< prefix of flow input files, e.g. 'laf' for COSMO-DE analyses
    381     CHARACTER(LEN=SNAME) ::  soil_prefix          !< prefix of soil input files, e.g. 'laf' for COSMO-DE analyses
    382     CHARACTER(LEN=SNAME) ::  radiation_prefix     !< prefix of radiation input files, e.g. 'laf' for COSMO-DE analyses
    383     CHARACTER(LEN=SNAME) ::  soilmoisture_prefix  !< prefix of input files for soil moisture spin-up, e.g. 'laf' for COSMO-DE analyses
    384     CHARACTER(LEN=SNAME) ::  flow_suffix          !< suffix of flow input files, e.g. 'flow'
    385     CHARACTER(LEN=SNAME) ::  soil_suffix          !< suffix of soil input files, e.g. 'soil'
    386     CHARACTER(LEN=SNAME) ::  radiation_suffix     !< suffix of radiation input files, e.g. 'radiation'
    387     CHARACTER(LEN=SNAME) ::  soilmoisture_suffix  !< suffix of input files for soil moisture spin-up, e.g. 'soilmoisture'
     382    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  flow_files      !< list of atmospheric input files (<prefix>YYYYMMDDHH-flow.nc)
     383    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  precip_files    !< list of precipitation input files (<prefix>YYYYMMDDHH-precip.nc)
     384    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  soil_files      !< list of soil input files (temperature, moisture, <prefix>YYYYMMDDHH-soil.nc)
     385    CHARACTER(LEN=PATH), ALLOCATABLE, DIMENSION(:) ::  radiation_files !< list of radiation input files (<prefix>YYYYMMDDHH-rad.nc)
     386
     387    CHARACTER(LEN=SNAME) ::  input_prefix          !< prefix of input files, e.g. 'laf' for COSMO-DE analyses
     388    CHARACTER(LEN=SNAME) ::  flow_prefix           !< prefix of flow input files, e.g. 'laf' for COSMO-DE analyses
     389    CHARACTER(LEN=SNAME) ::  soil_prefix           !< prefix of soil input files, e.g. 'laf' for COSMO-DE analyses
     390    CHARACTER(LEN=SNAME) ::  radiation_prefix      !< prefix of radiation input files, e.g. 'laf' for COSMO-DE analyses
     391    CHARACTER(LEN=SNAME) ::  precipitation_prefix  !< prefix of input files for precipitation forcing, e.g. 'laf' for COSMO-DE analyses
     392    CHARACTER(LEN=SNAME) ::  flow_suffix           !< suffix of flow input files, e.g. 'flow'
     393    CHARACTER(LEN=SNAME) ::  soil_suffix           !< suffix of soil input files, e.g. 'soil'
     394    CHARACTER(LEN=SNAME) ::  radiation_suffix      !< suffix of radiation input files, e.g. 'radiation'
     395    CHARACTER(LEN=SNAME) ::  precipitation_suffix  !< suffix of input files for precipition forcing, e.g. 'precip'
    388396                         
    389397    TYPE(nc_file) ::  output_file !< metadata of the dynamic driver
     
    408416!------------------------------------------------------------------------------
    409417    cfg%start_date = '2013072100'
    410     end_hour = 2
    411     start_hour_soil = -2
    412     start_hour_soilmoisture = - (4 * 7 * 24) - 2
    413418
    414419!
     
    429434    start_hour_soil = 0
    430435    start_hour_radiation = 0
    431     start_hour_soilmoisture = start_hour_flow - 2
    432     end_hour_soilmoisture = start_hour_flow
     436    start_hour_precipitation = start_hour_flow
    433437    step_hour = FORCING_STEP
    434438
     
    438442    cfg%soil_prefix = input_prefix
    439443    cfg%radiation_prefix = input_prefix
    440     cfg%soilmoisture_prefix  = input_prefix
     444    cfg%precipitation_prefix  = input_prefix
    441445
    442446    flow_suffix = '-flow'
    443447    soil_suffix = '-soil'
    444448    radiation_suffix = '-rad'
    445     soilmoisture_suffix = '-soilmoisture'
     449    precipitation_suffix = '-precip'
    446450
    447451    cfg%debug = .FALSE.
     
    472476    radiation_prefix = TRIM(cfg%input_prefix)
    473477    soil_prefix = TRIM(cfg%input_prefix)
    474     soilmoisture_prefix = TRIM(cfg%input_prefix)
     478    precipitation_prefix = TRIM(cfg%input_prefix)
    475479    IF (cfg%flow_prefix_is_set)  flow_prefix = TRIM(cfg%flow_prefix)
    476480    IF (cfg%radiation_prefix_is_set)  radiation_prefix = TRIM(cfg%radiation_prefix)
    477481    IF (cfg%soil_prefix_is_set)  soil_prefix = TRIM(cfg%soil_prefix)
    478     IF (cfg%soilmoisture_prefix_is_set)  soilmoisture_prefix = TRIM(cfg%soilmoisture_prefix)
     482    IF (cfg%precipitation_prefix_is_set)  precipitation_prefix = TRIM(cfg%precipitation_prefix)
    479483
    480484    output_file%name = cfg%output_file
     
    483487    boundary_variables_required = TRIM( cfg%bc_mode ) == 'real'
    484488    ls_forcing_variables_required = TRIM( cfg%bc_mode ) == 'ideal'
    485     surface_forcing_required = .FALSE.
     489    surface_forcing_required = .TRUE.
    486490
    487491    IF ( ls_forcing_variables_required )  THEN
     
    502506    CALL report('setup_parameters', "       forcing mode: " // TRIM(cfg%bc_mode))
    503507    CALL report('setup_parameters', "     averaging mode: " // TRIM(cfg%averaging_mode))
     508    CALL report('setup_parameters', "    averaging angle: " // real_to_str(cfg%averaging_angle))
    504509    CALL report('setup_parameters', "    averaging angle: " // real_to_str(cfg%averaging_angle))
    505510    CALL report('setup_parameters', "          data path: " // TRIM(cfg%input_path))
     
    508513    CALL report('setup_parameters', "      namelist file: " // TRIM(cfg%namelist_file))
    509514    CALL report('setup_parameters', "   output data file: " // TRIM(output_file%name))
     515    IF (cfg%process_precipitation )  THEN
     516        CALL report('setup_parameters', "      precipitation: enabled")
     517    ELSE
     518        CALL report('setup_parameters', "      precipitation: disabled")
     519    ENDIF
    510520    IF (cfg%debug )  CALL report('setup_parameters', "     debugging mode: enabled")
    511521
     
    543553!
    544554!-- Generate input file lists
    545     CALL get_input_file_list(                                               &
    546        cfg%start_date, start_hour_flow, end_hour, step_hour,              &
     555    CALL get_input_file_list(                                                  &
     556       cfg%start_date, start_hour_flow, end_hour, step_hour,                   &
    547557       cfg%input_path, flow_prefix, flow_suffix, flow_files)
    548     CALL get_input_file_list(                                               &
    549        cfg%start_date, start_hour_soil, end_hour, step_hour,              &
     558    CALL get_input_file_list(                                                  &
     559       cfg%start_date, start_hour_soil, end_hour, step_hour,                   &
    550560       cfg%input_path, soil_prefix, soil_suffix, soil_files)
    551     CALL get_input_file_list(                                               &
    552        cfg%start_date, start_hour_radiation, end_hour, step_hour,         &
    553        cfg%input_path, radiation_prefix, radiation_suffix, radiation_files, nocheck=.TRUE.)
    554     CALL get_input_file_list(                                               &
    555        cfg%start_date, start_hour_soilmoisture, end_hour_soilmoisture, step_hour, &
    556        cfg%input_path, soilmoisture_prefix, soilmoisture_suffix, soil_moisture_files, nocheck=.TRUE.)
     561    CALL get_input_file_list(                                                  &
     562       cfg%start_date, start_hour_radiation, end_hour, step_hour,              &
     563       cfg%input_path, radiation_prefix, radiation_suffix, radiation_files)
     564    CALL get_input_file_list(                                                  &
     565       cfg%start_date, start_hour_flow, end_hour, step_hour,                  &
     566       cfg%input_path, precipitation_prefix, precipitation_suffix, precip_files )
    557567
    558568!
     
    21372147    INTEGER(iwp) ::  ngroups
    21382148
    2139     ngroups = 16
     2149    ngroups = 17
    21402150    ALLOCATE( io_group_list(ngroups) )
    21412151
     
    22142224!-- rain
    22152225    io_group_list(8) = init_io_group(                                       &
    2216        in_files = soil_moisture_files,                                      &
     2226       in_files = precip_files,                                      &
    22172227       out_vars = output_var_table(33:33),                                  &
    22182228       in_var_list = input_var_table(8:8),                                  &
    2219        kind = 'accumulated'                                                 &
    2220     )
    2221     io_group_list(8)%to_be_processed = .FALSE.
     2229       kind = 'surface'                                                     &
     2230    )
     2231    io_group_list(8)%to_be_processed = cfg%process_precipitation
    22222232!
    22232233!-- snow
    22242234    io_group_list(9) = init_io_group(                                       &
    2225        in_files = soil_moisture_files,                                      &
     2235       in_files = precip_files,                                      &
    22262236       out_vars = output_var_table(34:34),                                  &
    22272237       in_var_list = input_var_table(9:9),                                  &
    2228        kind = 'accumulated'                                                 &
    2229     )
    2230     io_group_list(9)%to_be_processed = .FALSE.
     2238       kind = 'surface'                                                     &
     2239    )
     2240    io_group_list(9)%to_be_processed = cfg%process_precipitation
    22312241!
    22322242!-- graupel
    22332243    io_group_list(10) = init_io_group(                                      &
    2234        in_files = soil_moisture_files,                                      &
     2244       in_files = precip_files,                                      &
    22352245       out_vars = output_var_table(35:35),                                  &
    22362246       in_var_list = input_var_table(10:10),                                &
    2237        kind = 'accumulated'                                                 &
    2238     )
    2239     io_group_list(10)%to_be_processed = .FALSE.
     2247       kind = 'surface'                                                     &
     2248    )
     2249    io_group_list(10)%to_be_processed = cfg%process_precipitation
    22402250!
    22412251!-- evapotranspiration
    22422252    io_group_list(11) = init_io_group(                                      &
    2243        in_files = soil_moisture_files,                                      &
     2253       in_files = precip_files,                                      &
    22442254       out_vars = output_var_table(37:37),                                  &
    22452255       in_var_list = input_var_table(11:11),                                &
     
    22502260!-- 2m air temperature
    22512261    io_group_list(12) = init_io_group(                                      &
    2252        in_files = soil_moisture_files,                                      &
     2262       in_files = precip_files,                                      &
    22532263       out_vars = output_var_table(36:36),                                  &
    22542264       in_var_list = input_var_table(12:12),                                &
     
    22932303    io_group_list(16)%to_be_processed = .FALSE.
    22942304
     2305!-- fog and cloud water
     2306    io_group_list(17) = init_io_group(                                      &
     2307       in_files = flow_files,                                               &
     2308       out_vars = output_var_table(65:94),                                  & !qc, qi, qr, qs, qg
     2309       in_var_list = input_var_table(11:15),                                & !QC, QI, QR, QS, QG
     2310       kind = 'scalar'                                                      &
     2311    )
     2312    io_group_list(17)%to_be_processed = .TRUE.
     2313
     2314    CALL validate_io_groups( io_group_list )
     2315
    22952316 END SUBROUTINE setup_io_groups
     2317
     2318
     2319 SUBROUTINE validate_io_groups( io_group_list )
     2320    TYPE(io_group), TARGET, INTENT(INOUT) ::  io_group_list(:)
     2321
     2322    INTEGER(iwp)                 ::  group_idx, file_idx, outvar_idx
     2323    TYPE(io_group), POINTER      ::  group
     2324    CHARACTER(LEN=PATH), POINTER ::  filename
     2325    TYPE(nc_var), POINTER        ::  outvar, invar
     2326
     2327    DO group_idx = 1, SIZE( io_group_list )
     2328       group => io_group_list(group_idx)
     2329
     2330       IF (group%to_be_processed)  THEN
     2331          DO file_idx = 1, SIZE( group%in_files )
     2332             filename => group%in_files(file_idx)
     2333
     2334             IF (.NOT. file_is_present( filename, 'input', message ))  THEN
     2335                IF (group%is_optional)  THEN
     2336
     2337!--                deactivate group, warn and continue
     2338                   group%to_be_processed = .FALSE.
     2339                   message = "Optional IO group '" // TRIM( group%kind ) // "' was deactivated" // &
     2340                      " because the required file '" // TRIM( filename ) // "' was not found."
     2341                   CALL warn( 'validate_io_groups', message )
     2342                ELSE
     2343!--                abort due to missing input file
     2344                   message = "The input file '" // TRIM( filename ) // "' of the" // &
     2345                      " mandatory IO group '" // TRIM( group%kind ) // "' was not found."
     2346                   CALL inifor_abort( 'validate_io_groups', message  )
     2347                ENDIF
     2348             ELSE
     2349                message = "Set up input file name '" // TRIM(filename) // "'"
     2350                CALL report('verify_file', message)
     2351             ENDIF
     2352
     2353          ENDDO
     2354       
     2355!--       deactivate all optional output variables that have missing inputs
     2356          DO outvar_idx = 1, SIZE(group%out_vars)
     2357             outvar => group%out_vars(outvar_idx)
     2358
     2359             IF (outvar%is_optional)  THEN
     2360
     2361!--             only check first input file, assuming files at later times have the
     2362!--             same contents
     2363                filename => group%in_files(LBOUND( group%in_files, 1))
     2364                invar => group%in_var_list(outvar%input_id)
     2365
     2366!--             if corresponding invar not present, deactivate output_var
     2367                IF ( .NOT.netcdf_variable_present_in_file( invar%name, filename ) )  THEN
     2368                      ! deactivate output variable variable, warn and continue
     2369                      invar%to_be_processed = .FALSE.
     2370                      outvar%to_be_processed = .FALSE.
     2371                      message = "Optional output variable '" // TRIM( outvar%name ) // "' was deactivated" // &
     2372                         " because the corresponding input variable was not found in file '" // TRIM( filename ) // "'."
     2373                      CALL warn( 'validate_io_groups', message )
     2374                ENDIF
     2375             ENDIF
     2376
     2377             !IF ( .NOT.netcdf_variable_present_in_file( invar%name, filename ) )  THEN
     2378!--          !      abort due to missing input variable
     2379             !      message = "The mandatory input variable '" // TRIM( invar%name ) // &
     2380             !         " was not found in the input file '" // TRIM( filename ) // "'."
     2381             !      CALL inifor_abort( 'validate_io_groups', message  )
     2382             !   ENDIF
     2383             !IF ( .NOT.netcdf_variable_present_in_file( invar%name, filename ) )  THEN
     2384!--          !      abort due to missing input variable
     2385             !      message = "The mandatory input variable '" // TRIM( invar%name ) // &
     2386             !         " was not found in the input file '" // TRIM( filename ) // "'."
     2387             !      CALL inifor_abort( 'validate_io_groups', message  )
     2388             !   ENDIF
     2389             !ENDIF
     2390!--       outvar loop
     2391          ENDDO
     2392
     2393!--   group%to_be_processed conditional
     2394      ENDIF
     2395
     2396!-- groups loop
     2397    ENDDO
     2398   
     2399 END SUBROUTINE validate_io_groups
     2400
    22962401
    22972402
     
    23072412!> on the output quantity Theta.
    23082413!------------------------------------------------------------------------------!
    2309  FUNCTION init_io_group(in_files, out_vars, in_var_list, kind,              &
     2414 FUNCTION init_io_group(in_files, out_vars, in_var_list, kind,                 &
    23102415                        n_output_quantities) RESULT(group)
    23112416    CHARACTER(LEN=PATH), INTENT(IN) ::  in_files(:)
     
    23212426    group%n_inputs = SIZE(in_var_list)
    23222427    group%kind = TRIM(kind)
    2323 !
    2324 !-- For the 'thermodynamics' IO group, one quantity more than input variables
    2325 !-- is needed to compute all output variables of the IO group. Concretely, in
    2326 !-- preprocess() the density is computed from T,P or PP,QV in adddition to
    2327 !-- the variables Theta, p, qv. In read_input_variables(),
    2328 !-- n_output_quantities is used to allocate the correct number of input
    2329 !-- buffers.
    2330     IF ( PRESENT(n_output_quantities) )  THEN
     2428
     2429!
     2430!-- Set the number of output quantities, which is used to allocate input buffers
     2431!-- in the preprocess() routine. For passive scalars, there is a one-to-one
     2432!-- correspondance of input and output quantities. For instance, for every water
     2433!-- phase input variable (e.g. cloud water QC), there is a corresponding output
     2434!-- quantity (qc, which lead to a number of output netCDF variables:
     2435!-- init_atmosphere_qc, ls_forcing_left_qc, etc.)
     2436!--     If more output quantities than input quantities are to be produced,
     2437!-- n_output_quantities can be set through the optional subroutine parameter.
     2438!-- For the 'thermodynamics' IO group, one quantity more than input variables is
     2439!-- needed to compute all output variables of the IO group.  Concretely, in
     2440!-- preprocess() the density is computed from T,P or PP,QV in adddition to the
     2441!-- variables Theta, p, qv. In read_input_variables(), n_output_quantities is
     2442!-- used to allocate the correct number of input buffers.
     2443
     2444    IF  ( PRESENT(n_output_quantities) )  THEN
    23312445       group%n_output_quantities = n_output_quantities
    23322446    ELSE
     
    23932507
    23942508    n_invar = 17
    2395     n_outvar = 64
     2509    n_outvar = 94
    23962510    ALLOCATE( input_var_table(n_invar) )
    23972511    ALLOCATE( output_var_table(n_outvar) )
     
    24612575
    24622576    var => input_var_table(11)
    2463     var%name = 'AEVAP_S'
     2577    var%name = 'QC'
    24642578    var%to_be_processed = .TRUE.
    2465     var%is_upside_down = .FALSE.
     2579    var%is_upside_down = .TRUE.
    24662580
    24672581    var => input_var_table(12)
    2468     var%name = 'T_2M'
     2582    var%name = 'QI'
    24692583    var%to_be_processed = .TRUE.
    2470     var%is_upside_down = .FALSE.
     2584    var%is_upside_down = .TRUE.
    24712585
    24722586    var => input_var_table(13)
    2473     var%name = 'ASWDIFD_S'
     2587    var%name = 'QR'
    24742588    var%to_be_processed = .TRUE.
    2475     var%is_upside_down = .FALSE.
     2589    var%is_upside_down = .TRUE.
    24762590
    24772591    var => input_var_table(14)
    2478     var%name = 'ASWDIR_S'
     2592    var%name = 'QS'
    24792593    var%to_be_processed = .TRUE.
    2480     var%is_upside_down = .FALSE.
     2594    var%is_upside_down = .TRUE.
    24812595
    24822596    var => input_var_table(15)
    2483     var%name = 'ASOB_S'
     2597    var%name = 'QG'
    24842598    var%to_be_processed = .TRUE.
    2485     var%is_upside_down = .FALSE.
     2599    var%is_upside_down = .TRUE.
    24862600
    24872601    var => input_var_table(16)
    2488     var%name = 'ATHB_S'
    2489     var%to_be_processed = .TRUE.
     2602    var%name = '--'
     2603    var%to_be_processed = .FALSE.
    24902604    var%is_upside_down = .FALSE.
    24912605
     
    33323446    output_var_table(64)%averaging_grid => west_averaged_scalar_profile
    33333447    output_var_table(64)%to_be_processed = .NOT. cfg%ug_defined_by_user
     3448
     3449    output_var_table(65) = init_nc_var(                                      &
     3450       name              = 'init_atmosphere_qc',                            &
     3451       std_name          = "",                                              &
     3452       long_name         = "initial cloud water mixture fraction",          &
     3453       units             = "kg/kg",                                         &
     3454       kind              = "init scalar",                                   &
     3455       input_id          = 1_iwp,                                           &
     3456       output_file       = output_file,                                     &
     3457       grid              = palm_grid,                                       &
     3458       intermediate_grid = palm_intermediate,                               &
     3459       is_profile = (TRIM(ic_mode) == 'profile')                            &
     3460    )
     3461    IF (TRIM(ic_mode) == 'profile')  THEN
     3462       output_var_table(65)%averaging_grid => averaged_initial_scalar_profile
     3463    ENDIF
     3464    output_var_table(65)%is_optional = .TRUE.
     3465
     3466    output_var_table(66) = init_nc_var(                                     &
     3467       name              = 'ls_forcing_left_qc',                            &
     3468       std_name          = "",                                              &
     3469       long_name         = "large-scale forcing for left model boundary for the cloud water mixture fraction", &
     3470       units             = "kg/kg",                                         &
     3471       kind              = "left scalar",                                   &
     3472       input_id          = 1_iwp,                                           &
     3473       output_file       = output_file,                                     &
     3474       grid              = scalars_west_grid,                               &
     3475       intermediate_grid = scalars_west_intermediate                        &
     3476    )
     3477    output_var_table(66)%is_optional = .TRUE.
     3478
     3479    output_var_table(67) = init_nc_var(                                     &
     3480       name              = 'ls_forcing_right_qc',                           &
     3481       std_name          = "",                                              &
     3482       long_name         = "large-scale forcing for right model boundary for the cloud water mixture fraction", &
     3483       units             = "kg/kg",                                         &
     3484       kind              = "right scalar",                                  &
     3485       input_id          = 1_iwp,                                           &
     3486       output_file       = output_file,                                     &
     3487       grid              = scalars_east_grid,                               &
     3488       intermediate_grid = scalars_east_intermediate                        &
     3489    )
     3490    output_var_table(67)%is_optional = .TRUE.
     3491
     3492    output_var_table(68) = init_nc_var(                                     &
     3493       name              = 'ls_forcing_north_qc',                           &
     3494       std_name          = "",                                              &
     3495       long_name         = "large-scale forcing for north model boundary for the cloud water mixture fraction", &
     3496       units             = "kg/kg",                                         &
     3497       kind              = "north scalar",                                  &
     3498       input_id          = 1_iwp,                                           &
     3499       output_file       = output_file,                                     &
     3500       grid              = scalars_north_grid,                              &
     3501       intermediate_grid = scalars_north_intermediate                       &
     3502    )
     3503    output_var_table(68)%is_optional = .TRUE.
     3504
     3505    output_var_table(69) = init_nc_var(                                     &
     3506       name              = 'ls_forcing_south_qc',                           &
     3507       std_name          = "",                                              &
     3508       long_name         = "large-scale forcing for south model boundary for the cloud water mixture fraction", &
     3509       units             = "kg/kg",                                         &
     3510       kind              = "south scalar",                                  &
     3511       input_id          = 1_iwp,                                           &
     3512       output_file       = output_file,                                     &
     3513       grid              = scalars_south_grid,                              &
     3514       intermediate_grid = scalars_south_intermediate                       &
     3515    )
     3516    output_var_table(69)%is_optional = .TRUE.
     3517
     3518    output_var_table(70) = init_nc_var(                                     &
     3519       name              = 'ls_forcing_top_qc',                             &
     3520       std_name          = "",                                              &
     3521       long_name         = "large-scale forcing for top model boundary for the cloud water mixture fraction", &
     3522       units             = "kg/kg",                                         &
     3523       kind              = "top scalar",                                    &
     3524       input_id          = 1_iwp,                                           &
     3525       output_file       = output_file,                                     &
     3526       grid              = scalars_top_grid,                                &
     3527       intermediate_grid = scalars_top_intermediate                         &
     3528    )
     3529    output_var_table(70)%is_optional = .TRUE.
     3530
     3531    output_var_table(71) = init_nc_var(                                     &
     3532       name              = 'init_atmosphere_qi',                            &
     3533       std_name          = "",                                              &
     3534       long_name         = "initial cloud ice mixture fraction",            &
     3535       units             = "kg/kg",                                         &
     3536       kind              = "init scalar",                                   &
     3537       input_id          = 2_iwp,                                           &
     3538       output_file       = output_file,                                     &
     3539       grid              = palm_grid,                                       &
     3540       intermediate_grid = palm_intermediate,                               &
     3541       is_profile = (TRIM(ic_mode) == 'profile')                            &
     3542    )
     3543    IF (TRIM(ic_mode) == 'profile')  THEN
     3544       output_var_table(71)%averaging_grid => averaged_initial_scalar_profile
     3545    ENDIF
     3546    output_var_table(71)%is_optional = .TRUE.
     3547
     3548    output_var_table(72) = init_nc_var(                                     &
     3549       name              = 'ls_forcing_left_qi',                            &
     3550       std_name          = "",                                              &
     3551       long_name         = "large-scale forcing for left model boundary for the cloud ice mixture fraction", &
     3552       units             = "kg/kg",                                         &
     3553       kind              = "left scalar",                                   &
     3554       input_id          = 2_iwp,                                           &
     3555       output_file       = output_file,                                     &
     3556       grid              = scalars_west_grid,                               &
     3557       intermediate_grid = scalars_west_intermediate                        &
     3558    )
     3559    output_var_table(72)%is_optional = .TRUE.
     3560
     3561    output_var_table(73) = init_nc_var(                                     &
     3562       name              = 'ls_forcing_right_qi',                           &
     3563       std_name          = "",                                              &
     3564       long_name         = "large-scale forcing for right model boundary for the cloud ice mixture fraction", &
     3565       units             = "kg/kg",                                         &
     3566       kind              = "right scalar",                                  &
     3567       input_id          = 2_iwp,                                           &
     3568       output_file       = output_file,                                     &
     3569       grid              = scalars_east_grid,                               &
     3570       intermediate_grid = scalars_east_intermediate                        &
     3571    )
     3572    output_var_table(73)%is_optional = .TRUE.
     3573
     3574    output_var_table(74) = init_nc_var(                                     &
     3575       name              = 'ls_forcing_north_qi',                           &
     3576       std_name          = "",                                              &
     3577       long_name         = "large-scale forcing for north model boundary for the cloud ice mixture fraction", &
     3578       units             = "kg/kg",                                         &
     3579       kind              = "north scalar",                                  &
     3580       input_id          = 2_iwp,                                           &
     3581       output_file       = output_file,                                     &
     3582       grid              = scalars_north_grid,                              &
     3583       intermediate_grid = scalars_north_intermediate                       &
     3584    )
     3585    output_var_table(74)%is_optional = .TRUE.
     3586
     3587    output_var_table(75) = init_nc_var(                                     &
     3588       name              = 'ls_forcing_south_qi',                           &
     3589       std_name          = "",                                              &
     3590       long_name         = "large-scale forcing for south model boundary for the cloud ice mixture fraction", &
     3591       units             = "kg/kg",                                         &
     3592       kind              = "south scalar",                                  &
     3593       input_id          = 2_iwp,                                           &
     3594       output_file       = output_file,                                     &
     3595       grid              = scalars_south_grid,                              &
     3596       intermediate_grid = scalars_south_intermediate                       &
     3597    )
     3598    output_var_table(75)%is_optional = .TRUE.
     3599
     3600    output_var_table(76) = init_nc_var(                                     &
     3601       name              = 'ls_forcing_top_qi',                             &
     3602       std_name          = "",                                              &
     3603       long_name         = "large-scale forcing for top model boundary for the cloud ice mixture fraction", &
     3604       units             = "kg/kg",                                         &
     3605       kind              = "top scalar",                                    &
     3606       input_id          = 2_iwp,                                           &
     3607       output_file       = output_file,                                     &
     3608       grid              = scalars_top_grid,                                &
     3609       intermediate_grid = scalars_top_intermediate                         &
     3610    )
     3611    output_var_table(76)%is_optional = .TRUE.
     3612
     3613    output_var_table(77) = init_nc_var(                                     &
     3614       name              = 'init_atmosphere_qr',                            &
     3615       std_name          = "",                                              &
     3616       long_name         = "initial rain water mixture fraction",            &
     3617       units             = "kg/kg",                                         &
     3618       kind              = "init scalar",                                   &
     3619       input_id          = 3_iwp,                                           &
     3620       output_file       = output_file,                                     &
     3621       grid              = palm_grid,                                       &
     3622       intermediate_grid = palm_intermediate,                               &
     3623       is_profile = (TRIM(ic_mode) == 'profile')                            &
     3624    )
     3625    IF (TRIM(ic_mode) == 'profile')  THEN
     3626       output_var_table(77)%averaging_grid => averaged_initial_scalar_profile
     3627    ENDIF
     3628    output_var_table(77)%is_optional = .TRUE.
     3629
     3630    output_var_table(78) = init_nc_var(                                     &
     3631       name              = 'ls_forcing_left_qr',                            &
     3632       std_name          = "",                                              &
     3633       long_name         = "large-scale forcing for left model boundary for the rain water mixture fraction", &
     3634       units             = "kg/kg",                                         &
     3635       kind              = "left scalar",                                   &
     3636       input_id          = 3_iwp,                                           &
     3637       output_file       = output_file,                                     &
     3638       grid              = scalars_west_grid,                               &
     3639       intermediate_grid = scalars_west_intermediate                        &
     3640    )
     3641    output_var_table(78)%is_optional = .TRUE.
     3642
     3643    output_var_table(79) = init_nc_var(                                     &
     3644       name              = 'ls_forcing_right_qr',                           &
     3645       std_name          = "",                                              &
     3646       long_name         = "large-scale forcing for right model boundary for the rain water mixture fraction", &
     3647       units             = "kg/kg",                                         &
     3648       kind              = "right scalar",                                  &
     3649       input_id          = 3_iwp,                                           &
     3650       output_file       = output_file,                                     &
     3651       grid              = scalars_east_grid,                               &
     3652       intermediate_grid = scalars_east_intermediate                        &
     3653    )
     3654    output_var_table(79)%is_optional = .TRUE.
     3655
     3656    output_var_table(80) = init_nc_var(                                     &
     3657       name              = 'ls_forcing_north_qr',                           &
     3658       std_name          = "",                                              &
     3659       long_name         = "large-scale forcing for north model boundary for the rain water mixture fraction", &
     3660       units             = "kg/kg",                                         &
     3661       kind              = "north scalar",                                  &
     3662       input_id          = 3_iwp,                                           &
     3663       output_file       = output_file,                                     &
     3664       grid              = scalars_north_grid,                              &
     3665       intermediate_grid = scalars_north_intermediate                       &
     3666    )
     3667    output_var_table(80)%is_optional = .TRUE.
     3668
     3669    output_var_table(81) = init_nc_var(                                     &
     3670       name              = 'ls_forcing_south_qr',                           &
     3671       std_name          = "",                                              &
     3672       long_name         = "large-scale forcing for south model boundary for the rain water mixture fraction", &
     3673       units             = "kg/kg",                                         &
     3674       kind              = "south scalar",                                  &
     3675       input_id          = 3_iwp,                                           &
     3676       output_file       = output_file,                                     &
     3677       grid              = scalars_south_grid,                              &
     3678       intermediate_grid = scalars_south_intermediate                       &
     3679    )
     3680    output_var_table(81)%is_optional = .TRUE.
     3681
     3682    output_var_table(82) = init_nc_var(                                     &
     3683       name              = 'ls_forcing_top_qr',                             &
     3684       std_name          = "",                                              &
     3685       long_name         = "large-scale forcing for top model boundary for the rain water mixture fraction", &
     3686       units             = "kg/kg",                                         &
     3687       kind              = "top scalar",                                    &
     3688       input_id          = 3_iwp,                                           &
     3689       output_file       = output_file,                                     &
     3690       grid              = scalars_top_grid,                                &
     3691       intermediate_grid = scalars_top_intermediate                         &
     3692    )
     3693    output_var_table(82)%is_optional = .TRUE.
     3694
     3695    output_var_table(83) = init_nc_var(                                     &
     3696       name              = 'init_atmosphere_qs',                            &
     3697       std_name          = "",                                              &
     3698       long_name         = "initial snow mixture fraction",            &
     3699       units             = "kg/kg",                                         &
     3700       kind              = "init scalar",                                   &
     3701       input_id          = 4_iwp,                                           &
     3702       output_file       = output_file,                                     &
     3703       grid              = palm_grid,                                       &
     3704       intermediate_grid = palm_intermediate,                               &
     3705       is_profile = (TRIM(ic_mode) == 'profile')                            &
     3706    )
     3707    IF (TRIM(ic_mode) == 'profile')  THEN
     3708       output_var_table(83)%averaging_grid => averaged_initial_scalar_profile
     3709    ENDIF
     3710    output_var_table(83)%is_optional = .TRUE.
     3711
     3712    output_var_table(84) = init_nc_var(                                     &
     3713       name              = 'ls_forcing_left_qs',                            &
     3714       std_name          = "",                                              &
     3715       long_name         = "large-scale forcing for left model boundary for the snow mixture fraction", &
     3716       units             = "kg/kg",                                         &
     3717       kind              = "left scalar",                                   &
     3718       input_id          = 4_iwp,                                           &
     3719       output_file       = output_file,                                     &
     3720       grid              = scalars_west_grid,                               &
     3721       intermediate_grid = scalars_west_intermediate                        &
     3722    )
     3723    output_var_table(84)%is_optional = .TRUE.
     3724
     3725    output_var_table(85) = init_nc_var(                                     &
     3726       name              = 'ls_forcing_right_qs',                           &
     3727       std_name          = "",                                              &
     3728       long_name         = "large-scale forcing for right model boundary for the snow mixture fraction", &
     3729       units             = "kg/kg",                                         &
     3730       kind              = "right scalar",                                  &
     3731       input_id          = 4_iwp,                                           &
     3732       output_file       = output_file,                                     &
     3733       grid              = scalars_east_grid,                               &
     3734       intermediate_grid = scalars_east_intermediate                        &
     3735    )
     3736    output_var_table(85)%is_optional = .TRUE.
     3737
     3738    output_var_table(86) = init_nc_var(                                     &
     3739       name              = 'ls_forcing_north_qs',                           &
     3740       std_name          = "",                                              &
     3741       long_name         = "large-scale forcing for north model boundary for the snow mixture fraction", &
     3742       units             = "kg/kg",                                         &
     3743       kind              = "north scalar",                                  &
     3744       input_id          = 4_iwp,                                           &
     3745       output_file       = output_file,                                     &
     3746       grid              = scalars_north_grid,                              &
     3747       intermediate_grid = scalars_north_intermediate                       &
     3748    )
     3749    output_var_table(86)%is_optional = .TRUE.
     3750
     3751    output_var_table(87) = init_nc_var(                                     &
     3752       name              = 'ls_forcing_south_qs',                           &
     3753       std_name          = "",                                              &
     3754       long_name         = "large-scale forcing for south model boundary for the snow mixture fraction", &
     3755       units             = "kg/kg",                                         &
     3756       kind              = "south scalar",                                  &
     3757       input_id          = 4_iwp,                                           &
     3758       output_file       = output_file,                                     &
     3759       grid              = scalars_south_grid,                              &
     3760       intermediate_grid = scalars_south_intermediate                       &
     3761    )
     3762    output_var_table(87)%is_optional = .TRUE.
     3763
     3764    output_var_table(88) = init_nc_var(                                     &
     3765       name              = 'ls_forcing_top_qs',                             &
     3766       std_name          = "",                                              &
     3767       long_name         = "large-scale forcing for top model boundary for the snow mixture fraction", &
     3768       units             = "kg/kg",                                         &
     3769       kind              = "top scalar",                                    &
     3770       input_id          = 4_iwp,                                           &
     3771       output_file       = output_file,                                     &
     3772       grid              = scalars_top_grid,                                &
     3773       intermediate_grid = scalars_top_intermediate                         &
     3774    )
     3775    output_var_table(88)%is_optional = .TRUE.
     3776
     3777    output_var_table(89) = init_nc_var(                                     &
     3778       name              = 'init_atmosphere_qg',                            &
     3779       std_name          = "",                                              &
     3780       long_name         = "initial graupel mixture fraction",            &
     3781       units             = "kg/kg",                                         &
     3782       kind              = "init scalar",                                   &
     3783       input_id          = 5_iwp,                                           &
     3784       output_file       = output_file,                                     &
     3785       grid              = palm_grid,                                       &
     3786       intermediate_grid = palm_intermediate,                               &
     3787       is_profile = (TRIM(ic_mode) == 'profile')                            &
     3788    )
     3789    IF (TRIM(ic_mode) == 'profile')  THEN
     3790       output_var_table(89)%averaging_grid => averaged_initial_scalar_profile
     3791    ENDIF
     3792    output_var_table(89)%is_optional = .TRUE.
     3793
     3794    output_var_table(90) = init_nc_var(                                     &
     3795       name              = 'ls_forcing_left_qg',                            &
     3796       std_name          = "",                                              &
     3797       long_name         = "large-scale forcing for left model boundary for the graupel mixture fraction", &
     3798       units             = "kg/kg",                                         &
     3799       kind              = "left scalar",                                   &
     3800       input_id          = 5_iwp,                                           &
     3801       output_file       = output_file,                                     &
     3802       grid              = scalars_west_grid,                               &
     3803       intermediate_grid = scalars_west_intermediate                        &
     3804    )
     3805    output_var_table(90)%is_optional = .TRUE.
     3806
     3807    output_var_table(91) = init_nc_var(                                     &
     3808       name              = 'ls_forcing_right_qg',                           &
     3809       std_name          = "",                                              &
     3810       long_name         = "large-scale forcing for right model boundary for the graupel mixture fraction", &
     3811       units             = "kg/kg",                                         &
     3812       kind              = "right scalar",                                  &
     3813       input_id          = 5_iwp,                                           &
     3814       output_file       = output_file,                                     &
     3815       grid              = scalars_east_grid,                               &
     3816       intermediate_grid = scalars_east_intermediate                        &
     3817    )
     3818    output_var_table(91)%is_optional = .TRUE.
     3819
     3820    output_var_table(92) = init_nc_var(                                     &
     3821       name              = 'ls_forcing_north_qg',                           &
     3822       std_name          = "",                                              &
     3823       long_name         = "large-scale forcing for north model boundary for the graupel mixture fraction", &
     3824       units             = "kg/kg",                                         &
     3825       kind              = "north scalar",                                  &
     3826       input_id          = 5_iwp,                                           &
     3827       output_file       = output_file,                                     &
     3828       grid              = scalars_north_grid,                              &
     3829       intermediate_grid = scalars_north_intermediate                       &
     3830    )
     3831    output_var_table(92)%is_optional = .TRUE.
     3832
     3833    output_var_table(93) = init_nc_var(                                     &
     3834       name              = 'ls_forcing_south_qg',                           &
     3835       std_name          = "",                                              &
     3836       long_name         = "large-scale forcing for south model boundary for the graupel mixture fraction", &
     3837       units             = "kg/kg",                                         &
     3838       kind              = "south scalar",                                  &
     3839       input_id          = 5_iwp,                                           &
     3840       output_file       = output_file,                                     &
     3841       grid              = scalars_south_grid,                              &
     3842       intermediate_grid = scalars_south_intermediate                       &
     3843    )
     3844    output_var_table(93)%is_optional = .TRUE.
     3845
     3846    output_var_table(94) = init_nc_var(                                     &
     3847       name              = 'ls_forcing_top_qg',                             &
     3848       std_name          = "",                                              &
     3849       long_name         = "large-scale forcing for top model boundary for the graupel mixture fraction", &
     3850       units             = "kg/kg",                                         &
     3851       kind              = "top scalar",                                    &
     3852       input_id          = 5_iwp,                                           &
     3853       output_file       = output_file,                                     &
     3854       grid              = scalars_top_grid,                                &
     3855       intermediate_grid = scalars_top_intermediate                         &
     3856    )
     3857    output_var_table(94)%is_optional = .TRUE.
    33343858
    33353859!
     
    37114235   
    37124236    CALL report('fini_file_lists', 'Deallocating file lists', cfg%debug)
    3713     DEALLOCATE( flow_files, soil_files, radiation_files, soil_moisture_files )
     4237    DEALLOCATE( flow_files, soil_files, radiation_files, precip_files )
    37144238
    37154239 END SUBROUTINE fini_file_lists
     
    37274251!> array will match a COSMO-DE scalar array.
    37284252!------------------------------------------------------------------------------!
    3729  SUBROUTINE preprocess(group, input_buffer, cosmo_grid, iter)
     4253 SUBROUTINE preprocess( group, input_buffer, cosmo_grid )
    37304254
    37314255    TYPE(io_group), INTENT(INOUT), TARGET       ::  group
    37324256    TYPE(container), INTENT(INOUT), ALLOCATABLE ::  input_buffer(:)
    37334257    TYPE(grid_definition), INTENT(IN)           ::  cosmo_grid
    3734     INTEGER(iwp), INTENT(IN)                    ::  iter
    37354258   
    37364259    REAL(wp), ALLOCATABLE                       ::  basic_state_pressure(:)
    37374260    TYPE(container), ALLOCATABLE                ::  preprocess_buffer(:)
    3738     INTEGER(iwp)                                ::  hour, dt
    37394261    INTEGER(iwp)                                ::  i, j, k
    37404262    INTEGER(iwp)                                ::  nx, ny, nz
     
    39354457          input_buffer(:)%is_preprocessed = .TRUE.
    39364458
    3937        CASE( 'accumulated' ) !
    3938           message = "De-accumulating '" // TRIM(group%in_var_list(1)%name) //&
    3939                     "' in iteration " // TRIM(str(iter))
    3940           CALL report('preprocess', message)
    3941 
    3942           hour = iter - 1_iwp
    3943           dt = MODULO(hour, 3_iwp) + 1_iwp ! averaging period
    3944           SELECT CASE(dt)
    3945 
    3946 !
    3947 !--          input has been accumulated over one hour. Leave as is
    3948 !--          input_buffer(1)%array(:,:,:) carrries one-hour integral
    3949              CASE(1)
    3950              
    3951 !           
    3952 !--          input has been accumulated over two hours. Subtract previous step
    3953 !--          input_buffer(1)%array(:,:,:) carrries one-hour integral
    3954 !--          input_buffer(2)%array(:,:,:) carrries two-hour integral
    3955              CASE(2)
    3956                 CALL deaverage(                                                   &
    3957                          avg_1 = input_buffer(1)%array(:,:,:), t1 = 1.0_wp,     &
    3958                          avg_2 = input_buffer(2)%array(:,:,:), t2 = 1.0_wp,     &
    3959                          avg_3 = input_buffer(1)%array(:,:,:), t3 = 1.0_wp )
    3960 !           
    3961 !--             input_buffer(1)%array(:,:,:) carrries one-hour integral of second hour
    3962              
    3963 !           
    3964 !--          input has been accumulated over three hours. Subtract previous step
    3965 !--          input_buffer(1)%array(:,:,:) carrries three-hour integral
    3966 !--          input_buffer(2)%array(:,:,:) still carrries two-hour integral
    3967              CASE(3)
    3968                 CALL deaverage(                                                   &
    3969                         avg_1 = input_buffer(2)%array(:,:,:), t1 = 1.0_wp,      &
    3970                         avg_2 = input_buffer(1)%array(:,:,:), t2 = 1.0_wp,      &
    3971                         avg_3 = input_buffer(1)%array(:,:,:), t3 = 1.0_wp )
    3972 !           
    3973 !--             input_buffer(1)%array(:,:,:) carrries one-hour integral of third hourA
    3974              
    3975              CASE DEFAULT
    3976                 message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
    3977                 message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
    3978                 CALL inifor_abort('preprocess', message)
    3979 
    3980           END SELECT
    3981           input_buffer(:)%is_preprocessed = .TRUE.
    3982 
    3983        CASE( 'running average' ) !
    3984           message = "De-averaging '" // TRIM(group%in_var_list(1)%name) //   &
    3985                     "' in iteration " // TRIM(str(iter))
    3986           CALL report('preprocess', message)
    3987 
    3988           hour = iter - 1_iwp
    3989 !
    3990 !--       averaging period
    3991           dt = MODULO(hour, 3_iwp) + 1_iwp
    3992           SELECT CASE(dt)
    3993 !
    3994 !--          input has been accumulated over one hour. Leave as is
    3995 !--          input_buffer(1)%array(:,:,:) carrries one-hour integral
    3996              CASE(1)
    3997              
    3998 !           
    3999 !--          input has been accumulated over two hours. Subtract previous step
    4000 !--          input_buffer(1)%array(:,:,:) carrries one-hour integral
    4001 !--          input_buffer(2)%array(:,:,:) carrries two-hour integral
    4002              CASE(2)
    4003                 CALL deaverage( input_buffer(1)%array(:,:,:), 1.0_wp,           &
    4004                                 input_buffer(2)%array(:,:,:), 2.0_wp,           &
    4005                                 input_buffer(1)%array(:,:,:), 1.0_wp)
    4006 !           
    4007 !--             input_buffer(1)%array(:,:,:) carrries one-hour integral of second hour
    4008              
    4009 !           
    4010 !--          input has been accumulated over three hours. Subtract previous step
    4011 !--          input_buffer(1)%array(:,:,:) carrries three-hour integral
    4012 !--          input_buffer(2)%array(:,:,:) still carrries two-hour integral
    4013              CASE(3)
    4014                 CALL deaverage( input_buffer(2)%array(:,:,:), 2.0_wp,           &
    4015                                 input_buffer(1)%array(:,:,:), 3.0_wp,           &
    4016                                 input_buffer(1)%array(:,:,:), 1.0_wp)
    4017 !           
    4018 !--             input_buffer(1)%array(:,:,:) carrries one-hour integral of third hourA
    4019              
    4020              CASE DEFAULT
    4021                 message = "Invalid averaging period '" // TRIM(str(dt)) // " hours"
    4022                 CALL inifor_abort('preprocess', message)
    4023 
    4024           END SELECT
    4025           input_buffer(:)%is_preprocessed = .TRUE.
    4026 
    40274459       CASE DEFAULT
    40284460          message = "IO group kind '" // TRIM(group%kind) // "' is not supported."
  • palm/trunk/UTIL/inifor/src/inifor_io.f90

    r4569 r4659  
    2121! Current revisions:
    2222! -----------------
    23 ! 
    24 ! 
     23!
     24!
    2525! Former revisions:
    2626! -----------------
    2727! $Id$
     28! New command-line option '--precipitation' enables output of precipitation
     29!    surface forcing
     30! Only define netCDF variables in enabled IO groups
     31! Improved code formatting
     32!
     33!
     34! 4569 2020-06-19 12:46:17Z eckhard
    2835! Removed unused variable
    2936!
     
    450457    cfg%radiation_prefix_is_set = .FALSE.
    451458    cfg%soil_prefix_is_set = .FALSE.
    452     cfg%soilmoisture_prefix_is_set = .FALSE.
     459    cfg%precipitation_prefix_is_set = .FALSE.
     460    cfg%process_precipitation = .FALSE.
    453461    cfg%static_driver_is_set = .FALSE.
    454462    cfg%ug_defined_by_user = .FALSE.
     
    538546                cfg%soil_prefix_is_set = .TRUE.
    539547   
    540              CASE( '--soilmoisture-prefix')
    541                 CALL get_option_argument( i, arg )
    542                 cfg%soilmoisture_prefix = TRIM(arg)
    543                 cfg%soilmoisture_prefix_is_set = .TRUE.
     548             CASE( '--precipitation-prefix')
     549                CALL get_option_argument( i, arg )
     550                cfg%precipitation_prefix = TRIM(arg)
     551                cfg%precipitation_prefix_is_set = .TRUE.
     552
     553             CASE( '--precipitation')
     554                cfg%process_precipitation = .TRUE.
    544555
    545556             CASE( '-o', '--output' )
     
    567578                PRINT *, ""
    568579                PRINT *, &
    569                    "For documentation and a list of available command-line options " // NEW_LINE(" ") // &
     580                   "For documentation and a list of available command-line options " // NEW_LINE( " " ) // &
    570581                   " please visit https://palm.muk.uni-hannover.de/trac/wiki/doc/app/iofiles/inifor."
    571582                STOP
     
    628639 SUBROUTINE get_input_file_list( start_date_string, start_hour, end_hour,    &
    629640                                 step_hour, input_path, prefix, suffix,      &
    630                                  file_list, nocheck )
     641                                 file_list )
    631642
    632643    CHARACTER (LEN=DATE), INTENT(IN) ::  start_date_string
     
    634645    INTEGER(iwp),         INTENT(IN) ::  start_hour, end_hour, step_hour
    635646    CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) ::  file_list(:)
    636     LOGICAL, OPTIONAL, INTENT(IN)    ::  nocheck
    637 
    638     INTEGER(iwp) ::  i
    639     LOGICAL      ::  check_files
    640647
    641648    CALL get_datetime_file_list( start_date_string, start_hour, end_hour,    &
     
    643650                                 file_list )
    644651
    645     check_files = .TRUE.
    646     IF ( PRESENT ( nocheck ) )  THEN
    647        IF ( nocheck )  check_files = .FALSE.
    648     ENDIF
    649 
    650     IF ( check_files )  THEN
    651 
    652        tip = "Please check if you specified the correct file prefix " //     &
    653              "using the options --input-prefix, --flow-prefix, etc."
    654 
    655        DO  i = 1, SIZE(file_list)
    656            CALL verify_file(file_list(i), 'input', tip)
    657        ENDDO
    658 
    659     ENDIF
    660 
    661652 END SUBROUTINE get_input_file_list
    662653
     
    667658!> Abort INIFOR if the given file is not present.
    668659!------------------------------------------------------------------------------!
    669  SUBROUTINE verify_file(file_name, file_kind, tip)
     660LOGICAL FUNCTION file_is_present( filename, file_kind, message )
     661
     662    CHARACTER(LEN=*), INTENT(IN)            ::  filename, file_kind
     663    CHARACTER(LEN=*), INTENT(OUT)           ::  message
     664
     665    file_is_present = file_present(filename)
     666
     667    IF (.NOT. file_is_present)  THEN
     668
     669       IF (LEN( TRIM( filename ) ) == 0)  THEN
     670          message = "No name was given for the " // TRIM( file_kind ) // " file."
     671       ELSE
     672          message = "The " // TRIM( file_kind ) // " file '" //                  &
     673                    TRIM( filename ) // "' was not found."
     674       ENDIF
     675
     676    ENDIF
     677
     678END FUNCTION file_is_present
     679
     680
     681!------------------------------------------------------------------------------!
     682! Description:
     683! ------------
     684!> Abort INIFOR if the given file is not present.
     685!------------------------------------------------------------------------------!
     686 SUBROUTINE verify_file( file_name, file_kind )
    670687
    671688    CHARACTER(LEN=*), INTENT(IN)           ::  file_name, file_kind
    672     CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  tip
    673 
    674     IF (.NOT. file_present(file_name))  THEN
    675 
    676        IF (LEN(TRIM(file_name)) == 0)  THEN
    677 
    678           message = "No name was given for the " // TRIM(file_kind) // " file."
    679 
    680        ELSE
    681 
    682           message = "The " // TRIM(file_kind) // " file '" //                &
    683                     TRIM(file_name) // "' was not found."
    684 
    685           IF (PRESENT(tip))  THEN
    686              message = TRIM(message) // " " // TRIM(tip)
    687           ENDIF
    688 
    689        ENDIF
    690 
    691        CALL inifor_abort('verify_file', message)
    692 
    693     ENDIF
    694 
    695     message = "Set up input file name '" // TRIM(file_name) // "'"
    696     CALL report('verify_file', message)
     689
     690    IF (.NOT. file_is_present( file_name, file_kind, message ))  THEN
     691
     692       CALL inifor_abort( 'verify_file', message )
     693
     694    ENDIF
     695
     696    message = "Set up input file name '" // TRIM( file_name ) // "'"
     697    CALL report( 'verify_file', message )
    697698
    698699 END SUBROUTINE verify_file
    699 
    700 
    701700!------------------------------------------------------------------------------!
    702701! Description:
     
    705704!> i+1 of the argument list.
    706705!------------------------------------------------------------------------------!
    707  SUBROUTINE get_option_argument(i, arg)
     706 SUBROUTINE get_option_argument( i, arg )
    708707    CHARACTER(LEN=PATH), INTENT(INOUT) ::  arg
    709708    INTEGER, INTENT(INOUT)             ::  i
    710709
    711710    i = i + 1
    712     CALL GET_COMMAND_ARGUMENT(i, arg)
     711    CALL GET_COMMAND_ARGUMENT( i, arg )
    713712
    714713 END SUBROUTINE
     
    720719!> Checks the INIFOR configuration 'cfg' for plausibility.
    721720!------------------------------------------------------------------------------!
    722  SUBROUTINE validate_config(cfg)
     721 SUBROUTINE validate_config( cfg )
    723722    TYPE(inifor_config), INTENT(IN) ::  cfg
    724723
    725     CALL verify_file(cfg%hhl_file, 'HHL')
    726     CALL verify_file(cfg%namelist_file, 'NAMELIST')
    727     CALL verify_file(cfg%soiltyp_file, 'SOILTYP')
     724    CALL verify_file( cfg%hhl_file, 'HHL' )
     725    CALL verify_file( cfg%namelist_file, 'NAMELIST' )
     726    CALL verify_file( cfg%soiltyp_file, 'SOILTYP' )
    728727
    729728!
    730729!-- Only check optional static driver file name, if it has been given.
    731     IF (TRIM(cfg%static_driver_file) .NE. '')  THEN
    732        CALL verify_file(cfg%static_driver_file, 'static driver')
    733     ENDIF
    734 
    735     SELECT CASE( TRIM(cfg%ic_mode) )
    736        CASE( 'profile', 'volume')
     730    IF (TRIM( cfg%static_driver_file ) .NE. '')  THEN
     731       CALL verify_file( cfg%static_driver_file, 'static driver' )
     732    ENDIF
     733
     734    SELECT CASE( TRIM( cfg%ic_mode ) )
     735       CASE( 'profile', 'volume' )
    737736       CASE DEFAULT
    738           message = "Initialization mode '" // TRIM(cfg%ic_mode) //&
     737          message = "Initialization mode '" // TRIM( cfg%ic_mode ) //&
    739738                    "' is not supported. " //&
    740739                    "Please select either 'profile' or 'volume', " //&
     
    747746       CASE( 'real', 'ideal')
    748747       CASE DEFAULT
    749           message = "Forcing mode '" // TRIM(cfg%bc_mode) //&
     748          message = "Forcing mode '" // TRIM( cfg%bc_mode ) //&
    750749                    "' is not supported. " //&
    751750                    "Please select either 'real' or 'ideal', " //&
     
    755754    END SELECT
    756755
    757     SELECT CASE( TRIM(cfg%averaging_mode) )
     756    SELECT CASE( TRIM( cfg%averaging_mode ) )
    758757       CASE( 'level' )
    759758       CASE( 'height' )
    760           message = "Averaging mode '" // TRIM(cfg%averaging_mode) //&
     759          message = "Averaging mode '" // TRIM( cfg%averaging_mode ) //&
    761760                    "' is currently not supported. " //&
    762761                    "Please use level-based averaging by selecting 'level', " //&
     
    764763          CALL inifor_abort( 'validate_config', message )
    765764       CASE DEFAULT
    766           message = "Averaging mode '" // TRIM(cfg%averaging_mode) //&
     765          message = "Averaging mode '" // TRIM( cfg%averaging_mode ) //&
    767766                    "' is not supported. " //&
    768767          !          "Please select either 'height' or 'level', " //&
     
    782781    IF ( .NOT. cfg%static_driver_is_set .AND. .NOT. cfg%z0_is_set )  THEN
    783782       message =                                                               &
    784           "The vertical origin of the PALM grid has not been defined. " // NEW_LINE(" ") // &
    785           "Please specify the right value for your setup by either " // NEW_LINE(" ") // &
    786           "  - using the command-line option --elevation <height above sea level>, or by" // NEW_LINE(" ") // &
    787           "  - specifying a static driver file using --static <filename> in order to use " // NEW_LINE(" ") // &
     783          "The vertical origin of the PALM grid has not been defined. " // NEW_LINE( " " ) // &
     784          "Please specify the right value for your setup by either " // NEW_LINE( " " ) // &
     785          "  - using the command-line option --elevation <height above sea level>, or by" // NEW_LINE( " " ) // &
     786          "  - specifying a static driver file using --static <filename> in order to use " // NEW_LINE( " " ) // &
    788787          "    use the value of origin_z (and origin_lon and origin_lat) specifed therein."
    789788       CALL inifor_abort( 'validate_config', message )
     
    902901!>
    903902!------------------------------------------------------------------------------!
    904  SUBROUTINE get_soil_layer_thickness(depths, d_depth)
     903 SUBROUTINE get_soil_layer_thickness( depths, d_depth )
    905904
    906905    REAL(wp), INTENT(IN)  ::  depths(:)
     
    916915!> Check whether the given file is present on the filesystem.
    917916!------------------------------------------------------------------------------!
    918  LOGICAL FUNCTION file_present(filename)
     917 LOGICAL FUNCTION file_present( filename )
    919918    CHARACTER(LEN=PATH), INTENT(IN) ::  filename
    920919
    921     INQUIRE(FILE=filename, EXIST=file_present)
     920    INQUIRE( FILE=filename, EXIST=file_present )
    922921
    923922 END FUNCTION file_present
     
    11261125!> Defines the netCDF variables to be written to the dynamic driver file
    11271126!------------------------------------------------------------------------------!
    1128  SUBROUTINE setup_netcdf_variables(filename, output_variable_table)
    1129 
    1130     CHARACTER (LEN=*), INTENT(IN)        ::  filename
    1131     TYPE(nc_var), INTENT(INOUT), TARGET  ::  output_variable_table(:)
    1132 
    1133     TYPE(nc_var), POINTER                ::  var
    1134     INTEGER(iwp)                         ::  i
    1135     INTEGER                              ::  ncid
    1136     LOGICAL                              ::  to_be_written
     1127 SUBROUTINE setup_netcdf_variables(filename, io_group_list)
     1128
     1129    CHARACTER (LEN=*), INTENT(IN)       ::  filename
     1130    TYPE(io_group), INTENT(IN), TARGET  ::  io_group_list(:)
     1131
     1132    TYPE(io_group), POINTER             ::  group
     1133    TYPE(nc_var), POINTER               ::  var
     1134    INTEGER(iwp)                        ::  group_idx, var_idx, n_var
     1135    INTEGER                             ::  ncid
     1136    LOGICAL                             ::  to_be_written
    11371137
    11381138    message = "Defining variables in dynamic driver '" // TRIM(filename) // "'."
     
    11421142    CALL check(nf90_redef(ncid))
    11431143
    1144     DO  i = 1, SIZE(output_variable_table)
    1145 
    1146        var => output_variable_table(i)
    1147 
    1148        !to_be_written = ( var%to_be_processed  .AND. .NOT. var%is_internal) .OR. &
    1149        !                ( var%is_internal  .AND.  debug )
    1150        to_be_written = ( var%to_be_processed  .AND. .NOT. var%is_internal)
    1151 
    1152        IF ( to_be_written )  THEN
    1153           message = "  variable #" // TRIM(str(i)) // " '" // TRIM(var%name) // "'."
    1154           CALL report('setup_netcdf_variables', message)
    1155 
    1156           CALL netcdf_define_variable(var, ncid)
    1157           CALL netcdf_get_dimensions(var, ncid)
    1158        ENDIF
     1144    n_var = 0
     1145    DO  group_idx = 1, SIZE( io_group_list )
     1146
     1147       group => io_group_list(group_idx)
     1148       DO var_idx = 1, SIZE( group%out_vars )
     1149
     1150          to_be_written = .FALSE.
     1151
     1152          IF (ALLOCATED( group%out_vars ))  THEN
     1153             var => group%out_vars(var_idx)
     1154             n_var = n_var + 1
     1155
     1156             to_be_written = (                                                 &
     1157                group%to_be_processed  .AND.  var%to_be_processed              &
     1158                .AND. .NOT. var%is_internal                                    &
     1159             )
     1160          ENDIF
     1161
     1162          IF ( to_be_written )  THEN
     1163             message = "  variable #" // TRIM(str(n_var)) // " '" // TRIM(var%name) // "'."
     1164             CALL report('setup_netcdf_variables', message)
     1165
     1166             CALL netcdf_define_variable(var, ncid)
     1167             CALL netcdf_get_dimensions(var, ncid)
     1168          ENDIF
     1169
     1170       ENDDO
    11591171       
    11601172    ENDDO
     
    12021214!
    12031215!-- radiation budgets, precipitation
    1204     IF (group%kind == 'running average' .OR.                              &
    1205         group%kind == 'accumulated')  THEN
    1206 
    1207        IF (SIZE(group%in_var_list) .GT. 1 ) THEN
     1216    IF ( group%kind == 'running average' .OR.                                  &
     1217         group%kind == 'accumulated' )  THEN
     1218
     1219       IF ( SIZE( group%in_var_list ) .GT. 1 ) THEN
    12081220          message = "I/O groups may not contain more than one " // &
    12091221                    "accumulated variable. Group '" // TRIM(group%kind) //&
    1210                     "' contains " //                                        &
    1211                     TRIM( str(SIZE(group%in_var_list, kind=iwp)) ) // "."
    1212           CALL inifor_abort('read_input_variables | accumulation', message)
     1222                    "' contains " //                                           &
     1223                    TRIM( str( SIZE( group%in_var_list, kind=iwp ) ) ) // "."
     1224          CALL inifor_abort( 'read_input_variables | accumulation', message )
    12131225       ENDIF
    12141226
     
    12421254
    12431255!
    1244 !--    Allocate one input buffer per input_variable. If more quantities
     1256!--    Allocate one input buffer per output quantity. If more quantities
    12451257!--    have to be computed than input variables exist in this group,
    12461258!--    allocate more buffers. For instance, in the thermodynamics group,
     
    12481260!--    necessart (P, Theta, Rho, qv) for the corresponding output fields
    12491261!--    (p0, Theta, qv, ug, and vg)
    1250        nbuffers = MAX( group%n_inputs, group%n_output_quantities )
    1251        ALLOCATE( buffer(nbuffers) )
     1262       ALLOCATE( buffer(group%n_output_quantities) )
    12521263       CALL log_runtime('time', 'alloc')
    12531264       
     
    12581269          input_var => group%in_var_list(ivar)
    12591270
    1260 !
    1261 !         Check wheather P or PP is present in input file
    1262           IF (input_var%name == 'P')  THEN
    1263              input_var%name = TRIM( get_pressure_varname(input_file) )
    1264           CALL log_runtime('time', 'read')
     1271          IF ( input_var%to_be_processed )  THEN
     1272!            Check wheather P or PP is present in input file
     1273             IF (input_var%name == 'P')  THEN
     1274                input_var%name = TRIM( get_pressure_varname(input_file) )
     1275             CALL log_runtime('time', 'read')
     1276             ENDIF
     1277
     1278             CALL get_netcdf_variable(input_file, input_var, buffer(ivar)%array)
     1279
     1280             IF ( input_var%is_upside_down )  CALL reverse(buffer(ivar)%array)
     1281             CALL log_runtime('time', 'comp')
    12651282          ENDIF
    1266 
    1267           CALL get_netcdf_variable(input_file, input_var, buffer(ivar)%array)
    1268 
    1269           IF ( input_var%is_upside_down )  CALL reverse(buffer(ivar)%array)
    1270           CALL log_runtime('time', 'comp')
    12711283
    12721284       ENDDO
     
    16631675
    16641676
     1677 LOGICAL FUNCTION netcdf_variable_present_in_file( varname, filename )
     1678    CHARACTER(LEN=SNAME), INTENT(IN) ::  varname
     1679    CHARACTER(LEN=PATH), INTENT(IN)  ::  filename
     1680
     1681    INTEGER ::  ncid, varid
     1682   
     1683    netcdf_variable_present_in_file = (                                        &
     1684       nf90_open( TRIM( filename ), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR .AND. &
     1685       nf90_inq_varid( ncid, varname, varid ) .EQ. NF90_NOERR .AND.            &
     1686       nf90_close( ncid ) .EQ. NF90_NOERR                                      &
     1687    )
     1688 
     1689 END FUNCTION netcdf_variable_present_in_file
     1690
     1691
    16651692 END MODULE inifor_io
    16661693#endif
  • palm/trunk/UTIL/inifor/src/inifor_types.f90

    r4568 r4659  
    2121! Current revisions:
    2222! -----------------
    23 ! 
    24 ! 
     23!
     24!
    2525! Former revisions:
    2626! -----------------
    2727! $Id$
     28! Added flag in support of new command-line option '--precipitation'
     29! Improved code formatting
     30!
     31!
     32! 4568 2020-06-19 11:56:30Z eckhard
    2833! Handle COSMO soil data with and without additional surface temperature
    2934!
     
    123128    CHARACTER(LEN=SNAME) ::  radiation_prefix     !< Prefix of radiation input files, e.g 'laf' for COSMO-DE analyses
    124129    CHARACTER(LEN=SNAME) ::  soil_prefix          !< Prefix of soil input files, e.g. 'laf' for COSMO-DE analyses
    125     CHARACTER(LEN=SNAME) ::  soilmoisture_prefix  !< Prefix of input files for soil moisture spin-up, e.g 'laf' for COSMO-DE analyses
     130    CHARACTER(LEN=SNAME) ::  precipitation_prefix !< Prefix of input files for precipitation forcing, e.g 'laf' for COSMO-DE analyses
    126131
    127132    CHARACTER(LEN=SNAME) ::  averaging_mode       !< destinguishes between level-based and heigh-based averaging
     
    142147    LOGICAL              ::  radiation_prefix_is_set     !< indicates whether the radiation prefix was set manually
    143148    LOGICAL              ::  soil_prefix_is_set          !< indicates whether the soil prefix was set manually
    144     LOGICAL              ::  soilmoisture_prefix_is_set  !< indicates whether the soilmoisture prefix was set manually
     149    LOGICAL              ::  precipitation_prefix_is_set !< indicates whether the precipitation prefix was set manually
     150    LOGICAL              ::  process_precipitation       !< indicates whether precipitation should be processed
    145151    LOGICAL              ::  static_driver_is_set        !< indicates whether a static driver was given
    146152    LOGICAL              ::  ug_defined_by_user          !< indicates whether ug was set manually
     
    247253    LOGICAL                               ::  to_be_processed = .FALSE. !< INIFOR flag indicating whether variable shall be processed
    248254    LOGICAL                               ::  is_internal = .FALSE.     !< INIFOR flag indicating whether variable shall be written to netCDF file (.FALSE.) or kept for later (.TRUE.)
     255    LOGICAL                               ::  is_optional = .FALSE.     !< Flag indicating whether INIFOR may continue if the the netCDF variable cannot be processed, e.g. if files are missing
    249256    LOGICAL                               ::  is_read = .FALSE.         !< INIFOR flag indicating whether variable has been read
    250257    LOGICAL                               ::  is_upside_down  = .FALSE. !< INIFOR flag indicating whether vertical dimension is reversed (typically the case with COSMO-DE atmospheric fields)
     
    252259    TYPE(grid_definition), POINTER        ::  grid                      !< Pointer to the corresponding output grid
    253260    TYPE(grid_definition), POINTER        ::  intermediate_grid         !< Pointer to the corresponding intermediate grid
    254     TYPE(grid_definition), POINTER        ::  averaging_grid         !< Pointer to the corresponding intermediate grid
     261    TYPE(grid_definition), POINTER        ::  averaging_grid            !< Pointer to the corresponding intermediate grid
    255262 END TYPE nc_var
    256263
     
    265272!------------------------------------------------------------------------------!
    266273 TYPE io_group
    267     INTEGER(iwp)                          ::  nt             !< maximum number of output time steps across all output variables
    268     INTEGER(iwp)                          ::  nv             !< number of netCDF output variables
    269     INTEGER(iwp)                          ::  n_inputs       !< number of input variables
    270     INTEGER(iwp)                          ::  n_output_quantities !< number of physical quantities required for computing netCDF output variables
    271     CHARACTER(LEN=SNAME)             ::  kind           !< kind of I/O group
    272     CHARACTER(LEN=PATH), ALLOCATABLE ::  in_files(:)    !< list of nt input files
    273     TYPE(nc_var), ALLOCATABLE        ::  out_vars(:)    !< list of output variables
    274     TYPE(nc_var), ALLOCATABLE        ::  in_var_list(:) !< list of input variables
     274    INTEGER(iwp)                     ::  nt                  !< maximum number of output time steps across all output variables
     275    INTEGER(iwp)                     ::  nv                  !< number of netCDF output variables
     276    INTEGER(iwp)                     ::  n_inputs            !< number of input variables
     277    INTEGER(iwp)                     ::  n_output_quantities !< number of physical quantities required for computing netCDF output variables
     278    CHARACTER(LEN=SNAME)             ::  name                !< name of I/O group
     279    CHARACTER(LEN=SNAME)             ::  kind                !< kind of I/O group
     280    CHARACTER(LEN=PATH), ALLOCATABLE ::  in_files(:)         !< list of nt input files
     281    TYPE(nc_var), ALLOCATABLE        ::  out_vars(:)         !< list of output variables
     282    TYPE(nc_var), ALLOCATABLE        ::  in_var_list(:)      !< list of input variables
    275283    LOGICAL                          ::  to_be_processed = .FALSE. !< Inifor flag indicating whether I/O group shall be processed
    276284    LOGICAL                          ::  is_accumulated = .FALSE.  !< Flag indicating whether this I/O group contains accumulated variables
     285    LOGICAL                          ::  is_optional = .FALSE.     !< Flag indicating whether INIFOR may continue if group cannot be processed, e.g. if files are missing
    277286    LOGICAL                          ::  is_preprocessed = .FALSE. !< Inifor flag indicating whether the I/O group has been preprocessed
    278287 END TYPE io_group
Note: See TracChangeset for help on using the changeset viewer.