Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PLAG_RFLU_ModFindCells.F90
Go to the documentation of this file.
1 ! *********************************************************************
2 ! * Rocstar Simulation Suite *
3 ! * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4 ! * *
5 ! * Illinois Rocstar LLC *
6 ! * Champaign, IL *
7 ! * www.illinoisrocstar.com *
8 ! * sales@illinoisrocstar.com *
9 ! * *
10 ! * License: See LICENSE file in top level of distribution package or *
11 ! * http://opensource.org/licenses/NCSA *
12 ! *********************************************************************
13 ! *********************************************************************
14 ! * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15 ! * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16 ! * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17 ! * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18 ! * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19 ! * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20 ! * Arising FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21 ! * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22 ! *********************************************************************
23 ! ******************************************************************************
24 !
25 ! Purpose: Suite of routines for particle tracking on Eulerian grid.
26 !
27 ! Description: None.
28 !
29 ! Notes: None.
30 !
31 ! ******************************************************************************
32 !
33 ! $Id: PLAG_RFLU_ModFindCells.F90,v 1.16 2008/12/06 08:44:35 mtcampbe Exp $
34 !
35 ! Copyright: (c) 2005 by the University of Illinois
36 !
37 ! ******************************************************************************
38 
40 
41  USE modglobal, ONLY: t_global
42  USE modparameters
43  USE moddatatypes
44  USE modglobal, ONLY: t_global
45  USE modgrid, ONLY: t_grid
46  USE modpartlag, ONLY: t_plag, t_plag_input
47  USE modbndpatch, ONLY: t_patch
48  USE moddatastruct, ONLY: t_region
49  USE modborder, ONLY: t_border
50  USE moderror
51  USE modmpi
53 
54  USE modtools, ONLY: floatequal
55 
62  USE rflu_modoctree
64 
67 
69 
70  IMPLICIT NONE
71 
72  PRIVATE
73  PUBLIC :: plag_rflu_computedisttot, &
81 
82 ! ******************************************************************************
83 ! Declarations and definitions
84 ! ******************************************************************************
85 
86  CHARACTER(CHRLEN) :: RCSIdentString = &
87  '$RCSfile: PLAG_RFLU_ModFindCells.F90,v $ $Revision: 1.16 $'
88 
89 ! ******************************************************************************
90 ! Routines
91 ! ******************************************************************************
92 
93  CONTAINS
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 ! ******************************************************************************
106 !
107 ! Purpose: Compute total distance travelled.
108 !
109 ! Description: None.
110 !
111 ! Input:
112 ! pRegion Pointer to region
113 !
114 ! Output: None.
115 !
116 ! Notes: None.
117 !
118 ! ******************************************************************************
119 
120 SUBROUTINE plag_rflu_computedisttot(pRegion)
121 
122  IMPLICIT NONE
123 
124 ! ******************************************************************************
125 ! Declarations
126 ! ******************************************************************************
127 
128 ! ==============================================================================
129 ! Arguments
130 ! ==============================================================================
131 
132  TYPE(t_region), POINTER :: pregion
133 
134 ! ==============================================================================
135 ! Locals
136 ! ==============================================================================
137 
138  CHARACTER(CHRLEN) :: errorstring
139  INTEGER ::ipcl
140  REAL(RFREAL) :: xlocnew,xlocold,xtraj,ylocnew,ylocold,ytraj,zlocnew, &
141  zlocold,ztraj
142  TYPE(t_global), POINTER :: global
143  TYPE(t_grid), POINTER :: pgrid
144  TYPE(t_plag), POINTER :: pplag
145 
146 ! ******************************************************************************
147 ! Start
148 ! ******************************************************************************
149 
150  global => pregion%global
151 
152  CALL registerfunction(global,'PLAG_RFLU_ComputeDistTot',&
153  'PLAG_RFLU_ModFindCells.F90')
154 
155 ! ******************************************************************************
156 ! Set pointers
157 ! ******************************************************************************
158 
159  pgrid => pregion%grid
160  pplag => pregion%plag
161 
162 ! ******************************************************************************
163 ! Loop over particles
164 ! ******************************************************************************
165 
166  DO ipcl = 1,pplag%nPcls
167 
168 ! ==============================================================================
169 ! Compute distance travelled and trajectory
170 ! ==============================================================================
171 
172  xlocnew = pplag%cv(cv_plag_xpos,ipcl)
173  ylocnew = pplag%cv(cv_plag_ypos,ipcl)
174  zlocnew = pplag%cv(cv_plag_zpos,ipcl)
175 
176  xlocold = pplag%cvOld(cv_plag_xpos,ipcl)
177  ylocold = pplag%cvOld(cv_plag_ypos,ipcl)
178  zlocold = pplag%cvOld(cv_plag_zpos,ipcl)
179 
180  xtraj = xlocnew - xlocold
181  ytraj = ylocnew - ylocold
182  ztraj = zlocnew - zlocold
183 
184  pplag%arv(arv_plag_distot,ipcl) = sqrt( xtraj*xtraj + ytraj*ytraj &
185  + ztraj*ztraj )
186 
187  END DO ! iPcl
188 
189 ! ******************************************************************************
190 ! End
191 ! ******************************************************************************
192 
193  CALL deregisterfunction(global)
194 
195 END SUBROUTINE plag_rflu_computedisttot
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 ! ******************************************************************************
206 !
207 ! Purpose: Determine cells which contain particles using brute force approach.
208 !
209 ! Description: None.
210 !
211 ! Input:
212 ! pRegion Pointer to region
213 !
214 ! Output: None.
215 !
216 ! Notes: None.
217 !
218 ! ******************************************************************************
219 
220 SUBROUTINE plag_rflu_findcellsbrute(pRegion)
221 
222  IMPLICIT NONE
223 
224 ! ******************************************************************************
225 ! Declarations
226 ! ******************************************************************************
227 
228 ! ==============================================================================
229 ! Arguments
230 ! ==============================================================================
231 
232  TYPE(t_region), POINTER :: pregion
233 
234 ! ==============================================================================
235 ! Locals
236 ! ==============================================================================
237 
238  LOGICAL :: foundflag
239  CHARACTER(CHRLEN) :: errorstring
240  INTEGER :: errorflag,icg,ipcl
241  REAL(RFREAL) :: xloc,yloc,zloc
242  TYPE(t_global), POINTER :: global
243  TYPE(t_grid), POINTER :: pgrid
244  TYPE(t_plag), POINTER :: pplag
245 
246 ! ******************************************************************************
247 ! Start
248 ! ******************************************************************************
249 
250  global => pregion%global
251 
252  CALL registerfunction(global,'PLAG_RFLU_FindCellsBrute',&
253  'PLAG_RFLU_ModFindCells.F90')
254 
255 ! ******************************************************************************
256 ! Set variables and pointers
257 ! ******************************************************************************
258 
259  pgrid => pregion%grid
260  pplag => pregion%plag
261 
262 ! ******************************************************************************
263 ! Loop over particles
264 ! ******************************************************************************
265 
266  DO ipcl = 1,pplag%nPcls
267 
268 ! ==============================================================================
269 ! Get particle position
270 ! ==============================================================================
271 
272  xloc = pplag%cv(cv_plag_xpos,ipcl)
273  yloc = pplag%cv(cv_plag_ypos,ipcl)
274  zloc = pplag%cv(cv_plag_zpos,ipcl)
275 
276 ! ==============================================================================
277 ! Loop over actual cells
278 ! ==============================================================================
279 
280  foundflag = .false.
281 
282  cellloop: DO icg = 1,pgrid%nCells
283  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,icg) .EQV. .true. ) THEN
284  pplag%aiv(aiv_plag_regini,ipcl) = pregion%iRegionGlobal
285  pplag%aiv(aiv_plag_icells,ipcl) = icg
286 
287  foundflag = .true.
288 
289  EXIT cellloop
290  END IF ! RFLU_ICT_TestInCell
291  END DO cellloop
292 
293 ! ==============================================================================
294 ! Check whether particle was found
295 ! ==============================================================================
296 
297  IF ( foundflag .EQV. .false. ) THEN
298  WRITE(errorstring,'(I6)') ipcl
299  CALL errorstop(global,err_plag_pcl_not_found,__line__,trim(errorstring))
300  END IF ! foundFlag
301  END DO ! iPcl
302 
303 ! ******************************************************************************
304 ! End
305 ! ******************************************************************************
306 
307  CALL deregisterfunction(global)
308 
309 END SUBROUTINE plag_rflu_findcellsbrute
310 
311 
312 
313 
314 
315 
316 
317 ! ******************************************************************************
318 !
319 ! Purpose: Kernel for brute force search.
320 !
321 ! Description: None.
322 !
323 ! Input:
324 ! pRegion Pointer to region
325 ! xLoc,yLoc,zLoc Location
326 !
327 ! Output:
328 ! icgOut Cell containing location
329 !
330 ! Notes:
331 ! 1. icgOut is set to CRAZY_VALUE_INT if no cell contained location.
332 !
333 ! ******************************************************************************
334 
335 SUBROUTINE plag_rflu_findcellsbrutekernel(pRegion,xLoc,yLoc,zLoc,icgOut)
336 
337  IMPLICIT NONE
338 
339 ! ******************************************************************************
340 ! Declarations
341 ! ******************************************************************************
342 
343 ! ==============================================================================
344 ! Arguments
345 ! ==============================================================================
346 
347  INTEGER, INTENT(OUT) :: icgout
348  REAL(RFREAL), INTENT(IN) :: xloc,yloc,zloc
349  TYPE(t_region), POINTER :: pregion
350 
351 ! ==============================================================================
352 ! Locals
353 ! ==============================================================================
354 
355  INTEGER :: errorflag,icg
356  TYPE(t_global), POINTER :: global
357  TYPE(t_grid), POINTER :: pgrid
358 
359 ! ******************************************************************************
360 ! Start
361 ! ******************************************************************************
362 
363  global => pregion%global
364 
365  CALL registerfunction(global,'PLAG_RFLU_FindCellsBruteKernel',&
366  'PLAG_RFLU_ModFindCells.F90')
367 
368 ! ******************************************************************************
369 ! Set variables and pointers
370 ! ******************************************************************************
371 
372  pgrid => pregion%grid
373 
374 ! ******************************************************************************
375 ! Loop over cells
376 ! ******************************************************************************
377 
378  icgout = crazy_value_int
379 
380  cellloop: DO icg = 1,pgrid%nCells
381  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,icg) .EQV. .true. ) THEN
382  icgout = icg
383 
384  EXIT cellloop
385  END IF ! RFLU_ICT_TestInCell
386  END DO cellloop
387 
388 ! ******************************************************************************
389 ! End
390 ! ******************************************************************************
391 
392  CALL deregisterfunction(global)
393 
394 END SUBROUTINE plag_rflu_findcellsbrutekernel
395 
396 
397 
398 
399 
400 
401 
402 ! ******************************************************************************
403 !
404 ! Purpose: Determine cells which contain particles using modified brute
405 ! force approach.
406 !
407 ! Description: None.
408 !
409 ! Input:
410 ! pRegion Pointer to region
411 !
412 ! Output: None.
413 !
414 ! Notes:
415 ! 1. This routine is suitable to determine the cell containing a particle
416 ! after the latters position has been updated.
417 ! 2. This routine cannot be used in parallel runs and for particles which
418 ! leave the domain or bounce from solid walls.
419 !
420 ! ******************************************************************************
421 
422 SUBROUTINE plag_rflu_findcellsbrutemod(pRegion)
423 
424  IMPLICIT NONE
425 
426 ! ******************************************************************************
427 ! Declarations
428 ! ******************************************************************************
429 
430 ! ==============================================================================
431 ! Arguments
432 ! ==============================================================================
433 
434  TYPE(t_region), POINTER :: pregion
435 
436 ! ==============================================================================
437 ! Locals
438 ! ==============================================================================
439 
440  CHARACTER(CHRLEN) :: errorstring
441  INTEGER :: errorflag,icg,ipcl
442  REAL(RFREAL) :: xloc,yloc,zloc
443  TYPE(t_global), POINTER :: global
444  TYPE(t_grid), POINTER :: pgrid
445  TYPE(t_plag), POINTER :: pplag
446 
447 ! ******************************************************************************
448 ! Start
449 ! ******************************************************************************
450 
451  global => pregion%global
452 
453  CALL registerfunction(global,'PLAG_RFLU_FindCellsBruteMod',&
454  'PLAG_RFLU_ModFindCells.F90')
455 
456 ! ******************************************************************************
457 ! Set variables and pointers
458 ! ******************************************************************************
459 
460  pgrid => pregion%grid
461  pplag => pregion%plag
462 
463 ! ******************************************************************************
464 ! Loop over particles
465 ! ******************************************************************************
466 
467  DO ipcl = 1,pplag%nPcls
468 
469 ! ==============================================================================
470 ! Get particle cell and position
471 ! ==============================================================================
472 
473  icg = pplag%aivOld(aiv_plag_icells,ipcl) ! NOTE OLD cell index
474 
475  xloc = pplag%cv(cv_plag_xpos,ipcl) ! NOTE already NEW particle position
476  yloc = pplag%cv(cv_plag_ypos,ipcl)
477  zloc = pplag%cv(cv_plag_zpos,ipcl)
478 
479 ! ==============================================================================
480 ! Check if particle still in same cell
481 ! ==============================================================================
482 
483  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,icg) .EQV. .false. ) THEN
484 
485 ! ------------------------------------------------------------------------------
486 ! Find cell containing particle
487 ! ------------------------------------------------------------------------------
488 
489  CALL plag_rflu_findcellsbrutekernel(pregion,xloc,yloc,zloc,icg)
490 
491  IF ( icg /= crazy_value_int ) THEN
492  pplag%aiv(aiv_plag_icells,ipcl) = icg
493  ELSE
494 
495 ! TEMPORARY
496  WRITE(*,*) 'timeCurrent,iPcl,xLocOld,yLocOld,zLocOld,xLoc,yLoc,zLoc = ',&
497  global%currentTime,ipcl,pplag%cvOld(cv_plag_xpos:cv_plag_zpos,ipcl),&
498  xloc,yloc,zloc
499 ! END TEMPORARY
500 
501  WRITE(errorstring,'(I6)') ipcl
502  CALL errorstop(global,err_plag_pcl_not_found,__line__,trim(errorstring))
503  END IF ! icg
504 
505 ! ==============================================================================
506 ! Particle still in same cell, copy cell index
507 ! ==============================================================================
508 
509  ELSE
510  pplag%aiv(aiv_plag_icells,ipcl) = icg
511  END IF ! RFLU_ICT_TestInCell
512  END DO ! iPcl
513 
514 ! ******************************************************************************
515 ! End
516 ! ******************************************************************************
517 
518  CALL deregisterfunction(global)
519 
520 END SUBROUTINE plag_rflu_findcellsbrutemod
521 
522 
523 
524 
525 
526 
527 
528 ! ******************************************************************************
529 !
530 ! Purpose: Determine cells which contain particles using Lohners approach.
531 !
532 ! Description: Follow particle path by passing particle to face which failed
533 ! in-cell test by largest amount.
534 !
535 ! Input:
536 ! pRegion Pointer to region
537 !
538 ! Output: None.
539 !
540 ! Notes:
541 ! 1. See R. Lohner and J. Ambrosiano, A Vectorized Particle Tracer for
542 ! Unstructured Grids, J. Comp. Phys., Vol. 91, pp. 22-31, 1990.
543 !
544 ! ******************************************************************************
545 
546 SUBROUTINE plag_rflu_findcellslohner(pRegion)
547 
548  IMPLICIT NONE
549 
550 ! ******************************************************************************
551 ! Declarations
552 ! ******************************************************************************
553 
554 ! ==============================================================================
555 ! Arguments
556 ! ==============================================================================
557 
558  TYPE(t_region), POINTER :: pregion
559 
560 ! ==============================================================================
561 ! Locals
562 ! ==============================================================================
563 
564  LOGICAL :: testincell
565  CHARACTER(CHRLEN) :: errorstring
566  INTEGER :: c1,c1k,c2,c2k,errorflag,icg,icgout,ifg,iloc,ipcl,loopcounter
567  REAL(RFREAL) :: xloc,yloc,zloc
568  TYPE(t_global), POINTER :: global
569  TYPE(t_grid), POINTER :: pgrid
570  TYPE(t_patch), POINTER :: ppatch
571  TYPE(t_plag), POINTER :: pplag
572 
573 ! ******************************************************************************
574 ! Start
575 ! ******************************************************************************
576 
577  global => pregion%global
578 
579  CALL registerfunction(global,'PLAG_RFLU_FindCellsLohner',&
580  'PLAG_RFLU_ModFindCells.F90')
581 
582 ! ******************************************************************************
583 ! Set pointers
584 ! ******************************************************************************
585 
586  pgrid => pregion%grid
587  pplag => pregion%plag
588 
589 ! ******************************************************************************
590 ! Loop over particles
591 ! ******************************************************************************
592 
593  DO ipcl = 1,pplag%nPcls
594  loopcounter = 0 ! Reset loop counter
595 
596  xloc = pplag%cv(cv_plag_xpos,ipcl)
597  yloc = pplag%cv(cv_plag_ypos,ipcl)
598  zloc = pplag%cv(cv_plag_zpos,ipcl)
599 
600  icg = pplag%aivOld(aiv_plag_icells,ipcl)
601 
602 ! ==============================================================================
603 ! Loop until distance travelled along trajectory consumed
604 ! ==============================================================================
605 
606  infloop: DO
607  loopcounter = loopcounter + 1
608 
609 ! ------------------------------------------------------------------------------
610 ! Find appropriate intersection and associated face
611 ! ------------------------------------------------------------------------------
612 
613  CALL rflu_ict_testincelllohner(pregion,xloc,yloc,zloc,icg,testincell, &
614  iloc,ifg)
615 
616 ! ------------------------------------------------------------------------------
617 ! Check whether have remaining total distance
618 ! ------------------------------------------------------------------------------
619 
620 ! --- In-cell test successful --------------------------------------------------
621 
622  IF ( testincell .EQV. .true. ) THEN
623  pplag%aiv(aiv_plag_icells,ipcl) = icg
624 
625  EXIT infloop
626 
627 ! --- In-cell test failed ------------------------------------------------------
628 
629  ELSE
630 
631 ! ----- Intersect interior face
632 
633  IF ( iloc == 0 ) THEN
634  c1 = pgrid%f2c(1,ifg)
635  c2 = pgrid%f2c(2,ifg)
636 
637  c1k = rflu_getglobalcellkind(global,pgrid,c1)
638  c2k = rflu_getglobalcellkind(global,pgrid,c2)
639 
640  SELECT CASE ( rflu_getfacekind(global,c1k,c2k) )
641  CASE ( face_kind_aa ) ! Actual-actual face
642  IF ( c1 == icg ) THEN
643  icg = c2
644  ELSE
645  icg = c1
646  END IF ! c1
647 ! TO DO
648 ! CASE ( FACE_KIND_AV ) ! Actual-virtual face
649 ! Count particle intersections for each buffer
650 ! END TO DO
651  CASE default
652  CALL errorstop(global,err_reached_default,__line__)
653  END SELECT ! RFLU_GetFaceKind
654 
655 ! ----- Intersect boundary face
656 
657  ELSE ! Boundary face
658  ppatch => pregion%patches(iloc)
659 
660  SELECT CASE ( ppatch%bcType )
661  CASE default
662  CALL errorstop(global,err_reached_default,__line__)
663  END SELECT ! pPatch%bcType
664  END IF ! iLoc
665  END IF ! testInCell
666 
667 ! ------------------------------------------------------------------------------
668 ! Guard against infinite loop
669 ! ------------------------------------------------------------------------------
670 
671  IF ( loopcounter >= limit_infinite_loop ) THEN
672  CALL errorstop(global,err_infinite_loop,__line__)
673  END IF ! loopCounter
674 
675  END DO infloop
676  END DO ! iPcl
677 
678 ! ******************************************************************************
679 ! End
680 ! ******************************************************************************
681 
682  CALL deregisterfunction(global)
683 
684 END SUBROUTINE plag_rflu_findcellslohner
685 
686 
687 
688 
689 
690 
691 
692 ! ******************************************************************************
693 !
694 ! Purpose: Determine cells which contain particles using Octree approach.
695 !
696 ! Description: None.
697 !
698 ! Input:
699 ! pRegion Pointer to region
700 !
701 ! Output: None.
702 !
703 ! Notes:
704 ! 1. It is not enough to simply get closest cell from Octree, because
705 ! proximity to cell centroid does not guarantee that the specified
706 ! location is actually inside the cell.
707 ! 2. This routine is suitable to determine the cells which contain an
708 ! initial distribution of particles, but should not be used to track
709 ! moving particles, because it will be inefficient on account of it
710 ! not using knowledge of past position. It will also overwrite entry
711 ! containing initial region in particle data structure.
712 !
713 ! ******************************************************************************
714 
715 SUBROUTINE plag_rflu_findcellsoct(pRegion)
716 
718 
719  IMPLICIT NONE
720 
721 ! ******************************************************************************
722 ! Declarations
723 ! ******************************************************************************
724 
725 ! ==============================================================================
726 ! Arguments
727 ! ==============================================================================
728 
729  TYPE(t_region), POINTER :: pregion
730 
731 ! ==============================================================================
732 ! Locals
733 ! ==============================================================================
734 
735  LOGICAL :: foundflag
736  CHARACTER(CHRLEN) :: errorstring
737  INTEGER :: ccsize,errorflag,icg,ipcl
738  INTEGER, DIMENSION(:), ALLOCATABLE :: cc
739  REAL(RFREAL) :: delfrac,xdel,xloc,xmax,xmin,ydel,yloc,ymax,ymin,zdel,zloc, &
740  zmax,zmin
741  TYPE(t_global), POINTER :: global
742  TYPE(t_grid), POINTER :: pgrid
743  TYPE(t_plag), POINTER :: pplag
744 
745 ! ******************************************************************************
746 ! Start
747 ! ******************************************************************************
748 
749  global => pregion%global
750 
751  CALL registerfunction(global,'PLAG_RFLU_FindCellsOct',&
752  'PLAG_RFLU_ModFindCells.F90')
753 
754 ! ******************************************************************************
755 ! Set variables and pointers
756 ! ******************************************************************************
757 
758  pgrid => pregion%grid
759  pplag => pregion%plag
760 
761  delfrac = 0.01_rfreal
762 
763  ccsize = min(100,pgrid%nCells) ! Must be larger than unity
764 
765  ALLOCATE(cc(ccsize),stat=errorflag)
766  global%error = errorflag
767  IF ( global%error /= err_none ) THEN
768  CALL errorstop(global,err_allocate,__line__,'cc')
769  END IF ! global%error
770 
771 ! ******************************************************************************
772 ! Build bounding box
773 ! ******************************************************************************
774 
775  xmin = minval(pgrid%xyz(xcoord,1:pgrid%nVert))
776  xmax = maxval(pgrid%xyz(xcoord,1:pgrid%nVert))
777  ymin = minval(pgrid%xyz(ycoord,1:pgrid%nVert))
778  ymax = maxval(pgrid%xyz(ycoord,1:pgrid%nVert))
779  zmin = minval(pgrid%xyz(zcoord,1:pgrid%nVert))
780  zmax = maxval(pgrid%xyz(zcoord,1:pgrid%nVert))
781 
782  xdel = xmax - xmin
783  ydel = ymax - ymin
784  zdel = zmax - zmin
785 
786  xmin = xmin - delfrac*xdel
787  xmax = xmax + delfrac*xdel
788  ymin = ymin - delfrac*ydel
789  ymax = ymax + delfrac*ydel
790  zmin = zmin - delfrac*zdel
791  zmax = zmax + delfrac*zdel
792 
793 ! ******************************************************************************
794 ! Build Octree with cell centroids: NOTE only for actual cells
795 ! ******************************************************************************
796 
797  CALL rflu_createoctree(global,pgrid%nCells)
798 
799  CALL rflu_buildoctree(pgrid%cofg(xcoord,1:pgrid%nCells), &
800  pgrid%cofg(ycoord,1:pgrid%nCells), &
801  pgrid%cofg(zcoord,1:pgrid%nCells), &
803 
804 ! ******************************************************************************
805 ! Loop over particles
806 ! ******************************************************************************
807 
808  DO ipcl = 1,pplag%nPcls
809 
810 ! ==============================================================================
811 ! Test particle location against bounding box of partition
812 ! ==============================================================================
813 
814  xloc = pplag%cv(cv_plag_xpos,ipcl)
815  yloc = pplag%cv(cv_plag_ypos,ipcl)
816  zloc = pplag%cv(cv_plag_zpos,ipcl)
817 
818  IF ( rflu_testinboundbox(global,xloc,yloc,zloc,xmin,xmax,ymin,ymax, &
819  zmin,zmax) .EQV. .true. ) THEN
820 
821 ! ------------------------------------------------------------------------------
822 ! Query octree to get closest cells
823 ! ------------------------------------------------------------------------------
824 
825  CALL rflu_queryoctree(xloc,yloc,zloc,ccsize,cc)
826 
827 ! ------------------------------------------------------------------------------
828 ! Test cells obtained from Octree if they contain specified location
829 ! ------------------------------------------------------------------------------
830 
831  foundflag = .false.
832 
833  cellloop: DO icg = 1,ccsize
834  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,cc(icg)) .EQV. .true. ) THEN
835  pplag%aiv(aiv_plag_regini,ipcl) = pregion%iRegionGlobal
836  pplag%aiv(aiv_plag_icells,ipcl) = cc(icg)
837 
838  foundflag = .true.
839 
840  EXIT cellloop
841  END IF ! RFLU_ICT_TestInCell
842  END DO cellloop
843 
844 ! ------------------------------------------------------------------------------
845 ! Check whether particle was found
846 ! ------------------------------------------------------------------------------
847 
848  IF ( foundflag .EQV. .false. ) THEN
849  WRITE(errorstring,'(I6)') ipcl
850  CALL errorstop(global,err_plag_pcl_not_found,__line__, &
851  trim(errorstring))
852  END IF ! foundFlag
853 
854 ! ==============================================================================
855 ! Particle located outside bounding box of partition
856 ! ==============================================================================
857 
858  ELSE
859  WRITE(errorstring,'(I6)') ipcl
860  CALL errorstop(global,err_plag_pcl_not_found,__line__,trim(errorstring))
861  END IF ! RFLU_TestInBoundNox
862  END DO ! iPcl
863 
864 ! ******************************************************************************
865 ! Destroy Octree and deallocate temporary memory
866 ! ******************************************************************************
867 
868  CALL rflu_destroyoctree(global)
869 
870  DEALLOCATE(cc,stat=errorflag)
871  global%error = errorflag
872  IF ( global%error /= err_none ) THEN
873  CALL errorstop(global,err_deallocate,__line__,'cc')
874  END IF ! global%error
875 
876 ! ******************************************************************************
877 ! End
878 ! ******************************************************************************
879 
880  CALL deregisterfunction(global)
881 
882 END SUBROUTINE plag_rflu_findcellsoct
883 
884 
885 
886 
887 
888 
889 
890 
891 ! ******************************************************************************
892 !
893 ! Purpose: Kernel for Octree search
894 !
895 ! Description: None.
896 !
897 ! Input:
898 ! pRegion Pointer to region
899 ! xLoc,yLoc,zLoc Location
900 !
901 ! Output:
902 ! icgOut Cell containing location
903 !
904 ! Notes:
905 ! 1. It is not enough to simply get closest cell from Octree, because
906 ! proximity to cell centroid does not guarantee that the specified
907 ! location is actually inside the cell.
908 ! 2. This routine is suitable to determine the cell containing a particle
909 ! after the latters position has been updated.
910 ! 3. This routine cannot be used in parallel runs and for particles which
911 ! leave the domain or bounce from solid walls.
912 !
913 ! ******************************************************************************
914 
915 SUBROUTINE plag_rflu_findcellsoctkernel(pRegion,xLoc,yLoc,zLoc,xMin,xMax,&
916  ymin,ymax,zmin,zmax,icgout)
917 
919 
920  IMPLICIT NONE
921 
922 ! ******************************************************************************
923 ! Declarations
924 ! ******************************************************************************
925 
926 ! ==============================================================================
927 ! Arguments
928 ! ==============================================================================
929 
930  INTEGER, INTENT(INOUT) :: icgout
931  REAL(RFREAL), INTENT(IN) :: xloc,xmax,xmin,yloc,ymax,ymin,zloc,zmax,zmin
932  TYPE(t_region), POINTER :: pregion
933 
934 ! ==============================================================================
935 ! Locals
936 ! ==============================================================================
937 
938  LOGICAL :: foundflag
939  INTEGER :: ccsize,errorflag,icgloop,ipcl
940  INTEGER, DIMENSION(:), ALLOCATABLE :: cc
941  TYPE(t_global), POINTER :: global
942  TYPE(t_grid), POINTER :: pgrid
943 
944 ! ******************************************************************************
945 ! Start
946 ! ******************************************************************************
947 
948  global => pregion%global
949 
950  CALL registerfunction(global,'PLAG_RFLU_FindCellsOctKernel',&
951  'PLAG_RFLU_ModFindCells.F90')
952 
953 ! ******************************************************************************
954 ! Set variables and pointers
955 ! ******************************************************************************
956 
957  pgrid => pregion%grid
958 
959 ! ccSize = MIN(100,pGrid%nCells) ! Must be larger than unity
960 
961 ! TEMPORARY
962  ccsize = min(50,pgrid%nCells) ! Must be larger than unity
963 ! END TEMPORARY
964 
965  ALLOCATE(cc(ccsize),stat=errorflag)
966  global%error = errorflag
967  IF ( global%error /= err_none ) THEN
968  CALL errorstop(global,err_allocate,__line__,'cc')
969  END IF ! global%error
970 
971 ! ******************************************************************************
972 ! Test particle location against bounding box of partition
973 ! ******************************************************************************
974 
975  IF ( rflu_testinboundbox(global,xloc,yloc,zloc,xmin,xmax,ymin,ymax, &
976  zmin,zmax) .EQV. .true. ) THEN
977 
978 ! ==============================================================================
979 ! Query octree to get closest cells
980 ! ==============================================================================
981 
982  CALL rflu_queryoctree(xloc,yloc,zloc,ccsize,cc)
983 
984 ! ==============================================================================
985 ! Test cells obtained from Octree if they contain specified location
986 ! ==============================================================================
987 ! ------------------------------------------------------------------------------
988 
989  foundflag = .false.
990 
991  cellloop: DO icgloop = 1,ccsize
992  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,cc(icgloop)) .EQV. .true. ) THEN
993  icgout = cc(icgloop)
994 
995  foundflag = .true.
996 
997  EXIT cellloop
998  END IF ! RFLU_ICT_TestInCell
999  END DO cellloop
1000 
1001 ! ==============================================================================
1002 ! Check whether particle was found
1003 ! ==============================================================================
1004 
1005  IF ( foundflag .EQV. .false. ) THEN
1006  icgout = crazy_value_int
1007  END IF ! foundFlag
1008 
1009 ! ******************************************************************************
1010 ! Particle located outside bounding box of partition
1011 ! ******************************************************************************
1012 
1013  ELSE
1014  icgout = crazy_value_int
1015  END IF ! RFLU_TestInBoundNox
1016 
1017 ! ******************************************************************************
1018 ! Deallocate temporary memory
1019 ! ******************************************************************************
1020 
1021  DEALLOCATE(cc,stat=errorflag)
1022  global%error = errorflag
1023  IF ( global%error /= err_none ) THEN
1024  CALL errorstop(global,err_deallocate,__line__,'cc')
1025  END IF ! global%error
1026 
1027 ! ******************************************************************************
1028 ! End
1029 ! ******************************************************************************
1030 
1031  CALL deregisterfunction(global)
1032 
1033 END SUBROUTINE plag_rflu_findcellsoctkernel
1034 
1035 
1036 
1037 
1038 
1039 
1040 
1041 
1042 ! ******************************************************************************
1043 !
1044 ! Purpose: Determine cells which contain particles using modified Octree
1045 ! approach.
1046 !
1047 ! Description: None.
1048 !
1049 ! Input:
1050 ! pRegion Pointer to region
1051 !
1052 ! Output: None.
1053 !
1054 ! Notes:
1055 ! 1. It is not enough to simply get closest cell from Octree, because
1056 ! proximity to cell centroid does not guarantee that the specified
1057 ! location is actually inside the cell.
1058 ! 2. This routine is suitable to determine the cell containing a particle
1059 ! after the latters position has been updated.
1060 ! 3. This routine cannot be used in parallel runs and for particles which
1061 ! leave the domain or bounce from solid walls.
1062 !
1063 ! ******************************************************************************
1064 
1065 SUBROUTINE plag_rflu_findcellsoctmod(pRegion)
1066 
1068 
1069  IMPLICIT NONE
1070 
1071 ! ******************************************************************************
1072 ! Declarations
1073 ! ******************************************************************************
1074 
1075 ! ==============================================================================
1076 ! Arguments
1077 ! ==============================================================================
1078 
1079  TYPE(t_region), POINTER :: pregion
1080 
1081 ! ==============================================================================
1082 ! Locals
1083 ! ==============================================================================
1084 
1085  LOGICAL :: foundflag
1086  CHARACTER(CHRLEN) :: errorstring
1087  INTEGER :: ccsize,errorflag,icg,ipcl
1088  INTEGER, DIMENSION(:), ALLOCATABLE :: cc
1089  REAL(RFREAL) :: delfrac,xdel,xloc,xmax,xmin,ydel,yloc,ymax,ymin,zdel,zloc, &
1090  zmax,zmin
1091  TYPE(t_global), POINTER :: global
1092  TYPE(t_grid), POINTER :: pgrid
1093  TYPE(t_plag), POINTER :: pplag
1094 
1095 ! ******************************************************************************
1096 ! Start
1097 ! ******************************************************************************
1098 
1099  global => pregion%global
1100 
1101  CALL registerfunction(global,'PLAG_RFLU_FindCellsOctMod',&
1102  'PLAG_RFLU_ModFindCells.F90')
1103 
1104 ! ******************************************************************************
1105 ! Set variables and pointers
1106 ! ******************************************************************************
1107 
1108  pgrid => pregion%grid
1109  pplag => pregion%plag
1110 
1111  delfrac = 0.01_rfreal
1112 
1113 ! ccSize = MIN(100,pGrid%nCells) ! Must be larger than unity
1114 
1115 ! TEMPORARY
1116  ccsize = min(50,pgrid%nCells) ! Must be larger than unity
1117 ! END TEMPORARY
1118 
1119  ALLOCATE(cc(ccsize),stat=errorflag)
1120  global%error = errorflag
1121  IF ( global%error /= err_none ) THEN
1122  CALL errorstop(global,err_allocate,__line__,'cc')
1123  END IF ! global%error
1124 
1125 ! ******************************************************************************
1126 ! Build bounding box
1127 ! ******************************************************************************
1128 
1129  xmin = minval(pgrid%xyz(xcoord,1:pgrid%nVert))
1130  xmax = maxval(pgrid%xyz(xcoord,1:pgrid%nVert))
1131  ymin = minval(pgrid%xyz(ycoord,1:pgrid%nVert))
1132  ymax = maxval(pgrid%xyz(ycoord,1:pgrid%nVert))
1133  zmin = minval(pgrid%xyz(zcoord,1:pgrid%nVert))
1134  zmax = maxval(pgrid%xyz(zcoord,1:pgrid%nVert))
1135 
1136  xdel = xmax - xmin
1137  ydel = ymax - ymin
1138  zdel = zmax - zmin
1139 
1140  xmin = xmin - delfrac*xdel
1141  xmax = xmax + delfrac*xdel
1142  ymin = ymin - delfrac*ydel
1143  ymax = ymax + delfrac*ydel
1144  zmin = zmin - delfrac*zdel
1145  zmax = zmax + delfrac*zdel
1146 
1147 ! ******************************************************************************
1148 ! Build Octree with cell centroids: NOTE only for actual cells
1149 ! ******************************************************************************
1150 
1151  CALL rflu_createoctree(global,pgrid%nCells)
1152 
1153  CALL rflu_buildoctree(pgrid%cofg(xcoord,1:pgrid%nCells), &
1154  pgrid%cofg(ycoord,1:pgrid%nCells), &
1155  pgrid%cofg(zcoord,1:pgrid%nCells), &
1157 
1158 ! ******************************************************************************
1159 ! Loop over particles
1160 ! ******************************************************************************
1161 
1162  DO ipcl = 1,pplag%nPcls
1163 
1164 ! ==============================================================================
1165 ! Get particle cell and position
1166 ! ==============================================================================
1167 
1168  icg = pplag%aivOld(aiv_plag_icells,ipcl) ! NOTE OLD cell index
1169 
1170  xloc = pplag%cv(cv_plag_xpos,ipcl) ! NOTE already NEW particle position
1171  yloc = pplag%cv(cv_plag_ypos,ipcl)
1172  zloc = pplag%cv(cv_plag_zpos,ipcl)
1173 
1174 ! ==============================================================================
1175 ! Check if particle still in same cell
1176 ! ==============================================================================
1177 
1178  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,icg) .EQV. .false. ) THEN
1179 
1180 ! ------------------------------------------------------------------------------
1181 ! Test particle location against bounding box of partition
1182 ! ------------------------------------------------------------------------------
1183 
1184  IF ( rflu_testinboundbox(global,xloc,yloc,zloc,xmin,xmax,ymin,ymax, &
1185  zmin,zmax) .EQV. .true. ) THEN
1186 
1187 ! ----- Query octree to get closest cells --------------------------------------
1188 
1189  CALL rflu_queryoctree(xloc,yloc,zloc,ccsize,cc)
1190 
1191 ! ----- Test cells obtained from Octree if they contain specified location -----
1192 
1193  foundflag = .false.
1194 
1195  cellloop: DO icg = 1,ccsize
1196  IF ( rflu_ict_testincell(pregion,xloc,yloc,zloc,cc(icg)) .EQV. .true. ) THEN
1197  pplag%aiv(aiv_plag_icells,ipcl) = cc(icg)
1198 
1199  foundflag = .true.
1200 
1201  EXIT cellloop
1202  END IF ! RFLU_ICT_TestInCell
1203  END DO cellloop
1204 
1205 ! ----- Check whether particle was found ---------------------------------------
1206 
1207  IF ( foundflag .EQV. .false. ) THEN
1208  WRITE(errorstring,'(I6)') ipcl
1209  CALL errorstop(global,err_plag_pcl_not_found,__line__, &
1210  trim(errorstring))
1211  END IF ! foundFlag
1212 
1213 ! ------------------------------------------------------------------------------
1214 ! Particle located outside bounding box of partition
1215 ! ------------------------------------------------------------------------------
1216 
1217  ELSE
1218 
1219 ! TEMPORARY
1220  WRITE(*,*) 'timeCurrent,iPcl,xLocOld,yLocOld,zLocOld,xLoc,yLoc,zLoc = ',&
1221  global%currentTime,ipcl,pplag%cvOld(cv_plag_xpos:cv_plag_zpos,ipcl),&
1222  xloc,yloc,zloc
1223 ! END TEMPORARY
1224 
1225  WRITE(errorstring,'(I6)') ipcl
1226  CALL errorstop(global,err_plag_pcl_not_found,__line__,trim(errorstring))
1227  END IF ! RFLU_TestInBoundNox
1228 
1229 ! ==============================================================================
1230 ! Particle still in same cell, copy cell index
1231 ! ==============================================================================
1232 
1233  ELSE
1234  pplag%aiv(aiv_plag_icells,ipcl) = icg
1235  END IF ! RFLU_ICT_TestInCell
1236  END DO ! iPcl
1237 
1238 ! ******************************************************************************
1239 ! Destroy Octree and deallocate temporary memory
1240 ! ******************************************************************************
1241 
1242  CALL rflu_destroyoctree(global)
1243 
1244  DEALLOCATE(cc,stat=errorflag)
1245  global%error = errorflag
1246  IF ( global%error /= err_none ) THEN
1247  CALL errorstop(global,err_deallocate,__line__,'cc')
1248  END IF ! global%error
1249 
1250 ! ******************************************************************************
1251 ! End
1252 ! ******************************************************************************
1253 
1254  CALL deregisterfunction(global)
1255 
1256 END SUBROUTINE plag_rflu_findcellsoctmod
1257 
1258 
1259 
1260 
1261 
1262 
1263 
1264 ! ******************************************************************************
1265 !
1266 ! Purpose: Determine cells which contain particles by following trajectory
1267 ! using fast algorithm.
1268 !
1269 ! Description: Follow particle path by intersecting particle trajectory with
1270 ! faces and taking appropriate action determined by type of intersected face.
1271 !
1272 ! Input:
1273 ! pRegion Pointer to region
1274 ! iPclBeg Beginning particle index
1275 ! iPclEnd Ending particle index
1276 !
1277 ! Output: None.
1278 !
1279 ! Notes:
1280 ! 1. Need to properly handle particle deletion from outflow or motion
1281 ! between domain during an intermediate RK-stage as its final
1282 ! position at (n+1) step might not be outside the region.
1283 !
1284 ! ******************************************************************************
1285 
1286 SUBROUTINE plag_rflu_findcellstrajfast(pRegion,iPclBeg,iPclEnd)
1287 
1288  IMPLICIT NONE
1289 
1290 ! ******************************************************************************
1291 ! Declarations
1292 ! ******************************************************************************
1293 
1294 ! ==============================================================================
1295 ! Arguments
1296 ! ==============================================================================
1297 
1298  INTEGER :: ipclbeg,ipclend
1299  TYPE(t_region), POINTER :: pregion
1300 
1301 ! ==============================================================================
1302 ! Locals
1303 ! ==============================================================================
1304 
1305  LOGICAL :: incellcheckflag
1306  CHARACTER(CHRLEN) :: errorstring
1307  INTEGER :: c1,c1k,c2,c2k,errorflag,iborder,icg,ifg,ifgout,ifl,iloc,ilocout, &
1308  ipatch,ipcl,loopcounter
1309  REAL(RFREAL) :: dist,disttot,disttotcutoff,eps,fnx,fny,fnz,imagtraj,theta, &
1310  xloc,xlocnew,xlocold,xtraj,yloc,ylocnew,ylocold,ytraj,zloc, &
1311  zlocnew,zlocold,ztraj
1312  TYPE(t_border), POINTER :: pborder
1313  TYPE(t_global), POINTER :: global
1314  TYPE(t_grid), POINTER :: pgrid
1315  TYPE(t_patch), POINTER :: ppatch
1316  TYPE(t_plag), POINTER :: pplag
1317 
1318 ! ******************************************************************************
1319 ! Start
1320 ! ******************************************************************************
1321 
1322  global => pregion%global
1323 
1324  CALL registerfunction(global,'PLAG_RFLU_FindCellsTrajFast',&
1325  'PLAG_RFLU_ModFindCells.F90')
1326 
1327 ! ******************************************************************************
1328 ! Set variables and pointers
1329 ! ******************************************************************************
1330 
1331  pgrid => pregion%grid
1332  pplag => pregion%plag
1333 
1334  eps = epsilon(1.0_rfreal)
1335  disttotcutoff = 10*epsilon(1.0_rfreal) ! NOTE must be less than tolerICT
1336 
1337 ! ******************************************************************************
1338 ! Loop over particles
1339 ! ******************************************************************************
1340 
1341  DO ipcl = ipclbeg,ipclend
1342  loopcounter = 0 ! Reset loop counter
1343 
1344 ! ==============================================================================
1345 ! Set distance travelled and compute trajectory. NOTE that cannot compute
1346 ! trajectory (unit) vector from distTot because distTot diminishes as the
1347 ! particle travels along the trajectory but xLocNew and xLocOld (as well as
1348 ! y and z components) do not change.
1349 ! ==============================================================================
1350 
1351  disttot = pplag%arv(arv_plag_distot,ipcl)
1352 
1353  IF ( disttot < disttotcutoff ) THEN
1354  cycle
1355  END IF ! distTot
1356 
1357  xlocnew = pplag%cv(cv_plag_xpos,ipcl)
1358  ylocnew = pplag%cv(cv_plag_ypos,ipcl)
1359  zlocnew = pplag%cv(cv_plag_zpos,ipcl)
1360 
1361  xlocold = pplag%cvOld(cv_plag_xpos,ipcl)
1362  ylocold = pplag%cvOld(cv_plag_ypos,ipcl)
1363  zlocold = pplag%cvOld(cv_plag_zpos,ipcl)
1364 
1365  xtraj = xlocnew - xlocold
1366  ytraj = ylocnew - ylocold
1367  ztraj = zlocnew - zlocold
1368 
1369  imagtraj = 1.0_rfreal/(sqrt(xtraj*xtraj + ytraj*ytraj + ztraj*ztraj) + eps)
1370 
1371  xtraj = imagtraj*xtraj
1372  ytraj = imagtraj*ytraj
1373  ztraj = imagtraj*ztraj
1374 
1375 ! ------------------------------------------------------------------------------
1376 ! Set variables for trajectory loop
1377 ! ------------------------------------------------------------------------------
1378 
1379  xloc = xlocnew - disttot*xtraj
1380  yloc = ylocnew - disttot*ytraj
1381  zloc = zlocnew - disttot*ztraj
1382 
1383  icg = pplag%aivOld(aiv_plag_icells,ipcl)
1384 
1385 ! ==============================================================================
1386 ! Loop until distance travelled along trajectory consumed
1387 ! ==============================================================================
1388 
1389  trajloop: DO
1390  loopcounter = loopcounter + 1
1391 
1392 ! ------------------------------------------------------------------------------
1393 ! Find appropriate intersection and associated face
1394 ! ------------------------------------------------------------------------------
1395 
1396  CALL rflu_computelinecellxsectfast(pregion,xloc,yloc,zloc,xtraj,ytraj, &
1397  ztraj,icg,dist,iloc,ifg)
1398 
1399 ! ------------------------------------------------------------------------------
1400 ! Update total distance travelled
1401 ! ------------------------------------------------------------------------------
1402 
1403  disttot = disttot - dist
1404 
1405 ! ------------------------------------------------------------------------------
1406 ! Check whether have remaining total distance
1407 ! ------------------------------------------------------------------------------
1408 
1409 ! --- No distance remaining: Found cell containing new location ----------------
1410 
1411  IF ( disttot <= 0.0_rfreal ) THEN
1412  pplag%aiv(aiv_plag_icells,ipcl) = icg
1413 
1414  EXIT trajloop
1415 
1416 ! --- Distance remaining: Keep searching ---------------------------------------
1417 
1418  ELSE
1419 
1420 ! ----- Trajectory intersects interior face
1421 
1422  IF ( iloc == 0 ) THEN
1423  c1 = pgrid%f2c(1,ifg)
1424  c2 = pgrid%f2c(2,ifg)
1425 
1426  c1k = rflu_getglobalcellkind(global,pgrid,c1)
1427  c2k = rflu_getglobalcellkind(global,pgrid,c2)
1428 
1429  SELECT CASE ( rflu_getfacekind(global,c1k,c2k) )
1430  CASE ( face_kind_aa ) ! Actual-actual face
1431  IF ( c1 == icg ) THEN
1432  icg = c2
1433  ELSE
1434  icg = c1
1435  END IF ! c1
1436  CASE ( face_kind_av ) ! Actual-virtual face
1437  ifl = ifg - pgrid%nFaces + pgrid%nFacesAV
1438 
1439  iborder = pgrid%avf2b(1,ifl)
1440 
1441  pborder => pgrid%borders(iborder)
1442 
1443  pborder%nPclsSend = pborder%nPclsSend + 1
1444 
1445  IF ( pborder%nPclsSend > pborder%nPclsSendMax ) &
1446  CALL rflu_mpi_recreatebufferipclsend(pregion,pborder)
1447 
1448  pborder%iPclSend(1,pborder%nPclsSend) = ipcl
1449  pborder%iPclSend(2,pborder%nPclsSend) = pgrid%avf2b(2,ifl)
1450 
1451  pplag%aiv(aiv_plag_status,ipcl) = plag_status_comm
1452  pplag%arv(arv_plag_distot,ipcl) = disttot
1453 
1454  IF ( c1 == icg ) THEN
1455  icg = c2
1456  ELSE
1457  icg = c1
1458  END IF ! c1
1459 
1460  pplag%aiv(aiv_plag_icells,ipcl) = icg
1461 
1462  ipatch = pgrid%avf2p(ifl)
1463 
1464  IF ( ipatch /= crazy_value_int ) THEN ! Transform coordinates
1465  ppatch => pregion%patches(ipatch)
1466 
1467  IF ( ppatch%bcType == bc_periodic ) THEN
1468  CALL rflu_relp_transformvector(pregion,ppatch,xlocold, &
1469  ylocold,zlocold)
1470  CALL rflu_relp_transformvector(pregion,ppatch,xlocnew, &
1471  ylocnew,zlocnew)
1472  ELSE
1473  CALL errorstop(global,err_reached_default,__line__)
1474  END IF ! pPatch%bcType
1475  END IF ! iPatch
1476 
1477  EXIT trajloop
1478  CASE default
1479  CALL errorstop(global,err_reached_default,__line__)
1480  END SELECT ! RFLU_GetFaceKind
1481 
1482 ! ----- Trajectory intersects boundary face
1483 
1484  ELSE ! Boundary face
1485  ppatch => pregion%patches(iloc)
1486 
1487  fnx = ppatch%fn(xcoord,ifg)
1488  fny = ppatch%fn(ycoord,ifg)
1489  fnz = ppatch%fn(zcoord,ifg)
1490 
1491  theta = xtraj*fnx + ytraj*fny + ztraj*fnz
1492 
1493  SELECT CASE ( ppatch%bcType )
1494  CASE ( bc_slipwall:bc_slipwall+bc_range )
1495  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1496  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1497  ifg,ipcl,theta)
1498  END IF ! pPatch%plotStatsFlag
1499  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1500  ylocold,zlocold,xlocnew,ylocnew, &
1501  zlocnew,xtraj,ytraj,ztraj)
1502  CASE ( bc_noslipwall:bc_noslipwall+bc_range )
1503  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1504  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1505  ifg,ipcl,theta)
1506  END IF ! pPatch%plotStatsFlag
1507  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1508  ylocold,zlocold,xlocnew,ylocnew, &
1509  zlocnew,xtraj,ytraj,ztraj)
1510  CASE ( bc_injection:bc_injection+bc_range )
1511  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1512  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1513  ifg,ipcl,theta)
1514  END IF ! pPatch%plotStatsFlag
1515  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1516  ylocold,zlocold,xlocnew,ylocnew, &
1517  zlocnew,xtraj,ytraj,ztraj)
1518  CASE ( bc_outflow:bc_outflow+bc_range )
1519  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1520  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1521  ifg,ipcl,theta)
1522  END IF ! pPatch%plotStatsFlag
1523 
1524  pplag%aiv(aiv_plag_status,ipcl) = plag_status_delete
1525  EXIT trajloop
1526  CASE ( bc_farfield:bc_farfield+bc_range )
1527  pplag%aiv(aiv_plag_status,ipcl) = plag_status_delete
1528  EXIT trajloop
1529  CASE ( bc_symmetry:bc_symmetry+bc_range )
1530  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1531  ylocold,zlocold,xlocnew,ylocnew, &
1532  zlocnew,xtraj,ytraj,ztraj)
1533  CASE ( bc_virtual:bc_virtual+bc_range )
1534  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1535  ylocold,zlocold,xlocnew,ylocnew, &
1536  zlocnew,xtraj,ytraj,ztraj)
1537  CASE default
1538  CALL errorstop(global,err_reached_default,__line__)
1539  END SELECT ! pPatch%bcType
1540 
1541  END IF ! iLoc
1542  END IF ! distTot
1543 
1544 ! ------------------------------------------------------------------------------
1545 ! Guard against infinite loop
1546 ! ------------------------------------------------------------------------------
1547 
1548  IF ( loopcounter >= limit_infinite_loop ) THEN
1549  WRITE(stdout,'(A,1X,A)') solver_name, &
1550  'Infinite loop encountered in particle cell search algorithm'
1551  WRITE(stdout,'(A,3X,A)') solver_name,'Module: Lagrangian Particle (PLAG).'
1552 
1553  WRITE(stdout,'(A,3X,A,1X,1PE12.5)') solver_name,'Current time:', &
1554  global%currentTime
1555 
1556  WRITE(stdout,'(A,3X,A,1X,I5.5)') solver_name,'Global region:', &
1557  pregion%iRegionGlobal
1558  WRITE(stdout,'(A,6X,A,11(1X,A))') solver_name,'#', &
1559  ' iPcl ', &
1560  ' idIni ', &
1561  ' RegIni ', &
1562  ' icg ', &
1563  ' x-location ', &
1564  ' y-location ', &
1565  ' z-Location ', &
1566  ' Energy ', &
1567  ' Diameter '
1568 
1569  WRITE(stdout,'(A,4X,4(1X,I8),6(1X,E13.6))') solver_name,ipcl, &
1570  pplag%aivOld(aiv_plag_pidini,ipcl), &
1571  pplag%aivOld(aiv_plag_regini,ipcl), &
1572  icg,xloc,yloc,zloc, &
1573  pplag%cv(cv_plag_ener,ipcl), &
1574  pplag%dv(dv_plag_diam,ipcl)
1575 
1576  CALL errorstop(global,err_infinite_loop,__line__)
1577  END IF ! loopCounter
1578  END DO trajloop
1579 
1580 ! ==============================================================================
1581 ! Check that kept particles are indeed located in new cells
1582 ! ==============================================================================
1583 
1584  IF ( (global%checkLevel == check_high) .AND. &
1585  (pplag%aiv(aiv_plag_status,ipcl) == plag_status_keep) ) THEN
1586  CALL rflu_ict_testincellfancy(pregion,xlocnew,ylocnew,zlocnew,icg, &
1587  incellcheckflag,ilocout,ifgout)
1588 
1589  IF ( incellcheckflag .EQV. .false. ) THEN
1590  WRITE(stderr,'(A,1X,A,1X,I6)') solver_name,'Particle index:',ipcl
1591  WRITE(stderr,'(A,1X,A,1X,I6)') solver_name,'Cell which failed test:', &
1592  icg
1593  WRITE(stderr,'(A,1X,A,2(1X,I6))') solver_name, &
1594  'Face which failed test:', &
1595  ilocout,ifgout
1596  WRITE(stderr,'(A,1X,A,3(1X,E23.16))') solver_name, &
1597  'Particle old location:', &
1598  xlocold,ylocold,zlocold
1599  WRITE(stderr,'(A,1X,A,3(1X,E23.16))') solver_name, &
1600  'Particle new location:', &
1601  xlocnew,ylocnew,zlocnew
1602 
1603  WRITE(errorstring,'(I6)') ipcl
1604  CALL errorstop(global,err_plag_pcl_not_found,__line__, &
1605  trim(errorstring))
1606  END IF ! inCellCheckFlag
1607  END IF ! global%checkLevel
1608 
1609 ! ==============================================================================
1610 ! Store new position. IMPORTANT: Need to store new position because it may
1611 ! have been reflected and old position because it may have been transformed.
1612 ! ==============================================================================
1613 
1614  pplag%cv(cv_plag_xpos,ipcl) = xlocnew
1615  pplag%cv(cv_plag_ypos,ipcl) = ylocnew
1616  pplag%cv(cv_plag_zpos,ipcl) = zlocnew
1617 
1618  pplag%cvOld(cv_plag_xpos,ipcl) = xlocold
1619  pplag%cvOld(cv_plag_ypos,ipcl) = ylocold
1620  pplag%cvOld(cv_plag_zpos,ipcl) = zlocold
1621  END DO ! iPcl
1622 
1623 ! ******************************************************************************
1624 ! End
1625 ! ******************************************************************************
1626 
1627  CALL deregisterfunction(global)
1628 
1629 END SUBROUTINE plag_rflu_findcellstrajfast
1630 
1631 
1632 
1633 
1634 
1635 
1636 
1637 ! ******************************************************************************
1638 !
1639 ! Purpose: Determine cells which contain particles by following trajectory
1640 ! using safe algorithm.
1641 !
1642 ! Description: Follow particle path by intersecting particle trajectory with
1643 ! faces and taking appropriate action determined by type of intersected face.
1644 !
1645 ! Input:
1646 ! pRegion Pointer to region
1647 ! iPclBeg Beginning particle index
1648 ! iPclEnd Ending particle index
1649 !
1650 ! Output: None.
1651 !
1652 ! Notes:
1653 ! 1. Need to properly handle particle deletion from outflow or motion
1654 ! between domain during an intermediate RK-stage as its final
1655 ! position at (n+1) step might not be outside the region.
1656 !
1657 ! ******************************************************************************
1658 
1659 SUBROUTINE plag_rflu_findcellstrajsafe(pRegion,iPclBeg,iPclEnd)
1660 
1661  IMPLICIT NONE
1662 
1663 ! ******************************************************************************
1664 ! Declarations
1665 ! ******************************************************************************
1666 
1667 ! ==============================================================================
1668 ! Arguments
1669 ! ==============================================================================
1670 
1671  INTEGER :: ipclbeg,ipclend
1672  TYPE(t_region), POINTER :: pregion
1673 
1674 ! ==============================================================================
1675 ! Locals
1676 ! ==============================================================================
1677 
1678  LOGICAL :: incellcheckflag
1679  CHARACTER(CHRLEN) :: errorstring
1680  INTEGER :: c1,c1k,c2,c2k,errorflag,iborder,icg,ifg,ifgout,ifl,iloc, &
1681  ilocout,ipatch,ipcl,loopcounter
1682  REAL(RFREAL) :: dist,disttot,disttotcutoff,eps,fnx,fny,fnz,imagtraj,theta, &
1683  xloc,xlocnew,xlocold,xtraj,yloc,ylocnew,ylocold,ytraj,zloc, &
1684  zlocnew,zlocold,ztraj
1685  TYPE(t_border), POINTER :: pborder
1686  TYPE(t_global), POINTER :: global
1687  TYPE(t_grid), POINTER :: pgrid
1688  TYPE(t_patch), POINTER :: ppatch
1689  TYPE(t_plag), POINTER :: pplag
1690 
1691 ! ******************************************************************************
1692 ! Start
1693 ! ******************************************************************************
1694 
1695  global => pregion%global
1696 
1697  CALL registerfunction(global,'PLAG_RFLU_FindCellsTrajSafe',&
1698  'PLAG_RFLU_ModFindCells.F90')
1699 
1700 ! ******************************************************************************
1701 ! Set variables and pointers
1702 ! ******************************************************************************
1703 
1704  pgrid => pregion%grid
1705  pplag => pregion%plag
1706 
1707  eps = epsilon(1.0_rfreal)
1708  disttotcutoff = 10*eps ! NOTE must be less than tolerICT
1709 
1710 ! ******************************************************************************
1711 ! Loop over particles
1712 ! ******************************************************************************
1713 
1714  DO ipcl = ipclbeg,ipclend
1715  loopcounter = 0 ! Reset loop counter
1716 
1717 ! ==============================================================================
1718 ! Set distance travelled and compute trajectory. NOTE that cannot compute
1719 ! trajectory (unit) vector from distTot because distTot diminishes as the
1720 ! particle travels along the trajectory but xLocNew and xLocOld (as well as
1721 ! y and z components) do not change.
1722 ! ==============================================================================
1723 
1724  disttot = pplag%arv(arv_plag_distot,ipcl)
1725 
1726  IF ( disttot < disttotcutoff ) THEN
1727  cycle
1728  END IF ! distTot
1729 
1730  xlocnew = pplag%cv(cv_plag_xpos,ipcl)
1731  ylocnew = pplag%cv(cv_plag_ypos,ipcl)
1732  zlocnew = pplag%cv(cv_plag_zpos,ipcl)
1733 
1734  xlocold = pplag%cvOld(cv_plag_xpos,ipcl)
1735  ylocold = pplag%cvOld(cv_plag_ypos,ipcl)
1736  zlocold = pplag%cvOld(cv_plag_zpos,ipcl)
1737 
1738  xtraj = xlocnew - xlocold
1739  ytraj = ylocnew - ylocold
1740  ztraj = zlocnew - zlocold
1741 
1742  imagtraj = 1.0_rfreal/(sqrt(xtraj*xtraj + ytraj*ytraj + ztraj*ztraj) + eps)
1743 
1744  xtraj = imagtraj*xtraj
1745  ytraj = imagtraj*ytraj
1746  ztraj = imagtraj*ztraj
1747 
1748 ! ------------------------------------------------------------------------------
1749 ! Set variables for trajectory loop
1750 ! ------------------------------------------------------------------------------
1751 
1752  xloc = xlocnew - disttot*xtraj
1753  yloc = ylocnew - disttot*ytraj
1754  zloc = zlocnew - disttot*ztraj
1755 
1756  icg = pplag%aivOld(aiv_plag_icells,ipcl)
1757 
1758 ! ==============================================================================
1759 ! Loop until distance travelled along trajectory consumed
1760 ! ==============================================================================
1761 
1762  trajloop: DO
1763  loopcounter = loopcounter + 1
1764 
1765 ! ------------------------------------------------------------------------------
1766 ! Find appropriate intersection and associated face
1767 ! ------------------------------------------------------------------------------
1768 
1769  CALL rflu_computelinecellxsectsafe(pregion,xloc,yloc,zloc,xtraj,ytraj, &
1770  ztraj,icg,dist,iloc,ifg)
1771 
1772 ! ------------------------------------------------------------------------------
1773 ! Update total distance travelled
1774 ! ------------------------------------------------------------------------------
1775 
1776  disttot = disttot - dist
1777 
1778 ! ------------------------------------------------------------------------------
1779 ! Check whether have remaining total distance
1780 ! ------------------------------------------------------------------------------
1781 
1782 ! --- No distance remaining: Found cell containing new location ----------------
1783 
1784  IF ( disttot <= 0.0_rfreal ) THEN
1785  pplag%aiv(aiv_plag_icells,ipcl) = icg
1786 
1787  EXIT trajloop
1788 
1789 ! --- Distance remaining: Keep searching ---------------------------------------
1790 
1791  ELSE
1792 
1793 ! ----- Trajectory intersects interior face
1794 
1795  IF ( iloc == 0 ) THEN
1796  c1 = pgrid%f2c(1,ifg)
1797  c2 = pgrid%f2c(2,ifg)
1798 
1799  c1k = rflu_getglobalcellkind(global,pgrid,c1)
1800  c2k = rflu_getglobalcellkind(global,pgrid,c2)
1801 
1802  SELECT CASE ( rflu_getfacekind(global,c1k,c2k) )
1803  CASE ( face_kind_aa ) ! Actual-actual face
1804  IF ( c1 == icg ) THEN
1805  icg = c2
1806  ELSE
1807  icg = c1
1808  END IF ! c1
1809  CASE ( face_kind_av ) ! Actual-virtual face
1810  ifl = ifg - pgrid%nFaces + pgrid%nFacesAV
1811 
1812  iborder = pgrid%avf2b(1,ifl)
1813 
1814  pborder => pgrid%borders(iborder)
1815 
1816  pborder%nPclsSend = pborder%nPclsSend + 1
1817 
1818  IF ( pborder%nPclsSend > pborder%nPclsSendMax ) &
1819  CALL rflu_mpi_recreatebufferipclsend(pregion,pborder)
1820 
1821  pborder%iPclSend(1,pborder%nPclsSend) = ipcl
1822  pborder%iPclSend(2,pborder%nPclsSend) = pgrid%avf2b(2,ifl)
1823 
1824  pplag%aiv(aiv_plag_status,ipcl) = plag_status_comm
1825  pplag%arv(arv_plag_distot,ipcl) = disttot
1826 
1827  IF ( c1 == icg ) THEN
1828  icg = c2
1829  ELSE
1830  icg = c1
1831  END IF ! c1
1832 
1833  pplag%aiv(aiv_plag_icells,ipcl) = icg
1834 
1835  ipatch = pgrid%avf2p(ifl)
1836 
1837  IF ( ipatch /= crazy_value_int ) THEN ! Transform coordinates
1838  ppatch => pregion%patches(ipatch)
1839 
1840  IF ( ppatch%bcType == bc_periodic ) THEN
1841  CALL rflu_relp_transformvector(pregion,ppatch,xlocold, &
1842  ylocold,zlocold)
1843  CALL rflu_relp_transformvector(pregion,ppatch,xlocnew, &
1844  ylocnew,zlocnew)
1845  ELSE
1846  CALL errorstop(global,err_reached_default,__line__)
1847  END IF ! pPatch%bcType
1848  END IF ! iPatch
1849 
1850  EXIT trajloop
1851  CASE default
1852  CALL errorstop(global,err_reached_default,__line__)
1853  END SELECT ! RFLU_GetFaceKind
1854 
1855 ! ----- Trajectory intersects boundary face
1856 
1857  ELSE ! Boundary face
1858  ppatch => pregion%patches(iloc)
1859 
1860  fnx = ppatch%fn(xcoord,ifg)
1861  fny = ppatch%fn(ycoord,ifg)
1862  fnz = ppatch%fn(zcoord,ifg)
1863 
1864  theta = xtraj*fnx + ytraj*fny + ztraj*fnz
1865 
1866  SELECT CASE ( ppatch%bcType )
1867  CASE ( bc_slipwall:bc_slipwall+bc_range )
1868  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1869  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1870  ifg,ipcl,theta)
1871  END IF ! pPatch%plotStatsFlag
1872  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1873  ylocold,zlocold,xlocnew,ylocnew, &
1874  zlocnew,xtraj,ytraj,ztraj)
1875  CASE ( bc_noslipwall:bc_noslipwall+bc_range )
1876  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1877  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1878  ifg,ipcl,theta)
1879  END IF ! pPatch%plotStatsFlag
1880  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1881  ylocold,zlocold,xlocnew,ylocnew, &
1882  zlocnew,xtraj,ytraj,ztraj)
1883  CASE ( bc_injection:bc_injection+bc_range )
1884  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1885  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1886  ifg,ipcl,theta)
1887  END IF ! pPatch%plotStatsFlag
1888  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1889  ylocold,zlocold,xlocnew,ylocnew, &
1890  zlocnew,xtraj,ytraj,ztraj)
1891  CASE ( bc_outflow:bc_outflow+bc_range )
1892  IF ( ppatch%plotStatsFlag .EQV. .true. ) THEN
1893  CALL plag_gathersurfstats(pregion,pplag,ppatch%statsPlag,&
1894  ifg,ipcl,theta)
1895  END IF ! pPatch%plotStatsFlag
1896 
1897  pplag%aiv(aiv_plag_status,ipcl) = plag_status_delete
1898  EXIT trajloop
1899  CASE ( bc_farfield:bc_farfield+bc_range )
1900  pplag%aiv(aiv_plag_status,ipcl) = plag_status_delete
1901  EXIT trajloop
1902  CASE ( bc_symmetry:bc_symmetry+bc_range )
1903  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1904  ylocold,zlocold,xlocnew,ylocnew, &
1905  zlocnew,xtraj,ytraj,ztraj)
1906  CASE ( bc_virtual:bc_virtual+bc_range )
1907  CALL plag_reflectparticledata(ppatch,pplag,ifg,ipcl,xlocold, &
1908  ylocold,zlocold,xlocnew,ylocnew, &
1909  zlocnew,xtraj,ytraj,ztraj)
1910  CASE default
1911  CALL errorstop(global,err_reached_default,__line__)
1912  END SELECT ! pPatch%bcType
1913 
1914  END IF ! iLoc
1915  END IF ! distTot
1916 
1917 ! ------------------------------------------------------------------------------
1918 ! Guard against infinite loop
1919 ! ------------------------------------------------------------------------------
1920 
1921  IF ( loopcounter >= limit_infinite_loop ) THEN
1922  WRITE(stdout,'(A,1X,A)') solver_name, &
1923  'Infinite loop encountered in particle cell search algorithm'
1924  WRITE(stdout,'(A,3X,A)') solver_name,'Module: Lagrangian Particle (PLAG).'
1925 
1926  WRITE(stdout,'(A,3X,A,1X,1PE12.5)') solver_name,'Current time:', &
1927  global%currentTime
1928 
1929  WRITE(stdout,'(A,3X,A,1X,I5.5)') solver_name,'Global region:', &
1930  pregion%iRegionGlobal
1931  WRITE(stdout,'(A,6X,A,11(1X,A))') solver_name,'#', &
1932  ' iPcl ', &
1933  ' idIni ', &
1934  ' RegIni ', &
1935  ' icg ', &
1936  ' x-location ', &
1937  ' y-location ', &
1938  ' z-Location ', &
1939  ' Energy ', &
1940  ' Diameter '
1941 
1942  WRITE(stdout,'(A,4X,4(1X,I8),6(1X,E13.6))') solver_name,ipcl, &
1943  pplag%aivOld(aiv_plag_pidini,ipcl), &
1944  pplag%aivOld(aiv_plag_regini,ipcl), &
1945  icg,xloc,yloc,zloc, &
1946  pplag%cv(cv_plag_ener,ipcl), &
1947  pplag%dv(dv_plag_diam,ipcl)
1948 
1949  CALL errorstop(global,err_infinite_loop,__line__)
1950  END IF ! loopCounter
1951  END DO trajloop
1952 
1953 ! ==============================================================================
1954 ! Check that kept particles are indeed located in new cells
1955 ! ==============================================================================
1956 
1957  IF ( (global%checkLevel == check_high) .AND. &
1958  (pplag%aiv(aiv_plag_status,ipcl) == plag_status_keep) ) THEN
1959  CALL rflu_ict_testincellfancy(pregion,xlocnew,ylocnew,zlocnew,icg, &
1960  incellcheckflag,ilocout,ifgout)
1961 
1962  IF ( incellcheckflag .EQV. .false. ) THEN
1963  WRITE(stderr,'(A,1X,A,1X,I6)') solver_name,'Particle index:',ipcl
1964  WRITE(stderr,'(A,1X,A,1X,I6)') solver_name,'Cell which failed test:', &
1965  icg
1966  WRITE(stderr,'(A,1X,A,2(1X,I6))') solver_name, &
1967  'Face which failed test:', &
1968  ilocout,ifgout
1969  WRITE(stderr,'(A,1X,A,3(1X,E23.16))') solver_name, &
1970  'Particle old location:', &
1971  xlocold,ylocold,zlocold
1972  WRITE(stderr,'(A,1X,A,3(1X,E23.16))') solver_name, &
1973  'Particle new location:', &
1974  xlocnew,ylocnew,zlocnew
1975 
1976  WRITE(errorstring,'(I6)') ipcl
1977  CALL errorstop(global,err_plag_pcl_not_found,__line__, &
1978  trim(errorstring))
1979  END IF ! inCellCheckFlag
1980  END IF ! global%checkLevel
1981 
1982 ! ==============================================================================
1983 ! Store new position. IMPORTANT: Need to store new position because it may
1984 ! have been reflected and old position because it may have been transformed.
1985 ! ==============================================================================
1986 
1987  pplag%cv(cv_plag_xpos,ipcl) = xlocnew
1988  pplag%cv(cv_plag_ypos,ipcl) = ylocnew
1989  pplag%cv(cv_plag_zpos,ipcl) = zlocnew
1990 
1991  pplag%cvOld(cv_plag_xpos,ipcl) = xlocold
1992  pplag%cvOld(cv_plag_ypos,ipcl) = ylocold
1993  pplag%cvOld(cv_plag_zpos,ipcl) = zlocold
1994  END DO ! iPcl
1995 
1996 ! ******************************************************************************
1997 ! End
1998 ! ******************************************************************************
1999 
2000  CALL deregisterfunction(global)
2001 
2002 END SUBROUTINE plag_rflu_findcellstrajsafe
2003 
2004 
2005 
2006 
2007 
2008 ! ******************************************************************************
2009 ! End
2010 ! ******************************************************************************
2011 
2012 END MODULE plag_rflu_modfindcells
2013 
2014 ! ******************************************************************************
2015 !
2016 ! RCS Revision history:
2017 !
2018 ! $Log: PLAG_RFLU_ModFindCells.F90,v $
2019 ! Revision 1.16 2008/12/06 08:44:35 mtcampbe
2020 ! Updated license.
2021 !
2022 ! Revision 1.15 2008/11/19 22:17:48 mtcampbe
2023 ! Added Illinois Open Source License/Copyright
2024 !
2025 ! Revision 1.14 2006/08/18 21:11:35 fnajjar
2026 ! Enabled periodicity, cosmetics
2027 !
2028 ! Revision 1.13 2006/05/05 02:15:49 haselbac
2029 ! Bug fixes: Incorrect computation of traj, missing EXIT, wrong IF
2030 !
2031 ! Revision 1.12 2006/05/02 17:46:23 fnajjar
2032 ! Allowed surface statistics to be gathered on active patches
2033 !
2034 ! Revision 1.11 2006/04/07 15:19:24 haselbac
2035 ! Removed tabs
2036 !
2037 ! Revision 1.10 2005/12/24 21:39:47 haselbac
2038 ! Adapted to changes in ICT
2039 !
2040 ! Revision 1.9 2005/12/19 16:47:45 fnajjar
2041 ! Added verbosity around error trap for infinite loop counter
2042 !
2043 ! Revision 1.8 2005/12/14 21:21:21 fnajjar
2044 ! Added call for dynamic allocation of iPclSend
2045 !
2046 ! Revision 1.7 2005/12/02 20:07:50 fnajjar
2047 ! Added particle reflection for BC_VIRTUAL
2048 !
2049 ! Revision 1.6 2005/11/12 00:34:08 fnajjar
2050 ! Bug fix for iMagTraj in Fast and Safe
2051 !
2052 ! Revision 1.5 2005/09/20 15:46:35 fnajjar
2053 ! Fixed bug in TrajFast and added error trap for iPclSend overflow
2054 !
2055 ! Revision 1.4 2005/07/18 20:47:41 fnajjar
2056 ! Aligned fast routine with safe adding proper construct for trajectory
2057 !
2058 ! Revision 1.3 2005/05/18 22:17:50 fnajjar
2059 ! Added PLAG_RFLU_ComputeDistTot, changed comp of distTot and xyzLoc,
2060 ! infrast for comm
2061 !
2062 ! Revision 1.2 2005/05/02 21:59:38 haselbac
2063 ! Preparation for parallelization of FindCells routines, cosmetics
2064 !
2065 ! Revision 1.1 2005/04/27 14:55:55 fnajjar
2066 ! Initial import
2067 !
2068 ! ******************************************************************************
2069 
2070 
2071 
2072 
2073 
2074 
2075 
2076 
2077 
2078 
2079 
2080 
2081 
2082 
2083 
2084 
subroutine, public rflu_computelinecellxsectsafe(pRegion, xLoc, yLoc, zLoc, ex, ey, ez, icg, distOut, iPatchOut, ifgOut)
subroutine plag_reflectparticledata(pPatch, pPlag, ifl, iPcl, xLocOld, yLocOld, zLocOld, xLoc, yLoc, zLoc, xTraj, yTraj, zTraj)
double ymin() const
subroutine, public plag_rflu_findcellsoctmod(pRegion)
double xmax() const
subroutine, public rflu_queryoctree(XPT, YPT, ZPT, NUMP, NEIGHP)
subroutine, public rflu_ict_testincellfancy(pRegion, xLoc, yLoc, zLoc, icg, testInCell, iPatchOut, ifgOut)
LOGICAL function, public rflu_testinboundbox(global, xLoc, yLoc, zLoc, xMin, xMax, yMin, yMax, zMin, zMax)
subroutine, public plag_rflu_findcellstrajfast(pRegion, iPclBeg, iPclEnd)
INTEGER function, public rflu_getglobalcellkind(global, pGrid, icg)
subroutine, public rflu_ict_testincelllohner(pRegion, xLoc, yLoc, zLoc, icg, testInCell, iPatchOut, ifgOut)
double xmin() const
subroutine, public plag_rflu_findcellsbrute(pRegion)
subroutine registerfunction(global, funName, fileName)
Definition: ModError.F90:449
double zmin() const
subroutine plag_rflu_findcellsbrutekernel(pRegion, xLoc, yLoc, zLoc, icgOut)
double sqrt(double d)
Definition: double.h:73
subroutine, public plag_rflu_findcellsbrutemod(pRegion)
subroutine, public rflu_buildoctree(XI, YI, ZI, XLOW, XUPP, YLOW, YUPP, ZLOW, ZUPP)
subroutine, public plag_gathersurfstats(pRegion, pPlag, pStatsPlag, ifl, iPcl, thetaAngle)
subroutine, public plag_rflu_findcellslohner(pRegion)
subroutine, public rflu_destroyoctree(global)
subroutine, public plag_rflu_computedisttot(pRegion)
INTEGER function, public rflu_getfacekind(global, c1k, c2k)
subroutine, public rflu_relp_transformvector(pRegion, pPatch, vx, vy, vz)
double zmax() const
double ymax() const
LOGICAL function, public rflu_ict_testincell(pRegion, xLoc, yLoc, zLoc, icg)
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:346
subroutine errorstop(global, errorCode, errorLine, addMessage)
Definition: ModError.F90:483
subroutine, public plag_rflu_findcellsoct(pRegion)
long double dist(long double *coord1, long double *coord2, int size)
subroutine deregisterfunction(global)
Definition: ModError.F90:469
subroutine, public rflu_computelinecellxsectfast(pRegion, xLoc, yLoc, zLoc, ex, ey, ez, icg, distOut, iPatchOut, ifgOut)
subroutine, public rflu_createoctree(global, nPoints)
subroutine plag_rflu_findcellsoctkernel(pRegion, xLoc, yLoc, zLoc, xMin, xMax, yMin, yMax, zMin, zMax, icgOut)
LOGICAL function floatequal(a, b, tolIn)
Definition: ModTools.F90:99
subroutine, public rflu_mpi_recreatebufferipclsend(pRegion, pBorder)
subroutine, public plag_rflu_findcellstrajsafe(pRegion, iPclBeg, iPclEnd)