- Timestamp:
- May 18, 2020 3:23:29 PM (5 years ago)
- Location:
- palm/trunk/SOURCE
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/biometeorology_mod.f90
r4535 r4540 1 1 !> @file biometeorology_mod.f90 2 !-------------------------------------------------------------------------------- !2 !--------------------------------------------------------------------------------------------------! 3 3 ! This file is part of PALM-4U. 4 4 ! 5 ! PALM-4U is free software: you can redistribute it and/or modify it under the 6 ! terms of the GNU General Public License as published by the Free Software 7 ! Foundation, either version 3 of the License, or (at your option) any later 8 ! version. 9 ! 10 ! PALM-4U is distributed in the hope that it will be useful, but WITHOUT ANY 11 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 ! A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 ! 14 ! You should have received a copy of the GNU General Public License along with 15 ! PALM. If not, see <http://www.gnu.org/licenses/>. 5 ! PALM-4U is free software: You can redistribute it and/or modify it under the terms of the GNU 6 ! General Public License as published by the Free Software Foundation, either version 3 of the 7 ! License, or (at your option) any later version. 8 ! 9 ! PALM-4U is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 10 ! the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 11 ! Public License for more details. 12 ! 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/>. 16 15 ! 17 16 ! Copyright 2018-2020 Deutscher Wetterdienst (DWD) 18 17 ! Copyright 2018-2020 Institute of Computer Science, Academy of Sciences, Prague 19 18 ! Copyright 2018-2020 Leibniz Universitaet Hannover 20 !-------------------------------------------------------------------------------- !19 !--------------------------------------------------------------------------------------------------! 21 20 ! 22 21 ! Current revisions: … … 27 26 ! ----------------- 28 27 ! $Id$ 28 ! file re-formatted to follow the PALM coding standard 29 ! 30 ! 4535 2020-05-15 12:07:23Z raasch 29 31 ! bugfix for restart data format query 30 ! 32 ! 31 33 ! 4517 2020-05-03 14:29:30Z raasch 32 34 ! added restart with MPI-IO for reading local arrays 33 ! 35 ! 34 36 ! 4495 2020-04-13 20:11:20Z raasch 35 37 ! restart data handling with MPI-IO added 36 ! 38 ! 37 39 ! 4493 2020-04-10 09:49:43Z pavelkrc 38 40 ! Revise bad formatting 39 ! 41 ! 40 42 ! 4286 2019-10-30 16:01:14Z resler 41 43 ! implement new palm_date_time_mod 42 ! 44 ! 43 45 ! 4223 2019-09-10 09:20:47Z gronemeier 44 46 ! Corrected "Former revisions" section 45 ! 47 ! 46 48 ! 4168 2019-08-16 13:50:17Z suehring 47 49 ! Replace function get_topography_top_index by topo_top_ind 48 ! 50 ! 49 51 ! 4144 2019-08-06 09:11:47Z raasch 50 52 ! relational operators .EQ., .NE., etc. replaced by ==, /=, etc. 51 ! 53 ! 52 54 ! 4127 2019-07-30 14:47:10Z suehring 53 55 ! Output for bio_mrt added (merge from branch resler) 54 ! 56 ! 55 57 ! 4126 2019-07-30 11:09:11Z gronemeier 56 58 ! renamed vitd3_exposure_av into vitd3_dose, 57 59 ! renamed uvem_calc_exposure into bio_calculate_uv_exposure 58 ! 60 ! 59 61 ! 3885 2019-04-11 11:29:34Z kanani 60 ! Changes related to global restructuring of location messages and introduction 61 ! of additional debugmessages62 ! 62 ! Changes related to global restructuring of location messages and introduction of additional debug 63 ! messages 64 ! 63 65 ! 3753 2019-02-19 14:48:54Z dom_dwd_user 64 ! - Added automatic setting of mrt_nlevels in case it was not part of 65 ! radiation_parameters namelist(or set to 0 accidentially).66 ! - Added automatic setting of mrt_nlevels in case it was not part of radiation_parameters namelist 67 ! (or set to 0 accidentially). 66 68 ! - Minor speed improvoemnts in perceived temperature calculations. 67 69 ! - Perceived temperature regression arrays now declared as PARAMETERs. 68 ! 70 ! 69 71 ! 3750 2019-02-19 07:29:39Z dom_dwd_user 70 72 ! - Added addittional safety meassures to bio_calculate_thermal_index_maps. 71 73 ! - Replaced several REAL (un-)equality comparisons. 72 ! 74 ! 73 75 ! 3742 2019-02-14 11:25:22Z dom_dwd_user 74 ! - Allocation of the input _av grids was moved to the "sum" section of 75 ! bio_3d_data_averaging tomake sure averaging is only done once!76 ! - Moved call of bio_calculate_thermal_index_maps from biometeorology module to 77 ! time_integration tomake sure averaged input is updated before calculating.78 ! 76 ! - Allocation of the input _av grids was moved to the "sum" section of bio_3d_data_averaging to 77 ! make sure averaging is only done once! 78 ! - Moved call of bio_calculate_thermal_index_maps from biometeorology module to time_integration to 79 ! make sure averaged input is updated before calculating. 80 ! 79 81 ! 3740 2019-02-13 12:35:12Z dom_dwd_user 80 ! - Added safety-meassure to catch the case that 'bio_mrt_av' is stated after 81 ! 'bio_<index>' in theoutput section of the p3d file.82 ! 82 ! - Added safety-meassure to catch the case that 'bio_mrt_av' is stated after 'bio_<index>' in the 83 ! output section of the p3d file. 84 ! 83 85 ! 3739 2019-02-13 08:05:17Z dom_dwd_user 84 ! - Auto-adjusting thermal_comfort flag if not set by user, but thermal_indices 85 ! set as outputquantities.86 ! - Auto-adjusting thermal_comfort flag if not set by user, but thermal_indices set as output 87 ! quantities. 86 88 ! - Renamed flags "bio_<index>" to "do_calculate_<index>" for better readability 87 89 ! - Removed everything related to "time_bio_results" as this is never used. 88 ! - Moved humidity warning to check_data_output 90 ! - Moved humidity warning to check_data_output. 89 91 ! - Fixed bug in mrt calculation introduced with my commit yesterday. 90 ! 92 ! 91 93 ! 3735 2019-02-12 09:52:40Z dom_dwd_user 92 ! - Fixed auto-setting of thermal index calculation flags by output 93 ! as originally proposed byresler.94 ! - Fixed auto-setting of thermal index calculation flags by output as originally proposed by 95 ! resler. 94 96 ! - removed bio_pet and outher configuration variables. 95 97 ! - Updated namelist. 96 ! 98 ! 97 99 ! 3711 2019-01-31 13:44:26Z knoop 98 100 ! Introduced interface routine bio_init_checks + small error message changes 99 ! 101 ! 100 102 ! 3693 2019-01-23 15:20:53Z dom_dwd_user 101 ! Added usage of time_averaged mean radiant temperature, together with calculation, 102 ! grid and restartroutines. General cleanup and commenting.103 ! 103 ! Added usage of time_averaged mean radiant temperature, together with calculation, grid and restart 104 ! routines. General cleanup and commenting. 105 ! 104 106 ! 3685 2019-01-21 01:02:11Z knoop 105 107 ! Some interface calls moved to module_interface + cleanup 106 ! 108 ! 107 109 ! 3650 2019-01-04 13:01:33Z kanani 108 110 ! Bugfixes and additions for enabling restarts with biometeorology 109 ! 111 ! 110 112 ! 3448 2018-10-29 18:14:31Z kanani 111 113 ! Initial revision 112 114 ! 113 ! 115 ! 114 116 ! 115 117 ! Authors: … … 123 125 ! ------------ 124 126 !> Biometeorology module consisting of two parts: 125 !> 1.: Human thermal comfort module calculating thermal perception of a sample 126 !> human being under thecurrent meteorological conditions.127 !> 1.: Human thermal comfort module calculating thermal perception of a sample human being under the 128 !> current meteorological conditions. 127 129 !> 2.: Calculation of vitamin-D weighted UV exposure 128 130 !> 129 131 !> @todo Alphabetical sorting of "USE ..." lists, "ONLY" list, variable declarations 130 132 !> (per subroutine: first all CHARACTERs, then INTEGERs, LOGICALs, REALs, ) 131 !> @todo Comments start with capital letter --> "!-- Include..." 133 !> @todo Comments start with capital letter --> "!-- Include..." 132 134 !> @todo uv_vitd3dose-->new output type necessary (cumulative) 133 135 !> @todo consider upwelling radiation in UV … … 136 138 !> 137 139 !> @bug no known bugs by now 138 !------------------------------------------------------------------------------ !140 !--------------------------------------------------------------------------------------------------! 139 141 MODULE biometeorology_mod 140 142 141 USE arrays_3d, &143 USE arrays_3d, & 142 144 ONLY: pt, p, u, v, w, q 143 145 144 USE averaging, &146 USE averaging, & 145 147 ONLY: pt_av, q_av, u_av, v_av, w_av 146 148 147 USE basic_constants_and_equations_mod, &148 ONLY: c_p, degc_to_k, l_v, magnus, sigma_sb, pi149 150 USE control_parameters, &151 ONLY: average_count_3d, biometeorology, &152 debug_output, &153 dz, dz_stretch_factor, &154 dz_stretch_level, humidity, initializing_actions, nz_do3d, &149 USE basic_constants_and_equations_mod, & 150 ONLY: degc_to_k, c_p, l_v, magnus, pi, sigma_sb 151 152 USE control_parameters, & 153 ONLY: average_count_3d, biometeorology, & 154 debug_output, & 155 dz, dz_stretch_factor, & 156 dz_stretch_level, humidity, initializing_actions, nz_do3d, & 155 157 restart_data_format_output, surface_pressure 156 158 157 USE grid_variables, &159 USE grid_variables, & 158 160 ONLY: ddx, dx, ddy, dy 159 161 160 USE indices, &161 ONLY: nxl, nxr, nys, nyn, nzb, nzt, nys, nyn, nxl, nxr, nxlg, nxrg, &162 nysg, nyng,topo_top_ind162 USE indices, & 163 ONLY: nxl, nxr, nys, nyn, nzb, nzt, nys, nyn, nxl, nxr, nxlg, nxrg, nysg, nyng, & 164 topo_top_ind 163 165 164 166 USE kinds !< Set precision of INTEGER and REAL arrays according to PALM 165 167 166 USE netcdf_data_input_mod, &167 ONLY: netcdf_data_input_uvem, uvem_projarea_f, uvem_radiance_f,&168 uvem_irradiance_f, uvem_integration_f, building_obstruction_f169 170 USE palm_date_time_mod, &168 USE netcdf_data_input_mod, & 169 ONLY: building_obstruction_f, netcdf_data_input_uvem, uvem_integration_f, & 170 uvem_irradiance_f, uvem_projarea_f, uvem_radiance_f 171 172 USE palm_date_time_mod, & 171 173 ONLY: get_date_time 172 174 ! 173 175 !-- Import radiation model to obtain input for mean radiant temperature 174 USE radiation_model_mod, & 175 ONLY: ix, iy, iz, id, mrt_nlevels, mrt_include_sw, & 176 mrtinsw, mrtinlw, mrtbl, nmrtbl, radiation, & 177 radiation_interactions, rad_sw_in, & 178 rad_sw_out, rad_lw_in, rad_lw_out 176 USE radiation_model_mod, & 177 ONLY: id, ix, iy, iz, mrt_include_sw, mrt_nlevels, & 178 mrtbl, mrtinlw, mrtinsw, nmrtbl, radiation, & 179 rad_lw_in, rad_lw_out, rad_sw_in, rad_sw_out, radiation_interactions 179 180 180 181 USE restart_data_mpi_io_mod, & … … 184 185 IMPLICIT NONE 185 186 186 PRIVATE187 188 187 ! 189 188 !-- Declare all global variables within the module (alphabetical order) 190 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: tmrt_grid !< tmrt results (degree_C) 191 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: perct !< PT results (degree_C) 192 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: utci !< UTCI results (degree_C) 193 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: pet !< PET results (degree_C) 194 ! 195 !-- Grids for averaged thermal indices 196 REAL(wp), DIMENSION(:), ALLOCATABLE :: mrt_av_grid !< time average mean 197 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: tmrt_av_grid !< tmrt results (degree_C) 198 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: perct_av !< PT results (aver. input) (degree_C) 199 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: utci_av !< UTCI results (aver. input) (degree_C) 200 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: pet_av !< PET results (aver. input) (degree_C) 201 202 203 INTEGER( iwp ) :: bio_cell_level !< cell level biom calculates for 204 REAL ( wp ) :: bio_output_height !< height output is calculated in m 205 REAL ( wp ), PARAMETER :: human_absorb = 0.7_wp !< SW absorbtivity of a human body (Fanger 1972) 206 REAL ( wp ), PARAMETER :: human_emiss = 0.97_wp !< LW emissivity of a human body after (Fanger 1972) 207 REAL ( wp ), PARAMETER :: bio_fill_value = -9999._wp !< set module fill value, replace by global fill value as soon as available 208 ! 209 !-- 210 LOGICAL :: thermal_comfort = .FALSE. !< Enables or disables the entire thermal comfort part 211 LOGICAL :: do_average_theta = .FALSE. !< switch: do theta averaging in this module? (if .FALSE. this is done globally) 212 LOGICAL :: do_average_q = .FALSE. !< switch: do e averaging in this module? 213 LOGICAL :: do_average_u = .FALSE. !< switch: do u averaging in this module? 214 LOGICAL :: do_average_v = .FALSE. !< switch: do v averaging in this module? 215 LOGICAL :: do_average_w = .FALSE. !< switch: do w averaging in this module? 216 LOGICAL :: do_average_mrt = .FALSE. !< switch: do mrt averaging in this module? 189 INTEGER(iwp) :: bio_cell_level !< cell level biom calculates for 190 191 LOGICAL :: thermal_comfort = .FALSE. !< Enables or disables the entire thermal comfort part 192 LOGICAL :: do_average_theta = .FALSE. !< switch: do theta averaging in this module? (if .FALSE. this is done globally) 193 LOGICAL :: do_average_q = .FALSE. !< switch: do e averaging in this module? 194 LOGICAL :: do_average_u = .FALSE. !< switch: do u averaging in this module? 195 LOGICAL :: do_average_v = .FALSE. !< switch: do v averaging in this module? 196 LOGICAL :: do_average_w = .FALSE. !< switch: do w averaging in this module? 197 LOGICAL :: do_average_mrt = .FALSE. !< switch: do mrt averaging in this module? 217 198 LOGICAL :: average_trigger_perct = .FALSE. !< update averaged input on call to bio_perct? 218 199 LOGICAL :: average_trigger_utci = .FALSE. !< update averaged input on call to bio_utci? … … 227 208 LOGICAL :: do_calculate_mrt2d = .FALSE. !< Turn index MRT 2D (averaged or inst) on or off 228 209 210 REAL(wp) :: bio_output_height !< height output is calculated in m 211 212 REAL(wp), PARAMETER :: bio_fill_value = -9999.0_wp !< set module fill value, replace by global fill value as soon as available 213 REAL(wp), PARAMETER :: human_absorb = 0.7_wp !< SW absorbtivity of a human body (Fanger 1972) 214 REAL(wp), PARAMETER :: human_emiss = 0.97_wp !< LW emissivity of a human body after (Fanger 1972) 215 216 REAL(wp), DIMENSION(:), ALLOCATABLE :: mrt_av_grid !< time average mean 217 218 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: perct !< PT results (degree_C) 219 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: pet !< PET results (degree_C) 220 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: tmrt_grid !< tmrt results (degree_C) 221 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: utci !< UTCI results (degree_C) 222 ! 223 !-- Grids for averaged thermal indices 224 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: perct_av !< PT results (aver. input) (degree_C) 225 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: pet_av !< PET results (aver. input) (degree_C) 226 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: tmrt_av_grid !< tmrt results (degree_C) 227 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: utci_av !< UTCI results (aver. input) (degree_C) 228 229 229 ! 230 230 !-- UVEM parameters from here 231 !232 !-- Declare all global variables within the module (alphabetical order)233 INTEGER(iwp) :: bio_nmrtbl234 231 INTEGER(iwp) :: ai = 0 !< loop index in azimuth direction 235 232 INTEGER(iwp) :: bi = 0 !< loop index of bit location within an 8bit-integer (one Byte) 233 INTEGER(iwp) :: bio_nmrtbl 236 234 INTEGER(iwp) :: clothing = 1 !< clothing (0=unclothed, 1=Arms,Hands,Face free, 3=Hand,Face free) 237 235 INTEGER(iwp) :: iq = 0 !< loop index of irradiance quantity 238 236 INTEGER(iwp) :: pobi = 0 !< loop index of the position of corresponding byte within ibset byte vektor 239 INTEGER(iwp) :: obstruction_direct_beam = 0 !< Obstruction information for direct beam 237 INTEGER(iwp) :: obstruction_direct_beam = 0 !< Obstruction information for direct beam 240 238 INTEGER(iwp) :: zi = 0 !< loop index in zenith direction 241 239 242 INTEGER(KIND=1), DIMENSION(0:44) :: obstruction_temp1 = 0 !< temporary obstruction information stored with ibset 240 INTEGER(KIND=1), DIMENSION(0:44) :: obstruction_temp1 = 0 !< temporary obstruction information stored with ibset 243 241 INTEGER(iwp), DIMENSION(0:359) :: obstruction_temp2 = 0 !< restored temporary obstruction information from ibset file 244 242 … … 251 249 252 250 REAL(wp) :: diffuse_exposure = 0.0_wp !< calculated exposure by diffuse radiation 253 REAL(wp) :: direct_exposure = 0.0_wp !< calculated exposure by direct solar beam 254 REAL(wp) :: orientation_angle = 0.0_wp !< orientation of front/face of the human model 251 REAL(wp) :: direct_exposure = 0.0_wp !< calculated exposure by direct solar beam 252 REAL(wp) :: orientation_angle = 0.0_wp !< orientation of front/face of the human model 255 253 REAL(wp) :: projection_area_direct_beam = 0.0_wp !< projection area for direct solar beam 256 254 REAL(wp) :: saa = 180.0_wp !< solar azimuth angle … … 261 259 REAL(wp) :: yfactor = 0.0_wp !< relative y-position used for interpolation 262 260 263 REAL(wp), DIMENSION(0:2) :: irradiance = 0.0_wp !< iradiance values extracted from irradiance lookup table 261 REAL(wp), DIMENSION(0:2) :: irradiance = 0.0_wp !< iradiance values extracted from irradiance lookup table 264 262 265 263 REAL(wp), DIMENSION(0:2,0:90) :: irradiance_lookup_table = 0.0_wp !< irradiance lookup table … … 269 267 REAL(wp), DIMENSION(0:71,0:9) :: projection_area_direct_temp = 0.0_wp !< temporary projection area for direct solar beam 270 268 REAL(wp), DIMENSION(0:71,0:9) :: projection_area_temp = 0.0_wp !< temporary projection area for all directions 271 REAL(wp), DIMENSION(0:35,0:9) :: radiance_array = 0.0_wp !< radiance extracted from radiance_lookup_table 269 REAL(wp), DIMENSION(0:35,0:9) :: radiance_array = 0.0_wp !< radiance extracted from radiance_lookup_table 272 270 REAL(wp), DIMENSION(0:71,0:9) :: radiance_array_temp = 0.0_wp !< temporary radiance data 273 271 … … 277 275 REAL(wp), DIMENSION(0:35,0:9,0:90) :: radiance_lookup_table = 0.0_wp !< radiance lookup table 278 276 277 278 PRIVATE 279 279 280 ! 280 281 !-- INTERFACES that must be available to other modules (alphabetical order) 281 282 PUBLIC bio_3d_data_averaging, bio_check_data_output, & 283 bio_calculate_mrt_grid, bio_calculate_thermal_index_maps, bio_calc_ipt, & 284 bio_check_parameters, bio_data_output_3d, bio_data_output_2d, & 285 bio_define_netcdf_grid, bio_get_thermal_index_input_ij, bio_header, & 286 bio_init, bio_init_checks, bio_parin, thermal_comfort, & 287 bio_nmrtbl, bio_wrd_local, bio_rrd_local, bio_wrd_global, bio_rrd_global 282 PUBLIC bio_3d_data_averaging, bio_calculate_mrt_grid, bio_calculate_thermal_index_maps, & 283 bio_calc_ipt, bio_check_data_output, bio_check_parameters, & 284 bio_data_output_2d, bio_data_output_3d, bio_define_netcdf_grid, & 285 bio_get_thermal_index_input_ij, bio_header, bio_init, bio_init_checks, bio_nmrtbl, & 286 bio_parin, bio_rrd_global, bio_rrd_local, bio_wrd_global, bio_wrd_local, thermal_comfort 288 287 ! 289 288 !-- UVEM PUBLIC variables and methods … … 348 347 END INTERFACE bio_header 349 348 ! 350 !-- Initialization actions 349 !-- Initialization actions 351 350 INTERFACE bio_init 352 351 MODULE PROCEDURE bio_init … … 393 392 394 393 395 !------------------------------------------------------------------------------ !394 !--------------------------------------------------------------------------------------------------! 396 395 ! Description: 397 396 ! ------------ 398 !> Sum up and time-average biom input quantities as well as allocate 399 !> the array necessary for storing the average. 400 !> There is a considerable difference to the 3d_data_averaging subroutines 401 !> used by other modules: 402 !> For the thermal indices, the module needs to average the input conditions 403 !> not the result! 404 !------------------------------------------------------------------------------! 397 !> Sum up and time-average biom input quantities as well as allocate the array necessary for storing 398 !> the average. 399 !> There is a considerable difference to the 3d_data_averaging subroutines used by other modules: 400 !> For the thermal indices, the module needs to average the input conditions, not the result! 401 !--------------------------------------------------------------------------------------------------! 405 402 SUBROUTINE bio_3d_data_averaging( mode, variable ) 406 403 407 404 IMPLICIT NONE 408 405 409 CHARACTER (LEN=*) :: mode !< averaging mode: allocate, sum, or average406 CHARACTER (LEN=*) :: mode !< Averaging mode: allocate, sum, or average 410 407 CHARACTER (LEN=*) :: variable !< The variable in question 411 408 … … 425 422 ENDIF 426 423 mrt_av_grid = 0.0_wp 427 do_average_mrt = .FALSE. !< overwrite if that was enabled somehow424 do_average_mrt = .FALSE. !< Overwrite if that was enabled somehow 428 425 429 426 … … 431 428 432 429 ! 433 !-- Averaging, as well as the allocation of the required grids must be 434 !-- done only once, independent from for how many thermal indices 435 !-- averaged output is desired. 436 !-- Therefore wee need to memorize which index is the one that controls 437 !-- the averaging (what must be the first thermal index called). 438 !-- Indices are in unknown order as depending on the input file, 439 !-- determine first index to average und update only once 440 ! 441 !-- Only proceed here if this was not done for any index before. This 442 !-- is done only once during the whole model run. 443 IF ( .NOT. average_trigger_perct .AND. & 444 .NOT. average_trigger_utci .AND. & 445 .NOT. average_trigger_pet .AND. & 430 !-- Averaging, as well as the allocation of the required grids must be done only once, 431 !-- independent of for how many thermal indices averaged output is desired. 432 !-- Therefore we need to memorize which index is the one that controls the averaging 433 !-- (what must be the first thermal index called). 434 !-- Indices are in unknown order as depending on the input file, determine first index to 435 !-- average und update only once. 436 ! 437 !-- Only proceed here if this was not done for any index before. This is done only once 438 !-- during the whole model run. 439 IF ( .NOT. average_trigger_perct .AND. & 440 .NOT. average_trigger_utci .AND. & 441 .NOT. average_trigger_pet .AND. & 446 442 .NOT. average_trigger_mrt ) THEN 447 443 ! … … 461 457 ENDIF 462 458 ! 463 !-- Allocation of the input _av grids was moved to the "sum" section to 464 !-- make sure averaging is only done once! 465 459 !-- Allocation of the input _av grids was moved to the "sum" section to make sure averaging 460 !-- is only done once! 466 461 467 462 CASE ( 'uvem_vitd3dose*' ) 463 468 464 IF ( .NOT. ALLOCATED( vitd3_dose ) ) THEN 469 465 ALLOCATE( vitd3_dose(nysg:nyng,nxlg:nxrg) ) … … 482 478 CASE ( 'bio_mrt' ) 483 479 ! 484 !-- Consider the case 'bio_mrt' is called after some thermal index. In 485 !-- that case do_average_mrt will be .TRUE. leading to a double- 486 !-- averaging. 480 !-- Consider the case 'bio_mrt' is called after some thermal index. In that case 481 ! do_average_mrt will be .TRUE. leading to a double-averaging. 487 482 IF ( .NOT. do_average_mrt .AND. ALLOCATED( mrt_av_grid ) ) THEN 488 483 489 484 IF ( mrt_include_sw ) THEN 490 mrt_av_grid(:) = mrt_av_grid(:) + & 491 ( ( human_absorb * mrtinsw(:) + & 492 mrtinlw(:) ) / & 493 ( human_emiss * sigma_sb ) )**.25_wp - degc_to_k 485 mrt_av_grid(:) = mrt_av_grid(:) + & 486 ( ( human_absorb * mrtinsw(:) + & 487 mrtinlw(:) ) / ( human_emiss * sigma_sb ) )**.25_wp - degc_to_k 494 488 ELSE 495 mrt_av_grid(:) = mrt_av_grid(:) + & 496 ( mrtinlw(:) / & 497 ( human_emiss * sigma_sb ) )**.25_wp - degc_to_k 489 mrt_av_grid(:) = mrt_av_grid(:) + & 490 ( mrtinlw(:) / ( human_emiss * sigma_sb ) )**.25_wp - degc_to_k 498 491 ENDIF 499 492 ENDIF … … 501 494 CASE ( 'bio_perct*', 'bio_utci*', 'bio_pet*', 'bio_mrt*' ) 502 495 ! 503 !-- Only continue if the current index is the one to trigger the input 504 !-- averaging, see above 505 IF ( average_trigger_perct .AND. TRIM( variable ) /= & 506 'bio_perct*') RETURN 507 IF ( average_trigger_utci .AND. TRIM( variable ) /= & 508 'bio_utci*') RETURN 509 IF ( average_trigger_pet .AND. TRIM( variable ) /= & 510 'bio_pet*') RETURN 511 IF ( average_trigger_mrt .AND. TRIM( variable ) /= & 512 'bio_mrt*') RETURN 513 ! 514 !-- Now memorize which of the input grids are not averaged by other 515 !-- modules. Set averaging switch to .TRUE. and allocate the respective 516 !-- grid in that case. 496 !-- Only continue if the current index is the one to trigger the input averaging, see 497 !-- above. 498 IF ( average_trigger_perct .AND. TRIM( variable ) /= 'bio_perct*') RETURN 499 IF ( average_trigger_utci .AND. TRIM( variable ) /= 'bio_utci*' ) RETURN 500 IF ( average_trigger_pet .AND. TRIM( variable ) /= 'bio_pet*' ) RETURN 501 IF ( average_trigger_mrt .AND. TRIM( variable ) /= 'bio_mrt*' ) RETURN 502 ! 503 !-- Now memorize which of the input grids are not averaged by other modules. Set averaging 504 !-- switch to .TRUE. and allocate the respective grid in that case. 517 505 IF ( .NOT. ALLOCATED( pt_av ) ) THEN !< if not averaged by other module 518 506 ALLOCATE( pt_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) … … 546 534 547 535 ! 548 !-- u_av, v_av and w_av are always allocated536 !-- u_av, v_av and w_av are always allocated 549 537 IF ( .NOT. ALLOCATED( u_av ) ) THEN 550 538 ALLOCATE( u_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) … … 600 588 601 589 IF ( mrt_include_sw ) THEN 602 mrt_av_grid(:) = mrt_av_grid(:) + &603 ( ( human_absorb * mrtinsw(:) +&604 mrtinlw(:) ) /&605 ( human_emiss * sigma_sb ) )**.25_wp - degc_to_k606 607 mrt_av_grid(:) = mrt_av_grid(:) + &608 ( mrtinlw(:) /&609 ( human_emiss * sigma_sb ) )**.25_wp - degc_to_k590 mrt_av_grid(:) = mrt_av_grid(:) + & 591 ( ( human_absorb * mrtinsw(:) + & 592 mrtinlw(:) ) / & 593 ( human_emiss * sigma_sb ) )**0.25_wp - degc_to_k 594 ELSE 595 mrt_av_grid(:) = mrt_av_grid(:) + & 596 ( mrtinlw(:) / & 597 ( human_emiss * sigma_sb ) )**0.25_wp - degc_to_k 610 598 ENDIF 611 599 ENDIF … … 632 620 CASE ( 'bio_mrt' ) 633 621 ! 634 !-- Consider the case 'bio_mrt' is called after some thermal index. In 635 !-- that case do_average_mrt will be .TRUE. leading to a double- 636 !-- averaging. 622 !-- Consider the case 'bio_mrt' is called after some thermal index. In that case 623 !-- do_average_mrt will be .TRUE. leading to a double-averaging. 637 624 IF ( .NOT. do_average_mrt .AND. ALLOCATED( mrt_av_grid ) ) THEN 638 625 mrt_av_grid(:) = mrt_av_grid(:) / REAL( average_count_3d, KIND=wp ) … … 642 629 ! 643 630 !-- Only continue if update index, see above 644 IF ( average_trigger_perct .AND. &631 IF ( average_trigger_perct .AND. & 645 632 TRIM( variable ) /= 'bio_perct*' ) RETURN 646 IF ( average_trigger_utci .AND. &633 IF ( average_trigger_utci .AND. & 647 634 TRIM( variable ) /= 'bio_utci*' ) RETURN 648 IF ( average_trigger_pet .AND. &635 IF ( average_trigger_pet .AND. & 649 636 TRIM( variable ) /= 'bio_pet*' ) RETURN 650 IF ( average_trigger_mrt .AND. &637 IF ( average_trigger_mrt .AND. & 651 638 TRIM( variable ) /= 'bio_mrt*' ) RETURN 652 639 … … 655 642 DO j = nys, nyn 656 643 DO k = nzb, nzt+1 657 pt_av(k,j,i) = pt_av(k,j,i) / & 658 REAL( average_count_3d, KIND=wp ) 644 pt_av(k,j,i) = pt_av(k,j,i) / REAL( average_count_3d, KIND = wp ) 659 645 ENDDO 660 646 ENDDO … … 666 652 DO j = nys, nyn 667 653 DO k = nzb, nzt+1 668 q_av(k,j,i) = q_av(k,j,i) / & 669 REAL( average_count_3d, KIND=wp ) 654 q_av(k,j,i) = q_av(k,j,i) / REAL( average_count_3d, KIND = wp ) 670 655 ENDDO 671 656 ENDDO … … 677 662 DO j = nysg, nyng 678 663 DO k = nzb, nzt+1 679 u_av(k,j,i) = u_av(k,j,i) / & 680 REAL( average_count_3d, KIND=wp ) 664 u_av(k,j,i) = u_av(k,j,i) / REAL( average_count_3d, KIND = wp ) 681 665 ENDDO 682 666 ENDDO … … 688 672 DO j = nysg, nyng 689 673 DO k = nzb, nzt+1 690 v_av(k,j,i) = v_av(k,j,i) / & 691 REAL( average_count_3d, KIND=wp ) 674 v_av(k,j,i) = v_av(k,j,i) / REAL( average_count_3d, KIND = wp ) 692 675 ENDDO 693 676 ENDDO … … 699 682 DO j = nysg, nyng 700 683 DO k = nzb, nzt+1 701 w_av(k,j,i) = w_av(k,j,i) / & 702 REAL( average_count_3d, KIND=wp ) 684 w_av(k,j,i) = w_av(k,j,i) / REAL( average_count_3d, KIND = wp ) 703 685 ENDDO 704 686 ENDDO … … 707 689 708 690 IF ( ALLOCATED( mrt_av_grid ) .AND. do_average_mrt ) THEN 709 mrt_av_grid(:) = mrt_av_grid(:) / REAL( average_count_3d, & 710 KIND=wp ) 691 mrt_av_grid(:) = mrt_av_grid(:) / REAL( average_count_3d, KIND = wp ) 711 692 ENDIF 712 693 713 694 ! 714 !-- No averaging for UVEM since we are calculating a dose (only sum is 715 !-- calculated and saved to av.nc file) 716 695 !-- No averaging for UVEM SINce we are calculating a dose (only sum is calculated and saved to 696 !-- av.nc file) 717 697 END SELECT 718 698 … … 724 704 725 705 726 !------------------------------------------------------------------------------ !706 !--------------------------------------------------------------------------------------------------! 727 707 ! Description: 728 708 ! ------------ 729 709 !> Check data output for biometeorology model 730 !------------------------------------------------------------------------------ !710 !--------------------------------------------------------------------------------------------------! 731 711 SUBROUTINE bio_check_data_output( var, unit, i, j, ilen, k ) 732 712 733 USE control_parameters, &713 USE control_parameters, & 734 714 ONLY: data_output, message_string 735 715 … … 747 727 ! 748 728 !-- Allocate a temporary array with the desired output dimensions. 749 !-- Arrays for time-averaged thermal indices are also allocated here because 750 !-- they are not running through the standard averaging procedure in 751 !-- bio_3d_data_averaging as the values of the averaged thermal indices are 752 !-- derived in a single step based on priorly averaged arrays (see 729 !-- Arrays for time-averaged thermal indices are also allocated here because they are not running 730 !-- through the standard averaging procedure in bio_3d_data_averaging as the values of the 731 !-- averaged thermal indices are derived in a SINgle step based on priorly averaged arrays (see 753 732 !-- bio_calculate_thermal_index_maps). 754 733 CASE ( 'bio_mrt', 'bio_mrt*' ) … … 772 751 perct = REAL( bio_fill_value, KIND = wp ) 773 752 ENDIF 774 ELSE !< if averaged input753 ELSE !< if averaged input 775 754 do_calculate_perct_av = .TRUE. 776 755 IF ( .NOT. ALLOCATED( perct_av ) ) THEN … … 816 795 817 796 CASE ( 'uvem_vitd3*' ) 818 ! IF ( .NOT.uv_exposure ) THEN819 ! message_string = 'output of "' // TRIM( var ) // '" requi' // &797 ! IF ( .NOT. uv_exposure ) THEN 798 ! message_string = 'output of "' // TRIM( var ) // '" requi' // & 820 799 ! 'res a namelist &uvexposure_par' 821 800 ! CALL message( 'uvem_check_data_output', 'UV0001', 1, 2, 0, 6, 0 ) 822 801 ! ENDIF 823 802 IF ( k == 0 .OR. data_output(i)(ilen-2:ilen) /= '_xy' ) THEN 824 message_string = 'illegal value for data_output: "' // &825 TRIM( var ) // '" & only 2d-horizontal ' // &803 message_string = 'illegal value for data_output: "' // & 804 TRIM( var ) // '" & only 2d-horizontal ' // & 826 805 'cross sections are allowed for this value' 827 806 CALL message( 'check_parameters', 'PA0111', 1, 2, 0, 6, 0 ) … … 840 819 ! ENDIF 841 820 IF ( k == 0 .OR. data_output(i)(ilen-2:ilen) /= '_xy' ) THEN 842 message_string = 'illegal value for data_output: "' // &843 TRIM( var ) // '" & only 2d-horizontal ' // &821 message_string = 'illegal value for data_output: "' // & 822 TRIM( var ) // '" & only 2d-horizontal ' // & 844 823 'cross sections are allowed for this value' 845 824 CALL message( 'check_parameters', 'PA0111', 1, 2, 0, 6, 0 ) … … 857 836 858 837 ! 859 !-- 838 !-- Further checks if thermal comfort output is desired. 860 839 IF ( thermal_comfort .AND. unit == 'degree_C' ) THEN 861 840 ! 862 !-- Break if required modules "radiation" is not ava lable.841 !-- Break if required modules "radiation" is not available. 863 842 IF ( .NOT. radiation ) THEN 864 message_string = 'output of "' // TRIM( var ) // '" require' & 865 // 's radiation = .TRUE.' 843 message_string = 'output of "' // TRIM( var ) // '" require' // 's radiation = .TRUE.' 866 844 CALL message( 'check_parameters', 'PA0509', 1, 2, 0, 6, 0 ) 867 845 unit = 'illegal' 868 846 ENDIF 869 847 ! 870 !-- All "thermal_comfort" outputs except from 'bio_mrt' will also need 871 !-- humidity input. Checkalso for that.848 !-- All "thermal_comfort" outputs except from 'bio_mrt' will also need humidity input. Check 849 !-- also for that. 872 850 IF ( TRIM( var ) /= 'bio_mrt' ) THEN 873 851 IF ( .NOT. humidity ) THEN 874 message_string = 'The estimation of thermal comfort ' // &875 'requires air humidity information, but ' // &852 message_string = 'The estimation of thermal comfort ' // & 853 'requires air humidity information, but ' // & 876 854 'humidity module is disabled!' 877 855 CALL message( 'check_parameters', 'PA0561', 1, 2, 0, 6, 0 ) … … 885 863 END SUBROUTINE bio_check_data_output 886 864 887 !------------------------------------------------------------------------------ !865 !--------------------------------------------------------------------------------------------------! 888 866 ! Description: 889 867 ! ------------ 890 868 !> Check parameters routine for biom module 891 869 !> Currently unused but might come in handy for future checks? 892 !------------------------------------------------------------------------------ !870 !--------------------------------------------------------------------------------------------------! 893 871 SUBROUTINE bio_check_parameters 894 872 … … 897 875 898 876 899 900 877 END SUBROUTINE bio_check_parameters 901 878 902 879 903 !------------------------------------------------------------------------------ !880 !--------------------------------------------------------------------------------------------------! 904 881 ! Description: 905 882 ! ------------ 906 883 !> Subroutine defining 2D output variables 907 884 !> data_output_2d 1188ff 908 !------------------------------------------------------------------------------! 909 SUBROUTINE bio_data_output_2d( av, variable, found, grid, local_pf, & 910 two_d, nzb_do, nzt_do ) 885 !--------------------------------------------------------------------------------------------------! 886 SUBROUTINE bio_data_output_2d( av, variable, found, grid, local_pf, two_d, nzb_do, nzt_do) 911 887 912 888 … … 924 900 !-- Output variables 925 901 CHARACTER (LEN=*), INTENT(OUT) :: grid !< Grid type (always "zu1" for biom) 902 926 903 LOGICAL, INTENT(OUT) :: found !< Output found? 927 904 LOGICAL, INTENT(OUT) :: two_d !< Flag parameter that indicates 2D variables, … … 950 927 j = mrtbl(iy,l) 951 928 k = mrtbl(iz,l) 952 IF ( k < nzb_do .OR. k > nzt_do .OR. j < nys .OR. &929 IF ( k < nzb_do .OR. k > nzt_do .OR. j < nys .OR. & 953 930 j > nyn .OR. i < nxl .OR. i > nxr ) CYCLE 954 931 IF ( av == 0 ) THEN 955 932 IF ( mrt_include_sw ) THEN 956 local_pf(i,j,k) = ( ( human_absorb * mrtinsw(l) + & 957 mrtinlw(l) ) / & 958 ( human_emiss * sigma_sb ) )**.25_wp - & 959 degc_to_k 933 local_pf(i,j,k) = ( ( human_absorb * mrtinsw(l) + & 934 mrtinlw(l) ) / & 935 ( human_emiss * sigma_sb ) )**0.25_wp - degc_to_k 960 936 ELSE 961 local_pf(i,j,k) = ( mrtinlw(l) / & 962 ( human_emiss * sigma_sb ) )**.25_wp - & 963 degc_to_k 937 local_pf(i,j,k) = ( mrtinlw(l) / & 938 ( human_emiss * sigma_sb ) )**0.25_wp - degc_to_k 964 939 ENDIF 965 940 ELSE … … 1040 1015 1041 1016 ! 1042 !-- Before data is transfered to local_pf, transfer is it 2D dummy variable and exchange ghost points therein. 1043 !-- However, at this point this is only required for instantaneous arrays, time-averaged quantities are already exchanged. 1017 !-- Before data is transfered to local_pf, transfer is in 2D dummy variable and exchange ghost 1018 !-- points therein. However, at this point this is only required for instantaneous arrays, 1019 !-- time-averaged quantities are already exchanged. 1044 1020 CASE ( 'uvem_vitd3*_xy' ) ! 2d-array 1045 1021 IF ( av == 0 ) THEN … … 1077 1053 1078 1054 1079 !------------------------------------------------------------------------------ !1055 !--------------------------------------------------------------------------------------------------! 1080 1056 ! Description: 1081 1057 ! ------------ 1082 1058 !> Subroutine defining 3D output variables (dummy, always 2d!) 1083 1059 !> data_output_3d 709ff 1084 !------------------------------------------------------------------------------ !1060 !--------------------------------------------------------------------------------------------------! 1085 1061 SUBROUTINE bio_data_output_3d( av, variable, found, local_pf, nzb_do, nzt_do ) 1086 1062 … … 1094 1070 !-- Input variables 1095 1071 CHARACTER (LEN=*), INTENT(IN) :: variable !< Char identifier to select var for output 1072 1096 1073 INTEGER(iwp), INTENT(IN) :: av !< Use averaged data? 0 = no, 1 = yes? 1097 1074 INTEGER(iwp), INTENT(IN) :: nzb_do !< Unused. 2D. nz bottom to nz top … … 1100 1077 !-- Output variables 1101 1078 LOGICAL, INTENT(OUT) :: found !< Output found? 1079 1102 1080 REAL(sp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) :: local_pf !< Temp. result grid to return 1103 1081 ! … … 1108 1086 INTEGER(iwp) :: k !< Running index, z-dir 1109 1087 1110 ! 1088 ! REAL(wp) :: mrt !< Buffer for mean radiant temperature 1111 1089 1112 1090 found = .TRUE. … … 1120 1098 j = mrtbl(iy,l) 1121 1099 k = mrtbl(iz,l) 1122 IF ( k < nzb_do .OR. k > nzt_do .OR. j < nys .OR. &1100 IF ( k < nzb_do .OR. k > nzt_do .OR. j < nys .OR. & 1123 1101 j > nyn .OR. i < nxl .OR. i > nxr ) CYCLE 1124 1102 IF ( av == 0 ) THEN 1125 1103 IF ( mrt_include_sw ) THEN 1126 local_pf(i,j,k) = REAL( ( ( human_absorb * mrtinsw(l) + &1127 mrtinlw(l) ) /&1128 ( human_emiss * sigma_sb ) )**.25_wp -&1129 degc_to_k,KIND = sp )1104 local_pf(i,j,k) = REAL( ( ( human_absorb * mrtinsw(l) + & 1105 mrtinlw(l) ) / & 1106 ( human_emiss * sigma_sb ) )**0.25_wp - degc_to_k, & 1107 KIND = sp ) 1130 1108 ELSE 1131 local_pf(i,j,k) = REAL( ( mrtinlw(l) / &1132 ( human_emiss * sigma_sb ) )**.25_wp -&1133 degc_to_k,KIND = sp )1109 local_pf(i,j,k) = REAL( ( mrtinlw(l) / & 1110 ( human_emiss * sigma_sb ) )**0.25_wp - degc_to_k, & 1111 KIND = sp ) 1134 1112 ENDIF 1135 1113 ELSE … … 1145 1123 END SUBROUTINE bio_data_output_3d 1146 1124 1147 !------------------------------------------------------------------------------ !1125 !--------------------------------------------------------------------------------------------------! 1148 1126 ! Description: 1149 1127 ! ------------ … … 1151 1129 !> It is called out from subroutine netcdf_interface_mod. 1152 1130 !> netcdf_interface_mod 918ff 1153 !------------------------------------------------------------------------------ !1131 !--------------------------------------------------------------------------------------------------! 1154 1132 SUBROUTINE bio_define_netcdf_grid( var, found, grid_x, grid_y, grid_z ) 1155 1133 … … 1167 1145 ! 1168 1146 !-- Local variables 1147 INTEGER(iwp) :: l !< Length of the var array 1148 1169 1149 LOGICAL :: is2d !< Var is 2d? 1170 1171 INTEGER(iwp) :: l !< Length of the var array1172 1173 1150 1174 1151 found = .FALSE. … … 1196 1173 END SUBROUTINE bio_define_netcdf_grid 1197 1174 1198 !------------------------------------------------------------------------------ !1175 !--------------------------------------------------------------------------------------------------! 1199 1176 ! Description: 1200 1177 ! ------------ 1201 1178 !> Header output for biom module 1202 1179 !> header 982 1203 !------------------------------------------------------------------------------ !1180 !--------------------------------------------------------------------------------------------------! 1204 1181 SUBROUTINE bio_header( io ) 1205 1182 … … 1219 1196 WRITE( io, 3 ) TRIM( ACHAR( bio_cell_level ) ) 1220 1197 1221 1 FORMAT (//' Human thermal comfort module information:'/ &1198 1 FORMAT (//' Human thermal comfort module information:'/ & 1222 1199 ' ------------------------------'/) 1223 1200 2 FORMAT (' --> All indices calculated for a height of (m): ', A ) … … 1227 1204 1228 1205 1229 !------------------------------------------------------------------------------ !1206 !--------------------------------------------------------------------------------------------------! 1230 1207 ! Description: 1231 1208 ! ------------ 1232 1209 !> Initialization of the HTCM 1233 1210 !> init_3d_model 1987ff 1234 !------------------------------------------------------------------------------ !1211 !--------------------------------------------------------------------------------------------------! 1235 1212 SUBROUTINE bio_init 1236 1213 1237 USE netcdf_data_input_mod, &1214 USE netcdf_data_input_mod, & 1238 1215 ONLY: netcdf_data_input_uvem 1239 1216 … … 1245 1222 IF ( debug_output ) CALL debug_message( 'bio_init', 'start' ) 1246 1223 ! 1247 !-- Determine cell level corresponding to 1.1 m above ground level 1248 ! (gravimetric center of samplehuman)1224 !-- Determine cell level corresponding to 1.1 m above ground level (gravimetric center of sample 1225 !-- human) 1249 1226 1250 1227 bio_cell_level = 0_iwp … … 1268 1245 1269 1246 1270 !------------------------------------------------------------------------------ !1247 !--------------------------------------------------------------------------------------------------! 1271 1248 ! Description: 1272 1249 ! ------------ 1273 1250 !> Checks done after the Initialization 1274 !------------------------------------------------------------------------------ !1251 !--------------------------------------------------------------------------------------------------! 1275 1252 SUBROUTINE bio_init_checks 1276 1253 1277 USE control_parameters, &1254 USE control_parameters, & 1278 1255 ONLY: message_string 1279 1256 1280 1257 IF ( (.NOT. radiation_interactions) .AND. ( thermal_comfort ) ) THEN 1281 message_string = 'The mrt calculation requires ' // &1282 'enabled radiation_interactions but it ' // &1258 message_string = 'The mrt calculation requires ' // & 1259 'enabled radiation_interactions but it ' // & 1283 1260 'is disabled!' 1284 1261 CALL message( 'bio_init_checks', 'PAHU03', 1, 2, 0, 6, 0 ) … … 1289 1266 1290 1267 1291 !------------------------------------------------------------------------------ !1268 !--------------------------------------------------------------------------------------------------! 1292 1269 ! Description: 1293 1270 ! ------------ 1294 1271 !> Parin for &biometeorology_parameters for reading biomet parameters 1295 !------------------------------------------------------------------------------ !1272 !--------------------------------------------------------------------------------------------------! 1296 1273 SUBROUTINE bio_parin 1297 1274 … … 1300 1277 ! 1301 1278 !-- Internal variables 1302 CHARACTER (LEN=80) :: line !< Dummy string for current line in parameter file 1303 1304 NAMELIST /biometeorology_parameters/ thermal_comfort,&1305 c lothing,&1306 consider_obstructions,&1307 orientation_angle,&1308 sun_in_south,&1309 turn_to_sun, &1279 CHARACTER (LEN=80) :: line !< Dummy string for current line in parameter file 1280 1281 NAMELIST /biometeorology_parameters/ clothing, & 1282 consider_obstructions, & 1283 orientation_angle, & 1284 sun_in_south, & 1285 thermal_comfort, & 1286 turn_to_sun, & 1310 1287 uv_exposure 1311 1288 … … 1342 1319 END SUBROUTINE bio_parin 1343 1320 1344 !------------------------------------------------------------------------------ !1321 !--------------------------------------------------------------------------------------------------! 1345 1322 ! Description: 1346 1323 ! ------------ 1347 1324 !> Read module-specific global restart data (Fortran binary format). 1348 !------------------------------------------------------------------------------ !1325 !--------------------------------------------------------------------------------------------------! 1349 1326 SUBROUTINE bio_rrd_global_ftn( found ) 1350 1327 1351 USE control_parameters, &1328 USE control_parameters, & 1352 1329 ONLY: length, restart_string 1353 1330 … … 1363 1340 1364 1341 ! 1365 !-- read control flags to determine if input grids need to be averaged1342 !-- Read control flags to determine if input grids need to be averaged. 1366 1343 CASE ( 'do_average_theta' ) 1367 1344 READ ( 13 ) do_average_theta … … 1383 1360 1384 1361 ! 1385 !-- read control flags to determine which thermal index needs to trigger averaging1362 !-- Read control flags to determine which thermal index needs to trigger averaging. 1386 1363 CASE ( 'average_trigger_perct' ) 1387 1364 READ ( 13 ) average_trigger_perct … … 1407 1384 1408 1385 1409 !------------------------------------------------------------------------------ !1386 !--------------------------------------------------------------------------------------------------! 1410 1387 ! Description: 1411 1388 ! ------------ 1412 1389 !> Read module-specific global restart data (MPI-IO). 1413 !------------------------------------------------------------------------------ !1390 !--------------------------------------------------------------------------------------------------! 1414 1391 SUBROUTINE bio_rrd_global_mpi 1415 1392 … … 1433 1410 1434 1411 1435 !------------------------------------------------------------------------------ !1412 !--------------------------------------------------------------------------------------------------! 1436 1413 ! Description: 1437 1414 ! ------------ 1438 1415 !> Read module-specific local restart data arrays (Fortran binary format). 1439 !------------------------------------------------------------------------------ !1416 !--------------------------------------------------------------------------------------------------! 1440 1417 SUBROUTINE bio_rrd_local_ftn( found ) 1441 1418 1442 1419 1443 USE control_parameters, &1420 USE control_parameters, & 1444 1421 ONLY: length, restart_string 1445 1422 … … 1448 1425 1449 1426 1450 LOGICAL, INTENT(OUT) :: found !< variable found? yes = .T ., no = .F.1427 LOGICAL, INTENT(OUT) :: found !< variable found? yes = .TRUE., no = .FALSE. 1451 1428 1452 1429 found = .TRUE. … … 1487 1464 1488 1465 1489 !------------------------------------------------------------------------------ !1466 !--------------------------------------------------------------------------------------------------! 1490 1467 ! Description: 1491 1468 ! ------------ 1492 1469 !> Write global restart data for the biometeorology module. 1493 !------------------------------------------------------------------------------ !1470 !--------------------------------------------------------------------------------------------------! 1494 1471 SUBROUTINE bio_wrd_global 1495 1472 … … 1519 1496 WRITE ( 14 ) average_trigger_mrt 1520 1497 1521 ELSEIF ( restart_data_format_output(1:3) == 'mpi' ) THEN1498 ELSEIF ( TRIM( restart_data_format_output(1:3) ) == 'mpi' ) THEN 1522 1499 1523 1500 CALL wrd_mpi_io( 'do_average_theta', do_average_theta ) … … 1531 1508 CALL wrd_mpi_io( 'average_trigger_pet', average_trigger_pet ) 1532 1509 CALL wrd_mpi_io( 'average_trigger_mrt', average_trigger_mrt ) 1510 1533 1511 ENDIF 1534 1512 … … 1536 1514 1537 1515 1538 !------------------------------------------------------------------------------ !1516 !--------------------------------------------------------------------------------------------------! 1539 1517 ! Description: 1540 1518 ! ------------ 1541 1519 !> Write local restart data for the biometeorology module. 1542 !------------------------------------------------------------------------------ !1520 !--------------------------------------------------------------------------------------------------! 1543 1521 SUBROUTINE bio_wrd_local 1544 1522 … … 1558 1536 ENDIF 1559 1537 1560 ELSEIF ( restart_data_format_output(1:3) == 'mpi' ) THEN1538 ELSEIF ( TRIM( restart_data_format_output(1:3) ) == 'mpi' ) THEN 1561 1539 1562 1540 ! … … 1573 1551 END SUBROUTINE bio_wrd_local 1574 1552 1575 !------------------------------------------------------------------------------ !1553 !--------------------------------------------------------------------------------------------------! 1576 1554 ! Description: 1577 1555 ! ------------ 1578 1556 !> Calculate biometeorology MRT for all 2D grid 1579 !------------------------------------------------------------------------------ !1557 !--------------------------------------------------------------------------------------------------! 1580 1558 SUBROUTINE bio_calculate_mrt_grid ( av ) 1581 1559 … … 1605 1583 IF ( ALLOCATED( mrt_av_grid ) ) THEN 1606 1584 ! 1607 !-- Iterate over the radiation grid (radiation coordinates) and fill the1608 !-- tmrt_av_grid (x, y coordinates) where appropriate:1609 !-- tmrt_av_grid is written for all i / j if level (k)matches output height.1585 !-- Iterate over the radiation grid (radiation coordinates) and fill the tmrt_av_grid 1586 !-- (x, y coordinates) where appropriate: tmrt_av_grid is written for all i / j if level (k) 1587 !-- matches output height. 1610 1588 DO l = 1, nmrtbl 1611 1589 i = mrtbl(ix,l) … … 1614 1592 IF ( k - topo_top_ind(j,i,0) == bio_cell_level + 1_iwp) THEN 1615 1593 ! 1616 !-- Averaging was done before, so we can just copy the result here1594 !-- Averaging was done before, so we can just copy the result here. 1617 1595 tmrt_av_grid(j,i) = mrt_av_grid(l) 1618 1596 … … 1625 1603 ELSE 1626 1604 ! 1627 !-- Calculate biometeorology MRT from local radiation fluxes calculated by RTM and assign1628 !-- into 2D grid. Depending on selected output quantities, tmrt_grid might not have been1629 !-- allocated inbio_check_data_output yet.1605 !-- Calculate biometeorology MRT from local radiation fluxes calculated by RTM and assign into 2D 1606 !-- grid. Depending on selected output quantities, tmrt_grid might not have been allocated in 1607 !-- bio_check_data_output yet. 1630 1608 IF ( .NOT. ALLOCATED( tmrt_grid ) ) THEN 1631 1609 ALLOCATE( tmrt_grid (nys:nyn,nxl:nxr) ) … … 1639 1617 IF ( k - topo_top_ind(j,i,0) == bio_cell_level + 1_iwp) THEN 1640 1618 IF ( mrt_include_sw ) THEN 1641 tmrt_grid(j,i) = ( ( human_absorb * mrtinsw(l) +&1642 mrtinlw(l) ) /&1643 ( human_emiss * sigma_sb ) )**.25_wp -&1644 1619 tmrt_grid(j,i) = ( ( human_absorb * mrtinsw(l) + & 1620 mrtinlw(l) ) / & 1621 ( human_emiss * sigma_sb ) )**0.25_wp - & 1622 degc_to_k 1645 1623 ELSE 1646 tmrt_grid(j,i) = ( mrtinlw(l) /&1647 ( human_emiss * sigma_sb ) )**.25_wp -&1648 1624 tmrt_grid(j,i) = ( mrtinlw(l) / & 1625 ( human_emiss * sigma_sb ) )**0.25_wp - & 1626 degc_to_k 1649 1627 ENDIF 1650 1628 ENDIF … … 1652 1630 ENDIF 1653 1631 1654 END SUBROUTINE bio_calculate_mrt_grid1655 1656 1657 !------------------------------------------------------------------------------ !1632 END SUBROUTINE bio_calculate_mrt_grid 1633 1634 1635 !--------------------------------------------------------------------------------------------------! 1658 1636 ! Description: 1659 1637 ! ------------ 1660 1638 !> Calculate static thermal indices for 2D grid point i, j 1661 !------------------------------------------------------------------------------! 1662 SUBROUTINE bio_get_thermal_index_input_ij( average_input, i, j, ta, vp, ws, & 1663 pair, tmrt ) 1639 !--------------------------------------------------------------------------------------------------! 1640 SUBROUTINE bio_get_thermal_index_input_ij( average_input, i, j, ta, vp, ws, pair, tmrt ) 1664 1641 1665 1642 IMPLICIT NONE … … 1671 1648 ! 1672 1649 !-- Output parameters 1650 REAL(wp), INTENT ( OUT ) :: pair !< Air pressure (hPa) 1651 REAL(wp), INTENT ( OUT ) :: ta !< Air temperature (degree_C) 1673 1652 REAL(wp), INTENT ( OUT ) :: tmrt !< Mean radiant temperature (degree_C) 1674 REAL(wp), INTENT ( OUT ) :: ta !< Air temperature (degree_C)1675 1653 REAL(wp), INTENT ( OUT ) :: vp !< Vapour pressure (hPa) 1676 1654 REAL(wp), INTENT ( OUT ) :: ws !< Wind speed (local level) (m/s) 1677 REAL(wp), INTENT ( OUT ) :: pair !< Air pressure (hPa)1678 1655 ! 1679 1656 !-- Internal variables … … 1684 1661 1685 1662 ! 1686 !-- Determine cell level closest to 1.1m above ground 1687 ! by making use of truncation due to int cast 1663 !-- Determine cell level closest to 1.1m above ground by making use of truncation due to int cast. 1688 1664 k = INT( topo_top_ind(j,i,0) + bio_cell_level ) !< Vertical cell center closest to 1.1m 1689 1665 … … 1701 1677 ta = bio_fill_value 1702 1678 IF ( ALLOCATED( pt_av ) ) THEN 1703 ta = pt_av(k,j,i) - ( 0.0098_wp * dz(1) * ( k + .5_wp ) ) - degc_to_k1679 ta = pt_av(k,j,i) - ( 0.0098_wp * dz(1) * ( k + 0.5_wp ) ) - degc_to_k 1704 1680 ENDIF 1705 1681 … … 1710 1686 1711 1687 ws = bio_fill_value 1712 IF ( ALLOCATED( u_av ) .AND. ALLOCATED( v_av ) .AND. &1688 IF ( ALLOCATED( u_av ) .AND. ALLOCATED( v_av ) .AND. & 1713 1689 ALLOCATED( w_av ) ) THEN 1714 ws = ( 0.5_wp * ABS( u_av(k_wind,j,i) + u_av(k_wind,j,i+1) ) +&1715 0.5_wp * ABS( v_av(k_wind,j,i) + v_av(k_wind,j+1,i) ) +&1716 0.5_wp * ABS( w_av(k_wind,j,i) + w_av(k_wind+1,j,i) ) )1690 ws = ( 0.5_wp * ABS( u_av(k_wind,j,i) + u_av(k_wind,j,i+1) ) + & 1691 0.5_wp * ABS( v_av(k_wind,j,i) + v_av(k_wind,j+1,i) ) + & 1692 0.5_wp * ABS( w_av(k_wind,j,i) + w_av(k_wind+1,j,i) ) ) 1717 1693 ENDIF 1718 1694 ELSE 1719 1695 ! 1720 !-- Calculate ta from Tp assuming dry adiabatic laps rate1721 ta = pt(k,j,i) - ( 0.0098_wp * dz(1) * ( k + .5_wp ) ) - degc_to_k1696 !-- Calculate ta from Tp assuming dry adiabatic laps rate 1697 ta = pt(k,j,i) - ( 0.0098_wp * dz(1) * ( k + 0.5_wp ) ) - degc_to_k 1722 1698 1723 1699 vp = bio_fill_value … … 1726 1702 ENDIF 1727 1703 1728 ws = ( 0.5_wp * ABS( u(k_wind,j,i) + u(k_wind,j,i+1) ) + &1729 0.5_wp * ABS( v(k_wind,j,i) + v(k_wind,j+1,i) ) +&1730 0.5_wp * ABS( w(k_wind,j,i) + w(k_wind+1,j,i) ) )1704 ws = ( 0.5_wp * ABS( u(k_wind,j,i) + u(k_wind,j,i+1) ) + & 1705 0.5_wp * ABS( v(k_wind,j,i) + v(k_wind,j+1,i) ) + & 1706 0.5_wp * ABS( w(k_wind,j,i) + w(k_wind+1,j,i) ) ) 1731 1707 1732 1708 ENDIF … … 1735 1711 pair = surface_pressure 1736 1712 ! 1737 !-- Calculate water vapour pressure at saturation and convert to hPa 1738 !-- The magnus formula is limited to temperatures up to 333.15 K to 1739 ! avoid negative values of vp_sat 1740 IF ( vp > -998._wp ) THEN 1713 !-- Calculate water vapour pressure at saturation and convert to hPa. 1714 !-- The magnus formula is limited to temperatures up to 333.15 K to avoid negative values of vp_sat. 1715 IF ( vp > -998.0_wp ) THEN 1741 1716 vp_sat = 0.01_wp * magnus( MIN( ta + degc_to_k, 333.15_wp ) ) 1742 1717 vp = vp * pair / ( vp + 0.622_wp ) … … 1744 1719 ENDIF 1745 1720 ! 1746 !-- local mtr value at [i,j]1721 !-- Local mtr value at [i,j] 1747 1722 tmrt = bio_fill_value !< this can be a valid result (e.g. for inside some ostacle) 1748 1723 IF ( .NOT. average_input ) THEN … … 1757 1732 1758 1733 1759 !------------------------------------------------------------------------------ !1734 !--------------------------------------------------------------------------------------------------! 1760 1735 ! Description: 1761 1736 ! ------------ 1762 !> Calculate static thermal indices for any point within a 2D grid 1763 !> time_integration.f90: 1065ff 1764 !------------------------------------------------------------------------------! 1737 !> Calculate static thermal indices for any point within a 2D grid time_integration.f90: 1065ff 1738 !--------------------------------------------------------------------------------------------------! 1765 1739 SUBROUTINE bio_calculate_thermal_index_maps( av ) 1766 1740 … … 1774 1748 1775 1749 REAL(wp) :: clo !< Clothing index (no dimension) 1750 REAL(wp) :: pair !< Air pressure (hPa) 1751 REAL(wp) :: perct_ij !< Perceived temperature (degree_C) 1752 REAL(wp) :: pet_ij !< Physiologically equivalent temperature (degree_C) 1776 1753 REAL(wp) :: ta !< Air temperature (degree_C) 1754 REAL(wp) :: tmrt_ij !< Mean radiant temperature (degree_C) 1755 REAL(wp) :: utci_ij !< Universal thermal climate index (degree_C) 1777 1756 REAL(wp) :: vp !< Vapour pressure (hPa) 1778 1757 REAL(wp) :: ws !< Wind speed (local level) (m/s) 1779 REAL(wp) :: pair !< Air pressure (hPa) 1780 REAL(wp) :: perct_ij !< Perceived temperature (degree_C) 1781 REAL(wp) :: utci_ij !< Universal thermal climate index (degree_C) 1782 REAL(wp) :: pet_ij !< Physiologically equivalent temperature (degree_C) 1783 REAL(wp) :: tmrt_ij !< Mean radiant temperature (degree_C) 1784 1785 ! 1786 !-- Check if some thermal index is desired. Don't do anything if, e.g. only 1787 !-- bio_mrt is desired. 1788 IF ( do_calculate_perct .OR. do_calculate_perct_av .OR. & 1789 do_calculate_utci .OR. do_calculate_utci_av .OR. & 1790 do_calculate_pet .OR. do_calculate_pet_av .OR. & 1791 do_calculate_mrt2d ) THEN 1758 1759 ! 1760 !-- Check if some thermal index is desired. Don't do anything if, e.g. only bio_mrt is desired. 1761 IF ( do_calculate_perct .OR. do_calculate_perct_av .OR. do_calculate_utci .OR. & 1762 do_calculate_utci_av .OR. do_calculate_pet .OR. do_calculate_pet_av .OR. & 1763 do_calculate_mrt2d ) THEN 1792 1764 1793 1765 ! … … 1803 1775 ! 1804 1776 !-- Determine local meteorological conditions 1805 CALL bio_get_thermal_index_input_ij ( av, i, j, ta, vp, & 1806 ws, pair, tmrt_ij ) 1777 CALL bio_get_thermal_index_input_ij ( av, i, j, ta, vp, ws, pair, tmrt_ij ) 1807 1778 ! 1808 1779 !-- Only proceed if input is available … … 1810 1781 perct_ij = bio_fill_value !< within some obstacle 1811 1782 utci_ij = bio_fill_value 1812 IF ( .NOT. ( tmrt_ij <= -998. _wp .OR. vp <= -998._wp .OR.&1813 ws <= -998._wp .OR. ta <= -998._wp ) ) THEN1783 IF ( .NOT. ( tmrt_ij <= -998.0_wp .OR. vp <= -998.0_wp .OR. ws <= -998.0_wp .OR.& 1784 ta <= -998.0_wp ) ) THEN 1814 1785 ! 1815 1786 !-- Calculate static thermal indices based on local tmrt … … 1819 1790 ! 1820 1791 !-- Estimate local perceived temperature 1821 CALL calculate_perct_static( ta, vp, ws, tmrt_ij, pair, & 1822 clo, perct_ij ) 1792 CALL calculate_perct_static( ta, vp, ws, tmrt_ij, pair, clo, perct_ij ) 1823 1793 ENDIF 1824 1794 … … 1826 1796 ! 1827 1797 !-- Estimate local universal thermal climate index 1828 CALL calculate_utci_static( ta, vp, ws, tmrt_ij, & 1829 bio_output_height, utci_ij ) 1798 CALL calculate_utci_static( ta, vp, ws, tmrt_ij, bio_output_height, utci_ij ) 1830 1799 ENDIF 1831 1800 … … 1833 1802 ! 1834 1803 !-- Estimate local physiologically equivalent temperature 1835 CALL calculate_pet_static( ta, vp, ws, tmrt_ij, pair, & 1836 pet_ij ) 1804 CALL calculate_pet_static( ta, vp, ws, tmrt_ij, pair, pet_ij ) 1837 1805 ENDIF 1838 1806 ENDIF … … 1871 1839 END SUBROUTINE bio_calculate_thermal_index_maps 1872 1840 1873 !------------------------------------------------------------------------------ !1841 !--------------------------------------------------------------------------------------------------! 1874 1842 ! Description: 1875 1843 ! ------------ 1876 1844 !> Calculate dynamic thermal indices (currently only iPT, but expandable) 1877 !------------------------------------------------------------------------------ !1878 SUBROUTINE bio_calc_ipt( ta, vp, ws, pair, tmrt, dt, energy_storage, 1879 t_clo, clo, actlev, age,weight, height, work, sex, ipt )1845 !--------------------------------------------------------------------------------------------------! 1846 SUBROUTINE bio_calc_ipt( ta, vp, ws, pair, tmrt, dt, energy_storage, t_clo, clo, actlev, age, & 1847 weight, height, work, sex, ipt ) 1880 1848 1881 1849 IMPLICIT NONE 1882 1850 ! 1883 1851 !-- Input parameters 1884 REAL(wp), INTENT ( IN ) :: ta !< Air temperature (degree_C)1885 REAL(wp), INTENT ( IN ) :: vp !< Vapour pressure (hPa)1886 REAL(wp), INTENT ( IN ) :: ws !< Wind speed (local level) (m/s)1887 REAL(wp), INTENT ( IN ) :: pair !< Air pressure (hPa)1888 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degree_C)1889 REAL(wp), INTENT ( IN ) :: dt !< Time past since last calculation (s)1890 REAL(wp), INTENT ( IN ) :: age !< Age of agent (y)1891 REAL(wp), INTENT ( IN ) :: weight !< Weight of agent (Kg)1892 REAL(wp), INTENT ( IN ) :: height !< Height of agent (m)1893 REAL(wp), INTENT ( IN ) :: work !< Mechanical workload of agent1894 ! (without metabolism!) (W)1895 1852 INTEGER(iwp), INTENT ( IN ) :: sex !< Sex of agent (1 = male, 2 = female) 1853 1854 REAL(wp), INTENT ( IN ) :: age !< Age of agent (y) 1855 REAL(wp), INTENT ( IN ) :: dt !< Time past SINce last calculation (s) 1856 REAL(wp), INTENT ( IN ) :: height !< Height of agent (m) 1857 REAL(wp), INTENT ( IN ) :: pair !< Air pressure (hPa) 1858 REAL(wp), INTENT ( IN ) :: ta !< Air temperature (degree_C) 1859 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degree_C) 1860 REAL(wp), INTENT ( IN ) :: vp !< Vapour pressure (hPa) 1861 REAL(wp), INTENT ( IN ) :: weight !< Weight of agent (Kg) 1862 REAL(wp), INTENT ( IN ) :: work !< Mechanical workload of agent (without metabolism!) (W) 1863 REAL(wp), INTENT ( IN ) :: ws !< Wind speed (local level) (m/s) 1864 1896 1865 ! 1897 1866 !-- Both, input and output parameters 1867 Real(wp), INTENT ( INOUT ) :: actlev !< Individuals activity level 1868 !< per unit surface area (W/m²) 1869 Real(wp), INTENT ( INOUT ) :: clo !< Current clothing in sulation 1898 1870 Real(wp), INTENT ( INOUT ) :: energy_storage !< Energy storage (W/m²) 1899 Real(wp), INTENT ( INOUT ) :: t_clo !< Clothing temperature (degree_C) 1900 Real(wp), INTENT ( INOUT ) :: clo !< Current clothing in sulation 1901 Real(wp), INTENT ( INOUT ) :: actlev !< Individuals activity level 1902 ! per unit surface area (W/m²) 1871 Real(wp), INTENT ( INOUT ) :: t_clo !< Clothing temperature (degree_C) 1903 1872 ! 1904 1873 !-- Output parameters 1905 1874 REAL(wp), INTENT ( OUT ) :: ipt !< Instationary perceived temp. (degree_C) 1906 1875 ! 1907 !-- return immediatelly if nothing to do!1876 !-- Return immediatelly if nothing to do! 1908 1877 IF ( .NOT. thermal_comfort ) THEN 1909 1878 RETURN … … 1911 1880 ! 1912 1881 !-- If clo equals the initial value, this is the initial call 1913 IF ( clo <= -998._wp ) THEN 1914 ! 1915 !-- Initialize instationary perceived temperature with personalized 1916 ! PT as an initial guess, set actlev and clo 1917 CALL ipt_init( age, weight, height, sex, work, actlev, clo, & 1918 ta, vp, ws, tmrt, pair, dt, energy_storage, t_clo, & 1919 ipt ) 1882 IF ( clo <= -998.0_wp ) THEN 1883 ! 1884 !-- Initialize instationary perceived temperature with personalized PT as an initial guess, set 1885 !-- actlev and clo 1886 CALL ipt_init( age, weight, height, sex, work, actlev, clo, ta, vp, ws, tmrt, pair, dt, & 1887 energy_storage, t_clo, ipt ) 1920 1888 ELSE 1921 1889 ! 1922 1890 !-- Estimate local instatinoary perceived temperature 1923 CALL ipt_cycle ( ta, vp, ws, tmrt, pair, dt, energy_storage, t_clo, & 1924 clo, actlev, work, ipt ) 1891 CALL ipt_cycle ( ta, vp, ws, tmrt, pair, dt, energy_storage, t_clo, clo, actlev, work, ipt ) 1925 1892 ENDIF 1926 1893 … … 1929 1896 1930 1897 1931 !------------------------------------------------------------------------------ !1898 !--------------------------------------------------------------------------------------------------! 1932 1899 ! Description: 1933 1900 ! ------------ … … 1935 1902 !> computed by a 6th order approximation 1936 1903 !> 1937 !> UTCI regression equation after 1938 !> Bröde P, Fiala D, Blazejczyk K, Holmér I, Jendritzky G, Kampmann B, Tinz B, 1939 !> Havenith G (2012) Deriving the operational procedure for the Universal Thermal 1940 !> Climate Index (UTCI). International Journal of Biometeorology 56 (3):481-494. 1941 !> doi:10.1007/s00484-011-0454-1 1904 !> UTCI regression equation according to 1905 !> Bröde P, Fiala D, Blazejczyk K, Holmér I, Jendritzky G, Kampmann B, Tinz B, Havenith G (2012) 1906 !> Deriving the operational procedure for the Universal Thermal Climate Index (UTCI). International 1907 !> Journal of Biometeorology 56 (3):481-494. doi:10.1007/s00484-011-0454-1 1942 1908 !> 1943 1909 !> original source available at: 1944 1910 !> www.utci.org 1945 !------------------------------------------------------------------------------ !1911 !--------------------------------------------------------------------------------------------------! 1946 1912 SUBROUTINE calculate_utci_static( ta_in, vp, ws_hag, tmrt, hag, utci_ij ) 1947 1913 … … 1949 1915 ! 1950 1916 !-- Type of input of the argument list 1917 REAL(WP), INTENT ( IN ) :: hag !< Height of wind speed input (m) 1951 1918 REAL(WP), INTENT ( IN ) :: ta_in !< Local air temperature (degree_C) 1919 REAL(WP), INTENT ( IN ) :: tmrt !< Local mean radiant temperature (degree_C) 1952 1920 REAL(WP), INTENT ( IN ) :: vp !< Loacl vapour pressure (hPa) 1953 1921 REAL(WP), INTENT ( IN ) :: ws_hag !< Incident wind speed (m/s) 1954 REAL(WP), INTENT ( IN ) :: tmrt !< Local mean radiant temperature (degree_C)1955 REAL(WP), INTENT ( IN ) :: hag !< Height of wind speed input (m)1956 1922 ! 1957 1923 !-- Type of output of the argument list 1958 REAL(wp), INTENT ( OUT ) :: utci_ij !< Universal Thermal Climate Index (degree_C) 1959 1924 REAL(WP) :: d_tmrt !< delta-tmrt (degree_C) 1925 REAL(WP) :: d_tmrt2 !< 2 times d_tmrt 1926 REAL(WP) :: d_tmrt3 !< 3 times d_tmrt 1927 REAL(WP) :: d_tmrt4 !< 4 times d_tmrt 1928 REAL(WP) :: d_tmrt5 !< 5 times d_tmrt 1929 REAL(WP) :: d_tmrt6 !< 6 times d_tmrt 1930 REAL(WP) :: offset !< utci deviation by ta cond. exceeded (degree_C) 1931 REAL(WP) :: pa !< air pressure in kPa (kPa) 1932 REAL(WP) :: pa2 !< 2 times pa 1933 REAL(WP) :: pa3 !< 3 times pa 1934 REAL(WP) :: pa4 !< 4 times pa 1935 REAL(WP) :: pa5 !< 5 times pa 1936 REAL(WP) :: pa6 !< 6 times pa 1937 REAL(WP) :: part_d_tmrt !< Mean radiant temp. related part of the reg. 1938 REAL(WP) :: part_pa !< Air pressure related part of the regression 1939 REAL(WP) :: part_pa2 !< Air pressure^2 related part of the regression 1940 REAL(WP) :: part_pa3 !< Air pressure^3 related part of the regression 1941 REAL(WP) :: part_pa46 !< Air pressure^4-6 related part of the regression 1942 REAL(WP) :: part_ta !< Air temperature related part of the regression 1943 REAL(WP) :: part_va !< Vapour pressure related part of the regression 1960 1944 REAL(WP) :: ta !< air temperature modified by offset (degree_C) 1961 REAL(WP) :: pa !< air pressure in kPa (kPa)1962 REAL(WP) :: d_tmrt !< delta-tmrt (degree_C)1963 REAL(WP) :: va !< wind speed at 10 m above ground level (m/s)1964 REAL(WP) :: offset !< utci deviation by ta cond. exceeded (degree_C)1965 REAL(WP) :: part_ta !< Air temperature related part of the regression1966 1945 REAL(WP) :: ta2 !< 2 times ta 1967 1946 REAL(WP) :: ta3 !< 3 times ta … … 1969 1948 REAL(WP) :: ta5 !< 5 times ta 1970 1949 REAL(WP) :: ta6 !< 6 times ta 1971 REAL(WP) :: part_va !< Vapour pressure related part of the regression1950 REAL(WP) :: va !< wind speed at 10 m above ground level (m/s) 1972 1951 REAL(WP) :: va2 !< 2 times va 1973 1952 REAL(WP) :: va3 !< 3 times va … … 1975 1954 REAL(WP) :: va5 !< 5 times va 1976 1955 REAL(WP) :: va6 !< 6 times va 1977 REAL(WP) :: part_d_tmrt !< Mean radiant temp. related part of the reg. 1978 REAL(WP) :: d_tmrt2 !< 2 times d_tmrt 1979 REAL(WP) :: d_tmrt3 !< 3 times d_tmrt 1980 REAL(WP) :: d_tmrt4 !< 4 times d_tmrt 1981 REAL(WP) :: d_tmrt5 !< 5 times d_tmrt 1982 REAL(WP) :: d_tmrt6 !< 6 times d_tmrt 1983 REAL(WP) :: part_pa !< Air pressure related part of the regression 1984 REAL(WP) :: pa2 !< 2 times pa 1985 REAL(WP) :: pa3 !< 3 times pa 1986 REAL(WP) :: pa4 !< 4 times pa 1987 REAL(WP) :: pa5 !< 5 times pa 1988 REAL(WP) :: pa6 !< 6 times pa 1989 REAL(WP) :: part_pa2 !< Air pressure^2 related part of the regression 1990 REAL(WP) :: part_pa3 !< Air pressure^3 related part of the regression 1991 REAL(WP) :: part_pa46 !< Air pressure^4-6 related part of the regression 1956 1957 1958 REAL(wp), INTENT ( OUT ) :: utci_ij !< Universal Thermal Climate Index (degree_C) 1992 1959 1993 1960 ! 1994 1961 !-- Initialize 1995 offset = 0. _wp1962 offset = 0.0_wp 1996 1963 ta = ta_in 1997 1964 d_tmrt = tmrt - ta_in … … 2005 1972 ! 2006 1973 !-- Check if input values in range after Broede et al. (2012) 2007 IF ( ( d_tmrt > 70._wp ) .OR. ( d_tmrt < -30._wp ) .OR. & 2008 ( vp >= 50._wp ) ) THEN 1974 IF ( ( d_tmrt > 70.0_wp ) .OR. ( d_tmrt < -30.0_wp ) .OR. ( vp >= 50.0_wp ) ) THEN 2009 1975 utci_ij = bio_fill_value 2010 1976 RETURN … … 2012 1978 ! 2013 1979 !-- Apply eq. 2 in Broede et al. (2012) for ta out of bounds 2014 IF ( ta > 50._wp ) THEN 2015 offset = ta - 50._wp 2016 ta = 50._wp 2017 ENDIF 2018 IF ( ta < -50._wp ) THEN 2019 offset = ta + 50._wp 2020 ta = -50._wp 2021 ENDIF 2022 ! 2023 !-- For routine application. For wind speeds and relative 2024 !-- humidity values below 0.5 m/s or 5%, respectively, the 2025 !-- user is advised to use the lower bounds for the calculations. 1980 IF ( ta > 50.0_wp ) THEN 1981 offset = ta - 50.0_wp 1982 ta = 50.0_wp 1983 ENDIF 1984 IF ( ta < -50.0_wp ) THEN 1985 offset = ta + 50.0_wp 1986 ta = -50.0_wp 1987 ENDIF 1988 ! 1989 !-- For routine application. For wind speeds and relative humidity values below 0.5 m/s or 5%, 1990 !-- respectively, the user is advised to use the lower bounds for the calculations. 2026 1991 IF ( va < 0.5_wp ) va = 0.5_wp 2027 IF ( va > 17. _wp ) va = 17._wp1992 IF ( va > 17.0_wp ) va = 17.0_wp 2028 1993 2029 1994 ! 2030 1995 !-- Pre-calculate multiples of input parameters to save time later 2031 2032 1996 ta2 = ta * ta 2033 1997 ta3 = ta2 * ta … … 2056 2020 ! 2057 2021 !-- Pre-calculate parts of the regression equation 2058 part_ta = ( 6.07562052e-01_wp ) + &2059 ( -2.27712343e-02_wp ) * ta + &2060 ( 8.06470249e-04_wp ) * ta2 + &2061 ( -1.54271372e-04_wp ) * ta3 + &2062 ( -3.24651735e-06_wp ) * ta4 + &2063 ( 7.32602852e-08_wp ) * ta5 + &2022 part_ta = ( 6.07562052e-01_wp ) + & 2023 ( -2.27712343e-02_wp ) * ta + & 2024 ( 8.06470249e-04_wp ) * ta2 + & 2025 ( -1.54271372e-04_wp ) * ta3 + & 2026 ( -3.24651735e-06_wp ) * ta4 + & 2027 ( 7.32602852e-08_wp ) * ta5 + & 2064 2028 ( 1.35959073e-09_wp ) * ta6 2065 2029 2066 part_va = ( -2.25836520e+00_wp ) * va + & 2067 ( 8.80326035e-02_wp ) * ta * va + & 2068 ( 2.16844454e-03_wp ) * ta2 * va + & 2069 ( -1.53347087e-05_wp ) * ta3 * va + & 2070 ( -5.72983704e-07_wp ) * ta4 * va + & 2071 ( -2.55090145e-09_wp ) * ta5 * va + & 2072 ( -7.51269505e-01_wp ) * va2 + & 2073 ( -4.08350271e-03_wp ) * ta * va2 + & 2074 ( -5.21670675e-05_wp ) * ta2 * va2 + & 2075 ( 1.94544667e-06_wp ) * ta3 * va2 + & 2076 ( 1.14099531e-08_wp ) * ta4 * va2 + & 2077 ( 1.58137256e-01_wp ) * va3 + & 2078 ( -6.57263143e-05_wp ) * ta * va3 + & 2079 ( 2.22697524e-07_wp ) * ta2 * va3 + & 2080 ( -4.16117031e-08_wp ) * ta3 * va3 + & 2081 ( -1.27762753e-02_wp ) * va4 + & 2082 ( 9.66891875e-06_wp ) * ta * va4 + & 2083 ( 2.52785852e-09_wp ) * ta2 * va4 + & 2084 ( 4.56306672e-04_wp ) * va5 + & 2085 ( -1.74202546e-07_wp ) * ta * va5 + & 2086 ( -5.91491269e-06_wp ) * va6 2087 2088 part_d_tmrt = ( 3.98374029e-01_wp ) * d_tmrt + & 2089 ( 1.83945314e-04_wp ) * ta * d_tmrt + & 2090 ( -1.73754510e-04_wp ) * ta2 * d_tmrt + & 2091 ( -7.60781159e-07_wp ) * ta3 * d_tmrt + & 2092 ( 3.77830287e-08_wp ) * ta4 * d_tmrt + & 2093 ( 5.43079673e-10_wp ) * ta5 * d_tmrt + & 2094 ( -2.00518269e-02_wp ) * va * d_tmrt + & 2095 ( 8.92859837e-04_wp ) * ta * va * d_tmrt + & 2096 ( 3.45433048e-06_wp ) * ta2 * va * d_tmrt + & 2097 ( -3.77925774e-07_wp ) * ta3 * va * d_tmrt + & 2098 ( -1.69699377e-09_wp ) * ta4 * va * d_tmrt + & 2099 ( 1.69992415e-04_wp ) * va2 * d_tmrt + & 2100 ( -4.99204314e-05_wp ) * ta * va2 * d_tmrt + & 2101 ( 2.47417178e-07_wp ) * ta2 * va2 * d_tmrt + & 2102 ( 1.07596466e-08_wp ) * ta3 * va2 * d_tmrt + & 2103 ( 8.49242932e-05_wp ) * va3 * d_tmrt + & 2104 ( 1.35191328e-06_wp ) * ta * va3 * d_tmrt + & 2105 ( -6.21531254e-09_wp ) * ta2 * va3 * d_tmrt + & 2106 ( -4.99410301e-06_wp ) * va4 * d_tmrt + & 2107 ( -1.89489258e-08_wp ) * ta * va4 * d_tmrt + & 2108 ( 8.15300114e-08_wp ) * va5 * d_tmrt + & 2109 ( 7.55043090e-04_wp ) * d_tmrt2 + & 2110 ( -5.65095215e-05_wp ) * ta * d_tmrt2 + & 2111 ( -4.52166564e-07_wp ) * ta2 * d_tmrt2 + & 2112 ( 2.46688878e-08_wp ) * ta3 * d_tmrt2 + & 2113 ( 2.42674348e-10_wp ) * ta4 * d_tmrt2 + & 2114 ( 1.54547250e-04_wp ) * va * d_tmrt2 + & 2115 ( 5.24110970e-06_wp ) * ta * va * d_tmrt2 + & 2116 ( -8.75874982e-08_wp ) * ta2 * va * d_tmrt2 + & 2117 ( -1.50743064e-09_wp ) * ta3 * va * d_tmrt2 + & 2118 ( -1.56236307e-05_wp ) * va2 * d_tmrt2 + & 2119 ( -1.33895614e-07_wp ) * ta * va2 * d_tmrt2 + & 2120 ( 2.49709824e-09_wp ) * ta2 * va2 * d_tmrt2 + & 2121 ( 6.51711721e-07_wp ) * va3 * d_tmrt2 + & 2122 ( 1.94960053e-09_wp ) * ta * va3 * d_tmrt2 + & 2123 ( -1.00361113e-08_wp ) * va4 * d_tmrt2 + & 2124 ( -1.21206673e-05_wp ) * d_tmrt3 + & 2125 ( -2.18203660e-07_wp ) * ta * d_tmrt3 + & 2126 ( 7.51269482e-09_wp ) * ta2 * d_tmrt3 + & 2127 ( 9.79063848e-11_wp ) * ta3 * d_tmrt3 + & 2128 ( 1.25006734e-06_wp ) * va * d_tmrt3 + & 2129 ( -1.81584736e-09_wp ) * ta * va * d_tmrt3 + & 2130 ( -3.52197671e-10_wp ) * ta2 * va * d_tmrt3 + & 2131 ( -3.36514630e-08_wp ) * va2 * d_tmrt3 + & 2132 ( 1.35908359e-10_wp ) * ta * va2 * d_tmrt3 + & 2133 ( 4.17032620e-10_wp ) * va3 * d_tmrt3 + & 2134 ( -1.30369025e-09_wp ) * d_tmrt4 + & 2135 ( 4.13908461e-10_wp ) * ta * d_tmrt4 + & 2136 ( 9.22652254e-12_wp ) * ta2 * d_tmrt4 + & 2137 ( -5.08220384e-09_wp ) * va * d_tmrt4 + & 2138 ( -2.24730961e-11_wp ) * ta * va * d_tmrt4 + & 2139 ( 1.17139133e-10_wp ) * va2 * d_tmrt4 + & 2140 ( 6.62154879e-10_wp ) * d_tmrt5 + & 2141 ( 4.03863260e-13_wp ) * ta * d_tmrt5 + & 2142 ( 1.95087203e-12_wp ) * va * d_tmrt5 + & 2143 ( -4.73602469e-12_wp ) * d_tmrt6 2144 2145 part_pa = ( 5.12733497e+00_wp ) * pa + & 2146 ( -3.12788561e-01_wp ) * ta * pa + & 2147 ( -1.96701861e-02_wp ) * ta2 * pa + & 2148 ( 9.99690870e-04_wp ) * ta3 * pa + & 2149 ( 9.51738512e-06_wp ) * ta4 * pa + & 2150 ( -4.66426341e-07_wp ) * ta5 * pa + & 2151 ( 5.48050612e-01_wp ) * va * pa + & 2152 ( -3.30552823e-03_wp ) * ta * va * pa + & 2153 ( -1.64119440e-03_wp ) * ta2 * va * pa + & 2154 ( -5.16670694e-06_wp ) * ta3 * va * pa + & 2155 ( 9.52692432e-07_wp ) * ta4 * va * pa + & 2156 ( -4.29223622e-02_wp ) * va2 * pa + & 2157 ( 5.00845667e-03_wp ) * ta * va2 * pa + & 2158 ( 1.00601257e-06_wp ) * ta2 * va2 * pa + & 2159 ( -1.81748644e-06_wp ) * ta3 * va2 * pa + & 2160 ( -1.25813502e-03_wp ) * va3 * pa + & 2161 ( -1.79330391e-04_wp ) * ta * va3 * pa + & 2162 ( 2.34994441e-06_wp ) * ta2 * va3 * pa + & 2163 ( 1.29735808e-04_wp ) * va4 * pa + & 2164 ( 1.29064870e-06_wp ) * ta * va4 * pa + & 2165 ( -2.28558686e-06_wp ) * va5 * pa + & 2166 ( -3.69476348e-02_wp ) * d_tmrt * pa + & 2167 ( 1.62325322e-03_wp ) * ta * d_tmrt * pa + & 2168 ( -3.14279680e-05_wp ) * ta2 * d_tmrt * pa + & 2169 ( 2.59835559e-06_wp ) * ta3 * d_tmrt * pa + & 2170 ( -4.77136523e-08_wp ) * ta4 * d_tmrt * pa + & 2171 ( 8.64203390e-03_wp ) * va * d_tmrt * pa + & 2172 ( -6.87405181e-04_wp ) * ta * va * d_tmrt * pa + & 2173 ( -9.13863872e-06_wp ) * ta2 * va * d_tmrt * pa + & 2174 ( 5.15916806e-07_wp ) * ta3 * va * d_tmrt * pa + & 2175 ( -3.59217476e-05_wp ) * va2 * d_tmrt * pa + & 2176 ( 3.28696511e-05_wp ) * ta * va2 * d_tmrt * pa + & 2177 ( -7.10542454e-07_wp ) * ta2 * va2 * d_tmrt * pa + & 2178 ( -1.24382300e-05_wp ) * va3 * d_tmrt * pa + & 2179 ( -7.38584400e-09_wp ) * ta * va3 * d_tmrt * pa + & 2180 ( 2.20609296e-07_wp ) * va4 * d_tmrt * pa + & 2181 ( -7.32469180e-04_wp ) * d_tmrt2 * pa + & 2182 ( -1.87381964e-05_wp ) * ta * d_tmrt2 * pa + & 2183 ( 4.80925239e-06_wp ) * ta2 * d_tmrt2 * pa + & 2184 ( -8.75492040e-08_wp ) * ta3 * d_tmrt2 * pa + & 2185 ( 2.77862930e-05_wp ) * va * d_tmrt2 * pa + & 2186 ( -5.06004592e-06_wp ) * ta * va * d_tmrt2 * pa + & 2187 ( 1.14325367e-07_wp ) * ta2 * va * d_tmrt2 * pa + & 2188 ( 2.53016723e-06_wp ) * va2 * d_tmrt2 * pa + & 2189 ( -1.72857035e-08_wp ) * ta * va2 * d_tmrt2 * pa + & 2190 ( -3.95079398e-08_wp ) * va3 * d_tmrt2 * pa + & 2191 ( -3.59413173e-07_wp ) * d_tmrt3 * pa + & 2192 ( 7.04388046e-07_wp ) * ta * d_tmrt3 * pa + & 2193 ( -1.89309167e-08_wp ) * ta2 * d_tmrt3 * pa + & 2194 ( -4.79768731e-07_wp ) * va * d_tmrt3 * pa + & 2195 ( 7.96079978e-09_wp ) * ta * va * d_tmrt3 * pa + & 2196 ( 1.62897058e-09_wp ) * va2 * d_tmrt3 * pa + & 2197 ( 3.94367674e-08_wp ) * d_tmrt4 * pa + & 2198 ( -1.18566247e-09_wp ) * ta * d_tmrt4 * pa + & 2199 ( 3.34678041e-10_wp ) * va * d_tmrt4 * pa + & 2200 ( -1.15606447e-10_wp ) * d_tmrt5 * pa 2201 2202 part_pa2 = ( -2.80626406e+00_wp ) * pa2 + & 2203 ( 5.48712484e-01_wp ) * ta * pa2 + & 2204 ( -3.99428410e-03_wp ) * ta2 * pa2 + & 2205 ( -9.54009191e-04_wp ) * ta3 * pa2 + & 2206 ( 1.93090978e-05_wp ) * ta4 * pa2 + & 2207 ( -3.08806365e-01_wp ) * va * pa2 + & 2208 ( 1.16952364e-02_wp ) * ta * va * pa2 + & 2209 ( 4.95271903e-04_wp ) * ta2 * va * pa2 + & 2210 ( -1.90710882e-05_wp ) * ta3 * va * pa2 + & 2211 ( 2.10787756e-03_wp ) * va2 * pa2 + & 2212 ( -6.98445738e-04_wp ) * ta * va2 * pa2 + & 2213 ( 2.30109073e-05_wp ) * ta2 * va2 * pa2 + & 2214 ( 4.17856590e-04_wp ) * va3 * pa2 + & 2215 ( -1.27043871e-05_wp ) * ta * va3 * pa2 + & 2216 ( -3.04620472e-06_wp ) * va4 * pa2 + & 2217 ( 5.14507424e-02_wp ) * d_tmrt * pa2 + & 2218 ( -4.32510997e-03_wp ) * ta * d_tmrt * pa2 + & 2219 ( 8.99281156e-05_wp ) * ta2 * d_tmrt * pa2 + & 2220 ( -7.14663943e-07_wp ) * ta3 * d_tmrt * pa2 + & 2221 ( -2.66016305e-04_wp ) * va * d_tmrt * pa2 + & 2222 ( 2.63789586e-04_wp ) * ta * va * d_tmrt * pa2 + & 2223 ( -7.01199003e-06_wp ) * ta2 * va * d_tmrt * pa2 + & 2224 ( -1.06823306e-04_wp ) * va2 * d_tmrt * pa2 + & 2225 ( 3.61341136e-06_wp ) * ta * va2 * d_tmrt * pa2 + & 2226 ( 2.29748967e-07_wp ) * va3 * d_tmrt * pa2 + & 2227 ( 3.04788893e-04_wp ) * d_tmrt2 * pa2 + & 2228 ( -6.42070836e-05_wp ) * ta * d_tmrt2 * pa2 + & 2229 ( 1.16257971e-06_wp ) * ta2 * d_tmrt2 * pa2 + & 2230 ( 7.68023384e-06_wp ) * va * d_tmrt2 * pa2 + & 2231 ( -5.47446896e-07_wp ) * ta * va * d_tmrt2 * pa2 + & 2232 ( -3.59937910e-08_wp ) * va2 * d_tmrt2 * pa2 + & 2233 ( -4.36497725e-06_wp ) * d_tmrt3 * pa2 + & 2234 ( 1.68737969e-07_wp ) * ta * d_tmrt3 * pa2 + & 2235 ( 2.67489271e-08_wp ) * va * d_tmrt3 * pa2 + & 2236 ( 3.23926897e-09_wp ) * d_tmrt4 * pa2 2237 2238 part_pa3 = ( -3.53874123e-02_wp ) * pa3 + & 2239 ( -2.21201190e-01_wp ) * ta * pa3 + & 2240 ( 1.55126038e-02_wp ) * ta2 * pa3 + & 2241 ( -2.63917279e-04_wp ) * ta3 * pa3 + & 2242 ( 4.53433455e-02_wp ) * va * pa3 + & 2243 ( -4.32943862e-03_wp ) * ta * va * pa3 + & 2244 ( 1.45389826e-04_wp ) * ta2 * va * pa3 + & 2245 ( 2.17508610e-04_wp ) * va2 * pa3 + & 2246 ( -6.66724702e-05_wp ) * ta * va2 * pa3 + & 2247 ( 3.33217140e-05_wp ) * va3 * pa3 + & 2248 ( -2.26921615e-03_wp ) * d_tmrt * pa3 + & 2249 ( 3.80261982e-04_wp ) * ta * d_tmrt * pa3 + & 2250 ( -5.45314314e-09_wp ) * ta2 * d_tmrt * pa3 + & 2251 ( -7.96355448e-04_wp ) * va * d_tmrt * pa3 + & 2252 ( 2.53458034e-05_wp ) * ta * va * d_tmrt * pa3 + & 2253 ( -6.31223658e-06_wp ) * va2 * d_tmrt * pa3 + & 2254 ( 3.02122035e-04_wp ) * d_tmrt2 * pa3 + & 2255 ( -4.77403547e-06_wp ) * ta * d_tmrt2 * pa3 + & 2256 ( 1.73825715e-06_wp ) * va * d_tmrt2 * pa3 + & 2257 ( -4.09087898e-07_wp ) * d_tmrt3 * pa3 2258 2259 part_pa46 = ( 6.14155345e-01_wp ) * pa4 + & 2260 ( -6.16755931e-02_wp ) * ta * pa4 + & 2261 ( 1.33374846e-03_wp ) * ta2 * pa4 + & 2262 ( 3.55375387e-03_wp ) * va * pa4 + & 2263 ( -5.13027851e-04_wp ) * ta * va * pa4 + & 2264 ( 1.02449757e-04_wp ) * va2 * pa4 + & 2265 ( -1.48526421e-03_wp ) * d_tmrt * pa4 + & 2266 ( -4.11469183e-05_wp ) * ta * d_tmrt * pa4 + & 2267 ( -6.80434415e-06_wp ) * va * d_tmrt * pa4 + & 2268 ( -9.77675906e-06_wp ) * d_tmrt2 * pa4 + & 2269 ( 8.82773108e-02_wp ) * pa5 + & 2270 ( -3.01859306e-03_wp ) * ta * pa5 + & 2271 ( 1.04452989e-03_wp ) * va * pa5 + & 2272 ( 2.47090539e-04_wp ) * d_tmrt * pa5 + & 2273 ( 1.48348065e-03_wp ) * pa6 2274 ! 2275 !-- Calculate 6th order polynomial as approximation 2276 utci_ij = ta + part_ta + part_va + part_d_tmrt + part_pa + part_pa2 + & 2277 part_pa3 + part_pa46 2030 part_va = ( -2.25836520e+00_wp ) * va + & 2031 ( 8.80326035e-02_wp ) * ta * va + & 2032 ( 2.16844454e-03_wp ) * ta2 * va + & 2033 ( -1.53347087e-05_wp ) * ta3 * va + & 2034 ( -5.72983704e-07_wp ) * ta4 * va + & 2035 ( -2.55090145e-09_wp ) * ta5 * va + & 2036 ( -7.51269505e-01_wp ) * va2 + & 2037 ( -4.08350271e-03_wp ) * ta * va2 + & 2038 ( -5.21670675e-05_wp ) * ta2 * va2 + & 2039 ( 1.94544667e-06_wp ) * ta3 * va2 + & 2040 ( 1.14099531e-08_wp ) * ta4 * va2 + & 2041 ( 1.58137256e-01_wp ) * va3 + & 2042 ( -6.57263143e-05_wp ) * ta * va3 + & 2043 ( 2.22697524e-07_wp ) * ta2 * va3 + & 2044 ( -4.16117031e-08_wp ) * ta3 * va3 + & 2045 ( -1.27762753e-02_wp ) * va4 + & 2046 ( 9.66891875e-06_wp ) * ta * va4 + & 2047 ( 2.52785852e-09_wp ) * ta2 * va4 + & 2048 ( 4.56306672e-04_wp ) * va5 + & 2049 ( -1.74202546e-07_wp ) * ta * va5 + & 2050 ( -5.91491269e-06_wp ) * va6 2051 2052 part_d_tmrt = ( 3.98374029e-01_wp ) * d_tmrt + & 2053 ( 1.83945314e-04_wp ) * ta * d_tmrt + & 2054 ( -1.73754510e-04_wp ) * ta2 * d_tmrt + & 2055 ( -7.60781159e-07_wp ) * ta3 * d_tmrt + & 2056 ( 3.77830287e-08_wp ) * ta4 * d_tmrt + & 2057 ( 5.43079673e-10_wp ) * ta5 * d_tmrt + & 2058 ( -2.00518269e-02_wp ) * va * d_tmrt + & 2059 ( 8.92859837e-04_wp ) * ta * va * d_tmrt + & 2060 ( 3.45433048e-06_wp ) * ta2 * va * d_tmrt + & 2061 ( -3.77925774e-07_wp ) * ta3 * va * d_tmrt + & 2062 ( -1.69699377e-09_wp ) * ta4 * va * d_tmrt + & 2063 ( 1.69992415e-04_wp ) * va2 * d_tmrt + & 2064 ( -4.99204314e-05_wp ) * ta * va2 * d_tmrt + & 2065 ( 2.47417178e-07_wp ) * ta2 * va2 * d_tmrt + & 2066 ( 1.07596466e-08_wp ) * ta3 * va2 * d_tmrt + & 2067 ( 8.49242932e-05_wp ) * va3 * d_tmrt + & 2068 ( 1.35191328e-06_wp ) * ta * va3 * d_tmrt + & 2069 ( -6.21531254e-09_wp ) * ta2 * va3 * d_tmrt + & 2070 ( -4.99410301e-06_wp ) * va4 * d_tmrt + & 2071 ( -1.89489258e-08_wp ) * ta * va4 * d_tmrt + & 2072 ( 8.15300114e-08_wp ) * va5 * d_tmrt + & 2073 ( 7.55043090e-04_wp ) * d_tmrt2 + & 2074 ( -5.65095215e-05_wp ) * ta * d_tmrt2 + & 2075 ( -4.52166564e-07_wp ) * ta2 * d_tmrt2 + & 2076 ( 2.46688878e-08_wp ) * ta3 * d_tmrt2 + & 2077 ( 2.42674348e-10_wp ) * ta4 * d_tmrt2 + & 2078 ( 1.54547250e-04_wp ) * va * d_tmrt2 + & 2079 ( 5.24110970e-06_wp ) * ta * va * d_tmrt2 + & 2080 ( -8.75874982e-08_wp ) * ta2 * va * d_tmrt2 + & 2081 ( -1.50743064e-09_wp ) * ta3 * va * d_tmrt2 + & 2082 ( -1.56236307e-05_wp ) * va2 * d_tmrt2 + & 2083 ( -1.33895614e-07_wp ) * ta * va2 * d_tmrt2 + & 2084 ( 2.49709824e-09_wp ) * ta2 * va2 * d_tmrt2 + & 2085 ( 6.51711721e-07_wp ) * va3 * d_tmrt2 + & 2086 ( 1.94960053e-09_wp ) * ta * va3 * d_tmrt2 + & 2087 ( -1.00361113e-08_wp ) * va4 * d_tmrt2 + & 2088 ( -1.21206673e-05_wp ) * d_tmrt3 + & 2089 ( -2.18203660e-07_wp ) * ta * d_tmrt3 + & 2090 ( 7.51269482e-09_wp ) * ta2 * d_tmrt3 + & 2091 ( 9.79063848e-11_wp ) * ta3 * d_tmrt3 + & 2092 ( 1.25006734e-06_wp ) * va * d_tmrt3 + & 2093 ( -1.81584736e-09_wp ) * ta * va * d_tmrt3 + & 2094 ( -3.52197671e-10_wp ) * ta2 * va * d_tmrt3 + & 2095 ( -3.36514630e-08_wp ) * va2 * d_tmrt3 + & 2096 ( 1.35908359e-10_wp ) * ta * va2 * d_tmrt3 + & 2097 ( 4.17032620e-10_wp ) * va3 * d_tmrt3 + & 2098 ( -1.30369025e-09_wp ) * d_tmrt4 + & 2099 ( 4.13908461e-10_wp ) * ta * d_tmrt4 + & 2100 ( 9.22652254e-12_wp ) * ta2 * d_tmrt4 + & 2101 ( -5.08220384e-09_wp ) * va * d_tmrt4 + & 2102 ( -2.24730961e-11_wp ) * ta * va * d_tmrt4 + & 2103 ( 1.17139133e-10_wp ) * va2 * d_tmrt4 + & 2104 ( 6.62154879e-10_wp ) * d_tmrt5 + & 2105 ( 4.03863260e-13_wp ) * ta * d_tmrt5 + & 2106 ( 1.95087203e-12_wp ) * va * d_tmrt5 + & 2107 ( -4.73602469e-12_wp ) * d_tmrt6 2108 2109 part_pa = ( 5.12733497e+00_wp ) * pa + & 2110 ( -3.12788561e-01_wp ) * ta * pa + & 2111 ( -1.96701861e-02_wp ) * ta2 * pa + & 2112 ( 9.99690870e-04_wp ) * ta3 * pa + & 2113 ( 9.51738512e-06_wp ) * ta4 * pa + & 2114 ( -4.66426341e-07_wp ) * ta5 * pa + & 2115 ( 5.48050612e-01_wp ) * va * pa + & 2116 ( -3.30552823e-03_wp ) * ta * va * pa + & 2117 ( -1.64119440e-03_wp ) * ta2 * va * pa + & 2118 ( -5.16670694e-06_wp ) * ta3 * va * pa + & 2119 ( 9.52692432e-07_wp ) * ta4 * va * pa + & 2120 ( -4.29223622e-02_wp ) * va2 * pa + & 2121 ( 5.00845667e-03_wp ) * ta * va2 * pa + & 2122 ( 1.00601257e-06_wp ) * ta2 * va2 * pa + & 2123 ( -1.81748644e-06_wp ) * ta3 * va2 * pa + & 2124 ( -1.25813502e-03_wp ) * va3 * pa + & 2125 ( -1.79330391e-04_wp ) * ta * va3 * pa + & 2126 ( 2.34994441e-06_wp ) * ta2 * va3 * pa + & 2127 ( 1.29735808e-04_wp ) * va4 * pa + & 2128 ( 1.29064870e-06_wp ) * ta * va4 * pa + & 2129 ( -2.28558686e-06_wp ) * va5 * pa + & 2130 ( -3.69476348e-02_wp ) * d_tmrt * pa + & 2131 ( 1.62325322e-03_wp ) * ta * d_tmrt * pa + & 2132 ( -3.14279680e-05_wp ) * ta2 * d_tmrt * pa + & 2133 ( 2.59835559e-06_wp ) * ta3 * d_tmrt * pa + & 2134 ( -4.77136523e-08_wp ) * ta4 * d_tmrt * pa + & 2135 ( 8.64203390e-03_wp ) * va * d_tmrt * pa + & 2136 ( -6.87405181e-04_wp ) * ta * va * d_tmrt * pa + & 2137 ( -9.13863872e-06_wp ) * ta2 * va * d_tmrt * pa + & 2138 ( 5.15916806e-07_wp ) * ta3 * va * d_tmrt * pa + & 2139 ( -3.59217476e-05_wp ) * va2 * d_tmrt * pa + & 2140 ( 3.28696511e-05_wp ) * ta * va2 * d_tmrt * pa + & 2141 ( -7.10542454e-07_wp ) * ta2 * va2 * d_tmrt * pa + & 2142 ( -1.24382300e-05_wp ) * va3 * d_tmrt * pa + & 2143 ( -7.38584400e-09_wp ) * ta * va3 * d_tmrt * pa + & 2144 ( 2.20609296e-07_wp ) * va4 * d_tmrt * pa + & 2145 ( -7.32469180e-04_wp ) * d_tmrt2 * pa + & 2146 ( -1.87381964e-05_wp ) * ta * d_tmrt2 * pa + & 2147 ( 4.80925239e-06_wp ) * ta2 * d_tmrt2 * pa + & 2148 ( -8.75492040e-08_wp ) * ta3 * d_tmrt2 * pa + & 2149 ( 2.77862930e-05_wp ) * va * d_tmrt2 * pa + & 2150 ( -5.06004592e-06_wp ) * ta * va * d_tmrt2 * pa + & 2151 ( 1.14325367e-07_wp ) * ta2 * va * d_tmrt2 * pa + & 2152 ( 2.53016723e-06_wp ) * va2 * d_tmrt2 * pa + & 2153 ( -1.72857035e-08_wp ) * ta * va2 * d_tmrt2 * pa + & 2154 ( -3.95079398e-08_wp ) * va3 * d_tmrt2 * pa + & 2155 ( -3.59413173e-07_wp ) * d_tmrt3 * pa + & 2156 ( 7.04388046e-07_wp ) * ta * d_tmrt3 * pa + & 2157 ( -1.89309167e-08_wp ) * ta2 * d_tmrt3 * pa + & 2158 ( -4.79768731e-07_wp ) * va * d_tmrt3 * pa + & 2159 ( 7.96079978e-09_wp ) * ta * va * d_tmrt3 * pa + & 2160 ( 1.62897058e-09_wp ) * va2 * d_tmrt3 * pa + & 2161 ( 3.94367674e-08_wp ) * d_tmrt4 * pa + & 2162 ( -1.18566247e-09_wp ) * ta * d_tmrt4 * pa + & 2163 ( 3.34678041e-10_wp ) * va * d_tmrt4 * pa + & 2164 ( -1.15606447e-10_wp ) * d_tmrt5 * pa 2165 2166 part_pa2 = ( -2.80626406e+00_wp ) * pa2 + & 2167 ( 5.48712484e-01_wp ) * ta * pa2 + & 2168 ( -3.99428410e-03_wp ) * ta2 * pa2 + & 2169 ( -9.54009191e-04_wp ) * ta3 * pa2 + & 2170 ( 1.93090978e-05_wp ) * ta4 * pa2 + & 2171 ( -3.08806365e-01_wp ) * va * pa2 + & 2172 ( 1.16952364e-02_wp ) * ta * va * pa2 + & 2173 ( 4.95271903e-04_wp ) * ta2 * va * pa2 + & 2174 ( -1.90710882e-05_wp ) * ta3 * va * pa2 + & 2175 ( 2.10787756e-03_wp ) * va2 * pa2 + & 2176 ( -6.98445738e-04_wp ) * ta * va2 * pa2 + & 2177 ( 2.30109073e-05_wp ) * ta2 * va2 * pa2 + & 2178 ( 4.17856590e-04_wp ) * va3 * pa2 + & 2179 ( -1.27043871e-05_wp ) * ta * va3 * pa2 + & 2180 ( -3.04620472e-06_wp ) * va4 * pa2 + & 2181 ( 5.14507424e-02_wp ) * d_tmrt * pa2 + & 2182 ( -4.32510997e-03_wp ) * ta * d_tmrt * pa2 + & 2183 ( 8.99281156e-05_wp ) * ta2 * d_tmrt * pa2 + & 2184 ( -7.14663943e-07_wp ) * ta3 * d_tmrt * pa2 + & 2185 ( -2.66016305e-04_wp ) * va * d_tmrt * pa2 + & 2186 ( 2.63789586e-04_wp ) * ta * va * d_tmrt * pa2 + & 2187 ( -7.01199003e-06_wp ) * ta2 * va * d_tmrt * pa2 + & 2188 ( -1.06823306e-04_wp ) * va2 * d_tmrt * pa2 + & 2189 ( 3.61341136e-06_wp ) * ta * va2 * d_tmrt * pa2 + & 2190 ( 2.29748967e-07_wp ) * va3 * d_tmrt * pa2 + & 2191 ( 3.04788893e-04_wp ) * d_tmrt2 * pa2 + & 2192 ( -6.42070836e-05_wp ) * ta * d_tmrt2 * pa2 + & 2193 ( 1.16257971e-06_wp ) * ta2 * d_tmrt2 * pa2 + & 2194 ( 7.68023384e-06_wp ) * va * d_tmrt2 * pa2 + & 2195 ( -5.47446896e-07_wp ) * ta * va * d_tmrt2 * pa2 + & 2196 ( -3.59937910e-08_wp ) * va2 * d_tmrt2 * pa2 + & 2197 ( -4.36497725e-06_wp ) * d_tmrt3 * pa2 + & 2198 ( 1.68737969e-07_wp ) * ta * d_tmrt3 * pa2 + & 2199 ( 2.67489271e-08_wp ) * va * d_tmrt3 * pa2 + & 2200 ( 3.23926897e-09_wp ) * d_tmrt4 * pa2 2201 2202 part_pa3 = ( -3.53874123e-02_wp ) * pa3 + & 2203 ( -2.21201190e-01_wp ) * ta * pa3 + & 2204 ( 1.55126038e-02_wp ) * ta2 * pa3 + & 2205 ( -2.63917279e-04_wp ) * ta3 * pa3 + & 2206 ( 4.53433455e-02_wp ) * va * pa3 + & 2207 ( -4.32943862e-03_wp ) * ta * va * pa3 + & 2208 ( 1.45389826e-04_wp ) * ta2 * va * pa3 + & 2209 ( 2.17508610e-04_wp ) * va2 * pa3 + & 2210 ( -6.66724702e-05_wp ) * ta * va2 * pa3 + & 2211 ( 3.33217140e-05_wp ) * va3 * pa3 + & 2212 ( -2.26921615e-03_wp ) * d_tmrt * pa3 + & 2213 ( 3.80261982e-04_wp ) * ta * d_tmrt * pa3 + & 2214 ( -5.45314314e-09_wp ) * ta2 * d_tmrt * pa3 + & 2215 ( -7.96355448e-04_wp ) * va * d_tmrt * pa3 + & 2216 ( 2.53458034e-05_wp ) * ta * va * d_tmrt * pa3 + & 2217 ( -6.31223658e-06_wp ) * va2 * d_tmrt * pa3 + & 2218 ( 3.02122035e-04_wp ) * d_tmrt2 * pa3 + & 2219 ( -4.77403547e-06_wp ) * ta * d_tmrt2 * pa3 + & 2220 ( 1.73825715e-06_wp ) * va * d_tmrt2 * pa3 + & 2221 ( -4.09087898e-07_wp ) * d_tmrt3 * pa3 2222 2223 part_pa46 = ( 6.14155345e-01_wp ) * pa4 + & 2224 ( -6.16755931e-02_wp ) * ta * pa4 + & 2225 ( 1.33374846e-03_wp ) * ta2 * pa4 + & 2226 ( 3.55375387e-03_wp ) * va * pa4 + & 2227 ( -5.13027851e-04_wp ) * ta * va * pa4 + & 2228 ( 1.02449757e-04_wp ) * va2 * pa4 + & 2229 ( -1.48526421e-03_wp ) * d_tmrt * pa4 + & 2230 ( -4.11469183e-05_wp ) * ta * d_tmrt * pa4 + & 2231 ( -6.80434415e-06_wp ) * va * d_tmrt * pa4 + & 2232 ( -9.77675906e-06_wp ) * d_tmrt2 * pa4 + & 2233 ( 8.82773108e-02_wp ) * pa5 + & 2234 ( -3.01859306e-03_wp ) * ta * pa5 + & 2235 ( 1.04452989e-03_wp ) * va * pa5 + & 2236 ( 2.47090539e-04_wp ) * d_tmrt * pa5 + & 2237 ( 1.48348065e-03_wp ) * pa6 2238 ! 2239 !-- Calculate 6th order polynomial as approximation 2240 utci_ij = ta + part_ta + part_va + part_d_tmrt + part_pa + part_pa2 + part_pa3 + part_pa46 2278 2241 ! 2279 2242 !-- Consider offset in result … … 2285 2248 2286 2249 2287 !------------------------------------------------------------------------------ !2250 !--------------------------------------------------------------------------------------------------! 2288 2251 ! Description: 2289 2252 ! ------------ 2290 !> calculate_perct_static: Estimation of perceived temperature (PT, degree_C)2253 !> Calculate_perct_static: Estimation of perceived temperature (PT, degree_C) 2291 2254 !> Value of perct is the Perceived Temperature, degree centigrade 2292 !------------------------------------------------------------------------------ !2255 !--------------------------------------------------------------------------------------------------! 2293 2256 SUBROUTINE calculate_perct_static( ta, vp, ws, tmrt, pair, clo, perct_ij ) 2294 2257 … … 2296 2259 ! 2297 2260 !-- Type of input of the argument list 2261 REAL(wp), INTENT ( IN ) :: pair !< Local barometric air pressure (hPa) 2298 2262 REAL(wp), INTENT ( IN ) :: ta !< Local air temperature (degC) 2263 REAL(wp), INTENT ( IN ) :: tmrt !< Local mean radiant temperature (degC) 2299 2264 REAL(wp), INTENT ( IN ) :: vp !< Local vapour pressure (hPa) 2300 REAL(wp), INTENT ( IN ) :: tmrt !< Local mean radiant temperature (degC)2301 2265 REAL(wp), INTENT ( IN ) :: ws !< Local wind velocitry (m/s) 2302 REAL(wp), INTENT ( IN ) :: pair !< Local barometric air pressure (hPa)2303 2266 ! 2304 2267 !-- Type of output of the argument list 2268 REAL(wp), INTENT ( OUT ) :: clo !< Clothing index (dimensionless) 2305 2269 REAL(wp), INTENT ( OUT ) :: perct_ij !< Perceived temperature (degC) 2306 REAL(wp), INTENT ( OUT ) :: clo !< Clothing index (dimensionless)2307 2270 ! 2308 2271 !-- Parameters for standard "Klima-Michel" 2309 REAL(wp), PARAMETER :: eta = 0._wp !< Mechanical work efficiency for walking on flat ground 2310 !< (compare to Fanger (1972) pp 24f) 2311 REAL(wp), PARAMETER :: actlev = 134.6862_wp !< Workload by activity per standardized surface (A_Du) 2272 REAL(wp), PARAMETER :: actlev = 134.6862_wp !< Workload by activity per standardized surface 2273 !< (A_Du) 2274 REAL(wp), PARAMETER :: eta = 0.0_wp !< Mechanical work efficiency for walking on flat 2275 !< ground (compare to Fanger (1972) pp 24f) 2312 2276 ! 2313 2277 !-- Type of program variables 2314 REAL(wp), PARAMETER :: eps = 0.0005 !< Accuracy in clothing insulation (clo) for evaluation the root of Fanger's PMV (pmva=0)2315 REAL(wp) :: sclo !< summer clothing insulation2316 REAL(wp) :: wclo !< winter clothing insulation2317 REAL(wp) :: d_pmv !< PMV deviation (dimensionless --> PMV)2318 REAL(wp) :: svp_ta !< saturation vapor pressure (hPa)2319 REAL(wp) :: sult_lim !< threshold for sultrieness (hPa)2320 REAL(wp) :: dgtcm !< Mean deviation dependent on perct2321 REAL(wp) :: dgtcstd !< Mean deviation plus its standard deviation2322 REAL(wp) :: clon !< clo for neutral conditions (clo)2323 REAL(wp) :: ireq_minimal !< Minimal required clothing insulation (clo)2324 REAL(wp) :: pmv_w !< Fangers predicted mean vote for winter clothing2325 REAL(wp) :: pmv_s !< Fangers predicted mean vote for summer clothing2326 REAL(wp) :: pmva !< adjusted predicted mean vote2327 REAL(wp) :: ptc !< perceived temp. for cold conditions (degree_C)2328 REAL(wp) :: d_std !< factor to threshold for sultriness2329 REAL(wp) :: pmvs !< pred. mean vote considering sultrieness2330 2331 2278 INTEGER(iwp) :: ncount !< running index 2332 2279 INTEGER(iwp) :: nerr_cold !< error number (cold conditions) … … 2334 2281 2335 2282 LOGICAL :: sultrieness 2283 2284 REAL(wp), PARAMETER :: eps = 0.0005 !< Accuracy in clothing insulation (clo) for evaluation the 2285 !< root of Fanger's PMV (pmva=0) 2286 2287 REAL(wp) :: clon !< clo for neutral conditions (clo) 2288 REAL(wp) :: d_pmv !< PMV deviation (dimensionless --> PMV) 2289 REAL(wp) :: dgtcm !< Mean deviation dependent on perct 2290 REAL(wp) :: dgtcstd !< Mean deviation plus its standard deviation 2291 REAL(wp) :: d_std !< factor to threshold for sultriness 2292 REAL(wp) :: ireq_minimal !< Minimal required clothing insulation (clo) 2293 REAL(wp) :: pmv_s !< Fangers predicted mean vote for summer clothing 2294 REAL(wp) :: pmv_w !< Fangers predicted mean vote for winter clothing 2295 REAL(wp) :: pmva !< adjusted predicted mean vote 2296 REAL(wp) :: pmvs !< pred. mean vote considering sultrieness 2297 REAL(wp) :: ptc !< perceived temp. for cold conditions (degree_C) 2298 REAL(wp) :: sclo !< summer clothing insulation 2299 REAL(wp) :: svp_ta !< saturation vapor pressure (hPa) 2300 REAL(wp) :: sult_lim !< threshold for sultrieness (hPa) 2301 REAL(wp) :: wclo !< winter clothing insulation 2302 2336 2303 ! 2337 2304 !-- Initialise … … 2343 2310 ! 2344 2311 !-- Tresholds: clothing insulation (account for model inaccuracies) 2345 ! 2346 !-- summer clothing 2312 !-- Summer clothing 2347 2313 sclo = 0.44453_wp 2348 2314 ! 2349 !-- winter clothing2315 !-- Winter clothing 2350 2316 wclo = 1.76267_wp 2351 2317 ! 2352 !-- decision: firstlycalculate for winter or summer clothing2353 IF ( ta <= 10. _wp ) THEN2318 !-- Eecision: first calculate for winter or summer clothing 2319 IF ( ta <= 10.0_wp ) THEN 2354 2320 ! 2355 2321 !-- First guess: winter clothing insulation: cold stress … … 2358 2324 pmv_w = pmva 2359 2325 2360 IF ( pmva > 0. _wp ) THEN2326 IF ( pmva > 0.0_wp ) THEN 2361 2327 ! 2362 2328 !-- Case summer clothing insulation: heat load ? … … 2364 2330 CALL fanger ( ta, tmrt, vp, ws, pair, clo, actlev, eta, pmva ) 2365 2331 pmv_s = pmva 2366 IF ( pmva <= 0. _wp ) THEN2367 ! 2368 !-- Case: comfort achievable by varying clothing insulation 2369 !-- Between winter and summer setvalues2370 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta, sclo, 2371 pmv_s, wclo, pmv_w, eps,pmva, ncount, clo )2332 IF ( pmva <= 0.0_wp ) THEN 2333 ! 2334 !-- Case: comfort achievable by varying clothing insulation between winter and summer set 2335 !-- values 2336 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta, sclo, pmv_s, wclo, pmv_w, eps, & 2337 pmva, ncount, clo ) 2372 2338 IF ( ncount < 0_iwp ) THEN 2373 2339 nerr = -1_iwp … … 2376 2342 ELSE IF ( pmva > 0.06_wp ) THEN 2377 2343 clo = 0.5_wp 2378 CALL fanger ( ta, tmrt, vp, ws, pair, clo, actlev, eta, & 2379 pmva ) 2344 CALL fanger ( ta, tmrt, vp, ws, pair, clo, actlev, eta, pmva ) 2380 2345 ENDIF 2381 ELSE IF ( pmva < - 0.11_wp ) THEN2346 ELSE IF ( pmva < - 0.11_wp ) THEN 2382 2347 clo = 1.75_wp 2383 2348 CALL fanger ( ta, tmrt, vp, ws, pair, clo, actlev, eta, pmva ) … … 2390 2355 pmv_s = pmva 2391 2356 2392 IF ( pmva < 0. _wp ) THEN2357 IF ( pmva < 0.0_wp ) THEN 2393 2358 ! 2394 2359 !-- Case winter clothing insulation: cold stress ? … … 2397 2362 pmv_w = pmva 2398 2363 2399 IF ( pmva >= 0. _wp ) THEN2400 ! 2401 !-- Case: comfort achievable by varying clothing insulation 2402 !-- between winter and summer setvalues2403 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta, sclo, 2404 pmv _s, wclo, pmv_w, eps, pmva, ncount, clo )2364 IF ( pmva >= 0.0_wp ) THEN 2365 ! 2366 !-- Case: comfort achievable by varying clothing insulation between winter and summer set 2367 !-- values 2368 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta, sclo, pmv_s, wclo, pmv_w, eps, & 2369 pmva, ncount, clo ) 2405 2370 IF ( ncount < 0_iwp ) THEN 2406 2371 nerr = -1_iwp 2407 2372 RETURN 2408 2373 ENDIF 2409 ELSE IF ( pmva < - 0.11_wp ) THEN2374 ELSE IF ( pmva < - 0.11_wp ) THEN 2410 2375 clo = 1.75_wp 2411 CALL fanger ( ta, tmrt, vp, ws, pair, clo, actlev, eta, & 2412 pmva ) 2376 CALL fanger ( ta, tmrt, vp, ws, pair, clo, actlev, eta, pmva ) 2413 2377 ENDIF 2414 2378 ELSE IF ( pmva > 0.06_wp ) THEN … … 2423 2387 CALL perct_regression( pmva, clo, perct_ij ) 2424 2388 ptc = perct_ij 2425 IF ( clo >= 1.75_wp .AND. pmva <= - 0.11_wp ) THEN2389 IF ( clo >= 1.75_wp .AND. pmva <= - 0.11_wp ) THEN 2426 2390 ! 2427 2391 !-- Adjust for cold conditions according to Gagge 1986 … … 2429 2393 IF ( nerr_cold > 0_iwp ) nerr = -5_iwp 2430 2394 pmvs = pmva - d_pmv 2431 IF ( pmvs > - 0.11_wp ) THEN2432 d_pmv = 0. _wp2433 pmvs = - 0.11_wp2395 IF ( pmvs > - 0.11_wp ) THEN 2396 d_pmv = 0.0_wp 2397 pmvs = - 0.11_wp 2434 2398 ENDIF 2435 2399 CALL perct_regression( pmvs, clo, perct_ij ) … … 2439 2403 IF ( clo > 0.5_wp .AND. perct_ij <= 8.73_wp ) THEN 2440 2404 ! 2441 !-- Required clothing insulation (ireq) is exclusively defined for 2442 !-- perceived temperatures (perct) less 10 (C) for a 2443 !-- reference wind of 0.2 m/s according to 8.73 (C) for 0.1 m/s 2405 !-- Required clothing insulation (ireq) is exclusively defined for perceived temperatures (perct) 2406 !-- less 10 (C) for a reference wind of 0.2 m/s according to 8.73 (C) for 0.1 m/s. 2444 2407 clon = ireq_neutral ( perct_ij, ireq_minimal, nerr ) 2445 2408 clo = clon … … 2447 2410 CALL calc_sultr( ptc, dgtcm, dgtcstd, sult_lim ) 2448 2411 sultrieness = .FALSE. 2449 d_std = -99. _wp2412 d_std = -99.0_wp 2450 2413 IF ( pmva > 0.06_wp .AND. clo <= 0.5_wp ) THEN 2451 2414 ! … … 2455 2418 pmvs = pmva + d_pmv 2456 2419 CALL perct_regression( pmvs, clo, perct_ij ) 2457 IF ( sult_lim < 99. _wp ) THEN2420 IF ( sult_lim < 99.0_wp ) THEN 2458 2421 IF ( (perct_ij - ptc) > sult_lim ) sultrieness = .TRUE. 2459 2422 ! … … 2467 2430 END SUBROUTINE calculate_perct_static 2468 2431 2469 !------------------------------------------------------------------------------ !2432 !--------------------------------------------------------------------------------------------------! 2470 2433 ! Description: 2471 2434 ! ------------ 2472 !> The SUBROUTINE calculates the (saturation) water vapour pressure 2473 !> (hPa = hecto Pascal) for a given temperature ta (degC). 2474 !> 'ta' can be the air temperature or the dew point temperature. The first will 2475 !> result in the current vapor pressure (hPa), the latter will calulate the 2476 !> saturation vapor pressure (hPa). 2477 !------------------------------------------------------------------------------! 2435 !> The SUBROUTINE calculates the (saturation) water vapour pressure (hPa = hecto Pascal) for a given 2436 !> temperature ta (degC). 2437 !>'ta' can be the air temperature or the dew point temperature. The first will result in the current 2438 !> vapor pressure (hPa), the latter will calulate the saturation vapor pressure (hPa). 2439 !--------------------------------------------------------------------------------------------------! 2478 2440 SUBROUTINE saturation_vapor_pressure( ta, svp_ta ) 2479 2441 … … 2487 2449 2488 2450 2489 IF ( ta < 0. _wp ) THEN2451 IF ( ta < 0.0_wp ) THEN 2490 2452 ! 2491 2453 !-- ta < 0 (degC): water vapour pressure over ice … … 2504 2466 END SUBROUTINE saturation_vapor_pressure 2505 2467 2506 !------------------------------------------------------------------------------ !2468 !--------------------------------------------------------------------------------------------------! 2507 2469 ! Description: 2508 2470 ! ------------ 2509 !> Find the clothing insulation value clo_res (clo) to make Fanger's Predicted 2510 !> Mean Vote (PMV) equal comfort (pmva=0) for actual meteorological conditions 2511 !> (ta,tmrt, vp, ws, pair) and values of individual's activity level 2512 !------------------------------------------------------------------------------! 2513 SUBROUTINE iso_ridder( ta, tmrt, vp, ws, pair, actlev, eta, sclo, & 2514 pmv_s, wclo, pmv_w, eps, pmva, nerr, & 2515 clo_res ) 2471 !> Find the clothing insulation value clo_res (clo) to make Fanger's Predicted Mean Vote (PMV) equal 2472 !> comfort (pmva=0) for actual meteorological conditions (ta,tmrt, vp, ws, pair) and values of 2473 !> individual's activity level. 2474 !--------------------------------------------------------------------------------------------------! 2475 SUBROUTINE iso_ridder( ta, tmrt, vp, ws, pair, actlev, eta, sclo, pmv_s, wclo, pmv_w, eps, pmva, & 2476 nerr, clo_res ) 2516 2477 2517 2478 IMPLICIT NONE 2518 2479 ! 2519 2480 !-- Input variables of argument list: 2481 REAL(wp), INTENT ( IN ) :: actlev !< Individuals activity level per unit surface area (W/m2) 2482 REAL(wp), INTENT ( IN ) :: eps !< (0.05) accuracy in clothing insulation (clo) for evaluation the root of Fanger's PMV (pmva=0) 2483 REAL(wp), INTENT ( IN ) :: eta !< Individuals work efficiency (dimensionless) 2484 REAL(wp), INTENT ( IN ) :: pair !< Barometric air pressure (hPa) 2485 REAL(wp), INTENT ( IN ) :: pmv_s !< Fanger's PMV corresponding to sclo 2486 REAL(wp), INTENT ( IN ) :: pmv_w !< Fanger's PMV corresponding to wclo 2487 REAL(wp), INTENT ( IN ) :: sclo !< Lower threshold of bracketing clothing insulation (clo) 2520 2488 REAL(wp), INTENT ( IN ) :: ta !< Ambient temperature (degC) 2521 2489 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degC) 2522 2490 REAL(wp), INTENT ( IN ) :: vp !< Water vapour pressure (hPa) 2491 REAL(wp), INTENT ( IN ) :: wclo !< Upper threshold of bracketing clothing insulation (clo) 2523 2492 REAL(wp), INTENT ( IN ) :: ws !< Wind speed (m/s) 1 m above ground 2524 REAL(wp), INTENT ( IN ) :: pair !< Barometric air pressure (hPa)2525 REAL(wp), INTENT ( IN ) :: actlev !< Individuals activity level per unit surface area (W/m2)2526 REAL(wp), INTENT ( IN ) :: eta !< Individuals work efficiency (dimensionless)2527 REAL(wp), INTENT ( IN ) :: sclo !< Lower threshold of bracketing clothing insulation (clo)2528 REAL(wp), INTENT ( IN ) :: wclo !< Upper threshold of bracketing clothing insulation (clo)2529 REAL(wp), INTENT ( IN ) :: eps !< (0.05) accuracy in clothing insulation (clo) for2530 ! evaluation the root of Fanger's PMV (pmva=0)2531 REAL(wp), INTENT ( IN ) :: pmv_w !< Fanger's PMV corresponding to wclo2532 REAL(wp), INTENT ( IN ) :: pmv_s !< Fanger's PMV corresponding to sclo2533 2493 ! 2534 2494 !-- Output variables of argument list: 2535 REAL(wp), INTENT ( OUT ) :: pmva !< 0 (set to zero, because clo is evaluated for comfort)2536 REAL(wp), INTENT ( OUT ) :: clo_res !< Resulting clothing insulation value (clo)2537 2495 INTEGER(iwp), INTENT ( OUT ) :: nerr !< Error status / quality flag 2538 2496 !< nerr >= 0, o.k., and nerr is the number of iterations for convergence 2539 2497 !< nerr = -1: error = malfunction of Ridder's convergence method 2540 !< nerr = -2: error = maximum iterations (max_iteration) exceeded 2498 !< nerr = -2: error = maximum iterations (max_iteration) exceeded 2541 2499 !< nerr = -3: error = root not bracketed between sclo and wclo 2500 2501 REAL(wp), INTENT ( OUT ) :: clo_res !< Resulting clothing insulation value (clo) 2502 REAL(wp), INTENT ( OUT ) :: pmva !< 0 (set to zero, because clo is evaluated for comfort) 2542 2503 ! 2543 2504 !-- Type of program variables 2544 2505 INTEGER(iwp), PARAMETER :: max_iteration = 15_iwp !< max number of iterations 2506 INTEGER(iwp) :: j !< running index 2507 2545 2508 REAL(wp), PARAMETER :: guess_0 = -1.11e30_wp !< initial guess 2546 REAL(wp) :: x_ridder !< current guess for clothing insulation (clo) 2509 2547 2510 REAL(wp) :: clo_lower !< lower limit of clothing insulation (clo) 2548 2511 REAL(wp) :: clo_upper !< upper limit of clothing insulation (clo) 2512 REAL(wp) :: sroot !< sqrt of PMV-guess 2513 REAL(wp) :: x_average !< average of x_lower and x_upper (clo) 2549 2514 REAL(wp) :: x_lower !< lower guess for clothing insulation (clo) 2515 REAL(wp) :: x_new !< preliminary result for clothing insulation (clo) 2516 REAL(wp) :: x_ridder !< current guess for clothing insulation (clo) 2550 2517 REAL(wp) :: x_upper !< upper guess for clothing insulation (clo) 2551 REAL(wp) :: x_average !< average of x_lower and x_upper (clo)2552 REAL(wp) :: x_new !< preliminary result for clothing insulation (clo)2518 REAL(wp) :: y_average !< average of y_lower and y_upper 2519 REAL(wp) :: y_new !< preliminary result for pred. mean vote 2553 2520 REAL(wp) :: y_lower !< predicted mean vote for summer clothing 2554 2521 REAL(wp) :: y_upper !< predicted mean vote for winter clothing 2555 REAL(wp) :: y_average !< average of y_lower and y_upper2556 REAL(wp) :: y_new !< preliminary result for pred. mean vote2557 REAL(wp) :: sroot !< sqrt of PMV-guess2558 INTEGER(iwp) :: j !< running index2559 2522 ! 2560 2523 !-- Initialise … … 2563 2526 !-- Set pmva = 0 (comfort): Root of PMV depending on clothing insulation 2564 2527 x_ridder = bio_fill_value 2565 pmva = 0. _wp2528 pmva = 0.0_wp 2566 2529 clo_lower = sclo 2567 2530 y_lower = pmv_s 2568 2531 clo_upper = wclo 2569 2532 y_upper = pmv_w 2570 IF ( ( y_lower > 0. _wp .AND. y_upper < 0._wp ) .OR.&2571 ( y_lower < 0. _wp .AND. y_upper > 0._wp ) ) THEN2533 IF ( ( y_lower > 0.0_wp .AND. y_upper < 0.0_wp ) .OR. & 2534 ( y_lower < 0.0_wp .AND. y_upper > 0.0_wp ) ) THEN 2572 2535 x_lower = clo_lower 2573 2536 x_upper = clo_upper … … 2576 2539 DO j = 1_iwp, max_iteration 2577 2540 x_average = 0.5_wp * ( x_lower + x_upper ) 2578 CALL fanger ( ta, tmrt, vp, ws, pair, x_average, actlev, eta, & 2579 y_average ) 2541 CALL fanger ( ta, tmrt, vp, ws, pair, x_average, actlev, eta, y_average ) 2580 2542 sroot = SQRT( y_average**2 - y_lower * y_upper ) 2581 2543 IF ( ABS( sroot ) < 0.00001_wp ) THEN … … 2584 2546 RETURN 2585 2547 ENDIF 2586 x_new = x_average + ( x_average - x_lower ) * &2587 ( SIGN ( 1._wp, y_lower - y_upper ) * y_average / sroot )2548 x_new = x_average + ( x_average - x_lower ) * & 2549 ( SIGN ( 1.0_wp, y_lower - y_upper ) * y_average / sroot ) 2588 2550 IF ( ABS( x_new - x_ridder ) <= eps ) THEN 2589 2551 clo_res = x_ridder … … 2592 2554 ENDIF 2593 2555 x_ridder = x_new 2594 CALL fanger ( ta, tmrt, vp, ws, pair, x_ridder, actlev, eta, & 2595 y_new ) 2556 CALL fanger ( ta, tmrt, vp, ws, pair, x_ridder, actlev, eta, y_new ) 2596 2557 IF ( ABS( y_new ) < 0.00001_wp ) THEN 2597 2558 clo_res = x_ridder … … 2612 2573 ELSE 2613 2574 ! 2614 !-- Never get here in x_ridder: singularity in y2575 !-- Never get here in x_ridder: SINgularity in y 2615 2576 nerr = -1_iwp 2616 2577 clo_res = x_ridder … … 2642 2603 END SUBROUTINE iso_ridder 2643 2604 2644 !------------------------------------------------------------------------------ !2605 !--------------------------------------------------------------------------------------------------! 2645 2606 ! Description: 2646 2607 ! ------------ 2647 !> Regression relations between perceived temperature (perct) and (adjusted) 2648 !> PMV. The regression presumes the Klima-Michel settings for reference 2649 !> individual and reference environment. 2650 !------------------------------------------------------------------------------! 2608 !> Regression relations between perceived temperature (perct) and (adjusted) PMV. The regression 2609 !> presumes the Klima-Michel settings for reference individual and reference environment. 2610 !--------------------------------------------------------------------------------------------------! 2651 2611 SUBROUTINE perct_regression( pmv, clo, perct_ij ) 2652 2612 2653 2613 IMPLICIT NONE 2654 2614 2615 REAL(wp), INTENT ( IN ) :: clo !< clothing insulation index (clo) 2655 2616 REAL(wp), INTENT ( IN ) :: pmv !< Fangers predicted mean vote (dimensionless) 2656 REAL(wp), INTENT ( IN ) :: clo !< clothing insulation index (clo)2657 2617 2658 2618 REAL(wp), INTENT ( OUT ) :: perct_ij !< perct (degC) corresponding to given PMV / clo 2659 2619 2660 IF ( pmv <= - 0.11_wp ) THEN2620 IF ( pmv <= - 0.11_wp ) THEN 2661 2621 perct_ij = 5.805_wp + 12.6784_wp * pmv 2662 2622 ELSE … … 2670 2630 END SUBROUTINE perct_regression 2671 2631 2672 !------------------------------------------------------------------------------ !2632 !--------------------------------------------------------------------------------------------------! 2673 2633 ! Description: 2674 2634 ! ------------ 2675 2635 !> FANGER.F90 2676 2636 !> 2677 !> SI-VERSION: ACTLEV W m-2, DAMPFDRUCK hPa 2678 !> Berechnet das aktuelle Predicted Mean Vote nach Fanger 2679 !> 2637 !> SI-VERSION: ACTLEV W m-2, VAPOUR PRESSURE hPa 2638 !> Calculates the current Predicted Mean Vote according to Fanger. 2680 2639 !> The case of free convection (ws < 0.1 m/s) is dealt with ws = 0.1 m/s 2681 !------------------------------------------------------------------------------ !2640 !--------------------------------------------------------------------------------------------------! 2682 2641 SUBROUTINE fanger( ta, tmrt, pa, in_ws, pair, in_clo, actlev, eta, pmva ) 2683 2642 … … 2685 2644 ! 2686 2645 !-- Input variables of argument list: 2646 REAL(wp), INTENT ( IN ) :: actlev !< Individuals activity level per unit surface area (W/m2) 2647 REAL(wp), INTENT ( IN ) :: eta !< Individuals mechanical work efficiency (dimensionless) 2648 REAL(wp), INTENT ( IN ) :: in_clo !< Clothing insulation (clo) 2649 REAL(wp), INTENT ( IN ) :: in_ws !< Wind speed (m/s) 1 m above ground 2650 REAL(wp), INTENT ( IN ) :: pa !< Water vapour pressure (hPa) 2651 REAL(wp), INTENT ( IN ) :: pair !< Barometric pressure (hPa) at site 2687 2652 REAL(wp), INTENT ( IN ) :: ta !< Ambient air temperature (degC) 2688 2653 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degC) 2689 REAL(wp), INTENT ( IN ) :: pa !< Water vapour pressure (hPa) 2690 REAL(wp), INTENT ( IN ) :: pair !< Barometric pressure (hPa) at site 2691 REAL(wp), INTENT ( IN ) :: in_ws !< Wind speed (m/s) 1 m above ground 2692 REAL(wp), INTENT ( IN ) :: in_clo !< Clothing insulation (clo) 2693 REAL(wp), INTENT ( IN ) :: actlev !< Individuals activity level per unit surface area (W/m2) 2694 REAL(wp), INTENT ( IN ) :: eta !< Individuals mechanical work efficiency (dimensionless) 2654 2695 2655 ! 2696 2656 !-- Output variables of argument list: 2697 REAL(wp), INTENT ( OUT ) :: pmva !< Actual Predicted Mean Vote (PMV, 2698 !< dimensionless) according to Fanger corresponding to meteorological 2657 REAL(wp), INTENT ( OUT ) :: pmva !< Actual Predicted Mean Vote (PMV, 2658 !< dimensionless) according to Fanger corresponding to meteorological 2699 2659 !< (ta,tmrt,pa,ws,pair) and individual variables (clo, actlev, eta) 2700 2660 ! 2701 2661 !-- Internal variables 2702 REAL(wp) :: f_cl !< Increase in surface due to clothing (factor)2703 REAL(wp) :: heat_convection !< energy loss by autocnvection (W) 2662 INTEGER(iwp) :: i !< running index 2663 2704 2664 REAL(wp) :: activity !< persons activity (must stay == actlev, W) 2705 REAL(wp) :: t_skin_aver !< average skin temperature (degree_C)2706 2665 REAL(wp) :: bc !< preliminary result storage 2707 2666 REAL(wp) :: cc !< preliminary result storage 2667 REAL(wp) :: clo !< clothing insulation index (clo) 2708 2668 REAL(wp) :: dc !< preliminary result storage 2709 2669 REAL(wp) :: ec !< preliminary result storage 2670 REAL(wp) :: f_cl !< Increase in surface due to clothing (factor) 2710 2671 REAL(wp) :: gc !< preliminary result storage 2672 REAL(wp) :: heat_convection !< energy loss by autocnvection (W) 2673 REAL(wp) :: hr !< radiational heat resistence 2711 2674 REAL(wp) :: t_clothing !< clothing temperature (degree_C) 2712 REAL(wp) :: hr !< radiational heat resistence 2713 REAL(wp) :: clo !< clothing insulation index (clo) 2675 REAL(wp) :: t_skin_aver !< average skin temperature (degree_C) 2714 2676 REAL(wp) :: ws !< wind speed (m/s) 2715 REAL(wp) :: z1 !< Empiric factor for the adaption of the heat 2677 REAL(wp) :: z1 !< Empiric factor for the adaption of the heat 2716 2678 !< ballance equation to the psycho-physical scale (Equ. 40 in FANGER) 2717 2679 REAL(wp) :: z2 !< Water vapour diffution through the skin … … 2720 2682 REAL(wp) :: z5 !< Loss of radiational heat 2721 2683 REAL(wp) :: z6 !< Heat loss through forced convection 2722 INTEGER(iwp) :: i !< running index 2684 2723 2685 ! 2724 2686 !-- Clo must be > 0. to avoid div. by 0! 2725 2687 clo = in_clo 2726 IF ( clo <= 0. _wp ) clo = .001_wp2727 ! 2728 !-- f_cl = Increase in surface due to clothing2729 f_cl = 1. _wp +.15_wp * clo2688 IF ( clo <= 0.0_wp ) clo = .001_wp 2689 ! 2690 !-- f_cl = increase in surface due to clothing 2691 f_cl = 1.0_wp + 0.15_wp * clo 2730 2692 ! 2731 2693 !-- Case of free convection (ws < 0.1 m/s ) not considered 2732 2694 ws = in_ws 2733 IF ( ws < .1_wp ) THEN2734 ws = .1_wp2695 IF ( ws < 0.1_wp ) THEN 2696 ws = 0.1_wp 2735 2697 ENDIF 2736 2698 ! … … 2738 2700 heat_convection = 12.1_wp * SQRT( ws * pair / 1013.25_wp ) 2739 2701 ! 2740 !-- Activity = inner heat produ ktion per standardized surface2741 activity = actlev * ( 1. _wp - eta )2742 ! 2743 !-- T_skin_aver = average skin temperature2744 t_skin_aver = 35.7_wp - .0275_wp * activity2702 !-- Activity = inner heat production per standardized surface 2703 activity = actlev * ( 1.0_wp - eta ) 2704 ! 2705 !-- t_skin_aver = average skin temperature 2706 t_skin_aver = 35.7_wp - 0.0275_wp * activity 2745 2707 ! 2746 2708 !-- Calculation of constants for evaluation below 2747 bc = .155_wp * clo * 3.96_wp * 10._wp**( -8 ) * f_cl2709 bc = 0.155_wp * clo * 3.96_wp * 10.0_wp**( -8 ) * f_cl 2748 2710 cc = f_cl * heat_convection 2749 ec = .155_wp * clo2750 dc = ( 1. _wp + ec * cc ) / bc2711 ec = 0.155_wp * clo 2712 dc = ( 1.0_wp + ec * cc ) / bc 2751 2713 gc = ( t_skin_aver + bc * ( tmrt + degc_to_k )**4 + ec * cc * ta ) / bc 2752 2714 ! 2753 !-- Calculation of clothing surface temperature (t_clothing) based on 2754 !-- Newton-approximation with air temperature as initial guess2715 !-- Calculation of clothing surface temperature (t_clothing) based on Newton-approximation with air 2716 !-- temperature as initial guess. 2755 2717 t_clothing = ta 2756 2718 DO i = 1, 3 2757 t_clothing = t_clothing - ( ( t_clothing + degc_to_k )**4 + t_clothing &2758 * dc - gc ) / ( 4._wp * ( t_clothing + degc_to_k )**3 + dc )2719 t_clothing = t_clothing - ( ( t_clothing + degc_to_k )**4 + t_clothing * dc - gc ) / & 2720 ( 4.0_wp * ( t_clothing + degc_to_k )**3 + dc ) 2759 2721 ENDDO 2760 2722 ! 2761 !-- Empiric factor for the adaption of the heat ballance equation 2762 !-- to the psycho-physical scale (Equ.40 in FANGER)2763 z1 = ( .303_wp * EXP( -.036_wp * actlev ) +.0275_wp )2723 !-- Empiric factor for the adaption of the heat ballance equation to the psycho-physical scale (Equ. 2724 !-- 40 in FANGER) 2725 z1 = ( 0.303_wp * EXP( - 0.036_wp * actlev ) + 0.0275_wp ) 2764 2726 ! 2765 2727 !-- Water vapour diffution through the skin 2766 z2 = .31_wp * ( 57.3_wp -.07_wp * activity-pa )2728 z2 = 0.31_wp * ( 57.3_wp - 0.07_wp * activity-pa ) 2767 2729 ! 2768 2730 !-- Sweat evaporation from the skin surface 2769 z3 = .42_wp * ( activity - 58._wp )2731 z3 = 0.42_wp * ( activity - 58.0_wp ) 2770 2732 ! 2771 2733 !-- Loss of latent heat through respiration 2772 z4 = .0017_wp * actlev * ( 58.7_wp - pa ) + .0014_wp * actlev *&2773 ( 34._wp - ta )2734 z4 = 0.0017_wp * actlev * ( 58.7_wp - pa ) + 0.0014_wp * actlev * & 2735 ( 34.0_wp - ta ) 2774 2736 ! 2775 2737 !-- Loss of radiational heat 2776 z5 = 3.96e-8_wp * f_cl * ( ( t_clothing + degc_to_k )**4 - ( tmrt + & 2777 degc_to_k )**4 ) 2778 IF ( ABS( t_clothing - tmrt ) > 0._wp ) THEN 2738 z5 = 3.96e-8_wp * f_cl * ( ( t_clothing + degc_to_k )**4 - ( tmrt + degc_to_k )**4 ) 2739 IF ( ABS( t_clothing - tmrt ) > 0.0_wp ) THEN 2779 2740 hr = z5 / f_cl / ( t_clothing - tmrt ) 2780 2741 ELSE 2781 hr = 0. _wp2742 hr = 0.0_wp 2782 2743 ENDIF 2783 2744 ! … … 2790 2751 END SUBROUTINE fanger 2791 2752 2792 !------------------------------------------------------------------------------ !2753 !--------------------------------------------------------------------------------------------------! 2793 2754 ! Description: 2794 2755 ! ------------ 2795 !> For pmva > 0 and clo =0.5 the increment (deltapmv) is calculated 2796 !> that converts pmva into Gagge'set al. (1986) PMV*.2797 !------------------------------------------------------------------------------ !2756 !> For pmva > 0 and clo =0.5 the increment (deltapmv) is calculated that converts pmva into Gagge's 2757 !> et al. (1986) PMV*. 2758 !--------------------------------------------------------------------------------------------------! 2798 2759 REAL(wp) FUNCTION deltapmv( pmva, ta, vp, svp_ta, tmrt, ws, nerr ) 2799 2760 … … 2803 2764 !-- Input variables of argument list: 2804 2765 REAL(wp), INTENT ( IN ) :: pmva !< Actual Predicted Mean Vote (PMV) according to Fanger 2766 REAL(wp), INTENT ( IN ) :: svp_ta !< Saturation water vapour pressure (hPa) at ta 2805 2767 REAL(wp), INTENT ( IN ) :: ta !< Ambient temperature (degC) at screen level 2768 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degC) at screen level 2806 2769 REAL(wp), INTENT ( IN ) :: vp !< Water vapour pressure (hPa) at screen level 2807 REAL(wp), INTENT ( IN ) :: svp_ta !< Saturation water vapour pressure (hPa) at ta2808 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degC) at screen level2809 2770 REAL(wp), INTENT ( IN ) :: ws !< Wind speed (m/s) 1 m above ground 2810 2771 … … 2819 2780 ! 2820 2781 !-- Internal variables: 2821 REAL(wp) :: pmv !< temp storage og predicted mean vote 2822 REAL(wp) :: pa_p50 !< ratio actual water vapour pressure to that of relative humidity of 50 % 2823 REAL(wp) :: pa !< vapor pressure (hPa) with hard bounds 2782 INTEGER(iwp) :: nreg !< 2783 2824 2784 REAL(wp) :: apa !< natural logarithm of pa (with hard lower border) 2825 2785 REAL(wp) :: dapa !< difference of apa and pa_p50 2826 REAL(wp) :: sqvel !< square root of local wind velocity 2786 REAL(wp) :: dpmv_1 !< 2787 REAL(wp) :: dpmv_2 !< 2827 2788 REAL(wp) :: dtmrt !< difference mean radiation to air temperature 2789 REAL(wp) :: pa !< vapor pressure (hPa) with hard bounds 2790 REAL(wp) :: pa_p50 !< ratio actual water vapour pressure to that of relative humidity of 2791 !< 50 % 2792 REAL(wp) :: pmv !< temp storage og predicted mean vote 2793 REAL(wp) :: pmvs !< 2828 2794 REAL(wp) :: p10 !< lower bound for pa 2829 2795 REAL(wp) :: p95 !< upper bound for pa 2830 REAL(wp) :: weight !< 2831 REAL(wp) :: weight2 !< 2832 REAL(wp) :: dpmv_1 !< 2833 REAL(wp) :: dpmv_2 !< 2834 REAL(wp) :: pmvs !< 2835 INTEGER(iwp) :: nreg !< 2796 REAL(wp) :: sqvel !< square root of local wind velocity 2797 REAL(wp) :: weight !< 2798 REAL(wp) :: weight2 !< 2836 2799 2837 2800 ! 2838 2801 !-- Regression coefficients: 2839 REAL(wp), DIMENSION(0:7), PARAMETER :: bpmv = (/ &2840 - 0.0556602_wp, -0.1528680_wp, -0.2336104_wp, -0.2789387_wp,&2841 - 0.3551048_wp, -0.4304076_wp, -0.4884961_wp, -0.4897495_wp /)2842 2843 REAL(wp), DIMENSION(0:7), PARAMETER :: bpa_p50 = (/ &2844 - 0.1607154_wp, -0.4177296_wp, -0.4120541_wp, -0.0886564_wp,&2845 0.4285938_wp, 0.6281256_wp, 0.5067361_wp,0.3965169_wp /)2846 2847 REAL(wp), DIMENSION(0:7), PARAMETER :: bpa = (/ &2848 0.0580284_wp, 0.0836264_wp, 0.1009919_wp, 0.1020777_wp,&2849 0.0898681_wp, 0.0839116_wp, 0.0853258_wp,0.0866589_wp /)2850 2851 REAL(wp), DIMENSION(0:7), PARAMETER :: bapa = (/ &2852 - 1.7838788_wp, -2.9306231_wp, -1.6350334_wp, 0.6211547_wp,&2853 3.3918083_wp, 5.5521025_wp, 8.4897418_wp,16.6265851_wp /)2854 2855 REAL(wp), DIMENSION(0:7), PARAMETER :: bdapa = (/ &2856 1.6752720_wp, 2.7379504_wp, 1.2940526_wp, -1.0985759_wp,&2857 - 3.9054732_wp, -6.0403012_wp, -8.9437119_wp, -17.0671201_wp /)2858 2859 REAL(wp), DIMENSION(0:7), PARAMETER :: bsqvel = (/ &2860 - 0.0315598_wp, -0.0286272_wp, -0.0009228_wp, 0.0483344_wp,&2861 0.0992366_wp, 0.1491379_wp, 0.1951452_wp,0.2133949_wp /)2862 2863 REAL(wp), DIMENSION(0:7), PARAMETER :: bta = (/ &2864 0.0953986_wp, 0.1524760_wp, 0.0564241_wp, -0.0893253_wp,&2865 - 0.2398868_wp, -0.3515237_wp, -0.5095144_wp, -0.9469258_wp /)2866 2867 REAL(wp), DIMENSION(0:7), PARAMETER :: bdtmrt = (/ &2868 - 0.0004672_wp, -0.0000514_wp, -0.0018037_wp, -0.0049440_wp,&2869 - 0.0069036_wp, -0.0075844_wp, -0.0079602_wp, -0.0089439_wp /)2870 2871 REAL(wp), DIMENSION(0:7), PARAMETER :: aconst = (/ &2872 1.8686215_wp, 3.4260713_wp, 2.0116185_wp, -0.7777552_wp,&2873 - 4.6715853_wp, -7.7314281_wp, -11.7602578_wp, -23.5934198_wp /)2802 REAL(wp), DIMENSION(0:7), PARAMETER :: bpmv = (/ & 2803 - 0.0556602_wp, - 0.1528680_wp, - 0.2336104_wp, - 0.2789387_wp, & 2804 - 0.3551048_wp, - 0.4304076_wp, - 0.4884961_wp, - 0.4897495_wp /) 2805 2806 REAL(wp), DIMENSION(0:7), PARAMETER :: bpa_p50 = (/ & 2807 - 0.1607154_wp, - 0.4177296_wp, - 0.4120541_wp, - 0.0886564_wp, & 2808 0.4285938_wp, 0.6281256_wp, 0.5067361_wp, 0.3965169_wp /) 2809 2810 REAL(wp), DIMENSION(0:7), PARAMETER :: bpa = (/ & 2811 0.0580284_wp, 0.0836264_wp, 0.1009919_wp, 0.1020777_wp, & 2812 0.0898681_wp, 0.0839116_wp, 0.0853258_wp, 0.0866589_wp /) 2813 2814 REAL(wp), DIMENSION(0:7), PARAMETER :: bapa = (/ & 2815 - 1.7838788_wp, - 2.9306231_wp, - 1.6350334_wp, 0.6211547_wp, & 2816 3.3918083_wp, 5.5521025_wp, 8.4897418_wp, 16.6265851_wp /) 2817 2818 REAL(wp), DIMENSION(0:7), PARAMETER :: bdapa = (/ & 2819 1.6752720_wp, 2.7379504_wp, 1.2940526_wp, - 1.0985759_wp, & 2820 - 3.9054732_wp, - 6.0403012_wp, - 8.9437119_wp, - 17.0671201_wp /) 2821 2822 REAL(wp), DIMENSION(0:7), PARAMETER :: bsqvel = (/ & 2823 - 0.0315598_wp, - 0.0286272_wp, - 0.0009228_wp, 0.0483344_wp, & 2824 0.0992366_wp, 0.1491379_wp, 0.1951452_wp, 0.2133949_wp /) 2825 2826 REAL(wp), DIMENSION(0:7), PARAMETER :: bta = (/ & 2827 0.0953986_wp, 0.1524760_wp, 0.0564241_wp, - 0.0893253_wp, & 2828 - 0.2398868_wp, - 0.3515237_wp, - 0.5095144_wp, - 0.9469258_wp /) 2829 2830 REAL(wp), DIMENSION(0:7), PARAMETER :: bdtmrt = (/ & 2831 - 0.0004672_wp, - 0.0000514_wp, - 0.0018037_wp, - 0.0049440_wp, & 2832 - 0.0069036_wp, - 0.0075844_wp, - 0.0079602_wp, - 0.0089439_wp /) 2833 2834 REAL(wp), DIMENSION(0:7), PARAMETER :: aconst = (/ & 2835 1.8686215_wp, 3.4260713_wp, 2.0116185_wp, - 0.7777552_wp, & 2836 - 4.6715853_wp, - 7.7314281_wp, - 11.7602578_wp, - 23.5934198_wp /) 2874 2837 2875 2838 … … 2885 2848 pmv = pmva 2886 2849 ! 2887 !-- Water vapour pressure of air 2850 !-- Water vapour pressure of air 2888 2851 p10 = 0.05_wp * svp_ta 2889 2852 p95 = 1.00_wp * svp_ta … … 2902 2865 ENDIF 2903 2866 ENDIF 2904 IF ( pa > 0. _wp ) THEN2867 IF ( pa > 0.0_wp ) THEN 2905 2868 ! 2906 2869 !-- Natural logarithm of pa 2907 2870 apa = LOG( pa ) 2908 2871 ELSE 2909 apa = -5. _wp2872 apa = -5.0_wp 2910 2873 ENDIF 2911 2874 ! 2912 2875 !-- Ratio actual water vapour pressure to that of a r.H. of 50 % 2913 2876 pa_p50 = 0.5_wp * svp_ta 2914 IF ( pa_p50 > 0. _wp .AND. pa > 0._wp ) THEN2877 IF ( pa_p50 > 0.0_wp .AND. pa > 0.0_wp ) THEN 2915 2878 dapa = apa - LOG( pa_p50 ) 2916 2879 pa_p50 = pa / pa_p50 2917 2880 ELSE 2918 dapa = -5. _wp2919 pa_p50 = 0. _wp2881 dapa = -5.0_wp 2882 pa_p50 = 0.0_wp 2920 2883 ENDIF 2921 2884 ! 2922 2885 !-- Square root of wind velocity 2923 IF ( ws >= 0. _wp ) THEN2886 IF ( ws >= 0.0_wp ) THEN 2924 2887 sqvel = SQRT( ws ) 2925 2888 ELSE 2926 sqvel = 0. _wp2889 sqvel = 0.0_wp 2927 2890 ENDIF 2928 2891 ! … … 2934 2897 IF ( nreg < 0_iwp ) THEN 2935 2898 ! 2936 !-- value of the FUNCTION in the case pmv <= -12937 deltapmv = 0. _wp2899 !-- Value of the FUNCTION in the case pmv <= -1 2900 deltapmv = 0.0_wp 2938 2901 RETURN 2939 2902 ENDIF 2940 weight = MOD ( pmv, 1. _wp )2941 IF ( weight < 0. _wp ) weight = 0._wp2903 weight = MOD ( pmv, 1.0_wp ) 2904 IF ( weight < 0.0_wp ) weight = 0.0_wp 2942 2905 IF ( nreg > 5_iwp ) THEN 2943 2906 nreg = 5_iwp 2944 weight = pmv - 5. _wp2945 weight2 = pmv - 6. _wp2907 weight = pmv - 5.0_wp 2908 weight2 = pmv - 6.0_wp 2946 2909 IF ( weight2 > 0_iwp ) THEN 2947 2910 weight = ( weight - weight2 ) / weight … … 2950 2913 ! 2951 2914 !-- Regression valid for 0. <= pmv <= 6., bounds are checked above 2952 dpmv_1 = &2953 + bpa(nreg) * pa&2954 + bpmv(nreg) * pmv&2955 + bapa(nreg) * apa&2956 + bta(nreg) * ta&2957 + bdtmrt(nreg) * dtmrt&2958 + bdapa(nreg) * dapa&2959 + bsqvel(nreg) * sqvel&2960 + bpa_p50(nreg) * pa_p50&2961 + aconst(nreg)2962 2963 ! dpmv_2 = 0. _wp2915 dpmv_1 = & 2916 + bpa(nreg) * pa & 2917 + bpmv(nreg) * pmv & 2918 + bapa(nreg) * apa & 2919 + bta(nreg) * ta & 2920 + bdtmrt(nreg) * dtmrt & 2921 + bdapa(nreg) * dapa & 2922 + bsqvel(nreg) * sqvel & 2923 + bpa_p50(nreg) * pa_p50 & 2924 + aconst(nreg) 2925 2926 ! dpmv_2 = 0.0_wp 2964 2927 ! IF ( nreg < 6_iwp ) THEN !< nreg is always <= 5, see above 2965 dpmv_2 = &2966 + bpa(nreg+1_iwp) * pa&2967 + bpmv(nreg+1_iwp) * pmv&2968 + bapa(nreg+1_iwp) * apa&2969 + bta(nreg+1_iwp) * ta&2970 + bdtmrt(nreg+1_iwp) * dtmrt&2971 + bdapa(nreg+1_iwp) * dapa&2972 + bsqvel(nreg+1_iwp) * sqvel&2973 + bpa_p50(nreg+1_iwp) * pa_p50&2974 + aconst(nreg+1_iwp)2928 dpmv_2 = & 2929 + bpa(nreg+1_iwp) * pa & 2930 + bpmv(nreg+1_iwp) * pmv & 2931 + bapa(nreg+1_iwp) * apa & 2932 + bta(nreg+1_iwp) * ta & 2933 + bdtmrt(nreg+1_iwp) * dtmrt & 2934 + bdapa(nreg+1_iwp) * dapa & 2935 + bsqvel(nreg+1_iwp) * sqvel & 2936 + bpa_p50(nreg+1_iwp) * pa_p50 & 2937 + aconst(nreg+1_iwp) 2975 2938 ! ENDIF 2976 2939 ! 2977 2940 !-- Calculate pmv modification 2978 deltapmv = ( 1. _wp - weight ) * dpmv_1 + weight * dpmv_22941 deltapmv = ( 1.0_wp - weight ) * dpmv_1 + weight * dpmv_2 2979 2942 pmvs = pmva + deltapmv 2980 IF ( ( pmvs ) < 0. _wp ) THEN2943 IF ( ( pmvs ) < 0.0_wp ) THEN 2981 2944 ! 2982 2945 !-- Prevent negative pmv* due to problems with clothing insulation … … 2989 2952 ! 2990 2953 !-- Set pmvs to "0" for compliance with summer clothing insulation 2991 deltapmv = -1. _wp * pmva2954 deltapmv = -1.0_wp * pmva 2992 2955 ENDIF 2993 2956 ENDIF … … 2995 2958 END FUNCTION deltapmv 2996 2959 2997 !------------------------------------------------------------------------------ !2960 !--------------------------------------------------------------------------------------------------! 2998 2961 ! Description: 2999 2962 ! ------------ 3000 !> The subroutine "calc_sultr" returns a threshold value to perceived 3001 !> temperature allowing to decide whether the actual perceived temperature 3002 !> is linked to perecption of sultriness. The threshold values depends 3003 !> on the Fanger's classical PMV, expressed here as perceived temperature 3004 !> perct. 3005 !------------------------------------------------------------------------------! 2963 !> The subroutine "calc_sultr" returns a threshold value to perceived temperature allowing to decide 2964 !> whether the actual perceived temperature is linked to perecption of sultriness. The threshold 2965 !> values depends on the Fanger's classical PMV, expressed here as perceived temperature perct. 2966 !--------------------------------------------------------------------------------------------------! 3006 2967 SUBROUTINE calc_sultr( perct_ij, dperctm, dperctstd, sultr_res ) 3007 2968 … … 3009 2970 ! 3010 2971 !-- Input of the argument list: 3011 REAL(wp), INTENT ( IN ) :: perct_ij 2972 REAL(wp), INTENT ( IN ) :: perct_ij !< Classical perceived temperature: Base is Fanger's PMV 3012 2973 ! 3013 2974 !-- Additional output variables of argument list: 3014 REAL(wp), INTENT ( OUT ) :: dperctm !< Mean deviation perct (classical gt) to gt* (rational gt3015 !< calculated based on Gagge's rational PMV*)3016 REAL(wp), INTENT ( OUT ) :: dperctstd !< dperctm plus its standard deviation times a factor 2975 REAL(wp), INTENT ( OUT ) :: dperctm !< Mean deviation perct (classical gt) to gt* (rational 2976 !< gt calculated based on Gagge's rational PMV*) 2977 REAL(wp), INTENT ( OUT ) :: dperctstd !< dperctm plus its standard deviation times a factor 3017 2978 !< determining the significance to perceive sultriness 3018 2979 REAL(wp), INTENT ( OUT ) :: sultr_res 3019 2980 ! 3020 2981 !-- Types of coefficients mean deviation: third order polynomial 3021 REAL(wp), PARAMETER :: dperctka = 7.5776086_wp3022 REAL(wp), PARAMETER :: dperctkb = - 0.740603_wp3023 REAL(wp), PARAMETER :: dperctkc = 0.0213324_wp3024 REAL(wp), PARAMETER :: dperctkd = - 0.00027797237_wp2982 REAL(wp), PARAMETER :: dperctka = 7.5776086_wp 2983 REAL(wp), PARAMETER :: dperctkb = - 0.740603_wp 2984 REAL(wp), PARAMETER :: dperctkc = 0.0213324_wp 2985 REAL(wp), PARAMETER :: dperctkd = - 0.00027797237_wp 3025 2986 ! 3026 2987 !-- Types of coefficients mean deviation plus standard deviation 3027 2988 !-- regression coefficients: third order polynomial 3028 REAL(wp), PARAMETER :: dperctsa = 0.0268918_wp3029 REAL(wp), PARAMETER :: dperctsb = 0.0465957_wp3030 REAL(wp), PARAMETER :: dperctsc = - 0.00054709752_wp3031 REAL(wp), PARAMETER :: dperctsd = 0.0000063714823_wp3032 ! 3033 !-- Factor to mean standard deviation defining SIGNificance for 2989 REAL(wp), PARAMETER :: dperctsa = 0.0268918_wp 2990 REAL(wp), PARAMETER :: dperctsb = 0.0465957_wp 2991 REAL(wp), PARAMETER :: dperctsc = - 0.00054709752_wp 2992 REAL(wp), PARAMETER :: dperctsd = 0.0000063714823_wp 2993 ! 2994 !-- Factor to mean standard deviation defining SIGNificance for 3034 2995 !-- sultriness 3035 REAL(wp), PARAMETER :: faktor = 1. _wp2996 REAL(wp), PARAMETER :: faktor = 1.0_wp 3036 2997 ! 3037 2998 !-- Initialise 3038 sultr_res = 99. _wp3039 dperctm = 0. _wp3040 dperctstd = 999999. _wp3041 3042 IF ( perct_ij < 16.826_wp .OR. perct_ij > 56. _wp ) THEN2999 sultr_res = 99.0_wp 3000 dperctm = 0.0_wp 3001 dperctstd = 999999.0_wp 3002 3003 IF ( perct_ij < 16.826_wp .OR. perct_ij > 56.0_wp ) THEN 3043 3004 ! 3044 3005 !-- Unallowed value of classical perct! … … 3047 3008 ! 3048 3009 !-- Mean deviation dependent on perct 3049 dperctm = dperctka + dperctkb * perct_ij + dperctkc * perct_ij**2. _wp +&3050 dperctkd * perct_ij**3._wp3010 dperctm = dperctka + dperctkb * perct_ij + dperctkc * perct_ij**2.0_wp + dperctkd * & 3011 perct_ij**3.0_wp 3051 3012 ! 3052 3013 !-- Mean deviation plus its standard deviation 3053 dperctstd = dperctsa + dperctsb * perct_ij + dperctsc * perct_ij**2. _wp +&3054 dperctsd * perct_ij**3._wp3014 dperctstd = dperctsa + dperctsb * perct_ij + dperctsc * perct_ij**2.0_wp + dperctsd * & 3015 perct_ij**3.0_wp 3055 3016 ! 3056 3017 !-- Value of the FUNCTION 3057 3018 sultr_res = dperctm + faktor * dperctstd 3058 IF ( ABS( sultr_res ) > 99. _wp ) sultr_res = +99._wp3019 IF ( ABS( sultr_res ) > 99.0_wp ) sultr_res = +99.0_wp 3059 3020 3060 3021 END SUBROUTINE calc_sultr 3061 3022 3062 !------------------------------------------------------------------------------ !3023 !--------------------------------------------------------------------------------------------------! 3063 3024 ! Description: 3064 3025 ! ------------ 3065 !> Multiple linear regression to calculate an increment delta_cold, 3066 !> to adjust Fanger's classical PMV (pmva) by Gagge's 2 node model, 3067 !> applying Fanger's convective heat transfer coefficient, hcf. 3068 !> Wind velocitiy of the reference environment is 0.10 m/s 3069 !------------------------------------------------------------------------------! 3026 !> Multiple linear regression to calculate an increment delta_cold, to adjust Fanger's classical PMV 3027 !> (pmva) by Gagge's 2 node model, applying Fanger's convective heat transfer coefficient, hcf. 3028 !> Wind velocitiy of the reference environment is 0.10 m/s 3029 !--------------------------------------------------------------------------------------------------! 3070 3030 SUBROUTINE dpmv_cold( pmva, ta, ws, tmrt, nerr, dpmv_cold_res ) 3071 3031 … … 3075 3035 REAL(wp), INTENT ( IN ) :: pmva !< Fanger's classical predicted mean vote 3076 3036 REAL(wp), INTENT ( IN ) :: ta !< Air temperature 2 m above ground (degC) 3037 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degC) 3077 3038 REAL(wp), INTENT ( IN ) :: ws !< Relative wind velocity 1 m above ground (m/s) 3078 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degC)3079 3039 ! 3080 3040 !-- Type of output argument 3081 INTEGER(iwp), INTENT ( OUT ) :: nerr !< Error indicator: 0 = o.k., +1 = denominator for intersection = 0 3082 REAL(wp), INTENT ( OUT ) :: dpmv_cold_res !< Increment to adjust pmva according to the results of Gagge's 3083 !< 2 node model depending on the input 3041 INTEGER(iwp), INTENT ( OUT ) :: nerr !< Error indicator: 0 = o.k., +1 = denominator for 3042 !< intersection = 0 3043 3044 REAL(wp), INTENT ( OUT ) :: dpmv_cold_res !< Increment to adjust pmva according to the 3045 !< results of Gagge's 2 node model depending on the input 3084 3046 ! 3085 3047 !-- Type of program variables 3048 INTEGER(iwp) :: i !< running index 3049 INTEGER(iwp) :: i_bin !< result row number 3050 3086 3051 REAL(wp) :: delta_cold(3) 3052 REAL(wp) :: dtmrt !< delta mean radiant temperature 3087 3053 REAL(wp) :: pmv_cross(2) 3088 3054 REAL(wp) :: reg_a(3) 3089 3055 REAL(wp) :: r_denominator !< the regression equations denominator 3090 REAL(wp) :: dtmrt !< delta mean radiant temperature3091 3056 REAL(wp) :: sqrt_ws !< sqare root of wind speed 3092 INTEGER(iwp) :: i !< running index3093 INTEGER(iwp) :: i_bin !< result row number3094 3057 3095 3058 ! REAL(wp) :: coeff(3,5) !< unsafe! array is (re-)writable! … … 3104 3067 !-- Coefficient of the 3 regression lines: 3105 3068 ! 1:const 2:*pmva 3:*ta 4:*sqrt_ws 5:*dtmrt 3106 REAL(wp), DIMENSION(1:3,1:5), PARAMETER :: coeff = RESHAPE( (/ &3107 0.161_wp, 0.130_wp, -1.125E-03_wp, 1.106E-03_wp, -4.570E-04_wp, &3108 0.795_wp, 0.713_wp, -8.880E-03_wp, -1.803E-03_wp, -2.816E-03_wp, &3109 0.05761_wp, 0.458_wp, -1.829E-02_wp, -5.577E-03_wp, -1.970E-03_wp &3110 /), SHAPE( coeff), order=(/ 2, 1 /))3069 REAL(wp), DIMENSION(1:3,1:5), PARAMETER :: coeff = RESHAPE( (/ & 3070 0.161_wp, 0.130_wp, -1.125E-03_wp, 1.106E-03_wp, -4.570E-04_wp, & 3071 0.795_wp, 0.713_wp, -8.880E-03_wp, -1.803E-03_wp, -2.816E-03_wp, & 3072 0.05761_wp, 0.458_wp, -1.829E-02_wp, -5.577E-03_wp, -1.970E-03_wp & 3073 /), SHAPE( coeff ), order=(/ 2, 1 /) ) 3111 3074 ! 3112 3075 !-- Initialise 3113 3076 nerr = 0_iwp 3114 dpmv_cold_res = 0. _wp3077 dpmv_cold_res = 0.0_wp 3115 3078 dtmrt = tmrt - ta 3116 3079 sqrt_ws = ws … … 3121 3084 ENDIF 3122 3085 3123 delta_cold = 0. _wp3086 delta_cold = 0.0_wp 3124 3087 pmv_cross = pmva 3125 3088 … … 3127 3090 !-- Determine regression constant for given meteorological conditions 3128 3091 DO i = 1, 3 3129 reg_a(i) = coeff(i,1) + coeff(i,3) * ta + coeff(i,4) * & 3130 sqrt_ws + coeff(i,5)*dtmrt 3092 reg_a(i) = coeff(i,1) + coeff(i,3) * ta + coeff(i,4) * sqrt_ws + coeff(i,5)*dtmrt 3131 3093 delta_cold(i) = reg_a(i) + coeff(i,2) * pmva 3132 3094 ENDDO … … 3152 3114 ENDDO 3153 3115 ! 3154 !-- Adjust to operative temperature scaled according 3155 !-- to classical PMV (Fanger) 3116 !-- Adjust to operative temperature scaled according to classical PMV (Fanger) 3156 3117 dpmv_cold_res = delta_cold(i_bin) - dpmv_cold_adj(pmva) 3157 3118 3158 3119 END SUBROUTINE dpmv_cold 3159 3120 3160 !------------------------------------------------------------------------------ !3121 !--------------------------------------------------------------------------------------------------! 3161 3122 ! Description: 3162 3123 ! ------------ 3163 !> Calculates the summand dpmv_cold_adj adjusting to the operative temperature 3164 !> scaled according to classical PMV (Fanger) for cold conditions.3165 !> Valid for reference environment: v (1m) = 0.10 m/s,dTMRT = 0 K, r.h. = 50 %3166 !------------------------------------------------------------------------------ !3124 !> Calculates the summand dpmv_cold_adj adjusting to the operative temperature scaled according to 3125 !> classical PMV (Fanger) for cold conditions. Valid for reference environment: v (1m) = 0.10 m/s, 3126 !> dTMRT = 0 K, r.h. = 50 % 3127 !--------------------------------------------------------------------------------------------------! 3167 3128 REAL(wp) FUNCTION dpmv_cold_adj( pmva ) 3168 3129 3169 3130 IMPLICIT NONE 3170 3131 3171 REAL(wp), INTENT ( IN ) :: pmva !< (adjusted) Predicted Mean Vote3172 3173 REAL(wp) :: pmv !< pmv-part of the regression3174 3132 INTEGER(iwp) :: i !< running index 3175 3133 INTEGER(iwp) :: thr !< thermal range 3134 3135 REAL(wp), INTENT ( IN ) :: pmva !< (adjusted) Predicted Mean Vote 3136 3137 REAL(wp) :: pmv !< pmv-part of the regression 3138 3176 3139 ! 3177 3140 !-- Provide regression coefficients for three thermal ranges: 3178 !-- slightly cold cold very cold3179 REAL(wp), DIMENSION(1:3,0:3), PARAMETER :: coef = RESHAPE( (/ &3180 0.0941540_wp, -0.1506620_wp, -0.0871439_wp,&3181 0.0783162_wp, -1.0612651_wp, 0.1695040_wp,&3182 0.1350144_wp, -1.0049144_wp, -0.0167627_wp,&3183 0.1104037_wp, -0.2005277_wp, -0.0003230_wp&3184 /), SHAPE(coef), order=(/ 1, 2 /) )3141 !-- slightly cold cold very cold 3142 REAL(wp), DIMENSION(1:3,0:3), PARAMETER :: coef = RESHAPE( (/ & 3143 0.0941540_wp, -0.1506620_wp, -0.0871439_wp, & 3144 0.0783162_wp, -1.0612651_wp, 0.1695040_wp, & 3145 0.1350144_wp, -1.0049144_wp, -0.0167627_wp, & 3146 0.1104037_wp, -0.2005277_wp, -0.0003230_wp & 3147 /), SHAPE(coef), order=(/ 1, 2 /) ) 3185 3148 ! 3186 3149 !-- Select thermal range … … 3195 3158 !-- Initialize 3196 3159 dpmv_cold_adj = coef(thr,0) 3197 pmv = 1. _wp3160 pmv = 1.0_wp 3198 3161 ! 3199 3162 !-- Calculate pmv adjustment (dpmv_cold_adj) … … 3206 3169 END FUNCTION dpmv_cold_adj 3207 3170 3208 !------------------------------------------------------------------------------ !3171 !--------------------------------------------------------------------------------------------------! 3209 3172 ! Description: 3210 3173 ! ------------ 3211 !> Based on perceived temperature (perct) as input, ireq_neutral determines 3212 !> the required clothing insulation (clo) for thermally neutral conditions 3213 !> (neither body cooling nor body heating). It is related to the Klima- 3214 !> Michel activity level (134.682 W/m2). IREQ_neutral is only defined 3215 !> for perct < 10 (degC) 3216 !------------------------------------------------------------------------------! 3174 !> Based on perceived temperature (perct) as input, ireq_neutral determines the required clothing 3175 !> insulation (clo) for thermally neutral conditions (neither body cooling nor body heating). It is 3176 !> related to the Klima-Michel activity level (134.682 W/m2). IREQ_neutral is only defined for perct 3177 !> < 10 (degC) 3178 !--------------------------------------------------------------------------------------------------! 3217 3179 REAL(wp) FUNCTION ireq_neutral( perct_ij, ireq_minimal, nerr ) 3218 3180 … … 3220 3182 ! 3221 3183 !-- Type declaration of arguments 3184 INTEGER(iwp), INTENT ( OUT ) :: nerr 3185 3222 3186 REAL(wp), INTENT ( IN ) :: perct_ij 3223 3187 REAL(wp), INTENT ( OUT ) :: ireq_minimal 3224 INTEGER(iwp), INTENT ( OUT ) :: nerr3225 3188 ! 3226 3189 !-- Type declaration for internal varables … … 3254 3217 3255 3218 3256 !------------------------------------------------------------------------------ !3219 !--------------------------------------------------------------------------------------------------! 3257 3220 ! Description: 3258 3221 ! ------------ 3259 !> The SUBROUTINE surface area calculates the surface area of the individual 3260 !> according to its height(m), weight (kg), and age (y)3261 !------------------------------------------------------------------------------ !3222 !> The SUBROUTINE surface area calculates the surface area of the individual according to its height 3223 !> (m), weight (kg), and age (y) 3224 !--------------------------------------------------------------------------------------------------! 3262 3225 SUBROUTINE surface_area( height_cm, weight, age, surf ) 3263 3226 3264 3227 IMPLICIT NONE 3265 3228 3229 INTEGER(iwp), INTENT(in) :: age 3230 3231 REAL(wp) , INTENT(in) :: height_cm 3266 3232 REAL(wp) , INTENT(in) :: weight 3267 REAL(wp) , INTENT(in) :: height_cm 3268 INTEGER(iwp), INTENT(in) :: age 3233 3269 3234 REAL(wp) , INTENT(out) :: surf 3235 3270 3236 REAL(wp) :: height 3271 3237 3272 height = height_cm * 100. _wp3238 height = height_cm * 100.0_wp 3273 3239 ! 3274 3240 !-- According to Gehan-George, for children … … 3282 3248 ENDIF 3283 3249 ! 3284 !-- DuBois D, DuBois EF: A formula to estimate the approximate surface area if 3285 ! -- height and weight beknown. In: Arch. Int. Med.. 17, 1916, pp. 863:871.3250 !-- DuBois D, DuBois EF: A formula to estimate the approximate surface area if height and weight be 3251 !> known. In: Arch. Int. Med.. 17, 1916, pp. 863:871. 3286 3252 surf = 0.007184_wp * height**0.725_wp * weight**0.425_wp 3287 3253 RETURN … … 3289 3255 END SUBROUTINE surface_area 3290 3256 3291 !------------------------------------------------------------------------------ !3257 !--------------------------------------------------------------------------------------------------! 3292 3258 ! Description: 3293 3259 ! ------------ … … 3303 3269 !> - work load (W) 3304 3270 !> for a sample human. 3305 !------------------------------------------------------------------------------ !3271 !--------------------------------------------------------------------------------------------------! 3306 3272 SUBROUTINE persdat( age, weight, height, sex, work, a_surf, actlev ) 3307 3273 3308 3274 IMPLICIT NONE 3309 3275 3276 INTEGER(iwp), INTENT(in) :: sex 3277 3278 3310 3279 REAL(wp), INTENT(in) :: age 3280 REAL(wp), INTENT(in) :: height 3311 3281 REAL(wp), INTENT(in) :: weight 3312 REAL(wp), INTENT(in) :: height3313 3282 REAL(wp), INTENT(in) :: work 3314 INTEGER(iwp), INTENT(in) :: sex 3283 3315 3284 REAL(wp), INTENT(out) :: actlev 3285 3316 3286 REAL(wp) :: a_surf 3287 REAL(wp) :: basic_heat_prod 3317 3288 REAL(wp) :: energy_prod 3289 REAL(wp) :: factor 3318 3290 REAL(wp) :: s 3319 REAL(wp) :: factor 3320 REAL(wp) :: basic_heat_prod 3291 3321 3292 3322 3293 CALL surface_area( height, weight, INT( age ), a_surf ) 3323 s = height * 100. _wp / ( weight**( 1._wp / 3._wp ) )3324 factor = 1. _wp + .004_wp * ( 30._wp - age )3325 basic_heat_prod = 0. 3294 s = height * 100.0_wp / ( weight**( 1.0_wp / 3.0_wp ) ) 3295 factor = 1.0_wp + .004_wp * ( 30.0_wp - age ) 3296 basic_heat_prod = 0.0_wp 3326 3297 IF ( sex == 1_iwp ) THEN 3327 basic_heat_prod = 3.45_wp * weight**( 3. _wp / 4._wp ) * ( factor +&3328 .01_wp* ( s - 43.4_wp ) )3298 basic_heat_prod = 3.45_wp * weight**( 3.0_wp / 4.0_wp ) * ( factor + 0.01_wp & 3299 * ( s - 43.4_wp ) ) 3329 3300 ELSE IF ( sex == 2_iwp ) THEN 3330 basic_heat_prod = 3.19_wp * weight**( 3. _wp / 4._wp ) * ( factor +&3331 .018_wp* ( s - 42.1_wp ) )3301 basic_heat_prod = 3.19_wp * weight**( 3.0_wp / 4.0_wp ) * ( factor + 0.018_wp & 3302 * ( s - 42.1_wp ) ) 3332 3303 ENDIF 3333 3304 … … 3338 3309 3339 3310 3340 !------------------------------------------------------------------------------ !3311 !--------------------------------------------------------------------------------------------------! 3341 3312 ! Description: 3342 3313 ! ------------ 3343 3314 !> SUBROUTINE ipt_init 3344 3315 !> initializes the instationary perceived temperature 3345 !------------------------------------------------------------------------------! 3346 3347 SUBROUTINE ipt_init( age, weight, height, sex, work, actlev, clo, & 3348 ta, vp, ws, tmrt, pair, dt, storage, t_clothing, & 3349 ipt ) 3316 !--------------------------------------------------------------------------------------------------! 3317 3318 SUBROUTINE ipt_init( age, weight, height, sex, work, actlev, clo, ta, vp, ws, tmrt, pair, dt, & 3319 storage, t_clothing, ipt ) 3350 3320 3351 3321 IMPLICIT NONE 3352 3322 ! 3353 3323 !-- Input parameters 3324 3325 INTEGER(iwp), INTENT(in) :: sex !< Persons sex (1 = male, 2 = female) 3326 3354 3327 REAL(wp), INTENT(in) :: age !< Persons age (years) 3328 REAL(wp), INTENT(in) :: dt !< Timestep (s) 3329 REAL(wp), INTENT(in) :: height !< Persons height (m)7 3330 REAL(wp), INTENT(in) :: pair !< Air pressure (hPa) 3331 REAL(wp), INTENT(in) :: ta !< Air Temperature (degree_C) 3332 REAL(wp), INTENT(in) :: tmrt !< Mean radiant temperature (degree_C) 3333 REAL(wp), INTENT(in) :: vp !< Vapor pressure (hPa) 3355 3334 REAL(wp), INTENT(in) :: weight !< Persons weight (kg) 3356 REAL(wp), INTENT(in) :: height !< Persons height (m)3357 3335 REAL(wp), INTENT(in) :: work !< Current workload (W) 3358 REAL(wp), INTENT(in) :: ta !< Air Temperature (degree_C)3359 REAL(wp), INTENT(in) :: vp !< Vapor pressure (hPa)3360 3336 REAL(wp), INTENT(in) :: ws !< Wind speed in approx. 1.1m (m/s) 3361 REAL(wp), INTENT(in) :: tmrt !< Mean radiant temperature (degree_C)3362 REAL(wp), INTENT(in) :: pair !< Air pressure (hPa)3363 REAL(wp), INTENT(in) :: dt !< Timestep (s)3364 INTEGER(iwp), INTENT(in) :: sex !< Persons sex (1 = male, 2 = female)3365 3337 ! 3366 3338 !-- Output parameters 3367 3339 REAL(wp), INTENT(out) :: actlev 3368 3340 REAL(wp), INTENT(out) :: clo 3341 REAL(wp), INTENT(out) :: ipt 3369 3342 REAL(wp), INTENT(out) :: storage 3370 3343 REAL(wp), INTENT(out) :: t_clothing 3371 REAL(wp), INTENT(out) :: ipt3372 3344 ! 3373 3345 !-- Internal variables 3374 REAL(wp), PARAMETER :: eps = 0.0005_wp3375 REAL(wp), PARAMETER :: eta = 0._wp3376 REAL(wp) :: sclo3377 REAL(wp) :: wclo3378 REAL(wp) :: d_pmv3379 REAL(wp) :: svp_ta3380 REAL(wp) :: sult_lim3381 REAL(wp) :: dgtcm3382 REAL(wp) :: dgtcstd3383 REAL(wp) :: clon3384 REAL(wp) :: ireq_minimal3385 ! REAL(wp) :: clo_fanger3386 REAL(wp) :: pmv_w3387 REAL(wp) :: pmv_s3388 REAL(wp) :: pmva3389 REAL(wp) :: ptc3390 REAL(wp) :: d_std3391 REAL(wp) :: pmvs3392 REAL(wp) :: a_surf3393 ! REAL(wp) :: acti3394 3346 INTEGER(iwp) :: ncount 3395 3347 INTEGER(iwp) :: nerr_cold … … 3398 3350 LOGICAL :: sultrieness 3399 3351 3400 storage = 0._wp 3352 REAL(wp), PARAMETER :: eps = 0.0005_wp 3353 REAL(wp), PARAMETER :: eta = 0.0_wp 3354 3355 ! REAL(wp) :: acti 3356 REAL(wp) :: a_surf 3357 ! REAL(wp) :: clo_fanger 3358 REAL(wp) :: clon 3359 REAL(wp) :: d_pmv 3360 REAL(wp) :: d_std 3361 REAL(wp) :: dgtcm 3362 REAL(wp) :: dgtcstd 3363 REAL(wp) :: ireq_minimal 3364 REAL(wp) :: pmv_s 3365 REAL(wp) :: pmv_w 3366 REAL(wp) :: pmva 3367 REAL(wp) :: pmvs 3368 REAL(wp) :: ptc 3369 REAL(wp) :: sclo 3370 REAL(wp) :: sult_lim 3371 REAL(wp) :: svp_ta 3372 REAL(wp) :: wclo 3373 3374 3375 storage = 0.0_wp 3401 3376 CALL persdat( age, weight, height, sex, work, a_surf, actlev ) 3402 3377 ! … … 3415 3390 ! 3416 3391 !-- Decision: firstly calculate for winter or summer clothing 3417 IF ( ta <= 10. _wp ) THEN3392 IF ( ta <= 10.0_wp ) THEN 3418 3393 ! 3419 3394 !-- First guess: winter clothing insulation: cold stress 3420 3395 clo = wclo 3421 3396 t_clothing = bio_fill_value ! force initial run 3422 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, 3423 t_clothing, storage, dt,pmva )3397 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, & 3398 pmva ) 3424 3399 pmv_w = pmva 3425 3400 3426 IF ( pmva > 0. _wp ) THEN3427 ! 3428 !-- Case summer clothing insulation: heat load ? 3401 IF ( pmva > 0.0_wp ) THEN 3402 ! 3403 !-- Case summer clothing insulation: heat load ? 3429 3404 clo = sclo 3430 3405 t_clothing = bio_fill_value ! force initial run 3431 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, 3432 t_clothing, storage, dt,pmva )3406 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, & 3407 pmva ) 3433 3408 pmv_s = pmva 3434 IF ( pmva <= 0. _wp ) THEN3435 ! 3436 !-- Case: comfort achievable by varying clothing insulation 3437 !-- between winter and summer setvalues3438 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta , sclo, 3439 pmv_s, wclo, pmv_w, eps,pmva, ncount, clo )3409 IF ( pmva <= 0.0_wp ) THEN 3410 ! 3411 !-- Case: comfort achievable by varying clothing insulation between winter and summer set 3412 !-- values 3413 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta , sclo, pmv_s, wclo, pmv_w, eps,& 3414 pmva, ncount, clo ) 3440 3415 IF ( ncount < 0_iwp ) THEN 3441 3416 nerr = -1_iwp … … 3445 3420 clo = 0.5_wp 3446 3421 t_clothing = bio_fill_value 3447 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, &3448 t_clothing, storage,dt, pmva )3422 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, & 3423 dt, pmva ) 3449 3424 ENDIF 3450 ELSE IF ( pmva < - 0.11_wp ) THEN3425 ELSE IF ( pmva < - 0.11_wp ) THEN 3451 3426 clo = 1.75_wp 3452 3427 t_clothing = bio_fill_value 3453 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, 3454 t_clothing, storage, dt,pmva )3428 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, & 3429 pmva ) 3455 3430 ENDIF 3456 3431 … … 3460 3435 clo = sclo 3461 3436 t_clothing = bio_fill_value 3462 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, 3463 t_clothing, storage, dt,pmva )3437 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, & 3438 pmva ) 3464 3439 pmv_s = pmva 3465 3440 3466 IF ( pmva < 0. _wp ) THEN3441 IF ( pmva < 0.0_wp ) THEN 3467 3442 ! 3468 3443 !-- Case winter clothing insulation: cold stress ? 3469 3444 clo = wclo 3470 3445 t_clothing = bio_fill_value 3471 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, 3472 t_clothing, storage, dt,pmva )3446 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, & 3447 pmva ) 3473 3448 pmv_w = pmva 3474 3449 3475 IF ( pmva >= 0. _wp ) THEN3476 ! 3477 !-- Case: comfort achievable by varying clothing insulation 3478 !-- between winter and summer setvalues3479 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta, sclo, 3480 pmv _s, wclo, pmv_w, eps, pmva, ncount, clo )3450 IF ( pmva >= 0.0_wp ) THEN 3451 ! 3452 !-- Case: comfort achievable by varying clothing insulation between winter and summer set 3453 !-- values 3454 CALL iso_ridder ( ta, tmrt, vp, ws, pair, actlev, eta, sclo, pmv_s, wclo, pmv_w, eps, & 3455 pmva, ncount, clo ) 3481 3456 IF ( ncount < 0_wp ) THEN 3482 3457 nerr = -1_iwp 3483 3458 RETURN 3484 3459 ENDIF 3485 ELSE IF ( pmva < - 0.11_wp ) THEN3460 ELSE IF ( pmva < - 0.11_wp ) THEN 3486 3461 clo = 1.75_wp 3487 3462 t_clothing = bio_fill_value 3488 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, &3489 t_clothing, storage,dt, pmva )3463 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, & 3464 dt, pmva ) 3490 3465 ENDIF 3491 3466 ELSE IF ( pmva > 0.06_wp ) THEN 3492 3467 clo = 0.5_wp 3493 3468 t_clothing = bio_fill_value 3494 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, 3495 t_clothing, storage, dt,pmva )3469 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, & 3470 pmva ) 3496 3471 ENDIF 3497 3472 … … 3502 3477 CALL perct_regression( pmva, clo, ipt ) 3503 3478 ptc = ipt 3504 IF ( clo >= 1.75_wp .AND. pmva <= - 0.11_wp ) THEN3479 IF ( clo >= 1.75_wp .AND. pmva <= - 0.11_wp ) THEN 3505 3480 ! 3506 3481 !-- Adjust for cold conditions according to Gagge 1986 … … 3508 3483 IF ( nerr_cold > 0_iwp ) nerr = -5_iwp 3509 3484 pmvs = pmva - d_pmv 3510 IF ( pmvs > - 0.11_wp ) THEN3511 d_pmv = 0. _wp3512 pmvs = - 0.11_wp3485 IF ( pmvs > - 0.11_wp ) THEN 3486 d_pmv = 0.0_wp 3487 pmvs = - 0.11_wp 3513 3488 ENDIF 3514 3489 CALL perct_regression( pmvs, clo, ipt ) … … 3518 3493 IF ( clo > 0.5_wp .AND. ipt <= 8.73_wp ) THEN 3519 3494 ! 3520 !-- Required clothing insulation (ireq) is exclusively defined for 3521 !-- perceived temperatures (ipt) less 10 (C) for a 3522 !-- reference wind of 0.2 m/s according to 8.73 (C) for 0.1 m/s 3495 !-- Required clothing insulation (ireq) is exclusively defined for perceived temperatures (ipt) 3496 !-- less 10 (C) for a reference wind of 0.2 m/s according to 8.73 (C) for 0.1 m/s 3523 3497 clon = ireq_neutral ( ipt, ireq_minimal, nerr ) 3524 3498 clo = clon … … 3526 3500 CALL calc_sultr( ptc, dgtcm, dgtcstd, sult_lim ) 3527 3501 sultrieness = .FALSE. 3528 d_std = - 99._wp3502 d_std = - 99.0_wp 3529 3503 IF ( pmva > 0.06_wp .AND. clo <= 0.5_wp ) THEN 3530 3504 ! … … 3534 3508 pmvs = pmva + d_pmv 3535 3509 CALL perct_regression( pmvs, clo, ipt ) 3536 IF ( sult_lim < 99. _wp ) THEN3510 IF ( sult_lim < 99.0_wp ) THEN 3537 3511 IF ( (ipt - ptc) > sult_lim ) sultrieness = .TRUE. 3538 3512 ENDIF 3539 3513 ENDIF 3540 3514 3541 3515 3542 3516 END SUBROUTINE ipt_init 3543 3544 !------------------------------------------------------------------------------ !3517 3518 !--------------------------------------------------------------------------------------------------! 3545 3519 ! Description: 3546 3520 ! ------------ 3547 3521 !> SUBROUTINE ipt_cycle 3548 !> Calculates one timestep for the instationary version of perceived 3549 !> temperature (iPT, degree_C) for 3550 !> - standard measured/predicted meteorological values and TMRT 3551 !> as input; 3522 !> Calculates one timestep for the instationary version of perceived temperature (iPT, degree_C) for 3523 !> - standard measured/predicted meteorological values and TMRT as input; 3552 3524 !> - regressions for determination of PT; 3553 !> - adjustment to Gagge's PMV* (2-node-model, 1986) as base of PT 3554 !> under warm/humid conditions (Icl= 0.50 clo) and under cold 3555 !> conditions (Icl= 1.75 clo) 3556 !> 3557 !------------------------------------------------------------------------------! 3558 SUBROUTINE ipt_cycle( ta, vp, ws, tmrt, pair, dt, storage, t_clothing, clo, & 3559 actlev, work, ipt ) 3525 !> - adjustment to Gagge's PMV* (2-node-model, 1986) as base of PT under warm/humid conditions 3526 !> (Icl= 0.50 clo) and under cold conditions (Icl= 1.75 clo) 3527 !--------------------------------------------------------------------------------------------------! 3528 SUBROUTINE ipt_cycle( ta, vp, ws, tmrt, pair, dt, storage, t_clothing, clo, actlev, work, ipt ) 3560 3529 3561 3530 IMPLICIT NONE 3562 3531 ! 3563 3532 !-- Type of input of the argument list 3533 REAL(wp), INTENT ( IN ) :: actlev !< Internal heat production (W) 3534 REAL(wp), INTENT ( IN ) :: clo !< Clothing index (no dim) 3535 REAL(wp), INTENT ( IN ) :: dt !< Timestep (s) 3536 REAL(wp), INTENT ( IN ) :: pair !< Air pressure (hPa) 3564 3537 REAL(wp), INTENT ( IN ) :: ta !< Air temperature (degree_C) 3538 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degree_C) 3565 3539 REAL(wp), INTENT ( IN ) :: vp !< Vapor pressure (hPa) 3566 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degree_C)3540 REAL(wp), INTENT ( IN ) :: work !< Mechanical work load (W) 3567 3541 REAL(wp), INTENT ( IN ) :: ws !< Wind speed (m/s) 3568 REAL(wp), INTENT ( IN ) :: pair !< Air pressure (hPa)3569 REAL(wp), INTENT ( IN ) :: dt !< Timestep (s)3570 REAL(wp), INTENT ( IN ) :: clo !< Clothing index (no dim)3571 REAL(wp), INTENT ( IN ) :: actlev !< Internal heat production (W)3572 REAL(wp), INTENT ( IN ) :: work !< Mechanical work load (W)3573 3542 ! 3574 3543 !-- In and output parameters … … 3580 3549 ! 3581 3550 !-- Type of internal variables 3551 INTEGER(iwp) :: nerr 3552 INTEGER(iwp) :: nerr_cold 3553 3554 LOGICAL :: sultrieness 3555 3582 3556 REAL(wp) :: d_pmv 3583 REAL(wp) :: svp_ta 3584 REAL(wp) :: sult_lim 3557 REAL(wp) :: d_std 3585 3558 REAL(wp) :: dgtcm 3586 3559 REAL(wp) :: dgtcstd 3587 3560 REAL(wp) :: pmva 3561 REAL(wp) :: pmvs 3588 3562 REAL(wp) :: ptc 3589 REAL(wp) :: d_std 3590 REAL(wp) :: pmvs 3591 INTEGER(iwp) :: nerr_cold 3592 INTEGER(iwp) :: nerr 3593 3594 LOGICAL :: sultrieness 3563 REAL(wp) :: sult_lim 3564 REAL(wp) :: svp_ta 3595 3565 ! 3596 3566 !-- Initialise … … 3601 3571 ! 3602 3572 !-- Determine pmv_adjusted for current conditions 3603 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, & 3604 t_clothing, storage, dt, pmva ) 3573 CALL fanger_s_acti ( ta, tmrt, vp, ws, pair, clo, actlev, work, t_clothing, storage, dt, pmva ) 3605 3574 ! 3606 3575 !-- Determine perceived temperature by regression equation + adjustments … … 3614 3583 IF ( nerr_cold > 0_iwp ) nerr = -5_iwp 3615 3584 pmvs = pmva - d_pmv 3616 IF ( pmvs > - 0.11_wp ) THEN3617 d_pmv = 0. _wp3618 pmvs = - 0.11_wp3585 IF ( pmvs > - 0.11_wp ) THEN 3586 d_pmv = 0.0_wp 3587 pmvs = - 0.11_wp 3619 3588 ENDIF 3620 3589 CALL perct_regression( pmvs, clo, ipt ) … … 3625 3594 CALL calc_sultr( ptc, dgtcm, dgtcstd, sult_lim ) 3626 3595 sultrieness = .FALSE. 3627 d_std = - 99._wp3596 d_std = - 99.0_wp 3628 3597 IF ( pmva > 0.06_wp .AND. clo <= 0.5_wp ) THEN 3629 3598 ! … … 3633 3602 pmvs = pmva + d_pmv 3634 3603 CALL perct_regression( pmvs, clo, ipt ) 3635 IF ( sult_lim < 99. _wp ) THEN3604 IF ( sult_lim < 99.0_wp ) THEN 3636 3605 IF ( (ipt - ptc) > sult_lim ) sultrieness = .TRUE. 3637 3606 ENDIF … … 3640 3609 END SUBROUTINE ipt_cycle 3641 3610 3642 !------------------------------------------------------------------------------ !3611 !--------------------------------------------------------------------------------------------------! 3643 3612 ! Description: 3644 3613 ! ------------ 3645 !> SUBROUTINE fanger_s calculates the 3646 !> actual Predicted Mean Vote (dimensionless) according 3647 !> to Fanger corresponding to meteorological (ta,tmrt,pa,ws,pair) 3648 !> and individual variables (clo, actlev, eta) considering a storage 3649 !> and clothing temperature for a given timestep. 3650 !------------------------------------------------------------------------------! 3651 SUBROUTINE fanger_s_acti( ta, tmrt, pa, in_ws, pair, in_clo, actlev, & 3652 activity, t_cloth, s, dt, pmva ) 3614 !> SUBROUTINE fanger_s calculates the actual Predicted Mean Vote (dimensionless) according to Fanger 3615 !> corresponding to meteorological (ta,tmrt,pa,ws,pair) and individual variables (clo, actlev, eta) 3616 !> considering a storage and clothing temperature for a given timestep. 3617 !--------------------------------------------------------------------------------------------------! 3618 SUBROUTINE fanger_s_acti( ta, tmrt, pa, in_ws, pair, in_clo, actlev, activity, t_cloth, s, dt, & 3619 pmva ) 3653 3620 3654 3621 IMPLICIT NONE 3655 3622 ! 3656 3623 !-- Input argument types 3624 REAL(wp), INTENT ( IN ) :: activity !< Work load (W/m²) 3625 REAL(wp), INTENT ( IN ) :: actlev !< Metabolic + work energy (W/m²) 3626 REAL(wp), INTENT ( IN ) :: dt !< Timestep (s) 3627 REAL(wp), INTENT ( IN ) :: in_clo !< Clothing index (clo) (no dim) 3628 REAL(wp), INTENT ( IN ) :: in_ws !< Wind speed (m/s) 3629 REAL(wp), INTENT ( IN ) :: pa !< Vapour pressure (hPa) 3630 REAL(wp), INTENT ( IN ) :: pair !< Air pressure (hPa) 3657 3631 REAL(wp), INTENT ( IN ) :: ta !< Air temperature (degree_C) 3658 3632 REAL(wp), INTENT ( IN ) :: tmrt !< Mean radiant temperature (degree_C) 3659 REAL(wp), INTENT ( IN ) :: pa !< Vapour pressure (hPa)3660 REAL(wp), INTENT ( IN ) :: pair !< Air pressure (hPa)3661 REAL(wp), INTENT ( IN ) :: in_ws !< Wind speed (m/s)3662 REAL(wp), INTENT ( IN ) :: actlev !< Metabolic + work energy (W/m²)3663 REAL(wp), INTENT ( IN ) :: dt !< Timestep (s)3664 REAL(wp), INTENT ( IN ) :: activity !< Work load (W/m²)3665 REAL(wp), INTENT ( IN ) :: in_clo !< Clothing index (clo) (no dim)3666 3633 ! 3667 3634 !-- Output argument types … … 3672 3639 ! 3673 3640 !-- Internal variables 3674 REAL(wp), PARAMETER :: time_equil = 7200._wp3675 3676 REAL(wp) :: f_cl !< Increase in surface due to clothing (factor)3677 REAL(wp) :: heat_convection !< energy loss by autocnvection (W)3678 REAL(wp) :: t_skin_aver !< average skin temperature (degree_C)3679 REAL(wp) :: bc !< preliminary result storage3680 REAL(wp) :: cc !< preliminary result storage3681 REAL(wp) :: dc !< preliminary result storage3682 REAL(wp) :: ec !< preliminary result storage3683 REAL(wp) :: gc !< preliminary result storage3684 REAL(wp) :: t_clothing !< clothing temperature (degree_C)3685 ! REAL(wp) :: hr !< radiational heat resistence3686 REAL(wp) :: clo !< clothing insulation index (clo)3687 REAL(wp) :: ws !< wind speed (m/s)3688 REAL(wp) :: z1 !< Empiric factor for the adaption of the heat3689 !< ballance equation to the psycho-physical scale (Equ. 40 in FANGER)3690 REAL(wp) :: z2 !< Water vapour diffution through the skin3691 REAL(wp) :: z3 !< Sweat evaporation from the skin surface3692 REAL(wp) :: z4 !< Loss of latent heat through respiration3693 REAL(wp) :: z5 !< Loss of radiational heat3694 REAL(wp) :: z6 !< Heat loss through forced convection3695 REAL(wp) :: en !< Energy ballance (W)3696 REAL(wp) :: d_s !< Storage delta (W)3697 REAL(wp) :: adjustrate !< Max storage adjustment rate3698 REAL(wp) :: adjustrate_cloth !< max clothing temp. adjustment rate3699 3700 3641 INTEGER(iwp) :: i !< running index 3701 3642 INTEGER(iwp) :: niter !< Running index 3702 3643 3644 REAL(wp), PARAMETER :: time_equil = 7200.0_wp 3645 3646 REAL(wp) :: adjustrate !< Max storage adjustment rate 3647 REAL(wp) :: adjustrate_cloth !< max clothing temp. adjustment rate 3648 REAL(wp) :: bc !< preliminary result storage 3649 REAL(wp) :: cc !< preliminary result storage 3650 REAL(wp) :: clo !< clothing insulation index (clo) 3651 REAL(wp) :: d_s !< Storage delta (W) 3652 REAL(wp) :: dc !< preliminary result storage 3653 REAL(wp) :: en !< Energy ballance (W) 3654 REAL(wp) :: ec !< preliminary result storage 3655 REAL(wp) :: f_cl !< Increase in surface due to clothing (factor) 3656 REAL(wp) :: gc !< preliminary result storage 3657 REAL(wp) :: heat_convection !< energy loss by autocnvection (W) 3658 ! REAL(wp) :: hr !< radiational heat resistence 3659 REAL(wp) :: t_clothing !< clothing temperature (degree_C) 3660 REAL(wp) :: t_skin_aver !< average skin temperature (degree_C) 3661 REAL(wp) :: ws !< wind speed (m/s) 3662 REAL(wp) :: z1 !< Empiric factor for the adaption of the heat 3663 !< ballance equation to the psycho-physical scale 3664 !< (Equ. 40 in FANGER) 3665 REAL(wp) :: z2 !< Water vapour diffution through the skin 3666 REAL(wp) :: z3 !< Sweat evaporation from the skin surface 3667 REAL(wp) :: z4 !< Loss of latent heat through respiration 3668 REAL(wp) :: z5 !< Loss of radiational heat 3669 REAL(wp) :: z6 !< Heat loss through forced convection 3670 3671 3672 3673 3703 3674 ! 3704 3675 !-- Clo must be > 0. to avoid div. by 0! 3705 3676 clo = in_clo 3706 IF ( clo < 001. _wp ) clo =.001_wp3677 IF ( clo < 001.0_wp ) clo = 0.001_wp 3707 3678 ! 3708 3679 !-- Increase in surface due to clothing 3709 f_cl = 1. _wp +.15_wp * clo3680 f_cl = 1.0_wp + 0.15_wp * clo 3710 3681 ! 3711 3682 !-- Case of free convection (ws < 0.1 m/s ) not considered 3712 3683 ws = in_ws 3713 IF ( ws < .1_wp ) THEN3714 ws = .1_wp3684 IF ( ws < 0.1_wp ) THEN 3685 ws = 0.1_wp 3715 3686 ENDIF 3716 3687 ! … … 3719 3690 ! 3720 3691 !-- Average skin temperature 3721 t_skin_aver = 35.7_wp - .0275_wp * activity3692 t_skin_aver = 35.7_wp - 0.0275_wp * activity 3722 3693 ! 3723 3694 !-- Calculation of constants for evaluation below 3724 bc = .155_wp * clo * 3.96_wp * 10._wp**( -8._wp ) * f_cl3695 bc = 0.155_wp * clo * 3.96_wp * 10.0_wp**( -8.0_wp ) * f_cl 3725 3696 cc = f_cl * heat_convection 3726 ec = .155_wp * clo3727 dc = ( 1. _wp + ec * cc ) / bc3728 gc = ( t_skin_aver + bc * ( tmrt + 273.2_wp )**4. _wp + ec * cc * ta ) / bc3729 ! 3730 !-- Calculation of clothing surface temperature (t_clothing) based on 3731 !-- newton-approximation with airtemperature as initial guess3732 niter = INT( dt * 10. _wp, KIND=iwp )3697 ec = 0.155_wp * clo 3698 dc = ( 1.0_wp + ec * cc ) / bc 3699 gc = ( t_skin_aver + bc * ( tmrt + 273.2_wp )**4.0_wp + ec * cc * ta ) / bc 3700 ! 3701 !-- Calculation of clothing surface temperature (t_clothing) based on Newton-approximation with air 3702 !-- temperature as initial guess 3703 niter = INT( dt * 10.0_wp, KIND=iwp ) 3733 3704 IF ( niter < 1 ) niter = 1_iwp 3734 adjustrate = 1. _wp - EXP( -1._wp * ( 10._wp / time_equil ) * dt )3735 IF ( adjustrate >= 1. _wp ) adjustrate = 1._wp3736 adjustrate_cloth = adjustrate * 30. _wp3705 adjustrate = 1.0_wp - EXP( -1.0_wp * ( 10.0_wp / time_equil ) * dt ) 3706 IF ( adjustrate >= 1.0_wp ) adjustrate = 1.0_wp 3707 adjustrate_cloth = adjustrate * 30.0_wp 3737 3708 t_clothing = t_cloth 3738 3709 ! 3739 !-- Set initial values for niter, adjustrates and t_clothing if this is the 3740 !-- first call 3741 IF ( t_cloth <= -998._wp ) THEN ! If initial run 3710 !-- Set initial values for niter, adjustrates and t_clothing if this is the first call 3711 IF ( t_cloth <= -998.0_wp ) THEN ! If initial run 3742 3712 niter = 3_iwp 3743 adjustrate = 1. _wp3744 adjustrate_cloth = 1. _wp3713 adjustrate = 1.0_wp 3714 adjustrate_cloth = 1.0_wp 3745 3715 t_clothing = ta 3746 3716 ENDIF … … 3748 3718 !-- Update clothing temperature 3749 3719 DO i = 1, niter 3750 t_clothing = t_clothing - adjustrate_cloth * ( ( t_clothing + & 3751 273.2_wp )**4._wp + t_clothing * & 3752 dc - gc ) / ( 4._wp * ( t_clothing + 273.2_wp )**3._wp + dc ) 3720 t_clothing = t_clothing - adjustrate_cloth * ( ( t_clothing + 273.2_wp )**4.0_wp + & 3721 t_clothing * dc - gc ) / ( 4.0_wp * ( t_clothing + 273.2_wp )**3.0_wp + dc ) 3753 3722 ENDDO 3754 3723 ! 3755 !-- Empiric factor for the adaption of the heat ballance equation 3756 !-- to the psycho-physical scale(Equ. 40 in FANGER)3757 z1 = ( .303_wp * EXP( -.036_wp * actlev ) +.0275_wp )3724 !-- Empiric factor for the adaption of the heat ballance equation to the psycho-physical scale 3725 !-- (Equ. 40 in FANGER) 3726 z1 = ( 0.303_wp * EXP( - 0.036_wp * actlev ) + 0.0275_wp ) 3758 3727 ! 3759 3728 !-- Water vapour diffution through the skin 3760 z2 = .31_wp * ( 57.3_wp -.07_wp * activity-pa )3729 z2 = 0.31_wp * ( 57.3_wp - 0.07_wp * activity-pa ) 3761 3730 ! 3762 3731 !-- Sweat evaporation from the skin surface 3763 z3 = .42_wp * ( activity - 58._wp )3732 z3 = 0.42_wp * ( activity - 58.0_wp ) 3764 3733 ! 3765 3734 !-- Loss of latent heat through respiration 3766 z4 = .0017_wp * actlev * ( 58.7_wp - pa ) + .0014_wp * actlev * & 3767 ( 34._wp - ta ) 3735 z4 = 0.0017_wp * actlev * ( 58.7_wp - pa ) + 0.0014_wp * actlev * ( 34.0_wp - ta ) 3768 3736 ! 3769 3737 !-- Loss of radiational heat 3770 z5 = 3.96e-8_wp * f_cl * ( ( t_clothing + 273.2_wp )**4 - ( tmrt + & 3771 273.2_wp )**4 ) 3738 z5 = 3.96e-8_wp * f_cl * ( ( t_clothing + 273.2_wp )**4 - ( tmrt + 273.2_wp )**4 ) 3772 3739 ! 3773 3740 !-- Heat loss through forced convection … … 3778 3745 ! 3779 3746 !-- Manage storage 3780 d_s = adjustrate * en + ( 1. _wp - adjustrate ) * s3747 d_s = adjustrate * en + ( 1.0_wp - adjustrate ) * s 3781 3748 ! 3782 3749 !-- Predicted Mean Vote … … 3791 3758 3792 3759 3793 !------------------------------------------------------------------------------ !3760 !--------------------------------------------------------------------------------------------------! 3794 3761 ! 3795 3762 ! Description: … … 3798 3765 !> stationary (calculated based on MEMI), 3799 3766 !> Subroutine based on PETBER vers. 1.5.1996 by P. Hoeppe 3800 !------------------------------------------------------------------------------ !3767 !--------------------------------------------------------------------------------------------------! 3801 3768 3802 3769 SUBROUTINE calculate_pet_static( ta, vpa, v, tmrt, pair, pet_ij ) … … 3805 3772 ! 3806 3773 !-- Input arguments: 3774 REAL(wp), INTENT( IN ) :: pair !< Air pressure (hPa) 3807 3775 REAL(wp), INTENT( IN ) :: ta !< Air temperature (degree_C) 3808 3776 REAL(wp), INTENT( IN ) :: tmrt !< Mean radiant temperature (degree_C) 3809 3777 REAL(wp), INTENT( IN ) :: v !< Wind speed (m/s) 3810 3778 REAL(wp), INTENT( IN ) :: vpa !< Vapor pressure (hPa) 3811 REAL(wp), INTENT( IN ) :: pair !< Air pressure (hPa)3812 3779 ! 3813 3780 !-- Output arguments: … … 3827 3794 REAL(wp) :: rtv 3828 3795 REAL(wp) :: vpts !< Sat. vapor pressure over skin (hPa) 3796 REAL(wp) :: tcl !< Clothing temperature (degree_C) 3829 3797 REAL(wp) :: tsk !< Skin temperature (degree_C) 3830 REAL(wp) :: tcl !< Clothing temperature (degree_C)3831 3798 REAL(wp) :: wetsk !< Fraction of wet skin (factor) 3832 3799 ! … … 3836 3803 !-- MEMI configuration 3837 3804 REAL(wp) :: age !< Persons age (a) 3805 REAL(wp) :: clo !< Clothing insulation index (clo) 3806 REAL(wp) :: eta !< Work efficiency (dimensionless) 3807 REAL(wp) :: fcl !< Surface area modification by clothing (factor) 3808 REAL(wp) :: ht !< Persons height (m) 3838 3809 REAL(wp) :: mbody !< Persons body mass (kg) 3839 REAL(wp) :: ht !< Persons height (m)3840 3810 REAL(wp) :: work !< Work load (W) 3841 REAL(wp) :: eta !< Work efficiency (dimensionless) 3842 REAL(wp) :: clo !< Clothing insulation index (clo) 3843 REAL(wp) :: fcl !< Surface area modification by clothing (factor) 3844 ! INTEGER(iwp) :: pos !< Posture: 1 = standing, 2 = sitting 3845 ! INTEGER(iwp) :: sex !< Sex: 1 = male, 2 = female 3811 ! INTEGER(iwp) :: pos !< Posture: 1 = standing, 2 = sitting 3812 ! INTEGER(iwp) :: sex !< Sex: 1 = male, 2 = female 3846 3813 ! 3847 3814 !-- Configuration, keep standard parameters! 3848 age = 35. _wp3849 mbody = 75. _wp3815 age = 35.0_wp 3816 mbody = 75.0_wp 3850 3817 ht = 1.75_wp 3851 work = 80. _wp3852 eta = 0. _wp3818 work = 80.0_wp 3819 eta = 0.0_wp 3853 3820 clo = 0.9_wp 3854 3821 fcl = 1.15_wp 3855 3822 ! 3856 3823 !-- Call subfunctions 3857 CALL in_body( age, eta, ere, erel, ht, int_heat, mbody, pair, rtv, ta, & 3858 vpa, work ) 3859 3860 CALL heat_exch( acl, adu, aeff, clo, ere, erel, esw, facl, fcl, feff, ht, & 3861 int_heat, mbody, pair, rdcl, rdsk, ta, tcl, tmrt, tsk, v, vpa, & 3862 vpts, wetsk ) 3863 3864 CALL pet_iteration( acl, adu, aeff, esw, facl, feff, int_heat, pair, & 3865 rdcl, rdsk, rtv, ta, tcl, tsk, pet_ij, vpts, wetsk ) 3824 CALL in_body( age, eta, ere, erel, ht, int_heat, mbody, pair, rtv, ta, vpa, work ) 3825 3826 CALL heat_exch( acl, adu, aeff, clo, ere, erel, esw, facl, fcl, feff, ht, int_heat, mbody, & 3827 pair, rdcl, rdsk, ta, tcl, tmrt, tsk, v, vpa, vpts, wetsk ) 3828 3829 CALL pet_iteration( acl, adu, aeff, esw, facl, feff, int_heat, pair, rdcl, rdsk, rtv, ta, tcl, & 3830 tsk, pet_ij, vpts, wetsk ) 3866 3831 3867 3832 … … 3869 3834 3870 3835 3871 !------------------------------------------------------------------------------ !3836 !--------------------------------------------------------------------------------------------------! 3872 3837 ! Description: 3873 3838 ! ------------ 3874 3839 !> Calculate internal energy ballance 3875 !------------------------------------------------------------------------------! 3876 SUBROUTINE in_body( age, eta, ere, erel, ht, int_heat, mbody, pair, rtv, ta, & 3877 vpa, work ) 3840 !--------------------------------------------------------------------------------------------------! 3841 SUBROUTINE in_body( age, eta, ere, erel, ht, int_heat, mbody, pair, rtv, ta, vpa, work ) 3878 3842 ! 3879 3843 !-- Input arguments: 3844 REAL(wp), INTENT( IN ) :: age !< Persons age (a) 3845 REAL(wp), INTENT( IN ) :: eta !< Work efficiency (dimensionless) 3846 REAL(wp), INTENT( IN ) :: ht !< Persons height (m) 3847 REAL(wp), INTENT( IN ) :: mbody !< Persons body mass (kg) 3880 3848 REAL(wp), INTENT( IN ) :: pair !< air pressure (hPa) 3881 3849 REAL(wp), INTENT( IN ) :: ta !< air temperature (degree_C) 3882 3850 REAL(wp), INTENT( IN ) :: vpa !< vapor pressure (hPa) 3883 REAL(wp), INTENT( IN ) :: age !< Persons age (a)3884 REAL(wp), INTENT( IN ) :: mbody !< Persons body mass (kg)3885 REAL(wp), INTENT( IN ) :: ht !< Persons height (m)3886 3851 REAL(wp), INTENT( IN ) :: work !< Work load (W) 3887 REAL(wp), INTENT( IN ) :: eta !< Work efficiency (dimensionless)3888 3852 ! 3889 3853 !-- Output arguments: … … 3901 3865 ! 3902 3866 !-- Metabolic heat production 3903 met = 3.45_wp * mbody**( 3. _wp / 4._wp ) * (1._wp + 0.004_wp *&3904 ( 30. _wp - age) + 0.010_wp * ( ( ht * 100._wp /&3905 ( mbody**( 1. _wp / 3._wp ) ) ) - 43.4_wp ) )3867 met = 3.45_wp * mbody**( 3.0_wp / 4.0_wp ) * (1.0_wp + 0.004_wp * & 3868 ( 30.0_wp - age) + 0.010_wp * ( ( ht * 100.0_wp / & 3869 ( mbody**( 1.0_wp / 3.0_wp ) ) ) - 43.4_wp ) ) 3906 3870 met = work + met 3907 int_heat = met * (1. _wp - eta)3871 int_heat = met * (1.0_wp - eta) 3908 3872 ! 3909 3873 !-- Sensible respiration energy 3910 3874 tex = 0.47_wp * ta + 21.0_wp 3911 rtv = 1.44_wp * 10. _wp**(-6._wp) * met3875 rtv = 1.44_wp * 10.0_wp**(-6.0_wp) * met 3912 3876 eres = c_p * (ta - tex) * rtv 3913 3877 ! 3914 3878 !-- Latent respiration energy 3915 vpex = 6.11_wp * 10. _wp**( 7.45_wp * tex / ( 235._wp + tex ) )3879 vpex = 6.11_wp * 10.0_wp**( 7.45_wp * tex / ( 235.0_wp + tex ) ) 3916 3880 erel = 0.623_wp * l_v / pair * ( vpa - vpex ) * rtv 3917 3881 ! … … 3922 3886 3923 3887 3924 !------------------------------------------------------------------------------ !3888 !--------------------------------------------------------------------------------------------------! 3925 3889 ! Description: 3926 3890 ! ------------ 3927 3891 !> Calculate heat gain or loss 3928 !------------------------------------------------------------------------------! 3929 SUBROUTINE heat_exch( acl, adu, aeff, clo, ere, erel, esw, facl, fcl, feff, & 3930 ht, int_heat, mbody, pair, rdcl, rdsk, ta, tcl, tmrt, tsk, v, vpa, & 3931 vpts, wetsk ) 3892 !--------------------------------------------------------------------------------------------------! 3893 SUBROUTINE heat_exch( acl, adu, aeff, clo, ere, erel, esw, facl, fcl, feff, ht, int_heat, mbody, & 3894 pair, rdcl, rdsk, ta, tcl, tmrt, tsk, v, vpa, vpts, wetsk ) 3932 3895 3933 3896 ! 3934 3897 !-- Input arguments: 3898 REAL(wp), INTENT( IN ) :: clo !< clothing insulation (clo) 3899 REAL(wp), INTENT( IN ) :: fcl !< factor for surface area increase by clothing 3935 3900 REAL(wp), INTENT( IN ) :: ere !< Energy ballance (W) 3936 3901 REAL(wp), INTENT( IN ) :: erel !< Latent energy ballance (W) 3902 REAL(wp), INTENT( IN ) :: ht !< height (m) 3937 3903 REAL(wp), INTENT( IN ) :: int_heat !< internal heat production (W) 3904 REAL(wp), INTENT( IN ) :: mbody !< body mass (kg) 3938 3905 REAL(wp), INTENT( IN ) :: pair !< Air pressure (hPa) 3939 3906 REAL(wp), INTENT( IN ) :: ta !< Air temperature (degree_C) … … 3941 3908 REAL(wp), INTENT( IN ) :: v !< Wind speed (m/s) 3942 3909 REAL(wp), INTENT( IN ) :: vpa !< Vapor pressure (hPa) 3943 REAL(wp), INTENT( IN ) :: mbody !< body mass (kg)3944 REAL(wp), INTENT( IN ) :: ht !< height (m)3945 REAL(wp), INTENT( IN ) :: clo !< clothing insulation (clo)3946 REAL(wp), INTENT( IN ) :: fcl !< factor for surface area increase by clothing3947 3910 ! 3948 3911 !-- Output arguments: … … 3961 3924 ! 3962 3925 !-- Cconstants: 3963 ! REAL(wp), PARAMETER :: cair = 1010. _wp !< replaced by c_p3964 REAL(wp), PARAMETER :: cb = 3640. _wp !<3926 ! REAL(wp), PARAMETER :: cair = 1010.0_wp !< replaced by c_p 3927 REAL(wp), PARAMETER :: cb = 3640.0_wp !< 3965 3928 REAL(wp), PARAMETER :: emcl = 0.95_wp !< Longwave emission coef. of cloth 3966 3929 REAL(wp), PARAMETER :: emsk = 0.99_wp !< Longwave emission coef. of skin 3967 ! REAL(wp), PARAMETER :: evap = 2.42_wp * 10._wp **6._wp !< replaced by l_v3968 REAL(wp), PARAMETER :: food = 0. _wp !< Heat gain by food (W)3930 ! REAL(wp), PARAMETER :: evap = 2.42_wp * 10.0_wp **6.0_wp !< replaced by l_v 3931 REAL(wp), PARAMETER :: food = 0.0_wp !< Heat gain by food (W) 3969 3932 REAL(wp), PARAMETER :: po = 1013.25_wp !< Air pressure at sea level (hPa) 3970 REAL(wp), PARAMETER :: rob = 1.06_wp !< 3933 REAL(wp), PARAMETER :: rob = 1.06_wp !< 3971 3934 ! 3972 3935 !-- Internal variables 3973 REAL(wp) :: c(0:10) !< Core temperature array (degree_C) 3936 INTEGER(iwp) :: count1 !< running index 3937 INTEGER(iwp) :: count3 !< running index 3938 INTEGER(iwp) :: j !< running index 3939 INTEGER(iwp) :: i !< running index 3940 3941 LOGICAL :: skipincreasecount !< iteration control flag 3942 3974 3943 REAL(wp) :: cbare !< Convection through bare skin 3975 3944 REAL(wp) :: cclo !< Convection through clothing … … 3982 3951 REAL(wp) :: eswphy !< sweat created by physiology 3983 3952 REAL(wp) :: eswpot !< potential sweat evaporation 3984 REAL(wp) :: fec !< 3985 REAL(wp) :: hc !< 3986 REAL(wp) :: he !< 3987 REAL(wp) :: htcl !< 3988 REAL(wp) :: r1 !< 3989 REAL(wp) :: r2 !< 3953 REAL(wp) :: fec !< 3954 REAL(wp) :: hc !< 3955 REAL(wp) :: he !< 3956 REAL(wp) :: htcl !< 3957 REAL(wp) :: r1 !< 3958 REAL(wp) :: r2 !< 3990 3959 REAL(wp) :: rbare !< Radiational loss of bare skin (W/m²) 3991 REAL(wp) :: rcl !< 3960 REAL(wp) :: rcl !< 3992 3961 REAL(wp) :: rclo !< Radiational loss of clothing (W/m²) 3993 3962 REAL(wp) :: rclo2 !< Longwave radiation gain or loss (W/m²) 3994 3963 REAL(wp) :: rsum !< Radiational loss or gain (W/m²) 3995 REAL(wp) :: sw !< 3996 ! REAL(wp) :: swf !< female factor, currently unused 3997 REAL(wp) :: swm !< 3998 REAL(wp) :: tbody !< 3999 REAL(wp) :: tcore(1:7) !< 4000 REAL(wp) :: vb !< 4001 REAL(wp) :: vb1 !< 4002 REAL(wp) :: vb2 !< 4003 REAL(wp) :: wd !< 4004 REAL(wp) :: wr !< 4005 REAL(wp) :: ws !< 4006 REAL(wp) :: wsum !< 3964 REAL(wp) :: sw !< 3965 ! REAL(wp) :: swf !< female factor, currently unused 3966 REAL(wp) :: swm !< 3967 REAL(wp) :: tbody !< 3968 REAL(wp) :: vb !< 3969 REAL(wp) :: vb1 !< 3970 REAL(wp) :: vb2 !< 3971 REAL(wp) :: wd !< 3972 REAL(wp) :: wr !< 3973 REAL(wp) :: ws !< 3974 REAL(wp) :: wsum !< 4007 3975 REAL(wp) :: xx !< modification step (K) 4008 3976 REAL(wp) :: y !< fraction of bare skin 4009 INTEGER(iwp) :: count1 !< running index 4010 INTEGER(iwp) :: count3 !< running index 4011 INTEGER(iwp) :: j !< running index 4012 INTEGER(iwp) :: i !< running index 4013 LOGICAL :: skipIncreaseCount !< iteration control flag 3977 3978 REAL(wp) :: c(0:10) !< Core temperature array (degree_C) 3979 REAL(wp) :: tcore(1:7) !< 4014 3980 4015 3981 ! 4016 3982 !-- Initialize 4017 wetsk = 0. _wp !< skin is dry everywhere on init (no non-evaporated sweat)3983 wetsk = 0.0_wp !< skin is dry everywhere on init (no non-evaporated sweat) 4018 3984 ! 4019 3985 !-- Set Du Bois Area for the sample person … … 4028 3994 ! 4029 3995 !-- Set surface modification by clothing 4030 facl = ( - 2.36_wp + 173.51_wp * clo - 100.76_wp * clo * clo + 19.28_wp &4031 * ( clo**3._wp ) ) / 100._wp4032 IF ( facl > 1. _wp ) facl = 1._wp3996 facl = ( - 2.36_wp + 173.51_wp * clo - 100.76_wp * clo * clo + 19.28_wp * ( clo**3.0_wp ) ) & 3997 / 100.0_wp 3998 IF ( facl > 1.0_wp ) facl = 1.0_wp 4033 3999 ! 4034 4000 !-- Initialize heat resistences 4035 4001 rcl = ( clo / 6.45_wp ) / facl 4036 IF ( clo >= 2. _wp ) y = 1._wp4037 IF ( ( clo > 0.6_wp ) .AND. ( clo < 2. _wp ) ) y = ( ht - 0.2_wp ) / ht4002 IF ( clo >= 2.0_wp ) y = 1.0_wp 4003 IF ( ( clo > 0.6_wp ) .AND. ( clo < 2.0_wp ) ) y = ( ht - 0.2_wp ) / ht 4038 4004 IF ( ( clo <= 0.6_wp ) .AND. ( clo > 0.3_wp ) ) y = 0.5_wp 4039 IF ( ( clo <= 0.3_wp ) .AND. ( clo > 0. _wp ) ) y = 0.1_wp4040 r2 = adu * ( fcl - 1. _wp + facl ) / ( 2._wp * 3.14_wp * ht * y )4041 r1 = facl * adu / ( 2. _wp * 3.14_wp * ht * y )4005 IF ( ( clo <= 0.3_wp ) .AND. ( clo > 0.0_wp ) ) y = 0.1_wp 4006 r2 = adu * ( fcl - 1.0_wp + facl ) / ( 2.0_wp * 3.14_wp * ht * y ) 4007 r1 = facl * adu / ( 2.0_wp * 3.14_wp * ht * y ) 4042 4008 di = r2 - r1 4043 4009 … … 4046 4012 DO j = 1, 7 4047 4013 4048 tsk = 34. _wp4014 tsk = 34.0_wp 4049 4015 count1 = 0_iwp 4050 tcl = ( ta + tmrt + tsk ) / 3. _wp4016 tcl = ( ta + tmrt + tsk ) / 3.0_wp 4051 4017 count3 = 1_iwp 4052 enbal2 = 0. _wp4018 enbal2 = 0.0_wp 4053 4019 4054 4020 DO i = 1, 100 ! allow for 100 iterations max 4055 acl = adu * facl + adu * ( fcl - 1. _wp )4056 rclo2 = emcl * sigma_sb * ( ( tcl + degc_to_k )**4. _wp -&4057 ( tmrt + degc_to_k )**4._wp ) * feff4021 acl = adu * facl + adu * ( fcl - 1.0_wp ) 4022 rclo2 = emcl * sigma_sb * ( ( tcl + degc_to_k )**4.0_wp - & 4023 ( tmrt + degc_to_k )**4.0_wp ) * feff 4058 4024 htcl = 6.28_wp * ht * y * di / ( rcl * LOG( r2 / r1 ) * acl ) 4059 tsk = 1. _wp / htcl * ( hc * ( tcl - ta ) + rclo2 ) + tcl4025 tsk = 1.0_wp / htcl * ( hc * ( tcl - ta ) + rclo2 ) + tcl 4060 4026 ! 4061 4027 !-- Radiation saldo 4062 4028 aeff = adu * feff 4063 rbare = aeff * ( 1. _wp - facl ) * emsk * sigma_sb *&4064 ( ( tmrt + degc_to_k )**4._wp - ( tsk + degc_to_k )**4._wp )4065 rclo = feff * acl * emcl * sigma_sb * &4066 ( ( tmrt + degc_to_k )**4._wp - ( tcl + degc_to_k )**4._wp )4029 rbare = aeff * ( 1.0_wp - facl ) * emsk * sigma_sb * & 4030 ( ( tmrt + degc_to_k )**4.0_wp - ( tsk + degc_to_k )**4.0_wp ) 4031 rclo = feff * acl * emcl * sigma_sb * & 4032 ( ( tmrt + degc_to_k )**4.0_wp - ( tcl + degc_to_k )**4.0_wp ) 4067 4033 rsum = rbare + rclo 4068 4034 ! 4069 4035 !-- Convection 4070 cbare = hc * ( ta - tsk ) * adu * ( 1. _wp - facl )4036 cbare = hc * ( ta - tsk ) * adu * ( 1.0_wp - facl ) 4071 4037 cclo = hc * ( ta - tcl ) * acl 4072 4038 csum = cbare + cclo … … 4075 4041 c(0) = int_heat + ere 4076 4042 c(1) = adu * rob * cb 4077 c(2) = 18. _wp - 0.5_wp * tsk4043 c(2) = 18.0_wp - 0.5_wp * tsk 4078 4044 c(3) = 5.28_wp * adu * c(2) 4079 4045 c(4) = 0.0208_wp * c(1) … … 4081 4047 c(6) = c(3) - c(5) - tsk * c(4) 4082 4048 c(7) = - c(0) * c(2) - tsk * c(3) + tsk * c(5) 4083 c(8) = c(6) * c(6) - 4. _wp * c(4) * c(7)4049 c(8) = c(6) * c(6) - 4.0_wp * c(4) * c(7) 4084 4050 c(9) = 5.28_wp * adu - c(5) - c(4) * tsk 4085 c(10) = c(9) * c(9) - 4._wp * c(4) * & 4086 ( c(5) * tsk - c(0) - 5.28_wp * adu * tsk ) 4087 4088 IF ( ABS( tsk - 36._wp ) < 0.00001_wp ) tsk = 36.01_wp 4089 tcore(7) = c(0) / ( 5.28_wp * adu + c(1) * 6.3_wp / 3600._wp ) + tsk 4090 tcore(3) = c(0) / ( 5.28_wp * adu + ( c(1) * 6.3_wp / 3600._wp ) / & 4091 ( 1._wp + 0.5_wp * ( 34._wp - tsk ) ) ) + tsk 4092 IF ( c(10) >= 0._wp ) THEN 4093 tcore(6) = ( - c(9) - c(10)**0.5_wp ) / ( 2._wp * c(4) ) 4094 tcore(1) = ( - c(9) + c(10)**0.5_wp ) / ( 2._wp * c(4) ) 4051 c(10) = c(9) * c(9) - 4.0_wp * c(4) * ( c(5) * tsk - c(0) - 5.28_wp * adu * tsk ) 4052 4053 IF ( ABS( tsk - 36.0_wp ) < 0.00001_wp ) tsk = 36.01_wp 4054 tcore(7) = c(0) / ( 5.28_wp * adu + c(1) * 6.3_wp / 3600.0_wp ) + tsk 4055 tcore(3) = c(0) / ( 5.28_wp * adu + ( c(1) * 6.3_wp / 3600.0_wp ) / & 4056 ( 1.0_wp + 0.5_wp * ( 34.0_wp - tsk ) ) ) + tsk 4057 IF ( c(10) >= 0.0_wp ) THEN 4058 tcore(6) = ( - c(9) - c(10)**0.5_wp ) / ( 2.0_wp * c(4) ) 4059 tcore(1) = ( - c(9) + c(10)**0.5_wp ) / ( 2.0_wp * c(4) ) 4095 4060 ENDIF 4096 4061 4097 IF ( c(8) >= 0. _wp ) THEN4098 tcore(2) = ( - c(6) + ABS( c(8) )**0.5_wp ) / ( 2. _wp * c(4) )4099 tcore(5) = ( - c(6) - ABS( c(8) )**0.5_wp ) / ( 2. _wp * c(4) )4100 tcore(4) = c(0) / ( 5.28_wp * adu + c(1) * 1. _wp / 40._wp ) + tsk4062 IF ( c(8) >= 0.0_wp ) THEN 4063 tcore(2) = ( - c(6) + ABS( c(8) )**0.5_wp ) / ( 2.0_wp * c(4) ) 4064 tcore(5) = ( - c(6) - ABS( c(8) )**0.5_wp ) / ( 2.0_wp * c(4) ) 4065 tcore(4) = c(0) / ( 5.28_wp * adu + c(1) * 1.0_wp / 40.0_wp ) + tsk 4101 4066 ENDIF 4102 4067 ! 4103 4068 !-- Transpiration 4104 4069 tbody = 0.1_wp * tsk + 0.9_wp * tcore(j) 4105 swm = 304.94_wp * ( tbody - 36.6_wp ) * adu / 3600000. _wp4106 vpts = 6.11_wp * 10. _wp**( 7.45_wp * tsk / ( 235._wp + tsk ) )4107 4108 IF ( tbody <= 36.6_wp ) swm = 0. _wp !< no need for sweating4070 swm = 304.94_wp * ( tbody - 36.6_wp ) * adu / 3600000.0_wp 4071 vpts = 6.11_wp * 10.0_wp**( 7.45_wp * tsk / ( 235.0_wp + tsk ) ) 4072 4073 IF ( tbody <= 36.6_wp ) swm = 0.0_wp !< no need for sweating 4109 4074 4110 4075 sw = swm 4111 4076 eswphy = - sw * l_v 4112 4077 he = 0.633_wp * hc / ( pair * c_p ) 4113 fec = 1. _wp / ( 1._wp + 0.92_wp * hc * rcl )4078 fec = 1.0_wp / ( 1.0_wp + 0.92_wp * hc * rcl ) 4114 4079 eswpot = he * ( vpa - vpts ) * adu * l_v * fec 4115 4080 wetsk = eswphy / eswpot 4116 4081 4117 IF ( wetsk > 1. _wp ) wetsk = 1._wp4082 IF ( wetsk > 1.0_wp ) wetsk = 1.0_wp 4118 4083 ! 4119 4084 !-- Sweat production > evaporation? 4120 4085 eswdif = eswphy - eswpot 4121 4086 4122 IF ( eswdif <= 0._wp ) esw = eswpot !< Limit is evaporation 4123 IF ( eswdif > 0._wp ) esw = eswphy !< Limit is sweat production 4124 IF ( esw > 0._wp ) esw = 0._wp !< Sweat can't be evaporated, no more cooling effect 4087 IF ( eswdif <= 0.0_wp ) esw = eswpot !< Limit is evaporation 4088 IF ( eswdif > 0.0_wp ) esw = eswphy !< Limit is sweat production 4089 IF ( esw > 0.0_wp ) esw = 0.0_wp !< Sweat can't be evaporated, no more cooling 4090 !< effect 4125 4091 ! 4126 4092 !-- Diffusion 4127 rdsk = 0.79_wp * 10._wp**7._wp 4128 rdcl = 0._wp 4129 ed = l_v / ( rdsk + rdcl ) * adu * ( 1._wp - wetsk ) * ( vpa - & 4130 vpts ) 4093 rdsk = 0.79_wp * 10.0_wp**7.0_wp 4094 rdcl = 0.0_wp 4095 ed = l_v / ( rdsk + rdcl ) * adu * ( 1.0_wp - wetsk ) * ( vpa - vpts ) 4131 4096 ! 4132 4097 !-- Max vb 4133 vb1 = 34. _wp - tsk4098 vb1 = 34.0_wp - tsk 4134 4099 vb2 = tcore(j) - 36.6_wp 4135 4100 4136 IF ( vb2 < 0. _wp ) vb2 = 0._wp4137 IF ( vb1 < 0. _wp ) vb1 = 0._wp4138 vb = ( 6.3_wp + 75. _wp * vb2 ) / ( 1._wp + 0.5_wp * vb1 )4101 IF ( vb2 < 0.0_wp ) vb2 = 0.0_wp 4102 IF ( vb1 < 0.0_wp ) vb1 = 0.0_wp 4103 vb = ( 6.3_wp + 75.0_wp * vb2 ) / ( 1.0_wp + 0.5_wp * vb1 ) 4139 4104 ! 4140 4105 !-- Energy ballence … … 4143 4108 !-- Clothing temperature 4144 4109 xx = 0.001_wp 4145 IF ( count1 == 0_iwp ) xx = 1. _wp4110 IF ( count1 == 0_iwp ) xx = 1.0_wp 4146 4111 IF ( count1 == 1_iwp ) xx = 0.1_wp 4147 4112 IF ( count1 == 2_iwp ) xx = 0.01_wp 4148 4113 IF ( count1 == 3_iwp ) xx = 0.001_wp 4149 4114 4150 IF ( enbal > 0. _wp ) tcl = tcl + xx4151 IF ( enbal < 0. _wp ) tcl = tcl - xx4152 4153 skip IncreaseCount = .FALSE.4154 IF ( ( (enbal <= 0. _wp ) .AND. (enbal2 > 0._wp ) ) .OR.&4155 ( ( enbal >= 0. _wp ) .AND. ( enbal2 < 0._wp ) ) ) THEN4156 skip IncreaseCount = .TRUE.4115 IF ( enbal > 0.0_wp ) tcl = tcl + xx 4116 IF ( enbal < 0.0_wp ) tcl = tcl - xx 4117 4118 skipincreasecount = .FALSE. 4119 IF ( ( (enbal <= 0.0_wp ) .AND. (enbal2 > 0.0_wp ) ) .OR. & 4120 ( ( enbal >= 0.0_wp ) .AND. ( enbal2 < 0.0_wp ) ) ) THEN 4121 skipincreasecount = .TRUE. 4157 4122 ELSE 4158 4123 enbal2 = enbal … … 4160 4125 ENDIF 4161 4126 4162 IF ( ( count3 > 200_iwp ) .OR. skip IncreaseCount ) THEN4127 IF ( ( count3 > 200_iwp ) .OR. skipincreasecount ) THEN 4163 4128 IF ( count1 < 3_iwp ) THEN 4164 4129 count1 = count1 + 1_iwp 4165 enbal2 = 0. _wp4130 enbal2 = 0.0_wp 4166 4131 ELSE 4167 4132 EXIT … … 4172 4137 IF ( count1 == 3_iwp ) THEN 4173 4138 SELECT CASE ( j ) 4174 CASE ( 2, 5) 4175 IF ( .NOT. ( ( tcore(j) >= 36.6_wp ) .AND. & 4176 ( tsk <= 34.050_wp ) ) ) CYCLE 4139 CASE ( 2, 5) 4140 IF ( .NOT. ( ( tcore(j) >= 36.6_wp ) .AND. ( tsk <= 34.050_wp ) ) ) CYCLE 4177 4141 CASE ( 6, 1 ) 4178 IF ( c(10) < 0._wp ) CYCLE 4179 IF ( .NOT. ( ( tcore(j) >= 36.6_wp ) .AND. & 4180 ( tsk > 33.850_wp ) ) ) CYCLE 4142 IF ( c(10) < 0.0_wp ) CYCLE 4143 IF ( .NOT. ( ( tcore(j) >= 36.6_wp ) .AND. ( tsk > 33.850_wp ) ) ) CYCLE 4181 4144 CASE ( 3 ) 4182 IF ( .NOT. ( ( tcore(j) < 36.6_wp ) .AND. & 4183 ( tsk <= 34.000_wp ) ) ) CYCLE 4145 IF ( .NOT. ( ( tcore(j) < 36.6_wp ) .AND. ( tsk <= 34.000_wp ) ) ) CYCLE 4184 4146 CASE ( 7 ) 4185 IF ( .NOT. ( ( tcore(j) < 36.6_wp ) .AND. & 4186 ( tsk > 34.000_wp ) ) ) CYCLE 4147 IF ( .NOT. ( ( tcore(j) < 36.6_wp ) .AND. ( tsk > 34.000_wp ) ) ) CYCLE 4187 4148 CASE default 4188 4149 END SELECT 4189 4150 ENDIF 4190 4151 4191 IF ( ( j /= 4_iwp ) .AND. ( vb >= 91. _wp ) ) CYCLE4192 IF ( ( j == 4_iwp ) .AND. ( vb < 89. _wp ) ) CYCLE4193 IF ( vb > 90. _wp ) vb = 90._wp4152 IF ( ( j /= 4_iwp ) .AND. ( vb >= 91.0_wp ) ) CYCLE 4153 IF ( ( j == 4_iwp ) .AND. ( vb < 89.0_wp ) ) CYCLE 4154 IF ( vb > 90.0_wp ) vb = 90.0_wp 4194 4155 ! 4195 4156 !-- Loses by water 4196 ws = sw * 3600. _wp * 1000._wp4197 IF ( ws > 2000. _wp ) ws = 2000._wp4198 wd = ed / l_v * 3600. _wp * ( -1000._wp )4199 wr = erel / l_v * 3600. _wp * ( -1000._wp )4157 ws = sw * 3600.0_wp * 1000.0_wp 4158 IF ( ws > 2000.0_wp ) ws = 2000.0_wp 4159 wd = ed / l_v * 3600.0_wp * ( -1000.0_wp ) 4160 wr = erel / l_v * 3600.0_wp * ( -1000.0_wp ) 4200 4161 4201 4162 wsum = ws + wr + wd … … 4205 4166 END SUBROUTINE heat_exch 4206 4167 4207 !------------------------------------------------------------------------------ !4168 !--------------------------------------------------------------------------------------------------! 4208 4169 ! Description: 4209 4170 ! ------------ 4210 4171 !> Calculate PET 4211 !------------------------------------------------------------------------------ !4212 SUBROUTINE pet_iteration( acl, adu, aeff, esw, facl, feff, int_heat, pair, &4213 rdcl, rdsk, rtv, ta,tcl, tsk, pet_ij, vpts, wetsk )4172 !--------------------------------------------------------------------------------------------------! 4173 SUBROUTINE pet_iteration( acl, adu, aeff, esw, facl, feff, int_heat, pair, rdcl, rdsk, rtv, ta, & 4174 tcl, tsk, pet_ij, vpts, wetsk ) 4214 4175 ! 4215 4176 !-- Input arguments: 4216 REAL(wp), INTENT( IN ) :: acl !< clothing surface area (m²)4217 REAL(wp), INTENT( IN ) :: adu !< Du-Bois area (m²)4218 REAL(wp), INTENT( IN ) :: esw !< energy-loss through sweat evap. (W)4219 REAL(wp), INTENT( IN ) :: facl !< surface area extension through clothing (factor)4220 REAL(wp), INTENT( IN ) :: feff !< surface modification by posture (factor)4177 REAL(wp), INTENT( IN ) :: acl !< clothing surface area (m²) 4178 REAL(wp), INTENT( IN ) :: adu !< Du-Bois area (m²) 4179 REAL(wp), INTENT( IN ) :: esw !< energy-loss through sweat evap. (W) 4180 REAL(wp), INTENT( IN ) :: facl !< surface area extension through clothing (factor) 4181 REAL(wp), INTENT( IN ) :: feff !< surface modification by posture (factor) 4221 4182 REAL(wp), INTENT( IN ) :: int_heat !< internal heat production (W) 4222 REAL(wp), INTENT( IN ) :: pair !< air pressure (hPa)4223 REAL(wp), INTENT( IN ) :: rdcl !< diffusion resistence of clothing (factor)4224 REAL(wp), INTENT( IN ) :: rdsk !< diffusion resistence of skin (factor)4225 REAL(wp), INTENT( IN ) :: rtv !< respiratory volume4226 REAL(wp), INTENT( IN ) :: ta !< air temperature (degree_C)4227 REAL(wp), INTENT( IN ) :: tcl !< clothing temperature (degree_C)4228 REAL(wp), INTENT( IN ) :: tsk !< skin temperature (degree_C)4229 REAL(wp), INTENT( IN ) :: vpts !< sat. vapor pressure over skin (hPa)4230 REAL(wp), INTENT( IN ) :: wetsk !< fraction of wet skin (dimensionless)4183 REAL(wp), INTENT( IN ) :: pair !< air pressure (hPa) 4184 REAL(wp), INTENT( IN ) :: rdcl !< diffusion resistence of clothing (factor) 4185 REAL(wp), INTENT( IN ) :: rdsk !< diffusion resistence of skin (factor) 4186 REAL(wp), INTENT( IN ) :: rtv !< respiratory volume 4187 REAL(wp), INTENT( IN ) :: ta !< air temperature (degree_C) 4188 REAL(wp), INTENT( IN ) :: tcl !< clothing temperature (degree_C) 4189 REAL(wp), INTENT( IN ) :: tsk !< skin temperature (degree_C) 4190 REAL(wp), INTENT( IN ) :: vpts !< sat. vapor pressure over skin (hPa) 4191 REAL(wp), INTENT( IN ) :: wetsk !< fraction of wet skin (dimensionless) 4231 4192 ! 4232 4193 !-- Output arguments: … … 4240 4201 ! 4241 4202 !-- Internal variables 4203 INTEGER ( iwp ) :: count1 !< running index 4204 INTEGER ( iwp ) :: i !< running index 4205 4242 4206 REAL ( wp ) :: cbare !< Convection through bare skin 4243 4207 REAL ( wp ) :: cclo !< Convection through clothing … … 4257 4221 REAL ( wp ) :: xx !< Delta PET per iteration (K) 4258 4222 4259 INTEGER ( iwp ) :: count1 !< running index4260 INTEGER ( iwp ) :: i !< running index4261 4223 4262 4224 pet_ij = ta 4263 enbal2 = 0. _wp4225 enbal2 = 0.0_wp 4264 4226 4265 4227 DO count1 = 0, 3 … … 4270 4232 !-- Radiation 4271 4233 aeff = adu * feff 4272 rbare = aeff * ( 1. _wp - facl ) * emsk * sigma_sb * &4273 ( ( pet_ij + degc_to_k )**4._wp - ( tsk + degc_to_k )**4._wp )4234 rbare = aeff * ( 1.0_wp - facl ) * emsk * sigma_sb * & 4235 ( ( pet_ij + degc_to_k )**4.0_wp - ( tsk + degc_to_k )**4.0_wp ) 4274 4236 rclo = feff * acl * emcl * sigma_sb * & 4275 ( ( pet_ij + degc_to_k )**4._wp - ( tcl + degc_to_k )**4._wp )4237 ( ( pet_ij + degc_to_k )**4.0_wp - ( tcl + degc_to_k )**4.0_wp ) 4276 4238 rsum = rbare + rclo 4277 4239 ! 4278 4240 !-- Covection 4279 cbare = hc * ( pet_ij - tsk ) * adu * ( 1. _wp - facl )4241 cbare = hc * ( pet_ij - tsk ) * adu * ( 1.0_wp - facl ) 4280 4242 cclo = hc * ( pet_ij - tcl ) * acl 4281 4243 csum = cbare + cclo 4282 4244 ! 4283 4245 !-- Diffusion 4284 ed = l_v / ( rdsk + rdcl ) * adu * ( 1._wp - wetsk ) * ( 12._wp - & 4285 vpts ) 4246 ed = l_v / ( rdsk + rdcl ) * adu * ( 1.0_wp - wetsk ) * ( 12.0_wp - vpts ) 4286 4247 ! 4287 4248 !-- Respiration 4288 tex = 0.47_wp * pet_ij + 21. _wp4249 tex = 0.47_wp * pet_ij + 21.0_wp 4289 4250 eres = c_p * ( pet_ij - tex ) * rtv 4290 vpex = 6.11_wp * 10. _wp**( 7.45_wp * tex / ( 235._wp + tex ) )4291 erel = 0.623_wp * l_v / pair * ( 12. _wp - vpex ) * rtv4251 vpex = 6.11_wp * 10.0_wp**( 7.45_wp * tex / ( 235.0_wp + tex ) ) 4252 erel = 0.623_wp * l_v / pair * ( 12.0_wp - vpex ) * rtv 4292 4253 ere = eres + erel 4293 4254 ! … … 4297 4258 !-- Iteration concerning ta 4298 4259 xx = 0.001_wp 4299 IF ( count1 == 0_iwp ) xx = 1. _wp4260 IF ( count1 == 0_iwp ) xx = 1.0_wp 4300 4261 IF ( count1 == 1_iwp ) xx = 0.1_wp 4301 4262 IF ( count1 == 2_iwp ) xx = 0.01_wp 4302 4263 ! IF ( count1 == 3_iwp ) xx = 0.001_wp 4303 IF ( enbal > 0. _wp ) pet_ij = pet_ij - xx4304 IF ( enbal < 0. _wp ) pet_ij = pet_ij + xx4305 IF ( ( enbal <= 0. _wp ) .AND. ( enbal2 > 0._wp ) ) EXIT4306 IF ( ( enbal >= 0. _wp ) .AND. ( enbal2 < 0._wp ) ) EXIT4264 IF ( enbal > 0.0_wp ) pet_ij = pet_ij - xx 4265 IF ( enbal < 0.0_wp ) pet_ij = pet_ij + xx 4266 IF ( ( enbal <= 0.0_wp ) .AND. ( enbal2 > 0.0_wp ) ) EXIT 4267 IF ( ( enbal >= 0.0_wp ) .AND. ( enbal2 < 0.0_wp ) ) EXIT 4307 4268 4308 4269 enbal2 = enbal … … 4322 4283 4323 4284 USE control_parameters, & 4324 ONLY: latitude, longitude, time_ since_reference_point4285 ONLY: latitude, longitude, time_SINce_reference_point 4325 4286 4326 4287 IMPLICIT NONE … … 4328 4289 INTEGER(iwp) :: day_of_year = 0 !< day of year 4329 4290 4330 REAL(wp) :: alpha = 0.0_wp !< solar azimuth angle in radiant 4291 REAL(wp) :: alpha = 0.0_wp !< solar azimuth angle in radiant 4331 4292 REAL(wp) :: declination = 0.0_wp !< declination 4332 4293 REAL(wp) :: dtor = 0.0_wp !< factor to convert degree to radiant … … 4336 4297 REAL(wp) :: second_of_day = 0.0_wp !< current second of the day 4337 4298 REAL(wp) :: thetar = 0.0_wp !< angle for solar zenith angle calculation 4338 REAL(wp) :: thetasr = 0.0_wp !< angle for solar azimuth angle calculation 4339 REAL(wp) :: zgl = 0.0_wp !< calculated exposure by direct beam 4299 REAL(wp) :: thetasr = 0.0_wp !< angle for solar azimuth angle calculation 4300 REAL(wp) :: zgl = 0.0_wp !< calculated exposure by direct beam 4340 4301 REAL(wp) :: woz = 0.0_wp !< calculated exposure by diffuse radiation 4341 REAL(wp) :: wsp = 0.0_wp !< calculated exposure by direct beam 4342 4343 4344 CALL get_date_time( time_ since_reference_point,&4345 day_of_year = day_of_year,second_of_day = second_of_day )4302 REAL(wp) :: wsp = 0.0_wp !< calculated exposure by direct beam 4303 4304 4305 CALL get_date_time( time_SINce_reference_point, day_of_year = day_of_year, & 4306 second_of_day = second_of_day ) 4346 4307 dtor = pi / 180.0_wp 4347 4308 lat = latitude 4348 4309 lon = longitude 4349 4310 ! 4350 !-- calculation of js, necessary for calculation of equation of time (zgl) : 4351 js= 72.0_wp * ( REAL( day_of_year, KIND=wp ) + ( second_of_day / 86400.0_wp ) ) / 73.0_wp 4352 ! 4353 !-- calculation of equation of time (zgl): 4354 zgl = 0.0066_wp + 7.3525_wp * cos( ( js + 85.9_wp ) * dtor ) + 9.9359_wp * & 4355 cos( ( 2.0_wp * js + 108.9_wp ) * dtor ) + 0.3387_wp * cos( ( 3 * js + 105.2_wp ) * dtor ) 4356 ! 4357 !-- calculation of apparent solar time woz: 4358 woz = ( ( second_of_day / 3600.0_wp ) - ( 4.0_wp * ( 15.0_wp - lon ) ) / 60.0_wp ) + ( zgl / 60.0_wp ) 4359 ! 4360 !-- calculation of hour angle (wsp): 4311 !-- Calculation of js, necessary for calculation of equation of time (zgl) : 4312 js= 72.0_wp * ( REAL( day_of_year, KIND = wp ) + ( second_of_day / 86400.0_wp ) ) / 73.0_wp 4313 ! 4314 !-- Calculation of equation of time (zgl): 4315 zgl = 0.0066_wp + 7.3525_wp * COS( ( js + 85.9_wp ) * dtor ) + 9.9359_wp * & 4316 COS( ( 2.0_wp * js + 108.9_wp ) * dtor ) + 0.3387_wp * COS( ( 3 * js + 105.2_wp ) * dtor ) 4317 ! 4318 !-- Calculation of apparent solar time woz: 4319 woz = ( ( second_of_day / 3600.0_wp ) - ( 4.0_wp * ( 15.0_wp - lon ) ) / 60.0_wp ) + & 4320 ( zgl / 60.0_wp ) 4321 ! 4322 !-- Calculation of hour angle (wsp): 4361 4323 wsp = ( woz - 12.0_wp ) * 15.0_wp 4362 4324 ! 4363 !-- calculation of declination: 4364 declination = 0.3948_wp - 23.2559_wp * cos( ( js + 9.1_wp ) * dtor ) - & 4365 0.3915_wp * cos( ( 2.0_wp * js + 5.4_wp ) * dtor ) - 0.1764_wp * cos( ( 3.0_wp * js + 26.0_wp ) * dtor ) 4366 ! 4367 !-- calculation of solar zenith angle 4368 thetar = acos( sin( lat * dtor) * sin( declination * dtor ) + cos( wsp * dtor ) * & 4369 cos( lat * dtor ) * cos( declination * dtor ) ) 4370 thetasr = asin( sin( lat * dtor) * sin( declination * dtor ) + cos( wsp * dtor ) * & 4371 cos( lat * dtor ) * cos( declination * dtor ) ) 4325 !-- Calculation of declination: 4326 declination = 0.3948_wp - 23.2559_wp * COS( ( js + 9.1_wp ) * dtor ) - & 4327 0.3915_wp * COS( ( 2.0_wp * js + 5.4_wp ) * dtor ) - 0.1764_wp * & 4328 COS( ( 3.0_wp * js + 26.0_wp ) * dtor ) 4329 ! 4330 !-- Calculation of solar zenith angle 4331 thetar = ACOS( SIN( lat * dtor) * SIN( declination * dtor ) + COS( wsp * dtor ) * & 4332 COS( lat * dtor ) * COS( declination * dtor ) ) 4333 thetasr = ASIN( SIN( lat * dtor) * SIN( declination * dtor ) + COS( wsp * dtor ) * & 4334 COS( lat * dtor ) * COS( declination * dtor ) ) 4372 4335 sza = thetar / dtor 4373 4336 ! 4374 4337 !-- calculation of solar azimuth angle 4375 IF (woz <= 12.0_wp) alpha = pi - acos( ( sin(thetasr) * sin( lat * dtor ) -&4376 sin( declination * dtor ) ) / ( cos(thetasr) * cos( lat * dtor ) ) )4377 IF (woz > 12.0_wp) alpha = pi + acos( ( sin(thetasr) * sin( lat * dtor ) -&4378 sin( declination * dtor ) ) / ( cos(thetasr) * cos( lat * dtor ) ) )4338 IF (woz <= 12.0_wp) alpha = pi - ACOS( ( SIN(thetasr) * SIN( lat * dtor ) - & 4339 SIN( declination * dtor ) ) / ( COS(thetasr) * COS( lat * dtor ) ) ) 4340 IF (woz > 12.0_wp) alpha = pi + ACOS( ( SIN(thetasr) * SIN( lat * dtor ) - & 4341 SIN( declination * dtor ) ) / ( COS(thetasr) * COS( lat * dtor ) ) ) 4379 4342 saa = alpha / dtor 4380 4343 … … 4382 4345 4383 4346 4384 !------------------------------------------------------------------------------ !4347 !--------------------------------------------------------------------------------------------------! 4385 4348 ! Description: 4386 4349 ! ------------ 4387 4350 !> Module-specific routine for new module 4388 !-------------------------------------------------------------------------------------------------- -------------------!4351 !--------------------------------------------------------------------------------------------------! 4389 4352 SUBROUTINE bio_calculate_uv_exposure 4390 4353 4391 USE indices, 4392 ONLY: n ys, nyn, nxl, nxr4393 4394 4395 IMPLICIT NONE 4396 4354 USE indices, & 4355 ONLY: nxl, nxr, nyn, nys 4356 4357 4358 IMPLICIT NONE 4359 4397 4360 INTEGER(iwp) :: i !< loop index in x direction 4398 4361 INTEGER(iwp) :: j !< loop index in y direction … … 4400 4363 4401 4364 CALL uvem_solar_position 4402 4365 4403 4366 IF (sza >= 90) THEN 4404 4367 vitd3_exposure(:,:) = 0.0_wp 4405 4368 ELSE 4406 4369 4407 4370 DO ai = 0, 35 4408 4371 DO zi = 0, 9 4409 4372 projection_area_lookup_table(ai,zi) = uvem_projarea_f%var(clothing,zi,ai) 4410 4373 ENDDO 4411 4374 ENDDO 4412 4375 DO ai = 0, 35 4413 4376 DO zi = 0, 9 4414 4377 integration_array(ai,zi) = uvem_integration_f%var(zi,ai) 4415 4378 ENDDO 4416 4379 ENDDO 4417 4380 DO ai = 0, 2 4418 4381 DO zi = 0, 90 4419 4382 irradiance_lookup_table(ai,zi) = uvem_irradiance_f%var(zi,ai) 4420 4383 ENDDO 4421 4384 ENDDO … … 4427 4390 ENDDO 4428 4391 ENDDO 4429 4430 4431 4432 !-- rotate 3D-Model human to desired direction ----------------------------- 4392 4393 4394 !-- Rotate 3D-Model human to desired direction 4433 4395 projection_area_temp( 0:35,:) = projection_area_lookup_table 4434 projection_area_temp(36:71,:) = projection_area_lookup_table 4396 projection_area_temp(36:71,:) = projection_area_lookup_table 4435 4397 IF ( .NOT. turn_to_sun ) startpos_human = orientation_angle / 10.0_wp 4436 IF ( turn_to_sun ) startpos_human = saa / 10.0_wp 4398 IF ( turn_to_sun ) startpos_human = saa / 10.0_wp 4437 4399 DO ai = 0, 35 4438 4400 xfactor = ( startpos_human ) - INT( startpos_human ) 4439 4401 DO zi = 0, 9 4440 projection_area(ai,zi) = ( projection_area_temp( 36 - INT( startpos_human ) - 1 + ai , zi) * & 4441 ( xfactor ) ) & 4442 +( projection_area_temp( 36 - INT( startpos_human ) + ai , zi) * & 4443 ( 1.0_wp - xfactor ) ) 4402 projection_area(ai,zi) = ( projection_area_temp( 36 - & 4403 INT( startpos_human ) - 1 + ai , zi)& 4404 * ( xfactor ) ) & 4405 + ( projection_area_temp( 36 - & 4406 INT( startpos_human ) + ai , zi) & 4407 * ( 1.0_wp - xfactor ) ) 4444 4408 ENDDO 4445 ENDDO 4446 ! 4447 ! 4448 !-- interpolate to accurate Solar Zenith Angle ------------------4409 ENDDO 4410 ! 4411 ! 4412 !-- Interpolate to accurate Solar Zenith Angle 4449 4413 DO ai = 0, 35 4450 xfactor = ( sza)-INT(sza)4414 xfactor = ( sza )-INT( sza ) 4451 4415 DO zi = 0, 9 4452 radiance_array(ai,zi) = ( radiance_lookup_table(ai, zi, INT(sza) ) * ( 1.0_wp - xfactor) ) + & 4453 ( radiance_lookup_table(ai,zi,INT(sza) + 1) * xfactor ) 4416 radiance_array(ai,zi) = ( radiance_lookup_table(ai, zi, INT( sza ) ) * & 4417 ( 1.0_wp - xfactor) ) + & 4418 ( radiance_lookup_table(ai,zi,INT( sza ) + 1) * xfactor ) 4454 4419 ENDDO 4455 4420 ENDDO 4456 4421 DO iq = 0, 2 4457 irradiance(iq) = ( irradiance_lookup_table(iq, INT( sza) ) * ( 1.0_wp - xfactor)) +&4458 (irradiance_lookup_table(iq, INT(sza) + 1) * xfactor )4459 ENDDO 4460 ! 4461 !-- interpolate to accurate Solar Azimuth Angle ------------------4422 irradiance(iq) = ( irradiance_lookup_table(iq, INT( sza ) ) * ( 1.0_wp - xfactor)) + & 4423 ( irradiance_lookup_table(iq, INT( sza ) + 1) * xfactor ) 4424 ENDDO 4425 ! 4426 !-- Interpolate to accurate Solar Azimuth Angle 4462 4427 IF ( sun_in_south ) THEN 4463 4428 startpos_saa_float = 180.0_wp / 10.0_wp 4464 ELSE 4429 ELSE 4465 4430 startpos_saa_float = saa / 10.0_wp 4466 4431 ENDIF 4467 4432 radiance_array_temp( 0:35,:) = radiance_array 4468 4433 radiance_array_temp(36:71,:) = radiance_array 4469 xfactor = (startpos_saa_float) - INT( startpos_saa_float)4434 xfactor = (startpos_saa_float) - INT( startpos_saa_float ) 4470 4435 DO ai = 0, 35 4471 4436 DO zi = 0, 9 4472 radiance_array(ai,zi) = ( radiance_array_temp( 36 - INT( startpos_saa_float ) - 1 + ai , zi ) * & 4473 ( xfactor ) ) & 4474 + ( radiance_array_temp( 36 - INT( startpos_saa_float ) + ai , zi ) & 4475 * ( 1.0_wp - xfactor ) ) 4437 radiance_array(ai,zi) = ( radiance_array_temp(36 - & 4438 INT( startpos_saa_float ) - 1 + ai, zi) & 4439 * ( xfactor ) ) & 4440 + ( radiance_array_temp(36 - & 4441 INT( startpos_saa_float ) + ai, zi) & 4442 * ( 1.0_wp - xfactor ) ) 4476 4443 ENDDO 4477 ENDDO 4478 ! 4479 ! 4480 !-- calculate Projectionarea for direct beam -----------------------------'4444 ENDDO 4445 4446 ! 4447 !-- Calculate Projectionarea for direct beam 4481 4448 projection_area_direct_temp( 0:35,:) = projection_area 4482 4449 projection_area_direct_temp(36:71,:) = projection_area … … 4491 4458 ( projection_area_direct_temp( INT(startpos_saa_float) + 1,INT(sza/10.0_wp)+1) * & 4492 4459 ( xfactor ) * ( yfactor ) ) 4493 ! 4494 ! 4495 ! 4460 4461 4496 4462 DO i = nxl, nxr 4497 4463 DO j = nys, nyn 4498 ! 4499 ! !-- extract obstruction from IBSET-Integer_Array ------------------'4464 ! 4465 !-- Extract obstruction from IBSET-Integer_Array 4500 4466 IF (consider_obstructions ) THEN 4501 4467 obstruction_temp1 = building_obstruction_f%var_3d(:,j,i) 4502 4468 IF ( obstruction_temp1(0) /= 9 ) THEN 4503 DO pobi = 0, 44 4504 DO bi = 0, 7 4505 IF ( btest( obstruction_temp1(pobi), bi ) .EQV. .TRUE.) THEN4469 DO pobi = 0, 44 4470 DO bi = 0, 7 4471 IF ( BTEST( obstruction_temp1(pobi), bi ) .EQV. .TRUE.) THEN 4506 4472 obstruction_temp2( ( pobi * 8 ) + bi ) = 1 4507 4473 ELSE … … 4509 4475 ENDIF 4510 4476 ENDDO 4511 ENDDO 4512 DO zi = 0, 9 4477 ENDDO 4478 DO zi = 0, 9 4513 4479 obstruction(:,zi) = obstruction_temp2( zi * 36 :( zi * 36) + 35 ) 4514 4480 ENDDO 4515 ELSE 4481 ELSE 4516 4482 obstruction(:,:) = 0 4517 4483 ENDIF 4518 4484 ENDIF 4519 ! 4520 ! !-- calculated human exposure ------------------' 4521 diffuse_exposure = SUM( radiance_array * projection_area * integration_array * obstruction ) 4522 4523 obstruction_direct_beam = obstruction( nint(startpos_saa_float), nint( sza / 10.0_wp ) ) 4485 ! 4486 !-- Calculated human exposure 4487 diffuse_exposure = SUM( radiance_array * projection_area * integration_array * & 4488 obstruction ) 4489 4490 obstruction_direct_beam = obstruction( NINT( startpos_saa_float), & 4491 NINT( sza / 10.0_wp ) ) 4524 4492 IF (sza >= 89.99_wp) THEN 4525 4493 sza = 89.99999_wp 4526 4494 ENDIF 4527 ! 4528 !-- calculate direct normal irradiance (direct beam) ------------------'4529 direct_exposure = ( irradiance(1) / cos( pi * sza / 180.0_wp ) ) *&4530 projection_area_direct_beam * obstruction_direct_beam4531 4532 vitd3_exposure(j,i) = ( diffuse_exposure + direct_exposure ) / 1000.0_wp * 70.97_wp 4533 ! unit = international units vitamin D per second 4495 ! 4496 !-- Calculate direct normal irradiance (direct beam) 4497 direct_exposure = ( irradiance(1) / COS( pi * sza / 180.0_wp ) ) * & 4498 projection_area_direct_beam * obstruction_direct_beam 4499 4500 vitd3_exposure(j,i) = ( diffuse_exposure + direct_exposure ) / 1000.0_wp * 70.97_wp 4501 ! unit = international units vitamin D per second 4534 4502 ENDDO 4535 4503 ENDDO -
palm/trunk/SOURCE/time_integration_spinup.f90
r4457 r4540 1 1 !> @file time_integration_spinup.f90 2 !------------------------------------------------------------------------------ !2 !--------------------------------------------------------------------------------------------------! 3 3 ! This file is part of the PALM model system. 4 4 ! 5 ! PALM is free software: you can redistribute it and/or modify it under the 6 ! terms of the GNU General Public License as published by the Free Software 7 ! Foundation, either version 3 of the License, or (at your option) any later 8 ! version. 9 ! 10 ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY 11 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 ! A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 ! 14 ! You should have received a copy of the GNU General Public License along with 15 ! PALM. If not, see <http://www.gnu.org/licenses/>. 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. 8 ! 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. 12 ! 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/>. 16 15 ! 17 16 ! Copyright 1997-2020 Leibniz Universitaet Hannover 18 !------------------------------------------------------------------------------! 17 !--------------------------------------------------------------------------------------------------! 18 ! 19 19 ! 20 20 ! Current revisions: 21 ! ----------------- -21 ! ----------------- 22 22 ! 23 23 ! … … 25 25 ! ----------------- 26 26 ! $Id$ 27 ! use statement for exchange horiz added 28 ! 27 ! File re-formatted to follow the PALM coding standard 28 ! 29 ! 4457 2020-03-11 14:20:43Z raasch 30 ! Use statement for exchange horiz added 31 ! 29 32 ! 4444 2020-03-05 15:59:50Z raasch 30 ! bugfix: cpp-directives for serial mode added31 ! 33 ! Bugfix: cpp-directives for serial mode added 34 ! 32 35 ! 4360 2020-01-07 11:25:50Z suehring 33 36 ! Enable output of diagnostic quantities, e.g. 2-m temperature 34 ! 37 ! 35 38 ! 4227 2019-09-10 18:04:34Z gronemeier 36 ! implement new palm_date_time_mod37 ! 39 ! Implement new palm_date_time_mod 40 ! 38 41 ! 4223 2019-09-10 09:20:47Z gronemeier 39 42 ! Corrected "Former revisions" section 40 ! 43 ! 41 44 ! 4064 2019-07-01 05:33:33Z gronemeier 42 45 ! Moved call to radiation module out of intermediate time loop 43 ! 46 ! 44 47 ! 4023 2019-06-12 13:20:01Z maronga 45 48 ! Time stamps are now negative in run control output 46 ! 49 ! 47 50 ! 3885 2019-04-11 11:29:34Z kanani 48 ! Changes related to global restructuring of location messages and introduction 49 ! of additional debugmessages50 ! 51 ! Changes related to global restructuring of location messages and introduction of additional debug 52 ! messages 53 ! 51 54 ! 3766 2019-02-26 16:23:41Z raasch 52 ! unused variable removed53 ! 55 ! Unused variable removed 56 ! 54 57 ! 3719 2019-02-06 13:10:18Z kanani 55 ! Removed log_point(19,54,74,50,75), since they count together with same log 56 ! points in time_integration, impossible to separate the contributions.57 ! Instead, the entire spinup gets anindividual log_point in palm.f9058 ! 58 ! Removed log_point(19,54,74,50,75), since they count together with same log points in 59 ! time_integration, impossible to separate the contributions. Instead, the entire spinup gets an 60 ! individual log_point in palm.f90 61 ! 59 62 ! 3655 2019-01-07 16:51:22Z knoop 60 ! Removed call to calculation of near air (10 cm) potential temperature (now in 61 ! surface layer fluxes) 62 ! 63 ! Removed call to calculation of near air (10 cm) potential temperature (now in surface layer fluxes) 64 ! 63 65 ! 2296 2017-06-28 07:53:56Z maronga 64 66 ! Initial revision … … 67 69 ! Description: 68 70 ! ------------ 69 !> Integration in time of the non-atmospheric model components such as land 70 !> surface model and urban surface model71 !------------------------------------------------------------------------------ !71 !> Integration in time of the non-atmospheric model components such as land surface model and urban 72 !> surface model 73 !--------------------------------------------------------------------------------------------------! 72 74 SUBROUTINE time_integration_spinup 73 74 USE arrays_3d, & 75 ONLY: pt, pt_p, u, u_init, v, v_init 76 77 USE control_parameters, & 78 ONLY: averaging_interval_pr, calc_soil_moisture_during_spinup, & 79 constant_diffusion, constant_flux_layer, coupling_start_time, & 80 data_output_during_spinup, dopr_n, do_sum, & 81 dt_averaging_input_pr, dt_dopr, dt_dots, dt_do2d_xy, dt_do3d, & 82 dt_spinup, dt_3d, humidity, intermediate_timestep_count, & 83 intermediate_timestep_count_max, land_surface, & 84 simulated_time, simulated_time_chr, skip_time_dopr, & 85 skip_time_do2d_xy, skip_time_do3d, spinup_pt_amplitude, & 86 spinup_pt_mean, spinup_time, timestep_count, time_dopr, & 87 time_dopr_av, time_dots, time_do2d_xy, time_do3d, & 88 time_run_control, time_since_reference_point, urban_surface 89 90 USE cpulog, & 91 ONLY: cpu_log, log_point_s 92 93 USE diagnostic_output_quantities_mod, & 75 76 USE arrays_3d, & 77 ONLY: pt, & 78 pt_p, & 79 u, & 80 u_init, & 81 v, & 82 v_init 83 84 USE control_parameters, & 85 ONLY: averaging_interval_pr, & 86 calc_soil_moisture_during_spinup, & 87 constant_diffusion, & 88 constant_flux_layer, & 89 coupling_start_time, & 90 data_output_during_spinup, & 91 dopr_n, & 92 do_sum, & 93 dt_averaging_input_pr, & 94 dt_dopr, & 95 dt_dots, & 96 dt_do2d_xy, & 97 dt_do3d, & 98 dt_spinup, & 99 dt_3d, & 100 humidity, & 101 intermediate_timestep_count, & 102 intermediate_timestep_count_max, & 103 land_surface, & 104 simulated_time, & 105 simulated_time_chr, & 106 skip_time_dopr, & 107 skip_time_do2d_xy, & 108 skip_time_do3d, & 109 spinup_pt_amplitude, & 110 spinup_pt_mean, & 111 spinup_time, & 112 timestep_count, & 113 time_dopr, & 114 time_dopr_av, & 115 time_dots, & 116 time_do2d_xy, & 117 time_do3d, & 118 time_run_control, & 119 time_since_reference_point, & 120 urban_surface 121 122 USE cpulog, & 123 ONLY: cpu_log, & 124 log_point_s 125 126 USE diagnostic_output_quantities_mod, & 94 127 ONLY: doq_calculate 95 128 96 USE exchange_horiz_mod, &129 USE exchange_horiz_mod, & 97 130 ONLY: exchange_horiz 98 131 99 USE indices, & 100 ONLY: nbgp, nzb, nzt, nysg, nyng, nxlg, nxrg 101 102 USE land_surface_model_mod, & 103 ONLY: lsm_energy_balance, lsm_soil_model, lsm_swap_timelevel 132 USE indices, & 133 ONLY: nbgp, & 134 nzb, & 135 nzt, & 136 nysg, & 137 nyng, & 138 nxlg, & 139 nxrg 140 141 USE land_surface_model_mod, & 142 ONLY: lsm_energy_balance, & 143 lsm_soil_model, & 144 lsm_swap_timelevel 104 145 105 146 USE pegrid 106 147 107 148 #if defined( __parallel ) 108 USE pmc_interface, &149 USE pmc_interface, & 109 150 ONLY: nested_run 110 151 #endif … … 112 153 USE kinds 113 154 114 USE palm_date_time_mod, & 115 ONLY: get_date_time, seconds_per_hour 116 117 USE radiation_model_mod, & 118 ONLY: force_radiation_call, radiation, radiation_control, & 119 radiation_interaction, radiation_interactions, time_radiation 120 121 USE statistics, & 155 USE palm_date_time_mod, & 156 ONLY: get_date_time, & 157 seconds_per_hour 158 159 USE radiation_model_mod, & 160 ONLY: force_radiation_call, & 161 radiation, & 162 radiation_control, & 163 radiation_interaction, & 164 radiation_interactions, & 165 time_radiation 166 167 USE statistics, & 122 168 ONLY: flow_statistics_called 123 169 124 USE surface_layer_fluxes_mod, &170 USE surface_layer_fluxes_mod, & 125 171 ONLY: surface_layer_fluxes 126 172 127 USE surface_mod, & 128 ONLY : surf_lsm_h, surf_lsm_v, surf_usm_h, & 173 USE surface_mod, & 174 ONLY : surf_lsm_h, & 175 surf_lsm_v, surf_usm_h, & 129 176 surf_usm_v 130 177 131 USE urban_surface_mod, & 132 ONLY: usm_material_heat_model, usm_material_model, & 133 usm_surface_energy_balance, usm_swap_timelevel, & 178 USE urban_surface_mod, & 179 ONLY: usm_material_heat_model, & 180 usm_material_model, & 181 usm_surface_energy_balance, & 182 usm_swap_timelevel, & 134 183 usm_green_heat_model 135 184 … … 139 188 IMPLICIT NONE 140 189 141 CHARACTER (LEN=9) :: time_to_string !< 142 143 144 CHARACTER (LEN=1) :: sign_chr !< String containing '-' or ' ' 145 CHARACTER (LEN=9) :: time_since_reference_point_chr !< time since reference point, i.e., negative during spinup 146 147 INTEGER(iwp) :: i !< running index 148 INTEGER(iwp) :: j !< running index 149 INTEGER(iwp) :: k !< running index 150 INTEGER(iwp) :: l !< running index 151 INTEGER(iwp) :: m !< running index 152 153 INTEGER(iwp) :: current_timestep_number_spinup = 0 !< number if timestep during spinup 154 INTEGER(iwp) :: day_of_year !< day of the year 155 156 LOGICAL :: run_control_header_spinup = .FALSE. !< flag parameter for steering whether the header information must be output 157 190 CHARACTER(LEN=1) :: sign_chr !< String containing '-' or ' ' 191 CHARACTER(LEN=9) :: time_since_reference_point_chr !< time since reference point, i.e., negative during spinup 192 CHARACTER(LEN=9) :: time_to_string !< 193 194 195 INTEGER(iwp) :: current_timestep_number_spinup = 0 !< number if timestep during spinup 196 INTEGER(iwp) :: day_of_year !< day of the year 197 198 INTEGER(iwp) :: i !< running index 199 INTEGER(iwp) :: j !< running index 200 INTEGER(iwp) :: k !< running index 201 INTEGER(iwp) :: l !< running index 202 INTEGER(iwp) :: m !< running index 203 204 205 LOGICAL :: run_control_header_spinup = .FALSE. !< flag parameter for steering whether the header information must be output 206 207 208 REAL(wp) :: dt_save !< temporary storage for time step 158 209 REAL(wp) :: pt_spinup !< temporary storage of temperature 159 REAL(wp) :: dt_save !< temporary storage for time step160 210 REAL(wp) :: second_of_day !< second of the day 161 211 162 212 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: pt_save !< temporary storage of temperature 163 213 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: u_save !< temporary storage of u wind component … … 171 221 ALLOCATE( v_save(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 172 222 173 CALL exchange_horiz( pt, nbgp ) 174 CALL exchange_horiz( u, nbgp ) 175 CALL exchange_horiz( v, nbgp ) 176 223 CALL exchange_horiz( pt, nbgp ) 224 CALL exchange_horiz( u, nbgp ) 225 CALL exchange_horiz( v, nbgp ) 226 177 227 pt_save = pt 178 228 u_save = u … … 180 230 181 231 ! 182 !-- Set the same wall-adjacent velocity to all grid points. The sign of the 183 !-- original velocity field must be preserved because the surface schemes crash 184 !-- otherwise. The precise reason is still unknown. A minimum velocity of 0.1 185 !-- m/s is used to maintain turbulent transfer at the surface. 232 !-- Set the same wall-adjacent velocity to all grid points. The sign of the original velocity field 233 !-- must be preserved because the surface schemes crash otherwise. The precise reason is still 234 !-- unknown. A minimum velocity of 0.1 m/s is used to maintain turbulent transfer at the surface. 186 235 IF ( land_surface ) THEN 187 236 DO m = 1, surf_lsm_h%ns 188 i = surf_lsm_h%i(m) 237 i = surf_lsm_h%i(m) 189 238 j = surf_lsm_h%j(m) 190 239 k = surf_lsm_h%k(m) 191 u(k,j,i) = SIGN( 1.0_wp,u_init(k)) * MAX( ABS( u_init(k) ),0.1_wp)192 v(k,j,i) = SIGN( 1.0_wp,v_init(k)) * MAX( ABS( v_init(k) ),0.1_wp)240 u(k,j,i) = SIGN( 1.0_wp, u_init(k) ) * MAX( ABS( u_init(k) ), 0.1_wp) 241 v(k,j,i) = SIGN( 1.0_wp, v_init(k) ) * MAX( ABS( v_init(k) ), 0.1_wp) 193 242 ENDDO 194 243 195 244 DO l = 0, 3 196 245 DO m = 1, surf_lsm_v(l)%ns 197 i = surf_lsm_v(l)%i(m) 246 i = surf_lsm_v(l)%i(m) 198 247 j = surf_lsm_v(l)%j(m) 199 248 k = surf_lsm_v(l)%k(m) 200 u(k,j,i) = SIGN( 1.0_wp,u_init(k)) * MAX( ABS( u_init(k) ),0.1_wp)201 v(k,j,i) = SIGN( 1.0_wp,v_init(k)) * MAX( ABS( v_init(k) ),0.1_wp)249 u(k,j,i) = SIGN( 1.0_wp, u_init(k) ) * MAX( ABS( u_init(k) ), 0.1_wp) 250 v(k,j,i) = SIGN( 1.0_wp, v_init(k) ) * MAX( ABS( v_init(k) ), 0.1_wp) 202 251 ENDDO 203 252 ENDDO … … 206 255 IF ( urban_surface ) THEN 207 256 DO m = 1, surf_usm_h%ns 208 i = surf_usm_h%i(m) 257 i = surf_usm_h%i(m) 209 258 j = surf_usm_h%j(m) 210 259 k = surf_usm_h%k(m) 211 u(k,j,i) = SIGN( 1.0_wp,u_init(k)) * MAX( ABS( u_init(k) ),0.1_wp)212 v(k,j,i) = SIGN( 1.0_wp,v_init(k)) * MAX( ABS( v_init(k) ),0.1_wp)260 u(k,j,i) = SIGN( 1.0_wp, u_init(k) ) * MAX( ABS( u_init(k) ), 0.1_wp) 261 v(k,j,i) = SIGN( 1.0_wp, v_init(k) ) * MAX( ABS( v_init(k) ), 0.1_wp) 213 262 ENDDO 214 263 215 264 DO l = 0, 3 216 265 DO m = 1, surf_usm_v(l)%ns 217 i = surf_usm_v(l)%i(m) 266 i = surf_usm_v(l)%i(m) 218 267 j = surf_usm_v(l)%j(m) 219 268 k = surf_usm_v(l)%k(m) 220 u(k,j,i) = SIGN( 1.0_wp,u_init(k)) * MAX( ABS( u_init(k) ),0.1_wp)221 v(k,j,i) = SIGN( 1.0_wp,v_init(k)) * MAX( ABS( v_init(k) ),0.1_wp)269 u(k,j,i) = SIGN( 1.0_wp, u_init(k) ) * MAX( ABS( u_init(k) ), 0.1_wp) 270 v(k,j,i) = SIGN( 1.0_wp, v_init(k) ) * MAX( ABS( v_init(k) ), 0.1_wp) 222 271 ENDDO 223 272 ENDDO 224 273 ENDIF 225 274 226 CALL exchange_horiz( u, 227 CALL exchange_horiz( v, 275 CALL exchange_horiz( u, nbgp ) 276 CALL exchange_horiz( v, nbgp ) 228 277 229 278 dt_save = dt_3d … … 236 285 237 286 CALL cpu_log( log_point_s(15), 'timesteps spinup', 'start' ) 238 287 239 288 ! 240 289 !-- Start of intermediate step loop 241 290 intermediate_timestep_count = 0 242 DO WHILE ( intermediate_timestep_count < & 243 intermediate_timestep_count_max ) 291 DO WHILE ( intermediate_timestep_count < intermediate_timestep_count_max ) 244 292 245 293 intermediate_timestep_count = intermediate_timestep_count + 1 246 294 247 295 ! 248 !-- Set the steering factors for the prognostic equations which depend 249 !-- on the timestep scheme 296 !-- Set the steering factors for the prognostic equations which depend on the timestep scheme 250 297 CALL timestep_scheme_steering 251 298 252 299 253 300 ! 254 !-- Estimate a near-surface air temperature based on the position of the 255 !-- sun and user input about mean temperature and amplitude. The time is 256 !-- shifted by one hour to simulate a lag between air temperature and 257 !-- incoming radiation 258 CALL get_date_time( simulated_time - spinup_time - seconds_per_hour, & 259 day_of_year=day_of_year, & 260 second_of_day=second_of_day ) 261 262 pt_spinup = spinup_pt_mean + spinup_pt_amplitude & 263 * solar_angle(day_of_year, second_of_day) 264 265 ! 266 !-- Map air temperature to all grid points in the vicinity of a surface 267 !-- element 301 !-- Estimate a near-surface air temperature based on the position of the sun and user input 302 !-- about mean temperature and amplitude. The time is shifted by one hour to simulate a lag 303 !-- between air temperature and incoming radiation. 304 CALL get_date_time( simulated_time - spinup_time - seconds_per_hour, & 305 day_of_year = day_of_year, second_of_day = second_of_day ) 306 307 pt_spinup = spinup_pt_mean + spinup_pt_amplitude * & 308 solar_angle( day_of_year, second_of_day ) 309 310 ! 311 !-- Map air temperature to all grid points in the vicinity of a surface element 268 312 IF ( land_surface ) THEN 269 313 DO m = 1, surf_lsm_h%ns 270 i = surf_lsm_h%i(m) 314 i = surf_lsm_h%i(m) 271 315 j = surf_lsm_h%j(m) 272 316 k = surf_lsm_h%k(m) … … 276 320 DO l = 0, 3 277 321 DO m = 1, surf_lsm_v(l)%ns 278 i = surf_lsm_v(l)%i(m) 322 i = surf_lsm_v(l)%i(m) 279 323 j = surf_lsm_v(l)%j(m) 280 324 k = surf_lsm_v(l)%k(m) … … 286 330 IF ( urban_surface ) THEN 287 331 DO m = 1, surf_usm_h%ns 288 i = surf_usm_h%i(m) 332 i = surf_usm_h%i(m) 289 333 j = surf_usm_h%j(m) 290 334 k = surf_usm_h%k(m) … … 297 341 DO l = 0, 3 298 342 DO m = 1, surf_usm_v(l)%ns 299 i = surf_usm_v(l)%i(m) 343 i = surf_usm_v(l)%i(m) 300 344 j = surf_usm_v(l)%j(m) 301 345 k = surf_usm_v(l)%k(m) … … 308 352 ENDIF 309 353 310 CALL exchange_horiz( pt, nbgp )354 CALL exchange_horiz( pt, nbgp ) 311 355 312 356 … … 314 358 !-- Swap the time levels in preparation for the next time step. 315 359 timestep_count = timestep_count + 1 316 360 317 361 IF ( land_surface ) THEN 318 362 CALL lsm_swap_timelevel ( 0 ) … … 324 368 325 369 IF ( land_surface ) THEN 326 CALL lsm_swap_timelevel ( MOD( timestep_count, 2 ) )370 CALL lsm_swap_timelevel ( MOD( timestep_count, 2 ) ) 327 371 ENDIF 328 372 329 373 IF ( urban_surface ) THEN 330 CALL usm_swap_timelevel ( MOD( timestep_count, 2 ) )331 ENDIF 332 333 ! 334 !-- If required, compute virtual potential temperature 335 IF ( humidity ) THEN 336 CALL compute_vpt 337 ENDIF 374 CALL usm_swap_timelevel ( MOD( timestep_count, 2 ) ) 375 ENDIF 376 377 ! 378 !-- If required, compute virtual potential temperature 379 IF ( humidity ) THEN 380 CALL compute_vpt 381 ENDIF 338 382 339 383 ! … … 342 386 343 387 ! 344 !-- First the vertical (and horizontal) fluxes in the surface 345 !-- (constant flux) layer arecomputed388 !-- First the vertical (and horizontal) fluxes in the surface (constant flux) layer are 389 !-- computed 346 390 IF ( constant_flux_layer ) THEN 347 391 CALL surface_layer_fluxes … … 349 393 350 394 ! 351 !-- If required, solve the energy balance for the surface and run soil 352 !-- model. Call for horizontal as well as vertical surfaces.353 !-- The prognostic equation for soil moisure isswitched off395 !-- If required, solve the energy balance for the surface and run soil model. Call for 396 !-- horizontal as well as vertical surfaces. The prognostic equation for soil moisure is 397 !-- switched off 354 398 IF ( land_surface ) THEN 355 399 … … 378 422 379 423 ! 380 !-- If required, solve the energy balance for urban surfaces and run 381 !-- the material heat model 424 !-- If required, solve the energy balance for urban surfaces and run the material heat model 382 425 IF (urban_surface) THEN 383 426 … … 417 460 !-- Increase simulation time and output times 418 461 current_timestep_number_spinup = current_timestep_number_spinup + 1 419 simulated_time = simulated_time + dt_3d420 simulated_time_chr = time_to_string( simulated_time )421 time_since_reference_point = simulated_time - coupling_start_time422 time_since_reference_point_chr = time_to_string( ABS( time_since_reference_point) )423 462 simulated_time = simulated_time + dt_3d 463 simulated_time_chr = time_to_string( simulated_time ) 464 time_since_reference_point = simulated_time - coupling_start_time 465 time_since_reference_point_chr = time_to_string( ABS( time_since_reference_point ) ) 466 424 467 IF ( time_since_reference_point < 0.0_wp ) THEN 425 468 sign_chr = '-' … … 427 470 sign_chr = ' ' 428 471 ENDIF 429 430 472 473 431 474 IF ( data_output_during_spinup ) THEN 432 475 IF ( simulated_time >= skip_time_do2d_xy ) THEN 433 time_do2d_xy 476 time_do2d_xy = time_do2d_xy + dt_3d 434 477 ENDIF 435 478 IF ( simulated_time >= skip_time_do3d ) THEN 436 time_do3d 437 ENDIF 438 time_dots = time_dots + dt_3d479 time_do3d = time_do3d + dt_3d 480 ENDIF 481 time_dots = time_dots + dt_3d 439 482 IF ( simulated_time >= skip_time_dopr ) THEN 440 time_dopr = time_dopr + dt_3d441 ENDIF 442 time_run_control = time_run_control + dt_3d483 time_dopr = time_dopr + dt_3d 484 ENDIF 485 time_run_control = time_run_control + dt_3d 443 486 444 487 ! 445 488 !-- Carry out statistical analysis and output at the requested output times. 446 !-- The MOD function is used for calculating the output time counters (like 447 !-- time_dopr) in order to regard a possible decrease of the output time 448 !-- interval in case of restart runs 449 450 ! 451 !-- Set a flag indicating that so far no statistics have been created 452 !-- for this time step 489 !-- The MOD function is used for calculating the output time counters (like time_dopr) in 490 !-- order to regard a possible decrease of the output time interval in case of restart runs. 491 492 ! 493 !-- Set a flag indicating that so far no statistics have been created for this time step 453 494 flow_statistics_called = .FALSE. 454 495 455 496 ! 456 497 !-- If required, call flow_statistics for averaging in time 457 IF ( averaging_interval_pr /= 0.0_wp .AND. & 458 ( dt_dopr - time_dopr ) <= averaging_interval_pr .AND. & 459 simulated_time >= skip_time_dopr ) THEN 498 IF ( averaging_interval_pr /= 0.0_wp .AND. & 499 ( dt_dopr - time_dopr ) <= averaging_interval_pr .AND. & 500 simulated_time >= skip_time_dopr ) & 501 THEN 460 502 time_dopr_av = time_dopr_av + dt_3d 461 503 IF ( time_dopr_av >= dt_averaging_input_pr ) THEN 462 504 do_sum = .TRUE. 463 time_dopr_av = MOD( time_dopr_av, & 464 MAX( dt_averaging_input_pr, dt_3d ) ) 505 time_dopr_av = MOD( time_dopr_av, MAX( dt_averaging_input_pr, dt_3d ) ) 465 506 ENDIF 466 507 ENDIF … … 472 513 IF ( dopr_n /= 0 ) CALL data_output_profiles 473 514 time_dopr = MOD( time_dopr, MAX( dt_dopr, dt_3d ) ) 474 time_dopr_av = 0.0_wp ! due to averaging (see above)515 time_dopr_av = 0.0_wp ! Due to averaging (see above) 475 516 ENDIF 476 517 … … 502 543 503 544 ! 504 !-- Computation and output of run control parameters. 505 !-- This is also done whenever perturbations have been imposed 506 ! IF ( time_run_control >= dt_run_control .OR. & 507 ! timestep_scheme(1:5) /= 'runge' .OR. disturbance_created ) & 508 ! THEN 545 !-- Computation and output of run control parameters. This is also done whenever perturbations 546 !-- have been imposed 547 ! IF ( time_run_control >= dt_run_control .OR. & 548 ! timestep_scheme(1:5) /= 'runge' .OR. disturbance_created ) THEN 509 549 ! CALL run_control 510 550 ! IF ( time_run_control >= dt_run_control ) THEN 511 ! time_run_control = MOD( time_run_control, & 512 ! MAX( dt_run_control, dt_3d ) ) 551 ! time_run_control = MOD( time_run_control, MAX( dt_run_control, dt_3d ) ) 513 552 ! ENDIF 514 553 ! ENDIF … … 529 568 ! 530 569 !-- Write some general information about the spinup in run control file 531 WRITE ( 15, 101 ) current_timestep_number_spinup, sign_chr, time_since_reference_point_chr, dt_3d, pt_spinup 570 WRITE ( 15, 101 ) current_timestep_number_spinup, sign_chr, & 571 time_since_reference_point_chr, dt_3d, pt_spinup 532 572 ! 533 573 !-- Write buffer contents to disc immediately … … 537 577 538 578 539 ENDDO ! time loop579 ENDDO ! Time loop 540 580 541 581 ! … … 563 603 ! 564 604 !-- Formats 565 100 FORMAT (///'Spinup control output:'/ & 566 '---------------------------------'// & 567 'ITER. HH:MM:SS DT PT(z_MO)'/ & 568 '---------------------------------') 605 100 FORMAT (///'Spinup control output:---------------------------------'// & 606 'ITER. HH:MM:SS DT PT(z_MO)---------------------------------') 569 607 101 FORMAT (I5,2X,A1,A9,1X,F6.2,3X,F6.2,2X,F6.2) 570 608 … … 572 610 573 611 ! 574 !-- Returns the cosine of the solar zenith angle at a given time. This routine 575 !-- is similar to that for calculation zenith (see radiation_model_mod.f90) 576 !> @todo Load function calc_zenith of radiation model instead of 577 !> rewrite the function here. 578 FUNCTION solar_angle( day_of_year, second_of_day ) 579 580 USE basic_constants_and_equations_mod, & 612 !-- Returns the cosine of the solar zenith angle at a given time. This routine is similar to that 613 !-- for calculation zenith (see radiation_model_mod.f90) 614 !> @todo Load function calc_zenith of radiation model instead of rewrite the function here. 615 FUNCTION solar_angle( day_of_year, second_of_day ) 616 617 USE basic_constants_and_equations_mod, & 581 618 ONLY: pi 582 619 583 620 USE kinds 584 621 585 USE radiation_model_mod, & 586 ONLY: decl_1, decl_2, decl_3, lat, lon 587 588 IMPLICIT NONE 622 USE radiation_model_mod, & 623 ONLY: decl_1, & 624 decl_2, & 625 decl_3, & 626 lat, & 627 lon 628 629 IMPLICIT NONE 589 630 590 631 591 632 INTEGER(iwp), INTENT(IN) :: day_of_year !< day of the year 592 633 593 REAL(wp) :: declination 594 REAL(wp) :: hour_angle 595 REAL(wp), INTENT(IN) :: second_of_day 596 REAL(wp) :: solar_angle 597 ! 598 !-- Calculate solar declination and hour angle 599 declination = ASIN( decl_1 * SIN( decl_2 * REAL(day_of_year, KIND=wp) - decl_3) )600 hour_angle = 2.0_wp * pi * ( second_of_day / 86400.0_wp) + lon - pi634 REAL(wp) :: declination !< solar declination angle 635 REAL(wp) :: hour_angle !< solar hour angle 636 REAL(wp), INTENT(IN) :: second_of_day !< current time of the day in UTC 637 REAL(wp) :: solar_angle !< cosine of the solar zenith angle 638 ! 639 !-- Calculate solar declination and hour angle 640 declination = ASIN( decl_1 * SIN( decl_2 * REAL( day_of_year, KIND = wp) - decl_3 ) ) 641 hour_angle = 2.0_wp * pi * ( second_of_day / 86400.0_wp ) + lon - pi 601 642 602 643 ! 603 644 !-- Calculate cosine of solar zenith angle 604 solar_angle = SIN( lat) * SIN(declination) + COS(lat) * COS(declination)&605 * COS(hour_angle)645 solar_angle = SIN( lat ) * SIN( declination ) + COS( lat ) * COS( declination ) * & 646 COS( hour_angle ) 606 647 607 648 END FUNCTION solar_angle -
palm/trunk/SOURCE/time_to_string.f90
r4360 r4540 1 1 !> @file time_to_string.f90 2 !------------------------------------------------------------------------------ !2 !--------------------------------------------------------------------------------------------------! 3 3 ! This file is part of the PALM model system. 4 4 ! 5 ! PALM is free software: you can redistribute it and/or modify it under the 6 ! terms of the GNU General Public License as published by the Free Software 7 ! Foundation, either version 3 of the License, or (at your option) any later 8 ! version. 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. 9 8 ! 10 ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY 11 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR12 ! A PARTICULAR PURPOSE. See the GNU GeneralPublic License for more details.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. 13 12 ! 14 ! You should have received a copy of the GNU General Public License along with 15 ! PALM. If not, see<http://www.gnu.org/licenses/>.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/>. 16 15 ! 17 16 ! Copyright 1997-2020 Leibniz Universitaet Hannover 18 !------------------------------------------------------------------------------! 17 !--------------------------------------------------------------------------------------------------! 18 ! 19 19 ! 20 20 ! Current revisions: … … 25 25 ! ----------------- 26 26 ! $Id$ 27 ! File re-formatted to follow the PALM coding standard 28 ! 29 ! 30 ! 4360 2020-01-07 11:25:50Z suehring 27 31 ! Corrected "Former revisions" section 28 ! 32 ! 29 33 ! 3655 2019-01-07 16:51:22Z knoop 30 34 ! Corrected "Former revisions" section … … 37 41 ! ------------ 38 42 !> Transforming the time from real to character-string hh:mm:ss 39 !------------------------------------------------------------------------------ !43 !--------------------------------------------------------------------------------------------------! 40 44 FUNCTION time_to_string( time ) 41 45 42 46 43 47 USE kinds … … 45 49 IMPLICIT NONE 46 50 47 CHARACTER (LEN=9) :: time_to_string !<51 CHARACTER(LEN=9) :: time_to_string !< 48 52 49 INTEGER(iwp) :: hours !<50 INTEGER(iwp) :: minutes !<51 INTEGER(iwp) :: seconds !<53 INTEGER(iwp) :: hours !< 54 INTEGER(iwp) :: minutes !< 55 INTEGER(iwp) :: seconds !< 52 56 53 REAL(wp) :: rest_time !<54 REAL(wp) :: time !<57 REAL(wp) :: rest_time !< 58 REAL(wp) :: time !< 55 59 56 60 ! … … 64 68 !-- Build the string 65 69 IF ( hours < 100 ) THEN 66 WRITE (time_to_string,'(I2.2,'':'',I2.2,'':'',I2.2)') hours, minutes, & 67 seconds 70 WRITE (time_to_string,'(I2.2,'':'',I2.2,'':'',I2.2)') hours, minutes, seconds 68 71 ELSE 69 WRITE (time_to_string,'(I3.3,'':'',I2.2,'':'',I2.2)') hours, minutes, & 70 seconds 72 WRITE (time_to_string,'(I3.3,'':'',I2.2,'':'',I2.2)') hours, minutes, seconds 71 73 ENDIF 72 74 -
palm/trunk/SOURCE/timestep.f90
r4444 r4540 1 1 !> @file timestep.f90 2 !------------------------------------------------------------------------------ !2 !--------------------------------------------------------------------------------------------------! 3 3 ! This file is part of the PALM model system. 4 4 ! 5 ! PALM is free software: you can redistribute it and/or modify it under the 6 ! terms of the GNU General Public License as published by the Free Software 7 ! Foundation, either version 3 of the License, or (at your option) any later 8 ! version. 9 ! 10 ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY 11 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 ! A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 ! 14 ! You should have received a copy of the GNU General Public License along with 15 ! PALM. If not, see <http://www.gnu.org/licenses/>. 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. 8 ! 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. 12 ! 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/>. 16 15 ! 17 16 ! Copyright 1997-2020 Leibniz Universitaet Hannover 18 !------------------------------------------------------------------------------! 17 !--------------------------------------------------------------------------------------------------! 18 ! 19 19 ! 20 20 ! Current revisions: 21 ! ----------------- -21 ! ----------------- 22 22 ! 23 23 ! … … 25 25 ! ----------------- 26 26 ! $Id$ 27 ! bugfix: cpp-directives for serial mode added 28 ! 27 ! File re-formatted to follow the PALM coding standard 28 ! 29 ! 30 ! 4444 2020-03-05 15:59:50Z raasch 31 ! Bugfix: cpp-directives for serial mode added 32 ! 29 33 ! 4360 2020-01-07 11:25:50Z suehring 30 34 ! Added missing OpenMP directives 31 ! 35 ! 32 36 ! 4233 2019-09-20 09:55:54Z knoop 33 37 ! OpenACC data update host removed 34 ! 38 ! 35 39 ! 4182 2019-08-22 15:20:23Z scharf 36 40 ! Corrected "Former revisions" section 37 ! 41 ! 38 42 ! 4101 2019-07-17 15:14:26Z gronemeier 39 ! - consider 2*Km within diffusion criterion as Km is considered twice within 40 ! the diffusion of e, 41 ! - in RANS mode, instead of considering each wind component individually use 42 ! the wind speed of 3d wind vector in CFL criterion 43 ! - do not limit the increase of dt based on its previous value in RANS mode 43 ! - Consider 2*Km within diffusion criterion as Km is considered twice within the diffusion of e, 44 ! - in RANS mode, instead of considering each wind component individually use the wind speed of 3d 45 ! wind vector in CFL criterion 46 ! - Do not limit the increase of dt based on its previous value in RANS mode 44 47 ! 45 48 ! 3658 2019-01-07 20:28:54Z knoop … … 53 56 ! ------------ 54 57 !> Compute the time step under consideration of the FCL and diffusion criterion. 55 !------------------------------------------------------------------------------ !58 !--------------------------------------------------------------------------------------------------! 56 59 SUBROUTINE timestep 57 58 59 USE arrays_3d, & 60 ONLY: dzu, dzw, kh, km, u, u_stokes_zu, v, v_stokes_zu, w 61 62 USE control_parameters, & 63 ONLY: cfl_factor, dt_3d, dt_fixed, dt_max, galilei_transformation, & 64 message_string, rans_mode, stop_dt, timestep_reason, u_gtrans, & 65 use_ug_for_galilei_tr, v_gtrans 66 67 #if defined( __parallel ) 68 USE control_parameters, & 69 ONLY: coupling_mode, terminate_coupled, terminate_coupled_remote 70 #endif 71 72 USE cpulog, & 73 ONLY: cpu_log, log_point 74 75 USE grid_variables, & 76 ONLY: dx, dx2, dy, dy2 77 78 USE indices, & 79 ONLY: nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt 60 61 62 USE arrays_3d, & 63 ONLY: dzu, & 64 dzw, & 65 kh, & 66 km, & 67 u, & 68 u_stokes_zu, & 69 v, & 70 v_stokes_zu, & 71 w 72 73 USE control_parameters, & 74 ONLY: cfl_factor, & 75 dt_3d, & 76 dt_fixed, & 77 dt_max, & 78 galilei_transformation, & 79 message_string, & 80 rans_mode, & 81 stop_dt, & 82 timestep_reason, & 83 u_gtrans, & 84 use_ug_for_galilei_tr, & 85 v_gtrans 86 87 #if defined( __parallel ) 88 USE control_parameters, & 89 ONLY: coupling_mode, & 90 terminate_coupled, & 91 terminate_coupled_remote 92 #endif 93 94 USE cpulog, & 95 ONLY: cpu_log, & 96 log_point 97 98 USE grid_variables, & 99 ONLY: dx, & 100 dx2, & 101 dy, & 102 dy2 103 104 USE indices, & 105 ONLY: nxl, & 106 nxlg, & 107 nxr, & 108 nxrg, & 109 nyn, & 110 nyng, & 111 nys, & 112 nysg, & 113 nzb, & 114 nzt 80 115 81 116 USE interfaces … … 83 118 USE kinds 84 119 85 USE bulk_cloud_model_mod, &120 USE bulk_cloud_model_mod, & 86 121 ONLY: dt_precipitation 87 122 88 123 USE pegrid 89 124 90 USE pmc_interface, &125 USE pmc_interface, & 91 126 ONLY: nested_run 92 127 93 USE statistics, & 94 ONLY: flow_statistics_called, hom, u_max, u_max_ijk, v_max, v_max_ijk,& 95 w_max, w_max_ijk 96 97 #if defined( __parallel ) 98 USE vertical_nesting_mod, & 99 ONLY: vnested, vnest_timestep_sync 128 USE statistics, & 129 ONLY: flow_statistics_called, & 130 hom, & 131 u_max, & 132 u_max_ijk, & 133 v_max, & 134 v_max_ijk, & 135 w_max, & 136 w_max_ijk 137 138 #if defined( __parallel ) 139 USE vertical_nesting_mod, & 140 ONLY: vnested, & 141 vnest_timestep_sync 100 142 #endif 101 143 102 144 IMPLICIT NONE 103 145 104 INTEGER(iwp) :: i !<105 INTEGER(iwp) :: j !<106 INTEGER(iwp) :: k !<146 INTEGER(iwp) :: i !< 147 INTEGER(iwp) :: j !< 148 INTEGER(iwp) :: k !< 107 149 INTEGER(iwp) :: km_max_ijk(3) = -1 !< index values (i,j,k) of location where km_max occurs 108 150 INTEGER(iwp) :: kh_max_ijk(3) = -1 !< index values (i,j,k) of location where kh_max occurs 109 151 110 LOGICAL :: stop_dt_local !< local switch for controlling the time stepping111 112 REAL(wp) :: div !<113 REAL(wp) :: dt_diff !<114 REAL(wp) :: dt_diff_l !<115 REAL(wp) :: dt_u !<116 REAL(wp) :: dt_u_l !<117 REAL(wp) :: dt_v !<118 REAL(wp) :: dt_v_l !<119 REAL(wp) :: dt_w !<120 REAL(wp) :: dt_w_l !<121 REAL(wp) :: km_max 122 REAL(wp) :: kh_max 123 REAL(wp) :: u_gtrans_l !<124 REAL(wp) :: v_gtrans_l !<125 126 REAL(wp), DIMENSION(2) :: uv_gtrans_l !<127 #if defined( __parallel ) 128 REAL(wp), DIMENSION(2) :: uv_gtrans !<129 REAL(wp), DIMENSION(3) :: reduce !<130 REAL(wp), DIMENSION(3) :: reduce_l !<131 #endif 132 REAL(wp), DIMENSION(nzb+1:nzt) :: dxyz2_min !<152 LOGICAL :: stop_dt_local !< local switch for controlling the time stepping 153 154 REAL(wp) :: div !< 155 REAL(wp) :: dt_diff !< 156 REAL(wp) :: dt_diff_l !< 157 REAL(wp) :: dt_u !< 158 REAL(wp) :: dt_u_l !< 159 REAL(wp) :: dt_v !< 160 REAL(wp) :: dt_v_l !< 161 REAL(wp) :: dt_w !< 162 REAL(wp) :: dt_w_l !< 163 REAL(wp) :: km_max !< maximum of Km in entire domain 164 REAL(wp) :: kh_max !< maximum of Kh in entire domain 165 REAL(wp) :: u_gtrans_l !< 166 REAL(wp) :: v_gtrans_l !< 167 168 REAL(wp), DIMENSION(2) :: uv_gtrans_l !< 169 #if defined( __parallel ) 170 REAL(wp), DIMENSION(2) :: uv_gtrans !< 171 REAL(wp), DIMENSION(3) :: reduce !< 172 REAL(wp), DIMENSION(3) :: reduce_l !< 173 #endif 174 REAL(wp), DIMENSION(nzb+1:nzt) :: dxyz2_min !< 133 175 !$ACC DECLARE CREATE(dxyz2_min) 134 176 … … 137 179 138 180 ! 139 !-- In case of Galilei-transform not using the geostrophic wind as translation 140 !-- velocity, compute the volume-averaged horizontal velocity components, which 141 !-- will then be subtracted from the horizontal wind for the time step and 142 !-- horizontal advection routines. 181 !-- In case of Galilei-transform not using the geostrophic wind as translation velocity, compute the 182 !-- volume-averaged horizontal velocity components, which will then be subtracted from the 183 !-- horizontal wind for the time step and horizontal advection routines. 143 184 IF ( galilei_transformation .AND. .NOT. use_ug_for_galilei_tr ) THEN 144 185 IF ( flow_statistics_called ) THEN 145 186 ! 146 !-- Horizontal averages already existent, just need to average them 147 !-- vertically. 187 !-- Horizontal averages already existent, just need to average them vertically. 148 188 u_gtrans = 0.0_wp 149 189 v_gtrans = 0.0_wp … … 152 192 v_gtrans = v_gtrans + hom(k,1,2,0) 153 193 ENDDO 154 u_gtrans = u_gtrans / REAL( nzt - nzb, KIND =wp )155 v_gtrans = v_gtrans / REAL( nzt - nzb, KIND =wp )194 u_gtrans = u_gtrans / REAL( nzt - nzb, KIND = wp ) 195 v_gtrans = v_gtrans / REAL( nzt - nzb, KIND = wp ) 156 196 ELSE 157 197 ! … … 167 207 ENDDO 168 208 ENDDO 169 uv_gtrans_l(1) = u_gtrans_l / & 170 REAL( (nxr-nxl+1)*(nyn-nys+1)*(nzt-nzb), KIND=wp ) 171 uv_gtrans_l(2) = v_gtrans_l / & 172 REAL( (nxr-nxl+1)*(nyn-nys+1)*(nzt-nzb), KIND=wp ) 209 uv_gtrans_l(1) = u_gtrans_l / REAL( (nxr-nxl+1) * (nyn-nys+1) * (nzt-nzb), KIND = wp ) 210 uv_gtrans_l(2) = v_gtrans_l / REAL( (nxr-nxl+1) * (nyn-nys+1) * (nzt-nzb), KIND = wp ) 173 211 #if defined( __parallel ) 174 212 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 175 CALL MPI_ALLREDUCE( uv_gtrans_l, uv_gtrans, 2, MPI_REAL, MPI_SUM, & 176 comm2d, ierr ) 177 u_gtrans = uv_gtrans(1) / REAL( numprocs, KIND=wp ) 178 v_gtrans = uv_gtrans(2) / REAL( numprocs, KIND=wp ) 213 CALL MPI_ALLREDUCE( uv_gtrans_l, uv_gtrans, 2, MPI_REAL, MPI_SUM, comm2d, ierr ) 214 u_gtrans = uv_gtrans(1) / REAL( numprocs, KIND = wp ) 215 v_gtrans = uv_gtrans(2) / REAL( numprocs, KIND = wp ) 179 216 #else 180 217 u_gtrans = uv_gtrans_l(1) … … 185 222 186 223 ! 187 !-- Determine the maxima of the velocity components, including their 188 !-- grid index positions. 189 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, u, 'abs', 0.0_wp, & 190 u_max, u_max_ijk ) 191 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, v, 'abs', 0.0_wp, & 192 v_max, v_max_ijk ) 193 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, w, 'abs', 0.0_wp, & 194 w_max, w_max_ijk ) 224 !-- Determine the maxima of the velocity components, including their grid index positions. 225 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, u, 'abs', 0.0_wp, u_max, u_max_ijk ) 226 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, v, 'abs', 0.0_wp, v_max, v_max_ijk ) 227 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, w, 'abs', 0.0_wp, w_max, w_max_ijk ) 195 228 196 229 IF ( .NOT. dt_fixed ) THEN … … 215 248 DO j = nys, nyn 216 249 DO k = nzb+1, nzt 217 dt_u_l = MIN( dt_u_l, ( dx / & 218 ( ABS( u(k,j,i) - u_gtrans + u_stokes_zu(k) ) & 219 + 1.0E-10_wp ) ) ) 220 dt_v_l = MIN( dt_v_l, ( dy / & 221 ( ABS( v(k,j,i) - v_gtrans + v_stokes_zu(k) ) & 222 + 1.0E-10_wp ) ) ) 223 dt_w_l = MIN( dt_w_l, ( dzu(k) / & 224 ( ABS( w(k,j,i) ) + 1.0E-10_wp ) ) ) 250 dt_u_l = MIN( dt_u_l, ( dx / ( ABS( u(k,j,i) - u_gtrans + u_stokes_zu(k) ) & 251 + 1.0E-10_wp ) ) ) 252 dt_v_l = MIN( dt_v_l, ( dy / ( ABS( v(k,j,i) - v_gtrans + v_stokes_zu(k) ) & 253 + 1.0E-10_wp ) ) ) 254 dt_w_l = MIN( dt_w_l, ( dzu(k) / ( ABS( w(k,j,i) ) + 1.0E-10_wp ) ) ) 225 255 ENDDO 226 256 ENDDO … … 230 260 ! 231 261 !-- Consider the wind speed at the scalar-grid point 232 !-- !> @note considering the wind speed instead of each individual wind 233 !-- !> component is only a workaround so far. This might has to be 234 !-- !> changed in the future. 262 !-- !> @note Considering the wind speed instead of each individual wind component is only a 263 !-- !> workaround so far. This has to be changed in the future. 235 264 236 265 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & … … 243 272 DO j = nys, nyn 244 273 DO k = nzb+1, nzt 245 dt_u_l = MIN( dt_u_l, ( MIN( dx, dy, dzu(k) ) / ( & 246 SQRT( ( 0.5 * ( u(k,j,i) + u(k,j,i+1) ) - u_gtrans + u_stokes_zu(k) )**2 & 247 + ( 0.5 * ( v(k,j,i) + v(k,j+1,i) ) - v_gtrans + v_stokes_zu(k) )**2 & 248 + ( 0.5 * ( w(k,j,i) + w(k-1,j,i) ) )**2 ) & 249 + 1.0E-10_wp ) ) ) 274 dt_u_l = MIN( dt_u_l, ( MIN( dx, dy, dzu(k) ) / ( SQRT( & 275 ( 0.5 * ( u(k,j,i) + u(k,j,i+1) ) - u_gtrans + u_stokes_zu(k) )**2 & 276 + ( 0.5 * ( v(k,j,i) + v(k,j+1,i) ) - v_gtrans + v_stokes_zu(k) )**2 & 277 + ( 0.5 * ( w(k,j,i) + w(k-1,j,i) ) )**2 ) + 1.0E-10_wp ) ) ) 250 278 ENDDO 251 279 ENDDO 252 280 ENDDO 253 281 254 282 dt_v_l = dt_u_l 255 283 dt_w_l = dt_u_l … … 274 302 ! 275 303 !-- Compute time step according to the diffusion criterion. 276 !-- First calculate minimum grid spacing which only depends on index k. 277 !-- When using the dynamicsubgrid model, negative km are possible.304 !-- First calculate minimum grid spacing which only depends on index k. When using the dynamic 305 !-- subgrid model, negative km are possible. 278 306 dt_diff_l = 999999.0_wp 279 307 280 308 !$ACC PARALLEL LOOP PRESENT(dxyz2_min, dzw) 281 309 DO k = nzb+1, nzt 282 dxyz2_min(k) = MIN( dx2, dy2, dzw(k) *dzw(k) ) * 0.125_wp310 dxyz2_min(k) = MIN( dx2, dy2, dzw(k) * dzw(k) ) * 0.125_wp 283 311 ENDDO 284 312 … … 291 319 DO j = nys, nyn 292 320 DO k = nzb+1, nzt 293 dt_diff_l = MIN( dt_diff_l, & 294 dxyz2_min(k) / & 295 ( MAX( kh(k,j,i), 2.0_wp * ABS( km(k,j,i) ) ) & 296 + 1E-20_wp ) ) 321 dt_diff_l = MIN( dt_diff_l, dxyz2_min(k) / ( MAX( kh(k,j,i), 2.0_wp * & 322 ABS( km(k,j,i) ) ) + 1E-20_wp ) ) 297 323 ENDDO 298 324 ENDDO … … 301 327 #if defined( __parallel ) 302 328 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 303 CALL MPI_ALLREDUCE( dt_diff_l, dt_diff, 1, MPI_REAL, MPI_MIN, comm2d, & 304 ierr ) 329 CALL MPI_ALLREDUCE( dt_diff_l, dt_diff, 1, MPI_REAL, MPI_MIN, comm2d, ierr ) 305 330 #else 306 331 dt_diff = dt_diff_l … … 308 333 309 334 ! 310 !-- The time step is the minimum of the 3-4 components and the diffusion time 311 !-- step minus areduction (cfl_factor) to be on the safe side.335 !-- The time step is the minimum of the 3-4 components and the diffusion time step minus a 336 !-- reduction (cfl_factor) to be on the safe side. 312 337 !-- The time step must not exceed the maximum allowed value. 313 338 dt_3d = cfl_factor * MIN( dt_diff, dt_u, dt_v, dt_w, dt_precipitation ) … … 328 353 329 354 ! 330 !-- Determine the maxima of the diffusion coefficients, including their 331 !-- grid index positions. 332 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, km, 'abs', & 333 0.0_wp, km_max, km_max_ijk ) 334 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, kh, 'abs', & 335 0.0_wp, kh_max, kh_max_ijk ) 336 337 WRITE( message_string, * ) 'Time step has reached minimum limit.', & 338 '&dt = ', dt_3d, ' s Simulation is terminated.', & 339 '&dt_u = ', dt_u, ' s', & 340 '&dt_v = ', dt_v, ' s', & 341 '&dt_w = ', dt_w, ' s', & 342 '&dt_diff = ', dt_diff, ' s', & 343 '&u_max = ', u_max, ' m/s k=', u_max_ijk(1), & 344 ' j=', u_max_ijk(2), ' i=', u_max_ijk(3), & 345 '&v_max = ', v_max, ' m/s k=', v_max_ijk(1), & 346 ' j=', v_max_ijk(2), ' i=', v_max_ijk(3), & 347 '&w_max = ', w_max, ' m/s k=', w_max_ijk(1), & 348 ' j=', w_max_ijk(2), ' i=', w_max_ijk(3), & 349 '&km_max = ', km_max, ' m2/s2 k=', km_max_ijk(1), & 350 ' j=', km_max_ijk(2), ' i=', km_max_ijk(3), & 351 '&kh_max = ', kh_max, ' m2/s2 k=', kh_max_ijk(1), & 355 !-- Determine the maxima of the diffusion coefficients, including their grid index positions. 356 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, km, 'abs', 0.0_wp, km_max, & 357 km_max_ijk ) 358 CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, kh, 'abs', 0.0_wp, kh_max, & 359 kh_max_ijk ) 360 361 WRITE( message_string, * ) 'Time step has reached minimum limit.', & 362 '&dt = ', dt_3d, ' s Simulation is terminated.', & 363 '&dt_u = ', dt_u, ' s', & 364 '&dt_v = ', dt_v, ' s', & 365 '&dt_w = ', dt_w, ' s', & 366 '&dt_diff = ', dt_diff, ' s', & 367 '&u_max = ', u_max, ' m/s k=', u_max_ijk(1), & 368 ' j=', u_max_ijk(2), ' i=', u_max_ijk(3), & 369 '&v_max = ', v_max, ' m/s k=', v_max_ijk(1), & 370 ' j=', v_max_ijk(2), ' i=', v_max_ijk(3), & 371 '&w_max = ', w_max, ' m/s k=', w_max_ijk(1), & 372 ' j=', w_max_ijk(2), ' i=', w_max_ijk(3), & 373 '&km_max = ', km_max, ' m2/s2 k=', km_max_ijk(1), & 374 ' j=', km_max_ijk(2), ' i=', km_max_ijk(3), & 375 '&kh_max = ', kh_max, ' m2/s2 k=', kh_max_ijk(1), & 352 376 ' j=', kh_max_ijk(2), ' i=', kh_max_ijk(3) 353 377 CALL message( 'timestep', 'PA0312', 0, 1, 0, 6, 0 ) 354 378 ! 355 !-- In case of coupled runs inform the remote model of the termination 356 !-- and its reason, provided the remote model has not already been357 !-- informed of another termination reason (terminate_coupled > 0) before.379 !-- In case of coupled runs inform the remote model of the termination and its reason, 380 !-- provided the remote model has not already been informed of another termination reason 381 !-- (terminate_coupled > 0). 358 382 #if defined( __parallel ) 359 383 IF ( coupling_mode /= 'uncoupled' .AND. terminate_coupled == 0 ) THEN 360 384 terminate_coupled = 2 361 385 IF ( myid == 0 ) THEN 362 CALL MPI_SENDRECV( & 363 terminate_coupled, 1, MPI_INTEGER, target_id, 0, & 364 terminate_coupled_remote, 1, MPI_INTEGER, target_id, 0, & 365 comm_inter, status, ierr ) 386 CALL MPI_SENDRECV( terminate_coupled, 1, MPI_INTEGER, target_id, 0, & 387 terminate_coupled_remote, 1, MPI_INTEGER, target_id, 0, & 388 comm_inter, status, ierr ) 366 389 ENDIF 367 CALL MPI_BCAST( terminate_coupled_remote, 1, MPI_INTEGER, 0, & 368 comm2d, ierr) 390 CALL MPI_BCAST( terminate_coupled_remote, 1, MPI_INTEGER, 0, comm2d, ierr) 369 391 ENDIF 370 392 #endif … … 372 394 373 395 ! 374 !-- In case of nested runs all parent/child processes have to terminate if 375 !-- one process has set the stop flag, i.e. they need to set the stop flag 376 !-- too. 396 !-- In case of nested runs all parent/child processes have to terminate if one process has set 397 !-- the stop flag, i.e. they need to set the stop flag too. 377 398 IF ( nested_run ) THEN 378 399 stop_dt_local = stop_dt 379 400 #if defined( __parallel ) 380 CALL MPI_ALLREDUCE( stop_dt_local, stop_dt, 1, MPI_LOGICAL, MPI_LOR, & 381 MPI_COMM_WORLD, ierr ) 401 CALL MPI_ALLREDUCE( stop_dt_local, stop_dt, 1, MPI_LOGICAL, MPI_LOR, MPI_COMM_WORLD, ierr ) 382 402 #endif 383 403 ENDIF … … 395 415 #if defined( __parallel ) 396 416 ! 397 !-- Vertical nesting: coarse and fine grid timestep has to be identical 417 !-- Vertical nesting: coarse and fine grid timestep has to be identical 398 418 IF ( vnested ) CALL vnest_timestep_sync 399 419 #endif -
palm/trunk/SOURCE/timestep_scheme_steering.f90
r4360 r4540 1 1 !> @file timestep_scheme_steering.f90 2 !------------------------------------------------------------------------------ !2 !--------------------------------------------------------------------------------------------------! 3 3 ! This file is part of the PALM model system. 4 4 ! 5 ! PALM is free software: you can redistribute it and/or modify it under the 6 ! terms of the GNU General Public License as published by the Free Software 7 ! Foundation, either version 3 of the License, or (at your option) any later 8 ! version. 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. 9 8 ! 10 ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY 11 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR12 ! A PARTICULAR PURPOSE. See the GNU GeneralPublic License for more details.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. 13 12 ! 14 ! You should have received a copy of the GNU General Public License along with 15 ! PALM. If not, see<http://www.gnu.org/licenses/>.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/>. 16 15 ! 17 16 ! Copyright 1997-2020 Leibniz Universitaet Hannover 18 !------------------------------------------------------------------------------! 17 !--------------------------------------------------------------------------------------------------! 18 ! 19 19 ! 20 20 ! Current revisions: 21 ! ----------------- -21 ! ----------------- 22 22 ! 23 23 ! … … 25 25 ! ----------------- 26 26 ! $Id$ 27 ! File re-formatted to follow the PALM coding standard 28 ! 29 ! 30 ! 4360 2020-01-07 11:25:50Z suehring 27 31 ! Corrected "Former revisions" section 28 ! 32 ! 29 33 ! 3655 2019-01-07 16:51:22Z knoop 30 34 ! OpenACC port for SPEC … … 36 40 ! Description: 37 41 ! ------------ 38 !> Depending on the timestep scheme set the steering factors for the prognostic 39 !> equations. 40 !------------------------------------------------------------------------------! 42 !> Depending on the timestep scheme set the steering factors for the prognostic equations. 43 !--------------------------------------------------------------------------------------------------! 41 44 SUBROUTINE timestep_scheme_steering 42 43 45 44 USE control_parameters, & 45 ONLY: intermediate_timestep_count, timestep_scheme, tsc 46 47 USE control_parameters, & 48 ONLY: intermediate_timestep_count, & 49 timestep_scheme, & 50 tsc 46 51 47 52 USE kinds … … 52 57 IF ( timestep_scheme(1:5) == 'runge' ) THEN 53 58 ! 54 !-- Runge-Kutta schemes (here the factors depend on the respective 55 !-- intermediate step) 59 !-- Runge-Kutta schemes (here the factors depend on the respective intermediate step) 56 60 IF ( timestep_scheme == 'runge-kutta-2' ) THEN 57 61 IF ( intermediate_timestep_count == 1 ) THEN … … 62 66 ELSE 63 67 IF ( intermediate_timestep_count == 1 ) THEN 64 tsc(1:5) = (/ 1.0_wp, 1.0_wp / 3.0_wp, 68 tsc(1:5) = (/ 1.0_wp, 1.0_wp / 3.0_wp, 0.0_wp, 0.0_wp, 0.0_wp /) 65 69 ELSEIF ( intermediate_timestep_count == 2 ) THEN 66 70 tsc(1:5) = (/ 1.0_wp, 15.0_wp / 16.0_wp, -25.0_wp/48.0_wp, 0.0_wp, 0.0_wp /) 67 71 ELSE 68 72 tsc(1:5) = (/ 1.0_wp, 8.0_wp / 15.0_wp, 1.0_wp/15.0_wp, 0.0_wp, 1.0_wp /) 69 ENDIF 73 ENDIF 70 74 ENDIF 71 75 -
palm/trunk/SOURCE/transpose.f90
r4429 r4540 1 1 !> @file transpose.f90 2 !------------------------------------------------------------------------------ !2 !--------------------------------------------------------------------------------------------------! 3 3 ! This file is part of the PALM model system. 4 4 ! 5 ! PALM is free software: you can redistribute it and/or modify it under the 6 ! terms of the GNU General Public License as published by the Free Software 7 ! Foundation, either version 3 of the License, or (at your option) any later 8 ! version. 9 ! 10 ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY 11 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 ! A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 ! 14 ! You should have received a copy of the GNU General Public License along with 15 ! PALM. If not, see <http://www.gnu.org/licenses/>. 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. 8 ! 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. 12 ! 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/>. 16 15 ! 17 16 ! Copyright 1997-2020 Leibniz Universitaet Hannover 18 !------------------------------------------------------------------------------! 17 !--------------------------------------------------------------------------------------------------! 18 ! 19 19 ! 20 20 ! Current revisions: … … 25 25 ! ----------------- 26 26 ! $Id$ 27 ! bugfix: cpp-directives added for serial mode 28 ! 27 ! File re-formatted to follow the PALM coding standard 28 ! 29 ! 30 ! 4429 2020-02-27 15:24:30Z raasch 31 ! Bugfix: cpp-directives added for serial mode 32 ! 29 33 ! 4415 2020-02-20 10:30:33Z raasch 30 ! bugfix for misplaced preprocessor directive31 ! 34 ! Bugfix for misplaced preprocessor directive 35 ! 32 36 ! 4370 2020-01-10 14:00:44Z raasch 33 ! vector array renamed34 ! 37 ! Vector array renamed 38 ! 35 39 ! 4366 2020-01-09 08:12:43Z raasch 36 ! modifications for NEC vectorization37 ! 40 ! Modifications for NEC vectorization 41 ! 38 42 ! 4360 2020-01-07 11:25:50Z suehring 39 43 ! Added missing OpenMP directives 40 ! 44 ! 41 45 ! 4182 2019-08-22 15:20:23Z scharf 42 46 ! Corrected "Former revisions" section 43 ! 47 ! 44 48 ! 4171 2019-08-19 17:44:09Z gronemeier 45 ! loop reordering for performance optimization49 ! Loop reordering for performance optimization 46 50 ! 47 51 ! 3832 2019-03-28 13:16:58Z raasch 48 ! loop reordering for performance optimization52 ! Loop reordering for performance optimization 49 53 ! 50 54 ! 3694 2019-01-23 17:01:49Z knoop … … 57 61 ! Description: 58 62 ! ------------ 59 !> Resorting data for the transposition from x to y. The transposition itself 60 !> is carried out in transpose_xy61 !------------------------------------------------------------------------------ !63 !> Resorting data for the transposition from x to y. The transposition itself is carried out in 64 !> transpose_xy. 65 !--------------------------------------------------------------------------------------------------! 62 66 63 67 #define __acc_fft_device ( defined( _OPENACC ) && ( defined ( __cuda_fft ) ) ) … … 66 70 67 71 68 USE indices, & 69 ONLY: nx 70 71 USE kinds 72 73 USE transpose_indices, & 74 ONLY: nyn_x, nys_x, nzb_x, nzt_x 75 76 IMPLICIT NONE 77 78 REAL(wp) :: f_in(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 79 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 80 81 82 INTEGER(iwp) :: i !< 83 INTEGER(iwp) :: j !< 84 INTEGER(iwp) :: k !< 85 ! 86 !-- Rearrange indices of input array in order to make data to be send 87 !-- by MPI contiguous 88 !$OMP PARALLEL PRIVATE ( i, j, k ) 89 !$OMP DO 90 #if __acc_fft_device 91 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 92 !$ACC PRESENT(f_inv, f_in) 93 #endif 94 DO k = nzb_x, nzt_x 95 DO j = nys_x, nyn_x 96 DO i = 0, nx 97 f_inv(j,k,i) = f_in(i,j,k) 98 ENDDO 99 ENDDO 100 ENDDO 101 !$OMP END PARALLEL 102 103 END SUBROUTINE resort_for_xy 104 105 106 !------------------------------------------------------------------------------! 107 ! Description: 108 ! ------------ 109 !> Transposition of input array (f_in) from x to y. For the input array, all 110 !> elements along x reside on the same PE, while after transposition, all 111 !> elements along y reside on the same PE. 112 !------------------------------------------------------------------------------! 113 SUBROUTINE transpose_xy( f_inv, f_out ) 114 115 116 #if defined( __parallel ) 117 USE cpulog, & 118 ONLY: cpu_log, cpu_log_nowait, log_point_s 119 #endif 120 121 USE indices, & 122 ONLY: nx, ny 72 USE indices, & 73 ONLY: nx 123 74 124 75 USE kinds 125 76 126 USE pegrid 127 128 USE transpose_indices, & 129 ONLY: nxl_y, nxr_y, nyn_x, nys_x, nzb_x, nzb_y, nzt_x, nzt_y 77 USE transpose_indices, & 78 ONLY: nyn_x, & 79 nys_x, & 80 nzb_x, & 81 nzt_x 130 82 131 83 IMPLICIT NONE … … 135 87 INTEGER(iwp) :: k !< 136 88 137 #if defined( __parallel ) 138 INTEGER(iwp) :: l !< 139 INTEGER(iwp) :: ys !< 140 #endif 141 142 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 143 REAL(wp) :: f_out(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 144 145 #if defined( __parallel ) 146 REAL(wp), DIMENSION(nyn_x-nys_x+1,nzb_y:nzt_y,nxl_y:nxr_y,0:pdims(2)-1) :: work !< 89 REAL(wp) :: f_in(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 90 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 91 92 ! 93 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous 94 !$OMP PARALLEL PRIVATE ( i, j, k ) 95 !$OMP DO 96 #if __acc_fft_device 97 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 98 !$ACC PRESENT(f_inv, f_in) 99 #endif 100 DO k = nzb_x, nzt_x 101 DO j = nys_x, nyn_x 102 DO i = 0, nx 103 f_inv(j,k,i) = f_in(i,j,k) 104 ENDDO 105 ENDDO 106 ENDDO 107 !$OMP END PARALLEL 108 109 END SUBROUTINE resort_for_xy 110 111 112 !--------------------------------------------------------------------------------------------------! 113 ! Description: 114 ! ------------ 115 !> Transposition of input array (f_in) from x to y. For the input array, all elements along x reside 116 !> on the same PE, while after transposition, all elements along y reside on the same PE. 117 !--------------------------------------------------------------------------------------------------! 118 SUBROUTINE transpose_xy( f_inv, f_out ) 119 120 121 #if defined( __parallel ) 122 USE cpulog, & 123 ONLY: cpu_log, & 124 cpu_log_nowait, & 125 log_point_s 126 #endif 127 128 USE indices, & 129 ONLY: nx, & 130 ny 131 132 USE kinds 133 134 USE pegrid 135 136 USE transpose_indices, & 137 ONLY: nxl_y, & 138 nxr_y, & 139 nyn_x, & 140 nys_x, & 141 nzb_x, & 142 nzb_y, & 143 nzt_x, & 144 nzt_y 145 146 IMPLICIT NONE 147 148 INTEGER(iwp) :: i !< 149 INTEGER(iwp) :: j !< 150 INTEGER(iwp) :: k !< 151 152 #if defined( __parallel ) 153 INTEGER(iwp) :: l !< 154 INTEGER(iwp) :: ys !< 155 #endif 156 157 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 158 REAL(wp) :: f_out(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 159 160 #if defined( __parallel ) 161 REAL(wp), DIMENSION(nyn_x-nys_x+1,nzb_y:nzt_y,nxl_y:nxr_y,0:pdims(2)-1) :: work !< 147 162 #if __acc_fft_device 148 163 !$ACC DECLARE CREATE(work) … … 167 182 168 183 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 169 CALL MPI_ALLTOALL( f_inv(nys_x,nzb_x,0), sendrecvcount_xy, MPI_REAL, & 170 work(1,nzb_y,nxl_y,0), sendrecvcount_xy, MPI_REAL, & 171 comm1dy, ierr ) 184 CALL MPI_ALLTOALL( f_inv(nys_x,nzb_x,0), sendrecvcount_xy, MPI_REAL, & 185 work(1,nzb_y,nxl_y,0), sendrecvcount_xy, MPI_REAL, comm1dy, ierr ) 172 186 173 187 #if __acc_fft_device … … 227 241 228 242 229 !------------------------------------------------------------------------------ !243 !--------------------------------------------------------------------------------------------------! 230 244 ! Description: 231 245 ! ------------ 232 !> Resorting data after the transposition from x to z. The transposition itself 233 !> is carried out in transpose_xz234 !------------------------------------------------------------------------------ !246 !> Resorting data after the transposition from x to z. The transposition itself is carried out in 247 !> transpose_xz. 248 !--------------------------------------------------------------------------------------------------! 235 249 SUBROUTINE resort_for_xz( f_inv, f_out ) 236 250 237 251 238 USE indices, & 239 ONLY: nxl, nxr, nyn, nys, nz 240 241 USE kinds 242 243 IMPLICIT NONE 244 245 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 246 REAL(wp) :: f_out(1:nz,nys:nyn,nxl:nxr) !< 247 248 INTEGER(iwp) :: i !< 249 INTEGER(iwp) :: j !< 250 INTEGER(iwp) :: k !< 251 ! 252 !-- Rearrange indices of input array in order to make data to be send 253 !-- by MPI contiguous. 254 !-- In case of parallel fft/transposition, scattered store is faster in 255 !-- backward direction!!! 256 !$OMP PARALLEL PRIVATE ( i, j, k ) 257 !$OMP DO 258 #if __acc_fft_device 259 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 260 !$ACC PRESENT(f_out, f_inv) 261 #endif 262 DO i = nxl, nxr 263 DO j = nys, nyn 264 DO k = 1, nz 265 f_out(k,j,i) = f_inv(j,i,k) 266 ENDDO 267 ENDDO 268 ENDDO 269 !$OMP END PARALLEL 270 271 END SUBROUTINE resort_for_xz 272 273 274 !------------------------------------------------------------------------------! 275 ! Description: 276 ! ------------ 277 !> Transposition of input array (f_in) from x to z. For the input array, all 278 !> elements along x reside on the same PE, while after transposition, all 279 !> elements along z reside on the same PE. 280 !------------------------------------------------------------------------------! 281 SUBROUTINE transpose_xz( f_in, f_inv ) 282 283 #if defined( __parallel ) 284 USE cpulog, & 285 ONLY: cpu_log, cpu_log_nowait, log_point_s 286 287 USE fft_xy, & 288 ONLY: f_vec_x, temperton_fft_vec 289 #endif 290 291 USE indices, & 292 ONLY: nx, nxl, nxr, nyn, nys, nz 293 #if defined( __parallel ) 294 USE indices, & 295 ONLY: nnx 296 #endif 252 USE indices, & 253 ONLY: nxl, & 254 nxr, & 255 nyn, & 256 nys, & 257 nz 297 258 298 259 USE kinds 299 300 USE pegrid301 302 USE transpose_indices, &303 ONLY: nyn_x, nys_x, nzb_x, nzt_x304 260 305 261 IMPLICIT NONE … … 308 264 INTEGER(iwp) :: j !< 309 265 INTEGER(iwp) :: k !< 310 #if defined( __parallel ) 311 INTEGER(iwp) :: l !< 312 INTEGER(iwp) :: mm !< 313 INTEGER(iwp) :: xs !< 314 #endif 315 316 REAL(wp) :: f_in(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 317 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 318 319 #if defined( __parallel ) 320 REAL(wp), DIMENSION(nys_x:nyn_x,nnx,nzb_x:nzt_x,0:pdims(1)-1) :: work !< 266 267 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 268 REAL(wp) :: f_out(1:nz,nys:nyn,nxl:nxr) !< 269 270 ! 271 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 272 !-- In case of parallel fft/transposition, scattered store is faster in backward direction!!! 273 !$OMP PARALLEL PRIVATE ( i, j, k ) 274 !$OMP DO 275 #if __acc_fft_device 276 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 277 !$ACC PRESENT(f_out, f_inv) 278 #endif 279 DO i = nxl, nxr 280 DO j = nys, nyn 281 DO k = 1, nz 282 f_out(k,j,i) = f_inv(j,i,k) 283 ENDDO 284 ENDDO 285 ENDDO 286 !$OMP END PARALLEL 287 288 END SUBROUTINE resort_for_xz 289 290 291 !--------------------------------------------------------------------------------------------------! 292 ! Description: 293 ! ------------ 294 !> Transposition of input array (f_in) from x to z. For the input array, all elements along x reside 295 !> on the same PE, while after transposition, all elements along z reside on the same PE. 296 !--------------------------------------------------------------------------------------------------! 297 SUBROUTINE transpose_xz( f_in, f_inv ) 298 299 #if defined( __parallel ) 300 USE cpulog, & 301 ONLY: cpu_log, & 302 cpu_log_nowait, & 303 log_point_s 304 305 USE fft_xy, & 306 ONLY: f_vec_x, & 307 temperton_fft_vec 308 #endif 309 310 USE indices, & 311 ONLY: nx, & 312 nxl, & 313 nxr, & 314 nyn, & 315 nys, & 316 nz 317 318 #if defined( __parallel ) 319 USE indices, & 320 ONLY: nnx 321 #endif 322 323 USE kinds 324 325 USE pegrid 326 327 USE transpose_indices, & 328 ONLY: nyn_x, & 329 nys_x, & 330 nzb_x, & 331 nzt_x 332 333 IMPLICIT NONE 334 335 INTEGER(iwp) :: i !< 336 INTEGER(iwp) :: j !< 337 INTEGER(iwp) :: k !< 338 339 #if defined( __parallel ) 340 INTEGER(iwp) :: l !< 341 INTEGER(iwp) :: mm !< 342 INTEGER(iwp) :: xs !< 343 #endif 344 345 REAL(wp) :: f_in(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 346 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 347 348 #if defined( __parallel ) 349 REAL(wp), DIMENSION(nys_x:nyn_x,nnx,nzb_x:nzt_x,0:pdims(1)-1) :: work !< 321 350 #if __acc_fft_device 322 351 !$ACC DECLARE CREATE(work) … … 325 354 326 355 ! 327 !-- If the PE grid is one-dimensional along y, the array has only to be 328 !-- reordered locally andtherefore no transposition has to be done.356 !-- If the PE grid is one-dimensional along y, the array has only to be reordered locally and 357 !-- therefore no transposition has to be done. 329 358 IF ( pdims(1) /= 1 ) THEN 330 359 … … 383 412 384 413 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 385 CALL MPI_ALLTOALL( work(nys_x,1,nzb_x,0), sendrecvcount_zx, MPI_REAL, & 386 f_inv(nys,nxl,1), sendrecvcount_zx, MPI_REAL, & 387 comm1dx, ierr ) 414 CALL MPI_ALLTOALL( work(nys_x,1,nzb_x,0), sendrecvcount_zx, MPI_REAL, & 415 f_inv(nys,nxl,1), sendrecvcount_zx, MPI_REAL, comm1dx, ierr ) 388 416 389 417 #if __acc_fft_device … … 422 450 423 451 424 !------------------------------------------------------------------------------ !452 !--------------------------------------------------------------------------------------------------! 425 453 ! Description: 426 454 ! ------------ 427 !> Resorting data after the transposition from y to x. The transposition itself 428 !> is carried out in transpose_yx429 !------------------------------------------------------------------------------ !455 !> Resorting data after the transposition from y to x. The transposition itself is carried out in 456 !> transpose_yx. 457 !--------------------------------------------------------------------------------------------------! 430 458 SUBROUTINE resort_for_yx( f_inv, f_out ) 431 459 432 460 433 USE indices, & 434 ONLY: nx 435 436 USE kinds 437 438 USE transpose_indices, & 439 ONLY: nyn_x, nys_x, nzb_x, nzt_x 440 441 IMPLICIT NONE 442 443 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 444 REAL(wp) :: f_out(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 445 446 447 INTEGER(iwp) :: i !< 448 INTEGER(iwp) :: j !< 449 INTEGER(iwp) :: k !< 450 ! 451 !-- Rearrange indices of input array in order to make data to be send 452 !-- by MPI contiguous 453 !$OMP PARALLEL PRIVATE ( i, j, k ) 454 !$OMP DO 455 #if __acc_fft_device 456 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 457 !$ACC PRESENT(f_out, f_inv) 458 #endif 459 DO k = nzb_x, nzt_x 460 DO j = nys_x, nyn_x 461 DO i = 0, nx 462 f_out(i,j,k) = f_inv(j,k,i) 463 ENDDO 464 ENDDO 465 ENDDO 466 !$OMP END PARALLEL 467 468 END SUBROUTINE resort_for_yx 469 470 471 !------------------------------------------------------------------------------! 472 ! Description: 473 ! ------------ 474 !> Transposition of input array (f_in) from y to x. For the input array, all 475 !> elements along y reside on the same PE, while after transposition, all 476 !> elements along x reside on the same PE. 477 !------------------------------------------------------------------------------! 478 SUBROUTINE transpose_yx( f_in, f_inv ) 479 480 481 #if defined( __parallel ) 482 USE cpulog, & 483 ONLY: cpu_log, cpu_log_nowait, log_point_s 484 #endif 485 486 USE indices, & 487 ONLY: nx, ny 461 USE indices, & 462 ONLY: nx 488 463 489 464 USE kinds 490 465 491 USE pegrid 492 493 USE transpose_indices, & 494 ONLY: nxl_y, nxr_y, nyn_x, nys_x, nzb_x, nzb_y, nzt_x, nzt_y 466 USE transpose_indices, & 467 ONLY: nyn_x, & 468 nys_x, & 469 nzb_x, & 470 nzt_x 495 471 496 472 IMPLICIT NONE … … 499 475 INTEGER(iwp) :: j !< 500 476 INTEGER(iwp) :: k !< 501 #if defined( __parallel ) 502 INTEGER(iwp) :: l !< 503 INTEGER(iwp) :: ys !< 504 #endif 505 506 REAL(wp) :: f_in(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 507 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 508 509 #if defined( __parallel ) 510 REAL(wp), DIMENSION(nyn_x-nys_x+1,nzb_y:nzt_y,nxl_y:nxr_y,0:pdims(2)-1) :: work !< 477 478 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 479 REAL(wp) :: f_out(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 480 481 ! 482 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 483 !$OMP PARALLEL PRIVATE ( i, j, k ) 484 !$OMP DO 485 #if __acc_fft_device 486 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 487 !$ACC PRESENT(f_out, f_inv) 488 #endif 489 DO k = nzb_x, nzt_x 490 DO j = nys_x, nyn_x 491 DO i = 0, nx 492 f_out(i,j,k) = f_inv(j,k,i) 493 ENDDO 494 ENDDO 495 ENDDO 496 !$OMP END PARALLEL 497 498 END SUBROUTINE resort_for_yx 499 500 501 !--------------------------------------------------------------------------------------------------! 502 ! Description: 503 ! ------------ 504 !> Transposition of input array (f_in) from y to x. For the input array, all elements along y 505 !> reside on the same PE, while after transposition, all elements along x reside on the same PE. 506 !--------------------------------------------------------------------------------------------------! 507 SUBROUTINE transpose_yx( f_in, f_inv ) 508 509 510 #if defined( __parallel ) 511 USE cpulog, & 512 ONLY: cpu_log, & 513 cpu_log_nowait, & 514 log_point_s 515 #endif 516 517 USE indices, & 518 ONLY: nx, & 519 ny 520 521 USE kinds 522 523 USE pegrid 524 525 USE transpose_indices, & 526 ONLY: nxl_y, & 527 nxr_y, & 528 nyn_x, & 529 nys_x, & 530 nzb_x, & 531 nzb_y, & 532 nzt_x, & 533 nzt_y 534 535 IMPLICIT NONE 536 537 INTEGER(iwp) :: i !< 538 INTEGER(iwp) :: j !< 539 INTEGER(iwp) :: k !< 540 541 #if defined( __parallel ) 542 INTEGER(iwp) :: l !< 543 INTEGER(iwp) :: ys !< 544 #endif 545 546 REAL(wp) :: f_in(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 547 REAL(wp) :: f_inv(nys_x:nyn_x,nzb_x:nzt_x,0:nx) !< 548 549 #if defined( __parallel ) 550 REAL(wp), DIMENSION(nyn_x-nys_x+1,nzb_y:nzt_y,nxl_y:nxr_y,0:pdims(2)-1) :: work !< 511 551 #if __acc_fft_device 512 552 !$ACC DECLARE CREATE(work) … … 552 592 553 593 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 554 CALL MPI_ALLTOALL( work(1,nzb_y,nxl_y,0), sendrecvcount_xy, MPI_REAL, & 555 f_inv(nys_x,nzb_x,0), sendrecvcount_xy, MPI_REAL, & 556 comm1dy, ierr ) 594 CALL MPI_ALLTOALL( work(1,nzb_y,nxl_y,0), sendrecvcount_xy, MPI_REAL, & 595 f_inv(nys_x,nzb_x,0), sendrecvcount_xy, MPI_REAL, comm1dy, ierr ) 557 596 558 597 #if __acc_fft_device … … 570 609 571 610 ! 572 !-- Reorder array f_in the same way as ALLTOALL did it 611 !-- Reorder array f_in the same way as ALLTOALL did it. 573 612 !$OMP PARALLEL PRIVATE ( i, j, k ) 574 613 !$OMP DO … … 591 630 592 631 593 !------------------------------------------------------------------------------ !632 !--------------------------------------------------------------------------------------------------! 594 633 ! Description: 595 634 ! ------------ 596 !> Transposition of input array (f_in) from y to x. For the input array, all 597 !> elements along y reside on the same PE, while after transposition, all 598 !> elements along x reside on the same PE. 599 !> This is a direct transposition for arrays with indices in regular order 600 !> (k,j,i) (cf. transpose_yx). 601 !------------------------------------------------------------------------------! 635 !> Transposition of input array (f_in) from y to x. For the input array, all elements along y reside 636 !> on the same PE, while after transposition, all elements along x reside on the same PE. This is a 637 !> direct transposition for arrays with indices in regular order (k,j,i) (cf. transpose_yx). 638 !--------------------------------------------------------------------------------------------------! 602 639 #if defined( __parallel ) 603 640 SUBROUTINE transpose_yxd( f_in, f_out ) 604 641 605 642 606 USE cpulog, & 607 ONLY: cpu_log, log_point_s 608 609 USE indices, & 610 ONLY: nnx, nny, nnz, nx, nxl, nxr, nyn, nys, nz 643 USE cpulog, & 644 ONLY: cpu_log, & 645 log_point_s 646 647 USE indices, & 648 ONLY: nnx, & 649 nny, & 650 nnz, & 651 nx, & 652 nxl, & 653 nxr, & 654 nyn, & 655 nys, & 656 nz 611 657 612 658 USE kinds … … 614 660 USE pegrid 615 661 616 USE transpose_indices, & 617 ONLY: nyn_x, nys_x, nzb_x, nzt_x 662 USE transpose_indices, & 663 ONLY: nyn_x, & 664 nys_x, & 665 nzb_x, & 666 nzt_x 618 667 619 668 IMPLICIT NONE 620 669 621 INTEGER(iwp) :: i !< 622 INTEGER(iwp) :: j !< 623 INTEGER(iwp) :: k !< 624 INTEGER(iwp) :: l !< 625 INTEGER(iwp) :: m !< 626 INTEGER(iwp) :: xs !< 627 628 REAL(wp) :: f_in(1:nz,nys:nyn,nxl:nxr) !< 629 REAL(wp) :: f_inv(nxl:nxr,1:nz,nys:nyn) !< 630 REAL(wp) :: f_out(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 631 REAL(wp) :: work(nnx*nny*nnz) !< 632 633 ! 634 !-- Rearrange indices of input array in order to make data to be send 635 !-- by MPI contiguous 670 INTEGER(iwp) :: i !< 671 INTEGER(iwp) :: j !< 672 INTEGER(iwp) :: k !< 673 INTEGER(iwp) :: l !< 674 INTEGER(iwp) :: m !< 675 INTEGER(iwp) :: xs !< 676 677 REAL(wp) :: f_in(1:nz,nys:nyn,nxl:nxr) !< 678 REAL(wp) :: f_inv(nxl:nxr,1:nz,nys:nyn) !< 679 REAL(wp) :: f_out(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 680 REAL(wp) :: work(nnx*nny*nnz) !< 681 682 ! 683 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 636 684 DO k = 1, nz 637 685 DO j = nys, nyn … … 646 694 CALL cpu_log( log_point_s(32), 'mpi_alltoall', 'start' ) 647 695 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 648 CALL MPI_ALLTOALL( f_inv(nxl,1,nys), sendrecvcount_xy, MPI_REAL, & 649 work(1), sendrecvcount_xy, MPI_REAL, & 650 comm1dx, ierr ) 696 CALL MPI_ALLTOALL( f_inv(nxl,1,nys), sendrecvcount_xy, MPI_REAL, & 697 work(1), sendrecvcount_xy, MPI_REAL, comm1dx, ierr ) 651 698 CALL cpu_log( log_point_s(32), 'mpi_alltoall', 'stop' ) 652 699 … … 670 717 671 718 672 !------------------------------------------------------------------------------ !719 !--------------------------------------------------------------------------------------------------! 673 720 ! Description: 674 721 ! ------------ 675 !> Resorting data for the transposition from y to z. The transposition itself 676 !> is carried out in transpose_yz677 !------------------------------------------------------------------------------ !722 !> Resorting data for the transposition from y to z. The transposition itself is carried out in 723 !> transpose_yz. 724 !--------------------------------------------------------------------------------------------------! 678 725 SUBROUTINE resort_for_yz( f_in, f_inv ) 679 726 680 727 681 USE indices, & 682 ONLY: ny 683 684 USE kinds 685 686 USE transpose_indices, & 687 ONLY: nxl_y, nxr_y, nzb_y, nzt_y 688 689 IMPLICIT NONE 690 691 REAL(wp) :: f_in(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 692 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 693 694 INTEGER(iwp) :: i !< 695 INTEGER(iwp) :: j !< 696 INTEGER(iwp) :: k !< 697 698 ! 699 !-- Rearrange indices of input array in order to make data to be send 700 !-- by MPI contiguous 701 !$OMP PARALLEL PRIVATE ( i, j, k ) 702 !$OMP DO 703 #if __acc_fft_device 704 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 705 !$ACC PRESENT(f_inv, f_in) 706 #endif 707 DO k = nzb_y, nzt_y 708 DO i = nxl_y, nxr_y 709 DO j = 0, ny 710 f_inv(i,k,j) = f_in(j,i,k) 711 ENDDO 712 ENDDO 713 ENDDO 714 !$OMP END PARALLEL 715 716 END SUBROUTINE resort_for_yz 717 718 719 !------------------------------------------------------------------------------! 720 ! Description: 721 ! ------------ 722 !> Transposition of input array (f_in) from y to z. For the input array, all 723 !> elements along y reside on the same PE, while after transposition, all 724 !> elements along z reside on the same PE. 725 !------------------------------------------------------------------------------! 726 SUBROUTINE transpose_yz( f_inv, f_out ) 727 728 729 #if defined( __parallel ) 730 USE cpulog, & 731 ONLY: cpu_log, cpu_log_nowait, log_point_s 732 #endif 733 734 USE indices, & 735 ONLY: ny, nz 728 USE indices, & 729 ONLY: ny 736 730 737 731 USE kinds 738 732 739 USE pegrid 740 741 USE transpose_indices, & 742 ONLY: nxl_y, nxl_z, nxr_y, nxr_z, nyn_z, nys_z, nzb_y, nzt_y 733 USE transpose_indices, & 734 ONLY: nxl_y, & 735 nxr_y, & 736 nzb_y, & 737 nzt_y 743 738 744 739 IMPLICIT NONE … … 747 742 INTEGER(iwp) :: j !< 748 743 INTEGER(iwp) :: k !< 749 #if defined( __parallel ) 750 INTEGER(iwp) :: l !< 751 INTEGER(iwp) :: zs !< 752 #endif 753 754 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 755 REAL(wp) :: f_out(nxl_z:nxr_z,nys_z:nyn_z,1:nz) !< 756 757 #if defined( __parallel ) 758 REAL(wp), DIMENSION(nxl_z:nxr_z,nzt_y-nzb_y+1,nys_z:nyn_z,0:pdims(1)-1) :: work !< 744 745 REAL(wp) :: f_in(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 746 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 747 748 ! 749 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 750 !$OMP PARALLEL PRIVATE ( i, j, k ) 751 !$OMP DO 752 #if __acc_fft_device 753 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 754 !$ACC PRESENT(f_inv, f_in) 755 #endif 756 DO k = nzb_y, nzt_y 757 DO i = nxl_y, nxr_y 758 DO j = 0, ny 759 f_inv(i,k,j) = f_in(j,i,k) 760 ENDDO 761 ENDDO 762 ENDDO 763 !$OMP END PARALLEL 764 765 END SUBROUTINE resort_for_yz 766 767 768 !--------------------------------------------------------------------------------------------------! 769 ! Description: 770 ! ------------ 771 !> Transposition of input array (f_in) from y to z. For the input array, all elements along y reside 772 !> on the same PE, while after transposition, all elements along z reside on the same PE. 773 !--------------------------------------------------------------------------------------------------! 774 SUBROUTINE transpose_yz( f_inv, f_out ) 775 776 777 #if defined( __parallel ) 778 USE cpulog, & 779 ONLY: cpu_log, & 780 cpu_log_nowait, & 781 log_point_s 782 #endif 783 784 USE indices, & 785 ONLY: ny, & 786 nz 787 788 USE kinds 789 790 USE pegrid 791 792 USE transpose_indices, & 793 ONLY: nxl_y, & 794 nxl_z, & 795 nxr_y, & 796 nxr_z, & 797 nyn_z, & 798 nys_z, & 799 nzb_y, & 800 nzt_y 801 802 IMPLICIT NONE 803 804 INTEGER(iwp) :: i !< 805 INTEGER(iwp) :: j !< 806 INTEGER(iwp) :: k !< 807 808 #if defined( __parallel ) 809 INTEGER(iwp) :: l !< 810 INTEGER(iwp) :: zs !< 811 #endif 812 813 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 814 REAL(wp) :: f_out(nxl_z:nxr_z,nys_z:nyn_z,1:nz) !< 815 816 #if defined( __parallel ) 817 REAL(wp), DIMENSION(nxl_z:nxr_z,nzt_y-nzb_y+1,nys_z:nyn_z,0:pdims(1)-1) :: work !< 759 818 #if __acc_fft_device 760 819 !$ACC DECLARE CREATE(work) … … 764 823 765 824 ! 766 !-- If the PE grid is one-dimensional along y, only local reordering 767 !-- of the data is necessary and notransposition has to be done.825 !-- If the PE grid is one-dimensional along y, only local reordering of the data is necessary and no 826 !-- transposition has to be done. 768 827 IF ( pdims(1) == 1 ) THEN 769 828 … … 799 858 800 859 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 801 CALL MPI_ALLTOALL( f_inv(nxl_y,nzb_y,0), sendrecvcount_yz, MPI_REAL, & 802 work(nxl_z,1,nys_z,0), sendrecvcount_yz, MPI_REAL, & 803 comm1dx, ierr ) 860 CALL MPI_ALLTOALL( f_inv(nxl_y,nzb_y,0), sendrecvcount_yz, MPI_REAL, & 861 work(nxl_z,1,nys_z,0), sendrecvcount_yz, MPI_REAL, comm1dx, ierr ) 804 862 805 863 #if __acc_fft_device … … 840 898 841 899 842 !------------------------------------------------------------------------------ !900 !--------------------------------------------------------------------------------------------------! 843 901 ! Description: 844 902 ! ------------ 845 !> Resorting data for the transposition from z to x. The transposition itself 846 !> is carried out in transpose_zx847 !------------------------------------------------------------------------------ !903 !> Resorting data for the transposition from z to x. The transposition itself is carried out in 904 !> transpose_zx. 905 !--------------------------------------------------------------------------------------------------! 848 906 SUBROUTINE resort_for_zx( f_in, f_inv ) 849 907 850 908 851 USE indices, & 852 ONLY: nxl, nxr, nyn, nys, nz 853 854 USE kinds 855 856 IMPLICIT NONE 857 858 REAL(wp) :: f_in(1:nz,nys:nyn,nxl:nxr) !< 859 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 860 861 INTEGER(iwp) :: i !< 862 INTEGER(iwp) :: j !< 863 INTEGER(iwp) :: k !< 864 865 ! 866 !-- Rearrange indices of input array in order to make data to be send 867 !-- by MPI contiguous 868 !$OMP PARALLEL PRIVATE ( i, j, k ) 869 !$OMP DO 870 #if __acc_fft_device 871 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 872 !$ACC PRESENT(f_in, f_inv) 873 #endif 874 DO i = nxl, nxr 875 DO j = nys, nyn 876 DO k = 1,nz 877 f_inv(j,i,k) = f_in(k,j,i) 878 ENDDO 879 ENDDO 880 ENDDO 881 !$OMP END PARALLEL 882 883 END SUBROUTINE resort_for_zx 884 885 886 !------------------------------------------------------------------------------! 887 ! Description: 888 ! ------------ 889 !> Transposition of input array (f_in) from z to x. For the input array, all 890 !> elements along z reside on the same PE, while after transposition, all 891 !> elements along x reside on the same PE. 892 !------------------------------------------------------------------------------! 893 SUBROUTINE transpose_zx( f_inv, f_out ) 894 895 896 #if defined( __parallel ) 897 USE cpulog, & 898 ONLY: cpu_log, cpu_log_nowait, log_point_s 899 900 USE fft_xy, & 901 ONLY: f_vec_x, temperton_fft_vec 902 #endif 903 904 USE indices, & 905 ONLY: nx, nxl, nxr, nyn, nys, nz 906 #if defined( __parallel ) 907 USE indices, & 908 ONLY: nnx 909 #endif 909 USE indices, & 910 ONLY: nxl, & 911 nxr, & 912 nyn, & 913 nys, & 914 nz 910 915 911 916 USE kinds 912 913 USE pegrid914 915 USE transpose_indices, &916 ONLY: nyn_x, nys_x, nzb_x, nzt_x917 917 918 918 IMPLICIT NONE … … 921 921 INTEGER(iwp) :: j !< 922 922 INTEGER(iwp) :: k !< 923 #if defined( __parallel ) 924 INTEGER(iwp) :: l !< 925 INTEGER(iwp) :: mm !< 926 INTEGER(iwp) :: xs !< 927 #endif 928 929 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 930 REAL(wp) :: f_out(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 931 932 #if defined( __parallel ) 933 REAL(wp), DIMENSION(nys_x:nyn_x,nnx,nzb_x:nzt_x,0:pdims(1)-1) :: work !< 923 924 REAL(wp) :: f_in(1:nz,nys:nyn,nxl:nxr) !< 925 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 926 927 ! 928 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 929 !$OMP PARALLEL PRIVATE ( i, j, k ) 930 !$OMP DO 931 #if __acc_fft_device 932 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 933 !$ACC PRESENT(f_in, f_inv) 934 #endif 935 DO i = nxl, nxr 936 DO j = nys, nyn 937 DO k = 1,nz 938 f_inv(j,i,k) = f_in(k,j,i) 939 ENDDO 940 ENDDO 941 ENDDO 942 !$OMP END PARALLEL 943 944 END SUBROUTINE resort_for_zx 945 946 947 !--------------------------------------------------------------------------------------------------! 948 ! Description: 949 ! ------------ 950 !> Transposition of input array (f_in) from z to x. For the input array, all elements along z reside 951 !> on the same PE, while after transposition, all elements along x reside on the same PE. 952 !--------------------------------------------------------------------------------------------------! 953 SUBROUTINE transpose_zx( f_inv, f_out ) 954 955 956 #if defined( __parallel ) 957 USE cpulog, & 958 ONLY: cpu_log, & 959 cpu_log_nowait, & 960 log_point_s 961 962 USE fft_xy, & 963 ONLY: f_vec_x, & 964 temperton_fft_vec 965 #endif 966 967 USE indices, & 968 ONLY: nx, & 969 nxl, & 970 nxr, & 971 nyn, & 972 nys, & 973 nz 974 975 #if defined( __parallel ) 976 USE indices, & 977 ONLY: nnx 978 #endif 979 980 USE kinds 981 982 USE pegrid 983 984 USE transpose_indices, & 985 ONLY: nyn_x, & 986 nys_x, & 987 nzb_x, & 988 nzt_x 989 990 IMPLICIT NONE 991 992 INTEGER(iwp) :: i !< 993 INTEGER(iwp) :: j !< 994 INTEGER(iwp) :: k !< 995 996 #if defined( __parallel ) 997 INTEGER(iwp) :: l !< 998 INTEGER(iwp) :: mm !< 999 INTEGER(iwp) :: xs !< 1000 #endif 1001 1002 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 1003 REAL(wp) :: f_out(0:nx,nys_x:nyn_x,nzb_x:nzt_x) !< 1004 1005 #if defined( __parallel ) 1006 REAL(wp), DIMENSION(nys_x:nyn_x,nnx,nzb_x:nzt_x,0:pdims(1)-1) :: work !< 934 1007 #if __acc_fft_device 935 1008 !$ACC DECLARE CREATE(work) … … 939 1012 940 1013 ! 941 !-- If the PE grid is one-dimensional along y, only local reordering 942 !-- of the data is necessary and notransposition has to be done.1014 !-- If the PE grid is one-dimensional along y, only local reordering of the data is necessary and no 1015 !-- transposition has to be done. 943 1016 IF ( pdims(1) == 1 ) THEN 944 1017 … … 974 1047 975 1048 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 976 CALL MPI_ALLTOALL( f_inv(nys,nxl,1), sendrecvcount_zx, MPI_REAL, & 977 work(nys_x,1,nzb_x,0), sendrecvcount_zx, MPI_REAL, & 978 comm1dx, ierr ) 1049 CALL MPI_ALLTOALL( f_inv(nys,nxl,1), sendrecvcount_zx, MPI_REAL, & 1050 work(nys_x,1,nzb_x,0), sendrecvcount_zx, MPI_REAL, comm1dx, ierr ) 979 1051 980 1052 #if __acc_fft_device … … 1036 1108 1037 1109 1038 !------------------------------------------------------------------------------ !1110 !--------------------------------------------------------------------------------------------------! 1039 1111 ! Description: 1040 1112 ! ------------ 1041 !> Resorting data after the transposition from z to y. The transposition itself 1042 !> is carried out in transpose_zy1043 !------------------------------------------------------------------------------ !1113 !> Resorting data after the transposition from z to y. The transposition itself is carried out in 1114 !> transpose_zy. 1115 !--------------------------------------------------------------------------------------------------! 1044 1116 SUBROUTINE resort_for_zy( f_inv, f_out ) 1045 1117 1046 1118 1047 USE indices, & 1048 ONLY: ny 1049 1050 USE kinds 1051 1052 USE transpose_indices, & 1053 ONLY: nxl_y, nxr_y, nzb_y, nzt_y 1054 1055 IMPLICIT NONE 1056 1057 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 1058 REAL(wp) :: f_out(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 1059 1060 1061 INTEGER(iwp) :: i !< 1062 INTEGER(iwp) :: j !< 1063 INTEGER(iwp) :: k !< 1064 1065 ! 1066 !-- Rearrange indices of input array in order to make data to be send 1067 !-- by MPI contiguous 1068 !$OMP PARALLEL PRIVATE ( i, j, k ) 1069 !$OMP DO 1070 #if __acc_fft_device 1071 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 1072 !$ACC PRESENT(f_out, f_inv) 1073 #endif 1074 DO k = nzb_y, nzt_y 1075 DO i = nxl_y, nxr_y 1076 DO j = 0, ny 1077 f_out(j,i,k) = f_inv(i,k,j) 1078 ENDDO 1079 ENDDO 1080 ENDDO 1081 !$OMP END PARALLEL 1082 1083 END SUBROUTINE resort_for_zy 1084 1085 1086 !------------------------------------------------------------------------------! 1087 ! Description:cpu_log_nowait 1088 ! ------------ 1089 !> Transposition of input array (f_in) from z to y. For the input array, all 1090 !> elements along z reside on the same PE, while after transposition, all 1091 !> elements along y reside on the same PE. 1092 !------------------------------------------------------------------------------! 1093 SUBROUTINE transpose_zy( f_in, f_inv ) 1094 1095 1096 #if defined( __parallel ) 1097 USE cpulog, & 1098 ONLY: cpu_log, cpu_log_nowait, log_point_s 1099 #endif 1100 1101 USE indices, & 1102 ONLY: ny, nz 1119 USE indices, & 1120 ONLY: ny 1103 1121 1104 1122 USE kinds 1105 1123 1106 USE pegrid 1107 1108 USE transpose_indices, & 1109 ONLY: nxl_y, nxl_z, nxr_y, nxr_z, nyn_z, nys_z, nzb_y, nzt_y 1124 USE transpose_indices, & 1125 ONLY: nxl_y, & 1126 nxr_y, & 1127 nzb_y, & 1128 nzt_y 1110 1129 1111 1130 IMPLICIT NONE … … 1114 1133 INTEGER(iwp) :: j !< 1115 1134 INTEGER(iwp) :: k !< 1116 #if defined( __parallel ) 1117 INTEGER(iwp) :: l !< 1118 INTEGER(iwp) :: zs !< 1119 #endif 1120 1121 REAL(wp) :: f_in(nxl_z:nxr_z,nys_z:nyn_z,1:nz) !< 1122 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 1123 1124 #if defined( __parallel ) 1125 REAL(wp), DIMENSION(nxl_z:nxr_z,nzt_y-nzb_y+1,nys_z:nyn_z,0:pdims(1)-1) :: work !< 1135 1136 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 1137 REAL(wp) :: f_out(0:ny,nxl_y:nxr_y,nzb_y:nzt_y) !< 1138 1139 ! 1140 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 1141 !$OMP PARALLEL PRIVATE ( i, j, k ) 1142 !$OMP DO 1143 #if __acc_fft_device 1144 !$ACC PARALLEL LOOP COLLAPSE(3) PRIVATE(i,j,k) & 1145 !$ACC PRESENT(f_out, f_inv) 1146 #endif 1147 DO k = nzb_y, nzt_y 1148 DO i = nxl_y, nxr_y 1149 DO j = 0, ny 1150 f_out(j,i,k) = f_inv(i,k,j) 1151 ENDDO 1152 ENDDO 1153 ENDDO 1154 !$OMP END PARALLEL 1155 1156 END SUBROUTINE resort_for_zy 1157 1158 1159 !--------------------------------------------------------------------------------------------------! 1160 ! Description:cpu_log_nowait 1161 ! ------------ 1162 !> Transposition of input array (f_in) from z to y. For the input array, all elements along z reside 1163 !> on the same PE, while after transposition, all elements along y reside on the same PE. 1164 !--------------------------------------------------------------------------------------------------! 1165 SUBROUTINE transpose_zy( f_in, f_inv ) 1166 1167 1168 #if defined( __parallel ) 1169 USE cpulog, & 1170 ONLY: cpu_log, & 1171 cpu_log_nowait, & 1172 log_point_s 1173 #endif 1174 1175 USE indices, & 1176 ONLY: ny, & 1177 nz 1178 1179 USE kinds 1180 1181 USE pegrid 1182 1183 USE transpose_indices, & 1184 ONLY: nxl_y, & 1185 nxl_z, & 1186 nxr_y, & 1187 nxr_z, & 1188 nyn_z, & 1189 nys_z, & 1190 nzb_y, & 1191 nzt_y 1192 1193 IMPLICIT NONE 1194 1195 INTEGER(iwp) :: i !< 1196 INTEGER(iwp) :: j !< 1197 INTEGER(iwp) :: k !< 1198 1199 #if defined( __parallel ) 1200 INTEGER(iwp) :: l !< 1201 INTEGER(iwp) :: zs !< 1202 #endif 1203 1204 REAL(wp) :: f_in(nxl_z:nxr_z,nys_z:nyn_z,1:nz) !< 1205 REAL(wp) :: f_inv(nxl_y:nxr_y,nzb_y:nzt_y,0:ny) !< 1206 1207 #if defined( __parallel ) 1208 REAL(wp), DIMENSION(nxl_z:nxr_z,nzt_y-nzb_y+1,nys_z:nyn_z,0:pdims(1)-1) :: work !< 1126 1209 #if __acc_fft_device 1127 1210 !$ACC DECLARE CREATE(work) … … 1130 1213 1131 1214 ! 1132 !-- If the PE grid is one-dimensional along y, the array has only to be 1133 !-- reordered locally andtherefore no transposition has to be done.1215 !-- If the PE grid is one-dimensional along y, the array has only to be reordered locally and 1216 !-- therefore no transposition has to be done. 1134 1217 IF ( pdims(1) /= 1 ) THEN 1135 1218 … … 1169 1252 1170 1253 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 1171 CALL MPI_ALLTOALL( work(nxl_z,1,nys_z,0), sendrecvcount_yz, MPI_REAL, & 1172 f_inv(nxl_y,nzb_y,0), sendrecvcount_yz, MPI_REAL, & 1173 comm1dx, ierr ) 1254 CALL MPI_ALLTOALL( work(nxl_z,1,nys_z,0), sendrecvcount_yz, MPI_REAL, & 1255 f_inv(nxl_y,nzb_y,0), sendrecvcount_yz, MPI_REAL, comm1dx, ierr ) 1174 1256 1175 1257 #if __acc_fft_device … … 1207 1289 1208 1290 1209 !------------------------------------------------------------------------------ !1291 !--------------------------------------------------------------------------------------------------! 1210 1292 ! Description: 1211 1293 ! ------------ 1212 !> Transposition of input array (f_in) from z to y. For the input array, all 1213 !> elements along z reside on the same PE, while after transposition, all 1214 !> elements along y reside on the same PE. 1215 !> This is a direct transposition for arrays with indices in regular order 1216 !> (k,j,i) (cf. transpose_zy). 1217 !------------------------------------------------------------------------------! 1294 !> Transposition of input array (f_in) from z to y. For the input array, all elements along z reside 1295 !> on the same PE, while after transposition, all elements along y reside on the same PE. This is a 1296 !> direct transposition for arrays with indices in regular order (k,j,i) (cf. transpose_zy). 1297 !--------------------------------------------------------------------------------------------------! 1218 1298 #if defined( __parallel ) 1219 1299 SUBROUTINE transpose_zyd( f_in, f_out ) 1220 1300 1221 1301 1222 USE cpulog, & 1223 ONLY: cpu_log, log_point_s 1224 1225 USE indices, & 1226 ONLY: nnx, nny, nnz, nxl, nxr, nyn, nys, ny, nz 1302 USE cpulog, & 1303 ONLY: cpu_log, & 1304 log_point_s 1305 1306 USE indices, & 1307 ONLY: nnx, & 1308 nny, & 1309 nnz, & 1310 nxl, & 1311 nxr, & 1312 nyn, & 1313 nys, & 1314 ny, & 1315 nz 1227 1316 1228 1317 USE kinds … … 1230 1319 USE pegrid 1231 1320 1232 USE transpose_indices, & 1233 ONLY: nxl_yd, nxr_yd, nzb_yd, nzt_yd 1321 USE transpose_indices, & 1322 ONLY: nxl_yd, & 1323 nxr_yd, & 1324 nzb_yd, & 1325 nzt_yd 1234 1326 1235 1327 IMPLICIT NONE 1236 1328 1237 INTEGER(iwp) :: i !< 1238 INTEGER(iwp) :: j !< 1239 INTEGER(iwp) :: k !< 1240 INTEGER(iwp) :: l !< 1241 INTEGER(iwp) :: m !< 1242 INTEGER(iwp) :: ys !< 1243 1244 REAL(wp) :: f_in(1:nz,nys:nyn,nxl:nxr) !< 1245 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 1246 REAL(wp) :: f_out(0:ny,nxl_yd:nxr_yd,nzb_yd:nzt_yd) !< 1247 REAL(wp) :: work(nnx*nny*nnz) !< 1248 1249 ! 1250 !-- Rearrange indices of input array in order to make data to be send 1251 !-- by MPI contiguous 1329 INTEGER(iwp) :: i !< 1330 INTEGER(iwp) :: j !< 1331 INTEGER(iwp) :: k !< 1332 INTEGER(iwp) :: l !< 1333 INTEGER(iwp) :: m !< 1334 INTEGER(iwp) :: ys !< 1335 1336 REAL(wp) :: f_in(1:nz,nys:nyn,nxl:nxr) !< 1337 REAL(wp) :: f_inv(nys:nyn,nxl:nxr,1:nz) !< 1338 REAL(wp) :: f_out(0:ny,nxl_yd:nxr_yd,nzb_yd:nzt_yd) !< 1339 REAL(wp) :: work(nnx*nny*nnz) !< 1340 1341 ! 1342 !-- Rearrange indices of input array in order to make data to be send by MPI contiguous. 1252 1343 DO i = nxl, nxr 1253 1344 DO j = nys, nyn … … 1259 1350 1260 1351 ! 1261 !-- Move data to different array, because memory location of work1 is 1262 !-- needed further below (work1 = work2). 1263 !-- If the PE grid is one-dimensional along x, only local reordering 1264 !-- of the data is necessary and no transposition has to be done. 1352 !-- Move data to different array, because memory location of work1 is needed further below 1353 !-- (work1 = work2). If the PE grid is one-dimensional along x, only local reordering of the data is 1354 !-- necessary and no transposition has to be done. 1265 1355 IF ( pdims(2) == 1 ) THEN 1266 1356 DO k = 1, nz … … 1278 1368 CALL cpu_log( log_point_s(32), 'mpi_alltoall', 'start' ) 1279 1369 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 1280 CALL MPI_ALLTOALL( f_inv(nys,nxl,1), sendrecvcount_zyd, MPI_REAL, & 1281 work(1), sendrecvcount_zyd, MPI_REAL, & 1282 comm1dy, ierr ) 1370 CALL MPI_ALLTOALL( f_inv(nys,nxl,1), sendrecvcount_zyd, MPI_REAL, & 1371 work(1), sendrecvcount_zyd, MPI_REAL, comm1dy, ierr ) 1283 1372 CALL cpu_log( log_point_s(32), 'mpi_alltoall', 'stop' ) 1284 1373
Note: See TracChangeset
for help on using the changeset viewer.