MFIX  2016-1
get_delh.f
Go to the documentation of this file.
1 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
2 ! C
3 ! Module name: GET_DEL_H C
4 ! Purpose: Finds the normal distance and unit vector from a cut face C
5 ! to any point (x0,y0,z0) C
6 ! The unit normal vector points away from the boundary, C
7 ! towards the fluid. C
8 ! This subroutine must be called from a cut-cell C
9 ! C
10 ! Author: Jeff Dietiker Date: 21-Feb-08 C
11 ! Reviewer: Date: C
12 ! C
13 ! Revision Number # Date: ##-###-## C
14 ! Author: # C
15 ! Purpose: # C
16 ! C
17 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
18  SUBROUTINE get_del_h(IJK,TYPE_OF_CELL,X0,Y0,Z0,Del_H,Nx,Ny,Nz)
19 
20  USE param
21  USE param1
22  USE parallel
23  USE constant
24  USE run
25  USE toleranc
26  USE geometry
27  USE indices
28  USE compar
29  USE sendrecv
30  USE quadric
31  USE cutcell
32  USE functions
33 
34  IMPLICIT NONE
35  CHARACTER (LEN=*) :: TYPE_OF_CELL
36  DOUBLE PRECISION:: X0,Y0,Z0,XREF,YREF,ZREF
37  INTEGER :: IJK,I,J,K
38  DOUBLE PRECISION :: Del_H,Diagonal
39  DOUBLE PRECISION :: Nx,Ny,Nz
40 
41  SELECT CASE (type_of_cell)
42  CASE('SCALAR')
43 
44  IF(.NOT.cut_cell_at(ijk)) THEN
45  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H:'
46  WRITE(*,*)' SCALAR CELL',ijk,' IS NOT A CUT CELL'
47  WRITE(*,*)' MFiX will exit now.'
48  CALL mfix_exit(mype)
49  ENDIF
50 
51  nx = normal_s(ijk,1)
52  ny = normal_s(ijk,2)
53  nz = normal_s(ijk,3)
54 
55  xref = refp_s(ijk,1)
56  yref = refp_s(ijk,2)
57  zref = refp_s(ijk,3)
58 
59  CASE('U_MOMENTUM')
60 
61  IF(.NOT.cut_u_cell_at(ijk)) THEN
62  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H:'
63  WRITE(*,*)' U-MOMENTUM CELL',ijk,' IS NOT A CUT CELL'
64  WRITE(*,*)' MFiX will exit now.'
65  CALL mfix_exit(mype)
66  ENDIF
67 
68  nx = normal_u(ijk,1)
69  ny = normal_u(ijk,2)
70  nz = normal_u(ijk,3)
71 
72  xref = refp_u(ijk,1)
73  yref = refp_u(ijk,2)
74  zref = refp_u(ijk,3)
75 
76  IF(wall_u_at(ijk)) THEN
77  nx = zero
78  ny = zero
79  nz = zero
80  del_h = undefined
81  RETURN
82  ENDIF
83 
84  CASE('V_MOMENTUM')
85 
86  IF(.NOT.cut_v_cell_at(ijk)) THEN
87  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H:'
88  WRITE(*,*)' V-MOMENTUM CELL',ijk,' IS NOT A CUT CELL'
89  WRITE(*,*)' MFiX will exit now.'
90  CALL mfix_exit(mype)
91  ENDIF
92 
93  nx = normal_v(ijk,1)
94  ny = normal_v(ijk,2)
95  nz = normal_v(ijk,3)
96 
97  xref = refp_v(ijk,1)
98  yref = refp_v(ijk,2)
99  zref = refp_v(ijk,3)
100 
101  IF(wall_v_at(ijk)) THEN
102  nx = zero
103  ny = zero
104  nz = zero
105  del_h = undefined
106  RETURN
107  ENDIF
108 
109  CASE('W_MOMENTUM')
110 
111  IF(.NOT.cut_w_cell_at(ijk)) THEN
112  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H:'
113  WRITE(*,*)' W-MOMENTUM CELL',ijk,' IS NOT A CUT CELL'
114  WRITE(*,*)' MFiX will exit now.'
115  CALL mfix_exit(mype)
116  ENDIF
117 
118  nx = normal_w(ijk,1)
119  ny = normal_w(ijk,2)
120  nz = normal_w(ijk,3)
121 
122  xref = refp_w(ijk,1)
123  yref = refp_w(ijk,2)
124  zref = refp_w(ijk,3)
125 
126  IF(wall_w_at(ijk)) THEN
127  nx = zero
128  ny = zero
129  nz = zero
130  del_h = undefined
131  RETURN
132  ENDIF
133 
134  CASE DEFAULT
135  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H:'
136  WRITE(*,*)'UNKNOWN TYPE OF CELL:',type_of_cell
137  WRITE(*,*)'ACCEPTABLE TYPES ARE:'
138  WRITE(*,*)'SCALAR'
139  WRITE(*,*)'U_MOMENTUM'
140  WRITE(*,*)'V_MOMENTUM'
141  WRITE(*,*)'W_MOMENTUM'
142  CALL mfix_exit(mype)
143  END SELECT
144 
145 
146  del_h = nx * (x0 - xref) + ny * (y0 - yref) + nz * (z0 - zref)
147 
148 !======================================================================
149 ! Negative values of DEL_H are not accepted
150 !======================================================================
151 
152  i = i_of(ijk)
153  j = j_of(ijk)
154  k = k_of(ijk)
155 
156  IF(no_k) THEN
157  diagonal = sqrt(dx(i)**2 + dy(j)**2 )
158  ELSE
159  diagonal = sqrt(dx(i)**2 + dy(j)**2 + dz(k)**2)
160  ENDIF
161 
162  IF (del_h <= tol_delh * diagonal) THEN
163 
164  del_h = undefined
165  nx = zero
166  ny = zero
167  nz = zero
168 
169  ENDIF
170 
171  RETURN
172 
173 
174  END SUBROUTINE get_del_h
175 
176  SUBROUTINE get_del_h_des(IJK,TYPE_OF_CELL,X0,Y0,Z0,Del_H,Nx,Ny,Nz, allow_neg_dist)
178  USE param
179  USE param1
180  USE parallel
181  USE constant
182  USE run
183  USE toleranc
184  USE geometry
185  USE indices
186  USE compar
187  USE sendrecv
188  USE quadric
189  USE cutcell
190  USE functions
191 
192  IMPLICIT NONE
193  CHARACTER (LEN=*) :: TYPE_OF_CELL
194  DOUBLE PRECISION:: X0,Y0,Z0,XREF,YREF,ZREF
195  INTEGER :: IJK,I,J,K
196  DOUBLE PRECISION :: Del_H,Diagonal
197  DOUBLE PRECISION :: Nx,Ny,Nz
198 
199  LOGICAL :: ALLOW_NEG_DIST
200 
201  SELECT CASE (type_of_cell)
202  CASE('SCALAR')
203 
204  IF(.NOT.cut_cell_at(ijk)) THEN
205  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H_DES:'
206  WRITE(*,*)' SCALAR CELL',ijk,' IS NOT A CUT CELL'
207  WRITE(*,*)' I, J, K =',i_of(ijk), j_of(ijk), k_of(ijk)
208  WRITE(*,*)' MFiX will exit now.'
209  CALL mfix_exit(mype)
210  ENDIF
211 
212  nx = normal_s(ijk,1)
213  ny = normal_s(ijk,2)
214  nz = normal_s(ijk,3)
215 
216  xref = refp_s(ijk,1)
217  yref = refp_s(ijk,2)
218  zref = refp_s(ijk,3)
219 
220  CASE('U_MOMENTUM')
221 
222  IF(.NOT.cut_u_cell_at(ijk)) THEN
223  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H_DES:'
224  WRITE(*,*)' U-MOMENTUM CELL',ijk,' IS NOT A CUT CELL'
225  WRITE(*,*)' MFiX will exit now.'
226  CALL mfix_exit(mype)
227  ENDIF
228 
229  nx = normal_u(ijk,1)
230  ny = normal_u(ijk,2)
231  nz = normal_u(ijk,3)
232 
233  xref = refp_u(ijk,1)
234  yref = refp_u(ijk,2)
235  zref = refp_u(ijk,3)
236 
237  IF(wall_u_at(ijk)) THEN
238  nx = zero
239  ny = zero
240  nz = zero
241  del_h = undefined
242  RETURN
243  ENDIF
244 
245  CASE('V_MOMENTUM')
246 
247  IF(.NOT.cut_v_cell_at(ijk)) THEN
248  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H_DES:'
249  WRITE(*,*)' V-MOMENTUM CELL',ijk,' IS NOT A CUT CELL'
250  WRITE(*,*)' MFiX will exit now.'
251  CALL mfix_exit(mype)
252  ENDIF
253 
254  nx = normal_v(ijk,1)
255  ny = normal_v(ijk,2)
256  nz = normal_v(ijk,3)
257 
258  xref = refp_v(ijk,1)
259  yref = refp_v(ijk,2)
260  zref = refp_v(ijk,3)
261 
262  IF(wall_v_at(ijk)) THEN
263  nx = zero
264  ny = zero
265  nz = zero
266  del_h = undefined
267  RETURN
268  ENDIF
269 
270  CASE('W_MOMENTUM')
271 
272  IF(.NOT.cut_w_cell_at(ijk)) THEN
273  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H_DES:'
274  WRITE(*,*)' W-MOMENTUM CELL',ijk,' IS NOT A CUT CELL'
275  WRITE(*,*)' MFiX will exit now.'
276  CALL mfix_exit(mype)
277  ENDIF
278 
279  nx = normal_w(ijk,1)
280  ny = normal_w(ijk,2)
281  nz = normal_w(ijk,3)
282 
283  xref = refp_w(ijk,1)
284  yref = refp_w(ijk,2)
285  zref = refp_w(ijk,3)
286 
287  IF(wall_w_at(ijk)) THEN
288  nx = zero
289  ny = zero
290  nz = zero
291  del_h = undefined
292  RETURN
293  ENDIF
294 
295  CASE DEFAULT
296  WRITE(*,*)' EROR IN SUBROUTINE GET_DEL_H_DES:'
297  WRITE(*,*)'UNKNOWN TYPE OF CELL:',type_of_cell
298  WRITE(*,*)'ACCEPTABLE TYPES ARE:'
299  WRITE(*,*)'SCALAR'
300  WRITE(*,*)'U_MOMENTUM'
301  WRITE(*,*)'V_MOMENTUM'
302  WRITE(*,*)'W_MOMENTUM'
303  CALL mfix_exit(mype)
304  END SELECT
305 
306  del_h = nx * (x0 - xref) + ny * (y0 - yref) + nz * (z0 - zref)
307 
308 !======================================================================
309 ! Negative values of DEL_H are not accepted
310 !======================================================================
311 
312  i = i_of(ijk)
313  j = j_of(ijk)
314  k = k_of(ijk)
315 
316  IF(.NOT.allow_neg_dist) THEN
317  diagonal = sqrt(dx(i)**2 + dy(j)**2 + dz(k)**2)
318 
319  IF (del_h <= tol_delh * diagonal) THEN
320  del_h = undefined
321  nx = zero
322  ny = zero
323  nz = zero
324 
325  ENDIF
326  ENDIF
327 
328  RETURN
329 
330  END SUBROUTINE get_del_h_des
331 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
332 ! C
333 ! Module name: STORE_CUT_FACE_INFO C
334 ! Purpose: Compute and store unit normal vector and reference point C
335 ! Defining a cut face C
336 ! C
337 ! Author: Jeff Dietiker Date: 21-Feb-08 C
338 ! Reviewer: Date: C
339 ! C
340 ! Revision Number # Date: ##-###-## C
341 ! Author: # C
342 ! Purpose: # C
343 ! C
344 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
345  SUBROUTINE store_cut_face_info(IJK,TYPE_OF_CELL,N_CUT_FACE_NODES,COORD_CUT_FACE_NODES,X_MEAN,Y_MEAN,Z_MEAN)
347  USE param
348  USE param1
349  USE parallel
350  USE constant
351  USE run
352  USE toleranc
353  USE geometry
354  USE indices
355  USE compar
356  USE sendrecv
357  USE quadric
358  USE cutcell
359  USE functions
360 
361  IMPLICIT NONE
362  CHARACTER (LEN=*) :: TYPE_OF_CELL
363  INTEGER :: IJK
364  INTEGER :: N_CUT_FACE_NODES
365  DOUBLE PRECISION, DIMENSION(3,15) :: COORD_CUT_FACE_NODES
366  DOUBLE PRECISION :: X_MEAN,Y_MEAN,Z_MEAN
367  DOUBLE PRECISION, DIMENSION(3) :: NN,V,N1,N2
368  DOUBLE PRECISION :: NORM,N1_dot_N2
369  DOUBLE PRECISION, DIMENSION(3) :: VECTEMP,VECTEMP2
370 
371  IF(no_k) THEN ! 2D case
372 
373  nn(1) = coord_cut_face_nodes(2,1) - coord_cut_face_nodes(2,2) ! y1-y2
374  nn(2) = coord_cut_face_nodes(1,2) - coord_cut_face_nodes(1,1) ! x2-x1
375  nn(3) = zero
376 
377  ELSE
378 
379 !======================================================================
380 ! Make sure there are a least three points along the plane
381 !======================================================================
382 
383  IF(n_cut_face_nodes < 3) THEN
384  WRITE(*,*)' ERROR IN SUBROUTINE STORE_CUT_FACE_INFO:'
385  WRITE(*,*)' CUT FACE HAS LESS THAN 3 NODES.'
386  WRITE(*,*)' MFIX WILL EXIT NOW.'
387  CALL mfix_exit(mype)
388  END IF
389 
390 !======================================================================
391 ! Find tentative unit normal vector
392 ! and reverse sign if necessary
393 ! (unit vector must be pointing towards the fluid)
394 !======================================================================
395 
396  vectemp = coord_cut_face_nodes(:,2)-coord_cut_face_nodes(:,1)
397  vectemp2 = coord_cut_face_nodes(:,3)-coord_cut_face_nodes(:,1)
398  nn = cross_product(vectemp,vectemp2)
399 
400  ENDIF
401 
402  norm = sqrt(dot_product(nn(:),nn(:)))
403  nn = nn / norm
404 
405  v(1) = x_mean - coord_cut_face_nodes(1,1)
406  v(2) = y_mean - coord_cut_face_nodes(2,1)
407  v(3) = z_mean - coord_cut_face_nodes(3,1)
408 
409  IF (dot_product(nn,v) < zero) nn = - nn
410 
411  IF(n_cut_face_nodes > 3) THEN ! FOR 3D geometry, check normal of plane defined by nodes 1,2, and 4
412 
413  n1 = nn ! Keep copy of previous N (nodes 1,2,3)
414 
415  vectemp = coord_cut_face_nodes(:,2)-coord_cut_face_nodes(:,1)
416  vectemp2 = coord_cut_face_nodes(:,4)-coord_cut_face_nodes(:,1)
417 
418  n2 = cross_product(vectemp,vectemp2)
419 
420  norm = sqrt(dot_product(n2(:),n2(:)))
421  n2 = n2 / norm
422 
423  v(1) = x_mean - coord_cut_face_nodes(1,1)
424  v(2) = y_mean - coord_cut_face_nodes(2,1)
425  v(3) = z_mean - coord_cut_face_nodes(3,1)
426 
427  IF (dot_product(n2,v) < zero) n2 = - n2
428 
429  ENDIF
430 
431  n1_dot_n2 = dot_product(n1,n2)
432  debug_cg(ijk,1)=n1_dot_n2
433 
434  IF(n1_dot_n2<0.99) THEN
435 
436 ! What should be done when the unit vectors are different ?
437 
438  ENDIF
439 
440 !======================================================================
441 ! Store unit normal vector and reference point
442 !======================================================================
443 
444  SELECT CASE (type_of_cell)
445  CASE('SCALAR')
446 
447  normal_s(ijk,:) = nn
448  refp_s(ijk,:) = coord_cut_face_nodes(:,1)
449 
450  IF(do_k) CALL test_del_h(ijk,'SCALAR') ! test for negative del_H
451 
452  CASE('U_MOMENTUM')
453 
454  normal_u(ijk,:) = nn
455  refp_u(ijk,:) = coord_cut_face_nodes(:,1)
456 
457  CASE('V_MOMENTUM')
458 
459  normal_v(ijk,:) = nn
460  refp_v(ijk,:) = coord_cut_face_nodes(:,1)
461 
462  CASE('W_MOMENTUM')
463 
464  normal_w(ijk,:) = nn
465  refp_w(ijk,:) = coord_cut_face_nodes(:,1)
466 
467  CASE DEFAULT
468  WRITE(*,*)'SUBROUTINE: STORE_CUT_FACE_INFO'
469  WRITE(*,*)'UNKNOWN TYPE OF CELL:',type_of_cell
470  WRITE(*,*)'ACCEPTABLE TYPES ARE:'
471  WRITE(*,*)'SCALAR'
472  WRITE(*,*)'U_MOMENTUM'
473  WRITE(*,*)'V_MOMENTUM'
474  WRITE(*,*)'W_MOMENTUM'
475  CALL mfix_exit(mype)
476  END SELECT
477 
478  RETURN
479 
480  END SUBROUTINE store_cut_face_info
481 
482 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
483 ! C
484 ! Module name: TEST_DEL_H C
485 ! Purpose: tests the computation of wall distance C
486 ! If a negative distance is detected, the normal vector C
487 ! is inverted C
488 ! C
489 ! Author: Jeff Dietiker Date: 22-Feb-12 C
490 ! Reviewer: Date: C
491 ! C
492 ! Revision Number # Date: ##-###-## C
493 ! Author: # C
494 ! Purpose: # C
495 ! C
496 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
497  SUBROUTINE test_del_h(IJK,TYPE_OF_CELL)
499  USE param
500  USE param1
501  USE parallel
502  USE constant
503  USE run
504  USE toleranc
505  USE geometry
506  USE indices
507  USE compar
508  USE sendrecv
509  USE quadric
510  USE cutcell
511 
512  IMPLICIT NONE
513  CHARACTER (LEN=*) :: TYPE_OF_CELL
514  DOUBLE PRECISION:: X_COPY,Y_COPY,Z_COPY
515  INTEGER :: IJK
516  INTEGER :: NODE,N_N1,N_N2,NN
517  DOUBLE PRECISION :: Del_H
518  DOUBLE PRECISION :: Nx,Ny,Nz
519 
520  LOGICAL :: ALLOW_NEG_DIST = .true. ! forces GET_DEL_H_DES to output negative delh
521  ! i.e. do not let the subroutine overwrite negative values
522 
523 ! This subroutine tests values of del_H for nodes defining a cut cell.
524 ! Only nodes that are in the fluid region are tested.
525 ! Nodes belonging to the cut face should return zero (or near zero) values and are not tested.
526 ! If a negative del_H is detected, the unit normal vector is reversed.
527 
528  IF(no_k) THEN
529  n_n1 = 5
530  n_n2 = 8
531  ELSE
532  n_n1 = 1
533  n_n2 = 8
534  ENDIF
535 
536  CALL get_cell_node_coordinates(ijk,type_of_cell)
537 
538  DO node = 1,number_of_nodes(ijk)
539  IF(connectivity(ijk,node)<=ijkend3) THEN ! node does not belong to the cut-face
540  ! i.e. is in the fluid region
541 
542  DO nn = n_n1,n_n2 ! get node coordinate
543  IF(connectivity(ijk,node) == ijk_of_node(nn)) THEN
544  x_copy = x_node(nn)
545  y_copy = y_node(nn)
546  z_copy = z_node(nn)
547  EXIT
548  ENDIF
549  ENDDO
550 
551 ! Compute del_H
552  CALL get_del_h_des(ijk,type_of_cell,x_copy,y_copy,z_copy,del_h,nx,ny,nz, allow_neg_dist)
553 
554 
555  IF(del_h<zero) THEN
556 
557 
558  IF(print_warnings.AND.mype==pe_io) THEN
559  WRITE(*,*) ' Warning: Negative delh detected in scalar cell :',ijk
560  WRITE(*,*) ' Location (X,Y,Z) = ',x_copy,y_copy,z_copy
561  WRITE(*,*) ' Reverting unit normal vector.'
562  ENDIF
563 
564  normal_s(ijk,1) = -normal_s(ijk,1)
565  normal_s(ijk,2) = -normal_s(ijk,2)
566  normal_s(ijk,3) = -normal_s(ijk,3)
567 
568  ENDIF
569 
570  ENDIF
571  ENDDO
572 
573  RETURN
574 
575  END SUBROUTINE test_del_h
576 
577 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
578 ! C
579 ! Module name: GET_DISTANCE_TO_WALL C
580 ! Purpose: Finds the distance fraom any scalar cell to the closest C
581 ! wall C
582 ! C
583 ! Author: Jeff Dietiker Date: 16-May-13 C
584 ! Reviewer: Date: C
585 ! C
586 ! Revision Number # Date: ##-###-## C
587 ! Author: # C
588 ! Purpose: # C
589 ! C
590 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
591  SUBROUTINE get_distance_to_wall
593  USE param
594  USE param1
595  USE parallel
596  USE constant
597  USE run
598  USE toleranc
599  USE geometry
600  USE indices
601  USE compar
602  USE sendrecv
603  USE quadric
604  USE cutcell
605  USE functions
606 
607  USE mpi_utility
608 
609  IMPLICIT NONE
610 ! CHARACTER (LEN=*) :: TYPE_OF_CELL
611  DOUBLE PRECISION:: X0,Y0,Z0,XREF,YREF,ZREF
612  INTEGER :: IJK,NN
613 
614  DOUBLE PRECISION :: D_TO_CUT, D_TO_PE_REF
615 
616  INTEGER :: N_CUT_CELLS
617  INTEGER :: LIST_OF_CUT_CELLS(dimension_3)
618 
619  INTEGER :: iproc,IERR,IJK_OFFSET,nb,n1,n2
620  INTEGER :: GLOBAL_N_CUT_CELLS
621  INTEGER, DIMENSION(0:numPEs-1) :: disp,rcount
622  LOGICAL, DIMENSION(0:numPEs-1) :: ALREADY_VISITED
623  DOUBLE PRECISION, DIMENSION(0:numPEs-1,3) :: PE_REFP,ALL_PE_REFP
624  DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE :: LOCAL_REFP_S,GLOBAL_REFP_S
625 
626  IF(mype==pe_io) WRITE(*,*)'COMPUTING WALL DISTANCE...'
627 
628 ! Count the number of cut cells
629  n_cut_cells = 0
630  DO ijk = ijkstart3, ijkend3
631  IF(interior_cell_at(ijk).AND.cut_cell_at(ijk)) THEN
632  n_cut_cells = n_cut_cells + 1
633  list_of_cut_cells(n_cut_cells) = ijk
634  ENDIF
635  ENDDO
636 
637 ! Store cut cell reference points (centroid of cut cell face)
638 ! and save a reference point for the entire processor
639  ALLOCATE (local_refp_s(n_cut_cells,3))
640 
641  n_cut_cells = 0
642  pe_refp(mype,1) = zero
643  pe_refp(mype,2) = zero
644  pe_refp(mype,3) = zero
645 
646  DO ijk = ijkstart3, ijkend3
647  IF(interior_cell_at(ijk).AND.cut_cell_at(ijk)) THEN
648  n_cut_cells = n_cut_cells + 1
649  local_refp_s(n_cut_cells,1) = refp_s(ijk,1)
650  local_refp_s(n_cut_cells,2) = refp_s(ijk,2)
651  local_refp_s(n_cut_cells,3) = refp_s(ijk,3)
652 
653  pe_refp(mype,1) = pe_refp(mype,1) + refp_s(ijk,1)
654  pe_refp(mype,2) = pe_refp(mype,2) + refp_s(ijk,2)
655  pe_refp(mype,3) = pe_refp(mype,3) + refp_s(ijk,3)
656  ENDIF
657  ENDDO
658 
659  IF(n_cut_cells>0) THEN
660  pe_refp(mype,1) = pe_refp(mype,1) / n_cut_cells
661  pe_refp(mype,2) = pe_refp(mype,2) / n_cut_cells
662  pe_refp(mype,3) = pe_refp(mype,3) / n_cut_cells
663  ELSE
664  pe_refp(mype,1) = undefined
665  pe_refp(mype,2) = undefined
666  pe_refp(mype,3) = undefined
667  ENDIF
668 
669 !======================================================================
670 ! Now, gather the local reference points to head node
671 ! to get a global list, and broadcast it to each processor.
672 !======================================================================
673 
674 !======================================================================
675 ! First get the offset and build the rcount and disp arrays.
676 ! rcount is the number of elements to be gathered.
677 ! disp is the displacement of the variable size gather,
678 ! i.e. the cumulative sum at a given procesor.
679 !======================================================================
680 
681  CALL allgather_1i (n_cut_cells,rcount,ierr)
682 
683  IF (mype == 0) THEN
684  ijk_offset = 0
685  ELSE
686  ijk_offset = 0
687  DO iproc=0,mype-1
688  ijk_offset = ijk_offset + rcount(iproc)
689  ENDDO
690  ENDIF
691 
692  CALL allgather_1i (ijk_offset,disp,ierr)
693 
694  CALL allgather_1d (pe_refp(mype,1),all_pe_refp(:,1),ierr)
695  CALL allgather_1d (pe_refp(mype,2),all_pe_refp(:,2),ierr)
696  CALL allgather_1d (pe_refp(mype,3),all_pe_refp(:,3),ierr)
697 
698 !======================================================================
699 ! Get the global number of cut cells and allocate the
700 ! global reference point array. Each processor gets its own
701 ! copy of all cut cell reference points !!
702 !======================================================================
703  CALL global_all_sum(n_cut_cells, global_n_cut_cells, pe_io, ierr )
704  ALLOCATE (global_refp_s(global_n_cut_cells,3))
705 
706 !======================================================================
707 ! For a serial run, the global and local arrays are the same.
708 ! for a parallel run, first gather on head node, then broadcast to all.
709 !======================================================================
710 
711  IF(numpes==1) THEN ! Serial run
712  global_refp_s = local_refp_s
713  ELSE !Parallel run
714  call gatherv_1d( local_refp_s(:,1), n_cut_cells, global_refp_s(:,1), rcount, disp, pe_io, ierr )
715  call gatherv_1d( local_refp_s(:,2), n_cut_cells, global_refp_s(:,2), rcount, disp, pe_io, ierr )
716  call gatherv_1d( local_refp_s(:,3), n_cut_cells, global_refp_s(:,3), rcount, disp, pe_io, ierr )
717 
718  call bcast(global_refp_s(:,1))
719  call bcast(global_refp_s(:,2))
720  call bcast(global_refp_s(:,3))
721  ENDIF
722 
723 
724  already_visited(:) = .false.
725 !======================================================================
726 ! Loop through all scalar cells, grouped by processor.
727 ! Compute the distance to each cut cell and take the minimum
728 ! This is doe in three passes, in order of likelyhood to find a wall:
729 ! 1) Within local processor.
730 ! 2) Within neighboring processors (from send2 schedule)
731 ! 3) Within all other processors
732 !
733 ! The idea is that it is very likely that cut cells located
734 ! on current or neighbor processors will contribute to the
735 ! wall distance calculation, whereas cut cells located
736 ! on the other processors will not contribute
737 ! During the third pass, the entire processor is skipped
738 ! if a reference point (average of all cut faces reference
739 ! points) is farther than the current wall distance.
740 ! This should speed up the brute calculation of going
741 ! explicitely through all cut cells.
742 ! However, it is not guaranteed that dwall will be
743 ! independent of the grid partitionning. This is considered
744 ! very unlikely at the moment
745 ! Change DWALL_BRUTE_FORCE to .TRUE. to force brute-force
746 ! calculation.
747 !======================================================================
748 
749  DO ijk = ijkstart3, ijkend3
750 
751  CALL write_progress_bar(ijk,ijkend3 - ijkstart3 + 1,'C')
752 
753  IF(interior_cell_at(ijk)) THEN
754  dwall(ijk) = undefined
755 
756  IF(.NOT.blocked_cell_at(ijk)) THEN
757 
758 ! Get coordinates of cell center
759  CALL get_cell_node_coordinates(ijk,'SCALAR')
760 
761  x0 = x_node(0)
762  y0 = y_node(0)
763  z0 = z_node(0)
764 
765 !======================================================================
766 ! First pass: Loop through local cut cells
767 !======================================================================
768 
769  already_visited(mype) = .true.
770 
771  DO nn = 1,n_cut_cells
772 
773  xref = local_refp_s(nn,1)
774  yref = local_refp_s(nn,2)
775  zref = local_refp_s(nn,3)
776 
777  d_to_cut = sqrt((x0 - xref)**2 + (y0 - yref)**2 + (z0 - zref)**2)
778 
779  dwall(ijk) = min(dwall(ijk),d_to_cut)
780 
781  ENDDO
782 
783 
784 !======================================================================
785 ! Second pass: Loop through neighbor processors (use send2 schedule)
786 !======================================================================
787 
788  DO nb=1,nsend2
789  iproc = sendproc2(nb)
790  already_visited(iproc) = .true.
791  n1 = disp(iproc)+1
792  n2 = n1 + rcount(iproc) - 1
793 
794  DO nn = n1,n2
795 
796  xref = global_refp_s(nn,1)
797  yref = global_refp_s(nn,2)
798  zref = global_refp_s(nn,3)
799 
800  d_to_cut = sqrt((x0 - xref)**2 + (y0 - yref)**2 + (z0 - zref)**2)
801 
802  dwall(ijk) = min(dwall(ijk),d_to_cut)
803 
804  ENDDO
805 
806  ENDDO
807 
808 !======================================================================
809 ! Third pass: Loop through all other processors
810 ! skip already visited processors (myPE and its neigbhors)
811 ! First test if the average reference point is farther than dwall
812 ! if this is true, then skip the entire processor cut cells.
813 !======================================================================
814 
815 
816  DO iproc=0,numpes-1
817  IF(already_visited(iproc)) cycle
818 
819  xref = all_pe_refp(iproc,1)
820  yref = all_pe_refp(iproc,2)
821  zref = all_pe_refp(iproc,3)
822 
823  d_to_pe_ref = sqrt((x0 - xref)**2 + (y0 - yref)**2 + (z0 - zref)**2)
824 
825  IF((dwall(ijk) < d_to_pe_ref).AND. &
826  (.NOT.dwall_brute_force )) THEN
827  cycle
828  ELSE
829  n1 = disp(iproc)+1
830  n2 = n1 + rcount(iproc) - 1
831 
832  DO nn = n1,n2
833 
834  xref = global_refp_s(nn,1)
835  yref = global_refp_s(nn,2)
836  zref = global_refp_s(nn,3)
837 
838  d_to_cut = sqrt((x0 - xref)**2 + (y0 - yref)**2 + (z0 - zref)**2)
839 
840  dwall(ijk) = min(dwall(ijk),d_to_cut)
841 
842  ENDDO
843  ENDIF
844  ENDDO
845 
846  ENDIF
847 
848  ENDIF
849 
850  ENDDO
851 
852  call send_recv(dwall,2)
853 !======================================================================
854 ! Deallocate arrays before leaving
855 !======================================================================
856  DEALLOCATE (local_refp_s)
857  DEALLOCATE (global_refp_s)
858  RETURN
859 
860  END SUBROUTINE get_distance_to_wall
subroutine allgather_1d(lbuf, gbuf, idebug)
double precision, dimension(:,:), allocatable normal_u
Definition: cutcell_mod.f:203
integer, dimension(:), allocatable i_of
Definition: indices_mod.f:45
logical, dimension(:), allocatable wall_u_at
Definition: cutcell_mod.f:126
subroutine test_del_h(IJK, TYPE_OF_CELL)
Definition: get_delh.f:498
logical, dimension(:), allocatable cut_u_cell_at
Definition: cutcell_mod.f:356
integer ijkend3
Definition: compar_mod.f:80
double precision, dimension(:,:), allocatable debug_cg
Definition: cutcell_mod.f:444
integer dimension_3
Definition: param_mod.f:11
subroutine gatherv_1d(lbuf, sendcnt, gbuf, rcount, disp, mroot, idebug)
double precision, dimension(0:15) z_node
Definition: cutcell_mod.f:76
double precision, dimension(0:15) y_node
Definition: cutcell_mod.f:75
logical, dimension(:), allocatable wall_v_at
Definition: cutcell_mod.f:127
logical print_warnings
Definition: cutcell_mod.f:416
double precision, dimension(0:dim_j) dy
Definition: geometry_mod.f:70
subroutine allgather_1i(lbuf, gbuf, idebug)
double precision, dimension(:,:), allocatable normal_s
Definition: cutcell_mod.f:120
double precision, parameter undefined
Definition: param1_mod.f:18
double precision, dimension(0:dim_k) dz
Definition: geometry_mod.f:72
integer numpes
Definition: compar_mod.f:24
double precision, dimension(:,:), allocatable refp_v
Definition: cutcell_mod.f:244
integer, dimension(:), allocatable k_of
Definition: indices_mod.f:47
integer pe_io
Definition: compar_mod.f:30
double precision function, dimension(3) cross_product(A, B)
Definition: quadric_mod.f:98
logical dwall_brute_force
Definition: cutcell_mod.f:494
integer, dimension(:), allocatable j_of
Definition: indices_mod.f:46
logical, dimension(:), allocatable wall_w_at
Definition: cutcell_mod.f:128
subroutine get_cell_node_coordinates(IJK, TYPE_OF_CELL)
logical, dimension(:), allocatable cut_w_cell_at
Definition: cutcell_mod.f:358
double precision, dimension(0:dim_i) dx
Definition: geometry_mod.f:68
double precision, dimension(:,:), allocatable refp_s
Definition: cutcell_mod.f:123
integer, dimension(:), allocatable number_of_nodes
Definition: cutcell_mod.f:105
integer nsend2
Definition: sendrecv_mod.f:40
Definition: run_mod.f:13
double precision, dimension(:,:), allocatable refp_u
Definition: cutcell_mod.f:206
double precision, dimension(:,:), allocatable refp_w
Definition: cutcell_mod.f:283
Definition: param_mod.f:2
logical no_k
Definition: geometry_mod.f:28
logical, dimension(:), allocatable cut_v_cell_at
Definition: cutcell_mod.f:357
logical, dimension(:), allocatable interior_cell_at
Definition: cutcell_mod.f:40
double precision, dimension(:,:), allocatable normal_w
Definition: cutcell_mod.f:280
logical do_k
Definition: geometry_mod.f:30
logical, dimension(:), allocatable cut_cell_at
Definition: cutcell_mod.f:355
integer mype
Definition: compar_mod.f:24
subroutine store_cut_face_info(IJK, TYPE_OF_CELL, N_CUT_FACE_NODES, COORD_CUT_FACE_NODES, X_MEAN, Y_MEAN, Z_MEAN)
Definition: get_delh.f:346
integer ijkstart3
Definition: compar_mod.f:80
integer, dimension(:), pointer sendproc2
Definition: sendrecv_mod.f:29
subroutine write_progress_bar(I, I_MAX, JUSTIFICATION)
double precision tol_delh
Definition: cutcell_mod.f:377
subroutine get_del_h_des(IJK, TYPE_OF_CELL, X0, Y0, Z0, Del_H, Nx, Ny, Nz, allow_neg_dist)
Definition: get_delh.f:177
subroutine get_distance_to_wall
Definition: get_delh.f:592
double precision, dimension(:), allocatable dwall
Definition: cutcell_mod.f:488
subroutine get_del_h(IJK, TYPE_OF_CELL, X0, Y0, Z0, Del_H, Nx, Ny, Nz)
Definition: get_delh.f:19
logical, dimension(:), allocatable blocked_cell_at
Definition: cutcell_mod.f:361
double precision, dimension(:,:), allocatable normal_v
Definition: cutcell_mod.f:241
integer, dimension(0:15) ijk_of_node
Definition: cutcell_mod.f:78
double precision, parameter zero
Definition: param1_mod.f:27
double precision, dimension(0:15) x_node
Definition: cutcell_mod.f:74
integer, dimension(:,:), allocatable connectivity
Definition: cutcell_mod.f:111