Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PLAG_ModInjection.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 stochastic injection algorithm.
26 !
27 ! Description: None.
28 !
29 ! Notes: None.
30 !
31 ! ******************************************************************************
32 !
33 ! $Id: PLAG_ModInjection.F90,v 1.11 2008/12/06 08:44:34 mtcampbe Exp $
34 !
35 ! Copyright: (c) 2004-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
47  USE modbndpatch, ONLY: t_patch
48  USE moddatastruct, ONLY: t_region
49  USE moderror
50  USE modrandom, ONLY: rand1uniform
51 
54 
57 
58  IMPLICIT NONE
59 
60  PRIVATE
61  PUBLIC :: plag_ejectparticle, &
64 
65 ! ******************************************************************************
66 ! Declarations and definitions
67 ! ******************************************************************************
68 
69  CHARACTER(CHRLEN) :: RCSIdentString = &
70  '$RCSfile: PLAG_ModInjection.F90,v $ $Revision: 1.11 $'
71 
72 ! ******************************************************************************
73 ! Routines
74 ! ******************************************************************************
75 
76  CONTAINS
77 
78 
79 
80 !******************************************************************************
81 !
82 ! Purpose: Fills PLAG datastructure for ejected particle.
83 !
84 ! Description: none.
85 !
86 ! Input:
87 ! pGlobal Pointer to global data
88 ! pPlag Pointer to particle data
89 ! pTilePlag Pointer to tile particle data
90 ! iTile Tile index
91 ! icg Cell index
92 ! burnStat Particle burning status
93 ! nVert Number of vertices on tile element surface
94 ! normDirFlag Normal direction flag
95 ! xyzVertex Coordinates of element vertices
96 ! fn Face normal coordinates
97 ! fc Face centroids coordinates
98 ! cellHeight Cell height
99 ! plagVolRatio Volume ratio particles get from tiles
100 !
101 ! Output:
102 ! pPlag Plag values for cv, aiv, arv of current region.
103 ! pTilePlag Tile values for cv, dv of current region.
104 !
105 ! Notes: none.
106 !
107 !******************************************************************************
108 
109 SUBROUTINE plag_ejectparticle( pRegion,pPlag,pTilePlag, &
110  itile,icg,burnstat, &
111  nvert,normdirflag,xyzvertex, &
112  fn,fc,cellheight,plagvolratio )
113 
114 #ifdef RFLU
116 #endif
117 
118 ! ******************************************************************************
119 ! Definitions and declarations
120 ! ******************************************************************************
121 
122 ! ==============================================================================
123 ! Arguments
124 ! ==============================================================================
125 
126  INTEGER, INTENT(IN) :: burnstat,icg,itile,normdirflag,nvert
127 
128  REAL(RFREAL), INTENT(IN) :: cellheight,plagvolratio
129  REAL(RFREAL), DIMENSION(ZCOORD), INTENT(IN) :: fc,fn
130  REAL(RFREAL), DIMENSION(ZCOORD,4), INTENT(IN) :: xyzvertex
131 
132  TYPE(t_plag), POINTER :: pplag
133  TYPE(t_tile_plag), POINTER :: ptileplag
134  TYPE(t_region), POINTER :: pregion
135 
136 ! ==============================================================================
137 ! Locals
138 ! ==============================================================================
139 
140  INTEGER, PARAMETER :: iter_cell_locate_max = 20
141  INTEGER :: icont,icvplagmass,icvtilemass,ipcl,ireg,itercelllocate, &
142  ncont,nextidnumber,npcls,npclsmax
143  INTEGER, POINTER, DIMENSION(:) :: pcvplagmass, pcvtilemass
144  INTEGER, POINTER, DIMENSION(:,:) :: paiv
145 
146  LOGICAL :: celllocate
147 
148  REAL(RFREAL) :: plagmomenrm,sxn,syn,szn,xloc,yloc,zloc
149  REAL(RFREAL), DIMENSION(3) :: poolxyz
150  REAL(RFREAL), POINTER, DIMENSION(:,:) :: parv,pcvplag,pcvtile,pdvtile
151 
152  TYPE(t_global), POINTER :: global
153 ! ******************************************************************************
154 ! Start
155 ! ******************************************************************************
156 
157  rcsidentstring = '$RCSfile: PLAG_ModInjection.F90,v $ $Revision: 1.11 $'
158 
159  global => pregion%global
160 
161  CALL registerfunction( global, 'PLAG_EjectParticle',&
162  'PLAG_ModInjection.F90' )
163 
164 ! ******************************************************************************
165 ! Set pointers and variables
166 ! ******************************************************************************
167 
168  pcvplag => pplag%cv
169  pcvplagmass => pplag%cvPlagMass
170  paiv => pplag%aiv
171  parv => pplag%arv
172 
173  pcvtile => ptileplag%cv
174  pcvtilemass => ptileplag%cvTileMass
175  pdvtile => ptileplag%dv
176 
177  ireg = pregion%iRegionGlobal
178  ncont = pregion%plagInput%nCont
179 
180 ! ******************************************************************************
181 ! Load normals to point inwards
182 ! Note: RFLU defines normals pointing outwards.
183 ! ******************************************************************************
184 
185  sxn = fn(xcoord) *normdirflag
186  syn = fn(ycoord) *normdirflag
187  szn = fn(zcoord) *normdirflag
188 
189 ! ******************************************************************************
190 ! Increment PLAG datastructure for new injected particle
191 ! ******************************************************************************
192 
193  pplag%nPcls = pplag%nPcls + 1
194  ipcl = pplag%nPcls
195 
196  ptileplag%nPclsInjc(itile) = ptileplag%nPclsInjc(itile) + 1
197 
198 ! ******************************************************************************
199 ! Trap error if nPcls exceeds maximum datastructure dimension, nPclsMax
200 ! ******************************************************************************
201 
202  npcls = pplag%nPcls
203  npclsmax = pregion%plag%nPclsMax
204 
205  IF ( npcls >= npclsmax ) THEN
206  WRITE(stdout,*) ' PLAG_EjectParticle: Datastructure Dimension Exceeded ',&
207  npcls,npclsmax
208  CALL errorstop( global,err_plag_memoverflow,__line__ )
209  END IF ! nPcls
210 
211 ! ******************************************************************************
212 ! Keep track of global count in particle ejected in region
213 ! ******************************************************************************
214 
215  pplag%nextIdNumber = pplag%nextIdNumber + 1
216  nextidnumber = pplag%nextIdNumber
217 
218 ! ******************************************************************************
219 ! Compute PLAG cv datastructure for new injected particle
220 ! ******************************************************************************
221 
222  DO icont = 1, ncont
223  icvplagmass = pcvplagmass(icont)
224  icvtilemass = pcvtilemass(icont)
225  pcvplag(icvplagmass,ipcl) = pcvtile(icvtilemass,itile) *plagvolratio
226  END DO ! iCont
227 
228  pcvplag(cv_plag_ener,ipcl) = pcvtile(cv_tile_ener, itile) *plagvolratio
229 
230  plagmomenrm = pcvtile(cv_tile_momnrm,itile) *plagvolratio
231  pcvplag(cv_plag_xmom,ipcl) = plagmomenrm*sxn
232  pcvplag(cv_plag_ymom,ipcl) = plagmomenrm*syn
233  pcvplag(cv_plag_zmom,ipcl) = plagmomenrm*szn
234 
235  pcvplag(cv_plag_enervapor,ipcl) = 0._rfreal
236 
237 ! ******************************************************************************
238 ! Determine particle position
239 ! include a test to insure particle is in tile cell
240 ! Note: RFLU defines normals pointing outwards.
241 ! ******************************************************************************
242 
243  itercelllocate = 1
244 
245 199 CONTINUE
246 
247  CALL plag_injcsetpoolpos( pregion,nvert,normdirflag,xyzvertex, &
248  fc(xcoord:zcoord),fn(xcoord:zcoord), &
249  cellheight,poolxyz )
250 
251  xloc = poolxyz(xcoord)
252  yloc = poolxyz(ycoord)
253  zloc = poolxyz(zcoord)
254 
255  celllocate = rflu_ict_testincell(pregion,xloc,yloc,zloc,icg)
256 
257 ! TEMPORARY
258 ! PRINT*,' nVert = ', nVert
259 ! PRINT*,' icg = ' ,icg
260 ! PRINT*,' iTile = ' ,iTile
261 ! PRINT*,' normDirFlag = ', normDirFlag
262 ! PRINT*,' fc = ', fc(XCOORD:ZCOORD)
263 ! PRINT*,' fn = ', fn(XCOORD:ZCOORD)
264 ! PRINT*,' cellHeight = ', cellHeight
265 ! PRINT*,' poolxyz = ', poolxyz
266 ! PRINT*,' cellLocate = ', cellLocate
267 ! END TEMPORARY
268 
269  IF (celllocate .EQV. .false.) THEN
270  itercelllocate = itercelllocate+1
271  IF ( itercelllocate > iter_cell_locate_max ) THEN
272  WRITE(stdout,*) ' PLAG_EjectParticle: Unable to create a particle after ',&
273  iter_cell_locate_max, ' iterations'
274 
275  CALL errorstop( global,err_plag_cellindex,__line__ )
276  END IF ! iterCellLocate
277  goto 199
278  ENDIF ! cellLocate
279 
280  pcvplag(cv_plag_xpos,ipcl) = poolxyz(xcoord)
281  pcvplag(cv_plag_ypos,ipcl) = poolxyz(ycoord)
282  pcvplag(cv_plag_zpos,ipcl) = poolxyz(zcoord)
283 
284 ! ******************************************************************************
285 ! Set aiv and arv
286 ! ******************************************************************************
287 
288  paiv(aiv_plag_pidini,ipcl) = nextidnumber
289  paiv(aiv_plag_regini,ipcl) = ireg
290  paiv(aiv_plag_icells,ipcl) = icg
291  paiv(aiv_plag_status,ipcl) = plag_status_keep
292  paiv(aiv_plag_burnstat,ipcl) = burnstat
293 
294  parv(arv_plag_spload,ipcl) = pdvtile(dv_tile_spload,itile)
295 
296 ! ******************************************************************************
297 ! Decrease pool variables
298 ! ******************************************************************************
299 
300  DO icont = 1, ncont
301  icvplagmass = pcvplagmass(icont)
302  icvtilemass = pcvtilemass(icont)
303  pcvtile(icvtilemass,itile) = pcvtile(icvtilemass, itile) - &
304  pdvtile(dv_tile_spload,itile) * &
305  pcvplag(icvplagmass,ipcl)
306  END DO ! iCont
307 
308  pcvtile(cv_tile_momnrm,itile) = pcvtile(cv_tile_momnrm,itile) - &
309  pdvtile(dv_tile_spload,itile) * &
310  plagmomenrm
311 
312  pcvtile(cv_tile_ener ,itile) = pcvtile(cv_tile_ener ,itile) - &
313  pdvtile(dv_tile_spload,itile) * &
314  pcvplag(cv_plag_ener,ipcl)
315 
316 ! ******************************************************************************
317 ! End
318 ! ******************************************************************************
319 
320  CALL deregisterfunction( global )
321 
322 END SUBROUTINE plag_ejectparticle
323 
324 
325 
326 
327 ! ******************************************************************************
328 !
329 ! Purpose: Determine coordinates for injected particle on patch surface
330 ! based on random number generator.
331 !
332 ! Description: None.
333 !
334 ! Input:
335 ! pRegion Pointer to region data
336 ! nVert Number of vertices
337 ! normDirFlag Flag setting normal direction
338 ! xyzVertex Coordinates of patch
339 ! faceCentroid Coordinates of face centroid
340 ! sNormal Vector of face normal
341 ! cellHeight Height of cell to which patch is attached
342 !
343 ! Output:
344 ! posPlag Coordinates of injected particle
345 !
346 ! Notes:
347 ! 1. Normals need to be set pointing inward
348 ! 2. normDirFlag is set to -1 for RFLU and +1 for RFLO
349 ! 3. RFLU always set normals pointing outwards of the computational domain
350 ! 4. RFLU numbers vertices in the counterclockwise direction as 1-2-3-4
351 !
352 ! ******************************************************************************
353 
354  SUBROUTINE plag_injcsetpoolpos( pRegion,nVert,normDirFlag,xyzVertex, &
355  facecentroid,snormal,cellheight,posplag )
356 
357  IMPLICIT NONE
358 
359 ! ******************************************************************************
360 ! Definitions and declarations
361 ! ******************************************************************************
362 
363 ! ==============================================================================
364 ! Arguments
365 ! ==============================================================================
366 
367  INTEGER, INTENT(IN) :: nvert,normdirflag
368 
369  REAL(RFREAL), INTENT(IN) :: cellheight
370  REAL(RFREAL), DIMENSION(ZCOORD), INTENT(IN) :: facecentroid,snormal
371  REAL(RFREAL), DIMENSION(ZCOORD,4), INTENT(IN) :: xyzvertex
372  REAL(RFREAL), DIMENSION(ZCOORD), INTENT(OUT) :: posplag
373 
374  TYPE(t_region), POINTER :: pregion
375 
376 ! ==============================================================================
377 ! Locals
378 ! ==============================================================================
379 
380  LOGICAL :: usetriangle1
381 
382  REAL(RFREAL), PARAMETER :: height_fraction = 1.0e-3_rfreal
383  REAL(RFREAL) :: areatriangle1,areatriangle2,xrand,xtrirand,yrand,zrand
384  REAL(RFREAL), DIMENSION(ZCOORD) :: snormalinward, v1,v2
385 
386  TYPE(t_global), POINTER :: global
387 
388 ! ******************************************************************************
389 ! Start
390 ! ******************************************************************************
391 
392  rcsidentstring = '$RCSfile: PLAG_ModInjection.F90,v $ $Revision: 1.11 $'
393 
394  global => pregion%global
395 
396  CALL registerfunction(global,'PLAG_InjcSetPoolPos',&
397  'PLAG_ModInjection.F90' )
398 
399 ! ******************************************************************************
400 ! Set normals to point inwards
401 ! ******************************************************************************
402 
403  snormalinward(xcoord:zcoord) = normdirflag *snormal(xcoord:zcoord)
404 
405 ! ******************************************************************************
406 ! Select a random point within the appropriate triangle
407 ! ******************************************************************************
408 
409  xtrirand = rand1uniform(pregion%randData)
410  xrand = rand1uniform(pregion%randData)
411  yrand = rand1uniform(pregion%randData)
412 
413 ! ******************************************************************************
414 ! Reflect back into triangle
415 ! ******************************************************************************
416 
417  IF ( xrand+yrand > 1.0_rfreal ) THEN
418  xrand = 1.0_rfreal-xrand
419  yrand = 1.0_rfreal-yrand
420  ENDIF ! xRand
421 
422  zrand = 1.0_rfreal -(xrand+yrand)
423 
424 ! ******************************************************************************
425 ! Setup triangles depending on element type
426 ! ******************************************************************************
427 
428  SELECT CASE(nvert)
429 
430 ! ==============================================================================
431 ! For triangular elements, always select triangle1
432 ! ==============================================================================
433 
434  CASE (3)
435  usetriangle1 = .true.
436 
437 ! ==============================================================================
438 ! Partition the face into two triangles and compute the areas
439 ! of their projections normal to sNormal
440 ! ==============================================================================
441 
442  CASE (4)
443  v1(xcoord:zcoord) = xyzvertex(xcoord:zcoord,2) -xyzvertex(xcoord:zcoord,1)
444  v2(xcoord:zcoord) = xyzvertex(xcoord:zcoord,3) -xyzvertex(xcoord:zcoord,1)
445 
446  areatriangle1 = 0.5_rfreal*abs( snormal(xcoord)*(v1(2)*v2(3)-v1(3)*v2(2)) &
447  + snormal(ycoord)*(v1(3)*v2(1)-v1(1)*v2(3)) &
448  + snormal(zcoord)*(v1(1)*v2(2)-v1(2)*v2(1)) )
449 
450  v1(xcoord:zcoord) = xyzvertex(xcoord:zcoord,3) -xyzvertex(xcoord:zcoord,1)
451  v2(xcoord:zcoord) = xyzvertex(xcoord:zcoord,4) -xyzvertex(xcoord:zcoord,1)
452 
453  areatriangle2 = 0.5_rfreal*abs( snormal(xcoord)*(v1(2)*v2(3)-v1(3)*v2(2)) &
454  + snormal(ycoord)*(v1(3)*v2(1)-v1(1)*v2(3)) &
455  + snormal(zcoord)*(v1(1)*v2(2)-v1(2)*v2(1)) )
456 
457 ! ------------------------------------------------------------------------------
458 ! Select which triangle to select a point in
459 ! ------------------------------------------------------------------------------
460 
461  usetriangle1 = ( (areatriangle1+areatriangle2)*xtrirand < areatriangle1 )
462  END SELECT ! nVert
463 
464 ! ******************************************************************************
465 ! Set particle position on triangular tile
466 ! ******************************************************************************
467 
468  IF ( usetriangle1 ) THEN
469  posplag(xcoord:zcoord) = xrand*xyzvertex(xcoord:zcoord,1) &
470  + yrand*xyzvertex(xcoord:zcoord,2) &
471  + zrand*xyzvertex(xcoord:zcoord,3)
472  ELSE
473  posplag(xcoord:zcoord) = xrand*xyzvertex(xcoord:zcoord,1) &
474  + yrand*xyzvertex(xcoord:zcoord,3) &
475  + zrand*xyzvertex(xcoord:zcoord,4)
476  ENDIF ! useTriangle1
477 
478 ! ******************************************************************************
479 ! Adjust posPlag to be on tile surface
480 ! ******************************************************************************
481 
482  posplag(xcoord:zcoord) = posplag(xcoord:zcoord) &
483  - dot_product( posplag(xcoord:zcoord)- &
484  facecentroid(xcoord:zcoord), &
485  snormalinward(xcoord:zcoord)) &
486  * snormalinward(xcoord:zcoord)
487 
488 ! ******************************************************************************
489 ! Add tiny offset to put posPlag inside cell
490 ! ******************************************************************************
491 
492  posplag(xcoord:zcoord) = posplag(xcoord:zcoord) &
493  + height_fraction*cellheight &
494  *snormalinward(xcoord:zcoord)
495 
496 ! *****************************************************************************
497 ! End
498 ! *****************************************************************************
499 
500  CALL deregisterfunction(global)
501 
502  END SUBROUTINE plag_injcsetpoolpos
503 
504 
505 
506 !******************************************************************************
507 !
508 ! Purpose: Invoke ejection model1 to generate particles on tile surfaces.
509 !
510 ! Description: none.
511 !
512 ! Input:
513 ! pRegion Pointer to region data
514 ! pPlag Pointer to particle data
515 ! pTilePlag Pointer to tile particle data
516 ! iTile Tile identifier
517 ! icg Cell index
518 ! burnStat Particle burning status
519 ! nVert Number of vertices on tile element surface
520 ! normDirFlag Normal direction flag
521 ! xyzVertex Coordinates of element vertices
522 ! volMeanPart Mean particle volume
523 ! fn Face normal coordinates
524 ! fc Face centroids coordinates
525 ! cellHeight Cell height
526 !
527 ! Output:
528 ! pPlag Plag values for cv, aiv, arv of current region.
529 ! pTilePlag Tile values for cv, dv of current region.
530 !
531 ! Notes: none.
532 !
533 !******************************************************************************
534 
535 SUBROUTINE plag_invokeejecmodel1( pRegion,pPlag,pTilePlag, &
536  itile,icg,burnstat,nvert, &
537  normdirflag,xyzvertex, &
538  volmeanpart,fn,fc,cellheight )
539 
540 ! ******************************************************************************
541 ! Definitions and declarations
542 ! ******************************************************************************
543 
544 ! ==============================================================================
545 ! Arguments
546 ! ==============================================================================
547 
548  INTEGER, INTENT(IN) :: burnstat,icg,itile,normdirflag,nvert
549 
550  REAL(RFREAL), INTENT(IN) :: cellheight,volmeanpart
551  REAL(RFREAL), DIMENSION(ZCOORD), INTENT(IN) :: fc,fn
552  REAL(RFREAL), DIMENSION(ZCOORD,4), INTENT(IN) :: xyzvertex
553 
554  TYPE(t_region), POINTER :: pregion
555  TYPE(t_plag), POINTER :: pplag
556  TYPE(t_tile_plag), POINTER :: ptileplag
557 
558 ! ==============================================================================
559 ! Locals
560 ! ==============================================================================
561 
562  INTEGER :: injcdiamdist
563  INTEGER, POINTER, DIMENSION(:) :: pcvplagmass, pcvtilemass
564 
565  LOGICAL :: injectq
566 
567  REAL(RFREAL) :: injcbeta,pi,plagvolratio,poolvolsum,tinjccoeff,tinjcsum
568  REAL(RFREAL), POINTER, DIMENSION(:,:) :: pcvtile,pdvtile
569 
570  TYPE(t_global), POINTER :: global
571 
572 ! ******************************************************************************
573 ! Start
574 ! ******************************************************************************
575 
576  rcsidentstring = '$RCSfile: PLAG_ModInjection.F90,v $ $Revision: 1.11 $'
577 
578  global => pregion%global
579 
580  CALL registerfunction( global, 'PLAG_InvokeEjecModel1',&
581  'PLAG_ModInjection.F90' )
582 
583 ! ******************************************************************************
584 ! Set pointers and variables
585 ! ******************************************************************************
586 
587  pcvtile => ptileplag%cv
588  pcvtilemass => ptileplag%cvTileMass
589  pdvtile => ptileplag%dv
590 
591  injcdiamdist = pregion%plagInput%injcDiamDist
592  injcbeta = pregion%plagInput%injcBeta
593 
594 ! ******************************************************************************
595 ! Begin injection algorithm
596 ! ******************************************************************************
597 
598  poolvolsum = sum( pcvtile( pcvtilemass(:),itile ) / &
599  pregion%plagInput%dens(:) )
600 
601  pdvtile(dv_tile_poolvold,itile) = poolvolsum
602 
603  tinjccoeff = injcbeta *volmeanpart
604 
605  tinjcsum = 0.0_rfreal
606 
607  CALL plag_injcsetinjection( pregion,ptileplag,itile, &
608  tinjccoeff,tinjcsum,poolvolsum, &
609  injectq,plagvolratio )
610 
611 ! ******************************************************************************
612 ! If injectQ set to True, PLAG datastructure for new injected particle
613 ! ******************************************************************************
614 
615  DO WHILE ( injectq )
616 
617 ! TEMPORARY
618 ! PRINT*,'Ejection Model =', pRegion%plagInput%ejecModel
619 ! PRINT*,' IFC = ' ,iTile
620 ! PRINT*,'injectQ = ',injectQ
621 ! PRINT*,' plagVolRatio = ',plagVolRatio
622 ! PRINT*,' tInjcSum = ',tInjcSum
623 ! PRINT*,' poolVolSum = ',poolVolSum
624 ! PRINT*,' pDvTile(DV_TILE_DIAM,iTile) = ',pDvTile(DV_TILE_DIAM,iTile)
625 ! PRINT*,' pDvTile(DV_TILE_COUNTDOWN,iTile) = ',pDvTile(DV_TILE_COUNTDOWN,iTile)
626 ! END TEMPORARY
627 
628 ! ==============================================================================
629 ! Eject particle
630 ! ==============================================================================
631 
632  CALL plag_ejectparticle( pregion,pplag,ptileplag, &
633  itile,icg,burnstat, &
634  nvert,normdirflag,xyzvertex, &
635  fn,fc,cellheight,plagvolratio )
636 
637 ! ==============================================================================
638 ! Update tile diameter and superparticle loading factor
639 ! ==============================================================================
640 
641  CALL plag_injcmakeparticle( pregion, injcdiamdist, &
642  pdvtile(dv_tile_diam, itile), &
643  pdvtile(dv_tile_spload,itile) )
644 
645 ! ==============================================================================
646 ! Check if another particle could be injected
647 ! ==============================================================================
648 
649  CALL plag_injcsetinjection( pregion,ptileplag,itile, &
650  tinjccoeff,tinjcsum,poolvolsum, &
651  injectq,plagvolratio )
652 
653  END DO ! injectQ
654 
655 ! *****************************************************************************
656 ! End
657 ! *****************************************************************************
658 
659  CALL deregisterfunction(global)
660 
661 END SUBROUTINE plag_invokeejecmodel1
662 
663 
664 
665 !******************************************************************************
666 !
667 ! Purpose: Invoke conservative random ejection model
668 ! to generate particles on tile surfaces.
669 !
670 ! Description: none.
671 !
672 ! Input:
673 ! pRegion Pointer to region data
674 ! pPlag Pointer to particle data
675 ! pTilePlag Pointer to tile particle data
676 ! iTile Tile identifier
677 ! icg Cell index
678 ! burnStat Particle burning status
679 ! nVert Number of vertices on tile element surface
680 ! normDirFlag Normal direction flag
681 ! xyzVertex Coordinates of element vertices
682 ! volMeanPart Mean particle volume
683 ! fn Face normal coordinates
684 ! fc Face centroids coordinates
685 ! cellHeight Cell height
686 !
687 ! Output:
688 ! pPlag Plag values for cv, aiv, arv of current region.
689 ! pTilePlag Tile values for cv, dv of current region.
690 !
691 ! Notes: none.
692 !
693 !******************************************************************************
694 
695 SUBROUTINE plag_invokeconsrandejec( pRegion,pPlag,pTilePlag, &
696  itile,icg,burnstat,nvert, &
697  normdirflag,xyzvertex, &
698  volmeanpart,fn,fc,cellheight )
699 
700 ! ******************************************************************************
701 ! Definitions and declarations
702 ! ******************************************************************************
703 
704 ! ==============================================================================
705 ! Arguments
706 ! ==============================================================================
707 
708  INTEGER, INTENT(IN) :: burnstat,icg,itile,normdirflag,nvert
709 
710  REAL(RFREAL), INTENT(IN) :: cellheight,volmeanpart
711  REAL(RFREAL), DIMENSION(ZCOORD), INTENT(IN) :: fc,fn
712  REAL(RFREAL), DIMENSION(ZCOORD,4), INTENT(IN) :: xyzvertex
713 
714  TYPE(t_region), POINTER :: pregion
715  TYPE(t_plag), POINTER :: pplag
716  TYPE(t_tile_plag), POINTER :: ptileplag
717 
718 ! ==============================================================================
719 ! Locals
720 ! ==============================================================================
721 
722  INTEGER :: ejecmodel,injcdiamdist
723  INTEGER, POINTER, DIMENSION(:) :: pcvplagmass, pcvtilemass
724 
725  REAL(RFREAL) :: injcbeta,pi,plagvolratio,poolvolsum,tinjccoeff,tinjcsum
726  REAL(RFREAL) :: meansuperparticlevolume, spload
727  REAL(RFREAL) :: injcbetafac, injcbetafacinv
728  REAL(RFREAL) :: poolvololdsum, poolvolfinal, remainingvolume
729  REAL(RFREAL) :: currentsuperparticlevolume, poolvolume
730  REAL(RFREAL) :: poolexcess, pexcesss, possibleexcess
731  REAL(RFREAL) :: countdown, countdownnext, deltavolume, randunif
732  REAL(RFREAL) :: currentparticlevolume
733  REAL(RFREAL) :: poolvolcurr
734  REAL(RFREAL), POINTER, DIMENSION(:,:) :: pcvtile,pcvoldtile,pdvtile
735 
736  TYPE(t_global), POINTER :: global
737 
738 ! ******************************************************************************
739 ! Start
740 ! ******************************************************************************
741 
742  rcsidentstring = '$RCSfile: PLAG_ModInjection.F90,v $ $Revision: 1.11 $'
743 
744  global => pregion%global
745 
746  CALL registerfunction( global, 'PLAG_InvokeConsRandEjec',&
747  'PLAG_ModInjection.F90' )
748 
749 ! ******************************************************************************
750 ! Set pointers and variables
751 ! ******************************************************************************
752 
753  pcvtile => ptileplag%cv
754  pcvoldtile => ptileplag%cvOld
755  pcvtilemass => ptileplag%cvTileMass
756  pdvtile => ptileplag%dv
757 
758 
759  injcdiamdist = pregion%plagInput%injcDiamDist
760  injcbeta = pregion%plagInput%injcBeta
761 
762  pi = global%pi
763  spload = pregion%plagInput%spload
764  meansuperparticlevolume = volmeanpart *spload
765 
766  injcbetafac = 2.0_rfreal *injcbeta *meansuperparticlevolume**2
767  injcbetafacinv = 1.0_rfreal/injcbetafac
768 
769 ! ******************************************************************************
770 ! Begin injection algorithm
771 ! ******************************************************************************
772 
773 ! ==============================================================================
774 ! poolVolSum is the pool volume after the current timestep is finished
775 ! ==============================================================================
776 
777  poolvolsum = sum( pcvtile( pcvtilemass(:),itile ) / &
778  pregion%plagInput%dens(:) )
779 
780 ! ==============================================================================
781 ! poolVolOldSum is the pool volume before the current timestep began
782 ! ==============================================================================
783 
784  poolvololdsum = sum( pcvoldtile( pcvtilemass(:),itile ) / &
785  pregion%plagInput%dens(:) )
786 
787 ! ==============================================================================
788 ! poolVolume is built up incrementally with volume injection,
789 ! and is decremented when (super)particles are ejected
790 ! ==============================================================================
791 
792  poolvolume = poolvololdsum
793 
794 ! ==============================================================================
795 ! poolVolFinal starts with all volume injection having occurred,
796 ! and is decremented when (super)particles are ejected
797 ! ==============================================================================
798 
799  poolvolfinal = poolvolsum
800 
801 ! ==============================================================================
802 ! poolVolCurr starts with all volume injection having occurred,
803 ! and is decremented when (super)particles are ejected
804 ! ==============================================================================
805 
806  poolvolcurr = poolvolsum
807 
808 ! ==============================================================================
809 ! remainingVolume is the volume to be added to the pool over the
810 ! current time step: it decreases to 0 as all volume is added
811 ! ==============================================================================
812 
813  remainingvolume = poolvolsum -poolvololdsum
814 
815 ! TEMPORARY
816 ! PRINT*,'Ejection Model =', pRegion%plagInput%ejecModel
817 ! PRINT*,' IFC = ' ,iTile
818 ! PRINT*,' plagVolRatio = ',plagVolRatio
819 ! PRINT*,' poolVolSum = ',poolVolSum
820 ! PRINT*,' remainingVolume = ',remainingVolume
821 ! PRINT*,' pDvTile(DV_TILE_DIAM,iTile) = ',pDvTile(DV_TILE_DIAM,iTile)
822 ! PRINT*,' pDvTile(DV_TILE_COUNTDOWN,iTile) = ',pDvTile(DV_TILE_COUNTDOWN,iTile)
823 ! END TEMPORARY
824 
825 ! ==============================================================================
826 ! Start the ejection loop for CRE model
827 ! ==============================================================================
828 
829  creejectloop: DO
830  currentsuperparticlevolume = pi/6.0_rfreal *spload &
831  * pdvtile(dv_tile_diam,itile)**3.0_rfreal
832 
833  currentparticlevolume = pi/6.0_rfreal &
834  * pdvtile(dv_tile_diam,itile)**3.0_rfreal
835 
836 ! ------------------------------------------------------------------------------
837 ! poolExcess is the volume that would remain in the pool after ejection
838 ! ------------------------------------------------------------------------------
839 
840 ! poolExcess = poolVolume -currentSuperParticleVolume
841 
842 ! TEMPORARY
843  poolexcess = poolvolcurr -currentsuperparticlevolume
844 ! END TEMPORARY
845 
846 ! ------------------------------------------------------------------------------
847 ! possibleExcess is the volume that would remain in the pool at the end of
848 ! the timestep after the current particle is (and no others are) ejected
849 ! ------------------------------------------------------------------------------
850 
851  possibleexcess = poolexcess + remainingvolume
852 
853 ! ------------------------------------------------------------------------------
854 ! pExcessS is an auxiliary variable that occurs in a few formulas
855 ! ------------------------------------------------------------------------------
856 
857  IF ( poolexcess > 0.0_rfreal ) THEN
858  pexcesss = poolexcess**2
859  ELSE
860  pexcesss = 0.0_rfreal
861  ENDIF ! poolExcess
862 
863 ! ------------------------------------------------------------------------------
864 ! countdown is the internal ejection clock for the current particle: it
865 ! starts to tick down when pool volume > current (super)particle volume
866 ! ------------------------------------------------------------------------------
867 
868  countdown = pdvtile(dv_tile_countdown,itile)
869 
870 ! ------------------------------------------------------------------------------
871 ! countdownNext is what the clock could tick down to within remainingVolume
872 ! ------------------------------------------------------------------------------
873 
874  IF ( possibleexcess > 0.0_rfreal ) THEN
875  countdownnext = countdown + injcbetafacinv &
876  * (pexcesss -possibleexcess**2.0_rfreal)
877  ELSE
878  countdownnext = countdown
879  ENDIF ! possibleExcess
880 
881 ! ------------------------------------------------------------------------------
882 ! Pool volume too small to eject particle
883 ! ------------------------------------------------------------------------------
884 
885 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
886 ! if the clock cannot tick down to zero within remainingVolume, no more
887 ! particles will be ejected in this timestep
888 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
889 
890  IF ( countdownnext> 0.0_rfreal ) THEN
891  poolvolume = poolvolume + remainingvolume ! not needed except as check
892  pdvtile(dv_tile_countdown,itile) = countdownnext
893  EXIT creejectloop
894 
895 !-------------------------------------------------------------------------------
896 ! Pool volume big enough to eject particle
897 !-------------------------------------------------------------------------------
898 
899 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
900 ! if the clock can tick down below zero, then we need to find when it
901 ! reaches zero, and then eject the particle
902 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
903 
904  ELSE
905 
906 ! --- deltaVolume is the volume that must be added to the pool (out of
907 ! remainingVolume) in order to bring countdown exactly to zero
908 
909  deltavolume = sqrt(injcbetafac*countdown +pexcesss) -poolexcess
910 
911 ! --- therefore deltaVolume is added to the pool, the countdown hits zero,
912 ! and the particle is ejected
913 
914  poolvolume = poolvolume +deltavolume -currentsuperparticlevolume
915 
916 ! --- the deltaVolume added to the pool is taken from remainingVolume
917 
918  remainingvolume = remainingvolume -deltavolume
919 
920 ! --- plagVolRatio must be in terms of poolVolFinal: the pool cv variables
921 ! are expressed in terms of values at the end of the time step, not
922 ! in terms of the intermediate values like poolVolume
923 
924  plagvolratio = currentparticlevolume / poolvolfinal
925 
926 ! --- poolVolFinal, like the cv variables, is affected by particle ejection
927 
928  poolvolfinal = poolvolfinal -currentsuperparticlevolume
929 
930 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
931 ! Eject particle
932 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
933 
934  CALL plag_ejectparticle( pregion,pplag,ptileplag, &
935  itile,icg,burnstat, &
936  nvert,normdirflag,xyzvertex, &
937  fn,fc,cellheight,plagvolratio )
938 
939 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
940 ! Update tile diameter and superparticle loading factor
941 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
942 
943  CALL plag_injcmakeparticle( pregion, injcdiamdist, &
944  pdvtile(dv_tile_diam, itile), &
945  pdvtile(dv_tile_spload,itile) )
946 
947 ! TEMPORARY
948 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
949 ! Compute current pool volume after being decreased in PLAG_EjectParticle
950 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
951 
952  poolvolcurr = sum( pcvtile( pcvtilemass(:),itile ) / &
953  pregion%plagInput%dens(:) )
954 
955 ! END TEMPORARY
956 
957 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
958 ! Set countdown for new particle
959 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
960 
961  randunif = rand1uniform(pregion%randData)
962 
963  IF ( randunif <= 0.0_rfreal) THEN
964 ! ----- treats randUnif as 1.9e-22
965  pdvtile(dv_tile_countdown,itile) = 50.0_rfreal
966  ELSE
967  pdvtile(dv_tile_countdown,itile) = -log(randunif)
968  END IF ! randUnif
969 
970  END IF ! countdownNext
971  END DO creejectloop
972 
973 !------------------------------------------------------------------------------
974 ! Temporary check: poolVolume and poolVolFinal should now agree
975 !------------------------------------------------------------------------------
976 
977  IF ( abs(poolvolume - poolvolfinal) / poolvolfinal > 1.0e-10_rfreal) &
978  print*,'CRE check: iTile ', itile,(poolvolume - poolvolfinal) / poolvolfinal
979 
980 ! *****************************************************************************
981 ! End
982 ! *****************************************************************************
983 
984  CALL deregisterfunction(global)
985 
986 END SUBROUTINE plag_invokeconsrandejec
987 
988 ! ******************************************************************************
989 ! End
990 ! ******************************************************************************
991 
992 END MODULE plag_modinjection
993 
994 ! ******************************************************************************
995 !
996 ! RCS Revision history:
997 !
998 ! $Log: PLAG_ModInjection.F90,v $
999 ! Revision 1.11 2008/12/06 08:44:34 mtcampbe
1000 ! Updated license.
1001 !
1002 ! Revision 1.10 2008/11/19 22:17:46 mtcampbe
1003 ! Added Illinois Open Source License/Copyright
1004 !
1005 ! Revision 1.9 2007/03/06 23:15:32 fnajjar
1006 ! Renamed nPclsTot to nPclsMax
1007 !
1008 ! Revision 1.8 2006/04/07 15:19:23 haselbac
1009 ! Removed tabs
1010 !
1011 ! Revision 1.7 2005/12/30 16:26:25 fnajjar
1012 ! Bug fix for vertex and triangle defs in posPlag
1013 !
1014 ! Revision 1.6 2005/12/24 21:35:49 haselbac
1015 ! Adapted to changes in ICT, cosmetics
1016 !
1017 ! Revision 1.5 2005/01/20 15:36:19 fnajjar
1018 ! Bug fix to properly bypass negative pool volume
1019 !
1020 ! Revision 1.4 2004/07/28 18:56:54 fnajjar
1021 ! Included error trap for memory overflow
1022 !
1023 ! Revision 1.3 2004/07/12 15:52:38 fnajjar
1024 ! Included interface and routine for conservative random ejection model
1025 !
1026 ! Revision 1.2 2004/07/12 14:43:17 fnajjar
1027 ! Added pertinent routines to prepare for CRE ejection model
1028 !
1029 ! Revision 1.1 2004/03/08 22:35:37 fnajjar
1030 ! Initial import of Injection Module
1031 !
1032 ! ******************************************************************************
1033 
1034 
1035 
1036 
1037 
1038 
1039 
1040 
1041 
1042 
Tfloat sum() const
Return the sum of all the pixel values in an image.
Definition: CImg.h:13022
subroutine, public plag_ejectparticle(pRegion, pPlag, pTilePlag, iTile, icg, burnStat, nVert, normDirFlag, xyzVertex, fn, fc, cellHeight, plagVolRatio)
subroutine, public plag_invokeejecmodel1(pRegion, pPlag, pTilePlag, iTile, icg, burnStat, nVert, normDirFlag, xyzVertex, volMeanPart, fn, fc, cellHeight)
subroutine plag_injcsetinjection(region, pTilePlag, iTile, tCoeff, tSum, poolVol, injectQ, ratio)
subroutine registerfunction(global, funName, fileName)
Definition: ModError.F90:449
subroutine plag_injcmakeparticle(region, injcDiamDist, diam, spLoad)
REAL(RFREAL) function rand1uniform(rdata)
Definition: ModRandom.F90:345
double sqrt(double d)
Definition: double.h:73
subroutine plag_injcsetpoolpos(pRegion, nVert, normDirFlag, xyzVertex, faceCentroid, sNormal, cellHeight, posPlag)
static const double pi
Definition: smooth_medial.C:43
LOGICAL function, public rflu_ict_testincell(pRegion, xLoc, yLoc, zLoc, icg)
virtual std::ostream & print(std::ostream &os) const
subroutine errorstop(global, errorCode, errorLine, addMessage)
Definition: ModError.F90:483
long double dot_product(pnt vec1, pnt vec2)
subroutine deregisterfunction(global)
Definition: ModError.F90:469
subroutine, public plag_invokeconsrandejec(pRegion, pPlag, pTilePlag, iTile, icg, burnStat, nVert, normDirFlag, xyzVertex, volMeanPart, fn, fc, cellHeight)
IndexType nvert() const
Definition: Mesh.H:565