MFIX  2016-1
cfnewvalues.f
Go to the documentation of this file.
1 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
2 ! C
3 ! Module name: CFNEWVALUES C
4 !
5 ! Purpose: DES - Calculate the new values of particle velocity,
6 ! position, angular velocity etc
7 !
8 ! C
9 ! Comments: Implements Eqns 1, 2, 3, 4 & 5 from the following paper:
10 ! Tsuji Y., Kawaguchi T., and Tanak T., "Lagrangian numerical
11 ! simulation of plug glow of cohesionless particles in a
12 ! horizontal pipe", Powder technology, 71, 239-250, 1992
13 !
14 ! pradeep : changes for parallel processing
15 ! 1. periodic boundaries might lie in different proc. so adjust
16 ! particle position for periodic removed
17 ! C
18 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
19  SUBROUTINE cfnewvalues
20 
21 !-----------------------------------------------
22 ! Modules
23 !-----------------------------------------------
24  USE constant
25  USE des_bc
26  USE derived_types, only: multisap, boxhandle
27  USE discretelement
28  USE fldvar
29  USE mfix_pic
30  USE mpi_utility
31  USE parallel
32  USE run
33  USE param
34  USE param1
35  USE physprop
36  use geometry, only: do_k, no_k
38 
39  IMPLICIT NONE
40 !-----------------------------------------------
41 ! Local Variables
42 !-----------------------------------------------
43  INTEGER :: L
44  LOGICAL, SAVE :: FIRST_PASS = .true.
45  DOUBLE PRECISION :: OMEGA_MAG,OMEGA_UNIT(3),ROT_ANGLE
46 
47  type(aabb_t) aabb
48 
49 !-----------------------------------------------
50 
51 ! Adams-Bashforth defaults to Euler for the first time step.
52  IF(first_pass .AND. intg_adams_bashforth) THEN
53  DO l =1, max_pip
54  IF(is_nonexistent(l)) cycle ! Only real particles
55  IF(is_entering(l).or.is_entering_ghost(l)) cycle ! Only non-entering
56  IF(is_ghost(l)) cycle ! Skip ghost particles
57  des_acc_old(l,:) = fc(l,:)/pmass(l) + grav(:)
58  rot_acc_old(l,:) = tow(l,:)
59  ENDDO
60  ENDIF
61 
62 
63 !!$omp parallel default(none) &
64 !!$omp shared(MAX_PIP,INTG_EULER,INTG_ADAMS_BASHFORTH,fc,tow,do_nsearch, &
65 !!$omp omega_new,omega_old,pmass,grav,des_vel_new,des_pos_new, &
66 !!$omp des_vel_old,des_pos_old,dtsolid,omoi,des_acc_old,rot_acc_old, &
67 !!$omp ppos,neighbor_search_rad_ratio,des_radius,DO_OLD, iGlobal_ID, &
68 !!$omp particle_orientation,orientation,boxhandle,multisap,particle_state) &
69 !!$omp private(l,rot_angle,omega_mag,omega_unit,aabb)
70 
71 ! If a particle is classified as new, then forces are ignored.
72 ! Classification from new to existing is performed in routine
73 ! des_check_new_particle.f
74 
75 ! Advance particle position, velocity
76 ! first-order method
77  IF (intg_euler) THEN
78 !!$omp sections
79 !!$omp section
80  WHERE(particle_state == normal_particle) des_vel_new(:,1) = &
81  des_vel_new(:,1) + dtsolid*(fc(:,1)/pmass(:) + grav(1))
82  WHERE(particle_state < normal_ghost) des_pos_new(:,1) = &
83  des_pos_new(:,1) + des_vel_new(:,1)*dtsolid
84  fc(:,1) = zero
85 
86 !!$omp section
87  WHERE(particle_state == normal_particle) des_vel_new(:,2) = &
88  des_vel_new(:,2) + dtsolid*(fc(:,2)/pmass(:) + grav(2))
89  WHERE(particle_state < normal_ghost) des_pos_new(:,2) = &
90  des_pos_new(:,2) + des_vel_new(:,2)*dtsolid
91  fc(:,2) = zero
92 
93 !!$omp section
94  WHERE(particle_state == normal_particle) des_vel_new(:,3) = &
95  des_vel_new(:,3) + dtsolid*(fc(:,3)/pmass(:) + grav(3))
96  WHERE(particle_state < normal_ghost) des_pos_new(:,3) = &
97  des_pos_new(:,3) + des_vel_new(:,3)*dtsolid
98  fc(:,3) = zero
99 
100 !!$omp section
101  WHERE(particle_state == normal_particle) omega_new(:,1) = &
102  omega_new(:,1) + tow(:,1)*omoi(:)*dtsolid
103  tow(:,1) = zero
104 
105 !!$omp section
106  WHERE(particle_state == normal_particle)omega_new(:,2) = &
107  omega_new(:,2) + tow(:,2)*omoi(:)*dtsolid
108  tow(:,2) = zero
109 
110 !!$omp section
111  WHERE(particle_state == normal_particle)omega_new(:,3) = &
112  omega_new(:,3) + tow(:,3)*omoi(:)*dtsolid
113  tow(:,3) = zero
114 !!$omp end sections
115 
116 ! Second-order Adams-Bashforth/Trapezoidal scheme
117  ELSEIF (intg_adams_bashforth) THEN
118 
119 !!$omp sections
120 !!$omp section
121  WHERE(particle_state == normal_particle) &
122  fc(:max_pip,1) = fc(:max_pip,1)/pmass(:max_pip) + grav(1)
123  WHERE(particle_state == normal_particle) &
124  des_vel_new(:max_pip,1) = des_vel_old(:max_pip,1) + 0.5d0* &
125  (3.d0*fc(:max_pip,1)-des_acc_old(:max_pip,1) )*dtsolid
126  des_acc_old(:max_pip,1) = fc(:max_pip,1)
127 
128  WHERE(particle_state < normal_ghost) &
129  des_pos_new(:max_pip,1) = des_pos_old(:max_pip,1) + 0.5d0* &
130  (des_vel_old(:max_pip,1)+des_vel_new(:max_pip,1))*dtsolid
131  fc(:max_pip,1) = zero
132 
133 !!$omp section
134  WHERE(particle_state == normal_particle) &
135  fc(:max_pip,2) = fc(:max_pip,2)/pmass(:max_pip) + grav(2)
136  WHERE(particle_state == normal_particle) &
137  des_vel_new(:max_pip,2) = des_vel_old(:max_pip,2) + 0.5d0* &
138  (3.d0*fc(:max_pip,2)-des_acc_old(:max_pip,2) )*dtsolid
139  des_acc_old(:max_pip,2) = fc(:max_pip,2)
140 
141  WHERE(particle_state < normal_ghost) &
142  des_pos_new(:max_pip,2) = des_pos_old(:max_pip,2) + 0.5d0* &
143  (des_vel_old(:max_pip,2)+des_vel_new(:max_pip,2))*dtsolid
144  fc(:max_pip,2) = zero
145 
146 !!$omp section
147  WHERE(particle_state == normal_particle) &
148  fc(:max_pip,3) = fc(:max_pip,3)/pmass(:max_pip) + grav(3)
149  WHERE(particle_state == normal_particle) &
150  des_vel_new(:max_pip,3) = des_vel_old(:max_pip,3) + 0.5d0* &
151  (3.d0*fc(:max_pip,3)-des_acc_old(:max_pip,3) )*dtsolid
152  des_acc_old(:max_pip,3) = fc(:max_pip,3)
153 
154  WHERE(particle_state < normal_ghost) &
155  des_pos_new(:max_pip,3) = des_pos_old(:max_pip,3) + 0.5d0* &
156  (des_vel_old(:max_pip,3)+des_vel_new(:max_pip,3))*dtsolid
157  fc(:max_pip,3) = zero
158 
159 !!$omp section
160  WHERE(particle_state(:max_pip) == normal_particle) &
161  omega_new(:max_pip,1) = omega_old(:max_pip,1) + 0.5d0* &
162  (3.d0*tow(:max_pip,1)*omoi(:max_pip) - &
163  rot_acc_old(:max_pip,1))*dtsolid
164  WHERE(particle_state(:max_pip) == normal_particle) &
165  rot_acc_old(:max_pip,1) = tow(:max_pip,1)*omoi(:max_pip)
166  tow(:max_pip,1) = zero
167 
168 !!$omp section
169  WHERE(particle_state == normal_particle) &
170  omega_new(:max_pip,2) = omega_old(:max_pip,2) + 0.5d0* &
171  (3.d0*tow(:max_pip,2)*omoi(:max_pip)- &
172  rot_acc_old(:max_pip,2) )*dtsolid
173  WHERE(particle_state == normal_particle) &
174  rot_acc_old(:max_pip,2) = tow(:max_pip,2)*omoi(:max_pip)
175  tow(:max_pip,2) = zero
176 
177 !!$omp section
178  WHERE(particle_state == normal_particle) &
179  omega_new(:max_pip,3) = omega_old(:max_pip,3) + 0.5d0* &
180  (3.d0*tow(:max_pip,3)*omoi(:max_pip)- &
181  rot_acc_old(:max_pip,3) )*dtsolid
182  WHERE(particle_state == normal_particle) &
183  rot_acc_old(:max_pip,3) = tow(:max_pip,3)*omoi(:max_pip)
184  tow(:max_pip,3) = zero
185 
186 !!$omp end sections
187  ENDIF
188 
189 #ifdef do_sap
190 !!$omp single
191  DO l = 1, max_pip
192  aabb%minendpoint(:) = des_pos_new(l,:)-des_radius(l)
193  aabb%maxendpoint(:) = des_pos_new(l,:)+des_radius(l)
194  call multisap_update(multisap,aabb,boxhandle(l))
195  ENDDO
196 !!$omp end single
197 #endif
198 
199 ! Update particle orientation - Always first order
200 ! When omega is non-zero, compute the rotation angle, and apply the
201 ! Rodrigues' rotation formula
202 
203  IF(particle_orientation) THEN
204  DO l = 1, max_pip
205  omega_mag = omega_new(l,1)**2 +omega_new(l,2)**2 + omega_new(l,3)**2
206 
207  IF(omega_mag>zero) THEN
208  omega_mag=dsqrt(omega_mag)
209  omega_unit(:) = omega_new(l,:)/omega_mag
210  rot_angle = omega_mag * dtsolid
211 
212  orientation(:,l) = orientation(:,l)*dcos(rot_angle) + &
213  des_crossprdct(omega_unit,orientation(:,l))*dsin(rot_angle) + &
214  omega_unit(:)*dot_product(omega_unit,orientation(:,l))*&
215  (one-dcos(rot_angle))
216  ENDIF
217  ENDDO
218  ENDIF
219 
220 ! Check if the particle has moved a distance greater than or equal to
221 ! its radius since the last time a neighbor search was called. if so,
222 ! make sure that neighbor is called in des_time_march
223  IF(.NOT.do_nsearch) THEN
224 !!$omp do reduction (.or.:do_nsearch)
225  DO l = 1, max_pip
226  do_nsearch = do_nsearch .or. &
227  (des_pos_new(l,1) - ppos(l,1))**2+ &
228  (des_pos_new(l,2) - ppos(l,2))**2+ &
229  (des_pos_new(l,3) - ppos(l,3))**2 >= &
230  (neighbor_search_rad_ratio*des_radius(l))**2
231  ENDDO
232  ENDIF
233 
234 !!$omp end parallel
235 
236 #ifdef do_sap
237  call multisap_sort(multisap)
238 #endif
239 
240  first_pass = .false.
241 
242  1002 FORMAT(/1x,70('*')//&
243  ' From: CFNEWVALUES -',/&
244  ' Message: Particle ',i10, ' moved a distance ', es17.9, &
245  ' during a',/10x, 'single solids time step, which is ',&
246  ' greater than',/10x,'its radius: ', es17.9)
247  1003 FORMAT(1x,70('*')/)
248 
249  RETURN
250 
251  contains
252 
253  include 'functions.inc'
254 
255  END SUBROUTINE cfnewvalues
double precision, parameter one
Definition: param1_mod.f:29
subroutine cfnewvalues
Definition: cfnewvalues.f:20
subroutine, public multisap_update(this, aabb, handlelist)
Definition: multisap.f:249
subroutine, public multisap_sort(this)
Definition: multisap.f:322
Definition: run_mod.f:13
Definition: param_mod.f:2
type(multisap_t) multisap
logical no_k
Definition: geometry_mod.f:28
logical do_k
Definition: geometry_mod.f:30
type(boxhandlelist_t), dimension(:), allocatable boxhandle
double precision, parameter zero
Definition: param1_mod.f:27