Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RFLU_ModHashTable.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 to carry out hash table operations.
26 !
27 ! Description: None.
28 !
29 ! Notes: To create and use a hash table, one has to take the following steps:
30 ! 1. Allocate a table of the appropriate size by calling CreateHashTable.
31 ! This routine will automatically make the table larger in order to
32 ! reduce the number of collisions.
33 ! 2. Provide a routine which computes a key and call hashKey.
34 ! 3. Deallocate the table by calling DestroyHashTable.
35 !
36 ! ******************************************************************************
37 !
38 ! $Id: RFLU_ModHashTable.F90,v 1.17 2008/12/06 08:44:22 mtcampbe Exp $
39 !
40 ! Copyright: (c) 2002-2005 by the University of Illinois
41 !
42 ! ******************************************************************************
43 
45 
46  USE moddatatypes
47  USE modparameters
48  USE moderror
49  USE modglobal, ONLY: t_global
50  USE modgrid, ONLY: t_grid
51  USE modbndpatch, ONLY: t_patch
52 
53  IMPLICIT NONE
54 
55  PRIVATE :: rflu_findnearestprime, &
58 
59  PUBLIC :: rflu_createhashtable, &
62  rflu_hashedge, &
63  rflu_hashface, &
67 
68  SAVE
69 
70 ! ******************************************************************************
71 ! Declarations and definitions
72 ! ******************************************************************************
73 
74 ! ==============================================================================
75 ! Public
76 ! ==============================================================================
77 
78  INTEGER, PARAMETER, PUBLIC :: HASHTABLE_ENTRYSTATUS_OLD = 0, &
79  HASHTABLE_ENTRYSTATUS_NEW = 1
80 
81  INTEGER, PUBLIC :: hashTableCollisions,hashTableSize
82  INTEGER, ALLOCATABLE, DIMENSION(:), PUBLIC :: hashTable
83 
84 ! ==============================================================================
85 ! Private
86 ! ==============================================================================
87 
88  INTEGER, PARAMETER, PRIVATE :: HASHTABLE_INIT = 0 ! must be <= 0
89  INTEGER, PARAMETER, PRIVATE :: NPRIMES = 48
90 
91  INTEGER, PRIVATE :: primeNumbers(NPRIMES) = &
92  (/ 1, 251, 379, 509, &
93  761, 1021, 1531, 2039, &
94  3067, 4093, 6143, 8191, &
95  12289, 16381, 24571, 32749, &
96  49139, 65521, 98297, 131071, &
97  196613, 262139, 393209, 524287, &
98  786431, 1048573, 1572853, 2097143, &
99  3145721, 4194301, 6291449, 8388593, &
100  12582917, 16777213, 25165807, 33554393, &
101  50331599, 67108859, 100663261, 134217689, &
102  201326549, 268435399, 402653171, 536870909, &
103  805306349, 1073741789, 1610612711, 2147483647 /)
104 
105 
106 ! *****************************************************************************
107 ! Routines
108 ! *****************************************************************************
109 
110  CONTAINS
111 
112 
113 
114 
115 ! ******************************************************************************
116 !
117 ! Purpose: Create hash table.
118 !
119 ! Description: None.
120 !
121 ! Input:
122 ! global Global pointer
123 ! size Size of hash table
124 !
125 ! Output: None.
126 !
127 ! Notes: None.
128 !
129 ! ******************************************************************************
130 
131  SUBROUTINE rflu_createhashtable(global,size)
132 
133  IMPLICIT NONE
134 
135 ! ******************************************************************************
136 ! Declarations and definitions
137 ! ******************************************************************************
138 
139 ! ==============================================================================
140 ! Arguments
141 ! ==============================================================================
142 
143  INTEGER, INTENT(IN) :: size
144  TYPE(t_global), POINTER :: global
145 
146 ! ==============================================================================
147 ! Local variables
148 ! ==============================================================================
149 
150  INTEGER :: errorflag,ih
151 
152 ! ******************************************************************************
153 ! Start
154 ! ******************************************************************************
155 
156  CALL registerfunction(global,'RFLU_CreateHashTable',&
157  'RFLU_ModHashTable.F90')
158 
159 ! ******************************************************************************
160 ! Find nearest prime
161 ! ******************************************************************************
162 
163  CALL rflu_findnearestprime(2*size,hashtablesize)
164 
165 ! ******************************************************************************
166 ! Allocate memory and initialize
167 ! ******************************************************************************
168 
169  ALLOCATE(hashtable(hashtablesize),stat=errorflag)
170  global%error = errorflag
171  IF ( global%error /= err_none ) THEN
172  CALL errorstop(global,err_allocate,__line__,'hashTable')
173  END IF ! global%error
174 
175  DO ih = 1,hashtablesize
176  hashtable(ih) = hashtable_init
177  END DO ! ih
178 
179  hashtablecollisions = 0
180 
181 ! ******************************************************************************
182 ! End
183 ! ******************************************************************************
184 
185  CALL deregisterfunction(global)
186 
187  END SUBROUTINE rflu_createhashtable
188 
189 
190 
191 
192 
193 
194 
195 ! ******************************************************************************
196 !
197 ! Purpose: Destroy hash table
198 !
199 ! Description: None.
200 !
201 ! Input:
202 ! global Global pointer
203 !
204 ! Output: None.
205 !
206 ! Notes: None.
207 !
208 ! ******************************************************************************
209 
210  SUBROUTINE rflu_destroyhashtable(global)
211 
212  IMPLICIT NONE
213 
214 ! ******************************************************************************
215 ! Declarations and definitions
216 ! ******************************************************************************
217 
218 ! ==============================================================================
219 ! Arguments
220 ! ==============================================================================
221 
222  TYPE(t_global), POINTER :: global
223 
224 ! ==============================================================================
225 ! Local variables
226 ! ==============================================================================
227 
228  INTEGER :: errorflag
229 
230 ! ******************************************************************************
231 ! Start
232 ! ******************************************************************************
233 
234  CALL registerfunction(global,'RFLU_DestroyHashTable',&
235  'RFLU_ModHashTable.F90')
236 
237 ! ******************************************************************************
238 ! Deallocate memory
239 ! ******************************************************************************
240 
241  DEALLOCATE(hashtable,stat=errorflag)
242  global%error = errorflag
243  IF ( global%error /= err_none ) THEN
244  CALL errorstop(global,err_deallocate,__line__,'hashTable')
245  END IF ! global%error
246 
247 ! ******************************************************************************
248 ! End
249 ! ******************************************************************************
250 
251  CALL deregisterfunction(global)
252 
253  END SUBROUTINE rflu_destroyhashtable
254 
255 
256 
257 
258 
259 
260 
261 
262 
263 ! ******************************************************************************
264 !
265 ! Purpose: Find nearest prime for hash table size.
266 !
267 ! Description: None.
268 !
269 ! Input:
270 ! size Original size
271 !
272 ! Output:
273 ! primeSize Nearest prime to original size
274 !
275 ! Notes: None.
276 !
277 ! ******************************************************************************
278 
279  SUBROUTINE rflu_findnearestprime(size,primeSize)
280 
281  IMPLICIT NONE
282 
283 ! ******************************************************************************
284 ! Declarations and definitions
285 ! ******************************************************************************
286 
287 ! ==============================================================================
288 ! Arguments
289 ! ==============================================================================
290 
291  INTEGER, INTENT(IN) :: size
292  INTEGER, INTENT(OUT) :: primesize
293 
294 ! ==============================================================================
295 ! Local variables
296 ! ==============================================================================
297 
298  INTEGER :: i
299 
300 ! ******************************************************************************
301 ! Start, find nearest prime
302 ! ******************************************************************************
303 
304  DO i = 1,nprimes-1
305  IF ( size >= primenumbers(i) .AND. size < primenumbers(i+1) ) THEN
306  primesize = primenumbers(i+1)
307  EXIT
308  END IF ! size
309  END DO ! i
310 
311 ! ******************************************************************************
312 ! End
313 ! ******************************************************************************
314 
315  END SUBROUTINE rflu_findnearestprime
316 
317 
318 
319 
320 
321 
322 ! ******************************************************************************
323 !
324 ! Purpose: Compute key from series of integers.
325 !
326 ! Description: None.
327 !
328 ! Input:
329 ! a Set of integers
330 ! aSize Size of set of integers
331 !
332 ! Output:
333 ! key Key
334 !
335 ! Notes: None.
336 !
337 ! ******************************************************************************
338 
339  SUBROUTINE rflu_hashbuildkey(a,aSize,key)
340 
341  IMPLICIT NONE
342 
343 ! ******************************************************************************
344 ! Declarations and definitions
345 ! ******************************************************************************
346 
347 ! ==============================================================================
348 ! Arguments
349 ! ==============================================================================
350 
351  INTEGER, INTENT(IN) :: asize
352  INTEGER, INTENT(IN) :: a(1:asize)
353  INTEGER, INTENT(OUT) :: key
354 
355 ! ==============================================================================
356 ! Local variables
357 ! ==============================================================================
358 
359  INTEGER :: i,term
360  INTEGER, PARAMETER :: a_rand = 31415, b_rand = 27183
361 
362 ! ******************************************************************************
363 ! Start, compute key
364 ! ******************************************************************************
365 
366 
367 ! key = MOD(MOD(A_RAND*B_RAND,hashTableSize)*v1 + v2,HUGE(1)/10)
368 ! key = MOD(A_RAND*v1 + B_RAND*v2,hashTableSize)
369 
370 ! - ABS function used to guard against negative keys from integer overflow
371 ! key = ABS(ABS(A_RAND*v1) + ABS(MOD(A_RAND*B_RAND,hashTableSize)*v2))
372 
373  term = a_rand
374  key = 0
375 
376  DO i = 1,asize
377  term = mod(term*b_rand,hashtablesize)
378 
379  IF ( term < 0 ) THEN
380  term = term + huge(1) + 1
381  END IF ! term
382 
383  key = mod((term*key + a(i)),huge(1))
384 
385  IF ( key < 0 ) THEN
386  key = key + huge(1) + 1
387  END IF ! key
388  END DO ! i
389 
390 ! ******************************************************************************
391 ! End
392 ! ******************************************************************************
393 
394  END SUBROUTINE rflu_hashbuildkey
395 
396 
397 
398 
399 ! ******************************************************************************
400 !
401 ! Purpose: Compute key from integer.
402 !
403 ! Description: None.
404 !
405 ! Input:
406 ! a Integer
407 !
408 ! Output:
409 ! key Key
410 !
411 ! Notes: Added as separate function because passing single-element arrays lead
412 ! to warnings from Intel f90 compiler.
413 !
414 ! ******************************************************************************
415 
416  SUBROUTINE rflu_hashbuildkey1(a,key)
417 
418  IMPLICIT NONE
419 
420 ! ******************************************************************************
421 ! Declarations and definitions
422 ! ******************************************************************************
423 
424 ! ==============================================================================
425 ! Arguments
426 ! ==============================================================================
427 
428  INTEGER, INTENT(IN) :: a
429  INTEGER, INTENT(OUT) :: key
430 
431 ! ==============================================================================
432 ! Local variables
433 ! ==============================================================================
434 
435 ! ******************************************************************************
436 ! Start, compute key
437 ! ******************************************************************************
438 
439  key = mod(a,huge(1))
440 
441  IF ( key < 0 ) THEN
442  key = key + huge(1) + 1
443  END IF ! key
444 
445 ! ******************************************************************************
446 ! End
447 ! ******************************************************************************
448 
449  END SUBROUTINE rflu_hashbuildkey1
450 
451 
452 
453 
454 
455 
456 ! ******************************************************************************
457 !
458 ! Purpose: Hash edge.
459 !
460 ! Description: None.
461 !
462 ! Input:
463 ! key Key from which address is computed
464 ! pGrid Pointer to grid
465 ! v Edge vertices
466 !
467 ! Output:
468 ! edgeType Flag indicating whether edge is new or not
469 !
470 ! Notes: None.
471 !
472 ! ******************************************************************************
473 
474  SUBROUTINE rflu_hashedge(global,key,pGrid,v,edgeType)
475 
476  IMPLICIT NONE
477 
478 ! ******************************************************************************
479 ! Declarations and definitions
480 ! ******************************************************************************
481 
482 ! ==============================================================================
483 ! Arguments
484 ! ==============================================================================
485 
486  INTEGER, INTENT(IN) :: key
487  INTEGER, INTENT(IN) :: v(1:2)
488  INTEGER, INTENT(OUT) :: edgetype
489  TYPE(t_grid), POINTER :: pgrid
490  TYPE(t_global), POINTER :: global
491 
492 ! ==============================================================================
493 ! Local variables
494 ! ==============================================================================
495 
496  INTEGER :: addr,collcntr,incr
497 
498 ! ******************************************************************************
499 ! Start
500 ! ******************************************************************************
501 
502  CALL registerfunction(global,'RFLU_HashEdge',&
503  'RFLU_ModHashTable.F90')
504 
505 ! ******************************************************************************
506 ! Construct address from key based on sorted edge vertices
507 ! ******************************************************************************
508 
510 
511 ! ******************************************************************************
512 ! Insert edge into hash table
513 ! ******************************************************************************
514 
515  collcntr = 0
516 
517  DO
518  IF ( hashtable(addr) == hashtable_init ) THEN
519  IF ( pgrid%nEdgesTot == pgrid%nEdgesEst ) THEN
520  CALL errorstop(global,err_nedges_estimate,__line__)
521  END IF ! pGrid%nEdgesTot
522 
523  edgetype = edge_type_new
524 
525  pgrid%nEdgesTot = pgrid%nEdgesTot + 1
526  hashtable(addr) = pgrid%nEdgesTot
527 
528  pgrid%e2v(1,pgrid%nEdgesTot) = v(1)
529  pgrid%e2v(2,pgrid%nEdgesTot) = v(2)
530 
531  EXIT
532  ELSE
533  IF ( v(1) == pgrid%e2v(1,hashtable(addr)) .AND. &
534  v(2) == pgrid%e2v(2,hashtable(addr)) ) THEN
535  edgetype = edge_type_old
536 
537  EXIT
538  ELSE
539  hashtablecollisions = hashtablecollisions + 1
540 
541  IF ( collcntr == 0 ) THEN
542  CALL rflu_hashfuncsecondary(key,incr)
543  END IF ! collCntr
544 
545  collcntr = collcntr + 1
546  addr = mod(addr + incr,hashtablesize)
547 
548  IF ( addr == 0 ) THEN
549  addr = 1
550  END IF
551  END IF ! fv
552 
553  END IF ! hashTable
554  END DO ! <empty>
555 
556 ! ******************************************************************************
557 ! End
558 ! ******************************************************************************
559 
560  CALL deregisterfunction(global)
561 
562  END SUBROUTINE rflu_hashedge
563 
564 
565 
566 
567 
568 
569 
570 ! ******************************************************************************
571 !
572 ! Purpose: Hash face.
573 !
574 ! Description: None.
575 !
576 ! Input:
577 ! key Key from which address is computed
578 ! pGrid Pointer to grid
579 ! icg Global cell number
580 ! ifl Local face number
581 ! fv Face vertices (only three are needed)
582 ! nVert Number of vertices in face (3 = triangle, 4 = quadrilateral)
583 !
584 ! Output:
585 ! faceType Flag indicating whether face is new or not
586 !
587 ! Notes: None.
588 !
589 ! ******************************************************************************
590 
591  SUBROUTINE rflu_hashface(global,key,pGrid,icg,ifl,fv,nVert,faceType)
592 
593  IMPLICIT NONE
594 
595 ! ******************************************************************************
596 ! Declarations and definitions
597 ! ******************************************************************************
598 
599 ! ==============================================================================
600 ! Arguments
601 ! ==============================================================================
602 
603  INTEGER, INTENT(IN) :: icg,ifl,key,nvert
604  INTEGER, INTENT(IN) :: fv(1:3)
605  INTEGER, INTENT(OUT) :: facetype
606  TYPE(t_grid), POINTER :: pgrid
607  TYPE(t_global), POINTER :: global
608 
609 ! ==============================================================================
610 ! Local variables
611 ! ==============================================================================
612 
613  INTEGER :: addr,collcntr,incr
614 
615 ! ******************************************************************************
616 ! Start
617 ! ******************************************************************************
618 
619  CALL registerfunction(global,'RFLU_HashFace',&
620  'RFLU_ModHashTable.F90')
621 
622 ! ******************************************************************************
623 ! Construct address from key based on sorted face vertices
624 ! ******************************************************************************
625 
627 
628 ! ******************************************************************************
629 ! Insert face into hash table
630 ! ******************************************************************************
631 
632  collcntr = 0
633 
634  DO
635 
636 ! ==============================================================================
637 ! Entry not yet occupied
638 ! ==============================================================================
639 
640  IF ( hashtable(addr) == hashtable_init ) THEN
641  IF ( pgrid%nFacesTot == pgrid%nFacesEst ) THEN
642  CALL errorstop(global,err_nfaces_estimate,__line__)
643  END IF ! pGrid%nFacesTot
644 
645  facetype = face_type_new
646 
647  pgrid%nFacesTot = pgrid%nFacesTot + 1
648  hashtable(addr) = pgrid%nFacesTot
649 
650  pgrid%f2c(1 ,pgrid%nFacesTot) = icg
651  pgrid%f2c(3 ,pgrid%nFacesTot) = ifl
652  pgrid%f2c(4 ,pgrid%nFacesTot) = nvert
653  pgrid%f2v(1:3,pgrid%nFacesTot) = fv(1:3)
654 
655  EXIT
656 
657 ! ==============================================================================
658 ! Entry already occupied
659 ! ==============================================================================
660 
661  ELSE
662 
663 ! ------------------------------------------------------------------------------
664 ! Entry occupied by same face
665 ! ------------------------------------------------------------------------------
666 
667  IF ( fv(1) == pgrid%f2v(1,hashtable(addr)) .AND. &
668  fv(2) == pgrid%f2v(2,hashtable(addr)) .AND. &
669  fv(3) == pgrid%f2v(3,hashtable(addr)) ) THEN
670  facetype = face_type_old
671 
672  pgrid%f2c(2,hashtable(addr)) = icg
673 
674  IF ( pgrid%f2c(4,hashtable(addr)) /= nvert ) THEN
675  CALL errorstop(global,err_face_nvert_invalid,__line__)
676  END IF ! pGrid%f2c
677 
678  EXIT
679 
680 ! ------------------------------------------------------------------------------
681 ! Entry occupied by some other face: COLLISION
682 ! ------------------------------------------------------------------------------
683 
684  ELSE
685  hashtablecollisions = hashtablecollisions + 1
686 
687  IF ( collcntr == 0 ) THEN
688  CALL rflu_hashfuncsecondary(key,incr)
689  END IF ! collCntr
690 
691  collcntr = collcntr + 1
692  addr = mod(addr + incr,hashtablesize)
693 
694  IF ( addr == 0 ) THEN
695  addr = 1
696  END IF ! addr
697  END IF ! fv
698 
699  END IF ! hashTable
700  END DO ! <empty>
701 
702 ! ******************************************************************************
703 ! End
704 ! ******************************************************************************
705 
706  CALL deregisterfunction(global)
707 
708  END SUBROUTINE rflu_hashface
709 
710 
711 
712 
713 
714 
715 
716 ! ******************************************************************************
717 !
718 ! Purpose: Primary hash function: Compute address from key value.
719 !
720 ! Description: None.
721 !
722 ! Input:
723 ! key Key from which address is computed
724 !
725 ! Output:
726 ! addr Address
727 !
728 ! Notes: None.
729 !
730 ! ******************************************************************************
731 
732  SUBROUTINE rflu_hashfuncprimary(key,addr)
733 
734  IMPLICIT NONE
735 
736 ! ******************************************************************************
737 ! Declarations and definitions
738 ! ******************************************************************************
739 
740 ! ==============================================================================
741 ! Arguments
742 ! ==============================================================================
743 
744  INTEGER, INTENT(IN) :: key
745  INTEGER, INTENT(OUT) :: addr
746 
747 ! ******************************************************************************
748 ! Start, compute address
749 ! ******************************************************************************
750 
751 ! addr = 1 ! simple test, will lead to many collisions, but works
752  addr = 1 + mod(key,hashtablesize)
753 
754 ! ******************************************************************************
755 ! End
756 ! ******************************************************************************
757 
758  END SUBROUTINE rflu_hashfuncprimary
759 
760 
761 
762 
763 
764 
765 
766 ! ******************************************************************************
767 !
768 ! Purpose: Secondary hash function: Compute address from key value
769 !
770 ! Description: None.
771 !
772 ! Input:
773 ! key Key from which address is computed
774 !
775 ! Output:
776 ! addr Address
777 !
778 ! Notes: None.
779 !
780 ! ******************************************************************************
781 
782  SUBROUTINE rflu_hashfuncsecondary(key,addr)
783 
784  IMPLICIT NONE
785 
786 ! ******************************************************************************
787 ! Declarations and definitions
788 ! ******************************************************************************
789 
790 ! ==============================================================================
791 ! Arguments
792 ! ==============================================================================
793 
794  INTEGER, INTENT(IN) :: key
795  INTEGER, INTENT(OUT) :: addr
796 
797 ! ******************************************************************************
798 ! Start, compute address
799 ! ******************************************************************************
800 
801 ! addr = 1 ! simple test, will lead to many collisions, but works
802  addr = 1 + mod(key,hashtablesize-2)
803 
804 ! ******************************************************************************
805 ! End
806 ! ******************************************************************************
807 
808  END SUBROUTINE rflu_hashfuncsecondary
809 
810 
811 
812 
813 
814 
815 
816 ! ******************************************************************************
817 !
818 ! Purpose: Hash vertex.
819 !
820 ! Description: None.
821 !
822 ! Input:
823 ! global Pointer to global type
824 ! key Key from which address is computed
825 ! ivg Global boundary vertex number
826 ! nVert Number of vertices
827 ! vert List of vertices
828 !
829 ! Output:
830 ! nVert Number of vertices
831 ! vert List of vertices
832 ! errorFlag Error flag (optional)
833 !
834 ! Notes: None.
835 !
836 ! ******************************************************************************
837 
838  SUBROUTINE rflu_hashvertex(global,key,ivg,nVert,vert,errorFlag)
839 
840  IMPLICIT NONE
841 
842 ! ******************************************************************************
843 ! Declarations and definitions
844 ! ******************************************************************************
845 
846 ! ==============================================================================
847 ! Arguments
848 ! ==============================================================================
849 
850  INTEGER, INTENT(IN) :: ivg,key
851  INTEGER, INTENT(INOUT) :: nvert
852  INTEGER, INTENT(OUT), OPTIONAL :: errorflag
853  INTEGER, DIMENSION(:), INTENT(INOUT) :: vert
854  TYPE(t_patch), POINTER :: ppatch
855  TYPE(t_global), POINTER :: global
856 
857 ! ==============================================================================
858 ! Local variables
859 ! ==============================================================================
860 
861  INTEGER :: addr,collcntr,incr
862 
863 ! ******************************************************************************
864 ! Start
865 ! ******************************************************************************
866 
867  CALL registerfunction(global,'RFLU_HashVertex',&
868  'RFLU_ModHashTable.F90')
869 
870  IF ( present(errorflag) ) THEN
871  errorflag = err_none
872  END IF ! PRESENT
873 
874 ! ******************************************************************************
875 ! Construct address from key
876 ! ******************************************************************************
877 
879 
880 ! ******************************************************************************
881 ! Insert vertex into hash table
882 ! ******************************************************************************
883 
884  collcntr = 0
885 
886  emptyloop: DO
887  IF ( hashtable(addr) == hashtable_init ) THEN
888  IF ( nvert == SIZE(vert,1) ) THEN
889  IF ( .NOT. present(errorflag) ) THEN
890  CALL errorstop(global,err_nvert_estimate,__line__)
891  ELSE
892  errorflag = err_none + 1 ! Any value other than ERR_NONE
893  EXIT emptyloop
894  END IF ! errorFlag
895  END IF ! nVert
896 
897  hashtable(addr) = ivg
898  nvert = nvert + 1
899 
900  vert(nvert) = ivg
901 
902  EXIT emptyloop
903  ELSE
904  IF ( hashtable(addr) == ivg ) THEN
905  EXIT emptyloop
906  ELSE
907  hashtablecollisions = hashtablecollisions + 1
908 
909  IF ( collcntr == 0 ) THEN
910  CALL rflu_hashfuncsecondary(key,incr)
911  END IF ! collCntr
912 
913  collcntr = collcntr + 1
914  addr = mod(addr + incr,hashtablesize)
915 
916  IF ( addr == 0 ) THEN
917  addr = 1
918  END IF
919  END IF ! hashTable
920 
921  END IF ! hashTable
922  END DO emptyloop
923 
924 ! ******************************************************************************
925 ! End
926 ! ******************************************************************************
927 
928  CALL deregisterfunction(global)
929 
930  END SUBROUTINE rflu_hashvertex
931 
932 
933 
934 
935 
936 
937 ! ******************************************************************************
938 !
939 ! Purpose: Hash vertex and return some information about entry.
940 !
941 ! Description: None.
942 !
943 ! Input:
944 ! global Pointer to global type
945 ! key Key from which address is computed
946 ! ivg Global boundary vertex number
947 ! nVert Number of vertices
948 ! vert List of vertices
949 ! indx List of vertex indices
950 !
951 ! Output:
952 ! nVert Number of vertices
953 ! vert List of vertices
954 ! indx List of vertex indices
955 ! ivgStat Status of vertex entry
956 ! ivgIndx Index of vertex entry
957 !
958 ! Notes: None.
959 !
960 ! ******************************************************************************
961 
962  SUBROUTINE rflu_hashvertexfancy(global,key,ivg,nVert,vert,indx,ivgStat, &
963  ivgindx)
964 
965  IMPLICIT NONE
966 
967 ! ******************************************************************************
968 ! Declarations and definitions
969 ! ******************************************************************************
970 
971 ! ==============================================================================
972 ! Arguments
973 ! ==============================================================================
974 
975  INTEGER, INTENT(IN) :: ivg,key
976  INTEGER, INTENT(INOUT) :: nvert
977  INTEGER, INTENT(OUT) :: ivgindx,ivgstat
978  INTEGER, DIMENSION(:), INTENT(INOUT) :: indx,vert
979  TYPE(t_patch), POINTER :: ppatch
980  TYPE(t_global), POINTER :: global
981 
982 ! ==============================================================================
983 ! Local variables
984 ! ==============================================================================
985 
986  INTEGER :: addr,collcntr,incr
987 
988 ! ******************************************************************************
989 ! Start
990 ! ******************************************************************************
991 
992  CALL registerfunction(global,'RFLU_HashVertexFancy',&
993  'RFLU_ModHashTable.F90')
994 
995 ! ******************************************************************************
996 ! Construct address from key
997 ! ******************************************************************************
998 
1000 
1001 ! ******************************************************************************
1002 ! Insert vertex into hash table
1003 ! ******************************************************************************
1004 
1005  collcntr = 0
1006 
1007  DO
1008  IF ( hashtable(addr) == hashtable_init ) THEN
1009  IF ( nvert == SIZE(vert,1) ) THEN
1010  CALL errorstop(global,err_nvert_estimate,__line__)
1011  END IF ! nVert
1012 
1013  hashtable(addr) = ivg
1014  nvert = nvert + 1
1015 
1016  vert(nvert) = ivg
1017 
1018  indx(addr) = nvert
1019 
1020  ivgstat = hashtable_entrystatus_new
1021  ivgindx = crazy_value_int
1022 
1023  EXIT
1024  ELSE
1025  IF ( hashtable(addr) == ivg ) THEN
1026  ivgstat = hashtable_entrystatus_old
1027  ivgindx = indx(addr)
1028 
1029  EXIT
1030  ELSE
1031  hashtablecollisions = hashtablecollisions + 1
1032 
1033  IF ( collcntr == 0 ) THEN
1034  CALL rflu_hashfuncsecondary(key,incr)
1035  END IF ! collCntr
1036 
1037  collcntr = collcntr + 1
1038  addr = mod(addr + incr,hashtablesize)
1039 
1040  IF ( addr == 0 ) THEN
1041  addr = 1
1042  END IF
1043  END IF ! hashTable
1044 
1045  END IF ! hashTable
1046  END DO ! <empty>
1047 
1048 ! ******************************************************************************
1049 ! End
1050 ! ******************************************************************************
1051 
1052  CALL deregisterfunction(global)
1053 
1054  END SUBROUTINE rflu_hashvertexfancy
1055 
1056 
1057 
1058 
1059 
1060 
1061 
1062 ! ******************************************************************************
1063 !
1064 ! Purpose: Unhash boundary face to find the global cell number to which the
1065 ! face is attached.
1066 !
1067 ! Description: None.
1068 !
1069 ! Input:
1070 ! key Key from which address is computed
1071 ! pGrid Pointer to grid
1072 ! fv Face vertices (only three are needed)
1073 ! nVert Number of vertices in face (3 = triangle, 4 = quadrilateral)
1074 ! bcType Boundary-condition type assigned to face
1075 !
1076 ! Output:
1077 ! icg Global cell number to which boundary face is attached
1078 ! ifg Global face number
1079 !
1080 ! Notes: None.
1081 !
1082 ! ******************************************************************************
1083 
1084  SUBROUTINE rflu_unhashbface(global,key,pGrid,fv,nVert,bcType,icg,ifg)
1085 
1086  IMPLICIT NONE
1087 
1088 ! ******************************************************************************
1089 ! Declarations and definitions
1090 ! ******************************************************************************
1091 
1092 ! ==============================================================================
1093 ! Arguments
1094 ! ==============================================================================
1095 
1096  INTEGER, INTENT(IN) :: bctype,key,nvert
1097  INTEGER, INTENT(IN) :: fv(1:3)
1098  INTEGER, INTENT(OUT) :: icg,ifg
1099  TYPE(t_grid), POINTER :: pgrid
1100  TYPE(t_global), POINTER :: global
1101 
1102 ! ==============================================================================
1103 ! Local variables
1104 ! ==============================================================================
1105 
1106  INTEGER :: addr,collcntr,fvsize,incr
1107 
1108 ! ******************************************************************************
1109 ! Start
1110 ! ******************************************************************************
1111 
1112  CALL registerfunction(global,'RFLU_UnHashBFace',&
1113  'RFLU_ModHashTable.F90')
1114 
1115 ! ******************************************************************************
1116 ! Construct address from key based on sorted face vertices
1117 ! ******************************************************************************
1118 
1120 
1121 ! ******************************************************************************
1122 ! Insert face into hash table
1123 ! ******************************************************************************
1124 
1125  collcntr = 0
1126 
1127  DO
1128  ifg = hashtable(addr)
1129 
1130 ! ==============================================================================
1131 ! Entry not occupied, must have error in hash table
1132 ! ==============================================================================
1133 
1134  IF ( ifg == hashtable_init ) THEN
1135  CALL errorstop(global,err_hashtable,__line__)
1136 
1137 ! ==============================================================================
1138 ! Entry occupied
1139 ! ==============================================================================
1140 
1141  ELSE
1142 
1143 ! ------------------------------------------------------------------------------
1144 ! No collision if vertices match
1145 ! ------------------------------------------------------------------------------
1146 
1147  IF ( fv(1) == pgrid%f2v(1,ifg) .AND. &
1148  fv(2) == pgrid%f2v(2,ifg) .AND. &
1149  fv(3) == pgrid%f2v(3,ifg) ) THEN
1150  icg = pgrid%f2c(1,ifg)
1151 
1152 ! ------- If second entry IS NOT exterior cell (as initialized), then have error
1153 ! unless face is on symmetry or periodic patch, because there have
1154 ! virtual cells adjacent to patch
1155 
1156  IF ( pgrid%f2c(2,ifg) /= cell_type_ext ) THEN
1157  IF ( bctype /= bc_symmetry .AND. bctype /= bc_periodic ) THEN
1158  CALL errorstop(global,err_hashtable,__line__)
1159  END IF ! bcType
1160 
1161 ! ------- If second entry IS interior cell (as initialized), then only set to
1162 ! boundary cell type if face is not symmetry or periodic patch. This is
1163 ! done to make sure this boundary face shows up as a VX face in the
1164 ! final face list which is has to to get geometry correct. In the
1165 ! sketch below, the face in question is marked by '+'. This face MUST
1166 ! show up as a VX face. If it is marked as a VB face, it does not show
1167 ! up in the main facelist, and is then eliminated from the geometry
1168 ! computation because any faces (actual and virtual) are ignored
1169 ! (this is done because the AV and VV faces associated with sype
1170 ! patches appear on the patch face list AND in the volume face list).
1171 ! But by ignoring these faces, also do not get contribution of face
1172 ! marked below and geometry is incorrect. With the treatment below,
1173 ! have this face appear twice also, and this treatment thus not only
1174 ! fixes geometry computation problem, but is also more consistent with
1175 ! existing treatment.
1176 !
1177 ! | | |
1178 ! | virtual | real | real
1179 ! vx cell av cell aa cell
1180 ! | | |
1181 ! | | |
1182 ! |+++vx++++|---av----|------ <--- sype patch
1183 ! | |
1184 ! | virtual | virtual
1185 ! | cell vv cell
1186 ! | |
1187 ! |---vx----|------
1188 !
1189 
1190  ELSE
1191  IF ( bctype /= bc_symmetry .AND. bctype /= bc_periodic ) THEN
1192  pgrid%f2c(2,ifg) = cell_type_bnd
1193  ELSE
1194  IF ( icg <= pgrid%nCells ) THEN
1195  pgrid%f2c(2,ifg) = cell_type_bnd
1196  END IF ! icg
1197  END IF ! bcType
1198  END IF ! pGrid%f2c
1199 
1200  IF ( pgrid%f2c(4,ifg) /= nvert ) THEN
1201  CALL errorstop(global,err_face_nvert_invalid,__line__)
1202  END IF ! pGrid%f2c
1203 
1204  EXIT
1205 
1206 ! ------------------------------------------------------------------------------
1207 ! Collision if vertices do not match, generate new key and address
1208 ! ------------------------------------------------------------------------------
1209 
1210  ELSE
1211  IF ( collcntr == 0 ) THEN
1212  CALL rflu_hashfuncsecondary(key,incr)
1213  END IF ! collCntr
1214 
1215  collcntr = collcntr + 1
1216  addr = mod(addr + incr,hashtablesize)
1217 
1218  IF ( addr == 0 ) THEN
1219  addr = 1
1220  END IF
1221  END IF ! fv
1222 
1223  END IF ! hashTable
1224  END DO ! <empty>
1225 
1226 ! ******************************************************************************
1227 ! End
1228 ! ******************************************************************************
1229 
1230  CALL deregisterfunction(global)
1231 
1232  END SUBROUTINE rflu_unhashbface
1233 
1234 
1235 
1236 
1237 
1238 
1239 
1240 ! ******************************************************************************
1241 ! End
1242 ! ******************************************************************************
1243 
1244 END MODULE rflu_modhashtable
1245 
1246 
1247 ! ******************************************************************************
1248 !
1249 ! RCS Revision history:
1250 !
1251 ! $Log: RFLU_ModHashTable.F90,v $
1252 ! Revision 1.17 2008/12/06 08:44:22 mtcampbe
1253 ! Updated license.
1254 !
1255 ! Revision 1.16 2008/11/19 22:17:33 mtcampbe
1256 ! Added Illinois Open Source License/Copyright
1257 !
1258 ! Revision 1.15 2007/07/08 21:45:03 gzheng
1259 ! changed the PRESENT is used for PGI compiler
1260 !
1261 ! Revision 1.14 2006/12/15 13:24:20 haselbac
1262 ! Added new RFLU_HashBuildKey1 for single integers to avoid ifort warnings
1263 !
1264 ! Revision 1.13 2006/04/17 19:53:37 haselbac
1265 ! Bug fix: For serial cells, opposite cell should be BND, not EXT
1266 !
1267 ! Revision 1.12 2006/04/13 18:09:19 haselbac
1268 ! Bug fix: Treatment of virtual faces on sype patches
1269 !
1270 ! Revision 1.11 2006/04/07 15:19:19 haselbac
1271 ! Removed tabs
1272 !
1273 ! Revision 1.10 2006/03/25 21:53:29 haselbac
1274 ! Changes because of sype patches
1275 !
1276 ! Revision 1.9 2005/06/14 17:46:56 haselbac
1277 ! Adapted RFLU_HashVertex to return optional error flag
1278 !
1279 ! Revision 1.8 2005/04/21 01:36:26 haselbac
1280 ! Added routine which returns info, in particular if element already hashed
1281 !
1282 ! Revision 1.7 2004/12/04 03:31:04 haselbac
1283 ! Changed RFLU_HashBVertex so can be used for any type of vertex list
1284 !
1285 ! Revision 1.6 2004/07/06 15:14:42 haselbac
1286 ! Added subroutines for hashing objects, cosmetics
1287 !
1288 ! Revision 1.5 2004/01/22 16:03:59 haselbac
1289 ! Made contents of modules PRIVATE, only procs PUBLIC, to avoid errors on ALC and titan
1290 !
1291 ! Revision 1.4 2003/12/04 03:28:48 haselbac
1292 ! Increase size of hash table to avoid degeneracy for one case
1293 !
1294 ! Revision 1.3 2002/10/08 15:49:21 haselbac
1295 ! {IO}STAT=global%error replaced by {IO}STAT=errorFlag - SGI problem
1296 !
1297 ! Revision 1.2 2002/09/09 15:08:11 haselbac
1298 ! global now under regions
1299 !
1300 ! Revision 1.1 2002/03/01 16:31:21 haselbac
1301 ! Initial revision
1302 !
1303 ! ******************************************************************************
1304 
1305 
1306 
1307 
1308 
1309 
1310 
1311 
1312 
1313 
1314 
1315 
1316 
subroutine, private rflu_hashfuncprimary(key, addr)
subroutine, public rflu_createhashtable(global, size)
subroutine, public rflu_hashedge(global, key, pGrid, v, edgeType)
subroutine, public rflu_destroyhashtable(global)
subroutine rflu_hashbuildkey1(a, key)
subroutine registerfunction(global, funName, fileName)
Definition: ModError.F90:449
subroutine, public rflu_hashbuildkey(a, aSize, key)
int size() const
Definition: maps.h:78
subroutine, public rflu_unhashbface(global, key, pGrid, fv, nVert, bcType, icg, ifg)
subroutine, private rflu_hashfuncsecondary(key, addr)
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
subroutine, public rflu_hashvertexfancy(global, key, ivg, nVert, vert, indx, ivgStat, ivgIndx)
blockLoc i
Definition: read.cpp:79
subroutine, private rflu_findnearestprime(size, primeSize)
const void * addr(const COM::Attribute *attr) const
Obtain the address of an attribute associated with the node.
Definition: Manifold_2.C:1191
subroutine errorstop(global, errorCode, errorLine, addMessage)
Definition: ModError.F90:483
static T_Key key
Definition: vinci_lass.c:76
subroutine deregisterfunction(global)
Definition: ModError.F90:469
subroutine, public rflu_hashface(global, key, pGrid, icg, ifl, fv, nVert, faceType)
subroutine, public rflu_hashvertex(global, key, ivg, nVert, vert, errorFlag)
RT a() const
Definition: Line_2.h:140
IndexType nvert() const
Definition: Mesh.H:565