Changeset 4648 for palm/trunk/SOURCE/lagrangian_particle_model_mod.f90
- Timestamp:
- Aug 25, 2020 7:52:08 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/lagrangian_particle_model_mod.f90
r4629 r4648 1 1 !> @file lagrangian_particle_model_mod.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 !--------------------------------------------------------------------------------------------------! 19 18 ! 20 19 ! Current revisions: … … 25 24 ! ----------------- 26 25 ! $Id$ 26 ! file re-formatted to follow the PALM coding standard 27 ! 28 ! 4629 2020-07-29 09:37:56Z raasch 27 29 ! support for MPI Fortran77 interface (mpif.h) removed 28 30 ! … … 32 34 ! 4616 2020-07-21 10:09:46Z schwenkel 33 35 ! Bugfix in case of strechting: k-calculation limited lower bound of 1 34 ! 36 ! 35 37 ! 4589 2020-07-06 12:34:09Z suehring 36 38 ! remove unused variables 37 ! 39 ! 38 40 ! 4588 2020-07-06 11:06:02Z suehring 39 41 ! Simplify particle-speed interpolation in logarithmic layer 40 ! 42 ! 41 43 ! 4585 2020-06-30 15:05:20Z suehring 42 ! Limit logarithmically interpolated particle speed to the velocity component 43 ! at the first prognostic grid point (since no stability corrected interpolation44 ! is employed the particle speedcould be overestimated in unstable conditions).45 ! 44 ! Limit logarithmically interpolated particle speed to the velocity component at the first 45 ! prognostic grid point (since no stability corrected interpolation is employed the particle speed 46 ! could be overestimated in unstable conditions). 47 ! 46 48 ! 4546 2020-05-24 12:16:41Z raasch 47 49 ! Variables iran and iran_part completely removed, added I/O of parallel random numbers to restart 48 50 ! file 49 ! 51 ! 50 52 ! 4545 2020-05-22 13:17:57Z schwenkel 51 53 ! Using parallel random generator, thus preventing dependency of PE number 52 ! 54 ! 53 55 ! 4535 2020-05-15 12:07:23Z raasch 54 56 ! bugfix for restart data format query 55 ! 57 ! 56 58 ! 4520 2020-05-06 08:57:19Z schwenkel 57 59 ! Add error number 58 ! 60 ! 59 61 ! 4517 2020-05-03 14:29:30Z raasch 60 62 ! restart data handling with MPI-IO added 61 ! 63 ! 62 64 ! 4471 2020-03-24 12:08:06Z schwenkel 63 65 ! Bugfix in lpm_droplet_interactions_ptq 64 ! 66 ! 65 67 ! 4457 2020-03-11 14:20:43Z raasch 66 68 ! use statement for exchange horiz added 67 ! 69 ! 68 70 ! 4444 2020-03-05 15:59:50Z raasch 69 71 ! bugfix: cpp-directives for serial mode added 70 ! 72 ! 71 73 ! 4430 2020-02-27 18:02:20Z suehring 72 ! - Bugfix in logarithmic interpolation of near-ground particle speed (density 73 ! was not considered). 74 ! - Bugfix in logarithmic interpolation of near-ground particle speed (density was not considered). 74 75 ! - Revise CFL-check when SGS particle speeds are considered. 75 ! - In nested case with SGS particle speeds in the child domain, do not give 76 ! warning that particles are on domain boundaries. At the end of the particle77 ! t ime integration these will be transferred to the parent domain anyhow.78 ! 76 ! - In nested case with SGS particle speeds in the child domain, do not give warning that particles 77 ! are on domain boundaries. At the end of the particle time integration these will be transferred 78 ! to the parent domain anyhow. 79 ! 79 80 ! 4360 2020-01-07 11:25:50Z suehring 80 ! Introduction of wall_flags_total_0, which currently sets bits based on static 81 ! topographyinformation used in wall_flags_static_082 ! 81 ! Introduction of wall_flags_total_0, which currently sets bits based on static topography 82 ! information used in wall_flags_static_0 83 ! 83 84 ! 4336 2019-12-13 10:12:05Z raasch 84 ! bugfix: wrong header output of particle group features (density ratio) in case 85 ! of restartscorrected86 ! 85 ! bugfix: wrong header output of particle group features (density ratio) in case of restarts 86 ! corrected 87 ! 87 88 ! 4329 2019-12-10 15:46:36Z motisi 88 89 ! Renamed wall_flags_0 to wall_flags_static_0 89 ! 90 ! 90 91 ! 4282 2019-10-29 16:18:46Z schwenkel 91 92 ! Bugfix of particle timeseries in case of more than one particle group 92 ! 93 ! 93 94 ! 4277 2019-10-28 16:53:23Z schwenkel 94 95 ! Bugfix: Added first_call_lpm in use statement 95 ! 96 ! 96 97 ! 4276 2019-10-28 16:03:29Z schwenkel 97 98 ! Modularize lpm: Move conditions in time intergration to module 98 ! 99 ! 99 100 ! 4275 2019-10-28 15:34:55Z schwenkel 100 ! Change call of simple predictor corrector method, i.e. two divergence free 101 ! velocitiy fields arenow used.101 ! Change call of simple predictor corrector method, i.e. two divergence free velocitiy fields are 102 ! now used. 102 103 ! 103 104 ! 4232 2019-09-20 09:34:22Z knoop 104 105 ! Removed INCLUDE "mpif.h", as it is not needed because of USE pegrid 105 ! 106 ! 106 107 ! 4195 2019-08-28 13:44:27Z schwenkel 107 ! Bugfix for simple_corrector interpolation method in case of ocean runs and 108 ! output particleadvection interpolation method into header109 ! 108 ! Bugfix for simple_corrector interpolation method in case of ocean runs and output particle 109 ! advection interpolation method into header 110 ! 110 111 ! 4182 2019-08-22 15:20:23Z scharf 111 112 ! Corrected "Former revisions" section 112 ! 113 ! 113 114 ! 4168 2019-08-16 13:50:17Z suehring 114 115 ! Replace function get_topography_top_index by topo_top_ind 115 ! 116 ! 116 117 ! 4145 2019-08-06 09:55:22Z schwenkel 117 118 ! Some reformatting 118 ! 119 ! 119 120 ! 4144 2019-08-06 09:11:47Z raasch 120 121 ! relational operators .EQ., .NE., etc. replaced by ==, /=, etc. 121 ! 122 ! 122 123 ! 4143 2019-08-05 15:14:53Z schwenkel 123 124 ! Rename variable and change select case to if statement 124 ! 125 ! 125 126 ! 4122 2019-07-26 13:11:56Z schwenkel 126 127 ! Implement reset method as bottom boundary condition 127 ! 128 ! 128 129 ! 4121 2019-07-26 10:01:22Z schwenkel 129 ! Implementation of an simple method for interpolating the velocities to 130 ! particle position 131 ! 130 ! Implementation of an simple method for interpolating the velocities to particle position 131 ! 132 132 ! 4114 2019-07-23 14:09:27Z schwenkel 133 133 ! Bugfix: Added working precision for if statement 134 ! 134 ! 135 135 ! 4054 2019-06-27 07:42:18Z raasch 136 136 ! bugfix for calculating the minimum particle time step 137 ! 137 ! 138 138 ! 4044 2019-06-19 12:28:27Z schwenkel 139 139 ! Bugfix in case of grid strecting: corrected calculation of k-Index … … 141 141 ! 4043 2019-06-18 16:59:00Z schwenkel 142 142 ! Remove min_nr_particle, Add lpm_droplet_interactions_ptq into module 143 ! 143 ! 144 144 ! 4028 2019-06-13 12:21:37Z schwenkel 145 145 ! Further modularization of particle code components 146 ! 146 ! 147 147 ! 4020 2019-06-06 14:57:48Z schwenkel 148 ! Removing submodules 149 ! 148 ! Removing submodules 149 ! 150 150 ! 4018 2019-06-06 13:41:50Z eckhard 151 151 ! Bugfix for former revision 152 ! 152 ! 153 153 ! 4017 2019-06-06 12:16:46Z schwenkel 154 154 ! Modularization of all lagrangian particle model code components 155 ! 156 ! 3655 2019-01-07 16:51:22Z knoop 157 ! bugfix to guarantee correct particle releases in case that the release 158 ! interval is smaller thanthe model timestep155 ! 156 ! 3655 2019-01-07 16:51:22Z knoop 157 ! bugfix to guarantee correct particle releases in case that the release interval is smaller than 158 ! the model timestep 159 159 ! 160 160 ! Revision 1.1 1999/11/25 16:16:06 raasch … … 164 164 ! Description: 165 165 ! ------------ 166 !> The embedded LPM allows for studying transport and dispersion processes within 167 !> turbulent flows. This model including passive particles that do not show any 168 !> feedback on the turbulent flow. Further also particles with inertia and 169 !> cloud droplets ca be simulated explicitly. 166 !> The embedded LPM allows for studying transport and dispersion processes within turbulent flows. 167 !> This model is including passive particles that do not show any feedback on the turbulent flow. 168 !> Further also particles with inertia and cloud droplets can be simulated explicitly. 170 169 !> 171 170 !> @todo test lcm … … 173 172 !> @note <Enter notes on the module> 174 173 !> @bug <Enter bug on the module> 175 !------------------------------------------------------------------------------ !174 !--------------------------------------------------------------------------------------------------! 176 175 MODULE lagrangian_particle_model_mod 177 176 178 177 USE, INTRINSIC :: ISO_C_BINDING 179 178 180 USE arrays_3d, & 181 ONLY: de_dx, de_dy, de_dz, & 182 d_exner, & 183 dzw, zu, zw, ql_c, ql_v, ql_vp, hyp, & 184 pt, q, exner, ql, diss, e, u, v, w, km, ql_1, ql_2 185 186 USE averaging, & 187 ONLY: ql_c_av, pr_av, pc_av, ql_vp_av, ql_v_av 188 189 USE basic_constants_and_equations_mod, & 190 ONLY: molecular_weight_of_solute, molecular_weight_of_water, magnus, & 191 pi, rd_d_rv, rho_l, r_v, rho_s, vanthoff, l_v, kappa, g, lv_d_cp 192 193 USE control_parameters, & 194 ONLY: bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r, bc_dirichlet_s, & 195 child_domain, & 196 cloud_droplets, constant_flux_layer, current_timestep_number, & 197 dt_3d, dt_3d_reached, debug_output, first_call_lpm, humidity, & 198 dt_3d_reached_l, dt_dopts, dz, initializing_actions, & 199 intermediate_timestep_count, intermediate_timestep_count_max, & 200 message_string, molecular_viscosity, ocean_mode, & 201 particle_maximum_age, restart_data_format_input, & 202 restart_data_format_output, & 203 simulated_time, topography, dopts_time_count, & 204 time_since_reference_point, rho_surface, u_gtrans, v_gtrans, & 205 dz_stretch_level, dz_stretch_level_start 206 207 USE cpulog, & 179 USE arrays_3d, & 180 ONLY: d_exner, de_dx, de_dy, de_dz, diss, dzw, e, exner, hyp, km, pt, q, ql, ql_1, ql_2, & 181 ql_c, ql_v, ql_vp, u, v, w, zu, zw 182 183 USE averaging, & 184 ONLY: pc_av, pr_av, ql_c_av, ql_v_av, ql_vp_av 185 186 USE basic_constants_and_equations_mod, & 187 ONLY: g, kappa, l_v, lv_d_cp, magnus, molecular_weight_of_solute, & 188 molecular_weight_of_water, pi, r_v, rd_d_rv, rho_l, rho_s, vanthoff 189 190 USE control_parameters, & 191 ONLY: bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r, bc_dirichlet_s, & 192 child_domain, cloud_droplets, constant_flux_layer, current_timestep_number, & 193 debug_output, dopts_time_count, dt_3d, dt_3d_reached, dt_3d_reached_l, dt_dopts, dz,& 194 dz_stretch_level, dz_stretch_level_start, first_call_lpm, humidity, & 195 initializing_actions, intermediate_timestep_count, intermediate_timestep_count_max, & 196 message_string, molecular_viscosity, ocean_mode, particle_maximum_age, & 197 restart_data_format_input, restart_data_format_output, rho_surface, simulated_time, & 198 time_since_reference_point, topography, u_gtrans, v_gtrans 199 200 USE cpulog, & 208 201 ONLY: cpu_log, log_point, log_point_s 209 202 210 USE indices, & 211 ONLY: nx, nxl, nxlg, nxrg, nxr, ny, nyn, nys, nyng, nysg, nz, nzb, & 212 nzb_max, nzt,nbgp, ngp_2dh_outer, & 213 topo_top_ind, & 214 wall_flags_total_0 203 USE indices, & 204 ONLY: nbgp, ngp_2dh_outer, nx, nxl, nxlg, nxrg, nxr, ny, nyn, nys, nyng, nysg, nz, nzb, & 205 nzb_max, nzt, topo_top_ind, wall_flags_total_0 215 206 216 207 USE kinds … … 221 212 222 213 #if defined( __parallel ) 223 USE pmc_particle_interface, & 224 ONLY: pmcp_c_get_particle_from_parent, pmcp_p_fill_particle_win, & 225 pmcp_c_send_particle_to_parent, pmcp_p_empty_particle_win, & 226 pmcp_p_delete_particles_in_fine_grid_area, pmcp_g_init, & 227 pmcp_g_print_number_of_particles 214 USE pmc_particle_interface, & 215 ONLY: pmcp_c_get_particle_from_parent, pmcp_c_send_particle_to_parent, pmcp_g_init, & 216 pmcp_g_print_number_of_particles, pmcp_p_delete_particles_in_fine_grid_area, & 217 pmcp_p_empty_particle_win, pmcp_p_fill_particle_win 228 218 #endif 229 219 230 USE pmc_interface, &220 USE pmc_interface, & 231 221 ONLY: nested_run 232 222 233 USE grid_variables, &223 USE grid_variables, & 234 224 ONLY: ddx, dx, ddy, dy 235 225 236 USE netcdf_interface, & 237 ONLY: netcdf_data_format, netcdf_deflate, dopts_num, id_set_pts, & 238 id_var_dopts, id_var_time_pts, nc_stat, & 239 netcdf_handle_error 240 241 USE random_generator_parallel, & 242 ONLY: init_parallel_random_generator, & 243 random_dummy, & 244 random_number_parallel, & 245 random_number_parallel_gauss, & 246 random_seed_parallel, & 247 id_random_array 248 249 USE restart_data_mpi_io_mod, & 250 ONLY: rd_mpi_io_check_array, & 251 rd_mpi_io_check_open, & 252 rd_mpi_io_close, & 253 rd_mpi_io_open, & 254 rd_mpi_io_particle_filetypes, & 255 rrd_mpi_io, & 256 rrd_mpi_io_global_array, & 257 rrd_mpi_io_particles, & 258 wrd_mpi_io, & 259 wrd_mpi_io_global_array, & 226 USE netcdf_interface, & 227 ONLY: dopts_num, id_set_pts, id_var_dopts, id_var_time_pts, nc_stat, netcdf_data_format, & 228 netcdf_deflate, netcdf_handle_error 229 230 USE random_generator_parallel, & 231 ONLY: init_parallel_random_generator, & 232 id_random_array, & 233 random_dummy, & 234 random_number_parallel, & 235 random_number_parallel_gauss, & 236 random_seed_parallel 237 238 USE restart_data_mpi_io_mod, & 239 ONLY: rd_mpi_io_check_array, & 240 rd_mpi_io_check_open, & 241 rd_mpi_io_close, & 242 rd_mpi_io_open, & 243 rd_mpi_io_particle_filetypes, & 244 rrd_mpi_io, & 245 rrd_mpi_io_global_array, & 246 rrd_mpi_io_particles, & 247 wrd_mpi_io, & 248 wrd_mpi_io_global_array, & 260 249 wrd_mpi_io_particles 261 250 262 USE statistics, &251 USE statistics, & 263 252 ONLY: hom 264 253 265 USE surface_mod, &266 ONLY: bc_h, &267 surf_def_h, &268 surf_lsm_h, &254 USE surface_mod, & 255 ONLY: bc_h, & 256 surf_def_h, & 257 surf_lsm_h, & 269 258 surf_usm_h 270 259 … … 283 272 IMPLICIT NONE 284 273 274 INTEGER(iwp), PARAMETER :: nr_2_direction_move = 10000 !< 275 INTEGER(iwp), PARAMETER :: phase_init = 1 !< 276 INTEGER(iwp), PARAMETER, PUBLIC :: phase_release = 2 !< 277 278 REAL(wp), PARAMETER :: c_0 = 3.0_wp !< parameter for lagrangian timescale 279 285 280 CHARACTER(LEN=15) :: aero_species = 'nacl' !< aerosol species 286 281 CHARACTER(LEN=15) :: aero_type = 'maritime' !< aerosol type 282 CHARACTER(LEN=15) :: bc_par_b = 'reflect' !< bottom boundary condition 287 283 CHARACTER(LEN=15) :: bc_par_lr = 'cyclic' !< left/right boundary condition 288 284 CHARACTER(LEN=15) :: bc_par_ns = 'cyclic' !< north/south boundary condition 289 CHARACTER(LEN=15) :: bc_par_b = 'reflect' !< bottom boundary condition290 285 CHARACTER(LEN=15) :: bc_par_t = 'absorb' !< top boundary condition 291 286 CHARACTER(LEN=15) :: collision_kernel = 'none' !< collision kernel … … 296 291 CHARACTER(LEN=25) :: particle_advection_interpolation = 'trilinear' !< interpolation method for calculatin the particle 297 292 298 INTEGER(iwp) :: deleted_particles = 0 !< number of deleted particles per time step 293 INTEGER(iwp) :: deleted_particles = 0 !< number of deleted particles per time step 299 294 INTEGER(iwp) :: i_splitting_mode !< dummy for splitting mode 295 INTEGER(iwp) :: isf !< dummy for splitting function 300 296 INTEGER(iwp) :: max_number_particles_per_gridbox = 100 !< namelist parameter (see documentation) 301 INTEGER(iwp) :: isf !< dummy for splitting function302 297 INTEGER(iwp) :: number_particles_per_gridbox = -1 !< namelist parameter (see documentation) 303 INTEGER(iwp) :: number_of_sublayers = 20 !< number of sublayers for particle velocities betwenn surface and first grid level 304 INTEGER(iwp) :: offset_ocean_nzt = 0 !< in case of oceans runs, the vertical index calculations need an offset 305 INTEGER(iwp) :: offset_ocean_nzt_m1 = 0 !< in case of oceans runs, the vertical index calculations need an offset 298 INTEGER(iwp) :: number_of_sublayers = 20 !< number of sublayers for particle velocities betwenn surface 299 !< and first grid level 300 INTEGER(iwp) :: offset_ocean_nzt = 0 !< in case of oceans runs, the vertical index calculations need 301 !< an offset 302 INTEGER(iwp) :: offset_ocean_nzt_m1 = 0 !< in case of oceans runs, the vertical index calculations need 303 !< an offset 306 304 INTEGER(iwp) :: particles_per_point = 1 !< namelist parameter (see documentation) 307 305 INTEGER(iwp) :: radius_classes = 20 !< namelist parameter (see documentation) … … 310 308 INTEGER(iwp) :: step_dealloc = 100 !< namelist parameter (see documentation) 311 309 INTEGER(iwp) :: total_number_of_particles !< total number of particles in the whole model domain 310 INTEGER(iwp) :: trlp_count_recv_sum !< parameter for particle exchange of PEs 312 311 INTEGER(iwp) :: trlp_count_sum !< parameter for particle exchange of PEs 313 INTEGER(iwp) :: tr lp_count_recv_sum !< parameter for particle exchange of PEs312 INTEGER(iwp) :: trrp_count_recv_sum !< parameter for particle exchange of PEs 314 313 INTEGER(iwp) :: trrp_count_sum !< parameter for particle exchange of PEs 315 INTEGER(iwp) :: tr rp_count_recv_sum !< parameter for particle exchange of PEs314 INTEGER(iwp) :: trsp_count_recv_sum !< parameter for particle exchange of PEs 316 315 INTEGER(iwp) :: trsp_count_sum !< parameter for particle exchange of PEs 317 INTEGER(iwp) :: tr sp_count_recv_sum !< parameter for particle exchange of PEs316 INTEGER(iwp) :: trnp_count_recv_sum !< parameter for particle exchange of PEs 318 317 INTEGER(iwp) :: trnp_count_sum !< parameter for particle exchange of PEs 319 INTEGER(iwp) :: trnp_count_recv_sum !< parameter for particle exchange of PEs320 318 321 319 INTEGER(isp), DIMENSION(:,:,:), ALLOCATABLE :: seq_random_array_particles !< sequence of random array for particle 322 320 323 LOGICAL :: lagrangian_particle_model = .FALSE. !< namelist parameter (see documentation)324 321 LOGICAL :: curvature_solution_effects = .FALSE. !< namelist parameter (see documentation) 325 322 LOGICAL :: deallocate_memory = .TRUE. !< namelist parameter (see documentation) 326 323 LOGICAL :: hall_kernel = .FALSE. !< flag for collision kernel 324 LOGICAL :: interpolation_simple_corrector = .FALSE. !< flag for simple particle advection interpolation with corrector step 325 LOGICAL :: interpolation_simple_predictor = .FALSE. !< flag for simple particle advection interpolation with predictor step 326 LOGICAL :: interpolation_trilinear = .FALSE. !< flag for trilinear particle advection interpolation 327 LOGICAL :: lagrangian_particle_model = .FALSE. !< namelist parameter (see documentation) 327 328 LOGICAL :: merging = .FALSE. !< namelist parameter (see documentation) 328 329 LOGICAL :: random_start_position = .FALSE. !< namelist parameter (see documentation) … … 332 333 LOGICAL :: use_kernel_tables = .FALSE. !< parameter, which turns on the use of precalculated collision kernels 333 334 LOGICAL :: write_particle_statistics = .FALSE. !< namelist parameter (see documentation) 334 LOGICAL :: interpolation_simple_predictor = .FALSE. !< flag for simple particle advection interpolation with predictor step 335 LOGICAL :: interpolation_simple_corrector = .FALSE. !< flag for simple particle advection interpolation with corrector step 336 LOGICAL :: interpolation_trilinear = .FALSE. !< flag for trilinear particle advection interpolation 337 338 LOGICAL, DIMENSION(max_number_of_particle_groups) :: vertical_particle_advection = .TRUE. !< Switch for vertical particle transport 335 336 LOGICAL, DIMENSION(max_number_of_particle_groups) :: vertical_particle_advection = .TRUE. !< Switch for vertical particle 337 !< transport 339 338 340 339 REAL(wp) :: aero_weight = 1.0_wp !< namelist parameter (see documentation) … … 342 341 REAL(wp) :: dt_prel = 9999999.9_wp !< namelist parameter (see documentation) 343 342 REAL(wp) :: dt_write_particle_data = 9999999.9_wp !< namelist parameter (see documentation) 343 REAL(wp) :: epsilon_collision !< 344 344 REAL(wp) :: end_time_prel = 9999999.9_wp !< namelist parameter (see documentation) 345 345 REAL(wp) :: initial_weighting_factor = 1.0_wp !< namelist parameter (see documentation) … … 350 350 REAL(wp) :: radius_merge = 1.0E-7_wp !< namelist parameter (see documentation) 351 351 REAL(wp) :: radius_split = 40.0E-6_wp !< namelist parameter (see documentation) 352 REAL(wp) :: rclass_lbound !< 353 REAL(wp) :: rclass_ubound !< 352 354 REAL(wp) :: rm(3) = 1.0E-6_wp !< namelist parameter (see documentation) 353 355 REAL(wp) :: sgs_wf_part !< parameter for sgs 354 356 REAL(wp) :: time_write_particle_data = 0.0_wp !< write particle data at current time on file 357 REAL(wp) :: urms !< 355 358 REAL(wp) :: weight_factor_merge = -1.0_wp !< namelist parameter (see documentation) 356 359 REAL(wp) :: weight_factor_split = -1.0_wp !< namelist parameter (see documentation) 357 360 REAL(wp) :: z0_av_global !< horizontal mean value of z0 358 359 REAL(wp) :: rclass_lbound !<360 REAL(wp) :: rclass_ubound !<361 362 REAL(wp), PARAMETER :: c_0 = 3.0_wp !< parameter for lagrangian timescale363 361 364 362 REAL(wp), DIMENSION(max_number_of_particle_groups) :: density_ratio = 9999999.9_wp !< namelist parameter (see documentation) … … 376 374 REAL(wp), DIMENSION(:), ALLOCATABLE :: log_z_z0 !< Precalculate LOG(z/z0) 377 375 378 INTEGER(iwp), PARAMETER :: NR_2_direction_move = 10000 !<379 380 376 #if defined( __parallel ) 381 377 INTEGER(iwp) :: nr_move_north !< … … 385 381 TYPE(particle_type), DIMENSION(:), ALLOCATABLE :: move_also_south 386 382 #endif 387 388 REAL(wp) :: epsilon_collision !<389 REAL(wp) :: urms !<390 383 391 384 REAL(wp), DIMENSION(:), ALLOCATABLE :: epsclass !< dissipation rate class … … 404 397 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: w_t !< w value of old timelevel t 405 398 406 407 INTEGER(iwp), PARAMETER :: PHASE_INIT = 1 !<408 INTEGER(iwp), PARAMETER, PUBLIC :: PHASE_RELEASE = 2 !<409 410 399 SAVE 411 400 412 401 PRIVATE 413 402 414 PUBLIC lpm_parin, &415 lpm_header, &416 lpm_init_arrays, &417 lpm_init, &418 lpm_actions, &419 lpm_data_output_ptseries, &420 lpm_interaction_droplets_ptq, &421 lpm_rrd_local_particles, &422 lpm_wrd_local, &423 lpm_rrd_global, &424 lpm_wrd_global, &425 lpm_rrd_local, &403 PUBLIC lpm_parin, & 404 lpm_header, & 405 lpm_init_arrays, & 406 lpm_init, & 407 lpm_actions, & 408 lpm_data_output_ptseries, & 409 lpm_interaction_droplets_ptq, & 410 lpm_rrd_local_particles, & 411 lpm_wrd_local, & 412 lpm_rrd_global, & 413 lpm_wrd_global, & 414 lpm_rrd_local, & 426 415 lpm_check_parameters 427 416 … … 443 432 MODULE PROCEDURE lpm_init_arrays 444 433 END INTERFACE lpm_init_arrays 445 434 446 435 INTERFACE lpm_init 447 436 MODULE PROCEDURE lpm_init … … 544 533 545 534 CONTAINS 546 547 548 !------------------------------------------------------------------------------ !535 536 537 !--------------------------------------------------------------------------------------------------! 549 538 ! Description: 550 539 ! ------------ 551 540 !> Parin for &particle_parameters for the Lagrangian particle model 552 !------------------------------------------------------------------------------ !541 !--------------------------------------------------------------------------------------------------! 553 542 SUBROUTINE lpm_parin 554 543 555 544 CHARACTER (LEN=80) :: line !< 556 545 557 NAMELIST /particles_par/ &558 aero_species, &559 aero_type, &560 aero_weight, &561 alloc_factor, &562 bc_par_b, &563 bc_par_lr, &564 bc_par_ns, &565 bc_par_t, &566 collision_kernel, &567 curvature_solution_effects, &568 deallocate_memory, &569 density_ratio, &570 dissipation_classes, &571 dt_dopts, &572 dt_min_part, &573 dt_prel, &574 dt_write_particle_data, &575 end_time_prel, &576 initial_weighting_factor, &577 log_sigma, &578 max_number_particles_per_gridbox, &579 merging, &580 na, &581 number_concentration, &582 number_of_particle_groups, &583 number_particles_per_gridbox, &584 particles_per_point, &585 particle_advection_start, &586 particle_advection_interpolation, &587 particle_maximum_age, &588 pdx, &589 pdy, &590 pdz, &591 psb, &592 psl, &593 psn, &594 psr, &595 pss, &596 pst, &597 radius, &598 radius_classes, &599 radius_merge, &600 radius_split, &601 random_start_position, &602 read_particles_from_restartfile, &603 rm, &604 seed_follows_topography, &605 splitting, &606 splitting_factor, &607 splitting_factor_max, &608 splitting_function, &609 splitting_mode, &610 step_dealloc, &611 use_sgs_for_particles, &612 vertical_particle_advection, &613 weight_factor_merge, &614 weight_factor_split, &546 NAMELIST /particles_par/ & 547 aero_species, & 548 aero_type, & 549 aero_weight, & 550 alloc_factor, & 551 bc_par_b, & 552 bc_par_lr, & 553 bc_par_ns, & 554 bc_par_t, & 555 collision_kernel, & 556 curvature_solution_effects, & 557 deallocate_memory, & 558 density_ratio, & 559 dissipation_classes, & 560 dt_dopts, & 561 dt_min_part, & 562 dt_prel, & 563 dt_write_particle_data, & 564 end_time_prel, & 565 initial_weighting_factor, & 566 log_sigma, & 567 max_number_particles_per_gridbox, & 568 merging, & 569 na, & 570 number_concentration, & 571 number_of_particle_groups, & 572 number_particles_per_gridbox, & 573 particles_per_point, & 574 particle_advection_start, & 575 particle_advection_interpolation, & 576 particle_maximum_age, & 577 pdx, & 578 pdy, & 579 pdz, & 580 psb, & 581 psl, & 582 psn, & 583 psr, & 584 pss, & 585 pst, & 586 radius, & 587 radius_classes, & 588 radius_merge, & 589 radius_split, & 590 random_start_position, & 591 read_particles_from_restartfile, & 592 rm, & 593 seed_follows_topography, & 594 splitting, & 595 splitting_factor, & 596 splitting_factor_max, & 597 splitting_function, & 598 splitting_mode, & 599 step_dealloc, & 600 use_sgs_for_particles, & 601 vertical_particle_advection, & 602 weight_factor_merge, & 603 weight_factor_split, & 615 604 write_particle_statistics 616 605 617 NAMELIST /particle_parameters/ &618 aero_species, &619 aero_type, &620 aero_weight, &621 alloc_factor, &622 bc_par_b, &623 bc_par_lr, &624 bc_par_ns, &625 bc_par_t, &626 collision_kernel, &627 curvature_solution_effects, &628 deallocate_memory, &629 density_ratio, &630 dissipation_classes, &631 dt_dopts, &632 dt_min_part, &633 dt_prel, &634 dt_write_particle_data, &635 end_time_prel, &636 initial_weighting_factor, &637 log_sigma, &638 max_number_particles_per_gridbox, &639 merging, &640 na, &641 number_concentration, &642 number_of_output_particles, &643 number_of_particle_groups, &644 number_particles_per_gridbox, &645 oversize, &646 particles_per_point, &647 particle_advection_start, &648 particle_advection_interpolation, &649 particle_maximum_age, &650 part_output, &651 part_inc, &652 part_percent, &653 pdx, &654 pdy, &655 pdz, &656 psb, &657 psl, &658 psn, &659 psr, &660 pss, &661 pst, &662 radius, &663 radius_classes, &664 radius_merge, &665 radius_split, &666 random_start_position, &667 read_particles_from_restartfile, &668 rm, &669 seed_follows_topography, &670 splitting, &671 splitting_factor, &672 splitting_factor_max, &673 splitting_function, &674 splitting_mode, &675 step_dealloc, &676 unlimited_dimension, &677 use_sgs_for_particles, &678 vertical_particle_advection, &679 weight_factor_merge, &680 weight_factor_split, &606 NAMELIST /particle_parameters/ & 607 aero_species, & 608 aero_type, & 609 aero_weight, & 610 alloc_factor, & 611 bc_par_b, & 612 bc_par_lr, & 613 bc_par_ns, & 614 bc_par_t, & 615 collision_kernel, & 616 curvature_solution_effects, & 617 deallocate_memory, & 618 density_ratio, & 619 dissipation_classes, & 620 dt_dopts, & 621 dt_min_part, & 622 dt_prel, & 623 dt_write_particle_data, & 624 end_time_prel, & 625 initial_weighting_factor, & 626 log_sigma, & 627 max_number_particles_per_gridbox, & 628 merging, & 629 na, & 630 number_concentration, & 631 number_of_output_particles, & 632 number_of_particle_groups, & 633 number_particles_per_gridbox, & 634 oversize, & 635 particles_per_point, & 636 particle_advection_start, & 637 particle_advection_interpolation, & 638 particle_maximum_age, & 639 part_output, & 640 part_inc, & 641 part_percent, & 642 pdx, & 643 pdy, & 644 pdz, & 645 psb, & 646 psl, & 647 psn, & 648 psr, & 649 pss, & 650 pst, & 651 radius, & 652 radius_classes, & 653 radius_merge, & 654 radius_split, & 655 random_start_position, & 656 read_particles_from_restartfile, & 657 rm, & 658 seed_follows_topography, & 659 splitting, & 660 splitting_factor, & 661 splitting_factor_max, & 662 splitting_function, & 663 splitting_mode, & 664 step_dealloc, & 665 unlimited_dimension, & 666 use_sgs_for_particles, & 667 vertical_particle_advection, & 668 weight_factor_merge, & 669 weight_factor_split, & 681 670 write_particle_statistics 682 671 683 672 ! 684 !-- Position the namelist-file at the beginning (it was already opened in 685 !-- parin), search for the namelist-group of the package and position the686 !-- file at this line. Do the same for eachoptionally used package.673 !-- Position the namelist-file at the beginning (it was already opened in parin), search for the 674 !-- namelist-group of the package and position the file at this line. Do the same for each 675 !-- optionally used package. 687 676 line = ' ' 688 677 689 678 ! 690 679 !-- Try to find particles package … … 701 690 !-- Set flag that indicates that particles are switched on 702 691 particle_advection = .TRUE. 703 692 704 693 GOTO 14 705 694 … … 719 708 READ ( 11, particles_par, ERR = 13, END = 14 ) 720 709 721 message_string = 'namelist particles_par is deprecated and will be ' // &722 'removed in near future. Please use namelist ' // &710 message_string = 'namelist particles_par is deprecated and will be ' // & 711 'removed in near future. Please use namelist ' // & 723 712 'particle_parameters instead' 724 713 CALL message( 'package_parin', 'PA0487', 0, 1, 0, 6, 0 ) … … 737 726 738 727 END SUBROUTINE lpm_parin 739 740 !------------------------------------------------------------------------------ !728 729 !--------------------------------------------------------------------------------------------------! 741 730 ! Description: 742 731 ! ------------ 743 732 !> Writes used particle attributes in header file. 744 !------------------------------------------------------------------------------ !733 !--------------------------------------------------------------------------------------------------! 745 734 SUBROUTINE lpm_header ( io ) 746 735 … … 763 752 ENDIF 764 753 ENDIF 765 754 766 755 IF ( particle_advection ) THEN 767 756 ! 768 757 !-- Particle attributes 769 WRITE ( io, 480 ) particle_advection_start, TRIM(particle_advection_interpolation), & 770 dt_prel, bc_par_lr, & 771 bc_par_ns, bc_par_b, bc_par_t, particle_maximum_age, & 758 WRITE ( io, 480 ) particle_advection_start, TRIM(particle_advection_interpolation), & 759 dt_prel, bc_par_lr, bc_par_ns, bc_par_b, bc_par_t, particle_maximum_age, & 772 760 end_time_prel 773 761 IF ( use_sgs_for_particles ) WRITE ( io, 488 ) dt_min_part … … 801 789 WRITE ( io, 492 ) 802 790 ENDIF 803 WRITE ( io, 493 ) psl(i), psr(i), pss(i), psn(i), psb(i), pst(i), & 804 pdx(i), pdy(i), pdz(i) 791 WRITE ( io, 493 ) psl(i), psr(i), pss(i), psn(i), psb(i), pst(i), pdx(i), pdy(i), pdz(i) 805 792 IF ( .NOT. vertical_particle_advection(i) ) WRITE ( io, 482 ) 806 793 ENDDO 807 794 808 795 ENDIF 809 796 810 797 344 FORMAT (' Output format: ',A/) 811 798 354 FORMAT (' Output format: ',A, ' compressed with level: ',I1/) 812 799 813 433 FORMAT (' Cloud droplets treated explicitly using the Lagrangian part', & 814 'icle model') 815 434 FORMAT (' Curvature and solution effecs are considered for growth of', & 800 433 FORMAT (' Cloud droplets treated explicitly using the Lagrangian part','icle model') 801 434 FORMAT (' Curvature and solution effecs are considered for growth of', & 816 802 ' droplets < 1.0E-6 m') 817 803 435 FORMAT (' Droplet collision is handled by ',A,'-kernel') 818 436 FORMAT (' Fast kernel with fixed radius- and dissipation classes ', & 819 'are used'/ & 820 ' number of radius classes: ',I3,' interval ', & 821 '[1.0E-6,2.0E-4] m'/ & 822 ' number of dissipation classes: ',I2,' interval ', & 823 '[0,1000] cm**2/s**3') 804 436 FORMAT (' Fast kernel with fixed radius- and dissipation classes ','are used'/ & 805 ' number of radius classes: ',I3,' interval ','[1.0E-6,2.0E-4] m'/ & 806 ' number of dissipation classes: ',I2,' interval ','[0,1000] cm**2/s**3') 824 807 437 FORMAT (' Droplet collision is switched off') 825 808 826 480 FORMAT (' Particles:'/ & 827 ' ---------'// & 828 ' Particle advection is active (switched on at t = ', F7.1, & 829 ' s)'/ & 830 ' Interpolation of particle velocities is done by using ', A, & 831 ' method'/ & 832 ' Start of new particle generations every ',F6.1,' s'/ & 833 ' Boundary conditions: left/right: ', A, ' north/south: ', A/& 834 ' bottom: ', A, ' top: ', A/& 835 ' Maximum particle age: ',F9.1,' s'/ & 809 480 FORMAT (' Particles:'/ & 810 ' ---------'// & 811 ' Particle advection is active (switched on at t = ', F7.1,' s)'/ & 812 ' Interpolation of particle velocities is done by using ', A,' method'/ & 813 ' Start of new particle generations every ',F6.1,' s'/ & 814 ' Boundary conditions: left/right: ', A, ' north/south: ', A/ & 815 ' bottom: ', A, ' top: ', A/ & 816 ' Maximum particle age: ',F9.1,' s'/ & 836 817 ' Advection stopped at t = ',F9.1,' s'/) 837 818 481 FORMAT (' Particles have random start positions'/) … … 840 821 486 FORMAT (' Particle statistics are written on file'/) 841 822 487 FORMAT (' Number of particle groups: ',I2/) 842 488 FORMAT (' SGS velocity components are used for particle advection'/ &823 488 FORMAT (' SGS velocity components are used for particle advection'/ & 843 824 ' minimum timestep for advection:', F8.5/) 844 489 FORMAT (' Number of particles simultaneously released at each ', & 845 'point: ', I5/) 846 490 FORMAT (' Particle group ',I2,':'/ & 825 489 FORMAT (' Number of particles simultaneously released at each ','point: ', I5/) 826 490 FORMAT (' Particle group ',I2,':'/ & 847 827 ' Particle radius: ',E10.3, 'm') 848 491 FORMAT (' Particle inertia is activated'/ &828 491 FORMAT (' Particle inertia is activated'/ & 849 829 ' density_ratio (rho_fluid/rho_particle) =',F6.3/) 850 830 492 FORMAT (' Particles are advected only passively (no inertia)'/) 851 493 FORMAT (' Boundaries of particle source: x:',F8.1,' - ',F8.1,' m'/& 852 ' y:',F8.1,' - ',F8.1,' m'/& 853 ' z:',F8.1,' - ',F8.1,' m'/& 854 ' Particle distances: dx = ',F8.1,' m dy = ',F8.1, & 855 ' m dz = ',F8.1,' m'/) 856 494 FORMAT (' Output of particle time series in NetCDF format every ', & 857 F8.2,' s'/) 831 493 FORMAT (' Boundaries of particle source: x:',F8.1,' - ',F8.1,' m'/ & 832 ' y:',F8.1,' - ',F8.1,' m'/ & 833 ' z:',F8.1,' - ',F8.1,' m'/ & 834 ' Particle distances: dx = ',F8.1,' m dy = ',F8.1,' m dz = ',F8.1,' m'/) 835 494 FORMAT (' Output of particle time series in NetCDF format every ',F8.2,' s'/) 858 836 495 FORMAT (' Number of particles in total domain: ',I10/) 859 496 FORMAT (' Initial vertical particle positions are interpreted ', &837 496 FORMAT (' Initial vertical particle positions are interpreted ', & 860 838 'as relative to the given topography') 861 839 862 840 END SUBROUTINE lpm_header 863 864 !------------------------------------------------------------------------------ !841 842 !--------------------------------------------------------------------------------------------------! 865 843 ! Description: 866 844 ! ------------ 867 845 !> Writes used particle attributes in header file. 868 !------------------------------------------------------------------------------ !846 !--------------------------------------------------------------------------------------------------! 869 847 SUBROUTINE lpm_check_parameters 870 848 871 849 ! 872 850 !-- Collision kernels: … … 883 861 884 862 CASE DEFAULT 885 message_string = 'unknown collision kernel: collision_kernel = "' // &863 message_string = 'unknown collision kernel: collision_kernel = "' // & 886 864 TRIM( collision_kernel ) // '"' 887 865 CALL message( 'lpm_check_parameters', 'PA0350', 1, 2, 0, 6, 0 ) … … 891 869 892 870 ! 893 !-- Subgrid scale velocites with the simple interpolation method for resolved 894 !-- velocites is not implemented for passive particles. However, for cloud 895 !-- it can be combined as the sgs-velocites for active particles are 896 !-- calculated differently, i.e. no subboxes are needed. 897 IF ( .NOT. TRIM( particle_advection_interpolation ) == 'trilinear' .AND. & 898 use_sgs_for_particles .AND. .NOT. cloud_droplets ) THEN 899 message_string = 'subrgrid scale velocities in combination with ' // & 900 'simple interpolation method is not ' // & 871 !-- Subgrid scale velocites with the simple interpolation method for resolved velocites is not 872 !-- implemented for passive particles. However, for cloud it can be combined as the sgs-velocites 873 !-- for active particles are calculated differently, i.e. no subboxes are needed. 874 IF ( .NOT. TRIM( particle_advection_interpolation ) == 'trilinear' .AND. & 875 use_sgs_for_particles .AND. .NOT. cloud_droplets ) THEN 876 message_string = 'subrgrid scale velocities in combination with ' // & 877 'simple interpolation method is not ' // & 901 878 'implemented' 902 879 CALL message( 'lpm_check_parameters', 'PA0659', 1, 2, 0, 6, 0 ) … … 904 881 905 882 IF ( nested_run .AND. cloud_droplets ) THEN 906 message_string = 'nested runs in combination with cloud droplets ' // &883 message_string = 'nested runs in combination with cloud droplets ' // & 907 884 'is not implemented' 908 885 CALL message( 'lpm_check_parameters', 'PA0687', 1, 2, 0, 6, 0 ) … … 911 888 912 889 END SUBROUTINE lpm_check_parameters 913 914 !------------------------------------------------------------------------------ !890 891 !--------------------------------------------------------------------------------------------------! 915 892 ! Description: 916 893 ! ------------ 917 894 !> Initialize arrays for lpm 918 !------------------------------------------------------------------------------ !895 !--------------------------------------------------------------------------------------------------! 919 896 SUBROUTINE lpm_init_arrays 920 897 921 898 IF ( cloud_droplets ) THEN 922 899 ! 923 900 !-- Liquid water content, change in liquid water content 924 ALLOCATE ( ql_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg), &901 ALLOCATE ( ql_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 925 902 ql_2(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 926 903 !-- Real volume of particles (with weighting), volume of particles 927 ALLOCATE ( ql_v(nzb:nzt+1,nysg:nyng,nxlg:nxrg), &904 ALLOCATE ( ql_v(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 928 905 ql_vp(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 929 906 ENDIF 930 907 931 908 932 ALLOCATE( u_t(nzb:nzt+1,nysg:nyng,nxlg:nxrg), &933 v_t(nzb:nzt+1,nysg:nyng,nxlg:nxrg), &909 ALLOCATE( u_t(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 910 v_t(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 934 911 w_t(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 935 912 ! … … 946 923 947 924 END SUBROUTINE lpm_init_arrays 948 949 !------------------------------------------------------------------------------ !925 926 !--------------------------------------------------------------------------------------------------! 950 927 ! Description: 951 928 ! ------------ 952 929 !> Initialize Lagrangian particle model 953 !------------------------------------------------------------------------------ !930 !--------------------------------------------------------------------------------------------------! 954 931 SUBROUTINE lpm_init 955 932 … … 965 942 966 943 ! 967 !-- In case of oceans runs, the vertical index calculations need an offset, 968 !-- because otherwise the kindices will become negative944 !-- In case of oceans runs, the vertical index calculations need an offset, because otherwise the k 945 !-- indices will become negative 969 946 IF ( ocean_mode ) THEN 970 947 offset_ocean_nzt = nzt … … 973 950 974 951 ! 975 !-- Define block offsets for dividing a gridcell in 8 sub cells 976 !-- See documentation for List of subgrid boxes 977 !-- See pack_and_sort in lpm_pack_arrays.f90 for assignment of the subgrid boxes 952 !-- Define block offsets for dividing a gridcell in 8 sub cells. 953 !-- See documentation for List of subgrid boxes. 954 !-- See pack_and_sort in lpm_pack_arrays.f90 for assignment of the subgrid boxes. 978 955 block_offset(0) = block_offset_def ( 0, 0, 0) 979 956 block_offset(1) = block_offset_def ( 0, 0,-1) … … 987 964 !-- Check the number of particle groups. 988 965 IF ( number_of_particle_groups > max_number_of_particle_groups ) THEN 989 WRITE( message_string, * ) 'max_number_of_particle_groups =', &990 max_number_of_particle_groups , &991 '&number_of_particle_groups reset to ', &966 WRITE( message_string, * ) 'max_number_of_particle_groups =', & 967 max_number_of_particle_groups , & 968 '&number_of_particle_groups reset to ', & 992 969 max_number_of_particle_groups 993 970 CALL message( 'lpm_init', 'PA0213', 0, 1, 0, 6, 0 ) … … 995 972 ENDIF 996 973 ! 997 !-- Check if downward-facing walls exist. This case, reflection boundary 998 !-- conditions (as well as subgrid-scale velocities) may do not work 999 !-- propably (not realized so far). 974 !-- Check if downward-facing walls exist. This case, reflection boundary conditions (as well as 975 !-- subgrid-scale velocities) may do not work properly (not realized so far). 1000 976 IF ( surf_def_h(1)%ns >= 1 ) THEN 1001 WRITE( message_string, * ) 'Overhanging topography do not work '// &977 WRITE( message_string, * ) 'Overhanging topography do not work '// & 1002 978 'with particles' 1003 979 CALL message( 'lpm_init', 'PA0212', 0, 1, 0, 6, 0 ) … … 1019 995 1020 996 ! 1021 !-- If number_particles_per_gridbox is set, the parametres pdx, pdy and pdz are 1022 !-- calculateddiagnostically. Therfore an isotropic distribution is prescribed.997 !-- If number_particles_per_gridbox is set, the parametres pdx, pdy and pdz are calculated 998 !-- diagnostically. Therfore an isotropic distribution is prescribed. 1023 999 IF ( number_particles_per_gridbox /= -1 .AND. & 1024 1000 number_particles_per_gridbox >= 1 ) THEN … … 1026 1002 REAL(number_particles_per_gridbox))**0.3333333_wp 1027 1003 ! 1028 !-- Ensure a smooth value (two significant digits) of distance between 1029 !-- particles (pdx, pdy, pdz). 1004 !-- Ensure a smooth value (two significant digits) of distance between particles (pdx, pdy, pdz). 1030 1005 div = 1000.0_wp 1031 1006 DO WHILE ( pdx(1) < div ) … … 1066 1041 1067 1042 ! 1068 !-- Allocate array required for logarithmic vertical interpolation of 1069 !-- horizontal particle velocities between the surface and the first vertical 1070 !-- grid level. In order to avoid repeated CPU cost-intensive CALLS of 1071 !-- intrinsic FORTRAN procedure LOG(z/z0), LOG(z/z0) is precalculated for 1043 !-- Allocate array required for logarithmic vertical interpolation of horizontal particle velocities 1044 !-- between the surface and the first vertical grid level. In order to avoid repeated CPU 1045 !-- cost-intensive CALLS of intrinsic FORTRAN procedure LOG(z/z0), LOG(z/z0) is precalculated for 1072 1046 !-- several heights. Splitting into 20 sublayers turned out to be sufficient. 1073 !-- To obtain exact height levels of particles, linear interpolation is applied 1074 !-- (see lpm_advec.f90). 1047 !-- To obtain exact height levels of particles, linear interpolation is applied (see lpm_advec.f90). 1075 1048 IF ( constant_flux_layer ) THEN 1076 1049 … … 1079 1052 1080 1053 ! 1081 !-- Calculate horizontal mean value of z0 used for logartihmic 1082 !-- interpolation. Note: this is not exact for heterogeneous z0. 1083 !-- However, sensitivity studies showed that the effect is 1084 !-- negligible. 1085 z0_av_local = SUM( surf_def_h(0)%z0 ) + SUM( surf_lsm_h%z0 ) + & 1086 SUM( surf_usm_h%z0 ) 1054 !-- Calculate horizontal mean value of z0 used for logartihmic interpolation. Note: this is not 1055 !-- exact for heterogeneous z0. 1056 !-- However, sensitivity studies showed that the effect is negligible. 1057 z0_av_local = SUM( surf_def_h(0)%z0 ) + SUM( surf_lsm_h%z0 ) + SUM( surf_usm_h%z0 ) 1087 1058 z0_av_global = 0.0_wp 1088 1059 1089 1060 #if defined( __parallel ) 1090 CALL MPI_ALLREDUCE(z0_av_local, z0_av_global, 1, MPI_REAL, MPI_SUM, & 1091 comm2d, ierr ) 1061 CALL MPI_ALLREDUCE( z0_av_local, z0_av_global, 1, MPI_REAL, MPI_SUM, comm2d, ierr ) 1092 1062 #else 1093 1063 z0_av_global = z0_av_local … … 1143 1113 1144 1114 CASE DEFAULT 1145 WRITE( message_string, * ) 'unknown boundary condition ', &1115 WRITE( message_string, * ) 'unknown boundary condition ', & 1146 1116 'bc_par_b = "', TRIM( bc_par_b ), '"' 1147 1117 CALL message( 'lpm_init', 'PA0217', 1, 2, 0, 6, 0 ) … … 1160 1130 1161 1131 CASE DEFAULT 1162 WRITE( message_string, * ) 'unknown boundary condition ', &1132 WRITE( message_string, * ) 'unknown boundary condition ', & 1163 1133 'bc_par_t = "', TRIM( bc_par_t ), '"' 1164 1134 CALL message( 'lpm_init', 'PA0218', 1, 2, 0, 6, 0 ) … … 1180 1150 1181 1151 CASE DEFAULT 1182 WRITE( message_string, * ) 'unknown boundary condition ', &1152 WRITE( message_string, * ) 'unknown boundary condition ', & 1183 1153 'bc_par_lr = "', TRIM( bc_par_lr ), '"' 1184 1154 CALL message( 'lpm_init', 'PA0219', 1, 2, 0, 6, 0 ) … … 1200 1170 1201 1171 CASE DEFAULT 1202 WRITE( message_string, * ) 'unknown boundary condition ', &1172 WRITE( message_string, * ) 'unknown boundary condition ', & 1203 1173 'bc_par_ns = "', TRIM( bc_par_ns ), '"' 1204 1174 CALL message( 'lpm_init', 'PA0220', 1, 2, 0, 6, 0 ) … … 1217 1187 1218 1188 CASE DEFAULT 1219 WRITE( message_string, * ) 'unknown splitting_mode = "', & 1220 TRIM( splitting_mode ), '"' 1189 WRITE( message_string, * ) 'unknown splitting_mode = "', TRIM( splitting_mode ), '"' 1221 1190 CALL message( 'lpm_init', 'PA0146', 1, 2, 0, 6, 0 ) 1222 1191 … … 1234 1203 1235 1204 CASE DEFAULT 1236 WRITE( message_string, * ) 'unknown splitting function = "', &1205 WRITE( message_string, * ) 'unknown splitting function = "', & 1237 1206 TRIM( splitting_function ), '"' 1238 1207 CALL message( 'lpm_init', 'PA0147', 1, 2, 0, 6, 0 ) … … 1244 1213 1245 1214 ! 1246 !-- For the first model run of a possible job chain initialize the 1247 !-- particle s, otherwise read the particledata from restart file.1248 IF ( TRIM( initializing_actions ) == 'read_restart_data' &1215 !-- For the first model run of a possible job chain initialize the particles, otherwise read the 1216 !-- particle data from restart file. 1217 IF ( TRIM( initializing_actions ) == 'read_restart_data' & 1249 1218 .AND. read_particles_from_restartfile ) THEN 1250 1219 CALL lpm_rrd_local_particles 1251 1220 ELSE 1252 1221 ! 1253 !-- Allocate particle arrays and set attributes of the initial set of 1254 !-- particles, which can bealso periodically released at later times.1255 ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg), &1222 !-- Allocate particle arrays and set attributes of the initial set of particles, which can be 1223 !-- also periodically released at later times. 1224 ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 1256 1225 grid_particles(nzb+1:nzt,nys:nyn,nxl:nxr) ) 1257 1226 … … 1259 1228 prt_count = 0 1260 1229 ! 1261 !-- initialize counter for particle IDs1230 !-- Initialize counter for particle IDs 1262 1231 grid_particles%id_counter = 1 1263 1232 ! 1264 !-- Initialize all particles with dummy values (otherwise errors may 1265 !-- occur within restart runs). The reason for this is still not clear1266 !-- and may be presumably caused by errors in therespective user-interface.1267 zero_particle = particle_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, &1268 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, &1269 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, &1270 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, &1233 !-- Initialize all particles with dummy values (otherwise errors may occur within restart runs). 1234 !-- The reason for this is still not clear and may be presumably caused by errors in the 1235 !-- respective user-interface. 1236 zero_particle = particle_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 1237 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 1238 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 1239 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 1271 1240 0, 0, 0_idp, .FALSE., -1, -1 ) 1272 1241 1273 1242 particle_groups = particle_groups_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp ) 1274 1243 ! 1275 !-- Set values for the density ratio and radius for all particle 1276 !-- groups, if necessary 1244 !-- Set values for the density ratio and radius for all particle groups, if necessary. 1277 1245 IF ( density_ratio(1) == 9999999.9_wp ) density_ratio(1) = 0.0_wp 1278 1246 IF ( radius(1) == 9999999.9_wp ) radius(1) = 0.0_wp … … 1286 1254 DO i = 1, number_of_particle_groups 1287 1255 IF ( density_ratio(i) /= 0.0_wp .AND. radius(i) == 0 ) THEN 1288 WRITE( message_string, * ) 'particle group #', i, ' has a', &1256 WRITE( message_string, * ) 'particle group #', i, ' has a', & 1289 1257 'density ratio /= 0 but radius = 0' 1290 1258 CALL message( 'lpm_init', 'PA0215', 1, 2, 0, 6, 0 ) … … 1295 1263 1296 1264 ! 1297 !-- Initialize parallel random number sequence seed for particles 1265 !-- Initialize parallel random number sequence seed for particles. 1298 1266 !-- This is done separately here, as thus particle random numbers do not affect the random 1299 1267 !-- numbers used for the flow field (e.g. for generating flow disturbances). … … 1301 1269 seq_random_array_particles = 0 1302 1270 1303 !-- Initializing with random_seed_parallel for every vertical 1304 !-- gridpoint column. 1271 !-- Initializing with random_seed_parallel for every vertical gridpoint column. 1305 1272 random_dummy = 0 1306 1273 DO i = nxl, nxr … … 1322 1289 IF ( write_particle_statistics ) THEN 1323 1290 CALL check_open( 80 ) 1324 WRITE ( 80, 8000 ) current_timestep_number, simulated_time, & 1325 number_of_particles 1291 WRITE ( 80, 8000 ) current_timestep_number, simulated_time, number_of_particles 1326 1292 CALL close_file( 80 ) 1327 1293 ENDIF … … 1333 1299 #endif 1334 1300 1301 ! 1335 1302 !-- next line is in preparation for particle data output 1336 1303 ! CALL dop_init … … 1346 1313 1347 1314 END SUBROUTINE lpm_init 1348 1349 !------------------------------------------------------------------------------ !1315 1316 !--------------------------------------------------------------------------------------------------! 1350 1317 ! Description: 1351 1318 ! ------------ 1352 1319 !> Create Lagrangian particles 1353 !------------------------------------------------------------------------------ !1320 !--------------------------------------------------------------------------------------------------! 1354 1321 SUBROUTINE lpm_create_particle (phase) 1355 1322 … … 1378 1345 REAL(wp) :: rand_contr !< dummy argument for random position 1379 1346 1380 TYPE(particle_type),TARGET :: tmp_particle !< temporary particle used for initialization 1381 1382 1383 ! 1384 !-- Calculate particle positions and store particle attributes, if 1385 !-- particle is situated on this PE 1347 TYPE(particle_type), TARGET :: tmp_particle !< temporary particle used for initialization 1348 1349 1350 ! 1351 !-- Calculate particle positions and store particle attributes, if particle is situated on this PE. 1386 1352 DO loop_stride = 1, 2 1387 1353 first_stride = (loop_stride == 1) … … 1395 1361 !-- Calculate initial_weighting_factor diagnostically 1396 1362 IF ( number_concentration /= -1.0_wp .AND. number_concentration > 0.0_wp ) THEN 1397 initial_weighting_factor = number_concentration * & 1398 pdx(1) * pdy(1) * pdz(1) 1363 initial_weighting_factor = number_concentration * pdx(1) * pdy(1) * pdz(1) 1399 1364 END IF 1400 1365 … … 1406 1371 pos_y = pss(i) 1407 1372 DO WHILE ( pos_y <= psn(i) ) 1408 IF ( pos_y >= nys * dy .AND. & 1409 pos_y < ( nyn + 1 ) * dy ) THEN 1373 IF ( pos_y >= nys * dy .AND. pos_y < ( nyn + 1 ) * dy ) THEN 1410 1374 pos_x = psl(i) 1411 1375 xloop: DO WHILE ( pos_x <= psr(i) ) 1412 IF ( pos_x >= nxl * dx .AND. & 1413 pos_x < ( nxr + 1) * dx ) THEN 1376 IF ( pos_x >= nxl * dx .AND. pos_x < ( nxr + 1) * dx ) THEN 1414 1377 DO j = 1, particles_per_point 1415 1378 n = n + 1 … … 1450 1413 ! 1451 1414 !-- In case of stretching the actual k index is found iteratively 1452 IF ( dz_stretch_level /= -9999999.9_wp .OR. &1415 IF ( dz_stretch_level /= -9999999.9_wp .OR. & 1453 1416 dz_stretch_level_start(1) /= -9999999.9_wp ) THEN 1454 1417 kp = MAX( MINLOC( ABS( tmp_particle%z - zu ), DIM = 1 ) - 1, 1 ) … … 1457 1420 ENDIF 1458 1421 ! 1459 !-- Determine surface level. Therefore, check for 1460 !-- upward-facing wall on w-grid.1422 !-- Determine surface level. Therefore, check for upward-facing wall on 1423 !-- w-grid. 1461 1424 k_surf = topo_top_ind(jp,ip,3) 1462 1425 IF ( seed_follows_topography ) THEN … … 1465 1428 kp = kp + k_surf 1466 1429 tmp_particle%z = tmp_particle%z + zw(k_surf) 1467 ! -- Skip particle release if particle position is1468 !-- above model top, or within topography in case1469 !-- of overhanging structures.1470 IF ( kp > nzt .OR. &1471 .NOT. BTEST( wall_flags_total_0(kp,jp,ip), 0 ) ) THEN1430 ! 1431 !-- Skip particle release if particle position is above model top, or 1432 !-- within topography in case of overhanging structures. 1433 IF ( kp > nzt .OR. & 1434 .NOT. BTEST( wall_flags_total_0(kp,jp,ip), 0 ) ) THEN 1472 1435 pos_x = pos_x + pdx(i) 1473 1436 CYCLE xloop 1474 1437 ENDIF 1475 1438 ! 1476 !-- Skip particle release if particle position is 1477 !-- below surface, or within topography in case 1478 !-- of overhanging structures. 1479 ELSEIF ( .NOT. seed_follows_topography .AND. & 1480 tmp_particle%z <= zw(k_surf) .OR. & 1481 .NOT. BTEST( wall_flags_total_0(kp,jp,ip), 0 ) )& 1482 THEN 1439 !-- Skip particle release if particle position is below surface, or 1440 !-- within topography in case of overhanging structures. 1441 ELSEIF ( .NOT. seed_follows_topography .AND. & 1442 tmp_particle%z <= zw(k_surf) .OR. & 1443 .NOT. BTEST( wall_flags_total_0(kp,jp,ip), 0 ) ) THEN 1483 1444 pos_x = pos_x + pdx(i) 1484 1445 CYCLE xloop … … 1494 1455 write(6,*) 'xu ',ip,jp,kp,nxr,nyn,nzt 1495 1456 ENDIF 1496 grid_particles(kp,jp,ip)%particles(local_count(kp,jp,ip)) = tmp_particle 1457 grid_particles(kp,jp,ip)%particles(local_count(kp,jp,ip)) = & 1458 tmp_particle 1497 1459 ENDIF 1498 1460 ENDDO … … 1513 1475 DO jp = nys, nyn 1514 1476 DO kp = nzb+1, nzt 1515 IF ( phase == PHASE_INIT) THEN1477 IF ( phase == phase_init ) THEN 1516 1478 IF ( local_count(kp,jp,ip) > 0 ) THEN 1517 alloc_size = MAX( INT( local_count(kp,jp,ip) * & 1518 ( 1.0_wp + alloc_factor / 100.0_wp ) ), & 1519 1 ) 1479 alloc_size = MAX( INT( local_count(kp,jp,ip) * & 1480 ( 1.0_wp + alloc_factor / 100.0_wp ) ), 1 ) 1520 1481 ELSE 1521 1482 alloc_size = 1 … … 1525 1486 grid_particles(kp,jp,ip)%particles(n) = zero_particle 1526 1487 ENDDO 1527 ELSEIF ( phase == PHASE_RELEASE) THEN1488 ELSEIF ( phase == phase_release ) THEN 1528 1489 IF ( local_count(kp,jp,ip) > 0 ) THEN 1529 1490 new_size = local_count(kp,jp,ip) + prt_count(kp,jp,ip) 1530 alloc_size = MAX( INT( new_size * ( 1.0_wp + &1531 alloc_factor / 100.0_wp ) ), 1 )1491 alloc_size = MAX( INT( new_size * ( 1.0_wp + & 1492 alloc_factor / 100.0_wp ) ), 1 ) 1532 1493 IF( alloc_size > SIZE( grid_particles(kp,jp,ip)%particles) ) THEN 1533 1494 CALL realloc_particles_array( ip, jp, kp, alloc_size ) … … 1555 1516 DO n = local_start(kp,jp,ip), number_of_particles !only new particles 1556 1517 1557 particles(n)%id = 10000_idp**3 * grid_particles(kp,jp,ip)%id_counter + &1518 particles(n)%id = 10000_idp**3 * grid_particles(kp,jp,ip)%id_counter + & 1558 1519 10000_idp**2 * kp + 10000_idp * jp + ip 1559 1520 ! 1560 1521 !-- Count the number of particles that have been released before 1561 grid_particles(kp,jp,ip)%id_counter = & 1562 grid_particles(kp,jp,ip)%id_counter + 1 1522 grid_particles(kp,jp,ip)%id_counter = grid_particles(kp,jp,ip)%id_counter + 1 1563 1523 1564 1524 ENDDO … … 1585 1545 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 1586 1546 ! 1587 !-- Move only new particles. Moreover, limit random fluctuation 1588 !-- in order to prevent that particles move more than one grid box, 1589 !-- which would lead to problems concerning particle exchange 1590 !-- between processors in case pdx/pdy are larger than dx/dy, 1547 !-- Move only new particles. Moreover, limit random fluctuation in order to prevent that 1548 !-- particles move more than one grid box, which would lead to problems concerning 1549 !-- particle exchange between processors in case pdx/pdy are larger than dx/dy, 1591 1550 !-- respectively. 1592 1551 DO n = local_start(kp,jp,ip), number_of_particles 1593 1552 IF ( psl(particles(n)%group) /= psr(particles(n)%group) ) THEN 1594 1553 CALL random_number_parallel( random_dummy ) 1595 rand_contr = ( random_dummy - 0.5_wp ) * & 1596 pdx(particles(n)%group) 1597 particles(n)%x = particles(n)%x + & 1598 MERGE( rand_contr, SIGN( dx, rand_contr ), & 1599 ABS( rand_contr ) < dx & 1600 ) 1554 rand_contr = ( random_dummy - 0.5_wp ) * pdx(particles(n)%group) 1555 particles(n)%x = particles(n)%x + & 1556 MERGE( rand_contr, SIGN( dx, rand_contr ), & 1557 ABS( rand_contr ) < dx & 1558 ) 1601 1559 ENDIF 1602 1560 IF ( pss(particles(n)%group) /= psn(particles(n)%group) ) THEN 1603 1561 CALL random_number_parallel( random_dummy ) 1604 rand_contr = ( random_dummy - 0.5_wp ) * & 1605 pdy(particles(n)%group) 1606 particles(n)%y = particles(n)%y + & 1607 MERGE( rand_contr, SIGN( dy, rand_contr ), & 1608 ABS( rand_contr ) < dy & 1609 ) 1562 rand_contr = ( random_dummy - 0.5_wp ) * pdy(particles(n)%group) 1563 particles(n)%y = particles(n)%y + & 1564 MERGE( rand_contr, SIGN( dy, rand_contr ), & 1565 ABS( rand_contr ) < dy & 1566 ) 1610 1567 ENDIF 1611 1568 IF ( psb(particles(n)%group) /= pst(particles(n)%group) ) THEN 1612 1569 CALL random_number_parallel( random_dummy ) 1613 rand_contr = ( random_dummy - 0.5_wp ) * & 1614 pdz(particles(n)%group) 1615 particles(n)%z = particles(n)%z + & 1616 MERGE( rand_contr, SIGN( dzw(kp), rand_contr ), & 1617 ABS( rand_contr ) < dzw(kp) & 1618 ) 1570 rand_contr = ( random_dummy - 0.5_wp ) * pdz(particles(n)%group) 1571 particles(n)%z = particles(n)%z + & 1572 MERGE( rand_contr, SIGN( dzw(kp), rand_contr ), & 1573 ABS( rand_contr ) < dzw(kp) & 1574 ) 1619 1575 ENDIF 1620 1576 ENDDO 1621 1577 ! 1622 !-- Identify particles located outside the model domain and reflect 1623 !-- or absorb them ifnecessary.1578 !-- Identify particles located outside the model domain and reflect or absorb them if 1579 !-- necessary. 1624 1580 CALL lpm_boundary_conds( 'bottom/top', i, j, k ) 1625 1581 ! … … 1627 1583 !-- the particle speed is still zero at this point, wall 1628 1584 !-- reflection boundary conditions will not work in this case. 1629 particles => & 1630 grid_particles(kp,jp,ip)%particles(1:number_of_particles) 1585 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 1631 1586 DO n = local_start(kp,jp,ip), number_of_particles 1632 1587 i = particles(n)%x * ddx … … 1660 1615 ENDIF 1661 1616 ! 1662 !-- In case of random_start_position, delete particles identified by 1663 !-- lpm_exchange_horiz and lpm_boundary_conds. Then sort particles into blocks, 1664 !-- which is needed for a fast interpolation of the LES fields on the particle 1665 !-- position. 1617 !-- In case of random_start_position, delete particles identified by lpm_exchange_horiz and 1618 !-- lpm_boundary_conds. Then sort particles into blocks, which is needed for a fast interpolation of 1619 !-- the LES fields on the particle position. 1666 1620 CALL lpm_sort_and_delete 1667 1621 ! … … 1670 1624 DO jp = nys, nyn 1671 1625 DO kp = nzb+1, nzt 1672 number_of_particles = number_of_particles & 1673 + prt_count(kp,jp,ip) 1626 number_of_particles = number_of_particles + prt_count(kp,jp,ip) 1674 1627 ENDDO 1675 1628 ENDDO … … 1679 1632 #if defined( __parallel ) 1680 1633 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 1681 CALL MPI_ALLREDUCE( number_of_particles, total_number_of_particles, 1, &1682 MPI_INTEGER, MPI_SUM,comm2d, ierr )1634 CALL MPI_ALLREDUCE( number_of_particles, total_number_of_particles, 1, MPI_INTEGER, MPI_SUM, & 1635 comm2d, ierr ) 1683 1636 #else 1684 1637 total_number_of_particles = number_of_particles … … 1688 1641 1689 1642 END SUBROUTINE lpm_create_particle 1690 1691 1692 !------------------------------------------------------------------------------ !1643 1644 1645 !--------------------------------------------------------------------------------------------------! 1693 1646 ! Description: 1694 1647 ! ------------ 1695 !> This routine initialize the particles as aerosols with physio-chemical 1696 !> properties. 1697 !------------------------------------------------------------------------------! 1648 !> This routine initializes the particles as aerosols with physio-chemical properties. 1649 !--------------------------------------------------------------------------------------------------! 1698 1650 SUBROUTINE lpm_init_aerosols(local_start) 1651 1652 INTEGER(iwp) :: ip !< 1653 INTEGER(iwp) :: jp !< 1654 INTEGER(iwp) :: kp !< 1655 INTEGER(iwp) :: n !< 1656 1657 INTEGER(iwp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg), INTENT(IN) :: local_start !< 1699 1658 1700 1659 REAL(wp) :: afactor !< curvature effects … … 1703 1662 REAL(wp) :: e_a !< vapor pressure 1704 1663 REAL(wp) :: e_s !< saturation vapor pressure 1664 REAL(wp) :: rmax = 10.0e-6_wp !< maximum aerosol radius 1705 1665 REAL(wp) :: rmin = 0.005e-6_wp !< minimum aerosol radius 1706 REAL(wp) :: r max = 10.0e-6_wp !< maximum aerosol radius1666 REAL(wp) :: r_l !< left radius of bin 1707 1667 REAL(wp) :: r_mid !< mean radius of bin 1708 REAL(wp) :: r_l !< left radius of bin1709 1668 REAL(wp) :: r_r !< right radius of bin 1710 1669 REAL(wp) :: sigma !< surface tension 1711 1670 REAL(wp) :: t_int !< temperature 1712 1671 1713 INTEGER(iwp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg), INTENT(IN) :: local_start !<1714 1715 INTEGER(iwp) :: n !<1716 INTEGER(iwp) :: ip !<1717 INTEGER(iwp) :: jp !<1718 INTEGER(iwp) :: kp !<1719 1672 1720 1673 ! 1721 1674 !-- Set constants for different aerosol species 1722 1675 IF ( TRIM( aero_species ) == 'nacl' ) THEN 1723 molecular_weight_of_solute = 0.05844_wp 1676 molecular_weight_of_solute = 0.05844_wp 1724 1677 rho_s = 2165.0_wp 1725 1678 vanthoff = 2.0_wp 1726 1679 ELSEIF ( TRIM( aero_species ) == 'c3h4o4' ) THEN 1727 molecular_weight_of_solute = 0.10406_wp 1680 molecular_weight_of_solute = 0.10406_wp 1728 1681 rho_s = 1600.0_wp 1729 1682 vanthoff = 1.37_wp 1730 1683 ELSEIF ( TRIM( aero_species ) == 'nh4o3' ) THEN 1731 molecular_weight_of_solute = 0.08004_wp 1684 molecular_weight_of_solute = 0.08004_wp 1732 1685 rho_s = 1720.0_wp 1733 1686 vanthoff = 2.31_wp 1734 1687 ELSE 1735 WRITE( message_string, * ) 'unknown aerosol species ', &1736 'aero_species = "', TRIM( aero_species ), '"'1688 WRITE( message_string, * ) 'unknown aerosol species ', & 1689 'aero_species = "', TRIM( aero_species ), '"' 1737 1690 CALL message( 'lpm_init', 'PA0470', 1, 2, 0, 6, 0 ) 1738 1691 ENDIF … … 1771 1724 CONTINUE 1772 1725 ELSE 1773 WRITE( message_string, * ) 'unknown aerosol type ', &1774 'aero_type = "', TRIM( aero_type ), '"'1726 WRITE( message_string, * ) 'unknown aerosol type ', & 1727 'aero_type = "', TRIM( aero_type ), '"' 1775 1728 CALL message( 'lpm_init', 'PA0459', 1, 2, 0, 6, 0 ) 1776 1729 ENDIF … … 1787 1740 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 1788 1741 1789 dlogr = ( LOG10( rmax) - LOG10(rmin) ) / ( number_of_particles - local_start(kp,jp,ip) + 1 )1790 ! 1791 ! -- Initialize the aerosols with a predefined spectral distribution1792 !-- of the dry radius (logarithmically increasing bins) and a varying1793 !-- weighting factor1742 dlogr = ( LOG10( rmax ) - LOG10( rmin ) ) / & 1743 ( number_of_particles - local_start(kp,jp,ip) + 1 ) 1744 ! 1745 !-- Initialize the aerosols with a predefined spectral distribution of the dry radius 1746 !-- (logarithmically increasing bins) and a varying weighting factor. 1794 1747 DO n = local_start(kp,jp,ip), number_of_particles !only new particles 1795 1748 … … 1799 1752 1800 1753 particles(n)%aux1 = r_mid 1801 particles(n)%weight_factor = &1802 ( na(1) / ( SQRT( 2.0_wp * pi ) * log_sigma(1) ) * &1803 EXP( - LOG10( r_mid / rm(1) )**2 / ( 2.0_wp * log_sigma(1)**2 ) ) + &1804 na(2) / ( SQRT( 2.0_wp * pi ) * log_sigma(2) ) * &1805 EXP( - LOG10( r_mid / rm(2) )**2 / ( 2.0_wp * log_sigma(2)**2 ) ) + &1806 na(3) / ( SQRT( 2.0_wp * pi ) * log_sigma(3) ) * &1807 EXP( - LOG10( r_mid / rm(3) )**2 / ( 2.0_wp * log_sigma(3)**2 ) ) &1808 ) * ( LOG10( r_r) - LOG10(r_l) ) * ( dx * dy * dzw(kp) )1809 1810 ! 1811 !-- Multiply weight_factor with the namelist parameter aero_weight 1812 !-- to increase ordecrease the number of simulated aerosols1754 particles(n)%weight_factor = & 1755 ( na(1) / ( SQRT( 2.0_wp * pi ) * log_sigma(1) ) * & 1756 EXP( - LOG10( r_mid / rm(1) )**2 / ( 2.0_wp * log_sigma(1)**2 ) ) + & 1757 na(2) / ( SQRT( 2.0_wp * pi ) * log_sigma(2) ) * & 1758 EXP( - LOG10( r_mid / rm(2) )**2 / ( 2.0_wp * log_sigma(2)**2 ) ) + & 1759 na(3) / ( SQRT( 2.0_wp * pi ) * log_sigma(3) ) * & 1760 EXP( - LOG10( r_mid / rm(3) )**2 / ( 2.0_wp * log_sigma(3)**2 ) ) & 1761 ) * ( LOG10( r_r ) - LOG10( r_l ) ) * ( dx * dy * dzw(kp) ) 1762 1763 ! 1764 !-- Multiply weight_factor with the namelist parameter aero_weight to increase or 1765 !-- decrease the number of simulated aerosols 1813 1766 particles(n)%weight_factor = particles(n)%weight_factor * aero_weight 1814 1767 ! 1815 1768 !-- Create random numver with parallel number generator 1816 1769 CALL random_number_parallel( random_dummy ) 1817 IF ( particles(n)%weight_factor - FLOOR( particles(n)%weight_factor,KIND=wp)&1770 IF ( particles(n)%weight_factor - FLOOR( particles(n)%weight_factor, KIND=wp ) & 1818 1771 > random_dummy ) THEN 1819 particles(n)%weight_factor = FLOOR(particles(n)%weight_factor,KIND=wp) + 1.0_wp 1772 particles(n)%weight_factor = FLOOR( particles(n)%weight_factor, KIND=wp ) & 1773 + 1.0_wp 1820 1774 ELSE 1821 particles(n)%weight_factor = FLOOR( particles(n)%weight_factor,KIND=wp)1775 particles(n)%weight_factor = FLOOR( particles(n)%weight_factor, KIND=wp ) 1822 1776 ENDIF 1823 1777 ! … … 1827 1781 ENDDO 1828 1782 ! 1829 !-- Set particle radius to equilibrium radius based on the environmental 1830 !-- supersaturation (Khvorostyanov and Curry, 2007, JGR). This avoids 1831 !-- the sometimes lengthy growth toward their equilibrium radius within 1832 !-- the simulation. 1783 !-- Set particle radius to equilibrium radius based on the environmental supersaturation 1784 !-- (Khvorostyanov and Curry, 2007, JGR). This avoids the sometimes lengthy growth toward 1785 !-- their equilibrium radius within the simulation. 1833 1786 t_int = pt(kp,jp,ip) * exner(kp) 1834 1787 … … 1839 1792 afactor = 2.0_wp * sigma / ( rho_l * r_v * t_int ) 1840 1793 1841 bfactor = vanthoff * molecular_weight_of_water * &1794 bfactor = vanthoff * molecular_weight_of_water * & 1842 1795 rho_s / ( molecular_weight_of_solute * rho_l ) 1843 1796 ! 1844 !-- The formula is only valid for subsaturated environments. For 1845 !-- supersaturations higherthan -5 %, the supersaturation is set to -5%.1797 !-- The formula is only valid for subsaturated environments. For supersaturations higher 1798 !-- than -5 %, the supersaturation is set to -5%. 1846 1799 IF ( e_a / e_s >= 0.95_wp ) e_a = 0.95_wp * e_s 1847 1800 … … 1850 1803 !-- For details on this equation, see Eq. (14) of Khvorostyanov and 1851 1804 !-- Curry (2007, JGR) 1852 particles(n)%radius = bfactor**0.3333333_wp * &1853 particles(n)%aux1 / ( 1.0_wp - e_a / e_s )**0.3333333_wp /&1854 ( 1.0_wp + ( afactor / ( 3.0_wp * bfactor**0.3333333_wp *&1855 particles(n)%aux1 ) ) /&1856 ( 1.0_wp - e_a / e_s )**0.6666666_wp&1857 )1805 particles(n)%radius = bfactor**0.3333333_wp * & 1806 particles(n)%aux1 / ( 1.0_wp - e_a / e_s )**0.3333333_wp / & 1807 ( 1.0_wp + ( afactor / ( 3.0_wp * bfactor**0.3333333_wp * & 1808 particles(n)%aux1 ) ) / & 1809 ( 1.0_wp - e_a / e_s )**0.6666666_wp & 1810 ) 1858 1811 1859 1812 ENDDO … … 1869 1822 1870 1823 1871 !------------------------------------------------------------------------------ !1824 !--------------------------------------------------------------------------------------------------! 1872 1825 ! Description: 1873 1826 ! ------------ 1874 !> Calculates quantities required for considering the SGS velocity fluctuations 1875 !> in the particle transport by a stochastic approach. The respective 1876 !> quantities are: SGS-TKE gradients and horizontally averaged profiles of the 1877 !> SGS TKE and the resolved-scale velocity variances. 1878 !------------------------------------------------------------------------------! 1827 !> Calculates quantities required for considering the SGS velocity fluctuations in the particle 1828 !> transport by a stochastic approach. The respective quantities are: SGS-TKE gradients and 1829 !> horizontally averaged profiles of the SGS TKE and the resolved-scale velocity variances. 1830 !--------------------------------------------------------------------------------------------------! 1879 1831 SUBROUTINE lpm_init_sgs_tke 1880 1832 1881 USE exchange_horiz_mod, &1833 USE exchange_horiz_mod, & 1882 1834 ONLY: exchange_horiz 1883 1835 1884 USE statistics, &1836 USE statistics, & 1885 1837 ONLY: flow_statistics_called, hom, sums, sums_l 1886 1838 … … 1888 1840 INTEGER(iwp) :: j !< index variable along y 1889 1841 INTEGER(iwp) :: k !< index variable along z 1890 INTEGER(iwp) :: m !< running index for the surface elements 1842 INTEGER(iwp) :: m !< running index for the surface elements 1891 1843 1892 1844 REAL(wp) :: flag1 !< flag to mask topography … … 1898 1850 DO k = nzb, nzt+1 1899 1851 1900 IF ( .NOT. BTEST( wall_flags_total_0(k,j,i-1), 0 ) .AND. &1901 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. &1902 BTEST( wall_flags_total_0(k,j,i+1), 0 ) ) &1852 IF ( .NOT. BTEST( wall_flags_total_0(k,j,i-1), 0 ) .AND. & 1853 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. & 1854 BTEST( wall_flags_total_0(k,j,i+1), 0 ) ) & 1903 1855 THEN 1904 de_dx(k,j,i) = 2.0_wp * sgs_wf_part * & 1905 ( e(k,j,i+1) - e(k,j,i) ) * ddx 1906 ELSEIF ( BTEST( wall_flags_total_0(k,j,i-1), 0 ) .AND. & 1907 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. & 1908 .NOT. BTEST( wall_flags_total_0(k,j,i+1), 0 ) ) & 1856 de_dx(k,j,i) = 2.0_wp * sgs_wf_part * ( e(k,j,i+1) - e(k,j,i) ) * ddx 1857 ELSEIF ( BTEST( wall_flags_total_0(k,j,i-1), 0 ) .AND. & 1858 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. & 1859 .NOT. BTEST( wall_flags_total_0(k,j,i+1), 0 ) ) & 1909 1860 THEN 1910 de_dx(k,j,i) = 2.0_wp * sgs_wf_part * & 1911 ( e(k,j,i) - e(k,j,i-1) ) * ddx 1912 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) .AND. & 1913 .NOT. BTEST( wall_flags_total_0(k,j,i+1), 22 ) ) & 1861 de_dx(k,j,i) = 2.0_wp * sgs_wf_part * ( e(k,j,i) - e(k,j,i-1) ) * ddx 1862 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) .AND. & 1863 .NOT. BTEST( wall_flags_total_0(k,j,i+1), 22 ) ) & 1914 1864 THEN 1915 1865 de_dx(k,j,i) = 0.0_wp 1916 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j,i-1), 22 ) .AND. &1917 .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) ) &1866 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j,i-1), 22 ) .AND. & 1867 .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) ) & 1918 1868 THEN 1919 1869 de_dx(k,j,i) = 0.0_wp … … 1922 1872 ENDIF 1923 1873 1924 IF ( .NOT. BTEST( wall_flags_total_0(k,j-1,i), 0 ) .AND. &1925 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. &1926 BTEST( wall_flags_total_0(k,j+1,i), 0 ) ) &1874 IF ( .NOT. BTEST( wall_flags_total_0(k,j-1,i), 0 ) .AND. & 1875 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. & 1876 BTEST( wall_flags_total_0(k,j+1,i), 0 ) ) & 1927 1877 THEN 1928 de_dy(k,j,i) = 2.0_wp * sgs_wf_part * & 1929 ( e(k,j+1,i) - e(k,j,i) ) * ddy 1930 ELSEIF ( BTEST( wall_flags_total_0(k,j-1,i), 0 ) .AND. & 1931 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. & 1932 .NOT. BTEST( wall_flags_total_0(k,j+1,i), 0 ) ) & 1878 de_dy(k,j,i) = 2.0_wp * sgs_wf_part * ( e(k,j+1,i) - e(k,j,i) ) * ddy 1879 ELSEIF ( BTEST( wall_flags_total_0(k,j-1,i), 0 ) .AND. & 1880 BTEST( wall_flags_total_0(k,j,i), 0 ) .AND. & 1881 .NOT. BTEST( wall_flags_total_0(k,j+1,i), 0 ) ) & 1933 1882 THEN 1934 de_dy(k,j,i) = 2.0_wp * sgs_wf_part * & 1935 ( e(k,j,i) - e(k,j-1,i) ) * ddy 1936 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) .AND. & 1937 .NOT. BTEST( wall_flags_total_0(k,j+1,i), 22 ) ) & 1883 de_dy(k,j,i) = 2.0_wp * sgs_wf_part * ( e(k,j,i) - e(k,j-1,i) ) * ddy 1884 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) .AND. & 1885 .NOT. BTEST( wall_flags_total_0(k,j+1,i), 22 ) ) & 1938 1886 THEN 1939 1887 de_dy(k,j,i) = 0.0_wp 1940 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j-1,i), 22 ) .AND. &1941 .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) ) &1888 ELSEIF ( .NOT. BTEST( wall_flags_total_0(k,j-1,i), 22 ) .AND. & 1889 .NOT. BTEST( wall_flags_total_0(k,j,i), 22 ) ) & 1942 1890 THEN 1943 1891 de_dy(k,j,i) = 0.0_wp … … 1959 1907 flag1 = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_total_0(k,j,i), 0 ) ) 1960 1908 1961 de_dz(k,j,i) = 2.0_wp * sgs_wf_part * & 1962 ( e(k+1,j,i) - e(k-1,j,i) ) / ( zu(k+1) - zu(k-1) ) & 1963 * flag1 1909 de_dz(k,j,i) = 2.0_wp * sgs_wf_part * & 1910 ( e(k+1,j,i) - e(k-1,j,i) ) / ( zu(k+1) - zu(k-1) ) * flag1 1964 1911 ENDDO 1965 1912 ! … … 1967 1914 DO m = bc_h(0)%start_index(j,i), bc_h(0)%end_index(j,i) 1968 1915 k = bc_h(0)%k(m) 1969 de_dz(k,j,i) = 2.0_wp * sgs_wf_part * & 1970 ( e(k+1,j,i) - e(k,j,i) ) / ( zu(k+1) - zu(k) ) 1916 de_dz(k,j,i) = 2.0_wp * sgs_wf_part * ( e(k+1,j,i) - e(k,j,i) ) / ( zu(k+1) - zu(k) ) 1971 1917 ENDDO 1972 1918 ! … … 1974 1920 DO m = bc_h(1)%start_index(j,i), bc_h(1)%end_index(j,i) 1975 1921 k = bc_h(1)%k(m) 1976 de_dz(k,j,i) = 2.0_wp * sgs_wf_part * & 1977 ( e(k,j,i) - e(k-1,j,i) ) / ( zu(k) - zu(k-1) ) 1922 de_dz(k,j,i) = 2.0_wp * sgs_wf_part * ( e(k,j,i) - e(k-1,j,i) ) / ( zu(k) - zu(k-1) ) 1978 1923 ENDDO 1979 1924 … … 1990 1935 CALL exchange_horiz( diss, nbgp ) 1991 1936 ! 1992 !-- Set boundary conditions at non-periodic boundaries. Note, at non-period 1993 !-- boundaries zero-gradient boundary conditions are set for the subgrid TKE. 1994 !-- Thus, TKE gradients normal to the respective lateral boundaries are zero, 1995 !-- while tangetial TKE gradients then must be the same as within the prognostic 1996 !-- domain. 1937 !-- Set boundary conditions at non-periodic boundaries. Note, at non-period boundaries zero-gradient 1938 !-- boundary conditions are set for the subgrid TKE. 1939 !-- Thus, TKE gradients normal to the respective lateral boundaries are zero, 1940 !-- while tangetial TKE gradients then must be the same as within the prognostic domain. 1997 1941 IF ( bc_dirichlet_l ) THEN 1998 1942 de_dx(:,:,-1) = 0.0_wp 1999 de_dy(:,:,-1) = de_dy(:,:,0) 1943 de_dy(:,:,-1) = de_dy(:,:,0) 2000 1944 de_dz(:,:,-1) = de_dz(:,:,0) 2001 1945 ENDIF 2002 1946 IF ( bc_dirichlet_r ) THEN 2003 1947 de_dx(:,:,nxr+1) = 0.0_wp 2004 de_dy(:,:,nxr+1) = de_dy(:,:,nxr) 1948 de_dy(:,:,nxr+1) = de_dy(:,:,nxr) 2005 1949 de_dz(:,:,nxr+1) = de_dz(:,:,nxr) 2006 1950 ENDIF 2007 1951 IF ( bc_dirichlet_n ) THEN 2008 1952 de_dx(:,nyn+1,:) = de_dx(:,nyn,:) 2009 de_dy(:,nyn+1,:) = 0.0_wp 1953 de_dy(:,nyn+1,:) = 0.0_wp 2010 1954 de_dz(:,nyn+1,:) = de_dz(:,nyn,:) 2011 1955 ENDIF 2012 1956 IF ( bc_dirichlet_s ) THEN 2013 1957 de_dx(:,nys-1,:) = de_dx(:,nys,:) 2014 de_dy(:,nys-1,:) = 0.0_wp 1958 de_dy(:,nys-1,:) = 0.0_wp 2015 1959 de_dz(:,nys-1,:) = de_dz(:,nys,:) 2016 ENDIF 2017 ! 2018 !-- Calculate the horizontally averaged profiles of SGS TKE and resolved 2019 !-- velocity variances (they may have been already calculated in routine 2020 !-- flow_statistics). 1960 ENDIF 1961 ! 1962 !-- Calculate the horizontally averaged profiles of SGS TKE and resolved velocity variances (they 1963 !-- may have been already calculated in routine flow_statistics). 2021 1964 IF ( .NOT. flow_statistics_called ) THEN 2022 1965 2023 1966 ! 2024 !-- First calculate horizontally averaged profiles of the horizontal 2025 !-- velocities. 1967 !-- First calculate horizontally averaged profiles of the horizontal velocities. 2026 1968 sums_l(:,1,0) = 0.0_wp 2027 1969 sums_l(:,2,0) = 0.0_wp … … 2044 1986 !-- Compute total sum from local sums 2045 1987 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2046 CALL MPI_ALLREDUCE( sums_l(nzb,1,0), sums(nzb,1), nzt+2-nzb, &2047 MPI_REAL, MPI_SUM, comm2d,ierr )1988 CALL MPI_ALLREDUCE( sums_l(nzb,1,0), sums(nzb,1), nzt+2-nzb, MPI_REAL, MPI_SUM, comm2d, & 1989 ierr ) 2048 1990 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2049 CALL MPI_ALLREDUCE( sums_l(nzb,2,0), sums(nzb,2), nzt+2-nzb, &2050 MPI_REAL, MPI_SUM, comm2d,ierr )1991 CALL MPI_ALLREDUCE( sums_l(nzb,2,0), sums(nzb,2), nzt+2-nzb, MPI_REAL, MPI_SUM, comm2d, & 1992 ierr ) 2051 1993 #else 2052 1994 sums(:,1) = sums_l(:,1,0) … … 2055 1997 2056 1998 ! 2057 !-- Final values are obtained by division by the total number of grid 2058 !-- points used for thesummation.1999 !-- Final values are obtained by division by the total number of grid points used for the 2000 !-- summation. 2059 2001 hom(:,1,1,0) = sums(:,1) / ngp_2dh_outer(:,0) ! u 2060 2002 hom(:,1,2,0) = sums(:,2) / ngp_2dh_outer(:,0) ! v 2061 2003 2062 2004 ! 2063 !-- Now calculate the profiles of SGS TKE and the resolved-scale 2064 !-- velocity variances 2005 !-- Now calculate the profiles of SGS TKE and the resolved-scale velocity variances 2065 2006 sums_l(:,8,0) = 0.0_wp 2066 2007 sums_l(:,30,0) = 0.0_wp … … 2086 2027 !-- Compute total sum from local sums 2087 2028 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2088 CALL MPI_ALLREDUCE( sums_l(nzb,8,0), sums(nzb,8), nzt+2-nzb, &2089 MPI_REAL, MPI_SUM, comm2d,ierr )2029 CALL MPI_ALLREDUCE( sums_l(nzb,8,0), sums(nzb,8), nzt+2-nzb, MPI_REAL, MPI_SUM, comm2d, & 2030 ierr ) 2090 2031 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2091 CALL MPI_ALLREDUCE( sums_l(nzb,30,0), sums(nzb,30), nzt+2-nzb, &2092 MPI_REAL, MPI_SUM, comm2d,ierr )2032 CALL MPI_ALLREDUCE( sums_l(nzb,30,0), sums(nzb,30), nzt+2-nzb, MPI_REAL, MPI_SUM, comm2d, & 2033 ierr ) 2093 2034 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2094 CALL MPI_ALLREDUCE( sums_l(nzb,31,0), sums(nzb,31), nzt+2-nzb, &2095 MPI_REAL, MPI_SUM, comm2d,ierr )2035 CALL MPI_ALLREDUCE( sums_l(nzb,31,0), sums(nzb,31), nzt+2-nzb, MPI_REAL, MPI_SUM, comm2d, & 2036 ierr ) 2096 2037 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2097 CALL MPI_ALLREDUCE( sums_l(nzb,32,0), sums(nzb,32), nzt+2-nzb, &2098 MPI_REAL, MPI_SUM, comm2d,ierr )2038 CALL MPI_ALLREDUCE( sums_l(nzb,32,0), sums(nzb,32), nzt+2-nzb, MPI_REAL, MPI_SUM, comm2d, & 2039 ierr ) 2099 2040 2100 2041 #else … … 2106 2047 2107 2048 ! 2108 !-- Final values are obtained by division by the total number of grid 2109 !-- points used for thesummation.2049 !-- Final values are obtained by division by the total number of grid points used for the 2050 !-- summation. 2110 2051 hom(:,1,8,0) = sums(:,8) / ngp_2dh_outer(:,0) ! e 2111 2052 hom(:,1,30,0) = sums(:,30) / ngp_2dh_outer(:,0) ! u*2 2112 hom(:,1,31,0) = sums(:,31) / ngp_2dh_outer(:,0) ! v*2 2053 hom(:,1,31,0) = sums(:,31) / ngp_2dh_outer(:,0) ! v*2 2113 2054 hom(:,1,32,0) = sums(:,32) / ngp_2dh_outer(:,0) ! w*2 2114 2055 … … 2116 2057 2117 2058 END SUBROUTINE lpm_init_sgs_tke 2118 2119 2120 !------------------------------------------------------------------------------ !2059 2060 2061 !--------------------------------------------------------------------------------------------------! 2121 2062 ! Description: 2122 2063 ! ------------ 2123 !> Sobroutine control lpm actions, i.e. all actions during one time step. 2124 !------------------------------------------------------------------------------ !2064 !> Sobroutine control lpm actions, i.e. all actions during one time step. 2065 !--------------------------------------------------------------------------------------------------! 2125 2066 SUBROUTINE lpm_actions( location ) 2126 2067 2127 USE exchange_horiz_mod, &2068 USE exchange_horiz_mod, & 2128 2069 ONLY: exchange_horiz 2129 2070 … … 2152 2093 !-- The particle model is executed if particle advection start is reached and only at the end 2153 2094 !-- of the intermediate time step loop. 2154 IF ( time_since_reference_point >= particle_advection_start &2095 IF ( time_since_reference_point >= particle_advection_start & 2155 2096 .AND. intermediate_timestep_count == intermediate_timestep_count_max ) & 2156 2097 THEN … … 2158 2099 ! 2159 2100 !-- Write particle data at current time on file. 2160 !-- This has to be done here, before particles are further processed, 2161 !-- because they may be deleted within this timestep (in case that2162 !-- dt_write_particle_data = dt_prel =particle_maximum_age).2101 !-- This has to be done here, before particles are further processed, because they may be 2102 !-- deleted within this timestep (in case that dt_write_particle_data = dt_prel = 2103 !-- particle_maximum_age). 2163 2104 time_write_particle_data = time_write_particle_data + dt_3d 2164 2105 IF ( time_write_particle_data >= dt_write_particle_data ) THEN … … 2166 2107 CALL lpm_data_output_particles 2167 2108 ! 2168 !-- The MOD function allows for changes in the output interval with restart 2169 !-- runs. 2170 time_write_particle_data = MOD( time_write_particle_data, & 2109 !-- The MOD function allows for changes in the output interval with restart runs. 2110 time_write_particle_data = MOD( time_write_particle_data, & 2171 2111 MAX( dt_write_particle_data, dt_3d ) ) 2172 2112 ENDIF 2173 2113 2174 2114 ! 2175 !-- Initialize arrays for marking those particles to be deleted after the 2176 !-- (sub-) timestep 2115 !-- Initialize arrays for marking those particles to be deleted after the (sub-) timestep. 2177 2116 deleted_particles = 0 2178 2117 2179 2118 ! 2180 !-- Initialize variables used for accumulating the number of particles 2181 !-- xchanged between the subdomains during all sub-timesteps (if sgs 2182 !-- velocities are included). These data are output further below on the 2183 !-- particle statistics file. 2119 !-- Initialize variables used for accumulating the number of particles exchanged between 2120 !-- the subdomains during all sub-timesteps (if sgs velocities are included). These data 2121 !-- are output further below on the particle statistics file. 2184 2122 trlp_count_sum = 0 2185 2123 trlp_count_recv_sum = 0 … … 2195 2133 DO m = 1, number_of_particle_groups 2196 2134 IF ( particle_groups(m)%density_ratio /= 0.0_wp ) THEN 2197 particle_groups(m)%exp_arg = & 2198 4.5_wp * particle_groups(m)%density_ratio * & 2199 molecular_viscosity / ( particle_groups(m)%radius )**2 2200 2201 particle_groups(m)%exp_term = EXP( -particle_groups(m)%exp_arg * & 2202 dt_3d ) 2135 particle_groups(m)%exp_arg = 4.5_wp * particle_groups(m)%density_ratio * & 2136 molecular_viscosity / & 2137 ( particle_groups(m)%radius )**2 2138 2139 particle_groups(m)%exp_term = EXP( -particle_groups(m)%exp_arg * dt_3d ) 2203 2140 ENDIF 2204 2141 ENDDO 2205 2142 ! 2206 2143 !-- If necessary, release new set of particles 2207 IF ( ( simulated_time - last_particle_release_time ) >= dt_prel .AND. &2144 IF ( ( simulated_time - last_particle_release_time ) >= dt_prel .AND. & 2208 2145 end_time_prel > simulated_time ) THEN 2209 2146 DO WHILE ( ( simulated_time - last_particle_release_time ) >= dt_prel ) 2210 CALL lpm_create_particle( PHASE_RELEASE)2147 CALL lpm_create_particle( phase_release ) 2211 2148 last_particle_release_time = last_particle_release_time + dt_prel 2212 2149 ENDDO … … 2224 2161 ! 2225 2162 !-- Timestep loop for particle advection. 2226 !-- This loop has to be repeated until the advection time of every particle 2227 !-- (within the total domain!) has reached the LES timestep (dt_3d). 2228 !-- In case of including the SGS velocities, the particle timestep may be 2229 !-- smaller than the LES timestep (because of the Lagrangian timescale 2230 !-- restriction) and particles may require to undergo several particle 2231 !-- timesteps, before the LES timestep is reached. Because the number of these 2232 !-- particle timesteps to be carried out is unknown at first, these steps are 2233 !-- carried out in the following infinite loop with exit condition. 2163 !-- This loop has to be repeated until the advection time of every particle (within the 2164 !-- total domain!) has reached the LES timestep (dt_3d). 2165 !-- In case of including the SGS velocities, the particle timestep may be smaller than the 2166 !-- LES timestep (because of the Lagrangian timescale restriction) and particles may 2167 !-- require to undergo several particle timesteps, before the LES timestep is reached. 2168 !-- Because the number of these particle timesteps to be carried out is unknown at first, 2169 !-- these steps are carried out in the following infinite loop with exit condition. 2234 2170 DO 2235 2171 CALL cpu_log( log_point_s(44), 'lpm_advec', 'start' ) … … 2237 2173 2238 2174 ! 2239 !-- If particle advection includes SGS velocity components, calculate the 2240 !-- required SGS quantities (i.e. gradients of the TKE, as well as 2241 !-- horizontally averaged profiles of the SGS TKE and the resolved-scale 2242 !-- velocity variances) 2175 !-- If particle advection includes SGS velocity components, calculate the required SGS 2176 !-- quantities (i.e. gradients of the TKE, as well as horizontally averaged profiles of 2177 !-- the SGS TKE and the resolved-scale velocity variances) 2243 2178 IF ( use_sgs_for_particles .AND. .NOT. cloud_droplets ) THEN 2244 2179 CALL lpm_init_sgs_tke 2245 2180 ENDIF 2246 2181 ! 2247 !-- In case SGS-particle speed is considered, particles may carry out 2248 !-- several particle timesteps. In order to prevent unnecessary 2249 !-- treatment of particles that already reached the final time level, 2250 !-- particles are sorted into contiguous blocks of finished and 2251 !-- not-finished particles, in addition to their already sorting 2182 !-- In case SGS-particle speed is considered, particles may carry out several particle 2183 !-- timesteps. In order to prevent unnecessary treatment of particles that already 2184 !-- reached the final time level, particles are sorted into contiguous blocks of 2185 !-- finished and not-finished particles, in addition to their already sorting 2252 2186 !-- according to their sub-boxes. 2253 IF ( .NOT. first_loop_stride .AND. use_sgs_for_particles ) &2187 IF ( .NOT. first_loop_stride .AND. use_sgs_for_particles ) & 2254 2188 CALL lpm_sort_timeloop_done 2255 2189 DO i = nxl, nxr … … 2276 2210 particles(1:number_of_particles)%particle_mask = .TRUE. 2277 2211 ! 2278 !-- Initialize the variable storing the total time that a particle 2279 !-- has advanced within the timestep procedure2212 !-- Initialize the variable storing the total time that a particle has advanced 2213 !-- within the timestep procedure. 2280 2214 IF ( first_loop_stride ) THEN 2281 2215 particles(1:number_of_particles)%dt_sum = 0.0_wp 2282 2216 ENDIF 2283 2217 ! 2284 !-- Particle (droplet) growth by condensation/evaporation and 2285 !-- collision 2218 !-- Particle (droplet) growth by condensation/evaporation and collision 2286 2219 IF ( cloud_droplets .AND. first_loop_stride) THEN 2287 2220 ! … … 2296 2229 ENDIF 2297 2230 ! 2298 !-- Initialize the switch used for the loop exit condition checked 2299 !-- at the end of this loop. If at least one particle has failed to 2300 !-- reach the LES timestep, this switch will be set false in 2301 !-- lpm_advec. 2231 !-- Initialize the switch used for the loop exit condition checked at the end 2232 !-- of this loop. If at least one particle has failed to reach the LES 2233 !-- timestep, this switch will be set false in lpm_advec. 2302 2234 dt_3d_reached_l = .TRUE. 2303 2235 … … 2306 2238 CALL lpm_advec( i, j, k ) 2307 2239 ! 2308 !-- Particle reflection from walls. Only applied if the particles 2309 !-- are in the vertical range of the topography. (Here, some2310 !-- optimization is stillpossible.)2240 !-- Particle reflection from walls. Only applied if the particles are in the 2241 !-- vertical range of the topography. (Here, some optimization is still 2242 !-- possible.) 2311 2243 IF ( topography /= 'flat' .AND. k < nzb_max + 2 ) THEN 2312 2244 CALL lpm_boundary_conds( 'walls', i, j, k ) 2313 2245 ENDIF 2314 2246 ! 2315 !-- User-defined actions after the calculation of the new particle 2316 !-- position 2247 !-- User-defined actions after the calculation of the new particle position 2317 2248 CALL user_lpm_advec( i, j, k ) 2318 2249 ! 2319 !-- Apply boundary conditions to those particles that have crossed 2320 !-- the top or bottom boundary and delete those particles, which are 2321 !-- older than allowed 2250 !-- Apply boundary conditions to those particles that have crossed the top or 2251 !-- bottom boundary and delete those particles, which are older than allowed 2322 2252 CALL lpm_boundary_conds( 'bottom/top', i, j, k ) 2323 2253 ! 2324 !--- If not all particles of the actual grid cell have reached the 2325 !-- LES timestep, this cell has to do another loop iteration. Due to2326 !-- the fact that particles can move into neighboring grid cells,2327 !-- these neighbor cells also have toperform another loop iteration.2328 !-- Please note, this realization does not work properly if 2329 !-- particles move intoanother subdomain.2254 !--- If not all particles of the actual grid cell have reached the LES timestep, 2255 !-- this cell has to do another loop iteration. Due to the fact that particles 2256 !-- can move into neighboring grid cells, these neighbor cells also have to 2257 !-- perform another loop iteration. 2258 !-- Please note, this realization does not work properly if particles move into 2259 !-- another subdomain. 2330 2260 IF ( .NOT. dt_3d_reached_l ) THEN 2331 2261 ks = MAX(nzb+1,k-1) … … 2350 2280 dt_3d_reached_l = ALL(grid_particles(:,:,:)%time_loop_done) 2351 2281 ! 2352 !-- Find out, if all particles on every PE have completed the LES timestep 2353 !-- and set theswitch corespondingly2282 !-- Find out, if all particles on every PE have completed the LES timestep and set the 2283 !-- switch corespondingly 2354 2284 #if defined( __parallel ) 2355 2285 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2356 CALL MPI_ALLREDUCE( dt_3d_reached_l, dt_3d_reached, 1, MPI_LOGICAL, &2357 MPI_LAND,comm2d, ierr )2286 CALL MPI_ALLREDUCE( dt_3d_reached_l, dt_3d_reached, 1, MPI_LOGICAL, MPI_LAND, & 2287 comm2d, ierr ) 2358 2288 #else 2359 2289 dt_3d_reached = dt_3d_reached_l … … 2382 2312 IF ( .NOT. dt_3d_reached .OR. .NOT. nested_run ) THEN 2383 2313 ! 2384 !-- Pack particles (eliminate those marked for deletion), 2385 !-- determine new number ofparticles2314 !-- Pack particles (eliminate those marked for deletion), determine new number of 2315 !-- particles 2386 2316 CALL lpm_sort_and_delete 2387 2317 2388 !-- Initialize variables for the next (sub-) timestep, i.e., for marking 2389 !-- thoseparticles to be deleted after the timestep2318 !-- Initialize variables for the next (sub-) timestep, i.e., for marking those 2319 !-- particles to be deleted after the timestep 2390 2320 deleted_particles = 0 2391 2321 ENDIF … … 2398 2328 #if defined( __parallel ) 2399 2329 ! 2400 !-- in case of nested runs do the transfer of particles after every full model time step2330 !-- In case of nested runs do the transfer of particles after every full model time step 2401 2331 IF ( nested_run ) THEN 2402 2332 CALL particles_from_parent_to_child … … 2433 2363 2434 2364 ! 2435 !-- Write particle statistics (in particular the number of particles 2436 !-- exchanged between thesubdomains) on file2365 !-- Write particle statistics (in particular the number of particles exchanged between the 2366 !-- subdomains) on file 2437 2367 IF ( write_particle_statistics ) CALL lpm_write_exchange_statistics 2438 2368 ! 2439 !-- Execute Interactions of condnesation and evaporation to humidity and 2440 !-- temperature field 2369 !-- Execute Interactions of condnesation and evaporation to humidity and temperature field 2441 2370 IF ( cloud_droplets ) THEN 2442 2371 CALL lpm_interaction_droplets_ptq … … 2465 2394 CASE ( 'after_integration' ) 2466 2395 ! 2467 !-- Call at the end of timestep routine to save particle velocities fields 2468 !-- for the nexttimestep2396 !-- Call at the end of timestep routine to save particle velocities fields for the next 2397 !-- timestep 2469 2398 CALL lpm_swap_timelevel_for_particle_advection 2470 2399 … … 2475 2404 2476 2405 END SUBROUTINE lpm_actions 2477 2406 2478 2407 2479 2408 #if defined( __parallel ) 2480 !------------------------------------------------------------------------------ !2409 !--------------------------------------------------------------------------------------------------! 2481 2410 ! Description: 2482 2411 ! ------------ 2483 2412 ! 2484 !------------------------------------------------------------------------------ !2413 !--------------------------------------------------------------------------------------------------! 2485 2414 SUBROUTINE particles_from_parent_to_child 2486 2415 … … 2492 2421 END SUBROUTINE particles_from_parent_to_child 2493 2422 2494 2495 !------------------------------------------------------------------------------ !2423 2424 !--------------------------------------------------------------------------------------------------! 2496 2425 ! Description: 2497 2426 ! ------------ 2498 2427 ! 2499 !------------------------------------------------------------------------------ !2428 !--------------------------------------------------------------------------------------------------! 2500 2429 SUBROUTINE particles_from_child_to_parent 2501 2430 … … 2507 2436 END SUBROUTINE particles_from_child_to_parent 2508 2437 #endif 2509 2510 !------------------------------------------------------------------------------ !2438 2439 !--------------------------------------------------------------------------------------------------! 2511 2440 ! Description: 2512 2441 ! ------------ 2513 !> This routine write exchange statistics of the lpm in a ascii file. 2514 !------------------------------------------------------------------------------ !2442 !> This routine write exchange statistics of the lpm in a ascii file. 2443 !--------------------------------------------------------------------------------------------------! 2515 2444 SUBROUTINE lpm_write_exchange_statistics 2516 2445 … … 2526 2455 DO jp = nys, nyn 2527 2456 DO kp = nzb+1, nzt 2528 number_of_particles = number_of_particles & 2529 + prt_count(kp,jp,ip) 2457 number_of_particles = number_of_particles + prt_count(kp,jp,ip) 2530 2458 ENDDO 2531 2459 ENDDO … … 2534 2462 CALL check_open( 80 ) 2535 2463 #if defined( __parallel ) 2536 WRITE ( 80, 8000 ) current_timestep_number+1, simulated_time+dt_3d, & 2537 number_of_particles, pleft, trlp_count_sum, & 2538 trlp_count_recv_sum, pright, trrp_count_sum, & 2539 trrp_count_recv_sum, psouth, trsp_count_sum, & 2540 trsp_count_recv_sum, pnorth, trnp_count_sum, & 2541 trnp_count_recv_sum 2464 WRITE ( 80, 8000 ) current_timestep_number+1, simulated_time+dt_3d, number_of_particles, & 2465 pleft, trlp_count_sum, trlp_count_recv_sum, pright, trrp_count_sum, & 2466 trrp_count_recv_sum, psouth, trsp_count_sum, trsp_count_recv_sum, pnorth, & 2467 trnp_count_sum, trnp_count_recv_sum 2542 2468 #else 2543 WRITE ( 80, 8000 ) current_timestep_number+1, simulated_time+dt_3d, & 2544 number_of_particles 2469 WRITE ( 80, 8000 ) current_timestep_number+1, simulated_time+dt_3d, number_of_particles 2545 2470 #endif 2546 2471 CALL close_file( 80 ) 2547 2472 2548 2473 IF ( number_of_particles > 0 ) THEN 2549 WRITE(9,*) 'number_of_particles ', number_of_particles, 2550 current_timestep_number + 1,simulated_time + dt_3d2474 WRITE(9,*) 'number_of_particles ', number_of_particles, current_timestep_number + 1, & 2475 simulated_time + dt_3d 2551 2476 ENDIF 2552 2477 2553 2478 #if defined( __parallel ) 2554 CALL MPI_ALLREDUCE( number_of_particles, tot_number_of_particles, 1, 2555 MPI_INTEGER, MPI_SUM,comm2d, ierr )2479 CALL MPI_ALLREDUCE( number_of_particles, tot_number_of_particles, 1, MPI_INTEGER, MPI_SUM, & 2480 comm2d, ierr ) 2556 2481 #else 2557 2482 tot_number_of_particles = number_of_particles … … 2560 2485 #if defined( __parallel ) 2561 2486 IF ( nested_run ) THEN 2562 CALL pmcp_g_print_number_of_particles( simulated_time+dt_3d, & 2563 tot_number_of_particles) 2487 CALL pmcp_g_print_number_of_particles( simulated_time + dt_3d, tot_number_of_particles) 2564 2488 ENDIF 2565 2489 #endif … … 2571 2495 2572 2496 END SUBROUTINE lpm_write_exchange_statistics 2573 2574 2575 !------------------------------------------------------------------------------ !2497 2498 2499 !--------------------------------------------------------------------------------------------------! 2576 2500 ! Description: 2577 2501 ! ------------ 2578 !> Write particle data in FORTRAN binary and/or netCDF format 2579 !------------------------------------------------------------------------------ !2502 !> Write particle data in FORTRAN binary and/or netCDF format 2503 !--------------------------------------------------------------------------------------------------! 2580 2504 SUBROUTINE lpm_data_output_particles 2581 2505 2582 2506 INTEGER(iwp) :: ip !< 2583 2507 INTEGER(iwp) :: jp !< … … 2587 2511 2588 2512 ! 2589 !-- Attention: change version number for unit 85 (in routine check_open) 2590 !-- whenever the output formatfor this unit is changed!2513 !-- Attention: change version number for unit 85 (in routine check_open) whenever the output format 2514 !-- for this unit is changed! 2591 2515 CALL check_open( 85 ) 2592 2516 … … 2612 2536 ! !-- Output in netCDF format 2613 2537 ! CALL check_open( 108 ) 2614 ! 2538 ! 2615 2539 ! ! 2616 2540 ! !-- Update the NetCDF time axis 2617 2541 ! prt_time_count = prt_time_count + 1 2618 ! 2542 ! 2619 2543 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_time_prt, & 2620 2544 ! (/ simulated_time /), & 2621 2545 ! start = (/ prt_time_count /), count = (/ 1 /) ) 2622 2546 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 1 ) 2623 ! 2547 ! 2624 2548 ! ! 2625 2549 ! !-- Output the real number of particles used … … 2628 2552 ! start = (/ prt_time_count /), count = (/ 1 /) ) 2629 2553 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 2 ) 2630 ! 2554 ! 2631 2555 ! ! 2632 2556 ! !-- Output all particle attributes … … 2635 2559 ! count = (/ maximum_number_of_particles /) ) 2636 2560 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 3 ) 2637 ! 2561 ! 2638 2562 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(2), particles%user, & 2639 2563 ! start = (/ 1, prt_time_count /), & 2640 2564 ! count = (/ maximum_number_of_particles /) ) 2641 2565 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 4 ) 2642 ! 2566 ! 2643 2567 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(3), particles%origin_x, & 2644 2568 ! start = (/ 1, prt_time_count /), & 2645 2569 ! count = (/ maximum_number_of_particles /) ) 2646 2570 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 5 ) 2647 ! 2571 ! 2648 2572 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(4), particles%origin_y, & 2649 2573 ! start = (/ 1, prt_time_count /), & 2650 2574 ! count = (/ maximum_number_of_particles /) ) 2651 2575 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 6 ) 2652 ! 2576 ! 2653 2577 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(5), particles%origin_z, & 2654 2578 ! start = (/ 1, prt_time_count /), & 2655 2579 ! count = (/ maximum_number_of_particles /) ) 2656 2580 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 7 ) 2657 ! 2581 ! 2658 2582 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(6), particles%radius, & 2659 2583 ! start = (/ 1, prt_time_count /), & 2660 2584 ! count = (/ maximum_number_of_particles /) ) 2661 2585 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 8 ) 2662 ! 2586 ! 2663 2587 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(7), particles%speed_x, & 2664 2588 ! start = (/ 1, prt_time_count /), & 2665 2589 ! count = (/ maximum_number_of_particles /) ) 2666 2590 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 9 ) 2667 ! 2591 ! 2668 2592 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(8), particles%speed_y, & 2669 2593 ! start = (/ 1, prt_time_count /), & 2670 2594 ! count = (/ maximum_number_of_particles /) ) 2671 2595 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 10 ) 2672 ! 2596 ! 2673 2597 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(9), particles%speed_z, & 2674 2598 ! start = (/ 1, prt_time_count /), & 2675 2599 ! count = (/ maximum_number_of_particles /) ) 2676 2600 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 11 ) 2677 ! 2601 ! 2678 2602 ! nc_stat = NF90_PUT_VAR( id_set_prt,id_var_prt(10), & 2679 2603 ! particles%weight_factor, & … … 2681 2605 ! count = (/ maximum_number_of_particles /) ) 2682 2606 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 12 ) 2683 ! 2607 ! 2684 2608 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(11), particles%x, & 2685 2609 ! start = (/ 1, prt_time_count /), & 2686 2610 ! count = (/ maximum_number_of_particles /) ) 2687 2611 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 13 ) 2688 ! 2612 ! 2689 2613 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(12), particles%y, & 2690 2614 ! start = (/ 1, prt_time_count /), & 2691 2615 ! count = (/ maximum_number_of_particles /) ) 2692 2616 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 14 ) 2693 ! 2617 ! 2694 2618 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(13), particles%z, & 2695 2619 ! start = (/ 1, prt_time_count /), & 2696 2620 ! count = (/ maximum_number_of_particles /) ) 2697 2621 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 15 ) 2698 ! 2622 ! 2699 2623 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(14), particles%class, & 2700 2624 ! start = (/ 1, prt_time_count /), & 2701 2625 ! count = (/ maximum_number_of_particles /) ) 2702 2626 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 16 ) 2703 ! 2627 ! 2704 2628 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(15), particles%group, & 2705 2629 ! start = (/ 1, prt_time_count /), & 2706 2630 ! count = (/ maximum_number_of_particles /) ) 2707 2631 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 17 ) 2708 ! 2632 ! 2709 2633 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(16), & 2710 2634 ! particles%id2, & … … 2712 2636 ! count = (/ maximum_number_of_particles /) ) 2713 2637 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 18 ) 2714 ! 2638 ! 2715 2639 ! nc_stat = NF90_PUT_VAR( id_set_prt, id_var_prt(17), particles%id1, & 2716 2640 ! start = (/ 1, prt_time_count /), & 2717 2641 ! count = (/ maximum_number_of_particles /) ) 2718 2642 ! CALL netcdf_handle_error( 'lpm_data_output_particles', 19 ) 2719 ! 2643 ! 2720 2644 #endif 2721 2645 … … 2723 2647 2724 2648 END SUBROUTINE lpm_data_output_particles 2725 2726 !------------------------------------------------------------------------------ !2649 2650 !--------------------------------------------------------------------------------------------------! 2727 2651 ! Description: 2728 2652 ! ------------ 2729 2653 !> This routine calculates and provide particle timeseries output. 2730 !------------------------------------------------------------------------------ !2654 !--------------------------------------------------------------------------------------------------! 2731 2655 SUBROUTINE lpm_data_output_ptseries 2732 2656 2733 2657 INTEGER(iwp) :: i !< 2734 2658 INTEGER(iwp) :: inum !< … … 2752 2676 ! 2753 2677 !-- Update the particle time series time axis 2754 nc_stat = NF90_PUT_VAR( id_set_pts, id_var_time_pts, & 2755 (/ time_since_reference_point /), & 2678 nc_stat = NF90_PUT_VAR( id_set_pts, id_var_time_pts, (/ time_since_reference_point /), & 2756 2679 start = (/ dopts_time_count /), count = (/ 1 /) ) 2757 2680 CALL netcdf_handle_error( 'data_output_ptseries', 391 ) … … 2760 2683 ENDIF 2761 2684 2762 ALLOCATE( pts_value(0:number_of_particle_groups,dopts_num), &2685 ALLOCATE( pts_value(0:number_of_particle_groups,dopts_num), & 2763 2686 pts_value_l(0:number_of_particle_groups,dopts_num) ) 2764 2687 … … 2767 2690 2768 2691 ! 2769 !-- Calculate or collect the particle time series quantities for all particles 2770 !-- and seperately foreach particle group (if there is more than one group)2692 !-- Calculate or collect the particle time series quantities for all particles and seperately for 2693 !-- each particle group (if there is more than one group) 2771 2694 DO i = nxl, nxr 2772 2695 DO j = nys, nyn … … 2779 2702 IF ( particles(n)%particle_mask ) THEN ! Restrict analysis to active particles 2780 2703 2781 pts_value_l(0,1) = pts_value_l(0,1) + 1.0_wp ! total # of particles2782 pts_value_l(0,2) = pts_value_l(0,2) + &2783 ( particles(n)%x - particles(n)%origin_x ) ! mean x2784 pts_value_l(0,3) = pts_value_l(0,3) + &2785 ( particles(n)%y - particles(n)%origin_y ) ! mean y2786 pts_value_l(0,4) = pts_value_l(0,4) + &2787 ( particles(n)%z - particles(n)%origin_z ) ! mean z2788 pts_value_l(0,5) = pts_value_l(0,5) + particles(n)%z ! mean z (absolute)2789 pts_value_l(0,6) = pts_value_l(0,6) + particles(n)%speed_x ! mean u2790 pts_value_l(0,7) = pts_value_l(0,7) + particles(n)%speed_y ! mean v2791 pts_value_l(0,8) = pts_value_l(0,8) + particles(n)%speed_z ! mean w2792 pts_value_l(0,9) = pts_value_l(0,9) + particles(n)%rvar1 ! mean sgsu2793 pts_value_l(0,10) = pts_value_l(0,10) + particles(n)%rvar2 ! mean sgsv2794 pts_value_l(0,11) = pts_value_l(0,11) + particles(n)%rvar3 ! mean sgsw2704 pts_value_l(0,1) = pts_value_l(0,1) + 1.0_wp ! total # of particles 2705 pts_value_l(0,2) = pts_value_l(0,2) + & 2706 ( particles(n)%x - particles(n)%origin_x ) ! mean x 2707 pts_value_l(0,3) = pts_value_l(0,3) + & 2708 ( particles(n)%y - particles(n)%origin_y ) ! mean y 2709 pts_value_l(0,4) = pts_value_l(0,4) + & 2710 ( particles(n)%z - particles(n)%origin_z ) ! mean z 2711 pts_value_l(0,5) = pts_value_l(0,5) + particles(n)%z ! mean z (absolute) 2712 pts_value_l(0,6) = pts_value_l(0,6) + particles(n)%speed_x ! mean u 2713 pts_value_l(0,7) = pts_value_l(0,7) + particles(n)%speed_y ! mean v 2714 pts_value_l(0,8) = pts_value_l(0,8) + particles(n)%speed_z ! mean w 2715 pts_value_l(0,9) = pts_value_l(0,9) + particles(n)%rvar1 ! mean sgsu 2716 pts_value_l(0,10) = pts_value_l(0,10) + particles(n)%rvar2 ! mean sgsv 2717 pts_value_l(0,11) = pts_value_l(0,11) + particles(n)%rvar3 ! mean sgsw 2795 2718 IF ( particles(n)%speed_z > 0.0_wp ) THEN 2796 pts_value_l(0,12) = pts_value_l(0,12) + 1.0_wp ! # of upward moving prts 2797 pts_value_l(0,13) = pts_value_l(0,13) + & 2798 particles(n)%speed_z ! mean w upw. 2719 pts_value_l(0,12) = pts_value_l(0,12) + 1.0_wp ! # of upward moving prts 2720 pts_value_l(0,13) = pts_value_l(0,13) + particles(n)%speed_z ! mean w upw. 2799 2721 ELSE 2800 pts_value_l(0,14) = pts_value_l(0,14) + & 2801 particles(n)%speed_z ! mean w down 2722 pts_value_l(0,14) = pts_value_l(0,14) + particles(n)%speed_z ! mean w down 2802 2723 ENDIF 2803 pts_value_l(0,15) = pts_value_l(0,15) + particles(n)%radius ! mean rad2724 pts_value_l(0,15) = pts_value_l(0,15) + particles(n)%radius ! mean rad 2804 2725 pts_value_l(0,16) = MIN( pts_value_l(0,16), particles(n)%radius ) ! minrad 2805 2726 pts_value_l(0,17) = MAX( pts_value_l(0,17), particles(n)%radius ) ! maxrad … … 2812 2733 2813 2734 pts_value_l(jg,1) = pts_value_l(jg,1) + 1.0_wp 2814 pts_value_l(jg,2) = pts_value_l(jg,2) + &2815 ( particles(n)%x- particles(n)%origin_x )2816 pts_value_l(jg,3) = pts_value_l(jg,3) + &2817 ( particles(n)%y- particles(n)%origin_y )2818 pts_value_l(jg,4) = pts_value_l(jg,4) + &2819 ( particles(n)%z- particles(n)%origin_z )2735 pts_value_l(jg,2) = pts_value_l(jg,2) + & 2736 ( particles(n)%x - particles(n)%origin_x ) 2737 pts_value_l(jg,3) = pts_value_l(jg,3) + & 2738 ( particles(n)%y - particles(n)%origin_y ) 2739 pts_value_l(jg,4) = pts_value_l(jg,4) + & 2740 ( particles(n)%z - particles(n)%origin_z ) 2820 2741 pts_value_l(jg,5) = pts_value_l(jg,5) + particles(n)%z 2821 2742 pts_value_l(jg,6) = pts_value_l(jg,6) + particles(n)%speed_x … … 2853 2774 2854 2775 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2855 CALL MPI_ALLREDUCE( pts_value_l(0,1), pts_value(0,1), 15*inum, MPI_REAL, & 2856 MPI_SUM, comm2d, ierr ) 2776 CALL MPI_ALLREDUCE( pts_value_l(0,1), pts_value(0,1), 15*inum, MPI_REAL, MPI_SUM, comm2d, ierr ) 2857 2777 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2858 CALL MPI_ALLREDUCE( pts_value_l(0,16), pts_value(0,16), inum, MPI_REAL, & 2859 MPI_MIN, comm2d, ierr ) 2778 CALL MPI_ALLREDUCE( pts_value_l(0,16), pts_value(0,16), inum, MPI_REAL, MPI_MIN, comm2d, ierr ) 2860 2779 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2861 CALL MPI_ALLREDUCE( pts_value_l(0,17), pts_value(0,17), inum, MPI_REAL, & 2862 MPI_MAX, comm2d, ierr ) 2780 CALL MPI_ALLREDUCE( pts_value_l(0,17), pts_value(0,17), inum, MPI_REAL, MPI_MAX, comm2d, ierr ) 2863 2781 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2864 CALL MPI_ALLREDUCE( pts_value_l(0,18), pts_value(0,18), inum, MPI_REAL, & 2865 MPI_MAX, comm2d, ierr ) 2782 CALL MPI_ALLREDUCE( pts_value_l(0,18), pts_value(0,18), inum, MPI_REAL, MPI_MAX, comm2d, ierr ) 2866 2783 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2867 CALL MPI_ALLREDUCE( pts_value_l(0,19), pts_value(0,19), inum, MPI_REAL, & 2868 MPI_MIN, comm2d, ierr ) 2784 CALL MPI_ALLREDUCE( pts_value_l(0,19), pts_value(0,19), inum, MPI_REAL, MPI_MIN, comm2d, ierr ) 2869 2785 #else 2870 2786 pts_value(:,1:19) = pts_value_l(:,1:19) … … 2872 2788 2873 2789 ! 2874 !-- Normalize the above calculated quantities (except min/max values) with the 2875 !-- total number ofparticles2790 !-- Normalize the above calculated quantities (except min/max values) with the total number of 2791 !-- particles 2876 2792 IF ( number_of_particle_groups > 1 ) THEN 2877 2793 inum = number_of_particle_groups … … 2899 2815 2900 2816 ! 2901 !-- Calculate higher order moments of particle time series quantities, 2902 !-- seperately for each particlegroup (if there is more than one group)2817 !-- Calculate higher order moments of particle time series quantities, seperately for each particle 2818 !-- group (if there is more than one group) 2903 2819 DO i = nxl, nxr 2904 2820 DO j = nys, nyn … … 2909 2825 DO n = 1, number_of_particles 2910 2826 2911 pts_value_l(0,20) = pts_value_l(0,20) + ( particles(n)%x - &2912 particles(n)%origin_x - pts_value(0,2) )**2 ! x*22913 pts_value_l(0,21) = pts_value_l(0,21) + ( particles(n)%y - &2914 particles(n)%origin_y - pts_value(0,3) )**2 ! y*22915 pts_value_l(0,22) = pts_value_l(0,22) + ( particles(n)%z - &2916 particles(n)%origin_z - pts_value(0,4) )**2 ! z*22917 pts_value_l(0,23) = pts_value_l(0,23) + ( particles(n)%speed_x - &2918 pts_value(0,6) )**2! u*22919 pts_value_l(0,24) = pts_value_l(0,24) + ( particles(n)%speed_y - &2920 pts_value(0,7) )**2 ! v*22921 pts_value_l(0,25) = pts_value_l(0,25) + ( particles(n)%speed_z - &2922 pts_value(0,8) )**2 ! w*22923 pts_value_l(0,26) = pts_value_l(0,26) + ( particles(n)%rvar1 - &2924 pts_value(0,9) )**2 ! u"22925 pts_value_l(0,27) = pts_value_l(0,27) + ( particles(n)%rvar2 - &2926 pts_value(0,10) )**2 ! v"22927 pts_value_l(0,28) = pts_value_l(0,28) + ( particles(n)%rvar3 - &2827 pts_value_l(0,20) = pts_value_l(0,20) + ( particles(n)%x - & 2828 particles(n)%origin_x - pts_value(0,2) )**2 ! x*2 2829 pts_value_l(0,21) = pts_value_l(0,21) + ( particles(n)%y - & 2830 particles(n)%origin_y - pts_value(0,3) )**2 ! y*2 2831 pts_value_l(0,22) = pts_value_l(0,22) + ( particles(n)%z - & 2832 particles(n)%origin_z - pts_value(0,4) )**2 ! z*2 2833 pts_value_l(0,23) = pts_value_l(0,23) + ( particles(n)%speed_x - & 2834 pts_value(0,6) )**2 ! u*2 2835 pts_value_l(0,24) = pts_value_l(0,24) + ( particles(n)%speed_y - & 2836 pts_value(0,7) )**2 ! v*2 2837 pts_value_l(0,25) = pts_value_l(0,25) + ( particles(n)%speed_z - & 2838 pts_value(0,8) )**2 ! w*2 2839 pts_value_l(0,26) = pts_value_l(0,26) + ( particles(n)%rvar1 - & 2840 pts_value(0,9) )**2 ! u"2 2841 pts_value_l(0,27) = pts_value_l(0,27) + ( particles(n)%rvar2 - & 2842 pts_value(0,10) )**2 ! v"2 2843 pts_value_l(0,28) = pts_value_l(0,28) + ( particles(n)%rvar3 - & 2928 2844 pts_value(0,11) )**2 ! w"2 2929 2845 ! … … 2932 2848 jg = particles(n)%group 2933 2849 2934 pts_value_l(jg,20) = pts_value_l(jg,20) + ( particles(n)%x - &2935 particles(n)%origin_x - pts_value(jg,2) )**22936 pts_value_l(jg,21) = pts_value_l(jg,21) + ( particles(n)%y - &2937 particles(n)%origin_y - pts_value(jg,3) )**22938 pts_value_l(jg,22) = pts_value_l(jg,22) + ( particles(n)%z - &2939 particles(n)%origin_z - pts_value(jg,4) )**22940 pts_value_l(jg,23) = pts_value_l(jg,23) + ( particles(n)%speed_x - &2941 pts_value(jg,6) )**22942 pts_value_l(jg,24) = pts_value_l(jg,24) + ( particles(n)%speed_y - &2943 pts_value(jg,7) )**22944 pts_value_l(jg,25) = pts_value_l(jg,25) + ( particles(n)%speed_z - &2945 pts_value(jg,8) )**22946 pts_value_l(jg,26) = pts_value_l(jg,26) + ( particles(n)%rvar1 - &2947 pts_value(jg,9) )**22948 pts_value_l(jg,27) = pts_value_l(jg,27) + ( particles(n)%rvar2 - &2949 pts_value(jg,10) )**22950 pts_value_l(jg,28) = pts_value_l(jg,28) + ( particles(n)%rvar3 - &2951 pts_value(jg,11) )**22850 pts_value_l(jg,20) = pts_value_l(jg,20) + ( particles(n)%x - & 2851 particles(n)%origin_x - pts_value(jg,2) )**2 2852 pts_value_l(jg,21) = pts_value_l(jg,21) + ( particles(n)%y - & 2853 particles(n)%origin_y - pts_value(jg,3) )**2 2854 pts_value_l(jg,22) = pts_value_l(jg,22) + ( particles(n)%z - & 2855 particles(n)%origin_z - pts_value(jg,4) )**2 2856 pts_value_l(jg,23) = pts_value_l(jg,23) + ( particles(n)%speed_x - & 2857 pts_value(jg,6) )**2 2858 pts_value_l(jg,24) = pts_value_l(jg,24) + ( particles(n)%speed_y - & 2859 pts_value(jg,7) )**2 2860 pts_value_l(jg,25) = pts_value_l(jg,25) + ( particles(n)%speed_z - & 2861 pts_value(jg,8) )**2 2862 pts_value_l(jg,26) = pts_value_l(jg,26) + ( particles(n)%rvar1 - & 2863 pts_value(jg,9) )**2 2864 pts_value_l(jg,27) = pts_value_l(jg,27) + ( particles(n)%rvar2 - & 2865 pts_value(jg,10) )**2 2866 pts_value_l(jg,28) = pts_value_l(jg,28) + ( particles(n)%rvar3 - & 2867 pts_value(jg,11) )**2 2952 2868 ENDIF 2953 2869 … … 2961 2877 IF ( number_of_particle_groups > 1 ) THEN 2962 2878 DO j = 1, number_of_particle_groups 2963 pts_value_l(j,29) = ( pts_value_l(j,1) - & 2964 pts_value(j,1) / numprocs )**2 2879 pts_value_l(j,29) = ( pts_value_l(j,1) - pts_value(j,1) / numprocs )**2 2965 2880 ENDDO 2966 2881 ENDIF … … 2972 2887 2973 2888 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 2974 CALL MPI_ALLREDUCE( pts_value_l(0,20), pts_value(0,20), inum*10, MPI_REAL, &2975 MPI_SUM, comm2d,ierr )2889 CALL MPI_ALLREDUCE( pts_value_l(0,20), pts_value(0,20), inum*10, MPI_REAL, MPI_SUM, comm2d, & 2890 ierr ) 2976 2891 #else 2977 2892 pts_value(:,20:29) = pts_value_l(:,20:29) … … 2979 2894 2980 2895 ! 2981 !-- Normalize the above calculated quantities with the total number of 2982 !-- particles 2896 !-- Normalize the above calculated quantities with the total number of particles 2983 2897 IF ( number_of_particle_groups > 1 ) THEN 2984 2898 inum = number_of_particle_groups … … 3002 2916 DO j = 0, inum 3003 2917 DO i = 1, dopts_num 3004 nc_stat = NF90_PUT_VAR( id_set_pts, id_var_dopts(i,j), &3005 (/ pts_value(j,i) /), &3006 start = (/ dopts_time_count /), &2918 nc_stat = NF90_PUT_VAR( id_set_pts, id_var_dopts(i,j), & 2919 (/ pts_value(j,i) /), & 2920 start = (/ dopts_time_count /), & 3007 2921 count = (/ 1 /) ) 3008 2922 CALL netcdf_handle_error( 'data_output_ptseries', 392 ) … … 3018 2932 END SUBROUTINE lpm_data_output_ptseries 3019 2933 3020 3021 !------------------------------------------------------------------------------ !2934 2935 !--------------------------------------------------------------------------------------------------! 3022 2936 ! Description: 3023 2937 ! ------------ 3024 2938 !> This routine reads the respective restart data for the lpm. 3025 !------------------------------------------------------------------------------ !2939 !--------------------------------------------------------------------------------------------------! 3026 2940 SUBROUTINE lpm_rrd_local_particles 3027 2941 … … 3048 2962 !-- First open the input unit. 3049 2963 IF ( myid_char == '' ) THEN 3050 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN'//myid_char, & 3051 FORM='UNFORMATTED' ) 2964 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN'//myid_char, FORM='UNFORMATTED' ) 3052 2965 ELSE 3053 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN/'//myid_char, & 3054 FORM='UNFORMATTED' ) 2966 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_IN/'//myid_char, FORM='UNFORMATTED' ) 3055 2967 ENDIF 3056 2968 … … 3060 2972 particle_binary_version = '4.0' 3061 2973 IF ( TRIM( version_on_file ) /= TRIM( particle_binary_version ) ) THEN 3062 message_string = 'version mismatch concerning data from prior ' // &3063 'run &version on file = "' // &3064 TRIM( version_on_file ) // &3065 '&version in program = "' // &2974 message_string = 'version mismatch concerning data from prior ' // & 2975 'run &version on file = "' // & 2976 TRIM( version_on_file ) // & 2977 '&version in program = "' // & 3066 2978 TRIM( particle_binary_version ) // '"' 3067 2979 CALL message( 'lpm_read_restart_file', 'PA0214', 1, 2, 0, 6, 0 ) … … 3069 2981 3070 2982 ! 3071 !-- If less particles are stored on the restart file than prescribed by 3072 !-- 1, the remainder is initialized by zero_particle to avoid 3073 !-- errors. 3074 zero_particle = particle_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 3075 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 3076 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 3077 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 2983 !-- If less particles are stored on the restart file than prescribed by 1, the remainder is 2984 !-- initialized by zero_particle to avoid errors. 2985 zero_particle = particle_type( 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 2986 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 2987 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 2988 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, & 3078 2989 0, 0, 0_idp, .FALSE., -1, -1 ) 3079 2990 ! 3080 !-- Read some particle parameters and the size of the particle arrays, 3081 !-- allocate them and read their contents. 3082 READ ( 90 ) bc_par_b, bc_par_lr, bc_par_ns, bc_par_t, & 3083 last_particle_release_time, number_of_particle_groups, & 3084 particle_groups, time_write_particle_data 3085 3086 ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 2991 !-- Read some particle parameters and the size of the particle arrays, allocate them and read 2992 !-- their contents. 2993 READ ( 90 ) bc_par_b, bc_par_lr, bc_par_ns, bc_par_t, last_particle_release_time, & 2994 number_of_particle_groups, particle_groups, time_write_particle_data 2995 2996 ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 3087 2997 grid_particles(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 3088 2998 … … 3095 3005 number_of_particles = prt_count(kp,jp,ip) 3096 3006 IF ( number_of_particles > 0 ) THEN 3097 alloc_size = MAX( INT( number_of_particles * &3098 ( 1.0_wp + alloc_factor / 100.0_wp ) ),&3099 1 )3007 alloc_size = MAX( INT( number_of_particles * & 3008 ( 1.0_wp + alloc_factor / 100.0_wp ) ), & 3009 1 ) 3100 3010 ELSE 3101 3011 alloc_size = 1 … … 3110 3020 DEALLOCATE( tmp_particles ) 3111 3021 IF ( number_of_particles < alloc_size ) THEN 3112 grid_particles(kp,jp,ip)%particles(number_of_particles+1:alloc_size) &3022 grid_particles(kp,jp,ip)%particles(number_of_particles+1:alloc_size) & 3113 3023 = zero_particle 3114 3024 ENDIF … … 3128 3038 FLUSH(9) 3129 3039 3130 ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg), &3040 ALLOCATE( prt_count(nzb:nzt+1,nysg:nyng,nxlg:nxrg), & 3131 3041 grid_particles(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 3132 3042 3133 3043 ALLOCATE( prt_global_index(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ) 3134 3044 ! 3135 !-- Open restart file for read, if not already open, and do not allow usage of 3136 !-- shared-memory I/O 3045 !-- Open restart file for read, if not already open, and do not allow usage of shared-memory I/O 3137 3046 IF ( .NOT. rd_mpi_io_check_open() ) THEN 3138 3047 save_restart_data_format_input = restart_data_format_input … … 3156 3065 number_of_particles = prt_count(kp,jp,ip) 3157 3066 IF ( number_of_particles > 0 ) THEN 3158 alloc_size = MAX( INT( number_of_particles * &3159 ( 1.0_wp + alloc_factor / 100.0_wp ) ),&3160 1 )3067 alloc_size = MAX( INT( number_of_particles * & 3068 ( 1.0_wp + alloc_factor / 100.0_wp ) ), & 3069 1 ) 3161 3070 ELSE 3162 3071 alloc_size = 1 … … 3186 3095 ENDIF 3187 3096 ! 3188 !-- Must be called to sort particles into blocks, which is needed for a fast 3189 !-- interpolation of theLES fields on the particle position.3097 !-- Must be called to sort particles into blocks, which is needed for a fast interpolation of the 3098 !-- LES fields on the particle position. 3190 3099 CALL lpm_sort_and_delete 3191 3100 3192 3101 END SUBROUTINE lpm_rrd_local_particles 3193 3194 3195 !------------------------------------------------------------------------------ !3102 3103 3104 !--------------------------------------------------------------------------------------------------! 3196 3105 ! Description: 3197 3106 ! ------------ 3198 3107 !> Read module-specific local restart data arrays (Fortran binary format). 3199 !------------------------------------------------------------------------------! 3200 SUBROUTINE lpm_rrd_local_ftn( k, nxlf, nxlc, nxl_on_file, nxrf, nxrc, & 3201 nxr_on_file, nynf, nync, nyn_on_file, nysf, & 3202 nysc, nys_on_file, tmp_3d, found ) 3203 3204 3205 USE control_parameters, & 3108 !--------------------------------------------------------------------------------------------------! 3109 SUBROUTINE lpm_rrd_local_ftn( k, nxlf, nxlc, nxl_on_file, nxrf, nxrc, nxr_on_file, nynf, nync, & 3110 nyn_on_file, nysf, nysc, nys_on_file, tmp_3d, found ) 3111 3112 3113 USE control_parameters, & 3206 3114 ONLY: length, restart_string 3207 3115 … … 3220 3128 INTEGER(iwp) :: nys_on_file !< 3221 3129 3130 INTEGER(isp), DIMENSION(:,:,:), ALLOCATABLE :: tmp_2d_seq_random_particles !< temporary array for storing random generator 3131 !< data for the lpm 3132 3222 3133 LOGICAL, INTENT(OUT) :: found 3223 3224 INTEGER(isp), DIMENSION(:,:,:), ALLOCATABLE :: tmp_2d_seq_random_particles !< temporary array for storing random generator data for the lpm3225 3134 3226 3135 REAL(wp), DIMENSION(nzb:nzt+1,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d !< … … 3236 3145 ENDIF 3237 3146 IF ( k == 1 ) READ ( 13 ) tmp_3d 3238 pc_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &3147 pc_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = & 3239 3148 tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp) 3240 3149 … … 3244 3153 ENDIF 3245 3154 IF ( k == 1 ) READ ( 13 ) tmp_3d 3246 pr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &3155 pr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = & 3247 3156 tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp) 3248 3157 3249 3158 CASE ( 'ql_c_av' ) 3250 3159 IF ( .NOT. ALLOCATED( ql_c_av ) ) THEN … … 3252 3161 ENDIF 3253 3162 IF ( k == 1 ) READ ( 13 ) tmp_3d 3254 ql_c_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &3163 ql_c_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = & 3255 3164 tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp) 3256 3165 … … 3260 3169 ENDIF 3261 3170 IF ( k == 1 ) READ ( 13 ) tmp_3d 3262 ql_v_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &3171 ql_v_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = & 3263 3172 tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp) 3264 3173 … … 3268 3177 ENDIF 3269 3178 IF ( k == 1 ) READ ( 13 ) tmp_3d 3270 ql_vp_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &3179 ql_vp_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = & 3271 3180 tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp) 3272 3181 3273 3182 CASE ( 'seq_random_array_particles' ) 3274 3275 3276 3277 3278 3279 seq_random_array_particles(:,nysc:nync,nxlc:nxrc) =&3280 3281 3183 ALLOCATE( tmp_2d_seq_random_particles(5,nys_on_file:nyn_on_file,nxl_on_file:nxr_on_file) ) 3184 IF ( .NOT. ALLOCATED( seq_random_array_particles ) ) THEN 3185 ALLOCATE( seq_random_array_particles(5,nys:nyn,nxl:nxr) ) 3186 ENDIF 3187 IF ( k == 1 ) READ ( 13 ) tmp_2d_seq_random_particles 3188 seq_random_array_particles(:,nysc:nync,nxlc:nxrc) = & 3189 tmp_2d_seq_random_particles(:,nysf:nynf,nxlf:nxrf) 3190 DEALLOCATE( tmp_2d_seq_random_particles ) 3282 3191 3283 3192 CASE DEFAULT … … 3289 3198 END SUBROUTINE lpm_rrd_local_ftn 3290 3199 3291 3292 !------------------------------------------------------------------------------ !3200 3201 !--------------------------------------------------------------------------------------------------! 3293 3202 ! Description: 3294 3203 ! ------------ 3295 3204 !> Read module-specific local restart data arrays (MPI-IO). 3296 !------------------------------------------------------------------------------ !3205 !--------------------------------------------------------------------------------------------------! 3297 3206 SUBROUTINE lpm_rrd_local_mpi 3298 3207 … … 3349 3258 3350 3259 3351 !------------------------------------------------------------------------------ !3260 !--------------------------------------------------------------------------------------------------! 3352 3261 ! Description: 3353 3262 ! ------------ 3354 3263 !> This routine writes the respective restart data for the lpm. 3355 !------------------------------------------------------------------------------ !3264 !--------------------------------------------------------------------------------------------------! 3356 3265 SUBROUTINE lpm_wrd_local 3357 3266 3358 3267 CHARACTER (LEN=10) :: particle_binary_version !< 3359 3268 CHARACTER (LEN=32) :: tmp_name !< temporary variable … … 3364 3273 INTEGER(iwp) :: jp !< 3365 3274 INTEGER(iwp) :: k !< loop index 3366 INTEGER(iwp) :: kp !< 3275 INTEGER(iwp) :: kp !< 3367 3276 3368 3277 #if defined( __parallel ) … … 3382 3291 !-- First open the output unit. 3383 3292 IF ( myid_char == '' ) THEN 3384 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT'//myid_char, & 3385 FORM='UNFORMATTED') 3293 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT'//myid_char, FORM='UNFORMATTED') 3386 3294 ELSE 3387 3295 IF ( myid == 0 ) CALL local_system( 'mkdir PARTICLE_RESTART_DATA_OUT' ) 3388 3296 #if defined( __parallel ) 3389 3297 ! 3390 !-- Set a barrier in order to allow that thereafter all other processors 3391 !-- in the directorycreated by PE0 can open their file3298 !-- Set a barrier in order to allow that thereafter all other processors in the directory 3299 !-- created by PE0 can open their file 3392 3300 CALL MPI_BARRIER( comm2d, ierr ) 3393 3301 #endif 3394 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT/'//myid_char, & 3395 FORM='UNFORMATTED' ) 3302 OPEN ( 90, FILE='PARTICLE_RESTART_DATA_OUT/'//myid_char, FORM='UNFORMATTED' ) 3396 3303 ENDIF 3397 3304 3398 3305 ! 3399 3306 !-- Write the version number of the binary format. 3400 !-- Attention: After changes to the following output commands the version 3401 !-- --------- number of the variable particle_binary_version must be 3402 !-- changed! Also, the version number and the list of arrays 3403 !-- to be read in lpm_read_restart_file must be adjusted 3404 !-- accordingly. 3307 !-- Attention: After changes to the following output commands the version number of the variable 3308 !-- --------- particle_binary_version must be changed! Also, the version number and the list of 3309 !-- arrays to be read in lpm_read_restart_file must be adjusted accordingly. 3405 3310 particle_binary_version = '4.0' 3406 3311 WRITE ( 90 ) particle_binary_version … … 3408 3313 ! 3409 3314 !-- Write some particle parameters, the size of the particle arrays 3410 WRITE ( 90 ) bc_par_b, bc_par_lr, bc_par_ns, bc_par_t, & 3411 last_particle_release_time, number_of_particle_groups, & 3412 particle_groups, time_write_particle_data 3315 WRITE ( 90 ) bc_par_b, bc_par_lr, bc_par_ns, bc_par_t, last_particle_release_time, & 3316 number_of_particle_groups, particle_groups, time_write_particle_data 3413 3317 3414 3318 WRITE ( 90 ) prt_count 3415 3319 3416 3320 DO ip = nxl, nxr 3417 3321 DO jp = nys, nyn … … 3465 3369 3466 3370 #if defined( __parallel ) 3467 CALL MPI_ALLREDUCE( nr_particles_local, nr_particles_global, numprocs, MPI_INTEGER, 3468 MPI_SUM,comm2d, ierr )3371 CALL MPI_ALLREDUCE( nr_particles_local, nr_particles_global, numprocs, MPI_INTEGER, MPI_SUM,& 3372 comm2d, ierr ) 3469 3373 #else 3470 3374 nr_particles_global = nr_particles_local … … 3500 3404 3501 3405 3502 !------------------------------------------------------------------------------ !3406 !--------------------------------------------------------------------------------------------------! 3503 3407 ! Description: 3504 3408 ! ------------ 3505 3409 !> This routine writes the respective restart data for the lpm. 3506 !------------------------------------------------------------------------------ !3410 !--------------------------------------------------------------------------------------------------! 3507 3411 SUBROUTINE lpm_wrd_global 3508 3412 … … 3513 3417 REAL(wp), DIMENSION(4,max_number_of_particle_groups) :: particle_groups_array !< 3514 3418 3515 3419 3516 3420 IF ( TRIM( restart_data_format_output ) == 'fortran_binary' ) THEN 3517 3421 … … 3569 3473 3570 3474 END SUBROUTINE lpm_wrd_global 3571 3572 3573 !------------------------------------------------------------------------------ !3475 3476 3477 !--------------------------------------------------------------------------------------------------! 3574 3478 ! Description: 3575 3479 ! ------------ 3576 3480 !> Read module-specific global restart data (Fortran binary format). 3577 !------------------------------------------------------------------------------ !3481 !--------------------------------------------------------------------------------------------------! 3578 3482 SUBROUTINE lpm_rrd_global_ftn( found ) 3579 3580 USE control_parameters, &3483 3484 USE control_parameters, & 3581 3485 ONLY: length, restart_string 3582 3486 … … 3603 3507 found = .FALSE. 3604 3508 3605 END SELECT 3606 3509 END SELECT 3510 3607 3511 END SUBROUTINE lpm_rrd_global_ftn 3608 3512 3609 3513 3610 !------------------------------------------------------------------------------ !3514 !--------------------------------------------------------------------------------------------------! 3611 3515 ! Description: 3612 3516 ! ------------ 3613 3517 !> Read module-specific global restart data (MPI-IO). 3614 !------------------------------------------------------------------------------ !3518 !--------------------------------------------------------------------------------------------------! 3615 3519 SUBROUTINE lpm_rrd_global_mpi 3616 3520 … … 3661 3565 3662 3566 3663 !------------------------------------------------------------------------------ !3567 !--------------------------------------------------------------------------------------------------! 3664 3568 ! Description: 3665 3569 ! ------------ 3666 !> This is a submodule of the lagrangian particle model. It contains all 3667 !> dynamic processes of the lpm. This includes the advection (resolved and sub- 3668 !> grid scale) as well as the boundary conditions of particles. As a next step 3669 !> this submodule should be excluded as an own file. 3670 !------------------------------------------------------------------------------! 3570 !> This is a submodule of the lagrangian particle model. It contains all dynamic processes of the 3571 !> lpm. This includes the advection (resolved and sub-grid scale) as well as the boundary conditions 3572 !> of particles. As a next step this submodule should be excluded as an own file. 3573 !--------------------------------------------------------------------------------------------------! 3671 3574 SUBROUTINE lpm_advec (ip,jp,kp) 3672 3575 3673 LOGICAL :: subbox_at_wall !< flag to see if the current subgridbox is adjacent to a wall 3576 REAL(wp), PARAMETER :: a_rog = 9.65_wp !< parameter for fall velocity 3577 REAL(wp), PARAMETER :: b_rog = 10.43_wp !< parameter for fall velocity 3578 REAL(wp), PARAMETER :: c_rog = 0.6_wp !< parameter for fall velocity 3579 REAL(wp), PARAMETER :: k_cap_rog = 4.0_wp !< parameter for fall velocity 3580 REAL(wp), PARAMETER :: k_low_rog = 12.0_wp !< parameter for fall velocity 3581 REAL(wp), PARAMETER :: d0_rog = 0.745_wp !< separation diameter 3674 3582 3675 3583 INTEGER(iwp) :: i !< index variable along x … … 3681 3589 INTEGER(iwp) :: jp !< index variable along y 3682 3590 INTEGER(iwp) :: k !< index variable along z 3683 INTEGER(iwp) :: k_wall !< vertical index of topography top 3591 INTEGER(iwp) :: k_wall !< vertical index of topography top 3684 3592 INTEGER(iwp) :: kp !< index variable along z 3685 3593 INTEGER(iwp) :: k_next !< index variable along z … … 3687 3595 INTEGER(iwp) :: kkw !< index variable along z 3688 3596 INTEGER(iwp) :: n !< loop variable over all particles in a grid box 3597 INTEGER(iwp) :: nn !< loop variable over iterations steps 3689 3598 INTEGER(iwp) :: nb !< block number particles are sorted in 3690 3599 INTEGER(iwp) :: particle_end !< end index for partilce loop … … 3692 3601 INTEGER(iwp) :: subbox_end !< end index for loop over subboxes in particle advection 3693 3602 INTEGER(iwp) :: subbox_start !< start index for loop over subboxes in particle advection 3694 INTEGER(iwp) :: nn !< loop variable over iterations steps 3695 3603 3604 INTEGER(iwp), DIMENSION(0:7) :: end_index !< start particle index for current block 3696 3605 INTEGER(iwp), DIMENSION(0:7) :: start_index !< start particle index for current block 3697 INTEGER(iwp), DIMENSION(0:7) :: end_index !< start particle index for current block 3606 3607 LOGICAL :: subbox_at_wall !< flag to see if the current subgridbox is adjacent to a wall 3698 3608 3699 3609 REAL(wp) :: aa !< dummy argument for horizontal particle interpolation 3700 3610 REAL(wp) :: alpha !< interpolation facor for x-direction 3701 3702 3611 REAL(wp) :: bb !< dummy argument for horizontal particle interpolation 3703 3612 REAL(wp) :: beta !< interpolation facor for y-direction 3704 3613 REAL(wp) :: cc !< dummy argument for horizontal particle interpolation 3705 REAL(wp) :: d_z_p_z0 !< inverse of interpolation length for logarithmic interpolation 3706 REAL(wp) :: dd !< dummy argument for horizontal particle interpolation 3614 REAL(wp) :: d_z_p_z0 !< inverse of interpolation length for logarithmic interpolation 3615 REAL(wp) :: dd !< dummy argument for horizontal particle interpolation 3707 3616 REAL(wp) :: de_dx_int_l !< x/y-interpolated TKE gradient (x) at particle position at lower vertical level 3708 3617 REAL(wp) :: de_dx_int_u !< x/y-interpolated TKE gradient (x) at particle position at upper vertical level … … 3724 3633 REAL(wp) :: exp_term !< exponent term 3725 3634 REAL(wp) :: gamma !< interpolation facor for z-direction 3726 REAL(wp) :: gg !< dummy argument for horizontal particle interpolation 3635 REAL(wp) :: gg !< dummy argument for horizontal particle interpolation 3727 3636 REAL(wp) :: height_p !< dummy argument for logarithmic interpolation 3728 3637 REAL(wp) :: log_z_z0_int !< logarithmus used for surface_layer interpolation 3729 REAL(wp) :: RL!< Lagrangian autocorrelation coefficient3638 REAL(wp) :: rl !< Lagrangian autocorrelation coefficient 3730 3639 REAL(wp) :: rg1 !< Gaussian distributed random number 3731 3640 REAL(wp) :: rg2 !< Gaussian distributed random number … … 3739 3648 REAL(wp) :: v_int_u !< x/y-interpolated v-component at particle position at upper vertical level 3740 3649 REAL(wp) :: vnext !< calculated particle v-velocity of corrector step 3741 REAL(wp) :: vv_int !< dummy to compute interpolated mean SGS TKE, used to scale SGS advection 3650 REAL(wp) :: vv_int !< dummy to compute interpolated mean SGS TKE, used to scale SGS advection 3742 3651 REAL(wp) :: w_int_l !< x/y-interpolated w-component at particle position at lower vertical level 3743 3652 REAL(wp) :: w_int_u !< x/y-interpolated w-component at particle position at upper vertical level 3744 3653 REAL(wp) :: wnext !< calculated particle w-velocity of corrector step 3745 3654 REAL(wp) :: w_s !< terminal velocity of droplets 3746 REAL(wp) :: x !< dummy argument for horizontal particle interpolation 3655 REAL(wp) :: x !< dummy argument for horizontal particle interpolation 3747 3656 REAL(wp) :: xp !< calculated particle position in x of predictor step 3748 3657 REAL(wp) :: y !< dummy argument for horizontal particle interpolation … … 3751 3660 REAL(wp) :: zp !< calculated particle position in z of predictor step 3752 3661 3753 REAL(wp), PARAMETER :: a_rog = 9.65_wp !< parameter for fall velocity3754 REAL(wp), PARAMETER :: b_rog = 10.43_wp !< parameter for fall velocity3755 REAL(wp), PARAMETER :: c_rog = 0.6_wp !< parameter for fall velocity3756 REAL(wp), PARAMETER :: k_cap_rog = 4.0_wp !< parameter for fall velocity3757 REAL(wp), PARAMETER :: k_low_rog = 12.0_wp !< parameter for fall velocity3758 REAL(wp), PARAMETER :: d0_rog = 0.745_wp !< separation diameter3759 3760 REAL(wp), DIMENSION(number_of_particles) :: term_1_2 !< flag to communicate whether a particle is near topography or not3761 REAL(wp), DIMENSION(number_of_particles) :: dens_ratio !< ratio between the density of the fluid and the density of the particles3762 3662 REAL(wp), DIMENSION(number_of_particles) :: de_dx_int !< horizontal TKE gradient along x at particle position 3763 3663 REAL(wp), DIMENSION(number_of_particles) :: de_dy_int !< horizontal TKE gradient along y at particle position 3764 3664 REAL(wp), DIMENSION(number_of_particles) :: de_dz_int !< horizontal TKE gradient along z at particle position 3665 REAL(wp), DIMENSION(number_of_particles) :: dens_ratio !< ratio between the density of the fluid and the density of the 3666 !< particles 3765 3667 REAL(wp), DIMENSION(number_of_particles) :: diss_int !< dissipation at particle position 3766 3668 REAL(wp), DIMENSION(number_of_particles) :: dt_gap !< remaining time until particle time integration reaches LES time … … 3772 3674 REAL(wp), DIMENSION(number_of_particles) :: rvar2_temp !< SGS particle velocity - v-component 3773 3675 REAL(wp), DIMENSION(number_of_particles) :: rvar3_temp !< SGS particle velocity - w-component 3676 REAL(wp), DIMENSION(number_of_particles) :: term_1_2 !< flag to communicate whether a particle is near topography or not 3774 3677 REAL(wp), DIMENSION(number_of_particles) :: u_int !< u-component of particle speed 3775 REAL(wp), DIMENSION(number_of_particles) :: v_int !< v-component of particle speed 3678 REAL(wp), DIMENSION(number_of_particles) :: v_int !< v-component of particle speed 3776 3679 REAL(wp), DIMENSION(number_of_particles) :: w_int !< w-component of particle speed 3777 3680 REAL(wp), DIMENSION(number_of_particles) :: xv !< x-position … … 3783 3686 CALL cpu_log( log_point_s(44), 'lpm_advec', 'continue' ) 3784 3687 ! 3785 !-- Determine height of Prandtl layer and distance between Prandtl-layer 3786 !-- height and horizontal mean roughness height, which are required for 3787 !-- vertical logarithmic interpolation of horizontal particle speeds 3788 !-- (for particles below first vertical grid level). 3688 !-- Determine height of Prandtl layer and distance between Prandtl-layer height and horizontal mean 3689 !-- roughness height, which are required for vertical logarithmic interpolation of horizontal 3690 !-- particle speeds (for particles below first vertical grid level). 3789 3691 z_p = zu(nzb+1) - zw(nzb) 3790 3692 d_z_p_z0 = 1.0_wp / ( z_p - z0_av_global ) … … 3796 3698 3797 3699 ! 3798 !-- This case uses a simple interpolation method for the particle velocites, 3799 !-- and applying a predictor-corrector method. @note the current time divergence3800 !-- free time step is denoted with u_t etc.; the velocities of the time level of3801 !-- t+1 wit u,v, and w, as the model is called afterswap timelevel3700 !-- This case uses a simple interpolation method for the particle velocites, and applying a 3701 !-- predictor-corrector method. @note the current time divergence free time step is denoted with 3702 !-- u_t etc.; the velocities of the time level of t+1 wit u,v, and w, as the model is called after 3703 !-- swap timelevel 3802 3704 !-- @attention: for the corrector step the velocities of t(n+1) are required. 3803 !-- Therefore the particle code is executed at the end of the time intermediate 3804 !-- timestep routine. This interpolation method is described in more detail 3805 !-- in Grabowski et al., 2018 (GMD). 3705 !-- Therefore the particle code is executed at the end of the time intermediate timestep routine. 3706 !-- This interpolation method is described in more detail in Grabowski et al., 2018 (GMD). 3806 3707 IF ( interpolation_simple_corrector ) THEN 3807 3708 ! … … 3816 3717 v_int(n) = v_t(kp,jp,ip) * ( 1.0_wp - beta ) + v_t(kp,jp+1,ip) * beta 3817 3718 3818 gamma = MAX( MIN( ( particles(n)%z - zw(kkw) ) / 3819 ( zw(kkw+1) - zw(kkw) ), 1.0_wp ),0.0_wp )3719 gamma = MAX( MIN( ( particles(n)%z - zw(kkw) ) / ( zw(kkw+1) - zw(kkw) ), 1.0_wp ), & 3720 0.0_wp ) 3820 3721 w_int(n) = w_t(kkw,jp,ip) * ( 1.0_wp - gamma ) + w_t(kkw+1,jp,ip) * gamma 3821 3722 … … 3845 3746 !-- z_direction 3846 3747 k_next = MAX( MIN( FLOOR( zp / (zw(kkw+1)-zw(kkw)) + offset_ocean_nzt ), nzt ), 0) 3847 gamma = MAX( MIN( ( zp - zw(k_next) ) / &3748 gamma = MAX( MIN( ( zp - zw(k_next) ) / & 3848 3749 ( zw(k_next+1) - zw(k_next) ), 1.0_wp ), 0.0_wp ) 3849 3750 ! 3850 3751 !-- Calculate part of the corrector step 3851 unext = u(k_next+1, j_next, i_next) * ( 1.0_wp - alpha ) + &3752 unext = u(k_next+1, j_next, i_next) * ( 1.0_wp - alpha ) + & 3852 3753 u(k_next+1, j_next, i_next+1) * alpha 3853 3754 3854 vnext = v(k_next+1, j_next, i_next) * ( 1.0_wp - beta ) + &3755 vnext = v(k_next+1, j_next, i_next) * ( 1.0_wp - beta ) + & 3855 3756 v(k_next+1, j_next+1, i_next ) * beta 3856 3757 3857 wnext = w(k_next, j_next, i_next) * ( 1.0_wp - gamma ) + &3758 wnext = w(k_next, j_next, i_next) * ( 1.0_wp - gamma ) + & 3858 3759 w(k_next+1, j_next, i_next ) * gamma 3859 3760 3860 3761 ! 3861 !-- Calculate interpolated particle velocity with predictor 3862 !-- corrector step. u_int, v_int and w_int describes the part of 3863 !-- the predictor step. unext, vnext and wnext is the part of the 3864 !-- corrector step. The resulting new position is set below. The 3865 !-- implementation is based on Grabowski et al., 2018 (GMD). 3762 !-- Calculate interpolated particle velocity with predictor corrector step. u_int, v_int 3763 !-- and w_int describes the part of the predictor step. unext, vnext and wnext is the part 3764 !-- of the corrector step. The resulting new position is set below. The implementation is 3765 !-- based on Grabowski et al., 2018 (GMD). 3866 3766 u_int(n) = 0.5_wp * ( u_int(n) + unext ) 3867 3767 v_int(n) = 0.5_wp * ( v_int(n) + vnext ) … … 3871 3771 ENDDO 3872 3772 ! 3873 !-- This case uses a simple interpolation method for the particle velocites, 3874 !-- and applying apredictor.3773 !-- This case uses a simple interpolation method for the particle velocites, and applying a 3774 !-- predictor. 3875 3775 ELSEIF ( interpolation_simple_predictor ) THEN 3876 3776 ! … … 3886 3786 v_int(n) = v(kp,jp,ip) * ( 1.0_wp - beta ) + v(kp,jp+1,ip) * beta 3887 3787 3888 gamma = MAX( MIN( ( particles(n)%z - zw(kkw) ) / 3889 ( zw(kkw+1) - zw(kkw) ), 1.0_wp ),0.0_wp )3788 gamma = MAX( MIN( ( particles(n)%z - zw(kkw) ) / ( zw(kkw+1) - zw(kkw) ), 1.0_wp ), & 3789 0.0_wp ) 3890 3790 w_int(n) = w(kkw,jp,ip) * ( 1.0_wp - gamma ) + w(kkw+1,jp,ip) * gamma 3891 3791 ENDDO … … 3907 3807 ! 3908 3808 !-- Interpolation of the u velocity component onto particle position. 3909 !-- Particles are interpolation bi-linearly in the horizontal and a 3910 !-- linearly in the vertical. An exception is made for particles below 3911 !-- the first vertical grid level in case of a prandtl layer. In this 3912 !-- case the horizontal particle velocity components are determined using 3913 !-- Monin-Obukhov relations (if branch). 3914 !-- First, check if particle is located below first vertical grid level 3915 !-- above topography (Prandtl-layer height) 3809 !-- Particles are interpolation bi-linearly in the horizontal and a linearly in the 3810 !-- vertical. An exception is made for particles below the first vertical grid level in 3811 !-- case of a prandtl layer. In this case the horizontal particle velocity components are 3812 !-- determined using Monin-Obukhov relations (if branch). 3813 !-- First, check if particle is located below first vertical grid level above topography 3814 !-- (Prandtl-layer height). 3916 3815 !-- Determine vertical index of topography top 3917 3816 k_wall = topo_top_ind(jp,ip,0) … … 3925 3824 ! 3926 3825 !-- Determine the sublayer. Further used as index. 3927 height_p = ( zv(n) - zw(k_wall) - z0_av_global ) &3928 * REAL( number_of_sublayers, KIND=wp ) &3826 height_p = ( zv(n) - zw(k_wall) - z0_av_global ) & 3827 * REAL( number_of_sublayers, KIND=wp ) & 3929 3828 * d_z_p_z0 3930 3829 ! 3931 3830 !-- Calculate LOG(z/z0) for exact particle height. Therefore, 3932 3831 !-- interpolate linearly between precalculated logarithm. 3933 log_z_z0_int = log_z_z0(INT(height_p)) & 3934 + ( height_p - INT(height_p) ) & 3935 * ( log_z_z0(INT(height_p)+1) & 3936 - log_z_z0(INT(height_p)) & 3937 ) 3832 log_z_z0_int = log_z_z0( INT( height_p ) ) + ( height_p - INT( height_p ) ) * & 3833 ( log_z_z0( INT( height_p ) + 1 ) - log_z_z0( INT( height_p ) ) ) 3938 3834 ! 3939 3835 !-- Compute u*-portion for u-component based on mean roughness. 3940 !-- Note, neutral solution is applied for all situations, e.g. also for 3941 !-- unstable and stable situations. Even though this is not exact 3942 !-- this saves a lot of CPU time since several calls of intrinsic 3943 !-- FORTRAN procedures (LOG, ATAN) are avoided, This is justified 3944 !-- as sensitivity studies revealed no significant effect of 3945 !-- using the neutral solution also for un/stable situations. Based on the u* 3946 !-- recalculate the velocity at height z_particle. Since the analytical solution 3947 !-- only yields absolute values, include the sign using the intrinsic SIGN function. 3836 !-- Note, neutral solution is applied for all situations, e.g. also for unstable and 3837 !-- stable situations. Even though this is not exact this saves a lot of CPU time 3838 !-- since several calls of intrinsic FORTRAN procedures (LOG, ATAN) are avoided. This 3839 !-- is justified as sensitivity studies revealed no significant effect of using the 3840 !-- neutral solution also for un/stable situations. Based on the u* recalculate the 3841 !-- velocity at height z_particle. Since the analytical solution only yields absolute 3842 !-- values, include the sign using the intrinsic SIGN function. 3948 3843 us_int = kappa * 0.5_wp * ABS( u(k_wall+1,jp,ip) + u(k_wall+1,jp,ip+1) ) / & 3949 3844 log_z_z0(number_of_sublayers) … … 3953 3848 ENDIF 3954 3849 ! 3955 !-- Particle above the first grid level. Bi-linear interpolation in the 3956 !-- horizontal andlinear interpolation in the vertical direction.3850 !-- Particle above the first grid level. Bi-linear interpolation in the horizontal and 3851 !-- linear interpolation in the vertical direction. 3957 3852 ELSE 3958 3853 x = xv(n) - i * dx … … 3964 3859 gg = aa + bb + cc + dd 3965 3860 3966 u_int_l = ( ( gg - aa ) * u(k,j,i) + ( gg - bb ) * u(k,j,i+1) &3967 + ( gg - cc ) * u(k,j+1,i) + ( gg - dd ) * &3968 u(k,j+1,i+1) )/ ( 3.0_wp * gg ) - u_gtrans3861 u_int_l = ( ( gg - aa ) * u(k,j,i) + ( gg - bb ) * u(k,j,i+1) & 3862 + ( gg - cc ) * u(k,j+1,i) + ( gg - dd ) * u(k,j+1,i+1) ) & 3863 / ( 3.0_wp * gg ) - u_gtrans 3969 3864 3970 3865 IF ( k == nzt ) THEN 3971 3866 u_int(n) = u_int_l 3972 3867 ELSE 3973 u_int_u = ( ( gg-aa ) * u(k+1,j,i) + ( gg-bb ) * u(k+1,j,i+1) & 3974 + ( gg-cc ) * u(k+1,j+1,i) + ( gg-dd ) * & 3975 u(k+1,j+1,i+1) ) / ( 3.0_wp * gg ) - u_gtrans 3976 u_int(n) = u_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 3977 ( u_int_u - u_int_l ) 3868 u_int_u = ( ( gg-aa ) * u(k+1,j,i) + ( gg-bb ) * u(k+1,j,i+1) & 3869 + ( gg-cc ) * u(k+1,j+1,i) + ( gg-dd ) * u(k+1,j+1,i+1) ) & 3870 / ( 3.0_wp * gg ) - u_gtrans 3871 u_int(n) = u_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * ( u_int_u - u_int_l ) 3978 3872 ENDIF 3979 3873 ENDIF … … 3998 3892 ! 3999 3893 !-- Determine the sublayer. Further used as index. 4000 height_p = ( zv(n) - zw(k_wall) - z0_av_global ) &4001 * REAL( number_of_sublayers, KIND=wp ) &3894 height_p = ( zv(n) - zw(k_wall) - z0_av_global ) & 3895 * REAL( number_of_sublayers, KIND=wp ) & 4002 3896 * d_z_p_z0 4003 3897 ! 4004 !-- Calculate LOG(z/z0) for exact particle height. Therefore, 4005 !-- interpolate linearly between precalculated logarithm. 4006 log_z_z0_int = log_z_z0(INT(height_p)) & 4007 + ( height_p - INT(height_p) ) & 4008 * ( log_z_z0(INT(height_p)+1) & 4009 - log_z_z0(INT(height_p)) & 3898 !-- Calculate LOG(z/z0) for exact particle height. Therefore, interpolate linearly 3899 !-- between precalculated logarithm. 3900 log_z_z0_int = log_z_z0(INT(height_p)) & 3901 + ( height_p - INT(height_p) ) & 3902 * ( log_z_z0(INT(height_p)+1) - log_z_z0(INT(height_p)) & 4010 3903 ) 4011 3904 ! 4012 3905 !-- Compute u*-portion for v-component based on mean roughness. 4013 !-- Note, neutral solution is applied for all situations, e.g. also for 4014 !-- unstable and stable situations. Even though this is not exact 4015 !-- this saves a lot of CPU time since several calls of intrinsic 4016 !-- FORTRAN procedures (LOG, ATAN) are avoided, This is justified 4017 !-- as sensitivity studies revealed no significant effect of 4018 !-- using the neutral solution also for un/stable situations. Based on the u* 4019 !-- recalculate the velocity at height z_particle. Since the analytical solution 4020 !-- only yields absolute values, include the sign using the intrinsic SIGN function. 3906 !-- Note, neutral solution is applied for all situations, e.g. also for unstable and 3907 !-- stable situations. Even though this is not exact this saves a lot of CPU time 3908 !-- since several calls of intrinsic FORTRAN procedures (LOG, ATAN) are avoided, This 3909 !-- is justified as sensitivity studies revealed no significant effect of using the 3910 !-- neutral solution also for un/stable situations. Based on the u* recalculate the 3911 !-- velocity at height z_particle. Since the analytical solution only yields absolute 3912 !-- values, include the sign using the intrinsic SIGN function. 4021 3913 us_int = kappa * 0.5_wp * ABS( v(k_wall+1,jp,ip) + v(k_wall+1,jp+1,ip) ) / & 4022 3914 log_z_z0(number_of_sublayers) … … 4034 3926 gg = aa + bb + cc + dd 4035 3927 4036 v_int_l = ( ( gg - aa ) * v(k,j,i) + ( gg - bb ) * v(k,j,i+1) &4037 + ( gg - cc ) * v(k,j+1,i) + ( gg - dd ) * v(k,j+1,i+1) &3928 v_int_l = ( ( gg - aa ) * v(k,j,i) + ( gg - bb ) * v(k,j,i+1) & 3929 + ( gg - cc ) * v(k,j+1,i) + ( gg - dd ) * v(k,j+1,i+1) & 4038 3930 ) / ( 3.0_wp * gg ) - v_gtrans 4039 3931 … … 4041 3933 v_int(n) = v_int_l 4042 3934 ELSE 4043 v_int_u = ( ( gg-aa ) * v(k+1,j,i) + ( gg-bb ) * v(k+1,j,i+1) &4044 + ( gg-cc ) * v(k+1,j+1,i) + ( gg-dd ) * v(k+1,j+1,i+1) &3935 v_int_u = ( ( gg-aa ) * v(k+1,j,i) + ( gg-bb ) * v(k+1,j,i+1) & 3936 + ( gg-cc ) * v(k+1,j+1,i) + ( gg-dd ) * v(k+1,j+1,i+1) & 4045 3937 ) / ( 3.0_wp * gg ) - v_gtrans 4046 v_int(n) = v_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 4047 ( v_int_u - v_int_l ) 3938 v_int(n) = v_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * ( v_int_u - v_int_l ) 4048 3939 ENDIF 4049 3940 ENDIF … … 4065 3956 gg = aa + bb + cc + dd 4066 3957 4067 w_int_l = ( ( gg - aa ) * w(k,j,i) + ( gg - bb ) * w(k,j,i+1) &4068 + ( gg - cc ) * w(k,j+1,i) + ( gg - dd ) * w(k,j+1,i+1) &3958 w_int_l = ( ( gg - aa ) * w(k,j,i) + ( gg - bb ) * w(k,j,i+1) & 3959 + ( gg - cc ) * w(k,j+1,i) + ( gg - dd ) * w(k,j+1,i+1) & 4069 3960 ) / ( 3.0_wp * gg ) 4070 3961 … … 4072 3963 w_int(n) = w_int_l 4073 3964 ELSE 4074 w_int_u = ( ( gg-aa ) * w(k+1,j,i) + &4075 ( gg-bb ) * w(k+1,j,i+1) + &4076 ( gg-cc ) * w(k+1,j+1,i) + &4077 ( gg-dd ) * w(k+1,j+1,i+1) &3965 w_int_u = ( ( gg-aa ) * w(k+1,j,i) + & 3966 ( gg-bb ) * w(k+1,j,i+1) + & 3967 ( gg-cc ) * w(k+1,j+1,i) + & 3968 ( gg-dd ) * w(k+1,j+1,i+1) & 4078 3969 ) / ( 3.0_wp * gg ) 4079 w_int(n) = w_int_l + ( zv(n) - zw(k) ) / dzw(k+1) * & 4080 ( w_int_u - w_int_l ) 3970 w_int(n) = w_int_l + ( zv(n) - zw(k) ) / dzw(k+1) * ( w_int_u - w_int_l ) 4081 3971 ENDIF 4082 3972 ELSE … … 4087 3977 ENDIF 4088 3978 4089 !-- Interpolate and calculate quantities needed for calculating the SGS 4090 !-- velocities 3979 !-- Interpolate and calculate quantities needed for calculating the SGS velocities 4091 3980 IF ( use_sgs_for_particles .AND. .NOT. cloud_droplets ) THEN 4092 3981 … … 4100 3989 j = jp + MERGE( -1_iwp , 1_iwp, BTEST( nb, 1 ) ) 4101 3990 k = kp + MERGE( -1_iwp , 1_iwp, BTEST( nb, 0 ) ) 4102 IF ( .NOT. BTEST(wall_flags_total_0(k, jp, ip), 0) .OR. &4103 .NOT. BTEST(wall_flags_total_0(kp, j, ip), 0) .OR. &4104 .NOT. BTEST(wall_flags_total_0(kp, jp, i ), 0) ) &3991 IF ( .NOT. BTEST(wall_flags_total_0(k, jp, ip), 0) .OR. & 3992 .NOT. BTEST(wall_flags_total_0(kp, j, ip), 0) .OR. & 3993 .NOT. BTEST(wall_flags_total_0(kp, jp, i ), 0) ) & 4105 3994 THEN 4106 3995 subbox_at_wall = .TRUE. … … 4108 3997 ENDIF 4109 3998 IF ( subbox_at_wall ) THEN 4110 e_int(start_index(nb):end_index(nb)) = e(kp,jp,ip) 3999 e_int(start_index(nb):end_index(nb)) = e(kp,jp,ip) 4111 4000 diss_int(start_index(nb):end_index(nb)) = diss(kp,jp,ip) 4112 4001 de_dx_int(start_index(nb):end_index(nb)) = de_dx(kp,jp,ip) … … 4132 4021 gg = aa + bb + cc + dd 4133 4022 4134 e_int_l = ( ( gg-aa ) * e(k,j,i) + ( gg-bb ) * e(k,j,i+1) &4135 + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1) &4023 e_int_l = ( ( gg-aa ) * e(k,j,i) + ( gg-bb ) * e(k,j,i+1) & 4024 + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1) & 4136 4025 ) / ( 3.0_wp * gg ) 4137 4026 … … 4144 4033 ( gg - dd ) * e(k+1,j+1,i+1) & 4145 4034 ) / ( 3.0_wp * gg ) 4146 e_int(n) = e_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 4147 ( e_int_u - e_int_l ) 4035 e_int(n) = e_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * ( e_int_u - e_int_l ) 4148 4036 ENDIF 4149 4037 ! 4150 !-- Needed to avoid NaN particle velocities (this might not be 4151 !-- required any more) 4038 !-- Needed to avoid NaN particle velocities (this might not be required any more) 4152 4039 IF ( e_int(n) <= 0.0_wp ) THEN 4153 4040 e_int(n) = 1.0E-20_wp 4154 4041 ENDIF 4155 4042 ! 4156 !-- Interpolate the TKE gradient along x (adopt incides i,j,k and 4157 !-- all position variablesfrom above (TKE))4158 de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i) + &4159 ( gg - bb ) * de_dx(k,j,i+1) + &4160 ( gg - cc ) * de_dx(k,j+1,i) + &4161 ( gg - dd ) * de_dx(k,j+1,i+1) &4043 !-- Interpolate the TKE gradient along x (adopt incides i,j,k and all position variables 4044 !-- from above (TKE)) 4045 de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i) + & 4046 ( gg - bb ) * de_dx(k,j,i+1) + & 4047 ( gg - cc ) * de_dx(k,j+1,i) + & 4048 ( gg - dd ) * de_dx(k,j+1,i+1) & 4162 4049 ) / ( 3.0_wp * gg ) 4163 4050 … … 4165 4052 de_dx_int(n) = de_dx_int_l 4166 4053 ELSE 4167 de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i) + &4168 ( gg - bb ) * de_dx(k+1,j,i+1) + &4169 ( gg - cc ) * de_dx(k+1,j+1,i) + &4170 ( gg - dd ) * de_dx(k+1,j+1,i+1) &4054 de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i) + & 4055 ( gg - bb ) * de_dx(k+1,j,i+1) + & 4056 ( gg - cc ) * de_dx(k+1,j+1,i) + & 4057 ( gg - dd ) * de_dx(k+1,j+1,i+1) & 4171 4058 ) / ( 3.0_wp * gg ) 4172 de_dx_int(n) = de_dx_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * &4059 de_dx_int(n) = de_dx_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 4173 4060 ( de_dx_int_u - de_dx_int_l ) 4174 4061 ENDIF 4175 4062 ! 4176 4063 !-- Interpolate the TKE gradient along y 4177 de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i) + &4178 ( gg - bb ) * de_dy(k,j,i+1) + &4179 ( gg - cc ) * de_dy(k,j+1,i) + &4180 ( gg - dd ) * de_dy(k,j+1,i+1) &4064 de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i) + & 4065 ( gg - bb ) * de_dy(k,j,i+1) + & 4066 ( gg - cc ) * de_dy(k,j+1,i) + & 4067 ( gg - dd ) * de_dy(k,j+1,i+1) & 4181 4068 ) / ( 3.0_wp * gg ) 4182 4069 IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN 4183 4070 de_dy_int(n) = de_dy_int_l 4184 4071 ELSE 4185 de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i) + &4186 ( gg - bb ) * de_dy(k+1,j,i+1) + &4187 ( gg - cc ) * de_dy(k+1,j+1,i) + &4188 ( gg - dd ) * de_dy(k+1,j+1,i+1) &4072 de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i) + & 4073 ( gg - bb ) * de_dy(k+1,j,i+1) + & 4074 ( gg - cc ) * de_dy(k+1,j+1,i) + & 4075 ( gg - dd ) * de_dy(k+1,j+1,i+1) & 4189 4076 ) / ( 3.0_wp * gg ) 4190 de_dy_int(n) = de_dy_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * &4077 de_dy_int(n) = de_dy_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 4191 4078 ( de_dy_int_u - de_dy_int_l ) 4192 4079 ENDIF … … 4197 4084 de_dz_int(n) = 0.0_wp 4198 4085 ELSE 4199 de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i) + &4200 ( gg - bb ) * de_dz(k,j,i+1) + &4201 ( gg - cc ) * de_dz(k,j+1,i) + &4202 ( gg - dd ) * de_dz(k,j+1,i+1) &4086 de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i) + & 4087 ( gg - bb ) * de_dz(k,j,i+1) + & 4088 ( gg - cc ) * de_dz(k,j+1,i) + & 4089 ( gg - dd ) * de_dz(k,j+1,i+1) & 4203 4090 ) / ( 3.0_wp * gg ) 4204 4091 … … 4206 4093 de_dz_int(n) = de_dz_int_l 4207 4094 ELSE 4208 de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i) + &4209 ( gg - bb ) * de_dz(k+1,j,i+1) + &4210 ( gg - cc ) * de_dz(k+1,j+1,i) + &4211 ( gg - dd ) * de_dz(k+1,j+1,i+1) &4095 de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i) + & 4096 ( gg - bb ) * de_dz(k+1,j,i+1) + & 4097 ( gg - cc ) * de_dz(k+1,j+1,i) + & 4098 ( gg - dd ) * de_dz(k+1,j+1,i+1) & 4212 4099 ) / ( 3.0_wp * gg ) 4213 de_dz_int(n) = de_dz_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * &4100 de_dz_int(n) = de_dz_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 4214 4101 ( de_dz_int_u - de_dz_int_l ) 4215 4102 ENDIF … … 4218 4105 ! 4219 4106 !-- Interpolate the dissipation of TKE 4220 diss_int_l = ( ( gg - aa ) * diss(k,j,i) + &4221 ( gg - bb ) * diss(k,j,i+1) + &4222 ( gg - cc ) * diss(k,j+1,i) + &4223 ( gg - dd ) * diss(k,j+1,i+1) &4107 diss_int_l = ( ( gg - aa ) * diss(k,j,i) + & 4108 ( gg - bb ) * diss(k,j,i+1) + & 4109 ( gg - cc ) * diss(k,j+1,i) + & 4110 ( gg - dd ) * diss(k,j+1,i+1) & 4224 4111 ) / ( 3.0_wp * gg ) 4225 4112 … … 4227 4114 diss_int(n) = diss_int_l 4228 4115 ELSE 4229 diss_int_u = ( ( gg - aa ) * diss(k+1,j,i) + &4230 ( gg - bb ) * diss(k+1,j,i+1) + &4231 ( gg - cc ) * diss(k+1,j+1,i) + &4232 ( gg - dd ) * diss(k+1,j+1,i+1) &4116 diss_int_u = ( ( gg - aa ) * diss(k+1,j,i) + & 4117 ( gg - bb ) * diss(k+1,j,i+1) + & 4118 ( gg - cc ) * diss(k+1,j+1,i) + & 4119 ( gg - dd ) * diss(k+1,j+1,i+1) & 4233 4120 ) / ( 3.0_wp * gg ) 4234 diss_int(n) = diss_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * &4121 diss_int(n) = diss_int_l + ( zv(n) - zu(k) ) / dzw(k+1) * & 4235 4122 ( diss_int_u - diss_int_l ) 4236 4123 ENDIF … … 4250 4137 DO n = start_index(nb), end_index(nb) 4251 4138 ! 4252 !-- Vertical interpolation of the horizontally averaged SGS TKE and 4253 !-- resolved-scale velocity variances and use the interpolated values 4254 !-- to calculate the coefficient fs, which is a measure of the ratio 4255 !-- of the subgrid-scale turbulent kinetic energy to the total amount 4139 !-- Vertical interpolation of the horizontally averaged SGS TKE and resolved-scale velocity 4140 !-- variances and use the interpolated values to calculate the coefficient fs, which is a 4141 !-- measure of the ratio of the subgrid-scale turbulent kinetic energy to the total amount 4256 4142 !-- of turbulent kinetic energy. 4257 4143 IF ( k == 0 ) THEN 4258 4144 e_mean_int = hom(0,1,8,0) 4259 4145 ELSE 4260 e_mean_int = hom(k,1,8,0) + & 4261 ( hom(k+1,1,8,0) - hom(k,1,8,0) ) / & 4262 ( zu(k+1) - zu(k) ) * & 4263 ( zv(n) - zu(k) ) 4146 e_mean_int = hom(k,1,8,0) + ( hom(k+1,1,8,0) - hom(k,1,8,0) ) / & 4147 ( zu(k+1) - zu(k) ) * & 4148 ( zv(n) - zu(k) ) 4264 4149 ENDIF 4265 4150 … … 4274 4159 ( 1.0_wp * ( zw(kw+1) - zw(kw) ) ) ) 4275 4160 ELSE 4276 aa = hom(k,1,30,0) + ( hom(k+1,1,30,0) - hom(k,1,30,0) ) * &4161 aa = hom(k,1,30,0) + ( hom(k+1,1,30,0) - hom(k,1,30,0) ) * & 4277 4162 ( ( zv(n) - zu(k) ) / ( zu(k+1) - zu(k) ) ) 4278 bb = hom(k,1,31,0) + ( hom(k+1,1,31,0) - hom(k,1,31,0) ) * &4163 bb = hom(k,1,31,0) + ( hom(k+1,1,31,0) - hom(k,1,31,0) ) * & 4279 4164 ( ( zv(n) - zu(k) ) / ( zu(k+1) - zu(k) ) ) 4280 cc = hom(kw,1,32,0) + ( hom(kw+1,1,32,0)-hom(kw,1,32,0) ) * &4165 cc = hom(kw,1,32,0) + ( hom(kw+1,1,32,0)-hom(kw,1,32,0) ) * & 4281 4166 ( ( zv(n) - zw(kw) ) / ( zw(kw+1)-zw(kw) ) ) 4282 4167 ENDIF … … 4284 4169 vv_int = ( 1.0_wp / 3.0_wp ) * ( aa + bb + cc ) 4285 4170 ! 4286 !-- Needed to avoid NaN particle velocities. The value of 1.0 is just 4287 !-- an educated guess forthe given case.4171 !-- Needed to avoid NaN particle velocities. The value of 1.0 is just an educated guess for 4172 !-- the given case. 4288 4173 IF ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int == 0.0_wp ) THEN 4289 4174 fs_int(n) = 1.0_wp 4290 4175 ELSE 4291 fs_int(n) = ( 2.0_wp / 3.0_wp ) * e_mean_int / &4176 fs_int(n) = ( 2.0_wp / 3.0_wp ) * e_mean_int / & 4292 4177 ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int ) 4293 4178 ENDIF … … 4312 4197 ! 4313 4198 !-- Calculate the Lagrangian timescale according to Weil et al. (2004). 4314 lagr_timescale(n) = ( 4.0_wp * e_int(n) + 1E-20_wp ) / &4315 ( 3.0_wp * fs_int(n) * c_0 * diss_int(n) + 1E-20_wp )4316 4317 ! 4318 !-- Calculate the next particle timestep. dt_gap is the time needed to 4319 !-- complete the currentLES timestep.4199 lagr_timescale(n) = ( 4.0_wp * e_int(n) + 1E-20_wp ) / & 4200 ( 3.0_wp * fs_int(n) * c_0 * diss_int(n) + 1E-20_wp ) 4201 4202 ! 4203 !-- Calculate the next particle timestep. dt_gap is the time needed to complete the current 4204 !-- LES timestep. 4320 4205 dt_gap(n) = dt_3d - particles(n)%dt_sum 4321 4206 dt_particle(n) = MIN( dt_3d, 0.025_wp * lagr_timescale(n), dt_gap(n) ) … … 4323 4208 particles(n)%aux2 = dt_gap(n) 4324 4209 ! 4325 !-- The particle timestep should not be too small in order to prevent 4326 !-- the number ofparticle timesteps of getting too large4210 !-- The particle timestep should not be too small in order to prevent the number of 4211 !-- particle timesteps of getting too large 4327 4212 IF ( dt_particle(n) < dt_min_part ) THEN 4328 4213 IF ( dt_min_part < dt_gap(n) ) THEN … … 4340 4225 IF ( particles(n)%age == 0.0_wp ) THEN 4341 4226 ! 4342 !-- For new particles the SGS components are derived from the SGS 4343 !-- TKE. Limit the Gaussian random number to the interval 4344 !-- [-5.0*sigma, 5.0*sigma] in order to prevent the SGS velocities 4345 !-- from becoming unrealistically large. 4346 rvar1_temp(n) = SQRT( 2.0_wp * sgs_wf_part * e_int(n) & 4347 + 1E-20_wp ) * rg(n,1) 4348 rvar2_temp(n) = SQRT( 2.0_wp * sgs_wf_part * e_int(n) & 4349 + 1E-20_wp ) * rg(n,2) 4350 rvar3_temp(n) = SQRT( 2.0_wp * sgs_wf_part * e_int(n) & 4351 + 1E-20_wp ) * rg(n,3) 4227 !-- For new particles the SGS components are derived from the SGS TKE. Limit the 4228 !-- Gaussian random number to the interval [-5.0*sigma, 5.0*sigma] in order to prevent 4229 !-- the SGS velocities from becoming unrealistically large. 4230 rvar1_temp(n) = SQRT( 2.0_wp * sgs_wf_part * e_int(n) + 1E-20_wp ) * rg(n,1) 4231 rvar2_temp(n) = SQRT( 2.0_wp * sgs_wf_part * e_int(n) + 1E-20_wp ) * rg(n,2) 4232 rvar3_temp(n) = SQRT( 2.0_wp * sgs_wf_part * e_int(n) + 1E-20_wp ) * rg(n,3) 4352 4233 ELSE 4353 4234 ! 4354 !-- Restriction of the size of the new timestep: compared to the 4235 !-- Restriction of the size of the new timestep: compared to the 4355 4236 !-- previous timestep the increase must not exceed 200%. First, 4356 4237 !-- check if age > age_m, in order to prevent that particles get zero 4357 4238 !-- timestep. 4358 dt_particle_m = MERGE( dt_particle(n), & 4359 particles(n)%age - particles(n)%age_m, & 4360 particles(n)%age - particles(n)%age_m < & 4361 1E-8_wp ) 4239 dt_particle_m = MERGE( dt_particle(n), & 4240 particles(n)%age - particles(n)%age_m, & 4241 particles(n)%age - particles(n)%age_m < 1E-8_wp ) 4362 4242 IF ( dt_particle(n) > 2.0_wp * dt_particle_m ) THEN 4363 4243 dt_particle(n) = 2.0_wp * dt_particle_m 4364 4244 ENDIF 4365 4245 4366 !-- For old particles the SGS components are correlated with the 4367 !-- values from the previous timestep. Random numbers have also to 4368 !-- be limited (see above). 4369 !-- As negative values for the subgrid TKE are not allowed, the 4370 !-- change of the subgrid TKE with time cannot be smaller than 4371 !-- -e_int(n)/dt_particle. This value is used as a lower boundary 4372 !-- value for the change of TKE 4246 !-- For old particles the SGS components are correlated with the values from the 4247 !-- previous timestep. Random numbers have also to be limited (see above). 4248 !-- As negative values for the subgrid TKE are not allowed, the change of the subgrid 4249 !-- TKE with time cannot be smaller than -e_int(n)/dt_particle. This value is used as a 4250 !-- lower boundary value for the change of TKE 4373 4251 de_dt_min = - e_int(n) / dt_particle(n) 4374 4252 … … 4379 4257 ENDIF 4380 4258 4381 CALL weil_stochastic_eq( rvar1_temp(n), fs_int(n), e_int(n), & 4382 de_dx_int(n), de_dt, diss_int(n), & 4383 dt_particle(n), rg(n,1), term_1_2(n) ) 4384 4385 CALL weil_stochastic_eq( rvar2_temp(n), fs_int(n), e_int(n), & 4386 de_dy_int(n), de_dt, diss_int(n), & 4387 dt_particle(n), rg(n,2), term_1_2(n) ) 4388 4389 CALL weil_stochastic_eq( rvar3_temp(n), fs_int(n), e_int(n), & 4390 de_dz_int(n), de_dt, diss_int(n), & 4391 dt_particle(n), rg(n,3), term_1_2(n) ) 4259 CALL weil_stochastic_eq( rvar1_temp(n), fs_int(n), e_int(n), de_dx_int(n), de_dt, & 4260 diss_int(n), dt_particle(n), rg(n,1), term_1_2(n) ) 4261 4262 CALL weil_stochastic_eq( rvar2_temp(n), fs_int(n), e_int(n), de_dy_int(n), de_dt, & 4263 diss_int(n), dt_particle(n), rg(n,2), term_1_2(n) ) 4264 4265 CALL weil_stochastic_eq( rvar3_temp(n), fs_int(n), e_int(n), de_dz_int(n), de_dt, & 4266 diss_int(n), dt_particle(n), rg(n,3), term_1_2(n) ) 4392 4267 4393 4268 ENDIF … … 4396 4271 ENDDO 4397 4272 ! 4398 !-- Check if the added SGS velocities result in a violation of the CFL- 4399 !-- criterion. If yes, limt the SGS particle speed to match the 4400 !-- CFL criterion. Note, a re-calculation of the SGS particle speed with 4401 !-- smaller timestep does not necessarily fulfill the CFL criterion as the 4402 !-- new SGS speed can be even larger (due to the random term with scales with 4403 !-- the square-root of dt_particle, for small dt the random contribution increases). 4404 !-- Thus, we would need to re-calculate the SGS speeds as long as they would 4405 !-- fulfill the requirements, which could become computationally expensive, 4273 !-- Check if the added SGS velocities result in a violation of the CFL-criterion. If yes, limt 4274 !-- the SGS particle speed to match the CFL criterion. Note, a re-calculation of the SGS particle 4275 !-- speed with smaller timestep does not necessarily fulfill the CFL criterion as the new SGS 4276 !-- speed can be even larger (due to the random term with scales with the square-root of 4277 !-- dt_particle, for small dt the random contribution increases). 4278 !-- Thus, we would need to re-calculate the SGS speeds as long as they would fulfill the 4279 !-- requirements, which could become computationally expensive, 4406 4280 !-- Hence, we just limit them. 4407 4281 dz_temp = zw(kp)-zw(kp-1) … … 4409 4283 DO nb = 0, 7 4410 4284 DO n = start_index(nb), end_index(nb) 4411 IF ( ABS( u_int(n) + rvar1_temp(n) ) > ( dx / dt_particle(n) ) .OR. &4412 ABS( v_int(n) + rvar2_temp(n) ) > ( dy / dt_particle(n) ) .OR. &4285 IF ( ABS( u_int(n) + rvar1_temp(n) ) > ( dx / dt_particle(n) ) .OR. & 4286 ABS( v_int(n) + rvar2_temp(n) ) > ( dy / dt_particle(n) ) .OR. & 4413 4287 ABS( w_int(n) + rvar3_temp(n) ) > ( dz_temp / dt_particle(n) ) ) THEN 4414 4288 ! 4415 !-- If total speed exceeds the allowed speed according to CFL 4289 !-- If total speed exceeds the allowed speed according to CFL 4416 4290 !-- criterion, limit the SGS speed to 4417 4291 !-- dx_i / dt_particle - u_resolved_i, considering a safty factor. 4418 rvar1_temp(n) = MERGE( rvar1_temp(n), &4419 0.9_wp * &4420 SIGN( dx / dt_particle(n) &4421 - ABS( u_int(n) ), rvar1_temp(n) ),&4422 ABS( u_int(n) + rvar1_temp(n) ) < &4292 rvar1_temp(n) = MERGE( rvar1_temp(n), & 4293 0.9_wp * & 4294 SIGN( dx / dt_particle(n) & 4295 - ABS( u_int(n) ), rvar1_temp(n) ), & 4296 ABS( u_int(n) + rvar1_temp(n) ) < & 4423 4297 ( dx / dt_particle(n) ) ) 4424 rvar2_temp(n) = MERGE( rvar2_temp(n), &4425 0.9_wp * &4426 SIGN( dy / dt_particle(n) &4427 - ABS( v_int(n) ), rvar2_temp(n) ),&4428 ABS( v_int(n) + rvar2_temp(n) ) < &4298 rvar2_temp(n) = MERGE( rvar2_temp(n), & 4299 0.9_wp * & 4300 SIGN( dy / dt_particle(n) & 4301 - ABS( v_int(n) ), rvar2_temp(n) ), & 4302 ABS( v_int(n) + rvar2_temp(n) ) < & 4429 4303 ( dy / dt_particle(n) ) ) 4430 rvar3_temp(n) = MERGE( rvar3_temp(n), &4431 0.9_wp * &4432 SIGN( zw(kp)-zw(kp-1) / dt_particle(n) &4433 - ABS( w_int(n) ), rvar3_temp(n) ),&4434 ABS( w_int(n) + rvar3_temp(n) ) < &4304 rvar3_temp(n) = MERGE( rvar3_temp(n), & 4305 0.9_wp * & 4306 SIGN( zw(kp)-zw(kp-1) / dt_particle(n) & 4307 - ABS( w_int(n) ), rvar3_temp(n) ), & 4308 ABS( w_int(n) + rvar3_temp(n) ) < & 4435 4309 ( zw(kp)-zw(kp-1) / dt_particle(n) ) ) 4436 4310 ENDIF 4437 4311 ! 4438 !-- Update particle velocites 4312 !-- Update particle velocites 4439 4313 particles(n)%rvar1 = rvar1_temp(n) 4440 4314 particles(n)%rvar2 = rvar2_temp(n) … … 4444 4318 w_int(n) = w_int(n) + particles(n)%rvar3 4445 4319 ! 4446 !-- Store the SGS TKE of the current timelevel which is needed for 4447 !-- for calculating the SGSparticle velocities at the next timestep4320 !-- Store the SGS TKE of the current timelevel which is needed for for calculating the SGS 4321 !-- particle velocities at the next timestep 4448 4322 particles(n)%e_m = e_int(n) 4449 4323 ENDDO … … 4452 4326 ELSE 4453 4327 ! 4454 !-- If no SGS velocities are used, only the particle timestep has to 4455 !-- be set 4328 !-- If no SGS velocities are used, only the particle timestep has to be set 4456 4329 dt_particle = dt_3d 4457 4330 … … 4461 4334 IF ( ANY( dens_ratio == 0.0_wp ) ) THEN 4462 4335 ! 4463 !-- Decide whether the particle loop runs over the subboxes or only over 1, 4464 !-- number_of_particles. This depends on the selected interpolation method. 4465 !-- If particle interpolation method is not trilinear, then the sorting within 4466 !-- subboxes is not required. However, therefore the index start_index(nb) and 4467 !-- end_index(nb) are not defined and the loops are still over 4468 !-- number_of_particles. @todo find a more generic way to write this loop or 4469 !-- delete trilinear interpolation 4336 !-- Decide whether the particle loop runs over the subboxes or only over 1, number_of_particles. 4337 !-- This depends on the selected interpolation method. 4338 !-- If particle interpolation method is not trilinear, then the sorting within subboxes is not 4339 !-- required. However, therefore the index start_index(nb) and end_index(nb) are not defined and 4340 !-- the loops are still over number_of_particles. @todo find a more generic way to write this 4341 !-- loop or delete trilinear interpolation 4470 4342 IF ( interpolation_trilinear ) THEN 4471 4343 subbox_start = 0 … … 4476 4348 ENDIF 4477 4349 ! 4478 !-- loop over subboxes. In case of simple interpolation scheme no subboxes 4479 !-- are introduced, as they are not required. Accordingly, this loops goes 4480 !-- from 1 to 1. 4350 !-- loop over subboxes. In case of simple interpolation scheme no subboxes are introduced, as 4351 !-- they are not required. Accordingly, this loop goes from 1 to 1. 4481 4352 DO nb = subbox_start, subbox_end 4482 4353 IF ( interpolation_trilinear ) THEN … … 4507 4378 ! 4508 4379 !-- Transport of particles with inertia 4509 particles(n)%x = particles(n)%x + particles(n)%speed_x * & 4510 dt_particle(n) 4511 particles(n)%y = particles(n)%y + particles(n)%speed_y * & 4512 dt_particle(n) 4513 particles(n)%z = particles(n)%z + particles(n)%speed_z * & 4514 dt_particle(n) 4380 particles(n)%x = particles(n)%x + particles(n)%speed_x * dt_particle(n) 4381 particles(n)%y = particles(n)%y + particles(n)%speed_y * dt_particle(n) 4382 particles(n)%z = particles(n)%z + particles(n)%speed_z * dt_particle(n) 4515 4383 4516 4384 ! … … 4532 4400 IF ( use_sgs_for_particles ) THEN 4533 4401 lagr_timescale(n) = km(kp,jp,ip) / MAX( e(kp,jp,ip), 1.0E-20_wp ) 4534 RL = EXP( -1.0_wp * dt_3d / MAX( lagr_timescale(n), & 4535 1.0E-20_wp ) ) 4536 sigma = SQRT( e(kp,jp,ip) ) 4402 rl = EXP( -1.0_wp * dt_3d / MAX( lagr_timescale(n), 1.0E-20_wp ) ) 4403 sigma = SQRT( e(kp,jp,ip) ) 4537 4404 ! 4538 4405 !-- Calculate random component of particle sgs velocity using parallel … … 4545 4412 rg3 = random_dummy 4546 4413 4547 particles(n)%rvar1 = RL * particles(n)%rvar1 +&4548 SQRT( 1.0_wp - RL**2 ) * sigma * rg14549 particles(n)%rvar2 = RL * particles(n)%rvar2 +&4550 SQRT( 1.0_wp - RL**2 ) * sigma * rg24551 particles(n)%rvar3 = RL * particles(n)%rvar3 +&4552 SQRT( 1.0_wp - RL**2 ) * sigma * rg34414 particles(n)%rvar1 = rl * particles(n)%rvar1 + & 4415 SQRT( 1.0_wp - rl**2 ) * sigma * rg1 4416 particles(n)%rvar2 = rl * particles(n)%rvar2 + & 4417 SQRT( 1.0_wp - rl**2 ) * sigma * rg2 4418 particles(n)%rvar3 = rl * particles(n)%rvar3 + & 4419 SQRT( 1.0_wp - rl**2 ) * sigma * rg3 4553 4420 4554 4421 particles(n)%speed_x = u_int(n) + particles(n)%rvar1 … … 4570 4437 exp_term = particle_groups(particles(n)%group)%exp_term 4571 4438 ENDIF 4572 particles(n)%speed_x = particles(n)%speed_x * exp_term + &4439 particles(n)%speed_x = particles(n)%speed_x * exp_term + & 4573 4440 u_int(n) * ( 1.0_wp - exp_term ) 4574 particles(n)%speed_y = particles(n)%speed_y * exp_term + &4441 particles(n)%speed_y = particles(n)%speed_y * exp_term + & 4575 4442 v_int(n) * ( 1.0_wp - exp_term ) 4576 particles(n)%speed_z = particles(n)%speed_z * exp_term + &4577 ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * &4443 particles(n)%speed_z = particles(n)%speed_z * exp_term + & 4444 ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * & 4578 4445 g / exp_arg ) * ( 1.0_wp - exp_term ) 4579 4446 ENDIF … … 4585 4452 ELSE 4586 4453 ! 4587 !-- Decide whether the particle loop runs over the subboxes or only over 1, 4588 !-- number_of_particles.This depends on the selected interpolation method.4454 !-- Decide whether the particle loop runs over the subboxes or only over 1, number_of_particles. 4455 !-- This depends on the selected interpolation method. 4589 4456 IF ( interpolation_trilinear ) THEN 4590 4457 subbox_start = 0 … … 4594 4461 subbox_end = 1 4595 4462 ENDIF 4596 !-- loop over subboxes. In case of simple interpolation scheme no subboxes 4597 !-- are introduced, as they are not required. Accordingly, this loops goes 4598 !-- from 1 to 1. 4463 !-- loop over subboxes. In case of simple interpolation scheme no subboxes are introduced, as 4464 !-- they are not required. Accordingly, this loop goes from 1 to 1. 4599 4465 DO nb = subbox_start, subbox_end 4600 4466 IF ( interpolation_trilinear ) THEN … … 4618 4484 IF ( cloud_droplets ) THEN 4619 4485 ! 4620 !-- Terminal velocity is computed for vertical direction (Rogers et al., 4621 !-- 1993,J. Appl. Meteorol.)4486 !-- Terminal velocity is computed for vertical direction (Rogers et al., 1993, 4487 !-- J. Appl. Meteorol.) 4622 4488 diameter = particles(n)%radius * 2000.0_wp !diameter in mm 4623 4489 IF ( diameter <= d0_rog ) THEN … … 4632 4498 IF ( use_sgs_for_particles ) THEN 4633 4499 lagr_timescale(n) = km(kp,jp,ip) / MAX( e(kp,jp,ip), 1.0E-20_wp ) 4634 RL = EXP( -1.0_wp * dt_3d / MAX( lagr_timescale(n), & 4635 1.0E-20_wp ) ) 4636 sigma = SQRT( e(kp,jp,ip) ) 4637 4638 ! 4639 !-- Calculate random component of particle sgs velocity using parallel 4640 !-- random generator 4500 rl = EXP( -1.0_wp * dt_3d / MAX( lagr_timescale(n), 1.0E-20_wp ) ) 4501 sigma = SQRT( e(kp,jp,ip) ) 4502 4503 ! 4504 !-- Calculate random component of particle sgs velocity using parallel random 4505 !-- generator 4641 4506 CALL random_number_parallel_gauss( random_dummy ) 4642 4507 rg1 = random_dummy … … 4646 4511 rg3 = random_dummy 4647 4512 4648 particles(n)%rvar1 = RL * particles(n)%rvar1 +&4649 SQRT( 1.0_wp - RL**2 ) * sigma * rg14650 particles(n)%rvar2 = RL * particles(n)%rvar2 +&4651 SQRT( 1.0_wp - RL**2 ) * sigma * rg24652 particles(n)%rvar3 = RL * particles(n)%rvar3 +&4653 SQRT( 1.0_wp - RL**2 ) * sigma * rg34513 particles(n)%rvar1 = rl * particles(n)%rvar1 + & 4514 SQRT( 1.0_wp - rl**2 ) * sigma * rg1 4515 particles(n)%rvar2 = rl * particles(n)%rvar2 + & 4516 SQRT( 1.0_wp - rl**2 ) * sigma * rg2 4517 particles(n)%rvar3 = rl * particles(n)%rvar3 + & 4518 SQRT( 1.0_wp - rl**2 ) * sigma * rg3 4654 4519 4655 4520 particles(n)%speed_x = u_int(n) + particles(n)%rvar1 … … 4671 4536 exp_term = particle_groups(particles(n)%group)%exp_term 4672 4537 ENDIF 4673 particles(n)%speed_x = particles(n)%speed_x * exp_term + &4538 particles(n)%speed_x = particles(n)%speed_x * exp_term + & 4674 4539 u_int(n) * ( 1.0_wp - exp_term ) 4675 particles(n)%speed_y = particles(n)%speed_y * exp_term + &4540 particles(n)%speed_y = particles(n)%speed_y * exp_term + & 4676 4541 v_int(n) * ( 1.0_wp - exp_term ) 4677 particles(n)%speed_z = particles(n)%speed_z * exp_term + &4678 ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * g / &4542 particles(n)%speed_z = particles(n)%speed_z * exp_term + & 4543 ( w_int(n) - ( 1.0_wp - dens_ratio(n) ) * g / & 4679 4544 exp_arg ) * ( 1.0_wp - exp_term ) 4680 4545 ENDIF … … 4685 4550 4686 4551 ! 4687 !-- Store the old age of the particle ( needed to prevent that a 4688 !-- particle crosses several PEs during one timestep, and for the 4689 !-- evaluation of the subgrid particle velocity fluctuations ) 4552 !-- Store the old age of the particle ( needed to prevent that a particle crosses several PEs during 4553 !-- one timestep, and for the evaluation of the subgrid particle velocity fluctuations ) 4690 4554 particles(1:number_of_particles)%age_m = particles(1:number_of_particles)%age 4691 4555 4692 4556 ! 4693 !-- loop over subboxes. In case of simple interpolation scheme no subboxes 4694 !-- are introduced, as they are not required. Accordingly, this loops goes 4695 !-- from 1 to 1. 4696 ! 4697 !-- Decide whether the particle loop runs over the subboxes or only over 1, 4698 !-- number_of_particles. This depends on the selected interpolation method. 4557 !-- loop over subboxes. In case of simple interpolation scheme no subboxes are introduced, as 4558 !-- they are not required. Accordingly, this loop goes from 1 to 1. 4559 ! 4560 !-- Decide whether the particle loop runs over the subboxes or only over 1, number_of_particles. 4561 !-- This depends on the selected interpolation method. 4699 4562 IF ( interpolation_trilinear ) THEN 4700 4563 subbox_start = 0 … … 4713 4576 ENDIF 4714 4577 ! 4715 !-- Loop from particle start to particle end and increment the particle 4716 !-- age and the total time that the particle has advanced within the 4717 !-- particle timestep procedure. 4578 !-- Loop from particle start to particle end and increment the particle age and the total time 4579 !-- that the particle has advanced within the particle timestep procedure. 4718 4580 DO n = particle_start, particle_end 4719 4581 particles(n)%age = particles(n)%age + dt_particle(n) … … 4722 4584 ! 4723 4585 !-- Particles that leave the child domain during the SGS-timestep loop 4724 !-- must not continue timestepping until they are transferred to the 4586 !-- must not continue timestepping until they are transferred to the 4725 4587 !-- parent. Hence, set their dt_sum to dt. 4726 4588 IF ( child_domain .AND. use_sgs_for_particles ) THEN 4727 4589 DO n = particle_start, particle_end 4728 IF ( particles(n)%x < 0.0_wp .OR. &4729 particles(n)%y < 0.0_wp .OR. &4730 particles(n)%x > ( nx+1 ) * dx .OR. &4590 IF ( particles(n)%x < 0.0_wp .OR. & 4591 particles(n)%y < 0.0_wp .OR. & 4592 particles(n)%x > ( nx+1 ) * dx .OR. & 4731 4593 particles(n)%y < ( ny+1 ) * dy ) THEN 4732 4594 particles(n)%dt_sum = dt_3d … … 4735 4597 ENDIF 4736 4598 ! 4737 !-- Check whether there is still a particle that has not yet completed 4738 !-- the total LES timestep 4599 !-- Check whether there is still a particle that has not yet completed the total LES timestep 4739 4600 DO n = particle_start, particle_end 4740 IF ( ( dt_3d - particles(n)%dt_sum ) > 1E-8_wp ) & 4741 dt_3d_reached_l = .FALSE. 4601 IF ( ( dt_3d - particles(n)%dt_sum ) > 1E-8_wp ) dt_3d_reached_l = .FALSE. 4742 4602 ENDDO 4743 4603 ENDDO … … 4748 4608 END SUBROUTINE lpm_advec 4749 4609 4750 4751 !------------------------------------------------------------------------------ !4610 4611 !--------------------------------------------------------------------------------------------------! 4752 4612 ! Description: 4753 4613 ! ------------ 4754 !> Calculation of subgrid-scale particle speed using the stochastic model 4614 !> Calculation of subgrid-scale particle speed using the stochastic model 4755 4615 !> of Weil et al. (2004, JAS, 61, 2877-2887). 4756 !------------------------------------------------------------------------------! 4757 SUBROUTINE weil_stochastic_eq( v_sgs, fs_n, e_n, dedxi_n, dedt_n, diss_n, & 4758 dt_n, rg_n, fac ) 4616 !--------------------------------------------------------------------------------------------------! 4617 SUBROUTINE weil_stochastic_eq( v_sgs, fs_n, e_n, dedxi_n, dedt_n, diss_n, dt_n, rg_n, fac ) 4759 4618 4760 4619 REAL(wp) :: a1 !< dummy argument 4761 REAL(wp) :: dedt_n !< time derivative of TKE at particle position 4620 REAL(wp) :: dedt_n !< time derivative of TKE at particle position 4762 4621 REAL(wp) :: dedxi_n !< horizontal derivative of TKE at particle position 4763 REAL(wp) :: diss_n !< dissipation at particle position 4622 REAL(wp) :: diss_n !< dissipation at particle position 4764 4623 REAL(wp) :: dt_n !< particle timestep 4765 4624 REAL(wp) :: e_n !< TKE at particle position … … 4770 4629 REAL(wp) :: term2 !< drift correction term 4771 4630 REAL(wp) :: term3 !< random term 4772 REAL(wp) :: v_sgs !< subgrid-scale velocity component 4773 4774 !-- At first, limit TKE to a small non-zero number, in order to prevent 4775 !-- the occurrence of extremely large SGS-velocities in case TKE is zero, 4776 !-- (could occur at the simulation begin). 4631 REAL(wp) :: v_sgs !< subgrid-scale velocity component 4632 4633 !-- At first, limit TKE to a small non-zero number, in order to prevent the occurrence of extremely 4634 !-- large SGS-velocities in case TKE is zero, (could occur at the simulation begin). 4777 4635 e_n = MAX( e_n, 1E-20_wp ) 4778 4636 ! 4779 !-- Please note, terms 1 and 2 (drift and memory term, respectively) are 4780 !-- multiplied by a flag to switch of both terms near topography. 4781 !-- This is necessary, as both terms may cause a subgrid-scale velocity build up 4782 !-- if particles are trapped in regions with very small TKE, e.g. in narrow street 4783 !-- canyons resolved by only a few grid points. Hence, term 1 and term 2 are 4784 !-- disabled if one of the adjacent grid points belongs to topography. 4785 !-- Moreover, in this case, the previous subgrid-scale component is also set 4786 !-- to zero. 4637 !-- Please note, terms 1 and 2 (drift and memory term, respectively) are multiplied by a flag to 4638 !-- switch of both terms near topography. 4639 !-- This is necessary, as both terms may cause a subgrid-scale velocity build up if particles are 4640 !-- trapped in regions with very small TKE, e.g. in narrow street canyons resolved by only a few 4641 !-- grid points. Hence, term 1 and term 2 are disabled if one of the adjacent grid points belongs to 4642 !-- topography. 4643 !-- Moreover, in this case, the previous subgrid-scale component is also set to zero. 4787 4644 4788 4645 a1 = fs_n * c_0 * diss_n 4789 4646 ! 4790 4647 !-- Memory term 4791 term1 = - a1 * v_sgs * dt_n / ( 4.0_wp * sgs_wf_part * e_n + 1E-20_wp ) & 4792 * fac 4648 term1 = - a1 * v_sgs * dt_n / ( 4.0_wp * sgs_wf_part * e_n + 1E-20_wp ) * fac 4793 4649 ! 4794 4650 !-- Drift correction term 4795 term2 = ( ( dedt_n * v_sgs / e_n ) + dedxi_n ) * 0.5_wp * dt_n & 4796 * fac 4651 term2 = ( ( dedt_n * v_sgs / e_n ) + dedxi_n ) * 0.5_wp * dt_n * fac 4797 4652 ! 4798 4653 !-- Random term 4799 4654 term3 = SQRT( MAX( a1, 1E-20_wp ) ) * ( rg_n - 1.0_wp ) * SQRT( dt_n ) 4800 4655 ! 4801 !-- In cese one of the adjacent grid-boxes belongs to topograhy, the previous 4802 !-- subgrid-scale velocity component is set to zero, in order to prevent a 4803 !-- velocity build-up. 4804 !-- This case, set also previous subgrid-scale component to zero. 4656 !-- In case one of the adjacent grid-boxes belongs to topograhy, the previous subgrid-scale velocity 4657 !-- component is set to zero, in order to prevent a velocity build-up. 4658 !-- This case, set also previous subgrid-scale component to zero. 4805 4659 v_sgs = v_sgs * fac + term1 + term2 + term3 4806 4660 … … 4808 4662 4809 4663 4810 !------------------------------------------------------------------------------ !4664 !--------------------------------------------------------------------------------------------------! 4811 4665 ! Description: 4812 4666 ! ------------ 4813 4667 !> swap timelevel in case of particle advection interpolation 'simple-corrector' 4814 !> This routine is called at the end of one timestep, the velocities are then 4815 !> used for the nexttimestep4816 !------------------------------------------------------------------------------ !4668 !> This routine is called at the end of one timestep, the velocities are then used for the next 4669 !> timestep 4670 !--------------------------------------------------------------------------------------------------! 4817 4671 SUBROUTINE lpm_swap_timelevel_for_particle_advection 4818 4672 4819 4673 ! 4820 !-- save the divergence free velocites of t+1 to use them at the end of the 4821 !-- next time step 4674 !-- Save the divergence free velocites of t+1 to use them at the end of the next time step 4822 4675 u_t = u 4823 4676 v_t = v … … 4827 4680 4828 4681 4829 !------------------------------------------------------------------------------ !4682 !--------------------------------------------------------------------------------------------------! 4830 4683 ! Description: 4831 4684 ! ------------ 4832 4685 !> Boundary conditions for the Lagrangian particles. 4833 !> The routine consists of two different parts. One handles the bottom (flat) 4834 !> and top boundary. In this part, also particles which exceeded their lifetime 4835 !> are deleted. 4686 !> The routine consists of two different parts. One handles the bottom (flat) and top boundary. In 4687 !> this part, also particles which exceeded their lifetime are deleted. 4836 4688 !> The other part handles the reflection of particles from vertical walls. 4837 4689 !> This part was developed by Jin Zhang during 2006-2007. 4838 4690 !> 4839 !> To do: Code structure for finding the t_index values and for checking the 4840 !> ----- reflection conditions is basically the same for all four cases, so it4841 !> s hould be possible to further simplify/shorten it.4691 !> To do: Code structure for finding the t_index values and for checking the reflection conditions 4692 !> ------ is basically the same for all four cases, so it should be possible to further 4693 !> simplify/shorten it. 4842 4694 !> 4843 4695 !> THE WALLS PART OF THIS ROUTINE HAS NOT BEEN TESTED FOR OCEAN RUNS SO FAR!!!! 4844 4696 !> (see offset_ocean_*) 4845 !------------------------------------------------------------------------------ !4697 !--------------------------------------------------------------------------------------------------! 4846 4698 SUBROUTINE lpm_boundary_conds( location_bc , i, j, k ) 4847 4699 4848 4700 CHARACTER (LEN=*), INTENT(IN) :: location_bc !< general mode: boundary conditions at bottom/top of the model domain 4849 !< or at vertical surfaces (buildings, terrain steps) 4701 !< or at vertical surfaces (buildings, terrain steps) 4850 4702 INTEGER(iwp), INTENT(IN) :: i !< grid index of particle box along x 4851 4703 INTEGER(iwp), INTENT(IN) :: j !< grid index of particle box along y … … 4919 4771 4920 4772 ! 4921 !-- Apply boundary conditions to those particles that have crossed the top or 4922 !-- bottom boundary anddelete those particles, which are older than allowed4773 !-- Apply boundary conditions to those particles that have crossed the top or bottom boundary and 4774 !-- delete those particles, which are older than allowed 4923 4775 DO n = 1, number_of_particles 4924 4776 4925 4777 ! 4926 !-- Stop if particles have moved further than the length of one 4927 !-- PE subdomain (newly releasedparticles have age = age_m!)4778 !-- Stop if particles have moved further than the length of one PE subdomain (newly released 4779 !-- particles have age = age_m!) 4928 4780 IF ( particles(n)%age /= particles(n)%age_m ) THEN 4929 IF ( ABS(particles(n)%speed_x) > &4930 ((nxr-nxl+2)*dx)/(particles(n)%age-particles(n)%age_m) .OR. &4931 ABS(particles(n)%speed_y) > &4781 IF ( ABS(particles(n)%speed_x) > & 4782 ((nxr-nxl+2)*dx)/(particles(n)%age-particles(n)%age_m) .OR. & 4783 ABS(particles(n)%speed_y) > & 4932 4784 ((nyn-nys+2)*dy)/(particles(n)%age-particles(n)%age_m) ) THEN 4933 4785 4934 WRITE( message_string, * ) 'particle too fast. n = ', n 4786 WRITE( message_string, * ) 'particle too fast. n = ', n 4935 4787 CALL message( 'lpm_boundary_conds', 'PA0148', 2, 2, -1, 6, 1 ) 4936 4788 ENDIF 4937 4789 ENDIF 4938 4790 4939 IF ( particles(n)%age > particle_maximum_age .AND. & 4940 particles(n)%particle_mask ) & 4941 THEN 4791 IF ( particles(n)%age > particle_maximum_age .AND. particles(n)%particle_mask ) THEN 4942 4792 particles(n)%particle_mask = .FALSE. 4943 4793 deleted_particles = deleted_particles + 1 … … 5026 4876 k1 = k 5027 4877 ! 5028 !-- Determine horizontal as well as vertical walls at which particle can 5029 !-- be potentially reflected.4878 !-- Determine horizontal as well as vertical walls at which particle can be potentially 4879 !-- reflected. 5030 4880 !-- Start with walls aligned in yz layer. 5031 !-- Wall to the right 4881 !-- Wall to the right 5032 4882 IF ( prt_x > pos_x_old ) THEN 5033 4883 xwall = ( i1 + 1 ) * dx … … 5074 4924 z_wall_reached = .FALSE. 5075 4925 ! 5076 !-- Initialize time array 4926 !-- Initialize time array 5077 4927 t = 0.0_wp 5078 4928 ! 5079 !-- Check if particle can reach any wall. This case, calculate the 5080 !-- fractional time needed to reach this wall. Store this fractional 5081 !-- timestep in array t. Moreover, store indices for these grid 5082 !-- boxes where the respective wall belongs to. 4929 !-- Check if particle can reach any wall. This case, calculate the fractional time needed to 4930 !-- reach this wall. Store this fractional timestep in array t. Moreover, store indices for 4931 !-- these grid boxes where the respective wall belongs to. 5083 4932 !-- Start with x-direction. 5084 4933 t_index = 1 5085 t(t_index) = ( xwall - pos_x_old ) &5086 / MERGE( MAX( prt_x - pos_x_old, 1E-30_wp ),&5087 MIN( prt_x - pos_x_old, -1E-30_wp ),&5088 prt_x > pos_x_old )4934 t(t_index) = ( xwall - pos_x_old ) & 4935 / MERGE( MAX( prt_x - pos_x_old, 1E-30_wp ), & 4936 MIN( prt_x - pos_x_old, -1E-30_wp ), & 4937 prt_x > pos_x_old ) 5089 4938 x_ind(t_index) = i2 5090 4939 y_ind(t_index) = j1 … … 5094 4943 reach_z(t_index) = .FALSE. 5095 4944 ! 5096 !-- Store these values only if particle really reaches any wall. t must 5097 !-- be in a interval between [0:1].4945 !-- Store these values only if particle really reaches any wall. t must be in an interval 4946 !-- between [0:1]. 5098 4947 IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp ) THEN 5099 4948 t_index = t_index + 1 … … 5102 4951 ! 5103 4952 !-- y-direction 5104 t(t_index) = ( ywall - pos_y_old ) &5105 / MERGE( MAX( prt_y - pos_y_old, 1E-30_wp ),&5106 MIN( prt_y - pos_y_old, -1E-30_wp ),&5107 prt_y > pos_y_old )4953 t(t_index) = ( ywall - pos_y_old ) & 4954 / MERGE( MAX( prt_y - pos_y_old, 1E-30_wp ), & 4955 MIN( prt_y - pos_y_old, -1E-30_wp ), & 4956 prt_y > pos_y_old ) 5108 4957 x_ind(t_index) = i1 5109 4958 y_ind(t_index) = j2 … … 5118 4967 ! 5119 4968 !-- z-direction 5120 t(t_index) = (zwall - pos_z_old ) &5121 / MERGE( MAX( prt_z - pos_z_old, 1E-30_wp ),&5122 MIN( prt_z - pos_z_old, -1E-30_wp ),&5123 prt_z > pos_z_old )4969 t(t_index) = (zwall - pos_z_old ) & 4970 / MERGE( MAX( prt_z - pos_z_old, 1E-30_wp ), & 4971 MIN( prt_z - pos_z_old, -1E-30_wp ), & 4972 prt_z > pos_z_old ) 5124 4973 5125 4974 x_ind(t_index) = i1 … … 5139 4988 IF ( cross_wall_x .OR. cross_wall_y .OR. cross_wall_z ) THEN 5140 4989 ! 5141 !-- Sort fractional timesteps in ascending order. Also sort the 5142 !-- corresponding indices and flag according to the time interval a 5143 !-- particle reaches the respective wall. 4990 !-- Sort fractional timesteps in ascending order. Also sort the corresponding indices and 4991 !-- flag according to the time interval a particle reaches the respective wall. 5144 4992 inc = 1 5145 4993 jr = 1 … … 5187 5035 !-- Loop over all times a particle possibly moves into a new grid box 5188 5036 t_old = 0.0_wp 5189 DO t_index = 1, t_index_number 5190 ! 5191 !-- Calculate intermediate particle position according to the 5192 !-- timesteps a particle reaches any wall. 5193 pos_x = pos_x + ( t(t_index) - t_old ) * dt_particle & 5194 * particles(n)%speed_x 5195 pos_y = pos_y + ( t(t_index) - t_old ) * dt_particle & 5196 * particles(n)%speed_y 5197 pos_z = pos_z + ( t(t_index) - t_old ) * dt_particle & 5198 * particles(n)%speed_z 5199 ! 5200 !-- Obtain x/y grid indices for intermediate particle position from 5201 !-- sorted index array 5037 DO t_index = 1, t_index_number 5038 ! 5039 !-- Calculate intermediate particle position according to the timesteps a particle 5040 !-- reaches any wall. 5041 pos_x = pos_x + ( t(t_index) - t_old ) * dt_particle * particles(n)%speed_x 5042 pos_y = pos_y + ( t(t_index) - t_old ) * dt_particle * particles(n)%speed_y 5043 pos_z = pos_z + ( t(t_index) - t_old ) * dt_particle * particles(n)%speed_z 5044 ! 5045 !-- Obtain x/y grid indices for intermediate particle position from sorted index array 5202 5046 i3 = x_ind(t_index) 5203 5047 j3 = y_ind(t_index) … … 5205 5049 ! 5206 5050 !-- Check which wall is already reached 5207 IF ( .NOT. x_wall_reached ) x_wall_reached = reach_x(t_index) 5051 IF ( .NOT. x_wall_reached ) x_wall_reached = reach_x(t_index) 5208 5052 IF ( .NOT. y_wall_reached ) y_wall_reached = reach_y(t_index) 5209 5053 IF ( .NOT. z_wall_reached ) z_wall_reached = reach_z(t_index) 5210 5054 ! 5211 !-- Check if a particle needs to be reflected at any yz-wall. If 5212 !-- necessary, carry out reflection. Please note, a security 5213 !-- constant is required, as the particle position does not 5214 !-- necessarily exactly match the wall location due to rounding 5215 !-- errors. 5216 IF ( reach_x(t_index) .AND. & 5217 ABS( pos_x - xwall ) < eps .AND. & 5218 .NOT. BTEST(wall_flags_total_0(k3,j3,i3),0) .AND. & 5055 !-- Check if a particle needs to be reflected at any yz-wall. If necessary, carry out 5056 !-- reflection. Please note, a security constant is required, as the particle position 5057 !-- does not necessarily exactly match the wall location due to rounding errors. 5058 IF ( reach_x(t_index) .AND. & 5059 ABS( pos_x - xwall ) < eps .AND. & 5060 .NOT. BTEST(wall_flags_total_0(k3,j3,i3),0) .AND. & 5219 5061 .NOT. reflect_x ) THEN 5220 ! 5221 ! 5222 !-- Reflection in x-direction. 5223 !-- Ensure correct reflection by MIN/MAX functions, depending on 5224 !-- direction of particle transport.5225 !-- Due to rounding errors pos_x does not exactly match the wall 5226 !-- location, leading to erroneous reflection.5227 pos_x = MERGE( MIN( 2.0_wp * xwall - pos_x, xwall ), &5228 MAX( 2.0_wp * xwall - pos_x, xwall ), &5062 ! 5063 ! 5064 !-- Reflection in x-direction. 5065 !-- Ensure correct reflection by MIN/MAX functions, depending on direction of 5066 !-- particle transport. 5067 !-- Due to rounding errors pos_x does not exactly match the wall location, leading to 5068 !-- erroneous reflection. 5069 pos_x = MERGE( MIN( 2.0_wp * xwall - pos_x, xwall ), & 5070 MAX( 2.0_wp * xwall - pos_x, xwall ), & 5229 5071 particles(n)%x > xwall ) 5230 5072 ! 5231 !-- Change sign of particle speed 5073 !-- Change sign of particle speed 5232 5074 particles(n)%speed_x = - particles(n)%speed_x 5233 5075 ! … … 5238 5080 reflect_x = .TRUE. 5239 5081 ! 5240 !-- As the particle does not cross any further yz-wall during 5241 !-- this timestep, setfurther x-indices to the current one.5082 !-- As the particle does not cross any further yz-wall during this timestep, set 5083 !-- further x-indices to the current one. 5242 5084 x_ind(t_index:t_index_number) = i1 5243 5085 ! 5244 !-- If particle already reached the wall but was not reflected, 5245 !-- set further x-indices tothe new one.5246 ELSEIF ( x_wall_reached .AND..NOT. reflect_x ) THEN5086 !-- If particle already reached the wall but was not reflected, set further x-indices to 5087 !-- the new one. 5088 ELSEIF ( x_wall_reached .AND. .NOT. reflect_x ) THEN 5247 5089 x_ind(t_index:t_index_number) = i2 5248 ENDIF !particle reflection in x direction done 5249 5250 ! 5251 !-- Check if a particle needs to be reflected at any xz-wall. If 5252 !-- necessary, carry out reflection. Please note, a security 5253 !-- constant is required, as the particle position does not 5254 !-- necessarily exactly match the wall location due to rounding 5255 !-- errors. 5256 IF ( reach_y(t_index) .AND. & 5257 ABS( pos_y - ywall ) < eps .AND. & 5258 .NOT. BTEST(wall_flags_total_0(k3,j3,i3),0) .AND. & 5090 ENDIF !particle reflection in x direction done 5091 5092 ! 5093 !-- Check if a particle needs to be reflected at any xz-wall. If necessary, carry out 5094 !-- reflection. Please note, a security constant is required, as the particle position 5095 !-- does not necessarily exactly match the wall location due to rounding errors. 5096 IF ( reach_y(t_index) .AND. & 5097 ABS( pos_y - ywall ) < eps .AND. & 5098 .NOT. BTEST(wall_flags_total_0(k3,j3,i3),0) .AND. & 5259 5099 .NOT. reflect_y ) THEN 5260 ! 5261 ! 5262 !-- Reflection in y-direction. 5263 !-- Ensure correct reflection by MIN/MAX functions, depending on 5264 !-- direction of particle transport.5265 !-- Due to rounding errors pos_y does not exactly match the wall 5266 !-- location, leading to erroneous reflection.5267 pos_y = MERGE( MIN( 2.0_wp * ywall - pos_y, ywall ), &5268 MAX( 2.0_wp * ywall - pos_y, ywall ), &5100 ! 5101 ! 5102 !-- Reflection in y-direction. 5103 !-- Ensure correct reflection by MIN/MAX functions, depending on direction of 5104 !-- particle transport. 5105 !-- Due to rounding errors pos_y does not exactly match the wall location, leading to 5106 !-- erroneous reflection. 5107 pos_y = MERGE( MIN( 2.0_wp * ywall - pos_y, ywall ), & 5108 MAX( 2.0_wp * ywall - pos_y, ywall ), & 5269 5109 particles(n)%y > ywall ) 5270 5110 ! 5271 !-- Change sign of particle speed 5111 !-- Change sign of particle speed 5272 5112 particles(n)%speed_y = - particles(n)%speed_y 5273 5113 ! … … 5278 5118 reflect_y = .TRUE. 5279 5119 ! 5280 !-- As the particle does not cross any further xz-wall during 5281 !-- this timestep, setfurther y-indices to the current one.5120 !-- As the particle does not cross any further xz-wall during this timestep, set 5121 !-- further y-indices to the current one. 5282 5122 y_ind(t_index:t_index_number) = j1 5283 5123 ! 5284 !-- If particle already reached the wall but was not reflected, 5285 !-- set further y-indices tothe new one.5286 ELSEIF ( y_wall_reached .AND..NOT. reflect_y ) THEN5124 !-- If particle already reached the wall but was not reflected, set further y-indices to 5125 !-- the new one. 5126 ELSEIF ( y_wall_reached .AND. .NOT. reflect_y ) THEN 5287 5127 y_ind(t_index:t_index_number) = j2 5288 ENDIF !particle reflection in y direction done 5289 5290 ! 5291 !-- Check if a particle needs to be reflected at any xy-wall. If 5292 !-- necessary, carry out reflection. Please note, a security 5293 !-- constant is required, as the particle position does not 5294 !-- necessarily exactly match the wall location due to rounding 5295 !-- errors. 5296 IF ( reach_z(t_index) .AND. & 5297 ABS( pos_z - zwall ) < eps .AND. & 5298 .NOT. BTEST(wall_flags_total_0(k3,j3,i3),0) .AND. & 5128 ENDIF !particle reflection in y direction done 5129 5130 ! 5131 !-- Check if a particle needs to be reflected at any xy-wall. If necessary, carry out 5132 !-- reflection. Please note, a security constant is required, as the particle position 5133 !-- does not necessarily exactly match the wall location due to rounding errors. 5134 IF ( reach_z(t_index) .AND. & 5135 ABS( pos_z - zwall ) < eps .AND. & 5136 .NOT. BTEST(wall_flags_total_0(k3,j3,i3),0) .AND. & 5299 5137 .NOT. reflect_z ) THEN 5300 ! 5301 ! 5302 !-- Reflection in z-direction. 5303 !-- Ensure correct reflection by MIN/MAX functions, depending on 5304 !-- direction of particle transport.5305 !-- Due to rounding errors pos_z does not exactly match the wall 5306 !-- location, leading to erroneous reflection.5307 pos_z = MERGE( MIN( 2.0_wp * zwall - pos_z, zwall ), &5308 MAX( 2.0_wp * zwall - pos_z, zwall ), &5138 ! 5139 ! 5140 !-- Reflection in z-direction. 5141 !-- Ensure correct reflection by MIN/MAX functions, depending on direction of 5142 !-- particle transport. 5143 !-- Due to rounding errors pos_z does not exactly match the wall location, leading to 5144 !-- erroneous reflection. 5145 pos_z = MERGE( MIN( 2.0_wp * zwall - pos_z, zwall ), & 5146 MAX( 2.0_wp * zwall - pos_z, zwall ), & 5309 5147 particles(n)%z > zwall ) 5310 5148 ! 5311 !-- Change sign of particle speed 5149 !-- Change sign of particle speed 5312 5150 particles(n)%speed_z = - particles(n)%speed_z 5313 5151 ! … … 5318 5156 reflect_z = .TRUE. 5319 5157 ! 5320 !-- As the particle does not cross any further xy-wall during 5321 !-- this timestep, setfurther z-indices to the current one.5158 !-- As the particle does not cross any further xy-wall during this timestep, set 5159 !-- further z-indices to the current one. 5322 5160 z_ind(t_index:t_index_number) = k1 5323 5161 ! 5324 !-- If particle already reached the wall but was not reflected, 5325 !-- set further z-indices tothe new one.5326 ELSEIF ( z_wall_reached .AND..NOT. reflect_z ) THEN5162 !-- If particle already reached the wall but was not reflected, set further z-indices to 5163 !-- the new one. 5164 ELSEIF ( z_wall_reached .AND. .NOT. reflect_z ) THEN 5327 5165 z_ind(t_index:t_index_number) = k2 5328 ENDIF !particle reflection in z direction done5166 ENDIF !particle reflection in z direction done 5329 5167 5330 5168 ! … … 5334 5172 ENDDO 5335 5173 ! 5336 !-- If a particle was reflected, calculate final position from last 5337 !-- intermediate position. 5174 !-- If a particle was reflected, calculate final position from last intermediate position. 5338 5175 IF ( reflect_x .OR. reflect_y .OR. reflect_z ) THEN 5339 5176 5340 particles(n)%x = pos_x + ( 1.0_wp - t_old ) * dt_particle & 5341 * particles(n)%speed_x 5342 particles(n)%y = pos_y + ( 1.0_wp - t_old ) * dt_particle & 5343 * particles(n)%speed_y 5344 particles(n)%z = pos_z + ( 1.0_wp - t_old ) * dt_particle & 5345 * particles(n)%speed_z 5177 particles(n)%x = pos_x + ( 1.0_wp - t_old ) * dt_particle * particles(n)%speed_x 5178 particles(n)%y = pos_y + ( 1.0_wp - t_old ) * dt_particle * particles(n)%speed_y 5179 particles(n)%z = pos_z + ( 1.0_wp - t_old ) * dt_particle * particles(n)%speed_z 5346 5180 5347 5181 ENDIF … … 5358 5192 END SELECT 5359 5193 5360 END SUBROUTINE lpm_boundary_conds 5361 5362 5363 !------------------------------------------------------------------------------ !5194 END SUBROUTINE lpm_boundary_conds 5195 5196 5197 !--------------------------------------------------------------------------------------------------! 5364 5198 ! Description: 5365 5199 ! ------------ 5366 !> Calculates change in droplet radius by condensation/evaporation, using 5367 !> either an analytic formula or by numerically integrating the radius growth 5368 !> equation including curvature and solution effects using Rosenbrocks method 5369 !> (see Numerical recipes in FORTRAN, 2nd edition, p. 731). 5200 !> Calculates change in droplet radius by condensation/evaporation, using either an analytic formula 5201 !> or by numerically integrating the radius growth equation including curvature and solution effects 5202 !> using Rosenbrocks method (see Numerical recipes in FORTRAN, 2nd edition, p. 731). 5370 5203 !> The analytical formula and growth equation follow those given in 5371 5204 !> Rogers and Yau (A short course in cloud physics, 3rd edition, p. 102/103). 5372 !------------------------------------------------------------------------------ !5205 !--------------------------------------------------------------------------------------------------! 5373 5206 SUBROUTINE lpm_droplet_condensation (i,j,k) 5207 5208 ! 5209 !-- Parameters for Rosenbrock method (see Verwer et al., 1999) 5210 REAL(wp), PARAMETER :: prec = 1.0E-3_wp !< precision of Rosenbrock solution 5211 REAL(wp), PARAMETER :: q_increase = 1.5_wp !< increase factor in timestep 5212 REAL(wp), PARAMETER :: q_decrease = 0.9_wp !< decrease factor in timestep 5213 REAL(wp), PARAMETER :: gamma = 0.292893218814_wp !< = 1.0 - 1.0 / SQRT(2.0) 5214 ! 5215 !-- Parameters for terminal velocity 5216 REAL(wp), PARAMETER :: a_rog = 9.65_wp !< parameter for fall velocity 5217 REAL(wp), PARAMETER :: b_rog = 10.43_wp !< parameter for fall velocity 5218 REAL(wp), PARAMETER :: c_rog = 0.6_wp !< parameter for fall velocity 5219 REAL(wp), PARAMETER :: k_cap_rog = 4.0_wp !< parameter for fall velocity 5220 REAL(wp), PARAMETER :: k_low_rog = 12.0_wp !< parameter for fall velocity 5221 REAL(wp), PARAMETER :: d0_rog = 0.745_wp !< separation diameter 5374 5222 5375 5223 INTEGER(iwp), INTENT(IN) :: i !< 5376 5224 INTEGER(iwp), INTENT(IN) :: j !< 5377 5225 INTEGER(iwp), INTENT(IN) :: k !< 5378 INTEGER(iwp) :: n!<5226 INTEGER(iwp) :: n !< 5379 5227 5380 5228 REAL(wp) :: afactor !< curvature effects … … 5398 5246 REAL(wp) :: r_ros_ini !< initial Rosenbrock radius 5399 5247 REAL(wp) :: r0 !< gas-kinetic lengthscale 5248 REAL(wp) :: re_p !< particle Reynolds number 5400 5249 REAL(wp) :: sigma !< surface tension of water 5401 5250 REAL(wp) :: thermal_conductivity !< thermal conductivity for water 5402 5251 REAL(wp) :: t_int !< temperature 5403 5252 REAL(wp) :: w_s !< terminal velocity of droplets 5404 REAL(wp) :: re_p !< particle Reynolds number 5405 ! 5406 !-- Parameters for Rosenbrock method (see Verwer et al., 1999) 5407 REAL(wp), PARAMETER :: prec = 1.0E-3_wp !< precision of Rosenbrock solution 5408 REAL(wp), PARAMETER :: q_increase = 1.5_wp !< increase factor in timestep 5409 REAL(wp), PARAMETER :: q_decrease = 0.9_wp !< decrease factor in timestep 5410 REAL(wp), PARAMETER :: gamma = 0.292893218814_wp !< = 1.0 - 1.0 / SQRT(2.0) 5411 ! 5412 !-- Parameters for terminal velocity 5413 REAL(wp), PARAMETER :: a_rog = 9.65_wp !< parameter for fall velocity 5414 REAL(wp), PARAMETER :: b_rog = 10.43_wp !< parameter for fall velocity 5415 REAL(wp), PARAMETER :: c_rog = 0.6_wp !< parameter for fall velocity 5416 REAL(wp), PARAMETER :: k_cap_rog = 4.0_wp !< parameter for fall velocity 5417 REAL(wp), PARAMETER :: k_low_rog = 12.0_wp !< parameter for fall velocity 5418 REAL(wp), PARAMETER :: d0_rog = 0.745_wp !< separation diameter 5419 5253 5254 REAL(wp), DIMENSION(number_of_particles) :: new_r !< 5420 5255 REAL(wp), DIMENSION(number_of_particles) :: ventilation_effect !< 5421 REAL(wp), DIMENSION(number_of_particles) :: new_r !<5422 5256 5423 5257 CALL cpu_log( log_point_s(42), 'lpm_droplet_condens', 'start' ) … … 5437 5271 ! 5438 5272 !-- Moldecular diffusivity of water vapor in air (Hall und Pruppacher, 1976) 5439 diff_coeff = 0.211E-4_wp * ( t_int / 273.15_wp )**1.94_wp * & 5440 ( 101325.0_wp / hyp(k) ) 5273 diff_coeff = 0.211E-4_wp * ( t_int / 273.15_wp )**1.94_wp * ( 101325.0_wp / hyp(k) ) 5441 5274 ! 5442 5275 !-- Lengthscale for gas-kinetic effects (from Mordy, 1959, p. 23): … … 5445 5278 !-- Calculate effects of heat conductivity and diffusion of water vapor on the 5446 5279 !-- diffusional growth process (usually known as 1.0 / (F_k + F_d) ) 5447 ddenom = 1.0_wp / ( rho_l * r_v * t_int / ( e_s * diff_coeff ) + &5448 ( l_v / ( r_v * t_int ) - 1.0_wp ) * rho_l * &5449 l_v / ( thermal_conductivity * t_int ) &5280 ddenom = 1.0_wp / ( rho_l * r_v * t_int / ( e_s * diff_coeff ) + & 5281 ( l_v / ( r_v * t_int ) - 1.0_wp ) * rho_l * & 5282 l_v / ( thermal_conductivity * t_int ) & 5450 5283 ) 5451 5284 new_r = 0.0_wp … … 5458 5291 !-- Terminal velocity is computed for vertical direction (Rogers et al., 5459 5292 !-- 1993, J. Appl. Meteorol.) 5460 diameter = particles(n)%radius * 2000.0_wp !diameter in mm5293 diameter = particles(n)%radius * 2000.0_wp !diameter in mm 5461 5294 IF ( diameter <= d0_rog ) THEN 5462 5295 w_s = k_cap_rog * diameter * ( 1.0_wp - EXP( -k_low_rog * diameter ) ) … … 5476 5309 ELSE 5477 5310 ! 5478 !-- For small droplets or in supersaturated environments, the ventilation 5479 !-- effect does not play a role5311 !-- For small droplets or in supersaturated environments, the ventilation effect does not play 5312 !-- a role. 5480 5313 ventilation_effect(n) = 1.0_wp 5481 5314 ENDIF … … 5484 5317 IF( .NOT. curvature_solution_effects ) THEN 5485 5318 ! 5486 !-- Use analytic model for diffusional growth including gas-kinetic 5487 !-- effects (Mordy, 1959) butwithout the impact of aerosols.5319 !-- Use analytic model for diffusional growth including gas-kinetic effects (Mordy, 1959) but 5320 !-- without the impact of aerosols. 5488 5321 DO n = 1, number_of_particles 5489 arg = ( particles(n)%radius + r0 )**2 + 2.0_wp * dt_3d * ddenom * &5490 ventilation_effect(n) *&5322 arg = ( particles(n)%radius + r0 )**2 + 2.0_wp * dt_3d * ddenom * & 5323 ventilation_effect(n) * & 5491 5324 ( e_a / e_s - 1.0_wp ) 5492 5325 arg = MAX( arg, ( 0.01E-6 + r0 )**2 ) … … 5508 5341 ! 5509 5342 !-- Solute effect (bfactor) 5510 bfactor = vanthoff * rho_s * particles(n)%aux1**3 * &5343 bfactor = vanthoff * rho_s * particles(n)%aux1**3 * & 5511 5344 molecular_weight_of_water / ( rho_l * molecular_weight_of_solute ) 5512 5345 … … 5518 5351 ! 5519 5352 !-- Integrate growth equation using a 2nd-order Rosenbrock method 5520 !-- (see Verwer et al., 1999, Eq. (3.2)). The Rosenbrock method adjusts 5521 !-- its with internaltimestep to minimize the local truncation error.5353 !-- (see Verwer et al., 1999, Eq. (3.2)). The Rosenbrock method adjusts its with internal 5354 !-- timestep to minimize the local truncation error. 5522 5355 DO WHILE ( dt_ros_sum < dt_3d ) 5523 5356 … … 5526 5359 DO 5527 5360 5528 drdt = ddenom * ventilation_effect(n) * ( e_a / e_s - 1.0_wp - &5529 afactor / r_ros + &5530 bfactor / r_ros**3 &5361 drdt = ddenom * ventilation_effect(n) * ( e_a / e_s - 1.0_wp - & 5362 afactor / r_ros + & 5363 bfactor / r_ros**3 & 5531 5364 ) / ( r_ros + r0 ) 5532 5365 5533 d2rdtdr = -ddenom * ventilation_effect(n) * (&5534 ( e_a / e_s - 1.0_wp ) * r_ros**4 -&5535 afactor * r0 * r_ros**2 - &5536 2.0_wp * afactor * r_ros**3 + &5537 3.0_wp * bfactor * r0 + &5538 4.0_wp * bfactor * r_ros &5539 )&5366 d2rdtdr = -ddenom * ventilation_effect(n) * ( & 5367 ( e_a / e_s - 1.0_wp ) * r_ros**4 - & 5368 afactor * r0 * r_ros**2 - & 5369 2.0_wp * afactor * r_ros**3 + & 5370 3.0_wp * bfactor * r0 + & 5371 4.0_wp * bfactor * r_ros & 5372 ) & 5540 5373 / ( r_ros**4 * ( r_ros + r0 )**2 ) 5541 5374 … … 5545 5378 r_err = r_ros 5546 5379 5547 drdt = ddenom * ventilation_effect(n) * ( e_a / e_s - 1.0_wp - &5548 afactor / r_ros + &5549 bfactor / r_ros**3 &5380 drdt = ddenom * ventilation_effect(n) * ( e_a / e_s - 1.0_wp - & 5381 afactor / r_ros + & 5382 bfactor / r_ros**3 & 5550 5383 ) / ( r_ros + r0 ) 5551 5384 5552 k2 = ( drdt - dt_ros * 2.0 * gamma * d2rdtdr * k1 ) / &5385 k2 = ( drdt - dt_ros * 2.0 * gamma * d2rdtdr * k1 ) / & 5553 5386 ( 1.0_wp - dt_ros * gamma * d2rdtdr ) 5554 5387 5555 5388 r_ros = MAX(r_ros_ini + dt_ros * ( 1.5_wp * k1 + 0.5_wp * k2), particles(n)%aux1) 5556 5557 !--Check error of the solution, and reduce dt_ros if necessary.5389 ! 5390 !-- Check error of the solution, and reduce dt_ros if necessary. 5558 5391 error = ABS(r_err - r_ros) / r_ros 5559 5392 IF ( error > prec ) THEN … … 5569 5402 END DO 5570 5403 5571 END DO !Rosenbrock loop5404 END DO !Rosenbrock loop 5572 5405 ! 5573 5406 !-- Store new particle radius … … 5583 5416 DO n = 1, number_of_particles 5584 5417 ! 5585 !-- Sum up the change in liquid water for the respective grid 5586 !-- box for the computation of the release/depletion of water vapor 5587 !-- and heat. 5588 ql_c(k,j,i) = ql_c(k,j,i) + particles(n)%weight_factor * & 5589 rho_l * 1.33333333_wp * pi * & 5590 ( new_r(n)**3 - particles(n)%radius**3 ) / & 5418 !-- Sum up the change in liquid water for the respective grid box for the computation of the 5419 !-- release/depletion of water vapor and heat. 5420 ql_c(k,j,i) = ql_c(k,j,i) + particles(n)%weight_factor * & 5421 rho_l * 1.33333333_wp * pi * & 5422 ( new_r(n)**3 - particles(n)%radius**3 ) / & 5591 5423 ( rho_surface * dx * dy * dzw(k) ) 5592 5424 ! 5593 !-- Check if the increase in liqid water is not too big. If this is the case, 5594 !-- the model timestepmight be too long.5425 !-- Check if the increase in liqid water is not too big. If this is the case, the model timestep 5426 !-- might be too long. 5595 5427 IF ( ql_c(k,j,i) > 100.0_wp ) THEN 5596 WRITE( message_string, * ) 'k=',k,' j=',j,' i=',i, &5597 ' ql_c=',ql_c(k,j,i), '&part(',n,')%wf=',&5598 particles(n)%weight_factor,' delta_r=',delta_r5428 WRITE( message_string, * ) 'k=',k,' j=',j,' i=',i, & 5429 ' ql_c=',ql_c(k,j,i), '&part(',n,')%wf=', & 5430 particles(n)%weight_factor,' delta_r=',delta_r 5599 5431 CALL message( 'lpm_droplet_condensation', 'PA0143', 2, 2, -1, 6, 1 ) 5600 5432 ENDIF 5601 5433 ! 5602 !-- Check if the change in the droplet radius is not too big. If this is the 5603 !-- case, the modeltimestep might be too long.5434 !-- Check if the change in the droplet radius is not too big. If this is the case, the model 5435 !-- timestep might be too long. 5604 5436 delta_r = new_r(n) - particles(n)%radius 5605 5437 IF ( delta_r < 0.0_wp .AND. new_r(n) < 0.0_wp ) THEN 5606 WRITE( message_string, * ) '#1 k=',k,' j=',j,' i=',i, &5607 ' e_s=',e_s, ' e_a=',e_a,' t_int=',t_int,&5608 '&delta_r=',delta_r,&5609 ' particle_radius=',particles(n)%radius5438 WRITE( message_string, * ) '#1 k=',k,' j=',j,' i=',i, & 5439 ' e_s=',e_s, ' e_a=',e_a,' t_int=',t_int, & 5440 '&delta_r=',delta_r, & 5441 ' particle_radius=',particles(n)%radius 5610 5442 CALL message( 'lpm_droplet_condensation', 'PA0144', 2, 2, -1, 6, 1 ) 5611 5443 ENDIF 5612 5444 ! 5613 !-- Sum up the total volume of liquid water (needed below for 5614 !-- re-calculating the weightingfactors)5445 !-- Sum up the total volume of liquid water (needed below for re-calculating the weighting 5446 !-- factors) 5615 5447 ql_v(k,j,i) = ql_v(k,j,i) + particles(n)%weight_factor * new_r(n)**3 5616 5448 ! 5617 5449 !-- Determine radius class of the particle needed for collision 5618 5450 IF ( use_kernel_tables ) THEN 5619 particles(n)%class = ( LOG( new_r(n) ) - rclass_lbound ) / & 5620 ( rclass_ubound - rclass_lbound ) * & 5621 radius_classes 5451 particles(n)%class = ( LOG( new_r(n) ) - rclass_lbound ) / & 5452 ( rclass_ubound - rclass_lbound ) * radius_classes 5622 5453 particles(n)%class = MIN( particles(n)%class, radius_classes ) 5623 5454 particles(n)%class = MAX( particles(n)%class, 1 ) … … 5635 5466 5636 5467 5637 !------------------------------------------------------------------------------ !5468 !--------------------------------------------------------------------------------------------------! 5638 5469 ! Description: 5639 5470 ! ------------ 5640 !> Release of latent heat and change of mixing ratio due to condensation / 5641 !> evaporation of droplets. 5642 !------------------------------------------------------------------------------! 5471 !> Release of latent heat and change of mixing ratio due to condensation / evaporation of droplets. 5472 !--------------------------------------------------------------------------------------------------! 5643 5473 SUBROUTINE lpm_interaction_droplets_ptq 5644 5474 … … 5657 5487 5658 5488 q(k,j,i) = q(k,j,i) - ql_c(k,j,i) * flag 5659 pt(k,j,i) = pt(k,j,i) + lv_d_cp * ql_c(k,j,i) * d_exner(k) & 5660 * flag 5489 pt(k,j,i) = pt(k,j,i) + lv_d_cp * ql_c(k,j,i) * d_exner(k) * flag 5661 5490 ENDDO 5662 5491 ENDDO … … 5666 5495 5667 5496 5668 !------------------------------------------------------------------------------ !5497 !--------------------------------------------------------------------------------------------------! 5669 5498 ! Description: 5670 5499 ! ------------ 5671 !> Release of latent heat and change of mixing ratio due to condensation / 5672 !> evaporation of droplets.Call for grid point i,j5673 !------------------------------------------------------------------------------ !5500 !> Release of latent heat and change of mixing ratio due to condensation / evaporation of droplets. 5501 !> Call for grid point i,j 5502 !--------------------------------------------------------------------------------------------------! 5674 5503 SUBROUTINE lpm_interaction_droplets_ptq_ij( i, j ) 5675 5504 … … 5693 5522 5694 5523 5695 !------------------------------------------------------------------------------ !5524 !--------------------------------------------------------------------------------------------------! 5696 5525 ! Description: 5697 5526 ! ------------ 5698 5527 !> Calculate the liquid water content for each grid box. 5699 !------------------------------------------------------------------------------ !5528 !--------------------------------------------------------------------------------------------------! 5700 5529 SUBROUTINE lpm_calc_liquid_water_content 5701 5530 … … 5721 5550 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 5722 5551 ! 5723 !-- Calculate the total volume in the boxes (ql_v, weighting factor 5724 !-- has to beincluded) 5552 !-- Calculate the total volume in the boxes (ql_v, weighting factor has to beincluded) 5725 5553 DO n = 1, prt_count(k,j,i) 5726 ql_v(k,j,i) = ql_v(k,j,i) + particles(n)%weight_factor * & 5727 particles(n)%radius**3 5554 ql_v(k,j,i) = ql_v(k,j,i) + particles(n)%weight_factor * particles(n)%radius**3 5728 5555 ENDDO 5729 5556 ! 5730 5557 !-- Calculate the liquid water content 5731 5558 IF ( ql_v(k,j,i) /= 0.0_wp ) THEN 5732 ql(k,j,i) = ql(k,j,i) + rho_l * 1.33333333_wp * pi * & 5733 ql_v(k,j,i) / & 5734 ( rho_surface * dx * dy * dzw(k) ) 5559 ql(k,j,i) = ql(k,j,i) + rho_l * 1.33333333_wp * pi * & 5560 ql_v(k,j,i) / ( rho_surface * dx * dy * dzw(k) ) 5735 5561 IF ( ql(k,j,i) < 0.0_wp ) THEN 5736 WRITE( message_string, * ) 'LWC out of range: ' , & 5737 ql(k,j,i),i,j,k 5738 CALL message( 'lpm_calc_liquid_water_content', 'PA0719', & 5739 2, 2, -1, 6, 1 ) 5562 WRITE( message_string, * ) 'LWC out of range: ' , ql(k,j,i),i,j,k 5563 CALL message( 'lpm_calc_liquid_water_content', 'PA0719', 2, 2, -1, 6, 1 ) 5740 5564 ENDIF 5741 5565 ELSE … … 5751 5575 5752 5576 5753 !------------------------------------------------------------------------------ !5577 !--------------------------------------------------------------------------------------------------! 5754 5578 ! Description: 5755 5579 ! ------------ 5756 !> Calculates change in droplet radius by collision. Droplet collision is 5757 !> calculated for each grid box seperately. Collision is parameterized by 5758 !> using collision kernels. Two different kernels are available: 5759 !> Hall kernel: Kernel from Hall (1980, J. Atmos. Sci., 2486-2507), which 5760 !> considers collision due to pure gravitational effects. 5761 !> Wang kernel: Beside gravitational effects (treated with the Hall-kernel) also 5762 !> the effects of turbulence on the collision are considered using 5763 !> parameterizations of Ayala et al. (2008, New J. Phys., 10, 5764 !> 075015) and Wang and Grabowski (2009, Atmos. Sci. Lett., 10, 5765 !> 1-8). This kernel includes three possible effects of turbulence: 5580 !> Calculates change in droplet radius by collision. Droplet collision is calculated for each grid 5581 !> box seperately. Collision is parameterized by using collision kernels. Two different kernels are 5582 !> available: 5583 !> Hall kernel: Kernel from Hall (1980, J. Atmos. Sci., 2486-2507), which considers collision due to 5584 !> pure gravitational effects. 5585 !> Wang kernel: Beside gravitational effects (treated with the Hall-kernel) also the effects of 5586 !> turbulence on the collision are considered using parameterizations of Ayala et al. 5587 !> (2008, New J. Phys., 10, 075015) and Wang and Grabowski (2009, Atmos. Sci. Lett., 5588 !> 10, 1-8). This kernel includes three possible effects of turbulence: 5766 5589 !> the modification of the relative velocity between the droplets, 5767 !> the effect of preferential concentration, and the enhancement of5768 !> collision efficiencies.5769 !------------------------------------------------------------------------------ !5590 !> the effect of preferential concentration, 5591 !> and the enhancement of collision efficiencies. 5592 !--------------------------------------------------------------------------------------------------! 5770 5593 SUBROUTINE lpm_droplet_collision (i,j,k) 5771 5594 … … 5789 5612 REAL(wp) :: xsn !< aerosol mass of super-droplet n 5790 5613 5614 REAL(wp), DIMENSION(:), ALLOCATABLE :: aero_mass !< total aerosol mass of super droplet 5615 REAL(wp), DIMENSION(:), ALLOCATABLE :: mass !< total mass of super droplet 5791 5616 REAL(wp), DIMENSION(:), ALLOCATABLE :: weight !< weighting factor 5792 REAL(wp), DIMENSION(:), ALLOCATABLE :: mass !< total mass of super droplet5793 REAL(wp), DIMENSION(:), ALLOCATABLE :: aero_mass !< total aerosol mass of super droplet5794 5617 5795 5618 CALL cpu_log( log_point_s(43), 'lpm_droplet_coll', 'start' ) … … 5804 5627 IF ( use_kernel_tables ) THEN 5805 5628 ! 5806 !-- Fast method with pre-calculated collection kernels for 5807 !-- dis crete radius- and dissipation-classes.5629 !-- Fast method with pre-calculated collection kernels for discrete radius- and 5630 !-- dissipation-classes. 5808 5631 IF ( wang_kernel ) THEN 5809 eclass = INT( diss(k,j,i) * 1.0E4_wp / 600.0_wp * & 5810 dissipation_classes ) + 1 5632 eclass = INT( diss(k,j,i) * 1.0E4_wp / 600.0_wp * dissipation_classes ) + 1 5811 5633 epsilon_collision = diss(k,j,i) 5812 5634 ELSE … … 5822 5644 ELSE 5823 5645 ! 5824 !-- Collection kernels are re-calculated for every new 5825 !-- grid box. First, allocate memory for kernel table. 5826 !-- Third dimension is 1, because table is re-calculated for 5827 !-- every new dissipation value. 5646 !-- Collection kernels are re-calculated for every new grid box. First, allocate memory for 5647 !-- kernel table. 5648 !-- Third dimension is 1, because table is re-calculated for every new dissipation value. 5828 5649 ALLOCATE( ckernel(1:number_of_particles,1:number_of_particles,1:1) ) 5829 5650 ! 5830 !-- Now calculate collection kernel for this box. Note that 5831 !-- the kernel is based on theprevious time step5651 !-- Now calculate collection kernel for this box. Note that the kernel is based on the 5652 !-- previous time step 5832 5653 CALL recalculate_kernel( i, j, k ) 5833 5654 5834 5655 ENDIF 5835 5656 ! 5836 !-- Temporary fields for total mass of super-droplet, aerosol mass, and 5837 !-- weighting factor areallocated.5657 !-- Temporary fields for total mass of super-droplet, aerosol mass, and weighting factor are 5658 !-- allocated. 5838 5659 ALLOCATE(mass(1:number_of_particles), weight(1:number_of_particles)) 5839 5660 IF ( curvature_solution_effects ) ALLOCATE(aero_mass(1:number_of_particles)) 5840 5661 5841 mass(1:number_of_particles) = particles(1:number_of_particles)%weight_factor * &5842 particles(1:number_of_particles)%radius**3 * &5662 mass(1:number_of_particles) = particles(1:number_of_particles)%weight_factor * & 5663 particles(1:number_of_particles)%radius**3 * & 5843 5664 factor_volume_to_mass 5844 5665 … … 5846 5667 5847 5668 IF ( curvature_solution_effects ) THEN 5848 aero_mass(1:number_of_particles) = particles(1:number_of_particles)%weight_factor * &5849 particles(1:number_of_particles)%aux1**3 * &5669 aero_mass(1:number_of_particles) = particles(1:number_of_particles)%weight_factor * & 5670 particles(1:number_of_particles)%aux1**3 * & 5850 5671 4.0_wp / 3.0_wp * pi * rho_s 5851 5672 ENDIF … … 5856 5677 DO m = n, number_of_particles 5857 5678 ! 5858 !-- For collisions, the weighting factor of at least one super-droplet 5859 !-- needs to be largeror equal to one.5679 !-- For collisions, the weighting factor of at least one super-droplet needs to be larger 5680 !-- or equal to one. 5860 5681 IF ( MIN( weight(n), weight(m) ) < 1.0_wp ) CYCLE 5861 5682 ! … … 5873 5694 rclass_s = particles(m)%class 5874 5695 5875 collection_probability = MAX( weight(n), weight(m) ) * &5696 collection_probability = MAX( weight(n), weight(m) ) * & 5876 5697 ckernel(rclass_l,rclass_s,eclass) * ddV * dt_3d 5877 5698 ELSE 5878 collection_probability = MAX( weight(n), weight(m) ) * &5699 collection_probability = MAX( weight(n), weight(m) ) * & 5879 5700 ckernel(n,m,1) * ddV * dt_3d 5880 5701 ENDIF … … 5883 5704 !-- (Accordingly, p_crit will be 0.0, 1.0, 2.0, ...) 5884 5705 CALL random_number_parallel( random_dummy ) 5885 IF ( collection_probability - FLOOR(collection_probability) & 5886 > random_dummy ) THEN 5706 IF ( collection_probability - FLOOR(collection_probability) > random_dummy ) THEN 5887 5707 collection_probability = FLOOR(collection_probability) + 1.0_wp 5888 5708 ELSE … … 5919 5739 !-- particle m collects 1/2 weight(m) droplets of particle n. 5920 5740 !-- The total mass mass changes accordingly. 5921 !-- If n = m, the first half of the droplets coalesces with the 5922 !-- second half of the droplets; mass is unchanged because 5923 !-- xm = xn for n = m. 5741 !-- If n = m, the first half of the droplets coalesces with the second half of the 5742 !-- droplets; mass is unchanged because xm = xn for n = m. 5924 5743 !-- 5925 !-- Note: For m = n this equation is an approximation only 5926 !-- valid for weight >> 1 (which is usually the case). The 5927 !-- approximation is weight(n)-1 = weight(n). 5744 !-- Note: For m = n this equation is an approximation only valid for weight >> 1 5745 !-- (which is usually the case). The approximation is weight(n)-1 = weight(n). 5928 5746 mass(n) = mass(n) + 0.5_wp * weight(n) * ( xm - xn ) 5929 5747 mass(m) = mass(m) + 0.5_wp * weight(m) * ( xn - xm ) … … 5947 5765 IF ( ANY(weight < 0.0_wp) ) THEN 5948 5766 WRITE( message_string, * ) 'negative weighting factor' 5949 CALL message( 'lpm_droplet_collision', 'PA0028', & 5950 2, 2, -1, 6, 1 ) 5767 CALL message( 'lpm_droplet_collision', 'PA0028', 2, 2, -1, 6, 1 ) 5951 5768 ENDIF 5952 5769 5953 particles(1:number_of_particles)%radius = ( mass(1:number_of_particles) / &5954 ( weight(1:number_of_particles)&5955 * factor_volume_to_mass&5956 )&5770 particles(1:number_of_particles)%radius = ( mass(1:number_of_particles) / & 5771 ( weight(1:number_of_particles) & 5772 * factor_volume_to_mass & 5773 ) & 5957 5774 )**0.33333333333333_wp 5958 5775 5959 5776 IF ( curvature_solution_effects ) THEN 5960 particles(1:number_of_particles)%aux1 = ( aero_mass(1:number_of_particles) / &5961 ( weight(1:number_of_particles)&5962 * 4.0_wp / 3.0_wp * pi * rho_s&5963 )&5777 particles(1:number_of_particles)%aux1 = ( aero_mass(1:number_of_particles) / & 5778 ( weight(1:number_of_particles) & 5779 * 4.0_wp / 3.0_wp * pi * rho_s & 5780 ) & 5964 5781 )**0.33333333333333_wp 5965 5782 ENDIF … … 5974 5791 !-- Check if LWC is conserved during collision process 5975 5792 IF ( ql_v(k,j,i) /= 0.0_wp ) THEN 5976 IF ( ql_vp(k,j,i) / ql_v(k,j,i) >= 1.0001_wp .OR. &5793 IF ( ql_vp(k,j,i) / ql_v(k,j,i) >= 1.0001_wp .OR. & 5977 5794 ql_vp(k,j,i) / ql_v(k,j,i) <= 0.9999_wp ) THEN 5978 WRITE( message_string, * ) ' LWC is not conserved during', & 5979 ' collision! ', & 5980 ' LWC after condensation: ', ql_v(k,j,i), & 5795 WRITE( message_string, * ) ' LWC is not conserved during',' collision! ', & 5796 ' LWC after condensation: ', ql_v(k,j,i), & 5981 5797 ' LWC after collision: ', ql_vp(k,j,i) 5982 5798 CALL message( 'lpm_droplet_collision', 'PA0040', 2, 2, -1, 6, 1 ) … … 5989 5805 5990 5806 END SUBROUTINE lpm_droplet_collision 5991 5992 !------------------------------------------------------------------------------ !5807 5808 !--------------------------------------------------------------------------------------------------! 5993 5809 ! Description: 5994 5810 ! ------------ 5995 !> Initialization of the collision efficiency matrix with fixed radius and 5996 !> dissipation classes,calculated at simulation start only.5997 !------------------------------------------------------------------------------ !5811 !> Initialization of the collision efficiency matrix with fixed radius and dissipation classes, 5812 !> calculated at simulation start only. 5813 !--------------------------------------------------------------------------------------------------! 5998 5814 SUBROUTINE lpm_init_kernels 5999 5815 … … 6001 5817 INTEGER(iwp) :: j !< 6002 5818 INTEGER(iwp) :: k !< 6003 6004 ! 6005 !-- Calculate collision efficiencies for fixed radius- and dissipation 6006 !-- classes 5819 5820 ! 5821 !-- Calculate collision efficiencies for fixed radius- and dissipation classes 6007 5822 IF ( collision_kernel(6:9) == 'fast' ) THEN 6008 5823 6009 ALLOCATE( ckernel(1:radius_classes,1:radius_classes, &6010 0:dissipation_classes), epsclass(1:dissipation_classes),&5824 ALLOCATE( ckernel(1:radius_classes,1:radius_classes,0:dissipation_classes), & 5825 epsclass(1:dissipation_classes), & 6011 5826 radclass(1:radius_classes) ) 6012 5827 6013 5828 ! 6014 !-- Calculate the radius class bounds with logarithmic distances 6015 !-- in the interval[1.0E-6, 1000.0E-6] m5829 !-- Calculate the radius class bounds with logarithmic distances in the interval 5830 !-- [1.0E-6, 1000.0E-6] m 6016 5831 rclass_lbound = LOG( 1.0E-6_wp ) 6017 5832 rclass_ubound = LOG( 1000.0E-6_wp ) 6018 5833 radclass(1) = EXP( rclass_lbound ) 6019 5834 DO i = 2, radius_classes 6020 radclass(i) = EXP( rclass_lbound + &6021 ( rclass_ubound - rclass_lbound ) * &5835 radclass(i) = EXP( rclass_lbound + & 5836 ( rclass_ubound - rclass_lbound ) * & 6022 5837 ( i - 1.0_wp ) / ( radius_classes - 1.0_wp ) ) 6023 5838 ENDDO … … 6030 5845 ! 6031 5846 !-- Calculate collision efficiencies of the Wang/ayala kernel 6032 ALLOCATE( ec(1:radius_classes,1:radius_classes), &6033 ecf(1:radius_classes,1:radius_classes), &6034 gck(1:radius_classes,1:radius_classes), &5847 ALLOCATE( ec(1:radius_classes,1:radius_classes), & 5848 ecf(1:radius_classes,1:radius_classes), & 5849 gck(1:radius_classes,1:radius_classes), & 6035 5850 winf(1:radius_classes) ) 6036 5851 … … 6054 5869 ! 6055 5870 !-- Calculate collision efficiencies of the Hall kernel 6056 ALLOCATE( hkernel(1:radius_classes,1:radius_classes), &5871 ALLOCATE( hkernel(1:radius_classes,1:radius_classes), & 6057 5872 hwratio(1:radius_classes,1:radius_classes) ) 6058 5873 … … 6062 5877 DO j = 1, radius_classes 6063 5878 DO i = 1, radius_classes 6064 hkernel(i,j) = pi * ( radclass(j) + radclass(i) )**2 &5879 hkernel(i,j) = pi * ( radclass(j) + radclass(i) )**2 & 6065 5880 * ec(i,j) * ABS( winf(j) - winf(i) ) 6066 5881 ckernel(i,j,0) = hkernel(i,j) ! hall kernel stored on index 0 … … 6072 5887 IF ( j == -1 ) THEN 6073 5888 PRINT*, '*** Hall kernel' 6074 WRITE ( *,'(5X,20(F4.0,1X))' ) ( radclass(i)*1.0E6_wp, & 6075 i = 1,radius_classes ) 5889 WRITE ( *,'(5X,20(F4.0,1X))' ) ( radclass(i)*1.0E6_wp, i = 1,radius_classes ) 6076 5890 DO j = 1, radius_classes 6077 WRITE ( *,'(F4.0,1X,20(F8.4,1X))' ) radclass(j), & 6078 ( hkernel(i,j), i = 1,radius_classes ) 5891 WRITE ( *,'(F4.0,1X,20(F8.4,1X))' ) radclass(j), ( hkernel(i,j), i = 1,radius_classes ) 6079 5892 ENDDO 6080 5893 … … 6091 5904 6092 5905 PRINT*, '*** epsilon = ', epsclass(k) 6093 WRITE ( *,'(5X,20(F4.0,1X))' ) ( radclass(i) * 1.0E6_wp, & 6094 i = 1,radius_classes ) 5906 WRITE ( *,'(5X,20(F4.0,1X))' ) ( radclass(i) * 1.0E6_wp, i = 1,radius_classes ) 6095 5907 DO j = 1, radius_classes 6096 WRITE ( *,'(F4.0,1X,20(F8.4,1X))' ) radclass(j) * 1.0E6_wp, &6097 ( hwratio(i,j), i = 1,radius_classes )5908 WRITE ( *,'(F4.0,1X,20(F8.4,1X))' ) radclass(j) * 1.0E6_wp, & 5909 ( hwratio(i,j), i = 1,radius_classes ) 6098 5910 ENDDO 6099 5911 ENDDO … … 6105 5917 6106 5918 END SUBROUTINE lpm_init_kernels 6107 6108 !------------------------------------------------------------------------------ !5919 5920 !--------------------------------------------------------------------------------------------------! 6109 5921 ! Description: 6110 5922 ! ------------ 6111 5923 !> Calculation of collision kernels during each timestep and for each grid box 6112 !------------------------------------------------------------------------------ !5924 !--------------------------------------------------------------------------------------------------! 6113 5925 SUBROUTINE recalculate_kernel( i1, j1, k1 ) 6114 5926 … … 6123 5935 number_of_particles = prt_count(k1,j1,i1) 6124 5936 radius_classes = number_of_particles ! necessary to use the same 6125 ! subroutines as for 5937 ! subroutines as for 6126 5938 ! precalculated kernels 6127 5939 6128 ALLOCATE( ec(1:number_of_particles,1:number_of_particles), &5940 ALLOCATE( ec(1:number_of_particles,1:number_of_particles), & 6129 5941 radclass(1:number_of_particles), winf(1:number_of_particles) ) 6130 5942 … … 6143 5955 ! 6144 5956 !-- Call routines to calculate efficiencies for the Wang kernel 6145 ALLOCATE( gck(1:number_of_particles,1:number_of_particles), &5957 ALLOCATE( gck(1:number_of_particles,1:number_of_particles), & 6146 5958 ecf(1:number_of_particles,1:number_of_particles) ) 6147 5959 … … 6165 5977 DO j = 1, number_of_particles 6166 5978 DO i = 1, number_of_particles 6167 ckernel(i,j,1) = pi * ( radclass(j) + radclass(i) )**2 &5979 ckernel(i,j,1) = pi * ( radclass(j) + radclass(i) )**2 & 6168 5980 * ec(i,j) * ABS( winf(j) - winf(i) ) 6169 5981 ENDDO … … 6175 5987 END SUBROUTINE recalculate_kernel 6176 5988 6177 !------------------------------------------------------------------------------ !5989 !--------------------------------------------------------------------------------------------------! 6178 5990 ! Description: 6179 5991 ! ------------ 6180 !> Calculation of effects of turbulence on the geometric collision kernel 6181 !> (by including the droplets' average radial relative velocities and their 6182 !> radial distribution function) following the analytic model by Aayala et al. 6183 !> (2008, New J. Phys.). For details check the second part 2 of the publication, 6184 !> page 37ff. 5992 !> Calculation of effects of turbulence on the geometric collision kernel (by including the 5993 !> droplets' average radial relative velocities and their radial distribution function) following 5994 !> the analytic model by Aayala et al. (2008, New J. Phys.). For details check the second part 2 of 5995 !> the publication, page 37ff. 6185 5996 !> 6186 !> Input parameters, which need to be replaced by PALM parameters: 6187 !> water density, air density 6188 !------------------------------------------------------------------------------! 5997 !> Input parameters, which need to be replaced by PALM parameters: water density, air density 5998 !--------------------------------------------------------------------------------------------------! 6189 5999 SUBROUTINE turbsd 6190 6000 … … 6284 6094 t2 = tau(j) 6285 6095 6286 v1xysq = b1 * d1 * phi_w(c1,e1,v1,t1) - b1 * d2 * phi_w(c1,e2,v1,t1)&6287 - b2 * d1 * phi_w(c2,e1,v1,t1) + b2 * d2 * phi_w(c2,e2,v1,t1)6096 v1xysq = b1 * d1 * phi_w(c1,e1,v1,t1) - b1 * d2 * phi_w(c1,e2,v1,t1) & 6097 - b2 * d1 * phi_w(c2,e1,v1,t1) + b2 * d2 * phi_w(c2,e2,v1,t1) 6288 6098 v1xysq = v1xysq * urms**2 / t1 6289 6099 vrms1xy = SQRT( v1xysq ) 6290 6100 6291 v2xysq = b1 * d1 * phi_w(c1,e1,v2,t2) - b1 * d2 * phi_w(c1,e2,v2,t2)&6292 - b2 * d1 * phi_w(c2,e1,v2,t2) + b2 * d2 * phi_w(c2,e2,v2,t2)6101 v2xysq = b1 * d1 * phi_w(c1,e1,v2,t2) - b1 * d2 * phi_w(c1,e2,v2,t2) & 6102 - b2 * d1 * phi_w(c2,e1,v2,t2) + b2 * d2 * phi_w(c2,e2,v2,t2) 6293 6103 v2xysq = v2xysq * urms**2 / t2 6294 6104 vrms2xy = SQRT( v2xysq ) … … 6306 6116 ENDIF 6307 6117 6308 v1v2xy = b1 * d1 * zhi(c1,e1,v1,t1,v2,t2) - &6309 b1 * d2 * zhi(c1,e2,v1,t1,v2,t2) - &6310 b2 * d1 * zhi(c2,e1,v1,t1,v2,t2) + &6118 v1v2xy = b1 * d1 * zhi(c1,e1,v1,t1,v2,t2) - & 6119 b1 * d2 * zhi(c1,e2,v1,t1,v2,t2) - & 6120 b2 * d1 * zhi(c2,e1,v1,t1,v2,t2) + & 6311 6121 b2 * d2* zhi(c2,e2,v1,t1,v2,t2) 6312 6122 fr = d1 * EXP( -rrp / e1 ) - d2 * EXP( -rrp / e2 ) … … 6325 6135 ENDIF 6326 6136 6327 xx = -0.1988_wp * sst**4 + 1.5275_wp * sst**3 - 4.2942_wp * & 6328 sst**2 + 5.3406_wp * sst 6137 xx = -0.1988_wp * sst**4 + 1.5275_wp * sst**3 - 4.2942_wp * sst**2 + 5.3406_wp * sst 6329 6138 IF ( xx < 0.0_wp ) xx = 0.0_wp 6330 6139 yy = 0.1886_wp * EXP( 20.306_wp / lambda_re ) … … 6340 6149 6341 6150 ! 6342 !-- Calculate general collection kernel (without the consideration of 6343 !-- collection efficiencies) 6151 !-- Calculate general collection kernel (without the consideration of collection efficiencies) 6344 6152 gck(i,j) = 2.0_wp * pi * rrp**2 * wrfin * grfin 6345 6153 gck(j,i) = gck(i,j) … … 6352 6160 REAL(wp) FUNCTION phi_w( a, b, vsett, tau0 ) 6353 6161 ! 6354 !-- Function used in the Ayala et al. (2008) analytical model for turbulent 6355 !-- effects on thecollision kernel6356 6162 !-- Function used in the Ayala et al. (2008) analytical model for turbulent effects on the 6163 !-- collision kernel 6164 6357 6165 6358 6166 REAL(wp) :: a !< … … 6369 6177 REAL(wp) FUNCTION zhi( a, b, vsett1, tau1, vsett2, tau2 ) 6370 6178 ! 6371 !-- Function used in the Ayala et al. (2008) analytical model for turbulent 6372 !-- effects on the collisionkernel6179 !-- Function used in the Ayala et al. (2008) analytical model for turbulent effects on the collision 6180 !-- kernel 6373 6181 6374 6182 REAL(wp) :: a !< … … 6390 6198 aa4 = ( vsett2 / b )**2 - ( 1.0_wp / tau2 + 1.0_wp / a )**2 6391 6199 aa5 = vsett2 / b + 1.0_wp / tau2 + 1.0_wp / a 6392 aa6 = 1.0_wp / tau1 - 1.0_wp / a + ( 1.0_wp / tau2 + 1.0_wp / a) * & 6393 vsett1 / vsett2 6394 zhi = (1.0_wp / aa1 - 1.0_wp / aa2 ) * ( vsett1 - vsett2 ) * 0.5_wp / & 6395 b / aa3**2 + ( 4.0_wp / aa4 - 1.0_wp / aa5**2 - 1.0_wp / aa1**2 ) & 6396 * vsett2 * 0.5_wp / b /aa6 + ( 2.0_wp * ( b / aa2 - b / aa1 ) - & 6200 aa6 = 1.0_wp / tau1 - 1.0_wp / a + ( 1.0_wp / tau2 + 1.0_wp / a) * vsett1 / vsett2 6201 zhi = ( 1.0_wp / aa1 - 1.0_wp / aa2 ) * ( vsett1 - vsett2 ) * 0.5_wp / & 6202 b / aa3**2 + ( 4.0_wp / aa4 - 1.0_wp / aa5**2 - 1.0_wp / aa1**2 ) & 6203 * vsett2 * 0.5_wp / b /aa6 + ( 2.0_wp * ( b / aa2 - b / aa1 ) - & 6397 6204 vsett1 / aa2**2 + vsett2 / aa1**2 ) * 0.5_wp / b / aa3 6398 6205 … … 6400 6207 6401 6208 6402 !------------------------------------------------------------------------------ !6209 !--------------------------------------------------------------------------------------------------! 6403 6210 ! Description: 6404 6211 ! ------------ 6405 !> Parameterization of terminal velocity following Rogers et al. (1993, J. Appl. 6406 !> Meteorol.) 6407 !------------------------------------------------------------------------------! 6212 !> Parameterization of terminal velocity following Rogers et al. (1993, J. Appl.Meteorol.) 6213 !--------------------------------------------------------------------------------------------------! 6408 6214 SUBROUTINE fallg 6409 6215 6410 6216 INTEGER(iwp) :: j !< 6411 6217 6412 REAL(wp), PARAMETER :: k_cap_rog = 4.0_wp !< parameter6413 REAL(wp), PARAMETER :: k_low_rog = 12.0_wp !< parameter6414 6218 REAL(wp), PARAMETER :: a_rog = 9.65_wp !< parameter 6415 6219 REAL(wp), PARAMETER :: b_rog = 10.43_wp !< parameter 6416 6220 REAL(wp), PARAMETER :: c_rog = 0.6_wp !< parameter 6417 6221 REAL(wp), PARAMETER :: d0_rog = 0.745_wp !< seperation diameter 6222 REAL(wp), PARAMETER :: k_cap_rog = 4.0_wp !< parameter 6223 REAL(wp), PARAMETER :: k_low_rog = 12.0_wp !< parameter 6418 6224 6419 6225 REAL(wp) :: diameter !< droplet diameter in mm … … 6425 6231 6426 6232 IF ( diameter <= d0_rog ) THEN 6427 winf(j) = k_cap_rog * diameter * ( 1.0_wp - & 6428 EXP( -k_low_rog * diameter ) ) 6233 winf(j) = k_cap_rog * diameter * ( 1.0_wp - EXP( -k_low_rog * diameter ) ) 6429 6234 ELSE 6430 6235 winf(j) = a_rog - b_rog * EXP( -c_rog * diameter ) … … 6436 6241 6437 6242 6438 !------------------------------------------------------------------------------ !6243 !--------------------------------------------------------------------------------------------------! 6439 6244 ! Description: 6440 6245 ! ------------ 6441 6246 !> Interpolation of collision efficiencies (Hall, 1980, J. Atmos. Sci.) 6442 !------------------------------------------------------------------------------ !6247 !--------------------------------------------------------------------------------------------------! 6443 6248 SUBROUTINE effic 6444 6249 6445 6250 INTEGER(iwp) :: i !< 6446 6251 INTEGER(iwp) :: iq !< … … 6460 6265 6461 6266 REAL(wp), DIMENSION(1:21), SAVE :: rat !< 6462 6267 6463 6268 REAL(wp), DIMENSION(1:15), SAVE :: r0 !< 6464 6269 6465 6270 REAL(wp), DIMENSION(1:15,1:21), SAVE :: ecoll !< 6466 6271 … … 6470 6275 6471 6276 first = .FALSE. 6472 r0 = (/ 6.0_wp, 8.0_wp, 10.0_wp, 15.0_wp, 20.0_wp, 25.0_wp, &6473 30.0_wp, 40.0_wp, 50.0_wp, 60.0_wp, 70.0_wp, 100.0_wp, &6277 r0 = (/ 6.0_wp, 8.0_wp, 10.0_wp, 15.0_wp, 20.0_wp, 25.0_wp, & 6278 30.0_wp, 40.0_wp, 50.0_wp, 60.0_wp, 70.0_wp, 100.0_wp, & 6474 6279 150.0_wp, 200.0_wp, 300.0_wp /) 6475 6280 6476 rat = (/ 0.00_wp, 0.05_wp, 0.10_wp, 0.15_wp, 0.20_wp, 0.25_wp, &6477 0.30_wp, 0.35_wp, 0.40_wp, 0.45_wp, 0.50_wp, 0.55_wp, &6478 0.60_wp, 0.65_wp, 0.70_wp, 0.75_wp, 0.80_wp, 0.85_wp, &6281 rat = (/ 0.00_wp, 0.05_wp, 0.10_wp, 0.15_wp, 0.20_wp, 0.25_wp, & 6282 0.30_wp, 0.35_wp, 0.40_wp, 0.45_wp, 0.50_wp, 0.55_wp, & 6283 0.60_wp, 0.65_wp, 0.70_wp, 0.75_wp, 0.80_wp, 0.85_wp, & 6479 6284 0.90_wp, 0.95_wp, 1.00_wp /) 6480 6285 6481 ecoll(:,1) = (/ 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, &6482 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, &6286 ecoll(:,1) = (/ 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, & 6287 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, & 6483 6288 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp, 0.001_wp /) 6484 ecoll(:,2) = (/ 0.003_wp, 0.003_wp, 0.003_wp, 0.004_wp, 0.005_wp, &6485 0.005_wp, 0.005_wp, 0.010_wp, 0.100_wp, 0.050_wp, &6289 ecoll(:,2) = (/ 0.003_wp, 0.003_wp, 0.003_wp, 0.004_wp, 0.005_wp, & 6290 0.005_wp, 0.005_wp, 0.010_wp, 0.100_wp, 0.050_wp, & 6486 6291 0.200_wp, 0.500_wp, 0.770_wp, 0.870_wp, 0.970_wp /) 6487 ecoll(:,3) = (/ 0.007_wp, 0.007_wp, 0.007_wp, 0.008_wp, 0.009_wp, &6488 0.010_wp, 0.010_wp, 0.070_wp, 0.400_wp, 0.430_wp, &6292 ecoll(:,3) = (/ 0.007_wp, 0.007_wp, 0.007_wp, 0.008_wp, 0.009_wp, & 6293 0.010_wp, 0.010_wp, 0.070_wp, 0.400_wp, 0.430_wp, & 6489 6294 0.580_wp, 0.790_wp, 0.930_wp, 0.960_wp, 1.000_wp /) 6490 ecoll(:,4) = (/ 0.009_wp, 0.009_wp, 0.009_wp, 0.012_wp, 0.015_wp, &6491 0.010_wp, 0.020_wp, 0.280_wp, 0.600_wp, 0.640_wp, &6295 ecoll(:,4) = (/ 0.009_wp, 0.009_wp, 0.009_wp, 0.012_wp, 0.015_wp, & 6296 0.010_wp, 0.020_wp, 0.280_wp, 0.600_wp, 0.640_wp, & 6492 6297 0.750_wp, 0.910_wp, 0.970_wp, 0.980_wp, 1.000_wp /) 6493 ecoll(:,5) = (/ 0.014_wp, 0.014_wp, 0.014_wp, 0.015_wp, 0.016_wp, &6494 0.030_wp, 0.060_wp, 0.500_wp, 0.700_wp, 0.770_wp, &6298 ecoll(:,5) = (/ 0.014_wp, 0.014_wp, 0.014_wp, 0.015_wp, 0.016_wp, & 6299 0.030_wp, 0.060_wp, 0.500_wp, 0.700_wp, 0.770_wp, & 6495 6300 0.840_wp, 0.950_wp, 0.970_wp, 1.000_wp, 1.000_wp /) 6496 ecoll(:,6) = (/ 0.017_wp, 0.017_wp, 0.017_wp, 0.020_wp, 0.022_wp, &6497 0.060_wp, 0.100_wp, 0.620_wp, 0.780_wp, 0.840_wp, &6301 ecoll(:,6) = (/ 0.017_wp, 0.017_wp, 0.017_wp, 0.020_wp, 0.022_wp, & 6302 0.060_wp, 0.100_wp, 0.620_wp, 0.780_wp, 0.840_wp, & 6498 6303 0.880_wp, 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6499 ecoll(:,7) = (/ 0.030_wp, 0.030_wp, 0.024_wp, 0.022_wp, 0.032_wp, &6500 0.062_wp, 0.200_wp, 0.680_wp, 0.830_wp, 0.870_wp, &6304 ecoll(:,7) = (/ 0.030_wp, 0.030_wp, 0.024_wp, 0.022_wp, 0.032_wp, & 6305 0.062_wp, 0.200_wp, 0.680_wp, 0.830_wp, 0.870_wp, & 6501 6306 0.900_wp, 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6502 ecoll(:,8) = (/ 0.025_wp, 0.025_wp, 0.025_wp, 0.036_wp, 0.043_wp, &6503 0.130_wp, 0.270_wp, 0.740_wp, 0.860_wp, 0.890_wp, &6307 ecoll(:,8) = (/ 0.025_wp, 0.025_wp, 0.025_wp, 0.036_wp, 0.043_wp, & 6308 0.130_wp, 0.270_wp, 0.740_wp, 0.860_wp, 0.890_wp, & 6504 6309 0.920_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6505 ecoll(:,9) = (/ 0.027_wp, 0.027_wp, 0.027_wp, 0.040_wp, 0.052_wp, &6506 0.200_wp, 0.400_wp, 0.780_wp, 0.880_wp, 0.900_wp, &6310 ecoll(:,9) = (/ 0.027_wp, 0.027_wp, 0.027_wp, 0.040_wp, 0.052_wp, & 6311 0.200_wp, 0.400_wp, 0.780_wp, 0.880_wp, 0.900_wp, & 6507 6312 0.940_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6508 ecoll(:,10) = (/ 0.030_wp, 0.030_wp, 0.030_wp, 0.047_wp, 0.064_wp, &6509 0.250_wp, 0.500_wp, 0.800_wp, 0.900_wp, 0.910_wp, &6313 ecoll(:,10) = (/ 0.030_wp, 0.030_wp, 0.030_wp, 0.047_wp, 0.064_wp, & 6314 0.250_wp, 0.500_wp, 0.800_wp, 0.900_wp, 0.910_wp, & 6510 6315 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6511 ecoll(:,11) = (/ 0.040_wp, 0.040_wp, 0.033_wp, 0.037_wp, 0.068_wp, &6512 0.240_wp, 0.550_wp, 0.800_wp, 0.900_wp, 0.910_wp, &6316 ecoll(:,11) = (/ 0.040_wp, 0.040_wp, 0.033_wp, 0.037_wp, 0.068_wp, & 6317 0.240_wp, 0.550_wp, 0.800_wp, 0.900_wp, 0.910_wp, & 6513 6318 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6514 ecoll(:,12) = (/ 0.035_wp, 0.035_wp, 0.035_wp, 0.055_wp, 0.079_wp, &6515 0.290_wp, 0.580_wp, 0.800_wp, 0.900_wp, 0.910_wp, &6319 ecoll(:,12) = (/ 0.035_wp, 0.035_wp, 0.035_wp, 0.055_wp, 0.079_wp, & 6320 0.290_wp, 0.580_wp, 0.800_wp, 0.900_wp, 0.910_wp, & 6516 6321 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6517 ecoll(:,13) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.062_wp, 0.082_wp, &6518 0.290_wp, 0.590_wp, 0.780_wp, 0.900_wp, 0.910_wp, &6322 ecoll(:,13) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.062_wp, 0.082_wp, & 6323 0.290_wp, 0.590_wp, 0.780_wp, 0.900_wp, 0.910_wp, & 6519 6324 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6520 ecoll(:,14) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.060_wp, 0.080_wp, &6521 0.290_wp, 0.580_wp, 0.770_wp, 0.890_wp, 0.910_wp, &6325 ecoll(:,14) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.060_wp, 0.080_wp, & 6326 0.290_wp, 0.580_wp, 0.770_wp, 0.890_wp, 0.910_wp, & 6522 6327 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6523 ecoll(:,15) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.041_wp, 0.075_wp, &6524 0.250_wp, 0.540_wp, 0.760_wp, 0.880_wp, 0.920_wp, &6328 ecoll(:,15) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.041_wp, 0.075_wp, & 6329 0.250_wp, 0.540_wp, 0.760_wp, 0.880_wp, 0.920_wp, & 6525 6330 0.950_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6526 ecoll(:,16) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.052_wp, 0.067_wp, &6527 0.250_wp, 0.510_wp, 0.770_wp, 0.880_wp, 0.930_wp, &6331 ecoll(:,16) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.052_wp, 0.067_wp, & 6332 0.250_wp, 0.510_wp, 0.770_wp, 0.880_wp, 0.930_wp, & 6528 6333 0.970_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6529 ecoll(:,17) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.047_wp, 0.057_wp, &6530 0.250_wp, 0.490_wp, 0.770_wp, 0.890_wp, 0.950_wp, &6334 ecoll(:,17) = (/ 0.037_wp, 0.037_wp, 0.037_wp, 0.047_wp, 0.057_wp, & 6335 0.250_wp, 0.490_wp, 0.770_wp, 0.890_wp, 0.950_wp, & 6531 6336 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp, 1.000_wp /) 6532 ecoll(:,18) = (/ 0.036_wp, 0.036_wp, 0.036_wp, 0.042_wp, 0.048_wp, &6533 0.230_wp, 0.470_wp, 0.780_wp, 0.920_wp, 1.000_wp, &6337 ecoll(:,18) = (/ 0.036_wp, 0.036_wp, 0.036_wp, 0.042_wp, 0.048_wp, & 6338 0.230_wp, 0.470_wp, 0.780_wp, 0.920_wp, 1.000_wp, & 6534 6339 1.020_wp, 1.020_wp, 1.020_wp, 1.020_wp, 1.020_wp /) 6535 ecoll(:,19) = (/ 0.040_wp, 0.040_wp, 0.035_wp, 0.033_wp, 0.040_wp, &6536 0.112_wp, 0.450_wp, 0.790_wp, 1.010_wp, 1.030_wp, &6340 ecoll(:,19) = (/ 0.040_wp, 0.040_wp, 0.035_wp, 0.033_wp, 0.040_wp, & 6341 0.112_wp, 0.450_wp, 0.790_wp, 1.010_wp, 1.030_wp, & 6537 6342 1.040_wp, 1.040_wp, 1.040_wp, 1.040_wp, 1.040_wp /) 6538 ecoll(:,20) = (/ 0.033_wp, 0.033_wp, 0.033_wp, 0.033_wp, 0.033_wp, &6539 0.119_wp, 0.470_wp, 0.950_wp, 1.300_wp, 1.700_wp, &6343 ecoll(:,20) = (/ 0.033_wp, 0.033_wp, 0.033_wp, 0.033_wp, 0.033_wp, & 6344 0.119_wp, 0.470_wp, 0.950_wp, 1.300_wp, 1.700_wp, & 6540 6345 2.300_wp, 2.300_wp, 2.300_wp, 2.300_wp, 2.300_wp /) 6541 ecoll(:,21) = (/ 0.027_wp, 0.027_wp, 0.027_wp, 0.027_wp, 0.027_wp, &6542 0.125_wp, 0.520_wp, 1.400_wp, 2.300_wp, 3.000_wp, &6346 ecoll(:,21) = (/ 0.027_wp, 0.027_wp, 0.027_wp, 0.027_wp, 0.027_wp, & 6347 0.125_wp, 0.520_wp, 1.400_wp, 2.300_wp, 3.000_wp, & 6543 6348 4.000_wp, 4.000_wp, 4.000_wp, 4.000_wp, 4.000_wp /) 6544 6349 ENDIF 6545 6350 6546 6351 ! 6547 !-- Calculate the radius class index of particles with respect to array r 6548 !-- Radius has to be in microns 6352 !-- Calculate the radius class index of particles with respect to array r. 6353 !-- Radius has to be in microns. 6549 6354 ALLOCATE( ira(1:radius_classes) ) 6550 6355 DO j = 1, radius_classes … … 6561 6366 ! 6562 6367 !-- Two-dimensional linear interpolation of the collision efficiency. 6563 !-- Radius has to be in microns 6368 !-- Radius has to be in microns. 6564 6369 DO j = 1, radius_classes 6565 6370 DO i = 1, j … … 6572 6377 IF ( ir < 16 ) THEN 6573 6378 IF ( ir >= 2 ) THEN 6574 pp = ( ( MAX( radclass(j), radclass(i) ) * 1.0E6_wp ) - &6575 r0(ir-1) )/ ( r0(ir) - r0(ir-1) )6379 pp = ( ( MAX( radclass(j), radclass(i) ) * 1.0E6_wp ) - r0(ir-1) ) & 6380 / ( r0(ir) - r0(ir-1) ) 6576 6381 qq = ( rq - rat(iq-1) ) / ( rat(iq) - rat(iq-1) ) 6577 ec(j,i) = ( 1.0_wp - pp ) * ( 1.0_wp - qq ) & 6578 * ecoll(ir-1,iq-1) & 6579 + pp * ( 1.0_wp - qq ) * ecoll(ir,iq-1) & 6580 + qq * ( 1.0_wp - pp ) * ecoll(ir-1,iq) & 6382 ec(j,i) = ( 1.0_wp - pp ) * ( 1.0_wp - qq ) * ecoll(ir-1,iq-1) & 6383 + pp * ( 1.0_wp - qq ) * ecoll(ir,iq-1) & 6384 + qq * ( 1.0_wp - pp ) * ecoll(ir-1,iq) & 6581 6385 + pp * qq * ecoll(ir,iq) 6582 6386 ELSE … … 6602 6406 6603 6407 6604 !------------------------------------------------------------------------------ !6408 !--------------------------------------------------------------------------------------------------! 6605 6409 ! Description: 6606 6410 ! ------------ 6607 !> Interpolation of turbulent enhancement factor for collision efficencies 6608 !> followingWang and Grabowski (2009, Atmos. Sci. Let.)6609 !------------------------------------------------------------------------------ !6411 !> Interpolation of turbulent enhancement factor for collision efficencies following 6412 !> Wang and Grabowski (2009, Atmos. Sci. Let.) 6413 !--------------------------------------------------------------------------------------------------! 6610 6414 SUBROUTINE turb_enhance_eff 6611 6415 … … 6641 6445 first = .FALSE. 6642 6446 6643 r0 = (/ 10.0_wp, 20.0_wp, 30.0_wp, 40.0_wp, 50.0_wp, 60.0_wp, & 6644 100.0_wp /) 6645 6646 rat = (/ 0.0_wp, 0.1_wp, 0.2_wp, 0.3_wp, 0.4_wp, 0.5_wp, 0.6_wp, & 6647 0.7_wp, 0.8_wp, 0.9_wp, 1.0_wp /) 6447 r0 = (/ 10.0_wp, 20.0_wp, 30.0_wp, 40.0_wp, 50.0_wp, 60.0_wp, 100.0_wp /) 6448 6449 rat = (/ 0.0_wp, 0.1_wp, 0.2_wp, 0.3_wp, 0.4_wp, 0.5_wp, 0.6_wp, 0.7_wp, 0.8_wp, 0.9_wp, & 6450 1.0_wp /) 6648 6451 ! 6649 6452 !-- Tabulated turbulent enhancement factor at 100 cm**2/s**3 6650 ecoll_100(:,1) = (/ 1.74_wp, 1.74_wp, 1.773_wp, 1.49_wp, &6453 ecoll_100(:,1) = (/ 1.74_wp, 1.74_wp, 1.773_wp, 1.49_wp, & 6651 6454 1.207_wp, 1.207_wp, 1.0_wp /) 6652 ecoll_100(:,2) = (/ 1.46_wp, 1.46_wp, 1.421_wp, 1.245_wp, &6455 ecoll_100(:,2) = (/ 1.46_wp, 1.46_wp, 1.421_wp, 1.245_wp, & 6653 6456 1.069_wp, 1.069_wp, 1.0_wp /) 6654 ecoll_100(:,3) = (/ 1.32_wp, 1.32_wp, 1.245_wp, 1.123_wp, &6457 ecoll_100(:,3) = (/ 1.32_wp, 1.32_wp, 1.245_wp, 1.123_wp, & 6655 6458 1.000_wp, 1.000_wp, 1.0_wp /) 6656 ecoll_100(:,4) = (/ 1.250_wp, 1.250_wp, 1.148_wp, 1.087_wp, &6459 ecoll_100(:,4) = (/ 1.250_wp, 1.250_wp, 1.148_wp, 1.087_wp, & 6657 6460 1.025_wp, 1.025_wp, 1.0_wp /) 6658 ecoll_100(:,5) = (/ 1.186_wp, 1.186_wp, 1.066_wp, 1.060_wp, &6461 ecoll_100(:,5) = (/ 1.186_wp, 1.186_wp, 1.066_wp, 1.060_wp, & 6659 6462 1.056_wp, 1.056_wp, 1.0_wp /) 6660 ecoll_100(:,6) = (/ 1.045_wp, 1.045_wp, 1.000_wp, 1.014_wp, &6463 ecoll_100(:,6) = (/ 1.045_wp, 1.045_wp, 1.000_wp, 1.014_wp, & 6661 6464 1.028_wp, 1.028_wp, 1.0_wp /) 6662 ecoll_100(:,7) = (/ 1.070_wp, 1.070_wp, 1.030_wp, 1.038_wp, &6465 ecoll_100(:,7) = (/ 1.070_wp, 1.070_wp, 1.030_wp, 1.038_wp, & 6663 6466 1.046_wp, 1.046_wp, 1.0_wp /) 6664 ecoll_100(:,8) = (/ 1.000_wp, 1.000_wp, 1.054_wp, 1.042_wp, &6467 ecoll_100(:,8) = (/ 1.000_wp, 1.000_wp, 1.054_wp, 1.042_wp, & 6665 6468 1.029_wp, 1.029_wp, 1.0_wp /) 6666 ecoll_100(:,9) = (/ 1.223_wp, 1.223_wp, 1.117_wp, 1.069_wp, &6469 ecoll_100(:,9) = (/ 1.223_wp, 1.223_wp, 1.117_wp, 1.069_wp, & 6667 6470 1.021_wp, 1.021_wp, 1.0_wp /) 6668 ecoll_100(:,10) = (/ 1.570_wp, 1.570_wp, 1.244_wp, 1.166_wp, &6471 ecoll_100(:,10) = (/ 1.570_wp, 1.570_wp, 1.244_wp, 1.166_wp, & 6669 6472 1.088_wp, 1.088_wp, 1.0_wp /) 6670 ecoll_100(:,11) = (/ 20.3_wp, 20.3_wp, 14.6_wp, 8.61_wp, &6473 ecoll_100(:,11) = (/ 20.3_wp, 20.3_wp, 14.6_wp, 8.61_wp, & 6671 6474 2.60_wp, 2.60_wp, 1.0_wp /) 6672 6475 ! 6673 6476 !-- Tabulated turbulent enhancement factor at 400 cm**2/s**3 6674 ecoll_400(:,1) = (/ 4.976_wp, 4.976_wp, 3.593_wp, 2.519_wp, &6477 ecoll_400(:,1) = (/ 4.976_wp, 4.976_wp, 3.593_wp, 2.519_wp, & 6675 6478 1.445_wp, 1.445_wp, 1.0_wp /) 6676 ecoll_400(:,2) = (/ 2.984_wp, 2.984_wp, 2.181_wp, 1.691_wp, &6479 ecoll_400(:,2) = (/ 2.984_wp, 2.984_wp, 2.181_wp, 1.691_wp, & 6677 6480 1.201_wp, 1.201_wp, 1.0_wp /) 6678 ecoll_400(:,3) = (/ 1.988_wp, 1.988_wp, 1.475_wp, 1.313_wp, &6481 ecoll_400(:,3) = (/ 1.988_wp, 1.988_wp, 1.475_wp, 1.313_wp, & 6679 6482 1.150_wp, 1.150_wp, 1.0_wp /) 6680 ecoll_400(:,4) = (/ 1.490_wp, 1.490_wp, 1.187_wp, 1.156_wp, &6483 ecoll_400(:,4) = (/ 1.490_wp, 1.490_wp, 1.187_wp, 1.156_wp, & 6681 6484 1.126_wp, 1.126_wp, 1.0_wp /) 6682 ecoll_400(:,5) = (/ 1.249_wp, 1.249_wp, 1.088_wp, 1.090_wp, &6485 ecoll_400(:,5) = (/ 1.249_wp, 1.249_wp, 1.088_wp, 1.090_wp, & 6683 6486 1.092_wp, 1.092_wp, 1.0_wp /) 6684 ecoll_400(:,6) = (/ 1.139_wp, 1.139_wp, 1.130_wp, 1.091_wp, &6487 ecoll_400(:,6) = (/ 1.139_wp, 1.139_wp, 1.130_wp, 1.091_wp, & 6685 6488 1.051_wp, 1.051_wp, 1.0_wp /) 6686 ecoll_400(:,7) = (/ 1.220_wp, 1.220_wp, 1.190_wp, 1.138_wp, &6489 ecoll_400(:,7) = (/ 1.220_wp, 1.220_wp, 1.190_wp, 1.138_wp, & 6687 6490 1.086_wp, 1.086_wp, 1.0_wp /) 6688 ecoll_400(:,8) = (/ 1.325_wp, 1.325_wp, 1.267_wp, 1.165_wp, &6491 ecoll_400(:,8) = (/ 1.325_wp, 1.325_wp, 1.267_wp, 1.165_wp, & 6689 6492 1.063_wp, 1.063_wp, 1.0_wp /) 6690 ecoll_400(:,9) = (/ 1.716_wp, 1.716_wp, 1.345_wp, 1.223_wp, &6493 ecoll_400(:,9) = (/ 1.716_wp, 1.716_wp, 1.345_wp, 1.223_wp, & 6691 6494 1.100_wp, 1.100_wp, 1.0_wp /) 6692 ecoll_400(:,10) = (/ 3.788_wp, 3.788_wp, 1.501_wp, 1.311_wp, &6495 ecoll_400(:,10) = (/ 3.788_wp, 3.788_wp, 1.501_wp, 1.311_wp, & 6693 6496 1.120_wp, 1.120_wp, 1.0_wp /) 6694 ecoll_400(:,11) = (/ 36.52_wp, 36.52_wp, 19.16_wp, 22.80_wp, &6497 ecoll_400(:,11) = (/ 36.52_wp, 36.52_wp, 19.16_wp, 22.80_wp, & 6695 6498 26.0_wp, 26.0_wp, 1.0_wp /) 6696 6499 … … 6698 6501 6699 6502 ! 6700 !-- Calculate the radius class index of particles with respect to array r0 6503 !-- Calculate the radius class index of particles with respect to array r0. 6701 6504 !-- The droplet radius has to be given in microns. 6702 6505 ALLOCATE( ira(1:radius_classes) ) … … 6733 6536 IF ( ir < 8 ) THEN 6734 6537 IF ( ir >= 2 ) THEN 6735 pp = ( MAX( radclass(j), radclass(i) ) * 1.0E6_wp - &6736 r0(ir-1) )/ ( r0(ir) - r0(ir-1) )6538 pp = ( MAX( radclass(j), radclass(i) ) * 1.0E6_wp - r0(ir-1) ) & 6539 / ( r0(ir) - r0(ir-1) ) 6737 6540 qq = ( rq - rat(iq-1) ) / ( rat(iq) - rat(iq-1) ) 6738 y2 = ( 1.0_wp - pp ) * ( 1.0_wp - qq ) * ecoll_100(ir-1,iq-1) + &6739 pp * ( 1.0_wp - qq ) * ecoll_100(ir,iq-1) + &6740 qq * ( 1.0_wp - pp ) * ecoll_100(ir-1,iq) + &6541 y2 = ( 1.0_wp - pp ) * ( 1.0_wp - qq ) * ecoll_100(ir-1,iq-1) + & 6542 pp * ( 1.0_wp - qq ) * ecoll_100(ir,iq-1) + & 6543 qq * ( 1.0_wp - pp ) * ecoll_100(ir-1,iq) + & 6741 6544 pp * qq * ecoll_100(ir,iq) 6742 y3 = ( 1.0-pp ) * ( 1.0_wp - qq ) * ecoll_400(ir-1,iq-1) + &6743 pp * ( 1.0_wp - qq ) * ecoll_400(ir,iq-1) + &6744 qq * ( 1.0_wp - pp ) * ecoll_400(ir-1,iq) + &6545 y3 = ( 1.0-pp ) * ( 1.0_wp - qq ) * ecoll_400(ir-1,iq-1) + & 6546 pp * ( 1.0_wp - qq ) * ecoll_400(ir,iq-1) + & 6547 qq * ( 1.0_wp - pp ) * ecoll_400(ir-1,iq) + & 6745 6548 pp * qq * ecoll_400(ir,iq) 6746 6549 ELSE … … 6757 6560 !-- Linear interpolation of turbulent enhancement factor 6758 6561 IF ( epsilon_collision <= 0.01_wp ) THEN 6759 ecf(j,i) = ( epsilon_collision - 0.01_wp ) / ( 0.0_wp - 0.01_wp ) * y1&6760 + ( epsilon_collision - 0.0_wp ) / ( 0.01_wp - 0.0_wp ) * y26562 ecf(j,i) = ( epsilon_collision - 0.01_wp ) / ( 0.0_wp - 0.01_wp ) * y1 & 6563 + ( epsilon_collision - 0.0_wp ) / ( 0.01_wp - 0.0_wp ) * y2 6761 6564 ELSEIF ( epsilon_collision <= 0.06_wp ) THEN 6762 ecf(j,i) = ( epsilon_collision - 0.04_wp ) / ( 0.01_wp - 0.04_wp ) * y2&6763 + ( epsilon_collision - 0.01_wp ) / ( 0.04_wp - 0.01_wp ) * y36565 ecf(j,i) = ( epsilon_collision - 0.04_wp ) / ( 0.01_wp - 0.04_wp ) * y2 & 6566 + ( epsilon_collision - 0.01_wp ) / ( 0.04_wp - 0.01_wp ) * y3 6764 6567 ELSE 6765 ecf(j,i) = ( 0.06_wp - 0.04_wp ) / ( 0.01_wp - 0.04_wp ) * y2&6766 + ( 0.06_wp - 0.01_wp ) / ( 0.04_wp - 0.01_wp ) * y36568 ecf(j,i) = ( 0.06_wp - 0.04_wp ) / ( 0.01_wp - 0.04_wp ) * y2 & 6569 + ( 0.06_wp - 0.01_wp ) / ( 0.04_wp - 0.01_wp ) * y3 6767 6570 ENDIF 6768 6571 … … 6775 6578 6776 6579 END SUBROUTINE turb_enhance_eff 6777 6778 6779 !------------------------------------------------------------------------------ !6580 6581 6582 !-------------------------------------------------------------------------------------------------! 6780 6583 ! Description: 6781 6584 ! ------------ 6782 ! This routine is a part of the Lagrangian particle model. Super droplets which 6783 ! fulfill certain criterion's (e.g. a big weighting factor and a large radius) 6784 ! can be split into several super droplets with a reduced number of 6785 ! represented particles of every super droplet. This mechanism ensures an 6786 ! improved representation of the right tail of the drop size distribution with 6787 ! a feasible amount of computational costs. The limits of particle creation 6788 ! should be chosen carefully! The idea of this algorithm is based on 6789 ! Unterstrasser and Soelch, 2014. 6790 !------------------------------------------------------------------------------! 6585 ! This routine is a part of the Lagrangian particle model. Super droplets which fulfill certain 6586 ! criterion's (e.g. a big weighting factor and a large radius) can be split into several super 6587 ! droplets with a reduced number of represented particles of every super droplet. This mechanism 6588 ! ensures an improved representation of the right tail of the drop size distribution with a feasible 6589 ! amount of computational costs. The limits of particle creation should be chosen carefully! The 6590 ! idea of this algorithm is based on Unterstrasser and Soelch, 2014. 6591 !--------------------------------------------------------------------------------------------------! 6791 6592 SUBROUTINE lpm_splitting 6792 6593 6793 INTEGER(iwp) :: i !< 6594 INTEGER(iwp), PARAMETER :: n_max = 100 !< number of radii bin for splitting functions 6595 6596 INTEGER(iwp) :: i !< 6794 6597 INTEGER(iwp) :: j !< 6795 6598 INTEGER(iwp) :: jpp !< … … 6798 6601 INTEGER(iwp) :: new_particles_gb !< counter of created particles within one grid box 6799 6602 INTEGER(iwp) :: new_size !< new particle array size 6800 INTEGER(iwp) :: np !< 6603 INTEGER(iwp) :: np !< 6801 6604 INTEGER(iwp) :: old_size !< old particle array size 6802 6803 INTEGER(iwp), PARAMETER :: n_max = 100 !< number of radii bin for splitting functions6804 6605 6805 6606 LOGICAL :: first_loop_stride_sp = .TRUE. !< flag to calculate constants only once … … 6818 6619 REAL(wp) :: m3_total !< average average over all PEs third moment of DSD 6819 6620 REAL(wp) :: mu !< spectral shape parameter of gamma distribution 6820 REAL(wp) :: nrclgb !< number of cloudy grid boxes (ql >= 1.0E-5 kg/kg) 6621 REAL(wp) :: nrclgb !< number of cloudy grid boxes (ql >= 1.0E-5 kg/kg) 6821 6622 REAL(wp) :: nrclgb_total !< average over all PEs of number of cloudy grid boxes 6822 6623 REAL(wp) :: nr !< number concentration of cloud droplets … … 6824 6625 REAL(wp) :: nr0 !< intercept parameter of gamma distribution 6825 6626 REAL(wp) :: pirho_l !< pi * rho_l / 6.0 6826 REAL(wp) :: ql_crit = 1.0E-5_wp !< threshold lwc for cloudy grid cells 6827 !< (Siebesma et al 2003, JAS, 60) 6627 REAL(wp) :: ql_crit = 1.0E-5_wp !< threshold lwc for cloudy grid cells (Siebesma et al 2003, JAS, 60) 6828 6628 REAL(wp) :: rm !< volume averaged mean radius 6829 6629 REAL(wp) :: rm_total !< average over all PEs of volume averaged mean radius 6830 REAL(wp) :: r_min = 1.0E-6_wp !< minimum radius of approximated spectra 6630 REAL(wp) :: r_min = 1.0E-6_wp !< minimum radius of approximated spectra 6831 6631 REAL(wp) :: r_max = 1.0E-3_wp !< maximum radius of approximated spectra 6832 6632 REAL(wp) :: sigma_log = 1.5_wp !< standard deviation of the LOG-distribution … … 6849 6649 ENDDO 6850 6650 r_bin(n_max) = 10.0_wp**( LOG10(r_min) + n_max * dlog - 0.5_wp * dlog ) 6851 ENDIF 6651 ENDIF 6852 6652 factor_volume_to_mass = 4.0_wp / 3.0_wp * pi * rho_l 6853 6653 pirho_l = pi * rho_l / 6.0_wp 6854 6654 IF ( weight_factor_split == -1.0_wp ) THEN 6855 weight_factor_split = 0.1_wp * initial_weighting_factor 6655 weight_factor_split = 0.1_wp * initial_weighting_factor 6856 6656 ENDIF 6857 6657 ENDIF … … 6866 6666 new_particles_gb = 0 6867 6667 number_of_particles = prt_count(k,j,i) 6868 IF ( number_of_particles <= 0 .OR. & 6869 ql(k,j,i) < ql_crit ) CYCLE 6668 IF ( number_of_particles <= 0 .OR. ql(k,j,i) < ql_crit ) CYCLE 6870 6669 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 6871 6670 ! 6872 !-- Start splitting operations. Each particle is checked if it 6873 !-- fulfilled the splitting criterion's. In splitting mode 'const' 6874 !-- a critical radius (radius_split) a critical weighting factor 6875 !-- (weight_factor_split) and a splitting factor (splitting_factor) 6876 !-- must be prescribed (see particle_parameters). Super droplets 6877 !-- which have a larger radius and larger weighting factor are split 6878 !-- into 'splitting_factor' super droplets. Therefore, the weighting 6879 !-- factor of the super droplet and all created clones is reduced 6880 !-- by the factor of 'splitting_factor'. 6671 !-- Start splitting operations. Each particle is checked if it fulfilled the splitting 6672 !-- criterion's. In splitting mode 'const' a critical radius (radius_split) a critical 6673 !-- weighting factor (weight_factor_split) and a splitting factor (splitting_factor) 6674 !-- must be prescribed (see particle_parameters). Super droplets which have a larger 6675 !-- radius and larger weighting factor are split into 'splitting_factor' super droplets. 6676 !-- Therefore, the weighting factor of the super droplet and all created clones is 6677 !-- reduced by the factor of 'splitting_factor'. 6881 6678 DO n = 1, number_of_particles 6882 IF ( particles(n)%particle_mask .AND.&6883 particles(n)%radius >= radius_split .AND. &6884 particles(n)%weight_factor >= weight_factor_split ) &6679 IF ( particles(n)%particle_mask .AND. & 6680 particles(n)%radius >= radius_split .AND. & 6681 particles(n)%weight_factor >= weight_factor_split ) & 6885 6682 THEN 6886 6683 ! … … 6888 6685 new_size = prt_count(k,j,i) + splitting_factor - 1 6889 6686 ! 6890 !-- Cycle if maximum number of particles per grid box 6891 !-- is greater than the allowedmaximum number.6687 !-- Cycle if maximum number of particles per grid box is greater than the allowed 6688 !-- maximum number. 6892 6689 IF ( new_size >= max_number_particles_per_gridbox ) CYCLE 6893 6690 ! 6894 !-- Reallocate particle array if necessary. 6895 IF ( new_size > SIZE( particles) ) THEN6691 !-- Reallocate particle array if necessary. 6692 IF ( new_size > SIZE( particles ) ) THEN 6896 6693 CALL realloc_particles_array( i, j, k, new_size ) 6897 6694 ENDIF … … 6899 6696 ! 6900 6697 !-- Calculate new weighting factor. 6901 particles(n)%weight_factor = & 6902 particles(n)%weight_factor / splitting_factor 6698 particles(n)%weight_factor = particles(n)%weight_factor / splitting_factor 6903 6699 tmp_particle = particles(n) 6904 6700 ! 6905 6701 !-- Create splitting_factor-1 new particles. 6906 6702 DO jpp = 1, splitting_factor-1 6907 grid_particles(k,j,i)%particles(jpp+old_size) = & 6908 tmp_particle 6909 ENDDO 6703 grid_particles(k,j,i)%particles(jpp+old_size) = tmp_particle 6704 ENDDO 6910 6705 new_particles_gb = new_particles_gb + splitting_factor - 1 6911 ! 6706 ! 6912 6707 !-- Save the new number of super droplets for every grid box. 6913 prt_count(k,j,i) = prt_count(k,j,i) + & 6914 splitting_factor - 1 6708 prt_count(k,j,i) = prt_count(k,j,i) + splitting_factor - 1 6915 6709 ENDIF 6916 6710 ENDDO … … 6920 6714 ENDDO 6921 6715 6922 ELSEIF ( i_splitting_mode == 2 ) THEN 6716 ELSEIF ( i_splitting_mode == 2 ) THEN 6923 6717 ! 6924 6718 !-- Initialize summing variables. 6925 6719 lwc = 0.0_wp 6926 lwc_total = 0.0_wp 6720 lwc_total = 0.0_wp 6927 6721 m1 = 0.0_wp 6928 6722 m1_total = 0.0_wp … … 6942 6736 DO k = nzb+1, nzt 6943 6737 number_of_particles = prt_count(k,j,i) 6944 IF ( number_of_particles <= 0 .OR. & 6945 ql(k,j,i) < ql_crit ) CYCLE 6738 IF ( number_of_particles <= 0 .OR. ql(k,j,i) < ql_crit ) CYCLE 6946 6739 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 6947 6740 nrclgb = nrclgb + 1.0_wp … … 6949 6742 !-- Calculate moments of DSD. 6950 6743 DO n = 1, number_of_particles 6951 IF ( particles(n)%particle_mask .AND. & 6952 particles(n)%radius >= r_min ) & 6744 IF ( particles(n)%particle_mask .AND. particles(n)%radius >= r_min ) & 6953 6745 THEN 6954 6746 nr = nr + particles(n)%weight_factor 6955 rm = rm + factor_volume_to_mass * &6956 particles(n)%radius**3 * &6747 rm = rm + factor_volume_to_mass * & 6748 particles(n)%radius**3 * & 6957 6749 particles(n)%weight_factor 6958 IF ( isf == 1 ) THEN 6750 IF ( isf == 1 ) THEN 6959 6751 diameter = particles(n)%radius * 2.0_wp 6960 lwc = lwc + factor_volume_to_mass * &6961 particles(n)%radius**3 * &6962 particles(n)%weight_factor 6752 lwc = lwc + factor_volume_to_mass * & 6753 particles(n)%radius**3 * & 6754 particles(n)%weight_factor 6963 6755 m1 = m1 + particles(n)%weight_factor * diameter 6964 6756 m2 = m2 + particles(n)%weight_factor * diameter**2 … … 6966 6758 ENDIF 6967 6759 ENDIF 6968 ENDDO 6760 ENDDO 6969 6761 ENDDO 6970 6762 ENDDO … … 6973 6765 #if defined( __parallel ) 6974 6766 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 6975 CALL MPI_ALLREDUCE( nr, nr_total, 1 , & 6976 MPI_REAL, MPI_SUM, comm2d, ierr ) 6977 CALL MPI_ALLREDUCE( rm, rm_total, 1 , & 6978 MPI_REAL, MPI_SUM, comm2d, ierr ) 6767 CALL MPI_ALLREDUCE( nr, nr_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6768 CALL MPI_ALLREDUCE( rm, rm_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6979 6769 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 6980 CALL MPI_ALLREDUCE( nrclgb, nrclgb_total, 1 , & 6981 MPI_REAL, MPI_SUM, comm2d, ierr ) 6770 CALL MPI_ALLREDUCE( nrclgb, nrclgb_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6982 6771 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 6983 CALL MPI_ALLREDUCE( lwc, lwc_total, 1 , & 6984 MPI_REAL, MPI_SUM, comm2d, ierr ) 6772 CALL MPI_ALLREDUCE( lwc, lwc_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6985 6773 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 6986 CALL MPI_ALLREDUCE( m1, m1_total, 1 , & 6987 MPI_REAL, MPI_SUM, comm2d, ierr ) 6774 CALL MPI_ALLREDUCE( m1, m1_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6988 6775 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 6989 CALL MPI_ALLREDUCE( m2, m2_total, 1 , & 6990 MPI_REAL, MPI_SUM, comm2d, ierr ) 6776 CALL MPI_ALLREDUCE( m2, m2_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6991 6777 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr ) 6992 CALL MPI_ALLREDUCE( m3, m3_total, 1 , & 6993 MPI_REAL, MPI_SUM, comm2d, ierr ) 6994 #endif 6778 CALL MPI_ALLREDUCE( m3, m3_total, 1 , MPI_REAL, MPI_SUM, comm2d, ierr ) 6779 #endif 6995 6780 6996 6781 ! 6997 6782 !-- Calculate number concentration and mean volume averaged radius. 6998 nr_total = MERGE( nr_total / nrclgb_total, & 6999 0.0_wp, nrclgb_total > 0.0_wp & 7000 ) 7001 rm_total = MERGE( ( rm_total / & 7002 ( nr_total * factor_volume_to_mass ) & 7003 )**0.3333333_wp, 0.0_wp, nrclgb_total > 0.0_wp & 6783 nr_total = MERGE( nr_total / nrclgb_total, 0.0_wp, nrclgb_total > 0.0_wp ) 6784 rm_total = MERGE( ( rm_total / ( nr_total * factor_volume_to_mass ) )**0.3333333_wp, 0.0_wp,& 6785 nrclgb_total > 0.0_wp & 7004 6786 ) 7005 6787 ! 7006 6788 !-- Check which function should be used to approximate the DSD. 7007 6789 IF ( isf == 1 ) THEN 7008 lwc_total = MERGE( lwc_total / nrclgb_total, & 7009 0.0_wp, nrclgb_total > 0.0_wp & 7010 ) 7011 m1_total = MERGE( m1_total / nrclgb_total, & 7012 0.0_wp, nrclgb_total > 0.0_wp & 7013 ) 7014 m2_total = MERGE( m2_total / nrclgb_total, & 7015 0.0_wp, nrclgb_total > 0.0_wp & 7016 ) 7017 m3_total = MERGE( m3_total / nrclgb_total, & 7018 0.0_wp, nrclgb_total > 0.0_wp & 7019 ) 6790 lwc_total = MERGE( lwc_total / nrclgb_total, 0.0_wp, nrclgb_total > 0.0_wp ) 6791 m1_total = MERGE( m1_total / nrclgb_total, 0.0_wp, nrclgb_total > 0.0_wp ) 6792 m2_total = MERGE( m2_total / nrclgb_total, 0.0_wp, nrclgb_total > 0.0_wp ) 6793 m3_total = MERGE( m3_total / nrclgb_total, 0.0_wp, nrclgb_total > 0.0_wp ) 7020 6794 zeta = m1_total * m3_total / m2_total**2 7021 mu = MAX( ( ( 1.0_wp - zeta ) * 2.0_wp + 1.0_wp ) / & 7022 ( zeta - 1.0_wp ), 0.0_wp & 7023 ) 7024 7025 lambda = ( pirho_l * nr_total / lwc_total * & 7026 ( mu + 3.0_wp ) * ( mu + 2.0_wp ) * ( mu + 1.0_wp ) & 6795 mu = MAX( ( ( 1.0_wp - zeta ) * 2.0_wp + 1.0_wp ) / ( zeta - 1.0_wp ), 0.0_wp ) 6796 6797 lambda = ( pirho_l * nr_total / lwc_total * & 6798 ( mu + 3.0_wp ) * ( mu + 2.0_wp ) * ( mu + 1.0_wp ) & 7027 6799 )**0.3333333_wp 7028 nr0 = nr_total / gamma( mu + 1.0_wp ) * lambda**( mu + 1.0_wp ) 6800 nr0 = nr_total / gamma( mu + 1.0_wp ) * lambda**( mu + 1.0_wp ) 7029 6801 7030 6802 DO n = 0, n_max-1 7031 6803 diameter = r_bin_mid(n) * 2.0_wp 7032 an_spl(n) = nr0 * diameter**mu * EXP( -lambda * diameter ) * &7033 ( r_bin(n+1) - r_bin(n) ) * 2.0_wp 6804 an_spl(n) = nr0 * diameter**mu * EXP( -lambda * diameter ) * & 6805 ( r_bin(n+1) - r_bin(n) ) * 2.0_wp 7034 6806 ENDDO 7035 6807 ELSEIF ( isf == 2 ) THEN 7036 6808 DO n = 0, n_max-1 7037 an_spl(n) = nr_total / ( SQRT( 2.0_wp * pi ) * & 7038 LOG(sigma_log) * r_bin_mid(n) & 7039 ) * & 7040 EXP( -( LOG( r_bin_mid(n) / rm_total )**2 ) / & 7041 ( 2.0_wp * LOG(sigma_log)**2 ) & 7042 ) * & 6809 an_spl(n) = nr_total / ( SQRT( 2.0_wp * pi ) * LOG(sigma_log) * r_bin_mid(n) ) * & 6810 EXP( -( LOG( r_bin_mid(n) / rm_total )**2 ) / & 6811 ( 2.0_wp * LOG(sigma_log)**2 ) & 6812 ) * & 7043 6813 ( r_bin(n+1) - r_bin(n) ) 7044 6814 ENDDO 7045 6815 ELSEIF( isf == 3 ) THEN 7046 DO n = 0, n_max-1 7047 an_spl(n) = 3.0_wp * nr_total * r_bin_mid(n)**2 / rm_total**3 * &7048 EXP( - ( r_bin_mid(n)**3 / rm_total**3 ) ) *&6816 DO n = 0, n_max-1 6817 an_spl(n) = 3.0_wp * nr_total * r_bin_mid(n)**2 / rm_total**3 * & 6818 EXP( -( r_bin_mid(n)**3 / rm_total**3 ) ) * & 7049 6819 ( r_bin(n+1) - r_bin(n) ) 7050 6820 ENDDO … … 7058 6828 DO k = nzb+1, nzt 7059 6829 number_of_particles = prt_count(k,j,i) 7060 IF ( number_of_particles <= 0 .OR. & 7061 ql(k,j,i) < ql_crit ) CYCLE 6830 IF ( number_of_particles <= 0 .OR. ql(k,j,i) < ql_crit ) CYCLE 7062 6831 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 7063 6832 new_particles_gb = 0 7064 6833 ! 7065 !-- Start splitting operations. Each particle is checked if it 7066 !-- fulfilled the splitting criterion's. In splitting mode 'cl_av' 7067 !-- a critical radius (radius_split) and a splitting function must 7068 !-- be prescribed (see particles_par). The critical weighting factor 7069 !-- is calculated while approximating a 'gamma', 'log' or 'exp'- 7070 !-- drop size distribution. In this mode the DSD is calculated as 7071 !-- an average over all cloudy grid boxes. Super droplets which 7072 !-- have a larger radius and larger weighting factor are split into 7073 !-- 'splitting_factor' super droplets. In this case the splitting 7074 !-- factor is calculated of weighting factor of the super droplet 7075 !-- and the approximated number concentration for droplet of such 7076 !-- a size. Due to the splitting, the weighting factor of the 7077 !-- super droplet and all created clones is reduced by the factor 7078 !-- of 'splitting_facor'. 6834 !-- Start splitting operations. Each particle is checked if it fulfilled the splitting 6835 !-- criterion's. In splitting mode 'cl_av' a critical radius (radius_split) and a 6836 !-- splitting function must be prescribed (see particles_par). The critical weighting 6837 !-- factor is calculated while approximating a 'gamma', 'log' or 'exp'- drop size 6838 !-- distribution. In this mode the DSD is calculated as an average over all cloudy grid 6839 !-- boxes. Super droplets which have a larger radius and larger weighting factor are 6840 !-- split into 'splitting_factor' super droplets. In this case the splitting factor is 6841 !-- calculated of weighting factor of the super droplet and the approximated number 6842 !-- concentration for droplet of such a size. Due to the splitting, the weighting factor 6843 !-- of the super droplet and all created clones is reduced by the factor of 6844 !-- 'splitting_facor'. 7079 6845 DO n = 1, number_of_particles 7080 6846 DO np = 0, n_max-1 7081 IF ( r_bin(np) >= radius_split .AND.&7082 particles(n)%particle_mask .AND.&7083 particles(n)%radius >= r_bin(np) .AND.&7084 particles(n)%radius < r_bin(np+1) .AND. &7085 particles(n)%weight_factor >= an_spl(np) ) &6847 IF ( r_bin(np) >= radius_split .AND. & 6848 particles(n)%particle_mask .AND. & 6849 particles(n)%radius >= r_bin(np) .AND. & 6850 particles(n)%radius < r_bin(np+1) .AND. & 6851 particles(n)%weight_factor >= an_spl(np) ) & 7086 6852 THEN 7087 6853 ! 7088 6854 !-- Calculate splitting factor 7089 splitting_factor = & 7090 MIN( INT( particles(n)%weight_factor / & 7091 an_spl(np) & 7092 ), splitting_factor_max & 7093 ) 6855 splitting_factor = MIN( INT( particles(n)%weight_factor / & 6856 an_spl(np) & 6857 ), splitting_factor_max & 6858 ) 7094 6859 IF ( splitting_factor < 2 ) CYCLE 7095 6860 ! … … 7097 6862 new_size = prt_count(k,j,i) + splitting_factor - 1 7098 6863 ! 7099 !-- Cycle if maximum number of particles per grid box 7100 !-- is greater than the allowed maximum number. 7101 IF ( new_size >= max_number_particles_per_gridbox ) & 7102 CYCLE 7103 ! 7104 !-- Reallocate particle array if necessary. 7105 IF ( new_size > SIZE(particles) ) THEN 6864 !-- Cycle if maximum number of particles per grid box is greater than the 6865 !-- allowed maximum number. 6866 IF ( new_size >= max_number_particles_per_gridbox ) CYCLE 6867 ! 6868 !-- Reallocate particle array if necessary. 6869 IF ( new_size > SIZE( particles ) ) THEN 7106 6870 CALL realloc_particles_array( i, j, k, new_size ) 7107 6871 ENDIF 7108 6872 old_size = prt_count(k,j,i) 7109 new_particles_gb = new_particles_gb + & 7110 splitting_factor - 1 6873 new_particles_gb = new_particles_gb + splitting_factor - 1 7111 6874 ! 7112 6875 !-- Calculate new weighting factor. 7113 particles(n)%weight_factor = & 7114 particles(n)%weight_factor / splitting_factor 6876 particles(n)%weight_factor = particles(n)%weight_factor / splitting_factor 7115 6877 tmp_particle = particles(n) 7116 6878 ! 7117 6879 !-- Create splitting_factor-1 new particles. 7118 6880 DO jpp = 1, splitting_factor-1 7119 grid_particles(k,j,i)%particles(jpp+old_size) = & 7120 tmp_particle 6881 grid_particles(k,j,i)%particles(jpp+old_size) = tmp_particle 7121 6882 ENDDO 7122 6883 ! 7123 !-- Save the new number of super droplets. 7124 prt_count(k,j,i) = prt_count(k,j,i) + & 7125 splitting_factor - 1 6884 !-- Save the new number of super droplets. 6885 prt_count(k,j,i) = prt_count(k,j,i) + splitting_factor - 1 7126 6886 ENDIF 7127 6887 ENDDO 7128 ENDDO 6888 ENDDO 7129 6889 7130 6890 ENDDO … … 7132 6892 ENDDO 7133 6893 7134 ELSEIF ( i_splitting_mode == 3 ) THEN 6894 ELSEIF ( i_splitting_mode == 3 ) THEN 7135 6895 7136 6896 DO i = nxl, nxr … … 7145 6905 m3 = 0.0_wp 7146 6906 nr = 0.0_wp 7147 rm = 0.0_wp 6907 rm = 0.0_wp 7148 6908 7149 6909 new_particles_gb = 0 7150 6910 number_of_particles = prt_count(k,j,i) 7151 IF ( number_of_particles <= 0 .OR. & 7152 ql(k,j,i) < ql_crit ) CYCLE 6911 IF ( number_of_particles <= 0 .OR. ql(k,j,i) < ql_crit ) CYCLE 7153 6912 particles => grid_particles(k,j,i)%particles 7154 6913 ! 7155 6914 !-- Calculate moments of DSD. 7156 6915 DO n = 1, number_of_particles 7157 IF ( particles(n)%particle_mask .AND. & 7158 particles(n)%radius >= r_min ) & 6916 IF ( particles(n)%particle_mask .AND. particles(n)%radius >= r_min ) & 7159 6917 THEN 7160 6918 nr = nr + particles(n)%weight_factor 7161 rm = rm + factor_volume_to_mass * &7162 particles(n)%radius**3 * &6919 rm = rm + factor_volume_to_mass * & 6920 particles(n)%radius**3 * & 7163 6921 particles(n)%weight_factor 7164 6922 IF ( isf == 1 ) THEN 7165 6923 diameter = particles(n)%radius * 2.0_wp 7166 lwc = lwc + factor_volume_to_mass * &7167 particles(n)%radius**3 * &7168 particles(n)%weight_factor 6924 lwc = lwc + factor_volume_to_mass * & 6925 particles(n)%radius**3 * & 6926 particles(n)%weight_factor 7169 6927 m1 = m1 + particles(n)%weight_factor * diameter 7170 6928 m2 = m2 + particles(n)%weight_factor * diameter**2 … … 7182 6940 IF ( isf == 1 ) THEN 7183 6941 ! 7184 !-- Gamma size distribution to calculate 6942 !-- Gamma size distribution to calculate 7185 6943 !-- critical weight_factor (e.g. Marshall + Palmer, 1948). 7186 6944 zeta = m1 * m3 / m2**2 7187 mu = MAX( ( ( 1.0_wp - zeta ) * 2.0_wp + 1.0_wp ) / & 7188 ( zeta - 1.0_wp ), 0.0_wp & 7189 ) 7190 lambda = ( pirho_l * nr / lwc * & 7191 ( mu + 3.0_wp ) * ( mu + 2.0_wp ) * & 7192 ( mu + 1.0_wp ) & 6945 mu = MAX( ( ( 1.0_wp - zeta ) * 2.0_wp + 1.0_wp ) / ( zeta - 1.0_wp ), 0.0_wp ) 6946 lambda = ( pirho_l * nr / lwc * & 6947 ( mu + 3.0_wp ) * ( mu + 2.0_wp ) * ( mu + 1.0_wp ) & 7193 6948 )**0.3333333_wp 7194 nr0 = ( nr / (gamma( mu + 1.0_wp ) ) ) * &7195 lambda**( mu + 1.0_wp ) 6949 nr0 = ( nr / (gamma( mu + 1.0_wp ) ) ) * & 6950 lambda**( mu + 1.0_wp ) 7196 6951 7197 6952 DO n = 0, n_max-1 7198 6953 diameter = r_bin_mid(n) * 2.0_wp 7199 an_spl(n) = nr0 * diameter**mu * &7200 EXP( -lambda * diameter ) * &7201 ( r_bin(n+1) - r_bin(n) ) * 2.0_wp 6954 an_spl(n) = nr0 * diameter**mu * & 6955 EXP( -lambda * diameter ) * & 6956 ( r_bin(n+1) - r_bin(n) ) * 2.0_wp 7202 6957 ENDDO 7203 6958 ELSEIF ( isf == 2 ) THEN 7204 6959 ! 7205 !-- Lognormal size distribution to calculate critical 6960 !-- Lognormal size distribution to calculate critical 7206 6961 !-- weight_factor (e.g. Levin, 1971, Bradley + Stow, 1974). 7207 6962 DO n = 0, n_max-1 7208 an_spl(n) = nr / ( SQRT( 2.0_wp * pi ) * &7209 LOG(sigma_log) * r_bin_mid(n) &7210 ) *&7211 EXP( -( LOG( r_bin_mid(n) / rm )**2 ) / &7212 ( 2.0_wp * LOG(sigma_log)**2 ) &7213 ) *&6963 an_spl(n) = nr / ( SQRT( 2.0_wp * pi ) * & 6964 LOG(sigma_log) * r_bin_mid(n) & 6965 ) * & 6966 EXP( -( LOG( r_bin_mid(n) / rm )**2 ) / & 6967 ( 2.0_wp * LOG(sigma_log)**2 ) & 6968 ) * & 7214 6969 ( r_bin(n+1) - r_bin(n) ) 7215 6970 ENDDO 7216 6971 ELSEIF ( isf == 3 ) THEN 7217 6972 ! 7218 !-- Exponential size distribution to calculate critical 7219 !-- weight_factor (e.g. Berry + Reinhardt, 1974).6973 !-- Exponential size distribution to calculate critical weight_factor 6974 !-- (e.g. Berry + Reinhardt, 1974). 7220 6975 DO n = 0, n_max-1 7221 an_spl(n) = 3.0_wp * nr * r_bin_mid(n)**2 / rm**3 * &7222 EXP( - ( r_bin_mid(n)**3 / rm**3 ) ) * &6976 an_spl(n) = 3.0_wp * nr * r_bin_mid(n)**2 / rm**3 * & 6977 EXP( - ( r_bin_mid(n)**3 / rm**3 ) ) * & 7223 6978 ( r_bin(n+1) - r_bin(n) ) 7224 6979 ENDDO … … 7229 6984 an_spl = MAX(an_spl, 1.0_wp) 7230 6985 ! 7231 !-- Start splitting operations. Each particle is checked if it 7232 !-- fulfilled the splitting criterion's. In splitting mode 'gb_av' 7233 !-- a critical radius (radius_split) and a splitting function must 7234 !-- be prescribed (see particles_par). The critical weighting factor 7235 !-- is calculated while appoximating a 'gamma', 'log' or 'exp'- 7236 !-- drop size distribution. In this mode a DSD is calculated for 7237 !-- every cloudy grid box. Super droplets which have a larger 7238 !-- radius and larger weighting factor are split into 7239 !-- 'splitting_factor' super droplets. In this case the splitting 7240 !-- factor is calculated of weighting factor of the super droplet 7241 !-- and theapproximated number concentration for droplet of such 7242 !-- a size. Due to the splitting, the weighting factor of the 7243 !-- super droplet and all created clones is reduced by the factor 7244 !-- of 'splitting_facor'. 6986 !-- Start splitting operations. Each particle is checked if it fulfilled the splitting 6987 !-- criterions. In splitting mode 'gb_av' a critical radius (radius_split) and a 6988 !-- splitting function must be prescribed (see particles_par). The critical weighting 6989 !-- factor is calculated while appoximating a 'gamma', 'log' or 'exp'-drop size 6990 !-- distribution. In this mode a DSD is calculated for every cloudy grid box. Super 6991 !-- droplets which have a larger radius and larger weighting factor are split into 6992 !-- 'splitting_factor' super droplets. In this case the splitting factor is calculated 6993 !-- by the weighting factor of the super droplet and the approximated number 6994 !-- concentration for droplets of such size. Due to the splitting, the weighting factor 6995 !-- of the super droplet and all created clones are reduced by the factor of 6996 !-- 'splitting_facor'. 7245 6997 DO n = 1, number_of_particles 7246 6998 DO np = 0, n_max-1 7247 IF ( r_bin(np) >= radius_split .AND.&7248 particles(n)%particle_mask .AND.&7249 particles(n)%radius >= r_bin(np) .AND. &7250 particles(n)%radius < r_bin(np+1) .AND. &7251 particles(n)%weight_factor >= an_spl(np) ) &6999 IF ( r_bin(np) >= radius_split .AND. & 7000 particles(n)%particle_mask .AND. & 7001 particles(n)%radius >= r_bin(np) .AND. & 7002 particles(n)%radius < r_bin(np+1) .AND. & 7003 particles(n)%weight_factor >= an_spl(np) ) & 7252 7004 THEN 7253 7005 ! 7254 7006 !-- Calculate splitting factor. 7255 splitting_factor = & 7256 MIN( INT( particles(n)%weight_factor / & 7257 an_spl(np) & 7258 ), splitting_factor_max & 7259 ) 7007 splitting_factor = MIN( INT( particles(n)%weight_factor / an_spl(np) ), & 7008 splitting_factor_max & 7009 ) 7260 7010 IF ( splitting_factor < 2 ) CYCLE 7261 7011 … … 7266 7016 !-- Cycle if maximum number of particles per grid box 7267 7017 !-- is greater than the allowed maximum number. 7268 IF ( new_size >= max_number_particles_per_gridbox ) & 7269 CYCLE 7018 IF ( new_size >= max_number_particles_per_gridbox ) CYCLE 7270 7019 ! 7271 7020 !-- Reallocate particle array if necessary. 7272 IF ( new_size > SIZE( particles) ) THEN7021 IF ( new_size > SIZE( particles ) ) THEN 7273 7022 CALL realloc_particles_array( i, j, k, new_size ) 7274 7023 ENDIF 7275 7024 ! 7276 7025 !-- Calculate new weighting factor. 7277 particles(n)%weight_factor = & 7278 particles(n)%weight_factor / splitting_factor 7026 particles(n)%weight_factor = particles(n)%weight_factor / splitting_factor 7279 7027 tmp_particle = particles(n) 7280 7028 old_size = prt_count(k,j,i) … … 7282 7030 !-- Create splitting_factor-1 new particles. 7283 7031 DO jpp = 1, splitting_factor-1 7284 grid_particles(k,j,i)%particles( jpp + old_size ) = & 7285 tmp_particle 7032 grid_particles(k,j,i)%particles( jpp + old_size ) = tmp_particle 7286 7033 ENDDO 7287 7034 ! 7288 7035 !-- Save the new number of droplets for every grid box. 7289 prt_count(k,j,i) = prt_count(k,j,i) + & 7290 splitting_factor - 1 7291 new_particles_gb = new_particles_gb + & 7292 splitting_factor - 1 7036 prt_count(k,j,i) = prt_count(k,j,i) + splitting_factor - 1 7037 new_particles_gb = new_particles_gb + splitting_factor - 1 7293 7038 ENDIF 7294 7039 ENDDO … … 7302 7047 7303 7048 END SUBROUTINE lpm_splitting 7304 7305 7306 !------------------------------------------------------------------------------ !7049 7050 7051 !--------------------------------------------------------------------------------------------------! 7307 7052 ! Description: 7308 7053 ! ------------ 7309 ! This routine is a part of the Lagrangian particle model. Two Super droplets 7310 ! which fulfill certain criterion's (e.g. a big weighting factor and a small 7311 ! radius) can be merged into one super droplet with a increased number of 7312 ! represented particles of the super droplet. This mechanism ensures an 7313 ! improved a feasible amount of computational costs. The limits of particle 7314 ! creation should be chosen carefully! The idea of this algorithm is based on 7315 ! Unterstrasser and Soelch, 2014. 7316 !------------------------------------------------------------------------------! 7054 ! This routine is a part of the Lagrangian particle model. Two Super droplets which fulfill certain 7055 ! criterions (e.g. a big weighting factor and a small radius) can be merged into one super droplet 7056 ! with a increased number of represented particles of the super droplet. This mechanism ensures an 7057 ! improved feasible amount of computational costs. The limits of particle creation should be chosen 7058 ! carefully! The idea of this algorithm is based on Unterstrasser and Soelch, 2014. 7059 !--------------------------------------------------------------------------------------------------! 7317 7060 SUBROUTINE lpm_merging 7318 7061 … … 7324 7067 7325 7068 7326 REAL(wp) :: ql_crit = 1.0E-5_wp !< threshold lwc for cloudy grid cells 7069 REAL(wp) :: ql_crit = 1.0E-5_wp !< threshold lwc for cloudy grid cells 7327 7070 !< (e.g. Siebesma et al 2003, JAS, 60) 7328 7071 … … 7332 7075 7333 7076 IF ( weight_factor_merge == -1.0_wp ) THEN 7334 weight_factor_merge = 0.5_wp * initial_weighting_factor 7077 weight_factor_merge = 0.5_wp * initial_weighting_factor 7335 7078 ENDIF 7336 7079 … … 7340 7083 7341 7084 number_of_particles = prt_count(k,j,i) 7342 IF ( number_of_particles <= 0 .OR. & 7343 ql(k,j,i) >= ql_crit ) CYCLE 7085 IF ( number_of_particles <= 0 .OR. ql(k,j,i) >= ql_crit ) CYCLE 7344 7086 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 7345 7087 ! 7346 !-- Start merging operations: This routine delete super droplets with 7347 !-- a small radius (radius <= radius_merge) and a low weighting 7348 !-- factor (weight_factor <= weight_factor_merge). The number of 7349 !-- represented particles will be added to the next particle of the 7350 !-- particle array. Tests showed that this simplified method can be 7351 !-- used because it will only take place outside of cloudy grid 7352 !-- boxes where ql <= 1.0E-5 kg/kg. Therefore, especially former cloned 7353 !-- and subsequent evaporated super droplets will be merged. 7088 !-- Start merging operations: This routine deletes super droplets with a small radius 7089 !-- (radius <= radius_merge) and a low weighting factor (weight_factor <= 7090 !-- weight_factor_merge). The number of represented particles will be added to the next 7091 !-- particle of the particle array. Tests showed that this simplified method can be used 7092 !-- because it will only take place outside of cloudy grid boxes where ql <= 1.0E-5 kg/kg. 7093 !-- Therefore, especially former cloned and subsequent evaporated super droplets will be 7094 !-- merged. 7354 7095 DO n = 1, number_of_particles-1 7355 IF ( particles(n)%particle_mask .AND. &7356 particles(n+1)%particle_mask .AND. &7357 particles(n)%radius <= radius_merge .AND. &7358 particles(n)%weight_factor <= weight_factor_merge ) &7096 IF ( particles(n)%particle_mask .AND. & 7097 particles(n+1)%particle_mask .AND. & 7098 particles(n)%radius <= radius_merge .AND. & 7099 particles(n)%weight_factor <= weight_factor_merge ) & 7359 7100 THEN 7360 particles(n+1)%weight_factor = & 7361 particles(n+1)%weight_factor + & 7362 ( particles(n)%radius**3 / & 7363 particles(n+1)%radius**3 * & 7364 particles(n)%weight_factor & 7365 ) 7101 particles(n+1)%weight_factor = particles(n+1)%weight_factor + & 7102 ( particles(n)%radius**3 / & 7103 particles(n+1)%radius**3 * & 7104 particles(n)%weight_factor & 7105 ) 7366 7106 particles(n)%particle_mask = .FALSE. 7367 deleted_particles = deleted_particles + 1 7107 deleted_particles = deleted_particles + 1 7368 7108 merge_drp = merge_drp + 1 7369 7109 … … 7379 7119 END SUBROUTINE lpm_merging 7380 7120 7381 7382 7383 7384 !------------------------------------------------------------------------------ !7121 7122 7123 7124 !--------------------------------------------------------------------------------------------------! 7385 7125 ! Description: 7386 7126 ! ------------ 7387 7127 !> Exchange between subdomains. 7388 !> As soon as one particle has moved beyond the boundary of the domain, it 7389 !> is included in the relevant transfer arrays and marked for subsequent 7390 !> deletion on this PE. 7391 !> First sweep for crossings in x direction. Find out first the number of 7392 !> particles to be transferred and allocate temporary arrays needed to store 7393 !> them. 7394 !> For a one-dimensional decomposition along y, no transfer is necessary, 7395 !> because the particle remains on the PE, but the particle coordinate has to 7396 !> be adjusted. 7397 !------------------------------------------------------------------------------! 7128 !> As soon as one particle has moved beyond the boundary of the domain, it is included in the 7129 !> relevant transfer arrays and marked for subsequent deletion on this PE. 7130 !> First sweep for crossings in x direction. Find out first the number of particles to be 7131 !> transferred and allocate temporary arrays needed to store them. 7132 !> For a one-dimensional decomposition along y, no transfer is necessary, because the particle 7133 !> remains on the PE, but the particle coordinate has to be adjusted. 7134 !--------------------------------------------------------------------------------------------------! 7398 7135 SUBROUTINE lpm_exchange_horiz 7399 7136 … … 7401 7138 INTEGER(iwp) :: jp !< index variable along y 7402 7139 INTEGER(iwp) :: kp !< index variable along z 7403 INTEGER(iwp) :: n !< particle index variable 7140 INTEGER(iwp) :: n !< particle index variable 7404 7141 7405 7142 #if defined( __parallel ) … … 7432 7169 ! 7433 7170 !-- Exchange between subdomains. 7434 !-- As soon as one particle has moved beyond the boundary of the domain, it 7435 !-- is included in the relevant transfer arrays and marked for subsequent 7436 !-- deletion on this PE. 7437 !-- First sweep for crossings in x direction. Find out first the number of 7438 !-- particles to be transferred and allocate temporary arrays needed to store 7439 !-- them. 7440 !-- For a one-dimensional decomposition along y, no transfer is necessary, 7441 !-- because the particle remains on the PE, but the particle coordinate has to 7442 !-- be adjusted. 7171 !-- As soon as one particle has moved beyond the boundary of the domain, it is included in the 7172 !-- relevant transfer arrays and marked for subsequent deletion on this PE. 7173 !-- First sweep for crossings in x direction. Find out first the number of particles to be 7174 !-- transferred and allocate temporary arrays needed to store them. 7175 !-- For a one-dimensional decomposition along y, no transfer is necessary, because the particle 7176 !-- remains on the PE, but the particle coordinate has to be adjusted. 7443 7177 trlp_count = 0 7444 7178 trrp_count = 0 … … 7449 7183 IF ( pdims(1) /= 1 ) THEN 7450 7184 ! 7451 !-- First calculate the storage necessary for sending and receiving the data. 7452 !-- Compute only first(nxl) and last (nxr) loop iterration.7185 !-- First calculate the storage necessary for sending and receiving the data. Compute only first 7186 !-- (nxl) and last (nxr) loop iterration. 7453 7187 DO ip = nxl, nxr, nxr - nxl 7454 7188 DO jp = nys, nyn … … 7499 7233 DO n = 1, number_of_particles 7500 7234 ! 7501 !-- Only those particles that have not been marked as 'deleted' may 7502 !-- be moved. 7235 !-- Only those particles that have not been marked as 'deleted' may be moved. 7503 7236 IF ( particles(n)%particle_mask ) THEN 7504 7237 … … 7551 7284 ELSE 7552 7285 ! 7553 !-- Store particle data in the transfer array, which will be 7554 !-- send to theneighbouring PE7286 !-- Store particle data in the transfer array, which will be send to the 7287 !-- neighbouring PE 7555 7288 trlp_count = trlp_count + 1 7556 7289 trlp(trlp_count) = particles(n) … … 7569 7302 IF ( pdims(1) == 1 ) THEN 7570 7303 particles(n)%x = particles(n)%x - ( nx + 1 ) * dx 7571 particles(n)%origin_x = particles(n)%origin_x - & 7572 ( nx + 1 ) * dx 7304 particles(n)%origin_x = particles(n)%origin_x - ( nx + 1 ) * dx 7573 7305 ELSE 7574 7306 trrp_count = trrp_count + 1 7575 7307 trrp(trrp_count) = particles(n) 7576 7308 trrp(trrp_count)%x = trrp(trrp_count)%x - ( nx + 1 ) * dx 7577 trrp(trrp_count)%origin_x = trrp(trrp_count)%origin_x - &7578 ( nx + 1 ) * dx7309 trrp(trrp_count)%origin_x = trrp(trrp_count)%origin_x - & 7310 ( nx + 1 ) * dx 7579 7311 particles(n)%particle_mask = .FALSE. 7580 7312 deleted_particles = deleted_particles + 1 … … 7597 7329 ELSE 7598 7330 ! 7599 !-- Store particle data in the transfer array, which will be send 7600 !-- to theneighbouring PE7331 !-- Store particle data in the transfer array, which will be send to the 7332 !-- neighbouring PE 7601 7333 trrp_count = trrp_count + 1 7602 7334 trrp(trrp_count) = particles(n) … … 7615 7347 7616 7348 ! 7617 !-- STORAGE_SIZE returns the storage size of argument A in bits. However , it 7349 !-- STORAGE_SIZE returns the storage size of argument A in bits. However , it 7618 7350 !-- is needed in bytes. The function C_SIZEOF which produces this value directly 7619 7351 !-- causes problems with gfortran. For this reason the use of C_SIZEOF is avoided 7620 par_size = STORAGE_SIZE( trlp(1))/87621 7622 7623 ! 7624 !-- Allocate arrays required for north-south exchange, as these 7625 !-- are used directly after particles areexchange along x-direction.7626 ALLOCATE( move_also_north(1: NR_2_direction_move) )7627 ALLOCATE( move_also_south(1: NR_2_direction_move) )7352 par_size = STORAGE_SIZE( trlp(1) ) / 8 7353 7354 7355 ! 7356 !-- Allocate arrays required for north-south exchange, as these are used directly after particles 7357 !-- are exchange along x-direction. 7358 ALLOCATE( move_also_north(1:nr_2_direction_move) ) 7359 ALLOCATE( move_also_south(1:nr_2_direction_move) ) 7628 7360 7629 7361 nr_move_north = 0 7630 7362 nr_move_south = 0 7631 7363 ! 7632 !-- Send left boundary, receive right boundary (but first exchange how many 7633 !-- and check, if particlestorage must be extended)7364 !-- Send left boundary, receive right boundary (but first exchange how many and check, if particle 7365 !-- storage must be extended) 7634 7366 IF ( pdims(1) /= 1 ) THEN 7635 7367 7636 CALL MPI_SENDRECV( trlp_count, 1, MPI_INTEGER, pleft, 0, &7637 trrp_count_recv, 1, MPI_INTEGER, pright, 0, &7368 CALL MPI_SENDRECV( trlp_count, 1, MPI_INTEGER, pleft, 0, & 7369 trrp_count_recv, 1, MPI_INTEGER, pright, 0, & 7638 7370 comm2d, status, ierr ) 7639 7371 7640 7372 ALLOCATE(rvrp(MAX(1,trrp_count_recv))) 7641 7373 7642 CALL MPI_SENDRECV( trlp, max(1,trlp_count)*par_size, MPI_BYTE,& 7643 pleft, 1, rvrp, & 7644 max(1,trrp_count_recv)*par_size, MPI_BYTE, pright, 1,& 7374 CALL MPI_SENDRECV( trlp, MAX(1,trlp_count)*par_size, MPI_BYTE, pleft, 1, & 7375 rvrp, MAX(1,trrp_count_recv)*par_size, MPI_BYTE, pright, 1, & 7645 7376 comm2d, status, ierr ) 7646 7377 … … 7651 7382 ! 7652 7383 !-- Send right boundary, receive left boundary 7653 CALL MPI_SENDRECV( trrp_count, 1, MPI_INTEGER, pright, 0, &7654 trlp_count_recv, 1, MPI_INTEGER, pleft, 0, &7384 CALL MPI_SENDRECV( trrp_count, 1, MPI_INTEGER, pright, 0, & 7385 trlp_count_recv, 1, MPI_INTEGER, pleft, 0, & 7655 7386 comm2d, status, ierr ) 7656 7387 7657 7388 ALLOCATE(rvlp(MAX(1,trlp_count_recv))) 7658 7389 ! 7659 !-- This MPI_SENDRECV should work even with odd mixture on 32 and 64 Bit 7660 !-- variables in structure particle_type (due to the calculation of par_size) 7661 CALL MPI_SENDRECV( trrp, max(1,trrp_count)*par_size, MPI_BYTE,& 7662 pright, 1, rvlp, & 7663 max(1,trlp_count_recv)*par_size, MPI_BYTE, pleft, 1, & 7390 !-- This MPI_SENDRECV should work even with odd mixture on 32 and 64 Bit variables in structure 7391 !-- particle_type (due to the calculation of par_size) 7392 CALL MPI_SENDRECV( trrp, MAX(1,trrp_count)*par_size, MPI_BYTE, pright, 1, & 7393 rvlp, MAX(1,trlp_count_recv)*par_size, MPI_BYTE, pleft, 1, & 7664 7394 comm2d, status, ierr ) 7665 7395 … … 7672 7402 7673 7403 ! 7674 !-- Check whether particles have crossed the boundaries in y direction. Note 7675 !-- that this case can also apply to particles that have just been received 7676 !-- from the adjacent right or left PE. 7677 !-- Find out first the number of particles to be transferred and allocate 7678 !-- temporary arrays needed to store them. 7679 !-- For a one-dimensional decomposition along y, no transfer is necessary, 7680 !-- because the particle remains on the PE. 7404 !-- Check whether particles have crossed the boundaries in y direction. Note that this case can also 7405 !-- apply to particles that have just been received from the adjacent right or left PE. 7406 !-- Find out first the number of particles to be transferred and allocate temporary arrays needed to 7407 !-- store them. 7408 !-- For a one-dimensional decomposition along y, no transfer is necessary, because the particle 7409 !-- remains on the PE. 7681 7410 trsp_count = nr_move_south 7682 7411 trnp_count = nr_move_north … … 7687 7416 IF ( pdims(2) /= 1 ) THEN 7688 7417 ! 7689 !-- First calculate the storage necessary for sending and receiving the 7690 !-- data 7418 !-- First calculate the storage necessary for sending and receiving the data 7691 7419 DO ip = nxl, nxr 7692 7420 DO jp = nys, nyn, nyn-nys !compute only first (nys) and last (nyn) loop iterration … … 7737 7465 DO n = 1, number_of_particles 7738 7466 ! 7739 !-- Only those particles that have not been marked as 'deleted' may 7740 !-- be moved. 7467 !-- Only those particles that have not been marked as 'deleted' may be moved. 7741 7468 IF ( particles(n)%particle_mask ) THEN 7742 7469 … … 7755 7482 IF ( pdims(2) == 1 ) THEN 7756 7483 particles(n)%y = ( ny + 1 ) * dy + particles(n)%y 7757 particles(n)%origin_y = ( ny + 1 ) * dy + & 7758 particles(n)%origin_y 7484 particles(n)%origin_y = ( ny + 1 ) * dy + particles(n)%origin_y 7759 7485 ELSE 7760 7486 trsp_count = trsp_count + 1 7761 7487 trsp(trsp_count) = particles(n) 7762 trsp(trsp_count)%y = ( ny + 1 ) * dy + & 7763 trsp(trsp_count)%y 7764 trsp(trsp_count)%origin_y = trsp(trsp_count)%origin_y & 7765 + ( ny + 1 ) * dy 7488 trsp(trsp_count)%y = ( ny + 1 ) * dy + trsp(trsp_count)%y 7489 trsp(trsp_count)%origin_y = trsp(trsp_count)%origin_y & 7490 + ( ny + 1 ) * dy 7766 7491 particles(n)%particle_mask = .FALSE. 7767 7492 deleted_particles = deleted_particles + 1 … … 7770 7495 trsp(trsp_count)%y = trsp(trsp_count)%y - 1.0E-10_wp 7771 7496 !++ why is 1 subtracted in next statement??? 7772 trsp(trsp_count)%origin_y = & 7773 trsp(trsp_count)%origin_y - 1 7497 trsp(trsp_count)%origin_y = trsp(trsp_count)%origin_y - 1 7774 7498 ENDIF 7775 7499 … … 7791 7515 ELSE 7792 7516 ! 7793 !-- Store particle data in the transfer array, which will 7794 !-- be send to theneighbouring PE7517 !-- Store particle data in the transfer array, which will be send to the 7518 !-- neighbouring PE 7795 7519 trsp_count = trsp_count + 1 7796 7520 trsp(trsp_count) = particles(n) … … 7809 7533 IF ( pdims(2) == 1 ) THEN 7810 7534 particles(n)%y = particles(n)%y - ( ny + 1 ) * dy 7811 particles(n)%origin_y = & 7812 particles(n)%origin_y - ( ny + 1 ) * dy 7535 particles(n)%origin_y = particles(n)%origin_y - ( ny + 1 ) * dy 7813 7536 ELSE 7814 7537 trnp_count = trnp_count + 1 7815 7538 trnp(trnp_count) = particles(n) 7816 trnp(trnp_count)%y = & 7817 trnp(trnp_count)%y - ( ny + 1 ) * dy 7818 trnp(trnp_count)%origin_y = & 7819 trnp(trnp_count)%origin_y - ( ny + 1 ) * dy 7539 trnp(trnp_count)%y = trnp(trnp_count)%y - ( ny + 1 ) * dy 7540 trnp(trnp_count)%origin_y = & 7541 trnp(trnp_count)%origin_y - ( ny + 1 ) * dy 7820 7542 particles(n)%particle_mask = .FALSE. 7821 7543 deleted_particles = deleted_particles + 1 … … 7837 7559 ELSE 7838 7560 ! 7839 !-- Store particle data in the transfer array, which will 7840 !-- be send to theneighbouring PE7561 !-- Store particle data in the transfer array, which will be send to the 7562 !-- neighbouring PE 7841 7563 trnp_count = trnp_count + 1 7842 7564 trnp(trnp_count) = particles(n) … … 7854 7576 7855 7577 ! 7856 !-- Send front boundary, receive back boundary (but first exchange how many 7857 !-- and check, if particlestorage must be extended)7578 !-- Send front boundary, receive back boundary (but first exchange how many and check, if particle 7579 !-- storage must be extended) 7858 7580 IF ( pdims(2) /= 1 ) THEN 7859 7581 … … 7864 7586 ALLOCATE(rvnp(MAX(1,trnp_count_recv))) 7865 7587 ! 7866 !-- This MPI_SENDRECV should work even with odd mixture on 32 and 64 Bit 7867 !-- variables in structure particle_type (due to the calculation of par_size) 7868 CALL MPI_SENDRECV( trsp, trsp_count*par_size, MPI_BYTE, & 7869 psouth, 1, rvnp, & 7870 trnp_count_recv*par_size, MPI_BYTE, pnorth, 1, & 7588 !-- This MPI_SENDRECV should work even with odd mixture on 32 and 64 Bit variables in structure 7589 !-- particle_type (due to the calculation of par_size) 7590 CALL MPI_SENDRECV( trsp, trsp_count*par_size, MPI_BYTE, psouth, 1, & 7591 rvnp, trnp_count_recv*par_size, MPI_BYTE, pnorth, 1, & 7871 7592 comm2d, status, ierr ) 7872 7593 … … 7877 7598 ! 7878 7599 !-- Send back boundary, receive front boundary 7879 CALL MPI_SENDRECV( trnp_count, 1, MPI_INTEGER, pnorth, 0, &7880 trsp_count_recv, 1, MPI_INTEGER, psouth, 0, &7600 CALL MPI_SENDRECV( trnp_count, 1, MPI_INTEGER, pnorth, 0, & 7601 trsp_count_recv, 1, MPI_INTEGER, psouth, 0, & 7881 7602 comm2d, status, ierr ) 7882 7603 7883 7604 ALLOCATE(rvsp(MAX(1,trsp_count_recv))) 7884 7605 ! 7885 !-- This MPI_SENDRECV should work even with odd mixture on 32 and 64 Bit 7886 !-- variables in structure particle_type (due to the calculation of par_size) 7887 CALL MPI_SENDRECV( trnp, trnp_count*par_size, MPI_BYTE, & 7888 pnorth, 1, rvsp, & 7889 trsp_count_recv*par_size, MPI_BYTE, psouth, 1, & 7606 !-- This MPI_SENDRECV should work even with odd mixture on 32 and 64 Bit variables in structure 7607 !-- particle_type (due to the calculation of par_size) 7608 CALL MPI_SENDRECV( trnp, trnp_count*par_size, MPI_BYTE, pnorth, 1, & 7609 rvsp, trsp_count_recv*par_size, MPI_BYTE, psouth, 1, & 7890 7610 comm2d, status, ierr ) 7891 7611 … … 7922 7642 !-- Cyclic boundary. Relevant coordinate has to be changed. 7923 7643 particles(n)%x = ( nx + 1 ) * dx + particles(n)%x 7924 particles(n)%origin_x = ( nx + 1 ) * dx + & 7925 particles(n)%origin_x 7644 particles(n)%origin_x = ( nx + 1 ) * dx + particles(n)%origin_x 7926 7645 ELSEIF ( ibc_par_lr == 1 ) THEN 7927 7646 ! … … 7943 7662 !-- Cyclic boundary. Relevant coordinate has to be changed. 7944 7663 particles(n)%x = particles(n)%x - ( nx + 1 ) * dx 7945 particles(n)%origin_x = particles(n)%origin_x - & 7946 ( nx + 1 ) * dx 7664 particles(n)%origin_x = particles(n)%origin_x - ( nx + 1 ) * dx 7947 7665 7948 7666 ELSEIF ( ibc_par_lr == 1 ) THEN … … 7979 7697 !-- Cyclic boundary. Relevant coordinate has to be changed. 7980 7698 particles(n)%y = ( ny + 1 ) * dy + particles(n)%y 7981 particles(n)%origin_y = ( ny + 1 ) * dy + & 7982 particles(n)%origin_y 7699 particles(n)%origin_y = ( ny + 1 ) * dy + particles(n)%origin_y 7983 7700 7984 7701 ELSEIF ( ibc_par_ns == 1 ) THEN … … 8001 7718 !-- Cyclic boundary. Relevant coordinate has to be changed. 8002 7719 particles(n)%y = particles(n)%y - ( ny + 1 ) * dy 8003 particles(n)%origin_y = particles(n)%origin_y - & 8004 ( ny + 1 ) * dy 7720 particles(n)%origin_y = particles(n)%origin_y - ( ny + 1 ) * dy 8005 7721 8006 7722 ELSEIF ( ibc_par_ns == 1 ) THEN … … 8043 7759 8044 7760 #if defined( __parallel ) 8045 !------------------------------------------------------------------------------ !7761 !--------------------------------------------------------------------------------------------------! 8046 7762 ! Description: 8047 7763 ! ------------ 8048 !> If a particle moves from one processor to another, this subroutine moves 8049 !> the corresponding elements from the particle arrays of the old grid cells8050 !> to the particle arrays of the new gridcells.8051 !------------------------------------------------------------------------------ !7764 !> If a particle moves from one processor to another, this subroutine moves the corresponding 7765 !> elements from the particle arrays of the old grid cells to the particle arrays of the new grid 7766 !> cells. 7767 !--------------------------------------------------------------------------------------------------! 8052 7768 SUBROUTINE lpm_add_particles_to_gridcell (particle_array) 8053 7769 … … 8065 7781 TYPE(particle_type), DIMENSION(:), ALLOCATABLE :: temp_ns !< temporary particle array for reallocation 8066 7782 7783 8067 7784 pack_done = .FALSE. 8068 7785 8069 DO n = 1, SIZE( particle_array)7786 DO n = 1, SIZE( particle_array ) 8070 7787 8071 7788 IF ( .NOT. particle_array(n)%particle_mask ) CYCLE … … 8075 7792 ! 8076 7793 !-- In case of stretching the actual k index must be found 8077 IF ( dz_stretch_level /= -9999999.9_wp .OR. 8078 dz_stretch_level_start(1) /= -9999999.9_wp )THEN7794 IF ( dz_stretch_level /= -9999999.9_wp .OR. dz_stretch_level_start(1) /= -9999999.9_wp ) & 7795 THEN 8079 7796 kp = MAX( MINLOC( ABS( particle_array(n)%z - zu ), DIM = 1 ) - 1, 1 ) 8080 7797 ELSE … … 8082 7799 ENDIF 8083 7800 8084 IF ( ip >= nxl .AND. ip <= nxr .AND. jp >= nys .AND. jp <= nyn & 8085 .AND. kp >= nzb+1 .AND. kp <= nzt) THEN ! particle stays on processor 7801 IF ( ip >= nxl .AND. ip <= nxr .AND. jp >= nys .AND. jp <= nyn .AND. & 7802 kp >= nzb+1 .AND. kp <= nzt) THEN ! particle stays on processor 7803 8086 7804 number_of_particles = prt_count(kp,jp,ip) 8087 7805 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 8088 7806 8089 7807 pindex = prt_count(kp,jp,ip)+1 8090 IF( pindex > SIZE( grid_particles(kp,jp,ip)%particles) ) THEN7808 IF( pindex > SIZE( grid_particles(kp,jp,ip)%particles ) ) THEN 8091 7809 IF ( pack_done ) THEN 8092 7810 CALL realloc_particles_array ( ip, jp, kp ) … … 8095 7813 prt_count(kp,jp,ip) = number_of_particles 8096 7814 pindex = prt_count(kp,jp,ip)+1 8097 IF ( pindex > SIZE( grid_particles(kp,jp,ip)%particles) ) THEN7815 IF ( pindex > SIZE( grid_particles(kp,jp,ip)%particles ) ) THEN 8098 7816 CALL realloc_particles_array ( ip, jp, kp ) 8099 7817 ENDIF … … 8103 7821 grid_particles(kp,jp,ip)%particles(pindex) = particle_array(n) 8104 7822 prt_count(kp,jp,ip) = pindex 7823 8105 7824 ELSE 7825 8106 7826 IF ( jp <= nys - 1 ) THEN 7827 8107 7828 nr_move_south = nr_move_south+1 8108 7829 ! 8109 !-- Before particle information is swapped to exchange-array, check 8110 !-- if enough memory is allocated. If required, reallocate exchange 8111 !-- array. 8112 IF ( nr_move_south > SIZE(move_also_south) ) THEN 8113 ! 8114 !-- At first, allocate further temporary array to swap particle 8115 !-- information. 8116 ALLOCATE( temp_ns(SIZE(move_also_south)+NR_2_direction_move) ) 7830 !-- Before particle information is swapped to exchange-array, check if enough memory is 7831 !-- allocated. If required, reallocate exchange array. 7832 IF ( nr_move_south > SIZE( move_also_south ) ) THEN 7833 ! 7834 !-- At first, allocate further temporary array to swap particle information. 7835 ALLOCATE( temp_ns(SIZE( move_also_south )+nr_2_direction_move) ) 8117 7836 temp_ns(1:nr_move_south-1) = move_also_south(1:nr_move_south-1) 8118 7837 DEALLOCATE( move_also_south ) 8119 ALLOCATE( move_also_south(SIZE( temp_ns)) )7838 ALLOCATE( move_also_south(SIZE( temp_ns )) ) 8120 7839 move_also_south(1:nr_move_south-1) = temp_ns(1:nr_move_south-1) 8121 7840 DEALLOCATE( temp_ns ) … … 8129 7848 !-- Apply boundary condition along y 8130 7849 IF ( ibc_par_ns == 0 ) THEN 8131 move_also_south(nr_move_south)%y = &8132 move_also_south(nr_move_south)%y + ( ny + 1 ) * dy8133 move_also_south(nr_move_south)%origin_y = &8134 move_also_south(nr_move_south)%origin_y + ( ny + 1 ) * dy7850 move_also_south(nr_move_south)%y = & 7851 move_also_south(nr_move_south)%y + ( ny + 1 ) * dy 7852 move_also_south(nr_move_south)%origin_y = & 7853 move_also_south(nr_move_south)%origin_y + ( ny + 1 ) * dy 8135 7854 ELSEIF ( ibc_par_ns == 1 ) THEN 8136 7855 ! … … 8142 7861 ! 8143 7862 !-- Particle reflection 8144 move_also_south(nr_move_south)%y = & 8145 -move_also_south(nr_move_south)%y 8146 move_also_south(nr_move_south)%speed_y = & 8147 -move_also_south(nr_move_south)%speed_y 7863 move_also_south(nr_move_south)%y = -move_also_south(nr_move_south)%y 7864 move_also_south(nr_move_south)%speed_y = -move_also_south(nr_move_south)%speed_y 8148 7865 8149 7866 ENDIF 7867 8150 7868 ENDIF 7869 8151 7870 ELSEIF ( jp >= nyn+1 ) THEN 7871 8152 7872 nr_move_north = nr_move_north+1 8153 7873 ! 8154 !-- Before particle information is swapped to exchange-array, check 8155 !-- if enough memory is allocated. If required, reallocate exchange 8156 !-- array. 8157 IF ( nr_move_north > SIZE(move_also_north) ) THEN 8158 ! 8159 !-- At first, allocate further temporary array to swap particle 8160 !-- information. 8161 ALLOCATE( temp_ns(SIZE(move_also_north)+NR_2_direction_move) ) 7874 !-- Before particle information is swapped to exchange-array, check if enough memory is 7875 !-- allocated. If required, reallocate exchange array. 7876 IF ( nr_move_north > SIZE( move_also_north ) ) THEN 7877 ! 7878 !-- At first, allocate further temporary array to swap particle information. 7879 ALLOCATE( temp_ns(SIZE( move_also_north )+nr_2_direction_move) ) 8162 7880 temp_ns(1:nr_move_north-1) = move_also_south(1:nr_move_north-1) 8163 7881 DEALLOCATE( move_also_north ) 8164 ALLOCATE( move_also_north(SIZE( temp_ns)) )7882 ALLOCATE( move_also_north(SIZE( temp_ns )) ) 8165 7883 move_also_north(1:nr_move_north-1) = temp_ns(1:nr_move_north-1) 8166 7884 DEALLOCATE( temp_ns ) … … 8174 7892 IF ( ibc_par_ns == 0 ) THEN 8175 7893 8176 move_also_north(nr_move_north)%y = &8177 move_also_north(nr_move_north)%y - ( ny + 1 ) * dy8178 move_also_north(nr_move_north)%origin_y = &8179 move_also_north(nr_move_north)%origin_y - ( ny + 1 ) * dy7894 move_also_north(nr_move_north)%y = & 7895 move_also_north(nr_move_north)%y - ( ny + 1 ) * dy 7896 move_also_north(nr_move_north)%origin_y = & 7897 move_also_north(nr_move_north)%origin_y - ( ny + 1 ) * dy 8180 7898 ELSEIF ( ibc_par_ns == 1 ) THEN 8181 7899 ! … … 8187 7905 ! 8188 7906 !-- Particle reflection 8189 move_also_north(nr_move_north)%y = & 8190 -move_also_north(nr_move_north)%y 8191 move_also_north(nr_move_north)%speed_y = & 8192 -move_also_north(nr_move_north)%speed_y 7907 move_also_north(nr_move_north)%y = -move_also_north(nr_move_north)%y 7908 move_also_north(nr_move_north)%speed_y = -move_also_north(nr_move_north)%speed_y 8193 7909 8194 7910 ENDIF 7911 8195 7912 ENDIF 7913 8196 7914 ELSE 7915 8197 7916 IF ( .NOT. child_domain ) THEN 8198 7917 WRITE(0,'(a,8i7)') 'particle out of range ',myid,ip,jp,kp,nxl,nxr,nys,nyn 7918 8199 7919 ENDIF 7920 8200 7921 ENDIF 7922 8201 7923 ENDIF 7924 8202 7925 ENDDO 8203 7926 8204 7927 END SUBROUTINE lpm_add_particles_to_gridcell 8205 7928 #endif 8206 8207 8208 !------------------------------------------------------------------------------ !7929 7930 7931 !--------------------------------------------------------------------------------------------------! 8209 7932 ! Description: 8210 7933 ! ------------ 8211 !> If a particle moves from one grid cell to another (on the current 8212 !> processor!), this subroutine moves the corresponding element from the 8213 !> particle array of the old grid cell to the particle array of the new grid 8214 !> cell. 8215 !------------------------------------------------------------------------------! 7934 !> If a particle moves from one grid cell to another (on the current processor!), this subroutine 7935 !> moves the corresponding element from the particle array of the old grid cell to the particle 7936 !> array of the new grid cell. 7937 !--------------------------------------------------------------------------------------------------! 8216 7938 SUBROUTINE lpm_move_particle 8217 7939 8218 7940 INTEGER(iwp) :: i !< grid index (x) of particle position 8219 7941 INTEGER(iwp) :: ip !< index variable along x … … 8243 7965 k = kp 8244 7966 ! 8245 !-- Find correct vertical particle grid box (necessary in case of grid stretching) 8246 !-- Due to the CFL limitations only the neighbouring grid boxes are considered. 7967 !-- Find correct vertical particle grid box (necessary in case of grid stretching). 7968 !-- Due to the CFL limitations only the neighbouring grid boxes are considered. 8247 7969 IF( zw(k) < particles_before_move(n)%z ) k = k + 1 8248 IF( zw(k-1) > particles_before_move(n)%z ) k = k - 1 8249 8250 !-- For lpm_exchange_horiz to work properly particles need to be moved to the outermost gridboxes8251 !-- of the respective processor. If the particle index is inside the processor the following lines8252 !-- will not change the index7970 IF( zw(k-1) > particles_before_move(n)%z ) k = k - 1 7971 7972 !-- For lpm_exchange_horiz to work properly particles need to be moved to the outermost 7973 !-- gridboxes of the respective processor. If the particle index is inside the processor 7974 !-- the following lines will not change the index. 8253 7975 i = MIN ( i , nxr ) 8254 7976 i = MAX ( i , nxl ) … … 8263 7985 IF ( i /= ip .OR. j /= jp .OR. k /= kp ) THEN 8264 7986 !! 8265 !-- If the particle stays on the same processor, the particle 8266 !-- will be added to theparticle array of the new processor.7987 !-- If the particle stays on the same processor, the particle will be added to the 7988 !-- particle array of the new processor. 8267 7989 number_of_particles = prt_count(k,j,i) 8268 7990 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 8269 7991 8270 7992 pindex = prt_count(k,j,i)+1 8271 IF ( pindex > SIZE(grid_particles(k,j,i)%particles) ) & 8272 THEN 7993 IF ( pindex > SIZE( grid_particles(k,j,i)%particles ) ) THEN 8273 7994 CALL realloc_particles_array( i, j, k ) 8274 7995 ENDIF … … 8290 8011 8291 8012 END SUBROUTINE lpm_move_particle 8292 8293 8294 !------------------------------------------------------------------------------ !8013 8014 8015 !--------------------------------------------------------------------------------------------------! 8295 8016 ! Description: 8296 8017 ! ------------ 8297 !> Check CFL-criterion for each particle. If one particle violated the 8298 !> criterion the particle willbe deleted and a warning message is given.8299 !------------------------------------------------------------------------------ !8300 SUBROUTINE lpm_check_cfl 8018 !> Check CFL-criterion for each particle. If one particle violated the criterion the particle will 8019 !> be deleted and a warning message is given. 8020 !--------------------------------------------------------------------------------------------------! 8021 SUBROUTINE lpm_check_cfl 8301 8022 8302 8023 IMPLICIT NONE … … 8312 8033 number_of_particles = prt_count(k,j,i) 8313 8034 IF ( number_of_particles <= 0 ) CYCLE 8314 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 8035 particles => grid_particles(k,j,i)%particles(1:number_of_particles) 8315 8036 DO n = 1, number_of_particles 8316 8037 ! 8317 !-- Note, check for CFL does not work at first particle timestep 8318 !-- when both, age and age_m are zero.8038 !-- Note, check for CFL does not work at first particle timestep when both, age and 8039 !-- age_m are zero. 8319 8040 IF ( particles(n)%age - particles(n)%age_m > 0.0_wp ) THEN 8320 IF( ABS( particles(n)%speed_x ) > &8321 ( dx / ( particles(n)%age - particles(n)%age_m) ) .OR.&8322 ABS( particles(n)%speed_y ) > &8323 ( dy / ( particles(n)%age - particles(n)%age_m) ) .OR.&8324 ABS( particles(n)%speed_z ) > &8325 ( ( zw(k)-zw(k-1) )&8326 / ( particles(n)%age - particles(n)%age_m) ) )THEN8327 WRITE( message_string, * ) &8328 'Particle violated CFL-criterion: &particle with id ', &8329 particles(n)%id, ' will be deleted!'8041 IF( ABS( particles(n)%speed_x ) > & 8042 ( dx / ( particles(n)%age - particles(n)%age_m) ) .OR. & 8043 ABS( particles(n)%speed_y ) > & 8044 ( dy / ( particles(n)%age - particles(n)%age_m) ) .OR. & 8045 ABS( particles(n)%speed_z ) > & 8046 ( ( zw(k)-zw(k-1) ) / ( particles(n)%age - particles(n)%age_m) ) ) & 8047 THEN 8048 WRITE( message_string, * ) & 8049 'Particle violated CFL-criterion: &particle with id ', particles(n)%id, & 8050 ' will be deleted!' 8330 8051 CALL message( 'lpm_check_cfl', 'PA0475', 0, 1, -1, 6, 0 ) 8331 8052 … … 8336 8057 ENDDO 8337 8058 ENDDO 8338 ENDDO 8059 ENDDO 8339 8060 8340 8061 END SUBROUTINE lpm_check_cfl 8341 8342 8343 !------------------------------------------------------------------------------ !8062 8063 8064 !--------------------------------------------------------------------------------------------------! 8344 8065 ! Description: 8345 8066 ! ------------ 8346 !> If the allocated memory for the particle array do not suffice to add arriving8347 !> particles from neighbour grid cells, this subrouting reallocates the8348 !> particle array to assure enough memory is available.8349 !------------------------------------------------------------------------------ !8067 !> If the allocated memory for the particle array does not suffice to add arriving particles from 8068 !> neighbour grid cells, this subrouting reallocates the particle array to assure enough memory is 8069 !> available. 8070 !--------------------------------------------------------------------------------------------------! 8350 8071 SUBROUTINE realloc_particles_array ( i, j, k, size_in ) 8351 8072 … … 8355 8076 INTEGER(iwp), INTENT(IN), OPTIONAL :: size_in !< 8356 8077 8078 INTEGER(iwp) :: new_size !< 8357 8079 INTEGER(iwp) :: old_size !< 8358 INTEGER(iwp) :: new_size !<8359 8080 TYPE(particle_type), DIMENSION(:), ALLOCATABLE :: tmp_particles_d !< 8360 8081 TYPE(particle_type), DIMENSION(500) :: tmp_particles_s !< 8361 8082 8362 old_size = SIZE( grid_particles(k,j,i)%particles)8363 8364 IF ( PRESENT( size_in) )THEN8083 old_size = SIZE( grid_particles(k,j,i)%particles ) 8084 8085 IF ( PRESENT( size_in) ) THEN 8365 8086 new_size = size_in 8366 8087 ELSE … … 8397 8118 8398 8119 RETURN 8399 8120 8400 8121 END SUBROUTINE realloc_particles_array 8401 8402 8403 !------------------------------------------------------------------------------ !8122 8123 8124 !--------------------------------------------------------------------------------------------------! 8404 8125 ! Description: 8405 8126 ! ------------ 8406 !> Not needed but allocated space for particles is dealloced. 8407 !------------------------------------------------------------------------------ !8127 !> Not needed but allocated space for particles is dealloced. 8128 !--------------------------------------------------------------------------------------------------! 8408 8129 SUBROUTINE dealloc_particles_array 8409 8130 8410 8131 8411 8132 INTEGER(iwp) :: i !< 8412 8133 INTEGER(iwp) :: j !< … … 8431 8152 ! 8432 8153 !-- Check for large unused memory 8433 dealloc = ( ( number_of_particles < 1 .AND. &8434 old_size > 1 ) .OR.&8435 ( number_of_particles > 1 .AND.&8436 old_size - number_of_particles *&8437 ( 1.0_wp + 0.01_wp * alloc_factor ) > 0.0_wp ))8154 dealloc = ( ( number_of_particles < 1 .AND. old_size > 1 ) .OR. & 8155 ( number_of_particles > 1 .AND. & 8156 old_size - number_of_particles * ( 1.0_wp + 0.01_wp * alloc_factor ) & 8157 > 0.0_wp ) & 8158 ) 8438 8159 8439 8160 IF ( dealloc ) THEN 8440 8161 IF ( number_of_particles < 1 ) THEN 8441 8162 new_size = 1 8442 ELSE 8163 ELSE 8443 8164 new_size = INT( number_of_particles * ( 1.0_wp + 0.01_wp * alloc_factor ) ) 8444 8165 ENDIF … … 8474 8195 ENDDO 8475 8196 8476 END SUBROUTINE dealloc_particles_array 8477 8478 8479 !------------------------------------------------------------------------------ !8197 END SUBROUTINE dealloc_particles_array 8198 8199 8200 !--------------------------------------------------------------------------------------------------! 8480 8201 ! Description: 8481 8202 ! ----------- 8482 !> Routine for the whole processor 8483 !> Sort all particles into the 8 respective subgrid boxes (in case of trilinear 8484 !> interpolation method) and free space of particles which has been marked for 8485 !> deletion. 8486 !------------------------------------------------------------------------------! 8203 !> Routine for the whole processor. 8204 !> Sort all particles into the 8 respective subgrid boxes (in case of trilinear interpolation 8205 !> method) and free space of particles which has been marked for deletion. 8206 !--------------------------------------------------------------------------------------------------! 8487 8207 SUBROUTINE lpm_sort_and_delete 8488 8208 … … 8520 8240 nn = nn + 1 8521 8241 ! 8522 !-- Sorting particles with a binary scheme 8242 !-- Sorting particles with a binary scheme. 8523 8243 !-- sort_index=111_2=7_10 -> particle at the left,south,bottom subgridbox 8524 8244 !-- sort_index=000_2=0_10 -> particle at the right,north,top subgridbox 8525 !-- For this the center of the gridbox is calculated 8245 !-- For this the center of the gridbox is calculated. 8526 8246 i = (particles(n)%x + 0.5_wp * dx) * ddx 8527 8247 j = (particles(n)%y + 0.5_wp * dy) * ddy … … 8538 8258 ENDDO 8539 8259 ! 8540 !-- Delete and resort particles by overwritting and set 8541 !-- the number_of_particles to theactual value.8260 !-- Delete and resort particles by overwritting and set the number_of_particles to 8261 !-- the actual value. 8542 8262 nn = 0 8543 8263 DO is = 0,7 … … 8557 8277 ENDDO 8558 8278 8559 !-- In case of the simple interpolation method the particles must not 8560 !-- be sorted in subboxes. Particles marked for deletion however, must be 8561 !-- deleted and number of particles must be recalculated as it is also 8562 !-- done for the trilinear particle advection interpolation method. 8279 !-- In case of the simple interpolation method the particles must not be sorted in subboxes. 8280 !-- Particles marked for deletion however, must be deleted and number of particles must be 8281 !-- recalculated as it is also done for the trilinear particle advection interpolation method. 8563 8282 ELSE 8564 8283 … … 8571 8290 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 8572 8291 ! 8573 !-- Repack particles array, i.e. delete particles and recalculate 8574 !-- number of particles 8292 !-- Repack particles array, i.e. delete particles and recalculate number of particles 8575 8293 CALL lpm_pack 8576 8294 prt_count(kp,jp,ip) = number_of_particles … … 8583 8301 END SUBROUTINE lpm_sort_and_delete 8584 8302 8585 8586 !------------------------------------------------------------------------------ !8303 8304 !--------------------------------------------------------------------------------------------------! 8587 8305 ! Description: 8588 8306 ! ------------ 8589 8307 !> Move all particles not marked for deletion to lowest indices (packing) 8590 !------------------------------------------------------------------------------ !8308 !--------------------------------------------------------------------------------------------------! 8591 8309 SUBROUTINE lpm_pack 8592 8310 … … 8594 8312 INTEGER(iwp) :: nn !< 8595 8313 ! 8596 !-- Find out elements marked for deletion and move data from highest index 8597 !-- values to these freeindices8314 !-- Find out elements marked for deletion and move data from highest index values to these free 8315 !-- indices 8598 8316 nn = number_of_particles 8599 8317 … … 8618 8336 8619 8337 ! 8620 !-- The number of deleted particles has been determined in routines 8621 !-- lpm_ boundary_conds, lpm_droplet_collision, and lpm_exchange_horiz8338 !-- The number of deleted particles has been determined in routines lpm_boundary_conds, 8339 !-- lpm_droplet_collision, and lpm_exchange_horiz 8622 8340 number_of_particles = nn 8623 8341 8624 END SUBROUTINE lpm_pack 8625 8626 8627 !------------------------------------------------------------------------------ !8342 END SUBROUTINE lpm_pack 8343 8344 8345 !--------------------------------------------------------------------------------------------------! 8628 8346 ! Description: 8629 8347 ! ------------ 8630 !> Sort particles in each sub-grid box into two groups: particles that already 8631 !> completed the LES timestep, and particles that need further timestepping to 8632 !> complete the LES timestep. 8633 !------------------------------------------------------------------------------! 8348 !> Sort particles in each sub-grid box into two groups: particles that already completed the LES 8349 !> timestep, and particles that need further timestepping to complete the LES timestep. 8350 !--------------------------------------------------------------------------------------------------! 8634 8351 SUBROUTINE lpm_sort_timeloop_done 8635 8352 … … 8661 8378 end_index = grid_particles(k,j,i)%end_index(nb) 8662 8379 ! 8663 !-- Allocate temporary array used for sorting. 8380 !-- Allocate temporary array used for sorting. 8664 8381 ALLOCATE( sort_particles(start_index:end_index) ) 8665 8382 ! 8666 !-- Determine number of particles already completed the LES 8667 !-- timestep, and write them into a temporary array.8383 !-- Determine number of particles already completed the LES timestep, and write them 8384 !-- into a temporary array. 8668 8385 nf = start_index 8669 8386 num_finalized = 0 … … 8676 8393 ENDDO 8677 8394 ! 8678 !-- Determine number of particles that not completed the LES 8679 !-- timestep, and write them into a temporary array.8395 !-- Determine number of particles that not completed the LES timestep, and write them 8396 !-- into a temporary array. 8680 8397 nnf = nf 8681 8398 DO n = start_index, end_index … … 8687 8404 ! 8688 8405 !-- Write back sorted particles 8689 particles(start_index:end_index) = & 8690 sort_particles(start_index:end_index) 8691 ! 8692 !-- Determine updated start_index, used to masked already 8693 !-- completed particles. 8694 grid_particles(k,j,i)%start_index(nb) = & 8695 grid_particles(k,j,i)%start_index(nb) & 8696 + num_finalized 8406 particles(start_index:end_index) = sort_particles(start_index:end_index) 8407 ! 8408 !-- Determine updated start_index, used to masked already 8409 !-- completed particles. 8410 grid_particles(k,j,i)%start_index(nb) = grid_particles(k,j,i)%start_index(nb) & 8411 + num_finalized 8697 8412 ! 8698 8413 !-- Deallocate dummy array 8699 8414 DEALLOCATE ( sort_particles ) 8700 8415 ! 8701 !-- Finally, if number of non-completed particles is non zero 8702 !-- in any of the sub-boxes, set control flag appropriately. 8703 IF ( nnf > nf ) & 8704 grid_particles(k,j,i)%time_loop_done = .FALSE. 8416 !-- Finally, if number of non-completed particles is non zero 8417 !-- in any of the sub-boxes, set control flag appropriately. 8418 IF ( nnf > nf ) grid_particles(k,j,i)%time_loop_done = .FALSE. 8705 8419 8706 8420 ENDDO … … 8709 8423 ENDDO 8710 8424 8711 END SUBROUTINE lpm_sort_timeloop_done 8425 END SUBROUTINE lpm_sort_timeloop_done 8712 8426 8713 8427 END MODULE lagrangian_particle_model_mod
Note: See TracChangeset
for help on using the changeset viewer.