[4070] | 1 | !> @file data_output_module.f90 |
---|
| 2 | !--------------------------------------------------------------------------------------------------! |
---|
| 3 | ! This file is part of the PALM model system. |
---|
| 4 | ! |
---|
[4577] | 5 | ! PALM is free software: you can redistribute it and/or modify it under the terms of the GNU General |
---|
| 6 | ! Public License as published by the Free Software Foundation, either version 3 of the License, or |
---|
| 7 | ! (at your option) any later version. |
---|
[4070] | 8 | ! |
---|
[4577] | 9 | ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the |
---|
| 10 | ! implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
---|
| 11 | ! Public License for more details. |
---|
[4070] | 12 | ! |
---|
[4577] | 13 | ! You should have received a copy of the GNU General Public License along with PALM. If not, see |
---|
| 14 | ! <http://www.gnu.org/licenses/>. |
---|
[4070] | 15 | ! |
---|
[4481] | 16 | ! Copyright 2019-2020 Leibniz Universitaet Hannover |
---|
[4070] | 17 | !--------------------------------------------------------------------------------------------------! |
---|
| 18 | ! |
---|
| 19 | ! Current revisions: |
---|
| 20 | ! ------------------ |
---|
[4408] | 21 | ! |
---|
| 22 | ! |
---|
[4070] | 23 | ! Former revisions: |
---|
| 24 | ! ----------------- |
---|
| 25 | ! $Id: data_output_module.f90 4577 2020-06-25 09:53:58Z raasch $ |
---|
[4577] | 26 | ! file re-formatted to follow the PALM coding standard |
---|
| 27 | ! |
---|
| 28 | ! 4500 2020-04-17 10:12:45Z suehring |
---|
[4500] | 29 | ! Avoid uninitialized variables |
---|
[4577] | 30 | ! |
---|
[4500] | 31 | ! 4481 2020-03-31 18:55:54Z maronga |
---|
[4408] | 32 | ! Enable character-array output |
---|
| 33 | ! |
---|
| 34 | ! 4147 2019-08-07 09:42:31Z gronemeier |
---|
[4147] | 35 | ! corrected indentation according to coding standard |
---|
| 36 | ! |
---|
| 37 | ! 4141 2019-08-05 12:24:51Z gronemeier |
---|
[4070] | 38 | ! Initial revision |
---|
| 39 | ! |
---|
| 40 | ! |
---|
| 41 | ! Authors: |
---|
| 42 | ! -------- |
---|
| 43 | !> @author Tobias Gronemeier |
---|
| 44 | !> @author Helge Knoop |
---|
| 45 | ! |
---|
| 46 | !--------------------------------------------------------------------------------------------------! |
---|
| 47 | ! Description: |
---|
| 48 | ! ------------ |
---|
| 49 | !> Data-output module to handle output of variables into output files. |
---|
| 50 | !> |
---|
[4141] | 51 | !> The module first creates an interal database containing all meta data of all output quantities. |
---|
| 52 | !> After defining all meta data, the output files are initialized and prepared for writing. When |
---|
| 53 | !> writing is finished, files can be finalized and closed. |
---|
| 54 | !> The order of calls are as follows: |
---|
| 55 | !> 1. Initialize the module via |
---|
| 56 | !> 'dom_init' |
---|
| 57 | !> 2. Define output files via (multiple calls of) |
---|
| 58 | !> 'dom_def_file', 'dom_def_att', 'dom_def_dim', 'dom_def_var' |
---|
| 59 | !> 3. Leave definition stage via |
---|
| 60 | !> 'dom_def_end' |
---|
| 61 | !> 4. Write output data into file via |
---|
| 62 | !> 'dom_write_var' |
---|
| 63 | !> 5. Finalize the output via |
---|
| 64 | !> 'dom_finalize_output' |
---|
| 65 | !> If any routine exits with a non-zero return value, the error message of the last encountered |
---|
| 66 | !> error can be fetched via 'dom_get_error_message'. |
---|
| 67 | !> For debugging purposes, the content of the database can be written to the debug output via |
---|
| 68 | !> 'dom_database_debug_output'. |
---|
[4070] | 69 | !> |
---|
| 70 | !> @todo Convert variable if type of given values do not fit specified type. |
---|
| 71 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 72 | MODULE data_output_module |
---|
[4070] | 73 | |
---|
[4147] | 74 | USE kinds |
---|
[4070] | 75 | |
---|
[4577] | 76 | USE data_output_netcdf4_module, & |
---|
| 77 | ONLY: netcdf4_finalize, & |
---|
| 78 | netcdf4_get_error_message, & |
---|
| 79 | netcdf4_init_dimension, & |
---|
| 80 | netcdf4_init_module, & |
---|
| 81 | netcdf4_init_variable, & |
---|
| 82 | netcdf4_open_file, & |
---|
| 83 | netcdf4_stop_file_header_definition, & |
---|
| 84 | netcdf4_write_attribute, & |
---|
[4147] | 85 | netcdf4_write_variable |
---|
[4070] | 86 | |
---|
[4577] | 87 | USE data_output_binary_module, & |
---|
| 88 | ONLY: binary_finalize, & |
---|
| 89 | binary_get_error_message, & |
---|
| 90 | binary_init_dimension, & |
---|
| 91 | binary_init_module, & |
---|
| 92 | binary_init_variable, & |
---|
| 93 | binary_open_file, & |
---|
| 94 | binary_stop_file_header_definition, & |
---|
| 95 | binary_write_attribute, & |
---|
[4147] | 96 | binary_write_variable |
---|
[4070] | 97 | |
---|
[4147] | 98 | IMPLICIT NONE |
---|
[4070] | 99 | |
---|
[4147] | 100 | INTEGER, PARAMETER :: charlen = 100 !< maximum length of character variables |
---|
| 101 | INTEGER, PARAMETER :: no_id = -1 !< default ID if no ID was assigned |
---|
[4070] | 102 | |
---|
[4147] | 103 | TYPE attribute_type |
---|
| 104 | CHARACTER(LEN=charlen) :: data_type = '' !< data type |
---|
| 105 | CHARACTER(LEN=charlen) :: name !< attribute name |
---|
| 106 | CHARACTER(LEN=charlen) :: value_char !< attribute value if character |
---|
| 107 | INTEGER(KIND=1) :: value_int8 !< attribute value if 8bit integer |
---|
| 108 | INTEGER(KIND=2) :: value_int16 !< attribute value if 16bit integer |
---|
| 109 | INTEGER(KIND=4) :: value_int32 !< attribute value if 32bit integer |
---|
| 110 | REAL(KIND=4) :: value_real32 !< attribute value if 32bit real |
---|
| 111 | REAL(KIND=8) :: value_real64 !< attribute value if 64bit real |
---|
| 112 | END TYPE attribute_type |
---|
[4070] | 113 | |
---|
[4147] | 114 | TYPE variable_type |
---|
| 115 | CHARACTER(LEN=charlen) :: data_type = '' !< data type |
---|
| 116 | CHARACTER(LEN=charlen) :: name !< variable name |
---|
[4577] | 117 | CHARACTER(LEN=charlen), DIMENSION(:), ALLOCATABLE :: dimension_names !< list of |
---|
| 118 | !< dimension names used by variable |
---|
[4147] | 119 | INTEGER :: id = no_id !< id within file |
---|
[4577] | 120 | LOGICAL :: is_global = .FALSE. !< true if global |
---|
| 121 | !< variable |
---|
| 122 | INTEGER, DIMENSION(:), ALLOCATABLE :: dimension_ids !< list of |
---|
| 123 | !< dimension ids used by variable |
---|
| 124 | TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of |
---|
| 125 | !< attributes |
---|
[4147] | 126 | END TYPE variable_type |
---|
[4070] | 127 | |
---|
[4147] | 128 | TYPE dimension_type |
---|
| 129 | CHARACTER(LEN=charlen) :: data_type = '' !< data type |
---|
| 130 | CHARACTER(LEN=charlen) :: name !< dimension name |
---|
[4577] | 131 | INTEGER :: id = no_id !< dimension id within |
---|
| 132 | !< file |
---|
[4147] | 133 | INTEGER :: length !< length of dimension |
---|
[4577] | 134 | INTEGER :: length_mask !< length of masked |
---|
| 135 | !< dimension |
---|
| 136 | INTEGER :: variable_id = no_id !< associated variable |
---|
| 137 | !< id within file |
---|
[4147] | 138 | LOGICAL :: is_masked = .FALSE. !< true if masked |
---|
[4577] | 139 | INTEGER, DIMENSION(2) :: bounds !< lower and upper bound |
---|
| 140 | !< of dimension |
---|
| 141 | INTEGER, DIMENSION(:), ALLOCATABLE :: masked_indices !< list of masked |
---|
| 142 | !< indices of dimension |
---|
| 143 | INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE :: masked_values_int8 !< masked dimension |
---|
| 144 | !< values if 16bit integer |
---|
| 145 | INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE :: masked_values_int16 !< masked dimension |
---|
| 146 | !< values if 16bit integer |
---|
| 147 | INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE :: masked_values_int32 !< masked dimension |
---|
| 148 | !< values if 32bit integer |
---|
| 149 | INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: masked_values_intwp !< masked dimension |
---|
| 150 | !< values if working-precision int |
---|
| 151 | INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE :: values_int8 !< dimension values if |
---|
| 152 | !< 16bit integer |
---|
| 153 | INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE :: values_int16 !< dimension values if |
---|
| 154 | !< 16bit integer |
---|
| 155 | INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE :: values_int32 !< dimension values if |
---|
| 156 | !< 32bit integer |
---|
| 157 | INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: values_intwp !< dimension values if |
---|
| 158 | !< working-precision integer |
---|
[4147] | 159 | LOGICAL, DIMENSION(:), ALLOCATABLE :: mask !< mask |
---|
[4577] | 160 | REAL(KIND=4), DIMENSION(:), ALLOCATABLE :: masked_values_real32 !< masked dimension |
---|
| 161 | !< values if 32bit real |
---|
| 162 | REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: masked_values_real64 !< masked dimension |
---|
| 163 | !< values if 64bit real |
---|
| 164 | REAL(wp), DIMENSION(:), ALLOCATABLE :: masked_values_realwp !< masked dimension |
---|
| 165 | !< values if working-precision real |
---|
| 166 | REAL(KIND=4), DIMENSION(:), ALLOCATABLE :: values_real32 !< dimension values if |
---|
| 167 | !< 32bit real |
---|
| 168 | REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: values_real64 !< dimension values if |
---|
| 169 | !< 64bit real |
---|
| 170 | REAL(wp), DIMENSION(:), ALLOCATABLE :: values_realwp !< dimension values if |
---|
| 171 | !< working-precision real |
---|
[4147] | 172 | TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of attributes |
---|
| 173 | END TYPE dimension_type |
---|
[4070] | 174 | |
---|
[4147] | 175 | TYPE file_type |
---|
| 176 | CHARACTER(LEN=charlen) :: format = '' !< file format |
---|
| 177 | CHARACTER(LEN=charlen) :: name = '' !< file name |
---|
| 178 | INTEGER :: id = no_id !< id of file |
---|
| 179 | LOGICAL :: is_init = .FALSE. !< true if initialized |
---|
| 180 | TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: attributes !< list of attributes |
---|
| 181 | TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimensions !< list of dimensions |
---|
| 182 | TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: variables !< list of variables |
---|
| 183 | END TYPE file_type |
---|
[4070] | 184 | |
---|
| 185 | |
---|
[4577] | 186 | CHARACTER(LEN=800) :: internal_error_message = '' !< string containing the last error message |
---|
[4147] | 187 | CHARACTER(LEN=charlen) :: output_file_suffix = '' !< file suffix added to each file name |
---|
| 188 | CHARACTER(LEN=800) :: temp_string !< dummy string |
---|
[4070] | 189 | |
---|
[4147] | 190 | INTEGER :: debug_output_unit !< Fortran Unit Number of the debug-output file |
---|
| 191 | INTEGER :: nfiles = 0 !< number of files |
---|
| 192 | INTEGER :: master_rank = 0 !< master rank for tasks to be executed by single PE only |
---|
| 193 | INTEGER :: output_group_comm !< MPI communicator addressing all MPI ranks which participate in output |
---|
[4070] | 194 | |
---|
[4147] | 195 | LOGICAL :: print_debug_output = .FALSE. !< if true, debug output is printed |
---|
[4070] | 196 | |
---|
[4147] | 197 | TYPE(file_type), DIMENSION(:), ALLOCATABLE :: files !< file list |
---|
[4070] | 198 | |
---|
[4147] | 199 | SAVE |
---|
[4070] | 200 | |
---|
[4147] | 201 | PRIVATE |
---|
[4070] | 202 | |
---|
[4147] | 203 | !> Initialize the data-output module |
---|
| 204 | INTERFACE dom_init |
---|
| 205 | MODULE PROCEDURE dom_init |
---|
| 206 | END INTERFACE dom_init |
---|
[4070] | 207 | |
---|
[4147] | 208 | !> Add files to database |
---|
| 209 | INTERFACE dom_def_file |
---|
| 210 | MODULE PROCEDURE dom_def_file |
---|
| 211 | END INTERFACE dom_def_file |
---|
[4070] | 212 | |
---|
[4147] | 213 | !> Add dimensions to database |
---|
| 214 | INTERFACE dom_def_dim |
---|
| 215 | MODULE PROCEDURE dom_def_dim |
---|
| 216 | END INTERFACE dom_def_dim |
---|
[4070] | 217 | |
---|
[4147] | 218 | !> Add variables to database |
---|
| 219 | INTERFACE dom_def_var |
---|
| 220 | MODULE PROCEDURE dom_def_var |
---|
| 221 | END INTERFACE dom_def_var |
---|
[4070] | 222 | |
---|
[4147] | 223 | !> Add attributes to database |
---|
| 224 | INTERFACE dom_def_att |
---|
| 225 | MODULE PROCEDURE dom_def_att_char |
---|
| 226 | MODULE PROCEDURE dom_def_att_int8 |
---|
| 227 | MODULE PROCEDURE dom_def_att_int16 |
---|
| 228 | MODULE PROCEDURE dom_def_att_int32 |
---|
| 229 | MODULE PROCEDURE dom_def_att_real32 |
---|
| 230 | MODULE PROCEDURE dom_def_att_real64 |
---|
| 231 | END INTERFACE dom_def_att |
---|
[4070] | 232 | |
---|
[4147] | 233 | !> Prepare for output: evaluate database and create files |
---|
| 234 | INTERFACE dom_def_end |
---|
| 235 | MODULE PROCEDURE dom_def_end |
---|
| 236 | END INTERFACE dom_def_end |
---|
[4070] | 237 | |
---|
[4147] | 238 | !> Write variables to file |
---|
| 239 | INTERFACE dom_write_var |
---|
| 240 | MODULE PROCEDURE dom_write_var |
---|
| 241 | END INTERFACE dom_write_var |
---|
[4070] | 242 | |
---|
[4147] | 243 | !> Last actions required for output befor termination |
---|
| 244 | INTERFACE dom_finalize_output |
---|
| 245 | MODULE PROCEDURE dom_finalize_output |
---|
| 246 | END INTERFACE dom_finalize_output |
---|
[4070] | 247 | |
---|
[4147] | 248 | !> Return error message |
---|
| 249 | INTERFACE dom_get_error_message |
---|
| 250 | MODULE PROCEDURE dom_get_error_message |
---|
| 251 | END INTERFACE dom_get_error_message |
---|
[4070] | 252 | |
---|
[4147] | 253 | !> Write database to debug output |
---|
| 254 | INTERFACE dom_database_debug_output |
---|
| 255 | MODULE PROCEDURE dom_database_debug_output |
---|
| 256 | END INTERFACE dom_database_debug_output |
---|
[4141] | 257 | |
---|
[4147] | 258 | PUBLIC & |
---|
| 259 | dom_init, & |
---|
| 260 | dom_def_file, & |
---|
| 261 | dom_def_dim, & |
---|
| 262 | dom_def_var, & |
---|
| 263 | dom_def_att, & |
---|
| 264 | dom_def_end, & |
---|
| 265 | dom_write_var, & |
---|
| 266 | dom_finalize_output, & |
---|
| 267 | dom_get_error_message, & |
---|
| 268 | dom_database_debug_output |
---|
[4070] | 269 | |
---|
[4147] | 270 | CONTAINS |
---|
[4070] | 271 | |
---|
| 272 | |
---|
| 273 | !--------------------------------------------------------------------------------------------------! |
---|
| 274 | ! Description: |
---|
| 275 | ! ------------ |
---|
[4141] | 276 | !> Initialize data-output module. |
---|
| 277 | !> Provide some general information of the main program. |
---|
| 278 | !> The optional argument 'file_suffix_of_output_group' defines a file suffix which is added to all |
---|
| 279 | !> output files. If multiple output groups (groups of MPI ranks, defined by |
---|
| 280 | !> 'mpi_comm_of_output_group') exist, a unique file suffix must be given for each group. This |
---|
| 281 | !> prevents that multiple groups try to open and write to the same output file. |
---|
[4070] | 282 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 283 | SUBROUTINE dom_init( file_suffix_of_output_group, mpi_comm_of_output_group, master_output_rank, & |
---|
| 284 | program_debug_output_unit, debug_output ) |
---|
[4070] | 285 | |
---|
[4147] | 286 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: file_suffix_of_output_group !< file-name suffix added to each file; |
---|
| 287 | !> must be unique for each output group |
---|
[4070] | 288 | |
---|
[4147] | 289 | INTEGER, INTENT(IN), OPTIONAL :: master_output_rank !< MPI rank executing tasks which must |
---|
| 290 | !> be executed by a single PE only |
---|
| 291 | INTEGER, INTENT(IN) :: mpi_comm_of_output_group !< MPI communicator specifying the MPI group |
---|
| 292 | !> which participate in the output |
---|
| 293 | INTEGER, INTENT(IN) :: program_debug_output_unit !< file unit number for debug output |
---|
[4107] | 294 | |
---|
[4147] | 295 | LOGICAL, INTENT(IN) :: debug_output !< if true, debug output is printed |
---|
[4070] | 296 | |
---|
| 297 | |
---|
[4147] | 298 | IF ( PRESENT( file_suffix_of_output_group ) ) output_file_suffix = file_suffix_of_output_group |
---|
| 299 | IF ( PRESENT( master_output_rank ) ) master_rank = master_output_rank |
---|
[4107] | 300 | |
---|
[4147] | 301 | output_group_comm = mpi_comm_of_output_group |
---|
[4107] | 302 | |
---|
[4147] | 303 | debug_output_unit = program_debug_output_unit |
---|
| 304 | print_debug_output = debug_output |
---|
[4070] | 305 | |
---|
[4147] | 306 | CALL binary_init_module( output_file_suffix, output_group_comm, master_rank, & |
---|
| 307 | debug_output_unit, debug_output, no_id ) |
---|
[4070] | 308 | |
---|
[4147] | 309 | CALL netcdf4_init_module( output_file_suffix, output_group_comm, master_rank, & |
---|
| 310 | debug_output_unit, debug_output, no_id ) |
---|
[4070] | 311 | |
---|
[4147] | 312 | END SUBROUTINE dom_init |
---|
[4070] | 313 | |
---|
| 314 | !--------------------------------------------------------------------------------------------------! |
---|
| 315 | ! Description: |
---|
| 316 | ! ------------ |
---|
| 317 | !> Define output file. |
---|
[4141] | 318 | !> Example call: |
---|
| 319 | !> status = dom_def_file( 'my_output_file_name', 'binary' ) |
---|
[4070] | 320 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 321 | FUNCTION dom_def_file( file_name, file_format ) RESULT( return_value ) |
---|
[4070] | 322 | |
---|
[4577] | 323 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_file' !< name of this routine |
---|
| 324 | |
---|
[4147] | 325 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file to be created |
---|
| 326 | CHARACTER(LEN=*), INTENT(IN) :: file_format !< format of file to be created |
---|
[4070] | 327 | |
---|
[4147] | 328 | INTEGER :: f !< loop index |
---|
| 329 | INTEGER :: return_value !< return value |
---|
[4070] | 330 | |
---|
[4147] | 331 | TYPE(file_type), DIMENSION(:), ALLOCATABLE :: files_tmp !< temporary file list |
---|
[4070] | 332 | |
---|
| 333 | |
---|
[4147] | 334 | return_value = 0 |
---|
[4070] | 335 | |
---|
[4147] | 336 | CALL internal_message( 'debug', routine_name // ': define file "' // TRIM( file_name ) // '"' ) |
---|
| 337 | ! |
---|
| 338 | !-- Allocate file list or extend it by 1 |
---|
| 339 | IF ( .NOT. ALLOCATED( files ) ) THEN |
---|
[4116] | 340 | |
---|
[4147] | 341 | nfiles = 1 |
---|
| 342 | ALLOCATE( files(nfiles) ) |
---|
[4070] | 343 | |
---|
[4147] | 344 | ELSE |
---|
[4070] | 345 | |
---|
[4147] | 346 | nfiles = SIZE( files ) |
---|
| 347 | ! |
---|
| 348 | !-- Check if file already exists |
---|
| 349 | DO f = 1, nfiles |
---|
| 350 | IF ( files(f)%name == TRIM( file_name ) ) THEN |
---|
| 351 | return_value = 1 |
---|
| 352 | CALL internal_message( 'error', routine_name // & |
---|
| 353 | ': file "' // TRIM( file_name ) // '" already exists' ) |
---|
| 354 | EXIT |
---|
| 355 | ENDIF |
---|
| 356 | ENDDO |
---|
| 357 | ! |
---|
| 358 | !-- Extend file list |
---|
| 359 | IF ( return_value == 0 ) THEN |
---|
| 360 | ALLOCATE( files_tmp(nfiles) ) |
---|
| 361 | files_tmp = files |
---|
| 362 | DEALLOCATE( files ) |
---|
| 363 | nfiles = nfiles + 1 |
---|
| 364 | ALLOCATE( files(nfiles) ) |
---|
| 365 | files(:nfiles-1) = files_tmp |
---|
| 366 | DEALLOCATE( files_tmp ) |
---|
| 367 | ENDIF |
---|
[4070] | 368 | |
---|
[4147] | 369 | ENDIF |
---|
| 370 | ! |
---|
| 371 | !-- Add new file to database |
---|
| 372 | IF ( return_value == 0 ) THEN |
---|
| 373 | files(nfiles)%name = TRIM( file_name ) |
---|
| 374 | files(nfiles)%format = TRIM( file_format ) |
---|
| 375 | ENDIF |
---|
[4070] | 376 | |
---|
[4147] | 377 | END FUNCTION dom_def_file |
---|
[4070] | 378 | |
---|
| 379 | !--------------------------------------------------------------------------------------------------! |
---|
| 380 | ! Description: |
---|
| 381 | ! ------------ |
---|
[4141] | 382 | !> Define dimension. |
---|
| 383 | !> Dimensions can either be limited (a lower and upper bound is given) or unlimited (only a lower |
---|
| 384 | !> bound is given). Also, instead of providing all values of the dimension, a single value can be |
---|
| 385 | !> given which is then used to fill the entire dimension. |
---|
| 386 | !> An optional mask can be given to mask limited dimensions. |
---|
| 387 | !> Example call: |
---|
| 388 | !> - fixed dimension with 100 entries (values known): |
---|
| 389 | !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & |
---|
| 390 | !> output_type='real32', bounds=(/1,100/), & |
---|
| 391 | !> values_real32=my_dim(1:100), mask=my_dim_mask(1:100) ) |
---|
| 392 | !> - fixed dimension with 50 entries (values not yet known): |
---|
| 393 | !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & |
---|
| 394 | !> output_type='int32', bounds=(/0,49/), & |
---|
| 395 | !> values_int32=(/fill_value/) ) |
---|
| 396 | !> - masked dimension with 75 entries: |
---|
| 397 | !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & |
---|
| 398 | !> output_type='real64', bounds=(/101,175/), & |
---|
| 399 | !> values_real64=my_dim(1:75), mask=my_dim_mask(1:75) ) |
---|
| 400 | !> - unlimited dimension: |
---|
| 401 | !> status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', & |
---|
| 402 | !> output_type='real32', bounds=(/1/), & |
---|
| 403 | !> values_real32=(/fill_value/) ) |
---|
[4070] | 404 | !> |
---|
| 405 | !> @todo Convert given values into selected output_type. |
---|
| 406 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 407 | FUNCTION dom_def_dim( file_name, dimension_name, output_type, bounds, & |
---|
| 408 | values_int8, values_int16, values_int32, values_intwp, & |
---|
| 409 | values_real32, values_real64, values_realwp, & |
---|
| 410 | mask ) RESULT( return_value ) |
---|
[4070] | 411 | |
---|
[4577] | 412 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_dim' !< name of this routine |
---|
| 413 | |
---|
[4147] | 414 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 415 | CHARACTER(LEN=*), INTENT(IN) :: dimension_name !< name of dimension |
---|
| 416 | CHARACTER(LEN=*), INTENT(IN) :: output_type !< data type of dimension variable in output file |
---|
[4070] | 417 | |
---|
[4147] | 418 | INTEGER :: d !< loop index |
---|
| 419 | INTEGER :: f !< loop index |
---|
| 420 | INTEGER :: i !< loop index |
---|
| 421 | INTEGER :: j !< loop index |
---|
[4500] | 422 | INTEGER :: ndims = 0 !< number of dimensions in file |
---|
[4147] | 423 | INTEGER :: return_value !< return value |
---|
[4070] | 424 | |
---|
[4147] | 425 | INTEGER, DIMENSION(:), INTENT(IN) :: bounds !< lower and upper bound of dimension variable |
---|
| 426 | INTEGER(KIND=1), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int8 !< values of dimension |
---|
| 427 | INTEGER(KIND=2), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int16 !< values of dimension |
---|
| 428 | INTEGER(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL :: values_int32 !< values of dimension |
---|
| 429 | INTEGER(iwp), DIMENSION(:), INTENT(IN), OPTIONAL :: values_intwp !< values of dimension |
---|
[4070] | 430 | |
---|
[4147] | 431 | LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL :: mask !< mask of dimesion |
---|
[4070] | 432 | |
---|
[4147] | 433 | REAL(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL :: values_real32 !< values of dimension |
---|
| 434 | REAL(KIND=8), DIMENSION(:), INTENT(IN), OPTIONAL :: values_real64 !< values of dimension |
---|
| 435 | REAL(wp), DIMENSION(:), INTENT(IN), OPTIONAL :: values_realwp !< values of dimension |
---|
[4070] | 436 | |
---|
[4147] | 437 | TYPE(dimension_type) :: dimension !< new dimension |
---|
| 438 | TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimensions_tmp !< temporary dimension list |
---|
[4070] | 439 | |
---|
| 440 | |
---|
[4147] | 441 | return_value = 0 |
---|
[4070] | 442 | |
---|
[4577] | 443 | CALL internal_message( 'debug', routine_name // & |
---|
| 444 | ': define dimension ' // & |
---|
| 445 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 446 | '", file "' // TRIM( file_name ) // '")' ) |
---|
[4116] | 447 | |
---|
[4147] | 448 | dimension%name = TRIM( dimension_name ) |
---|
| 449 | dimension%data_type = TRIM( output_type ) |
---|
| 450 | ! |
---|
| 451 | !-- Check dimension bounds and allocate dimension according to bounds |
---|
| 452 | IF ( SIZE( bounds ) == 1 ) THEN |
---|
| 453 | ! |
---|
[4577] | 454 | !-- Dimension has only lower bound, which means it changes its size during simulation. |
---|
[4147] | 455 | !-- Set length to -1 as indicator. |
---|
| 456 | dimension%bounds(:) = bounds(1) |
---|
| 457 | dimension%length = -1 |
---|
[4070] | 458 | |
---|
[4147] | 459 | IF ( PRESENT( mask ) ) THEN |
---|
| 460 | return_value = 1 |
---|
[4577] | 461 | CALL internal_message( 'error', routine_name // & |
---|
| 462 | ': unlimited dimensions cannot be masked ' // & |
---|
| 463 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 464 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 465 | ENDIF |
---|
[4070] | 466 | |
---|
[4147] | 467 | ELSEIF ( SIZE( bounds ) == 2 ) THEN |
---|
[4070] | 468 | |
---|
[4147] | 469 | dimension%bounds = bounds |
---|
| 470 | dimension%length = bounds(2) - bounds(1) + 1 |
---|
| 471 | ! |
---|
| 472 | !-- Save dimension values |
---|
| 473 | IF ( PRESENT( values_int8 ) ) THEN |
---|
| 474 | ALLOCATE( dimension%values_int8(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 475 | IF ( SIZE( values_int8 ) == dimension%length ) THEN |
---|
| 476 | dimension%values_int8 = values_int8 |
---|
| 477 | ELSEIF ( SIZE( values_int8 ) == 1 ) THEN |
---|
| 478 | dimension%values_int8(:) = values_int8(1) |
---|
| 479 | ELSE |
---|
| 480 | return_value = 2 |
---|
| 481 | ENDIF |
---|
| 482 | ELSEIF( PRESENT( values_int16 ) ) THEN |
---|
| 483 | ALLOCATE( dimension%values_int16(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 484 | IF ( SIZE( values_int16 ) == dimension%length ) THEN |
---|
| 485 | dimension%values_int16 = values_int16 |
---|
| 486 | ELSEIF ( SIZE( values_int16 ) == 1 ) THEN |
---|
| 487 | dimension%values_int16(:) = values_int16(1) |
---|
| 488 | ELSE |
---|
| 489 | return_value = 2 |
---|
| 490 | ENDIF |
---|
| 491 | ELSEIF( PRESENT( values_int32 ) ) THEN |
---|
| 492 | ALLOCATE( dimension%values_int32(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 493 | IF ( SIZE( values_int32 ) == dimension%length ) THEN |
---|
| 494 | dimension%values_int32 = values_int32 |
---|
| 495 | ELSEIF ( SIZE( values_int32 ) == 1 ) THEN |
---|
| 496 | dimension%values_int32(:) = values_int32(1) |
---|
| 497 | ELSE |
---|
| 498 | return_value = 2 |
---|
| 499 | ENDIF |
---|
| 500 | ELSEIF( PRESENT( values_intwp ) ) THEN |
---|
| 501 | ALLOCATE( dimension%values_intwp(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 502 | IF ( SIZE( values_intwp ) == dimension%length ) THEN |
---|
| 503 | dimension%values_intwp = values_intwp |
---|
| 504 | ELSEIF ( SIZE( values_intwp ) == 1 ) THEN |
---|
| 505 | dimension%values_intwp(:) = values_intwp(1) |
---|
| 506 | ELSE |
---|
| 507 | return_value = 2 |
---|
| 508 | ENDIF |
---|
| 509 | ELSEIF( PRESENT( values_real32 ) ) THEN |
---|
| 510 | ALLOCATE( dimension%values_real32(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 511 | IF ( SIZE( values_real32 ) == dimension%length ) THEN |
---|
| 512 | dimension%values_real32 = values_real32 |
---|
| 513 | ELSEIF ( SIZE( values_real32 ) == 1 ) THEN |
---|
| 514 | dimension%values_real32(:) = values_real32(1) |
---|
| 515 | ELSE |
---|
| 516 | return_value = 2 |
---|
| 517 | ENDIF |
---|
| 518 | ELSEIF( PRESENT( values_real64 ) ) THEN |
---|
| 519 | ALLOCATE( dimension%values_real64(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 520 | IF ( SIZE( values_real64 ) == dimension%length ) THEN |
---|
| 521 | dimension%values_real64 = values_real64 |
---|
| 522 | ELSEIF ( SIZE( values_real64 ) == 1 ) THEN |
---|
| 523 | dimension%values_real64(:) = values_real64(1) |
---|
| 524 | ELSE |
---|
| 525 | return_value = 2 |
---|
| 526 | ENDIF |
---|
| 527 | ELSEIF( PRESENT( values_realwp ) ) THEN |
---|
| 528 | ALLOCATE( dimension%values_realwp(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 529 | IF ( SIZE( values_realwp ) == dimension%length ) THEN |
---|
| 530 | dimension%values_realwp = values_realwp |
---|
| 531 | ELSEIF ( SIZE( values_realwp ) == 1 ) THEN |
---|
| 532 | dimension%values_realwp(:) = values_realwp(1) |
---|
| 533 | ELSE |
---|
| 534 | return_value = 2 |
---|
| 535 | ENDIF |
---|
| 536 | ELSE |
---|
| 537 | return_value = 1 |
---|
[4577] | 538 | CALL internal_message( 'error', routine_name // & |
---|
| 539 | ': no values given ' // & |
---|
| 540 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 541 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 542 | ENDIF |
---|
[4070] | 543 | |
---|
[4147] | 544 | IF ( return_value == 2 ) THEN |
---|
| 545 | return_value = 1 |
---|
[4577] | 546 | CALL internal_message( 'error', routine_name // & |
---|
| 547 | ': number of values and given bounds do not match ' // & |
---|
| 548 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 549 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 550 | ENDIF |
---|
| 551 | ! |
---|
| 552 | !-- Initialize mask |
---|
| 553 | IF ( PRESENT( mask ) .AND. return_value == 0 ) THEN |
---|
[4070] | 554 | |
---|
[4147] | 555 | IF ( dimension%length == SIZE( mask ) ) THEN |
---|
[4070] | 556 | |
---|
[4147] | 557 | IF ( ALL( mask ) ) THEN |
---|
[4070] | 558 | |
---|
[4577] | 559 | CALL internal_message( 'debug', routine_name // & |
---|
| 560 | ': mask contains only TRUE values. Ignoring mask ' // & |
---|
| 561 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 562 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4070] | 563 | |
---|
[4147] | 564 | ELSE |
---|
[4070] | 565 | |
---|
[4147] | 566 | dimension%is_masked = .TRUE. |
---|
| 567 | dimension%length_mask = COUNT( mask ) |
---|
[4070] | 568 | |
---|
[4147] | 569 | ALLOCATE( dimension%mask(dimension%bounds(1):dimension%bounds(2)) ) |
---|
| 570 | ALLOCATE( dimension%masked_indices(0:dimension%length_mask-1) ) |
---|
[4070] | 571 | |
---|
[4147] | 572 | dimension%mask = mask |
---|
| 573 | ! |
---|
| 574 | !-- Save masked positions and masked values |
---|
| 575 | IF ( ALLOCATED( dimension%values_int8 ) ) THEN |
---|
[4070] | 576 | |
---|
[4147] | 577 | ALLOCATE( dimension%masked_values_int8(0:dimension%length_mask-1) ) |
---|
| 578 | j = 0 |
---|
| 579 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
| 580 | IF ( dimension%mask(i) ) THEN |
---|
| 581 | dimension%masked_values_int8(j) = dimension%values_int8(i) |
---|
| 582 | dimension%masked_indices(j) = i |
---|
| 583 | j = j + 1 |
---|
| 584 | ENDIF |
---|
| 585 | ENDDO |
---|
[4070] | 586 | |
---|
[4147] | 587 | ELSEIF ( ALLOCATED( dimension%values_int16 ) ) THEN |
---|
[4070] | 588 | |
---|
[4147] | 589 | ALLOCATE( dimension%masked_values_int16(0:dimension%length_mask-1) ) |
---|
| 590 | j = 0 |
---|
| 591 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
| 592 | IF ( dimension%mask(i) ) THEN |
---|
| 593 | dimension%masked_values_int16(j) = dimension%values_int16(i) |
---|
| 594 | dimension%masked_indices(j) = i |
---|
| 595 | j = j + 1 |
---|
| 596 | ENDIF |
---|
| 597 | ENDDO |
---|
[4070] | 598 | |
---|
[4147] | 599 | ELSEIF ( ALLOCATED( dimension%values_int32 ) ) THEN |
---|
[4070] | 600 | |
---|
[4147] | 601 | ALLOCATE( dimension%masked_values_int32(0:dimension%length_mask-1) ) |
---|
| 602 | j = 0 |
---|
[4577] | 603 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
[4147] | 604 | IF ( dimension%mask(i) ) THEN |
---|
| 605 | dimension%masked_values_int32(j) = dimension%values_int32(i) |
---|
| 606 | dimension%masked_indices(j) = i |
---|
| 607 | j = j + 1 |
---|
| 608 | ENDIF |
---|
| 609 | ENDDO |
---|
[4070] | 610 | |
---|
[4147] | 611 | ELSEIF ( ALLOCATED( dimension%values_intwp ) ) THEN |
---|
[4070] | 612 | |
---|
[4147] | 613 | ALLOCATE( dimension%masked_values_intwp(0:dimension%length_mask-1) ) |
---|
| 614 | j = 0 |
---|
| 615 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
| 616 | IF ( dimension%mask(i) ) THEN |
---|
| 617 | dimension%masked_values_intwp(j) = dimension%values_intwp(i) |
---|
| 618 | dimension%masked_indices(j) = i |
---|
| 619 | j = j + 1 |
---|
| 620 | ENDIF |
---|
| 621 | ENDDO |
---|
[4070] | 622 | |
---|
[4147] | 623 | ELSEIF ( ALLOCATED( dimension%values_real32 ) ) THEN |
---|
[4070] | 624 | |
---|
[4147] | 625 | ALLOCATE( dimension%masked_values_real32(0:dimension%length_mask-1) ) |
---|
| 626 | j = 0 |
---|
| 627 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
| 628 | IF ( dimension%mask(i) ) THEN |
---|
| 629 | dimension%masked_values_real32(j) = dimension%values_real32(i) |
---|
| 630 | dimension%masked_indices(j) = i |
---|
| 631 | j = j + 1 |
---|
| 632 | ENDIF |
---|
| 633 | ENDDO |
---|
[4070] | 634 | |
---|
[4147] | 635 | ELSEIF ( ALLOCATED(dimension%values_real64) ) THEN |
---|
[4070] | 636 | |
---|
[4147] | 637 | ALLOCATE( dimension%masked_values_real64(0:dimension%length_mask-1) ) |
---|
| 638 | j = 0 |
---|
| 639 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
| 640 | IF ( dimension%mask(i) ) THEN |
---|
| 641 | dimension%masked_values_real64(j) = dimension%values_real64(i) |
---|
| 642 | dimension%masked_indices(j) = i |
---|
| 643 | j = j + 1 |
---|
| 644 | ENDIF |
---|
| 645 | ENDDO |
---|
[4070] | 646 | |
---|
[4147] | 647 | ELSEIF ( ALLOCATED(dimension%values_realwp) ) THEN |
---|
[4070] | 648 | |
---|
[4147] | 649 | ALLOCATE( dimension%masked_values_realwp(0:dimension%length_mask-1) ) |
---|
| 650 | j = 0 |
---|
| 651 | DO i = dimension%bounds(1), dimension%bounds(2) |
---|
| 652 | IF ( dimension%mask(i) ) THEN |
---|
| 653 | dimension%masked_values_realwp(j) = dimension%values_realwp(i) |
---|
| 654 | dimension%masked_indices(j) = i |
---|
| 655 | j = j + 1 |
---|
| 656 | ENDIF |
---|
| 657 | ENDDO |
---|
[4070] | 658 | |
---|
[4147] | 659 | ENDIF |
---|
[4070] | 660 | |
---|
[4147] | 661 | ENDIF ! if not all mask = true |
---|
[4070] | 662 | |
---|
[4147] | 663 | ELSE |
---|
| 664 | return_value = 1 |
---|
[4577] | 665 | CALL internal_message( 'error', routine_name // & |
---|
| 666 | ': size of mask and given bounds do not match ' // & |
---|
| 667 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 668 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 669 | ENDIF |
---|
[4070] | 670 | |
---|
[4147] | 671 | ENDIF |
---|
[4141] | 672 | |
---|
[4147] | 673 | ELSE |
---|
[4141] | 674 | |
---|
[4147] | 675 | return_value = 1 |
---|
[4577] | 676 | CALL internal_message( 'error', routine_name // & |
---|
| 677 | ': at least one but no more than two bounds must be given ' // & |
---|
| 678 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 679 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4141] | 680 | |
---|
[4147] | 681 | ENDIF |
---|
| 682 | ! |
---|
| 683 | !-- Add dimension to database |
---|
| 684 | IF ( return_value == 0 ) THEN |
---|
[4141] | 685 | |
---|
[4147] | 686 | DO f = 1, nfiles |
---|
[4070] | 687 | |
---|
[4147] | 688 | IF ( TRIM( file_name ) == files(f)%name ) THEN |
---|
[4070] | 689 | |
---|
[4147] | 690 | IF ( files(f)%is_init ) THEN |
---|
[4070] | 691 | |
---|
[4147] | 692 | return_value = 1 |
---|
[4577] | 693 | CALL internal_message( 'error', routine_name // & |
---|
| 694 | ': file already initialized. ' // & |
---|
| 695 | 'No further dimension definition allowed ' // & |
---|
| 696 | '(dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 697 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 698 | EXIT |
---|
[4070] | 699 | |
---|
[4147] | 700 | ELSEIF ( .NOT. ALLOCATED( files(f)%dimensions ) ) THEN |
---|
[4070] | 701 | |
---|
[4147] | 702 | ndims = 1 |
---|
| 703 | ALLOCATE( files(f)%dimensions(ndims) ) |
---|
[4070] | 704 | |
---|
[4147] | 705 | ELSE |
---|
| 706 | ! |
---|
| 707 | !-- Check if any variable of the same name as the new dimension is already defined |
---|
| 708 | IF ( ALLOCATED( files(f)%variables ) ) THEN |
---|
| 709 | DO i = 1, SIZE( files(f)%variables ) |
---|
| 710 | IF ( files(f)%variables(i)%name == dimension%name ) THEN |
---|
| 711 | return_value = 1 |
---|
[4577] | 712 | CALL internal_message( 'error', routine_name // & |
---|
| 713 | ': file already has a variable of this name defined. ' // & |
---|
| 714 | 'Defining a dimension of the same name is not allowed ' // & |
---|
| 715 | '(dimension "' // TRIM( dimension_name ) // & |
---|
| 716 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4147] | 717 | EXIT |
---|
| 718 | ENDIF |
---|
| 719 | ENDDO |
---|
| 720 | ENDIF |
---|
[4070] | 721 | |
---|
[4147] | 722 | IF ( return_value == 0 ) THEN |
---|
| 723 | ! |
---|
| 724 | !-- Check if dimension already exists in file |
---|
| 725 | ndims = SIZE( files(f)%dimensions ) |
---|
[4070] | 726 | |
---|
[4147] | 727 | DO d = 1, ndims |
---|
| 728 | IF ( files(f)%dimensions(d)%name == dimension%name ) THEN |
---|
| 729 | return_value = 1 |
---|
[4577] | 730 | CALL internal_message( 'error', routine_name // & |
---|
| 731 | ': dimension already exists in file ' // & |
---|
| 732 | '(dimension "' // TRIM( dimension_name ) // & |
---|
| 733 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4147] | 734 | EXIT |
---|
| 735 | ENDIF |
---|
| 736 | ENDDO |
---|
| 737 | ! |
---|
| 738 | !-- Extend dimension list |
---|
| 739 | IF ( return_value == 0 ) THEN |
---|
| 740 | ALLOCATE( dimensions_tmp(ndims) ) |
---|
| 741 | dimensions_tmp = files(f)%dimensions |
---|
| 742 | DEALLOCATE( files(f)%dimensions ) |
---|
| 743 | ndims = ndims + 1 |
---|
| 744 | ALLOCATE( files(f)%dimensions(ndims) ) |
---|
| 745 | files(f)%dimensions(:ndims-1) = dimensions_tmp |
---|
| 746 | DEALLOCATE( dimensions_tmp ) |
---|
| 747 | ENDIF |
---|
| 748 | ENDIF |
---|
[4070] | 749 | |
---|
[4147] | 750 | ENDIF |
---|
| 751 | ! |
---|
| 752 | !-- Add new dimension to database |
---|
| 753 | IF ( return_value == 0 ) files(f)%dimensions(ndims) = dimension |
---|
[4106] | 754 | |
---|
[4147] | 755 | EXIT |
---|
[4106] | 756 | |
---|
[4147] | 757 | ENDIF |
---|
| 758 | ENDDO |
---|
[4070] | 759 | |
---|
[4147] | 760 | IF ( f > nfiles ) THEN |
---|
| 761 | return_value = 1 |
---|
[4577] | 762 | CALL internal_message( 'error', routine_name // & |
---|
| 763 | ': file not found (dimension "' // TRIM( dimension_name ) // & |
---|
[4147] | 764 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 765 | ENDIF |
---|
[4070] | 766 | |
---|
[4147] | 767 | ENDIF |
---|
[4070] | 768 | |
---|
[4147] | 769 | END FUNCTION dom_def_dim |
---|
[4106] | 770 | |
---|
[4070] | 771 | !--------------------------------------------------------------------------------------------------! |
---|
| 772 | ! Description: |
---|
| 773 | ! ------------ |
---|
| 774 | !> Add variable to database. |
---|
[4141] | 775 | !> If a variable is identical for each MPI rank, the optional argument 'is_global' should be set to |
---|
[4577] | 776 | !> .TRUE. This flags the variable to be a global variable and is later only written once by the |
---|
[4141] | 777 | !> master output rank. |
---|
[4123] | 778 | !> Example call: |
---|
[4141] | 779 | !> dom_def_var( file_name = 'my_output_file_name', & |
---|
| 780 | !> variable_name = 'u', & |
---|
[4123] | 781 | !> dimension_names = (/'x ', 'y ', 'z ', 'time'/), & |
---|
| 782 | !> output_type = 'real32' ) |
---|
| 783 | !> @note The order of dimensions must match in reversed order to the dimensions of the |
---|
| 784 | !> corresponding variable array. The last given dimension can also be non-existent within the |
---|
| 785 | !> variable array if at any given call of 'dom_write_var' for this variable, the last |
---|
| 786 | !> dimension has only a single index. |
---|
| 787 | !> Hence, the array 'u' must be allocated with dimension 'x' as its last dimension, preceded |
---|
| 788 | !> by 'y', then 'z', and 'time' being the first dimension. If at any given write statement, |
---|
| 789 | !> only a single index of dimension 'time' is to be written, the dimension can be non-present |
---|
| 790 | !> in the variable array leaving dimension 'z' as the first dimension. |
---|
| 791 | !> So, the variable array needs to be allocated like either: |
---|
| 792 | !> ALLOCATE( u(<time>,<z>,<y>,<x>) ) |
---|
| 793 | !> or |
---|
| 794 | !> ALLOCATE( u(<z>,<y>,<x>) ) |
---|
[4070] | 795 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 796 | FUNCTION dom_def_var( file_name, variable_name, dimension_names, output_type, is_global ) & |
---|
[4147] | 797 | RESULT( return_value ) |
---|
[4070] | 798 | |
---|
[4577] | 799 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_var' !< name of this routine |
---|
| 800 | |
---|
[4147] | 801 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
[4577] | 802 | CHARACTER(LEN=*), INTENT(IN) :: output_type !< data type of variable |
---|
[4147] | 803 | CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable |
---|
[4070] | 804 | |
---|
[4147] | 805 | CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: dimension_names !< list of dimension names |
---|
[4070] | 806 | |
---|
[4147] | 807 | INTEGER :: d !< loop index |
---|
| 808 | INTEGER :: f !< loop index |
---|
| 809 | INTEGER :: i !< loop index |
---|
| 810 | INTEGER :: nvars !< number of variables in file |
---|
| 811 | INTEGER :: return_value !< return value |
---|
[4070] | 812 | |
---|
[4147] | 813 | LOGICAL :: found !< true if requested dimension is defined in file |
---|
| 814 | LOGICAL, INTENT(IN), OPTIONAL :: is_global !< true if variable is global (same on all PE) |
---|
[4070] | 815 | |
---|
[4147] | 816 | TYPE(variable_type) :: variable !< new variable |
---|
| 817 | TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: variables_tmp !< temporary variable list |
---|
[4070] | 818 | |
---|
| 819 | |
---|
[4147] | 820 | return_value = 0 |
---|
| 821 | found = .FALSE. |
---|
[4070] | 822 | |
---|
[4577] | 823 | CALL internal_message( 'debug', routine_name // & |
---|
| 824 | ': define variable (variable "' // TRIM( variable_name ) // & |
---|
[4147] | 825 | '", file "' // TRIM( file_name ) // '")' ) |
---|
[4116] | 826 | |
---|
[4147] | 827 | variable%name = TRIM( variable_name ) |
---|
[4070] | 828 | |
---|
[4147] | 829 | ALLOCATE( variable%dimension_names(SIZE( dimension_names )) ) |
---|
| 830 | ALLOCATE( variable%dimension_ids(SIZE( dimension_names )) ) |
---|
[4070] | 831 | |
---|
[4147] | 832 | variable%dimension_names = dimension_names |
---|
| 833 | variable%dimension_ids = -1 |
---|
| 834 | variable%data_type = TRIM( output_type ) |
---|
[4070] | 835 | |
---|
[4147] | 836 | IF ( PRESENT( is_global ) ) THEN |
---|
| 837 | variable%is_global = is_global |
---|
| 838 | ELSE |
---|
| 839 | variable%is_global = .FALSE. |
---|
| 840 | ENDIF |
---|
| 841 | ! |
---|
| 842 | !-- Add variable to database |
---|
| 843 | DO f = 1, nfiles |
---|
[4070] | 844 | |
---|
[4147] | 845 | IF ( TRIM( file_name ) == files(f)%name ) THEN |
---|
[4070] | 846 | |
---|
[4147] | 847 | IF ( files(f)%is_init ) THEN |
---|
[4070] | 848 | |
---|
[4147] | 849 | return_value = 1 |
---|
[4577] | 850 | CALL internal_message( 'error', routine_name // & |
---|
| 851 | ': file already initialized. No further variable definition allowed ' // & |
---|
| 852 | '(variable "' // TRIM( variable_name ) // & |
---|
| 853 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4147] | 854 | EXIT |
---|
[4070] | 855 | |
---|
[4147] | 856 | ELSEIF ( ALLOCATED( files(f)%dimensions ) ) THEN |
---|
| 857 | ! |
---|
| 858 | !-- Check if any dimension of the same name as the new variable is already defined |
---|
| 859 | DO d = 1, SIZE( files(f)%dimensions ) |
---|
| 860 | IF ( files(f)%dimensions(d)%name == variable%name ) THEN |
---|
| 861 | return_value = 1 |
---|
[4577] | 862 | CALL internal_message( 'error', routine_name // & |
---|
| 863 | ': file already has a dimension of this name defined. ' // & |
---|
| 864 | 'Defining a variable of the same name is not allowed ' // & |
---|
| 865 | '(variable "' // TRIM( variable_name ) // & |
---|
| 866 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4147] | 867 | EXIT |
---|
| 868 | ENDIF |
---|
| 869 | ENDDO |
---|
| 870 | ! |
---|
| 871 | !-- Check if dimensions assigned to variable are defined within file |
---|
| 872 | IF ( return_value == 0 ) THEN |
---|
| 873 | DO i = 1, SIZE( variable%dimension_names ) |
---|
| 874 | found = .FALSE. |
---|
| 875 | DO d = 1, SIZE( files(f)%dimensions ) |
---|
| 876 | IF ( files(f)%dimensions(d)%name == variable%dimension_names(i) ) THEN |
---|
| 877 | found = .TRUE. |
---|
| 878 | EXIT |
---|
| 879 | ENDIF |
---|
| 880 | ENDDO |
---|
| 881 | IF ( .NOT. found ) THEN |
---|
| 882 | return_value = 1 |
---|
[4577] | 883 | CALL internal_message( 'error', routine_name // & |
---|
| 884 | ': required dimension "'// TRIM( variable%dimension_names(i) ) // & |
---|
| 885 | '" for variable is not defined ' // & |
---|
| 886 | '(variable "' // TRIM( variable_name ) // & |
---|
| 887 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4147] | 888 | EXIT |
---|
| 889 | ENDIF |
---|
| 890 | ENDDO |
---|
| 891 | ENDIF |
---|
[4106] | 892 | |
---|
[4147] | 893 | ELSE |
---|
[4106] | 894 | |
---|
[4147] | 895 | return_value = 1 |
---|
[4577] | 896 | CALL internal_message( 'error', routine_name // & |
---|
| 897 | ': no dimensions defined in file. Cannot define variable '// & |
---|
| 898 | '(variable "' // TRIM( variable_name ) // & |
---|
| 899 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4070] | 900 | |
---|
[4147] | 901 | ENDIF |
---|
[4106] | 902 | |
---|
[4147] | 903 | IF ( return_value == 0 ) THEN |
---|
| 904 | ! |
---|
| 905 | !-- Check if variable already exists |
---|
| 906 | IF ( .NOT. ALLOCATED( files(f)%variables ) ) THEN |
---|
[4070] | 907 | |
---|
[4147] | 908 | nvars = 1 |
---|
| 909 | ALLOCATE( files(f)%variables(nvars) ) |
---|
[4070] | 910 | |
---|
[4147] | 911 | ELSE |
---|
[4070] | 912 | |
---|
[4147] | 913 | nvars = SIZE( files(f)%variables ) |
---|
| 914 | DO i = 1, nvars |
---|
| 915 | IF ( files(f)%variables(i)%name == variable%name ) THEN |
---|
| 916 | return_value = 1 |
---|
[4577] | 917 | CALL internal_message( 'error', routine_name // & |
---|
| 918 | ': variable already exists '// & |
---|
| 919 | '(variable "' // TRIM( variable_name ) // & |
---|
| 920 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4147] | 921 | EXIT |
---|
| 922 | ENDIF |
---|
| 923 | ENDDO |
---|
[4070] | 924 | |
---|
[4147] | 925 | IF ( return_value == 0 ) THEN |
---|
| 926 | ! |
---|
| 927 | !-- Extend variable list |
---|
| 928 | ALLOCATE( variables_tmp(nvars) ) |
---|
| 929 | variables_tmp = files(f)%variables |
---|
| 930 | DEALLOCATE( files(f)%variables ) |
---|
| 931 | nvars = nvars + 1 |
---|
| 932 | ALLOCATE( files(f)%variables(nvars) ) |
---|
| 933 | files(f)%variables(:nvars-1) = variables_tmp |
---|
| 934 | DEALLOCATE( variables_tmp ) |
---|
| 935 | ENDIF |
---|
[4070] | 936 | |
---|
[4147] | 937 | ENDIF |
---|
| 938 | ! |
---|
| 939 | !-- Add new variable to database |
---|
| 940 | IF ( return_value == 0 ) files(f)%variables(nvars) = variable |
---|
[4070] | 941 | |
---|
[4147] | 942 | ENDIF |
---|
[4070] | 943 | |
---|
[4147] | 944 | EXIT |
---|
[4070] | 945 | |
---|
[4147] | 946 | ENDIF |
---|
[4070] | 947 | |
---|
[4147] | 948 | ENDDO |
---|
[4070] | 949 | |
---|
[4147] | 950 | IF ( f > nfiles ) THEN |
---|
| 951 | return_value = 1 |
---|
[4577] | 952 | CALL internal_message( 'error', routine_name // & |
---|
| 953 | ': file not found (variable "' // TRIM( variable_name ) // & |
---|
[4147] | 954 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 955 | ENDIF |
---|
[4070] | 956 | |
---|
[4147] | 957 | END FUNCTION dom_def_var |
---|
[4070] | 958 | |
---|
| 959 | !--------------------------------------------------------------------------------------------------! |
---|
| 960 | ! Description: |
---|
| 961 | ! ------------ |
---|
| 962 | !> Create attribute with value of type character. |
---|
[4141] | 963 | !> If the optional argument 'variable_name' is given, the attribute is added to the respective |
---|
| 964 | !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to |
---|
| 965 | !> the file itself. |
---|
| 966 | !> If an attribute of similar name already exists, it is updated (overwritten) with the new value. |
---|
| 967 | !> If the optional argument 'append' is set TRUE, the value of an already existing attribute of |
---|
| 968 | !> similar name is appended by the new value instead of overwritten. |
---|
| 969 | !> Example call: |
---|
| 970 | !> - define a global file attribute: |
---|
| 971 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 972 | !> attribute_name='my_attribute', & |
---|
| 973 | !> value='This is the attribute value' ) |
---|
| 974 | !> - define a variable attribute: |
---|
| 975 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 976 | !> variable_name='my_variable', & |
---|
| 977 | !> attribute_name='my_attribute', & |
---|
| 978 | !> value='This is the attribute value' ) |
---|
| 979 | !> - append an attribute: |
---|
| 980 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 981 | !> attribute_name='my_attribute', & |
---|
| 982 | !> value=' and this part was appended', append=.TRUE. ) |
---|
[4070] | 983 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 984 | FUNCTION dom_def_att_char( file_name, variable_name, attribute_name, value, append ) & |
---|
| 985 | RESULT( return_value ) |
---|
[4070] | 986 | |
---|
[4577] | 987 | CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute |
---|
[4147] | 988 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 989 | CHARACTER(LEN=*), INTENT(IN) :: value !< attribute value |
---|
| 990 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable |
---|
| 991 | CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name |
---|
[4070] | 992 | |
---|
[4147] | 993 | ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_char' !< name of routine |
---|
[4070] | 994 | |
---|
[4147] | 995 | INTEGER :: return_value !< return value |
---|
[4070] | 996 | |
---|
[4147] | 997 | LOGICAL :: append_internal !< same as 'append' |
---|
| 998 | LOGICAL, INTENT(IN), OPTIONAL :: append !< if true, append value to existing value |
---|
[4070] | 999 | |
---|
[4147] | 1000 | TYPE(attribute_type) :: attribute !< new attribute |
---|
[4070] | 1001 | |
---|
| 1002 | |
---|
[4147] | 1003 | return_value = 0 |
---|
[4070] | 1004 | |
---|
[4147] | 1005 | IF ( PRESENT( append ) ) THEN |
---|
| 1006 | append_internal = append |
---|
| 1007 | ELSE |
---|
| 1008 | append_internal = .FALSE. |
---|
| 1009 | ENDIF |
---|
[4070] | 1010 | |
---|
[4147] | 1011 | attribute%name = TRIM( attribute_name ) |
---|
| 1012 | attribute%data_type = 'char' |
---|
| 1013 | attribute%value_char = TRIM( value ) |
---|
[4070] | 1014 | |
---|
[4147] | 1015 | IF ( PRESENT( variable_name ) ) THEN |
---|
| 1016 | variable_name_internal = TRIM( variable_name ) |
---|
| 1017 | ELSE |
---|
| 1018 | variable_name_internal = '' |
---|
| 1019 | ENDIF |
---|
[4070] | 1020 | |
---|
[4577] | 1021 | return_value = save_attribute_in_database( file_name=TRIM( file_name ), & |
---|
| 1022 | variable_name=TRIM( variable_name_internal ), & |
---|
| 1023 | attribute=attribute, append=append_internal ) |
---|
[4141] | 1024 | |
---|
[4147] | 1025 | END FUNCTION dom_def_att_char |
---|
[4070] | 1026 | |
---|
| 1027 | !--------------------------------------------------------------------------------------------------! |
---|
| 1028 | ! Description: |
---|
| 1029 | ! ------------ |
---|
| 1030 | !> Create attribute with value of type int8. |
---|
[4141] | 1031 | !> If the optional argument 'variable_name' is given, the attribute is added to the respective |
---|
| 1032 | !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to |
---|
| 1033 | !> the file itself. |
---|
| 1034 | !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). |
---|
| 1035 | !> Example call: |
---|
| 1036 | !> - define a global file attribute: |
---|
| 1037 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1038 | !> attribute_name='my_attribute', & |
---|
| 1039 | !> value=0_1 ) |
---|
| 1040 | !> - define a variable attribute: |
---|
| 1041 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1042 | !> variable_name='my_variable', & |
---|
| 1043 | !> attribute_name='my_attribute', & |
---|
| 1044 | !> value=1_1 ) |
---|
[4070] | 1045 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 1046 | FUNCTION dom_def_att_int8( file_name, variable_name, attribute_name, value, append ) & |
---|
[4147] | 1047 | RESULT( return_value ) |
---|
[4070] | 1048 | |
---|
[4577] | 1049 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_int8' !< name of routine |
---|
| 1050 | |
---|
| 1051 | CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute |
---|
[4147] | 1052 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 1053 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable |
---|
| 1054 | CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name |
---|
[4070] | 1055 | |
---|
[4147] | 1056 | INTEGER(KIND=1), INTENT(IN) :: value !< attribute value |
---|
[4070] | 1057 | |
---|
[4147] | 1058 | INTEGER :: return_value !< return value |
---|
[4070] | 1059 | |
---|
[4147] | 1060 | LOGICAL :: append_internal !< same as 'append' |
---|
| 1061 | LOGICAL, INTENT(IN), OPTIONAL :: append !< if true, append value to existing value |
---|
[4070] | 1062 | |
---|
[4147] | 1063 | TYPE(attribute_type) :: attribute !< new attribute |
---|
[4070] | 1064 | |
---|
| 1065 | |
---|
[4147] | 1066 | return_value = 0 |
---|
[4070] | 1067 | |
---|
[4147] | 1068 | IF ( PRESENT( variable_name ) ) THEN |
---|
| 1069 | variable_name_internal = TRIM( variable_name ) |
---|
| 1070 | ELSE |
---|
| 1071 | variable_name_internal = '' |
---|
| 1072 | ENDIF |
---|
[4141] | 1073 | |
---|
[4147] | 1074 | IF ( PRESENT( append ) ) THEN |
---|
| 1075 | IF ( append ) THEN |
---|
| 1076 | return_value = 1 |
---|
[4577] | 1077 | CALL internal_message( 'error', routine_name // & |
---|
| 1078 | ': numeric attribute cannot be appended ' // & |
---|
| 1079 | '(attribute "' // TRIM( attribute_name ) // & |
---|
| 1080 | '", variable "' // TRIM( variable_name_internal ) // & |
---|
[4147] | 1081 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 1082 | ENDIF |
---|
| 1083 | ENDIF |
---|
[4070] | 1084 | |
---|
[4147] | 1085 | IF ( return_value == 0 ) THEN |
---|
| 1086 | append_internal = .FALSE. |
---|
[4070] | 1087 | |
---|
[4147] | 1088 | attribute%name = TRIM( attribute_name ) |
---|
| 1089 | attribute%data_type = 'int8' |
---|
| 1090 | attribute%value_int8 = value |
---|
[4070] | 1091 | |
---|
[4577] | 1092 | return_value = save_attribute_in_database( file_name=TRIM( file_name ), & |
---|
| 1093 | variable_name=TRIM( variable_name_internal ), & |
---|
| 1094 | attribute=attribute, append=append_internal ) |
---|
[4147] | 1095 | ENDIF |
---|
[4070] | 1096 | |
---|
[4147] | 1097 | END FUNCTION dom_def_att_int8 |
---|
[4070] | 1098 | |
---|
| 1099 | !--------------------------------------------------------------------------------------------------! |
---|
| 1100 | ! Description: |
---|
| 1101 | ! ------------ |
---|
| 1102 | !> Create attribute with value of type int16. |
---|
[4141] | 1103 | !> If the optional argument 'variable_name' is given, the attribute is added to the respective |
---|
| 1104 | !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to |
---|
| 1105 | !> the file itself. |
---|
| 1106 | !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). |
---|
| 1107 | !> Example call: |
---|
| 1108 | !> - define a global file attribute: |
---|
| 1109 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1110 | !> attribute_name='my_attribute', & |
---|
| 1111 | !> value=0_2 ) |
---|
| 1112 | !> - define a variable attribute: |
---|
| 1113 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1114 | !> variable_name='my_variable', & |
---|
| 1115 | !> attribute_name='my_attribute', & |
---|
| 1116 | !> value=1_2 ) |
---|
[4070] | 1117 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 1118 | FUNCTION dom_def_att_int16( file_name, variable_name, attribute_name, value, append ) & |
---|
[4147] | 1119 | RESULT( return_value ) |
---|
[4070] | 1120 | |
---|
[4577] | 1121 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_int16' !< name of routine |
---|
| 1122 | |
---|
| 1123 | CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute |
---|
[4147] | 1124 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 1125 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable |
---|
| 1126 | CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name |
---|
[4070] | 1127 | |
---|
[4147] | 1128 | INTEGER(KIND=2), INTENT(IN) :: value !< attribute value |
---|
[4070] | 1129 | |
---|
[4147] | 1130 | INTEGER :: return_value !< return value |
---|
[4070] | 1131 | |
---|
[4147] | 1132 | LOGICAL :: append_internal !< same as 'append' |
---|
| 1133 | LOGICAL, INTENT(IN), OPTIONAL :: append !< if true, append value to existing value |
---|
[4070] | 1134 | |
---|
[4147] | 1135 | TYPE(attribute_type) :: attribute !< new attribute |
---|
[4070] | 1136 | |
---|
| 1137 | |
---|
[4147] | 1138 | return_value = 0 |
---|
[4070] | 1139 | |
---|
[4147] | 1140 | IF ( PRESENT( variable_name ) ) THEN |
---|
| 1141 | variable_name_internal = TRIM( variable_name ) |
---|
| 1142 | ELSE |
---|
| 1143 | variable_name_internal = '' |
---|
| 1144 | ENDIF |
---|
[4141] | 1145 | |
---|
[4147] | 1146 | IF ( PRESENT( append ) ) THEN |
---|
| 1147 | IF ( append ) THEN |
---|
| 1148 | return_value = 1 |
---|
[4577] | 1149 | CALL internal_message( 'error', routine_name // & |
---|
| 1150 | ': numeric attribute cannot be appended ' // & |
---|
| 1151 | '(attribute "' // TRIM( attribute_name ) // & |
---|
| 1152 | '", variable "' // TRIM( variable_name_internal ) // & |
---|
[4147] | 1153 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 1154 | ENDIF |
---|
| 1155 | ENDIF |
---|
[4070] | 1156 | |
---|
[4147] | 1157 | IF ( return_value == 0 ) THEN |
---|
| 1158 | append_internal = .FALSE. |
---|
[4070] | 1159 | |
---|
[4147] | 1160 | attribute%name = TRIM( attribute_name ) |
---|
| 1161 | attribute%data_type = 'int16' |
---|
| 1162 | attribute%value_int16 = value |
---|
[4070] | 1163 | |
---|
[4577] | 1164 | return_value = save_attribute_in_database( file_name=TRIM( file_name ), & |
---|
| 1165 | variable_name=TRIM( variable_name_internal ), & |
---|
| 1166 | attribute=attribute, append=append_internal ) |
---|
[4147] | 1167 | ENDIF |
---|
[4070] | 1168 | |
---|
[4147] | 1169 | END FUNCTION dom_def_att_int16 |
---|
[4070] | 1170 | |
---|
| 1171 | !--------------------------------------------------------------------------------------------------! |
---|
| 1172 | ! Description: |
---|
| 1173 | ! ------------ |
---|
| 1174 | !> Create attribute with value of type int32. |
---|
[4141] | 1175 | !> If the optional argument 'variable_name' is given, the attribute is added to the respective |
---|
| 1176 | !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to |
---|
| 1177 | !> the file itself. |
---|
| 1178 | !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). |
---|
| 1179 | !> Example call: |
---|
| 1180 | !> - define a global file attribute: |
---|
| 1181 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1182 | !> attribute_name='my_attribute', & |
---|
| 1183 | !> value=0_4 ) |
---|
| 1184 | !> - define a variable attribute: |
---|
| 1185 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1186 | !> variable_name='my_variable', & |
---|
| 1187 | !> attribute_name='my_attribute', & |
---|
| 1188 | !> value=1_4 ) |
---|
[4070] | 1189 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 1190 | FUNCTION dom_def_att_int32( file_name, variable_name, attribute_name, value, append ) & |
---|
[4147] | 1191 | RESULT( return_value ) |
---|
[4070] | 1192 | |
---|
[4577] | 1193 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_int32' !< name of routine |
---|
| 1194 | |
---|
| 1195 | |
---|
| 1196 | CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute |
---|
[4147] | 1197 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 1198 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable |
---|
| 1199 | CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name |
---|
[4070] | 1200 | |
---|
[4147] | 1201 | INTEGER(KIND=4), INTENT(IN) :: value !< attribute value |
---|
[4070] | 1202 | |
---|
[4147] | 1203 | INTEGER :: return_value !< return value |
---|
[4070] | 1204 | |
---|
[4147] | 1205 | LOGICAL :: append_internal !< same as 'append' |
---|
| 1206 | LOGICAL, INTENT(IN), OPTIONAL :: append !< if true, append value to existing value |
---|
[4070] | 1207 | |
---|
[4147] | 1208 | TYPE(attribute_type) :: attribute !< new attribute |
---|
[4070] | 1209 | |
---|
| 1210 | |
---|
[4147] | 1211 | return_value = 0 |
---|
[4070] | 1212 | |
---|
[4147] | 1213 | IF ( PRESENT( variable_name ) ) THEN |
---|
| 1214 | variable_name_internal = TRIM( variable_name ) |
---|
| 1215 | ELSE |
---|
| 1216 | variable_name_internal = '' |
---|
| 1217 | ENDIF |
---|
[4141] | 1218 | |
---|
[4147] | 1219 | IF ( PRESENT( append ) ) THEN |
---|
| 1220 | IF ( append ) THEN |
---|
| 1221 | return_value = 1 |
---|
[4577] | 1222 | CALL internal_message( 'error', routine_name // & |
---|
| 1223 | ': numeric attribute cannot be appended ' // & |
---|
| 1224 | '(attribute "' // TRIM( attribute_name ) // & |
---|
| 1225 | '", variable "' // TRIM( variable_name_internal ) // & |
---|
[4147] | 1226 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 1227 | ENDIF |
---|
| 1228 | ENDIF |
---|
[4070] | 1229 | |
---|
[4147] | 1230 | IF ( return_value == 0 ) THEN |
---|
| 1231 | append_internal = .FALSE. |
---|
[4070] | 1232 | |
---|
[4147] | 1233 | attribute%name = TRIM( attribute_name ) |
---|
| 1234 | attribute%data_type = 'int32' |
---|
| 1235 | attribute%value_int32 = value |
---|
[4070] | 1236 | |
---|
[4577] | 1237 | return_value = save_attribute_in_database( file_name=TRIM( file_name ), & |
---|
| 1238 | variable_name=TRIM( variable_name_internal ), & |
---|
| 1239 | attribute=attribute, append=append_internal ) |
---|
[4147] | 1240 | ENDIF |
---|
[4070] | 1241 | |
---|
[4147] | 1242 | END FUNCTION dom_def_att_int32 |
---|
[4070] | 1243 | |
---|
| 1244 | !--------------------------------------------------------------------------------------------------! |
---|
| 1245 | ! Description: |
---|
| 1246 | ! ------------ |
---|
| 1247 | !> Create attribute with value of type real32. |
---|
[4141] | 1248 | !> If the optional argument 'variable_name' is given, the attribute is added to the respective |
---|
| 1249 | !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to |
---|
| 1250 | !> the file itself. |
---|
| 1251 | !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). |
---|
| 1252 | !> Example call: |
---|
| 1253 | !> - define a global file attribute: |
---|
| 1254 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1255 | !> attribute_name='my_attribute', & |
---|
| 1256 | !> value=1.0_4 ) |
---|
| 1257 | !> - define a variable attribute: |
---|
| 1258 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1259 | !> variable_name='my_variable', & |
---|
| 1260 | !> attribute_name='my_attribute', & |
---|
| 1261 | !> value=1.0_4 ) |
---|
[4070] | 1262 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 1263 | FUNCTION dom_def_att_real32( file_name, variable_name, attribute_name, value, append ) & |
---|
[4147] | 1264 | RESULT( return_value ) |
---|
[4070] | 1265 | |
---|
[4577] | 1266 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_real32' !< name of routine |
---|
| 1267 | |
---|
| 1268 | CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute |
---|
[4147] | 1269 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 1270 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable |
---|
| 1271 | CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name |
---|
[4070] | 1272 | |
---|
[4147] | 1273 | INTEGER :: return_value !< return value |
---|
[4070] | 1274 | |
---|
[4147] | 1275 | LOGICAL :: append_internal !< same as 'append' |
---|
| 1276 | LOGICAL, INTENT(IN), OPTIONAL :: append !< if true, append value to existing value |
---|
[4070] | 1277 | |
---|
[4147] | 1278 | REAL(KIND=4), INTENT(IN) :: value !< attribute value |
---|
[4070] | 1279 | |
---|
[4147] | 1280 | TYPE(attribute_type) :: attribute !< new attribute |
---|
[4070] | 1281 | |
---|
| 1282 | |
---|
[4147] | 1283 | return_value = 0 |
---|
[4070] | 1284 | |
---|
[4147] | 1285 | IF ( PRESENT( variable_name ) ) THEN |
---|
| 1286 | variable_name_internal = TRIM( variable_name ) |
---|
| 1287 | ELSE |
---|
| 1288 | variable_name_internal = '' |
---|
| 1289 | ENDIF |
---|
[4141] | 1290 | |
---|
[4147] | 1291 | IF ( PRESENT( append ) ) THEN |
---|
| 1292 | IF ( append ) THEN |
---|
| 1293 | return_value = 1 |
---|
[4577] | 1294 | CALL internal_message( 'error', routine_name // & |
---|
| 1295 | ': numeric attribute cannot be appended ' // & |
---|
| 1296 | '(attribute "' // TRIM( attribute_name ) // & |
---|
| 1297 | '", variable "' // TRIM( variable_name_internal ) // & |
---|
[4147] | 1298 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 1299 | ENDIF |
---|
| 1300 | ENDIF |
---|
[4070] | 1301 | |
---|
[4147] | 1302 | IF ( return_value == 0 ) THEN |
---|
| 1303 | append_internal = .FALSE. |
---|
[4070] | 1304 | |
---|
[4147] | 1305 | attribute%name = TRIM( attribute_name ) |
---|
| 1306 | attribute%data_type = 'real32' |
---|
| 1307 | attribute%value_real32 = value |
---|
[4070] | 1308 | |
---|
[4577] | 1309 | return_value = save_attribute_in_database( file_name=TRIM( file_name ), & |
---|
| 1310 | variable_name=TRIM( variable_name_internal ), & |
---|
| 1311 | attribute=attribute, append=append_internal ) |
---|
[4147] | 1312 | ENDIF |
---|
[4070] | 1313 | |
---|
[4147] | 1314 | END FUNCTION dom_def_att_real32 |
---|
[4070] | 1315 | |
---|
| 1316 | !--------------------------------------------------------------------------------------------------! |
---|
| 1317 | ! Description: |
---|
| 1318 | ! ------------ |
---|
| 1319 | !> Create attribute with value of type real64. |
---|
[4141] | 1320 | !> If the optional argument 'variable_name' is given, the attribute is added to the respective |
---|
| 1321 | !> variable or dimension of that name. Otherwise, the attribute is added as a global attribute to |
---|
| 1322 | !> the file itself. |
---|
| 1323 | !> Numerical attributes cannot be appended, only updated (append=.TRUE. will cause an error). |
---|
| 1324 | !> Example call: |
---|
| 1325 | !> - define a global file attribute: |
---|
| 1326 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1327 | !> attribute_name='my_attribute', & |
---|
| 1328 | !> value=0.0_8 ) |
---|
| 1329 | !> - define a variable attribute: |
---|
| 1330 | !> dom_def_att( file_name='my_output_file_name', & |
---|
| 1331 | !> variable_name='my_variable', & |
---|
| 1332 | !> attribute_name='my_attribute', & |
---|
| 1333 | !> value=1.0_8 ) |
---|
[4070] | 1334 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 1335 | FUNCTION dom_def_att_real64( file_name, variable_name, attribute_name, value, append ) & |
---|
[4147] | 1336 | RESULT( return_value ) |
---|
[4070] | 1337 | |
---|
[4577] | 1338 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_att_real64' !< name of routine |
---|
| 1339 | |
---|
| 1340 | CHARACTER(LEN=*), INTENT(IN) :: attribute_name !< name of attribute |
---|
[4147] | 1341 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 1342 | CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: variable_name !< name of variable |
---|
| 1343 | CHARACTER(LEN=charlen) :: variable_name_internal !< internal copy of variable_name |
---|
[4070] | 1344 | |
---|
[4147] | 1345 | INTEGER :: return_value !< return value |
---|
[4070] | 1346 | |
---|
[4147] | 1347 | LOGICAL :: append_internal !< same as 'append' |
---|
| 1348 | LOGICAL, INTENT(IN), OPTIONAL :: append !< if true, append value to existing value |
---|
[4070] | 1349 | |
---|
[4147] | 1350 | REAL(KIND=8), INTENT(IN) :: value !< attribute value |
---|
[4070] | 1351 | |
---|
[4147] | 1352 | TYPE(attribute_type) :: attribute !< new attribute |
---|
[4070] | 1353 | |
---|
| 1354 | |
---|
[4147] | 1355 | return_value = 0 |
---|
[4070] | 1356 | |
---|
[4147] | 1357 | IF ( PRESENT( variable_name ) ) THEN |
---|
| 1358 | variable_name_internal = TRIM( variable_name ) |
---|
| 1359 | ELSE |
---|
| 1360 | variable_name_internal = '' |
---|
| 1361 | ENDIF |
---|
[4141] | 1362 | |
---|
[4147] | 1363 | IF ( PRESENT( append ) ) THEN |
---|
| 1364 | IF ( append ) THEN |
---|
| 1365 | return_value = 1 |
---|
[4577] | 1366 | CALL internal_message( 'error', routine_name // & |
---|
| 1367 | ': numeric attribute cannot be appended ' // & |
---|
| 1368 | '(attribute "' // TRIM( attribute_name ) // & |
---|
| 1369 | '", variable "' // TRIM( variable_name_internal ) // & |
---|
[4147] | 1370 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 1371 | ENDIF |
---|
| 1372 | ENDIF |
---|
[4070] | 1373 | |
---|
[4147] | 1374 | IF ( return_value == 0 ) THEN |
---|
| 1375 | append_internal = .FALSE. |
---|
[4070] | 1376 | |
---|
[4147] | 1377 | attribute%name = TRIM( attribute_name ) |
---|
| 1378 | attribute%data_type = 'real64' |
---|
| 1379 | attribute%value_real64 = value |
---|
[4070] | 1380 | |
---|
[4577] | 1381 | return_value = save_attribute_in_database( file_name=TRIM( file_name ), & |
---|
| 1382 | variable_name=TRIM( variable_name_internal ), & |
---|
| 1383 | attribute=attribute, append=append_internal ) |
---|
[4147] | 1384 | ENDIF |
---|
[4141] | 1385 | |
---|
[4147] | 1386 | END FUNCTION dom_def_att_real64 |
---|
[4141] | 1387 | |
---|
| 1388 | !--------------------------------------------------------------------------------------------------! |
---|
| 1389 | ! Description: |
---|
| 1390 | ! ------------ |
---|
| 1391 | !> End output definition. |
---|
| 1392 | !> The database is cleared from unused files and dimensions. Then, the output files are initialized |
---|
| 1393 | !> and prepared for writing output values to them. The saved values of the dimensions are written |
---|
| 1394 | !> to the files. |
---|
| 1395 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 1396 | FUNCTION dom_def_end() RESULT( return_value ) |
---|
[4141] | 1397 | |
---|
[4147] | 1398 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_def_end' !< name of routine |
---|
[4141] | 1399 | |
---|
[4147] | 1400 | INTEGER :: d !< loop index |
---|
| 1401 | INTEGER :: f !< loop index |
---|
| 1402 | INTEGER :: return_value !< return value |
---|
[4141] | 1403 | |
---|
[4147] | 1404 | INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE, TARGET :: values_int8 !< target array for dimension values |
---|
| 1405 | INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE, TARGET :: values_int16 !< target array for dimension values |
---|
| 1406 | INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE, TARGET :: values_int32 !< target array for dimension values |
---|
| 1407 | INTEGER(iwp), DIMENSION(:), ALLOCATABLE, TARGET :: values_intwp !< target array for dimension values |
---|
[4141] | 1408 | |
---|
[4147] | 1409 | INTEGER(KIND=1), DIMENSION(:), POINTER, CONTIGUOUS :: values_int8_pointer !< pointer to target array |
---|
| 1410 | INTEGER(KIND=2), DIMENSION(:), POINTER, CONTIGUOUS :: values_int16_pointer !< pointer to target array |
---|
| 1411 | INTEGER(KIND=4), DIMENSION(:), POINTER, CONTIGUOUS :: values_int32_pointer !< pointer to target array |
---|
| 1412 | INTEGER(iwp), DIMENSION(:), POINTER, CONTIGUOUS :: values_intwp_pointer !< pointer to target array |
---|
[4141] | 1413 | |
---|
[4147] | 1414 | REAL(KIND=4), DIMENSION(:), ALLOCATABLE, TARGET :: values_real32 !< target array for dimension values |
---|
| 1415 | REAL(KIND=8), DIMENSION(:), ALLOCATABLE, TARGET :: values_real64 !< target array for dimension values |
---|
| 1416 | REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET :: values_realwp !< target array for dimension values |
---|
[4141] | 1417 | |
---|
[4147] | 1418 | REAL(KIND=4), DIMENSION(:), POINTER, CONTIGUOUS :: values_real32_pointer !< pointer to target array |
---|
| 1419 | REAL(KIND=8), DIMENSION(:), POINTER, CONTIGUOUS :: values_real64_pointer !< pointer to target array |
---|
| 1420 | REAL(wp), DIMENSION(:), POINTER, CONTIGUOUS :: values_realwp_pointer !< pointer to target array |
---|
[4141] | 1421 | |
---|
| 1422 | |
---|
[4147] | 1423 | return_value = 0 |
---|
| 1424 | CALL internal_message( 'debug', routine_name // ': start' ) |
---|
| 1425 | ! |
---|
| 1426 | !-- Clear database from empty files and unused dimensions |
---|
| 1427 | IF ( nfiles > 0 ) return_value = cleanup_database() |
---|
[4141] | 1428 | |
---|
[4147] | 1429 | IF ( return_value == 0 ) THEN |
---|
| 1430 | DO f = 1, nfiles |
---|
| 1431 | ! |
---|
| 1432 | !-- Skip initialization if file is already initialized |
---|
| 1433 | IF ( files(f)%is_init ) CYCLE |
---|
[4141] | 1434 | |
---|
[4577] | 1435 | CALL internal_message( 'debug', routine_name // ': initialize file "' // & |
---|
[4147] | 1436 | TRIM( files(f)%name ) // '"' ) |
---|
| 1437 | ! |
---|
| 1438 | !-- Open file |
---|
[4577] | 1439 | CALL open_output_file( files(f)%format, files(f)%name, files(f)%id, & |
---|
[4147] | 1440 | return_value=return_value ) |
---|
| 1441 | ! |
---|
| 1442 | !-- Initialize file header: |
---|
| 1443 | !-- define dimensions and variables and write attributes |
---|
[4577] | 1444 | IF ( return_value == 0 ) CALL init_file_header( files(f), return_value=return_value ) |
---|
[4147] | 1445 | ! |
---|
| 1446 | !-- End file definition |
---|
[4577] | 1447 | IF ( return_value == 0 ) & |
---|
| 1448 | CALL stop_file_header_definition( files(f)%format, files(f)%id, files(f)%name, & |
---|
| 1449 | return_value ) |
---|
[4141] | 1450 | |
---|
[4147] | 1451 | IF ( return_value == 0 ) THEN |
---|
| 1452 | ! |
---|
| 1453 | !-- Flag file as initialized |
---|
| 1454 | files(f)%is_init = .TRUE. |
---|
| 1455 | ! |
---|
| 1456 | !-- Write dimension values into file |
---|
| 1457 | DO d = 1, SIZE( files(f)%dimensions ) |
---|
| 1458 | IF ( ALLOCATED( files(f)%dimensions(d)%values_int8 ) ) THEN |
---|
[4577] | 1459 | ALLOCATE( values_int8(files(f)%dimensions(d)%bounds(1): & |
---|
[4141] | 1460 | files(f)%dimensions(d)%bounds(2)) ) |
---|
[4147] | 1461 | values_int8 = files(f)%dimensions(d)%values_int8 |
---|
| 1462 | values_int8_pointer => values_int8 |
---|
[4577] | 1463 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1464 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1465 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1466 | values_int8_1d=values_int8_pointer ) |
---|
| 1467 | DEALLOCATE( values_int8 ) |
---|
| 1468 | ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_int16 ) ) THEN |
---|
[4577] | 1469 | ALLOCATE( values_int16(files(f)%dimensions(d)%bounds(1): & |
---|
[4141] | 1470 | files(f)%dimensions(d)%bounds(2)) ) |
---|
[4147] | 1471 | values_int16 = files(f)%dimensions(d)%values_int16 |
---|
| 1472 | values_int16_pointer => values_int16 |
---|
[4577] | 1473 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1474 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1475 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1476 | values_int16_1d=values_int16_pointer ) |
---|
| 1477 | DEALLOCATE( values_int16 ) |
---|
| 1478 | ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_int32 ) ) THEN |
---|
[4577] | 1479 | ALLOCATE( values_int32(files(f)%dimensions(d)%bounds(1): & |
---|
[4141] | 1480 | files(f)%dimensions(d)%bounds(2)) ) |
---|
[4147] | 1481 | values_int32 = files(f)%dimensions(d)%values_int32 |
---|
| 1482 | values_int32_pointer => values_int32 |
---|
[4577] | 1483 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1484 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1485 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1486 | values_int32_1d=values_int32_pointer ) |
---|
| 1487 | DEALLOCATE( values_int32 ) |
---|
| 1488 | ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_intwp ) ) THEN |
---|
[4577] | 1489 | ALLOCATE( values_intwp(files(f)%dimensions(d)%bounds(1): & |
---|
[4141] | 1490 | files(f)%dimensions(d)%bounds(2)) ) |
---|
[4147] | 1491 | values_intwp = files(f)%dimensions(d)%values_intwp |
---|
| 1492 | values_intwp_pointer => values_intwp |
---|
[4577] | 1493 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1494 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1495 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1496 | values_intwp_1d=values_intwp_pointer ) |
---|
| 1497 | DEALLOCATE( values_intwp ) |
---|
| 1498 | ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_real32 ) ) THEN |
---|
[4577] | 1499 | ALLOCATE( values_real32(files(f)%dimensions(d)%bounds(1): & |
---|
[4147] | 1500 | files(f)%dimensions(d)%bounds(2)) ) |
---|
| 1501 | values_real32 = files(f)%dimensions(d)%values_real32 |
---|
| 1502 | values_real32_pointer => values_real32 |
---|
[4577] | 1503 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1504 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1505 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1506 | values_real32_1d=values_real32_pointer ) |
---|
| 1507 | DEALLOCATE( values_real32 ) |
---|
| 1508 | ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_real64 ) ) THEN |
---|
[4577] | 1509 | ALLOCATE( values_real64(files(f)%dimensions(d)%bounds(1): & |
---|
[4147] | 1510 | files(f)%dimensions(d)%bounds(2)) ) |
---|
| 1511 | values_real64 = files(f)%dimensions(d)%values_real64 |
---|
| 1512 | values_real64_pointer => values_real64 |
---|
[4577] | 1513 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1514 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1515 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1516 | values_real64_1d=values_real64_pointer ) |
---|
| 1517 | DEALLOCATE( values_real64 ) |
---|
| 1518 | ELSEIF ( ALLOCATED( files(f)%dimensions(d)%values_realwp ) ) THEN |
---|
[4577] | 1519 | ALLOCATE( values_realwp(files(f)%dimensions(d)%bounds(1): & |
---|
[4147] | 1520 | files(f)%dimensions(d)%bounds(2)) ) |
---|
| 1521 | values_realwp = files(f)%dimensions(d)%values_realwp |
---|
| 1522 | values_realwp_pointer => values_realwp |
---|
[4577] | 1523 | return_value = dom_write_var( files(f)%name, files(f)%dimensions(d)%name, & |
---|
| 1524 | bounds_start=(/ files(f)%dimensions(d)%bounds(1) /), & |
---|
| 1525 | bounds_end =(/ files(f)%dimensions(d)%bounds(2) /), & |
---|
[4147] | 1526 | values_realwp_1d=values_realwp_pointer ) |
---|
| 1527 | DEALLOCATE( values_realwp ) |
---|
| 1528 | ENDIF |
---|
| 1529 | IF ( return_value /= 0 ) EXIT |
---|
| 1530 | ENDDO |
---|
[4141] | 1531 | |
---|
[4147] | 1532 | ENDIF |
---|
[4141] | 1533 | |
---|
[4147] | 1534 | IF ( return_value /= 0 ) EXIT |
---|
[4141] | 1535 | |
---|
[4147] | 1536 | ENDDO |
---|
| 1537 | ENDIF |
---|
[4141] | 1538 | |
---|
[4147] | 1539 | CALL internal_message( 'debug', routine_name // ': finished' ) |
---|
[4141] | 1540 | |
---|
[4147] | 1541 | END FUNCTION dom_def_end |
---|
[4141] | 1542 | |
---|
| 1543 | !--------------------------------------------------------------------------------------------------! |
---|
| 1544 | ! Description: |
---|
| 1545 | ! ------------ |
---|
| 1546 | !> Write variable to file. |
---|
| 1547 | !> Example call: |
---|
| 1548 | !> dom_write_var( file_name = 'my_output_file_name', & |
---|
| 1549 | !> name = 'u', & |
---|
| 1550 | !> bounds_start = (/nxl, nys, nzb, time_step/), & |
---|
| 1551 | !> bounds_end = (/nxr, nyn, nzt, time_step/), & |
---|
| 1552 | !> values_real64_3d = u ) |
---|
| 1553 | !> @note The order of dimension bounds must match to the order of dimensions given in call |
---|
| 1554 | !> 'dom_def_var'. I.e., the corresponding variable definition should be like: |
---|
| 1555 | !> dom_def_var( file_name = 'my_output_file_name', & |
---|
| 1556 | !> name = 'u', & |
---|
| 1557 | !> dimension_names = (/'x ', 'y ', 'z ', 'time'/), & |
---|
| 1558 | !> output_type = <desired-output-type> ) |
---|
| 1559 | !> @note The values given do not need to be of the same data type as was defined in the |
---|
| 1560 | !> corresponding 'dom_def_var' call. If the output format 'netcdf' was chosen, the values are |
---|
| 1561 | !> automatically converted to the data type given during the definition. If 'binary' was |
---|
| 1562 | !> chosen, the values are written to file as given in the 'dom_write_var' call. |
---|
| 1563 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 1564 | FUNCTION dom_write_var( file_name, variable_name, bounds_start, bounds_end, & |
---|
| 1565 | values_char_0d, values_char_1d, values_char_2d, values_char_3d, & |
---|
| 1566 | values_int8_0d, values_int8_1d, values_int8_2d, values_int8_3d, & |
---|
| 1567 | values_int16_0d, values_int16_1d, values_int16_2d, values_int16_3d, & |
---|
| 1568 | values_int32_0d, values_int32_1d, values_int32_2d, values_int32_3d, & |
---|
| 1569 | values_intwp_0d, values_intwp_1d, values_intwp_2d, values_intwp_3d, & |
---|
| 1570 | values_real32_0d, values_real32_1d, values_real32_2d, values_real32_3d, & |
---|
| 1571 | values_real64_0d, values_real64_1d, values_real64_2d, values_real64_3d, & |
---|
| 1572 | values_realwp_0d, values_realwp_1d, values_realwp_2d, values_realwp_3d & |
---|
[4147] | 1573 | ) RESULT( return_value ) |
---|
[4141] | 1574 | |
---|
[4577] | 1575 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_write_var' !< name of routine |
---|
| 1576 | |
---|
[4147] | 1577 | CHARACTER(LEN=charlen) :: file_format !< file format chosen for file |
---|
| 1578 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 1579 | CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable |
---|
[4141] | 1580 | |
---|
[4408] | 1581 | CHARACTER(LEN=1), POINTER, INTENT(IN), OPTIONAL :: values_char_0d !< output variable |
---|
| 1582 | CHARACTER(LEN=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_char_1d !< output variable |
---|
| 1583 | CHARACTER(LEN=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_char_2d !< output variable |
---|
| 1584 | CHARACTER(LEN=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_char_3d !< output variable |
---|
| 1585 | |
---|
| 1586 | CHARACTER(LEN=1), TARGET, ALLOCATABLE, DIMENSION(:) :: values_char_1d_resorted !< resorted output variable |
---|
| 1587 | CHARACTER(LEN=1), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_char_2d_resorted !< resorted output variable |
---|
| 1588 | CHARACTER(LEN=1), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_char_3d_resorted !< resorted output variable |
---|
| 1589 | |
---|
| 1590 | CHARACTER(LEN=1), POINTER :: values_char_0d_pointer !< pointer to resortet array |
---|
| 1591 | CHARACTER(LEN=1), POINTER, CONTIGUOUS, DIMENSION(:) :: values_char_1d_pointer !< pointer to resortet array |
---|
| 1592 | CHARACTER(LEN=1), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_char_2d_pointer !< pointer to resortet array |
---|
| 1593 | CHARACTER(LEN=1), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_char_3d_pointer !< pointer to resortet array |
---|
| 1594 | |
---|
[4147] | 1595 | INTEGER :: file_id !< file ID |
---|
| 1596 | INTEGER :: i !< loop index |
---|
| 1597 | INTEGER :: j !< loop index |
---|
| 1598 | INTEGER :: k !< loop index |
---|
| 1599 | INTEGER :: output_return_value !< return value of a called output routine |
---|
| 1600 | INTEGER :: return_value !< return value |
---|
| 1601 | INTEGER :: variable_id !< variable ID |
---|
[4141] | 1602 | |
---|
[4147] | 1603 | INTEGER, DIMENSION(:), INTENT(IN) :: bounds_end !< end index per dimension of variable |
---|
| 1604 | INTEGER, DIMENSION(:), INTENT(IN) :: bounds_start !< start index per dimension of variable |
---|
[4577] | 1605 | |
---|
[4147] | 1606 | INTEGER, DIMENSION(:), ALLOCATABLE :: bounds_origin !< first index of each dimension |
---|
| 1607 | INTEGER, DIMENSION(:), ALLOCATABLE :: bounds_start_internal !< start index per dim. for output after masking |
---|
| 1608 | INTEGER, DIMENSION(:), ALLOCATABLE :: value_counts !< count of indices to be written per dimension |
---|
| 1609 | INTEGER, DIMENSION(:,:), ALLOCATABLE :: masked_indices !< list containing all output indices along a dimension |
---|
[4141] | 1610 | |
---|
[4147] | 1611 | LOGICAL :: do_output !< true if any data lies within given range of masked dimension |
---|
| 1612 | LOGICAL :: is_global !< true if variable is global |
---|
[4141] | 1613 | |
---|
[4147] | 1614 | INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL :: values_int8_0d !< output variable |
---|
| 1615 | INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL :: values_int16_0d !< output variable |
---|
| 1616 | INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL :: values_int32_0d !< output variable |
---|
| 1617 | INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL :: values_intwp_0d !< output variable |
---|
| 1618 | INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int8_1d !< output variable |
---|
| 1619 | INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int16_1d !< output variable |
---|
| 1620 | INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_int32_1d !< output variable |
---|
| 1621 | INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_intwp_1d !< output variable |
---|
| 1622 | INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int8_2d !< output variable |
---|
| 1623 | INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int16_2d !< output variable |
---|
| 1624 | INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_int32_2d !< output variable |
---|
| 1625 | INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_intwp_2d !< output variable |
---|
| 1626 | INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int8_3d !< output variable |
---|
| 1627 | INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int16_3d !< output variable |
---|
| 1628 | INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_int32_3d !< output variable |
---|
| 1629 | INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_intwp_3d !< output variable |
---|
[4141] | 1630 | |
---|
[4147] | 1631 | INTEGER(KIND=1), POINTER :: values_int8_0d_pointer !< pointer to resortet array |
---|
| 1632 | INTEGER(KIND=2), POINTER :: values_int16_0d_pointer !< pointer to resortet array |
---|
| 1633 | INTEGER(KIND=4), POINTER :: values_int32_0d_pointer !< pointer to resortet array |
---|
| 1634 | INTEGER(iwp), POINTER :: values_intwp_0d_pointer !< pointer to resortet array |
---|
| 1635 | INTEGER(KIND=1), POINTER, CONTIGUOUS, DIMENSION(:) :: values_int8_1d_pointer !< pointer to resortet array |
---|
| 1636 | INTEGER(KIND=2), POINTER, CONTIGUOUS, DIMENSION(:) :: values_int16_1d_pointer !< pointer to resortet array |
---|
| 1637 | INTEGER(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:) :: values_int32_1d_pointer !< pointer to resortet array |
---|
| 1638 | INTEGER(iwp), POINTER, CONTIGUOUS, DIMENSION(:) :: values_intwp_1d_pointer !< pointer to resortet array |
---|
| 1639 | INTEGER(KIND=1), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_int8_2d_pointer !< pointer to resortet array |
---|
| 1640 | INTEGER(KIND=2), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_int16_2d_pointer !< pointer to resortet array |
---|
| 1641 | INTEGER(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_int32_2d_pointer !< pointer to resortet array |
---|
| 1642 | INTEGER(iwp), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_intwp_2d_pointer !< pointer to resortet array |
---|
| 1643 | INTEGER(KIND=1), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_int8_3d_pointer !< pointer to resortet array |
---|
| 1644 | INTEGER(KIND=2), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_int16_3d_pointer !< pointer to resortet array |
---|
| 1645 | INTEGER(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_int32_3d_pointer !< pointer to resortet array |
---|
| 1646 | INTEGER(iwp), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_intwp_3d_pointer !< pointer to resortet array |
---|
[4141] | 1647 | |
---|
[4577] | 1648 | INTEGER(KIND=1), TARGET, ALLOCATABLE, DIMENSION(:) :: values_int8_1d_resorted !< resorted output variable |
---|
| 1649 | INTEGER(KIND=2), TARGET, ALLOCATABLE, DIMENSION(:) :: values_int16_1d_resorted !< resorted output variable |
---|
| 1650 | INTEGER(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:) :: values_int32_1d_resorted !< resorted output variable |
---|
| 1651 | INTEGER(iwp), TARGET, ALLOCATABLE, DIMENSION(:) :: values_intwp_1d_resorted !< resorted output variable |
---|
| 1652 | INTEGER(KIND=1), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_int8_2d_resorted !< resorted output variable |
---|
| 1653 | INTEGER(KIND=2), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_int16_2d_resorted !< resorted output variable |
---|
| 1654 | INTEGER(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_int32_2d_resorted !< resorted output variable |
---|
| 1655 | INTEGER(iwp), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_intwp_2d_resorted !< resorted output variable |
---|
| 1656 | INTEGER(KIND=1), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_int8_3d_resorted !< resorted output variable |
---|
| 1657 | INTEGER(KIND=2), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_int16_3d_resorted !< resorted output variable |
---|
| 1658 | INTEGER(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_int32_3d_resorted !< resorted output variable |
---|
| 1659 | INTEGER(iwp), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_intwp_3d_resorted !< resorted output variable |
---|
| 1660 | |
---|
[4147] | 1661 | REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL :: values_real32_0d !< output variable |
---|
| 1662 | REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL :: values_real64_0d !< output variable |
---|
| 1663 | REAL(wp), POINTER, INTENT(IN), OPTIONAL :: values_realwp_0d !< output variable |
---|
| 1664 | REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_real32_1d !< output variable |
---|
| 1665 | REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_real64_1d !< output variable |
---|
| 1666 | REAL(wp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:) :: values_realwp_1d !< output variable |
---|
| 1667 | REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_real32_2d !< output variable |
---|
| 1668 | REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_real64_2d !< output variable |
---|
| 1669 | REAL(wp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: values_realwp_2d !< output variable |
---|
| 1670 | REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_real32_3d !< output variable |
---|
| 1671 | REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_real64_3d !< output variable |
---|
| 1672 | REAL(wp), POINTER, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) :: values_realwp_3d !< output variable |
---|
[4141] | 1673 | |
---|
[4147] | 1674 | REAL(KIND=4), POINTER :: values_real32_0d_pointer !< pointer to resortet array |
---|
| 1675 | REAL(KIND=8), POINTER :: values_real64_0d_pointer !< pointer to resortet array |
---|
| 1676 | REAL(wp), POINTER :: values_realwp_0d_pointer !< pointer to resortet array |
---|
| 1677 | REAL(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:) :: values_real32_1d_pointer !< pointer to resortet array |
---|
| 1678 | REAL(KIND=8), POINTER, CONTIGUOUS, DIMENSION(:) :: values_real64_1d_pointer !< pointer to resortet array |
---|
| 1679 | REAL(wp), POINTER, CONTIGUOUS, DIMENSION(:) :: values_realwp_1d_pointer !< pointer to resortet array |
---|
| 1680 | REAL(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_real32_2d_pointer !< pointer to resortet array |
---|
| 1681 | REAL(KIND=8), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_real64_2d_pointer !< pointer to resortet array |
---|
| 1682 | REAL(wp), POINTER, CONTIGUOUS, DIMENSION(:,:) :: values_realwp_2d_pointer !< pointer to resortet array |
---|
| 1683 | REAL(KIND=4), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_real32_3d_pointer !< pointer to resortet array |
---|
| 1684 | REAL(KIND=8), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_real64_3d_pointer !< pointer to resortet array |
---|
| 1685 | REAL(wp), POINTER, CONTIGUOUS, DIMENSION(:,:,:) :: values_realwp_3d_pointer !< pointer to resortet array |
---|
[4141] | 1686 | |
---|
[4577] | 1687 | REAL(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:) :: values_real32_1d_resorted !< resorted output variable |
---|
| 1688 | REAL(KIND=8), TARGET, ALLOCATABLE, DIMENSION(:) :: values_real64_1d_resorted !< resorted output variable |
---|
| 1689 | REAL(wp), TARGET, ALLOCATABLE, DIMENSION(:) :: values_realwp_1d_resorted !< resorted output variable |
---|
| 1690 | REAL(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_real32_2d_resorted !< resorted output variable |
---|
| 1691 | REAL(KIND=8), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_real64_2d_resorted !< resorted output variable |
---|
| 1692 | REAL(wp), TARGET, ALLOCATABLE, DIMENSION(:,:) :: values_realwp_2d_resorted !< resorted output variable |
---|
| 1693 | REAL(KIND=4), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_real32_3d_resorted !< resorted output variable |
---|
| 1694 | REAL(KIND=8), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_real64_3d_resorted !< resorted output variable |
---|
| 1695 | REAL(wp), TARGET, ALLOCATABLE, DIMENSION(:,:,:) :: values_realwp_3d_resorted !< resorted output variable |
---|
| 1696 | |
---|
[4147] | 1697 | TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: dimension_list !< list of used dimensions of variable |
---|
[4141] | 1698 | |
---|
| 1699 | |
---|
[4147] | 1700 | return_value = 0 |
---|
| 1701 | output_return_value = 0 |
---|
[4141] | 1702 | |
---|
[4577] | 1703 | CALL internal_message( 'debug', routine_name // ': write ' // TRIM( variable_name ) // & |
---|
[4147] | 1704 | ' into file ' // TRIM( file_name ) ) |
---|
| 1705 | ! |
---|
| 1706 | !-- Search for variable within file |
---|
[4577] | 1707 | CALL find_var_in_file( file_name, variable_name, file_format, file_id, variable_id, & |
---|
[4147] | 1708 | is_global, dimension_list, return_value=return_value ) |
---|
[4141] | 1709 | |
---|
[4147] | 1710 | IF ( return_value == 0 ) THEN |
---|
| 1711 | ! |
---|
| 1712 | !-- Check if the correct amount of variable bounds were given |
---|
[4577] | 1713 | IF ( SIZE( bounds_start ) /= SIZE( dimension_list ) .OR. & |
---|
| 1714 | SIZE( bounds_end ) /= SIZE( dimension_list ) ) THEN |
---|
[4147] | 1715 | return_value = 1 |
---|
[4577] | 1716 | CALL internal_message( 'error', routine_name // & |
---|
| 1717 | ': number bounds do not match with ' // & |
---|
| 1718 | 'number of dimensions of variable ' // & |
---|
| 1719 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 1720 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 1721 | ENDIF |
---|
[4141] | 1722 | |
---|
[4147] | 1723 | ENDIF |
---|
[4141] | 1724 | |
---|
[4147] | 1725 | IF ( return_value == 0 ) THEN |
---|
| 1726 | ! |
---|
| 1727 | !-- Save starting index (lower bounds) of each dimension |
---|
| 1728 | ALLOCATE( bounds_origin(SIZE( dimension_list )) ) |
---|
| 1729 | ALLOCATE( bounds_start_internal(SIZE( dimension_list )) ) |
---|
| 1730 | ALLOCATE( value_counts(SIZE( dimension_list )) ) |
---|
[4141] | 1731 | |
---|
[4147] | 1732 | WRITE( temp_string, * ) bounds_start |
---|
[4577] | 1733 | CALL internal_message( 'debug', routine_name // & |
---|
| 1734 | ': file "' // TRIM( file_name ) // & |
---|
| 1735 | '", variable "' // TRIM( variable_name ) // & |
---|
[4147] | 1736 | '", bounds_start =' // TRIM( temp_string ) ) |
---|
| 1737 | WRITE( temp_string, * ) bounds_end |
---|
[4577] | 1738 | CALL internal_message( 'debug', routine_name // & |
---|
| 1739 | ': file "' // TRIM( file_name ) // & |
---|
| 1740 | '", variable "' // TRIM( variable_name ) // & |
---|
[4147] | 1741 | '", bounds_end =' // TRIM( temp_string ) ) |
---|
| 1742 | ! |
---|
| 1743 | !-- Get bounds for masking |
---|
[4577] | 1744 | CALL get_masked_indices_and_masked_dimension_bounds( dimension_list, bounds_start, & |
---|
| 1745 | bounds_end, bounds_start_internal, value_counts, bounds_origin, masked_indices ) |
---|
[4141] | 1746 | |
---|
[4147] | 1747 | do_output = .NOT. ANY( value_counts == 0 ) |
---|
[4141] | 1748 | |
---|
[4147] | 1749 | WRITE( temp_string, * ) bounds_start_internal |
---|
[4577] | 1750 | CALL internal_message( 'debug', routine_name // & |
---|
| 1751 | ': file "' // TRIM( file_name ) // & |
---|
| 1752 | '", variable "' // TRIM( variable_name ) // & |
---|
[4147] | 1753 | '", bounds_start_internal =' // TRIM( temp_string ) ) |
---|
| 1754 | WRITE( temp_string, * ) value_counts |
---|
[4577] | 1755 | CALL internal_message( 'debug', routine_name // & |
---|
| 1756 | ': file "' // TRIM( file_name ) // & |
---|
| 1757 | '", variable "' // TRIM( variable_name ) // & |
---|
[4147] | 1758 | '", value_counts =' // TRIM( temp_string ) ) |
---|
| 1759 | ! |
---|
| 1760 | !-- Mask and resort variable |
---|
[4408] | 1761 | !-- character output |
---|
| 1762 | IF ( PRESENT( values_char_0d ) ) THEN |
---|
| 1763 | values_char_0d_pointer => values_char_0d |
---|
| 1764 | ELSEIF ( PRESENT( values_char_1d ) ) THEN |
---|
| 1765 | IF ( do_output ) THEN |
---|
| 1766 | ALLOCATE( values_char_1d_resorted(0:value_counts(1)-1) ) |
---|
| 1767 | !$OMP PARALLEL PRIVATE (i) |
---|
| 1768 | !$OMP DO |
---|
| 1769 | DO i = 0, value_counts(1) - 1 |
---|
| 1770 | values_char_1d_resorted(i) = values_char_1d(masked_indices(1,i)) |
---|
| 1771 | ENDDO |
---|
| 1772 | !$OMP END PARALLEL |
---|
| 1773 | ELSE |
---|
| 1774 | ALLOCATE( values_char_1d_resorted(1) ) |
---|
| 1775 | values_char_1d_resorted = ' ' |
---|
| 1776 | ENDIF |
---|
| 1777 | values_char_1d_pointer => values_char_1d_resorted |
---|
| 1778 | ELSEIF ( PRESENT( values_char_2d ) ) THEN |
---|
| 1779 | IF ( do_output ) THEN |
---|
[4577] | 1780 | ALLOCATE( values_char_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4408] | 1781 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 1782 | !$OMP DO |
---|
| 1783 | DO i = 0, value_counts(1) - 1 |
---|
| 1784 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 1785 | values_char_2d_resorted(i,j) = values_char_2d(masked_indices(2,j), & |
---|
| 1786 | masked_indices(1,i)) |
---|
[4408] | 1787 | ENDDO |
---|
| 1788 | ENDDO |
---|
| 1789 | !$OMP END PARALLEL |
---|
| 1790 | ELSE |
---|
| 1791 | ALLOCATE( values_char_2d_resorted(1,1) ) |
---|
| 1792 | values_char_2d_resorted = ' ' |
---|
| 1793 | ENDIF |
---|
| 1794 | values_char_2d_pointer => values_char_2d_resorted |
---|
| 1795 | ELSEIF ( PRESENT( values_char_3d ) ) THEN |
---|
| 1796 | IF ( do_output ) THEN |
---|
[4577] | 1797 | ALLOCATE( values_char_3d_resorted(0:value_counts(1)-1, & |
---|
| 1798 | 0:value_counts(2)-1, & |
---|
[4408] | 1799 | 0:value_counts(3)-1) ) |
---|
| 1800 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 1801 | !$OMP DO |
---|
| 1802 | DO i = 0, value_counts(1) - 1 |
---|
| 1803 | DO j = 0, value_counts(2) - 1 |
---|
| 1804 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 1805 | values_char_3d_resorted(i,j,k) = values_char_3d(masked_indices(3,k), & |
---|
| 1806 | masked_indices(2,j), & |
---|
| 1807 | masked_indices(1,i)) |
---|
[4408] | 1808 | ENDDO |
---|
| 1809 | ENDDO |
---|
| 1810 | ENDDO |
---|
| 1811 | !$OMP END PARALLEL |
---|
| 1812 | ELSE |
---|
| 1813 | ALLOCATE( values_char_3d_resorted(1,1,1) ) |
---|
| 1814 | values_char_3d_resorted = ' ' |
---|
| 1815 | ENDIF |
---|
| 1816 | values_char_3d_pointer => values_char_3d_resorted |
---|
| 1817 | ! |
---|
[4147] | 1818 | !-- 8bit integer output |
---|
[4408] | 1819 | ELSEIF ( PRESENT( values_int8_0d ) ) THEN |
---|
[4147] | 1820 | values_int8_0d_pointer => values_int8_0d |
---|
| 1821 | ELSEIF ( PRESENT( values_int8_1d ) ) THEN |
---|
| 1822 | IF ( do_output ) THEN |
---|
| 1823 | ALLOCATE( values_int8_1d_resorted(0:value_counts(1)-1) ) |
---|
| 1824 | !$OMP PARALLEL PRIVATE (i) |
---|
| 1825 | !$OMP DO |
---|
| 1826 | DO i = 0, value_counts(1) - 1 |
---|
| 1827 | values_int8_1d_resorted(i) = values_int8_1d(masked_indices(1,i)) |
---|
| 1828 | ENDDO |
---|
| 1829 | !$OMP END PARALLEL |
---|
| 1830 | ELSE |
---|
| 1831 | ALLOCATE( values_int8_1d_resorted(1) ) |
---|
| 1832 | values_int8_1d_resorted = 0_1 |
---|
| 1833 | ENDIF |
---|
| 1834 | values_int8_1d_pointer => values_int8_1d_resorted |
---|
| 1835 | ELSEIF ( PRESENT( values_int8_2d ) ) THEN |
---|
| 1836 | IF ( do_output ) THEN |
---|
[4577] | 1837 | ALLOCATE( values_int8_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 1838 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 1839 | !$OMP DO |
---|
| 1840 | DO i = 0, value_counts(1) - 1 |
---|
| 1841 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 1842 | values_int8_2d_resorted(i,j) = values_int8_2d(masked_indices(2,j), & |
---|
| 1843 | masked_indices(1,i)) |
---|
[4147] | 1844 | ENDDO |
---|
| 1845 | ENDDO |
---|
| 1846 | !$OMP END PARALLEL |
---|
| 1847 | ELSE |
---|
| 1848 | ALLOCATE( values_int8_2d_resorted(1,1) ) |
---|
| 1849 | values_int8_2d_resorted = 0_1 |
---|
| 1850 | ENDIF |
---|
| 1851 | values_int8_2d_pointer => values_int8_2d_resorted |
---|
| 1852 | ELSEIF ( PRESENT( values_int8_3d ) ) THEN |
---|
| 1853 | IF ( do_output ) THEN |
---|
[4577] | 1854 | ALLOCATE( values_int8_3d_resorted(0:value_counts(1)-1, & |
---|
| 1855 | 0:value_counts(2)-1, & |
---|
[4141] | 1856 | 0:value_counts(3)-1) ) |
---|
[4147] | 1857 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 1858 | !$OMP DO |
---|
| 1859 | DO i = 0, value_counts(1) - 1 |
---|
| 1860 | DO j = 0, value_counts(2) - 1 |
---|
| 1861 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 1862 | values_int8_3d_resorted(i,j,k) = values_int8_3d(masked_indices(3,k), & |
---|
| 1863 | masked_indices(2,j), & |
---|
[4147] | 1864 | masked_indices(1,i) ) |
---|
| 1865 | ENDDO |
---|
| 1866 | ENDDO |
---|
| 1867 | ENDDO |
---|
| 1868 | !$OMP END PARALLEL |
---|
| 1869 | ELSE |
---|
| 1870 | ALLOCATE( values_int8_3d_resorted(1,1,1) ) |
---|
| 1871 | values_int8_3d_resorted = 0_1 |
---|
| 1872 | ENDIF |
---|
| 1873 | values_int8_3d_pointer => values_int8_3d_resorted |
---|
| 1874 | ! |
---|
| 1875 | !-- 16bit integer output |
---|
| 1876 | ELSEIF ( PRESENT( values_int16_0d ) ) THEN |
---|
| 1877 | values_int16_0d_pointer => values_int16_0d |
---|
| 1878 | ELSEIF ( PRESENT( values_int16_1d ) ) THEN |
---|
| 1879 | IF ( do_output ) THEN |
---|
| 1880 | ALLOCATE( values_int16_1d_resorted(0:value_counts(1)-1) ) |
---|
| 1881 | !$OMP PARALLEL PRIVATE (i) |
---|
| 1882 | !$OMP DO |
---|
| 1883 | DO i = 0, value_counts(1) - 1 |
---|
| 1884 | values_int16_1d_resorted(i) = values_int16_1d(masked_indices(1,i)) |
---|
| 1885 | ENDDO |
---|
| 1886 | !$OMP END PARALLEL |
---|
| 1887 | ELSE |
---|
| 1888 | ALLOCATE( values_int16_1d_resorted(1) ) |
---|
| 1889 | values_int16_1d_resorted = 0_1 |
---|
| 1890 | ENDIF |
---|
| 1891 | values_int16_1d_pointer => values_int16_1d_resorted |
---|
| 1892 | ELSEIF ( PRESENT( values_int16_2d ) ) THEN |
---|
| 1893 | IF ( do_output ) THEN |
---|
[4577] | 1894 | ALLOCATE( values_int16_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 1895 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 1896 | !$OMP DO |
---|
| 1897 | DO i = 0, value_counts(1) - 1 |
---|
| 1898 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 1899 | values_int16_2d_resorted(i,j) = values_int16_2d(masked_indices(2,j), & |
---|
[4147] | 1900 | masked_indices(1,i)) |
---|
| 1901 | ENDDO |
---|
| 1902 | ENDDO |
---|
| 1903 | !$OMP END PARALLEL |
---|
| 1904 | ELSE |
---|
| 1905 | ALLOCATE( values_int16_2d_resorted(1,1) ) |
---|
| 1906 | values_int16_2d_resorted = 0_1 |
---|
| 1907 | ENDIF |
---|
| 1908 | values_int16_2d_pointer => values_int16_2d_resorted |
---|
| 1909 | ELSEIF ( PRESENT( values_int16_3d ) ) THEN |
---|
| 1910 | IF ( do_output ) THEN |
---|
[4577] | 1911 | ALLOCATE( values_int16_3d_resorted(0:value_counts(1)-1, & |
---|
| 1912 | 0:value_counts(2)-1, & |
---|
[4141] | 1913 | 0:value_counts(3)-1) ) |
---|
[4147] | 1914 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 1915 | !$OMP DO |
---|
| 1916 | DO i = 0, value_counts(1) - 1 |
---|
| 1917 | DO j = 0, value_counts(2) - 1 |
---|
| 1918 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 1919 | values_int16_3d_resorted(i,j,k) = values_int16_3d(masked_indices(3,k), & |
---|
| 1920 | masked_indices(2,j), & |
---|
| 1921 | masked_indices(1,i)) |
---|
[4147] | 1922 | ENDDO |
---|
| 1923 | ENDDO |
---|
| 1924 | ENDDO |
---|
| 1925 | !$OMP END PARALLEL |
---|
| 1926 | ELSE |
---|
| 1927 | ALLOCATE( values_int16_3d_resorted(1,1,1) ) |
---|
| 1928 | values_int16_3d_resorted = 0_1 |
---|
| 1929 | ENDIF |
---|
| 1930 | values_int16_3d_pointer => values_int16_3d_resorted |
---|
| 1931 | ! |
---|
| 1932 | !-- 32bit integer output |
---|
| 1933 | ELSEIF ( PRESENT( values_int32_0d ) ) THEN |
---|
| 1934 | values_int32_0d_pointer => values_int32_0d |
---|
| 1935 | ELSEIF ( PRESENT( values_int32_1d ) ) THEN |
---|
| 1936 | IF ( do_output ) THEN |
---|
| 1937 | ALLOCATE( values_int32_1d_resorted(0:value_counts(1)-1) ) |
---|
| 1938 | !$OMP PARALLEL PRIVATE (i) |
---|
| 1939 | !$OMP DO |
---|
| 1940 | DO i = 0, value_counts(1) - 1 |
---|
| 1941 | values_int32_1d_resorted(i) = values_int32_1d(masked_indices(1,i)) |
---|
| 1942 | ENDDO |
---|
| 1943 | !$OMP END PARALLEL |
---|
| 1944 | ELSE |
---|
| 1945 | ALLOCATE( values_int32_1d_resorted(1) ) |
---|
| 1946 | values_int32_1d_resorted = 0_1 |
---|
| 1947 | ENDIF |
---|
| 1948 | values_int32_1d_pointer => values_int32_1d_resorted |
---|
| 1949 | ELSEIF ( PRESENT( values_int32_2d ) ) THEN |
---|
| 1950 | IF ( do_output ) THEN |
---|
[4577] | 1951 | ALLOCATE( values_int32_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 1952 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 1953 | !$OMP DO |
---|
| 1954 | DO i = 0, value_counts(1) - 1 |
---|
| 1955 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 1956 | values_int32_2d_resorted(i,j) = values_int32_2d(masked_indices(2,j), & |
---|
| 1957 | masked_indices(1,i)) |
---|
[4147] | 1958 | ENDDO |
---|
| 1959 | ENDDO |
---|
| 1960 | !$OMP END PARALLEL |
---|
| 1961 | ELSE |
---|
| 1962 | ALLOCATE( values_int32_2d_resorted(1,1) ) |
---|
| 1963 | values_int32_2d_resorted = 0_1 |
---|
| 1964 | ENDIF |
---|
| 1965 | values_int32_2d_pointer => values_int32_2d_resorted |
---|
| 1966 | ELSEIF ( PRESENT( values_int32_3d ) ) THEN |
---|
| 1967 | IF ( do_output ) THEN |
---|
[4577] | 1968 | ALLOCATE( values_int32_3d_resorted(0:value_counts(1)-1, & |
---|
| 1969 | 0:value_counts(2)-1, & |
---|
[4141] | 1970 | 0:value_counts(3)-1) ) |
---|
[4147] | 1971 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 1972 | !$OMP DO |
---|
| 1973 | DO i = 0, value_counts(1) - 1 |
---|
| 1974 | DO j = 0, value_counts(2) - 1 |
---|
| 1975 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 1976 | values_int32_3d_resorted(i,j,k) = values_int32_3d(masked_indices(3,k), & |
---|
| 1977 | masked_indices(2,j), & |
---|
| 1978 | masked_indices(1,i)) |
---|
[4147] | 1979 | ENDDO |
---|
| 1980 | ENDDO |
---|
| 1981 | ENDDO |
---|
| 1982 | !$OMP END PARALLEL |
---|
| 1983 | ELSE |
---|
| 1984 | ALLOCATE( values_int32_3d_resorted(1,1,1) ) |
---|
| 1985 | values_int32_3d_resorted = 0_1 |
---|
| 1986 | ENDIF |
---|
| 1987 | values_int32_3d_pointer => values_int32_3d_resorted |
---|
| 1988 | ! |
---|
[4577] | 1989 | !-- Working-precision integer output |
---|
[4147] | 1990 | ELSEIF ( PRESENT( values_intwp_0d ) ) THEN |
---|
| 1991 | values_intwp_0d_pointer => values_intwp_0d |
---|
| 1992 | ELSEIF ( PRESENT( values_intwp_1d ) ) THEN |
---|
| 1993 | IF ( do_output ) THEN |
---|
| 1994 | ALLOCATE( values_intwp_1d_resorted(0:value_counts(1)-1) ) |
---|
| 1995 | !$OMP PARALLEL PRIVATE (i) |
---|
| 1996 | !$OMP DO |
---|
| 1997 | DO i = 0, value_counts(1) - 1 |
---|
| 1998 | values_intwp_1d_resorted(i) = values_intwp_1d(masked_indices(1,i)) |
---|
| 1999 | ENDDO |
---|
| 2000 | !$OMP END PARALLEL |
---|
| 2001 | ELSE |
---|
| 2002 | ALLOCATE( values_intwp_1d_resorted(1) ) |
---|
| 2003 | values_intwp_1d_resorted = 0_1 |
---|
| 2004 | ENDIF |
---|
| 2005 | values_intwp_1d_pointer => values_intwp_1d_resorted |
---|
| 2006 | ELSEIF ( PRESENT( values_intwp_2d ) ) THEN |
---|
| 2007 | IF ( do_output ) THEN |
---|
[4577] | 2008 | ALLOCATE( values_intwp_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 2009 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 2010 | !$OMP DO |
---|
| 2011 | DO i = 0, value_counts(1) - 1 |
---|
| 2012 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 2013 | values_intwp_2d_resorted(i,j) = values_intwp_2d(masked_indices(2,j), & |
---|
| 2014 | masked_indices(1,i)) |
---|
[4147] | 2015 | ENDDO |
---|
| 2016 | ENDDO |
---|
| 2017 | !$OMP END PARALLEL |
---|
| 2018 | ELSE |
---|
| 2019 | ALLOCATE( values_intwp_2d_resorted(1,1) ) |
---|
| 2020 | values_intwp_2d_resorted = 0_1 |
---|
| 2021 | ENDIF |
---|
| 2022 | values_intwp_2d_pointer => values_intwp_2d_resorted |
---|
| 2023 | ELSEIF ( PRESENT( values_intwp_3d ) ) THEN |
---|
| 2024 | IF ( do_output ) THEN |
---|
[4577] | 2025 | ALLOCATE( values_intwp_3d_resorted(0:value_counts(1)-1, & |
---|
| 2026 | 0:value_counts(2)-1, & |
---|
[4141] | 2027 | 0:value_counts(3)-1) ) |
---|
[4147] | 2028 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 2029 | !$OMP DO |
---|
| 2030 | DO i = 0, value_counts(1) - 1 |
---|
| 2031 | DO j = 0, value_counts(2) - 1 |
---|
| 2032 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 2033 | values_intwp_3d_resorted(i,j,k) = values_intwp_3d(masked_indices(3,k), & |
---|
| 2034 | masked_indices(2,j), & |
---|
| 2035 | masked_indices(1,i)) |
---|
[4147] | 2036 | ENDDO |
---|
| 2037 | ENDDO |
---|
| 2038 | ENDDO |
---|
| 2039 | !$OMP END PARALLEL |
---|
| 2040 | ELSE |
---|
| 2041 | ALLOCATE( values_intwp_3d_resorted(1,1,1) ) |
---|
| 2042 | values_intwp_3d_resorted = 0_1 |
---|
| 2043 | ENDIF |
---|
| 2044 | values_intwp_3d_pointer => values_intwp_3d_resorted |
---|
| 2045 | ! |
---|
| 2046 | !-- 32bit real output |
---|
| 2047 | ELSEIF ( PRESENT( values_real32_0d ) ) THEN |
---|
| 2048 | values_real32_0d_pointer => values_real32_0d |
---|
| 2049 | ELSEIF ( PRESENT( values_real32_1d ) ) THEN |
---|
| 2050 | IF ( do_output ) THEN |
---|
| 2051 | ALLOCATE( values_real32_1d_resorted(0:value_counts(1)-1) ) |
---|
| 2052 | !$OMP PARALLEL PRIVATE (i) |
---|
| 2053 | !$OMP DO |
---|
| 2054 | DO i = 0, value_counts(1) - 1 |
---|
| 2055 | values_real32_1d_resorted(i) = values_real32_1d(masked_indices(1,i)) |
---|
| 2056 | ENDDO |
---|
| 2057 | !$OMP END PARALLEL |
---|
| 2058 | ELSE |
---|
| 2059 | ALLOCATE( values_real32_1d_resorted(1) ) |
---|
| 2060 | values_real32_1d_resorted = 0_1 |
---|
| 2061 | ENDIF |
---|
| 2062 | values_real32_1d_pointer => values_real32_1d_resorted |
---|
| 2063 | ELSEIF ( PRESENT( values_real32_2d ) ) THEN |
---|
| 2064 | IF ( do_output ) THEN |
---|
[4577] | 2065 | ALLOCATE( values_real32_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 2066 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 2067 | !$OMP DO |
---|
| 2068 | DO i = 0, value_counts(1) - 1 |
---|
| 2069 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 2070 | values_real32_2d_resorted(i,j) = values_real32_2d(masked_indices(2,j), & |
---|
| 2071 | masked_indices(1,i)) |
---|
[4147] | 2072 | ENDDO |
---|
| 2073 | ENDDO |
---|
| 2074 | !$OMP END PARALLEL |
---|
| 2075 | ELSE |
---|
| 2076 | ALLOCATE( values_real32_2d_resorted(1,1) ) |
---|
| 2077 | values_real32_2d_resorted = 0_1 |
---|
| 2078 | ENDIF |
---|
| 2079 | values_real32_2d_pointer => values_real32_2d_resorted |
---|
| 2080 | ELSEIF ( PRESENT( values_real32_3d ) ) THEN |
---|
| 2081 | IF ( do_output ) THEN |
---|
[4577] | 2082 | ALLOCATE( values_real32_3d_resorted(0:value_counts(1)-1, & |
---|
| 2083 | 0:value_counts(2)-1, & |
---|
[4147] | 2084 | 0:value_counts(3)-1) ) |
---|
| 2085 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 2086 | !$OMP DO |
---|
| 2087 | DO i = 0, value_counts(1) - 1 |
---|
| 2088 | DO j = 0, value_counts(2) - 1 |
---|
| 2089 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 2090 | values_real32_3d_resorted(i,j,k) = values_real32_3d(masked_indices(3,k), & |
---|
| 2091 | masked_indices(2,j), & |
---|
| 2092 | masked_indices(1,i)) |
---|
[4147] | 2093 | ENDDO |
---|
| 2094 | ENDDO |
---|
| 2095 | ENDDO |
---|
| 2096 | !$OMP END PARALLEL |
---|
| 2097 | ELSE |
---|
| 2098 | ALLOCATE( values_real32_3d_resorted(1,1,1) ) |
---|
| 2099 | values_real32_3d_resorted = 0_1 |
---|
| 2100 | ENDIF |
---|
| 2101 | values_real32_3d_pointer => values_real32_3d_resorted |
---|
| 2102 | ! |
---|
| 2103 | !-- 64bit real output |
---|
| 2104 | ELSEIF ( PRESENT( values_real64_0d ) ) THEN |
---|
| 2105 | values_real64_0d_pointer => values_real64_0d |
---|
| 2106 | ELSEIF ( PRESENT( values_real64_1d ) ) THEN |
---|
| 2107 | IF ( do_output ) THEN |
---|
| 2108 | ALLOCATE( values_real64_1d_resorted(0:value_counts(1)-1) ) |
---|
| 2109 | !$OMP PARALLEL PRIVATE (i) |
---|
| 2110 | !$OMP DO |
---|
| 2111 | DO i = 0, value_counts(1) - 1 |
---|
| 2112 | values_real64_1d_resorted(i) = values_real64_1d(masked_indices(1,i)) |
---|
| 2113 | ENDDO |
---|
| 2114 | !$OMP END PARALLEL |
---|
| 2115 | ELSE |
---|
| 2116 | ALLOCATE( values_real64_1d_resorted(1) ) |
---|
| 2117 | values_real64_1d_resorted = 0_1 |
---|
| 2118 | ENDIF |
---|
| 2119 | values_real64_1d_pointer => values_real64_1d_resorted |
---|
| 2120 | ELSEIF ( PRESENT( values_real64_2d ) ) THEN |
---|
| 2121 | IF ( do_output ) THEN |
---|
[4577] | 2122 | ALLOCATE( values_real64_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 2123 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 2124 | !$OMP DO |
---|
| 2125 | DO i = 0, value_counts(1) - 1 |
---|
| 2126 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 2127 | values_real64_2d_resorted(i,j) = values_real64_2d(masked_indices(2,j), & |
---|
| 2128 | masked_indices(1,i)) |
---|
[4147] | 2129 | ENDDO |
---|
| 2130 | ENDDO |
---|
| 2131 | !$OMP END PARALLEL |
---|
| 2132 | ELSE |
---|
| 2133 | ALLOCATE( values_real64_2d_resorted(1,1) ) |
---|
| 2134 | values_real64_2d_resorted = 0_1 |
---|
| 2135 | ENDIF |
---|
| 2136 | values_real64_2d_pointer => values_real64_2d_resorted |
---|
| 2137 | ELSEIF ( PRESENT( values_real64_3d ) ) THEN |
---|
| 2138 | IF ( do_output ) THEN |
---|
[4577] | 2139 | ALLOCATE( values_real64_3d_resorted(0:value_counts(1)-1, & |
---|
| 2140 | 0:value_counts(2)-1, & |
---|
[4147] | 2141 | 0:value_counts(3)-1) ) |
---|
| 2142 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 2143 | !$OMP DO |
---|
| 2144 | DO i = 0, value_counts(1) - 1 |
---|
| 2145 | DO j = 0, value_counts(2) - 1 |
---|
| 2146 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 2147 | values_real64_3d_resorted(i,j,k) = values_real64_3d(masked_indices(3,k), & |
---|
| 2148 | masked_indices(2,j), & |
---|
| 2149 | masked_indices(1,i)) |
---|
[4147] | 2150 | ENDDO |
---|
| 2151 | ENDDO |
---|
| 2152 | ENDDO |
---|
| 2153 | !$OMP END PARALLEL |
---|
| 2154 | ELSE |
---|
| 2155 | ALLOCATE( values_real64_3d_resorted(1,1,1) ) |
---|
| 2156 | values_real64_3d_resorted = 0_1 |
---|
| 2157 | ENDIF |
---|
| 2158 | values_real64_3d_pointer => values_real64_3d_resorted |
---|
| 2159 | ! |
---|
[4577] | 2160 | !-- Working-precision real output |
---|
[4147] | 2161 | ELSEIF ( PRESENT( values_realwp_0d ) ) THEN |
---|
| 2162 | values_realwp_0d_pointer => values_realwp_0d |
---|
| 2163 | ELSEIF ( PRESENT( values_realwp_1d ) ) THEN |
---|
| 2164 | IF ( do_output ) THEN |
---|
| 2165 | ALLOCATE( values_realwp_1d_resorted(0:value_counts(1)-1) ) |
---|
| 2166 | !$OMP PARALLEL PRIVATE (i) |
---|
| 2167 | !$OMP DO |
---|
| 2168 | DO i = 0, value_counts(1) - 1 |
---|
| 2169 | values_realwp_1d_resorted(i) = values_realwp_1d(masked_indices(1,i)) |
---|
| 2170 | ENDDO |
---|
| 2171 | !$OMP END PARALLEL |
---|
| 2172 | ELSE |
---|
| 2173 | ALLOCATE( values_realwp_1d_resorted(1) ) |
---|
| 2174 | values_realwp_1d_resorted = 0_1 |
---|
| 2175 | ENDIF |
---|
| 2176 | values_realwp_1d_pointer => values_realwp_1d_resorted |
---|
| 2177 | ELSEIF ( PRESENT( values_realwp_2d ) ) THEN |
---|
| 2178 | IF ( do_output ) THEN |
---|
[4577] | 2179 | ALLOCATE( values_realwp_2d_resorted(0:value_counts(1)-1,0:value_counts(2)-1) ) |
---|
[4147] | 2180 | !$OMP PARALLEL PRIVATE (i,j) |
---|
| 2181 | !$OMP DO |
---|
| 2182 | DO i = 0, value_counts(1) - 1 |
---|
| 2183 | DO j = 0, value_counts(2) - 1 |
---|
[4577] | 2184 | values_realwp_2d_resorted(i,j) = values_realwp_2d(masked_indices(2,j), & |
---|
| 2185 | masked_indices(1,i)) |
---|
[4147] | 2186 | ENDDO |
---|
| 2187 | ENDDO |
---|
| 2188 | !$OMP END PARALLEL |
---|
| 2189 | ELSE |
---|
| 2190 | ALLOCATE( values_realwp_2d_resorted(1,1) ) |
---|
| 2191 | values_realwp_2d_resorted = 0_1 |
---|
| 2192 | ENDIF |
---|
| 2193 | values_realwp_2d_pointer => values_realwp_2d_resorted |
---|
| 2194 | ELSEIF ( PRESENT( values_realwp_3d ) ) THEN |
---|
| 2195 | IF ( do_output ) THEN |
---|
[4577] | 2196 | ALLOCATE( values_realwp_3d_resorted(0:value_counts(1)-1, & |
---|
| 2197 | 0:value_counts(2)-1, & |
---|
[4147] | 2198 | 0:value_counts(3)-1) ) |
---|
| 2199 | !$OMP PARALLEL PRIVATE (i,j,k) |
---|
| 2200 | !$OMP DO |
---|
| 2201 | DO i = 0, value_counts(1) - 1 |
---|
| 2202 | DO j = 0, value_counts(2) - 1 |
---|
| 2203 | DO k = 0, value_counts(3) - 1 |
---|
[4577] | 2204 | values_realwp_3d_resorted(i,j,k) = values_realwp_3d(masked_indices(3,k), & |
---|
| 2205 | masked_indices(2,j), & |
---|
| 2206 | masked_indices(1,i)) |
---|
[4147] | 2207 | ENDDO |
---|
| 2208 | ENDDO |
---|
| 2209 | ENDDO |
---|
| 2210 | !$OMP END PARALLEL |
---|
| 2211 | ELSE |
---|
| 2212 | ALLOCATE( values_realwp_3d_resorted(1,1,1) ) |
---|
| 2213 | values_realwp_3d_resorted = 0_1 |
---|
| 2214 | ENDIF |
---|
| 2215 | values_realwp_3d_pointer => values_realwp_3d_resorted |
---|
[4141] | 2216 | |
---|
[4147] | 2217 | ELSE |
---|
| 2218 | return_value = 1 |
---|
[4577] | 2219 | CALL internal_message( 'error', routine_name // & |
---|
| 2220 | ': no output values given ' // & |
---|
| 2221 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 2222 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 2223 | ENDIF |
---|
[4141] | 2224 | |
---|
[4147] | 2225 | DEALLOCATE( masked_indices ) |
---|
[4141] | 2226 | |
---|
[4147] | 2227 | ENDIF ! Check for error |
---|
[4141] | 2228 | |
---|
[4147] | 2229 | IF ( return_value == 0 ) THEN |
---|
| 2230 | ! |
---|
| 2231 | !-- Write variable into file |
---|
| 2232 | SELECT CASE ( TRIM( file_format ) ) |
---|
[4141] | 2233 | |
---|
[4147] | 2234 | CASE ( 'binary' ) |
---|
| 2235 | ! |
---|
[4577] | 2236 | !-- Character output |
---|
[4408] | 2237 | IF ( PRESENT( values_char_0d ) ) THEN |
---|
[4577] | 2238 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2239 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2240 | values_char_0d=values_char_0d_pointer, return_value=output_return_value ) |
---|
| 2241 | ELSEIF ( PRESENT( values_char_1d ) ) THEN |
---|
[4577] | 2242 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2243 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2244 | values_char_1d=values_char_1d_pointer, return_value=output_return_value ) |
---|
| 2245 | ELSEIF ( PRESENT( values_char_2d ) ) THEN |
---|
[4577] | 2246 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2247 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2248 | values_char_2d=values_char_2d_pointer, return_value=output_return_value ) |
---|
| 2249 | ELSEIF ( PRESENT( values_char_3d ) ) THEN |
---|
[4577] | 2250 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2251 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2252 | values_char_3d=values_char_3d_pointer, return_value=output_return_value ) |
---|
| 2253 | ! |
---|
[4147] | 2254 | !-- 8bit integer output |
---|
[4408] | 2255 | ELSEIF ( PRESENT( values_int8_0d ) ) THEN |
---|
[4577] | 2256 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2257 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2258 | values_int8_0d=values_int8_0d_pointer, return_value=output_return_value ) |
---|
| 2259 | ELSEIF ( PRESENT( values_int8_1d ) ) THEN |
---|
[4577] | 2260 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2261 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2262 | values_int8_1d=values_int8_1d_pointer, return_value=output_return_value ) |
---|
| 2263 | ELSEIF ( PRESENT( values_int8_2d ) ) THEN |
---|
[4577] | 2264 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2265 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2266 | values_int8_2d=values_int8_2d_pointer, return_value=output_return_value ) |
---|
| 2267 | ELSEIF ( PRESENT( values_int8_3d ) ) THEN |
---|
[4577] | 2268 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2269 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2270 | values_int8_3d=values_int8_3d_pointer, return_value=output_return_value ) |
---|
| 2271 | ! |
---|
| 2272 | !-- 16bit integer output |
---|
| 2273 | ELSEIF ( PRESENT( values_int16_0d ) ) THEN |
---|
[4577] | 2274 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2275 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2276 | values_int16_0d=values_int16_0d_pointer, return_value=output_return_value ) |
---|
| 2277 | ELSEIF ( PRESENT( values_int16_1d ) ) THEN |
---|
[4577] | 2278 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2279 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2280 | values_int16_1d=values_int16_1d_pointer, return_value=output_return_value ) |
---|
| 2281 | ELSEIF ( PRESENT( values_int16_2d ) ) THEN |
---|
[4577] | 2282 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2283 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2284 | values_int16_2d=values_int16_2d_pointer, return_value=output_return_value ) |
---|
| 2285 | ELSEIF ( PRESENT( values_int16_3d ) ) THEN |
---|
[4577] | 2286 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2287 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2288 | values_int16_3d=values_int16_3d_pointer, return_value=output_return_value ) |
---|
| 2289 | ! |
---|
| 2290 | !-- 32bit integer output |
---|
| 2291 | ELSEIF ( PRESENT( values_int32_0d ) ) THEN |
---|
[4577] | 2292 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2293 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2294 | values_int32_0d=values_int32_0d_pointer, return_value=output_return_value ) |
---|
| 2295 | ELSEIF ( PRESENT( values_int32_1d ) ) THEN |
---|
[4577] | 2296 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2297 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2298 | values_int32_1d=values_int32_1d_pointer, return_value=output_return_value ) |
---|
| 2299 | ELSEIF ( PRESENT( values_int32_2d ) ) THEN |
---|
[4577] | 2300 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2301 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2302 | values_int32_2d=values_int32_2d_pointer, return_value=output_return_value ) |
---|
| 2303 | ELSEIF ( PRESENT( values_int32_3d ) ) THEN |
---|
[4577] | 2304 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2305 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2306 | values_int32_3d=values_int32_3d_pointer, return_value=output_return_value ) |
---|
| 2307 | ! |
---|
[4577] | 2308 | !-- Working-precision integer output |
---|
[4147] | 2309 | ELSEIF ( PRESENT( values_intwp_0d ) ) THEN |
---|
[4577] | 2310 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2311 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2312 | values_intwp_0d=values_intwp_0d_pointer, return_value=output_return_value ) |
---|
| 2313 | ELSEIF ( PRESENT( values_intwp_1d ) ) THEN |
---|
[4577] | 2314 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2315 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2316 | values_intwp_1d=values_intwp_1d_pointer, return_value=output_return_value ) |
---|
| 2317 | ELSEIF ( PRESENT( values_intwp_2d ) ) THEN |
---|
[4577] | 2318 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2319 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2320 | values_intwp_2d=values_intwp_2d_pointer, return_value=output_return_value ) |
---|
| 2321 | ELSEIF ( PRESENT( values_intwp_3d ) ) THEN |
---|
[4577] | 2322 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2323 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2324 | values_intwp_3d=values_intwp_3d_pointer, return_value=output_return_value ) |
---|
| 2325 | ! |
---|
| 2326 | !-- 32bit real output |
---|
| 2327 | ELSEIF ( PRESENT( values_real32_0d ) ) THEN |
---|
[4577] | 2328 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2329 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2330 | values_real32_0d=values_real32_0d_pointer, return_value=output_return_value ) |
---|
| 2331 | ELSEIF ( PRESENT( values_real32_1d ) ) THEN |
---|
[4577] | 2332 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2333 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2334 | values_real32_1d=values_real32_1d_pointer, return_value=output_return_value ) |
---|
| 2335 | ELSEIF ( PRESENT( values_real32_2d ) ) THEN |
---|
[4577] | 2336 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2337 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2338 | values_real32_2d=values_real32_2d_pointer, return_value=output_return_value ) |
---|
| 2339 | ELSEIF ( PRESENT( values_real32_3d ) ) THEN |
---|
[4577] | 2340 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2341 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2342 | values_real32_3d=values_real32_3d_pointer, return_value=output_return_value ) |
---|
| 2343 | ! |
---|
| 2344 | !-- 64bit real output |
---|
| 2345 | ELSEIF ( PRESENT( values_real64_0d ) ) THEN |
---|
[4577] | 2346 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2347 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2348 | values_real64_0d=values_real64_0d_pointer, return_value=output_return_value ) |
---|
| 2349 | ELSEIF ( PRESENT( values_real64_1d ) ) THEN |
---|
[4577] | 2350 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2351 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2352 | values_real64_1d=values_real64_1d_pointer, return_value=output_return_value ) |
---|
| 2353 | ELSEIF ( PRESENT( values_real64_2d ) ) THEN |
---|
[4577] | 2354 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2355 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2356 | values_real64_2d=values_real64_2d_pointer, return_value=output_return_value ) |
---|
| 2357 | ELSEIF ( PRESENT( values_real64_3d ) ) THEN |
---|
[4577] | 2358 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2359 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2360 | values_real64_3d=values_real64_3d_pointer, return_value=output_return_value ) |
---|
| 2361 | ! |
---|
| 2362 | !-- working-precision real output |
---|
| 2363 | ELSEIF ( PRESENT( values_realwp_0d ) ) THEN |
---|
[4577] | 2364 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2365 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2366 | values_realwp_0d=values_realwp_0d_pointer, return_value=output_return_value ) |
---|
| 2367 | ELSEIF ( PRESENT( values_realwp_1d ) ) THEN |
---|
[4577] | 2368 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2369 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2370 | values_realwp_1d=values_realwp_1d_pointer, return_value=output_return_value ) |
---|
| 2371 | ELSEIF ( PRESENT( values_realwp_2d ) ) THEN |
---|
[4577] | 2372 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2373 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2374 | values_realwp_2d=values_realwp_2d_pointer, return_value=output_return_value ) |
---|
| 2375 | ELSEIF ( PRESENT( values_realwp_3d ) ) THEN |
---|
[4577] | 2376 | CALL binary_write_variable( file_id, variable_id, & |
---|
| 2377 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2378 | values_realwp_3d=values_realwp_3d_pointer, return_value=output_return_value ) |
---|
| 2379 | ELSE |
---|
| 2380 | return_value = 1 |
---|
[4577] | 2381 | CALL internal_message( 'error', routine_name // & |
---|
| 2382 | ': output_type not supported by file format "' // & |
---|
| 2383 | TRIM( file_format ) // '" ' // & |
---|
| 2384 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 2385 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 2386 | ENDIF |
---|
[4141] | 2387 | |
---|
[4147] | 2388 | CASE ( 'netcdf4-parallel', 'netcdf4-serial' ) |
---|
| 2389 | ! |
---|
[4577] | 2390 | !-- Character output |
---|
[4408] | 2391 | IF ( PRESENT( values_char_0d ) ) THEN |
---|
[4577] | 2392 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2393 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2394 | values_char_0d=values_char_0d_pointer, return_value=output_return_value ) |
---|
| 2395 | ELSEIF ( PRESENT( values_char_1d ) ) THEN |
---|
[4577] | 2396 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2397 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2398 | values_char_1d=values_char_1d_pointer, return_value=output_return_value ) |
---|
| 2399 | ELSEIF ( PRESENT( values_char_2d ) ) THEN |
---|
[4577] | 2400 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2401 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2402 | values_char_2d=values_char_2d_pointer, return_value=output_return_value ) |
---|
| 2403 | ELSEIF ( PRESENT( values_char_3d ) ) THEN |
---|
[4577] | 2404 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2405 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4408] | 2406 | values_char_3d=values_char_3d_pointer, return_value=output_return_value ) |
---|
| 2407 | ! |
---|
[4147] | 2408 | !-- 8bit integer output |
---|
[4408] | 2409 | ELSEIF ( PRESENT( values_int8_0d ) ) THEN |
---|
[4577] | 2410 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2411 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2412 | values_int8_0d=values_int8_0d_pointer, return_value=output_return_value ) |
---|
| 2413 | ELSEIF ( PRESENT( values_int8_1d ) ) THEN |
---|
[4577] | 2414 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2415 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2416 | values_int8_1d=values_int8_1d_pointer, return_value=output_return_value ) |
---|
| 2417 | ELSEIF ( PRESENT( values_int8_2d ) ) THEN |
---|
[4577] | 2418 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2419 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2420 | values_int8_2d=values_int8_2d_pointer, return_value=output_return_value ) |
---|
| 2421 | ELSEIF ( PRESENT( values_int8_3d ) ) THEN |
---|
[4577] | 2422 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2423 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2424 | values_int8_3d=values_int8_3d_pointer, return_value=output_return_value ) |
---|
| 2425 | ! |
---|
| 2426 | !-- 16bit integer output |
---|
| 2427 | ELSEIF ( PRESENT( values_int16_0d ) ) THEN |
---|
[4577] | 2428 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2429 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2430 | values_int16_0d=values_int16_0d_pointer, return_value=output_return_value ) |
---|
| 2431 | ELSEIF ( PRESENT( values_int16_1d ) ) THEN |
---|
[4577] | 2432 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2433 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2434 | values_int16_1d=values_int16_1d_pointer, return_value=output_return_value ) |
---|
| 2435 | ELSEIF ( PRESENT( values_int16_2d ) ) THEN |
---|
[4577] | 2436 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2437 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2438 | values_int16_2d=values_int16_2d_pointer, return_value=output_return_value ) |
---|
| 2439 | ELSEIF ( PRESENT( values_int16_3d ) ) THEN |
---|
[4577] | 2440 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2441 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2442 | values_int16_3d=values_int16_3d_pointer, return_value=output_return_value ) |
---|
| 2443 | ! |
---|
| 2444 | !-- 32bit integer output |
---|
| 2445 | ELSEIF ( PRESENT( values_int32_0d ) ) THEN |
---|
[4577] | 2446 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2447 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2448 | values_int32_0d=values_int32_0d_pointer, return_value=output_return_value ) |
---|
| 2449 | ELSEIF ( PRESENT( values_int32_1d ) ) THEN |
---|
[4577] | 2450 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2451 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2452 | values_int32_1d=values_int32_1d_pointer, return_value=output_return_value ) |
---|
| 2453 | ELSEIF ( PRESENT( values_int32_2d ) ) THEN |
---|
[4577] | 2454 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2455 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2456 | values_int32_2d=values_int32_2d_pointer, return_value=output_return_value ) |
---|
| 2457 | ELSEIF ( PRESENT( values_int32_3d ) ) THEN |
---|
[4577] | 2458 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2459 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2460 | values_int32_3d=values_int32_3d_pointer, return_value=output_return_value ) |
---|
| 2461 | ! |
---|
[4577] | 2462 | !-- Working-precision integer output |
---|
[4147] | 2463 | ELSEIF ( PRESENT( values_intwp_0d ) ) THEN |
---|
[4577] | 2464 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2465 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2466 | values_intwp_0d=values_intwp_0d_pointer, return_value=output_return_value ) |
---|
| 2467 | ELSEIF ( PRESENT( values_intwp_1d ) ) THEN |
---|
[4577] | 2468 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2469 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2470 | values_intwp_1d=values_intwp_1d_pointer, return_value=output_return_value ) |
---|
| 2471 | ELSEIF ( PRESENT( values_intwp_2d ) ) THEN |
---|
[4577] | 2472 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2473 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2474 | values_intwp_2d=values_intwp_2d_pointer, return_value=output_return_value ) |
---|
| 2475 | ELSEIF ( PRESENT( values_intwp_3d ) ) THEN |
---|
[4577] | 2476 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2477 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2478 | values_intwp_3d=values_intwp_3d_pointer, return_value=output_return_value ) |
---|
| 2479 | ! |
---|
| 2480 | !-- 32bit real output |
---|
| 2481 | ELSEIF ( PRESENT( values_real32_0d ) ) THEN |
---|
[4577] | 2482 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2483 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2484 | values_real32_0d=values_real32_0d_pointer, return_value=output_return_value ) |
---|
| 2485 | ELSEIF ( PRESENT( values_real32_1d ) ) THEN |
---|
[4577] | 2486 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2487 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2488 | values_real32_1d=values_real32_1d_pointer, return_value=output_return_value ) |
---|
| 2489 | ELSEIF ( PRESENT( values_real32_2d ) ) THEN |
---|
[4577] | 2490 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2491 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2492 | values_real32_2d=values_real32_2d_pointer, return_value=output_return_value ) |
---|
| 2493 | ELSEIF ( PRESENT( values_real32_3d ) ) THEN |
---|
[4577] | 2494 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2495 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2496 | values_real32_3d=values_real32_3d_pointer, return_value=output_return_value ) |
---|
| 2497 | ! |
---|
| 2498 | !-- 64bit real output |
---|
| 2499 | ELSEIF ( PRESENT( values_real64_0d ) ) THEN |
---|
[4577] | 2500 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2501 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2502 | values_real64_0d=values_real64_0d_pointer, return_value=output_return_value ) |
---|
| 2503 | ELSEIF ( PRESENT( values_real64_1d ) ) THEN |
---|
[4577] | 2504 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2505 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2506 | values_real64_1d=values_real64_1d_pointer, return_value=output_return_value ) |
---|
| 2507 | ELSEIF ( PRESENT( values_real64_2d ) ) THEN |
---|
[4577] | 2508 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2509 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2510 | values_real64_2d=values_real64_2d_pointer, return_value=output_return_value ) |
---|
| 2511 | ELSEIF ( PRESENT( values_real64_3d ) ) THEN |
---|
[4577] | 2512 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2513 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2514 | values_real64_3d=values_real64_3d_pointer, return_value=output_return_value ) |
---|
| 2515 | ! |
---|
| 2516 | !-- working-precision real output |
---|
| 2517 | ELSEIF ( PRESENT( values_realwp_0d ) ) THEN |
---|
[4577] | 2518 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2519 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2520 | values_realwp_0d=values_realwp_0d_pointer, return_value=output_return_value ) |
---|
| 2521 | ELSEIF ( PRESENT( values_realwp_1d ) ) THEN |
---|
[4577] | 2522 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2523 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2524 | values_realwp_1d=values_realwp_1d_pointer, return_value=output_return_value ) |
---|
| 2525 | ELSEIF ( PRESENT( values_realwp_2d ) ) THEN |
---|
[4577] | 2526 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2527 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2528 | values_realwp_2d=values_realwp_2d_pointer, return_value=output_return_value ) |
---|
| 2529 | ELSEIF ( PRESENT( values_realwp_3d ) ) THEN |
---|
[4577] | 2530 | CALL netcdf4_write_variable( file_id, variable_id, & |
---|
| 2531 | bounds_start_internal, value_counts, bounds_origin, is_global, & |
---|
[4147] | 2532 | values_realwp_3d=values_realwp_3d_pointer, return_value=output_return_value ) |
---|
| 2533 | ELSE |
---|
| 2534 | return_value = 1 |
---|
[4577] | 2535 | CALL internal_message( 'error', routine_name // & |
---|
| 2536 | ': output_type not supported by file format "' // & |
---|
| 2537 | TRIM( file_format ) // '" ' // & |
---|
| 2538 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 2539 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 2540 | ENDIF |
---|
[4141] | 2541 | |
---|
[4147] | 2542 | CASE DEFAULT |
---|
| 2543 | return_value = 1 |
---|
[4577] | 2544 | CALL internal_message( 'error', routine_name // & |
---|
| 2545 | ': file format "' // TRIM( file_format ) // & |
---|
| 2546 | '" not supported ' // & |
---|
| 2547 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 2548 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
[4141] | 2549 | |
---|
[4147] | 2550 | END SELECT |
---|
[4141] | 2551 | |
---|
[4147] | 2552 | IF ( return_value == 0 .AND. output_return_value /= 0 ) THEN |
---|
| 2553 | return_value = 1 |
---|
[4577] | 2554 | CALL internal_message( 'error', routine_name // & |
---|
| 2555 | ': error while writing variable ' // & |
---|
| 2556 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 2557 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 2558 | ENDIF |
---|
[4141] | 2559 | |
---|
[4147] | 2560 | ENDIF |
---|
[4141] | 2561 | |
---|
[4147] | 2562 | END FUNCTION dom_write_var |
---|
[4070] | 2563 | |
---|
| 2564 | !--------------------------------------------------------------------------------------------------! |
---|
| 2565 | ! Description: |
---|
| 2566 | ! ------------ |
---|
[4141] | 2567 | !> Finalize output. |
---|
| 2568 | !> All necessary steps are carried out to close all output files. If a file could not be closed, |
---|
| 2569 | !> this is noted in the error message. |
---|
| 2570 | !> |
---|
| 2571 | !> @bug if multiple files failed to be closed, only the last failure is given in the error message. |
---|
| 2572 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 2573 | FUNCTION dom_finalize_output() RESULT( return_value ) |
---|
[4141] | 2574 | |
---|
[4147] | 2575 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_finalize_output' !< name of routine |
---|
[4141] | 2576 | |
---|
[4147] | 2577 | INTEGER :: f !< loop index |
---|
| 2578 | INTEGER :: output_return_value !< return value from called routines |
---|
| 2579 | INTEGER :: return_value !< return value |
---|
| 2580 | INTEGER :: return_value_internal !< error code after closing a single file |
---|
[4141] | 2581 | |
---|
| 2582 | |
---|
[4147] | 2583 | return_value = 0 |
---|
[4141] | 2584 | |
---|
[4147] | 2585 | DO f = 1, nfiles |
---|
[4141] | 2586 | |
---|
[4147] | 2587 | IF ( files(f)%is_init ) THEN |
---|
[4141] | 2588 | |
---|
[4147] | 2589 | output_return_value = 0 |
---|
| 2590 | return_value_internal = 0 |
---|
[4141] | 2591 | |
---|
[4147] | 2592 | SELECT CASE ( TRIM( files(f)%format ) ) |
---|
[4141] | 2593 | |
---|
[4147] | 2594 | CASE ( 'binary' ) |
---|
| 2595 | CALL binary_finalize( files(f)%id, output_return_value ) |
---|
[4141] | 2596 | |
---|
[4147] | 2597 | CASE ( 'netcdf4-parallel', 'netcdf4-serial' ) |
---|
| 2598 | CALL netcdf4_finalize( files(f)%id, output_return_value ) |
---|
[4141] | 2599 | |
---|
[4147] | 2600 | CASE DEFAULT |
---|
| 2601 | return_value_internal = 1 |
---|
[4141] | 2602 | |
---|
[4147] | 2603 | END SELECT |
---|
[4141] | 2604 | |
---|
[4147] | 2605 | IF ( output_return_value /= 0 ) THEN |
---|
| 2606 | return_value = output_return_value |
---|
[4577] | 2607 | CALL internal_message( 'error', routine_name // & |
---|
| 2608 | ': error while finalizing file "' // & |
---|
[4147] | 2609 | TRIM( files(f)%name ) // '"' ) |
---|
| 2610 | ELSEIF ( return_value_internal /= 0 ) THEN |
---|
| 2611 | return_value = return_value_internal |
---|
[4577] | 2612 | CALL internal_message( 'error', routine_name // & |
---|
| 2613 | ': unsupported file format "' // & |
---|
| 2614 | TRIM( files(f)%format ) // '" for file "' // & |
---|
[4147] | 2615 | TRIM( files(f)%name ) // '"' ) |
---|
| 2616 | ENDIF |
---|
[4141] | 2617 | |
---|
[4147] | 2618 | ENDIF |
---|
[4141] | 2619 | |
---|
[4147] | 2620 | ENDDO |
---|
[4141] | 2621 | |
---|
[4147] | 2622 | END FUNCTION dom_finalize_output |
---|
[4141] | 2623 | |
---|
| 2624 | !--------------------------------------------------------------------------------------------------! |
---|
| 2625 | ! Description: |
---|
| 2626 | ! ------------ |
---|
| 2627 | !> Return the last created error message. |
---|
| 2628 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 2629 | FUNCTION dom_get_error_message() RESULT( error_message ) |
---|
[4141] | 2630 | |
---|
[4147] | 2631 | CHARACTER(LEN=800) :: error_message !< return error message to main program |
---|
[4141] | 2632 | |
---|
| 2633 | |
---|
[4147] | 2634 | error_message = TRIM( internal_error_message ) |
---|
[4141] | 2635 | |
---|
[4147] | 2636 | error_message = TRIM( error_message ) // TRIM( binary_get_error_message() ) |
---|
[4141] | 2637 | |
---|
[4147] | 2638 | error_message = TRIM( error_message ) // TRIM( netcdf4_get_error_message() ) |
---|
[4141] | 2639 | |
---|
[4147] | 2640 | internal_error_message = '' |
---|
| 2641 | |
---|
| 2642 | END FUNCTION dom_get_error_message |
---|
| 2643 | |
---|
[4141] | 2644 | !--------------------------------------------------------------------------------------------------! |
---|
| 2645 | ! Description: |
---|
| 2646 | ! ------------ |
---|
[4070] | 2647 | !> Add attribute to database. |
---|
| 2648 | !> |
---|
| 2649 | !> @todo Try to combine similar code parts and shorten routine. |
---|
| 2650 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 2651 | FUNCTION save_attribute_in_database( file_name, variable_name, attribute, append ) & |
---|
| 2652 | RESULT( return_value ) |
---|
[4070] | 2653 | |
---|
[4577] | 2654 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'save_attribute_in_database' !< name of routine |
---|
| 2655 | |
---|
[4147] | 2656 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 2657 | CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable |
---|
[4070] | 2658 | |
---|
[4147] | 2659 | INTEGER :: a !< loop index |
---|
| 2660 | INTEGER :: d !< loop index |
---|
| 2661 | INTEGER :: f !< loop index |
---|
| 2662 | INTEGER :: natts !< number of attributes |
---|
| 2663 | INTEGER :: return_value !< return value |
---|
[4070] | 2664 | |
---|
[4147] | 2665 | LOGICAL :: found !< true if variable or dimension of name 'variable_name' found |
---|
| 2666 | LOGICAL, INTENT(IN) :: append !< if true, append value to existing value |
---|
[4070] | 2667 | |
---|
[4147] | 2668 | TYPE(attribute_type), INTENT(IN) :: attribute !< new attribute |
---|
[4070] | 2669 | |
---|
[4147] | 2670 | TYPE(attribute_type), DIMENSION(:), ALLOCATABLE :: atts_tmp !< temporary attribute list |
---|
[4070] | 2671 | |
---|
| 2672 | |
---|
[4147] | 2673 | return_value = 0 |
---|
| 2674 | found = .FALSE. |
---|
[4070] | 2675 | |
---|
[4577] | 2676 | CALL internal_message( 'debug', routine_name // & |
---|
| 2677 | ': define attribute "' // TRIM( attribute%name ) // & |
---|
| 2678 | '" of variable "' // TRIM( variable_name ) // & |
---|
[4147] | 2679 | '" in file "' // TRIM( file_name ) // '"' ) |
---|
[4116] | 2680 | |
---|
[4147] | 2681 | DO f = 1, nfiles |
---|
[4070] | 2682 | |
---|
[4147] | 2683 | IF ( TRIM( file_name ) == files(f)%name ) THEN |
---|
[4070] | 2684 | |
---|
[4147] | 2685 | IF ( files(f)%is_init ) THEN |
---|
| 2686 | return_value = 1 |
---|
[4577] | 2687 | CALL internal_message( 'error', routine_name // ': file "' // TRIM( file_name ) // & |
---|
[4147] | 2688 | '" is already initialized. No further attribute definition allowed!' ) |
---|
| 2689 | EXIT |
---|
| 2690 | ENDIF |
---|
| 2691 | ! |
---|
| 2692 | !-- Add attribute to file |
---|
| 2693 | IF ( TRIM( variable_name ) == '' ) THEN |
---|
| 2694 | ! |
---|
| 2695 | !-- Initialize first file attribute |
---|
| 2696 | IF ( .NOT. ALLOCATED( files(f)%attributes ) ) THEN |
---|
| 2697 | natts = 1 |
---|
| 2698 | ALLOCATE( files(f)%attributes(natts) ) |
---|
| 2699 | ELSE |
---|
| 2700 | natts = SIZE( files(f)%attributes ) |
---|
| 2701 | ! |
---|
| 2702 | !-- Check if attribute already exists |
---|
| 2703 | DO a = 1, natts |
---|
| 2704 | IF ( files(f)%attributes(a)%name == attribute%name ) THEN |
---|
| 2705 | IF ( append ) THEN |
---|
| 2706 | ! |
---|
| 2707 | !-- Append existing string attribute |
---|
[4577] | 2708 | files(f)%attributes(a)%value_char = & |
---|
| 2709 | TRIM( files(f)%attributes(a)%value_char ) // & |
---|
| 2710 | TRIM( attribute%value_char ) |
---|
[4147] | 2711 | ELSE |
---|
| 2712 | files(f)%attributes(a) = attribute |
---|
| 2713 | ENDIF |
---|
| 2714 | found = .TRUE. |
---|
| 2715 | EXIT |
---|
| 2716 | ENDIF |
---|
| 2717 | ENDDO |
---|
| 2718 | ! |
---|
| 2719 | !-- Extend attribute list by 1 |
---|
| 2720 | IF ( .NOT. found ) THEN |
---|
| 2721 | ALLOCATE( atts_tmp(natts) ) |
---|
| 2722 | atts_tmp = files(f)%attributes |
---|
| 2723 | DEALLOCATE( files(f)%attributes ) |
---|
| 2724 | natts = natts + 1 |
---|
| 2725 | ALLOCATE( files(f)%attributes(natts) ) |
---|
| 2726 | files(f)%attributes(:natts-1) = atts_tmp |
---|
| 2727 | DEALLOCATE( atts_tmp ) |
---|
| 2728 | ENDIF |
---|
| 2729 | ENDIF |
---|
| 2730 | ! |
---|
| 2731 | !-- Save new attribute to the end of the attribute list |
---|
| 2732 | IF ( .NOT. found ) THEN |
---|
| 2733 | files(f)%attributes(natts) = attribute |
---|
| 2734 | found = .TRUE. |
---|
| 2735 | ENDIF |
---|
[4106] | 2736 | |
---|
[4147] | 2737 | EXIT |
---|
[4070] | 2738 | |
---|
[4147] | 2739 | ELSE |
---|
| 2740 | ! |
---|
| 2741 | !-- Add attribute to dimension |
---|
| 2742 | IF ( ALLOCATED( files(f)%dimensions ) ) THEN |
---|
[4070] | 2743 | |
---|
[4147] | 2744 | DO d = 1, SIZE( files(f)%dimensions ) |
---|
[4070] | 2745 | |
---|
[4147] | 2746 | IF ( files(f)%dimensions(d)%name == TRIM( variable_name ) ) THEN |
---|
[4070] | 2747 | |
---|
[4147] | 2748 | IF ( .NOT. ALLOCATED( files(f)%dimensions(d)%attributes ) ) THEN |
---|
| 2749 | ! |
---|
| 2750 | !-- Initialize first attribute |
---|
| 2751 | natts = 1 |
---|
| 2752 | ALLOCATE( files(f)%dimensions(d)%attributes(natts) ) |
---|
| 2753 | ELSE |
---|
| 2754 | natts = SIZE( files(f)%dimensions(d)%attributes ) |
---|
| 2755 | ! |
---|
| 2756 | !-- Check if attribute already exists |
---|
| 2757 | DO a = 1, natts |
---|
| 2758 | IF ( files(f)%dimensions(d)%attributes(a)%name == attribute%name ) & |
---|
| 2759 | THEN |
---|
| 2760 | IF ( append ) THEN |
---|
| 2761 | ! |
---|
| 2762 | !-- Append existing character attribute |
---|
[4577] | 2763 | files(f)%dimensions(d)%attributes(a)%value_char = & |
---|
| 2764 | TRIM( files(f)%dimensions(d)%attributes(a)%value_char ) // & |
---|
[4147] | 2765 | TRIM( attribute%value_char ) |
---|
| 2766 | ELSE |
---|
| 2767 | ! |
---|
| 2768 | !-- Update existing attribute |
---|
| 2769 | files(f)%dimensions(d)%attributes(a) = attribute |
---|
| 2770 | ENDIF |
---|
| 2771 | found = .TRUE. |
---|
| 2772 | EXIT |
---|
| 2773 | ENDIF |
---|
| 2774 | ENDDO |
---|
| 2775 | ! |
---|
| 2776 | !-- Extend attribute list |
---|
| 2777 | IF ( .NOT. found ) THEN |
---|
| 2778 | ALLOCATE( atts_tmp(natts) ) |
---|
| 2779 | atts_tmp = files(f)%dimensions(d)%attributes |
---|
| 2780 | DEALLOCATE( files(f)%dimensions(d)%attributes ) |
---|
| 2781 | natts = natts + 1 |
---|
| 2782 | ALLOCATE( files(f)%dimensions(d)%attributes(natts) ) |
---|
| 2783 | files(f)%dimensions(d)%attributes(:natts-1) = atts_tmp |
---|
| 2784 | DEALLOCATE( atts_tmp ) |
---|
| 2785 | ENDIF |
---|
| 2786 | ENDIF |
---|
| 2787 | ! |
---|
| 2788 | !-- Add new attribute to database |
---|
| 2789 | IF ( .NOT. found ) THEN |
---|
| 2790 | files(f)%dimensions(d)%attributes(natts) = attribute |
---|
| 2791 | found = .TRUE. |
---|
| 2792 | ENDIF |
---|
[4070] | 2793 | |
---|
[4147] | 2794 | EXIT |
---|
[4070] | 2795 | |
---|
[4147] | 2796 | ENDIF ! dimension found |
---|
[4070] | 2797 | |
---|
[4147] | 2798 | ENDDO ! loop over dimensions |
---|
[4070] | 2799 | |
---|
[4147] | 2800 | ENDIF ! dimensions exist in file |
---|
| 2801 | ! |
---|
| 2802 | !-- Add attribute to variable |
---|
| 2803 | IF ( .NOT. found .AND. ALLOCATED( files(f)%variables) ) THEN |
---|
[4070] | 2804 | |
---|
[4147] | 2805 | DO d = 1, SIZE( files(f)%variables ) |
---|
[4070] | 2806 | |
---|
[4147] | 2807 | IF ( files(f)%variables(d)%name == TRIM( variable_name ) ) THEN |
---|
[4070] | 2808 | |
---|
[4147] | 2809 | IF ( .NOT. ALLOCATED( files(f)%variables(d)%attributes ) ) THEN |
---|
| 2810 | ! |
---|
| 2811 | !-- Initialize first attribute |
---|
| 2812 | natts = 1 |
---|
| 2813 | ALLOCATE( files(f)%variables(d)%attributes(natts) ) |
---|
| 2814 | ELSE |
---|
| 2815 | natts = SIZE( files(f)%variables(d)%attributes ) |
---|
| 2816 | ! |
---|
| 2817 | !-- Check if attribute already exists |
---|
| 2818 | DO a = 1, natts |
---|
[4577] | 2819 | IF ( files(f)%variables(d)%attributes(a)%name == attribute%name ) THEN |
---|
[4147] | 2820 | IF ( append ) THEN |
---|
| 2821 | ! |
---|
| 2822 | !-- Append existing character attribute |
---|
[4577] | 2823 | files(f)%variables(d)%attributes(a)%value_char = & |
---|
| 2824 | TRIM( files(f)%variables(d)%attributes(a)%value_char ) // & |
---|
[4147] | 2825 | TRIM( attribute%value_char ) |
---|
| 2826 | ELSE |
---|
| 2827 | ! |
---|
| 2828 | !-- Update existing attribute |
---|
| 2829 | files(f)%variables(d)%attributes(a) = attribute |
---|
| 2830 | ENDIF |
---|
| 2831 | found = .TRUE. |
---|
| 2832 | EXIT |
---|
| 2833 | ENDIF |
---|
| 2834 | ENDDO |
---|
| 2835 | ! |
---|
| 2836 | !-- Extend attribute list |
---|
| 2837 | IF ( .NOT. found ) THEN |
---|
| 2838 | ALLOCATE( atts_tmp(natts) ) |
---|
| 2839 | atts_tmp = files(f)%variables(d)%attributes |
---|
| 2840 | DEALLOCATE( files(f)%variables(d)%attributes ) |
---|
| 2841 | natts = natts + 1 |
---|
| 2842 | ALLOCATE( files(f)%variables(d)%attributes(natts) ) |
---|
| 2843 | files(f)%variables(d)%attributes(:natts-1) = atts_tmp |
---|
| 2844 | DEALLOCATE( atts_tmp ) |
---|
| 2845 | ENDIF |
---|
[4070] | 2846 | |
---|
[4147] | 2847 | ENDIF |
---|
| 2848 | ! |
---|
| 2849 | !-- Add new attribute to database |
---|
| 2850 | IF ( .NOT. found ) THEN |
---|
| 2851 | files(f)%variables(d)%attributes(natts) = attribute |
---|
| 2852 | found = .TRUE. |
---|
| 2853 | ENDIF |
---|
[4070] | 2854 | |
---|
[4147] | 2855 | EXIT |
---|
[4070] | 2856 | |
---|
[4147] | 2857 | ENDIF ! variable found |
---|
[4070] | 2858 | |
---|
[4147] | 2859 | ENDDO ! loop over variables |
---|
[4070] | 2860 | |
---|
[4147] | 2861 | ENDIF ! variables exist in file |
---|
[4070] | 2862 | |
---|
[4147] | 2863 | IF ( .NOT. found ) THEN |
---|
| 2864 | return_value = 1 |
---|
[4577] | 2865 | CALL internal_message( 'error', & |
---|
| 2866 | routine_name // & |
---|
| 2867 | ': requested dimension/variable "' // TRIM( variable_name ) // & |
---|
| 2868 | '" for attribute "' // TRIM( attribute%name ) // & |
---|
| 2869 | '" does not exist in file "' // TRIM( file_name ) // '"' ) |
---|
[4147] | 2870 | ENDIF |
---|
[4070] | 2871 | |
---|
[4147] | 2872 | EXIT |
---|
[4070] | 2873 | |
---|
[4147] | 2874 | ENDIF ! variable_name not empty |
---|
[4070] | 2875 | |
---|
[4147] | 2876 | ENDIF ! check file_name |
---|
[4070] | 2877 | |
---|
[4147] | 2878 | ENDDO ! loop over files |
---|
[4070] | 2879 | |
---|
[4147] | 2880 | IF ( .NOT. found .AND. return_value == 0 ) THEN |
---|
| 2881 | return_value = 1 |
---|
[4577] | 2882 | CALL internal_message( 'error', & |
---|
| 2883 | routine_name // & |
---|
| 2884 | ': requested file "' // TRIM( file_name ) // & |
---|
| 2885 | '" for attribute "' // TRIM( attribute%name ) // & |
---|
[4147] | 2886 | '" does not exist' ) |
---|
| 2887 | ENDIF |
---|
[4070] | 2888 | |
---|
[4147] | 2889 | END FUNCTION save_attribute_in_database |
---|
[4070] | 2890 | |
---|
| 2891 | !--------------------------------------------------------------------------------------------------! |
---|
| 2892 | ! Description: |
---|
| 2893 | ! ------------ |
---|
| 2894 | !> Check database and delete any unused dimensions and empty files (i.e. files |
---|
| 2895 | !> without variables). |
---|
| 2896 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 2897 | FUNCTION cleanup_database() RESULT( return_value ) |
---|
[4070] | 2898 | |
---|
[4147] | 2899 | ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'cleanup_database' !< name of routine |
---|
[4070] | 2900 | |
---|
[4147] | 2901 | INTEGER :: d !< loop index |
---|
| 2902 | INTEGER :: f !< loop index |
---|
| 2903 | INTEGER :: i !< loop index |
---|
| 2904 | INTEGER :: ndims !< number of dimensions in a file |
---|
| 2905 | INTEGER :: ndims_used !< number of used dimensions in a file |
---|
| 2906 | INTEGER :: nfiles_used !< number of used files |
---|
| 2907 | INTEGER :: nvars !< number of variables in a file |
---|
| 2908 | INTEGER :: return_value !< return value |
---|
[4070] | 2909 | |
---|
[4147] | 2910 | LOGICAL, DIMENSION(1:nfiles) :: file_is_used !< true if file contains variables |
---|
| 2911 | LOGICAL, DIMENSION(:), ALLOCATABLE :: dimension_is_used !< true if dimension is used by any variable |
---|
[4070] | 2912 | |
---|
[4147] | 2913 | TYPE(dimension_type), DIMENSION(:), ALLOCATABLE :: used_dimensions !< list of used dimensions |
---|
[4070] | 2914 | |
---|
[4147] | 2915 | TYPE(file_type), DIMENSION(:), ALLOCATABLE :: used_files !< list of used files |
---|
[4070] | 2916 | |
---|
| 2917 | |
---|
[4147] | 2918 | return_value = 0 |
---|
| 2919 | ! |
---|
| 2920 | !-- Flag files which contain output variables as used |
---|
| 2921 | file_is_used(:) = .FALSE. |
---|
| 2922 | DO f = 1, nfiles |
---|
| 2923 | IF ( ALLOCATED( files(f)%variables ) ) THEN |
---|
| 2924 | file_is_used(f) = .TRUE. |
---|
| 2925 | ENDIF |
---|
| 2926 | ENDDO |
---|
| 2927 | ! |
---|
| 2928 | !-- Copy flagged files into temporary list |
---|
| 2929 | nfiles_used = COUNT( file_is_used ) |
---|
| 2930 | ALLOCATE( used_files(nfiles_used) ) |
---|
| 2931 | i = 0 |
---|
| 2932 | DO f = 1, nfiles |
---|
| 2933 | IF ( file_is_used(f) ) THEN |
---|
| 2934 | i = i + 1 |
---|
| 2935 | used_files(i) = files(f) |
---|
| 2936 | ENDIF |
---|
| 2937 | ENDDO |
---|
| 2938 | ! |
---|
| 2939 | !-- Replace file list with list of used files |
---|
| 2940 | DEALLOCATE( files ) |
---|
| 2941 | nfiles = nfiles_used |
---|
| 2942 | ALLOCATE( files(nfiles) ) |
---|
| 2943 | files = used_files |
---|
| 2944 | DEALLOCATE( used_files ) |
---|
| 2945 | ! |
---|
| 2946 | !-- Check every file for unused dimensions |
---|
| 2947 | DO f = 1, nfiles |
---|
| 2948 | ! |
---|
| 2949 | !-- If a file is already initialized, it was already checked previously |
---|
| 2950 | IF ( files(f)%is_init ) CYCLE |
---|
| 2951 | ! |
---|
| 2952 | !-- Get number of defined dimensions |
---|
| 2953 | ndims = SIZE( files(f)%dimensions ) |
---|
| 2954 | ALLOCATE( dimension_is_used(ndims) ) |
---|
| 2955 | ! |
---|
| 2956 | !-- Go through all variables and flag all used dimensions |
---|
| 2957 | nvars = SIZE( files(f)%variables ) |
---|
| 2958 | DO d = 1, ndims |
---|
| 2959 | DO i = 1, nvars |
---|
[4577] | 2960 | dimension_is_used(d) = & |
---|
| 2961 | ANY( files(f)%dimensions(d)%name == files(f)%variables(i)%dimension_names ) |
---|
[4147] | 2962 | IF ( dimension_is_used(d) ) EXIT |
---|
| 2963 | ENDDO |
---|
| 2964 | ENDDO |
---|
| 2965 | ! |
---|
| 2966 | !-- Copy used dimensions to temporary list |
---|
| 2967 | ndims_used = COUNT( dimension_is_used ) |
---|
| 2968 | ALLOCATE( used_dimensions(ndims_used) ) |
---|
| 2969 | i = 0 |
---|
| 2970 | DO d = 1, ndims |
---|
| 2971 | IF ( dimension_is_used(d) ) THEN |
---|
| 2972 | i = i + 1 |
---|
| 2973 | used_dimensions(i) = files(f)%dimensions(d) |
---|
| 2974 | ENDIF |
---|
| 2975 | ENDDO |
---|
| 2976 | ! |
---|
| 2977 | !-- Replace dimension list with list of used dimensions |
---|
| 2978 | DEALLOCATE( files(f)%dimensions ) |
---|
| 2979 | ndims = ndims_used |
---|
| 2980 | ALLOCATE( files(f)%dimensions(ndims) ) |
---|
| 2981 | files(f)%dimensions = used_dimensions |
---|
| 2982 | DEALLOCATE( used_dimensions ) |
---|
| 2983 | DEALLOCATE( dimension_is_used ) |
---|
[4070] | 2984 | |
---|
[4147] | 2985 | ENDDO |
---|
[4070] | 2986 | |
---|
[4147] | 2987 | END FUNCTION cleanup_database |
---|
[4070] | 2988 | |
---|
| 2989 | !--------------------------------------------------------------------------------------------------! |
---|
| 2990 | ! Description: |
---|
| 2991 | ! ------------ |
---|
| 2992 | !> Open requested output file. |
---|
| 2993 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 2994 | SUBROUTINE open_output_file( file_format, file_name, file_id, return_value ) |
---|
[4070] | 2995 | |
---|
[4577] | 2996 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'open_output_file' !< name of routine |
---|
| 2997 | |
---|
[4147] | 2998 | CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file |
---|
| 2999 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file to be checked |
---|
[4070] | 3000 | |
---|
[4147] | 3001 | INTEGER, INTENT(OUT) :: file_id !< file ID |
---|
| 3002 | INTEGER :: output_return_value !< return value of a called output routine |
---|
| 3003 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
[4070] | 3004 | |
---|
| 3005 | |
---|
[4147] | 3006 | return_value = 0 |
---|
| 3007 | output_return_value = 0 |
---|
[4070] | 3008 | |
---|
[4147] | 3009 | SELECT CASE ( TRIM( file_format ) ) |
---|
[4070] | 3010 | |
---|
[4147] | 3011 | CASE ( 'binary' ) |
---|
| 3012 | CALL binary_open_file( 'binary', file_name, file_id, output_return_value ) |
---|
[4070] | 3013 | |
---|
[4147] | 3014 | CASE ( 'netcdf4-serial' ) |
---|
| 3015 | CALL netcdf4_open_file( 'serial', file_name, file_id, output_return_value ) |
---|
[4070] | 3016 | |
---|
[4147] | 3017 | CASE ( 'netcdf4-parallel' ) |
---|
| 3018 | CALL netcdf4_open_file( 'parallel', file_name, file_id, output_return_value ) |
---|
[4070] | 3019 | |
---|
[4147] | 3020 | CASE DEFAULT |
---|
| 3021 | return_value = 1 |
---|
[4070] | 3022 | |
---|
[4147] | 3023 | END SELECT |
---|
[4070] | 3024 | |
---|
[4147] | 3025 | IF ( output_return_value /= 0 ) THEN |
---|
| 3026 | return_value = output_return_value |
---|
[4577] | 3027 | CALL internal_message( 'error', routine_name // & |
---|
[4147] | 3028 | ': error while opening file "' // TRIM( file_name ) // '"' ) |
---|
| 3029 | ELSEIF ( return_value /= 0 ) THEN |
---|
[4577] | 3030 | CALL internal_message( 'error', routine_name // & |
---|
| 3031 | ': file "' // TRIM( file_name ) // & |
---|
| 3032 | '": file format "' // TRIM( file_format ) // & |
---|
[4147] | 3033 | '" not supported' ) |
---|
| 3034 | ENDIF |
---|
[4070] | 3035 | |
---|
[4147] | 3036 | END SUBROUTINE open_output_file |
---|
[4070] | 3037 | |
---|
| 3038 | !--------------------------------------------------------------------------------------------------! |
---|
| 3039 | ! Description: |
---|
| 3040 | ! ------------ |
---|
[4141] | 3041 | !> Initialize attributes, dimensions and variables in a file. |
---|
[4070] | 3042 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3043 | SUBROUTINE init_file_header( file, return_value ) |
---|
[4070] | 3044 | |
---|
[4147] | 3045 | ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'init_file_header' !< name of routine |
---|
[4070] | 3046 | |
---|
[4147] | 3047 | INTEGER :: a !< loop index |
---|
| 3048 | INTEGER :: d !< loop index |
---|
| 3049 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
[4070] | 3050 | |
---|
[4147] | 3051 | TYPE(file_type), INTENT(INOUT) :: file !< initialize header of this file |
---|
[4070] | 3052 | |
---|
| 3053 | |
---|
[4147] | 3054 | return_value = 0 |
---|
| 3055 | ! |
---|
| 3056 | !-- Write file attributes |
---|
| 3057 | IF ( ALLOCATED( file%attributes ) ) THEN |
---|
| 3058 | DO a = 1, SIZE( file%attributes ) |
---|
[4577] | 3059 | return_value = write_attribute( file%format, file%id, file%name, & |
---|
| 3060 | variable_id=no_id, variable_name='', & |
---|
[4147] | 3061 | attribute=file%attributes(a) ) |
---|
| 3062 | IF ( return_value /= 0 ) EXIT |
---|
| 3063 | ENDDO |
---|
| 3064 | ENDIF |
---|
[4070] | 3065 | |
---|
[4147] | 3066 | IF ( return_value == 0 ) THEN |
---|
| 3067 | ! |
---|
| 3068 | !-- Initialize file dimensions |
---|
| 3069 | DO d = 1, SIZE( file%dimensions ) |
---|
[4070] | 3070 | |
---|
[4147] | 3071 | IF ( .NOT. file%dimensions(d)%is_masked ) THEN |
---|
| 3072 | ! |
---|
| 3073 | !-- Initialize non-masked dimension |
---|
[4577] | 3074 | CALL init_file_dimension( file%format, file%id, file%name, & |
---|
| 3075 | file%dimensions(d)%id, file%dimensions(d)%name, & |
---|
| 3076 | file%dimensions(d)%data_type, file%dimensions(d)%length, & |
---|
| 3077 | file%dimensions(d)%variable_id, return_value ) |
---|
[4070] | 3078 | |
---|
[4147] | 3079 | ELSE |
---|
| 3080 | ! |
---|
| 3081 | !-- Initialize masked dimension |
---|
[4577] | 3082 | CALL init_file_dimension( file%format, file%id, file%name, & |
---|
| 3083 | file%dimensions(d)%id, file%dimensions(d)%name, & |
---|
| 3084 | file%dimensions(d)%data_type, file%dimensions(d)%length_mask,& |
---|
| 3085 | file%dimensions(d)%variable_id, return_value ) |
---|
[4070] | 3086 | |
---|
[4147] | 3087 | ENDIF |
---|
[4070] | 3088 | |
---|
[4147] | 3089 | IF ( return_value == 0 .AND. ALLOCATED( file%dimensions(d)%attributes ) ) THEN |
---|
| 3090 | ! |
---|
| 3091 | !-- Write dimension attributes |
---|
| 3092 | DO a = 1, SIZE( file%dimensions(d)%attributes ) |
---|
[4577] | 3093 | return_value = write_attribute( file%format, file%id, file%name, & |
---|
| 3094 | variable_id=file%dimensions(d)%variable_id, & |
---|
| 3095 | variable_name=file%dimensions(d)%name, & |
---|
| 3096 | attribute=file%dimensions(d)%attributes(a) ) |
---|
[4147] | 3097 | IF ( return_value /= 0 ) EXIT |
---|
| 3098 | ENDDO |
---|
| 3099 | ENDIF |
---|
[4070] | 3100 | |
---|
[4147] | 3101 | IF ( return_value /= 0 ) EXIT |
---|
[4070] | 3102 | |
---|
[4147] | 3103 | ENDDO |
---|
| 3104 | ! |
---|
| 3105 | !-- Save dimension IDs for variables wihtin database |
---|
[4577] | 3106 | IF ( return_value == 0 ) & |
---|
[4147] | 3107 | CALL collect_dimesion_ids_for_variables( file%name, file%variables, file%dimensions, & |
---|
| 3108 | return_value ) |
---|
| 3109 | ! |
---|
| 3110 | !-- Initialize file variables |
---|
| 3111 | IF ( return_value == 0 ) THEN |
---|
| 3112 | DO d = 1, SIZE( file%variables ) |
---|
[4070] | 3113 | |
---|
[4577] | 3114 | CALL init_file_variable( file%format, file%id, file%name, & |
---|
| 3115 | file%variables(d)%id, file%variables(d)%name, file%variables(d)%data_type, & |
---|
| 3116 | file%variables(d)%dimension_ids, & |
---|
[4147] | 3117 | file%variables(d)%is_global, return_value ) |
---|
[4070] | 3118 | |
---|
[4147] | 3119 | IF ( return_value == 0 .AND. ALLOCATED( file%variables(d)%attributes ) ) THEN |
---|
| 3120 | ! |
---|
| 3121 | !-- Write variable attributes |
---|
| 3122 | DO a = 1, SIZE( file%variables(d)%attributes ) |
---|
[4577] | 3123 | return_value = write_attribute( file%format, file%id, file%name, & |
---|
| 3124 | variable_id=file%variables(d)%id, & |
---|
| 3125 | variable_name=file%variables(d)%name, & |
---|
| 3126 | attribute=file%variables(d)%attributes(a) ) |
---|
[4147] | 3127 | IF ( return_value /= 0 ) EXIT |
---|
| 3128 | ENDDO |
---|
| 3129 | ENDIF |
---|
[4070] | 3130 | |
---|
[4147] | 3131 | IF ( return_value /= 0 ) EXIT |
---|
[4070] | 3132 | |
---|
[4147] | 3133 | ENDDO |
---|
| 3134 | ENDIF |
---|
[4070] | 3135 | |
---|
[4147] | 3136 | ENDIF |
---|
[4070] | 3137 | |
---|
[4147] | 3138 | END SUBROUTINE init_file_header |
---|
[4070] | 3139 | |
---|
| 3140 | !--------------------------------------------------------------------------------------------------! |
---|
| 3141 | ! Description: |
---|
| 3142 | ! ------------ |
---|
[4141] | 3143 | !> Initialize dimension in file. |
---|
| 3144 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 3145 | SUBROUTINE init_file_dimension( file_format, file_id, file_name, & |
---|
| 3146 | dimension_id, dimension_name, dimension_type, dimension_length, & |
---|
| 3147 | variable_id, return_value ) |
---|
[4141] | 3148 | |
---|
[4577] | 3149 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'init_file_dimension' !< file format chosen for file |
---|
| 3150 | |
---|
[4147] | 3151 | CHARACTER(LEN=*), INTENT(IN) :: dimension_name !< name of dimension |
---|
| 3152 | CHARACTER(LEN=*), INTENT(IN) :: dimension_type !< data type of dimension |
---|
| 3153 | CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file |
---|
| 3154 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
[4141] | 3155 | |
---|
[4147] | 3156 | INTEGER, INTENT(OUT) :: dimension_id !< dimension ID |
---|
| 3157 | INTEGER, INTENT(IN) :: dimension_length !< length of dimension |
---|
| 3158 | INTEGER, INTENT(IN) :: file_id !< file ID |
---|
| 3159 | INTEGER :: output_return_value !< return value of a called output routine |
---|
| 3160 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
| 3161 | INTEGER, INTENT(OUT) :: variable_id !< associated variable ID |
---|
[4141] | 3162 | |
---|
| 3163 | |
---|
[4147] | 3164 | return_value = 0 |
---|
| 3165 | output_return_value = 0 |
---|
[4141] | 3166 | |
---|
[4577] | 3167 | temp_string = '(file "' // TRIM( file_name ) // & |
---|
[4147] | 3168 | '", dimension "' // TRIM( dimension_name ) // '")' |
---|
[4141] | 3169 | |
---|
[4147] | 3170 | SELECT CASE ( TRIM( file_format ) ) |
---|
[4141] | 3171 | |
---|
[4147] | 3172 | CASE ( 'binary' ) |
---|
[4577] | 3173 | CALL binary_init_dimension( 'binary', file_id, dimension_id, variable_id, & |
---|
| 3174 | dimension_name, dimension_type, dimension_length, & |
---|
| 3175 | return_value=output_return_value ) |
---|
[4141] | 3176 | |
---|
[4147] | 3177 | CASE ( 'netcdf4-serial' ) |
---|
[4577] | 3178 | CALL netcdf4_init_dimension( 'serial', file_id, dimension_id, variable_id, & |
---|
| 3179 | dimension_name, dimension_type, dimension_length, & |
---|
| 3180 | return_value=output_return_value ) |
---|
[4141] | 3181 | |
---|
[4147] | 3182 | CASE ( 'netcdf4-parallel' ) |
---|
[4577] | 3183 | CALL netcdf4_init_dimension( 'parallel', file_id, dimension_id, variable_id, & |
---|
| 3184 | dimension_name, dimension_type, dimension_length, & |
---|
| 3185 | return_value=output_return_value ) |
---|
[4141] | 3186 | |
---|
[4147] | 3187 | CASE DEFAULT |
---|
| 3188 | return_value = 1 |
---|
[4577] | 3189 | CALL internal_message( 'error', routine_name // & |
---|
| 3190 | ': file format "' // TRIM( file_format ) // & |
---|
[4147] | 3191 | '" not supported ' // TRIM( temp_string ) ) |
---|
[4141] | 3192 | |
---|
[4147] | 3193 | END SELECT |
---|
[4141] | 3194 | |
---|
[4147] | 3195 | IF ( output_return_value /= 0 ) THEN |
---|
| 3196 | return_value = output_return_value |
---|
[4577] | 3197 | CALL internal_message( 'error', routine_name // & |
---|
[4147] | 3198 | ': error while defining dimension ' // TRIM( temp_string ) ) |
---|
| 3199 | ENDIF |
---|
[4141] | 3200 | |
---|
[4147] | 3201 | END SUBROUTINE init_file_dimension |
---|
[4141] | 3202 | |
---|
| 3203 | !--------------------------------------------------------------------------------------------------! |
---|
| 3204 | ! Description: |
---|
| 3205 | ! ------------ |
---|
| 3206 | !> Initialize variable. |
---|
| 3207 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 3208 | SUBROUTINE init_file_variable( file_format, file_id, file_name, & |
---|
| 3209 | variable_id, variable_name, variable_type, dimension_ids, & |
---|
[4147] | 3210 | is_global, return_value ) |
---|
[4141] | 3211 | |
---|
[4577] | 3212 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'init_file_variable' !< file format chosen for file |
---|
| 3213 | |
---|
[4147] | 3214 | CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file |
---|
| 3215 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< file name |
---|
| 3216 | CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable |
---|
| 3217 | CHARACTER(LEN=*), INTENT(IN) :: variable_type !< data type of variable |
---|
[4141] | 3218 | |
---|
[4147] | 3219 | INTEGER, INTENT(IN) :: file_id !< file ID |
---|
| 3220 | INTEGER :: output_return_value !< return value of a called output routine |
---|
| 3221 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
| 3222 | INTEGER, INTENT(OUT) :: variable_id !< variable ID |
---|
[4141] | 3223 | |
---|
[4147] | 3224 | INTEGER, DIMENSION(:), INTENT(IN) :: dimension_ids !< list of dimension IDs used by variable |
---|
[4141] | 3225 | |
---|
[4147] | 3226 | LOGICAL, INTENT(IN) :: is_global !< true if variable is global |
---|
[4141] | 3227 | |
---|
| 3228 | |
---|
[4147] | 3229 | return_value = 0 |
---|
| 3230 | output_return_value = 0 |
---|
[4141] | 3231 | |
---|
[4147] | 3232 | temp_string = '(file "' // TRIM( file_name ) // & |
---|
| 3233 | '", variable "' // TRIM( variable_name ) // '")' |
---|
[4141] | 3234 | |
---|
[4147] | 3235 | SELECT CASE ( TRIM( file_format ) ) |
---|
[4141] | 3236 | |
---|
[4147] | 3237 | CASE ( 'binary' ) |
---|
[4577] | 3238 | CALL binary_init_variable( 'binary', file_id, variable_id, variable_name, & |
---|
[4147] | 3239 | variable_type, dimension_ids, is_global, return_value=output_return_value ) |
---|
[4141] | 3240 | |
---|
[4147] | 3241 | CASE ( 'netcdf4-serial' ) |
---|
[4577] | 3242 | CALL netcdf4_init_variable( 'serial', file_id, variable_id, variable_name, & |
---|
[4147] | 3243 | variable_type, dimension_ids, is_global, return_value=output_return_value ) |
---|
[4141] | 3244 | |
---|
[4147] | 3245 | CASE ( 'netcdf4-parallel' ) |
---|
[4577] | 3246 | CALL netcdf4_init_variable( 'parallel', file_id, variable_id, variable_name, & |
---|
[4147] | 3247 | variable_type, dimension_ids, is_global, return_value=output_return_value ) |
---|
[4141] | 3248 | |
---|
[4147] | 3249 | CASE DEFAULT |
---|
| 3250 | return_value = 1 |
---|
[4577] | 3251 | CALL internal_message( 'error', routine_name // & |
---|
| 3252 | ': file format "' // TRIM( file_format ) // & |
---|
[4147] | 3253 | '" not supported ' // TRIM( temp_string ) ) |
---|
[4141] | 3254 | |
---|
[4147] | 3255 | END SELECT |
---|
[4141] | 3256 | |
---|
[4147] | 3257 | IF ( output_return_value /= 0 ) THEN |
---|
| 3258 | return_value = output_return_value |
---|
| 3259 | CALL internal_message( 'error', routine_name // & |
---|
| 3260 | ': error while defining variable ' // TRIM( temp_string ) ) |
---|
| 3261 | ENDIF |
---|
[4141] | 3262 | |
---|
[4147] | 3263 | END SUBROUTINE init_file_variable |
---|
[4141] | 3264 | |
---|
| 3265 | !--------------------------------------------------------------------------------------------------! |
---|
| 3266 | ! Description: |
---|
| 3267 | ! ------------ |
---|
[4070] | 3268 | !> Write attribute to file. |
---|
| 3269 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 3270 | FUNCTION write_attribute( file_format, file_id, file_name, variable_id, variable_name, attribute )& |
---|
| 3271 | RESULT( return_value ) |
---|
[4070] | 3272 | |
---|
[4577] | 3273 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'write_attribute' !< file format chosen for file |
---|
| 3274 | |
---|
[4147] | 3275 | CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format chosen for file |
---|
| 3276 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< file name |
---|
| 3277 | CHARACTER(LEN=*), INTENT(IN) :: variable_name !< variable name |
---|
[4070] | 3278 | |
---|
[4147] | 3279 | INTEGER, INTENT(IN) :: file_id !< file ID |
---|
[4577] | 3280 | INTEGER :: output_return_value !< return value of a called output routine |
---|
[4147] | 3281 | INTEGER :: return_value !< return value |
---|
| 3282 | INTEGER, INTENT(IN) :: variable_id !< variable ID |
---|
[4070] | 3283 | |
---|
[4147] | 3284 | TYPE(attribute_type), INTENT(IN) :: attribute !< attribute to be written |
---|
[4070] | 3285 | |
---|
| 3286 | |
---|
[4147] | 3287 | return_value = 0 |
---|
| 3288 | output_return_value = 0 |
---|
| 3289 | ! |
---|
| 3290 | !-- Prepare for possible error message |
---|
[4577] | 3291 | temp_string = '(file "' // TRIM( file_name ) // & |
---|
| 3292 | '", variable "' // TRIM( variable_name ) // & |
---|
[4147] | 3293 | '", attribute "' // TRIM( attribute%name ) // '")' |
---|
| 3294 | ! |
---|
| 3295 | !-- Write attribute to file |
---|
| 3296 | SELECT CASE ( TRIM( file_format ) ) |
---|
[4106] | 3297 | |
---|
[4147] | 3298 | CASE ( 'binary' ) |
---|
[4106] | 3299 | |
---|
[4147] | 3300 | SELECT CASE ( TRIM( attribute%data_type ) ) |
---|
[4070] | 3301 | |
---|
[4147] | 3302 | CASE( 'char' ) |
---|
[4577] | 3303 | CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3304 | attribute_name=attribute%name, value_char=attribute%value_char, & |
---|
[4147] | 3305 | return_value=output_return_value ) |
---|
[4070] | 3306 | |
---|
[4147] | 3307 | CASE( 'int8' ) |
---|
[4577] | 3308 | CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3309 | attribute_name=attribute%name, value_int8=attribute%value_int8, & |
---|
[4147] | 3310 | return_value=output_return_value ) |
---|
[4070] | 3311 | |
---|
[4147] | 3312 | CASE( 'int16' ) |
---|
[4577] | 3313 | CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3314 | attribute_name=attribute%name, value_int16=attribute%value_int16, & |
---|
[4147] | 3315 | return_value=output_return_value ) |
---|
[4070] | 3316 | |
---|
[4147] | 3317 | CASE( 'int32' ) |
---|
[4577] | 3318 | CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3319 | attribute_name=attribute%name, value_int32=attribute%value_int32, & |
---|
[4147] | 3320 | return_value=output_return_value ) |
---|
[4070] | 3321 | |
---|
[4147] | 3322 | CASE( 'real32' ) |
---|
[4577] | 3323 | CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3324 | attribute_name=attribute%name, value_real32=attribute%value_real32, & |
---|
[4147] | 3325 | return_value=output_return_value ) |
---|
[4070] | 3326 | |
---|
[4147] | 3327 | CASE( 'real64' ) |
---|
[4577] | 3328 | CALL binary_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3329 | attribute_name=attribute%name, value_real64=attribute%value_real64, & |
---|
[4147] | 3330 | return_value=output_return_value ) |
---|
[4070] | 3331 | |
---|
[4147] | 3332 | CASE DEFAULT |
---|
| 3333 | return_value = 1 |
---|
[4577] | 3334 | CALL internal_message( 'error', routine_name // & |
---|
| 3335 | ': file format "' // TRIM( file_format ) // & |
---|
| 3336 | '" does not support attribute data type "'// & |
---|
| 3337 | TRIM( attribute%data_type ) // & |
---|
[4147] | 3338 | '" ' // TRIM( temp_string ) ) |
---|
[4070] | 3339 | |
---|
[4147] | 3340 | END SELECT |
---|
[4070] | 3341 | |
---|
[4147] | 3342 | CASE ( 'netcdf4-parallel', 'netcdf4-serial' ) |
---|
[4070] | 3343 | |
---|
[4147] | 3344 | SELECT CASE ( TRIM( attribute%data_type ) ) |
---|
[4070] | 3345 | |
---|
[4147] | 3346 | CASE( 'char' ) |
---|
[4577] | 3347 | CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3348 | attribute_name=attribute%name, value_char=attribute%value_char, & |
---|
[4147] | 3349 | return_value=output_return_value ) |
---|
[4070] | 3350 | |
---|
[4147] | 3351 | CASE( 'int8' ) |
---|
[4577] | 3352 | CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3353 | attribute_name=attribute%name, value_int8=attribute%value_int8, & |
---|
[4147] | 3354 | return_value=output_return_value ) |
---|
[4070] | 3355 | |
---|
[4147] | 3356 | CASE( 'int16' ) |
---|
[4577] | 3357 | CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3358 | attribute_name=attribute%name, value_int16=attribute%value_int16, & |
---|
[4147] | 3359 | return_value=output_return_value ) |
---|
[4070] | 3360 | |
---|
[4147] | 3361 | CASE( 'int32' ) |
---|
[4577] | 3362 | CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3363 | attribute_name=attribute%name, value_int32=attribute%value_int32, & |
---|
[4147] | 3364 | return_value=output_return_value ) |
---|
[4070] | 3365 | |
---|
[4147] | 3366 | CASE( 'real32' ) |
---|
[4577] | 3367 | CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3368 | attribute_name=attribute%name, value_real32=attribute%value_real32, & |
---|
[4147] | 3369 | return_value=output_return_value ) |
---|
[4070] | 3370 | |
---|
[4147] | 3371 | CASE( 'real64' ) |
---|
[4577] | 3372 | CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id, & |
---|
| 3373 | attribute_name=attribute%name, value_real64=attribute%value_real64, & |
---|
[4147] | 3374 | return_value=output_return_value ) |
---|
[4070] | 3375 | |
---|
[4147] | 3376 | CASE DEFAULT |
---|
| 3377 | return_value = 1 |
---|
[4577] | 3378 | CALL internal_message( 'error', routine_name // & |
---|
| 3379 | ': file format "' // TRIM( file_format ) // & |
---|
| 3380 | '" does not support attribute data type "'// & |
---|
| 3381 | TRIM( attribute%data_type ) // & |
---|
[4147] | 3382 | '" ' // TRIM( temp_string ) ) |
---|
[4070] | 3383 | |
---|
[4147] | 3384 | END SELECT |
---|
[4070] | 3385 | |
---|
[4147] | 3386 | CASE DEFAULT |
---|
| 3387 | return_value = 1 |
---|
[4577] | 3388 | CALL internal_message( 'error', routine_name // & |
---|
| 3389 | ': unsupported file format "' // TRIM( file_format ) // & |
---|
[4147] | 3390 | '" ' // TRIM( temp_string ) ) |
---|
[4070] | 3391 | |
---|
[4147] | 3392 | END SELECT |
---|
[4070] | 3393 | |
---|
[4147] | 3394 | IF ( output_return_value /= 0 ) THEN |
---|
| 3395 | return_value = output_return_value |
---|
[4577] | 3396 | CALL internal_message( 'error', routine_name // & |
---|
[4147] | 3397 | ': error while writing attribute ' // TRIM( temp_string ) ) |
---|
| 3398 | ENDIF |
---|
[4070] | 3399 | |
---|
[4147] | 3400 | END FUNCTION write_attribute |
---|
[4113] | 3401 | |
---|
[4070] | 3402 | !--------------------------------------------------------------------------------------------------! |
---|
| 3403 | ! Description: |
---|
| 3404 | ! ------------ |
---|
[4141] | 3405 | !> Get dimension IDs and save them to variables. |
---|
[4070] | 3406 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3407 | SUBROUTINE collect_dimesion_ids_for_variables( file_name, variables, dimensions, return_value ) |
---|
[4070] | 3408 | |
---|
[4577] | 3409 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'collect_dimesion_ids_for_variables' !< file format chosen for file |
---|
| 3410 | |
---|
[4147] | 3411 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
[4070] | 3412 | |
---|
[4147] | 3413 | INTEGER :: d !< loop index |
---|
| 3414 | INTEGER :: i !< loop index |
---|
| 3415 | INTEGER :: j !< loop index |
---|
| 3416 | INTEGER :: ndims !< number of dimensions |
---|
| 3417 | INTEGER :: nvars !< number of variables |
---|
| 3418 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
[4070] | 3419 | |
---|
[4577] | 3420 | LOGICAL :: found = .FALSE. !< true if dimension required by variable was found in dimension list |
---|
[4070] | 3421 | |
---|
[4147] | 3422 | TYPE(dimension_type), DIMENSION(:), INTENT(IN) :: dimensions !< list of dimensions in file |
---|
[4070] | 3423 | |
---|
[4147] | 3424 | TYPE(variable_type), DIMENSION(:), INTENT(INOUT) :: variables !< list of variables in file |
---|
[4070] | 3425 | |
---|
| 3426 | |
---|
[4147] | 3427 | return_value = 0 |
---|
| 3428 | ndims = SIZE( dimensions ) |
---|
| 3429 | nvars = SIZE( variables ) |
---|
[4070] | 3430 | |
---|
[4147] | 3431 | DO i = 1, nvars |
---|
| 3432 | DO j = 1, SIZE( variables(i)%dimension_names ) |
---|
| 3433 | found = .FALSE. |
---|
| 3434 | DO d = 1, ndims |
---|
| 3435 | IF ( variables(i)%dimension_names(j) == dimensions(d)%name ) THEN |
---|
| 3436 | variables(i)%dimension_ids(j) = dimensions(d)%id |
---|
| 3437 | found = .TRUE. |
---|
| 3438 | EXIT |
---|
| 3439 | ENDIF |
---|
| 3440 | ENDDO |
---|
| 3441 | IF ( .NOT. found ) THEN |
---|
| 3442 | return_value = 1 |
---|
[4577] | 3443 | CALL internal_message( 'error', routine_name // & |
---|
| 3444 | ': required dimension "' // TRIM( variables(i)%dimension_names(j) ) // & |
---|
| 3445 | '" is undefined (variable "' // TRIM( variables(i)%name ) // & |
---|
[4147] | 3446 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 3447 | EXIT |
---|
| 3448 | ENDIF |
---|
| 3449 | ENDDO |
---|
| 3450 | IF ( .NOT. found ) EXIT |
---|
| 3451 | ENDDO |
---|
[4070] | 3452 | |
---|
[4147] | 3453 | END SUBROUTINE collect_dimesion_ids_for_variables |
---|
[4070] | 3454 | |
---|
| 3455 | !--------------------------------------------------------------------------------------------------! |
---|
| 3456 | ! Description: |
---|
| 3457 | ! ------------ |
---|
[4141] | 3458 | !> Leave file definition/initialization. |
---|
[4070] | 3459 | !> |
---|
| 3460 | !> @todo Do we need an MPI barrier at the end? |
---|
| 3461 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3462 | SUBROUTINE stop_file_header_definition( file_format, file_id, file_name, return_value ) |
---|
[4070] | 3463 | |
---|
[4577] | 3464 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'stop_file_header_definition' !< name of routine |
---|
| 3465 | |
---|
[4147] | 3466 | CHARACTER(LEN=*), INTENT(IN) :: file_format !< file format |
---|
| 3467 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< file name |
---|
[4070] | 3468 | |
---|
[4147] | 3469 | INTEGER, INTENT(IN) :: file_id !< file id |
---|
| 3470 | INTEGER :: output_return_value !< return value of a called output routine |
---|
| 3471 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
[4070] | 3472 | |
---|
| 3473 | |
---|
[4147] | 3474 | return_value = 0 |
---|
| 3475 | output_return_value = 0 |
---|
[4106] | 3476 | |
---|
[4147] | 3477 | temp_string = '(file "' // TRIM( file_name ) // '")' |
---|
[4106] | 3478 | |
---|
[4147] | 3479 | SELECT CASE ( TRIM( file_format ) ) |
---|
[4070] | 3480 | |
---|
[4147] | 3481 | CASE ( 'binary' ) |
---|
| 3482 | CALL binary_stop_file_header_definition( file_id, output_return_value ) |
---|
[4070] | 3483 | |
---|
[4147] | 3484 | CASE ( 'netcdf4-parallel', 'netcdf4-serial' ) |
---|
| 3485 | CALL netcdf4_stop_file_header_definition( file_id, output_return_value ) |
---|
[4070] | 3486 | |
---|
[4147] | 3487 | CASE DEFAULT |
---|
| 3488 | return_value = 1 |
---|
[4577] | 3489 | CALL internal_message( 'error', routine_name // & |
---|
| 3490 | ': file format "' // TRIM( file_format ) // & |
---|
[4147] | 3491 | '" not supported ' // TRIM( temp_string ) ) |
---|
[4070] | 3492 | |
---|
[4147] | 3493 | END SELECT |
---|
[4070] | 3494 | |
---|
[4147] | 3495 | IF ( output_return_value /= 0 ) THEN |
---|
| 3496 | return_value = output_return_value |
---|
[4577] | 3497 | CALL internal_message( 'error', routine_name // & |
---|
| 3498 | ': error while leaving file-definition state ' // & |
---|
[4147] | 3499 | TRIM( temp_string ) ) |
---|
| 3500 | ENDIF |
---|
[4106] | 3501 | |
---|
[4147] | 3502 | ! CALL MPI_Barrier( MPI_COMM_WORLD, return_value ) |
---|
[4070] | 3503 | |
---|
[4147] | 3504 | END SUBROUTINE stop_file_header_definition |
---|
[4070] | 3505 | |
---|
| 3506 | !--------------------------------------------------------------------------------------------------! |
---|
| 3507 | ! Description: |
---|
| 3508 | ! ------------ |
---|
[4141] | 3509 | !> Find a requested variable 'variable_name' and its used dimensions in requested file 'file_name'. |
---|
[4070] | 3510 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 3511 | SUBROUTINE find_var_in_file( file_name, variable_name, file_format, file_id, variable_id, & |
---|
[4147] | 3512 | is_global, dimensions, return_value ) |
---|
[4070] | 3513 | |
---|
[4577] | 3514 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'find_var_in_file' !< name of routine |
---|
| 3515 | |
---|
[4147] | 3516 | CHARACTER(LEN=charlen), INTENT(OUT) :: file_format !< file format chosen for file |
---|
| 3517 | CHARACTER(LEN=*), INTENT(IN) :: file_name !< name of file |
---|
| 3518 | CHARACTER(LEN=*), INTENT(IN) :: variable_name !< name of variable |
---|
[4070] | 3519 | |
---|
[4147] | 3520 | INTEGER :: d !< loop index |
---|
| 3521 | INTEGER :: dd !< loop index |
---|
| 3522 | INTEGER :: f !< loop index |
---|
| 3523 | INTEGER, INTENT(OUT) :: file_id !< file ID |
---|
| 3524 | INTEGER, INTENT(OUT) :: return_value !< return value |
---|
| 3525 | INTEGER, INTENT(OUT) :: variable_id !< variable ID |
---|
[4070] | 3526 | |
---|
[4147] | 3527 | INTEGER, DIMENSION(:), ALLOCATABLE :: dimension_ids !< list of dimension IDs used by variable |
---|
[4070] | 3528 | |
---|
[4147] | 3529 | LOGICAL :: found !< true if requested variable found in requested file |
---|
| 3530 | LOGICAL, INTENT(OUT) :: is_global !< true if variable is global |
---|
[4070] | 3531 | |
---|
[4147] | 3532 | TYPE(dimension_type), DIMENSION(:), ALLOCATABLE, INTENT(OUT) :: dimensions !< list of dimensions used by variable |
---|
[4070] | 3533 | |
---|
| 3534 | |
---|
[4147] | 3535 | return_value = 0 |
---|
| 3536 | found = .FALSE. |
---|
[4070] | 3537 | |
---|
[4147] | 3538 | DO f = 1, nfiles |
---|
| 3539 | IF ( TRIM( file_name ) == TRIM( files(f)%name ) ) THEN |
---|
[4113] | 3540 | |
---|
[4147] | 3541 | IF ( .NOT. files(f)%is_init ) THEN |
---|
| 3542 | return_value = 1 |
---|
[4577] | 3543 | CALL internal_message( 'error', routine_name // & |
---|
| 3544 | ': file not initialized. ' // & |
---|
| 3545 | 'Writing variable to file is impossible ' // & |
---|
| 3546 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 3547 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 3548 | EXIT |
---|
| 3549 | ENDIF |
---|
[4113] | 3550 | |
---|
[4147] | 3551 | file_id = files(f)%id |
---|
| 3552 | file_format = files(f)%format |
---|
| 3553 | ! |
---|
| 3554 | !-- Search for variable in file |
---|
| 3555 | DO d = 1, SIZE( files(f)%variables ) |
---|
| 3556 | IF ( TRIM( variable_name ) == TRIM( files(f)%variables(d)%name ) ) THEN |
---|
[4070] | 3557 | |
---|
[4147] | 3558 | variable_id = files(f)%variables(d)%id |
---|
| 3559 | is_global = files(f)%variables(d)%is_global |
---|
[4070] | 3560 | |
---|
[4147] | 3561 | ALLOCATE( dimension_ids(SIZE( files(f)%variables(d)%dimension_ids )) ) |
---|
| 3562 | ALLOCATE( dimensions(SIZE( files(f)%variables(d)%dimension_ids )) ) |
---|
[4070] | 3563 | |
---|
[4147] | 3564 | dimension_ids = files(f)%variables(d)%dimension_ids |
---|
[4070] | 3565 | |
---|
[4147] | 3566 | found = .TRUE. |
---|
| 3567 | EXIT |
---|
[4070] | 3568 | |
---|
[4147] | 3569 | ENDIF |
---|
| 3570 | ENDDO |
---|
[4070] | 3571 | |
---|
[4147] | 3572 | IF ( found ) THEN |
---|
| 3573 | ! |
---|
| 3574 | !-- Get list of dimensions used by variable |
---|
| 3575 | DO d = 1, SIZE( files(f)%dimensions ) |
---|
| 3576 | DO dd = 1, SIZE( dimension_ids ) |
---|
| 3577 | IF ( dimension_ids(dd) == files(f)%dimensions(d)%id ) THEN |
---|
| 3578 | dimensions(dd) = files(f)%dimensions(d) |
---|
| 3579 | EXIT |
---|
| 3580 | ENDIF |
---|
| 3581 | ENDDO |
---|
| 3582 | ENDDO |
---|
[4070] | 3583 | |
---|
[4147] | 3584 | ELSE |
---|
| 3585 | ! |
---|
| 3586 | !-- If variable was not found, search for a dimension instead |
---|
| 3587 | DO d = 1, SIZE( files(f)%dimensions ) |
---|
| 3588 | IF ( TRIM( variable_name ) == TRIM( files(f)%dimensions(d)%name ) ) THEN |
---|
[4070] | 3589 | |
---|
[4147] | 3590 | variable_id = files(f)%dimensions(d)%variable_id |
---|
| 3591 | is_global = .TRUE. |
---|
[4070] | 3592 | |
---|
[4147] | 3593 | ALLOCATE( dimensions(1) ) |
---|
[4070] | 3594 | |
---|
[4147] | 3595 | dimensions(1) = files(f)%dimensions(d) |
---|
[4070] | 3596 | |
---|
[4147] | 3597 | found = .TRUE. |
---|
| 3598 | EXIT |
---|
[4070] | 3599 | |
---|
[4147] | 3600 | ENDIF |
---|
| 3601 | ENDDO |
---|
[4070] | 3602 | |
---|
[4147] | 3603 | ENDIF |
---|
| 3604 | ! |
---|
| 3605 | !-- If variable was not found in requested file, return an error |
---|
| 3606 | IF ( .NOT. found ) THEN |
---|
| 3607 | return_value = 1 |
---|
[4577] | 3608 | CALL internal_message( 'error', routine_name // & |
---|
| 3609 | ': variable not found in file ' // & |
---|
| 3610 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 3611 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 3612 | ENDIF |
---|
[4070] | 3613 | |
---|
[4147] | 3614 | EXIT |
---|
[4070] | 3615 | |
---|
[4147] | 3616 | ENDIF ! file found |
---|
| 3617 | ENDDO ! loop over files |
---|
[4070] | 3618 | |
---|
[4147] | 3619 | IF ( .NOT. found .AND. return_value == 0 ) THEN |
---|
| 3620 | return_value = 1 |
---|
[4577] | 3621 | CALL internal_message( 'error', routine_name // & |
---|
| 3622 | ': file not found ' // & |
---|
| 3623 | '(variable "' // TRIM( variable_name ) // & |
---|
[4147] | 3624 | '", file "' // TRIM( file_name ) // '")!' ) |
---|
| 3625 | ENDIF |
---|
[4070] | 3626 | |
---|
[4147] | 3627 | END SUBROUTINE find_var_in_file |
---|
[4070] | 3628 | |
---|
| 3629 | !--------------------------------------------------------------------------------------------------! |
---|
| 3630 | ! Description: |
---|
| 3631 | ! ------------ |
---|
| 3632 | !> Search for masked indices of dimensions within the given bounds ('bounds_start' and |
---|
[4123] | 3633 | !> 'bounds_end'). Return the masked indices ('masked_indices') of the dimensions, the first index |
---|
| 3634 | !> of the masked dimensions containing these indices ('bounds_masked_start'), the count of masked |
---|
| 3635 | !> indices within given bounds ('value_counts') and the origin index of each dimension |
---|
| 3636 | !> ('bounds_origin'). If, for any dimension, no masked index lies within the given bounds, counts, |
---|
| 3637 | !> starts and origins are set to zero for all dimensions. |
---|
[4070] | 3638 | !--------------------------------------------------------------------------------------------------! |
---|
[4577] | 3639 | SUBROUTINE get_masked_indices_and_masked_dimension_bounds( & |
---|
| 3640 | dimensions, bounds_start, bounds_end, bounds_masked_start, value_counts, & |
---|
[4147] | 3641 | bounds_origin, masked_indices ) |
---|
[4070] | 3642 | |
---|
[4147] | 3643 | ! CHARACTER(LEN=*), PARAMETER :: routine_name = 'get_masked_indices_and_masked_dimension_bounds' !< name of routine |
---|
[4070] | 3644 | |
---|
[4147] | 3645 | INTEGER :: d !< loop index |
---|
| 3646 | INTEGER :: i !< loop index |
---|
[4070] | 3647 | |
---|
[4147] | 3648 | INTEGER, DIMENSION(:), INTENT(IN) :: bounds_end !< upper bonuds to be searched in |
---|
| 3649 | INTEGER, DIMENSION(:), INTENT(OUT) :: bounds_masked_start !< lower bounds of masked dimensions within given bounds |
---|
| 3650 | INTEGER, DIMENSION(:), INTENT(OUT) :: bounds_origin !< first index of each dimension, 0 if dimension is masked |
---|
| 3651 | INTEGER, DIMENSION(:), INTENT(IN) :: bounds_start !< lower bounds to be searched in |
---|
| 3652 | INTEGER, DIMENSION(:), INTENT(OUT) :: value_counts !< count of indices per dimension to be output |
---|
[4070] | 3653 | |
---|
[4147] | 3654 | INTEGER, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: masked_indices !< masked indices within given bounds |
---|
[4070] | 3655 | |
---|
[4147] | 3656 | TYPE(dimension_type), DIMENSION(:), INTENT(IN) :: dimensions !< dimensions to be searched for masked indices |
---|
[4070] | 3657 | |
---|
| 3658 | |
---|
[4147] | 3659 | ALLOCATE( masked_indices(SIZE( dimensions ),0:MAXVAL( bounds_end - bounds_start + 1 )) ) |
---|
| 3660 | masked_indices = -HUGE( 0 ) |
---|
| 3661 | ! |
---|
| 3662 | !-- Check for masking and update lower and upper bounds if masked |
---|
| 3663 | DO d = 1, SIZE( dimensions ) |
---|
[4070] | 3664 | |
---|
[4147] | 3665 | IF ( dimensions(d)%is_masked ) THEN |
---|
[4070] | 3666 | |
---|
[4147] | 3667 | bounds_origin(d) = 0 |
---|
[4070] | 3668 | |
---|
[4147] | 3669 | bounds_masked_start(d) = -HUGE( 0 ) |
---|
| 3670 | ! |
---|
| 3671 | !-- Find number of masked values within given variable bounds |
---|
| 3672 | value_counts(d) = 0 |
---|
[4577] | 3673 | DO i = LBOUND( dimensions(d)%masked_indices, DIM=1 ), & |
---|
[4147] | 3674 | UBOUND( dimensions(d)%masked_indices, DIM=1 ) |
---|
| 3675 | ! |
---|
| 3676 | !-- Is masked index within given bounds? |
---|
[4577] | 3677 | IF ( dimensions(d)%masked_indices(i) >= bounds_start(d) .AND. & |
---|
[4147] | 3678 | dimensions(d)%masked_indices(i) <= bounds_end(d) ) THEN |
---|
| 3679 | ! |
---|
| 3680 | !-- Save masked index |
---|
| 3681 | masked_indices(d,value_counts(d)) = dimensions(d)%masked_indices(i) |
---|
| 3682 | value_counts(d) = value_counts(d) + 1 |
---|
| 3683 | ! |
---|
| 3684 | !-- Save bounds of mask within given bounds |
---|
| 3685 | IF ( bounds_masked_start(d) == -HUGE( 0 ) ) bounds_masked_start(d) = i |
---|
[4123] | 3686 | |
---|
[4147] | 3687 | ENDIF |
---|
[4070] | 3688 | |
---|
[4147] | 3689 | ENDDO |
---|
| 3690 | ! |
---|
| 3691 | !-- Set masked bounds to zero if no masked index lies within bounds |
---|
| 3692 | IF ( value_counts(d) == 0 ) THEN |
---|
| 3693 | bounds_origin(:) = 0 |
---|
| 3694 | bounds_masked_start(:) = 0 |
---|
| 3695 | value_counts(:) = 0 |
---|
| 3696 | EXIT |
---|
| 3697 | ENDIF |
---|
[4070] | 3698 | |
---|
[4147] | 3699 | ELSE |
---|
| 3700 | ! |
---|
| 3701 | !-- If dimension is not masked, save all indices within bounds for output |
---|
| 3702 | bounds_origin(d) = dimensions(d)%bounds(1) |
---|
| 3703 | bounds_masked_start(d) = bounds_start(d) |
---|
| 3704 | value_counts(d) = bounds_end(d) - bounds_start(d) + 1 |
---|
[4070] | 3705 | |
---|
[4147] | 3706 | DO i = 0, value_counts(d) - 1 |
---|
| 3707 | masked_indices(d,i) = bounds_start(d) + i |
---|
| 3708 | ENDDO |
---|
[4070] | 3709 | |
---|
[4147] | 3710 | ENDIF |
---|
[4070] | 3711 | |
---|
[4147] | 3712 | ENDDO |
---|
[4070] | 3713 | |
---|
[4147] | 3714 | END SUBROUTINE get_masked_indices_and_masked_dimension_bounds |
---|
[4070] | 3715 | |
---|
| 3716 | !--------------------------------------------------------------------------------------------------! |
---|
| 3717 | ! Description: |
---|
| 3718 | ! ------------ |
---|
[4577] | 3719 | !> Message routine writing debug information into the debug file or creating the error message |
---|
| 3720 | !> string. |
---|
[4070] | 3721 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3722 | SUBROUTINE internal_message( level, string ) |
---|
[4070] | 3723 | |
---|
[4147] | 3724 | CHARACTER(LEN=*), INTENT(IN) :: level !< message importance level |
---|
| 3725 | CHARACTER(LEN=*), INTENT(IN) :: string !< message string |
---|
[4070] | 3726 | |
---|
| 3727 | |
---|
[4147] | 3728 | IF ( TRIM( level ) == 'error' ) THEN |
---|
[4070] | 3729 | |
---|
[4147] | 3730 | WRITE( internal_error_message, '(A,A)' ) 'DOM ERROR: ', string |
---|
[4070] | 3731 | |
---|
[4147] | 3732 | ELSEIF ( TRIM( level ) == 'debug' .AND. print_debug_output ) THEN |
---|
[4070] | 3733 | |
---|
[4147] | 3734 | WRITE( debug_output_unit, '(A,A)' ) 'DOM DEBUG: ', string |
---|
| 3735 | FLUSH( debug_output_unit ) |
---|
[4070] | 3736 | |
---|
[4147] | 3737 | ENDIF |
---|
[4070] | 3738 | |
---|
[4147] | 3739 | END SUBROUTINE internal_message |
---|
[4070] | 3740 | |
---|
[4141] | 3741 | !--------------------------------------------------------------------------------------------------! |
---|
| 3742 | ! Description: |
---|
| 3743 | ! ------------ |
---|
| 3744 | !> Print contents of the created database to debug_output_unit. This routine can be called at any |
---|
| 3745 | !> stage after the call to 'dom_init'. Multiple calls are possible. |
---|
| 3746 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3747 | SUBROUTINE dom_database_debug_output |
---|
[4070] | 3748 | |
---|
[4147] | 3749 | CHARACTER(LEN=*), PARAMETER :: separation_string = '---' !< string separating blocks in output |
---|
| 3750 | CHARACTER(LEN=*), PARAMETER :: routine_name = 'dom_database_debug_output' !< name of this routine |
---|
[4070] | 3751 | |
---|
[4577] | 3752 | INTEGER, PARAMETER :: indent_depth = 3 !< space per indentation |
---|
| 3753 | INTEGER, PARAMETER :: max_keyname_length = 6 !< length of longest key name |
---|
| 3754 | |
---|
| 3755 | CHARACTER(LEN=50) :: write_format1 !< format for write statements |
---|
| 3756 | |
---|
[4147] | 3757 | INTEGER :: f !< loop index |
---|
| 3758 | INTEGER :: indent_level !< indentation level |
---|
| 3759 | INTEGER :: natts !< number of attributes |
---|
| 3760 | INTEGER :: ndims !< number of dimensions |
---|
| 3761 | INTEGER :: nvars !< number of variables |
---|
[4070] | 3762 | |
---|
| 3763 | |
---|
[4147] | 3764 | CALL internal_message( 'debug', routine_name // ': write database to debug output' ) |
---|
[4070] | 3765 | |
---|
[4147] | 3766 | WRITE( debug_output_unit, '(A)' ) 'DOM database:' |
---|
| 3767 | WRITE( debug_output_unit, '(A)' ) REPEAT( separation_string // ' ', 4 ) |
---|
[4106] | 3768 | |
---|
[4577] | 3769 | IF ( .NOT. ALLOCATED( files ) .OR. nfiles == 0 ) THEN |
---|
[4070] | 3770 | |
---|
[4147] | 3771 | WRITE( debug_output_unit, '(A)' ) 'database is empty' |
---|
[4070] | 3772 | |
---|
[4147] | 3773 | ELSE |
---|
[4070] | 3774 | |
---|
[4147] | 3775 | indent_level = 1 |
---|
[4577] | 3776 | WRITE( write_format1, '(A,I3,A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A,T', & |
---|
| 3777 | indent_level * indent_depth + 1 + max_keyname_length, & |
---|
| 3778 | ',(": ")' |
---|
[4070] | 3779 | |
---|
[4147] | 3780 | DO f = 1, nfiles |
---|
[4070] | 3781 | |
---|
[4147] | 3782 | natts = 0 |
---|
| 3783 | ndims = 0 |
---|
| 3784 | nvars = 0 |
---|
| 3785 | IF ( ALLOCATED( files(f)%attributes ) ) natts = SIZE( files(f)%attributes ) |
---|
| 3786 | IF ( ALLOCATED( files(f)%dimensions ) ) ndims = SIZE( files(f)%dimensions ) |
---|
| 3787 | IF ( ALLOCATED( files(f)%variables ) ) nvars = SIZE( files(f)%variables ) |
---|
[4070] | 3788 | |
---|
[4147] | 3789 | WRITE( debug_output_unit, '(A)' ) 'file:' |
---|
| 3790 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',A)' ) 'name', TRIM( files(f)%name ) |
---|
| 3791 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',A)' ) 'format', TRIM(files(f)%format) |
---|
| 3792 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',I7)' ) 'id', files(f)%id |
---|
| 3793 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',L1)' ) 'is init', files(f)%is_init |
---|
| 3794 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',I7)' ) '#atts', natts |
---|
| 3795 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',I7)' ) '#dims', ndims |
---|
| 3796 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',I7)' ) '#vars', nvars |
---|
[4070] | 3797 | |
---|
[4147] | 3798 | IF ( natts /= 0 ) CALL print_attributes( indent_level, files(f)%attributes ) |
---|
| 3799 | IF ( ndims /= 0 ) CALL print_dimensions( indent_level, files(f)%dimensions ) |
---|
| 3800 | IF ( nvars /= 0 ) CALL print_variables( indent_level, files(f)%variables ) |
---|
[4070] | 3801 | |
---|
[4147] | 3802 | WRITE( debug_output_unit, '(/A/)' ) REPEAT( separation_string // ' ', 4 ) |
---|
[4070] | 3803 | |
---|
[4147] | 3804 | ENDDO |
---|
[4141] | 3805 | |
---|
[4147] | 3806 | ENDIF |
---|
[4070] | 3807 | |
---|
[4147] | 3808 | CONTAINS |
---|
[4070] | 3809 | |
---|
[4577] | 3810 | !--------------------------------------------------------------------------------------------------! |
---|
| 3811 | ! Description: |
---|
| 3812 | ! ------------ |
---|
| 3813 | !> Print list of attributes. |
---|
| 3814 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3815 | SUBROUTINE print_attributes( indent_level, attributes ) |
---|
[4070] | 3816 | |
---|
[4577] | 3817 | INTEGER, PARAMETER :: max_keyname_length = 6 !< length of longest key name |
---|
| 3818 | |
---|
[4147] | 3819 | CHARACTER(LEN=50) :: write_format1 !< format for write statements |
---|
| 3820 | CHARACTER(LEN=50) :: write_format2 !< format for write statements |
---|
[4070] | 3821 | |
---|
[4147] | 3822 | INTEGER :: i !< loop index |
---|
| 3823 | INTEGER, INTENT(IN) :: indent_level !< indentation level |
---|
| 3824 | INTEGER :: nelement !< number of elements to print |
---|
[4070] | 3825 | |
---|
[4147] | 3826 | TYPE(attribute_type), DIMENSION(:), INTENT(IN) :: attributes !< list of attributes |
---|
[4070] | 3827 | |
---|
| 3828 | |
---|
[4147] | 3829 | WRITE( write_format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A' |
---|
[4577] | 3830 | WRITE( write_format2, '(A,I3,A,I3,A)' ) & |
---|
| 3831 | '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', & |
---|
[4147] | 3832 | ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")' |
---|
[4070] | 3833 | |
---|
[4577] | 3834 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',A)' ) & |
---|
[4147] | 3835 | REPEAT( separation_string // ' ', 4 ) |
---|
| 3836 | WRITE( debug_output_unit, TRIM( write_format1 ) // ')' ) 'attributes:' |
---|
[4070] | 3837 | |
---|
[4147] | 3838 | nelement = SIZE( attributes ) |
---|
| 3839 | DO i = 1, nelement |
---|
[4577] | 3840 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 3841 | 'name', TRIM( attributes(i)%name ) |
---|
[4577] | 3842 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 3843 | 'type', TRIM( attributes(i)%data_type ) |
---|
[4141] | 3844 | |
---|
[4147] | 3845 | IF ( TRIM( attributes(i)%data_type ) == 'char' ) THEN |
---|
[4577] | 3846 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 3847 | 'value', TRIM( attributes(i)%value_char ) |
---|
| 3848 | ELSEIF ( TRIM( attributes(i)%data_type ) == 'int8' ) THEN |
---|
[4577] | 3849 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I4)' ) & |
---|
[4147] | 3850 | 'value', attributes(i)%value_int8 |
---|
| 3851 | ELSEIF ( TRIM( attributes(i)%data_type ) == 'int16' ) THEN |
---|
[4577] | 3852 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I6)' ) & |
---|
[4147] | 3853 | 'value', attributes(i)%value_int16 |
---|
| 3854 | ELSEIF ( TRIM( attributes(i)%data_type ) == 'int32' ) THEN |
---|
[4577] | 3855 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I11)' ) & |
---|
[4147] | 3856 | 'value', attributes(i)%value_int32 |
---|
| 3857 | ELSEIF ( TRIM( attributes(i)%data_type ) == 'real32' ) THEN |
---|
[4577] | 3858 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E14.7)' ) & |
---|
[4147] | 3859 | 'value', attributes(i)%value_real32 |
---|
| 3860 | ELSEIF ( TRIM(attributes(i)%data_type) == 'real64' ) THEN |
---|
[4577] | 3861 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E22.15)' ) & |
---|
[4147] | 3862 | 'value', attributes(i)%value_real64 |
---|
| 3863 | ENDIF |
---|
[4577] | 3864 | IF ( i < nelement ) & |
---|
[4147] | 3865 | WRITE( debug_output_unit, TRIM( write_format1 ) // ')' ) separation_string |
---|
| 3866 | ENDDO |
---|
[4141] | 3867 | |
---|
[4147] | 3868 | END SUBROUTINE print_attributes |
---|
[4141] | 3869 | |
---|
[4577] | 3870 | !--------------------------------------------------------------------------------------------------! |
---|
| 3871 | ! Description: |
---|
| 3872 | ! ------------ |
---|
| 3873 | !> Print list of dimensions. |
---|
| 3874 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 3875 | SUBROUTINE print_dimensions( indent_level, dimensions ) |
---|
[4141] | 3876 | |
---|
[4577] | 3877 | INTEGER, PARAMETER :: max_keyname_length = 15 !< length of longest key name |
---|
| 3878 | |
---|
[4147] | 3879 | CHARACTER(LEN=50) :: write_format1 !< format for write statements |
---|
| 3880 | CHARACTER(LEN=50) :: write_format2 !< format for write statements |
---|
[4141] | 3881 | |
---|
[4147] | 3882 | INTEGER :: i !< loop index |
---|
| 3883 | INTEGER, INTENT(IN) :: indent_level !< indentation level |
---|
| 3884 | INTEGER :: j !< loop index |
---|
| 3885 | INTEGER :: nelement !< number of elements to print |
---|
[4141] | 3886 | |
---|
[4147] | 3887 | LOGICAL :: is_masked !< true if dimension is masked |
---|
[4141] | 3888 | |
---|
[4147] | 3889 | TYPE(dimension_type), DIMENSION(:), INTENT(IN) :: dimensions !< list of dimensions |
---|
[4141] | 3890 | |
---|
| 3891 | |
---|
[4147] | 3892 | WRITE( write_format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A' |
---|
[4577] | 3893 | WRITE( write_format2, '(A,I3,A,I3,A)' ) & |
---|
| 3894 | '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', & |
---|
[4147] | 3895 | ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")' |
---|
[4141] | 3896 | |
---|
[4577] | 3897 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',A)' ) & |
---|
[4147] | 3898 | REPEAT( separation_string // ' ', 4 ) |
---|
| 3899 | WRITE( debug_output_unit, TRIM( write_format1 ) // ')' ) 'dimensions:' |
---|
[4141] | 3900 | |
---|
[4147] | 3901 | nelement = SIZE( dimensions ) |
---|
| 3902 | DO i = 1, nelement |
---|
| 3903 | is_masked = dimensions(i)%is_masked |
---|
| 3904 | ! |
---|
| 3905 | !-- Print general information |
---|
[4577] | 3906 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 3907 | 'name', TRIM( dimensions(i)%name ) |
---|
[4577] | 3908 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 3909 | 'type', TRIM( dimensions(i)%data_type ) |
---|
[4577] | 3910 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)' ) & |
---|
[4147] | 3911 | 'id', dimensions(i)%id |
---|
[4577] | 3912 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)' ) & |
---|
[4147] | 3913 | 'length', dimensions(i)%length |
---|
[4577] | 3914 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7,A,I7)' ) & |
---|
[4147] | 3915 | 'bounds', dimensions(i)%bounds(1), ',', dimensions(i)%bounds(2) |
---|
[4577] | 3916 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',L1)' ) & |
---|
[4147] | 3917 | 'is masked', dimensions(i)%is_masked |
---|
| 3918 | ! |
---|
| 3919 | !-- Print information about mask |
---|
| 3920 | IF ( is_masked ) THEN |
---|
[4577] | 3921 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)' ) & |
---|
[4147] | 3922 | 'masked length', dimensions(i)%length_mask |
---|
[4141] | 3923 | |
---|
[4577] | 3924 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',L1)', ADVANCE='no' ) & |
---|
[4147] | 3925 | 'mask', dimensions(i)%mask(dimensions(i)%bounds(1)) |
---|
| 3926 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
| 3927 | WRITE( debug_output_unit, '(A,L1)', ADVANCE='no' ) ',', dimensions(i)%mask(j) |
---|
| 3928 | ENDDO |
---|
| 3929 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
[4141] | 3930 | |
---|
[4577] | 3931 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I6)', ADVANCE='no' ) & |
---|
[4147] | 3932 | 'masked indices', dimensions(i)%masked_indices(0) |
---|
| 3933 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 3934 | WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) & |
---|
[4147] | 3935 | ',', dimensions(i)%masked_indices(j) |
---|
| 3936 | ENDDO |
---|
| 3937 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3938 | ENDIF |
---|
| 3939 | ! |
---|
| 3940 | !-- Print saved values |
---|
| 3941 | IF ( ALLOCATED( dimensions(i)%values_int8 ) ) THEN |
---|
[4141] | 3942 | |
---|
[4577] | 3943 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I4)', ADVANCE='no' ) & |
---|
[4147] | 3944 | 'values', dimensions(i)%values_int8(dimensions(i)%bounds(1)) |
---|
| 3945 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 3946 | WRITE( debug_output_unit, '(A,I4)', ADVANCE='no' ) & |
---|
[4147] | 3947 | ',', dimensions(i)%values_int8(j) |
---|
| 3948 | ENDDO |
---|
| 3949 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3950 | IF ( is_masked ) THEN |
---|
[4577] | 3951 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I4)', ADVANCE='no' ) & |
---|
[4147] | 3952 | 'masked values', dimensions(i)%masked_values_int8(0) |
---|
| 3953 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 3954 | WRITE( debug_output_unit, '(A,I4)', ADVANCE='no' ) & |
---|
[4147] | 3955 | ',', dimensions(i)%masked_values_int8(j) |
---|
| 3956 | ENDDO |
---|
| 3957 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3958 | ENDIF |
---|
[4141] | 3959 | |
---|
[4147] | 3960 | ELSEIF ( ALLOCATED( dimensions(i)%values_int16 ) ) THEN |
---|
[4141] | 3961 | |
---|
[4577] | 3962 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I6)', ADVANCE='no' ) & |
---|
[4147] | 3963 | 'values', dimensions(i)%values_int16(dimensions(i)%bounds(1)) |
---|
| 3964 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 3965 | WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) & |
---|
[4147] | 3966 | ',', dimensions(i)%values_int16(j) |
---|
| 3967 | ENDDO |
---|
| 3968 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3969 | IF ( is_masked ) THEN |
---|
[4577] | 3970 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I6)', ADVANCE='no' ) & |
---|
[4147] | 3971 | 'masked values', dimensions(i)%masked_values_int16(0) |
---|
| 3972 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 3973 | WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) & |
---|
[4147] | 3974 | ',', dimensions(i)%masked_values_int16(j) |
---|
| 3975 | ENDDO |
---|
| 3976 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3977 | ENDIF |
---|
[4141] | 3978 | |
---|
[4147] | 3979 | ELSEIF ( ALLOCATED( dimensions(i)%values_int32 ) ) THEN |
---|
[4141] | 3980 | |
---|
[4577] | 3981 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I11)', ADVANCE='no' ) & |
---|
[4147] | 3982 | 'values', dimensions(i)%values_int32(dimensions(i)%bounds(1)) |
---|
| 3983 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 3984 | WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) & |
---|
[4147] | 3985 | ',', dimensions(i)%values_int32(j) |
---|
| 3986 | ENDDO |
---|
| 3987 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3988 | IF ( is_masked ) THEN |
---|
[4577] | 3989 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I11)', ADVANCE='no' ) & |
---|
[4147] | 3990 | 'masked values', dimensions(i)%masked_values_int32(0) |
---|
| 3991 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 3992 | WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) & |
---|
[4147] | 3993 | ',', dimensions(i)%masked_values_int32(j) |
---|
| 3994 | ENDDO |
---|
| 3995 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 3996 | ENDIF |
---|
[4141] | 3997 | |
---|
[4147] | 3998 | ELSEIF ( ALLOCATED( dimensions(i)%values_intwp ) ) THEN |
---|
[4141] | 3999 | |
---|
[4577] | 4000 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I11)', ADVANCE='no' ) & |
---|
[4147] | 4001 | 'values', dimensions(i)%values_intwp(dimensions(i)%bounds(1)) |
---|
| 4002 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 4003 | WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) & |
---|
[4147] | 4004 | ',', dimensions(i)%values_intwp(j) |
---|
| 4005 | ENDDO |
---|
| 4006 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4007 | IF ( is_masked ) THEN |
---|
[4577] | 4008 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I11)', ADVANCE='no' ) & |
---|
[4147] | 4009 | 'masked values', dimensions(i)%masked_values_intwp(0) |
---|
| 4010 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 4011 | WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) & |
---|
[4147] | 4012 | ',', dimensions(i)%masked_values_intwp(j) |
---|
| 4013 | ENDDO |
---|
| 4014 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4015 | ENDIF |
---|
[4141] | 4016 | |
---|
[4147] | 4017 | ELSEIF ( ALLOCATED( dimensions(i)%values_real32 ) ) THEN |
---|
[4141] | 4018 | |
---|
[4577] | 4019 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E14.7)', ADVANCE='no' ) & |
---|
[4147] | 4020 | 'values', dimensions(i)%values_real32(dimensions(i)%bounds(1)) |
---|
| 4021 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 4022 | WRITE( debug_output_unit, '(A,E14.7)', ADVANCE='no' ) & |
---|
[4147] | 4023 | ',', dimensions(i)%values_real32(j) |
---|
| 4024 | ENDDO |
---|
| 4025 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4026 | IF ( is_masked ) THEN |
---|
[4577] | 4027 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E14.7)', ADVANCE='no' ) & |
---|
[4147] | 4028 | 'masked values', dimensions(i)%masked_values_real32(0) |
---|
| 4029 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 4030 | WRITE( debug_output_unit, '(A,E14.7)', ADVANCE='no' ) & |
---|
[4147] | 4031 | ',', dimensions(i)%masked_values_real32(j) |
---|
| 4032 | ENDDO |
---|
| 4033 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4034 | ENDIF |
---|
[4141] | 4035 | |
---|
[4147] | 4036 | ELSEIF ( ALLOCATED( dimensions(i)%values_real64 ) ) THEN |
---|
[4141] | 4037 | |
---|
[4577] | 4038 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4039 | 'values', dimensions(i)%values_real64(dimensions(i)%bounds(1)) |
---|
| 4040 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 4041 | WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4042 | ',', dimensions(i)%values_real64(j) |
---|
| 4043 | ENDDO |
---|
| 4044 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4045 | IF ( is_masked ) THEN |
---|
[4577] | 4046 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4047 | 'masked values', dimensions(i)%masked_values_real64(0) |
---|
| 4048 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 4049 | WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4050 | ',', dimensions(i)%masked_values_real64(j) |
---|
| 4051 | ENDDO |
---|
| 4052 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4053 | ENDIF |
---|
[4141] | 4054 | |
---|
[4147] | 4055 | ELSEIF ( ALLOCATED( dimensions(i)%values_realwp ) ) THEN |
---|
[4141] | 4056 | |
---|
[4577] | 4057 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4058 | 'values', dimensions(i)%values_realwp(dimensions(i)%bounds(1)) |
---|
| 4059 | DO j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2) |
---|
[4577] | 4060 | WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4061 | ',', dimensions(i)%values_realwp(j) |
---|
| 4062 | ENDDO |
---|
| 4063 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4064 | IF ( is_masked ) THEN |
---|
[4577] | 4065 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4066 | 'masked values', dimensions(i)%masked_values_realwp(0) |
---|
| 4067 | DO j = 1, dimensions(i)%length_mask-1 |
---|
[4577] | 4068 | WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) & |
---|
[4147] | 4069 | ',', dimensions(i)%masked_values_realwp(j) |
---|
| 4070 | ENDDO |
---|
| 4071 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
| 4072 | ENDIF |
---|
[4141] | 4073 | |
---|
[4147] | 4074 | ENDIF |
---|
[4141] | 4075 | |
---|
[4577] | 4076 | IF ( ALLOCATED( dimensions(i)%attributes ) ) & |
---|
[4147] | 4077 | CALL print_attributes( indent_level+1, dimensions(i)%attributes ) |
---|
[4141] | 4078 | |
---|
[4577] | 4079 | IF ( i < nelement ) & |
---|
[4147] | 4080 | WRITE( debug_output_unit, TRIM( write_format1 ) // ')' ) separation_string |
---|
| 4081 | ENDDO |
---|
[4141] | 4082 | |
---|
[4147] | 4083 | END SUBROUTINE print_dimensions |
---|
[4141] | 4084 | |
---|
[4577] | 4085 | !--------------------------------------------------------------------------------------------------! |
---|
| 4086 | ! Description: |
---|
| 4087 | ! ------------ |
---|
| 4088 | !> Print list of variables. |
---|
| 4089 | !--------------------------------------------------------------------------------------------------! |
---|
[4147] | 4090 | SUBROUTINE print_variables( indent_level, variables ) |
---|
[4141] | 4091 | |
---|
[4577] | 4092 | INTEGER, PARAMETER :: max_keyname_length = 16 !< length of longest key name |
---|
| 4093 | |
---|
[4147] | 4094 | CHARACTER(LEN=50) :: write_format1 !< format for write statements |
---|
| 4095 | CHARACTER(LEN=50) :: write_format2 !< format for write statements |
---|
[4141] | 4096 | |
---|
[4147] | 4097 | INTEGER :: i !< loop index |
---|
| 4098 | INTEGER, INTENT(IN) :: indent_level !< indentation level |
---|
| 4099 | INTEGER :: j !< loop index |
---|
| 4100 | INTEGER :: nelement !< number of elements to print |
---|
[4141] | 4101 | |
---|
[4147] | 4102 | TYPE(variable_type), DIMENSION(:), INTENT(IN) :: variables !< list of variables |
---|
[4141] | 4103 | |
---|
| 4104 | |
---|
[4147] | 4105 | WRITE( write_format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A' |
---|
[4577] | 4106 | WRITE( write_format2, '(A,I3,A,I3,A)' ) & |
---|
| 4107 | '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', & |
---|
[4147] | 4108 | ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")' |
---|
[4141] | 4109 | |
---|
[4577] | 4110 | WRITE( debug_output_unit, TRIM( write_format1 ) // ',A)' ) & |
---|
[4147] | 4111 | REPEAT( separation_string // ' ', 4 ) |
---|
| 4112 | WRITE( debug_output_unit, TRIM( write_format1 ) // ')' ) 'variables:' |
---|
[4141] | 4113 | |
---|
[4147] | 4114 | nelement = SIZE( variables ) |
---|
| 4115 | DO i = 1, nelement |
---|
[4577] | 4116 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 4117 | 'name', TRIM( variables(i)%name ) |
---|
[4577] | 4118 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)' ) & |
---|
[4147] | 4119 | 'type', TRIM( variables(i)%data_type ) |
---|
[4577] | 4120 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)' ) & |
---|
[4147] | 4121 | 'id', variables(i)%id |
---|
[4577] | 4122 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',L1)' ) & |
---|
[4147] | 4123 | 'is global', variables(i)%is_global |
---|
[4141] | 4124 | |
---|
[4577] | 4125 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)', ADVANCE='no' ) & |
---|
[4147] | 4126 | 'dimension names', TRIM( variables(i)%dimension_names(1) ) |
---|
| 4127 | DO j = 2, SIZE( variables(i)%dimension_names ) |
---|
[4577] | 4128 | WRITE( debug_output_unit, '(A,A)', ADVANCE='no' ) & |
---|
[4147] | 4129 | ',', TRIM( variables(i)%dimension_names(j) ) |
---|
| 4130 | ENDDO |
---|
| 4131 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
[4141] | 4132 | |
---|
[4577] | 4133 | WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)', ADVANCE='no' ) & |
---|
[4147] | 4134 | 'dimension ids', variables(i)%dimension_ids(1) |
---|
| 4135 | DO j = 2, SIZE( variables(i)%dimension_names ) |
---|
[4577] | 4136 | WRITE( debug_output_unit, '(A,I7)', ADVANCE='no' ) & |
---|
[4147] | 4137 | ',', variables(i)%dimension_ids(j) |
---|
| 4138 | ENDDO |
---|
| 4139 | WRITE( debug_output_unit, '(A)' ) '' ! write line-end |
---|
[4141] | 4140 | |
---|
[4577] | 4141 | IF ( ALLOCATED( variables(i)%attributes ) ) & |
---|
[4147] | 4142 | CALL print_attributes( indent_level+1, variables(i)%attributes ) |
---|
[4577] | 4143 | IF ( i < nelement ) & |
---|
[4147] | 4144 | WRITE( debug_output_unit, TRIM( write_format1 ) // ')' ) separation_string |
---|
| 4145 | ENDDO |
---|
[4141] | 4146 | |
---|
[4147] | 4147 | END SUBROUTINE print_variables |
---|
[4141] | 4148 | |
---|
[4147] | 4149 | END SUBROUTINE dom_database_debug_output |
---|
[4141] | 4150 | |
---|
[4577] | 4151 | END MODULE data_output_module |
---|