-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathArrayUtils.f90
116 lines (94 loc) · 2.84 KB
/
ArrayUtils.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
module ArrayUtils
use MiscUtils
use MpiUtils
implicit none
INTERFACE Reallocate
module procedure Realloc_R, Realloc_D, Realloc_I
END INTERFACE Reallocate
contains
subroutine realloc_R(arr, new_size, keep)
real, allocatable, intent(inout) :: arr(:)
integer, intent(in) :: new_size
logical, intent(in), optional :: keep
integer sz
real, allocatable :: tmp(:)
if (.not. allocated(arr)) then
allocate(arr(new_size))
return
end if
if (LBOUND(arr,1)/=1) call MpiStop('Realloc only works on arrays starting at 1')
if (new_size/=size(arr)) then
allocate(tmp(new_size))
if (DefaultTrue(keep)) then
sz = min(new_size, size(arr))
tmp(:sz) = arr(:sz)
end if
call move_alloc(tmp, arr)
end if
end subroutine realloc_R
subroutine realloc_D(arr, new_size, keep)
double precision, allocatable, intent(inout) :: arr(:)
integer, intent(in) :: new_size
logical, intent(in), optional :: keep
integer sz
double precision, allocatable :: tmp(:)
if (.not. allocated(arr)) then
allocate(arr(new_size))
return
end if
if (LBOUND(arr,1)/=1) call MpiStop('Realloc only works on arrays starting at 1')
if (new_size/=size(arr)) then
allocate(tmp(new_size))
if (DefaultTrue(keep)) then
sz = min(new_size, size(arr))
tmp(:sz) = arr(:sz)
end if
call move_alloc(tmp, arr)
end if
end subroutine realloc_D
subroutine realloc_I(arr, new_size, keep)
integer, allocatable, intent(inout) :: arr(:)
integer, intent(in) :: new_size
logical, intent(in), optional :: keep
integer sz
integer, allocatable :: tmp(:)
if (.not. allocated(arr)) then
allocate(arr(new_size))
return
end if
if (LBOUND(arr,1)/=1) call MpiStop('Realloc only works on arrays starting at 1')
if (new_size/=size(arr)) then
allocate(tmp(new_size))
if (DefaultTrue(keep)) then
sz = min(new_size, size(arr))
tmp(:sz) = arr(:sz)
end if
call move_alloc(tmp, arr)
end if
end subroutine realloc_I
function IndexOf(aval,arr, n)
integer, intent(in) :: n, arr(n), aval
integer IndexOf, i
do i=1,n
if (arr(i)==aval) then
IndexOf= i
return
end if
end do
IndexOf = 0
end function IndexOf
function MaxIndex(arr, n)
integer, intent(in) :: n
real, intent(in) :: arr(n)
integer locs(1:1), MaxIndex
locs = maxloc(arr(1:n))
MaxIndex = locs(1)
end function MaxIndex
function MinIndex(arr, n)
integer, intent(in) :: n
real, intent(in) :: arr(n)
integer locs(1:1), MinIndex
locs = minloc(arr(1:n))
MinIndex = locs(1)
end function MinIndex
end module ArrayUtils