SUBROUTINE lpm_advec !--------------------------------------------------------------------------------! ! This file is part of PALM. ! ! PALM is free software: you can redistribute it and/or modify it under the terms ! of the GNU General Public License as published by the Free Software Foundation, ! either version 3 of the License, or (at your option) any later version. ! ! PALM is distributed in the hope that it will be useful, but WITHOUT ANY ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR ! A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License along with ! PALM. If not, see . ! ! Copyright 1997-2014 Leibniz Universitaet Hannover !--------------------------------------------------------------------------------! ! ! Current revisions: ! ------------------ ! ! ! Former revisions: ! ----------------- ! $Id: lpm_advec.f90 1323 2014-03-20 17:09:54Z witha $ ! ! 1322 2014-03-20 16:38:49Z raasch ! REAL constants defined as wp_kind ! ! 1320 2014-03-20 08:40:49Z raasch ! ONLY-attribute added to USE-statements, ! kind-parameters added to all INTEGER and REAL declaration statements, ! kinds are defined in new module kinds, ! revision history before 2012 removed, ! comment fields (!:) to be used for variable explanations added to ! all variable declaration statements ! ! 1314 2014-03-14 18:25:17Z suehring ! Vertical logarithmic interpolation of horizontal particle speed for particles ! between roughness height and first vertical grid level. ! ! 1036 2012-10-22 13:43:42Z raasch ! code put under GPL (PALM 3.9) ! ! 849 2012-03-15 10:35:09Z raasch ! initial revision (former part of advec_particles) ! ! ! Description: ! ------------ ! Calculation of new particle positions due to advection using a simple Euler ! scheme. Particles may feel inertia effects. SGS transport can be included ! using the stochastic model of Weil et al. (2004, JAS, 61, 2877-2887). !------------------------------------------------------------------------------! USE arrays_3d, & ONLY: de_dx, de_dy, de_dz, diss, e, u, us, usws, v, vsws, w, z0, zu, zw USE control_parameters, & ONLY: atmos_ocean_sign, cloud_droplets, dt_3d, dt_3d_reached_l, dz, & g, kappa, molecular_viscosity, prandtl_layer, topography, & u_gtrans, v_gtrans USE grid_variables, & ONLY: ddx, dx, ddy, dy USE indices, & ONLY: nzb, nzb_s_inner, nzt USE kinds USE particle_attributes, & ONLY: c_0, density_ratio, dt_min_part, iran_part, log_z_z0, & number_of_particles, number_of_sublayers, particles, & particle_groups, offset_ocean_nzt, offset_ocean_nzt_m1, & sgs_wfu_part, sgs_wfv_part, sgs_wfw_part, use_sgs_for_particles,& vertical_particle_advection, z0_av_global USE statistics, & ONLY: hom IMPLICIT NONE INTEGER(iwp) :: agp !: INTEGER(iwp) :: gp_outside_of_building(1:8) !: INTEGER(iwp) :: i !: INTEGER(iwp) :: j !: INTEGER(iwp) :: k !: INTEGER(iwp) :: kw !: INTEGER(iwp) :: n !: INTEGER(iwp) :: num_gp !: REAL(wp) :: aa !: REAL(wp) :: bb !: REAL(wp) :: cc !: REAL(wp) :: d_sum !: REAL(wp) :: d_z_p_z0 !: REAL(wp) :: dd !: REAL(wp) :: de_dx_int !: REAL(wp) :: de_dx_int_l !: REAL(wp) :: de_dx_int_u !: REAL(wp) :: de_dy_int !: REAL(wp) :: de_dy_int_l !: REAL(wp) :: de_dy_int_u !: REAL(wp) :: de_dt !: REAL(wp) :: de_dt_min !: REAL(wp) :: de_dz_int !: REAL(wp) :: de_dz_int_l !: REAL(wp) :: de_dz_int_u !: REAL(wp) :: dens_ratio !: REAL(wp) :: diss_int !: REAL(wp) :: diss_int_l !: REAL(wp) :: diss_int_u !: REAL(wp) :: dt_gap !: REAL(wp) :: dt_particle !: REAL(wp) :: dt_particle_m !: REAL(wp) :: e_int !: REAL(wp) :: e_int_l !: REAL(wp) :: e_int_u !: REAL(wp) :: e_mean_int !: REAL(wp) :: exp_arg !: REAL(wp) :: exp_term !: REAL(wp) :: fs_int !: REAL(wp) :: gg !: REAL(wp) :: height_int !: REAL(wp) :: height_p !: REAL(wp) :: lagr_timescale !: REAL(wp) :: location(1:30,1:3) !: REAL(wp) :: log_z_z0_int !: REAL(wp) :: random_gauss !: REAL(wp) :: u_int !: REAL(wp) :: u_int_l !: REAL(wp) :: u_int_u !: REAL(wp) :: us_int !: REAL(wp) :: v_int !: REAL(wp) :: v_int_l !: REAL(wp) :: v_int_u !: REAL(wp) :: vv_int !: REAL(wp) :: w_int !: REAL(wp) :: w_int_l !: REAL(wp) :: w_int_u !: REAL(wp) :: x !: REAL(wp) :: y !: REAL(wp) :: z_p !: REAL(wp), DIMENSION(1:30) :: d_gp_pl !: REAL(wp), DIMENSION(1:30) :: de_dxi !: REAL(wp), DIMENSION(1:30) :: de_dyi !: REAL(wp), DIMENSION(1:30) :: de_dzi !: REAL(wp), DIMENSION(1:30) :: dissi !: REAL(wp), DIMENSION(1:30) :: ei !: ! !-- Determine height of Prandtl layer and distance between Prandtl-layer !-- height and horizontal mean roughness height, which are required for !-- vertical logarithmic interpolation of horizontal particle speeds !-- (for particles below first vertical grid level). z_p = zu(nzb+1) - zw(nzb) d_z_p_z0 = 1.0 / ( z_p - z0_av_global ) DO n = 1, number_of_particles ! !-- Move particle only if the LES timestep has not (approximately) been !-- reached IF ( ( dt_3d - particles(n)%dt_sum ) < 1E-8 ) CYCLE ! !-- Determine bottom index k = ( particles(n)%z + 0.5 * dz * atmos_ocean_sign ) / dz & + offset_ocean_nzt ! only exact if equidistant ! !-- Interpolation of the u velocity component onto particle position. !-- Particles are interpolation bi-linearly in the horizontal and a !-- linearly in the vertical. An exception is made for particles below !-- the first vertical grid level in case of a prandtl layer. In this !-- case the horizontal particle velocity components are determined using !-- Monin-Obukhov relations (if branch). !-- First, check if particle is located below first vertical grid level !-- (Prandtl-layer height) IF ( prandtl_layer .AND. particles(n)%z < z_p ) THEN ! !-- Resolved-scale horizontal particle velocity is zero below z0. IF ( particles(n)%z < z0_av_global ) THEN u_int = 0.0 ELSE ! !-- Determine the sublayer. Further used as index. height_p = ( particles(n)%z - z0_av_global ) & * REAL( number_of_sublayers, KIND=wp ) & * d_z_p_z0 ! !-- Calculate LOG(z/z0) for exact particle height. Therefore, !-- interpolate linearly between precalculated logarithm. log_z_z0_int = log_z_z0(INT(height_p)) & + ( height_p - INT(height_p) ) & * ( log_z_z0(INT(height_p)+1) & - log_z_z0(INT(height_p)) & ) ! !-- Neutral solution is applied for all situations, e.g. also for !-- unstable and stable situations. Even though this is not exact !-- this saves a lot of CPU time since several calls of intrinsic !-- FORTRAN procedures (LOG, ATAN) are avoided, This is justified !-- as sensitivity studies revealed no significant effect of !-- using the neutral solution also for un/stable situations. !-- Calculated left and bottom index on u grid. i = ( particles(n)%x + 0.5 * dx ) * ddx j = particles(n)%y * ddy us_int = 0.5 * ( us(j,i) + us(j,i-1) ) u_int = -usws(j,i) / ( us_int * kappa + 1E-10_wp ) & * log_z_z0_int ENDIF ! !-- Particle above the first grid level. Bi-linear interpolation in the !-- horizontal and linear interpolation in the vertical direction. ELSE ! !-- Interpolate u velocity-component, determine left, front, bottom !-- index of u-array. Adopt k index from above i = ( particles(n)%x + 0.5 * dx ) * ddx j = particles(n)%y * ddy ! !-- Interpolation of the velocity components in the xy-plane x = particles(n)%x + ( 0.5 - i ) * dx y = particles(n)%y - j * dy aa = x**2 + y**2 bb = ( dx - x )**2 + y**2 cc = x**2 + ( dy - y )**2 dd = ( dx - x )**2 + ( dy - y )**2 gg = aa + bb + cc + dd u_int_l = ( ( gg - aa ) * u(k,j,i) + ( gg - bb ) * u(k,j,i+1) & + ( gg - cc ) * u(k,j+1,i) + ( gg - dd ) * u(k,j+1,i+1)& ) / ( 3.0 * gg ) - u_gtrans IF ( k+1 == nzt+1 ) THEN u_int = u_int_l ELSE u_int_u = ( ( gg-aa ) * u(k+1,j,i) + ( gg-bb ) * u(k+1,j,i+1) & + ( gg-cc ) * u(k+1,j+1,i) + ( gg-dd ) * u(k+1,j+1,i+1) & ) / ( 3.0 * gg ) - u_gtrans u_int = u_int_l + ( particles(n)%z - zu(k) ) / dz * & ( u_int_u - u_int_l ) ENDIF ENDIF ! !-- Same procedure for interpolation of the v velocity-component. IF ( prandtl_layer .AND. particles(n)%z < z_p ) THEN ! !-- Resolved-scale horizontal particle velocity is zero below z0. IF ( particles(n)%z < z0_av_global ) THEN v_int = 0.0 ELSE ! !-- Neutral solution is applied for all situations, e.g. also for !-- unstable and stable situations. Even though this is not exact !-- this saves a lot of CPU time since several calls of intrinsic !-- FORTRAN procedures (LOG, ATAN) are avoided, This is justified !-- as sensitivity studies revealed no significant effect of !-- using the neutral solution also for un/stable situations. !-- Calculated left and bottom index on v grid. i = particles(n)%x * ddx j = ( particles(n)%y + 0.5 * dy ) * ddy us_int = 0.5 * ( us(j,i) + us(j-1,i) ) v_int = -vsws(j,i) / ( us_int * kappa + 1E-10_wp ) & * log_z_z0_int ENDIF ! !-- Particle above the first grid level. Bi-linear interpolation in the !-- horizontal and linear interpolation in the vertical direction. ELSE i = particles(n)%x * ddx j = ( particles(n)%y + 0.5 * dy ) * ddy x = particles(n)%x - i * dx y = particles(n)%y + ( 0.5 - j ) * dy aa = x**2 + y**2 bb = ( dx - x )**2 + y**2 cc = x**2 + ( dy - y )**2 dd = ( dx - x )**2 + ( dy - y )**2 gg = aa + bb + cc + dd v_int_l = ( ( gg - aa ) * v(k,j,i) + ( gg - bb ) * v(k,j,i+1) & + ( gg - cc ) * v(k,j+1,i) + ( gg - dd ) * v(k,j+1,i+1)& ) / ( 3.0 * gg ) - v_gtrans IF ( k+1 == nzt+1 ) THEN v_int = v_int_l ELSE v_int_u = ( ( gg-aa ) * v(k+1,j,i) + ( gg-bb ) * v(k+1,j,i+1) & + ( gg-cc ) * v(k+1,j+1,i) + ( gg-dd ) * v(k+1,j+1,i+1) & ) / ( 3.0 * gg ) - v_gtrans v_int = v_int_l + ( particles(n)%z - zu(k) ) / dz * & ( v_int_u - v_int_l ) ENDIF ENDIF ! !-- Same procedure for interpolation of the w velocity-component IF ( vertical_particle_advection(particles(n)%group) ) THEN i = particles(n)%x * ddx j = particles(n)%y * ddy k = particles(n)%z / dz + offset_ocean_nzt_m1 x = particles(n)%x - i * dx y = particles(n)%y - j * dy aa = x**2 + y**2 bb = ( dx - x )**2 + y**2 cc = x**2 + ( dy - y )**2 dd = ( dx - x )**2 + ( dy - y )**2 gg = aa + bb + cc + dd w_int_l = ( ( gg - aa ) * w(k,j,i) + ( gg - bb ) * w(k,j,i+1) & + ( gg - cc ) * w(k,j+1,i) + ( gg - dd ) * w(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( k+1 == nzt+1 ) THEN w_int = w_int_l ELSE w_int_u = ( ( gg-aa ) * w(k+1,j,i) + & ( gg-bb ) * w(k+1,j,i+1) + & ( gg-cc ) * w(k+1,j+1,i) + & ( gg-dd ) * w(k+1,j+1,i+1) & ) / ( 3.0 * gg ) w_int = w_int_l + ( particles(n)%z - zw(k) ) / dz * & ( w_int_u - w_int_l ) ENDIF ELSE w_int = 0.0 ENDIF ! !-- Interpolate and calculate quantities needed for calculating the SGS !-- velocities IF ( use_sgs_for_particles ) THEN ! !-- Interpolate TKE i = particles(n)%x * ddx j = particles(n)%y * ddy k = ( particles(n)%z + 0.5 * dz * atmos_ocean_sign ) / dz & + offset_ocean_nzt ! only exact if eq.dist IF ( topography == 'flat' ) THEN x = particles(n)%x - i * dx y = particles(n)%y - j * dy aa = x**2 + y**2 bb = ( dx - x )**2 + y**2 cc = x**2 + ( dy - y )**2 dd = ( dx - x )**2 + ( dy - y )**2 gg = aa + bb + cc + dd e_int_l = ( ( gg-aa ) * e(k,j,i) + ( gg-bb ) * e(k,j,i+1) & + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( k+1 == nzt+1 ) THEN e_int = e_int_l ELSE e_int_u = ( ( gg - aa ) * e(k+1,j,i) + & ( gg - bb ) * e(k+1,j,i+1) + & ( gg - cc ) * e(k+1,j+1,i) + & ( gg - dd ) * e(k+1,j+1,i+1) & ) / ( 3.0 * gg ) e_int = e_int_l + ( particles(n)%z - zu(k) ) / dz * & ( e_int_u - e_int_l ) ENDIF ! !-- Interpolate the TKE gradient along x (adopt incides i,j,k and !-- all position variables from above (TKE)) de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i) + & ( gg - bb ) * de_dx(k,j,i+1) + & ( gg - cc ) * de_dx(k,j+1,i) + & ( gg - dd ) * de_dx(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN de_dx_int = de_dx_int_l ELSE de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i) + & ( gg - bb ) * de_dx(k+1,j,i+1) + & ( gg - cc ) * de_dx(k+1,j+1,i) + & ( gg - dd ) * de_dx(k+1,j+1,i+1) & ) / ( 3.0 * gg ) de_dx_int = de_dx_int_l + ( particles(n)%z - zu(k) ) / dz * & ( de_dx_int_u - de_dx_int_l ) ENDIF ! !-- Interpolate the TKE gradient along y de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i) + & ( gg - bb ) * de_dy(k,j,i+1) + & ( gg - cc ) * de_dy(k,j+1,i) + & ( gg - dd ) * de_dy(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN de_dy_int = de_dy_int_l ELSE de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i) + & ( gg - bb ) * de_dy(k+1,j,i+1) + & ( gg - cc ) * de_dy(k+1,j+1,i) + & ( gg - dd ) * de_dy(k+1,j+1,i+1) & ) / ( 3.0 * gg ) de_dy_int = de_dy_int_l + ( particles(n)%z - zu(k) ) / dz * & ( de_dy_int_u - de_dy_int_l ) ENDIF ! !-- Interpolate the TKE gradient along z IF ( particles(n)%z < 0.5 * dz ) THEN de_dz_int = 0.0 ELSE de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i) + & ( gg - bb ) * de_dz(k,j,i+1) + & ( gg - cc ) * de_dz(k,j+1,i) + & ( gg - dd ) * de_dz(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN de_dz_int = de_dz_int_l ELSE de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i) + & ( gg - bb ) * de_dz(k+1,j,i+1) + & ( gg - cc ) * de_dz(k+1,j+1,i) + & ( gg - dd ) * de_dz(k+1,j+1,i+1) & ) / ( 3.0 * gg ) de_dz_int = de_dz_int_l + ( particles(n)%z - zu(k) ) / dz * & ( de_dz_int_u - de_dz_int_l ) ENDIF ENDIF ! !-- Interpolate the dissipation of TKE diss_int_l = ( ( gg - aa ) * diss(k,j,i) + & ( gg - bb ) * diss(k,j,i+1) + & ( gg - cc ) * diss(k,j+1,i) + & ( gg - dd ) * diss(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( k+1 == nzt+1 ) THEN diss_int = diss_int_l ELSE diss_int_u = ( ( gg - aa ) * diss(k+1,j,i) + & ( gg - bb ) * diss(k+1,j,i+1) + & ( gg - cc ) * diss(k+1,j+1,i) + & ( gg - dd ) * diss(k+1,j+1,i+1) & ) / ( 3.0 * gg ) diss_int = diss_int_l + ( particles(n)%z - zu(k) ) / dz * & ( diss_int_u - diss_int_l ) ENDIF ELSE ! !-- In case that there are buildings it has to be determined !-- how many of the gridpoints defining the particle box are !-- situated within a building !-- gp_outside_of_building(1): i,j,k !-- gp_outside_of_building(2): i,j+1,k !-- gp_outside_of_building(3): i,j,k+1 !-- gp_outside_of_building(4): i,j+1,k+1 !-- gp_outside_of_building(5): i+1,j,k !-- gp_outside_of_building(6): i+1,j+1,k !-- gp_outside_of_building(7): i+1,j,k+1 !-- gp_outside_of_building(8): i+1,j+1,k+1 gp_outside_of_building = 0 location = 0.0 num_gp = 0 IF ( k > nzb_s_inner(j,i) .OR. nzb_s_inner(j,i) == 0 ) THEN num_gp = num_gp + 1 gp_outside_of_building(1) = 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j,i) dissi(num_gp) = diss(k,j,i) de_dxi(num_gp) = de_dx(k,j,i) de_dyi(num_gp) = de_dy(k,j,i) de_dzi(num_gp) = de_dz(k,j,i) ENDIF IF ( k > nzb_s_inner(j+1,i) .OR. nzb_s_inner(j+1,i) == 0 ) & THEN num_gp = num_gp + 1 gp_outside_of_building(2) = 1 location(num_gp,1) = i * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j+1,i) dissi(num_gp) = diss(k,j+1,i) de_dxi(num_gp) = de_dx(k,j+1,i) de_dyi(num_gp) = de_dy(k,j+1,i) de_dzi(num_gp) = de_dz(k,j+1,i) ENDIF IF ( k+1 > nzb_s_inner(j,i) .OR. nzb_s_inner(j,i) == 0 ) THEN num_gp = num_gp + 1 gp_outside_of_building(3) = 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy location(num_gp,3) = (k+1) * dz - 0.5 * dz ei(num_gp) = e(k+1,j,i) dissi(num_gp) = diss(k+1,j,i) de_dxi(num_gp) = de_dx(k+1,j,i) de_dyi(num_gp) = de_dy(k+1,j,i) de_dzi(num_gp) = de_dz(k+1,j,i) ENDIF IF ( k+1 > nzb_s_inner(j+1,i) .OR. nzb_s_inner(j+1,i) == 0 ) & THEN num_gp = num_gp + 1 gp_outside_of_building(4) = 1 location(num_gp,1) = i * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = (k+1) * dz - 0.5 * dz ei(num_gp) = e(k+1,j+1,i) dissi(num_gp) = diss(k+1,j+1,i) de_dxi(num_gp) = de_dx(k+1,j+1,i) de_dyi(num_gp) = de_dy(k+1,j+1,i) de_dzi(num_gp) = de_dz(k+1,j+1,i) ENDIF IF ( k > nzb_s_inner(j,i+1) .OR. nzb_s_inner(j,i+1) == 0 ) & THEN num_gp = num_gp + 1 gp_outside_of_building(5) = 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j,i+1) dissi(num_gp) = diss(k,j,i+1) de_dxi(num_gp) = de_dx(k,j,i+1) de_dyi(num_gp) = de_dy(k,j,i+1) de_dzi(num_gp) = de_dz(k,j,i+1) ENDIF IF ( k > nzb_s_inner(j+1,i+1) .OR. nzb_s_inner(j+1,i+1) == 0 ) & THEN num_gp = num_gp + 1 gp_outside_of_building(6) = 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j+1,i+1) dissi(num_gp) = diss(k,j+1,i+1) de_dxi(num_gp) = de_dx(k,j+1,i+1) de_dyi(num_gp) = de_dy(k,j+1,i+1) de_dzi(num_gp) = de_dz(k,j+1,i+1) ENDIF IF ( k+1 > nzb_s_inner(j,i+1) .OR. nzb_s_inner(j,i+1) == 0 ) & THEN num_gp = num_gp + 1 gp_outside_of_building(7) = 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy location(num_gp,3) = (k+1) * dz - 0.5 * dz ei(num_gp) = e(k+1,j,i+1) dissi(num_gp) = diss(k+1,j,i+1) de_dxi(num_gp) = de_dx(k+1,j,i+1) de_dyi(num_gp) = de_dy(k+1,j,i+1) de_dzi(num_gp) = de_dz(k+1,j,i+1) ENDIF IF ( k+1 > nzb_s_inner(j+1,i+1) .OR. nzb_s_inner(j+1,i+1) == 0)& THEN num_gp = num_gp + 1 gp_outside_of_building(8) = 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = (k+1) * dz - 0.5 * dz ei(num_gp) = e(k+1,j+1,i+1) dissi(num_gp) = diss(k+1,j+1,i+1) de_dxi(num_gp) = de_dx(k+1,j+1,i+1) de_dyi(num_gp) = de_dy(k+1,j+1,i+1) de_dzi(num_gp) = de_dz(k+1,j+1,i+1) ENDIF ! !-- If all gridpoints are situated outside of a building, then the !-- ordinary interpolation scheme can be used. IF ( num_gp == 8 ) THEN x = particles(n)%x - i * dx y = particles(n)%y - j * dy aa = x**2 + y**2 bb = ( dx - x )**2 + y**2 cc = x**2 + ( dy - y )**2 dd = ( dx - x )**2 + ( dy - y )**2 gg = aa + bb + cc + dd e_int_l = (( gg-aa ) * e(k,j,i) + ( gg-bb ) * e(k,j,i+1) & + ( gg-cc ) * e(k,j+1,i) + ( gg-dd ) * e(k,j+1,i+1)& ) / ( 3.0 * gg ) IF ( k+1 == nzt+1 ) THEN e_int = e_int_l ELSE e_int_u = ( ( gg - aa ) * e(k+1,j,i) + & ( gg - bb ) * e(k+1,j,i+1) + & ( gg - cc ) * e(k+1,j+1,i) + & ( gg - dd ) * e(k+1,j+1,i+1) & ) / ( 3.0 * gg ) e_int = e_int_l + ( particles(n)%z - zu(k) ) / dz * & ( e_int_u - e_int_l ) ENDIF ! !-- Interpolate the TKE gradient along x (adopt incides i,j,k !-- and all position variables from above (TKE)) de_dx_int_l = ( ( gg - aa ) * de_dx(k,j,i) + & ( gg - bb ) * de_dx(k,j,i+1) + & ( gg - cc ) * de_dx(k,j+1,i) + & ( gg - dd ) * de_dx(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN de_dx_int = de_dx_int_l ELSE de_dx_int_u = ( ( gg - aa ) * de_dx(k+1,j,i) + & ( gg - bb ) * de_dx(k+1,j,i+1) + & ( gg - cc ) * de_dx(k+1,j+1,i) + & ( gg - dd ) * de_dx(k+1,j+1,i+1) & ) / ( 3.0 * gg ) de_dx_int = de_dx_int_l + ( particles(n)%z - zu(k) ) / & dz * ( de_dx_int_u - de_dx_int_l ) ENDIF ! !-- Interpolate the TKE gradient along y de_dy_int_l = ( ( gg - aa ) * de_dy(k,j,i) + & ( gg - bb ) * de_dy(k,j,i+1) + & ( gg - cc ) * de_dy(k,j+1,i) + & ( gg - dd ) * de_dy(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN de_dy_int = de_dy_int_l ELSE de_dy_int_u = ( ( gg - aa ) * de_dy(k+1,j,i) + & ( gg - bb ) * de_dy(k+1,j,i+1) + & ( gg - cc ) * de_dy(k+1,j+1,i) + & ( gg - dd ) * de_dy(k+1,j+1,i+1) & ) / ( 3.0 * gg ) de_dy_int = de_dy_int_l + ( particles(n)%z - zu(k) ) / & dz * ( de_dy_int_u - de_dy_int_l ) ENDIF ! !-- Interpolate the TKE gradient along z IF ( particles(n)%z < 0.5 * dz ) THEN de_dz_int = 0.0 ELSE de_dz_int_l = ( ( gg - aa ) * de_dz(k,j,i) + & ( gg - bb ) * de_dz(k,j,i+1) + & ( gg - cc ) * de_dz(k,j+1,i) + & ( gg - dd ) * de_dz(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( ( k+1 == nzt+1 ) .OR. ( k == nzb ) ) THEN de_dz_int = de_dz_int_l ELSE de_dz_int_u = ( ( gg - aa ) * de_dz(k+1,j,i) + & ( gg - bb ) * de_dz(k+1,j,i+1) + & ( gg - cc ) * de_dz(k+1,j+1,i) + & ( gg - dd ) * de_dz(k+1,j+1,i+1) & ) / ( 3.0 * gg ) de_dz_int = de_dz_int_l + ( particles(n)%z - zu(k) ) /& dz * ( de_dz_int_u - de_dz_int_l ) ENDIF ENDIF ! !-- Interpolate the dissipation of TKE diss_int_l = ( ( gg - aa ) * diss(k,j,i) + & ( gg - bb ) * diss(k,j,i+1) + & ( gg - cc ) * diss(k,j+1,i) + & ( gg - dd ) * diss(k,j+1,i+1) & ) / ( 3.0 * gg ) IF ( k+1 == nzt+1 ) THEN diss_int = diss_int_l ELSE diss_int_u = ( ( gg - aa ) * diss(k+1,j,i) + & ( gg - bb ) * diss(k+1,j,i+1) + & ( gg - cc ) * diss(k+1,j+1,i) + & ( gg - dd ) * diss(k+1,j+1,i+1) & ) / ( 3.0 * gg ) diss_int = diss_int_l + ( particles(n)%z - zu(k) ) / dz *& ( diss_int_u - diss_int_l ) ENDIF ELSE ! !-- If wall between gridpoint 1 and gridpoint 5, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(1) == 1 .AND. & gp_outside_of_building(5) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j,i) dissi(num_gp) = diss(k,j,i) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k,j,i) de_dzi(num_gp) = de_dz(k,j,i) ENDIF IF ( gp_outside_of_building(5) == 1 .AND. & gp_outside_of_building(1) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j,i+1) dissi(num_gp) = diss(k,j,i+1) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k,j,i+1) de_dzi(num_gp) = de_dz(k,j,i+1) ENDIF ! !-- If wall between gridpoint 5 and gridpoint 6, then !-- then Neumann boundary condition has to be applied IF ( gp_outside_of_building(5) == 1 .AND. & gp_outside_of_building(6) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j,i+1) dissi(num_gp) = diss(k,j,i+1) de_dxi(num_gp) = de_dx(k,j,i+1) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k,j,i+1) ENDIF IF ( gp_outside_of_building(6) == 1 .AND. & gp_outside_of_building(5) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j+1,i+1) dissi(num_gp) = diss(k,j+1,i+1) de_dxi(num_gp) = de_dx(k,j+1,i+1) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k,j+1,i+1) ENDIF ! !-- If wall between gridpoint 2 and gridpoint 6, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(2) == 1 .AND. & gp_outside_of_building(6) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j+1,i) dissi(num_gp) = diss(k,j+1,i) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k,j+1,i) de_dzi(num_gp) = de_dz(k,j+1,i) ENDIF IF ( gp_outside_of_building(6) == 1 .AND. & gp_outside_of_building(2) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j+1,i+1) dissi(num_gp) = diss(k,j+1,i+1) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k,j+1,i+1) de_dzi(num_gp) = de_dz(k,j+1,i+1) ENDIF ! !-- If wall between gridpoint 1 and gridpoint 2, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(1) == 1 .AND. & gp_outside_of_building(2) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j,i) dissi(num_gp) = diss(k,j,i) de_dxi(num_gp) = de_dx(k,j,i) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k,j,i) ENDIF IF ( gp_outside_of_building(2) == 1 .AND. & gp_outside_of_building(1) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz - 0.5 * dz ei(num_gp) = e(k,j+1,i) dissi(num_gp) = diss(k,j+1,i) de_dxi(num_gp) = de_dx(k,j+1,i) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k,j+1,i) ENDIF ! !-- If wall between gridpoint 3 and gridpoint 7, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(3) == 1 .AND. & gp_outside_of_building(7) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j,i) dissi(num_gp) = diss(k+1,j,i) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k+1,j,i) de_dzi(num_gp) = de_dz(k+1,j,i) ENDIF IF ( gp_outside_of_building(7) == 1 .AND. & gp_outside_of_building(3) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j,i+1) dissi(num_gp) = diss(k+1,j,i+1) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k+1,j,i+1) de_dzi(num_gp) = de_dz(k+1,j,i+1) ENDIF ! !-- If wall between gridpoint 7 and gridpoint 8, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(7) == 1 .AND. & gp_outside_of_building(8) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j,i+1) dissi(num_gp) = diss(k+1,j,i+1) de_dxi(num_gp) = de_dx(k+1,j,i+1) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k+1,j,i+1) ENDIF IF ( gp_outside_of_building(8) == 1 .AND. & gp_outside_of_building(7) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j+1,i+1) dissi(num_gp) = diss(k+1,j+1,i+1) de_dxi(num_gp) = de_dx(k+1,j+1,i+1) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k+1,j+1,i+1) ENDIF ! !-- If wall between gridpoint 4 and gridpoint 8, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(4) == 1 .AND. & gp_outside_of_building(8) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j+1,i) dissi(num_gp) = diss(k+1,j+1,i) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k+1,j+1,i) de_dzi(num_gp) = de_dz(k+1,j+1,i) ENDIF IF ( gp_outside_of_building(8) == 1 .AND. & gp_outside_of_building(4) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx + 0.5 * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j+1,i+1) dissi(num_gp) = diss(k+1,j+1,i+1) de_dxi(num_gp) = 0.0 de_dyi(num_gp) = de_dy(k+1,j+1,i+1) de_dzi(num_gp) = de_dz(k+1,j+1,i+1) ENDIF ! !-- If wall between gridpoint 3 and gridpoint 4, then !-- Neumann boundary condition has to be applied IF ( gp_outside_of_building(3) == 1 .AND. & gp_outside_of_building(4) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j,i) dissi(num_gp) = diss(k+1,j,i) de_dxi(num_gp) = de_dx(k+1,j,i) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k+1,j,i) ENDIF IF ( gp_outside_of_building(4) == 1 .AND. & gp_outside_of_building(3) == 0 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy + 0.5 * dy location(num_gp,3) = k * dz + 0.5 * dz ei(num_gp) = e(k+1,j+1,i) dissi(num_gp) = diss(k+1,j+1,i) de_dxi(num_gp) = de_dx(k+1,j+1,i) de_dyi(num_gp) = 0.0 de_dzi(num_gp) = de_dz(k+1,j+1,i) ENDIF ! !-- If wall between gridpoint 1 and gridpoint 3, then !-- Neumann boundary condition has to be applied !-- (only one case as only building beneath is possible) IF ( gp_outside_of_building(1) == 0 .AND. & gp_outside_of_building(3) == 1 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz ei(num_gp) = e(k+1,j,i) dissi(num_gp) = diss(k+1,j,i) de_dxi(num_gp) = de_dx(k+1,j,i) de_dyi(num_gp) = de_dy(k+1,j,i) de_dzi(num_gp) = 0.0 ENDIF ! !-- If wall between gridpoint 5 and gridpoint 7, then !-- Neumann boundary condition has to be applied !-- (only one case as only building beneath is possible) IF ( gp_outside_of_building(5) == 0 .AND. & gp_outside_of_building(7) == 1 ) THEN num_gp = num_gp + 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = j * dy location(num_gp,3) = k * dz ei(num_gp) = e(k+1,j,i+1) dissi(num_gp) = diss(k+1,j,i+1) de_dxi(num_gp) = de_dx(k+1,j,i+1) de_dyi(num_gp) = de_dy(k+1,j,i+1) de_dzi(num_gp) = 0.0 ENDIF ! !-- If wall between gridpoint 2 and gridpoint 4, then !-- Neumann boundary condition has to be applied !-- (only one case as only building beneath is possible) IF ( gp_outside_of_building(2) == 0 .AND. & gp_outside_of_building(4) == 1 ) THEN num_gp = num_gp + 1 location(num_gp,1) = i * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz ei(num_gp) = e(k+1,j+1,i) dissi(num_gp) = diss(k+1,j+1,i) de_dxi(num_gp) = de_dx(k+1,j+1,i) de_dyi(num_gp) = de_dy(k+1,j+1,i) de_dzi(num_gp) = 0.0 ENDIF ! !-- If wall between gridpoint 6 and gridpoint 8, then !-- Neumann boundary condition has to be applied !-- (only one case as only building beneath is possible) IF ( gp_outside_of_building(6) == 0 .AND. & gp_outside_of_building(8) == 1 ) THEN num_gp = num_gp + 1 location(num_gp,1) = (i+1) * dx location(num_gp,2) = (j+1) * dy location(num_gp,3) = k * dz ei(num_gp) = e(k+1,j+1,i+1) dissi(num_gp) = diss(k+1,j+1,i+1) de_dxi(num_gp) = de_dx(k+1,j+1,i+1) de_dyi(num_gp) = de_dy(k+1,j+1,i+1) de_dzi(num_gp) = 0.0 ENDIF ! !-- Carry out the interpolation IF ( num_gp == 1 ) THEN ! !-- If only one of the gridpoints is situated outside of the !-- building, it follows that the values at the particle !-- location are the same as the gridpoint values e_int = ei(num_gp) diss_int = dissi(num_gp) de_dx_int = de_dxi(num_gp) de_dy_int = de_dyi(num_gp) de_dz_int = de_dzi(num_gp) ELSE IF ( num_gp > 1 ) THEN d_sum = 0.0 ! !-- Evaluation of the distances between the gridpoints !-- contributing to the interpolated values, and the particle !-- location DO agp = 1, num_gp d_gp_pl(agp) = ( particles(n)%x-location(agp,1) )**2 & + ( particles(n)%y-location(agp,2) )**2 & + ( particles(n)%z-location(agp,3) )**2 d_sum = d_sum + d_gp_pl(agp) ENDDO ! !-- Finally the interpolation can be carried out e_int = 0.0 diss_int = 0.0 de_dx_int = 0.0 de_dy_int = 0.0 de_dz_int = 0.0 DO agp = 1, num_gp e_int = e_int + ( d_sum - d_gp_pl(agp) ) * & ei(agp) / ( (num_gp-1) * d_sum ) diss_int = diss_int + ( d_sum - d_gp_pl(agp) ) * & dissi(agp) / ( (num_gp-1) * d_sum ) de_dx_int = de_dx_int + ( d_sum - d_gp_pl(agp) ) * & de_dxi(agp) / ( (num_gp-1) * d_sum ) de_dy_int = de_dy_int + ( d_sum - d_gp_pl(agp) ) * & de_dyi(agp) / ( (num_gp-1) * d_sum ) de_dz_int = de_dz_int + ( d_sum - d_gp_pl(agp) ) * & de_dzi(agp) / ( (num_gp-1) * d_sum ) ENDDO ENDIF ENDIF ENDIF ! !-- Vertically interpolate the horizontally averaged SGS TKE and !-- resolved-scale velocity variances and use the interpolated values !-- to calculate the coefficient fs, which is a measure of the ratio !-- of the subgrid-scale turbulent kinetic energy to the total amount !-- of turbulent kinetic energy. IF ( k == 0 ) THEN e_mean_int = hom(0,1,8,0) ELSE e_mean_int = hom(k,1,8,0) + & ( hom(k+1,1,8,0) - hom(k,1,8,0) ) / & ( zu(k+1) - zu(k) ) * & ( particles(n)%z - zu(k) ) ENDIF kw = particles(n)%z / dz IF ( k == 0 ) THEN aa = hom(k+1,1,30,0) * ( particles(n)%z / & ( 0.5 * ( zu(k+1) - zu(k) ) ) ) bb = hom(k+1,1,31,0) * ( particles(n)%z / & ( 0.5 * ( zu(k+1) - zu(k) ) ) ) cc = hom(kw+1,1,32,0) * ( particles(n)%z / & ( 1.0 * ( zw(kw+1) - zw(kw) ) ) ) ELSE aa = hom(k,1,30,0) + ( hom(k+1,1,30,0) - hom(k,1,30,0) ) * & ( ( particles(n)%z - zu(k) ) / ( zu(k+1) - zu(k) ) ) bb = hom(k,1,31,0) + ( hom(k+1,1,31,0) - hom(k,1,31,0) ) * & ( ( particles(n)%z - zu(k) ) / ( zu(k+1) - zu(k) ) ) cc = hom(kw,1,32,0) + ( hom(kw+1,1,32,0)-hom(kw,1,32,0) ) *& ( ( particles(n)%z - zw(kw) ) / ( zw(kw+1)-zw(kw) ) ) ENDIF vv_int = ( 1.0_wp / 3.0_wp ) * ( aa + bb + cc ) fs_int = ( 2.0_wp / 3.0_wp ) * e_mean_int / & ( vv_int + ( 2.0_wp / 3.0_wp ) * e_mean_int ) ! !-- Calculate the Lagrangian timescale according to Weil et al. (2004). lagr_timescale = ( 4.0 * e_int ) / & ( 3.0 * fs_int * c_0 * diss_int ) ! !-- Calculate the next particle timestep. dt_gap is the time needed to !-- complete the current LES timestep. dt_gap = dt_3d - particles(n)%dt_sum dt_particle = MIN( dt_3d, 0.025 * lagr_timescale, dt_gap ) ! !-- The particle timestep should not be too small in order to prevent !-- the number of particle timesteps of getting too large IF ( dt_particle < dt_min_part .AND. dt_min_part < dt_gap ) & THEN dt_particle = dt_min_part ENDIF ! !-- Calculate the SGS velocity components IF ( particles(n)%age == 0.0 ) THEN ! !-- For new particles the SGS components are derived from the SGS !-- TKE. Limit the Gaussian random number to the interval !-- [-5.0*sigma, 5.0*sigma] in order to prevent the SGS velocities !-- from becoming unrealistically large. particles(n)%rvar1 = SQRT( 2.0 * sgs_wfu_part * e_int ) * & ( random_gauss( iran_part, 5.0_wp ) - 1.0_wp ) particles(n)%rvar2 = SQRT( 2.0 * sgs_wfv_part * e_int ) * & ( random_gauss( iran_part, 5.0_wp ) - 1.0_wp ) particles(n)%rvar3 = SQRT( 2.0 * sgs_wfw_part * e_int ) * & ( random_gauss( iran_part, 5.0_wp ) - 1.0_wp ) ELSE ! !-- Restriction of the size of the new timestep: compared to the !-- previous timestep the increase must not exceed 200% dt_particle_m = particles(n)%age - particles(n)%age_m IF ( dt_particle > 2.0 * dt_particle_m ) THEN dt_particle = 2.0 * dt_particle_m ENDIF ! !-- For old particles the SGS components are correlated with the !-- values from the previous timestep. Random numbers have also to !-- be limited (see above). !-- As negative values for the subgrid TKE are not allowed, the !-- change of the subgrid TKE with time cannot be smaller than !-- -e_int/dt_particle. This value is used as a lower boundary !-- value for the change of TKE de_dt_min = - e_int / dt_particle de_dt = ( e_int - particles(n)%e_m ) / dt_particle_m IF ( de_dt < de_dt_min ) THEN de_dt = de_dt_min ENDIF particles(n)%rvar1 = particles(n)%rvar1 - fs_int * c_0 * & diss_int * particles(n)%rvar1 * dt_particle /& ( 4.0 * sgs_wfu_part * e_int ) + & ( 2.0 * sgs_wfu_part * de_dt * & particles(n)%rvar1 / & ( 2.0 * sgs_wfu_part * e_int ) + de_dx_int & ) * dt_particle / 2.0 + & SQRT( fs_int * c_0 * diss_int ) * & ( random_gauss( iran_part, 5.0_wp ) - 1.0_wp ) * & SQRT( dt_particle ) particles(n)%rvar2 = particles(n)%rvar2 - fs_int * c_0 * & diss_int * particles(n)%rvar2 * dt_particle /& ( 4.0 * sgs_wfv_part * e_int ) + & ( 2.0 * sgs_wfv_part * de_dt * & particles(n)%rvar2 / & ( 2.0 * sgs_wfv_part * e_int ) + de_dy_int & ) * dt_particle / 2.0_wp + & SQRT( fs_int * c_0 * diss_int ) * & ( random_gauss( iran_part, 5.0_wp ) - 1.0_wp ) * & SQRT( dt_particle ) particles(n)%rvar3 = particles(n)%rvar3 - fs_int * c_0 * & diss_int * particles(n)%rvar3 * dt_particle /& ( 4.0 * sgs_wfw_part * e_int ) + & ( 2.0 * sgs_wfw_part * de_dt * & particles(n)%rvar3 / & ( 2.0 * sgs_wfw_part * e_int ) + de_dz_int & ) * dt_particle / 2.0_wp + & SQRT( fs_int * c_0 * diss_int ) * & ( random_gauss( iran_part, 5.0_wp ) - 1.0_wp ) * & SQRT( dt_particle ) ENDIF u_int = u_int + particles(n)%rvar1 v_int = v_int + particles(n)%rvar2 w_int = w_int + particles(n)%rvar3 ! !-- Store the SGS TKE of the current timelevel which is needed for !-- for calculating the SGS particle velocities at the next timestep particles(n)%e_m = e_int ELSE ! !-- If no SGS velocities are used, only the particle timestep has to !-- be set dt_particle = dt_3d ENDIF ! !-- Store the old age of the particle ( needed to prevent that a !-- particle crosses several PEs during one timestep, and for the !-- evaluation of the subgrid particle velocity fluctuations ) particles(n)%age_m = particles(n)%age ! !-- Particle advection IF ( particle_groups(particles(n)%group)%density_ratio == 0.0 ) THEN ! !-- Pure passive transport (without particle inertia) particles(n)%x = particles(n)%x + u_int * dt_particle particles(n)%y = particles(n)%y + v_int * dt_particle particles(n)%z = particles(n)%z + w_int * dt_particle particles(n)%speed_x = u_int particles(n)%speed_y = v_int particles(n)%speed_z = w_int ELSE ! !-- Transport of particles with inertia particles(n)%x = particles(n)%x + particles(n)%speed_x * & dt_particle particles(n)%y = particles(n)%y + particles(n)%speed_y * & dt_particle particles(n)%z = particles(n)%z + particles(n)%speed_z * & dt_particle ! !-- Update of the particle velocity dens_ratio = particle_groups(particles(n)%group)%density_ratio IF ( cloud_droplets ) THEN exp_arg = 4.5 * dens_ratio * molecular_viscosity / & ( particles(n)%radius )**2 * & ( 1.0 + 0.15 * ( 2.0 * particles(n)%radius * & SQRT( ( u_int - particles(n)%speed_x )**2 + & ( v_int - particles(n)%speed_y )**2 + & ( w_int - particles(n)%speed_z )**2 ) / & molecular_viscosity )**0.687_wp & ) exp_term = EXP( -exp_arg * dt_particle ) ELSEIF ( use_sgs_for_particles ) THEN exp_arg = particle_groups(particles(n)%group)%exp_arg exp_term = EXP( -exp_arg * dt_particle ) ELSE exp_arg = particle_groups(particles(n)%group)%exp_arg exp_term = particle_groups(particles(n)%group)%exp_term ENDIF particles(n)%speed_x = particles(n)%speed_x * exp_term + & u_int * ( 1.0 - exp_term ) particles(n)%speed_y = particles(n)%speed_y * exp_term + & v_int * ( 1.0 - exp_term ) particles(n)%speed_z = particles(n)%speed_z * exp_term + & ( w_int - ( 1.0 - dens_ratio ) * g / exp_arg )& * ( 1.0 - exp_term ) ENDIF ! !-- Increment the particle age and the total time that the particle !-- has advanced within the particle timestep procedure particles(n)%age = particles(n)%age + dt_particle particles(n)%dt_sum = particles(n)%dt_sum + dt_particle ! !-- Check whether there is still a particle that has not yet completed !-- the total LES timestep IF ( ( dt_3d - particles(n)%dt_sum ) > 1E-8 ) THEN dt_3d_reached_l = .FALSE. ENDIF ENDDO END SUBROUTINE lpm_advec