Changeset 4107 for palm/trunk/UTIL


Ignore:
Timestamp:
Jul 22, 2019 8:51:35 AM (5 years ago)
Author:
gronemeier
Message:

changes in data-output module (data_output_module.f90, data_output_binary_module.f90, data_output_netcdf4_module.f90, binary_to_netcdf.f90):

  • add support for different output groups of MPI ranks (required for, e.g., nesting runs)
  • revise output messages
File:
1 edited

Legend:

Unmodified
Added
Removed
  • palm/trunk/UTIL/binary_to_netcdf.f90

    r4075 r4107  
    8282
    8383
    84    CHARACTER(LEN=200)            ::  temp_string      !< dummy string
    85 
    86    CHARACTER(LEN=:), ALLOCATABLE ::  filename_prefix  !< prefix of names of files to be read
    87 
    88    CHARACTER(LEN=*), PARAMETER   ::  routine_name = 'binary_to_netcdf'             !< name of routine
    89    CHARACTER(LEN=*), PARAMETER   ::  config_file_name = 'BINARY_TO_NETCDF_CONFIG'  !< name of configuration file
    90 
    91    CHARACTER(LEN=charlen_internal), DIMENSION(:), ALLOCATABLE ::  filename_list  !< list of netcdf file names
     84   CHARACTER(LEN=charlen_internal)                            ::  temp_string      !< dummy string
     85   CHARACTER(LEN=:),                              ALLOCATABLE ::  filename_prefix  !< prefix of names of files to be read
     86   CHARACTER(LEN=charlen_internal), DIMENSION(:), ALLOCATABLE ::  group_names      !< names of output groups
     87   CHARACTER(LEN=charlen_internal), DIMENSION(:), ALLOCATABLE ::  filename_list    !< list of netcdf file names
     88
     89   CHARACTER(LEN=*), PARAMETER   ::  routine_name = 'binary_to_netcdf'                  !< name of routine
     90   CHARACTER(LEN=*), PARAMETER   ::  config_file_name_base = 'BINARY_TO_NETCDF_CONFIG'  !< name of config file
     91   CHARACTER(LEN=*), PARAMETER   ::  &
     92      config_file_list_name = 'BINARY_CONFIG_LIST'  !< file containing list of binary config files of each output group
    9293
    9394   INTEGER(iwp) ::  charlen            !< length of characters (strings) in binary file
    9495   INTEGER(iwp) ::  dom_global_id      !< global ID within a single file defined by DOM
     96   INTEGER      ::  dom_master_rank    !< master MPI rank in DOM (rank which wrote additional information in DOM)
     97   INTEGER      ::  dom_nrank          !< number of MPI ranks used by DOM
    9598   INTEGER(iwp) ::  file_index         !< loop index to loop over files
     99   INTEGER      ::  group              !< loop index to loop over groups
    96100   INTEGER(iwp) ::  nc_file_id         !< ID of netcdf output file
    97101   INTEGER(iwp) ::  nfiles             !< number of output files defined in config file
     102   INTEGER      ::  ngroup             !< number of output-file groups
    98103   INTEGER      ::  return_value       !< return value
    99104   INTEGER      ::  your_return_value  !< returned value of called routine
     
    104109   INTEGER(iwp)    ::  dummy_intwp  !< dummy variable used for reading
    105110
    106    INTEGER, PARAMETER ::  bin_file_unit = 2     !< Fortran unit of binary file
    107    INTEGER, PARAMETER ::  config_file_unit = 1  !< Fortran unit of configuration file
     111   INTEGER, PARAMETER ::  bin_file_unit = 12          !< Fortran unit of binary file
     112   INTEGER, PARAMETER ::  config_file_unit = 11       !< Fortran unit of configuration file
     113   INTEGER, PARAMETER ::  config_file_list_unit = 10  !< Fortran unit of file containing config-file list
    108114
    109115   INTEGER, DIMENSION(:), ALLOCATABLE ::  dim_id_netcdf  !< mapped dimension id within NetCDF file:
     
    126132   return_value = 0
    127133
    128    CALL internal_message( 'info', routine_name // ': Start converting binary files...' )
    129 
    130    CALL read_config( your_return_value )
    131 
    132    IF ( your_return_value == 0 )  THEN
    133       DO  file_index = 1, nfiles
    134 
    135          CALL internal_message( 'info', routine_name // &
    136                                 ': create file ' // TRIM( filename_list(file_index) ) )
    137 
    138          CALL read_binary_header( TRIM( filename_list(file_index) ), your_return_value )
     134   CALL internal_message( 'info', 'Start ' // routine_name // ' ...' )
     135
     136   CALL get_group_names( return_value )
     137
     138   IF ( return_value == 0 )  THEN
     139
     140      !-- Go through each group of output files (all marked by same file suffix)
     141      DO  group = 1, ngroup
     142
     143         CALL internal_message( 'info', 'Start converting ' // TRIM( group_names(group) ) // &
     144                                ' binary files:' )
     145
     146         CALL read_config( TRIM( group_names(group) ), your_return_value )
    139147
    140148         IF ( your_return_value == 0 )  THEN
    141             CALL define_netcdf_files( TRIM( filename_list(file_index) ), your_return_value )
     149            DO  file_index = 1, nfiles
     150
     151               CALL internal_message( 'info', 'Create file ' // TRIM( filename_list(file_index) ) )
     152
     153               CALL read_binary_header( TRIM( filename_list(file_index) ), your_return_value )
     154
     155               IF ( your_return_value == 0 )  THEN
     156                  CALL define_netcdf_files( TRIM( filename_list(file_index) ), your_return_value )
     157               ELSE
     158                  return_value = your_return_value
     159               ENDIF
     160
     161               IF ( your_return_value == 0 )  THEN
     162                  CALL convert_data_to_netcdf( TRIM( filename_list(file_index) ), your_return_value )
     163               ELSE
     164                  return_value = your_return_value
     165               ENDIF
     166
     167            ENDDO
    142168         ELSE
    143169            return_value = your_return_value
    144170         ENDIF
    145171
    146          IF ( your_return_value == 0 )  THEN
    147             CALL convert_data_to_netcdf( TRIM( filename_list(file_index) ), your_return_value )
    148          ELSE
    149             return_value = your_return_value
    150          ENDIF
     172         IF ( ALLOCATED( filename_list   ) )  DEALLOCATE( filename_list   )
     173         IF ( ALLOCATED( filename_prefix ) )  DEALLOCATE( filename_prefix )
    151174
    152175      ENDDO
    153    ELSE
    154       return_value = your_return_value
     176
    155177   ENDIF
    156178
    157179   IF ( return_value == 0 )  THEN
    158       CALL internal_message( 'info', routine_name // ': Execution finished' )
     180      CALL internal_message( 'info', 'Execution finished' )
    159181   ELSE
    160182      CALL internal_message( 'error', routine_name // ': Error during execution! Check results!' )
     
    168190! Description:
    169191! ------------
     192!> Check if any configuration file is present in the current directory and get the list of all
     193!> these files and extract the output-group names.
     194!--------------------------------------------------------------------------------------------------!
     195SUBROUTINE get_group_names( return_value )
     196
     197   CHARACTER(LEN=charlen_internal) ::  file_name  !< file name read from list
     198
     199   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'get_group_names'  !< name of routine
     200
     201   INTEGER              ::  i             !< loop index
     202   INTEGER              ::  io_stat       !< status of Fortran I/O operations
     203   INTEGER, INTENT(OUT) ::  return_value  !< return value
     204
     205
     206   CALL internal_message( 'info', 'Check if anything to convert...' )
     207
     208   !-- Search for configuration files and save the list of file names in a separate file
     209   CALL EXECUTE_COMMAND_LINE( &
     210           COMMAND='find . -type f -name "' // config_file_name_base // '*" | ' // &
     211                   'sed -r "s/^\.\/(' // config_file_name_base // ')?(.+)$/\1\2/" > ' // &
     212                   config_file_list_name, &
     213           WAIT=.TRUE., &
     214           EXITSTAT=return_value )
     215
     216   !-- Read the config-file-name list and extract the group names from the file names
     217   IF ( return_value /= 0 )  THEN
     218
     219      CALL internal_message( 'error', routine_name // &
     220                             ': error while searching for configuration files: ' // &
     221                             'System returned non-zero exit status. ' // &
     222                             'Please report this error to the developers!' )
     223
     224   ELSE
     225
     226      OPEN( config_file_list_unit, FILE=config_file_list_name, FORM='formatted', &
     227            STATUS='OLD', IOSTAT=io_stat )
     228
     229      !-- Count the configuration files
     230      ngroup = 0
     231      DO WHILE ( io_stat == 0 )
     232         READ( config_file_list_unit, '(A)', IOSTAT=io_stat )  file_name
     233         IF ( io_stat == 0 )  ngroup = ngroup + 1
     234      ENDDO
     235      REWIND( config_file_list_unit )
     236
     237      IF ( ngroup /= 0 )  THEN
     238
     239         ALLOCATE( group_names(ngroup) )
     240
     241         !-- Extract the group names
     242         DO  i = 1, ngroup
     243            READ( config_file_list_unit, '(A)', IOSTAT=io_stat )  file_name
     244            IF ( INDEX( TRIM( file_name ), config_file_name_base ) == 1 )  THEN
     245               IF ( TRIM( file_name ) ==  TRIM( config_file_name_base ) )  THEN
     246                  group_names(i) = ''
     247               ELSE
     248                  group_names(i) = file_name(LEN_TRIM( config_file_name_base )+1:)
     249               ENDIF
     250            ELSE
     251               return_value = 1
     252               CALL internal_message( 'error', routine_name // &
     253                                      ': error while getting list of binary config files: ' // &
     254                                      'Unexpected text found in file list. ' // &
     255                                      'Please report this error to the developers!' )
     256               EXIT
     257            ENDIF
     258         ENDDO
     259
     260      ELSE
     261         CALL internal_message( 'info', 'No configuration files found. ' // &
     262                                'No binary files to convert to NetCDF.' )
     263      ENDIF
     264
     265      CLOSE( config_file_list_unit )
     266
     267   ENDIF
     268
     269END SUBROUTINE get_group_names
     270
     271!--------------------------------------------------------------------------------------------------!
     272! Description:
     273! ------------
    170274!> Read configuration file.
    171275!--------------------------------------------------------------------------------------------------!
    172 SUBROUTINE read_config( return_value )
     276SUBROUTINE read_config( group_name, return_value )
    173277
    174278   CHARACTER(LEN=:), ALLOCATABLE ::  read_string                   !< string read from file
     279   CHARACTER(LEN=*), INTENT(IN)  ::  group_name                    !< group name
    175280   CHARACTER(LEN=*), PARAMETER   ::  routine_name = 'read_config'  !< name of routine
     281
     282   CHARACTER(LEN=charlen_internal) ::  config_file_name  !< config file name with additional suffix
    176283
    177284   CHARACTER(LEN=charlen_internal), DIMENSION(:), ALLOCATABLE ::  filename_list_tmp  !< temporary list of file names
     
    183290
    184291   return_value = 0
     292
     293   config_file_name = config_file_name_base // group_name
    185294
    186295   OPEN( config_file_unit, FILE=config_file_name, FORM='unformatted', &
     
    196305   IF ( return_value == 0 )  THEN
    197306
     307      READ( config_file_unit ) dom_nrank
     308
     309      IF ( dom_nrank > 1000000 )  THEN
     310         dom_nrank = 1000000
     311         CALL internal_message( 'info', routine_name // &
     312                 ': number of MPI ranks used in PALM is greater than the maximum ' // &
     313                 'amount I can handle. I will only consider the first 1000000 output files.' )
     314      ENDIF
     315
     316      READ( config_file_unit ) dom_master_rank
    198317      READ( config_file_unit ) filename_prefix_length
    199318
     
    201320
    202321      READ( config_file_unit ) filename_prefix
    203 
    204322      READ( config_file_unit ) charlen
    205 
    206323      READ( config_file_unit ) dom_global_id
    207324
     
    233350               ENDIF
    234351
    235                filename_list(nfiles) = TRIM( read_string )
     352               filename_list(nfiles) = TRIM( read_string ) // group_name
    236353
    237354            ENDIF
     
    280397   return_value = 0
    281398
    282    !-- Open binary file of PE0
    283    bin_filename = TRIM( filename_prefix ) // TRIM( bin_filename_body ) // '_000000'
     399   !-- Open binary file written by dom_master_rank
     400   WRITE( bin_filename , '(A,I6.6)' ) &
     401      TRIM( filename_prefix ) // TRIM( bin_filename_body ) // '_', dom_master_rank
    284402
    285403   CALL internal_message( 'debug', routine_name // ': read file ' // TRIM( bin_filename ) )
     
    426544   ENDDO  ! iterate over file header
    427545
     546   CLOSE( bin_file_unit )
     547
    428548END SUBROUTINE read_binary_header
    429549
     
    679799
    680800   !-- Open binary files of every possible PE
    681    DO  pe_id = 0, 999999
     801   DO  pe_id = 0, dom_nrank - 1
    682802
    683803      WRITE( bin_filename, '(A, I6.6)' ) &
     
    689809      IF ( file_exists )  THEN
    690810
    691          !-- Open file and skip header (file of PE0 is already opened)
    692          IF ( pe_id /= 0 )  THEN
    693 
    694             OPEN( bin_file_unit, FILE=bin_filename, FORM='UNFORMATTED', STATUS='OLD' )
    695 
    696             CALL internal_message( 'debug', routine_name // &
    697                                    ': read binary file ' // TRIM( bin_filename ) )
    698 
    699             read_string = ''
    700             DO WHILE ( TRIM( read_string ) /= '*** end file header ***' )
    701 
    702                READ( bin_file_unit ) read_string
    703 
    704                SELECT CASE ( TRIM( read_string ) )
    705 
    706                   CASE ( 'char' )
    707                      READ( bin_file_unit ) read_string
    708 
    709                   CASE ( 'int8' )
    710                      READ( bin_file_unit ) dummy_int8
    711 
    712                   CASE ( 'int16' )
    713                      READ( bin_file_unit ) dummy_int16
    714 
    715                   CASE ( 'int32' )
    716                      READ( bin_file_unit ) dummy_int32
    717 
    718                   CASE ( 'real32' )
    719                      READ( bin_file_unit ) dummy_real32
    720 
    721                   CASE ( 'real64' )
    722                      READ( bin_file_unit ) dummy_real64
    723 
    724                END SELECT
    725 
    726             ENDDO
    727 
    728          ENDIF
     811         OPEN( bin_file_unit, FILE=bin_filename, FORM='UNFORMATTED', STATUS='OLD' )
     812
     813         CALL internal_message( 'debug', routine_name // &
     814                                ': read binary file ' // TRIM( bin_filename ) )
     815
     816         read_string = ''
     817         DO WHILE ( TRIM( read_string ) /= '*** end file header ***' )
     818
     819            READ( bin_file_unit ) read_string
     820
     821            SELECT CASE ( TRIM( read_string ) )
     822
     823               CASE ( 'char' )
     824                  READ( bin_file_unit ) read_string
     825
     826               CASE ( 'int8' )
     827                  READ( bin_file_unit ) dummy_int8
     828
     829               CASE ( 'int16' )
     830                  READ( bin_file_unit ) dummy_int16
     831
     832               CASE ( 'int32' )
     833                  READ( bin_file_unit ) dummy_int32
     834
     835               CASE ( 'real32' )
     836                  READ( bin_file_unit ) dummy_real32
     837
     838               CASE ( 'real64' )
     839                  READ( bin_file_unit ) dummy_real64
     840
     841            END SELECT
     842
     843         ENDDO
    729844
    730845         !-- Read variable data
     
    873988         CLOSE( bin_file_unit )
    874989
    875       ELSE
    876 
    877          EXIT
    878 
    879990      ENDIF  ! if file exists
    880991
Note: See TracChangeset for help on using the changeset viewer.