[1833] | 1 | !> @file spectra_mod.f90 |
---|
[4591] | 2 | !--------------------------------------------------------------------------------------------------! |
---|
[2696] | 3 | ! This file is part of the PALM model system. |
---|
[1036] | 4 | ! |
---|
[4591] | 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. |
---|
[1036] | 8 | ! |
---|
[4591] | 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. |
---|
[1036] | 12 | ! |
---|
[4591] | 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/>. |
---|
[1036] | 15 | ! |
---|
[4828] | 16 | ! Copyright 1997-2021 Leibniz Universitaet Hannover |
---|
[4591] | 17 | !--------------------------------------------------------------------------------------------------! |
---|
[1036] | 18 | ! |
---|
[4591] | 19 | ! |
---|
[247] | 20 | ! Current revisions: |
---|
[1] | 21 | ! ----------------- |
---|
[4591] | 22 | ! |
---|
| 23 | ! |
---|
[1787] | 24 | ! Former revisions: |
---|
| 25 | ! ----------------- |
---|
| 26 | ! $Id: spectra_mod.f90 4842 2021-01-14 10:42:28Z raasch $ |
---|
[4842] | 27 | ! reading of namelist file and actions in case of namelist errors revised so that statement labels |
---|
| 28 | ! and goto statements are not required any more, |
---|
| 29 | ! deprecated namelist removed |
---|
| 30 | ! |
---|
| 31 | ! 4828 2021-01-05 11:21:41Z Giersch |
---|
[4629] | 32 | ! support for MPI Fortran77 interface (mpif.h) removed |
---|
| 33 | ! |
---|
| 34 | ! 4591 2020-07-06 15:56:08Z raasch |
---|
[4591] | 35 | ! File re-formatted to follow the PALM coding standard |
---|
| 36 | ! |
---|
| 37 | ! 4429 2020-02-27 15:24:30Z raasch |
---|
| 38 | ! Bugfix: preprocessor directives rearranged for serial mode |
---|
| 39 | ! |
---|
[4429] | 40 | ! 4360 2020-01-07 11:25:50Z suehring |
---|
[4182] | 41 | ! Corrected "Former revisions" section |
---|
[4591] | 42 | ! |
---|
[4182] | 43 | ! 3805 2019-03-20 15:26:35Z raasch |
---|
[4591] | 44 | ! Unused variable removed |
---|
| 45 | ! |
---|
[3805] | 46 | ! 3655 2019-01-07 16:51:22Z knoop |
---|
[3421] | 47 | ! Renamed output variables |
---|
[1787] | 48 | ! |
---|
[4182] | 49 | ! Revision 1.1 2001/01/05 15:08:07 raasch |
---|
| 50 | ! Initial revision |
---|
| 51 | ! |
---|
[4591] | 52 | !--------------------------------------------------------------------------------------------------! |
---|
[1] | 53 | ! Description: |
---|
| 54 | ! ------------ |
---|
[4591] | 55 | !> Calculate horizontal spectra along x and y. |
---|
| 56 | !> ATTENTION: 1d-decomposition along y still needs improvement, because in that case the gridpoint |
---|
| 57 | !> number along z still depends on the PE number because transpose_xz has to be used |
---|
| 58 | !> (and possibly also transpose_zyd needs modification). |
---|
| 59 | !--------------------------------------------------------------------------------------------------! |
---|
[1833] | 60 | MODULE spectra_mod |
---|
[1] | 61 | |
---|
[1786] | 62 | USE kinds |
---|
[1320] | 63 | |
---|
[1786] | 64 | PRIVATE |
---|
[1320] | 65 | |
---|
[4591] | 66 | CHARACTER (LEN=10), DIMENSION(10) :: data_output_sp = ' ' !< |
---|
| 67 | CHARACTER (LEN=2), DIMENSION(10) :: spectra_direction = 'x' !< |
---|
[1320] | 68 | |
---|
[4591] | 69 | INTEGER(iwp) :: average_count_sp = 0 !< |
---|
| 70 | INTEGER(iwp) :: comp_spectra_level(100) = 999999 !< |
---|
| 71 | INTEGER(iwp) :: dosp_time_count = 0 !< |
---|
| 72 | INTEGER(iwp) :: n_sp_x = 0, n_sp_y = 0 !< |
---|
[1320] | 73 | |
---|
[1833] | 74 | LOGICAL :: calculate_spectra = .FALSE. !< internal switch that spectra are calculated |
---|
| 75 | LOGICAL :: spectra_initialized = .FALSE. !< internal switch that spectra related quantities are initialized |
---|
[1320] | 76 | |
---|
[1833] | 77 | REAL(wp) :: averaging_interval_sp = 9999999.9_wp !< averaging interval for spectra output |
---|
| 78 | REAL(wp) :: dt_dosp = 9999999.9_wp !< time interval for spectra output |
---|
| 79 | REAL(wp) :: skip_time_dosp = 9999999.9_wp !< no output of spectra data before this interval has passed |
---|
[1] | 80 | |
---|
[4591] | 81 | REAL(wp), DIMENSION(:), ALLOCATABLE :: var_d !< |
---|
[1833] | 82 | |
---|
[4591] | 83 | REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: spectrum_x !< |
---|
| 84 | REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: spectrum_y !< |
---|
[1833] | 85 | |
---|
[1786] | 86 | SAVE |
---|
[1320] | 87 | |
---|
[1786] | 88 | INTERFACE calc_spectra |
---|
| 89 | MODULE PROCEDURE calc_spectra |
---|
| 90 | END INTERFACE calc_spectra |
---|
[1320] | 91 | |
---|
[1786] | 92 | INTERFACE preprocess_spectra |
---|
| 93 | MODULE PROCEDURE preprocess_spectra |
---|
| 94 | END INTERFACE preprocess_spectra |
---|
[1] | 95 | |
---|
[4429] | 96 | #if defined( __parallel ) |
---|
[1786] | 97 | INTERFACE calc_spectra_x |
---|
| 98 | MODULE PROCEDURE calc_spectra_x |
---|
| 99 | END INTERFACE calc_spectra_x |
---|
[1] | 100 | |
---|
[1786] | 101 | INTERFACE calc_spectra_y |
---|
| 102 | MODULE PROCEDURE calc_spectra_y |
---|
| 103 | END INTERFACE calc_spectra_y |
---|
[4429] | 104 | #endif |
---|
[1] | 105 | |
---|
[1833] | 106 | INTERFACE spectra_check_parameters |
---|
| 107 | MODULE PROCEDURE spectra_check_parameters |
---|
| 108 | END INTERFACE spectra_check_parameters |
---|
[1] | 109 | |
---|
[1833] | 110 | INTERFACE spectra_header |
---|
| 111 | MODULE PROCEDURE spectra_header |
---|
| 112 | END INTERFACE spectra_header |
---|
[1786] | 113 | |
---|
[1833] | 114 | INTERFACE spectra_init |
---|
| 115 | MODULE PROCEDURE spectra_init |
---|
| 116 | END INTERFACE spectra_init |
---|
| 117 | |
---|
| 118 | INTERFACE spectra_parin |
---|
| 119 | MODULE PROCEDURE spectra_parin |
---|
| 120 | END INTERFACE spectra_parin |
---|
| 121 | |
---|
[4591] | 122 | PUBLIC average_count_sp, & |
---|
| 123 | averaging_interval_sp, & |
---|
| 124 | calc_spectra, & |
---|
| 125 | calculate_spectra, & |
---|
| 126 | comp_spectra_level, & |
---|
| 127 | data_output_sp, & |
---|
| 128 | dosp_time_count, & |
---|
| 129 | dt_dosp, & |
---|
| 130 | n_sp_x, & |
---|
| 131 | n_sp_y, & |
---|
| 132 | skip_time_dosp, & |
---|
| 133 | spectra_check_parameters, & |
---|
| 134 | spectra_direction, & |
---|
| 135 | spectra_header, & |
---|
| 136 | spectra_init, & |
---|
| 137 | spectra_parin, & |
---|
| 138 | spectrum_x, & |
---|
| 139 | spectrum_y, & |
---|
| 140 | var_d |
---|
[1833] | 141 | |
---|
| 142 | |
---|
[1786] | 143 | CONTAINS |
---|
| 144 | |
---|
[4591] | 145 | !--------------------------------------------------------------------------------------------------! |
---|
[1833] | 146 | ! Description: |
---|
| 147 | ! ------------ |
---|
| 148 | !> Parin for &spectra_par for calculating spectra |
---|
[4591] | 149 | !--------------------------------------------------------------------------------------------------! |
---|
| 150 | SUBROUTINE spectra_parin |
---|
[1833] | 151 | |
---|
[4591] | 152 | USE control_parameters, & |
---|
[4842] | 153 | ONLY: dt_data_output |
---|
[1833] | 154 | |
---|
[4591] | 155 | IMPLICIT NONE |
---|
[1833] | 156 | |
---|
[4842] | 157 | CHARACTER(LEN=100) :: line !< dummy string that contains the current line of the parameter file |
---|
[1833] | 158 | |
---|
[4842] | 159 | INTEGER(iwp) :: io_status !< status after reading the namelist file |
---|
[1833] | 160 | |
---|
[4842] | 161 | |
---|
[4591] | 162 | NAMELIST /spectra_parameters/ & |
---|
| 163 | averaging_interval_sp, & |
---|
| 164 | comp_spectra_level, & |
---|
| 165 | data_output_sp, & |
---|
| 166 | dt_dosp, & |
---|
| 167 | skip_time_dosp, & |
---|
| 168 | spectra_direction |
---|
[1833] | 169 | ! |
---|
[4842] | 170 | !-- Position the namelist-file at the beginning (it was already opened in parin), and try to read |
---|
| 171 | !-- the namelist. |
---|
| 172 | REWIND( 11 ) |
---|
| 173 | READ( 11, spectra_parameters, IOSTAT=io_status ) |
---|
[1833] | 174 | |
---|
| 175 | ! |
---|
[4842] | 176 | !-- Action depending on the READ status |
---|
| 177 | IF ( io_status == 0 ) THEN |
---|
[1833] | 178 | ! |
---|
[4842] | 179 | !-- spectra_parameters namelist was found and read correctly. |
---|
| 180 | !-- Default setting of dt_dosp here (instead of check_parameters), because its current value is |
---|
| 181 | !-- needed in init_pegrid. |
---|
| 182 | IF ( dt_dosp == 9999999.9_wp ) dt_dosp = dt_data_output |
---|
[2932] | 183 | ! |
---|
[4842] | 184 | !-- Set general switch that spectra shall be calculated. |
---|
| 185 | calculate_spectra = .TRUE. |
---|
[2932] | 186 | |
---|
[4842] | 187 | ELSEIF ( io_status > 0 ) THEN |
---|
[2932] | 188 | ! |
---|
[4842] | 189 | !-- spectra_parameters namelist was found but contained errors. Print an error message including |
---|
| 190 | !-- the line that caused the problem. |
---|
| 191 | BACKSPACE( 11 ) |
---|
| 192 | READ( 11 , '(A)' ) line |
---|
| 193 | CALL parin_fail_message( 'spectra_parameters', line ) |
---|
[2932] | 194 | |
---|
[4842] | 195 | ENDIF |
---|
[3246] | 196 | |
---|
[4591] | 197 | END SUBROUTINE spectra_parin |
---|
| 198 | |
---|
| 199 | |
---|
| 200 | |
---|
| 201 | !--------------------------------------------------------------------------------------------------! |
---|
[1833] | 202 | ! Description: |
---|
| 203 | ! ------------ |
---|
| 204 | !> Initialization of spectra related variables |
---|
[4591] | 205 | !--------------------------------------------------------------------------------------------------! |
---|
| 206 | SUBROUTINE spectra_init |
---|
[1833] | 207 | |
---|
[4591] | 208 | USE indices, & |
---|
| 209 | ONLY: nx, & |
---|
| 210 | ny, & |
---|
| 211 | nzb, & |
---|
| 212 | nzt |
---|
[1833] | 213 | |
---|
[4591] | 214 | IMPLICIT NONE |
---|
[1833] | 215 | |
---|
[4591] | 216 | IF ( spectra_initialized ) RETURN |
---|
[1833] | 217 | |
---|
[4591] | 218 | IF ( dt_dosp /= 9999999.9_wp ) THEN |
---|
[1833] | 219 | |
---|
[4591] | 220 | IF ( .NOT. ALLOCATED( spectrum_x ) ) THEN |
---|
| 221 | ALLOCATE( spectrum_x( 1:nx/2, 1:100, 1:10 ) ) |
---|
| 222 | spectrum_x = 0.0_wp |
---|
| 223 | ENDIF |
---|
[2956] | 224 | |
---|
[4591] | 225 | IF ( .NOT. ALLOCATED( spectrum_y ) ) THEN |
---|
| 226 | ALLOCATE( spectrum_y( 1:ny/2, 1:100, 1:10 ) ) |
---|
| 227 | spectrum_y = 0.0_wp |
---|
[1833] | 228 | ENDIF |
---|
| 229 | |
---|
[4591] | 230 | ALLOCATE( var_d(nzb:nzt+1) ) |
---|
| 231 | var_d = 0.0_wp |
---|
| 232 | ENDIF |
---|
[1833] | 233 | |
---|
[4591] | 234 | spectra_initialized = .TRUE. |
---|
[1833] | 235 | |
---|
[4591] | 236 | END SUBROUTINE spectra_init |
---|
[1833] | 237 | |
---|
| 238 | |
---|
[4591] | 239 | |
---|
| 240 | !--------------------------------------------------------------------------------------------------! |
---|
[1833] | 241 | ! Description: |
---|
| 242 | ! ------------ |
---|
| 243 | !> Check spectra related quantities |
---|
[4591] | 244 | !--------------------------------------------------------------------------------------------------! |
---|
| 245 | SUBROUTINE spectra_check_parameters |
---|
[1833] | 246 | |
---|
[4591] | 247 | USE control_parameters, & |
---|
| 248 | ONLY: averaging_interval, & |
---|
| 249 | message_string, & |
---|
| 250 | skip_time_data_output |
---|
[1833] | 251 | |
---|
[4591] | 252 | IMPLICIT NONE |
---|
[1833] | 253 | |
---|
| 254 | ! |
---|
[4591] | 255 | !-- Check the average interval |
---|
| 256 | IF ( averaging_interval_sp == 9999999.9_wp ) THEN |
---|
| 257 | averaging_interval_sp = averaging_interval |
---|
| 258 | ENDIF |
---|
[1833] | 259 | |
---|
[4591] | 260 | IF ( averaging_interval_sp > dt_dosp ) THEN |
---|
| 261 | WRITE( message_string, * ) 'averaging_interval_sp = ', averaging_interval_sp, & |
---|
| 262 | ' must be <= dt_dosp = ', dt_dosp |
---|
| 263 | CALL message( 'spectra_check_parameters', 'PA0087', 1, 2, 0, 6, 0 ) |
---|
| 264 | ENDIF |
---|
[1833] | 265 | |
---|
| 266 | ! |
---|
[4591] | 267 | !-- Set the default skip time interval for data output, if necessary |
---|
| 268 | IF ( skip_time_dosp == 9999999.9_wp ) skip_time_dosp = skip_time_data_output |
---|
[1833] | 269 | |
---|
[4591] | 270 | END SUBROUTINE spectra_check_parameters |
---|
[1833] | 271 | |
---|
| 272 | |
---|
| 273 | |
---|
[4591] | 274 | !--------------------------------------------------------------------------------------------------! |
---|
[1833] | 275 | ! Description: |
---|
| 276 | ! ------------ |
---|
| 277 | !> Header output for spectra |
---|
| 278 | !> |
---|
| 279 | !> @todo Output of netcdf data format and compression level |
---|
[4591] | 280 | !--------------------------------------------------------------------------------------------------! |
---|
| 281 | SUBROUTINE spectra_header ( io ) |
---|
[1833] | 282 | |
---|
[4591] | 283 | USE control_parameters, & |
---|
| 284 | ONLY: dt_averaging_input_pr |
---|
[1833] | 285 | |
---|
[4591] | 286 | ! USE netcdf_interface, & |
---|
| 287 | ! ONLY: netcdf_data_format_string, & |
---|
| 288 | ! netcdf_deflate |
---|
[1833] | 289 | |
---|
[4591] | 290 | IMPLICIT NONE |
---|
[1833] | 291 | |
---|
[4591] | 292 | ! CHARACTER (LEN=40) :: output_format !< internal string |
---|
[1833] | 293 | |
---|
[4591] | 294 | INTEGER(iwp) :: i !< internal counter |
---|
| 295 | INTEGER(iwp), INTENT(IN) :: io !< unit of the output file |
---|
[1833] | 296 | |
---|
| 297 | ! |
---|
[4591] | 298 | !-- Spectra output |
---|
| 299 | IF ( dt_dosp /= 9999999.9_wp ) THEN |
---|
| 300 | WRITE ( io, 1 ) |
---|
[1833] | 301 | |
---|
[4591] | 302 | ! output_format = netcdf_data_format_string |
---|
| 303 | ! IF ( netcdf_deflate == 0 ) THEN |
---|
| 304 | ! WRITE ( io, 2 ) output_format |
---|
| 305 | ! ELSE |
---|
| 306 | ! WRITE ( io, 3 ) TRIM( output_format ), netcdf_deflate |
---|
| 307 | ! ENDIF |
---|
| 308 | WRITE ( io, 2 ) 'see profiles or other quantities' |
---|
| 309 | WRITE ( io, 4 ) dt_dosp |
---|
| 310 | IF ( skip_time_dosp /= 0.0_wp ) WRITE ( io, 5 ) skip_time_dosp |
---|
| 311 | WRITE ( io, 6 ) ( data_output_sp(i), i = 1,10 ), & |
---|
| 312 | ( spectra_direction(i), i = 1,10 ), & |
---|
| 313 | ( comp_spectra_level(i), i = 1,100 ), & |
---|
| 314 | averaging_interval_sp, dt_averaging_input_pr |
---|
| 315 | ENDIF |
---|
[1833] | 316 | |
---|
[4591] | 317 | 1 FORMAT (' Spectra:') |
---|
| 318 | 2 FORMAT (' Output format: ',A/) |
---|
| 319 | ! 3 FORMAT (' Output format: ',A, ' compressed with level: ',I1/) |
---|
| 320 | 4 FORMAT (' Output every ',F7.1,' s'/) |
---|
| 321 | 5 FORMAT (' No output during initial ',F8.2,' s') |
---|
| 322 | 6 FORMAT (' Arrays: ', 10(A5,',')/ & |
---|
| 323 | ' Directions: ', 10(A5,',')/ & |
---|
| 324 | ' height levels k = ', 20(I3,',')/ & |
---|
| 325 | ' ', 20(I3,',')/ & |
---|
| 326 | ' ', 20(I3,',')/ & |
---|
| 327 | ' ', 20(I3,',')/ & |
---|
| 328 | ' ', 19(I3,','),I3,'.'/ & |
---|
| 329 | ' Time averaged over ', F7.1, ' s,' / & |
---|
| 330 | ' Profiles for the time averaging are taken every ', & |
---|
| 331 | F6.1,' s') |
---|
[1833] | 332 | |
---|
[4591] | 333 | END SUBROUTINE spectra_header |
---|
[1833] | 334 | |
---|
| 335 | |
---|
[4591] | 336 | !--------------------------------------------------------------------------------------------------! |
---|
| 337 | ! Description: |
---|
| 338 | ! ------------ |
---|
| 339 | !> @todo Missing subroutine description. |
---|
| 340 | !--------------------------------------------------------------------------------------------------! |
---|
[1833] | 341 | |
---|
[4591] | 342 | SUBROUTINE calc_spectra |
---|
[1786] | 343 | |
---|
[4591] | 344 | USE arrays_3d, & |
---|
| 345 | ONLY: d |
---|
[4429] | 346 | #if defined( __parallel ) |
---|
[4591] | 347 | USE arrays_3d, & |
---|
| 348 | ONLY: tend |
---|
[4429] | 349 | #endif |
---|
[1786] | 350 | |
---|
[4591] | 351 | USE control_parameters, & |
---|
| 352 | ONLY: bc_lr_cyc, & |
---|
| 353 | bc_ns_cyc, & |
---|
| 354 | message_string, & |
---|
| 355 | psolver |
---|
[1786] | 356 | |
---|
[4591] | 357 | USE cpulog, & |
---|
| 358 | ONLY: cpu_log, & |
---|
| 359 | log_point |
---|
[1786] | 360 | |
---|
[4591] | 361 | USE fft_xy, & |
---|
| 362 | ONLY: fft_init |
---|
[1786] | 363 | |
---|
[4591] | 364 | USE indices, & |
---|
| 365 | ONLY: nxl, & |
---|
| 366 | nxr, & |
---|
| 367 | nyn, & |
---|
| 368 | nys, & |
---|
| 369 | nzb, & |
---|
| 370 | nzt |
---|
[1786] | 371 | |
---|
[4591] | 372 | USE kinds |
---|
[1786] | 373 | |
---|
[4591] | 374 | USE pegrid, & |
---|
| 375 | ONLY: myid |
---|
[4429] | 376 | #if defined( __parallel ) |
---|
[4591] | 377 | USE pegrid, & |
---|
| 378 | ONLY: pdims |
---|
[4429] | 379 | #endif |
---|
[1786] | 380 | |
---|
[4591] | 381 | IMPLICIT NONE |
---|
[1786] | 382 | |
---|
[4591] | 383 | INTEGER(iwp) :: m !< |
---|
| 384 | INTEGER(iwp) :: pr !< |
---|
[1786] | 385 | |
---|
| 386 | |
---|
[1] | 387 | ! |
---|
[4591] | 388 | !-- Check if user gave any levels for spectra to be calculated |
---|
| 389 | IF ( comp_spectra_level(1) == 999999 ) RETURN |
---|
[1] | 390 | |
---|
[4591] | 391 | CALL cpu_log( log_point(30), 'calc_spectra', 'start' ) |
---|
[1786] | 392 | |
---|
[1] | 393 | ! |
---|
[4591] | 394 | !-- Initialize spectra related quantities |
---|
| 395 | CALL spectra_init |
---|
[1833] | 396 | |
---|
| 397 | ! |
---|
[4591] | 398 | !-- Initialize ffts |
---|
| 399 | CALL fft_init |
---|
[225] | 400 | |
---|
[1] | 401 | ! |
---|
[4591] | 402 | !-- Reallocate array d in required size |
---|
| 403 | IF ( psolver(1:9) == 'multigrid' ) THEN |
---|
| 404 | DEALLOCATE( d ) |
---|
| 405 | ALLOCATE( d(nzb+1:nzt,nys:nyn,nxl:nxr) ) |
---|
| 406 | ENDIF |
---|
[1] | 407 | |
---|
[4591] | 408 | m = 1 |
---|
| 409 | DO WHILE ( data_output_sp(m) /= ' ' .AND. m <= 10 ) |
---|
[1] | 410 | ! |
---|
[4591] | 411 | !-- Transposition from z --> x ( y --> x in case of a 1d-decomposition along x) |
---|
| 412 | IF ( INDEX( spectra_direction(m), 'x' ) /= 0 ) THEN |
---|
[247] | 413 | |
---|
[1786] | 414 | ! |
---|
[4591] | 415 | !-- Calculation of spectra works for cyclic boundary conditions only |
---|
| 416 | IF ( .NOT. bc_lr_cyc ) THEN |
---|
[1] | 417 | |
---|
[4591] | 418 | message_string = 'non-cyclic lateral boundaries along x do' // & |
---|
| 419 | ' not & allow calculation of spectra along x' |
---|
| 420 | CALL message( 'calc_spectra', 'PA0160', 1, 2, 0, 6, 0 ) |
---|
| 421 | ENDIF |
---|
[1] | 422 | |
---|
[4591] | 423 | CALL preprocess_spectra( m, pr ) |
---|
[1786] | 424 | |
---|
[1] | 425 | #if defined( __parallel ) |
---|
[4591] | 426 | IF ( pdims(2) /= 1 ) THEN |
---|
| 427 | CALL resort_for_zx( d, tend ) |
---|
| 428 | CALL transpose_zx( tend, d ) |
---|
| 429 | ELSE |
---|
| 430 | CALL transpose_yxd( d, d ) |
---|
| 431 | ENDIF |
---|
| 432 | CALL calc_spectra_x( d, m ) |
---|
[1] | 433 | #else |
---|
[4591] | 434 | message_string = 'sorry, calculation of spectra in non parallel mode& is still not ' // & |
---|
| 435 | 'realized' |
---|
| 436 | CALL message( 'calc_spectra', 'PA0161', 1, 2, 0, 6, 0 ) |
---|
[1] | 437 | #endif |
---|
| 438 | |
---|
[4591] | 439 | ENDIF |
---|
[1] | 440 | |
---|
| 441 | ! |
---|
[4591] | 442 | !-- Transposition from z --> y (d is rearranged only in case of a 1d-decomposition along x) |
---|
| 443 | IF ( INDEX( spectra_direction(m), 'y' ) /= 0 ) THEN |
---|
[1] | 444 | |
---|
| 445 | ! |
---|
[4591] | 446 | !-- Calculation of spectra works for cyclic boundary conditions only |
---|
| 447 | IF ( .NOT. bc_ns_cyc ) THEN |
---|
| 448 | IF ( myid == 0 ) THEN |
---|
| 449 | message_string = 'non-cyclic lateral boundaries along y' // & |
---|
| 450 | ' do not & allow calculation of spectra along y' |
---|
| 451 | CALL message( 'calc_spectra', 'PA0162', 1, 2, 0, 6, 0 ) |
---|
[1] | 452 | ENDIF |
---|
[4591] | 453 | CALL local_stop |
---|
| 454 | ENDIF |
---|
[1] | 455 | |
---|
[4591] | 456 | CALL preprocess_spectra( m, pr ) |
---|
[1] | 457 | |
---|
| 458 | #if defined( __parallel ) |
---|
[4591] | 459 | CALL transpose_zyd( d, d ) |
---|
| 460 | CALL calc_spectra_y( d, m ) |
---|
[1] | 461 | #else |
---|
[4591] | 462 | message_string = 'sorry, calculation of spectra in non parallel mode& is still not ' // & |
---|
| 463 | 'realized' |
---|
| 464 | CALL message( 'calc_spectra', 'PA0161', 1, 2, 0, 6, 0 ) |
---|
[1] | 465 | #endif |
---|
| 466 | |
---|
[4591] | 467 | ENDIF |
---|
[1] | 468 | |
---|
| 469 | ! |
---|
[4591] | 470 | !-- Increase counter for next spectrum |
---|
| 471 | m = m + 1 |
---|
[1] | 472 | |
---|
[4591] | 473 | ENDDO |
---|
| 474 | |
---|
[1] | 475 | ! |
---|
[4591] | 476 | !-- Increase counter for averaging process in routine plot_spectra |
---|
| 477 | average_count_sp = average_count_sp + 1 |
---|
[1] | 478 | |
---|
[4591] | 479 | CALL cpu_log( log_point(30), 'calc_spectra', 'stop' ) |
---|
[1] | 480 | |
---|
[4591] | 481 | END SUBROUTINE calc_spectra |
---|
[1] | 482 | |
---|
| 483 | |
---|
[4591] | 484 | !--------------------------------------------------------------------------------------------------! |
---|
[1682] | 485 | ! Description: |
---|
| 486 | ! ------------ |
---|
| 487 | !> @todo Missing subroutine description. |
---|
[4591] | 488 | !--------------------------------------------------------------------------------------------------! |
---|
| 489 | SUBROUTINE preprocess_spectra( m, pr ) |
---|
[1] | 490 | |
---|
[4591] | 491 | USE arrays_3d, & |
---|
| 492 | ONLY: d, & |
---|
| 493 | pt, & |
---|
| 494 | q, & |
---|
| 495 | s, & |
---|
| 496 | u, & |
---|
| 497 | v, & |
---|
| 498 | w |
---|
[1320] | 499 | |
---|
[4591] | 500 | USE indices, & |
---|
| 501 | ONLY: ngp_2dh, & |
---|
| 502 | nxl, & |
---|
| 503 | nxr, & |
---|
| 504 | nyn, & |
---|
| 505 | nys, & |
---|
| 506 | nzb, & |
---|
| 507 | nzt |
---|
[1320] | 508 | |
---|
[4591] | 509 | USE kinds |
---|
[1320] | 510 | |
---|
[1815] | 511 | #if defined( __parallel ) |
---|
[4591] | 512 | USE MPI |
---|
[2841] | 513 | |
---|
[4591] | 514 | USE pegrid, & |
---|
| 515 | ONLY: collective_wait, & |
---|
| 516 | comm2d, & |
---|
| 517 | ierr |
---|
[4429] | 518 | #endif |
---|
[1] | 519 | |
---|
[4591] | 520 | USE statistics, & |
---|
| 521 | ONLY: hom |
---|
[1320] | 522 | |
---|
| 523 | |
---|
[4591] | 524 | IMPLICIT NONE |
---|
[1320] | 525 | |
---|
[4591] | 526 | INTEGER(iwp) :: i !< |
---|
| 527 | INTEGER(iwp) :: j !< |
---|
| 528 | INTEGER(iwp) :: k !< |
---|
| 529 | INTEGER(iwp) :: m !< |
---|
| 530 | INTEGER(iwp) :: pr !< |
---|
[1] | 531 | |
---|
[4591] | 532 | REAL(wp), DIMENSION(nzb:nzt+1) :: var_d_l !< |
---|
[1] | 533 | |
---|
[4629] | 534 | |
---|
[4591] | 535 | SELECT CASE ( TRIM( data_output_sp(m) ) ) |
---|
| 536 | |
---|
| 537 | CASE ( 'u' ) |
---|
| 538 | pr = 1 |
---|
| 539 | d(nzb+1:nzt,nys:nyn,nxl:nxr) = u(nzb+1:nzt,nys:nyn,nxl:nxr) |
---|
| 540 | |
---|
| 541 | CASE ( 'v' ) |
---|
| 542 | pr = 2 |
---|
| 543 | d(nzb+1:nzt,nys:nyn,nxl:nxr) = v(nzb+1:nzt,nys:nyn,nxl:nxr) |
---|
| 544 | |
---|
| 545 | CASE ( 'w' ) |
---|
| 546 | pr = 3 |
---|
| 547 | d(nzb+1:nzt,nys:nyn,nxl:nxr) = w(nzb+1:nzt,nys:nyn,nxl:nxr) |
---|
| 548 | |
---|
| 549 | CASE ( 'theta' ) |
---|
| 550 | pr = 4 |
---|
| 551 | d(nzb+1:nzt,nys:nyn,nxl:nxr) = pt(nzb+1:nzt,nys:nyn,nxl:nxr) |
---|
| 552 | |
---|
| 553 | CASE ( 'q' ) |
---|
| 554 | pr = 41 |
---|
| 555 | d(nzb+1:nzt,nys:nyn,nxl:nxr) = q(nzb+1:nzt,nys:nyn,nxl:nxr) |
---|
| 556 | |
---|
| 557 | CASE ( 's' ) |
---|
| 558 | pr = 117 |
---|
| 559 | d(nzb+1:nzt,nys:nyn,nxl:nxr) = s(nzb+1:nzt,nys:nyn,nxl:nxr) |
---|
| 560 | |
---|
| 561 | CASE DEFAULT |
---|
[144] | 562 | ! |
---|
[4591] | 563 | !-- The DEFAULT case is reached either if the parameter data_output_sp(m) contains a wrong |
---|
| 564 | !-- character string or if the user has coded a special case in the user interface. There, the |
---|
| 565 | !-- subroutine user_spectra checks which of these two conditions applies. |
---|
| 566 | CALL user_spectra( 'preprocess', m, pr ) |
---|
[1] | 567 | |
---|
[4591] | 568 | END SELECT |
---|
| 569 | |
---|
[1] | 570 | ! |
---|
[4591] | 571 | !-- Subtract horizontal mean from the array, for which spectra have to be calculated. Moreover, |
---|
| 572 | !-- calculate variance of the respective quantitiy, later used for normalizing spectra output. |
---|
| 573 | var_d_l(:) = 0.0_wp |
---|
| 574 | DO i = nxl, nxr |
---|
| 575 | DO j = nys, nyn |
---|
| 576 | DO k = nzb+1, nzt |
---|
| 577 | d(k,j,i) = d(k,j,i) - hom(k,1,pr,0) |
---|
| 578 | var_d_l(k) = var_d_l(k) + d(k,j,i) * d(k,j,i) |
---|
[1] | 579 | ENDDO |
---|
| 580 | ENDDO |
---|
[4591] | 581 | ENDDO |
---|
[1431] | 582 | ! |
---|
[4591] | 583 | !-- Compute total variance from local variances |
---|
| 584 | var_d(:) = 0.0_wp |
---|
| 585 | #if defined( __parallel ) |
---|
| 586 | IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) |
---|
| 587 | CALL MPI_ALLREDUCE( var_d_l(0), var_d(0), nzt+1-nzb, MPI_REAL, MPI_SUM, comm2d, ierr ) |
---|
[1431] | 588 | #else |
---|
[4591] | 589 | var_d(:) = var_d_l(:) |
---|
[1431] | 590 | #endif |
---|
[4591] | 591 | var_d(:) = var_d(:) / ngp_2dh(0) |
---|
[1] | 592 | |
---|
[4591] | 593 | END SUBROUTINE preprocess_spectra |
---|
[1] | 594 | |
---|
| 595 | |
---|
[4591] | 596 | !--------------------------------------------------------------------------------------------------! |
---|
[1682] | 597 | ! Description: |
---|
| 598 | ! ------------ |
---|
| 599 | !> @todo Missing subroutine description. |
---|
[4591] | 600 | !--------------------------------------------------------------------------------------------------! |
---|
[4429] | 601 | #if defined( __parallel ) |
---|
[4591] | 602 | SUBROUTINE calc_spectra_x( ddd, m ) |
---|
[1] | 603 | |
---|
[4591] | 604 | USE fft_xy, & |
---|
| 605 | ONLY: fft_x_1d |
---|
[1320] | 606 | |
---|
[4591] | 607 | USE grid_variables, & |
---|
| 608 | ONLY: dx |
---|
[1320] | 609 | |
---|
[4591] | 610 | USE indices, & |
---|
| 611 | ONLY: nx, & |
---|
| 612 | ny |
---|
[1320] | 613 | |
---|
[4591] | 614 | USE kinds |
---|
[1320] | 615 | |
---|
[4591] | 616 | USE MPI |
---|
[2841] | 617 | |
---|
[4591] | 618 | USE pegrid, & |
---|
| 619 | ONLY: comm2d, & |
---|
| 620 | ierr, & |
---|
| 621 | myid |
---|
[1320] | 622 | |
---|
[4591] | 623 | USE transpose_indices, & |
---|
| 624 | ONLY: nyn_x, & |
---|
| 625 | nys_x, & |
---|
| 626 | nzb_x, & |
---|
| 627 | nzt_x |
---|
[1320] | 628 | |
---|
| 629 | |
---|
[4591] | 630 | IMPLICIT NONE |
---|
[1] | 631 | |
---|
[4591] | 632 | INTEGER(iwp) :: i !< |
---|
| 633 | INTEGER(iwp) :: j !< |
---|
| 634 | INTEGER(iwp) :: k !< |
---|
| 635 | INTEGER(iwp) :: m !< |
---|
| 636 | INTEGER(iwp) :: n !< |
---|
[1320] | 637 | |
---|
[4591] | 638 | REAL(wp) :: exponent !< |
---|
| 639 | REAL(wp) :: sum_spec_dum !< wavenumber-integrated spectrum |
---|
[1] | 640 | |
---|
[4591] | 641 | REAL(wp), DIMENSION(0:nx) :: work !< |
---|
| 642 | |
---|
| 643 | REAL(wp), DIMENSION(0:nx/2) :: sums_spectra_l !< |
---|
| 644 | |
---|
| 645 | REAL(wp), DIMENSION(0:nx/2,100) :: sums_spectra !< |
---|
| 646 | |
---|
| 647 | REAL(wp), DIMENSION(0:nx,nys_x:nyn_x,nzb_x:nzt_x) :: ddd !< |
---|
| 648 | |
---|
[1] | 649 | ! |
---|
[4591] | 650 | !-- Exponent for geometric average |
---|
| 651 | exponent = 1.0_wp / ( ny + 1.0_wp ) |
---|
[1] | 652 | |
---|
| 653 | ! |
---|
[4591] | 654 | !-- Loop over all levels defined by the user |
---|
| 655 | n = 1 |
---|
| 656 | DO WHILE ( comp_spectra_level(n) /= 999999 .AND. n <= 100 ) |
---|
[1] | 657 | |
---|
[4591] | 658 | k = comp_spectra_level(n) |
---|
[1] | 659 | |
---|
| 660 | ! |
---|
[4591] | 661 | !-- Calculate FFT only if the corresponding level is situated on this PE |
---|
| 662 | IF ( k >= nzb_x .AND. k <= nzt_x ) THEN |
---|
[1] | 663 | |
---|
[4591] | 664 | DO j = nys_x, nyn_x |
---|
[1] | 665 | |
---|
[4591] | 666 | work = ddd(0:nx,j,k) |
---|
| 667 | CALL fft_x_1d( work, 'forward' ) |
---|
[1786] | 668 | |
---|
[4591] | 669 | ddd(0,j,k) = dx * work(0)**2 |
---|
| 670 | DO i = 1, nx/2 |
---|
| 671 | ddd(i,j,k) = dx * ( work(i)**2 + work(nx+1-i)**2 ) |
---|
[1] | 672 | ENDDO |
---|
| 673 | |
---|
[4591] | 674 | ENDDO |
---|
| 675 | |
---|
[1] | 676 | ! |
---|
[4591] | 677 | !-- Local sum and geometric average of these spectra (WARNING: no global sum should be |
---|
| 678 | !-- performed, because floating point overflow may occur) |
---|
| 679 | DO i = 0, nx/2 |
---|
[1] | 680 | |
---|
[4591] | 681 | sums_spectra_l(i) = 1.0_wp |
---|
| 682 | DO j = nys_x, nyn_x |
---|
| 683 | sums_spectra_l(i) = sums_spectra_l(i) * ddd(i,j,k)**exponent |
---|
[1] | 684 | ENDDO |
---|
| 685 | |
---|
[4591] | 686 | ENDDO |
---|
[1] | 687 | |
---|
[4591] | 688 | ELSE |
---|
[1] | 689 | |
---|
[4591] | 690 | sums_spectra_l = 1.0_wp |
---|
| 691 | |
---|
| 692 | ENDIF |
---|
| 693 | |
---|
[1] | 694 | ! |
---|
[4591] | 695 | !-- Global sum of spectra on PE0 (from where they are written on file) |
---|
| 696 | sums_spectra(:,n) = 0.0_wp |
---|
| 697 | #if defined( __parallel ) |
---|
| 698 | CALL MPI_BARRIER( comm2d, ierr ) ! Necessary? |
---|
| 699 | CALL MPI_REDUCE( sums_spectra_l(0), sums_spectra(0,n), nx/2+1, MPI_REAL, MPI_PROD, 0, & |
---|
| 700 | comm2d, ierr ) |
---|
[1] | 701 | #else |
---|
[4591] | 702 | sums_spectra(:,n) = sums_spectra_l |
---|
[1] | 703 | #endif |
---|
[1431] | 704 | ! |
---|
[4591] | 705 | !-- Normalize spectra by variance |
---|
| 706 | sum_spec_dum = SUM( sums_spectra(1:nx/2,n) ) |
---|
[2215] | 707 | |
---|
[4591] | 708 | IF ( sum_spec_dum /= 0.0_wp ) THEN |
---|
| 709 | sums_spectra(1:nx/2,n) = sums_spectra(1:nx/2,n) * var_d(k) / sum_spec_dum |
---|
| 710 | ENDIF |
---|
| 711 | n = n + 1 |
---|
[1] | 712 | |
---|
[4591] | 713 | ENDDO |
---|
| 714 | n = n - 1 |
---|
[1] | 715 | |
---|
[4591] | 716 | IF ( myid == 0 ) THEN |
---|
[1] | 717 | ! |
---|
[4591] | 718 | !-- Sum of spectra for later averaging (see routine data_output_spectra) |
---|
| 719 | DO i = 1, nx/2 |
---|
| 720 | DO k = 1, n |
---|
| 721 | spectrum_x(i,k,m) = spectrum_x(i,k,m) + sums_spectra(i,k) |
---|
[1] | 722 | ENDDO |
---|
[4591] | 723 | ENDDO |
---|
[1] | 724 | |
---|
[4591] | 725 | ENDIF |
---|
[1] | 726 | ! |
---|
[4591] | 727 | !-- n_sp_x is needed by data_output_spectra_x |
---|
| 728 | n_sp_x = n |
---|
[1] | 729 | |
---|
[4591] | 730 | END SUBROUTINE calc_spectra_x |
---|
[4429] | 731 | #endif |
---|
[1] | 732 | |
---|
| 733 | |
---|
[4591] | 734 | !--------------------------------------------------------------------------------------------------! |
---|
[1682] | 735 | ! Description: |
---|
| 736 | ! ------------ |
---|
| 737 | !> @todo Missing subroutine description. |
---|
[4591] | 738 | !--------------------------------------------------------------------------------------------------! |
---|
[4429] | 739 | #if defined( __parallel ) |
---|
[4591] | 740 | SUBROUTINE calc_spectra_y( ddd, m ) |
---|
[1] | 741 | |
---|
[4591] | 742 | USE fft_xy, & |
---|
| 743 | ONLY: fft_y_1d |
---|
[1320] | 744 | |
---|
[4591] | 745 | USE grid_variables, & |
---|
| 746 | ONLY: dy |
---|
[1320] | 747 | |
---|
[4591] | 748 | USE indices, & |
---|
| 749 | ONLY: nx, & |
---|
| 750 | ny |
---|
[1320] | 751 | |
---|
[4591] | 752 | USE kinds |
---|
[1320] | 753 | |
---|
[4591] | 754 | USE MPI |
---|
[2841] | 755 | |
---|
[4591] | 756 | USE pegrid, & |
---|
| 757 | ONLY: comm2d, & |
---|
| 758 | ierr, & |
---|
| 759 | myid |
---|
[1320] | 760 | |
---|
[4591] | 761 | USE transpose_indices, & |
---|
| 762 | ONLY: nxl_yd, & |
---|
| 763 | nxr_yd, & |
---|
| 764 | nzb_yd, & |
---|
| 765 | nzt_yd |
---|
[1320] | 766 | |
---|
| 767 | |
---|
[4591] | 768 | IMPLICIT NONE |
---|
[1] | 769 | |
---|
[4591] | 770 | INTEGER(iwp) :: i !< |
---|
| 771 | INTEGER(iwp) :: j !< |
---|
| 772 | INTEGER(iwp) :: k !< |
---|
| 773 | INTEGER(iwp) :: m !< |
---|
| 774 | INTEGER(iwp) :: n !< |
---|
[1320] | 775 | |
---|
[4591] | 776 | REAL(wp) :: exponent !< |
---|
| 777 | REAL(wp) :: sum_spec_dum !< wavenumber-integrated spectrum |
---|
[1] | 778 | |
---|
[4591] | 779 | REAL(wp), DIMENSION(0:ny) :: work !< |
---|
[1] | 780 | |
---|
[4591] | 781 | REAL(wp), DIMENSION(0:ny/2) :: sums_spectra_l !< |
---|
| 782 | |
---|
| 783 | REAL(wp), DIMENSION(0:ny/2,100) :: sums_spectra !< |
---|
| 784 | |
---|
| 785 | REAL(wp), DIMENSION(0:ny,nxl_yd:nxr_yd,nzb_yd:nzt_yd) :: ddd !< |
---|
| 786 | |
---|
| 787 | |
---|
[1] | 788 | ! |
---|
[4591] | 789 | !-- Exponent for geometric average |
---|
| 790 | exponent = 1.0_wp / ( nx + 1.0_wp ) |
---|
[1] | 791 | |
---|
| 792 | ! |
---|
[4591] | 793 | !-- Loop over all levels defined by the user |
---|
| 794 | n = 1 |
---|
| 795 | DO WHILE ( comp_spectra_level(n) /= 999999 .AND. n <= 100 ) |
---|
[1] | 796 | |
---|
[4591] | 797 | k = comp_spectra_level(n) |
---|
[1] | 798 | |
---|
| 799 | ! |
---|
[4591] | 800 | !-- Calculate FFT only if the corresponding level is situated on this PE |
---|
| 801 | IF ( k >= nzb_yd .AND. k <= nzt_yd ) THEN |
---|
[1] | 802 | |
---|
[4591] | 803 | DO i = nxl_yd, nxr_yd |
---|
[1] | 804 | |
---|
[4591] | 805 | work = ddd(0:ny,i,k) |
---|
| 806 | CALL fft_y_1d( work, 'forward' ) |
---|
[1786] | 807 | |
---|
[4591] | 808 | ddd(0,i,k) = dy * work(0)**2 |
---|
| 809 | DO j = 1, ny/2 |
---|
| 810 | ddd(j,i,k) = dy * ( work(j)**2 + work(ny+1-j)**2 ) |
---|
[1] | 811 | ENDDO |
---|
| 812 | |
---|
[4591] | 813 | ENDDO |
---|
| 814 | |
---|
[1] | 815 | ! |
---|
[4591] | 816 | !-- Local sum and geometric average of these spectra (WARNING: no global sum should be |
---|
| 817 | !-- performed, because floating point overflow may occur) |
---|
| 818 | DO j = 0, ny/2 |
---|
[1] | 819 | |
---|
[4591] | 820 | sums_spectra_l(j) = 1.0_wp |
---|
| 821 | DO i = nxl_yd, nxr_yd |
---|
| 822 | sums_spectra_l(j) = sums_spectra_l(j) * ddd(j,i,k)**exponent |
---|
[1] | 823 | ENDDO |
---|
| 824 | |
---|
[4591] | 825 | ENDDO |
---|
[1] | 826 | |
---|
[4591] | 827 | ELSE |
---|
[1] | 828 | |
---|
[4591] | 829 | sums_spectra_l = 1.0_wp |
---|
| 830 | |
---|
| 831 | ENDIF |
---|
| 832 | |
---|
[1] | 833 | ! |
---|
[4591] | 834 | !-- Global sum of spectra on PE0 (from where they are written on file) |
---|
| 835 | sums_spectra(:,n) = 0.0_wp |
---|
| 836 | #if defined( __parallel ) |
---|
| 837 | CALL MPI_BARRIER( comm2d, ierr ) ! Necessary? |
---|
| 838 | CALL MPI_REDUCE( sums_spectra_l(0), sums_spectra(0,n), ny/2+1, MPI_REAL, MPI_PROD, 0, & |
---|
| 839 | comm2d, ierr ) |
---|
[1] | 840 | #else |
---|
[4591] | 841 | sums_spectra(:,n) = sums_spectra_l |
---|
[1] | 842 | #endif |
---|
[1431] | 843 | ! |
---|
[4591] | 844 | !-- Normalize spectra by variance |
---|
| 845 | sum_spec_dum = SUM( sums_spectra(1:ny/2,n) ) |
---|
| 846 | IF ( sum_spec_dum /= 0.0_wp ) THEN |
---|
| 847 | sums_spectra(1:ny/2,n) = sums_spectra(1:ny/2,n) * var_d(k) / sum_spec_dum |
---|
| 848 | ENDIF |
---|
| 849 | n = n + 1 |
---|
[1] | 850 | |
---|
[4591] | 851 | ENDDO |
---|
| 852 | n = n - 1 |
---|
[1] | 853 | |
---|
| 854 | |
---|
[4591] | 855 | IF ( myid == 0 ) THEN |
---|
[1] | 856 | ! |
---|
[4591] | 857 | !-- Sum of spectra for later averaging (see routine data_output_spectra) |
---|
| 858 | DO j = 1, ny/2 |
---|
| 859 | DO k = 1, n |
---|
| 860 | spectrum_y(j,k,m) = spectrum_y(j,k,m) + sums_spectra(j,k) |
---|
[1] | 861 | ENDDO |
---|
[4591] | 862 | ENDDO |
---|
[1] | 863 | |
---|
[4591] | 864 | ENDIF |
---|
[1] | 865 | |
---|
| 866 | ! |
---|
[4591] | 867 | !-- n_sp_y is needed by data_output_spectra_y |
---|
| 868 | n_sp_y = n |
---|
[1] | 869 | |
---|
[4591] | 870 | END SUBROUTINE calc_spectra_y |
---|
[4429] | 871 | #endif |
---|
[1786] | 872 | |
---|
[1833] | 873 | END MODULE spectra_mod |
---|