ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/md_code/neighborLists.F90
Revision: 284
Committed: Tue Feb 25 21:30:09 2003 UTC (21 years, 4 months ago) by chuckv
File size: 5897 byte(s)
Log Message:
Added neighbor list module that auto expands...

File Contents

# Content
1 !! Module neighborLists
2 !! Impliments verlet neighbor lists for force modules.
3 !! Automagically expands neighbor list if size too small
4 !! up to maxAllocations times. If after maxAllocations we try to
5 !! expand the neighbor list, we get an error message and quit.
6 !! @author Charles F. Vardeman II
7 !! @author Matthew Meineke
8 !! @author J. Daniel Gezelter
9 !! @version $Id: neighborLists.F90,v 1.1 2003-02-25 21:30:09 chuckv Exp $,
10
11 module neighborLists
12 use simulation
13 #ifdef IS_MPI
14 use mpiSimulation
15 #endif
16
17 implicit none
18 PRIVATE
19
20 !--------------MODULE VARIABLES---------------------->
21 !! Parameter for size > # of long range particles neighbor list
22 !! should be.
23 integer, parameter, :: listMultiplier = 80
24 !! Maximum number of times we should reallocate neighbor list.
25 integer, parameter, :: maxAllocations = 5
26 !! Number of times we have allocated the neighbor list.
27 integer, save :: nAllocations = 0
28 !! Pointer array to location in list for atom i.
29 integer, dimension(:),public, pointer :: point => null()
30 !! Neighbor list for atom i.
31 integer, dimension(:),public, pointer :: list => null()
32 !! Position array of previous positions for check. Allocated first time
33 !! into save_neighborList.
34 real( kind = dp ),dimension(:,:), allocatable , save :: q0 = 0.0_dp
35 !! Current list size
36 integer, save :: listSize
37 !--------------MODULE ACCESS-------------------------->
38 public :: expandList
39 public :: check
40 public :: save_neighborList
41
42 contains
43
44
45 subroutine expandList(error)
46 integer, intent(out) :: error
47
48 integer :: alloc_error
49 integer :: oldSize = 0
50 integer :: newSize = 0
51 integer,dimension(:), pointer :: new_list => null()
52 error = 0
53
54
55 !! First time through we should allocate point and list.
56 !! If one is associated and one is not, something is wrong
57 !! and return a error.
58 #ifndef IS_MPI !!/Non MPI
59 if (.not. associated(point) .and. &
60 .not. associated(list) ) then
61 allocate(point(getNlocal()),stat=alloc_error)
62 if (alloc_error /= 0) then
63 error = -1
64 return
65 end if
66 allocate(list(listMultiplier * getNlocal()),stat=alloc_error)
67 if (alloc_error /= 0) then
68 error = -1
69 return
70 end if
71 nAllocations = nAllocations + 1
72 else
73 error = -1
74 return
75 end if
76 #else !!// MPI
77 if (.not. associated(point) .and. &
78 .not. associated(list) ) then
79 allocate(point(getNRow()),stat=alloc_error)
80 if (alloc_error /= 0) then
81 error = -1
82 return
83 end if
84 allocate(list(listMultiplier * getNCol()),stat=alloc_error)
85 if (alloc_error /= 0) then
86 error = -1
87 return
88 end if
89 nAllocations = nAllocations + 1
90 return
91 else
92 error = -1
93 return
94 end if
95 #endif !! //MPI
96
97 ! Expand the neighbor list
98
99 ! Check to see if we have exceeded the maximum number of allocations.
100 if (nAllocations > maxAllocations) then
101 error = -1
102 return
103 else !! Expand the list.
104 oldSize = size(list)
105
106 #ifndef IS_MPI !!Not MPI
107 newSize = listMultiplier * getNlocal() + oldSize
108 allocate(newList(newSize), stat=alloc_error)
109 if (alloc_error /= 0) then
110 error = -1
111 return
112 end if
113 #else !! IS_MPI
114 newSize = listMultiplier * getNCol() + oldSize
115 allocate(newList(newSize), stat = alloc_error)
116 if (alloc_error /= 0) then
117 error = -1
118 return
119 end if
120 #endif !! IS_MPI
121 !! Copy old list to new list
122 do i = 1, oldSize
123 newList(i) = list(i)
124 end do
125 !! Free old list
126 deallocate(list,stat=alloc_error)
127 if (alloc_error /= 0) then
128 error = -1
129 return
130 end if
131
132 !! Point list at new list
133 list => newList
134 end if
135
136 listSize = size(list)
137 end subroutine expandList
138
139 !! checks to see if any long range particle has moved
140 !! through the neighbor list skin thickness.
141 subroutine check(q,update_nlist)
142 real( kind = dp ), dimension(:,:) :: q
143 integer :: i
144 real( kind = DP ) :: dispmx
145 logical, intent(out) :: update_nlist
146 real( kind = DP ) :: dispmx_tmp
147 real( kind = dp ) :: skin_thickness
148 integer :: nlocal
149
150 nlocal = getNlocal()
151 skin_thickness = getRcut() - getRlist()
152 dispmx = 0.0E0_DP
153 !! calculate the largest displacement of any atom in any direction
154
155
156
157 #ifdef MPI
158
159 !! If we have changed the particle idents, then we need to update
160 if (.not. allocated(q0) .or. &
161 size(q0) /= nlocal) then
162 update_nlist = .true.
163 return
164 end if
165
166 dispmx_tmp = 0.0E0_DP
167 do i = 1, nlocal
168 dispmx_tmp = max( abs ( q(1,i) - q0(1,i) ), dispmx )
169 dispmx_tmp = max( abs ( q(2,i) - q0(2,i) ), dispmx )
170 dispmx_tmp = max( abs ( q(3,i) - q0(3,i) ), dispmx )
171 end do
172 call mpi_allreduce(dispmx_tmp,dispmx,1,mpi_double_precision, &
173 mpi_max,mpi_comm_world,mpi_err)
174 #else
175
176 do i = 1, nlocal
177 dispmx = max( abs ( q(1,i) - q0(1,i) ), dispmx )
178 dispmx = max( abs ( q(2,i) - q0(2,i) ), dispmx )
179 dispmx = max( abs ( q(3,i) - q0(3,i) ), dispmx )
180 end do
181 #endif
182
183 !! a conservative test of list skin crossings
184 dispmx = 2.0E0_DP * sqrt (3.0E0_DP * dispmx * dispmx)
185
186 update_nlist = (dispmx.gt.(skin_thickness))
187
188 end subroutine check
189
190
191 !! Saves neighbor list for comparison in check.
192 !! Save_neighborList will work even if the number of
193 !! local atoms has changed.
194 subroutine save_neighborList(q)
195 real(kind = dp ), dimension(:,:), intent(in) :: q
196 integer :: list_size
197
198 !! get size of list
199 list_size = size(q)
200
201 if (.not. allocated(q0)) then
202 allocate(q0(3,list_size))
203 else if( list_size > size(q0)) then
204 deallocate(q0)
205 allocate(q0(3,list_size))
206 endif
207 q0 = q
208 end subroutine save_neighborList
209
210
211 end module neighborLists