1 |
gezelter |
246 |
!! |
2 |
|
|
!! Copyright (c) 2005 The University of Notre Dame. All Rights Reserved. |
3 |
|
|
!! |
4 |
|
|
!! The University of Notre Dame grants you ("Licensee") a |
5 |
|
|
!! non-exclusive, royalty free, license to use, modify and |
6 |
|
|
!! redistribute this software in source and binary code form, provided |
7 |
|
|
!! that the following conditions are met: |
8 |
|
|
!! |
9 |
|
|
!! 1. Acknowledgement of the program authors must be made in any |
10 |
|
|
!! publication of scientific results based in part on use of the |
11 |
|
|
!! program. An acceptable form of acknowledgement is citation of |
12 |
|
|
!! the article in which the program was described (Matthew |
13 |
|
|
!! A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher |
14 |
|
|
!! J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented |
15 |
|
|
!! Parallel Simulation Engine for Molecular Dynamics," |
16 |
|
|
!! J. Comput. Chem. 26, pp. 252-271 (2005)) |
17 |
|
|
!! |
18 |
|
|
!! 2. Redistributions of source code must retain the above copyright |
19 |
|
|
!! notice, this list of conditions and the following disclaimer. |
20 |
|
|
!! |
21 |
|
|
!! 3. Redistributions in binary form must reproduce the above copyright |
22 |
|
|
!! notice, this list of conditions and the following disclaimer in the |
23 |
|
|
!! documentation and/or other materials provided with the |
24 |
|
|
!! distribution. |
25 |
|
|
!! |
26 |
|
|
!! This software is provided "AS IS," without a warranty of any |
27 |
|
|
!! kind. All express or implied conditions, representations and |
28 |
|
|
!! warranties, including any implied warranty of merchantability, |
29 |
|
|
!! fitness for a particular purpose or non-infringement, are hereby |
30 |
|
|
!! excluded. The University of Notre Dame and its licensors shall not |
31 |
|
|
!! be liable for any damages suffered by licensee as a result of |
32 |
|
|
!! using, modifying or distributing the software or its |
33 |
|
|
!! derivatives. In no event will the University of Notre Dame or its |
34 |
|
|
!! licensors be liable for any lost revenue, profit or data, or for |
35 |
|
|
!! direct, indirect, special, consequential, incidental or punitive |
36 |
|
|
!! damages, however caused and regardless of the theory of liability, |
37 |
|
|
!! arising out of the use of or inability to use software, even if the |
38 |
|
|
!! University of Notre Dame has been advised of the possibility of |
39 |
|
|
!! such damages. |
40 |
|
|
!! |
41 |
|
|
|
42 |
gezelter |
2 |
! vector_class.F90 |
43 |
|
|
!! Module Vector_class |
44 |
|
|
!! Fortran 95 Vector class module. Similar to java.util vector class. |
45 |
|
|
!! |
46 |
|
|
!! The Vector class implements a growable array of objects. Like an array, |
47 |
|
|
!! it contains components that can be accessed using an integer index. |
48 |
|
|
!! However, the size of a Vector can grow as needed to accommodate |
49 |
|
|
!! adding and removing items after the Vector has been created. |
50 |
|
|
!! Each vector tries to optimize storage management by maintaining a |
51 |
|
|
!! capacity and a capacityIncrement. The capacity is always at least as |
52 |
|
|
!! large as the vector size; |
53 |
|
|
!! it is usually larger because as components are added to the vector, |
54 |
|
|
!! the vector's storage increases in chunks the size of capacityIncrement. |
55 |
|
|
!! An application can increase the capacity of a vector before inserting a |
56 |
|
|
!! large number of components; this reduces the amount of incremental |
57 |
|
|
!! reallocation. |
58 |
|
|
!! |
59 |
|
|
!! |
60 |
|
|
!! @author J. Daniel Gezelter |
61 |
|
|
!! @author Charles F. Vardeman II |
62 |
|
|
!! @author Matthew Meineke |
63 |
gezelter |
246 |
!! @version $Id: vector_class.F90,v 1.2 2005-01-12 22:41:39 gezelter Exp $, $Date: 2005-01-12 22:41:39 $, $Name: not supported by cvs2svn $, $Revision: 1.2 $ |
64 |
gezelter |
2 |
|
65 |
|
|
module Vector_class |
66 |
|
|
|
67 |
|
|
implicit NONE |
68 |
|
|
PRIVATE |
69 |
|
|
|
70 |
|
|
public :: initialize |
71 |
|
|
public :: getSize |
72 |
|
|
public :: getElementAt |
73 |
|
|
public :: getPropertyListSize |
74 |
|
|
public :: getPropertyNameAt |
75 |
|
|
public :: addElement |
76 |
|
|
public :: setElementProperty |
77 |
|
|
public :: getElementProperty |
78 |
|
|
public :: getMatchingElementList |
79 |
|
|
public :: getFirstMatchingElement |
80 |
|
|
|
81 |
|
|
integer, parameter :: logical_data_type = 1 |
82 |
|
|
integer, parameter :: integer_data_type = 2 |
83 |
|
|
integer, parameter :: real_data_type = 3 |
84 |
|
|
|
85 |
|
|
!! |
86 |
|
|
type, public :: Vector |
87 |
|
|
PRIVATE |
88 |
|
|
integer :: initialCapacity = 10 |
89 |
|
|
integer :: capacityIncrement = 0 |
90 |
|
|
integer :: elementCount = 0 |
91 |
|
|
|
92 |
|
|
integer :: initialProperties = 5 |
93 |
|
|
integer :: PropertyIncrement = 0 |
94 |
|
|
integer :: propertyCount = 0 |
95 |
|
|
|
96 |
|
|
integer, pointer :: ElementData(:) => null() |
97 |
|
|
character(len=100), pointer :: PropertyDescriptions(:) => null() |
98 |
|
|
integer, pointer :: PropertyDataType(:) => null() |
99 |
|
|
real(kind = 8), pointer :: realElementProperties(:,:) => null() |
100 |
|
|
integer, pointer :: integerElementProperties(:,:) => null() |
101 |
|
|
logical, pointer :: logicalElementProperties(:,:) => null() |
102 |
|
|
end type Vector |
103 |
|
|
|
104 |
|
|
!! Initialize vector |
105 |
|
|
interface initialize |
106 |
|
|
module procedure initialize_0i |
107 |
|
|
module procedure initialize_1i |
108 |
|
|
module procedure initialize_2i |
109 |
|
|
module procedure initialize_3i |
110 |
|
|
module procedure initialize_4i |
111 |
|
|
end interface |
112 |
|
|
|
113 |
|
|
interface setElementProperty |
114 |
|
|
module procedure setElementPropertyReal |
115 |
|
|
module procedure setElementPropertyInt |
116 |
|
|
module procedure setElementPropertyLogical |
117 |
|
|
end interface |
118 |
|
|
|
119 |
|
|
interface getElementProperty |
120 |
|
|
module procedure getElementPropertyReal |
121 |
|
|
module procedure getElementPropertyInt |
122 |
|
|
module procedure getElementPropertyLogical |
123 |
|
|
end interface |
124 |
|
|
|
125 |
|
|
interface getMatchingElementList |
126 |
|
|
module procedure getMatchingElementList1i |
127 |
|
|
module procedure getMatchingElementList2i |
128 |
|
|
module procedure getMatchingElementList1l |
129 |
|
|
module procedure getMatchingElementList2l |
130 |
|
|
end interface |
131 |
|
|
|
132 |
|
|
interface getFirstMatchingElement |
133 |
|
|
module procedure getFirstMatchingElement1i |
134 |
|
|
module procedure getFirstMatchingElement2i |
135 |
|
|
module procedure getFirstMatchingElement1l |
136 |
|
|
module procedure getFirstMatchingElement2l |
137 |
|
|
end interface |
138 |
|
|
contains |
139 |
|
|
|
140 |
|
|
function getSize(this) result (ne) |
141 |
|
|
type(Vector), pointer :: this |
142 |
|
|
integer :: ne |
143 |
|
|
ne = this%elementCount |
144 |
|
|
end function getSize |
145 |
|
|
|
146 |
|
|
function getElementAt(this, loc) result (id) |
147 |
|
|
type(Vector), pointer :: this |
148 |
|
|
integer, intent(in) :: loc |
149 |
|
|
integer :: id |
150 |
|
|
id = this%ElementData(loc) |
151 |
|
|
end function getElementAt |
152 |
|
|
|
153 |
|
|
function getPropertyListSize(this) result (np) |
154 |
|
|
type(Vector), pointer :: this |
155 |
|
|
integer :: np |
156 |
|
|
np = this%propertyCount |
157 |
|
|
end function getPropertyListSize |
158 |
|
|
|
159 |
|
|
function getPropertyNameAt(this, loc) result (pn) |
160 |
|
|
type(Vector), pointer :: this |
161 |
|
|
integer, intent(in) :: loc |
162 |
|
|
character(len=len(this%PropertyDescriptions)) :: pn |
163 |
|
|
pn = this%PropertyDescriptions(loc) |
164 |
|
|
end function getPropertyNameAt |
165 |
|
|
|
166 |
|
|
function getFirstMatchingElement1i(this, MatchName, MatchValue) result (id) |
167 |
|
|
type(Vector), pointer :: this |
168 |
|
|
character(len=*), intent(in) :: MatchName |
169 |
|
|
integer, intent(in) :: MatchValue |
170 |
|
|
integer :: id |
171 |
|
|
integer :: i, j |
172 |
|
|
|
173 |
|
|
id = 0 |
174 |
|
|
|
175 |
|
|
do i = 1, this%propertyCount |
176 |
|
|
if (this%PropertyDescriptions(i) == MatchName) then |
177 |
|
|
do j = 1, this%elementCount |
178 |
|
|
if (this%integerElementProperties(j, i) == MatchValue) then |
179 |
|
|
id = j |
180 |
|
|
return |
181 |
|
|
endif |
182 |
|
|
enddo |
183 |
|
|
endif |
184 |
|
|
enddo |
185 |
|
|
return |
186 |
|
|
end function getFirstMatchingElement1i |
187 |
|
|
|
188 |
|
|
function getFirstMatchingElement2i(this, MatchName1, MatchValue1, & |
189 |
|
|
MatchName2, MatchValue2) result (id) |
190 |
|
|
type(Vector), pointer :: this |
191 |
|
|
character(len=*), intent(in) :: MatchName1, MatchName2 |
192 |
|
|
integer, intent(in) :: MatchValue1, MatchValue2 |
193 |
|
|
integer :: id |
194 |
|
|
integer :: i, j, MatchID1, MatchID2 |
195 |
|
|
logical :: found1 = .false. |
196 |
|
|
logical :: found2 = .false. |
197 |
|
|
|
198 |
|
|
id = 0 |
199 |
|
|
! first figure out which properties we are using to do the match: |
200 |
|
|
|
201 |
|
|
do i = 1, this%propertyCount |
202 |
|
|
if (this%PropertyDescriptions(i) == MatchName1) then |
203 |
|
|
MatchID1 = i |
204 |
|
|
found1 = .true. |
205 |
|
|
endif |
206 |
|
|
if (this%PropertyDescriptions(i) == MatchName2) then |
207 |
|
|
MatchID2 = i |
208 |
|
|
found2 = .true. |
209 |
|
|
endif |
210 |
|
|
|
211 |
|
|
if (found1.and.found2) then |
212 |
|
|
do j = 1, this%elementCount |
213 |
|
|
if ((this%integerElementProperties(j, MatchID1) == MatchValue1) & |
214 |
|
|
.and. & |
215 |
|
|
(this%integerElementProperties(j, MatchID2) ==MatchValue2)) & |
216 |
|
|
then |
217 |
|
|
id = j |
218 |
|
|
return |
219 |
|
|
endif |
220 |
|
|
enddo |
221 |
|
|
endif |
222 |
|
|
end do |
223 |
|
|
|
224 |
|
|
return |
225 |
|
|
end function getFirstMatchingElement2i |
226 |
|
|
|
227 |
|
|
function getFirstMatchingElement1l(this, MatchName, MatchValue) result (id) |
228 |
|
|
type(Vector), pointer :: this |
229 |
|
|
character(len=*), intent(in) :: MatchName |
230 |
|
|
logical, intent(in) :: MatchValue |
231 |
|
|
integer :: id |
232 |
|
|
integer :: i, j |
233 |
|
|
|
234 |
|
|
id = 0 |
235 |
|
|
|
236 |
|
|
do i = 1, this%propertyCount |
237 |
|
|
if (this%PropertyDescriptions(i) == MatchName) then |
238 |
|
|
do j = 1, this%elementCount |
239 |
|
|
if (this%logicalElementProperties(j, i) .eqv. MatchValue) then |
240 |
|
|
id = j |
241 |
|
|
return |
242 |
|
|
endif |
243 |
|
|
enddo |
244 |
|
|
endif |
245 |
|
|
enddo |
246 |
|
|
return |
247 |
|
|
end function getFirstMatchingElement1l |
248 |
|
|
|
249 |
|
|
function getFirstMatchingElement2l(this, MatchName1, MatchValue1, & |
250 |
|
|
MatchName2, MatchValue2) result (id) |
251 |
|
|
type(Vector), pointer :: this |
252 |
|
|
character(len=*), intent(in) :: MatchName1, MatchName2 |
253 |
|
|
logical, intent(in) :: MatchValue1, MatchValue2 |
254 |
|
|
integer :: id |
255 |
|
|
integer :: i, j, MatchID1, MatchID2 |
256 |
|
|
logical :: found1 = .false. |
257 |
|
|
logical :: found2 = .false. |
258 |
|
|
|
259 |
|
|
id = 0 |
260 |
|
|
! first figure out which properties we are using to do the match: |
261 |
|
|
|
262 |
|
|
do i = 1, this%propertyCount |
263 |
|
|
if (this%PropertyDescriptions(i) == MatchName1) then |
264 |
|
|
MatchID1 = i |
265 |
|
|
found1 = .true. |
266 |
|
|
endif |
267 |
|
|
if (this%PropertyDescriptions(i) == MatchName2) then |
268 |
|
|
MatchID2 = i |
269 |
|
|
found2 = .true. |
270 |
|
|
endif |
271 |
|
|
|
272 |
|
|
if (found1.and.found2) then |
273 |
|
|
do j = 1, this%elementCount |
274 |
|
|
if ((this%logicalElementProperties(j, MatchID1).eqv.MatchValue1) & |
275 |
|
|
.and. & |
276 |
|
|
(this%logicalElementProperties(j, MatchID2).eqv.MatchValue2)) & |
277 |
|
|
then |
278 |
|
|
id = j |
279 |
|
|
return |
280 |
|
|
endif |
281 |
|
|
enddo |
282 |
|
|
endif |
283 |
|
|
end do |
284 |
|
|
|
285 |
|
|
return |
286 |
|
|
end function getFirstMatchingElement2l |
287 |
|
|
|
288 |
|
|
subroutine getMatchingElementList1i(this, MatchName, MatchValue, & |
289 |
|
|
nMatches, MatchList) |
290 |
|
|
type(Vector), pointer :: this |
291 |
|
|
character(len=*), intent(in) :: MatchName |
292 |
|
|
integer, intent(in) :: MatchValue |
293 |
|
|
integer, intent(out) :: nMatches |
294 |
|
|
integer, pointer :: MatchList(:) |
295 |
|
|
integer :: i |
296 |
|
|
|
297 |
|
|
! first figure out which property we are using to do the match: |
298 |
|
|
|
299 |
|
|
do i = 1, this%propertyCount |
300 |
|
|
if (this%PropertyDescriptions(i) == MatchName) then |
301 |
|
|
call getAllMatches1i(this, i, MatchValue, nMatches, MatchList) |
302 |
|
|
return |
303 |
|
|
endif |
304 |
|
|
enddo |
305 |
|
|
return |
306 |
|
|
end subroutine getMatchingElementList1i |
307 |
|
|
|
308 |
|
|
subroutine getMatchingElementList2i(this, MatchName1, MatchValue1, & |
309 |
|
|
MatchName2, MatchValue2, nMatches, MatchList) |
310 |
|
|
type(Vector), pointer :: this |
311 |
|
|
character(len=*), intent(in) :: MatchName1, MatchName2 |
312 |
|
|
integer, intent(in) :: MatchValue1, MatchValue2 |
313 |
|
|
integer, intent(out) :: nMatches |
314 |
|
|
integer, pointer :: MatchList(:) |
315 |
|
|
integer :: i, MatchID1, MatchID2 |
316 |
|
|
logical :: found1 = .false. |
317 |
|
|
logical :: found2 = .false. |
318 |
|
|
|
319 |
|
|
! first figure out which properties we are using to do the match: |
320 |
|
|
|
321 |
|
|
do i = 1, this%propertyCount |
322 |
|
|
if (this%PropertyDescriptions(i) == MatchName1) then |
323 |
|
|
MatchID1 = i |
324 |
|
|
found1 = .true. |
325 |
|
|
endif |
326 |
|
|
if (this%PropertyDescriptions(i) == MatchName2) then |
327 |
|
|
MatchID2 = i |
328 |
|
|
found2 = .true. |
329 |
|
|
endif |
330 |
|
|
|
331 |
|
|
if (found1.and.found2) then |
332 |
|
|
call getAllMatches2i(this, MatchID1, MatchValue1, & |
333 |
|
|
MatchID2, MatchValue2, nMatches, MatchList) |
334 |
|
|
return |
335 |
|
|
endif |
336 |
|
|
enddo |
337 |
|
|
return |
338 |
|
|
end subroutine getMatchingElementList2i |
339 |
|
|
|
340 |
|
|
subroutine getMatchingElementList1l(this, MatchName, MatchValue, & |
341 |
|
|
nMatches, MatchList) |
342 |
|
|
type(Vector), pointer :: this |
343 |
|
|
character(len=*), intent(in) :: MatchName |
344 |
|
|
logical, intent(in) :: MatchValue |
345 |
|
|
integer, intent(out) :: nMatches |
346 |
|
|
integer, pointer :: MatchList(:) |
347 |
|
|
integer :: i |
348 |
|
|
|
349 |
|
|
! first figure out which property we are using to do the match: |
350 |
|
|
|
351 |
|
|
do i = 1, this%propertyCount |
352 |
|
|
if (this%PropertyDescriptions(i) == MatchName) then |
353 |
|
|
call getAllMatches1l(this, i, MatchValue, nMatches, MatchList) |
354 |
|
|
return |
355 |
|
|
endif |
356 |
|
|
enddo |
357 |
|
|
return |
358 |
|
|
end subroutine getMatchingElementList1l |
359 |
|
|
|
360 |
|
|
subroutine getMatchingElementList2l(this, MatchName1, MatchValue1, & |
361 |
|
|
MatchName2, MatchValue2, nMatches, MatchList) |
362 |
|
|
type(Vector), pointer :: this |
363 |
|
|
character(len=*), intent(in) :: MatchName1, MatchName2 |
364 |
|
|
logical, intent(in) :: MatchValue1, MatchValue2 |
365 |
|
|
integer, intent(out) :: nMatches |
366 |
|
|
integer, pointer :: MatchList(:) |
367 |
|
|
integer :: i, MatchID1, MatchID2 |
368 |
|
|
logical :: found1 = .false. |
369 |
|
|
logical :: found2 = .false. |
370 |
|
|
|
371 |
|
|
! first figure out which properties we are using to do the match: |
372 |
|
|
|
373 |
|
|
do i = 1, this%propertyCount |
374 |
|
|
if (this%PropertyDescriptions(i) == MatchName1) then |
375 |
|
|
MatchID1 = i |
376 |
|
|
found1 = .true. |
377 |
|
|
endif |
378 |
|
|
if (this%PropertyDescriptions(i) == MatchName2) then |
379 |
|
|
MatchID2 = i |
380 |
|
|
found2 = .true. |
381 |
|
|
endif |
382 |
|
|
|
383 |
|
|
if (found1.and.found2) then |
384 |
|
|
call getAllMatches2l(this, MatchID1, MatchValue1, & |
385 |
|
|
MatchID2, MatchValue2, nMatches, MatchList) |
386 |
|
|
return |
387 |
|
|
endif |
388 |
|
|
enddo |
389 |
|
|
return |
390 |
|
|
end subroutine getMatchingElementList2l |
391 |
|
|
|
392 |
|
|
subroutine getAllMatches1i(this, MatchID, MatchValue, nMatches, MatchList) |
393 |
|
|
type(Vector), pointer :: this |
394 |
|
|
integer, intent(in) :: MatchID |
395 |
|
|
integer, intent(in) :: MatchValue |
396 |
|
|
integer, pointer :: MatchList(:) |
397 |
|
|
integer, allocatable :: MatchListTemp(:) |
398 |
|
|
integer, intent(out) :: nMatches |
399 |
|
|
integer :: error, i |
400 |
|
|
|
401 |
|
|
if(associated(MatchList)) deallocate(MatchList) |
402 |
|
|
MatchList => null() |
403 |
|
|
|
404 |
|
|
allocate(MatchListTemp(this%elementCount), stat=error) |
405 |
|
|
if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!' |
406 |
|
|
|
407 |
|
|
nMatches = 0 |
408 |
|
|
|
409 |
|
|
do i = 1, this%elementCount |
410 |
|
|
if (this%integerElementProperties(i, MatchID) == MatchValue) then |
411 |
|
|
nMatches = nMatches + 1 |
412 |
|
|
MatchListTemp(nMatches) = i |
413 |
|
|
endif |
414 |
|
|
enddo |
415 |
|
|
|
416 |
|
|
|
417 |
|
|
if (nMatches .ne. 0) then |
418 |
|
|
allocate(MatchList(nMatches), stat=error) |
419 |
|
|
if (error.ne.0) write(*, *) 'Could not allocate MatchList!' |
420 |
|
|
do i = 1, nMatches |
421 |
|
|
MatchList(i) = MatchListTemp(i) |
422 |
|
|
enddo |
423 |
|
|
endif |
424 |
|
|
|
425 |
|
|
deallocate(MatchListTemp) |
426 |
|
|
|
427 |
|
|
|
428 |
|
|
end subroutine getAllMatches1i |
429 |
|
|
|
430 |
|
|
subroutine getAllMatches2i(this, MatchID1, MatchValue1, & |
431 |
|
|
MatchID2, MatchValue2, nMatches, MatchList) |
432 |
|
|
type(Vector), pointer :: this |
433 |
|
|
integer, intent(in) :: MatchID1, MatchID2 |
434 |
|
|
integer, intent(in) :: MatchValue1, MatchValue2 |
435 |
|
|
integer, pointer :: MatchList(:) |
436 |
|
|
integer, allocatable :: MatchListTemp(:) |
437 |
|
|
integer, intent(out) :: nMatches |
438 |
|
|
integer :: error, i |
439 |
|
|
|
440 |
|
|
if(associated(MatchList)) deallocate(MatchList) |
441 |
|
|
MatchList => null() |
442 |
|
|
|
443 |
|
|
allocate(MatchListTemp(this%elementCount), stat=error) |
444 |
|
|
if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!' |
445 |
|
|
|
446 |
|
|
nMatches = 0 |
447 |
|
|
|
448 |
|
|
do i = 1, this%elementCount |
449 |
|
|
if ((this%integerElementProperties(i, MatchID1) == MatchValue1) .and. & |
450 |
|
|
(this%integerElementProperties(i, MatchID2) == MatchValue2)) then |
451 |
|
|
nMatches = nMatches + 1 |
452 |
|
|
MatchListTemp(nMatches) = i |
453 |
|
|
endif |
454 |
|
|
enddo |
455 |
|
|
|
456 |
|
|
if (nMatches .ne. 0) then |
457 |
|
|
allocate(MatchList(nMatches), stat=error) |
458 |
|
|
if (error.ne.0) write(*, *) 'Could not allocate MatchList!' |
459 |
|
|
do i = 1, nMatches |
460 |
|
|
MatchList(i) = MatchListTemp(i) |
461 |
|
|
enddo |
462 |
|
|
endif |
463 |
|
|
|
464 |
|
|
deallocate(MatchListTemp) |
465 |
|
|
|
466 |
|
|
end subroutine getAllMatches2i |
467 |
|
|
|
468 |
|
|
subroutine getAllMatches1l(this, MatchID, MatchValue, nMatches, MatchList) |
469 |
|
|
type(Vector), pointer :: this |
470 |
|
|
integer, intent(in) :: MatchID |
471 |
|
|
logical, intent(in) :: MatchValue |
472 |
|
|
integer, pointer :: MatchList(:) |
473 |
|
|
integer, allocatable :: MatchListTemp(:) |
474 |
|
|
integer, intent(out) :: nMatches |
475 |
|
|
integer :: error, i |
476 |
|
|
|
477 |
|
|
if(associated(MatchList)) deallocate(MatchList) |
478 |
|
|
MatchList => null() |
479 |
|
|
|
480 |
|
|
allocate(MatchListTemp(this%elementCount), stat=error) |
481 |
|
|
if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!' |
482 |
|
|
|
483 |
|
|
nMatches = 0 |
484 |
|
|
|
485 |
|
|
do i = 1, this%elementCount |
486 |
|
|
if (this%logicalElementProperties(i, MatchID).eqv.MatchValue) then |
487 |
|
|
nMatches = nMatches + 1 |
488 |
|
|
MatchListTemp(nMatches) = i |
489 |
|
|
endif |
490 |
|
|
enddo |
491 |
|
|
|
492 |
|
|
if (nMatches .ne. 0) then |
493 |
|
|
allocate(MatchList(nMatches), stat=error) |
494 |
|
|
if (error.ne.0) write(*, *) 'Could not allocate MatchList!' |
495 |
|
|
do i = 1, nMatches |
496 |
|
|
MatchList(i) = MatchListTemp(i) |
497 |
|
|
enddo |
498 |
|
|
endif |
499 |
|
|
|
500 |
|
|
deallocate(MatchListTemp) |
501 |
|
|
|
502 |
|
|
end subroutine getAllMatches1l |
503 |
|
|
|
504 |
|
|
subroutine getAllMatches2l(this, MatchID1, MatchValue1, & |
505 |
|
|
MatchID2, MatchValue2, nMatches, MatchList) |
506 |
|
|
type(Vector), pointer :: this |
507 |
|
|
integer, intent(in) :: MatchID1, MatchID2 |
508 |
|
|
logical, intent(in) :: MatchValue1, MatchValue2 |
509 |
|
|
integer, pointer :: MatchList(:) |
510 |
|
|
integer, allocatable :: MatchListTemp(:) |
511 |
|
|
integer, intent(out) :: nMatches |
512 |
|
|
integer :: error, i |
513 |
|
|
|
514 |
|
|
if(associated(MatchList)) deallocate(MatchList) |
515 |
|
|
MatchList => null() |
516 |
|
|
|
517 |
|
|
allocate(MatchListTemp(this%elementCount), stat=error) |
518 |
|
|
if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!' |
519 |
|
|
|
520 |
|
|
nMatches = 0 |
521 |
|
|
|
522 |
|
|
do i = 1, this%elementCount |
523 |
|
|
if ((this%logicalElementProperties(i, MatchID1).eqv.MatchValue1) .and. & |
524 |
|
|
(this%logicalElementProperties(i, MatchID2).eqv.MatchValue2)) then |
525 |
|
|
nMatches = nMatches + 1 |
526 |
|
|
MatchListTemp(nMatches) = i |
527 |
|
|
endif |
528 |
|
|
enddo |
529 |
|
|
|
530 |
|
|
if (nMatches .ne. 0) then |
531 |
|
|
allocate(MatchList(nMatches), stat=error) |
532 |
|
|
if (error.ne.0) write(*, *) 'Could not allocate MatchList!' |
533 |
|
|
do i = 1, nMatches |
534 |
|
|
MatchList(i) = MatchListTemp(i) |
535 |
|
|
enddo |
536 |
|
|
endif |
537 |
|
|
|
538 |
|
|
deallocate(MatchListTemp) |
539 |
|
|
|
540 |
|
|
end subroutine getAllMatches2l |
541 |
|
|
|
542 |
|
|
|
543 |
|
|
subroutine getElementPropertyReal(this, id, PropName, pv) |
544 |
|
|
type(Vector), pointer :: this |
545 |
|
|
integer :: id, whichprop |
546 |
|
|
character(len=*) :: PropName |
547 |
|
|
real( kind = 8 ) :: pv |
548 |
|
|
|
549 |
|
|
whichprop = getPropertyIndex(this, PropName) |
550 |
|
|
if (whichprop .eq. 0 ) then |
551 |
|
|
write(*,*) 'unknown property: ', PropName |
552 |
|
|
pv = 0.0 |
553 |
|
|
else |
554 |
|
|
if (this%PropertyDataType(whichprop) .ne. real_data_type) then |
555 |
|
|
write(*,*) 'Property: ', PropName, " is not real data type." |
556 |
|
|
pv = 0.0 |
557 |
|
|
else |
558 |
|
|
pv = this%realElementProperties(id, whichprop) |
559 |
|
|
endif |
560 |
|
|
endif |
561 |
|
|
end subroutine getElementPropertyReal |
562 |
|
|
|
563 |
|
|
subroutine getElementPropertyInt(this, id, PropName, pv) |
564 |
|
|
type(Vector), pointer :: this |
565 |
|
|
integer :: id, whichprop |
566 |
|
|
character(len=*) :: PropName |
567 |
|
|
integer :: pv |
568 |
|
|
|
569 |
|
|
whichprop = getPropertyIndex(this, PropName) |
570 |
|
|
if (whichprop .eq. 0 ) then |
571 |
|
|
write(*,*) 'unknown property! ', PropName |
572 |
|
|
pv = 0 |
573 |
|
|
else |
574 |
|
|
if (this%PropertyDataType(whichprop) .ne. integer_data_type) then |
575 |
|
|
write(*,*) 'Property! ', PropName, " is not integer data type." |
576 |
|
|
pv = 0 |
577 |
|
|
else |
578 |
|
|
pv = this%integerElementProperties(id, whichprop) |
579 |
|
|
endif |
580 |
|
|
endif |
581 |
|
|
end subroutine getElementPropertyInt |
582 |
|
|
|
583 |
|
|
subroutine getElementPropertyLogical(this, id, PropName, pv) |
584 |
|
|
type(Vector), pointer :: this |
585 |
|
|
integer :: id, whichprop |
586 |
|
|
character(len=*) :: PropName |
587 |
|
|
logical :: pv |
588 |
|
|
|
589 |
|
|
whichprop = getPropertyIndex(this, PropName) |
590 |
|
|
if (whichprop .eq. 0 ) then |
591 |
|
|
write(*,*) 'unknown property! ', PropName |
592 |
|
|
pv = .false. |
593 |
|
|
else |
594 |
|
|
if (this%PropertyDataType(whichprop) .ne. logical_data_type) then |
595 |
|
|
write(*,*) 'Property! ', PropName, " is not logical data type." |
596 |
|
|
pv = .false. |
597 |
|
|
else |
598 |
|
|
pv = this%logicalElementProperties(id, whichprop) |
599 |
|
|
endif |
600 |
|
|
endif |
601 |
|
|
end subroutine getElementPropertyLogical |
602 |
|
|
|
603 |
|
|
function getPropertyIndex(this, PropName) result (id) |
604 |
|
|
type(Vector), pointer :: this |
605 |
|
|
integer :: id, i |
606 |
|
|
character(len=*) :: PropName |
607 |
|
|
|
608 |
|
|
do i = 1, this%propertyCount |
609 |
|
|
if (this%PropertyDescriptions(i) == PropName) then |
610 |
|
|
id = i |
611 |
|
|
return |
612 |
|
|
endif |
613 |
|
|
enddo |
614 |
|
|
id = 0 |
615 |
|
|
end function getPropertyIndex |
616 |
|
|
|
617 |
|
|
subroutine ensureCapacityHelper(this, minCapacity, minPropCap) |
618 |
|
|
type(Vector), pointer :: this, that |
619 |
|
|
integer, intent(in) :: minCapacity, minPropCap |
620 |
|
|
integer :: oldCapacity, oldPropCap |
621 |
|
|
integer :: newCapacity, newPropCap |
622 |
|
|
logical :: resizeFlag |
623 |
|
|
|
624 |
|
|
resizeFlag = .false. |
625 |
|
|
|
626 |
|
|
! first time: allocate a new vector with default size |
627 |
|
|
|
628 |
|
|
if (.not. associated(this)) then |
629 |
|
|
this => initialize() |
630 |
|
|
endif |
631 |
|
|
|
632 |
|
|
oldCapacity = size(this%ElementData) |
633 |
|
|
oldPropCap = size(this%PropertyDescriptions) |
634 |
|
|
|
635 |
|
|
if (minCapacity > oldCapacity) then |
636 |
|
|
if (this%capacityIncrement .gt. 0) then |
637 |
|
|
newCapacity = oldCapacity + this%capacityIncrement |
638 |
|
|
else |
639 |
|
|
newCapacity = oldCapacity * 2 |
640 |
|
|
endif |
641 |
|
|
if (newCapacity .lt. minCapacity) then |
642 |
|
|
newCapacity = minCapacity |
643 |
|
|
endif |
644 |
|
|
resizeFlag = .true. |
645 |
|
|
else |
646 |
|
|
newCapacity = oldCapacity |
647 |
|
|
endif |
648 |
|
|
|
649 |
|
|
!!! newCapacity is not set..... |
650 |
|
|
if (minPropCap > oldPropCap) then |
651 |
|
|
if (this%PropertyIncrement .gt. 0) then |
652 |
|
|
newPropCap = oldPropCap + this%PropertyIncrement |
653 |
|
|
else |
654 |
|
|
newPropCap = oldPropCap * 2 |
655 |
|
|
endif |
656 |
|
|
if (newPropCap .lt. minPropCap) then |
657 |
|
|
newPropCap = minPropCap |
658 |
|
|
endif |
659 |
|
|
resizeFlag = .true. |
660 |
|
|
else |
661 |
|
|
newPropCap = oldPropCap |
662 |
|
|
endif |
663 |
|
|
|
664 |
|
|
if (resizeFlag) then |
665 |
|
|
that => initialize(newCapacity, newPropCap, & |
666 |
|
|
this%capacityIncrement, this%PropertyIncrement) |
667 |
|
|
call copyAllData(this, that) |
668 |
|
|
deallocate(this) |
669 |
|
|
this => that |
670 |
|
|
endif |
671 |
|
|
end subroutine ensureCapacityHelper |
672 |
|
|
|
673 |
|
|
subroutine copyAllData(v1, v2) |
674 |
|
|
type(Vector), pointer :: v1 |
675 |
|
|
type(Vector), pointer :: v2 |
676 |
|
|
integer :: i, j |
677 |
|
|
|
678 |
|
|
do i = 1, v1%elementCount |
679 |
|
|
v2%elementData(i) = v1%elementData(i) |
680 |
|
|
do j = 1, v1%propertyCount |
681 |
|
|
|
682 |
|
|
if (v1%PropertyDataType(j) .eq. integer_data_type) & |
683 |
|
|
v2%integerElementProperties(i,j) = & |
684 |
|
|
v1%integerElementProperties(i,j) |
685 |
|
|
|
686 |
|
|
if (v1%PropertyDataType(j) .eq. real_data_type) & |
687 |
|
|
v2%realElementProperties(i,j) = v1%realElementProperties(i,j) |
688 |
|
|
|
689 |
|
|
if (v1%PropertyDataType(j) .eq. logical_data_type) & |
690 |
|
|
v2%logicalElementProperties(i,j) = & |
691 |
|
|
v1%logicalElementProperties(i,j) |
692 |
|
|
enddo |
693 |
|
|
enddo |
694 |
|
|
|
695 |
|
|
do j = 1, v1%propertyCount |
696 |
|
|
v2%PropertyDescriptions(j) = v1%PropertyDescriptions(j) |
697 |
|
|
v2%PropertyDataType(j) = v1%PropertyDataType(j) |
698 |
|
|
enddo |
699 |
|
|
|
700 |
|
|
v2%elementCount = v1%elementCount |
701 |
|
|
v2%propertyCount = v1%propertyCount |
702 |
|
|
|
703 |
|
|
return |
704 |
|
|
end subroutine copyAllData |
705 |
|
|
|
706 |
|
|
function addElement(this) result (id) |
707 |
|
|
type(Vector), pointer :: this |
708 |
|
|
integer :: id |
709 |
|
|
integer :: error |
710 |
|
|
|
711 |
|
|
if (.not. associated(this)) then |
712 |
|
|
call ensureCapacityHelper(this,1,0) |
713 |
|
|
else |
714 |
|
|
call ensureCapacityHelper(this, this%elementCount + 1, this%PropertyCount) |
715 |
|
|
end if |
716 |
|
|
|
717 |
|
|
this%elementCount = this%elementCount + 1 |
718 |
|
|
|
719 |
|
|
!! We never use this and we set the entire array to the same value |
720 |
|
|
this%elementData = this%elementCount |
721 |
|
|
id = this%elementCount |
722 |
|
|
end function addElement |
723 |
|
|
|
724 |
|
|
recursive subroutine setElementPropertyReal(this, id, PropName, PropValue) |
725 |
|
|
type(Vector), pointer :: this |
726 |
|
|
integer :: id, i |
727 |
|
|
character(len=*), intent(in) :: PropName |
728 |
|
|
real( kind = 8 ), intent(in) :: PropValue |
729 |
|
|
logical :: foundit |
730 |
|
|
|
731 |
|
|
foundit = .false. |
732 |
|
|
|
733 |
|
|
! first make sure that the PropName isn't in the list of known properties: |
734 |
|
|
|
735 |
|
|
do i = 1, this%propertyCount |
736 |
|
|
if (PropName == this%PropertyDescriptions(i)) then |
737 |
|
|
foundit = .true. |
738 |
|
|
this%realElementProperties(id,i) = PropValue |
739 |
|
|
endif |
740 |
|
|
enddo |
741 |
|
|
|
742 |
|
|
if (.not.foundit) then |
743 |
|
|
call addPropertyToVector(this, PropName, real_data_type) |
744 |
|
|
call setElementPropertyReal(this, id, PropName, PropValue) |
745 |
|
|
endif |
746 |
|
|
end subroutine setElementPropertyReal |
747 |
|
|
|
748 |
|
|
recursive subroutine setElementPropertyInt(this, id, PropName, PropValue) |
749 |
|
|
type(Vector), pointer :: this |
750 |
|
|
integer :: id, i |
751 |
|
|
character(len=*), intent(in) :: PropName |
752 |
|
|
integer, intent(in) :: PropValue |
753 |
|
|
logical :: foundit |
754 |
|
|
|
755 |
|
|
foundit = .false. |
756 |
|
|
! first make sure that the PropName isn't in the list of known properties: |
757 |
|
|
do i = 1, this%propertyCount |
758 |
|
|
if (PropName == this%PropertyDescriptions(i)) then |
759 |
|
|
foundit = .true. |
760 |
|
|
this%integerElementProperties(id,i) = PropValue |
761 |
|
|
endif |
762 |
|
|
enddo |
763 |
|
|
|
764 |
|
|
if (.not.foundit) then |
765 |
|
|
call addPropertyToVector(this, PropName, integer_data_type) |
766 |
|
|
call setElementPropertyInt(this, id, PropName, PropValue) |
767 |
|
|
endif |
768 |
|
|
end subroutine setElementPropertyInt |
769 |
|
|
|
770 |
|
|
recursive subroutine setElementPropertyLogical(this, id, PropName, PropValue) |
771 |
|
|
type(Vector), pointer :: this |
772 |
|
|
integer :: id, i |
773 |
|
|
character(len=*), intent(in) :: PropName |
774 |
|
|
logical, intent(in) :: PropValue |
775 |
|
|
logical :: foundit |
776 |
|
|
|
777 |
|
|
foundit = .false. |
778 |
|
|
! first make sure that the PropName isn't in the list of known properties: |
779 |
|
|
do i = 1, this%propertyCount |
780 |
|
|
if (PropName == this%PropertyDescriptions(i)) then |
781 |
|
|
foundit = .true. |
782 |
|
|
this%logicalElementProperties(id,i) = PropValue |
783 |
|
|
endif |
784 |
|
|
enddo |
785 |
|
|
|
786 |
|
|
if (.not.foundit) then |
787 |
|
|
call addPropertyToVector(this, PropName, logical_data_type) |
788 |
|
|
call setElementPropertyLogical(this, id, PropName, PropValue) |
789 |
|
|
endif |
790 |
|
|
end subroutine setElementPropertyLogical |
791 |
|
|
|
792 |
|
|
subroutine addPropertyToVector(this, PropName, data_type) |
793 |
|
|
type(Vector), pointer :: this |
794 |
|
|
character(len=*), intent(in) :: PropName |
795 |
|
|
integer data_type |
796 |
|
|
|
797 |
|
|
call ensureCapacityHelper(this, this%elementCount, this%propertyCount + 1) |
798 |
|
|
this%propertyCount = this%propertyCount + 1 |
799 |
|
|
this%PropertyDescriptions(this%propertyCount) = PropName |
800 |
|
|
this%PropertyDataType(this%propertyCount) = data_type |
801 |
|
|
end subroutine addPropertyToVector |
802 |
|
|
|
803 |
|
|
function initialize_0i() result(this) |
804 |
|
|
type(Vector), pointer :: this |
805 |
|
|
this => initialize_2i(10, 5) |
806 |
|
|
end function initialize_0i |
807 |
|
|
|
808 |
|
|
function initialize_1i(nprop) result(this) |
809 |
|
|
integer, intent(in) :: nprop |
810 |
|
|
type(Vector), pointer :: this |
811 |
|
|
this => initialize_2i(10, nprop) |
812 |
|
|
end function initialize_1i |
813 |
|
|
|
814 |
|
|
function initialize_2i(cap, nprop) result(this) |
815 |
|
|
integer, intent(in) :: cap, nprop |
816 |
|
|
type(Vector), pointer :: this |
817 |
|
|
this => initialize_4i(cap, nprop, 0, 0) |
818 |
|
|
end function initialize_2i |
819 |
|
|
|
820 |
|
|
function initialize_3i(cap, nprop, capinc) result(this) |
821 |
|
|
integer, intent(in) :: cap, nprop, capinc |
822 |
|
|
type(Vector), pointer :: this |
823 |
|
|
this => initialize_4i(cap, nprop, capinc, 0) |
824 |
|
|
end function initialize_3i |
825 |
|
|
|
826 |
|
|
function initialize_4i(cap, nprop, capinc, propinc) result(this) |
827 |
|
|
integer, intent(in) :: cap, nprop, capinc, propinc |
828 |
|
|
integer :: error |
829 |
|
|
type(Vector), pointer :: this |
830 |
|
|
|
831 |
|
|
nullify(this) |
832 |
|
|
|
833 |
|
|
if (cap < 0) then |
834 |
|
|
write(*,*) 'Bogus Capacity:', cap |
835 |
|
|
return |
836 |
|
|
endif |
837 |
|
|
if (nprop < 0) then |
838 |
|
|
write(*,*) 'Bogus Number of Properties:', nprop |
839 |
|
|
return |
840 |
|
|
endif |
841 |
|
|
|
842 |
|
|
allocate(this,stat=error) |
843 |
|
|
if ( error /= 0 ) then |
844 |
|
|
write(*,*) 'Could not allocate Vector!' |
845 |
|
|
return |
846 |
|
|
end if |
847 |
|
|
|
848 |
|
|
this%initialCapacity = cap |
849 |
|
|
this%initialProperties = nprop |
850 |
|
|
this%capacityIncrement = capinc |
851 |
|
|
this%propertyIncrement = propinc |
852 |
|
|
|
853 |
|
|
allocate(this%elementData(this%initialCapacity), stat=error) |
854 |
|
|
if(error /= 0) write(*,*) 'Could not allocate elementData!' |
855 |
|
|
|
856 |
|
|
|
857 |
|
|
allocate(this%PropertyDescriptions(this%initialProperties), & |
858 |
|
|
stat=error) |
859 |
|
|
if(error /= 0) write(*,*) 'Could not allocate PropertyDescriptions!' |
860 |
|
|
|
861 |
|
|
allocate(this%PropertyDataType(this%initialProperties), & |
862 |
|
|
stat=error) |
863 |
|
|
if(error /= 0) write(*,*) 'Could not allocate PropertyDataType!' |
864 |
|
|
|
865 |
|
|
allocate(this%integerElementProperties(this%initialCapacity, & |
866 |
|
|
this%initialProperties), stat=error) |
867 |
|
|
if(error /= 0) write(*,*) 'Could not allocate integerElementProperties!' |
868 |
|
|
|
869 |
|
|
allocate(this%realElementProperties(this%initialCapacity, & |
870 |
|
|
this%initialProperties), stat=error) |
871 |
|
|
if(error /= 0) write(*,*) 'Could not allocate realElementProperties!' |
872 |
|
|
|
873 |
|
|
allocate(this%logicalElementProperties(this%initialCapacity, & |
874 |
|
|
this%initialProperties), stat=error) |
875 |
|
|
if(error .ne. 0) write(*,*) 'Could not allocate logicalElementProperties!' |
876 |
|
|
|
877 |
|
|
end function initialize_4i |
878 |
|
|
|
879 |
|
|
|
880 |
|
|
|
881 |
|
|
end module Vector_class |