MFIX  2016-1
mass_inflow_pic.f
Go to the documentation of this file.
1 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
2 ! C
3 ! Subroutine: MPPIC_MI_BC C
4 ! Purpose: C
5 ! C
6 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
7  SUBROUTINE mass_inflow_pic
8 
9 ! Modules
10 !---------------------------------------------------------------------//
11  USE bc
12  USE constant
13  USE cutcell
14  USE discretelement
15  use error_manager
16  USE functions
17  USE geometry
18  USE mfix_pic
19  USE mpi_utility
20  USE param, only: dimension_m
21  USE param1, only: half, zero
22  use physprop, only: mmax, d_p0, ro_s0
23  USE pic_bc
24  USE randomno
25  USE run
26  IMPLICIT NONE
27 
28 ! Local Variables
29 !---------------------------------------------------------------------//
30  INTEGER :: WDIR, IDIM, IPCOUNT, LAST_EMPTY_SPOT, NEW_SPOT
31  INTEGER :: BCV, BCV_I, L, LC, PIP_ADD_COUNT, IPROC
32  INTEGER :: IFLUID, JFLUID, KFLUID, IJK, M
33  DOUBLE PRECISION :: CORD_START(3), DOML(3),WALL_NORM(3)
34  DOUBLE PRECISION :: AREA_INFLOW, VEL_INFLOW(dimn), STAT_WT
35 
36  LOGICAL :: DELETE_PART
37  DOUBLE PRECISION :: EPS_INFLOW(dimension_m)
38  DOUBLE PRECISION :: REAL_PARTS(dimension_m)
39  DOUBLE PRECISION :: COMP_PARTS(dimension_m)
40  DOUBLE PRECISION :: VEL_NORM_MAG, VOL_INFLOW, VOL_IJK
41 
42 ! Temp logical variables for checking constant npc and statwt specification
43  LOGICAL :: CONST_NPC, CONST_STATWT
44 
45  DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: RANDPOS
46  INTEGER :: CNP_CELL_COUNT
47  DOUBLE PRECISION :: RNP_CELL_COUNT
48  integer :: lglobal_id
49  integer, dimension(0:numpes-1) :: add_count_all
50 
51  LOGICAL, parameter :: setDBG = .true.
52  LOGICAL :: dFlag
53 
54  type :: ty_spotlist
55  integer spot
56  type(ty_spotlist),pointer :: next => null()
57  end type ty_spotlist
58 
59  type(ty_spotlist),pointer :: &
60  cur_spotlist => null(), &
61  prev_spotlist => null(), &
62  temp_spotlist => null()
63 !......................................................................!
64 
65 
66  CALL init_err_msg("PIC_MI_BC")
67 
68  dflag = (dmp_log .AND. setdbg)
69  pip_add_count = 0
70  last_empty_spot = 0
71 
72  ALLOCATE(cur_spotlist); cur_spotlist%spot = -1
73 
74  DO bcv_i = 1, pic_bcmi
75  bcv = pic_bcmi_map(bcv_i)
76 
77  wall_norm(1:3) = pic_bcmi_normdir(bcv_i,1:3)
78 
79  !Find the direction of the normal for this wall
80  wdir = 0
81  DO idim = 1, dimn
82  wdir = wdir + abs(wall_norm(idim))*idim
83  end DO
84 
85  DO lc=pic_bcmi_ijkstart(bcv_i), pic_bcmi_ijkend(bcv_i)
86  ijk = pic_bcmi_ijk(lc)
87 
88  IF(.NOT.fluid_at(ijk)) cycle
89 
90  ifluid = i_of(ijk)
91  jfluid = j_of(ijk)
92  kfluid = k_of(ijk)
93 
94  cord_start(1) = xe(ifluid) - pic_bcmi_offset(bcv_i,1)*dx(ifluid)
95 
96  cord_start(2) = yn(jfluid) - pic_bcmi_offset(bcv_i,2)*dy(jfluid)
97 
98 
99  cord_start(3) = merge(zero, zt(kfluid) - pic_bcmi_offset(bcv_i,3)*dz(kfluid), no_k)
100 
101  doml(1) = dx(ifluid)
102  doml(2) = dy(jfluid)
103  doml(3) = merge(dz(1), dz(kfluid), no_k)
104 
105  area_inflow = doml(1)*doml(2)*doml(3)/doml(wdir)
106 
107  vol_ijk = doml(1)*doml(2)*doml(3)
108 
109  doml(wdir) = zero
110  !set this to zero as the particles will
111  !be seeded only on the BC plane
112 
113  DO m = 1, des_mmax+mmax
114 
115  IF(solids_model(m) /= 'PIC') cycle
116 
117  eps_inflow(m) = bc_rop_s(bcv, m)/ro_s0(m)
118  vel_inflow(1) = bc_u_s(bcv, m)
119  vel_inflow(2) = bc_v_s(bcv, m)
120  vel_inflow(3) = bc_w_s(bcv, m)
121 
122  vel_norm_mag = abs(dot_product(vel_inflow(1:dimn), wall_norm(1:dimn)))
123  vol_inflow = area_inflow*vel_norm_mag*dtsolid
124 
125  real_parts(m) = 6.d0*eps_inflow(m)*vol_inflow/&
126  (pi*(d_p0(m)**3.d0))
127  comp_parts(m) = zero
128 
129  const_npc = (bc_pic_mi_const_npc (bcv, m) .ne. 0)
130  const_statwt = (bc_pic_mi_const_statwt(bcv, m) .ne. zero)
131  IF(const_npc) THEN
132  IF(eps_inflow(m).GT.zero) &
133  comp_parts(m) = REAL(bc_pic_mi_const_npc(bcv, m))* &
134  VOL_INFLOW/VOL_IJK
135  ELSEIF(const_statwt) THEN
136  comp_parts(m) = real_parts(m)/ &
137  bc_pic_mi_const_statwt(bcv, m)
138  ENDIF
139 
140  pic_bcmi_rnp(lc,m) = pic_bcmi_rnp(lc,m) + real_parts(m)
141 
142  pic_bcmi_cnp(lc,m) = pic_bcmi_cnp(lc,m) + comp_parts(m)
143 
144 
145  IF(pic_bcmi_cnp(lc,m).GE.1.d0) THEN
146  cnp_cell_count = int(pic_bcmi_cnp(lc,m))
147  pic_bcmi_cnp(lc,m) = pic_bcmi_cnp(lc,m) - cnp_cell_count
148 
149  rnp_cell_count = pic_bcmi_rnp(lc,m)
150  pic_bcmi_rnp(lc,m) = zero
151 
152  !set pic_bcmi_rnp to zero to reflect that all real particles have been seeded
153  stat_wt = rnp_cell_count/REAL(cnp_cell_count)
154  ALLOCATE(randpos(cnp_cell_count*dimn))
155  CALL uni_rno(randpos(:))
156 
157  DO ipcount = 1, cnp_cell_count
158 
159 
160  CALL pic_find_empty_spot(last_empty_spot, new_spot)
161 
162  des_pos_old( new_spot,1:dimn) = cord_start(1:dimn) &
163  & + randpos((ipcount-1)*dimn+1: &
164  & (ipcount-1)*dimn+dimn)*doml(1:dimn)
165  des_pos_new( new_spot,:) = des_pos_old(new_spot,:)
166  des_vel_old(new_spot,1:dimn) = vel_inflow(1:dimn)
167 
168  des_vel_new( new_spot,:) = des_vel_old( new_spot,:)
169 
170  des_radius(new_spot) = d_p0(m)*half
171 
172  ro_sol(new_spot) = ro_s0(m)
173 
174  des_stat_wt(new_spot) = stat_wt
175 
176  pijk(new_spot, 1) = ifluid
177  pijk(new_spot, 2) = jfluid
178  pijk(new_spot, 3) = kfluid
179  pijk(new_spot, 4) = ijk
180  pijk(new_spot, 5) = m
181 
182  pvol(new_spot) = (4.0d0/3.0d0)*pi*des_radius(new_spot)**3
183  pmass(new_spot) = pvol(new_spot)*ro_sol(new_spot)
184 
185  fc( new_spot,:) = zero
186  delete_part = .false.
187  IF(pic_bcmi_incl_cutcell(bcv_i)) &
189  (des_pos_new( new_spot,1:dimn), &
190  delete_part)
191 
192  IF(.NOT.delete_part) THEN
193 
194  pip = pip+1
195  pip_add_count = pip_add_count + 1
196  CALL set_normal(new_spot)
197  ! add to the list
198  ALLOCATE(temp_spotlist)
199  temp_spotlist%spot = new_spot
200  temp_spotlist%next => cur_spotlist
201  cur_spotlist => temp_spotlist
202  nullify(temp_spotlist)
203 
204  ELSE
205  CALL set_nonexistent(new_spot)
206  last_empty_spot = new_spot - 1
207  ENDIF
208 
209  !WRITE(*,'(A,2(2x,i5), 2x, A,2x, 3(2x,i2),2x, A, 3(2x,g17.8))') &
210  ! 'NEW PART AT ', NEW_SPOT, MAX_PIP, 'I, J, K = ', IFLUID, JFLUID, KFLUID, 'POS =', DES_POS_NEW(NEW_SPOT,:)
211  !IF(DMP_LOG) WRITE(UNIT_LOG,'(A,2x,i5, 2x, A,2x, 3(2x,i2),2x, A, 3(2x,g17.8))') &
212  ! 'NEW PART AT ', NEW_SPOT, 'I, J, K = ', IFLUID, JFLUID, KFLUID, 'POS =', DES_POS_NEW(NEW_SPOT,:)
213 
214  !WRITE(*,*) 'WDIR, DOML = ', WDIR, DOML(:)
215  END DO
216  DEALLOCATE(randpos)
217 
218  end IF
219  end DO
220  end DO
221  end DO
222 
223 !Now assign global id to new particles added
224  add_count_all(:) = 0
225  add_count_all(mype) = pip_add_count
226  call global_all_sum(add_count_all(0:numpes-1))
227  lglobal_id = imax_global_id + sum(add_count_all(0:mype-1))
228 
229  do l = 1,pip_add_count
230  lglobal_id = lglobal_id + 1
231  iglobal_id(cur_spotlist%spot)= lglobal_id
232  prev_spotlist=> cur_spotlist
233  cur_spotlist => cur_spotlist%next
234  deallocate(prev_spotlist)
235  end do
236  deallocate(cur_spotlist)
237  imax_global_id = imax_global_id + sum(add_count_all(0:numpes-1))
238 
239  IF(pic_report_seeding_stats) then
240 
241  IF(sum(add_count_all(:)).GT.0) THEN
242  WRITE(err_msg,'(/,2x,A,2x,i10)') &
243  'TOTAL NUMBER OF PARCELS ADDED GLOBALLY = ',&
244  sum(add_count_all(:))
245 
246  call flush_err_msg(header = .false., footer = .false.)
247 
248  DO iproc = 0, numpes-1
249  IF(dmp_log) WRITE(unit_log, '(/,A,i4,2x,A,2x,i5)') &
250  'PARCELS ADDED ON PROC:', iproc,&
251  ' EQUAL TO', add_count_all(iproc)
252  ENDDO
253  ENDIF
254 
255  ENDIF
256 
257  CALL finl_err_msg
258  RETURN
259  END SUBROUTINE mass_inflow_pic
260 
261 
262 
263 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
264 ! C
265 ! Subroutine: PIC_FIND_EMPTY_SPOT C
266 ! Purpose: C
267 ! C
268 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
269  SUBROUTINE pic_find_empty_spot(LAST_INDEX, EMPTY_SPOT)
271 ! Modules
272 !---------------------------------------------------------------------//
273  USE funits
274  USE mpi_utility
275  USE error_manager
276  USE discretelement, only: max_pip
277  USE functions, only: is_nonexistent
278  IMPLICIT NONE
279 
280 ! Dummy arguments
281 !---------------------------------------------------------------------//
282  INTEGER, INTENT(INOUT) :: LAST_INDEX
283  INTEGER, INTENT(OUT) :: EMPTY_SPOT
284 
285 ! Local Variables
286 !---------------------------------------------------------------------//
287  LOGICAL :: SPOT_FOUND
288  INTEGER :: LL
289 !......................................................................!
290 
291  CALL init_err_msg("PIC_FIND_EMPTY_SPOT")
292 
293  IF(last_index.EQ.max_pip) THEN
294  WRITE(err_msg,2001)
295 
296  CALL flush_err_msg(abort = .true.)
297  call mfix_exit(mype)
298  ENDIF
299  spot_found = .false.
300 
301  DO ll = last_index+1, max_pip
302 
303  if(is_nonexistent(ll)) THEN
304  empty_spot = ll
305  last_index = ll
306  spot_found = .true.
307  EXIT
308  ENDIF
309  ENDDO
310 
311  IF(.NOT.spot_found) THEN
312  WRITE(err_msg,2002)
313  CALL flush_err_msg(abort = .true.)
314  ENDIF
315 
316  2001 FORMAT(/,5x, &
317  & 'ERROR IN PIC_FIND_EMPTY_SPOT', /5x, &
318  & 'NO MORE EMPTY SPOT IN THE PARTICLE ARRAY TO ADD A NEW PARTICLE',/5x, &
319  & 'TERMINAL ERROR: STOPPING')
320 
321  2002 FORMAT(/,5x, &
322  & 'ERROR IN PIC_FIND_EMPTY_SPOT', /5x, &
323  & 'COULD NOT FIND A SPOT FOR ADDING NEW PARTICLE',/5x, &
324  & 'INCREASE THE SIZE OF THE INITIAL ARRAYS', 5x, &
325  & 'TERMINAL ERROR: STOPPING')
326 
327  CALL finl_err_msg
328  END SUBROUTINE pic_find_empty_spot
329 
330 
331 
332 
333 
334 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
335 ! C
336 ! Subroutine: PIC_FIND_NEW_CELL C
337 ! Purpose: C
338 ! C
339 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
340  SUBROUTINE pic_find_new_cell(LL)
342 ! Modules
343 !---------------------------------------------------------------------//
344  USE discretelement
345  use mpi_utility
346  USE cutcell
347  USE functions
348  IMPLICIT NONE
349 
350 ! Dummy arguments
351 !---------------------------------------------------------------------//
352  INTEGER, INTENT(IN) :: LL
353 
354 ! Local Variables
355 !---------------------------------------------------------------------//
356  DOUBLE PRECISION :: XPOS, YPOS, ZPOS
357  INTEGER :: I, J, K
358 !......................................................................!
359 
360  i = pijk(ll,1)
361  j = pijk(ll,2)
362  k = pijk(ll,3)
363  xpos = des_pos_new(ll,1)
364  ypos = des_pos_new(ll,2)
365  IF (dimn .EQ. 3) THEN
366  zpos = des_pos_new(ll,3)
367  ENDIF
368 
369  IF(xpos >= xe(i-1) .AND. xpos < xe(i)) THEN
370  pijk(ll,1) = i
371  ELSEIF(xpos >= xe(i)) THEN
372  pijk(ll,1) = i+1
373  ELSE
374  pijk(ll,1) = i-1
375  END IF
376 
377  IF(ypos >= yn(j-1) .AND. ypos < yn(j)) THEN
378  pijk(ll,2) = j
379  ELSEIF(ypos >= yn(j))THEN
380  pijk(ll,2) = j+1
381  ELSE
382  pijk(ll,2) = j-1
383  END IF
384 
385  IF(dimn.EQ.2) THEN
386  pijk(ll,3) = 1
387  ELSE
388  IF(zpos >= zt(k-1) .AND. zpos < zt(k)) THEN
389  pijk(ll,3) = k
390  ELSEIF(zpos >= zt(k)) THEN
391  pijk(ll,3) = k+1
392  ELSE
393  pijk(ll,3) = k-1
394  END IF
395  ENDIF
396 
397  i = pijk(ll,1)
398  j = pijk(ll,2)
399  k = pijk(ll,3)
400 
401  IF(i.EQ.iend1+1) then
402  IF(xpos>=xe(iend1-1) .AND. xpos<=xe(iend1)) pijk(ll,1) = iend1
403  ENDIF
404 
405  IF(j.EQ.jend1+1) then
406  IF(ypos>=yn(jend1-1) .AND. ypos<=yn(jend1)) pijk(ll,2) = jend1
407  ENDIF
408 
409  IF(dimn.EQ.3.AND.k.EQ.kend1+1) THEN
410  IF(zpos>=zt(kend1-1) .AND. zpos<=zt(kend1)) pijk(ll,3) = kend1
411  ENDIF
412 
413  pijk(ll,4) = funijk(pijk(ll,1), pijk(ll,2),pijk(ll,3))
414 
415  END SUBROUTINE pic_find_new_cell
416 
integer pic_bcmi
Definition: pic_bc_mod.f:18
double precision, dimension(dim_m) d_p0
Definition: physprop_mod.f:25
subroutine finl_err_msg
subroutine pic_find_empty_spot(LAST_INDEX, EMPTY_SPOT)
integer, dimension(:), allocatable pic_bcmi_ijkstart
Definition: pic_bc_mod.f:34
double precision, dimension(dimension_bc, dim_m) bc_w_s
Definition: bc_mod.f:129
double precision, dimension(:,:), allocatable pic_bcmi_cnp
Definition: pic_bc_mod.f:51
double precision, dimension(0:dim_j) dy
Definition: geometry_mod.f:70
logical, dimension(:), allocatable pic_bcmi_incl_cutcell
Definition: pic_bc_mod.f:57
integer, dimension(:), allocatable pic_bcmi_ijk
Definition: pic_bc_mod.f:37
character(len=3), dimension(dim_m) solids_model
Definition: run_mod.f:253
double precision, dimension(0:dim_k) dz
Definition: geometry_mod.f:72
integer, dimension(dimension_bc, dim_m) bc_pic_mi_const_npc
Definition: bc_mod.f:412
subroutine pic_find_new_cell(LL)
subroutine check_if_parcel_overlaps_stl(POS, OVERLAP_EXISTS)
subroutine init_err_msg(CALLER)
integer mmax
Definition: physprop_mod.f:19
integer, dimension(:,:), allocatable pic_bcmi_normdir
Definition: pic_bc_mod.f:40
double precision, dimension(0:dim_i) dx
Definition: geometry_mod.f:68
double precision, parameter half
Definition: param1_mod.f:28
Definition: run_mod.f:13
Definition: param_mod.f:2
logical no_k
Definition: geometry_mod.f:28
double precision, dimension(dimension_bc, dim_m) bc_v_s
Definition: bc_mod.f:121
subroutine mass_inflow_pic
double precision, dimension(dimension_bc, dim_m) bc_pic_mi_const_statwt
Definition: bc_mod.f:417
double precision, dimension(dimension_bc, dim_m) bc_u_s
Definition: bc_mod.f:113
integer, dimension(:), allocatable pic_bcmi_ijkend
Definition: pic_bc_mod.f:35
character(len=line_length), dimension(line_count) err_msg
double precision, dimension(dim_m) ro_s0
Definition: physprop_mod.f:28
subroutine, public uni_rno(Y)
Definition: randomno_mod.f:25
double precision, parameter pi
Definition: constant_mod.f:158
integer, dimension(:,:), allocatable pic_bcmi_offset
Definition: pic_bc_mod.f:47
integer dimension_m
Definition: param_mod.f:18
double precision, dimension(:), allocatable des_stat_wt
Definition: mfix_pic_mod.f:54
logical pic_report_seeding_stats
Definition: pic_bc_mod.f:60
double precision, dimension(:,:), allocatable pic_bcmi_rnp
Definition: pic_bc_mod.f:53
double precision, parameter zero
Definition: param1_mod.f:27
subroutine flush_err_msg(DEBUG, HEADER, FOOTER, ABORT, LOG, CALL_TREE)
double precision, dimension(dimension_bc, dim_m) bc_rop_s
Definition: bc_mod.f:92
Definition: bc_mod.f:23
integer, dimension(dimension_bc) pic_bcmi_map
Definition: pic_bc_mod.f:24