source: palm/trunk/SOURCE/lpm_boundary_conds.f90 @ 2000

Last change on this file since 2000 was 2000, checked in by knoop, 5 years ago

Forced header and separation lines into 80 columns

  • Property svn:keywords set to Id
File size: 24.1 KB
Line 
1!> @file lpm_boundary_conds.f90
2!------------------------------------------------------------------------------!
3! This file is part of PALM.
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/>.
16!
17! Copyright 1997-2016 Leibniz Universitaet Hannover
18!------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22! Forced header and separation lines into 80 columns
23!
24! Former revisions:
25! -----------------
26! $Id: lpm_boundary_conds.f90 2000 2016-08-20 18:09:15Z knoop $
27!
28! 1929 2016-06-09 16:25:25Z suehring
29! Rewritten wall reflection
30!
31! 1822 2016-04-07 07:49:42Z hoffmann
32! Tails removed. Unused variables removed.
33!
34! 1682 2015-10-07 23:56:08Z knoop
35! Code annotations made doxygen readable
36!
37! 1359 2014-04-11 17:15:14Z hoffmann
38! New particle structure integrated.
39! Kind definition added to all floating point numbers.
40!
41! 1320 2014-03-20 08:40:49Z raasch
42! ONLY-attribute added to USE-statements,
43! kind-parameters added to all INTEGER and REAL declaration statements,
44! kinds are defined in new module kinds,
45! revision history before 2012 removed,
46! comment fields (!:) to be used for variable explanations added to
47! all variable declaration statements
48!
49! 1036 2012-10-22 13:43:42Z raasch
50! code put under GPL (PALM 3.9)
51!
52! 849 2012-03-15 10:35:09Z raasch
53! routine renamed lpm_boundary_conds, bottom and top boundary conditions
54! included (former part of advec_particles)
55!
56! 824 2012-02-17 09:09:57Z raasch
57! particle attributes speed_x|y|z_sgs renamed rvar1|2|3
58!
59! Initial version (2007/03/09)
60!
61! Description:
62! ------------
63!> Boundary conditions for the Lagrangian particles.
64!> The routine consists of two different parts. One handles the bottom (flat)
65!> and top boundary. In this part, also particles which exceeded their lifetime
66!> are deleted.
67!> The other part handles the reflection of particles from vertical walls.
68!> This part was developed by Jin Zhang during 2006-2007.
69!>
70!> To do: Code structure for finding the t_index values and for checking the
71!> -----  reflection conditions is basically the same for all four cases, so it
72!>        should be possible to further simplify/shorten it.
73!>
74!> THE WALLS PART OF THIS ROUTINE HAS NOT BEEN TESTED FOR OCEAN RUNS SO FAR!!!!
75!> (see offset_ocean_*)
76!------------------------------------------------------------------------------!
77 SUBROUTINE lpm_boundary_conds( range )
78 
79
80    USE arrays_3d,                                                             &
81        ONLY:  zu, zw
82
83    USE control_parameters,                                                    &
84        ONLY:  dz, message_string, particle_maximum_age
85
86    USE cpulog,                                                                &
87        ONLY:  cpu_log, log_point_s
88
89    USE grid_variables,                                                        &
90        ONLY:  ddx, dx, ddy, dy
91
92    USE indices,                                                               &
93        ONLY:  nxl, nxr, nyn, nys, nz, nzb_s_inner
94
95    USE kinds
96
97    USE particle_attributes,                                                   &
98        ONLY:  deleted_particles, ibc_par_b, ibc_par_t, number_of_particles,   &
99               particles, particle_type, offset_ocean_nzt_m1,                  &
100               use_sgs_for_particles
101
102    USE pegrid
103
104    IMPLICIT NONE
105
106    CHARACTER (LEN=*) ::  range     !<
107   
108    INTEGER(iwp) ::  inc            !< dummy for sorting algorithmus
109    INTEGER(iwp) ::  ir             !< dummy for sorting algorithmus
110    INTEGER(iwp) ::  i1             !< grid index (x) of old particle position
111    INTEGER(iwp) ::  i2             !< grid index (x) of current particle position
112    INTEGER(iwp) ::  i3             !< grid index (x) of intermediate particle position
113    INTEGER(iwp) ::  jr             !< dummy for sorting algorithmus
114    INTEGER(iwp) ::  j1             !< grid index (y) of old particle position
115    INTEGER(iwp) ::  j2             !< grid index (x) of current particle position
116    INTEGER(iwp) ::  j3             !< grid index (x) of intermediate particle position
117    INTEGER(iwp) ::  n              !< particle number
118    INTEGER(iwp) ::  t_index        !< running index for intermediate particle timesteps in reflection algorithmus
119    INTEGER(iwp) ::  t_index_number !< number of intermediate particle timesteps in reflection algorithmus
120    INTEGER(iwp) ::  tmp_x          !< dummy for sorting algorithmus
121    INTEGER(iwp) ::  tmp_y          !< dummy for sorting algorithmus
122
123    INTEGER(iwp), DIMENSION(0:10) :: x_ind(0:10) = 0 !< index array (x) of intermediate particle positions
124    INTEGER(iwp), DIMENSION(0:10) :: y_ind(0:10) = 0 !< index array (x) of intermediate particle positions
125   
126    LOGICAL  ::  cross_wall_x    !< flag to check if particle reflection along x is necessary
127    LOGICAL  ::  cross_wall_y    !< flag to check if particle reflection along y is necessary
128    LOGICAL  ::  downwards       !< flag to check if particle reflection along z is necessary (only if particle move downwards)
129    LOGICAL  ::  reflect_x       !< flag to check if particle is already reflected along x
130    LOGICAL  ::  reflect_y       !< flag to check if particle is already reflected along y
131    LOGICAL  ::  reflect_z       !< flag to check if particle is already reflected along z
132    LOGICAL  ::  tmp_reach_x     !< dummy for sorting algorithmus
133    LOGICAL  ::  tmp_reach_y     !< dummy for sorting algorithmus
134    LOGICAL  ::  tmp_reach_z     !< dummy for sorting algorithmus
135    LOGICAL  ::  x_wall_reached  !< flag to check if particle has already reached wall
136    LOGICAL  ::  y_wall_reached  !< flag to check if particle has already reached wall
137
138    LOGICAL, DIMENSION(0:10) ::  reach_x  !< flag to check if particle is at a yz-wall
139    LOGICAL, DIMENSION(0:10) ::  reach_y  !< flag to check if particle is at a xz-wall
140    LOGICAL, DIMENSION(0:10) ::  reach_z  !< flag to check if particle is at a xy-wall
141
142    REAL(wp) ::  dt_particle    !< particle timestep
143    REAL(wp) ::  dum            !< dummy argument
144    REAL(wp) ::  eps = 1E-10_wp !< security number to check if particle has reached a wall
145    REAL(wp) ::  pos_x          !< intermediate particle position (x)
146    REAL(wp) ::  pos_x_old      !< particle position (x) at previous particle timestep
147    REAL(wp) ::  pos_y          !< intermediate particle position (y)
148    REAL(wp) ::  pos_y_old      !< particle position (y) at previous particle timestep
149    REAL(wp) ::  pos_z          !< intermediate particle position (z)
150    REAL(wp) ::  pos_z_old      !< particle position (z) at previous particle timestep
151    REAL(wp) ::  prt_x          !< current particle position (x)
152    REAL(wp) ::  prt_y          !< current particle position (y)
153    REAL(wp) ::  prt_z          !< current particle position (z)
154    REAL(wp) ::  t_old          !< previous reflection time
155    REAL(wp) ::  tmp_t          !< dummy for sorting algorithmus
156    REAL(wp) ::  xwall          !< location of wall in x
157    REAL(wp) ::  ywall          !< location of wall in y
158    REAL(wp) ::  zwall1         !< location of wall in z (old grid box)
159    REAL(wp) ::  zwall2         !< location of wall in z (current grid box)
160    REAL(wp) ::  zwall3         !< location of wall in z (old y, current x)
161    REAL(wp) ::  zwall4         !< location of wall in z (current y, old x)
162
163    REAL(wp), DIMENSION(0:10) ::  t  !< reflection time
164
165
166    IF ( range == 'bottom/top' )  THEN
167
168!
169!--    Apply boundary conditions to those particles that have crossed the top or
170!--    bottom boundary and delete those particles, which are older than allowed
171       DO  n = 1, number_of_particles
172
173!
174!--       Stop if particles have moved further than the length of one
175!--       PE subdomain (newly released particles have age = age_m!)
176          IF ( particles(n)%age /= particles(n)%age_m )  THEN
177             IF ( ABS(particles(n)%speed_x) >                                  &
178                  ((nxr-nxl+2)*dx)/(particles(n)%age-particles(n)%age_m)  .OR. &
179                  ABS(particles(n)%speed_y) >                                  &
180                  ((nyn-nys+2)*dy)/(particles(n)%age-particles(n)%age_m) )  THEN
181
182                  WRITE( message_string, * )  'particle too fast.  n = ',  n
183                  CALL message( 'lpm_boundary_conds', 'PA0148', 2, 2, -1, 6, 1 )
184             ENDIF
185          ENDIF
186
187          IF ( particles(n)%age > particle_maximum_age  .AND.  &
188               particles(n)%particle_mask )                              &
189          THEN
190             particles(n)%particle_mask  = .FALSE.
191             deleted_particles = deleted_particles + 1
192          ENDIF
193
194          IF ( particles(n)%z >= zu(nz)  .AND.  particles(n)%particle_mask )  THEN
195             IF ( ibc_par_t == 1 )  THEN
196!
197!--             Particle absorption
198                particles(n)%particle_mask  = .FALSE.
199                deleted_particles = deleted_particles + 1
200             ELSEIF ( ibc_par_t == 2 )  THEN
201!
202!--             Particle reflection
203                particles(n)%z       = 2.0_wp * zu(nz) - particles(n)%z
204                particles(n)%speed_z = -particles(n)%speed_z
205                IF ( use_sgs_for_particles  .AND. &
206                     particles(n)%rvar3 > 0.0_wp )  THEN
207                   particles(n)%rvar3 = -particles(n)%rvar3
208                ENDIF
209             ENDIF
210          ENDIF
211         
212          IF ( particles(n)%z < zw(0)  .AND.  particles(n)%particle_mask )  THEN
213             IF ( ibc_par_b == 1 )  THEN
214!
215!--             Particle absorption
216                particles(n)%particle_mask  = .FALSE.
217                deleted_particles = deleted_particles + 1
218             ELSEIF ( ibc_par_b == 2 )  THEN
219!
220!--             Particle reflection
221                particles(n)%z       = 2.0_wp * zw(0) - particles(n)%z
222                particles(n)%speed_z = -particles(n)%speed_z
223                IF ( use_sgs_for_particles  .AND. &
224                     particles(n)%rvar3 < 0.0_wp )  THEN
225                   particles(n)%rvar3 = -particles(n)%rvar3
226                ENDIF
227             ENDIF
228          ENDIF
229       ENDDO
230
231    ELSEIF ( range == 'walls' )  THEN
232
233
234       CALL cpu_log( log_point_s(48), 'lpm_wall_reflect', 'start' )
235
236       DO  n = 1, number_of_particles
237!
238!--       Recalculate particle timestep
239          dt_particle = particles(n)%age - particles(n)%age_m
240!
241!--       Obtain x/y indices for current particle position
242          i2 = ( particles(n)%x + 0.5_wp * dx ) * ddx
243          j2 = ( particles(n)%y + 0.5_wp * dy ) * ddy
244!
245!--       Save current particle positions
246          prt_x = particles(n)%x
247          prt_y = particles(n)%y
248          prt_z = particles(n)%z
249!
250!--       Recalculate old particle positions
251          pos_x_old = particles(n)%x - particles(n)%speed_x * dt_particle
252          pos_y_old = particles(n)%y - particles(n)%speed_y * dt_particle
253          pos_z_old = particles(n)%z - particles(n)%speed_z * dt_particle
254!
255!--       Obtain x/y indices for old particle positions
256          i1 = ( pos_x_old + 0.5_wp * dx ) * ddx
257          j1 = ( pos_y_old + 0.5_wp * dy ) * ddy
258!
259!--       Determine horizontal as well as vertical walls at which particle can
260!--       be potentially reflected.
261!--       Start with walls aligned in yz layer.
262!--       Wall to the right
263          IF ( prt_x > pos_x_old )  THEN
264             xwall = ( i1 + 0.5_wp ) * dx
265!
266!--       Wall to the left
267          ELSE
268             xwall = ( i1 - 0.5_wp ) * dx
269          ENDIF
270!
271!--       Walls aligned in xz layer
272!--       Wall to the north
273          IF ( prt_y > pos_y_old )  THEN
274             ywall = ( j1 + 0.5_wp ) * dy
275!--       Wall to the south
276          ELSE
277             ywall = ( j1 - 0.5_wp ) * dy
278          ENDIF
279!
280!--       Walls aligned in xy layer at which particle can be possiblly reflected
281          zwall1 = zw(nzb_s_inner(j2,i2))
282          zwall2 = zw(nzb_s_inner(j1,i1))
283          zwall3 = zw(nzb_s_inner(j1,i2))
284          zwall4 = zw(nzb_s_inner(j2,i1))
285!
286!--       Initialize flags to check if particle reflection is necessary
287          downwards    = .FALSE.
288          cross_wall_x = .FALSE.
289          cross_wall_y = .FALSE.
290!
291!--       Initialize flags to check if a wall is reached
292          reach_x      = .FALSE.
293          reach_y      = .FALSE.
294          reach_z      = .FALSE.
295!
296!--       Initialize flags to check if a particle was already reflected
297          reflect_x = .FALSE.
298          reflect_y = .FALSE.
299          reflect_z = .FALSE.
300!
301!--       Initialize flags to check if a vertical wall is already crossed.
302!--       ( Required to obtain correct indices. )
303          x_wall_reached = .FALSE.
304          y_wall_reached = .FALSE.
305!
306!--       Initialize time array
307          t     = 0.0_wp
308!
309!--       Check if particle can reach any wall. This case, calculate the
310!--       fractional time needed to reach this wall. Store this fractional
311!--       timestep in array t. Moreover, store indices for these grid
312!--       boxes where the respective wall belongs to. 
313!--       Start with x-direction.
314          t_index    = 1
315          t(t_index) = ( xwall - pos_x_old )                                   &
316                     / MERGE( MAX( prt_x - pos_x_old,  1E-30_wp ),             &
317                              MIN( prt_x - pos_x_old, -1E-30_wp ),             &
318                              prt_x > pos_x_old )
319          x_ind(t_index)   = i2
320          y_ind(t_index)   = j1
321          reach_x(t_index) = .TRUE.
322          reach_y(t_index) = .FALSE.
323          reach_z(t_index) = .FALSE.
324!
325!--       Store these values only if particle really reaches any wall. t must
326!--       be in a interval between [0:1].
327          IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp )  THEN
328             t_index      = t_index + 1
329             cross_wall_x = .TRUE.
330          ENDIF
331!
332!--       y-direction
333          t(t_index) = ( ywall - pos_y_old )                                   &
334                     / MERGE( MAX( prt_y - pos_y_old,  1E-30_wp ),             &
335                              MIN( prt_y - pos_y_old, -1E-30_wp ),             &
336                              prt_y > pos_y_old )
337          x_ind(t_index)   = i1
338          y_ind(t_index)   = j2
339          reach_x(t_index) = .FALSE.
340          reach_y(t_index) = .TRUE.
341          reach_z(t_index) = .FALSE.
342          IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp )  THEN
343             t_index      = t_index + 1
344             cross_wall_y = .TRUE.
345          ENDIF
346!
347!--       z-direction
348!--       At first, check if particle moves downwards. Only in this case a
349!--       particle can be reflected vertically.
350          IF ( prt_z < pos_z_old )  THEN
351
352             downwards = .TRUE.
353             dum       =  1.0_wp / MERGE( MAX( prt_z - pos_z_old,  1E-30_wp ), &
354                                          MIN( prt_z - pos_z_old, -1E-30_wp ), &
355                                          prt_z > pos_z_old )
356
357             t(t_index)       = ( zwall1 - pos_z_old ) * dum
358             x_ind(t_index)   = i2
359             y_ind(t_index)   = j2
360             reach_x(t_index) = .FALSE.
361             reach_y(t_index) = .FALSE.
362             reach_z(t_index) = .TRUE.
363             IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp )            &
364                t_index = t_index + 1
365
366             reach_x(t_index) = .FALSE.
367             reach_y(t_index) = .FALSE.
368             reach_z(t_index) = .TRUE.
369             t(t_index)       = ( zwall2 - pos_z_old ) * dum
370             x_ind(t_index)   = i1
371             y_ind(t_index)   = j1
372             IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp )            &
373                t_index = t_index + 1
374
375             reach_x(t_index) = .FALSE.
376             reach_y(t_index) = .FALSE.
377             reach_z(t_index) = .TRUE.
378             t(t_index)       = ( zwall3 - pos_z_old ) * dum
379             x_ind(t_index)   = i2
380             y_ind(t_index)   = j1
381             IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp )            &
382                t_index = t_index + 1
383
384             reach_x(t_index) = .FALSE.
385             reach_y(t_index) = .FALSE.
386             reach_z(t_index) = .TRUE.
387             t(t_index)       = ( zwall4 - pos_z_old ) * dum
388             x_ind(t_index)   = i1
389             y_ind(t_index)   = j2
390             IF ( t(t_index) <= 1.0_wp .AND. t(t_index) >= 0.0_wp )            &
391                t_index = t_index + 1
392
393          END IF
394          t_index_number = t_index - 1
395!
396!--       Carry out reflection only if particle reaches any wall
397          IF ( cross_wall_x .OR. cross_wall_y .OR. downwards )  THEN
398!
399!--          Sort fractional timesteps in ascending order. Also sort the
400!--          corresponding indices and flag according to the time interval a 
401!--          particle reaches the respective wall.
402             inc = 1
403             jr  = 1
404             DO WHILE ( inc <= t_index_number )
405                inc = 3 * inc + 1
406             ENDDO
407
408             DO WHILE ( inc > 1 )
409                inc = inc / 3
410                DO  ir = inc+1, t_index_number
411                   tmp_t       = t(ir)
412                   tmp_x       = x_ind(ir)
413                   tmp_y       = y_ind(ir)
414                   tmp_reach_x = reach_x(ir)
415                   tmp_reach_y = reach_y(ir)
416                   tmp_reach_z = reach_z(ir)
417                   jr    = ir
418                   DO WHILE ( t(jr-inc) > tmp_t )
419                      t(jr)       = t(jr-inc)
420                      x_ind(jr)   = x_ind(jr-inc)
421                      y_ind(jr)   = y_ind(jr-inc)
422                      reach_x(jr) = reach_x(jr-inc)
423                      reach_y(jr) = reach_y(jr-inc)
424                      reach_z(jr) = reach_z(jr-inc)
425                      jr    = jr - inc
426                      IF ( jr <= inc )  EXIT
427                   ENDDO
428                   t(jr)       = tmp_t
429                   x_ind(jr)   = tmp_x
430                   y_ind(jr)   = tmp_y
431                   reach_x(jr) = tmp_reach_x
432                   reach_y(jr) = tmp_reach_y
433                   reach_z(jr) = tmp_reach_z
434                ENDDO
435             ENDDO
436!
437!--          Initialize temporary particle positions
438             pos_x = pos_x_old
439             pos_y = pos_y_old
440             pos_z = pos_z_old
441!
442!--          Loop over all times a particle possibly moves into a new grid box
443             t_old = 0.0_wp
444             DO t_index = 1, t_index_number
445!           
446!--             Calculate intermediate particle position according to the
447!--             timesteps a particle reaches any wall.
448                pos_x = pos_x + ( t(t_index) - t_old ) * dt_particle           &
449                                                       * particles(n)%speed_x
450                pos_y = pos_y + ( t(t_index) - t_old ) * dt_particle           &
451                                                       * particles(n)%speed_y
452                pos_z = pos_z + ( t(t_index) - t_old ) * dt_particle           &
453                                                       * particles(n)%speed_z
454!
455!--             Obtain x/y grid indices for intermediate particle position from
456!--             sorted index array
457                i3 = x_ind(t_index)
458                j3 = y_ind(t_index)
459!
460!--             Check which wall is already reached
461                IF ( .NOT. x_wall_reached )  x_wall_reached = reach_x(t_index) 
462                IF ( .NOT. y_wall_reached )  y_wall_reached = reach_y(t_index) 
463!
464!--             Check if a particle needs to be reflected at any yz-wall. If
465!--             necessary, carry out reflection. Please note, a security
466!--             constant is required, as the particle position do not
467!--             necessarily exactly match the wall location due to rounding
468!--             errors.   
469                IF ( ABS( pos_x - xwall ) < eps      .AND.                     &
470                     pos_z <= zw(nzb_s_inner(j3,i3)) .AND.                     &
471                     reach_x(t_index)                .AND.                     &
472                     .NOT. reflect_x )  THEN
473!
474!--                Reflection in x-direction.
475!--                Ensure correct reflection by MIN/MAX functions, depending on
476!--                direction of particle transport.
477!--                Due to rounding errors pos_x do not exactly matches the wall
478!--                location, leading to erroneous reflection.             
479                   pos_x = MERGE( MIN( 2.0_wp * xwall - pos_x, xwall ),        &
480                                  MAX( 2.0_wp * xwall - pos_x, xwall ),        &
481                                  particles(n)%x > xwall )
482!
483!--                Change sign of particle speed                     
484                   particles(n)%speed_x = - particles(n)%speed_x
485!
486!--                Change also sign of subgrid-scale particle speed
487                   particles(n)%rvar1 = - particles(n)%rvar1
488!
489!--                Set flag that reflection along x is already done
490                   reflect_x          = .TRUE.
491!
492!--                As particle do not crosses any further yz-wall during
493!--                this timestep, set further x-indices to the current one.
494                   x_ind(t_index:t_index_number) = i1
495!
496!--             If particle already reached the wall but was not reflected,
497!--             set further x-indices to the new one.
498                ELSEIF ( x_wall_reached .AND. .NOT. reflect_x )  THEN
499                    x_ind(t_index:t_index_number) = i2
500                ENDIF
501!
502!--             Check if a particle needs to be reflected at any xz-wall. If
503!--             necessary, carry out reflection.
504                IF ( ABS( pos_y - ywall ) < eps      .AND.                     &
505                     pos_z <= zw(nzb_s_inner(j3,i3)) .AND.                     &
506                     reach_y(t_index)                .AND.                     &
507                     .NOT. reflect_y ) THEN
508
509                   pos_y = MERGE( MIN( 2.0_wp * ywall - pos_y, ywall ),        &
510                                  MAX( 2.0_wp * ywall - pos_y, ywall ),        &
511                                  particles(n)%y > ywall ) 
512
513                   particles(n)%speed_y = - particles(n)%speed_y     
514                   particles(n)%rvar2   = - particles(n)%rvar2       
515     
516                   reflect_y            = .TRUE.
517                   y_ind(t_index:t_index_number) = j1
518
519                ELSEIF ( y_wall_reached .AND. .NOT. reflect_y )  THEN
520                   y_ind(t_index:t_index_number) = j2
521                ENDIF
522!
523!--             Check if a particle needs to be reflected at any xy-wall. If
524!--             necessary, carry out reflection.
525                IF ( downwards .AND. reach_z(t_index) .AND.                    &
526                     .NOT. reflect_z )  THEN
527                   IF ( pos_z - zw(nzb_s_inner(j3,i3)) < eps ) THEN
528 
529                      pos_z = MAX( 2.0_wp * zw(nzb_s_inner(j3,i3)) - pos_z,    &
530                                   zw(nzb_s_inner(j3,i3)) )
531
532                      particles(n)%speed_z = - particles(n)%speed_z
533                      particles(n)%rvar3   = - particles(n)%rvar3
534
535                      reflect_z            = .TRUE.
536
537                   ENDIF
538
539                ENDIF
540!
541!--             Swap time
542                t_old = t(t_index)
543
544             ENDDO
545!
546!--          If a particle was reflected, calculate final position from last
547!--          intermediate position.
548             IF ( reflect_x .OR. reflect_y .OR. reflect_z )  THEN
549
550                particles(n)%x = pos_x + ( 1.0_wp - t_old ) * dt_particle      &
551                                                         * particles(n)%speed_x
552                particles(n)%y = pos_y + ( 1.0_wp - t_old ) * dt_particle      &
553                                                         * particles(n)%speed_y
554                particles(n)%z = pos_z + ( 1.0_wp - t_old ) * dt_particle      &
555                                                         * particles(n)%speed_z
556
557             ENDIF
558
559          ENDIF
560
561       ENDDO
562
563       CALL cpu_log( log_point_s(48), 'lpm_wall_reflect', 'stop' )
564
565    ENDIF
566
567 END SUBROUTINE lpm_boundary_conds
Note: See TracBrowser for help on using the repository browser.