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

inifor: Support for COSMO cloud water and precipitation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.