Changeset 4141
- Timestamp:
- Aug 5, 2019 12:24:51 PM (5 years ago)
- Location:
- palm/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/data_output_binary_module.f90
r4123 r4141 52 52 IMPLICIT NONE 53 53 54 INTEGER (iwp), PARAMETER :: charlen = 100_iwp!< maximum length of character variables54 INTEGER, PARAMETER :: charlen = 100 !< maximum length of character variables 55 55 56 56 CHARACTER(LEN=*), PARAMETER :: config_file_name = 'BINARY_TO_NETCDF_CONFIG' !< name of config file … … 62 62 CHARACTER(LEN=800) :: temp_string !< dummy string 63 63 64 INTEGER (iwp):: binary_file_lowest_unit = 1000 !< lowest unit number of all binary files created by this module65 INTEGER (iwp):: config_file_unit !< unit number of config file66 INTEGER (iwp):: debug_output_unit !< Fortran Unit Number of the debug-output file67 INTEGER (iwp):: global_id_in_file = -1 !< value of global ID within a file68 INTEGER 69 INTEGER (iwp):: next_available_unit !< next unit number available for new file70 INTEGER 71 72 INTEGER (iwp), DIMENSION(:), ALLOCATABLE :: files_highest_var_id !< highest assigned ID of variable or dimension in a file64 INTEGER :: binary_file_lowest_unit = 1000 !< lowest unit number of all binary files created by this module 65 INTEGER :: config_file_unit !< unit number of config file 66 INTEGER :: debug_output_unit !< Fortran Unit Number of the debug-output file 67 INTEGER :: global_id_in_file = -1 !< value of global ID within a file 68 INTEGER :: master_rank !< master rank for tasks to be executed by single PE only 69 INTEGER :: next_available_unit !< next unit number available for new file 70 INTEGER :: output_group_comm !< MPI communicator addressing all MPI ranks which participate in output 71 72 INTEGER, DIMENSION(:), ALLOCATABLE :: files_highest_variable_id !< highest assigned ID of variable or dimension in a file 73 73 74 74 LOGICAL :: binary_open_file_first_call = .TRUE. !< true if binary_open_file routine was not called yet … … 100 100 END INTERFACE binary_write_attribute 101 101 102 INTERFACE binary_ init_end103 MODULE PROCEDURE binary_ init_end104 END INTERFACE binary_ init_end102 INTERFACE binary_stop_file_header_definition 103 MODULE PROCEDURE binary_stop_file_header_definition 104 END INTERFACE binary_stop_file_header_definition 105 105 106 106 INTERFACE binary_write_variable … … 120 120 binary_get_error_message, & 121 121 binary_init_dimension, & 122 binary_ init_end, &122 binary_stop_file_header_definition, & 123 123 binary_init_module, & 124 124 binary_init_variable, & … … 143 143 !> must be unique for each output group 144 144 145 INTEGER (iwp), INTENT(IN) :: dom_global_id !< global id within a file defined by DOM146 INTEGER, 147 INTEGER, 148 INTEGER (iwp), INTENT(IN) :: program_debug_output_unit !< file unit number for debug output145 INTEGER, INTENT(IN) :: dom_global_id !< global id within a file defined by DOM 146 INTEGER, INTENT(IN) :: master_output_rank !< MPI rank executing tasks which must be executed by a single PE 147 INTEGER, INTENT(IN) :: mpi_comm_of_output_group !< MPI communicator specifying the rank group participating in output 148 INTEGER, INTENT(IN) :: program_debug_output_unit !< file unit number for debug output 149 149 150 150 LOGICAL, INTENT(IN) :: debug_output !< if true, debug output is printed … … 167 167 !> Open binary file. 168 168 !--------------------------------------------------------------------------------------------------! 169 SUBROUTINE binary_open_file( mode, file name, file_id, return_value )169 SUBROUTINE binary_open_file( mode, file_name, file_id, return_value ) 170 170 171 171 CHARACTER(LEN=charlen) :: bin_filename = '' !< actual name of binary file 172 CHARACTER(LEN=charlen), INTENT(IN) :: file name!< name of file172 CHARACTER(LEN=charlen), INTENT(IN) :: file_name !< name of file 173 173 CHARACTER(LEN=7) :: my_rank_char !< string containing value of my_rank with leading zeros 174 174 CHARACTER(LEN=*), INTENT(IN) :: mode !< operation mode … … 176 176 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_open_file' !< name of this routine 177 177 178 INTEGER (iwp), INTENT(OUT) :: file_id !< file ID179 INTEGER 180 INTEGER :: nrank!< number of MPI ranks participating in output181 INTEGER (iwp), INTENT(OUT) :: return_value !< return value182 183 INTEGER (iwp), DIMENSION(:), ALLOCATABLE :: files_highest_var_id_tmp !< temporary list of given variable IDs in file178 INTEGER, INTENT(OUT) :: file_id !< file ID 179 INTEGER :: my_rank !< MPI rank of local processor 180 INTEGER :: nranks !< number of MPI ranks participating in output 181 INTEGER, INTENT(OUT) :: return_value !< return value 182 183 INTEGER, DIMENSION(:), ALLOCATABLE :: files_highest_variable_id_tmp !< temporary list of given variable IDs in file 184 184 185 185 LOGICAL :: file_exists !< true if file to be opened already exists … … 189 189 190 190 #if defined( __parallel ) 191 CALL MPI_COMM_SIZE( output_group_comm, nrank , return_value )191 CALL MPI_COMM_SIZE( output_group_comm, nranks, return_value ) 192 192 IF ( return_value == 0 ) CALL MPI_COMM_RANK( output_group_comm, my_rank, return_value ) 193 193 IF ( return_value == 0 ) THEN … … 197 197 ENDIF 198 198 #else 199 nrank = 1199 nranks = 1 200 200 my_rank = master_rank 201 201 WRITE( my_rank_char, '("_",I6.6)' ) my_rank … … 237 237 238 238 !-- Write some general information to config file 239 WRITE( config_file_unit ) nrank 239 WRITE( config_file_unit ) nranks 240 240 WRITE( config_file_unit ) master_rank 241 241 WRITE( config_file_unit ) LEN( file_prefix ) … … 260 260 IF ( return_value == 0 ) THEN 261 261 262 bin_filename = file_prefix // TRIM( file name ) // TRIM( file_suffix ) // my_rank_char262 bin_filename = file_prefix // TRIM( file_name ) // TRIM( file_suffix ) // my_rank_char 263 263 264 264 !-- Remove any pre-existing file … … 267 267 IF ( file_exists ) THEN 268 268 CALL internal_message( 'debug', routine_name // & 269 269 ': remove existing file ' // TRIM( bin_filename ) ) 270 270 !> @note Fortran2008 feature 'EXECUTE_COMMAND_LINE' not yet supported by 271 271 !> PGI 18.10 compiler. Hence, non-standard 'SYSTEM' call must be used … … 282 282 IF ( return_value == 0 ) THEN 283 283 284 !-- Add file name to config file284 !-- Add file_name to config file 285 285 IF ( my_rank == master_rank ) THEN 286 WRITE( config_file_unit ) file name286 WRITE( config_file_unit ) file_name 287 287 ENDIF 288 288 … … 294 294 WRITE ( file_id ) charlen 295 295 WRITE ( file_id ) file_id 296 WRITE ( file_id ) file name296 WRITE ( file_id ) file_name 297 297 298 298 !-- Extend file-variable/dimension-ID list by 1 and set it to 0 for new file. 299 IF ( ALLOCATED( files_highest_var _id ) ) THEN300 ALLOCATE( files_highest_var _id_tmp(SIZE( files_highest_var_id )) )301 files_highest_var _id_tmp = files_highest_var_id302 DEALLOCATE( files_highest_var _id )303 ALLOCATE( files_highest_var _id(binary_file_lowest_unit+1:file_id) )304 files_highest_var _id(:file_id-1) = files_highest_var_id_tmp305 DEALLOCATE( files_highest_var _id_tmp )299 IF ( ALLOCATED( files_highest_variable_id ) ) THEN 300 ALLOCATE( files_highest_variable_id_tmp(SIZE( files_highest_variable_id )) ) 301 files_highest_variable_id_tmp = files_highest_variable_id 302 DEALLOCATE( files_highest_variable_id ) 303 ALLOCATE( files_highest_variable_id(binary_file_lowest_unit+1:file_id) ) 304 files_highest_variable_id(:file_id-1) = files_highest_variable_id_tmp 305 DEALLOCATE( files_highest_variable_id_tmp ) 306 306 ELSE 307 ALLOCATE( files_highest_var _id(binary_file_lowest_unit+1:file_id) )307 ALLOCATE( files_highest_variable_id(binary_file_lowest_unit+1:file_id) ) 308 308 ENDIF 309 files_highest_var _id(file_id) = 0_iwp309 files_highest_variable_id(file_id) = 0 310 310 311 311 ELSE 312 312 return_value = 1 313 313 CALL internal_message( 'error', routine_name // & 314 ': could not open file "' // TRIM( filename ) // '"')314 ': could not open file "' // TRIM( file_name ) // '"') 315 315 ENDIF 316 316 … … 324 324 !> Write attribute to file. 325 325 !--------------------------------------------------------------------------------------------------! 326 SUBROUTINE binary_write_attribute( file_id, var _id, att_name, att_value_char, &327 att_value_int8, att_value_int16, att_value_int32,&328 att_value_real32, att_value_real64, return_value )326 SUBROUTINE binary_write_attribute( file_id, variable_id, attribute_name, & 327 value_char, value_int8, value_int16, value_int32, & 328 value_real32, value_real64, return_value ) 329 329 330 330 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_write_attribute' !< name of this routine 331 331 332 CHARACTER(LEN=charlen), INTENT(IN) :: att _name !< name of attribute333 CHARACTER(LEN=charlen), INTENT(IN), OPTIONAL :: att_value_char !< value of attribute334 CHARACTER(LEN=charlen) :: att _type !< data type of attribute335 CHARACTER(LEN=charlen) :: out _str!< output string336 337 INTEGER(KIND=1), INTENT(IN), OPTIONAL :: att_value_int8 !< value of attribute338 INTEGER(KIND=2), INTENT(IN), OPTIONAL :: att_value_int16 !< value of attribute339 INTEGER(KIND=4), INTENT(IN), OPTIONAL :: att_value_int32 !< value of attribute340 341 INTEGER (iwp), INTENT(IN) :: file_id !< file ID342 INTEGER (iwp), INTENT(IN) :: var_id!< variable ID343 INTEGER (iwp), INTENT(OUT) :: return_value !< return value344 345 REAL(KIND=4), INTENT(IN), OPTIONAL :: att_value_real32 !< value of attribute346 REAL(KIND=8), INTENT(IN), OPTIONAL :: att_value_real64 !< value of attribute332 CHARACTER(LEN=charlen), INTENT(IN) :: attribute_name !< name of attribute 333 CHARACTER(LEN=charlen), INTENT(IN), OPTIONAL :: value_char !< value of attribute 334 CHARACTER(LEN=charlen) :: attribute_type !< data type of attribute 335 CHARACTER(LEN=charlen) :: output_string !< output string 336 337 INTEGER(KIND=1), INTENT(IN), OPTIONAL :: value_int8 !< value of attribute 338 INTEGER(KIND=2), INTENT(IN), OPTIONAL :: value_int16 !< value of attribute 339 INTEGER(KIND=4), INTENT(IN), OPTIONAL :: value_int32 !< value of attribute 340 341 INTEGER, INTENT(IN) :: file_id !< file ID 342 INTEGER, INTENT(IN) :: variable_id !< variable ID 343 INTEGER, INTENT(OUT) :: return_value !< return value 344 345 REAL(KIND=4), INTENT(IN), OPTIONAL :: value_real32 !< value of attribute 346 REAL(KIND=8), INTENT(IN), OPTIONAL :: value_real64 !< value of attribute 347 347 348 348 … … 350 350 351 351 CALL internal_message( 'debug', TRIM( routine_name ) // & 352 ': write attribute ' // TRIM( att_name ) )352 ': write attribute ' // TRIM( attribute_name ) ) 353 353 354 354 !-- Write attribute to file 355 out _str= 'attribute'356 WRITE( file_id ) out _str357 358 WRITE( file_id ) var _id359 WRITE( file_id ) att _name360 361 IF ( PRESENT( att_value_char ) ) THEN362 att _type = 'char'363 WRITE( file_id ) att _type364 WRITE( file_id ) att_value_char365 ELSEIF ( PRESENT( att_value_int8 ) ) THEN366 att _type = 'int8'367 WRITE( file_id ) att _type368 WRITE( file_id ) att_value_int8369 ELSEIF ( PRESENT( att_value_int16 ) ) THEN370 att _type = 'int16'371 WRITE( file_id ) att _type372 WRITE( file_id ) att_value_int16373 ELSEIF ( PRESENT( att_value_int32 ) ) THEN374 att _type = 'int32'375 WRITE( file_id ) att _type376 WRITE( file_id ) att_value_int32377 ELSEIF ( PRESENT( att_value_real32 ) ) THEN378 att _type = 'real32'379 WRITE( file_id ) att _type380 WRITE( file_id ) att_value_real32381 ELSEIF ( PRESENT( att_value_real64 ) ) THEN382 att _type = 'real64'383 WRITE( file_id ) att _type384 WRITE( file_id ) att_value_real64355 output_string = 'attribute' 356 WRITE( file_id ) output_string 357 358 WRITE( file_id ) variable_id 359 WRITE( file_id ) attribute_name 360 361 IF ( PRESENT( value_char ) ) THEN 362 attribute_type = 'char' 363 WRITE( file_id ) attribute_type 364 WRITE( file_id ) value_char 365 ELSEIF ( PRESENT( value_int8 ) ) THEN 366 attribute_type = 'int8' 367 WRITE( file_id ) attribute_type 368 WRITE( file_id ) value_int8 369 ELSEIF ( PRESENT( value_int16 ) ) THEN 370 attribute_type = 'int16' 371 WRITE( file_id ) attribute_type 372 WRITE( file_id ) value_int16 373 ELSEIF ( PRESENT( value_int32 ) ) THEN 374 attribute_type = 'int32' 375 WRITE( file_id ) attribute_type 376 WRITE( file_id ) value_int32 377 ELSEIF ( PRESENT( value_real32 ) ) THEN 378 attribute_type = 'real32' 379 WRITE( file_id ) attribute_type 380 WRITE( file_id ) value_real32 381 ELSEIF ( PRESENT( value_real64 ) ) THEN 382 attribute_type = 'real64' 383 WRITE( file_id ) attribute_type 384 WRITE( file_id ) value_real64 385 385 ELSE 386 386 return_value = 1 387 387 CALL internal_message( 'error', TRIM( routine_name ) // & 388 ': attribute "' // TRIM( att_name ) // '": no value given' )388 ': no value given for attribute "' // TRIM( attribute_name ) // '"' ) 389 389 ENDIF 390 390 … … 394 394 ! Description: 395 395 ! ------------ 396 !> Initialize dimension. Write information in file header and save dimension397 !> values to be later written to file.398 !--------------------------------------------------------------------------------------------------! 399 SUBROUTINE binary_init_dimension( mode, file_id, dim _id, var_id, &400 dim _name, dim_type, dim_length, return_value )401 402 CHARACTER(LEN=charlen), INTENT(IN) :: dim _name !< name of dimension403 CHARACTER(LEN=charlen), INTENT(IN) :: dim _type !< data type of dimension404 CHARACTER(LEN=charlen) :: out _str!< output string405 CHARACTER(LEN=*), INTENT(IN) :: mode !< operation mode396 !> Initialize dimension. Write information in file header 397 !> and save dimension values to be later written to file. 398 !--------------------------------------------------------------------------------------------------! 399 SUBROUTINE binary_init_dimension( mode, file_id, dimension_id, variable_id, & 400 dimension_name, dimension_type, dimension_length, return_value ) 401 402 CHARACTER(LEN=charlen), INTENT(IN) :: dimension_name !< name of dimension 403 CHARACTER(LEN=charlen), INTENT(IN) :: dimension_type !< data type of dimension 404 CHARACTER(LEN=charlen) :: output_string !< output string 405 CHARACTER(LEN=*), INTENT(IN) :: mode !< operation mode 406 406 407 407 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_init_dimension' !< name of this routine 408 408 409 INTEGER (iwp), INTENT(OUT) :: dim_id!< dimension ID410 INTEGER (iwp), INTENT(IN) :: dim_length!< length of dimension411 INTEGER (iwp), INTENT(IN) :: file_id!< file ID412 INTEGER (iwp), INTENT(OUT) :: return_value!< return value413 INTEGER (iwp), INTENT(OUT) :: var_id!< variable ID409 INTEGER, INTENT(OUT) :: dimension_id !< dimension ID 410 INTEGER, INTENT(IN) :: dimension_length !< length of dimension 411 INTEGER, INTENT(IN) :: file_id !< file ID 412 INTEGER, INTENT(OUT) :: return_value !< return value 413 INTEGER, INTENT(OUT) :: variable_id !< variable ID 414 414 415 415 416 416 return_value = 0 417 417 418 CALL internal_message( 'debug', routine_name // ': init dimension ' // TRIM( dim _name ) )418 CALL internal_message( 'debug', routine_name // ': init dimension ' // TRIM( dimension_name ) ) 419 419 420 420 !-- Check mode (not required, added for compatibility reasons only) … … 422 422 423 423 !-- Assign dimension ID 424 dim _id = files_highest_var_id( file_id ) + 1425 files_highest_var _id( file_id ) = dim_id424 dimension_id = files_highest_variable_id( file_id ) + 1 425 files_highest_variable_id( file_id ) = dimension_id 426 426 427 427 !-- Define dimension in file 428 out _str= 'dimension'429 WRITE( file_id ) out _str430 WRITE( file_id ) dim _name431 WRITE( file_id ) dim _id432 WRITE( file_id ) dim _type433 WRITE( file_id ) dim _length428 output_string = 'dimension' 429 WRITE( file_id ) output_string 430 WRITE( file_id ) dimension_name 431 WRITE( file_id ) dimension_id 432 WRITE( file_id ) dimension_type 433 WRITE( file_id ) dimension_length 434 434 435 435 !-- Define variable associated with dimension 436 CALL binary_init_variable( mode, file_id, var _id, dim_name, dim_type, (/dim_id/), &437 is_global=.TRUE., return_value=return_value )436 CALL binary_init_variable( mode, file_id, variable_id, dimension_name, dimension_type, & 437 (/ dimension_id /), is_global=.TRUE., return_value=return_value ) 438 438 IF ( return_value /= 0 ) THEN 439 439 CALL internal_message( 'error', routine_name // & 440 ': init dimension "' // TRIM( dim_name ) // '"' )440 ': init dimension "' // TRIM( dimension_name ) // '"' ) 441 441 ENDIF 442 442 … … 448 448 !> Initialize variable. Write information of variable into file header. 449 449 !--------------------------------------------------------------------------------------------------! 450 SUBROUTINE binary_init_variable( mode, file_id, var _id, var_name, var_type, &451 var_dim_ids, is_global, return_value )452 453 CHARACTER(LEN=charlen) :: out _str!< output string454 CHARACTER(LEN=charlen), INTENT(IN) :: var _name!< name of variable455 CHARACTER(LEN=charlen), INTENT(IN) :: var _type!< data type of variable456 CHARACTER(LEN=*), INTENT(IN) :: mode !< operation mode450 SUBROUTINE binary_init_variable( mode, file_id, variable_id, variable_name, variable_type, & 451 dimension_ids, is_global, return_value ) 452 453 CHARACTER(LEN=charlen) :: output_string !< output string 454 CHARACTER(LEN=charlen), INTENT(IN) :: variable_name !< name of variable 455 CHARACTER(LEN=charlen), INTENT(IN) :: variable_type !< data type of variable 456 CHARACTER(LEN=*), INTENT(IN) :: mode !< operation mode 457 457 458 458 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_init_variable' !< name of this routine 459 459 460 INTEGER (iwp), INTENT(IN) :: file_id !< file ID461 INTEGER (iwp), INTENT(OUT) :: var_id!< variable ID462 INTEGER (iwp), INTENT(OUT) :: return_value !< return value463 464 INTEGER (iwp), DIMENSION(:), INTENT(IN) :: var_dim_ids !< list of dimension IDs used by variable460 INTEGER, INTENT(IN) :: file_id !< file ID 461 INTEGER, INTENT(OUT) :: variable_id !< variable ID 462 INTEGER, INTENT(OUT) :: return_value !< return value 463 464 INTEGER, DIMENSION(:), INTENT(IN) :: dimension_ids !< list of dimension IDs used by variable 465 465 466 466 LOGICAL, INTENT(IN) :: is_global !< true if variable is global (same on all PE) … … 469 469 return_value = 0 470 470 471 CALL internal_message( 'debug', routine_name // ': init variable ' // TRIM( var _name ) )471 CALL internal_message( 'debug', routine_name // ': init variable ' // TRIM( variable_name ) ) 472 472 473 473 !-- Check mode (not required, added for compatibility reasons only) … … 478 478 479 479 !-- Assign variable ID 480 var _id = files_highest_var_id( file_id ) + 1481 files_highest_var _id( file_id ) = var_id480 variable_id = files_highest_variable_id( file_id ) + 1 481 files_highest_variable_id( file_id ) = variable_id 482 482 483 483 !-- Write variable information in file 484 out _str= 'variable'485 WRITE( file_id ) out _str486 WRITE( file_id ) var _name487 WRITE( file_id ) var _id488 WRITE( file_id ) var _type489 WRITE( file_id ) SIZE( var_dim_ids )490 WRITE( file_id ) var_dim_ids484 output_string = 'variable' 485 WRITE( file_id ) output_string 486 WRITE( file_id ) variable_name 487 WRITE( file_id ) variable_id 488 WRITE( file_id ) variable_type 489 WRITE( file_id ) SIZE( dimension_ids ) 490 WRITE( file_id ) dimension_ids 491 491 492 492 END SUBROUTINE binary_init_variable … … 497 497 !> Leave file definition state. 498 498 !--------------------------------------------------------------------------------------------------! 499 SUBROUTINE binary_ init_end( file_id, return_value )500 501 CHARACTER(LEN=charlen) :: out _str!< output string502 503 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_ init_end' !< name of this routine504 505 INTEGER (iwp), INTENT(IN) :: file_id !< file ID506 INTEGER (iwp), INTENT(OUT) :: return_value !< return value499 SUBROUTINE binary_stop_file_header_definition( file_id, return_value ) 500 501 CHARACTER(LEN=charlen) :: output_string !< output string 502 503 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_stop_file_header_definition' !< name of this routine 504 505 INTEGER, INTENT(IN) :: file_id !< file ID 506 INTEGER, INTENT(OUT) :: return_value !< return value 507 507 508 508 … … 510 510 511 511 WRITE( temp_string, * ) file_id 512 CALL internal_message( 'debug', & 513 routine_name // & 512 CALL internal_message( 'debug', routine_name // & 514 513 ': finalize file definition (file_id=' // TRIM( temp_string ) // ')' ) 515 514 516 out _str= '*** end file header ***'517 WRITE( file_id ) out _str518 519 END SUBROUTINE binary_ init_end515 output_string = '*** end file header ***' 516 WRITE( file_id ) output_string 517 518 END SUBROUTINE binary_stop_file_header_definition 520 519 521 520 !--------------------------------------------------------------------------------------------------! … … 524 523 !> Write variable to file. 525 524 !--------------------------------------------------------------------------------------------------! 526 SUBROUTINE binary_write_variable( &527 file_id, var _id, bounds_start, value_counts, bounds_origin,&528 is_global, &529 va r_int8_0d, var_int8_1d, var_int8_2d, var_int8_3d, &530 va r_int16_0d, var_int16_1d, var_int16_2d, var_int16_3d, &531 va r_int32_0d, var_int32_1d, var_int32_2d, var_int32_3d, &532 va r_intwp_0d, var_intwp_1d, var_intwp_2d, var_intwp_3d, &533 va r_real32_0d, var_real32_1d, var_real32_2d, var_real32_3d, &534 va r_real64_0d, var_real64_1d, var_real64_2d, var_real64_3d, &535 va r_realwp_0d, var_realwp_1d, var_realwp_2d, var_realwp_3d, &525 SUBROUTINE binary_write_variable( & 526 file_id, variable_id, bounds_start, value_counts, bounds_origin, & 527 is_global, & 528 values_int8_0d, values_int8_1d, values_int8_2d, values_int8_3d, & 529 values_int16_0d, values_int16_1d, values_int16_2d, values_int16_3d, & 530 values_int32_0d, values_int32_1d, values_int32_2d, values_int32_3d, & 531 values_intwp_0d, values_intwp_1d, values_intwp_2d, values_intwp_3d, & 532 values_real32_0d, values_real32_1d, values_real32_2d, values_real32_3d, & 533 values_real64_0d, values_real64_1d, values_real64_2d, values_real64_3d, & 534 values_realwp_0d, values_realwp_1d, values_realwp_2d, values_realwp_3d, & 536 535 return_value ) 537 536 538 CHARACTER(LEN=charlen) :: out _str!< output string537 CHARACTER(LEN=charlen) :: output_string !< output string 539 538 540 539 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_write_variable' !< name of this routine 541 540 542 INTEGER(iwp), INTENT(IN) :: file_id !< file ID 543 INTEGER(iwp), INTENT(OUT) :: return_value !< return value 544 INTEGER(iwp), INTENT(IN) :: var_id !< variable ID 545 546 INTEGER(iwp), DIMENSION(:), INTENT(IN) :: bounds_origin !< starting index of each dimension 547 INTEGER(iwp), DIMENSION(:), INTENT(IN) :: bounds_start !< starting index of variable 548 INTEGER(iwp), DIMENSION(:), INTENT(IN) :: value_counts !< count of values along each dimension to be written 549 550 INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL :: var_int8_0d !< output variable 551 INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_int8_1d !< output variable 552 INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_int8_2d !< output variable 553 INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_int8_3d !< output variable 554 555 INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL :: var_int16_0d !< output variable 556 INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_int16_1d !< output variable 557 INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_int16_2d !< output variable 558 INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_int16_3d !< output variable 559 560 INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL :: var_int32_0d !< output variable 561 INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_int32_1d !< output variable 562 INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_int32_2d !< output variable 563 INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_int32_3d !< output variable 564 565 INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL :: var_intwp_0d !< output variable 566 INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_intwp_1d !< output variable 567 INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_intwp_2d !< output variable 568 INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_intwp_3d !< output variable 541 INTEGER, INTENT(IN) :: file_id !< file ID 542 INTEGER, INTENT(OUT) :: return_value !< return value 543 INTEGER, INTENT(IN) :: variable_id !< variable ID 544 545 INTEGER, DIMENSION(:), INTENT(IN) :: bounds_origin !< starting index of each dimension 546 INTEGER, DIMENSION(:), INTENT(IN) :: bounds_start !< starting index of variable 547 INTEGER, DIMENSION(:), INTENT(IN) :: value_counts !< count of values along each dimension to be written 548 549 INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL :: values_int8_0d !< output variable 550 INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL :: values_int16_0d !< output variable 551 INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL :: values_int32_0d !< output variable 552 INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL :: values_intwp_0d !< output variable 553 INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int8_1d !< output variable 554 INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int16_1d !< output variable 555 INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int32_1d !< output variable 556 INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_intwp_1d !< output variable 557 INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int8_2d !< output variable 558 INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int16_2d !< output variable 559 INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int32_2d !< output variable 560 INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_intwp_2d !< output variable 561 INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int8_3d !< output variable 562 INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int16_3d !< output variable 563 INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int32_3d !< output variable 564 INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_intwp_3d !< output variable 569 565 570 566 LOGICAL, INTENT(IN) :: is_global !< true if variable is global (same on all PE) 571 567 572 REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL :: var_real32_0d !< output variable 573 REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_real32_1d !< output variable 574 REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_real32_2d !< output variable 575 REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_real32_3d !< output variable 576 577 REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL :: var_real64_0d !< output variable 578 REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_real64_1d !< output variable 579 REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_real64_2d !< output variable 580 REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_real64_3d !< output variable 581 582 REAL(wp), POINTER, INTENT(IN), OPTIONAL :: var_realwp_0d !< output variable 583 REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: var_realwp_1d !< output variable 584 REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: var_realwp_2d !< output variable 585 REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: var_realwp_3d !< output variable 568 REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL :: values_real32_0d !< output variable 569 REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL :: values_real64_0d !< output variable 570 REAL(wp), POINTER, INTENT(IN), OPTIONAL :: values_realwp_0d !< output variable 571 REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_real32_1d !< output variable 572 REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_real64_1d !< output variable 573 REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_realwp_1d !< output variable 574 REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_real32_2d !< output variable 575 REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_real64_2d !< output variable 576 REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_realwp_2d !< output variable 577 REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_real32_3d !< output variable 578 REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_real64_3d !< output variable 579 REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_realwp_3d !< output variable 586 580 587 581 588 582 return_value = 0 589 583 590 WRITE( temp_string, '(": write variable ",I6," into file ",I6)' ) var _id, file_id584 WRITE( temp_string, '(": write variable ",I6," into file ",I6)' ) variable_id, file_id 591 585 CALL internal_message( 'debug', routine_name // TRIM( temp_string ) ) 592 586 … … 594 588 595 589 IF ( .NOT. ANY( value_counts == 0 ) ) THEN 596 WRITE( file_id ) var _id590 WRITE( file_id ) variable_id 597 591 WRITE( file_id ) bounds_start 598 592 WRITE( file_id ) value_counts 599 593 WRITE( file_id ) bounds_origin 600 594 !-- 8bit integer output 601 IF ( PRESENT( va r_int8_0d ) ) THEN602 out _str= 'int8'603 WRITE( file_id ) out _str604 WRITE( file_id ) va r_int8_0d605 ELSEIF ( PRESENT( va r_int8_1d ) ) THEN606 out _str= 'int8'607 WRITE( file_id ) out _str608 WRITE( file_id ) va r_int8_1d609 ELSEIF ( PRESENT( va r_int8_2d ) ) THEN610 out _str= 'int8'611 WRITE( file_id ) out _str612 WRITE( file_id ) va r_int8_2d613 ELSEIF ( PRESENT( va r_int8_3d ) ) THEN614 out _str= 'int8'615 WRITE( file_id ) out _str616 WRITE( file_id ) va r_int8_3d595 IF ( PRESENT( values_int8_0d ) ) THEN 596 output_string = 'int8' 597 WRITE( file_id ) output_string 598 WRITE( file_id ) values_int8_0d 599 ELSEIF ( PRESENT( values_int8_1d ) ) THEN 600 output_string = 'int8' 601 WRITE( file_id ) output_string 602 WRITE( file_id ) values_int8_1d 603 ELSEIF ( PRESENT( values_int8_2d ) ) THEN 604 output_string = 'int8' 605 WRITE( file_id ) output_string 606 WRITE( file_id ) values_int8_2d 607 ELSEIF ( PRESENT( values_int8_3d ) ) THEN 608 output_string = 'int8' 609 WRITE( file_id ) output_string 610 WRITE( file_id ) values_int8_3d 617 611 !-- 16bit integer output 618 ELSEIF ( PRESENT( va r_int16_0d ) ) THEN619 out _str= 'int16'620 WRITE( file_id ) out _str621 WRITE( file_id ) va r_int16_0d622 ELSEIF ( PRESENT( va r_int16_1d ) ) THEN623 out _str= 'int16'624 WRITE( file_id ) out _str625 WRITE( file_id ) va r_int16_1d626 ELSEIF ( PRESENT( va r_int16_2d ) ) THEN627 out _str= 'int16'628 WRITE( file_id ) out _str629 WRITE( file_id ) va r_int16_2d630 ELSEIF ( PRESENT( va r_int16_3d ) ) THEN631 out _str= 'int16'632 WRITE( file_id ) out _str633 WRITE( file_id ) va r_int16_3d612 ELSEIF ( PRESENT( values_int16_0d ) ) THEN 613 output_string = 'int16' 614 WRITE( file_id ) output_string 615 WRITE( file_id ) values_int16_0d 616 ELSEIF ( PRESENT( values_int16_1d ) ) THEN 617 output_string = 'int16' 618 WRITE( file_id ) output_string 619 WRITE( file_id ) values_int16_1d 620 ELSEIF ( PRESENT( values_int16_2d ) ) THEN 621 output_string = 'int16' 622 WRITE( file_id ) output_string 623 WRITE( file_id ) values_int16_2d 624 ELSEIF ( PRESENT( values_int16_3d ) ) THEN 625 output_string = 'int16' 626 WRITE( file_id ) output_string 627 WRITE( file_id ) values_int16_3d 634 628 !-- 32bit integer output 635 ELSEIF ( PRESENT( va r_int32_0d ) ) THEN636 out _str= 'int32'637 WRITE( file_id ) out _str638 WRITE( file_id ) va r_int32_0d639 ELSEIF ( PRESENT( va r_int32_1d ) ) THEN640 out _str= 'int32'641 WRITE( file_id ) out _str642 WRITE( file_id ) va r_int32_1d643 ELSEIF ( PRESENT( va r_int32_2d ) ) THEN644 out _str= 'int32'645 WRITE( file_id ) out _str646 WRITE( file_id ) va r_int32_2d647 ELSEIF ( PRESENT( va r_int32_3d ) ) THEN648 out _str= 'int32'649 WRITE( file_id ) out _str650 WRITE( file_id ) va r_int32_3d629 ELSEIF ( PRESENT( values_int32_0d ) ) THEN 630 output_string = 'int32' 631 WRITE( file_id ) output_string 632 WRITE( file_id ) values_int32_0d 633 ELSEIF ( PRESENT( values_int32_1d ) ) THEN 634 output_string = 'int32' 635 WRITE( file_id ) output_string 636 WRITE( file_id ) values_int32_1d 637 ELSEIF ( PRESENT( values_int32_2d ) ) THEN 638 output_string = 'int32' 639 WRITE( file_id ) output_string 640 WRITE( file_id ) values_int32_2d 641 ELSEIF ( PRESENT( values_int32_3d ) ) THEN 642 output_string = 'int32' 643 WRITE( file_id ) output_string 644 WRITE( file_id ) values_int32_3d 651 645 !-- working-precision integer output 652 ELSEIF ( PRESENT( va r_intwp_0d ) ) THEN653 out _str= 'intwp'654 WRITE( file_id ) out _str655 WRITE( file_id ) va r_intwp_0d656 ELSEIF ( PRESENT( va r_intwp_1d ) ) THEN657 out _str= 'intwp'658 WRITE( file_id ) out _str659 WRITE( file_id ) va r_intwp_1d660 ELSEIF ( PRESENT( va r_intwp_2d ) ) THEN661 out _str= 'intwp'662 WRITE( file_id ) out _str663 WRITE( file_id ) va r_intwp_2d664 ELSEIF ( PRESENT( va r_intwp_3d ) ) THEN665 out _str= 'intwp'666 WRITE( file_id ) out _str667 WRITE( file_id ) va r_intwp_3d646 ELSEIF ( PRESENT( values_intwp_0d ) ) THEN 647 output_string = 'intwp' 648 WRITE( file_id ) output_string 649 WRITE( file_id ) values_intwp_0d 650 ELSEIF ( PRESENT( values_intwp_1d ) ) THEN 651 output_string = 'intwp' 652 WRITE( file_id ) output_string 653 WRITE( file_id ) values_intwp_1d 654 ELSEIF ( PRESENT( values_intwp_2d ) ) THEN 655 output_string = 'intwp' 656 WRITE( file_id ) output_string 657 WRITE( file_id ) values_intwp_2d 658 ELSEIF ( PRESENT( values_intwp_3d ) ) THEN 659 output_string = 'intwp' 660 WRITE( file_id ) output_string 661 WRITE( file_id ) values_intwp_3d 668 662 !-- 32bit real output 669 ELSEIF ( PRESENT( va r_real32_0d ) ) THEN670 out _str= 'real32'671 WRITE( file_id ) out _str672 WRITE( file_id ) va r_real32_0d673 ELSEIF ( PRESENT( va r_real32_1d ) ) THEN674 out _str= 'real32'675 WRITE( file_id ) out _str676 WRITE( file_id ) va r_real32_1d677 ELSEIF ( PRESENT( va r_real32_2d ) ) THEN678 out _str= 'real32'679 WRITE( file_id ) out _str680 WRITE( file_id ) va r_real32_2d681 ELSEIF ( PRESENT( va r_real32_3d ) ) THEN682 out _str= 'real32'683 WRITE( file_id ) out _str684 WRITE( file_id ) va r_real32_3d663 ELSEIF ( PRESENT( values_real32_0d ) ) THEN 664 output_string = 'real32' 665 WRITE( file_id ) output_string 666 WRITE( file_id ) values_real32_0d 667 ELSEIF ( PRESENT( values_real32_1d ) ) THEN 668 output_string = 'real32' 669 WRITE( file_id ) output_string 670 WRITE( file_id ) values_real32_1d 671 ELSEIF ( PRESENT( values_real32_2d ) ) THEN 672 output_string = 'real32' 673 WRITE( file_id ) output_string 674 WRITE( file_id ) values_real32_2d 675 ELSEIF ( PRESENT( values_real32_3d ) ) THEN 676 output_string = 'real32' 677 WRITE( file_id ) output_string 678 WRITE( file_id ) values_real32_3d 685 679 !-- 64bit real output 686 ELSEIF ( PRESENT( va r_real64_0d ) ) THEN687 out _str= 'real64'688 WRITE( file_id ) out _str689 WRITE( file_id ) va r_real64_0d690 ELSEIF ( PRESENT( va r_real64_1d ) ) THEN691 out _str= 'real64'692 WRITE( file_id ) out _str693 WRITE( file_id ) va r_real64_1d694 ELSEIF ( PRESENT( va r_real64_2d ) ) THEN695 out _str= 'real64'696 WRITE( file_id ) out _str697 WRITE( file_id ) va r_real64_2d698 ELSEIF ( PRESENT( va r_real64_3d ) ) THEN699 out _str= 'real64'700 WRITE( file_id ) out _str701 WRITE( file_id ) va r_real64_3d680 ELSEIF ( PRESENT( values_real64_0d ) ) THEN 681 output_string = 'real64' 682 WRITE( file_id ) output_string 683 WRITE( file_id ) values_real64_0d 684 ELSEIF ( PRESENT( values_real64_1d ) ) THEN 685 output_string = 'real64' 686 WRITE( file_id ) output_string 687 WRITE( file_id ) values_real64_1d 688 ELSEIF ( PRESENT( values_real64_2d ) ) THEN 689 output_string = 'real64' 690 WRITE( file_id ) output_string 691 WRITE( file_id ) values_real64_2d 692 ELSEIF ( PRESENT( values_real64_3d ) ) THEN 693 output_string = 'real64' 694 WRITE( file_id ) output_string 695 WRITE( file_id ) values_real64_3d 702 696 !-- working-precision real output 703 ELSEIF ( PRESENT( va r_realwp_0d ) ) THEN704 out _str= 'realwp'705 WRITE( file_id ) out _str706 WRITE( file_id ) va r_realwp_0d707 ELSEIF ( PRESENT( va r_realwp_1d ) ) THEN708 out _str= 'realwp'709 WRITE( file_id ) out _str710 WRITE( file_id ) va r_realwp_1d711 ELSEIF ( PRESENT( va r_realwp_2d ) ) THEN712 out _str= 'realwp'713 WRITE( file_id ) out _str714 WRITE( file_id ) va r_realwp_2d715 ELSEIF ( PRESENT( va r_realwp_3d ) ) THEN716 out _str= 'realwp'717 WRITE( file_id ) out _str718 WRITE( file_id ) va r_realwp_3d697 ELSEIF ( PRESENT( values_realwp_0d ) ) THEN 698 output_string = 'realwp' 699 WRITE( file_id ) output_string 700 WRITE( file_id ) values_realwp_0d 701 ELSEIF ( PRESENT( values_realwp_1d ) ) THEN 702 output_string = 'realwp' 703 WRITE( file_id ) output_string 704 WRITE( file_id ) values_realwp_1d 705 ELSEIF ( PRESENT( values_realwp_2d ) ) THEN 706 output_string = 'realwp' 707 WRITE( file_id ) output_string 708 WRITE( file_id ) values_realwp_2d 709 ELSEIF ( PRESENT( values_realwp_3d ) ) THEN 710 output_string = 'realwp' 711 WRITE( file_id ) output_string 712 WRITE( file_id ) values_realwp_3d 719 713 ELSE 720 714 return_value = 1 … … 733 727 SUBROUTINE binary_finalize( file_id, return_value ) 734 728 735 CHARACTER(LEN=charlen) :: out _str!< output string729 CHARACTER(LEN=charlen) :: output_string !< output string 736 730 737 731 CHARACTER(LEN=*), PARAMETER :: routine_name = 'binary_finalize' !< name of this routine 738 732 739 INTEGER (iwp), INTENT(IN) :: file_id !< file ID740 INTEGER (iwp), INTENT(OUT) :: return_value !< return value733 INTEGER, INTENT(IN) :: file_id !< file ID 734 INTEGER, INTENT(OUT) :: return_value !< return value 741 735 742 736 743 737 IF ( config_file_open ) THEN 744 738 745 out _str= '*** end config file ***'746 WRITE( config_file_unit ) out _str739 output_string = '*** end config file ***' 740 WRITE( config_file_unit ) output_string 747 741 748 742 CLOSE( config_file_unit, IOSTAT=return_value ) … … 762 756 IF ( return_value == 0 ) THEN 763 757 764 WRITE( temp_string,*) file_id758 WRITE( temp_string, * ) file_id 765 759 CALL internal_message( 'debug', routine_name // & 766 760 ': close file (file_id=' // TRIM( temp_string ) // ')' ) 767 761 768 762 CLOSE( file_id, IOSTAT=return_value ) 769 763 IF ( return_value /= 0 ) THEN 770 WRITE(temp_string,*) file_id 771 CALL internal_message( 'error', & 772 routine_name // & 764 WRITE( temp_string, * ) file_id 765 CALL internal_message( 'error', routine_name // & 773 766 ': cannot close file (file_id=' // TRIM( temp_string ) // ')' ) 774 767 ENDIF … … 778 771 END SUBROUTINE binary_finalize 779 772 780 781 773 !--------------------------------------------------------------------------------------------------! 782 774 ! Description: … … 809 801 !> Return the last created error message. 810 802 !--------------------------------------------------------------------------------------------------! 811 SUBROUTINE binary_get_error_message( error_message ) 812 813 CHARACTER(LEN=800), INTENT(OUT) :: error_message !< return error message to main program 814 815 816 error_message = internal_error_message 817 818 END SUBROUTINE binary_get_error_message 819 803 FUNCTION binary_get_error_message() RESULT( error_message ) 804 805 CHARACTER(LEN=800) :: error_message !< return error message to main program 806 807 808 error_message = TRIM( internal_error_message ) 809 810 internal_error_message = '' 811 812 END FUNCTION binary_get_error_message 820 813 821 814 END MODULE data_output_binary_module -
palm/trunk/SOURCE/data_output_module.f90
r4124 r4141 38 38 !> Data-output module to handle output of variables into output files. 39 39 !> 40 !> The module first creates an interal database containing all meta data of all 41 !> output quantities. Output files are then inititialized and prepared for 42 !> storing data, which are finally written to file. 40 !> The module first creates an interal database containing all meta data of all output quantities. 41 !> After defining all meta data, the output files are initialized and prepared for writing. When 42 !> writing is finished, files can be finalized and closed. 43 !> The order of calls are as follows: 44 !> 1. Initialize the module via 45 !> 'dom_init' 46 !> 2. Define output files via (multiple calls of) 47 !> 'dom_def_file', 'dom_def_att', 'dom_def_dim', 'dom_def_var' 48 !> 3. Leave definition stage via 49 !> 'dom_def_end' 50 !> 4. Write output data into file via 51 !> 'dom_write_var' 52 !> 5. Finalize the output via 53 !> 'dom_finalize_output' 54 !> If any routine exits with a non-zero return value, the error message of the last encountered 55 !> error can be fetched via 'dom_get_error_message'. 56 !> For debugging purposes, the content of the database can be written to the debug output via 57 !> 'dom_database_debug_output'. 43 58 !> 44 59 !> @todo Convert variable if type of given values do not fit specified type. 45 !> @todo Remove iwp from index (and similar) variables.46 60 !--------------------------------------------------------------------------------------------------! 47 61 MODULE data_output_module … … 52 66 ONLY: netcdf4_init_dimension, & 53 67 netcdf4_get_error_message, & 54 netcdf4_ init_end, &68 netcdf4_stop_file_header_definition, & 55 69 netcdf4_init_module, & 56 70 netcdf4_init_variable, & … … 64 78 binary_get_error_message, & 65 79 binary_init_dimension, & 66 binary_ init_end, &80 binary_stop_file_header_definition, & 67 81 binary_init_module, & 68 82 binary_init_variable, & … … 73 87 IMPLICIT NONE 74 88 75 INTEGER(iwp), PARAMETER :: charlen = 100_iwp !< maximum length of character variables 89 INTEGER, PARAMETER :: charlen = 100 !< maximum length of character variables 90 INTEGER, PARAMETER :: no_id = -1 !< default ID if no ID was assigned 76 91 77 92 TYPE attribute_type … … 87 102 88 103 TYPE variable_type 89 CHARACTER(LEN=charlen) :: data_type = '' !< data type90 CHARACTER(LEN=charlen) :: name !< variable name91 INTEGER (iwp) :: id = -1!< id within file92 LOGICAL :: is_global = .FALSE. !< true if global variable93 CHARACTER(LEN=charlen), DIMENSION(:), ALLOCATABLE :: dimension_names !< list of dimension names94 INTEGER (iwp), DIMENSION(:), ALLOCATABLE :: dimension_ids !< list of dimension ids95 TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of attributes104 CHARACTER(LEN=charlen) :: data_type = '' !< data type 105 CHARACTER(LEN=charlen) :: name !< variable name 106 INTEGER :: id = no_id !< id within file 107 LOGICAL :: is_global = .FALSE. !< true if global variable 108 CHARACTER(LEN=charlen), DIMENSION(:), ALLOCATABLE :: dimension_names !< list of dimension names used by variable 109 INTEGER, DIMENSION(:), ALLOCATABLE :: dimension_ids !< list of dimension ids used by variable 110 TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of attributes 96 111 END TYPE variable_type 97 112 98 113 TYPE dimension_type 99 CHARACTER(LEN=charlen) :: data_type = ''!< data type100 CHARACTER(LEN=charlen) :: name!< dimension name101 INTEGER (iwp) :: id = -1!< dimension id within file102 INTEGER (iwp) :: length!< length of dimension103 INTEGER (iwp) :: length_mask!< length of masked dimension104 INTEGER (iwp) :: var_id = -1!< associated variable id within file105 LOGICAL :: is_masked = .FALSE.!< true if masked106 INTEGER (iwp),DIMENSION(2) :: bounds !< lower and upper bound of dimension107 INTEGER (iwp),DIMENSION(:), ALLOCATABLE :: masked_indices !< list of masked indices of dimension114 CHARACTER(LEN=charlen) :: data_type = '' !< data type 115 CHARACTER(LEN=charlen) :: name !< dimension name 116 INTEGER :: id = no_id !< dimension id within file 117 INTEGER :: length !< length of dimension 118 INTEGER :: length_mask !< length of masked dimension 119 INTEGER :: variable_id = no_id !< associated variable id within file 120 LOGICAL :: is_masked = .FALSE. !< true if masked 121 INTEGER, DIMENSION(2) :: bounds !< lower and upper bound of dimension 122 INTEGER, DIMENSION(:), ALLOCATABLE :: masked_indices !< list of masked indices of dimension 108 123 INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE :: masked_values_int8 !< masked dimension values if 16bit integer 109 124 INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE :: masked_values_int16 !< masked dimension values if 16bit integer … … 125 140 126 141 TYPE file_type 127 CHARACTER(LEN=charlen) :: format = '' !< file format128 CHARACTER(LEN=charlen) :: name = '' !< file name129 INTEGER (iwp) :: id = -1!< id of file130 LOGICAL :: is_init = .FALSE. !< true if initialized131 TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of attributes132 TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimensions !< list of dimensions133 TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: variables !< list of variables142 CHARACTER(LEN=charlen) :: format = '' !< file format 143 CHARACTER(LEN=charlen) :: name = '' !< file name 144 INTEGER :: id = no_id !< id of file 145 LOGICAL :: is_init = .FALSE. !< true if initialized 146 TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of attributes 147 TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimensions !< list of dimensions 148 TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: variables !< list of variables 134 149 END TYPE file_type 135 150 136 151 137 CHARACTER(LEN=charlen) :: output_file_format = 'binary' !< file format (namelist parameter) 138 CHARACTER(LEN=charlen) :: output_file_suffix = '' !< file suffix added to each file name 139 140 CHARACTER(LEN=800) :: internal_error_message = '' !< string containing the last error message 141 CHARACTER(LEN=800) :: temp_string !< dummy string 142 143 INTEGER(iwp) :: debug_output_unit !< Fortran Unit Number of the debug-output file 144 INTEGER :: nf = 0 !< number of files 145 INTEGER :: master_rank = 0 !< master rank for tasks to be executed by single PE only 146 INTEGER :: output_group_comm !< MPI communicator addressing all MPI ranks which participate in output 147 148 INTEGER(iwp), PARAMETER :: no_var_id = -1 !< value of var_id if no variable is selected 152 CHARACTER(LEN=charlen) :: output_file_suffix = '' !< file suffix added to each file name 153 CHARACTER(LEN=800) :: internal_error_message = '' !< string containing the last error message 154 CHARACTER(LEN=800) :: temp_string !< dummy string 155 156 INTEGER :: debug_output_unit !< Fortran Unit Number of the debug-output file 157 INTEGER :: nfiles = 0 !< number of files 158 INTEGER :: master_rank = 0 !< master rank for tasks to be executed by single PE only 159 INTEGER :: output_group_comm !< MPI communicator addressing all MPI ranks which participate in output 149 160 150 161 LOGICAL :: print_debug_output = .FALSE. !< if true, debug output is printed … … 187 198 188 199 !> Prepare for output: evaluate database and create files 189 INTERFACE dom_ start_output190 MODULE PROCEDURE dom_ start_output191 END INTERFACE dom_ start_output200 INTERFACE dom_def_end 201 MODULE PROCEDURE dom_def_end 202 END INTERFACE dom_def_end 192 203 193 204 !> Write variables to file … … 206 217 END INTERFACE dom_get_error_message 207 218 219 !> Write database to debug output 220 INTERFACE dom_database_debug_output 221 MODULE PROCEDURE dom_database_debug_output 222 END INTERFACE dom_database_debug_output 223 208 224 PUBLIC & 209 dom_database_debug_output, & 225 dom_init, & 226 dom_def_file, & 227 dom_def_dim, & 228 dom_def_var, & 210 229 dom_def_att, & 211 dom_def_dim, & 212 dom_def_file, & 213 dom_def_var, & 230 dom_def_end, & 231 dom_write_var, & 214 232 dom_finalize_output, & 215 233 dom_get_error_message, & 216 dom_init, & 217 dom_start_output, & 218 dom_write_var 234 dom_database_debug_output 219 235 220 236 CONTAINS … … 224 240 ! Description: 225 241 ! ------------ 226 !> Initialize data-output module 242 !> Initialize data-output module. 243 !> Provide some general information of the main program. 244 !> The optional argument 'file_suffix_of_output_group' defines a file suffix which is added to all 245 !> output files. If multiple output groups (groups of MPI ranks, defined by 246 !> 'mpi_comm_of_output_group') exist, a unique file suffix must be given for each group. This 247 !> prevents that multiple groups try to open and write to the same output file. 227 248 !--------------------------------------------------------------------------------------------------! 228 249 SUBROUTINE dom_init( file_suffix_of_output_group, mpi_comm_of_output_group, master_output_rank, & … … 238 259 INTEGER, INTENT(IN) :: program_debug_output_unit !< file unit number for debug output 239 260 240 LOGICAL, INTENT(IN) :: debug_output!< if true, debug output is printed261 LOGICAL, INTENT(IN) :: debug_output !< if true, debug output is printed 241 262 242 263 … … 250 271 251 272 CALL binary_init_module( output_file_suffix, output_group_comm, master_rank, & 252 debug_output_unit, debug_output, no_ var_id )273 debug_output_unit, debug_output, no_id ) 253 274 254 275 CALL netcdf4_init_module( output_file_suffix, output_group_comm, master_rank, & 255 debug_output_unit, debug_output, no_ var_id )276 debug_output_unit, debug_output, no_id ) 256 277 257 278 END SUBROUTINE dom_init 258 259 !--------------------------------------------------------------------------------------------------!260 ! Description:261 ! ------------262 !> Debugging output. Print contents of output database to debug_output_unit.263 !--------------------------------------------------------------------------------------------------!264 SUBROUTINE dom_database_debug_output265 266 CHARACTER(LEN=*), PARAMETER :: separation_string = '---' !< string separating blocks in output267 CHARACTER(LEN=50) :: format1 !< format for write statements268 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_database_debug_output' !< name of this routine269 270 INTEGER :: f !< loop index271 INTEGER, PARAMETER :: indent_depth = 3 !< space per indentation272 INTEGER :: indent_level !< indentation level273 INTEGER, PARAMETER :: max_keyname_length = 6 !< length of longest key name274 INTEGER :: natt !< number of attributes275 INTEGER :: ndim !< number of dimensions276 INTEGER :: nvar !< number of variables277 278 279 CALL internal_message( 'debug', routine_name // ': write data base to debug output' )280 281 WRITE( debug_output_unit, '(A)' ) 'DOM data base:'282 WRITE( debug_output_unit, '(A)' ) REPEAT( separation_string // ' ', 4 )283 284 IF ( .NOT. ALLOCATED( files ) .OR. nf == 0 ) THEN285 286 WRITE( debug_output_unit, '(A)' ) 'database is empty'287 288 ELSE289 290 indent_level = 1291 WRITE( format1, '(A,I3,A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A,T', &292 indent_level * indent_depth + 1 + max_keyname_length, &293 ',(": ")'294 295 DO f = 1, nf296 297 natt = 0298 ndim = 0299 nvar = 0300 IF ( ALLOCATED( files(f)%attributes ) ) natt = SIZE( files(f)%attributes )301 IF ( ALLOCATED( files(f)%dimensions ) ) ndim = SIZE( files(f)%dimensions )302 IF ( ALLOCATED( files(f)%variables ) ) nvar = SIZE( files(f)%variables )303 304 WRITE( debug_output_unit, '(A)' ) 'file:'305 WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) 'name', TRIM( files(f)%name )306 WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) 'format', TRIM( files(f)%format )307 WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) 'id', files(f)%id308 WRITE( debug_output_unit, TRIM( format1 ) // ',L1)' ) 'is init', files(f)%is_init309 WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) '#atts', natt310 WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) '#dims', ndim311 WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) '#vars', nvar312 313 IF ( natt /= 0 ) CALL print_attributes( indent_level, files(f)%attributes )314 IF ( ndim /= 0 ) CALL print_dimensions( indent_level, files(f)%dimensions )315 IF ( nvar /= 0 ) CALL print_variables( indent_level, files(f)%variables )316 317 WRITE( debug_output_unit, '(/A/)' ) REPEAT( separation_string // ' ', 4 )318 319 ENDDO320 321 ENDIF322 323 CONTAINS324 325 !--------------------------------------------------------------------------------------------!326 ! Description:327 ! ------------328 !> Print list of attributes.329 !--------------------------------------------------------------------------------------------!330 SUBROUTINE print_attributes( indent_level, attributes )331 332 CHARACTER(LEN=50) :: format1 !< format for write statements333 CHARACTER(LEN=50) :: format2 !< format for write statements334 335 INTEGER :: i !< loop index336 INTEGER, INTENT(IN) :: indent_level !< indentation level337 INTEGER, PARAMETER :: max_keyname_length = 6 !< length of longest key name338 INTEGER :: nelement !< number of elements to print339 340 TYPE(attribute_type), DIMENSION(:), INTENT(IN) :: attributes !< list of attributes341 342 343 WRITE( format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A'344 WRITE( format2, '(A,I3,A,I3,A)' ) &345 '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', &346 ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")'347 348 WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) REPEAT( separation_string // ' ', 4 )349 WRITE( debug_output_unit, TRIM( format1 ) // ')' ) 'attributes:'350 351 nelement = SIZE( attributes )352 DO i = 1, nelement353 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &354 'name', TRIM( attributes(i)%name )355 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &356 'type', TRIM( attributes(i)%data_type )357 358 IF ( TRIM( attributes(i)%data_type ) == 'char' ) THEN359 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &360 'value', TRIM( attributes(i)%value_char )361 ELSEIF ( TRIM( attributes(i)%data_type ) == 'int8' ) THEN362 WRITE( debug_output_unit, TRIM( format2 ) // ',I4)' ) &363 'value', attributes(i)%value_int8364 ELSEIF ( TRIM( attributes(i)%data_type ) == 'int16' ) THEN365 WRITE( debug_output_unit, TRIM( format2 ) // ',I6)' ) &366 'value', attributes(i)%value_int16367 ELSEIF ( TRIM( attributes(i)%data_type ) == 'int32' ) THEN368 WRITE( debug_output_unit, TRIM( format2 ) // ',I11)' ) &369 'value', attributes(i)%value_int32370 ELSEIF ( TRIM( attributes(i)%data_type ) == 'real32' ) THEN371 WRITE( debug_output_unit, TRIM( format2 ) // ',E14.7)' ) &372 'value', attributes(i)%value_real32373 ELSEIF ( TRIM(attributes(i)%data_type) == 'real64' ) THEN374 WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)' ) &375 'value', attributes(i)%value_real64376 ENDIF377 IF ( i < nelement ) &378 WRITE( debug_output_unit, TRIM( format1 ) // ')' ) separation_string379 ENDDO380 381 END SUBROUTINE print_attributes382 383 !--------------------------------------------------------------------------------------------!384 ! Description:385 ! ------------386 !> Print list of dimensions.387 !--------------------------------------------------------------------------------------------!388 SUBROUTINE print_dimensions( indent_level, dimensions )389 390 CHARACTER(LEN=50) :: format1 !< format for write statements391 CHARACTER(LEN=50) :: format2 !< format for write statements392 393 INTEGER :: i !< loop index394 INTEGER, INTENT(IN) :: indent_level !< indentation level395 INTEGER :: j !< loop index396 INTEGER, PARAMETER :: max_keyname_length = 15 !< length of longest key name397 INTEGER :: nelement !< number of elements to print398 399 LOGICAL :: is_masked !< true if dimension is masked400 401 TYPE(dimension_type), DIMENSION(:), INTENT(IN) :: dimensions !< list of dimensions402 403 404 WRITE( format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A'405 WRITE( format2, '(A,I3,A,I3,A)' ) &406 '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', &407 ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")'408 409 WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) REPEAT( separation_string // ' ', 4 )410 WRITE( debug_output_unit, TRIM( format1 ) // ')' ) 'dimensions:'411 412 nelement = SIZE( dimensions )413 DO i = 1, nelement414 is_masked = dimensions(i)%is_masked415 416 !-- Print general information417 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &418 'name', TRIM( dimensions(i)%name )419 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &420 'type', TRIM( dimensions(i)%data_type )421 WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &422 'id', dimensions(i)%id423 WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &424 'length', dimensions(i)%length425 WRITE( debug_output_unit, TRIM( format2 ) // ',I7,A,I7)' ) &426 'bounds', dimensions(i)%bounds(1), ',', dimensions(i)%bounds(2)427 WRITE( debug_output_unit, TRIM( format2 ) // ',L1)' ) &428 'is masked', dimensions(i)%is_masked429 430 !-- Print information about mask431 IF ( is_masked ) THEN432 WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &433 'masked length', dimensions(i)%length_mask434 435 WRITE( debug_output_unit, TRIM( format2 ) // ',L1)', ADVANCE='no' ) &436 'mask', dimensions(i)%mask(dimensions(i)%bounds(1))437 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)438 WRITE( debug_output_unit, '(A,L1)', ADVANCE='no' ) ',', dimensions(i)%mask(j)439 ENDDO440 WRITE( debug_output_unit, '(A)' ) '' ! write line-end441 442 WRITE( debug_output_unit, TRIM( format2 ) // ',I6)', ADVANCE='no' ) &443 'masked indices', dimensions(i)%masked_indices(0)444 DO j = 1, dimensions(i)%length_mask-1445 WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) &446 ',', dimensions(i)%masked_indices(j)447 ENDDO448 WRITE( debug_output_unit, '(A)' ) '' ! write line-end449 ENDIF450 451 !-- Print saved values452 IF ( ALLOCATED( dimensions(i)%values_int8 ) ) THEN453 454 WRITE( debug_output_unit, TRIM( format2 ) // ',I4)', ADVANCE='no' ) &455 'values', dimensions(i)%values_int8(dimensions(i)%bounds(1))456 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)457 WRITE( debug_output_unit, '(A,I4)', ADVANCE='no' ) &458 ',', dimensions(i)%values_int8(j)459 ENDDO460 WRITE( debug_output_unit, '(A)' ) '' ! write line-end461 IF ( is_masked ) THEN462 WRITE( debug_output_unit, TRIM( format2 ) // ',I4)', ADVANCE='no' ) &463 'masked values', dimensions(i)%masked_values_int8(0)464 DO j = 1, dimensions(i)%length_mask-1465 WRITE( debug_output_unit, '(A,I4)', ADVANCE='no' ) &466 ',', dimensions(i)%masked_values_int8(j)467 ENDDO468 WRITE( debug_output_unit, '(A)' ) '' ! write line-end469 ENDIF470 471 ELSEIF ( ALLOCATED( dimensions(i)%values_int16 ) ) THEN472 473 WRITE( debug_output_unit, TRIM( format2 ) // ',I6)', ADVANCE='no' ) &474 'values', dimensions(i)%values_int16(dimensions(i)%bounds(1))475 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)476 WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) &477 ',', dimensions(i)%values_int16(j)478 ENDDO479 WRITE( debug_output_unit, '(A)' ) '' ! write line-end480 IF ( is_masked ) THEN481 WRITE( debug_output_unit, TRIM( format2 ) // ',I6)', ADVANCE='no' ) &482 'masked values', dimensions(i)%masked_values_int16(0)483 DO j = 1, dimensions(i)%length_mask-1484 WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) &485 ',', dimensions(i)%masked_values_int16(j)486 ENDDO487 WRITE( debug_output_unit, '(A)' ) '' ! write line-end488 ENDIF489 490 ELSEIF ( ALLOCATED( dimensions(i)%values_int32 ) ) THEN491 492 WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &493 'values', dimensions(i)%values_int32(dimensions(i)%bounds(1))494 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)495 WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &496 ',', dimensions(i)%values_int32(j)497 ENDDO498 WRITE( debug_output_unit, '(A)' ) '' ! write line-end499 IF ( is_masked ) THEN500 WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &501 'masked values', dimensions(i)%masked_values_int32(0)502 DO j = 1, dimensions(i)%length_mask-1503 WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &504 ',', dimensions(i)%masked_values_int32(j)505 ENDDO506 WRITE( debug_output_unit, '(A)' ) '' ! write line-end507 ENDIF508 509 ELSEIF ( ALLOCATED( dimensions(i)%values_intwp ) ) THEN510 511 WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &512 'values', dimensions(i)%values_intwp(dimensions(i)%bounds(1))513 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)514 WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &515 ',', dimensions(i)%values_intwp(j)516 ENDDO517 WRITE( debug_output_unit, '(A)' ) '' ! write line-end518 IF ( is_masked ) THEN519 WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &520 'masked values', dimensions(i)%masked_values_intwp(0)521 DO j = 1, dimensions(i)%length_mask-1522 WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &523 ',', dimensions(i)%masked_values_intwp(j)524 ENDDO525 WRITE( debug_output_unit, '(A)' ) '' ! write line-end526 ENDIF527 528 ELSEIF ( ALLOCATED( dimensions(i)%values_real32 ) ) THEN529 530 WRITE( debug_output_unit, TRIM( format2 ) // ',E14.7)', ADVANCE='no' ) &531 'values', dimensions(i)%values_real32(dimensions(i)%bounds(1))532 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)533 WRITE( debug_output_unit, '(A,E14.7)', ADVANCE='no' ) &534 ',', dimensions(i)%values_real32(j)535 ENDDO536 WRITE( debug_output_unit, '(A)' ) '' ! write line-end537 IF ( is_masked ) THEN538 WRITE( debug_output_unit, TRIM( format2 ) // ',E14.7)', ADVANCE='no' ) &539 'masked values', dimensions(i)%masked_values_real32(0)540 DO j = 1, dimensions(i)%length_mask-1541 WRITE( debug_output_unit, '(A,E14.7)', ADVANCE='no' ) &542 ',', dimensions(i)%masked_values_real32(j)543 ENDDO544 WRITE( debug_output_unit, '(A)' ) '' ! write line-end545 ENDIF546 547 ELSEIF ( ALLOCATED( dimensions(i)%values_real64 ) ) THEN548 549 WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &550 'values', dimensions(i)%values_real64(dimensions(i)%bounds(1))551 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)552 WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &553 ',', dimensions(i)%values_real64(j)554 ENDDO555 WRITE( debug_output_unit, '(A)' ) '' ! write line-end556 IF ( is_masked ) THEN557 WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &558 'masked values', dimensions(i)%masked_values_real64(0)559 DO j = 1, dimensions(i)%length_mask-1560 WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &561 ',', dimensions(i)%masked_values_real64(j)562 ENDDO563 WRITE( debug_output_unit, '(A)' ) '' ! write line-end564 ENDIF565 566 ELSEIF ( ALLOCATED( dimensions(i)%values_realwp ) ) THEN567 568 WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &569 'values', dimensions(i)%values_realwp(dimensions(i)%bounds(1))570 DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)571 WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &572 ',', dimensions(i)%values_realwp(j)573 ENDDO574 WRITE( debug_output_unit, '(A)' ) '' ! write line-end575 IF ( is_masked ) THEN576 WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &577 'masked values', dimensions(i)%masked_values_realwp(0)578 DO j = 1, dimensions(i)%length_mask-1579 WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &580 ',', dimensions(i)%masked_values_realwp(j)581 ENDDO582 WRITE( debug_output_unit, '(A)' ) '' ! write line-end583 ENDIF584 585 ENDIF586 587 IF ( ALLOCATED( dimensions(i)%attributes ) ) &588 CALL print_attributes( indent_level+1, dimensions(i)%attributes )589 590 IF ( i < nelement ) &591 WRITE( debug_output_unit, TRIM( format1 ) // ')' ) separation_string592 ENDDO593 594 END SUBROUTINE print_dimensions595 596 !--------------------------------------------------------------------------------------------!597 ! Description:598 ! ------------599 !> Print list of variables.600 !--------------------------------------------------------------------------------------------!601 SUBROUTINE print_variables( indent_level, variables )602 603 CHARACTER(LEN=50) :: format1 !< format for write statements604 CHARACTER(LEN=50) :: format2 !< format for write statements605 606 INTEGER :: i !< loop index607 INTEGER, INTENT(IN) :: indent_level !< indentation level608 INTEGER :: j !< loop index609 INTEGER, PARAMETER :: max_keyname_length = 16 !< length of longest key name610 INTEGER :: nelement !< number of elements to print611 612 TYPE(variable_type), DIMENSION(:), INTENT(IN) :: variables !< list of variables613 614 615 WRITE( format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A'616 WRITE( format2, '(A,I3,A,I3,A)' ) &617 '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', &618 ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")'619 620 WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) REPEAT( separation_string // ' ', 4 )621 WRITE( debug_output_unit, TRIM( format1 ) // ')' ) 'variables:'622 623 nelement = SIZE( variables )624 DO i = 1, nelement625 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &626 'name', TRIM( variables(i)%name )627 WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &628 'type', TRIM( variables(i)%data_type )629 WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &630 'id', variables(i)%id631 WRITE( debug_output_unit, TRIM( format2 ) // ',L1)' ) &632 'is global', variables(i)%is_global633 634 WRITE( debug_output_unit, TRIM( format2 ) // ',A)', ADVANCE='no' ) &635 'dimension names', TRIM( variables(i)%dimension_names(1) )636 DO j = 2, SIZE( variables(i)%dimension_names )637 WRITE( debug_output_unit, '(A,A)', ADVANCE='no' ) &638 ',', TRIM( variables(i)%dimension_names(j) )639 ENDDO640 WRITE( debug_output_unit, '(A)' ) '' ! write line-end641 642 WRITE( debug_output_unit, TRIM( format2 ) // ',I7)', ADVANCE='no' ) &643 'dimension ids', variables(i)%dimension_ids(1)644 DO j = 2, SIZE( variables(i)%dimension_names )645 WRITE( debug_output_unit, '(A,I7)', ADVANCE='no' ) &646 ',', variables(i)%dimension_ids(j)647 ENDDO648 WRITE( debug_output_unit, '(A)' ) '' ! write line-end649 650 IF ( ALLOCATED( variables(i)%attributes ) ) &651 CALL print_attributes( indent_level+1, variables(i)%attributes )652 IF ( i < nelement ) &653 WRITE( debug_output_unit, TRIM( format1 ) // ')' ) separation_string654 ENDDO655 656 END SUBROUTINE print_variables657 658 END SUBROUTINE dom_database_debug_output659 279 660 280 !--------------------------------------------------------------------------------------------------! … … 662 282 ! ------------ 663 283 !> Define output file. 664 !--------------------------------------------------------------------------------------------------! 665 FUNCTION dom_def_file( filename, format ) RESULT( return_value ) 666 667 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file to be created 668 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: format !< format of file to be created 284 !> Example call: 285 !> status = dom_def_file( 'my_output_file_name', 'binary' ) 286 !--------------------------------------------------------------------------------------------------! 287 FUNCTION dom_def_file( file_name, file_format ) RESULT( return_value ) 288 289 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file to be created 290 CHARACTER(LEN=*), INTENT(IN) :: file_format !< format of file to be created 669 291 670 292 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_file' !< name of this routine 671 293 672 INTEGER (iwp):: f !< loop index673 INTEGER (iwp):: return_value !< return value294 INTEGER :: f !< loop index 295 INTEGER :: return_value !< return value 674 296 675 297 TYPE(file_type), DIMENSION(:), ALLOCATABLE :: files_tmp !< temporary file list … … 678 300 return_value = 0 679 301 680 CALL internal_message( 'debug', routine_name // ': define file "' // TRIM( file name ) // '"' )302 CALL internal_message( 'debug', routine_name // ': define file "' // TRIM( file_name ) // '"' ) 681 303 682 304 !-- Allocate file list or extend it by 1 683 305 IF ( .NOT. ALLOCATED( files ) ) THEN 684 306 685 nf = 1686 ALLOCATE( files(nf ) )307 nfiles = 1 308 ALLOCATE( files(nfiles) ) 687 309 688 310 ELSE 689 311 690 nf = SIZE( files )312 nfiles = SIZE( files ) 691 313 !-- Check if file already exists 692 DO f = 1, nf 693 IF ( files(f)%name == TRIM( file name ) ) THEN314 DO f = 1, nfiles 315 IF ( files(f)%name == TRIM( file_name ) ) THEN 694 316 return_value = 1 695 CALL internal_message( 'error', routine_name // ': file "' // TRIM( filename ) //&696 317 CALL internal_message( 'error', routine_name // & 318 ': file "' // TRIM( file_name ) // '" already exists' ) 697 319 EXIT 698 320 ENDIF … … 701 323 !-- Extend file list 702 324 IF ( return_value == 0 ) THEN 703 ALLOCATE( files_tmp(nf ) )325 ALLOCATE( files_tmp(nfiles) ) 704 326 files_tmp = files 705 327 DEALLOCATE( files ) 706 nf = nf+ 1707 ALLOCATE( files(nf ) )708 files(:nf -1) = files_tmp328 nfiles = nfiles + 1 329 ALLOCATE( files(nfiles) ) 330 files(:nfiles-1) = files_tmp 709 331 DEALLOCATE( files_tmp ) 710 332 ENDIF … … 714 336 !-- Add new file to database 715 337 IF ( return_value == 0 ) THEN 716 files(nf)%name = TRIM( filename ) 717 IF ( PRESENT( format ) ) THEN 718 files(nf)%format = TRIM( format ) 719 ELSE 720 files(nf)%format = TRIM( output_file_format ) 721 ENDIF 338 files(nfiles)%name = TRIM( file_name ) 339 files(nfiles)%format = TRIM( file_format ) 722 340 ENDIF 723 341 … … 727 345 ! Description: 728 346 ! ------------ 729 !> Define dimension of type integer. 347 !> Define dimension. 348 !> Dimensions can either be limited (a lower and upper bound is given) or unlimited (only a lower 349 !> bound is given). Also, instead of providing all values of the dimension, a single value can be 350 !> given which is then used to fill the entire dimension. 351 !> An optional mask can be given to mask limited dimensions. 352 !> Example call: 353 !> - fixed dimension with 100 entries (values known): 354 !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & 355 !> output_type='real32', bounds=(/1,100/), & 356 !> values_real32=my_dim(1:100), mask=my_dim_mask(1:100) ) 357 !> - fixed dimension with 50 entries (values not yet known): 358 !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & 359 !> output_type='int32', bounds=(/0,49/), & 360 !> values_int32=(/fill_value/) ) 361 !> - masked dimension with 75 entries: 362 !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & 363 !> output_type='real64', bounds=(/101,175/), & 364 !> values_real64=my_dim(1:75), mask=my_dim_mask(1:75) ) 365 !> - unlimited dimension: 366 !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & 367 !> output_type='real32', bounds=(/1/), & 368 !> values_real32=(/fill_value/) ) 730 369 !> 731 370 !> @todo Convert given values into selected output_type. 732 371 !--------------------------------------------------------------------------------------------------! 733 FUNCTION dom_def_dim( file name, name, output_type, bounds,&372 FUNCTION dom_def_dim( file_name, dimension_name, output_type, bounds, & 734 373 values_int8, values_int16, values_int32, values_intwp, & 735 374 values_real32, values_real64, values_realwp, & 736 375 mask ) RESULT( return_value ) 737 376 738 CHARACTER(LEN=*), INTENT(IN) :: file name!< name of file739 CHARACTER(LEN=*), INTENT(IN) :: name!< name of dimension740 CHARACTER(LEN=*), INTENT(IN) :: output_type !< data type of dimension variable in output file377 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 378 CHARACTER(LEN=*), INTENT(IN) :: dimension_name !< name of dimension 379 CHARACTER(LEN=*), INTENT(IN) :: output_type !< data type of dimension variable in output file 741 380 742 381 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_dim' !< name of this routine 743 382 744 INTEGER(iwp) :: d !< loop index 745 INTEGER(iwp) :: f !< loop index 746 INTEGER(iwp) :: i !< loop index 747 INTEGER(iwp) :: j !< loop index 748 INTEGER(iwp) :: ndim !< number of dimensions in file 749 INTEGER(iwp) :: return_value !< return value 750 751 INTEGER(iwp), DIMENSION(:), INTENT(IN) :: bounds !< lower and upper bound of dimension variable 752 753 INTEGER(KIND=1), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int8 !< values of dimension 754 INTEGER(KIND=2), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int16 !< values of dimension 755 INTEGER(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int32 !< values of dimension 756 INTEGER(iwp), DIMENSION(:), INTENT(IN), OPTIONAL :: values_intwp !< values of dimension 757 758 LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL :: mask !< mask of dimesion 759 760 REAL(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL :: values_real32 !< values of dimension 761 REAL(KIND=8), DIMENSION(:), INTENT(IN), OPTIONAL :: values_real64 !< values of dimension 762 REAL(wp), DIMENSION(:), INTENT(IN), OPTIONAL :: values_realwp !< values of dimension 763 764 TYPE(dimension_type) :: dimension !< new dimension 765 766 TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dims_tmp !< temporary dimension list 383 INTEGER :: d !< loop index 384 INTEGER :: f !< loop index 385 INTEGER :: i !< loop index 386 INTEGER :: j !< loop index 387 INTEGER :: ndims !< number of dimensions in file 388 INTEGER :: return_value !< return value 389 390 INTEGER, DIMENSION(:), INTENT(IN) :: bounds !< lower and upper bound of dimension variable 391 INTEGER(KIND=1), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int8 !< values of dimension 392 INTEGER(KIND=2), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int16 !< values of dimension 393 INTEGER(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int32 !< values of dimension 394 INTEGER(iwp), DIMENSION(:), INTENT(IN), OPTIONAL :: values_intwp !< values of dimension 395 396 LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL :: mask !< mask of dimesion 397 398 REAL(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL :: values_real32 !< values of dimension 399 REAL(KIND=8), DIMENSION(:), INTENT(IN), OPTIONAL :: values_real64 !< values of dimension 400 REAL(wp), DIMENSION(:), INTENT(IN), OPTIONAL :: values_realwp !< values of dimension 401 402 TYPE(dimension_type) :: dimension !< new dimension 403 TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimensions_tmp !< temporary dimension list 767 404 768 405 769 406 return_value = 0 770 407 771 CALL internal_message( 'debug', routine_name // & 772 ': define dimension "' // TRIM( name ) // & 773 '" in file "' // TRIM( filename ) // '"' ) 774 775 dimension%name = TRIM( name ) 408 CALL internal_message( 'debug', routine_name // & 409 ': define dimension ' // & 410 '(dimension "' // TRIM( dimension_name ) // & 411 '", file "' // TRIM( file_name ) // '")' ) 412 413 dimension%name = TRIM( dimension_name ) 776 414 dimension%data_type = TRIM( output_type ) 777 415 … … 783 421 !-- Set length to -1 as indicator. 784 422 dimension%bounds(:) = bounds(1) 785 dimension%length = -1 _iwp423 dimension%length = -1 786 424 787 425 IF ( PRESENT( mask ) ) THEN 788 426 return_value = 1 789 CALL internal_message( 'error', routine_name // & 790 ': unlimited dimension "' // TRIM( name ) // & 791 '" in file "' // TRIM( filename ) // '" cannot be masked' ) 427 CALL internal_message( 'error', routine_name // & 428 ': unlimited dimensions cannot be masked ' // & 429 '(dimension "' // TRIM( dimension_name ) // & 430 '", file "' // TRIM( file_name ) // '")!' ) 792 431 ENDIF 793 432 … … 803 442 dimension%values_int8 = values_int8 804 443 ELSEIF ( SIZE( values_int8 ) == 1 ) THEN 805 dimension%values_int8(:) = values_int8 444 dimension%values_int8(:) = values_int8(1) 806 445 ELSE 807 446 return_value = 2 … … 812 451 dimension%values_int16 = values_int16 813 452 ELSEIF ( SIZE( values_int16 ) == 1 ) THEN 814 dimension%values_int16(:) = values_int16 453 dimension%values_int16(:) = values_int16(1) 815 454 ELSE 816 455 return_value = 2 … … 821 460 dimension%values_int32 = values_int32 822 461 ELSEIF ( SIZE( values_int32 ) == 1 ) THEN 823 dimension%values_int32(:) = values_int32 462 dimension%values_int32(:) = values_int32(1) 824 463 ELSE 825 464 return_value = 2 … … 830 469 dimension%values_intwp = values_intwp 831 470 ELSEIF ( SIZE( values_intwp ) == 1 ) THEN 832 dimension%values_intwp(:) = values_intwp 471 dimension%values_intwp(:) = values_intwp(1) 833 472 ELSE 834 473 return_value = 2 … … 839 478 dimension%values_real32 = values_real32 840 479 ELSEIF ( SIZE( values_real32 ) == 1 ) THEN 841 dimension%values_real32(:) = values_real32 480 dimension%values_real32(:) = values_real32(1) 842 481 ELSE 843 482 return_value = 2 … … 848 487 dimension%values_real64 = values_real64 849 488 ELSEIF ( SIZE( values_real64 ) == 1 ) THEN 850 dimension%values_real64(:) = values_real64 489 dimension%values_real64(:) = values_real64(1) 851 490 ELSE 852 491 return_value = 2 … … 857 496 dimension%values_realwp = values_realwp 858 497 ELSEIF ( SIZE( values_realwp ) == 1 ) THEN 859 dimension%values_realwp(:) = values_realwp 498 dimension%values_realwp(:) = values_realwp(1) 860 499 ELSE 861 500 return_value = 2 … … 863 502 ELSE 864 503 return_value = 1 865 CALL internal_message( 'error', routine_name // ': ' // & 866 TRIM( name ) // ': no values given' ) 504 CALL internal_message( 'error', routine_name // & 505 ': no values given ' // & 506 '(dimension "' // TRIM( dimension_name ) // & 507 '", file "' // TRIM( file_name ) // '")!' ) 867 508 ENDIF 868 509 869 510 IF ( return_value == 2 ) THEN 870 511 return_value = 1 871 CALL internal_message( 'error', routine_name // & 872 ': dimension ' // TRIM( name ) // & 873 ': number of values and given bounds do not match' ) 512 CALL internal_message( 'error', routine_name // & 513 ': number of values and given bounds do not match ' // & 514 '(dimension "' // TRIM( dimension_name ) // & 515 '", file "' // TRIM( file_name ) // '")!' ) 874 516 ENDIF 875 517 … … 877 519 IF ( PRESENT( mask ) .AND. return_value == 0 ) THEN 878 520 879 dimension%is_masked = .TRUE.880 881 521 IF ( dimension%length == SIZE( mask ) ) THEN 882 522 883 dimension%length_mask = COUNT( mask ) 884 885 ALLOCATE( dimension%mask(dimension%bounds(1):dimension%bounds(2)) ) 886 ALLOCATE( dimension%masked_indices(0:dimension%length_mask-1) ) 887 888 dimension%mask = mask 889 890 !-- Save masked positions and masked values 891 IF ( ALLOCATED( dimension%values_int8 ) ) THEN 892 893 ALLOCATE( dimension%masked_values_int8(0:dimension%length_mask-1) ) 894 j = 0 895 DO i = 0, dimension%length-1 896 IF ( dimension%mask(i) ) THEN 897 dimension%masked_values_int8(j) = dimension%values_int8(i) 898 dimension%masked_indices(j) = i 899 j = j + 1 900 ENDIF 901 ENDDO 902 903 ELSEIF ( ALLOCATED( dimension%values_int16 ) ) THEN 904 905 ALLOCATE( dimension%masked_values_int16(0:dimension%length_mask-1) ) 906 j = 0 907 DO i = 0, dimension%length-1 908 IF ( dimension%mask(i) ) THEN 909 dimension%masked_values_int16(j) = dimension%values_int16(i) 910 dimension%masked_indices(j) = i 911 j = j + 1 912 ENDIF 913 ENDDO 914 915 ELSEIF ( ALLOCATED( dimension%values_int32 ) ) THEN 916 917 ALLOCATE( dimension%masked_values_int32(0:dimension%length_mask-1) ) 918 j = 0 919 DO i = 0, dimension%length-1 920 IF ( dimension%mask(i) ) THEN 921 dimension%masked_values_int32(j) = dimension%values_int32(i) 922 dimension%masked_indices(j) = i 923 j = j + 1 924 ENDIF 925 ENDDO 926 927 ELSEIF ( ALLOCATED( dimension%values_intwp ) ) THEN 928 929 ALLOCATE( dimension%masked_values_intwp(0:dimension%length_mask-1) ) 930 j = 0 931 DO i = 0, dimension%length-1 932 IF ( dimension%mask(i) ) THEN 933 dimension%masked_values_intwp(j) = dimension%values_intwp(i) 934 dimension%masked_indices(j) = i 935 j = j + 1 936 ENDIF 937 ENDDO 938 939 ELSEIF ( ALLOCATED( dimension%values_real32 ) ) THEN 940 941 ALLOCATE( dimension%masked_values_real32(0:dimension%length_mask-1) ) 942 j = 0 943 DO i = 0, dimension%length-1 944 IF ( dimension%mask(i) ) THEN 945 dimension%masked_values_real32(j) = dimension%values_real32(i) 946 dimension%masked_indices(j) = i 947 j = j + 1 948 ENDIF 949 ENDDO 950 951 ELSEIF ( ALLOCATED(dimension%values_real64) ) THEN 952 953 ALLOCATE( dimension%masked_values_real64(0:dimension%length_mask-1) ) 954 j = 0 955 DO i = 0, dimension%length-1 956 IF ( dimension%mask(i) ) THEN 957 dimension%masked_values_real64(j) = dimension%values_real64(i) 958 dimension%masked_indices(j) = i 959 j = j + 1 960 ENDIF 961 ENDDO 962 963 ELSEIF ( ALLOCATED(dimension%values_realwp) ) THEN 964 965 ALLOCATE( dimension%masked_values_realwp(0:dimension%length_mask-1) ) 966 j = 0 967 DO i = dimension%bounds(1), dimension%bounds(2) !> @todo change loop also for other data types 968 IF ( dimension%mask(i) ) THEN 969 dimension%masked_values_realwp(j) = dimension%values_realwp(i) 970 dimension%masked_indices(j) = i 971 j = j + 1 972 ENDIF 973 ENDDO 974 975 ENDIF 523 IF ( ALL( mask ) ) THEN 524 525 CALL internal_message( 'debug', routine_name // & 526 ': mask contains only TRUE values. Ignoring mask ' // & 527 '(dimension "' // TRIM( dimension_name ) // & 528 '", file "' // TRIM( file_name ) // '")!' ) 529 530 ELSE 531 532 dimension%is_masked = .TRUE. 533 dimension%length_mask = COUNT( mask ) 534 535 ALLOCATE( dimension%mask(dimension%bounds(1):dimension%bounds(2)) ) 536 ALLOCATE( dimension%masked_indices(0:dimension%length_mask-1) ) 537 538 dimension%mask = mask 539 540 !-- Save masked positions and masked values 541 IF ( ALLOCATED( dimension%values_int8 ) ) THEN 542 543 ALLOCATE( dimension%masked_values_int8(0:dimension%length_mask-1) ) 544 j = 0 545 DO i = dimension%bounds(1), dimension%bounds(2) 546 IF ( dimension%mask(i) ) THEN 547 dimension%masked_values_int8(j) = dimension%values_int8(i) 548 dimension%masked_indices(j) = i 549 j = j + 1 550 ENDIF 551 ENDDO 552 553 ELSEIF ( ALLOCATED( dimension%values_int16 ) ) THEN 554 555 ALLOCATE( dimension%masked_values_int16(0:dimension%length_mask-1) ) 556 j = 0 557 DO i = dimension%bounds(1), dimension%bounds(2) 558 IF ( dimension%mask(i) ) THEN 559 dimension%masked_values_int16(j) = dimension%values_int16(i) 560 dimension%masked_indices(j) = i 561 j = j + 1 562 ENDIF 563 ENDDO 564 565 ELSEIF ( ALLOCATED( dimension%values_int32 ) ) THEN 566 567 ALLOCATE( dimension%masked_values_int32(0:dimension%length_mask-1) ) 568 j = 0 569 DO i =dimension%bounds(1), dimension%bounds(2) 570 IF ( dimension%mask(i) ) THEN 571 dimension%masked_values_int32(j) = dimension%values_int32(i) 572 dimension%masked_indices(j) = i 573 j = j + 1 574 ENDIF 575 ENDDO 576 577 ELSEIF ( ALLOCATED( dimension%values_intwp ) ) THEN 578 579 ALLOCATE( dimension%masked_values_intwp(0:dimension%length_mask-1) ) 580 j = 0 581 DO i = dimension%bounds(1), dimension%bounds(2) 582 IF ( dimension%mask(i) ) THEN 583 dimension%masked_values_intwp(j) = dimension%values_intwp(i) 584 dimension%masked_indices(j) = i 585 j = j + 1 586 ENDIF 587 ENDDO 588 589 ELSEIF ( ALLOCATED( dimension%values_real32 ) ) THEN 590 591 ALLOCATE( dimension%masked_values_real32(0:dimension%length_mask-1) ) 592 j = 0 593 DO i = dimension%bounds(1), dimension%bounds(2) 594 IF ( dimension%mask(i) ) THEN 595 dimension%masked_values_real32(j) = dimension%values_real32(i) 596 dimension%masked_indices(j) = i 597 j = j + 1 598 ENDIF 599 ENDDO 600 601 ELSEIF ( ALLOCATED(dimension%values_real64) ) THEN 602 603 ALLOCATE( dimension%masked_values_real64(0:dimension%length_mask-1) ) 604 j = 0 605 DO i = dimension%bounds(1), dimension%bounds(2) 606 IF ( dimension%mask(i) ) THEN 607 dimension%masked_values_real64(j) = dimension%values_real64(i) 608 dimension%masked_indices(j) = i 609 j = j + 1 610 ENDIF 611 ENDDO 612 613 ELSEIF ( ALLOCATED(dimension%values_realwp) ) THEN 614 615 ALLOCATE( dimension%masked_values_realwp(0:dimension%length_mask-1) ) 616 j = 0 617 DO i = dimension%bounds(1), dimension%bounds(2) 618 IF ( dimension%mask(i) ) THEN 619 dimension%masked_values_realwp(j) = dimension%values_realwp(i) 620 dimension%masked_indices(j) = i 621 j = j + 1 622 ENDIF 623 ENDDO 624 625 ENDIF 626 627 ENDIF ! if not all mask = true 976 628 977 629 ELSE 978 630 return_value = 1 979 CALL internal_message( 'error', routine_name // & 980 ': dimension ' // TRIM( name ) // & 981 ': size of mask and given bounds do not match' ) 631 CALL internal_message( 'error', routine_name // & 632 ': size of mask and given bounds do not match ' // & 633 '(dimension "' // TRIM( dimension_name ) // & 634 '", file "' // TRIM( file_name ) // '")!' ) 982 635 ENDIF 983 636 … … 989 642 CALL internal_message( 'error', routine_name // & 990 643 ': at least one but no more than two bounds must be given ' // & 991 '(dimension "' // TRIM( name ) // & 992 '", file "' // TRIM( filename ) // & 993 '")!' ) 644 '(dimension "' // TRIM( dimension_name ) // & 645 '", file "' // TRIM( file_name ) // '")!' ) 994 646 995 647 ENDIF … … 998 650 IF ( return_value == 0 ) THEN 999 651 1000 DO f = 1, nf 1001 1002 IF ( TRIM( file name ) == files(f)%name ) THEN652 DO f = 1, nfiles 653 654 IF ( TRIM( file_name ) == files(f)%name ) THEN 1003 655 1004 656 IF ( files(f)%is_init ) THEN 1005 657 1006 658 return_value = 1 1007 CALL internal_message( 'error', & 1008 routine_name // ': file "' // TRIM( filename ) // & 1009 '" is already initialized. No further dimension definition allowed!' ) 659 CALL internal_message( 'error', routine_name // & 660 ': file already initialized. ' // & 661 'No further dimension definition allowed ' // & 662 '(dimension "' // TRIM( dimension_name ) // & 663 '", file "' // TRIM( file_name ) // '")!' ) 1010 664 EXIT 1011 665 1012 666 ELSEIF ( .NOT. ALLOCATED( files(f)%dimensions ) ) THEN 1013 667 1014 ndim = 11015 ALLOCATE( files(f)%dimensions(ndim ) )668 ndims = 1 669 ALLOCATE( files(f)%dimensions(ndims) ) 1016 670 1017 671 ELSE … … 1022 676 IF ( files(f)%variables(i)%name == dimension%name ) THEN 1023 677 return_value = 1 1024 CALL internal_message( 'error', routine_name // & 1025 ': file "' // TRIM( filename ) // & 1026 '" already has a variable of name "' // & 1027 TRIM( dimension%name ) // '" defined. ' // & 1028 'Defining a dimension of the same ' // & 1029 'name is not allowed.' ) 678 CALL internal_message( 'error', routine_name // & 679 ': file already has a variable of this name defined. ' // & 680 'Defining a dimension of the same name is not allowed ' // & 681 '(dimension "' // TRIM( dimension_name ) // & 682 '", file "' // TRIM( file_name ) // '")!' ) 1030 683 EXIT 1031 684 ENDIF … … 1035 688 IF ( return_value == 0 ) THEN 1036 689 !-- Check if dimension already exists in file 1037 ndim = SIZE( files(f)%dimensions )1038 1039 DO d = 1, ndim 690 ndims = SIZE( files(f)%dimensions ) 691 692 DO d = 1, ndims 1040 693 IF ( files(f)%dimensions(d)%name == dimension%name ) THEN 1041 694 return_value = 1 1042 CALL internal_message( 'error', 1043 routine_name //&1044 ' : dimension "' // TRIM(name ) // &1045 '" already exists in file "' // TRIM( filename ) // '"' )695 CALL internal_message( 'error', routine_name // & 696 ': dimension already exists in file ' // & 697 '(dimension "' // TRIM( dimension_name ) // & 698 '", file "' // TRIM( file_name ) // '")!' ) 1046 699 EXIT 1047 700 ENDIF … … 1050 703 !-- Extend dimension list 1051 704 IF ( return_value == 0 ) THEN 1052 ALLOCATE( dim s_tmp(ndim) )1053 dim s_tmp = files(f)%dimensions705 ALLOCATE( dimensions_tmp(ndims) ) 706 dimensions_tmp = files(f)%dimensions 1054 707 DEALLOCATE( files(f)%dimensions ) 1055 ndim = ndim+ 11056 ALLOCATE( files(f)%dimensions(ndim ) )1057 files(f)%dimensions(:ndim -1) = dims_tmp1058 DEALLOCATE( dim s_tmp )708 ndims = ndims + 1 709 ALLOCATE( files(f)%dimensions(ndims) ) 710 files(f)%dimensions(:ndims-1) = dimensions_tmp 711 DEALLOCATE( dimensions_tmp ) 1059 712 ENDIF 1060 713 ENDIF … … 1063 716 1064 717 !-- Add new dimension to database 1065 IF ( return_value == 0 ) files(f)%dimensions(ndim ) = dimension718 IF ( return_value == 0 ) files(f)%dimensions(ndims) = dimension 1066 719 1067 720 EXIT … … 1070 723 ENDDO 1071 724 1072 IF ( f > nf ) THEN725 IF ( f > nfiles ) THEN 1073 726 return_value = 1 1074 CALL internal_message( 'error', routine_name // &1075 ': file not found (dimension "' // TRIM( name ) // &1076 '", file "' // TRIM( file name ) // '")!' )727 CALL internal_message( 'error', routine_name // & 728 ': file not found (dimension "' // TRIM( dimension_name ) // & 729 '", file "' // TRIM( file_name ) // '")!' ) 1077 730 ENDIF 1078 731 … … 1085 738 ! ------------ 1086 739 !> Add variable to database. 740 !> If a variable is identical for each MPI rank, the optional argument 'is_global' should be set to 741 !> TRUE. This flags the variable to be a global variable and is later only written once by the 742 !> master output rank. 1087 743 !> Example call: 1088 !> dom_def_var( file name = 'DATA_OUTPUT_3D', &1089 !> name = 'u', &744 !> dom_def_var( file_name = 'my_output_file_name', & 745 !> variable_name = 'u', & 1090 746 !> dimension_names = (/'x ', 'y ', 'z ', 'time'/), & 1091 747 !> output_type = 'real32' ) … … 1103 759 !> ALLOCATE( u(<z>,<y>,<x>) ) 1104 760 !--------------------------------------------------------------------------------------------------! 1105 FUNCTION dom_def_var( file name,name, dimension_names, output_type, is_global ) &761 FUNCTION dom_def_var( file_name, variable_name, dimension_names, output_type, is_global ) & 1106 762 RESULT( return_value ) 1107 763 1108 CHARACTER(LEN=*), INTENT(IN) :: file name!< name of file1109 CHARACTER(LEN=*), INTENT(IN) :: name!< name of variable1110 CHARACTER(LEN=*), INTENT(IN) :: output_type !< data type of variable764 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 765 CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable 766 CHARACTER(LEN=*), INTENT(IN) :: output_type !< data type of variable 1111 767 1112 768 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_var' !< name of this routine … … 1114 770 CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: dimension_names !< list of dimension names 1115 771 1116 INTEGER(iwp) :: d !< loop index 1117 INTEGER(iwp) :: f !< loop index 1118 INTEGER(iwp) :: i !< loop index 1119 INTEGER(iwp) :: nvar !< number of variables in file 1120 INTEGER(iwp) :: return_value !< return value 1121 1122 LOGICAL :: found = .FALSE. !< true if requested dimension is defined in file 1123 LOGICAL, INTENT(IN), OPTIONAL :: is_global !< true if variable is global (same on all PE) 1124 1125 TYPE(variable_type) :: variable !< new variable 1126 1127 TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: vars_tmp !< temporary variable list 772 INTEGER :: d !< loop index 773 INTEGER :: f !< loop index 774 INTEGER :: i !< loop index 775 INTEGER :: nvars !< number of variables in file 776 INTEGER :: return_value !< return value 777 778 LOGICAL :: found !< true if requested dimension is defined in file 779 LOGICAL, INTENT(IN), OPTIONAL :: is_global !< true if variable is global (same on all PE) 780 781 TYPE(variable_type) :: variable !< new variable 782 TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: variables_tmp !< temporary variable list 1128 783 1129 784 1130 785 return_value = 0 1131 1132 CALL internal_message( 'debug', routine_name // & 1133 ': define variable "' // TRIM( name ) // & 1134 '" in file "' // TRIM( filename ) // '"' ) 1135 1136 variable%name = TRIM( name ) 786 found = .FALSE. 787 788 CALL internal_message( 'debug', routine_name // & 789 ': define variable (variable "' // TRIM( variable_name ) // & 790 '", file "' // TRIM( file_name ) // '")' ) 791 792 variable%name = TRIM( variable_name ) 1137 793 1138 794 ALLOCATE( variable%dimension_names(SIZE( dimension_names )) ) … … 1150 806 1151 807 !-- Add variable to database 1152 DO f = 1, nf 1153 1154 IF ( TRIM( file name ) == files(f)%name ) THEN808 DO f = 1, nfiles 809 810 IF ( TRIM( file_name ) == files(f)%name ) THEN 1155 811 1156 812 IF ( files(f)%is_init ) THEN 1157 813 1158 814 return_value = 1 1159 CALL internal_message( 'error', routine_name // ': file "' // TRIM( filename ) // & 1160 '" is already initialized. No further variable definition allowed!' ) 815 CALL internal_message( 'error', routine_name // & 816 ': file already initialized. No further variable definition allowed ' // & 817 '(variable "' // TRIM( variable_name ) // & 818 '", file "' // TRIM( file_name ) // '")!' ) 1161 819 EXIT 1162 820 … … 1167 825 IF ( files(f)%dimensions(d)%name == variable%name ) THEN 1168 826 return_value = 1 1169 CALL internal_message( 'error', routine_name // &1170 ': file "' // TRIM( filename ) //&1171 '" already has a dimension of name "' // &1172 TRIM( variable%name ) // '" defined. ' //&1173 'Defining a variable of the same name is not allowed.' )827 CALL internal_message( 'error', routine_name // & 828 ': file already has a dimension of this name defined. ' // & 829 'Defining a variable of the same name is not allowed ' // & 830 '(variable "' // TRIM( variable_name ) // & 831 '", file "' // TRIM( file_name ) // '")!' ) 1174 832 EXIT 1175 833 ENDIF … … 1188 846 IF ( .NOT. found ) THEN 1189 847 return_value = 1 1190 CALL internal_message( 'error', & 1191 routine_name // & 1192 ': required dimension "' // & 1193 TRIM( variable%dimension_names(i) ) // & 1194 '" for variable "' // TRIM( name ) // & 1195 '" is not defined in file "' // TRIM( filename ) // & 1196 '"!' ) 848 CALL internal_message( 'error', routine_name // & 849 ': required dimension "'// TRIM( variable%dimension_names(i) ) // & 850 '" for variable is not defined ' // & 851 '(variable "' // TRIM( variable_name ) // & 852 '", file "' // TRIM( file_name ) // '")!' ) 1197 853 EXIT 1198 854 ENDIF … … 1203 859 1204 860 return_value = 1 1205 CALL internal_message( 'error', routine_name // 1206 ': cannot define variable "' // TRIM( name )// &1207 '" in file "' // TRIM( filename ) //&1208 '" because no dimensions defined in file.' )861 CALL internal_message( 'error', routine_name // & 862 ': no dimensions defined in file. Cannot define variable '// & 863 '(variable "' // TRIM( variable_name ) // & 864 '", file "' // TRIM( file_name ) // '")!' ) 1209 865 1210 866 ENDIF … … 1215 871 IF ( .NOT. ALLOCATED( files(f)%variables ) ) THEN 1216 872 1217 nvar = 11218 ALLOCATE( files(f)%variables(nvar ) )873 nvars = 1 874 ALLOCATE( files(f)%variables(nvars) ) 1219 875 1220 876 ELSE 1221 877 1222 nvar = SIZE( files(f)%variables )1223 DO i = 1, nvar 878 nvars = SIZE( files(f)%variables ) 879 DO i = 1, nvars 1224 880 IF ( files(f)%variables(i)%name == variable%name ) THEN 1225 881 return_value = 1 1226 CALL internal_message( 'error', routine_name // 1227 ': variable "' // TRIM( name ) //&1228 '" already exists in file "' //&1229 TRIM( filename ) // '"!' )882 CALL internal_message( 'error', routine_name // & 883 ': variable already exists '// & 884 '(variable "' // TRIM( variable_name ) // & 885 '", file "' // TRIM( file_name ) // '")!' ) 1230 886 EXIT 1231 887 ENDIF … … 1234 890 IF ( return_value == 0 ) THEN 1235 891 !-- Extend variable list 1236 ALLOCATE( var s_tmp(nvar) )1237 var s_tmp = files(f)%variables892 ALLOCATE( variables_tmp(nvars) ) 893 variables_tmp = files(f)%variables 1238 894 DEALLOCATE( files(f)%variables ) 1239 nvar = nvar+ 11240 ALLOCATE( files(f)%variables(nvar ) )1241 files(f)%variables(:nvar -1) = vars_tmp1242 DEALLOCATE( var s_tmp )895 nvars = nvars + 1 896 ALLOCATE( files(f)%variables(nvars) ) 897 files(f)%variables(:nvars-1) = variables_tmp 898 DEALLOCATE( variables_tmp ) 1243 899 ENDIF 1244 900 … … 1246 902 1247 903 !-- Add new variable to database 1248 IF ( return_value == 0 ) files(f)%variables(nvar ) = variable904 IF ( return_value == 0 ) files(f)%variables(nvars) = variable 1249 905 1250 906 ENDIF … … 1256 912 ENDDO 1257 913 1258 IF ( f > nf ) THEN914 IF ( f > nfiles ) THEN 1259 915 return_value = 1 1260 CALL internal_message( 'error', routine_name // &1261 ': file not found (variable "' // TRIM( name ) //&1262 '", file "' // TRIM( file name ) // '")!' )916 CALL internal_message( 'error', routine_name // & 917 ': file not found (variable "' // TRIM( variable_name ) // & 918 '", file "' // TRIM( file_name ) // '")!' ) 1263 919 ENDIF 1264 920 … … 1269 925 ! ------------ 1270 926 !> Create attribute with value of type character. 1271 !--------------------------------------------------------------------------------------------------! 1272 FUNCTION dom_def_att_char( filename, variable, name, value, append ) RESULT( return_value ) 1273 1274 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1275 CHARACTER(LEN=*), INTENT(IN) :: name !< name of attribute 1276 CHARACTER(LEN=*), INTENT(IN) :: value !< attribute value 1277 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable !< name of variable 927 !> If the optional argument 'variable_name' is given, the attribute is added to the respective 928 !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to 929 !> the file itself. 930 !> If an attribute of similar name already exists, it is updated (overwritten) with the new value. 931 !> If the optional argument 'append' is set TRUE, the value of an already existing attribute of 932 !> similar name is appended by the new value instead of overwritten. 933 !> Example call: 934 !> - define a global file attribute: 935 !> dom_def_att( file_name='my_output_file_name', & 936 !> attribute_name='my_attribute', & 937 !> value='This is the attribute value' ) 938 !> - define a variable attribute: 939 !> dom_def_att( file_name='my_output_file_name', & 940 !> variable_name='my_variable', & 941 !> attribute_name='my_attribute', & 942 !> value='This is the attribute value' ) 943 !> - append an attribute: 944 !> dom_def_att( file_name='my_output_file_name', & 945 !> attribute_name='my_attribute', & 946 !> value=' and this part was appended', append=.TRUE. ) 947 !--------------------------------------------------------------------------------------------------! 948 FUNCTION dom_def_att_char( file_name, variable_name, attribute_name, value, append ) & 949 RESULT( return_value ) 950 951 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 952 CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute 953 CHARACTER(LEN=*), INTENT(IN) :: value !< attribute value 954 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 955 CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name 1278 956 1279 957 ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_char' !< name of routine 1280 958 1281 INTEGER (iwp):: return_value !< return value959 INTEGER :: return_value !< return value 1282 960 1283 961 LOGICAL :: append_internal !< same as 'append' … … 1295 973 ENDIF 1296 974 1297 attribute%name = TRIM( name )975 attribute%name = TRIM( attribute_name ) 1298 976 attribute%data_type = 'char' 1299 977 attribute%value_char = TRIM( value ) 1300 978 1301 IF ( PRESENT( variable ) ) THEN 1302 return_value = dom_def_att_save( TRIM( filename ), TRIM( variable ), & 1303 attribute=attribute, append=append_internal ) 979 IF ( PRESENT( variable_name ) ) THEN 980 variable_name_internal = TRIM( variable_name ) 1304 981 ELSE 1305 return_value = dom_def_att_save( TRIM( filename ), & 1306 attribute=attribute, append=append_internal ) 982 variable_name_internal = '' 1307 983 ENDIF 984 985 return_value = save_attribute_in_database( file_name=TRIM( file_name ), & 986 variable_name=TRIM( variable_name_internal ), & 987 attribute=attribute, append=append_internal ) 1308 988 1309 989 END FUNCTION dom_def_att_char … … 1313 993 ! ------------ 1314 994 !> Create attribute with value of type int8. 1315 !--------------------------------------------------------------------------------------------------! 1316 FUNCTION dom_def_att_int8( filename, variable, name, value, append ) RESULT( return_value ) 1317 1318 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1319 CHARACTER(LEN=*), INTENT(IN) :: name !< name of attribute 1320 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable !< name of variable 995 !> If the optional argument 'variable_name' is given, the attribute is added to the respective 996 !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to 997 !> the file itself. 998 !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). 999 !> Example call: 1000 !> - define a global file attribute: 1001 !> dom_def_att( file_name='my_output_file_name', & 1002 !> attribute_name='my_attribute', & 1003 !> value=0_1 ) 1004 !> - define a variable attribute: 1005 !> dom_def_att( file_name='my_output_file_name', & 1006 !> variable_name='my_variable', & 1007 !> attribute_name='my_attribute', & 1008 !> value=1_1 ) 1009 !--------------------------------------------------------------------------------------------------! 1010 FUNCTION dom_def_att_int8( file_name, variable_name, attribute_name, value, append ) & 1011 RESULT( return_value ) 1012 1013 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 1014 CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute 1015 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 1016 CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name 1321 1017 1322 1018 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_int8' !< name of routine … … 1324 1020 INTEGER(KIND=1), INTENT(IN) :: value !< attribute value 1325 1021 1326 INTEGER (iwp):: return_value !< return value1022 INTEGER :: return_value !< return value 1327 1023 1328 1024 LOGICAL :: append_internal !< same as 'append' … … 1333 1029 1334 1030 return_value = 0 1031 1032 IF ( PRESENT( variable_name ) ) THEN 1033 variable_name_internal = TRIM( variable_name ) 1034 ELSE 1035 variable_name_internal = '' 1036 ENDIF 1335 1037 1336 1038 IF ( PRESENT( append ) ) THEN 1337 1039 IF ( append ) THEN 1338 1040 return_value = 1 1339 CALL internal_message( 'error', & 1340 routine_name // & 1341 ': attribute "' // TRIM( name ) // & 1342 '": append of numeric attribute not possible.' ) 1041 CALL internal_message( 'error', routine_name // & 1042 ': numeric attribute cannot be appended ' // & 1043 '(attribute "' // TRIM( attribute_name ) // & 1044 '", variable "' // TRIM( variable_name_internal ) // & 1045 '", file "' // TRIM( file_name ) // '")!' ) 1343 1046 ENDIF 1344 1047 ENDIF … … 1347 1050 append_internal = .FALSE. 1348 1051 1349 attribute%name = TRIM( name )1052 attribute%name = TRIM( attribute_name ) 1350 1053 attribute%data_type = 'int8' 1351 1054 attribute%value_int8 = value 1352 1055 1353 IF ( PRESENT( variable ) ) THEN 1354 return_value = dom_def_att_save( TRIM( filename ), TRIM( variable ), & 1355 attribute=attribute, append=append_internal ) 1356 ELSE 1357 return_value = dom_def_att_save( TRIM( filename ), & 1358 attribute=attribute, append=append_internal ) 1359 ENDIF 1056 return_value = save_attribute_in_database( file_name=TRIM( file_name ), & 1057 variable_name=TRIM( variable_name_internal ), & 1058 attribute=attribute, append=append_internal ) 1360 1059 ENDIF 1361 1060 … … 1366 1065 ! ------------ 1367 1066 !> Create attribute with value of type int16. 1368 !--------------------------------------------------------------------------------------------------! 1369 FUNCTION dom_def_att_int16( filename, variable, name, value, append ) RESULT( return_value ) 1370 1371 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1372 CHARACTER(LEN=*), INTENT(IN) :: name !< name of attribute 1373 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable !< name of variable 1067 !> If the optional argument 'variable_name' is given, the attribute is added to the respective 1068 !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to 1069 !> the file itself. 1070 !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). 1071 !> Example call: 1072 !> - define a global file attribute: 1073 !> dom_def_att( file_name='my_output_file_name', & 1074 !> attribute_name='my_attribute', & 1075 !> value=0_2 ) 1076 !> - define a variable attribute: 1077 !> dom_def_att( file_name='my_output_file_name', & 1078 !> variable_name='my_variable', & 1079 !> attribute_name='my_attribute', & 1080 !> value=1_2 ) 1081 !--------------------------------------------------------------------------------------------------! 1082 FUNCTION dom_def_att_int16( file_name, variable_name, attribute_name, value, append ) & 1083 RESULT( return_value ) 1084 1085 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 1086 CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute 1087 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 1088 CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name 1374 1089 1375 1090 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_int16' !< name of routine … … 1377 1092 INTEGER(KIND=2), INTENT(IN) :: value !< attribute value 1378 1093 1379 INTEGER (iwp):: return_value !< return value1094 INTEGER :: return_value !< return value 1380 1095 1381 1096 LOGICAL :: append_internal !< same as 'append' … … 1386 1101 1387 1102 return_value = 0 1103 1104 IF ( PRESENT( variable_name ) ) THEN 1105 variable_name_internal = TRIM( variable_name ) 1106 ELSE 1107 variable_name_internal = '' 1108 ENDIF 1388 1109 1389 1110 IF ( PRESENT( append ) ) THEN 1390 1111 IF ( append ) THEN 1391 1112 return_value = 1 1392 CALL internal_message( 'error', & 1393 routine_name // & 1394 ': attribute "' // TRIM( name ) // & 1395 '": append of numeric attribute not possible.' ) 1113 CALL internal_message( 'error', routine_name // & 1114 ': numeric attribute cannot be appended ' // & 1115 '(attribute "' // TRIM( attribute_name ) // & 1116 '", variable "' // TRIM( variable_name_internal ) // & 1117 '", file "' // TRIM( file_name ) // '")!' ) 1396 1118 ENDIF 1397 1119 ENDIF … … 1400 1122 append_internal = .FALSE. 1401 1123 1402 attribute%name = TRIM( name )1124 attribute%name = TRIM( attribute_name ) 1403 1125 attribute%data_type = 'int16' 1404 1126 attribute%value_int16 = value 1405 1127 1406 IF ( PRESENT( variable ) ) THEN 1407 return_value = dom_def_att_save( TRIM( filename ), TRIM( variable ), & 1408 attribute=attribute, append=append_internal ) 1409 ELSE 1410 return_value = dom_def_att_save( TRIM( filename ), & 1411 attribute=attribute, append=append_internal ) 1412 ENDIF 1128 return_value = save_attribute_in_database( file_name=TRIM( file_name ), & 1129 variable_name=TRIM( variable_name_internal ), & 1130 attribute=attribute, append=append_internal ) 1413 1131 ENDIF 1414 1132 … … 1419 1137 ! ------------ 1420 1138 !> Create attribute with value of type int32. 1421 !--------------------------------------------------------------------------------------------------! 1422 FUNCTION dom_def_att_int32( filename, variable, name, value, append ) RESULT( return_value ) 1423 1424 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1425 CHARACTER(LEN=*), INTENT(IN) :: name !< name of attribute 1426 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable !< name of variable 1139 !> If the optional argument 'variable_name' is given, the attribute is added to the respective 1140 !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to 1141 !> the file itself. 1142 !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). 1143 !> Example call: 1144 !> - define a global file attribute: 1145 !> dom_def_att( file_name='my_output_file_name', & 1146 !> attribute_name='my_attribute', & 1147 !> value=0_4 ) 1148 !> - define a variable attribute: 1149 !> dom_def_att( file_name='my_output_file_name', & 1150 !> variable_name='my_variable', & 1151 !> attribute_name='my_attribute', & 1152 !> value=1_4 ) 1153 !--------------------------------------------------------------------------------------------------! 1154 FUNCTION dom_def_att_int32( file_name, variable_name, attribute_name, value, append ) & 1155 RESULT( return_value ) 1156 1157 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 1158 CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute 1159 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 1160 CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name 1427 1161 1428 1162 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_int32' !< name of routine … … 1430 1164 INTEGER(KIND=4), INTENT(IN) :: value !< attribute value 1431 1165 1432 INTEGER (iwp):: return_value !< return value1166 INTEGER :: return_value !< return value 1433 1167 1434 1168 LOGICAL :: append_internal !< same as 'append' … … 1439 1173 1440 1174 return_value = 0 1175 1176 IF ( PRESENT( variable_name ) ) THEN 1177 variable_name_internal = TRIM( variable_name ) 1178 ELSE 1179 variable_name_internal = '' 1180 ENDIF 1441 1181 1442 1182 IF ( PRESENT( append ) ) THEN 1443 1183 IF ( append ) THEN 1444 1184 return_value = 1 1445 CALL internal_message( 'error', & 1446 routine_name // & 1447 ': attribute "' // TRIM( name ) // & 1448 '": append of numeric attribute not possible.' ) 1185 CALL internal_message( 'error', routine_name // & 1186 ': numeric attribute cannot be appended ' // & 1187 '(attribute "' // TRIM( attribute_name ) // & 1188 '", variable "' // TRIM( variable_name_internal ) // & 1189 '", file "' // TRIM( file_name ) // '")!' ) 1449 1190 ENDIF 1450 1191 ENDIF … … 1453 1194 append_internal = .FALSE. 1454 1195 1455 attribute%name = TRIM( name )1196 attribute%name = TRIM( attribute_name ) 1456 1197 attribute%data_type = 'int32' 1457 1198 attribute%value_int32 = value 1458 1199 1459 IF ( PRESENT( variable ) ) THEN 1460 return_value = dom_def_att_save( TRIM( filename ), TRIM( variable ), & 1461 attribute=attribute, append=append_internal ) 1462 ELSE 1463 return_value = dom_def_att_save( TRIM( filename ), & 1464 attribute=attribute, append=append_internal ) 1465 ENDIF 1200 return_value = save_attribute_in_database( file_name=TRIM( file_name ), & 1201 variable_name=TRIM( variable_name_internal ), & 1202 attribute=attribute, append=append_internal ) 1466 1203 ENDIF 1467 1204 … … 1472 1209 ! ------------ 1473 1210 !> Create attribute with value of type real32. 1474 !--------------------------------------------------------------------------------------------------! 1475 FUNCTION dom_def_att_real32( filename, variable, name, value, append ) RESULT( return_value ) 1476 1477 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1478 CHARACTER(LEN=*), INTENT(IN) :: name !< name of attribute 1479 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable !< name of variable 1211 !> If the optional argument 'variable_name' is given, the attribute is added to the respective 1212 !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to 1213 !> the file itself. 1214 !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). 1215 !> Example call: 1216 !> - define a global file attribute: 1217 !> dom_def_att( file_name='my_output_file_name', & 1218 !> attribute_name='my_attribute', & 1219 !> value=1.0_4 ) 1220 !> - define a variable attribute: 1221 !> dom_def_att( file_name='my_output_file_name', & 1222 !> variable_name='my_variable', & 1223 !> attribute_name='my_attribute', & 1224 !> value=1.0_4 ) 1225 !--------------------------------------------------------------------------------------------------! 1226 FUNCTION dom_def_att_real32( file_name, variable_name, attribute_name, value, append ) & 1227 RESULT( return_value ) 1228 1229 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 1230 CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute 1231 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 1232 CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name 1480 1233 1481 1234 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_real32' !< name of routine 1482 1235 1483 INTEGER (iwp):: return_value !< return value1236 INTEGER :: return_value !< return value 1484 1237 1485 1238 LOGICAL :: append_internal !< same as 'append' … … 1492 1245 1493 1246 return_value = 0 1247 1248 IF ( PRESENT( variable_name ) ) THEN 1249 variable_name_internal = TRIM( variable_name ) 1250 ELSE 1251 variable_name_internal = '' 1252 ENDIF 1494 1253 1495 1254 IF ( PRESENT( append ) ) THEN 1496 1255 IF ( append ) THEN 1497 1256 return_value = 1 1498 CALL internal_message( 'error', & 1499 routine_name // & 1500 ': attribute "' // TRIM( name ) // & 1501 '": append of numeric attribute not possible.' ) 1257 CALL internal_message( 'error', routine_name // & 1258 ': numeric attribute cannot be appended ' // & 1259 '(attribute "' // TRIM( attribute_name ) // & 1260 '", variable "' // TRIM( variable_name_internal ) // & 1261 '", file "' // TRIM( file_name ) // '")!' ) 1502 1262 ENDIF 1503 1263 ENDIF … … 1506 1266 append_internal = .FALSE. 1507 1267 1508 attribute%name = TRIM( name )1268 attribute%name = TRIM( attribute_name ) 1509 1269 attribute%data_type = 'real32' 1510 1270 attribute%value_real32 = value 1511 1271 1512 IF ( PRESENT( variable ) ) THEN 1513 return_value = dom_def_att_save( TRIM( filename ), TRIM( variable ), & 1514 attribute=attribute, append=append_internal ) 1515 ELSE 1516 return_value = dom_def_att_save( TRIM( filename ), & 1517 attribute=attribute, append=append_internal ) 1518 ENDIF 1272 return_value = save_attribute_in_database( file_name=TRIM( file_name ), & 1273 variable_name=TRIM( variable_name_internal ), & 1274 attribute=attribute, append=append_internal ) 1519 1275 ENDIF 1520 1276 … … 1525 1281 ! ------------ 1526 1282 !> Create attribute with value of type real64. 1527 !--------------------------------------------------------------------------------------------------! 1528 FUNCTION dom_def_att_real64( filename, variable, name, value, append ) RESULT( return_value ) 1529 1530 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1531 CHARACTER(LEN=*), INTENT(IN) :: name !< name of attribute 1532 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable !< name of variable 1283 !> If the optional argument 'variable_name' is given, the attribute is added to the respective 1284 !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to 1285 !> the file itself. 1286 !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). 1287 !> Example call: 1288 !> - define a global file attribute: 1289 !> dom_def_att( file_name='my_output_file_name', & 1290 !> attribute_name='my_attribute', & 1291 !> value=0.0_8 ) 1292 !> - define a variable attribute: 1293 !> dom_def_att( file_name='my_output_file_name', & 1294 !> variable_name='my_variable', & 1295 !> attribute_name='my_attribute', & 1296 !> value=1.0_8 ) 1297 !--------------------------------------------------------------------------------------------------! 1298 FUNCTION dom_def_att_real64( file_name, variable_name, attribute_name, value, append ) & 1299 RESULT( return_value ) 1300 1301 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 1302 CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute 1303 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 1304 CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name 1533 1305 1534 1306 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_real64' !< name of routine 1535 1307 1536 INTEGER (iwp):: return_value !< return value1308 INTEGER :: return_value !< return value 1537 1309 1538 1310 LOGICAL :: append_internal !< same as 'append' … … 1545 1317 1546 1318 return_value = 0 1319 1320 IF ( PRESENT( variable_name ) ) THEN 1321 variable_name_internal = TRIM( variable_name ) 1322 ELSE 1323 variable_name_internal = '' 1324 ENDIF 1547 1325 1548 1326 IF ( PRESENT( append ) ) THEN 1549 1327 IF ( append ) THEN 1550 1328 return_value = 1 1551 CALL internal_message( 'error', & 1552 routine_name // & 1553 ': attribute "' // TRIM( name ) // & 1554 '": append of numeric attribute not possible.' ) 1329 CALL internal_message( 'error', routine_name // & 1330 ': numeric attribute cannot be appended ' // & 1331 '(attribute "' // TRIM( attribute_name ) // & 1332 '", variable "' // TRIM( variable_name_internal ) // & 1333 '", file "' // TRIM( file_name ) // '")!' ) 1555 1334 ENDIF 1556 1335 ENDIF … … 1559 1338 append_internal = .FALSE. 1560 1339 1561 attribute%name = TRIM( name )1340 attribute%name = TRIM( attribute_name ) 1562 1341 attribute%data_type = 'real64' 1563 1342 attribute%value_real64 = value 1564 1343 1565 IF ( PRESENT( variable ) ) THEN 1566 return_value = dom_def_att_save( TRIM( filename ), TRIM( variable ), & 1567 attribute=attribute, append=append_internal ) 1344 return_value = save_attribute_in_database( file_name=TRIM( file_name ), & 1345 variable_name=TRIM( variable_name_internal ), & 1346 attribute=attribute, append=append_internal ) 1347 ENDIF 1348 1349 END FUNCTION dom_def_att_real64 1350 1351 !--------------------------------------------------------------------------------------------------! 1352 ! Description: 1353 ! ------------ 1354 !> End output definition. 1355 !> The database is cleared from unused files and dimensions. Then, the output files are initialized 1356 !> and prepared for writing output values to them. The saved values of the dimensions are written 1357 !> to the files. 1358 !--------------------------------------------------------------------------------------------------! 1359 FUNCTION dom_def_end() RESULT( return_value ) 1360 1361 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_end' !< name of routine 1362 1363 INTEGER :: d !< loop index 1364 INTEGER :: f !< loop index 1365 INTEGER :: return_value !< return value 1366 1367 INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE, TARGET :: values_int8 !< target array for dimension values 1368 INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE, TARGET :: values_int16 !< target array for dimension values 1369 INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE, TARGET :: values_int32 !< target array for dimension values 1370 INTEGER(iwp), DIMENSION(:), ALLOCATABLE, TARGET :: values_intwp !< target array for dimension values 1371 1372 INTEGER(KIND=1), DIMENSION(:), POINTER, CONTIGUOUS :: values_int8_pointer !< pointer to target array 1373 INTEGER(KIND=2), DIMENSION(:), POINTER, CONTIGUOUS :: values_int16_pointer !< pointer to target array 1374 INTEGER(KIND=4), DIMENSION(:), POINTER, CONTIGUOUS :: values_int32_pointer !< pointer to target array 1375 INTEGER(iwp), DIMENSION(:), POINTER, CONTIGUOUS :: values_intwp_pointer !< pointer to target array 1376 1377 REAL(KIND=4), DIMENSION(:), ALLOCATABLE, TARGET :: values_real32 !< target array for dimension values 1378 REAL(KIND=8), DIMENSION(:), ALLOCATABLE, TARGET :: values_real64 !< target array for dimension values 1379 REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET :: values_realwp !< target array for dimension values 1380 1381 REAL(KIND=4), DIMENSION(:), POINTER, CONTIGUOUS :: values_real32_pointer !< pointer to target array 1382 REAL(KIND=8), DIMENSION(:), POINTER, CONTIGUOUS :: values_real64_pointer !< pointer to target array 1383 REAL(wp), DIMENSION(:), POINTER, CONTIGUOUS :: values_realwp_pointer !< pointer to target array 1384 1385 1386 return_value = 0 1387 CALL internal_message( 'debug', routine_name // ': start' ) 1388 1389 !-- Clear database from empty files and unused dimensions 1390 IF ( nfiles > 0 ) return_value = cleanup_database() 1391 1392 IF ( return_value == 0 ) THEN 1393 DO f = 1, nfiles 1394 1395 !-- Skip initialization if file is already initialized 1396 IF ( files(f)%is_init ) CYCLE 1397 1398 CALL internal_message( 'debug', routine_name // ': initialize file "' // & 1399 TRIM( files(f)%name ) // '"' ) 1400 1401 !-- Open file 1402 CALL open_output_file( files(f)%format, files(f)%name, files(f)%id, & 1403 return_value=return_value ) 1404 1405 !-- Initialize file header: 1406 !-- define dimensions and variables and write attributes 1407 IF ( return_value == 0 ) & 1408 CALL init_file_header( files(f), return_value=return_value ) 1409 1410 !-- End file definition 1411 IF ( return_value == 0 ) & 1412 CALL stop_file_header_definition( files(f)%format, files(f)%id, & 1413 files(f)%name, return_value ) 1414 1415 IF ( return_value == 0 ) THEN 1416 1417 !-- Flag file as initialized 1418 files(f)%is_init = .TRUE. 1419 1420 !-- Write dimension values into file 1421 DO d = 1, SIZE( files(f)%dimensions ) 1422 IF ( ALLOCATED( files(f)%dimensions(d)%values_int8 ) ) THEN 1423 ALLOCATE( values_int8(files(f)%dimensions(d)%bounds(1): & 1424 files(f)%dimensions(d)%bounds(2)) ) 1425 values_int8 = files(f)%dimensions(d)%values_int8 1426 values_int8_pointer => values_int8 1427 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1428 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1429 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1430 values_int8_1d=values_int8_pointer ) 1431 DEALLOCATE( values_int8 ) 1432 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_int16 ) ) THEN 1433 ALLOCATE( values_int16(files(f)%dimensions(d)%bounds(1): & 1434 files(f)%dimensions(d)%bounds(2)) ) 1435 values_int16 = files(f)%dimensions(d)%values_int16 1436 values_int16_pointer => values_int16 1437 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1438 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1439 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1440 values_int16_1d=values_int16_pointer ) 1441 DEALLOCATE( values_int16 ) 1442 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_int32 ) ) THEN 1443 ALLOCATE( values_int32(files(f)%dimensions(d)%bounds(1): & 1444 files(f)%dimensions(d)%bounds(2)) ) 1445 values_int32 = files(f)%dimensions(d)%values_int32 1446 values_int32_pointer => values_int32 1447 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1448 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1449 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1450 values_int32_1d=values_int32_pointer ) 1451 DEALLOCATE( values_int32 ) 1452 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_intwp ) ) THEN 1453 ALLOCATE( values_intwp(files(f)%dimensions(d)%bounds(1): & 1454 files(f)%dimensions(d)%bounds(2)) ) 1455 values_intwp = files(f)%dimensions(d)%values_intwp 1456 values_intwp_pointer => values_intwp 1457 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1458 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1459 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1460 values_intwp_1d=values_intwp_pointer ) 1461 DEALLOCATE( values_intwp ) 1462 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_real32 ) ) THEN 1463 ALLOCATE( values_real32(files(f)%dimensions(d)%bounds(1): & 1464 files(f)%dimensions(d)%bounds(2)) ) 1465 values_real32 = files(f)%dimensions(d)%values_real32 1466 values_real32_pointer => values_real32 1467 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1468 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1469 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1470 values_real32_1d=values_real32_pointer ) 1471 DEALLOCATE( values_real32 ) 1472 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_real64 ) ) THEN 1473 ALLOCATE( values_real64(files(f)%dimensions(d)%bounds(1): & 1474 files(f)%dimensions(d)%bounds(2)) ) 1475 values_real64 = files(f)%dimensions(d)%values_real64 1476 values_real64_pointer => values_real64 1477 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1478 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1479 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1480 values_real64_1d=values_real64_pointer ) 1481 DEALLOCATE( values_real64 ) 1482 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_realwp ) ) THEN 1483 ALLOCATE( values_realwp(files(f)%dimensions(d)%bounds(1): & 1484 files(f)%dimensions(d)%bounds(2)) ) 1485 values_realwp = files(f)%dimensions(d)%values_realwp 1486 values_realwp_pointer => values_realwp 1487 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1488 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1489 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1490 values_realwp_1d=values_realwp_pointer ) 1491 DEALLOCATE( values_realwp ) 1492 ENDIF 1493 IF ( return_value /= 0 ) EXIT 1494 ENDDO 1495 1496 ENDIF 1497 1498 IF ( return_value /= 0 ) EXIT 1499 1500 ENDDO 1501 ENDIF 1502 1503 CALL internal_message( 'debug', routine_name // ': finished' ) 1504 1505 END FUNCTION dom_def_end 1506 1507 !--------------------------------------------------------------------------------------------------! 1508 ! Description: 1509 ! ------------ 1510 !> Write variable to file. 1511 !> Example call: 1512 !> dom_write_var( file_name = 'my_output_file_name', & 1513 !> name = 'u', & 1514 !> bounds_start = (/nxl, nys, nzb, time_step/), & 1515 !> bounds_end = (/nxr, nyn, nzt, time_step/), & 1516 !> values_real64_3d = u ) 1517 !> @note The order of dimension bounds must match to the order of dimensions given in call 1518 !> 'dom_def_var'. I.e., the corresponding variable definition should be like: 1519 !> dom_def_var( file_name = 'my_output_file_name', & 1520 !> name = 'u', & 1521 !> dimension_names = (/'x ', 'y ', 'z ', 'time'/), & 1522 !> output_type = <desired-output-type> ) 1523 !> @note The values given do not need to be of the same data type as was defined in the 1524 !> corresponding 'dom_def_var' call. If the output format 'netcdf' was chosen, the values are 1525 !> automatically converted to the data type given during the definition. If 'binary' was 1526 !> chosen, the values are written to file as given in the 'dom_write_var' call. 1527 !--------------------------------------------------------------------------------------------------! 1528 FUNCTION dom_write_var( file_name, variable_name, bounds_start, bounds_end, & 1529 values_int8_0d, values_int8_1d, values_int8_2d, values_int8_3d, & 1530 values_int16_0d, values_int16_1d, values_int16_2d, values_int16_3d, & 1531 values_int32_0d, values_int32_1d, values_int32_2d, values_int32_3d, & 1532 values_intwp_0d, values_intwp_1d, values_intwp_2d, values_intwp_3d, & 1533 values_real32_0d, values_real32_1d, values_real32_2d, values_real32_3d, & 1534 values_real64_0d, values_real64_1d, values_real64_2d, values_real64_3d, & 1535 values_realwp_0d, values_realwp_1d, values_realwp_2d, values_realwp_3d & 1536 ) RESULT( return_value ) 1537 1538 CHARACTER(LEN=charlen) :: file_format !< file format chosen for file 1539 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 1540 CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable 1541 1542 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_write_var' !< name of routine 1543 1544 INTEGER :: file_id !< file ID 1545 INTEGER :: i !< loop index 1546 INTEGER :: j !< loop index 1547 INTEGER :: k !< loop index 1548 INTEGER :: output_return_value !< return value of a called output routine 1549 INTEGER :: return_value !< return value 1550 INTEGER :: variable_id !< variable ID 1551 1552 INTEGER, DIMENSION(:), INTENT(IN) :: bounds_end !< end index per dimension of variable 1553 INTEGER, DIMENSION(:), INTENT(IN) :: bounds_start !< start index per dimension of variable 1554 INTEGER, DIMENSION(:), ALLOCATABLE :: bounds_origin !< first index of each dimension 1555 INTEGER, DIMENSION(:), ALLOCATABLE :: bounds_start_internal !< start index per dim. for output after masking 1556 INTEGER, DIMENSION(:), ALLOCATABLE :: value_counts !< count of indices to be written per dimension 1557 INTEGER, DIMENSION(:,:), ALLOCATABLE :: masked_indices !< list containing all output indices along a dimension 1558 1559 LOGICAL :: do_output !< true if any data lies within given range of masked dimension 1560 LOGICAL :: is_global !< true if variable is global 1561 1562 INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL :: values_int8_0d !< output variable 1563 INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL :: values_int16_0d !< output variable 1564 INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL :: values_int32_0d !< output variable 1565 INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL :: values_intwp_0d !< output variable 1566 INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int8_1d !< output variable 1567 INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int16_1d !< output variable 1568 INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int32_1d !< output variable 1569 INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_intwp_1d !< output variable 1570 INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int8_2d !< output variable 1571 INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int16_2d !< output variable 1572 INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int32_2d !< output variable 1573 INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_intwp_2d !< output variable 1574 INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int8_3d !< output variable 1575 INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int16_3d !< output variable 1576 INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int32_3d !< output variable 1577 INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_intwp_3d !< output variable 1578 1579 INTEGER(KIND=1), TARGET, ALLOCATABLE, DIMENSION(:) :: values_int8_1d_resorted !< resorted output variable 1580 INTEGER(KIND=2), TARGET, ALLOCATABLE, DIMENSION(:) :: values_int16_1d_resorted !< resorted output variable 1581 INTEGER(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:) :: values_int32_1d_resorted !< resorted output variable 1582 INTEGER(iwp), TARGET, ALLOCATABLE, DIMENSION(:) :: values_intwp_1d_resorted !< resorted output variable 1583 INTEGER(KIND=1), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_int8_2d_resorted !< resorted output variable 1584 INTEGER(KIND=2), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_int16_2d_resorted !< resorted output variable 1585 INTEGER(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_int32_2d_resorted !< resorted output variable 1586 INTEGER(iwp), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_intwp_2d_resorted !< resorted output variable 1587 INTEGER(KIND=1), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_int8_3d_resorted !< resorted output variable 1588 INTEGER(KIND=2), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_int16_3d_resorted !< resorted output variable 1589 INTEGER(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_int32_3d_resorted !< resorted output variable 1590 INTEGER(iwp), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_intwp_3d_resorted !< resorted output variable 1591 1592 INTEGER(KIND=1), POINTER :: values_int8_0d_pointer !< pointer to resortet array 1593 INTEGER(KIND=2), POINTER :: values_int16_0d_pointer !< pointer to resortet array 1594 INTEGER(KIND=4), POINTER :: values_int32_0d_pointer !< pointer to resortet array 1595 INTEGER(iwp), POINTER :: values_intwp_0d_pointer !< pointer to resortet array 1596 INTEGER(KIND=1), POINTER, CONTIGUOUS, DIMENSION(:) :: values_int8_1d_pointer !< pointer to resortet array 1597 INTEGER(KIND=2), POINTER, CONTIGUOUS, DIMENSION(:) :: values_int16_1d_pointer !< pointer to resortet array 1598 INTEGER(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:) :: values_int32_1d_pointer !< pointer to resortet array 1599 INTEGER(iwp), POINTER, CONTIGUOUS, DIMENSION(:) :: values_intwp_1d_pointer !< pointer to resortet array 1600 INTEGER(KIND=1), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_int8_2d_pointer !< pointer to resortet array 1601 INTEGER(KIND=2), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_int16_2d_pointer !< pointer to resortet array 1602 INTEGER(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_int32_2d_pointer !< pointer to resortet array 1603 INTEGER(iwp), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_intwp_2d_pointer !< pointer to resortet array 1604 INTEGER(KIND=1), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_int8_3d_pointer !< pointer to resortet array 1605 INTEGER(KIND=2), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_int16_3d_pointer !< pointer to resortet array 1606 INTEGER(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_int32_3d_pointer !< pointer to resortet array 1607 INTEGER(iwp), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_intwp_3d_pointer !< pointer to resortet array 1608 1609 REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL :: values_real32_0d !< output variable 1610 REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL :: values_real64_0d !< output variable 1611 REAL(wp), POINTER, INTENT(IN), OPTIONAL :: values_realwp_0d !< output variable 1612 REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_real32_1d !< output variable 1613 REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_real64_1d !< output variable 1614 REAL(wp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_realwp_1d !< output variable 1615 REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_real32_2d !< output variable 1616 REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_real64_2d !< output variable 1617 REAL(wp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_realwp_2d !< output variable 1618 REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_real32_3d !< output variable 1619 REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_real64_3d !< output variable 1620 REAL(wp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_realwp_3d !< output variable 1621 1622 REAL(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:) :: values_real32_1d_resorted !< resorted output variable 1623 REAL(KIND=8), TARGET, ALLOCATABLE, DIMENSION(:) :: values_real64_1d_resorted !< resorted output variable 1624 REAL(wp), TARGET, ALLOCATABLE, DIMENSION(:) :: values_realwp_1d_resorted !< resorted output variable 1625 REAL(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_real32_2d_resorted !< resorted output variable 1626 REAL(KIND=8), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_real64_2d_resorted !< resorted output variable 1627 REAL(wp), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_realwp_2d_resorted !< resorted output variable 1628 REAL(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_real32_3d_resorted !< resorted output variable 1629 REAL(KIND=8), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_real64_3d_resorted !< resorted output variable 1630 REAL(wp), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_realwp_3d_resorted !< resorted output variable 1631 1632 REAL(KIND=4), POINTER :: values_real32_0d_pointer !< pointer to resortet array 1633 REAL(KIND=8), POINTER :: values_real64_0d_pointer !< pointer to resortet array 1634 REAL(wp), POINTER :: values_realwp_0d_pointer !< pointer to resortet array 1635 REAL(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:) :: values_real32_1d_pointer !< pointer to resortet array 1636 REAL(KIND=8), POINTER, CONTIGUOUS, DIMENSION(:) :: values_real64_1d_pointer !< pointer to resortet array 1637 REAL(wp), POINTER, CONTIGUOUS, DIMENSION(:) :: values_realwp_1d_pointer !< pointer to resortet array 1638 REAL(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_real32_2d_pointer !< pointer to resortet array 1639 REAL(KIND=8), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_real64_2d_pointer !< pointer to resortet array 1640 REAL(wp), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_realwp_2d_pointer !< pointer to resortet array 1641 REAL(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_real32_3d_pointer !< pointer to resortet array 1642 REAL(KIND=8), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_real64_3d_pointer !< pointer to resortet array 1643 REAL(wp), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_realwp_3d_pointer !< pointer to resortet array 1644 1645 TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimension_list !< list of used dimensions of variable 1646 1647 1648 return_value = 0 1649 output_return_value = 0 1650 1651 CALL internal_message( 'debug', routine_name // ': write ' // TRIM( variable_name ) // & 1652 ' into file ' // TRIM( file_name ) ) 1653 1654 !-- Search for variable within file 1655 CALL find_var_in_file( file_name, variable_name, file_format, file_id, variable_id, & 1656 is_global, dimension_list, return_value=return_value ) 1657 1658 IF ( return_value == 0 ) THEN 1659 1660 !-- Check if the correct amount of variable bounds were given 1661 IF ( SIZE( bounds_start ) /= SIZE( dimension_list ) .OR. & 1662 SIZE( bounds_end ) /= SIZE( dimension_list ) ) THEN 1663 return_value = 1 1664 CALL internal_message( 'error', routine_name // & 1665 ': number bounds do not match with ' // & 1666 'number of dimensions of variable ' // & 1667 '(variable "' // TRIM( variable_name ) // & 1668 '", file "' // TRIM( file_name ) // '")!' ) 1669 ENDIF 1670 1671 ENDIF 1672 1673 IF ( return_value == 0 ) THEN 1674 1675 !-- Save starting index (lower bounds) of each dimension 1676 ALLOCATE( bounds_origin(SIZE( dimension_list )) ) 1677 ALLOCATE( bounds_start_internal(SIZE( dimension_list )) ) 1678 ALLOCATE( value_counts(SIZE( dimension_list )) ) 1679 1680 WRITE( temp_string, * ) bounds_start 1681 CALL internal_message( 'debug', routine_name // & 1682 ': file "' // TRIM( file_name ) // & 1683 '", variable "' // TRIM( variable_name ) // & 1684 '", bounds_start =' // TRIM( temp_string ) ) 1685 WRITE( temp_string, * ) bounds_end 1686 CALL internal_message( 'debug', routine_name // & 1687 ': file "' // TRIM( file_name ) // & 1688 '", variable "' // TRIM( variable_name ) // & 1689 '", bounds_end =' // TRIM( temp_string ) ) 1690 1691 !-- Get bounds for masking 1692 CALL get_masked_indices_and_masked_dimension_bounds( dimension_list, & 1693 bounds_start, bounds_end, bounds_start_internal, value_counts, bounds_origin, & 1694 masked_indices ) 1695 1696 do_output = .NOT. ANY( value_counts == 0 ) 1697 1698 WRITE( temp_string, * ) bounds_start_internal 1699 CALL internal_message( 'debug', routine_name // & 1700 ': file "' // TRIM( file_name ) // & 1701 '", variable "' // TRIM( variable_name ) // & 1702 '", bounds_start_internal =' // TRIM( temp_string ) ) 1703 WRITE( temp_string, * ) value_counts 1704 CALL internal_message( 'debug', routine_name // & 1705 ': file "' // TRIM( file_name ) // & 1706 '", variable "' // TRIM( variable_name ) // & 1707 '", value_counts =' // TRIM( temp_string ) ) 1708 1709 !-- Mask and resort variable 1710 !-- 8bit integer output 1711 IF ( PRESENT( values_int8_0d ) ) THEN 1712 values_int8_0d_pointer => values_int8_0d 1713 ELSEIF ( PRESENT( values_int8_1d ) ) THEN 1714 IF ( do_output ) THEN 1715 ALLOCATE( values_int8_1d_resorted(0:value_counts(1)-1) ) 1716 !$OMP PARALLEL PRIVATE (i) 1717 !$OMP DO 1718 DO i = 0, value_counts(1) - 1 1719 values_int8_1d_resorted(i) = values_int8_1d(masked_indices(1,i)) 1720 ENDDO 1721 !$OMP END PARALLEL 1722 ELSE 1723 ALLOCATE( values_int8_1d_resorted(1) ) 1724 values_int8_1d_resorted = 0_1 1725 ENDIF 1726 values_int8_1d_pointer => values_int8_1d_resorted 1727 ELSEIF ( PRESENT( values_int8_2d ) ) THEN 1728 IF ( do_output ) THEN 1729 ALLOCATE( values_int8_2d_resorted(0:value_counts(1)-1, & 1730 0:value_counts(2)-1) ) 1731 !$OMP PARALLEL PRIVATE (i,j) 1732 !$OMP DO 1733 DO i = 0, value_counts(1) - 1 1734 DO j = 0, value_counts(2) - 1 1735 values_int8_2d_resorted(i,j) = values_int8_2d(masked_indices(2,j), & 1736 masked_indices(1,i) ) 1737 ENDDO 1738 ENDDO 1739 !$OMP END PARALLEL 1740 ELSE 1741 ALLOCATE( values_int8_2d_resorted(1,1) ) 1742 values_int8_2d_resorted = 0_1 1743 ENDIF 1744 values_int8_2d_pointer => values_int8_2d_resorted 1745 ELSEIF ( PRESENT( values_int8_3d ) ) THEN 1746 IF ( do_output ) THEN 1747 ALLOCATE( values_int8_3d_resorted(0:value_counts(1)-1, & 1748 0:value_counts(2)-1, & 1749 0:value_counts(3)-1) ) 1750 !$OMP PARALLEL PRIVATE (i,j,k) 1751 !$OMP DO 1752 DO i = 0, value_counts(1) - 1 1753 DO j = 0, value_counts(2) - 1 1754 DO k = 0, value_counts(3) - 1 1755 values_int8_3d_resorted(i,j,k) = values_int8_3d(masked_indices(3,k), & 1756 masked_indices(2,j), & 1757 masked_indices(1,i) ) 1758 ENDDO 1759 ENDDO 1760 ENDDO 1761 !$OMP END PARALLEL 1762 ELSE 1763 ALLOCATE( values_int8_3d_resorted(1,1,1) ) 1764 values_int8_3d_resorted = 0_1 1765 ENDIF 1766 values_int8_3d_pointer => values_int8_3d_resorted 1767 1768 !-- 16bit integer output 1769 ELSEIF ( PRESENT( values_int16_0d ) ) THEN 1770 values_int16_0d_pointer => values_int16_0d 1771 ELSEIF ( PRESENT( values_int16_1d ) ) THEN 1772 IF ( do_output ) THEN 1773 ALLOCATE( values_int16_1d_resorted(0:value_counts(1)-1) ) 1774 !$OMP PARALLEL PRIVATE (i) 1775 !$OMP DO 1776 DO i = 0, value_counts(1) - 1 1777 values_int16_1d_resorted(i) = values_int16_1d(masked_indices(1,i)) 1778 ENDDO 1779 !$OMP END PARALLEL 1780 ELSE 1781 ALLOCATE( values_int16_1d_resorted(1) ) 1782 values_int16_1d_resorted = 0_1 1783 ENDIF 1784 values_int16_1d_pointer => values_int16_1d_resorted 1785 ELSEIF ( PRESENT( values_int16_2d ) ) THEN 1786 IF ( do_output ) THEN 1787 ALLOCATE( values_int16_2d_resorted(0:value_counts(1)-1, & 1788 0:value_counts(2)-1) ) 1789 !$OMP PARALLEL PRIVATE (i,j) 1790 !$OMP DO 1791 DO i = 0, value_counts(1) - 1 1792 DO j = 0, value_counts(2) - 1 1793 values_int16_2d_resorted(i,j) = values_int16_2d(masked_indices(2,j), & 1794 masked_indices(1,i)) 1795 ENDDO 1796 ENDDO 1797 !$OMP END PARALLEL 1798 ELSE 1799 ALLOCATE( values_int16_2d_resorted(1,1) ) 1800 values_int16_2d_resorted = 0_1 1801 ENDIF 1802 values_int16_2d_pointer => values_int16_2d_resorted 1803 ELSEIF ( PRESENT( values_int16_3d ) ) THEN 1804 IF ( do_output ) THEN 1805 ALLOCATE( values_int16_3d_resorted(0:value_counts(1)-1, & 1806 0:value_counts(2)-1, & 1807 0:value_counts(3)-1) ) 1808 !$OMP PARALLEL PRIVATE (i,j,k) 1809 !$OMP DO 1810 DO i = 0, value_counts(1) - 1 1811 DO j = 0, value_counts(2) - 1 1812 DO k = 0, value_counts(3) - 1 1813 values_int16_3d_resorted(i,j,k) = values_int16_3d(masked_indices(3,k), & 1814 masked_indices(2,j), & 1815 masked_indices(1,i) ) 1816 ENDDO 1817 ENDDO 1818 ENDDO 1819 !$OMP END PARALLEL 1820 ELSE 1821 ALLOCATE( values_int16_3d_resorted(1,1,1) ) 1822 values_int16_3d_resorted = 0_1 1823 ENDIF 1824 values_int16_3d_pointer => values_int16_3d_resorted 1825 1826 !-- 32bit integer output 1827 ELSEIF ( PRESENT( values_int32_0d ) ) THEN 1828 values_int32_0d_pointer => values_int32_0d 1829 ELSEIF ( PRESENT( values_int32_1d ) ) THEN 1830 IF ( do_output ) THEN 1831 ALLOCATE( values_int32_1d_resorted(0:value_counts(1)-1) ) 1832 !$OMP PARALLEL PRIVATE (i) 1833 !$OMP DO 1834 DO i = 0, value_counts(1) - 1 1835 values_int32_1d_resorted(i) = values_int32_1d(masked_indices(1,i)) 1836 ENDDO 1837 !$OMP END PARALLEL 1838 ELSE 1839 ALLOCATE( values_int32_1d_resorted(1) ) 1840 values_int32_1d_resorted = 0_1 1841 ENDIF 1842 values_int32_1d_pointer => values_int32_1d_resorted 1843 ELSEIF ( PRESENT( values_int32_2d ) ) THEN 1844 IF ( do_output ) THEN 1845 ALLOCATE( values_int32_2d_resorted(0:value_counts(1)-1, & 1846 0:value_counts(2)-1) ) 1847 !$OMP PARALLEL PRIVATE (i,j) 1848 !$OMP DO 1849 DO i = 0, value_counts(1) - 1 1850 DO j = 0, value_counts(2) - 1 1851 values_int32_2d_resorted(i,j) = values_int32_2d(masked_indices(2,j), & 1852 masked_indices(1,i) ) 1853 ENDDO 1854 ENDDO 1855 !$OMP END PARALLEL 1856 ELSE 1857 ALLOCATE( values_int32_2d_resorted(1,1) ) 1858 values_int32_2d_resorted = 0_1 1859 ENDIF 1860 values_int32_2d_pointer => values_int32_2d_resorted 1861 ELSEIF ( PRESENT( values_int32_3d ) ) THEN 1862 IF ( do_output ) THEN 1863 ALLOCATE( values_int32_3d_resorted(0:value_counts(1)-1, & 1864 0:value_counts(2)-1, & 1865 0:value_counts(3)-1) ) 1866 !$OMP PARALLEL PRIVATE (i,j,k) 1867 !$OMP DO 1868 DO i = 0, value_counts(1) - 1 1869 DO j = 0, value_counts(2) - 1 1870 DO k = 0, value_counts(3) - 1 1871 values_int32_3d_resorted(i,j,k) = values_int32_3d(masked_indices(3,k), & 1872 masked_indices(2,j), & 1873 masked_indices(1,i) ) 1874 ENDDO 1875 ENDDO 1876 ENDDO 1877 !$OMP END PARALLEL 1878 ELSE 1879 ALLOCATE( values_int32_3d_resorted(1,1,1) ) 1880 values_int32_3d_resorted = 0_1 1881 ENDIF 1882 values_int32_3d_pointer => values_int32_3d_resorted 1883 1884 !-- working-precision integer output 1885 ELSEIF ( PRESENT( values_intwp_0d ) ) THEN 1886 values_intwp_0d_pointer => values_intwp_0d 1887 ELSEIF ( PRESENT( values_intwp_1d ) ) THEN 1888 IF ( do_output ) THEN 1889 ALLOCATE( values_intwp_1d_resorted(0:value_counts(1)-1) ) 1890 !$OMP PARALLEL PRIVATE (i) 1891 !$OMP DO 1892 DO i = 0, value_counts(1) - 1 1893 values_intwp_1d_resorted(i) = values_intwp_1d(masked_indices(1,i)) 1894 ENDDO 1895 !$OMP END PARALLEL 1896 ELSE 1897 ALLOCATE( values_intwp_1d_resorted(1) ) 1898 values_intwp_1d_resorted = 0_1 1899 ENDIF 1900 values_intwp_1d_pointer => values_intwp_1d_resorted 1901 ELSEIF ( PRESENT( values_intwp_2d ) ) THEN 1902 IF ( do_output ) THEN 1903 ALLOCATE( values_intwp_2d_resorted(0:value_counts(1)-1, & 1904 0:value_counts(2)-1) ) 1905 !$OMP PARALLEL PRIVATE (i,j) 1906 !$OMP DO 1907 DO i = 0, value_counts(1) - 1 1908 DO j = 0, value_counts(2) - 1 1909 values_intwp_2d_resorted(i,j) = values_intwp_2d(masked_indices(2,j), & 1910 masked_indices(1,i) ) 1911 ENDDO 1912 ENDDO 1913 !$OMP END PARALLEL 1914 ELSE 1915 ALLOCATE( values_intwp_2d_resorted(1,1) ) 1916 values_intwp_2d_resorted = 0_1 1917 ENDIF 1918 values_intwp_2d_pointer => values_intwp_2d_resorted 1919 ELSEIF ( PRESENT( values_intwp_3d ) ) THEN 1920 IF ( do_output ) THEN 1921 ALLOCATE( values_intwp_3d_resorted(0:value_counts(1)-1, & 1922 0:value_counts(2)-1, & 1923 0:value_counts(3)-1) ) 1924 !$OMP PARALLEL PRIVATE (i,j,k) 1925 !$OMP DO 1926 DO i = 0, value_counts(1) - 1 1927 DO j = 0, value_counts(2) - 1 1928 DO k = 0, value_counts(3) - 1 1929 values_intwp_3d_resorted(i,j,k) = values_intwp_3d(masked_indices(3,k), & 1930 masked_indices(2,j), & 1931 masked_indices(1,i) ) 1932 ENDDO 1933 ENDDO 1934 ENDDO 1935 !$OMP END PARALLEL 1936 ELSE 1937 ALLOCATE( values_intwp_3d_resorted(1,1,1) ) 1938 values_intwp_3d_resorted = 0_1 1939 ENDIF 1940 values_intwp_3d_pointer => values_intwp_3d_resorted 1941 1942 !-- 32bit real output 1943 ELSEIF ( PRESENT( values_real32_0d ) ) THEN 1944 values_real32_0d_pointer => values_real32_0d 1945 ELSEIF ( PRESENT( values_real32_1d ) ) THEN 1946 IF ( do_output ) THEN 1947 ALLOCATE( values_real32_1d_resorted(0:value_counts(1)-1) ) 1948 !$OMP PARALLEL PRIVATE (i) 1949 !$OMP DO 1950 DO i = 0, value_counts(1) - 1 1951 values_real32_1d_resorted(i) = values_real32_1d(masked_indices(1,i)) 1952 ENDDO 1953 !$OMP END PARALLEL 1954 ELSE 1955 ALLOCATE( values_real32_1d_resorted(1) ) 1956 values_real32_1d_resorted = 0_1 1957 ENDIF 1958 values_real32_1d_pointer => values_real32_1d_resorted 1959 ELSEIF ( PRESENT( values_real32_2d ) ) THEN 1960 IF ( do_output ) THEN 1961 ALLOCATE( values_real32_2d_resorted(0:value_counts(1)-1, & 1962 0:value_counts(2)-1) ) 1963 !$OMP PARALLEL PRIVATE (i,j) 1964 !$OMP DO 1965 DO i = 0, value_counts(1) - 1 1966 DO j = 0, value_counts(2) - 1 1967 values_real32_2d_resorted(i,j) = values_real32_2d(masked_indices(2,j), & 1968 masked_indices(1,i) ) 1969 ENDDO 1970 ENDDO 1971 !$OMP END PARALLEL 1972 ELSE 1973 ALLOCATE( values_real32_2d_resorted(1,1) ) 1974 values_real32_2d_resorted = 0_1 1975 ENDIF 1976 values_real32_2d_pointer => values_real32_2d_resorted 1977 ELSEIF ( PRESENT( values_real32_3d ) ) THEN 1978 IF ( do_output ) THEN 1979 ALLOCATE( values_real32_3d_resorted(0:value_counts(1)-1, & 1980 0:value_counts(2)-1, & 1981 0:value_counts(3)-1) ) 1982 !$OMP PARALLEL PRIVATE (i,j,k) 1983 !$OMP DO 1984 DO i = 0, value_counts(1) - 1 1985 DO j = 0, value_counts(2) - 1 1986 DO k = 0, value_counts(3) - 1 1987 values_real32_3d_resorted(i,j,k) = values_real32_3d(masked_indices(3,k), & 1988 masked_indices(2,j), & 1989 masked_indices(1,i) ) 1990 ENDDO 1991 ENDDO 1992 ENDDO 1993 !$OMP END PARALLEL 1994 ELSE 1995 ALLOCATE( values_real32_3d_resorted(1,1,1) ) 1996 values_real32_3d_resorted = 0_1 1997 ENDIF 1998 values_real32_3d_pointer => values_real32_3d_resorted 1999 2000 !-- 64bit real output 2001 ELSEIF ( PRESENT( values_real64_0d ) ) THEN 2002 values_real64_0d_pointer => values_real64_0d 2003 ELSEIF ( PRESENT( values_real64_1d ) ) THEN 2004 IF ( do_output ) THEN 2005 ALLOCATE( values_real64_1d_resorted(0:value_counts(1)-1) ) 2006 !$OMP PARALLEL PRIVATE (i) 2007 !$OMP DO 2008 DO i = 0, value_counts(1) - 1 2009 values_real64_1d_resorted(i) = values_real64_1d(masked_indices(1,i)) 2010 ENDDO 2011 !$OMP END PARALLEL 2012 ELSE 2013 ALLOCATE( values_real64_1d_resorted(1) ) 2014 values_real64_1d_resorted = 0_1 2015 ENDIF 2016 values_real64_1d_pointer => values_real64_1d_resorted 2017 ELSEIF ( PRESENT( values_real64_2d ) ) THEN 2018 IF ( do_output ) THEN 2019 ALLOCATE( values_real64_2d_resorted(0:value_counts(1)-1, & 2020 0:value_counts(2)-1) ) 2021 !$OMP PARALLEL PRIVATE (i,j) 2022 !$OMP DO 2023 DO i = 0, value_counts(1) - 1 2024 DO j = 0, value_counts(2) - 1 2025 values_real64_2d_resorted(i,j) = values_real64_2d(masked_indices(2,j), & 2026 masked_indices(1,i) ) 2027 ENDDO 2028 ENDDO 2029 !$OMP END PARALLEL 2030 ELSE 2031 ALLOCATE( values_real64_2d_resorted(1,1) ) 2032 values_real64_2d_resorted = 0_1 2033 ENDIF 2034 values_real64_2d_pointer => values_real64_2d_resorted 2035 ELSEIF ( PRESENT( values_real64_3d ) ) THEN 2036 IF ( do_output ) THEN 2037 ALLOCATE( values_real64_3d_resorted(0:value_counts(1)-1, & 2038 0:value_counts(2)-1, & 2039 0:value_counts(3)-1) ) 2040 !$OMP PARALLEL PRIVATE (i,j,k) 2041 !$OMP DO 2042 DO i = 0, value_counts(1) - 1 2043 DO j = 0, value_counts(2) - 1 2044 DO k = 0, value_counts(3) - 1 2045 values_real64_3d_resorted(i,j,k) = values_real64_3d(masked_indices(3,k), & 2046 masked_indices(2,j), & 2047 masked_indices(1,i) ) 2048 ENDDO 2049 ENDDO 2050 ENDDO 2051 !$OMP END PARALLEL 2052 ELSE 2053 ALLOCATE( values_real64_3d_resorted(1,1,1) ) 2054 values_real64_3d_resorted = 0_1 2055 ENDIF 2056 values_real64_3d_pointer => values_real64_3d_resorted 2057 2058 !-- working-precision real output 2059 ELSEIF ( PRESENT( values_realwp_0d ) ) THEN 2060 values_realwp_0d_pointer => values_realwp_0d 2061 ELSEIF ( PRESENT( values_realwp_1d ) ) THEN 2062 IF ( do_output ) THEN 2063 ALLOCATE( values_realwp_1d_resorted(0:value_counts(1)-1) ) 2064 !$OMP PARALLEL PRIVATE (i) 2065 !$OMP DO 2066 DO i = 0, value_counts(1) - 1 2067 values_realwp_1d_resorted(i) = values_realwp_1d(masked_indices(1,i)) 2068 ENDDO 2069 !$OMP END PARALLEL 2070 ELSE 2071 ALLOCATE( values_realwp_1d_resorted(1) ) 2072 values_realwp_1d_resorted = 0_1 2073 ENDIF 2074 values_realwp_1d_pointer => values_realwp_1d_resorted 2075 ELSEIF ( PRESENT( values_realwp_2d ) ) THEN 2076 IF ( do_output ) THEN 2077 ALLOCATE( values_realwp_2d_resorted(0:value_counts(1)-1, & 2078 0:value_counts(2)-1) ) 2079 !$OMP PARALLEL PRIVATE (i,j) 2080 !$OMP DO 2081 DO i = 0, value_counts(1) - 1 2082 DO j = 0, value_counts(2) - 1 2083 values_realwp_2d_resorted(i,j) = values_realwp_2d(masked_indices(2,j), & 2084 masked_indices(1,i) ) 2085 ENDDO 2086 ENDDO 2087 !$OMP END PARALLEL 2088 ELSE 2089 ALLOCATE( values_realwp_2d_resorted(1,1) ) 2090 values_realwp_2d_resorted = 0_1 2091 ENDIF 2092 values_realwp_2d_pointer => values_realwp_2d_resorted 2093 ELSEIF ( PRESENT( values_realwp_3d ) ) THEN 2094 IF ( do_output ) THEN 2095 ALLOCATE( values_realwp_3d_resorted(0:value_counts(1)-1, & 2096 0:value_counts(2)-1, & 2097 0:value_counts(3)-1) ) 2098 !$OMP PARALLEL PRIVATE (i,j,k) 2099 !$OMP DO 2100 DO i = 0, value_counts(1) - 1 2101 DO j = 0, value_counts(2) - 1 2102 DO k = 0, value_counts(3) - 1 2103 values_realwp_3d_resorted(i,j,k) = values_realwp_3d(masked_indices(3,k), & 2104 masked_indices(2,j), & 2105 masked_indices(1,i) ) 2106 ENDDO 2107 ENDDO 2108 ENDDO 2109 !$OMP END PARALLEL 2110 ELSE 2111 ALLOCATE( values_realwp_3d_resorted(1,1,1) ) 2112 values_realwp_3d_resorted = 0_1 2113 ENDIF 2114 values_realwp_3d_pointer => values_realwp_3d_resorted 2115 1568 2116 ELSE 1569 return_value = dom_def_att_save( TRIM( filename ), & 1570 attribute=attribute, append=append_internal ) 2117 return_value = 1 2118 CALL internal_message( 'error', routine_name // & 2119 ': no output values given ' // & 2120 '(variable "' // TRIM( variable_name ) // & 2121 '", file "' // TRIM( file_name ) // '")!' ) 1571 2122 ENDIF 2123 2124 DEALLOCATE( masked_indices ) 2125 2126 ENDIF ! Check for error 2127 2128 IF ( return_value == 0 ) THEN 2129 2130 !-- Write variable into file 2131 SELECT CASE ( TRIM( file_format ) ) 2132 2133 CASE ( 'binary' ) 2134 !-- 8bit integer output 2135 IF ( PRESENT( values_int8_0d ) ) THEN 2136 CALL binary_write_variable( file_id, variable_id, & 2137 bounds_start_internal, value_counts, bounds_origin, is_global, & 2138 values_int8_0d=values_int8_0d_pointer, return_value=output_return_value ) 2139 ELSEIF ( PRESENT( values_int8_1d ) ) THEN 2140 CALL binary_write_variable( file_id, variable_id, & 2141 bounds_start_internal, value_counts, bounds_origin, is_global, & 2142 values_int8_1d=values_int8_1d_pointer, return_value=output_return_value ) 2143 ELSEIF ( PRESENT( values_int8_2d ) ) THEN 2144 CALL binary_write_variable( file_id, variable_id, & 2145 bounds_start_internal, value_counts, bounds_origin, is_global, & 2146 values_int8_2d=values_int8_2d_pointer, return_value=output_return_value ) 2147 ELSEIF ( PRESENT( values_int8_3d ) ) THEN 2148 CALL binary_write_variable( file_id, variable_id, & 2149 bounds_start_internal, value_counts, bounds_origin, is_global, & 2150 values_int8_3d=values_int8_3d_pointer, return_value=output_return_value ) 2151 !-- 16bit integer output 2152 ELSEIF ( PRESENT( values_int16_0d ) ) THEN 2153 CALL binary_write_variable( file_id, variable_id, & 2154 bounds_start_internal, value_counts, bounds_origin, is_global, & 2155 values_int16_0d=values_int16_0d_pointer, return_value=output_return_value ) 2156 ELSEIF ( PRESENT( values_int16_1d ) ) THEN 2157 CALL binary_write_variable( file_id, variable_id, & 2158 bounds_start_internal, value_counts, bounds_origin, is_global, & 2159 values_int16_1d=values_int16_1d_pointer, return_value=output_return_value ) 2160 ELSEIF ( PRESENT( values_int16_2d ) ) THEN 2161 CALL binary_write_variable( file_id, variable_id, & 2162 bounds_start_internal, value_counts, bounds_origin, is_global, & 2163 values_int16_2d=values_int16_2d_pointer, return_value=output_return_value ) 2164 ELSEIF ( PRESENT( values_int16_3d ) ) THEN 2165 CALL binary_write_variable( file_id, variable_id, & 2166 bounds_start_internal, value_counts, bounds_origin, is_global, & 2167 values_int16_3d=values_int16_3d_pointer, return_value=output_return_value ) 2168 !-- 32bit integer output 2169 ELSEIF ( PRESENT( values_int32_0d ) ) THEN 2170 CALL binary_write_variable( file_id, variable_id, & 2171 bounds_start_internal, value_counts, bounds_origin, is_global, & 2172 values_int32_0d=values_int32_0d_pointer, return_value=output_return_value ) 2173 ELSEIF ( PRESENT( values_int32_1d ) ) THEN 2174 CALL binary_write_variable( file_id, variable_id, & 2175 bounds_start_internal, value_counts, bounds_origin, is_global, & 2176 values_int32_1d=values_int32_1d_pointer, return_value=output_return_value ) 2177 ELSEIF ( PRESENT( values_int32_2d ) ) THEN 2178 CALL binary_write_variable( file_id, variable_id, & 2179 bounds_start_internal, value_counts, bounds_origin, is_global, & 2180 values_int32_2d=values_int32_2d_pointer, return_value=output_return_value ) 2181 ELSEIF ( PRESENT( values_int32_3d ) ) THEN 2182 CALL binary_write_variable( file_id, variable_id, & 2183 bounds_start_internal, value_counts, bounds_origin, is_global, & 2184 values_int32_3d=values_int32_3d_pointer, return_value=output_return_value ) 2185 !-- working-precision integer output 2186 ELSEIF ( PRESENT( values_intwp_0d ) ) THEN 2187 CALL binary_write_variable( file_id, variable_id, & 2188 bounds_start_internal, value_counts, bounds_origin, is_global, & 2189 values_intwp_0d=values_intwp_0d_pointer, return_value=output_return_value ) 2190 ELSEIF ( PRESENT( values_intwp_1d ) ) THEN 2191 CALL binary_write_variable( file_id, variable_id, & 2192 bounds_start_internal, value_counts, bounds_origin, is_global, & 2193 values_intwp_1d=values_intwp_1d_pointer, return_value=output_return_value ) 2194 ELSEIF ( PRESENT( values_intwp_2d ) ) THEN 2195 CALL binary_write_variable( file_id, variable_id, & 2196 bounds_start_internal, value_counts, bounds_origin, is_global, & 2197 values_intwp_2d=values_intwp_2d_pointer, return_value=output_return_value ) 2198 ELSEIF ( PRESENT( values_intwp_3d ) ) THEN 2199 CALL binary_write_variable( file_id, variable_id, & 2200 bounds_start_internal, value_counts, bounds_origin, is_global, & 2201 values_intwp_3d=values_intwp_3d_pointer, return_value=output_return_value ) 2202 !-- 32bit real output 2203 ELSEIF ( PRESENT( values_real32_0d ) ) THEN 2204 CALL binary_write_variable( file_id, variable_id, & 2205 bounds_start_internal, value_counts, bounds_origin, is_global, & 2206 values_real32_0d=values_real32_0d_pointer, return_value=output_return_value ) 2207 ELSEIF ( PRESENT( values_real32_1d ) ) THEN 2208 CALL binary_write_variable( file_id, variable_id, & 2209 bounds_start_internal, value_counts, bounds_origin, is_global, & 2210 values_real32_1d=values_real32_1d_pointer, return_value=output_return_value ) 2211 ELSEIF ( PRESENT( values_real32_2d ) ) THEN 2212 CALL binary_write_variable( file_id, variable_id, & 2213 bounds_start_internal, value_counts, bounds_origin, is_global, & 2214 values_real32_2d=values_real32_2d_pointer, return_value=output_return_value ) 2215 ELSEIF ( PRESENT( values_real32_3d ) ) THEN 2216 CALL binary_write_variable( file_id, variable_id, & 2217 bounds_start_internal, value_counts, bounds_origin, is_global, & 2218 values_real32_3d=values_real32_3d_pointer, return_value=output_return_value ) 2219 !-- 64bit real output 2220 ELSEIF ( PRESENT( values_real64_0d ) ) THEN 2221 CALL binary_write_variable( file_id, variable_id, & 2222 bounds_start_internal, value_counts, bounds_origin, is_global, & 2223 values_real64_0d=values_real64_0d_pointer, return_value=output_return_value ) 2224 ELSEIF ( PRESENT( values_real64_1d ) ) THEN 2225 CALL binary_write_variable( file_id, variable_id, & 2226 bounds_start_internal, value_counts, bounds_origin, is_global, & 2227 values_real64_1d=values_real64_1d_pointer, return_value=output_return_value ) 2228 ELSEIF ( PRESENT( values_real64_2d ) ) THEN 2229 CALL binary_write_variable( file_id, variable_id, & 2230 bounds_start_internal, value_counts, bounds_origin, is_global, & 2231 values_real64_2d=values_real64_2d_pointer, return_value=output_return_value ) 2232 ELSEIF ( PRESENT( values_real64_3d ) ) THEN 2233 CALL binary_write_variable( file_id, variable_id, & 2234 bounds_start_internal, value_counts, bounds_origin, is_global, & 2235 values_real64_3d=values_real64_3d_pointer, return_value=output_return_value ) 2236 !-- working-precision real output 2237 ELSEIF ( PRESENT( values_realwp_0d ) ) THEN 2238 CALL binary_write_variable( file_id, variable_id, & 2239 bounds_start_internal, value_counts, bounds_origin, is_global, & 2240 values_realwp_0d=values_realwp_0d_pointer, return_value=output_return_value ) 2241 ELSEIF ( PRESENT( values_realwp_1d ) ) THEN 2242 CALL binary_write_variable( file_id, variable_id, & 2243 bounds_start_internal, value_counts, bounds_origin, is_global, & 2244 values_realwp_1d=values_realwp_1d_pointer, return_value=output_return_value ) 2245 ELSEIF ( PRESENT( values_realwp_2d ) ) THEN 2246 CALL binary_write_variable( file_id, variable_id, & 2247 bounds_start_internal, value_counts, bounds_origin, is_global, & 2248 values_realwp_2d=values_realwp_2d_pointer, return_value=output_return_value ) 2249 ELSEIF ( PRESENT( values_realwp_3d ) ) THEN 2250 CALL binary_write_variable( file_id, variable_id, & 2251 bounds_start_internal, value_counts, bounds_origin, is_global, & 2252 values_realwp_3d=values_realwp_3d_pointer, return_value=output_return_value ) 2253 ELSE 2254 return_value = 1 2255 CALL internal_message( 'error', routine_name // & 2256 ': output_type not supported by file format "' // & 2257 TRIM( file_format ) // '" ' // & 2258 '(variable "' // TRIM( variable_name ) // & 2259 '", file "' // TRIM( file_name ) // '")!' ) 2260 ENDIF 2261 2262 CASE ( 'netcdf4-parallel', 'netcdf4-serial' ) 2263 !-- 8bit integer output 2264 IF ( PRESENT( values_int8_0d ) ) THEN 2265 CALL netcdf4_write_variable( file_id, variable_id, & 2266 bounds_start_internal, value_counts, bounds_origin, is_global, & 2267 values_int8_0d=values_int8_0d_pointer, return_value=output_return_value ) 2268 ELSEIF ( PRESENT( values_int8_1d ) ) THEN 2269 CALL netcdf4_write_variable( file_id, variable_id, & 2270 bounds_start_internal, value_counts, bounds_origin, is_global, & 2271 values_int8_1d=values_int8_1d_pointer, return_value=output_return_value ) 2272 ELSEIF ( PRESENT( values_int8_2d ) ) THEN 2273 CALL netcdf4_write_variable( file_id, variable_id, & 2274 bounds_start_internal, value_counts, bounds_origin, is_global, & 2275 values_int8_2d=values_int8_2d_pointer, return_value=output_return_value ) 2276 ELSEIF ( PRESENT( values_int8_3d ) ) THEN 2277 CALL netcdf4_write_variable( file_id, variable_id, & 2278 bounds_start_internal, value_counts, bounds_origin, is_global, & 2279 values_int8_3d=values_int8_3d_pointer, return_value=output_return_value ) 2280 !-- 16bit integer output 2281 ELSEIF ( PRESENT( values_int16_0d ) ) THEN 2282 CALL netcdf4_write_variable( file_id, variable_id, & 2283 bounds_start_internal, value_counts, bounds_origin, is_global, & 2284 values_int16_0d=values_int16_0d_pointer, return_value=output_return_value ) 2285 ELSEIF ( PRESENT( values_int16_1d ) ) THEN 2286 CALL netcdf4_write_variable( file_id, variable_id, & 2287 bounds_start_internal, value_counts, bounds_origin, is_global, & 2288 values_int16_1d=values_int16_1d_pointer, return_value=output_return_value ) 2289 ELSEIF ( PRESENT( values_int16_2d ) ) THEN 2290 CALL netcdf4_write_variable( file_id, variable_id, & 2291 bounds_start_internal, value_counts, bounds_origin, is_global, & 2292 values_int16_2d=values_int16_2d_pointer, return_value=output_return_value ) 2293 ELSEIF ( PRESENT( values_int16_3d ) ) THEN 2294 CALL netcdf4_write_variable( file_id, variable_id, & 2295 bounds_start_internal, value_counts, bounds_origin, is_global, & 2296 values_int16_3d=values_int16_3d_pointer, return_value=output_return_value ) 2297 !-- 32bit integer output 2298 ELSEIF ( PRESENT( values_int32_0d ) ) THEN 2299 CALL netcdf4_write_variable( file_id, variable_id, & 2300 bounds_start_internal, value_counts, bounds_origin, is_global, & 2301 values_int32_0d=values_int32_0d_pointer, return_value=output_return_value ) 2302 ELSEIF ( PRESENT( values_int32_1d ) ) THEN 2303 CALL netcdf4_write_variable( file_id, variable_id, & 2304 bounds_start_internal, value_counts, bounds_origin, is_global, & 2305 values_int32_1d=values_int32_1d_pointer, return_value=output_return_value ) 2306 ELSEIF ( PRESENT( values_int32_2d ) ) THEN 2307 CALL netcdf4_write_variable( file_id, variable_id, & 2308 bounds_start_internal, value_counts, bounds_origin, is_global, & 2309 values_int32_2d=values_int32_2d_pointer, return_value=output_return_value ) 2310 ELSEIF ( PRESENT( values_int32_3d ) ) THEN 2311 CALL netcdf4_write_variable( file_id, variable_id, & 2312 bounds_start_internal, value_counts, bounds_origin, is_global, & 2313 values_int32_3d=values_int32_3d_pointer, return_value=output_return_value ) 2314 !-- working-precision integer output 2315 ELSEIF ( PRESENT( values_intwp_0d ) ) THEN 2316 CALL netcdf4_write_variable( file_id, variable_id, & 2317 bounds_start_internal, value_counts, bounds_origin, is_global, & 2318 values_intwp_0d=values_intwp_0d_pointer, return_value=output_return_value ) 2319 ELSEIF ( PRESENT( values_intwp_1d ) ) THEN 2320 CALL netcdf4_write_variable( file_id, variable_id, & 2321 bounds_start_internal, value_counts, bounds_origin, is_global, & 2322 values_intwp_1d=values_intwp_1d_pointer, return_value=output_return_value ) 2323 ELSEIF ( PRESENT( values_intwp_2d ) ) THEN 2324 CALL netcdf4_write_variable( file_id, variable_id, & 2325 bounds_start_internal, value_counts, bounds_origin, is_global, & 2326 values_intwp_2d=values_intwp_2d_pointer, return_value=output_return_value ) 2327 ELSEIF ( PRESENT( values_intwp_3d ) ) THEN 2328 CALL netcdf4_write_variable( file_id, variable_id, & 2329 bounds_start_internal, value_counts, bounds_origin, is_global, & 2330 values_intwp_3d=values_intwp_3d_pointer, return_value=output_return_value ) 2331 !-- 32bit real output 2332 ELSEIF ( PRESENT( values_real32_0d ) ) THEN 2333 CALL netcdf4_write_variable( file_id, variable_id, & 2334 bounds_start_internal, value_counts, bounds_origin, is_global, & 2335 values_real32_0d=values_real32_0d_pointer, return_value=output_return_value ) 2336 ELSEIF ( PRESENT( values_real32_1d ) ) THEN 2337 CALL netcdf4_write_variable( file_id, variable_id, & 2338 bounds_start_internal, value_counts, bounds_origin, is_global, & 2339 values_real32_1d=values_real32_1d_pointer, return_value=output_return_value ) 2340 ELSEIF ( PRESENT( values_real32_2d ) ) THEN 2341 CALL netcdf4_write_variable( file_id, variable_id, & 2342 bounds_start_internal, value_counts, bounds_origin, is_global, & 2343 values_real32_2d=values_real32_2d_pointer, return_value=output_return_value ) 2344 ELSEIF ( PRESENT( values_real32_3d ) ) THEN 2345 CALL netcdf4_write_variable( file_id, variable_id, & 2346 bounds_start_internal, value_counts, bounds_origin, is_global, & 2347 values_real32_3d=values_real32_3d_pointer, return_value=output_return_value ) 2348 !-- 64bit real output 2349 ELSEIF ( PRESENT( values_real64_0d ) ) THEN 2350 CALL netcdf4_write_variable( file_id, variable_id, & 2351 bounds_start_internal, value_counts, bounds_origin, is_global, & 2352 values_real64_0d=values_real64_0d_pointer, return_value=output_return_value ) 2353 ELSEIF ( PRESENT( values_real64_1d ) ) THEN 2354 CALL netcdf4_write_variable( file_id, variable_id, & 2355 bounds_start_internal, value_counts, bounds_origin, is_global, & 2356 values_real64_1d=values_real64_1d_pointer, return_value=output_return_value ) 2357 ELSEIF ( PRESENT( values_real64_2d ) ) THEN 2358 CALL netcdf4_write_variable( file_id, variable_id, & 2359 bounds_start_internal, value_counts, bounds_origin, is_global, & 2360 values_real64_2d=values_real64_2d_pointer, return_value=output_return_value ) 2361 ELSEIF ( PRESENT( values_real64_3d ) ) THEN 2362 CALL netcdf4_write_variable( file_id, variable_id, & 2363 bounds_start_internal, value_counts, bounds_origin, is_global, & 2364 values_real64_3d=values_real64_3d_pointer, return_value=output_return_value ) 2365 !-- working-precision real output 2366 ELSEIF ( PRESENT( values_realwp_0d ) ) THEN 2367 CALL netcdf4_write_variable( file_id, variable_id, & 2368 bounds_start_internal, value_counts, bounds_origin, is_global, & 2369 values_realwp_0d=values_realwp_0d_pointer, return_value=output_return_value ) 2370 ELSEIF ( PRESENT( values_realwp_1d ) ) THEN 2371 CALL netcdf4_write_variable( file_id, variable_id, & 2372 bounds_start_internal, value_counts, bounds_origin, is_global, & 2373 values_realwp_1d=values_realwp_1d_pointer, return_value=output_return_value ) 2374 ELSEIF ( PRESENT( values_realwp_2d ) ) THEN 2375 CALL netcdf4_write_variable( file_id, variable_id, & 2376 bounds_start_internal, value_counts, bounds_origin, is_global, & 2377 values_realwp_2d=values_realwp_2d_pointer, return_value=output_return_value ) 2378 ELSEIF ( PRESENT( values_realwp_3d ) ) THEN 2379 CALL netcdf4_write_variable( file_id, variable_id, & 2380 bounds_start_internal, value_counts, bounds_origin, is_global, & 2381 values_realwp_3d=values_realwp_3d_pointer, return_value=output_return_value ) 2382 ELSE 2383 return_value = 1 2384 CALL internal_message( 'error', routine_name // & 2385 ': output_type not supported by file format "' // & 2386 TRIM( file_format ) // '" ' // & 2387 '(variable "' // TRIM( variable_name ) // & 2388 '", file "' // TRIM( file_name ) // '")!' ) 2389 ENDIF 2390 2391 CASE DEFAULT 2392 return_value = 1 2393 CALL internal_message( 'error', routine_name // & 2394 ': file format "' // TRIM( file_format ) // & 2395 '" not supported ' // & 2396 '(variable "' // TRIM( variable_name ) // & 2397 '", file "' // TRIM( file_name ) // '")!' ) 2398 2399 END SELECT 2400 2401 IF ( return_value == 0 .AND. output_return_value /= 0 ) THEN 2402 return_value = 1 2403 CALL internal_message( 'error', routine_name // & 2404 ': error while writing variable ' // & 2405 '(variable "' // TRIM( variable_name ) // & 2406 '", file "' // TRIM( file_name ) // '")!' ) 2407 ENDIF 2408 1572 2409 ENDIF 1573 2410 1574 END FUNCTION dom_def_att_real64 2411 END FUNCTION dom_write_var 2412 2413 !--------------------------------------------------------------------------------------------------! 2414 ! Description: 2415 ! ------------ 2416 !> Finalize output. 2417 !> All necessary steps are carried out to close all output files. If a file could not be closed, 2418 !> this is noted in the error message. 2419 !> 2420 !> @bug if multiple files failed to be closed, only the last failure is given in the error message. 2421 !--------------------------------------------------------------------------------------------------! 2422 FUNCTION dom_finalize_output() RESULT( return_value ) 2423 2424 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_finalize_output' !< name of routine 2425 2426 INTEGER :: f !< loop index 2427 INTEGER :: output_return_value !< return value from called routines 2428 INTEGER :: return_value !< return value 2429 INTEGER :: return_value_internal !< error code after closing a single file 2430 2431 2432 return_value = 0 2433 2434 DO f = 1, nfiles 2435 2436 IF ( files(f)%is_init ) THEN 2437 2438 output_return_value = 0 2439 return_value_internal = 0 2440 2441 SELECT CASE ( TRIM( files(f)%format ) ) 2442 2443 CASE ( 'binary' ) 2444 CALL binary_finalize( files(f)%id, output_return_value ) 2445 2446 CASE ( 'netcdf4-parallel', 'netcdf4-serial' ) 2447 CALL netcdf4_finalize( files(f)%id, output_return_value ) 2448 2449 CASE DEFAULT 2450 return_value_internal = 1 2451 2452 END SELECT 2453 2454 IF ( output_return_value /= 0 ) THEN 2455 return_value = output_return_value 2456 CALL internal_message( 'error', routine_name // & 2457 ': error while finalizing file "' // & 2458 TRIM( files(f)%name ) // '"' ) 2459 ELSEIF ( return_value_internal /= 0 ) THEN 2460 return_value = return_value_internal 2461 CALL internal_message( 'error', routine_name // & 2462 ': unsupported file format "' // & 2463 TRIM( files(f)%format ) // '" for file "' // & 2464 TRIM( files(f)%name ) // '"' ) 2465 ENDIF 2466 2467 ENDIF 2468 2469 ENDDO 2470 2471 END FUNCTION dom_finalize_output 2472 2473 !--------------------------------------------------------------------------------------------------! 2474 ! Description: 2475 ! ------------ 2476 !> Return the last created error message. 2477 !--------------------------------------------------------------------------------------------------! 2478 FUNCTION dom_get_error_message() RESULT( error_message ) 2479 2480 CHARACTER(LEN=800) :: error_message !< return error message to main program 2481 2482 2483 error_message = TRIM( internal_error_message ) 2484 2485 error_message = TRIM( error_message ) // TRIM( binary_get_error_message() ) 2486 2487 error_message = TRIM( error_message ) // TRIM( netcdf4_get_error_message() ) 2488 2489 internal_error_message = '' 2490 2491 END FUNCTION dom_get_error_message 1575 2492 1576 2493 !--------------------------------------------------------------------------------------------------! … … 1581 2498 !> @todo Try to combine similar code parts and shorten routine. 1582 2499 !--------------------------------------------------------------------------------------------------! 1583 FUNCTION dom_def_att_save( filename, variable_name, attribute, append ) RESULT( return_value ) 1584 1585 CHARACTER(LEN=*), INTENT(IN) :: filename !< name of file 1586 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable 1587 1588 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_save' !< name of routine 1589 1590 INTEGER(iwp) :: a !< loop index 1591 INTEGER(iwp) :: d !< loop index 1592 INTEGER(iwp) :: f !< loop index 1593 INTEGER(iwp) :: natt !< number of attributes 1594 INTEGER(iwp) :: return_value !< return value 2500 FUNCTION save_attribute_in_database( file_name, variable_name, attribute, append ) & 2501 RESULT( return_value ) 2502 2503 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 2504 CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable 2505 2506 CHARACTER(LEN=*), PARAMETER :: routine_name = 'save_attribute_in_database' !< name of routine 2507 2508 INTEGER :: a !< loop index 2509 INTEGER :: d !< loop index 2510 INTEGER :: f !< loop index 2511 INTEGER :: natts !< number of attributes 2512 INTEGER :: return_value !< return value 1595 2513 1596 2514 LOGICAL :: found !< true if variable or dimension of name 'variable_name' found … … 1605 2523 found = .FALSE. 1606 2524 1607 IF ( PRESENT( variable_name ) ) THEN 1608 CALL internal_message( 'debug', routine_name // & 1609 ': define attribute "' // TRIM( attribute%name ) // & 1610 '" of variable "' // TRIM( variable_name ) // & 1611 '" in file "' // TRIM( filename ) // '"' ) 1612 ELSE 1613 CALL internal_message( 'debug', routine_name // & 1614 ': define attribute "' // TRIM( attribute%name ) // & 1615 '" in file "' // TRIM( filename ) // '"' ) 1616 ENDIF 1617 1618 DO f = 1, nf 1619 1620 IF ( TRIM( filename ) == files(f)%name ) THEN 2525 CALL internal_message( 'debug', routine_name // & 2526 ': define attribute "' // TRIM( attribute%name ) // & 2527 '" of variable "' // TRIM( variable_name ) // & 2528 '" in file "' // TRIM( file_name ) // '"' ) 2529 2530 DO f = 1, nfiles 2531 2532 IF ( TRIM( file_name ) == files(f)%name ) THEN 1621 2533 1622 2534 IF ( files(f)%is_init ) THEN 1623 2535 return_value = 1 1624 CALL internal_message( 'error', routine_name // ': file "' // TRIM( file name ) // &2536 CALL internal_message( 'error', routine_name // ': file "' // TRIM( file_name ) // & 1625 2537 '" is already initialized. No further attribute definition allowed!' ) 1626 2538 EXIT … … 1628 2540 1629 2541 !-- Add attribute to file 1630 IF ( .NOT. PRESENT( variable_name )) THEN2542 IF ( TRIM( variable_name ) == '' ) THEN 1631 2543 1632 2544 !-- Initialize first file attribute 1633 2545 IF ( .NOT. ALLOCATED( files(f)%attributes ) ) THEN 1634 natt = 11635 ALLOCATE( files(f)%attributes(natt ) )2546 natts = 1 2547 ALLOCATE( files(f)%attributes(natts) ) 1636 2548 ELSE 1637 natt = SIZE( files(f)%attributes )2549 natts = SIZE( files(f)%attributes ) 1638 2550 1639 2551 !-- Check if attribute already exists 1640 DO a = 1, natt 2552 DO a = 1, natts 1641 2553 IF ( files(f)%attributes(a)%name == attribute%name ) THEN 1642 2554 IF ( append ) THEN … … 1655 2567 !-- Extend attribute list by 1 1656 2568 IF ( .NOT. found ) THEN 1657 ALLOCATE( atts_tmp(natt ) )2569 ALLOCATE( atts_tmp(natts) ) 1658 2570 atts_tmp = files(f)%attributes 1659 2571 DEALLOCATE( files(f)%attributes ) 1660 natt = natt+ 11661 ALLOCATE( files(f)%attributes(natt ) )1662 files(f)%attributes(:natt -1) = atts_tmp2572 natts = natts + 1 2573 ALLOCATE( files(f)%attributes(natts) ) 2574 files(f)%attributes(:natts-1) = atts_tmp 1663 2575 DEALLOCATE( atts_tmp ) 1664 2576 ENDIF … … 1667 2579 !-- Save new attribute to the end of the attribute list 1668 2580 IF ( .NOT. found ) THEN 1669 files(f)%attributes(natt ) = attribute2581 files(f)%attributes(natts) = attribute 1670 2582 found = .TRUE. 1671 2583 ENDIF … … 1684 2596 IF ( .NOT. ALLOCATED( files(f)%dimensions(d)%attributes ) ) THEN 1685 2597 !-- Initialize first attribute 1686 natt = 11687 ALLOCATE( files(f)%dimensions(d)%attributes(natt ) )2598 natts = 1 2599 ALLOCATE( files(f)%dimensions(d)%attributes(natts) ) 1688 2600 ELSE 1689 natt = SIZE( files(f)%dimensions(d)%attributes )2601 natts = SIZE( files(f)%dimensions(d)%attributes ) 1690 2602 1691 2603 !-- Check if attribute already exists 1692 DO a = 1, natt 2604 DO a = 1, natts 1693 2605 IF ( files(f)%dimensions(d)%attributes(a)%name == attribute%name ) & 1694 2606 THEN … … 1709 2621 !-- Extend attribute list 1710 2622 IF ( .NOT. found ) THEN 1711 ALLOCATE( atts_tmp(natt ) )2623 ALLOCATE( atts_tmp(natts) ) 1712 2624 atts_tmp = files(f)%dimensions(d)%attributes 1713 2625 DEALLOCATE( files(f)%dimensions(d)%attributes ) 1714 natt = natt+ 11715 ALLOCATE( files(f)%dimensions(d)%attributes(natt ) )1716 files(f)%dimensions(d)%attributes(:natt -1) = atts_tmp2626 natts = natts + 1 2627 ALLOCATE( files(f)%dimensions(d)%attributes(natts) ) 2628 files(f)%dimensions(d)%attributes(:natts-1) = atts_tmp 1717 2629 DEALLOCATE( atts_tmp ) 1718 2630 ENDIF … … 1721 2633 !-- Add new attribute to database 1722 2634 IF ( .NOT. found ) THEN 1723 files(f)%dimensions(d)%attributes(natt ) = attribute2635 files(f)%dimensions(d)%attributes(natts) = attribute 1724 2636 found = .TRUE. 1725 2637 ENDIF … … 1742 2654 IF ( .NOT. ALLOCATED( files(f)%variables(d)%attributes ) ) THEN 1743 2655 !-- Initialize first attribute 1744 natt = 11745 ALLOCATE( files(f)%variables(d)%attributes(natt ) )2656 natts = 1 2657 ALLOCATE( files(f)%variables(d)%attributes(natts) ) 1746 2658 ELSE 1747 natt = SIZE( files(f)%variables(d)%attributes )2659 natts = SIZE( files(f)%variables(d)%attributes ) 1748 2660 1749 2661 !-- Check if attribute already exists 1750 DO a = 1, natt 2662 DO a = 1, natts 1751 2663 IF ( files(f)%variables(d)%attributes(a)%name == attribute%name ) & 1752 2664 THEN … … 1767 2679 !-- Extend attribute list 1768 2680 IF ( .NOT. found ) THEN 1769 ALLOCATE( atts_tmp(natt ) )2681 ALLOCATE( atts_tmp(natts) ) 1770 2682 atts_tmp = files(f)%variables(d)%attributes 1771 2683 DEALLOCATE( files(f)%variables(d)%attributes ) 1772 natt = natt+ 11773 ALLOCATE( files(f)%variables(d)%attributes(natt ) )1774 files(f)%variables(d)%attributes(:natt -1) = atts_tmp2684 natts = natts + 1 2685 ALLOCATE( files(f)%variables(d)%attributes(natts) ) 2686 files(f)%variables(d)%attributes(:natts-1) = atts_tmp 1775 2687 DEALLOCATE( atts_tmp ) 1776 2688 ENDIF … … 1780 2692 !-- Add new attribute to database 1781 2693 IF ( .NOT. found ) THEN 1782 files(f)%variables(d)%attributes(natt ) = attribute2694 files(f)%variables(d)%attributes(natts) = attribute 1783 2695 found = .TRUE. 1784 2696 ENDIF … … 1798 2710 ': requested dimension/variable "' // TRIM( variable_name ) // & 1799 2711 '" for attribute "' // TRIM( attribute%name ) // & 1800 '" does not exist in file "' // TRIM( file name ) // '"' )2712 '" does not exist in file "' // TRIM( file_name ) // '"' ) 1801 2713 ENDIF 1802 2714 1803 2715 EXIT 1804 2716 1805 ENDIF ! variable_name present1806 1807 ENDIF ! check file name2717 ENDIF ! variable_name not empty 2718 2719 ENDIF ! check file_name 1808 2720 1809 2721 ENDDO ! loop over files … … 1813 2725 CALL internal_message( 'error', & 1814 2726 routine_name // & 1815 ': requested file "' // TRIM( file name ) //&2727 ': requested file "' // TRIM( file_name ) // & 1816 2728 '" for attribute "' // TRIM( attribute%name ) // & 1817 2729 '" does not exist' ) 1818 2730 ENDIF 1819 2731 1820 END FUNCTION dom_def_att_save 1821 1822 !--------------------------------------------------------------------------------------------------! 1823 ! Description: 1824 ! ------------ 1825 !> Start with output: clear database from unused files/dimensions, initialize 1826 !> files and write dimension values to files. 1827 !--------------------------------------------------------------------------------------------------! 1828 FUNCTION dom_start_output() RESULT( return_value ) 1829 1830 CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_start_output' !< name of routine 1831 1832 INTEGER(iwp) :: d !< loop index 1833 INTEGER(iwp) :: f !< loop index 1834 INTEGER(iwp) :: return_value !< return value 1835 1836 INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE, TARGET :: values_int8 !< target array for dimension values 1837 INTEGER(KIND=1), DIMENSION(:), POINTER, CONTIGUOUS :: values_int8_pointer !< pointer to target array 1838 1839 INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE, TARGET :: values_int16 !< target array for dimension values 1840 INTEGER(KIND=2), DIMENSION(:), POINTER, CONTIGUOUS :: values_int16_pointer !< pointer to target array 1841 1842 INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE, TARGET :: values_int32 !< target array for dimension values 1843 INTEGER(KIND=4), DIMENSION(:), POINTER, CONTIGUOUS :: values_int32_pointer !< pointer to target array 1844 1845 INTEGER(iwp), DIMENSION(:), ALLOCATABLE, TARGET :: values_intwp !< target array for dimension values 1846 INTEGER(iwp), DIMENSION(:), POINTER, CONTIGUOUS :: values_intwp_pointer !< pointer to target array 1847 1848 REAL(KIND=4), DIMENSION(:), ALLOCATABLE, TARGET :: values_real32 !< target array for dimension values 1849 REAL(KIND=4), DIMENSION(:), POINTER, CONTIGUOUS :: values_real32_pointer !< pointer to target array 1850 1851 REAL(KIND=8), DIMENSION(:), ALLOCATABLE, TARGET :: values_real64 !< target array for dimension values 1852 REAL(KIND=8), DIMENSION(:), POINTER, CONTIGUOUS :: values_real64_pointer !< pointer to target array 1853 1854 REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET :: values_realwp !< target array for dimension values 1855 REAL(wp), DIMENSION(:), POINTER, CONTIGUOUS :: values_realwp_pointer !< pointer to target array 1856 1857 1858 return_value = 0 1859 CALL internal_message( 'debug', routine_name // ': start' ) 1860 1861 !-- Clear database from empty files and unused dimensions 1862 IF ( nf > 0 ) return_value = cleanup_database() 1863 1864 IF ( return_value == 0 ) THEN 1865 DO f = 1, nf 1866 1867 !-- Skip initialization if file is already initialized 1868 IF ( files(f)%is_init ) CYCLE 1869 1870 CALL internal_message( 'debug', routine_name // ': initialize file "' // & 1871 TRIM( files(f)%name ) // '"' ) 1872 1873 !-- Open file 1874 CALL open_output_file( files(f)%format, files(f)%name, files(f)%id, & 1875 return_value=return_value ) 1876 1877 !-- Initialize file header: 1878 !-- define dimensions and variables and write attributes 1879 IF ( return_value == 0 ) & 1880 CALL dom_init_file_header( files(f), return_value=return_value ) 1881 1882 !-- End file definition 1883 IF ( return_value == 0 ) & 1884 CALL dom_init_end( files(f)%format, files(f)%id, files(f)%name, return_value ) 1885 1886 IF ( return_value == 0 ) THEN 1887 1888 !-- Flag file as initialized 1889 files(f)%is_init = .TRUE. 1890 1891 !-- Write dimension values into file 1892 DO d = 1, SIZE( files(f)%dimensions ) 1893 IF ( ALLOCATED( files(f)%dimensions(d)%values_int8 ) ) THEN 1894 ALLOCATE( values_int8(files(f)%dimensions(d)%bounds(1): & 1895 files(f)%dimensions(d)%bounds(2)) ) 1896 values_int8 = files(f)%dimensions(d)%values_int8 1897 values_int8_pointer => values_int8 1898 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1899 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1900 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1901 var_int8_1d=values_int8_pointer ) 1902 DEALLOCATE( values_int8 ) 1903 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_int16 ) ) THEN 1904 ALLOCATE( values_int16(files(f)%dimensions(d)%bounds(1): & 1905 files(f)%dimensions(d)%bounds(2)) ) 1906 values_int16 = files(f)%dimensions(d)%values_int16 1907 values_int16_pointer => values_int16 1908 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1909 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1910 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1911 var_int16_1d=values_int16_pointer ) 1912 DEALLOCATE( values_int16 ) 1913 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_int32 ) ) THEN 1914 ALLOCATE( values_int32(files(f)%dimensions(d)%bounds(1): & 1915 files(f)%dimensions(d)%bounds(2)) ) 1916 values_int32 = files(f)%dimensions(d)%values_int32 1917 values_int32_pointer => values_int32 1918 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1919 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1920 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1921 var_int32_1d=values_int32_pointer ) 1922 DEALLOCATE( values_int32 ) 1923 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_intwp ) ) THEN 1924 ALLOCATE( values_intwp(files(f)%dimensions(d)%bounds(1): & 1925 files(f)%dimensions(d)%bounds(2)) ) 1926 values_intwp = files(f)%dimensions(d)%values_intwp 1927 values_intwp_pointer => values_intwp 1928 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1929 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1930 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1931 var_intwp_1d=values_intwp_pointer ) 1932 DEALLOCATE( values_intwp ) 1933 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_real32 ) ) THEN 1934 ALLOCATE( values_real32(files(f)%dimensions(d)%bounds(1): & 1935 files(f)%dimensions(d)%bounds(2)) ) 1936 values_real32 = files(f)%dimensions(d)%values_real32 1937 values_real32_pointer => values_real32 1938 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1939 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1940 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1941 var_real32_1d=values_real32_pointer ) 1942 DEALLOCATE( values_real32 ) 1943 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_real64 ) ) THEN 1944 ALLOCATE( values_real64(files(f)%dimensions(d)%bounds(1): & 1945 files(f)%dimensions(d)%bounds(2)) ) 1946 values_real64 = files(f)%dimensions(d)%values_real64 1947 values_real64_pointer => values_real64 1948 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1949 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1950 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1951 var_real64_1d=values_real64_pointer ) 1952 DEALLOCATE( values_real64 ) 1953 ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_realwp ) ) THEN 1954 ALLOCATE( values_realwp(files(f)%dimensions(d)%bounds(1): & 1955 files(f)%dimensions(d)%bounds(2)) ) 1956 values_realwp = files(f)%dimensions(d)%values_realwp 1957 values_realwp_pointer => values_realwp 1958 return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & 1959 bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & 1960 bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & 1961 var_realwp_1d=values_realwp_pointer ) 1962 DEALLOCATE( values_realwp ) 1963 ENDIF 1964 IF ( return_value /= 0 ) EXIT 1965 ENDDO 1966 1967 ENDIF 1968 1969 IF ( return_value /= 0 ) EXIT 1970 1971 ENDDO 1972 ENDIF 1973 1974 CALL internal_message( 'debug', routine_name // ': finished' ) 1975 1976 END FUNCTION dom_start_output 2732 END FUNCTION save_attribute_in_database 1977 2733 1978 2734 !--------------------------------------------------------------------------------------------------! … … 1986 2742 ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'cleanup_database' !< name of routine 1987 2743 1988 INTEGER (iwp):: d !< loop index1989 INTEGER (iwp):: f !< loop index1990 INTEGER (iwp):: i !< loop index1991 INTEGER (iwp) :: ndim!< number of dimensions in a file1992 INTEGER (iwp) :: ndim_used!< number of used dimensions in a file1993 INTEGER (iwp) :: nf_used!< number of used files1994 INTEGER (iwp) :: nvar!< number of variables in a file1995 INTEGER (iwp):: return_value !< return value1996 1997 LOGICAL, DIMENSION(1:nf ):: file_is_used !< true if file contains variables1998 LOGICAL, DIMENSION(:), ALLOCATABLE :: dimension_is_used !< true if dimension is used by any variable2744 INTEGER :: d !< loop index 2745 INTEGER :: f !< loop index 2746 INTEGER :: i !< loop index 2747 INTEGER :: ndims !< number of dimensions in a file 2748 INTEGER :: ndims_used !< number of used dimensions in a file 2749 INTEGER :: nfiles_used !< number of used files 2750 INTEGER :: nvars !< number of variables in a file 2751 INTEGER :: return_value !< return value 2752 2753 LOGICAL, DIMENSION(1:nfiles) :: file_is_used !< true if file contains variables 2754 LOGICAL, DIMENSION(:), ALLOCATABLE :: dimension_is_used !< true if dimension is used by any variable 1999 2755 2000 2756 TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: used_dimensions !< list of used dimensions … … 2007 2763 !-- Flag files which contain output variables as used 2008 2764 file_is_used(:) = .FALSE. 2009 DO f = 1, nf 2765 DO f = 1, nfiles 2010 2766 IF ( ALLOCATED( files(f)%variables ) ) THEN 2011 2767 file_is_used(f) = .TRUE. … … 2014 2770 2015 2771 !-- Copy flagged files into temporary list 2016 nf _used = COUNT( file_is_used )2017 ALLOCATE( used_files(nf _used) )2772 nfiles_used = COUNT( file_is_used ) 2773 ALLOCATE( used_files(nfiles_used) ) 2018 2774 i = 0 2019 DO f = 1, nf 2775 DO f = 1, nfiles 2020 2776 IF ( file_is_used(f) ) THEN 2021 2777 i = i + 1 … … 2026 2782 !-- Replace file list with list of used files 2027 2783 DEALLOCATE( files ) 2028 nf = nf_used2029 ALLOCATE( files(nf ) )2784 nfiles = nfiles_used 2785 ALLOCATE( files(nfiles) ) 2030 2786 files = used_files 2031 2787 DEALLOCATE( used_files ) 2032 2788 2033 2789 !-- Check every file for unused dimensions 2034 DO f = 1, nf 2790 DO f = 1, nfiles 2035 2791 2036 2792 !-- If a file is already initialized, it was already checked previously … … 2038 2794 2039 2795 !-- Get number of defined dimensions 2040 ndim = SIZE( files(f)%dimensions )2041 ALLOCATE( dimension_is_used(ndim ) )2796 ndims = SIZE( files(f)%dimensions ) 2797 ALLOCATE( dimension_is_used(ndims) ) 2042 2798 2043 2799 !-- Go through all variables and flag all used dimensions 2044 nvar = SIZE( files(f)%variables )2045 DO d = 1, ndim 2046 DO i = 1, nvar 2800 nvars = SIZE( files(f)%variables ) 2801 DO d = 1, ndims 2802 DO i = 1, nvars 2047 2803 dimension_is_used(d) = & 2048 2804 ANY( files(f)%dimensions(d)%name == files(f)%variables(i)%dimension_names ) … … 2052 2808 2053 2809 !-- Copy used dimensions to temporary list 2054 ndim _used = COUNT( dimension_is_used )2055 ALLOCATE( used_dimensions(ndim _used) )2810 ndims_used = COUNT( dimension_is_used ) 2811 ALLOCATE( used_dimensions(ndims_used) ) 2056 2812 i = 0 2057 DO d = 1, ndim 2813 DO d = 1, ndims 2058 2814 IF ( dimension_is_used(d) ) THEN 2059 2815 i = i + 1 … … 2064 2820 !-- Replace dimension list with list of used dimensions 2065 2821 DEALLOCATE( files(f)%dimensions ) 2066 ndim = ndim_used2067 ALLOCATE( files(f)%dimensions(ndim ) )2822 ndims = ndims_used 2823 ALLOCATE( files(f)%dimensions(ndims) ) 2068 2824 files(f)%dimensions = used_dimensions 2069 2825 DEALLOCATE( used_dimensions ) … … 2079 2835 !> Open requested output file. 2080 2836 !--------------------------------------------------------------------------------------------------! 2081 SUBROUTINE open_output_file( file_format, file name, file_id, return_value )2837 SUBROUTINE open_output_file( file_format, file_name, file_id, return_value ) 2082 2838 2083 2839 CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file 2084 CHARACTER(LEN=*), INTENT(IN) :: file name!< name of file to be checked2840 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file to be checked 2085 2841 2086 2842 CHARACTER(LEN=*), PARAMETER :: routine_name = 'open_output_file' !< name of routine 2087 2843 2088 INTEGER (iwp), INTENT(OUT) :: file_id !< file ID2089 INTEGER (iwp):: output_return_value !< return value of a called output routine2090 INTEGER (iwp), INTENT(OUT) :: return_value !< return value2844 INTEGER, INTENT(OUT) :: file_id !< file ID 2845 INTEGER :: output_return_value !< return value of a called output routine 2846 INTEGER, INTENT(OUT) :: return_value !< return value 2091 2847 2092 2848 … … 2097 2853 2098 2854 CASE ( 'binary' ) 2099 CALL binary_open_file( 'binary', file name, file_id, output_return_value )2855 CALL binary_open_file( 'binary', file_name, file_id, output_return_value ) 2100 2856 2101 2857 CASE ( 'netcdf4-serial' ) 2102 CALL netcdf4_open_file( 'serial', file name, file_id, output_return_value )2858 CALL netcdf4_open_file( 'serial', file_name, file_id, output_return_value ) 2103 2859 2104 2860 CASE ( 'netcdf4-parallel' ) 2105 CALL netcdf4_open_file( 'parallel', file name, file_id, output_return_value )2861 CALL netcdf4_open_file( 'parallel', file_name, file_id, output_return_value ) 2106 2862 2107 2863 CASE DEFAULT … … 2113 2869 return_value = output_return_value 2114 2870 CALL internal_message( 'error', routine_name // & 2115 ': error while opening file "' // TRIM( file name ) // '"' )2871 ': error while opening file "' // TRIM( file_name ) // '"' ) 2116 2872 ELSEIF ( return_value /= 0 ) THEN 2117 CALL internal_message( 'error', routine_name // 2118 ': file "' // TRIM( filename ) //&2119 2120 2873 CALL internal_message( 'error', routine_name // & 2874 ': file "' // TRIM( file_name ) // & 2875 '": file format "' // TRIM( file_format ) // & 2876 '" not supported' ) 2121 2877 ENDIF 2122 2878 … … 2126 2882 ! Description: 2127 2883 ! ------------ 2128 !> Define attributes, dimensions and variables.2129 !--------------------------------------------------------------------------------------------------! 2130 SUBROUTINE dom_init_file_header( file, return_value )2131 2132 ! CHARACTER(LEN=*), PARAMETER :: routine_name = ' dom_init_file_header' !< name of routine2133 2134 INTEGER (iwp):: a !< loop index2135 INTEGER (iwp):: d !< loop index2136 INTEGER (iwp), INTENT(OUT) :: return_value !< return value2884 !> Initialize attributes, dimensions and variables in a file. 2885 !--------------------------------------------------------------------------------------------------! 2886 SUBROUTINE init_file_header( file, return_value ) 2887 2888 ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'init_file_header' !< name of routine 2889 2890 INTEGER :: a !< loop index 2891 INTEGER :: d !< loop index 2892 INTEGER, INTENT(OUT) :: return_value !< return value 2137 2893 2138 2894 TYPE(file_type), INTENT(INOUT) :: file !< initialize header of this file … … 2144 2900 IF ( ALLOCATED( file%attributes ) ) THEN 2145 2901 DO a = 1, SIZE( file%attributes ) 2146 return_value = write_attribute( file%format, file%id, file%name, var_id=no_var_id, & 2902 return_value = write_attribute( file%format, file%id, file%name, & 2903 variable_id=no_id, variable_name='', & 2147 2904 attribute=file%attributes(a) ) 2148 2905 IF ( return_value /= 0 ) EXIT … … 2158 2915 2159 2916 !-- Initialize non-masked dimension 2160 CALL init_file_dimension( file%format, file%id, file%name, &2161 file%dimensions(d)%id, file%dimensions(d)% var_id,&2162 file%dimensions(d)% name, file%dimensions(d)%data_type, &2163 file%dimensions(d)% length, return_value )2917 CALL init_file_dimension( file%format, file%id, file%name, & 2918 file%dimensions(d)%id, file%dimensions(d)%name, & 2919 file%dimensions(d)%data_type, file%dimensions(d)%length, & 2920 file%dimensions(d)%variable_id, return_value ) 2164 2921 2165 2922 ELSE 2166 2923 2167 2924 !-- Initialize masked dimension 2168 CALL init_file_dimension( file%format, file%id, file%name, &2169 file%dimensions(d)%id, file%dimensions(d)% var_id,&2170 file%dimensions(d)% name, file%dimensions(d)%data_type, &2171 file%dimensions(d)% length_mask, return_value )2925 CALL init_file_dimension( file%format, file%id, file%name, & 2926 file%dimensions(d)%id, file%dimensions(d)%name, & 2927 file%dimensions(d)%data_type, file%dimensions(d)%length_mask, & 2928 file%dimensions(d)%variable_id, return_value ) 2172 2929 2173 2930 ENDIF … … 2177 2934 DO a = 1, SIZE( file%dimensions(d)%attributes ) 2178 2935 return_value = write_attribute( file%format, file%id, file%name, & 2179 var _id=file%dimensions(d)%var_id,&2180 var _name=file%dimensions(d)%name,&2936 variable_id=file%dimensions(d)%variable_id, & 2937 variable_name=file%dimensions(d)%name, & 2181 2938 attribute=file%dimensions(d)%attributes(a) ) 2182 2939 IF ( return_value /= 0 ) EXIT … … 2190 2947 !-- Save dimension IDs for variables wihtin database 2191 2948 IF ( return_value == 0 ) & 2192 CALL collect_dimesion_ids_for_variables( file%variables, file%dimensions, return_value ) 2949 CALL collect_dimesion_ids_for_variables( file%name, file%variables, file%dimensions, & 2950 return_value ) 2193 2951 2194 2952 !-- Initialize file variables … … 2205 2963 DO a = 1, SIZE( file%variables(d)%attributes ) 2206 2964 return_value = write_attribute( file%format, file%id, file%name, & 2207 var _id=file%variables(d)%id,&2208 var _name=file%variables(d)%name,&2965 variable_id=file%variables(d)%id, & 2966 variable_name=file%variables(d)%name, & 2209 2967 attribute=file%variables(d)%attributes(a) ) 2210 2968 IF ( return_value /= 0 ) EXIT … … 2219 2977 ENDIF 2220 2978 2221 END SUBROUTINE dom_init_file_header 2979 END SUBROUTINE init_file_header 2980 2981 !--------------------------------------------------------------------------------------------------! 2982 ! Description: 2983 ! ------------ 2984 !> Initialize dimension in file. 2985 !--------------------------------------------------------------------------------------------------! 2986 SUBROUTINE init_file_dimension( file_format, file_id, file_name, & 2987 dimension_id, dimension_name, dimension_type, dimension_length, & 2988 variable_id, return_value ) 2989 2990 CHARACTER(LEN=*), INTENT(IN) :: dimension_name !< name of dimension 2991 CHARACTER(LEN=*), INTENT(IN) :: dimension_type !< data type of dimension 2992 CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file 2993 CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file 2994 2995 CHARACTER(LEN=*), PARAMETER :: routine_name = 'init_file_dimension' !< file format chosen for file 2996 2997 INTEGER, INTENT(OUT) :: dimension_id !< dimension ID 2998 INTEGER, INTENT(IN) :: dimension_length !< length of dimension 2999 INTEGER, INTENT(IN) :: file_id !< file ID 3000 INTEGER :: output_return_value !< return value of a called output routine 3001 INTEGER, INTENT(OUT) :: return_value !< return value 3002 INTEGER, INTENT(OUT) :: variable_id !< associated variable ID 3003 3004 3005 return_value = 0 3006 output_return_value = 0 3007 3008 temp_string = '(file "' // TRIM( file_name ) // & 3009 '", dimension "' // TRIM( dimension_name ) // '")' 3010 3011 SELECT CASE ( TRIM( file_format ) ) 3012 3013 CASE ( 'binary' ) 3014 CALL binary_init_dimension( 'binary', file_id, dimension_id, variable_id, & 3015 dimension_name, dimension_type, dimension_length, & 3016 return_value=output_return_value ) 3017 3018 CASE ( 'netcdf4-serial' ) 3019 CALL netcdf4_init_dimension( 'serial', file_id, dimension_id, variable_id, & 3020 dimension_name, dimension_type, dimension_length, & 3021 return_value=output_return_value ) 3022 3023 CASE ( 'netcdf4-parallel' ) 3024 CALL netcdf4_init_dimension( 'parallel', file_id, dimension_id, variable_id, & 3025 dimension_name, dimension_type, dimension_length, & 3026 return_value=output_return_value ) 3027 3028 CASE DEFAULT 3029 return_value = 1 3030 CALL internal_message( 'error', routine_name // & 3031 ': file format "' // TRIM( file_format ) // & 3032 '" not supported ' // TRIM( temp_string ) ) 3033 3034 END SELECT 3035 3036 IF ( output_return_value /= 0 ) THEN 3037 return_value = output_return_value 3038 CALL internal_message( 'error', routine_name // & 3039 ': error while defining dimension ' // TRIM( temp_string ) ) 3040 ENDIF 3041 3042 END SUBROUTINE init_file_dimension 3043 3044 !--------------------------------------------------------------------------------------------------! 3045 ! Description: 3046 ! ------------ 3047 !> Initialize variable. 3048 !--------------------------------------------------------------------------------------------------! 3049 SUBROUTINE init_file_variable( file_format, file_id, file_name, & 3050 variable_id, variable_name, variable_type, dimension_ids, & 3051 is_global, return_value ) 3052 3053 CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file 3054 CHARACTER(LEN=*), INTENT(IN) :: file_name !< file name 3055 CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable 3056 CHARACTER(LEN=*), INTENT(IN) :: variable_type !< data type of variable 3057 3058 CHARACTER(LEN=*), PARAMETER :: routine_name = 'init_file_variable' !< file format chosen for file 3059 3060 INTEGER, INTENT(IN) :: file_id !< file ID 3061 INTEGER :: output_return_value !< return value of a called output routine 3062 INTEGER, INTENT(OUT) :: return_value !< return value 3063 INTEGER, INTENT(OUT) :: variable_id !< variable ID 3064 3065 INTEGER, DIMENSION(:), INTENT(IN) :: dimension_ids !< list of dimension IDs used by variable 3066 3067 LOGICAL, INTENT(IN) :: is_global !< true if variable is global 3068 3069 3070 return_value = 0 3071 output_return_value = 0 3072 3073 temp_string = '(file "' // TRIM( file_name ) // & 3074 '", variable "' // TRIM( variable_name ) // '")' 3075 3076 SELECT CASE ( TRIM( file_format ) ) 3077 3078 CASE ( 'binary' ) 3079 CALL binary_init_variable( 'binary', file_id, variable_id, variable_name, & 3080 variable_type, dimension_ids, is_global, return_value=output_return_value ) 3081 3082 CASE ( 'netcdf4-serial' ) 3083 CALL netcdf4_init_variable( 'serial', file_id, variable_id, variable_name, & 3084 variable_type, dimension_ids, is_global, return_value=output_return_value ) 3085 3086 CASE ( 'netcdf4-parallel' ) 3087 CALL netcdf4_init_variable( 'parallel', file_id, variable_id, variable_name, & 3088 variable_type, dimension_ids, is_global, return_value=output_return_value ) 3089 3090 CASE DEFAULT 3091 return_value = 1 3092 CALL internal_message( 'error', routine_name // & 3093 ': file format "' // TRIM( file_format ) // & 3094 '" not supported ' // TRIM( temp_string ) ) 3095 3096 END SELECT 3097 3098 IF ( output_return_value /= 0 ) THEN 3099 return_value = output_return_value 3100 CALL internal_message( 'error', routine_name // & 3101 ': error while defining variable ' // TRIM( temp_string ) ) 3102 ENDIF 3103 3104 END SUBROUTINE init_file_variable 2222 3105 2223 3106 !--------------------------------------------------------------------------------------------------! … … 2226 3109 !> Write attribute to file. 2227 3110 !--------------------------------------------------------------------------------------------------! 2228 FUNCTION write_attribute( file_format, file_id, file_name, var_id, var_name, attribute ) RESULT( return_value ) 2229 2230 CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file 2231 CHARACTER(LEN=*), INTENT(IN) :: file_name !< file name 2232 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: var_name !< variable name 3111 FUNCTION write_attribute( file_format, file_id, file_name, & 3112 variable_id, variable_name, attribute ) RESULT( return_value ) 3113 3114 CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file 3115 CHARACTER(LEN=*), INTENT(IN) :: file_name !< file name 3116 CHARACTER(LEN=*), INTENT(IN) :: variable_name !< variable name 2233 3117 2234 3118 CHARACTER(LEN=*), PARAMETER :: routine_name = 'write_attribute' !< file format chosen for file 2235 3119 2236 INTEGER (iwp), INTENT(IN) :: file_id !< file ID2237 INTEGER (iwp):: return_value !< return value2238 INTEGER (iwp):: output_return_value !< return value of a called output routine2239 INTEGER (iwp), INTENT(IN) :: var_id!< variable ID3120 INTEGER, INTENT(IN) :: file_id !< file ID 3121 INTEGER :: return_value !< return value 3122 INTEGER :: output_return_value !< return value of a called output routine 3123 INTEGER, INTENT(IN) :: variable_id !< variable ID 2240 3124 2241 3125 TYPE(attribute_type), INTENT(IN) :: attribute !< attribute to be written … … 2246 3130 2247 3131 !-- Prepare for possible error message 2248 IF ( PRESENT( var_name ) ) THEN 2249 temp_string = '(file "' // TRIM( file_name ) // & 2250 '", variable "' // TRIM( var_name ) // & 2251 '", attribute "' // TRIM( attribute%name ) // '")' 2252 ELSE 2253 temp_string = '(file "' // TRIM( file_name ) // & 2254 '", attribute "' // TRIM( attribute%name ) // '")' 2255 ENDIF 3132 temp_string = '(file "' // TRIM( file_name ) // & 3133 '", variable "' // TRIM( variable_name ) // & 3134 '", attribute "' // TRIM( attribute%name ) // '")' 2256 3135 2257 3136 !-- Write attribute to file … … 2263 3142 2264 3143 CASE( 'char' ) 2265 CALL binary_write_attribute( file_id=file_id, var _id=var_id,&2266 att _name=attribute%name, att_value_char=attribute%value_char, &3144 CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & 3145 attribute_name=attribute%name, value_char=attribute%value_char, & 2267 3146 return_value=output_return_value ) 2268 3147 2269 3148 CASE( 'int8' ) 2270 CALL binary_write_attribute( file_id=file_id, var _id=var_id,&2271 att _name=attribute%name, att_value_int8=attribute%value_int8, &3149 CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & 3150 attribute_name=attribute%name, value_int8=attribute%value_int8, & 2272 3151 return_value=output_return_value ) 2273 3152 2274 3153 CASE( 'int16' ) 2275 CALL binary_write_attribute( file_id=file_id, var _id=var_id,&2276 &nb