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
|
module sectors
use globals
implicit none
contains
subroutine ONETO2(id, box_size, x, y)
implicit none
integer, intent(in) :: id
integer, intent(in) :: box_size
integer, intent(out) :: x, y
y = id / box_size
x = mod(id, box_size)
end subroutine ONETO2
function TWOtoONE(x, y, box_size) result(id)
implicit none
integer, intent(in) :: x, y, box_size
integer :: id
id = y * box_size + x
end function TWOtoONE
function get_neighbour_ids(p, N) result (neighbours)
integer, intent(in) :: p !> The sequential position
integer, intent(in) :: N !> The grid size (i.e., NxN sectors)
integer, allocatable, dimension(:) :: neighbours !> The list of neighbours
integer :: i,j,k
integer :: x_cell, y_cell, x_test, y_test
integer :: max_list(9)
!> Don't save the values between calls
k = 1
max_list = -1
call ONETO2(p,N,x_cell,y_cell)
max_list(k) = p
!print *, max_list
!> Start by just getting all of the neighbours
do i = -1,1
do j = -1,1
if(i == 0 .and. j == 0) cycle !> Skip the cell itself
!> The "test" coordinate
x_test = x_cell + i
y_test = y_cell + j
!> If the coordinates are real (within the expected range), add them to the list:
if((x_test .ge. 0 .and. x_test .lt. N) .and. (y_test .ge. 0 .and. y_test .lt. N)) then
!> Increment the number of correct coordinates
k = k + 1
!> Flip a zero to the new coordinate in the max list
max_list(k) = TWOtoONE(x_test, y_test, N)
end if
end do
end do
!> Return a vector of all non-zero elements
neighbours = pack(max_list, max_list>= 0.0)
end function get_neighbour_ids
end module sectors
|