ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
partitionMod.F90
Go to the documentation of this file.
2  !
3  ! This local module contains definitions of derived datatypes
4  ! as well as variables used in the partitioning directory.
5  !
6  use constants
7  implicit none
8  save
9  !
10  ! The definition of the derived datatype distributionBlockType
11  !
13  !
14  ! Block dimensions and local block ID.
15  !
16  ! nx, ny, nz - block integer dimensions for no halo cell based
17  ! quantities.
18  ! il, jl, kl - block integer dimensions for no halo node based
19  ! quantities.
20  ! blockID - local block ID on the processor this block is
21  ! stored.
22 
23  integer(kind=intType) :: nx, ny, nz, &
24  il, jl, kl
25  integer(kind=intType) :: blockid
26  !
27  ! Total number cells and faces inside the block. In the number
28  ! faces the work for nonmatching block boundaries is included,
29  ! such that the load balance is still guaranteed.
30  !
31  ! Ncell : total number of cells in this block.
32  ! Nface : total number of faces in this block.
33 
34  integer(kind=intType) :: ncell, nface
35  !
36  ! Block boundary conditions.
37  !
38  ! nSubface - Number of subfaces on this block.
39  ! n1to1 - Number of 1 to 1 block boundaries.
40  ! nBocos - Number of physical boundary subfaces.
41  ! BCType(:) - Boundary condition type for each
42  ! subface. See the module BCTypes for
43  ! the possibilities.
44  ! BCFaceID(:) - Block face location of each subface.
45  ! Possible values are: iMin, iMax, jMin,
46  ! jMax, kMin, kMax.
47  ! cgnsSubface(:) - The subface in the corresponding cgns
48  ! block. As cgns distinguishes between
49  ! boundary and internal boundaries, the
50  ! BCType of the subface is needed to
51  ! know which one to take. A zero
52  ! indicates that this face was obtained
53  ! by splitting a cgns block.
54  ! inBeg(:), inEnd(:) - Lower and upper limits for the nodes
55  ! jnBeg(:), jnEnd(:) in each of the index directions on a
56  ! knBeg(:), knEnd(:) given subface. Note that one of these
57  ! indices will not change since we will
58  ! be moving on a face.
59  ! dinBeg(:), dinEnd(:) - Lower and upper limits for the nodes
60  ! djnBeg(:), djnEnd(:) in the each of the index directions
61  ! dknBeg(:), dknEnd(:) of the donor subface for this
62  ! particular subface. Note that one of
63  ! these indices will not change since we
64  ! will be moving on a face.
65  ! neighBlock(:) - Block number to which this subface
66  ! connects. This value is set to zero if
67  ! this subface is not connected to
68  ! another block.
69  ! l1(:), l2(:), - Short hand for the transformation
70  ! l3(:) matrix between this subface and the
71  ! neighbor block. These value are set to
72  ! zero if this subface is not connected
73  ! to another block.
74  ! groupNum(:) - Group number to which this subface
75  ! belongs. If this subface does not
76  ! belong to any group, the corresponding
77  ! entry in this array is zeroed out.
78 
79  integer(kind=intType) :: nsubface, n1to1, nbocos
80 
81  integer(kind=intType), dimension(:), pointer :: bctype
82  integer(kind=intType), dimension(:), pointer :: bcfaceid
83  integer(kind=intType), dimension(:), pointer :: cgnssubface
84 
85  integer(kind=intType), dimension(:), pointer :: inbeg, inend
86  integer(kind=intType), dimension(:), pointer :: jnbeg, jnend
87  integer(kind=intType), dimension(:), pointer :: knbeg, knend
88 
89  integer(kind=intType), dimension(:), pointer :: dinbeg, dinend
90  integer(kind=intType), dimension(:), pointer :: djnbeg, djnend
91  integer(kind=intType), dimension(:), pointer :: dknbeg, dknend
92 
93  integer(kind=intType), dimension(:), pointer :: neighblock
94  integer(kind=intType), dimension(:), pointer :: l1, l2, l3
95  integer(kind=intType), dimension(:), pointer :: groupnum
96 
97  !
98  ! Relation to the original cgns grid.
99  !
100  ! cgnsBlockID - block/zone number of the cgns grid to which
101  ! this block is related.
102  ! iBegOr, iEndOr - range of points of this block in the
103  ! jBegOr, jEndOr corresponding cgns block, i.e. for this block
104  ! kBegOr, kEndOr iBegOr <= i <= iEndOr, jBegOr <= j <= jEndOr,
105  ! kBegOr <= k <= kEndOr.
106  ! It is of course possible that the entire
107  ! block is stored.
108 
109  integer(kind=intType) :: cgnsblockid
110  integer(kind=intType) :: ibegor, iendor, jbegor, jendor
111  integer(kind=intType) :: kbegor, kendor
112 
113  end type distributionblocktype
114 
115  ! nBlocks : Number of blocks to be distributed.
116  ! blocks(nBlocks): The array with the block info.
117 
118  integer(kind=intType) :: nblocks
119  type(distributionblocktype), dimension(:), allocatable :: blocks
120 
121  !
122  ! Type definition to store the way the original cgns blocks are
123  ! split for load balancing reasons.
124  !
126 
127  ! nSubBlocks: # of subblocks into which the original
128  ! block is split.
129  ! ranges(nsubblocks,3,2): The nodal range in the original
130  ! block of these subblocks.
131 
132  integer(kind=intType) :: nsubblocks
133  integer(kind=intType), dimension(:, :, :), pointer :: ranges
134 
135  end type splitcgnstype
136 
137  !
138  ! Type definition needed to determine the processor ID's and
139  ! nodal ranges of the subblocks for every CGNS block.
140  !
142 
143  ! cgnsBlockID - block/zone number of the cgns grid to which
144  ! this subblock is related.
145  ! procID - Processor ID on which this subblock is
146  ! stored.
147  ! blockID - local block ID on the processor this block is
148  ! stored.
149  ! iBegOr, iEndOr - range of points of this block in the
150  ! jBegOr, jEndOr corresponding cgns block, i.e. for this block
151  ! kBegOr, kEndOr iBegOr <= i <= iEndOr, jBegOr <= j <= jEndOr,
152  ! kBegOr <= k <= kEndOr.
153  ! It is of course possible that the entire
154  ! block is stored.
155 
156  integer :: cgnsblockid
157  integer :: procid
158  integer :: blockid
159  integer :: ibegor, iendor, jbegor, jendor, kbegor, kendor
160 
161  end type subblocksofcgnstype
162 
163  ! Interface for the extension of the operators <= and <.
164  ! These are needed for the sorting of subblocksOfCGNSType. Note
165  ! that the = operator does not need to be defined, because
166  ! subblocksOfCGNSType only contains primitive types.
167 
168  interface operator(<=)
169  module procedure lessequalsubblocksofcgnstype
170  end interface operator(<=)
171 
172  interface operator(<)
173  module procedure lesssubblocksofcgnstype
174  end interface operator(<)
175  !
176  ! Type definition needed to determine the number of distinct
177  ! non-matching abutting subfaces in the CGNS file.
178  !
180 
181  ! iBeg, iEnd - Nodal subface range om the CGNS block, i-direction
182  ! jBeg, jEnd - Idem in the j-direction
183  ! kBeg, kEnd - Idem in the k-direction
184  ! connID - The cgns connectivity ID.
185 
186  integer :: ibeg, jbeg, kbeg, iend, jend, kend
187  integer :: connid
188 
189  end type subfacenonmatchtype
190 
191  ! Interface for the extension of the operators <= and <.
192  ! These are needed for the sorting of subfaceNonMatchType. Note
193  ! that the = operator does not need to be defined, because
194  ! subfaceNonMatchType only contains primitive types.
195 
196  interface operator(<=)
197  module procedure lessequalsubfacenonmatchtype
198  end interface operator(<=)
199 
200  interface operator(<)
201  module procedure lesssubfacenonmatchtype
202  end interface operator(<)
203 
205 
206  ! iMin: minimum i-index in the subrange.
207  ! jMin: minimum j-index in the subrange.
208  ! kMin: minimum k-index in the subrange.
209  ! iMax: maximum i-index in the subrange.
210  ! jMax: maximum j-index in the subrange.
211  ! kMax: maximum k-index in the subrange.
212 
213  integer(kind=intType) :: imin, jmin, kmin
214  integer(kind=intType) :: imax, jmax, kmax
215 
216  end type sortsubrangetype
217 
218  ! Interfaces for the definitions of the operators <=, < and /=.
219  ! These are needed for the sorting of this derived data type.
220  ! Note that the = operator does not need to be defined, because
221  ! sortSubRangeType only contains primitive types.
222 
223  interface operator(<=)
224  module procedure lessequalsortsubrangetype
225  end interface operator(<=)
226 
227  interface operator(<)
228  module procedure lesssortsubrangetype
229  end interface operator(<)
230 
231  ! Definition of the derived data type.
232 
234  integer(kind=intType) :: n1, n2, n3, n4
235  real(kind=realtype) :: dist
236  end type fourintplusrealtype
237 
238  ! Interfaces for the definitions of the operators <=, < and /=.
239  ! These are needed for the sorting of this derived data type.
240  ! Note that the = operator does not need to be defined, because
241  ! fourIntPlusRealType only contains primitive types.
242 
243  interface operator(<=)
244  module procedure lessequalfourintplusrealtype
245  end interface operator(<=)
246 
247  interface operator(<)
248  module procedure lessfourintplusrealtype
249  end interface operator(<)
250 
251  interface operator(/=)
252  module procedure notequalfourintplusrealtype
253  end interface operator(/=)
254 
255  ! ==========================================================================
256  !
257  ! Variable to store the partition number (processor ID) of the
258  ! computational blocks.
259  !
260  ! ubvec(2): Tolerance for the constraints.
261  ! part(nBlocks): The processor ID for each block, starting at 0.
262 
263  real, dimension(2) :: ubvec
264 
265  integer(kind=intType), dimension(:), allocatable :: part
266  !
267  ! Variables needed for the reading of the grid files.
268  !
269  ! nGridsRead: Number of grids to read.
270  ! fileIDs(nGridsRead): The file ID's.
271  ! gridFiles(nGridsRead): Names of the grid files to read.
272  ! interpolSpectral: Whether or not to interpolate the
273  ! coordinates for the time spectral mode.
274 
275  integer(kind=intType) :: ngridsread
276  logical :: interpolspectral
277 
278  integer, dimension(:), allocatable :: fileids
279 
280  character(len=maxStringLen), dimension(:), allocatable :: gridfiles
281  ! ==========================================================================
282 
283 contains
284  !
285  ! Functions to simulate the operators <= and < for the derived
286  ! datatypes subblocksOfCGNSType and subfaceNonMatchType.
287  !
288  logical function lessequalsubblocksofcgnstype(g1, g2)
289  !
290  ! This function returns .true. if g1 <= g2 and .false.
291  ! otherwise. The comparison is firstly based on the CGNS block
292  ! ID, then the processor ID and finally the local block ID.
293  !
294  implicit none
295  !
296  ! Function arguments.
297  !
298  type(subblocksofcgnstype), intent(in) :: g1, g2
299 
300  ! Comparison of the CGNS block ID. If not equal, set
301  ! lessEqualSubblocksOfCGNSType appropriately and return.
302 
303  if (g1%cgnsBlockID < g2%cgnsBlockID) then
305  return
306  else if (g1%cgnsBlockID > g2%cgnsBlockID) then
308  return
309  end if
310 
311  ! Compare the processor ID's.
312 
313  if (g1%procID < g2%procID) then
315  return
316  else if (g1%procID > g2%procID) then
318  return
319  end if
320 
321  ! Compare the local block ID's.
322 
323  if (g1%blockID < g2%blockID) then
325  return
326  else if (g1%blockID > g2%blockID) then
328  return
329  end if
330 
331  ! It does not make sense to compare the subranges, because
332  ! these are identical if we came so far. Both entities are
333  ! identical. So set lessEqualSubblocksOfCGNSType to .true.
334 
336 
337  end function lessequalsubblocksofcgnstype
338 
339  !===============================================================
340 
341  logical function lesssubblocksofcgnstype(g1, g2)
342  !
343  ! This function returns .true. if g1 < g2 and .false.
344  ! otherwise. The comparison is firstly based on the CGNS block
345  ! ID, then the processor ID and finally the local blockID.
346  !
347  implicit none
348  !
349  ! Function arguments.
350  !
351  type(subblocksofcgnstype), intent(in) :: g1, g2
352 
353  ! Comparison of the CGNS block ID. If not equal, set
354  ! lessSubblocksOfCGNSType appropriately and return.
355 
356  if (g1%cgnsBlockID < g2%cgnsBlockID) then
357  lesssubblocksofcgnstype = .true.
358  return
359  else if (g1%cgnsBlockID > g2%cgnsBlockID) then
360  lesssubblocksofcgnstype = .false.
361  return
362  end if
363 
364  ! Compare the processor ID's.
365 
366  if (g1%procID < g2%procID) then
367  lesssubblocksofcgnstype = .true.
368  return
369  else if (g1%procID > g2%procID) then
370  lesssubblocksofcgnstype = .false.
371  return
372  end if
373 
374  ! Compare the local block ID's.
375 
376  if (g1%blockID < g2%blockID) then
377  lesssubblocksofcgnstype = .true.
378  return
379  else if (g1%blockID > g2%blockID) then
380  lesssubblocksofcgnstype = .false.
381  return
382  end if
383 
384  ! It does not make sense to compare the subranges, because
385  ! these are identical if we came so far. Both entities are
386  ! identical. So set lessSubblocksOfCGNSType to .false.
387 
388  lesssubblocksofcgnstype = .false.
389 
390  end function lesssubblocksofcgnstype
391 
392  !===============================================================
393 
394  logical function lessequalsubfacenonmatchtype(g1, g2)
395  !
396  ! This function returns .true. if g1 <= g2 and .false.
397  ! otherwise. The comparison is firstly based on the i-range,
398  ! followed by the j-range and k-range. If these are all the
399  ! same the connectivity ID is compared.
400  !
401  implicit none
402  !
403  ! Function arguments.
404  !
405  type(subfacenonmatchtype), intent(in) :: g1, g2
406 
407  ! Comparison of the iBeg value. If different set
408  ! lessEqualSubfaceNonMatchType appropriately and return.
409 
410  if (g1%iBeg < g2%iBeg) then
412  return
413  else if (g1%iBeg > g2%iBeg) then
415  return
416  end if
417 
418  ! The iEnd value.
419 
420  if (g1%iEnd < g2%iEnd) then
422  return
423  else if (g1%iEnd > g2%iEnd) then
425  return
426  end if
427 
428  ! The jBeg value.
429 
430  if (g1%jBeg < g2%jBeg) then
432  return
433  else if (g1%jBeg > g2%jBeg) then
435  return
436  end if
437 
438  ! The jEnd value.
439 
440  if (g1%jEnd < g2%jEnd) then
442  return
443  else if (g1%jEnd > g2%jEnd) then
445  return
446  end if
447 
448  ! The kBeg value.
449 
450  if (g1%kBeg < g2%kBeg) then
452  return
453  else if (g1%kBeg > g2%kBeg) then
455  return
456  end if
457 
458  ! The kEnd value.
459 
460  if (g1%kEnd < g2%kEnd) then
462  return
463  else if (g1%kEnd > g2%kEnd) then
465  return
466  end if
467 
468  ! The subrange is identical. Compare the connectivity ID.
469 
470  if (g1%connID < g2%connID) then
472  return
473  else if (g1%connID > g2%connID) then
475  return
476  end if
477 
478  ! g1 and g2 are identical. Return .true.
479 
481 
482  end function lessequalsubfacenonmatchtype
483 
484  !===============================================================
485 
486  logical function lesssubfacenonmatchtype(g1, g2)
487  !
488  ! This function returns .true. if g1 < g2 and .false.
489  ! otherwise. The comparison is firstly based on the i-range,
490  ! followed by the j-range and k-range. If these are all the
491  ! same the connectivity ID is compared.
492  !
493  implicit none
494  !
495  ! Function arguments.
496  !
497  type(subfacenonmatchtype), intent(in) :: g1, g2
498 
499  ! Comparison of the iBeg value. If different set
500  ! lessEqualSubfaceNonMatchType appropriately and return.
501 
502  if (g1%iBeg < g2%iBeg) then
503  lesssubfacenonmatchtype = .true.
504  return
505  else if (g1%iBeg > g2%iBeg) then
506  lesssubfacenonmatchtype = .false.
507  return
508  end if
509 
510  ! The iEnd value.
511 
512  if (g1%iEnd < g2%iEnd) then
513  lesssubfacenonmatchtype = .true.
514  return
515  else if (g1%iEnd > g2%iEnd) then
516  lesssubfacenonmatchtype = .false.
517  return
518  end if
519 
520  ! The jBeg value.
521 
522  if (g1%jBeg < g2%jBeg) then
523  lesssubfacenonmatchtype = .true.
524  return
525  else if (g1%jBeg > g2%jBeg) then
526  lesssubfacenonmatchtype = .false.
527  return
528  end if
529 
530  ! The jEnd value.
531 
532  if (g1%jEnd < g2%jEnd) then
533  lesssubfacenonmatchtype = .true.
534  return
535  else if (g1%jEnd > g2%jEnd) then
536  lesssubfacenonmatchtype = .false.
537  return
538  end if
539 
540  ! The kBeg value.
541 
542  if (g1%kBeg < g2%kBeg) then
543  lesssubfacenonmatchtype = .true.
544  return
545  else if (g1%kBeg > g2%kBeg) then
546  lesssubfacenonmatchtype = .false.
547  return
548  end if
549 
550  ! The kEnd value.
551 
552  if (g1%kEnd < g2%kEnd) then
553  lesssubfacenonmatchtype = .true.
554  return
555  else if (g1%kEnd > g2%kEnd) then
556  lesssubfacenonmatchtype = .false.
557  return
558  end if
559 
560  ! The subrange is identical. Compare the connectivity ID.
561 
562  if (g1%connID < g2%connID) then
563  lesssubfacenonmatchtype = .true.
564  return
565  else if (g1%connID > g2%connID) then
566  lesssubfacenonmatchtype = .false.
567  return
568  end if
569 
570  ! g1 and g2 are identical. Return .false.
571 
572  lesssubfacenonmatchtype = .false.
573 
574  end function lesssubfacenonmatchtype
575 
576  subroutine qsortsubblocksofcgnstype(arr, nn)
577  !
578  ! qsortSubblocksOfCGNSType sorts the array of the derived
579  ! datatype subblocksOfCGNSType in increasing order based on the
580  ! <= operator for this derived data type.
581  !
582  use constants
583  use utils, only: terminate
584  implicit none
585  !
586  ! Subroutine arguments.
587  !
588  integer(kind=intType), intent(in) :: nn
589 
590  type(subblocksofcgnstype), dimension(*), intent(inout) :: arr
591  !
592  ! Local variables.
593  !
594  integer(kind=intType), parameter :: m = 7
595 
596  integer(kind=intType) :: nStack
597  integer(kind=intType) :: i, j, k, r, l, jStack, ii
598 
599  integer :: ierr
600 
601  type(subblocksofcgnstype) :: a, tmp
602 
603  integer(kind=intType), allocatable, dimension(:) :: stack
604  integer(kind=intType), allocatable, dimension(:) :: tmpStack
605 
606  ! Allocate the memory for stack.
607 
608  nstack = 100
609  allocate (stack(nstack), stat=ierr)
610  if (ierr /= 0) &
611  call terminate("qsortSubblocksOfCGNSType", &
612  "Memory allocation failure for stack")
613 
614  ! Initialize the variables that control the sorting.
615 
616  jstack = 0
617  l = 1
618  r = nn
619 
620  ! Start of the algorithm
621 
622  do
623 
624  ! Check for the size of the subarray.
625 
626  if ((r - l) < m) then
627 
628  ! Perform insertion sort
629 
630  do j = l + 1, r
631  a = arr(j)
632  do i = (j - 1), l, -1
633  if (arr(i) <= a) exit
634  arr(i + 1) = arr(i)
635  end do
636  arr(i + 1) = a
637  end do
638 
639  ! In case there are no more elements on the stack, exit from
640  ! the outermost do-loop. Algorithm has finished.
641 
642  if (jstack == 0) exit
643 
644  ! Pop stack and begin a new round of partitioning.
645 
646  r = stack(jstack)
647  l = stack(jstack - 1)
648  jstack = jstack - 2
649 
650  else
651 
652  ! Subarray is larger than the threshold for a linear sort.
653  ! Choose median of left, center and right elements as
654  ! partitioning element a.
655  ! Also rearrange so that (l) <= (l+1) <= (r).
656 
657  k = (l + r) / 2
658  tmp = arr(k) ! Swap the elements
659  arr(k) = arr(l + 1) ! k and l+1.
660  arr(l + 1) = tmp
661 
662  if (arr(r) < arr(l)) then
663  tmp = arr(l) ! Swap the elements
664  arr(l) = arr(r) ! r and l.
665  arr(r) = tmp
666  end if
667 
668  if (arr(r) < arr(l + 1)) then
669  tmp = arr(l + 1) ! Swap the elements
670  arr(l + 1) = arr(r) ! r and l+1.
671  arr(r) = tmp
672  end if
673 
674  if (arr(l + 1) < arr(l)) then
675  tmp = arr(l + 1) ! Swap the elements
676  arr(l + 1) = arr(l) ! l and l+1.
677  arr(l) = tmp
678  end if
679 
680  ! Initialize the pointers for partitioning.
681 
682  i = l + 1
683  j = r
684  a = arr(l + 1)
685 
686  ! The innermost loop
687 
688  do
689 
690  ! Scan up to find element >= a.
691  do
692  i = i + 1
693  if (a <= arr(i)) exit
694  end do
695 
696  ! Scan down to find element <= a.
697  do
698  j = j - 1
699  if (arr(j) <= a) exit
700  end do
701 
702  ! Exit the loop in case the pointers i and j crossed.
703 
704  if (j < i) exit
705 
706  ! Swap the element i and j.
707 
708  tmp = arr(i)
709  arr(i) = arr(j)
710  arr(j) = tmp
711  end do
712 
713  ! Swap the entries j and l+1. Remember that a equals
714  ! arr(l+1).
715 
716  arr(l + 1) = arr(j)
717  arr(j) = a
718 
719  ! Push pointers to larger subarray on stack,
720  ! process smaller subarray immediately.
721 
722  jstack = jstack + 2
723  if (jstack > nstack) then
724 
725  ! Storage of the stack is too small. Reallocate.
726 
727  allocate (tmpstack(nstack), stat=ierr)
728  if (ierr /= 0) &
729  call terminate("qsortSubblocksOfCGNSType", &
730  "Memory allocation error for tmpStack")
731  tmpstack = stack
732 
733  ! Free the memory of stack, store the old value of nStack
734  ! in tmp and increase nStack.
735 
736  deallocate (stack, stat=ierr)
737  if (ierr /= 0) &
738  call terminate("qsortSubblocksOfCGNSType", &
739  "Deallocation error for stack")
740  ii = nstack
741  nstack = nstack + 100
742 
743  ! Allocate the memory for stack and copy the old values
744  ! from tmpStack.
745 
746  allocate (stack(nstack), stat=ierr)
747  if (ierr /= 0) &
748  call terminate("qsortSubblocksOfCGNSType", &
749  "Memory reallocation error for stack")
750  stack(1:ii) = tmpstack(1:ii)
751 
752  ! And finally release the memory of tmpStack.
753 
754  deallocate (tmpstack, stat=ierr)
755  if (ierr /= 0) &
756  call terminate("qsortSubblocksOfCGNSType", &
757  "Deallocation error for tmpStack")
758  end if
759 
760  if ((r - i + 1) >= (j - l)) then
761  stack(jstack) = r
762  r = j - 1
763  stack(jstack - 1) = j
764  else
765  stack(jstack) = j - 1
766  stack(jstack - 1) = l
767  l = j
768  end if
769 
770  end if
771  end do
772 
773  ! Release the memory of stack.
774 
775  deallocate (stack, stat=ierr)
776  if (ierr /= 0) &
777  call terminate("qsortSubblocksOfCGNSType", &
778  "Deallocation error for stack")
779 
780  ! Check in debug mode whether the array is really sorted.
781 
782  if (debug) then
783  do i = 1, (nn - 1)
784  if (arr(i + 1) < arr(i)) &
785  call terminate("qsortSubblocksOfCGNSType", &
786  "Array is not sorted correctly")
787  end do
788  end if
789 
790  end subroutine qsortsubblocksofcgnstype
791 
792  subroutine qsortsubfacenonmatchtype(arr, nn)
793  !
794  ! qsortSubfaceNonMatchType sorts the array of the derived
795  ! datatype subfaceNonMatchType in increasing order based on the
796  ! <= operator for this derived data type.
797  !
798  use constants
799  use utils, only: terminate
800  implicit none
801  !
802  ! Subroutine arguments.
803  !
804  integer(kind=intType), intent(in) :: nn
805 
806  type(subfacenonmatchtype), dimension(*), intent(inout) :: arr
807  !
808  ! Local variables.
809  !
810  integer(kind=intType), parameter :: m = 7
811 
812  integer(kind=intType) :: nStack
813  integer(kind=intType) :: i, j, k, r, l, jStack, ii
814 
815  integer :: ierr
816 
817  type(subfacenonmatchtype) :: a, tmp
818 
819  integer(kind=intType), allocatable, dimension(:) :: stack
820  integer(kind=intType), allocatable, dimension(:) :: tmpStack
821 
822  ! Allocate the memory for stack.
823 
824  nstack = 100
825  allocate (stack(nstack), stat=ierr)
826  if (ierr /= 0) &
827  call terminate("qsortSubfaceNonMatchType", &
828  "Memory allocation failure for stack")
829 
830  ! Initialize the variables that control the sorting.
831 
832  jstack = 0
833  l = 1
834  r = nn
835 
836  ! Start of the algorithm
837 
838  do
839 
840  ! Check for the size of the subarray.
841 
842  if ((r - l) < m) then
843 
844  ! Perform insertion sort
845 
846  do j = l + 1, r
847  a = arr(j)
848  do i = (j - 1), l, -1
849  if (arr(i) <= a) exit
850  arr(i + 1) = arr(i)
851  end do
852  arr(i + 1) = a
853  end do
854 
855  ! In case there are no more elements on the stack, exit from
856  ! the outermost do-loop. Algorithm has finished.
857 
858  if (jstack == 0) exit
859 
860  ! Pop stack and begin a new round of partitioning.
861 
862  r = stack(jstack)
863  l = stack(jstack - 1)
864  jstack = jstack - 2
865 
866  else
867 
868  ! Subarray is larger than the threshold for a linear sort.
869  ! Choose median of left, center and right elements as
870  ! partitioning element a.
871  ! Also rearrange so that (l) <= (l+1) <= (r).
872 
873  k = (l + r) / 2
874  tmp = arr(k) ! Swap the elements
875  arr(k) = arr(l + 1) ! k and l+1.
876  arr(l + 1) = tmp
877 
878  if (arr(r) < arr(l)) then
879  tmp = arr(l) ! Swap the elements
880  arr(l) = arr(r) ! r and l.
881  arr(r) = tmp
882  end if
883 
884  if (arr(r) < arr(l + 1)) then
885  tmp = arr(l + 1) ! Swap the elements
886  arr(l + 1) = arr(r) ! r and l+1.
887  arr(r) = tmp
888  end if
889 
890  if (arr(l + 1) < arr(l)) then
891  tmp = arr(l + 1) ! Swap the elements
892  arr(l + 1) = arr(l) ! l and l+1.
893  arr(l) = tmp
894  end if
895 
896  ! Initialize the pointers for partitioning.
897 
898  i = l + 1
899  j = r
900  a = arr(l + 1)
901 
902  ! The innermost loop
903 
904  do
905 
906  ! Scan up to find element >= a.
907  do
908  i = i + 1
909  if (a <= arr(i)) exit
910  end do
911 
912  ! Scan down to find element <= a.
913  do
914  j = j - 1
915  if (arr(j) <= a) exit
916  end do
917 
918  ! Exit the loop in case the pointers i and j crossed.
919 
920  if (j < i) exit
921 
922  ! Swap the element i and j.
923 
924  tmp = arr(i)
925  arr(i) = arr(j)
926  arr(j) = tmp
927  end do
928 
929  ! Swap the entries j and l+1. Remember that a equals
930  ! arr(l+1).
931 
932  arr(l + 1) = arr(j)
933  arr(j) = a
934 
935  ! Push pointers to larger subarray on stack,
936  ! process smaller subarray immediately.
937 
938  jstack = jstack + 2
939  if (jstack > nstack) then
940 
941  ! Storage of the stack is too small. Reallocate.
942 
943  allocate (tmpstack(nstack), stat=ierr)
944  if (ierr /= 0) &
945  call terminate("qsortSubfaceNonMatchType", &
946  "Memory allocation error for tmpStack")
947  tmpstack = stack
948 
949  ! Free the memory of stack, store the old value of nStack
950  ! in tmp and increase nStack.
951 
952  deallocate (stack, stat=ierr)
953  if (ierr /= 0) &
954  call terminate("qsortSubfaceNonMatchType", &
955  "Deallocation error for stack")
956  ii = nstack
957  nstack = nstack + 100
958 
959  ! Allocate the memory for stack and copy the old values
960  ! from tmpStack.
961 
962  allocate (stack(nstack), stat=ierr)
963  if (ierr /= 0) &
964  call terminate("qsortSubfaceNonMatchType", &
965  "Memory reallocation error for stack")
966  stack(1:ii) = tmpstack(1:ii)
967 
968  ! And finally release the memory of tmpStack.
969 
970  deallocate (tmpstack, stat=ierr)
971  if (ierr /= 0) &
972  call terminate("qsortSubfaceNonMatchType", &
973  "Deallocation error for tmpStack")
974  end if
975 
976  if ((r - i + 1) >= (j - l)) then
977  stack(jstack) = r
978  r = j - 1
979  stack(jstack - 1) = j
980  else
981  stack(jstack) = j - 1
982  stack(jstack - 1) = l
983  l = j
984  end if
985 
986  end if
987  end do
988 
989  ! Release the memory of stack.
990 
991  deallocate (stack, stat=ierr)
992  if (ierr /= 0) &
993  call terminate("qsortSubfaceNonMatchType", &
994  "Deallocation error for stack")
995 
996  ! Check in debug mode whether the array is really sorted.
997 
998  if (debug) then
999  do i = 1, (nn - 1)
1000  if (arr(i + 1) < arr(i)) &
1001  call terminate("qsortSubfaceNonMatchType", &
1002  "Array is not sorted correctly")
1003  end do
1004  end if
1005 
1006  end subroutine qsortsubfacenonmatchtype
1007 
1008  logical function lessequalsortsubrangetype(g1, g2)
1009  !
1010  ! lessEqualSortSubRangeType defines the operator <= for the
1011  ! derived datatype sortSubRangeType. The comparison is first
1012  ! based on kMin, followed by jMin and finally iMin.
1013  ! The comparison is therefore not based on the max values.
1014  !
1015  implicit none
1016  !
1017  ! Function arguments.
1018  !
1019  type(sortsubrangetype), intent(in) :: g1, g2
1020  !
1021  ! Begin executation.
1022  !
1023  ! Compare the kMin index and return .true. or .false. if they
1024  ! differ.
1025 
1026  if (g1%kMin < g2%kMin) then
1027  lessequalsortsubrangetype = .true.
1028  return
1029  else if (g1%kMin > g2%kMin) then
1030  lessequalsortsubrangetype = .false.
1031  return
1032  end if
1033 
1034  ! kMin indices are equal. Compare the jMin's.
1035 
1036  if (g1%jMin < g2%jMin) then
1037  lessequalsortsubrangetype = .true.
1038  return
1039  else if (g1%jMin > g2%jMin) then
1040  lessequalsortsubrangetype = .false.
1041  return
1042  end if
1043 
1044  ! Also the jMin's are equal. Compare iMin's.
1045 
1046  if (g1%iMin < g2%iMin) then
1047  lessequalsortsubrangetype = .true.
1048  return
1049  else if (g1%iMin > g2%iMin) then
1050  lessequalsortsubrangetype = .false.
1051  return
1052  end if
1053 
1054  ! g1 equals g2. Return .true.
1055 
1056  lessequalsortsubrangetype = .true.
1057 
1058  end function lessequalsortsubrangetype
1059 
1060  !===============================================================
1061 
1062  logical function lesssortsubrangetype(g1, g2)
1063  !
1064  ! lessSortSubRangeType defines the operator < for the derived
1065  ! datatype sortSubRangeType. The comparison is first based on
1066  ! kMin, followed by jMin and finally iMin.
1067  ! The comparison is therefore not based on the max values.
1068  !
1069  implicit none
1070  !
1071  ! Function arguments.
1072  !
1073  type(sortsubrangetype), intent(in) :: g1, g2
1074  !
1075  ! Begin executation.
1076  !
1077  ! Compare the kMin index and return .true. or .false. if they
1078  ! differ.
1079 
1080  if (g1%kMin < g2%kMin) then
1081  lesssortsubrangetype = .true.
1082  return
1083  else if (g1%kMin > g2%kMin) then
1084  lesssortsubrangetype = .false.
1085  return
1086  end if
1087 
1088  ! kMin indices are equal. Compare the jMin's.
1089 
1090  if (g1%jMin < g2%jMin) then
1091  lesssortsubrangetype = .true.
1092  return
1093  else if (g1%jMin > g2%jMin) then
1094  lesssortsubrangetype = .false.
1095  return
1096  end if
1097 
1098  ! Also the jMin's are equal. Compare iMin's.
1099 
1100  if (g1%iMin < g2%iMin) then
1101  lesssortsubrangetype = .true.
1102  return
1103  else if (g1%iMin > g2%iMin) then
1104  lesssortsubrangetype = .false.
1105  return
1106  end if
1107 
1108  ! g1 equals g2. Return .false.
1109 
1110  lesssortsubrangetype = .false.
1111 
1112  end function lesssortsubrangetype
1113 
1114  ! ==================================================================
1115 
1116  subroutine sortrangessplitinfo(splitInfo)
1117  !
1118  ! sortRangesSplitInfo sort the ranges of the given subblocks in
1119  ! increasing order such that a unique ordering is obtained,
1120  ! independent of the history of the splitting.
1121  !
1122  use constants
1123  implicit none
1124  !
1125  ! Subroutine arguments.
1126  !
1127  type(splitcgnstype), intent(inout) :: splitInfo
1128  !
1129  ! Local variables.
1130  !
1131  integer(kind=intType) :: i, nSubBlocks
1132 
1133  type(sortsubrangetype), dimension(splitInfo%nSubBlocks) :: subRanges
1134 
1135  ! Copy the subface range from splitInfo into subRanges.
1136 
1137  nsubblocks = splitinfo%nSubBlocks
1138 
1139  do i = 1, nsubblocks
1140  subranges(i)%iMin = splitinfo%ranges(i, 1, 1)
1141  subranges(i)%jMin = splitinfo%ranges(i, 2, 1)
1142  subranges(i)%kMin = splitinfo%ranges(i, 3, 1)
1143 
1144  subranges(i)%iMax = splitinfo%ranges(i, 1, 2)
1145  subranges(i)%jMax = splitinfo%ranges(i, 2, 2)
1146  subranges(i)%kMax = splitinfo%ranges(i, 3, 2)
1147  end do
1148 
1149  ! Sort subRanges in increasing order.
1150 
1151  call qsortsortsubrangetype(subranges, nsubblocks)
1152 
1153  ! Copy the data back into splitInfo.
1154 
1155  do i = 1, nsubblocks
1156  splitinfo%ranges(i, 1, 1) = subranges(i)%iMin
1157  splitinfo%ranges(i, 2, 1) = subranges(i)%jMin
1158  splitinfo%ranges(i, 3, 1) = subranges(i)%kMin
1159 
1160  splitinfo%ranges(i, 1, 2) = subranges(i)%iMax
1161  splitinfo%ranges(i, 2, 2) = subranges(i)%jMax
1162  splitinfo%ranges(i, 3, 2) = subranges(i)%kMax
1163  end do
1164 
1165  end subroutine sortrangessplitinfo
1166 
1167  ! ==================================================================
1168 
1169  subroutine qsortsortsubrangetype(arr, nn)
1170  !
1171  ! qsortSortSubRangeType sorts the given number of halo's in
1172  ! increasing order based on the <= operator for this derived
1173  ! data type.
1174  !
1175  use utils, only: terminate
1176  implicit none
1177  !
1178  ! Subroutine arguments.
1179  !
1180  integer(kind=intType), intent(in) :: nn
1181 
1182  type(sortsubrangetype), dimension(*), intent(inout) :: arr
1183  !
1184  ! Local variables.
1185  !
1186  integer(kind=intType), parameter :: m = 7
1187 
1188  integer(kind=intType) :: nStack
1189  integer(kind=intType) :: i, j, k, r, l, jStack, ii
1190 
1191  integer :: ierr
1192 
1193  type(sortsubrangetype) :: a, tmp
1194 
1195  integer(kind=intType), allocatable, dimension(:) :: stack
1196  integer(kind=intType), allocatable, dimension(:) :: tmpStack
1197 
1198  ! Allocate the memory for stack.
1199 
1200  nstack = 100
1201  allocate (stack(nstack), stat=ierr)
1202  if (ierr /= 0) &
1203  call terminate("qsortSortSubRangeType", &
1204  "Memory allocation failure for stack")
1205 
1206  ! Initialize the variables that control the sorting.
1207 
1208  jstack = 0
1209  l = 1
1210  r = nn
1211 
1212  ! Start of the algorithm
1213 
1214  do
1215 
1216  ! Check for the size of the subarray.
1217 
1218  if ((r - l) < m) then
1219 
1220  ! Perform insertion sort
1221 
1222  do j = l + 1, r
1223  a = arr(j)
1224  do i = (j - 1), l, -1
1225  if (arr(i) <= a) exit
1226  arr(i + 1) = arr(i)
1227  end do
1228  arr(i + 1) = a
1229  end do
1230 
1231  ! In case there are no more elements on the stack, exit from
1232  ! the outermost do-loop. Algorithm has finished.
1233 
1234  if (jstack == 0) exit
1235 
1236  ! Pop stack and begin a new round of partitioning.
1237 
1238  r = stack(jstack)
1239  l = stack(jstack - 1)
1240  jstack = jstack - 2
1241 
1242  else
1243 
1244  ! Subarray is larger than the threshold for a linear sort.
1245  ! Choose median of left, center and right elements as
1246  ! partitioning element a.
1247  ! Also rearrange so that (l) <= (l+1) <= (r).
1248 
1249  k = (l + r) / 2
1250  tmp = arr(k) ! Swap the elements
1251  arr(k) = arr(l + 1) ! k and l+1.
1252  arr(l + 1) = tmp
1253 
1254  if (arr(r) < arr(l)) then
1255  tmp = arr(l) ! Swap the elements
1256  arr(l) = arr(r) ! r and l.
1257  arr(r) = tmp
1258  end if
1259 
1260  if (arr(r) < arr(l + 1)) then
1261  tmp = arr(l + 1) ! Swap the elements
1262  arr(l + 1) = arr(r) ! r and l+1.
1263  arr(r) = tmp
1264  end if
1265 
1266  if (arr(l + 1) < arr(l)) then
1267  tmp = arr(l + 1) ! Swap the elements
1268  arr(l + 1) = arr(l) ! l and l+1.
1269  arr(l) = tmp
1270  end if
1271 
1272  ! Initialize the pointers for partitioning.
1273 
1274  i = l + 1
1275  j = r
1276  a = arr(l + 1)
1277 
1278  ! The innermost loop
1279 
1280  do
1281 
1282  ! Scan up to find element >= a.
1283  do
1284  i = i + 1
1285  if (a <= arr(i)) exit
1286  end do
1287 
1288  ! Scan down to find element <= a.
1289  do
1290  j = j - 1
1291  if (arr(j) <= a) exit
1292  end do
1293 
1294  ! Exit the loop in case the pointers i and j crossed.
1295 
1296  if (j < i) exit
1297 
1298  ! Swap the element i and j.
1299 
1300  tmp = arr(i)
1301  arr(i) = arr(j)
1302  arr(j) = tmp
1303  end do
1304 
1305  ! Swap the entries j and l+1. Remember that a equals
1306  ! arr(l+1).
1307 
1308  arr(l + 1) = arr(j)
1309  arr(j) = a
1310 
1311  ! Push pointers to larger subarray on stack,
1312  ! process smaller subarray immediately.
1313 
1314  jstack = jstack + 2
1315  if (jstack > nstack) then
1316 
1317  ! Storage of the stack is too small. Reallocate.
1318 
1319  allocate (tmpstack(nstack), stat=ierr)
1320  if (ierr /= 0) &
1321  call terminate("qsortSortSubRangeType", &
1322  "Memory allocation error for tmpStack")
1323  tmpstack = stack
1324 
1325  ! Free the memory of stack, store the old value of nStack
1326  ! in tmp and increase nStack.
1327 
1328  deallocate (stack, stat=ierr)
1329  if (ierr /= 0) &
1330  call terminate("qsortSortSubRangeType", &
1331  "Deallocation error for stack")
1332  ii = nstack
1333  nstack = nstack + 100
1334 
1335  ! Allocate the memory for stack and copy the old values
1336  ! from tmpStack.
1337 
1338  allocate (stack(nstack), stat=ierr)
1339  if (ierr /= 0) &
1340  call terminate("qsortSortSubRangeType", &
1341  "Memory reallocation error for stack")
1342  stack(1:ii) = tmpstack(1:ii)
1343 
1344  ! And finally release the memory of tmpStack.
1345 
1346  deallocate (tmpstack, stat=ierr)
1347  if (ierr /= 0) &
1348  call terminate("qsortSortSubRangeType", &
1349  "Deallocation error for tmpStack")
1350  end if
1351 
1352  if ((r - i + 1) >= (j - l)) then
1353  stack(jstack) = r
1354  r = j - 1
1355  stack(jstack - 1) = j
1356  else
1357  stack(jstack) = j - 1
1358  stack(jstack - 1) = l
1359  l = j
1360  end if
1361 
1362  end if
1363  end do
1364 
1365  ! Release the memory of stack.
1366 
1367  deallocate (stack, stat=ierr)
1368  if (ierr /= 0) &
1369  call terminate("qsortSortSubRangeType", &
1370  "Deallocation error for stack")
1371 
1372  ! Check in debug mode whether the array is really sorted.
1373 
1374  if (debug) then
1375  do i = 1, (nn - 1)
1376  if (arr(i + 1) < arr(i)) &
1377  call terminate("qsortSortSubRangeType", &
1378  "Array is not sorted correctly")
1379  end do
1380  end if
1381 
1382  end subroutine qsortsortsubrangetype
1383 
1384  !
1385  ! Functions to define the operators <, <= and /=.
1386  ! Note that the comparison is only based on the integers.
1387  ! The real contains additional info, the maximum deviation,
1388  ! which is normally different even if the subfaces are
1389  ! identical.
1390  !
1391  logical function lessequalfourintplusrealtype(g1, g2)
1392  implicit none
1393  type(fourintplusrealtype), intent(in) :: g1, g2
1394 
1395  ! Compare the first element.
1396 
1397  if (g1%n1 < g2%n1) then
1399  return
1400  else if (g1%n1 > g2%n1) then
1402  return
1403  end if
1404 
1405  ! Compare the second element.
1406 
1407  if (g1%n2 < g2%n2) then
1409  return
1410  else if (g1%n2 > g2%n2) then
1412  return
1413  end if
1414 
1415  ! Compare the third element.
1416 
1417  if (g1%n3 < g2%n3) then
1419  return
1420  else if (g1%n3 > g2%n3) then
1422  return
1423  end if
1424 
1425  ! Compare the fourth element.
1426 
1427  if (g1%n4 < g2%n4) then
1429  return
1430  else if (g1%n4 > g2%n4) then
1432  return
1433  end if
1434 
1435  ! g1 equals g2. Return .true.
1436 
1438 
1439  end function lessequalfourintplusrealtype
1440 
1441  !===============================================================
1442 
1443  logical function lessfourintplusrealtype(g1, g2)
1444  implicit none
1445  type(fourintplusrealtype), intent(in) :: g1, g2
1446 
1447  ! Compare the first element.
1448 
1449  if (g1%n1 < g2%n1) then
1450  lessfourintplusrealtype = .true.
1451  return
1452  else if (g1%n1 > g2%n1) then
1453  lessfourintplusrealtype = .false.
1454  return
1455  end if
1456 
1457  ! Compare the second element.
1458 
1459  if (g1%n2 < g2%n2) then
1460  lessfourintplusrealtype = .true.
1461  return
1462  else if (g1%n2 > g2%n2) then
1463  lessfourintplusrealtype = .false.
1464  return
1465  end if
1466 
1467  ! Compare the third element.
1468 
1469  if (g1%n3 < g2%n3) then
1470  lessfourintplusrealtype = .true.
1471  return
1472  else if (g1%n3 > g2%n3) then
1473  lessfourintplusrealtype = .false.
1474  return
1475  end if
1476 
1477  ! Compare the fourth element.
1478 
1479  if (g1%n4 < g2%n4) then
1480  lessfourintplusrealtype = .true.
1481  return
1482  else if (g1%n4 > g2%n4) then
1483  lessfourintplusrealtype = .false.
1484  return
1485  end if
1486 
1487  ! g1 equals g2. Return .false.
1488 
1489  lessfourintplusrealtype = .false.
1490 
1491  end function lessfourintplusrealtype
1492 
1493  !===============================================================
1494 
1495  logical function notequalfourintplusrealtype(g1, g2)
1496  implicit none
1497  type(fourintplusrealtype), intent(in) :: g1, g2
1498 
1500  if (g1%n1 == g2%n1 .and. g1%n2 == g2%n2 .and. &
1501  g1%n3 == g2%n3 .and. g1%n4 == g2%n4) &
1502  notequalfourintplusrealtype = .false.
1503 
1504  end function notequalfourintplusrealtype
1505 
1506  ! ==================================================================
1507 
1508  subroutine sortbadentities(nEntities, entities, dist, sortDist)
1509  !
1510  ! sortBadEntities sorts the given number of entities in
1511  ! increasing order and gets rid of the multiple entries.
1512  !
1513  use constants
1514  implicit none
1515  !
1516  ! Subroutine arguments.
1517  !
1518  integer(kind=intType), intent(inout) :: nEntities
1519  integer(kind=intType), dimension(4, *), intent(inout) :: entities
1520  real(kind=realtype), dimension(*), intent(inout) :: dist
1521 
1522  logical, intent(in) :: sortDist
1523  !
1524  ! Local variables.
1525  !
1526  integer(kind=intType) :: nn, mm
1527 
1528  type(fourintplusrealtype), dimension(nEntities) :: tmp
1529 
1530  ! Return immediately if there are no entities to be sorted.
1531 
1532  if (nentities == 0) return
1533 
1534  ! Copy the info into tmp. If the distances must be sorted as
1535  ! well, copy the info. Otherwise simply put zero.
1536 
1537  do nn = 1, nentities
1538  tmp(nn)%n1 = entities(1, nn)
1539  tmp(nn)%n2 = entities(2, nn)
1540  tmp(nn)%n3 = entities(3, nn)
1541  tmp(nn)%n4 = entities(4, nn)
1542  if (sortdist) then
1543  tmp(nn)%dist = dist(nn)
1544  else
1545  tmp(nn)%dist = zero
1546  end if
1547  end do
1548 
1549  ! Sort tmp in increasing order.
1550 
1551  call qsortfourintplusrealtype(tmp, nentities)
1552 
1553  ! Get rid of the multiple entries. Note that the exceptional
1554  ! case of zero entities does not to be considered, because in
1555  ! that case this part of the subroutine is not executed.
1556  ! If multiple entries are present the distance is taken as
1557  ! the maximum of the two.
1558 
1559  mm = 1
1560  do nn = 2, nentities
1561  if (tmp(nn) /= tmp(mm)) then
1562  mm = mm + 1
1563  tmp(mm) = tmp(nn)
1564  else
1565  tmp(mm)%dist = max(tmp(mm)%dist, tmp(nn)%dist)
1566  end if
1567  end do
1568 
1569  ! Copy the data back info entities and dist. The latter
1570  ! only if the distances should be sorted as well.
1571 
1572  nentities = mm
1573 
1574  do nn = 1, nentities
1575  entities(1, nn) = tmp(nn)%n1
1576  entities(2, nn) = tmp(nn)%n2
1577  entities(3, nn) = tmp(nn)%n3
1578  entities(4, nn) = tmp(nn)%n4
1579  if (sortdist) dist(nn) = tmp(nn)%dist
1580  end do
1581 
1582  end subroutine sortbadentities
1583 
1584  ! ==================================================================
1585 
1586  subroutine qsortfourintplusrealtype(arr, nn)
1587  !
1588  ! qsortFourIntPlusRealType sorts the given number of halo's in
1589  ! increasing order based on the <= operator for this derived
1590  ! data type.
1591  !
1592  use constants
1593  use utils, only: terminate
1594  implicit none
1595  !
1596  ! Subroutine arguments.
1597  !
1598  integer(kind=intType), intent(in) :: nn
1599 
1600  type(fourintplusrealtype), dimension(*), intent(inout) :: arr
1601  !
1602  ! Local variables.
1603  !
1604  integer(kind=intType), parameter :: m = 7
1605 
1606  integer(kind=intType) :: nStack
1607  integer(kind=intType) :: i, j, k, r, l, jStack, ii
1608 
1609  integer :: ierr
1610 
1611  type(fourintplusrealtype) :: a, tmp
1612 
1613  integer(kind=intType), allocatable, dimension(:) :: stack
1614  integer(kind=intType), allocatable, dimension(:) :: tmpStack
1615 
1616  ! Allocate the memory for stack.
1617 
1618  nstack = 100
1619  allocate (stack(nstack), stat=ierr)
1620  if (ierr /= 0) &
1621  call terminate("qsortFourIntPlusRealType", &
1622  "Memory allocation failure for stack")
1623 
1624  ! Initialize the variables that control the sorting.
1625 
1626  jstack = 0
1627  l = 1
1628  r = nn
1629 
1630  ! Start of the algorithm
1631 
1632  do
1633 
1634  ! Check for the size of the subarray.
1635 
1636  if ((r - l) < m) then
1637 
1638  ! Perform insertion sort
1639 
1640  do j = l + 1, r
1641  a = arr(j)
1642  do i = (j - 1), l, -1
1643  if (arr(i) <= a) exit
1644  arr(i + 1) = arr(i)
1645  end do
1646  arr(i + 1) = a
1647  end do
1648 
1649  ! In case there are no more elements on the stack, exit from
1650  ! the outermost do-loop. Algorithm has finished.
1651 
1652  if (jstack == 0) exit
1653 
1654  ! Pop stack and begin a new round of partitioning.
1655 
1656  r = stack(jstack)
1657  l = stack(jstack - 1)
1658  jstack = jstack - 2
1659 
1660  else
1661 
1662  ! Subarray is larger than the threshold for a linear sort.
1663  ! Choose median of left, center and right elements as
1664  ! partitioning element a.
1665  ! Also rearrange so that (l) <= (l+1) <= (r).
1666 
1667  k = (l + r) / 2
1668  tmp = arr(k) ! Swap the elements
1669  arr(k) = arr(l + 1) ! k and l+1.
1670  arr(l + 1) = tmp
1671 
1672  if (arr(r) < arr(l)) then
1673  tmp = arr(l) ! Swap the elements
1674  arr(l) = arr(r) ! r and l.
1675  arr(r) = tmp
1676  end if
1677 
1678  if (arr(r) < arr(l + 1)) then
1679  tmp = arr(l + 1) ! Swap the elements
1680  arr(l + 1) = arr(r) ! r and l+1.
1681  arr(r) = tmp
1682  end if
1683 
1684  if (arr(l + 1) < arr(l)) then
1685  tmp = arr(l + 1) ! Swap the elements
1686  arr(l + 1) = arr(l) ! l and l+1.
1687  arr(l) = tmp
1688  end if
1689 
1690  ! Initialize the pointers for partitioning.
1691 
1692  i = l + 1
1693  j = r
1694  a = arr(l + 1)
1695 
1696  ! The innermost loop
1697 
1698  do
1699 
1700  ! Scan up to find element >= a.
1701  do
1702  i = i + 1
1703  if (a <= arr(i)) exit
1704  end do
1705 
1706  ! Scan down to find element <= a.
1707  do
1708  j = j - 1
1709  if (arr(j) <= a) exit
1710  end do
1711 
1712  ! Exit the loop in case the pointers i and j crossed.
1713 
1714  if (j < i) exit
1715 
1716  ! Swap the element i and j.
1717 
1718  tmp = arr(i)
1719  arr(i) = arr(j)
1720  arr(j) = tmp
1721  end do
1722 
1723  ! Swap the entries j and l+1. Remember that a equals
1724  ! arr(l+1).
1725 
1726  arr(l + 1) = arr(j)
1727  arr(j) = a
1728 
1729  ! Push pointers to larger subarray on stack,
1730  ! process smaller subarray immediately.
1731 
1732  jstack = jstack + 2
1733  if (jstack > nstack) then
1734 
1735  ! Storage of the stack is too small. Reallocate.
1736 
1737  allocate (tmpstack(nstack), stat=ierr)
1738  if (ierr /= 0) &
1739  call terminate("qsortFourIntPlusRealType", &
1740  "Memory allocation error for tmpStack")
1741  tmpstack = stack
1742 
1743  ! Free the memory of stack, store the old value of nStack
1744  ! in tmp and increase nStack.
1745 
1746  deallocate (stack, stat=ierr)
1747  if (ierr /= 0) &
1748  call terminate("qsortFourIntPlusRealType", &
1749  "Deallocation error for stack")
1750  ii = nstack
1751  nstack = nstack + 100
1752 
1753  ! Allocate the memory for stack and copy the old values
1754  ! from tmpStack.
1755 
1756  allocate (stack(nstack), stat=ierr)
1757  if (ierr /= 0) &
1758  call terminate("qsortFourIntPlusRealType", &
1759  "Memory reallocation error for stack")
1760  stack(1:ii) = tmpstack(1:ii)
1761 
1762  ! And finally release the memory of tmpStack.
1763 
1764  deallocate (tmpstack, stat=ierr)
1765  if (ierr /= 0) &
1766  call terminate("qsortFourIntPlusRealType", &
1767  "Deallocation error for tmpStack")
1768  end if
1769 
1770  if ((r - i + 1) >= (j - l)) then
1771  stack(jstack) = r
1772  r = j - 1
1773  stack(jstack - 1) = j
1774  else
1775  stack(jstack) = j - 1
1776  stack(jstack - 1) = l
1777  l = j
1778  end if
1779 
1780  end if
1781  end do
1782 
1783  ! Release the memory of stack.
1784 
1785  deallocate (stack, stat=ierr)
1786  if (ierr /= 0) &
1787  call terminate("qsortFourIntPlusRealType", &
1788  "Deallocation error for stack")
1789 
1790  ! Check in debug mode whether the array is really sorted.
1791 
1792  if (debug) then
1793  do i = 1, (nn - 1)
1794  if (arr(i + 1) < arr(i)) &
1795  call terminate("qsortFourIntPlusRealType", &
1796  "Array is not sorted correctly")
1797  end do
1798  end if
1799 
1800  end subroutine qsortfourintplusrealtype
1801 
1802 end module partitionmod
real(kind=realtype), parameter zero
Definition: constants.F90:71
integer(kind=inttype), parameter imax
Definition: constants.F90:293
integer(kind=inttype), parameter kmin
Definition: constants.F90:296
integer(kind=inttype), parameter jmax
Definition: constants.F90:295
integer(kind=inttype), parameter imin
Definition: constants.F90:292
integer(kind=inttype), parameter kmax
Definition: constants.F90:297
integer(kind=inttype), parameter jmin
Definition: constants.F90:294
integer(kind=inttype) ngridsread
logical function lessequalsubfacenonmatchtype(g1, g2)
subroutine qsortfourintplusrealtype(arr, nn)
subroutine sortrangessplitinfo(splitInfo)
logical function lessfourintplusrealtype(g1, g2)
logical function lessequalsubblocksofcgnstype(g1, g2)
logical function lesssubfacenonmatchtype(g1, g2)
subroutine qsortsubfacenonmatchtype(arr, nn)
character(len=maxstringlen), dimension(:), allocatable gridfiles
logical function notequalfourintplusrealtype(g1, g2)
logical function lessequalsortsubrangetype(g1, g2)
logical interpolspectral
subroutine qsortsubblocksofcgnstype(arr, nn)
logical function lesssortsubrangetype(g1, g2)
integer(kind=inttype), dimension(:), allocatable part
integer, dimension(:), allocatable fileids
logical function lessequalfourintplusrealtype(g1, g2)
real, dimension(2) ubvec
logical function lesssubblocksofcgnstype(g1, g2)
integer(kind=inttype) nblocks
subroutine qsortsortsubrangetype(arr, nn)
subroutine sortbadentities(nEntities, entities, dist, sortDist)
type(distributionblocktype), dimension(:), allocatable blocks
Definition: utils.F90:1
subroutine terminate(routineName, errorMessage)
Definition: utils.F90:502