ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/utils/vector_class.F90
Revision: 2204
Committed: Fri Apr 15 22:04:00 2005 UTC (19 years, 2 months ago) by gezelter
File size: 29531 byte(s)
Log Message:
xemacs has been drafted to perform our indentation services

File Contents

# User Rev Content
1 gezelter 1930 !!
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 1490 ! 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 2204 !! @version $Id: vector_class.F90,v 1.7 2005-04-15 22:03:59 gezelter Exp $, $Date: 2005-04-15 22:03:59 $, $Name: not supported by cvs2svn $, $Revision: 1.7 $
64 gezelter 1490
65     module Vector_class
66 gezelter 2204
67 gezelter 1490 implicit NONE
68     PRIVATE
69 gezelter 2204
70 gezelter 1490 public :: initialize
71 chuckv 2166 public :: destroy
72 gezelter 1490 public :: getSize
73     public :: getElementAt
74     public :: getPropertyListSize
75     public :: getPropertyNameAt
76     public :: addElement
77     public :: setElementProperty
78     public :: getElementProperty
79     public :: getMatchingElementList
80     public :: getFirstMatchingElement
81    
82 gezelter 2204
83 gezelter 1490 integer, parameter :: logical_data_type = 1
84     integer, parameter :: integer_data_type = 2
85     integer, parameter :: real_data_type = 3
86    
87 gezelter 2204 !!
88 gezelter 1490 type, public :: Vector
89     PRIVATE
90     integer :: initialCapacity = 10
91     integer :: capacityIncrement = 0
92     integer :: elementCount = 0
93 gezelter 2204
94 gezelter 1490 integer :: initialProperties = 5
95     integer :: PropertyIncrement = 0
96     integer :: propertyCount = 0
97 gezelter 2204
98 gezelter 1490 integer, pointer :: ElementData(:) => null()
99     character(len=100), pointer :: PropertyDescriptions(:) => null()
100     integer, pointer :: PropertyDataType(:) => null()
101     real(kind = 8), pointer :: realElementProperties(:,:) => null()
102     integer, pointer :: integerElementProperties(:,:) => null()
103     logical, pointer :: logicalElementProperties(:,:) => null()
104     end type Vector
105    
106 gezelter 2204 !! Initialize vector
107 gezelter 1490 interface initialize
108     module procedure initialize_0i
109     module procedure initialize_1i
110     module procedure initialize_2i
111     module procedure initialize_3i
112     module procedure initialize_4i
113     end interface
114    
115     interface setElementProperty
116     module procedure setElementPropertyReal
117     module procedure setElementPropertyInt
118     module procedure setElementPropertyLogical
119     end interface
120    
121     interface getElementProperty
122     module procedure getElementPropertyReal
123     module procedure getElementPropertyInt
124     module procedure getElementPropertyLogical
125     end interface
126    
127     interface getMatchingElementList
128     module procedure getMatchingElementList1i
129     module procedure getMatchingElementList2i
130     module procedure getMatchingElementList1l
131     module procedure getMatchingElementList2l
132     end interface
133    
134     interface getFirstMatchingElement
135     module procedure getFirstMatchingElement1i
136     module procedure getFirstMatchingElement2i
137     module procedure getFirstMatchingElement1l
138     module procedure getFirstMatchingElement2l
139     end interface
140     contains
141    
142     function getSize(this) result (ne)
143     type(Vector), pointer :: this
144     integer :: ne
145     ne = this%elementCount
146     end function getSize
147    
148     function getElementAt(this, loc) result (id)
149     type(Vector), pointer :: this
150     integer, intent(in) :: loc
151     integer :: id
152     id = this%ElementData(loc)
153     end function getElementAt
154    
155     function getPropertyListSize(this) result (np)
156     type(Vector), pointer :: this
157     integer :: np
158     np = this%propertyCount
159     end function getPropertyListSize
160    
161     function getPropertyNameAt(this, loc) result (pn)
162     type(Vector), pointer :: this
163     integer, intent(in) :: loc
164     character(len=len(this%PropertyDescriptions)) :: pn
165     pn = this%PropertyDescriptions(loc)
166     end function getPropertyNameAt
167    
168     function getFirstMatchingElement1i(this, MatchName, MatchValue) result (id)
169     type(Vector), pointer :: this
170     character(len=*), intent(in) :: MatchName
171     integer, intent(in) :: MatchValue
172     integer :: id
173     integer :: i, j
174 gezelter 2204
175 gezelter 1490 id = 0
176 gezelter 2204
177 gezelter 1490 do i = 1, this%propertyCount
178     if (this%PropertyDescriptions(i) == MatchName) then
179     do j = 1, this%elementCount
180     if (this%integerElementProperties(j, i) == MatchValue) then
181     id = j
182     return
183     endif
184     enddo
185     endif
186     enddo
187     return
188     end function getFirstMatchingElement1i
189    
190     function getFirstMatchingElement2i(this, MatchName1, MatchValue1, &
191     MatchName2, MatchValue2) result (id)
192     type(Vector), pointer :: this
193     character(len=*), intent(in) :: MatchName1, MatchName2
194     integer, intent(in) :: MatchValue1, MatchValue2
195     integer :: id
196     integer :: i, j, MatchID1, MatchID2
197     logical :: found1 = .false.
198     logical :: found2 = .false.
199    
200     id = 0
201     ! first figure out which properties we are using to do the match:
202    
203     do i = 1, this%propertyCount
204     if (this%PropertyDescriptions(i) == MatchName1) then
205     MatchID1 = i
206     found1 = .true.
207     endif
208     if (this%PropertyDescriptions(i) == MatchName2) then
209     MatchID2 = i
210     found2 = .true.
211     endif
212    
213     if (found1.and.found2) then
214     do j = 1, this%elementCount
215     if ((this%integerElementProperties(j, MatchID1) == MatchValue1) &
216     .and. &
217     (this%integerElementProperties(j, MatchID2) ==MatchValue2)) &
218     then
219     id = j
220     return
221     endif
222     enddo
223     endif
224     end do
225 gezelter 2204
226 gezelter 1490 return
227     end function getFirstMatchingElement2i
228    
229     function getFirstMatchingElement1l(this, MatchName, MatchValue) result (id)
230     type(Vector), pointer :: this
231     character(len=*), intent(in) :: MatchName
232     logical, intent(in) :: MatchValue
233     integer :: id
234     integer :: i, j
235 gezelter 2204
236 gezelter 1490 id = 0
237    
238     do i = 1, this%propertyCount
239     if (this%PropertyDescriptions(i) == MatchName) then
240     do j = 1, this%elementCount
241     if (this%logicalElementProperties(j, i) .eqv. MatchValue) then
242     id = j
243     return
244     endif
245     enddo
246     endif
247     enddo
248     return
249     end function getFirstMatchingElement1l
250    
251     function getFirstMatchingElement2l(this, MatchName1, MatchValue1, &
252     MatchName2, MatchValue2) result (id)
253     type(Vector), pointer :: this
254     character(len=*), intent(in) :: MatchName1, MatchName2
255     logical, intent(in) :: MatchValue1, MatchValue2
256     integer :: id
257     integer :: i, j, MatchID1, MatchID2
258     logical :: found1 = .false.
259     logical :: found2 = .false.
260    
261     id = 0
262     ! first figure out which properties we are using to do the match:
263    
264     do i = 1, this%propertyCount
265     if (this%PropertyDescriptions(i) == MatchName1) then
266     MatchID1 = i
267     found1 = .true.
268     endif
269     if (this%PropertyDescriptions(i) == MatchName2) then
270     MatchID2 = i
271     found2 = .true.
272     endif
273    
274     if (found1.and.found2) then
275     do j = 1, this%elementCount
276     if ((this%logicalElementProperties(j, MatchID1).eqv.MatchValue1) &
277     .and. &
278     (this%logicalElementProperties(j, MatchID2).eqv.MatchValue2)) &
279     then
280     id = j
281     return
282     endif
283     enddo
284     endif
285     end do
286 gezelter 2204
287 gezelter 1490 return
288     end function getFirstMatchingElement2l
289    
290     subroutine getMatchingElementList1i(this, MatchName, MatchValue, &
291     nMatches, MatchList)
292     type(Vector), pointer :: this
293     character(len=*), intent(in) :: MatchName
294     integer, intent(in) :: MatchValue
295     integer, intent(out) :: nMatches
296     integer, pointer :: MatchList(:)
297     integer :: i
298    
299     ! first figure out which property we are using to do the match:
300    
301     do i = 1, this%propertyCount
302     if (this%PropertyDescriptions(i) == MatchName) then
303     call getAllMatches1i(this, i, MatchValue, nMatches, MatchList)
304     return
305     endif
306     enddo
307     return
308     end subroutine getMatchingElementList1i
309    
310     subroutine getMatchingElementList2i(this, MatchName1, MatchValue1, &
311     MatchName2, MatchValue2, nMatches, MatchList)
312     type(Vector), pointer :: this
313     character(len=*), intent(in) :: MatchName1, MatchName2
314     integer, intent(in) :: MatchValue1, MatchValue2
315     integer, intent(out) :: nMatches
316     integer, pointer :: MatchList(:)
317     integer :: i, MatchID1, MatchID2
318     logical :: found1 = .false.
319     logical :: found2 = .false.
320 gezelter 2204
321 gezelter 1490 ! first figure out which properties we are using to do the match:
322 gezelter 2204
323 gezelter 1490 do i = 1, this%propertyCount
324     if (this%PropertyDescriptions(i) == MatchName1) then
325     MatchID1 = i
326     found1 = .true.
327     endif
328     if (this%PropertyDescriptions(i) == MatchName2) then
329     MatchID2 = i
330     found2 = .true.
331     endif
332 gezelter 2204
333 gezelter 1490 if (found1.and.found2) then
334     call getAllMatches2i(this, MatchID1, MatchValue1, &
335     MatchID2, MatchValue2, nMatches, MatchList)
336     return
337     endif
338     enddo
339     return
340     end subroutine getMatchingElementList2i
341    
342     subroutine getMatchingElementList1l(this, MatchName, MatchValue, &
343     nMatches, MatchList)
344     type(Vector), pointer :: this
345     character(len=*), intent(in) :: MatchName
346     logical, intent(in) :: MatchValue
347     integer, intent(out) :: nMatches
348     integer, pointer :: MatchList(:)
349     integer :: i
350    
351     ! first figure out which property we are using to do the match:
352    
353     do i = 1, this%propertyCount
354     if (this%PropertyDescriptions(i) == MatchName) then
355     call getAllMatches1l(this, i, MatchValue, nMatches, MatchList)
356     return
357     endif
358     enddo
359     return
360     end subroutine getMatchingElementList1l
361    
362     subroutine getMatchingElementList2l(this, MatchName1, MatchValue1, &
363     MatchName2, MatchValue2, nMatches, MatchList)
364     type(Vector), pointer :: this
365     character(len=*), intent(in) :: MatchName1, MatchName2
366     logical, intent(in) :: MatchValue1, MatchValue2
367     integer, intent(out) :: nMatches
368     integer, pointer :: MatchList(:)
369     integer :: i, MatchID1, MatchID2
370     logical :: found1 = .false.
371     logical :: found2 = .false.
372 gezelter 2204
373 gezelter 1490 ! first figure out which properties we are using to do the match:
374 gezelter 2204
375 gezelter 1490 do i = 1, this%propertyCount
376     if (this%PropertyDescriptions(i) == MatchName1) then
377     MatchID1 = i
378     found1 = .true.
379     endif
380     if (this%PropertyDescriptions(i) == MatchName2) then
381     MatchID2 = i
382     found2 = .true.
383     endif
384 gezelter 2204
385 gezelter 1490 if (found1.and.found2) then
386     call getAllMatches2l(this, MatchID1, MatchValue1, &
387     MatchID2, MatchValue2, nMatches, MatchList)
388     return
389     endif
390     enddo
391     return
392     end subroutine getMatchingElementList2l
393 gezelter 2204
394 gezelter 1490 subroutine getAllMatches1i(this, MatchID, MatchValue, nMatches, MatchList)
395     type(Vector), pointer :: this
396     integer, intent(in) :: MatchID
397     integer, intent(in) :: MatchValue
398     integer, pointer :: MatchList(:)
399     integer, allocatable :: MatchListTemp(:)
400     integer, intent(out) :: nMatches
401     integer :: error, i
402 gezelter 2204
403 gezelter 1490 if(associated(MatchList)) deallocate(MatchList)
404     MatchList => null()
405    
406     allocate(MatchListTemp(this%elementCount), stat=error)
407     if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!'
408 gezelter 2204
409 gezelter 1490 nMatches = 0
410 gezelter 2204
411 gezelter 1490 do i = 1, this%elementCount
412     if (this%integerElementProperties(i, MatchID) == MatchValue) then
413     nMatches = nMatches + 1
414     MatchListTemp(nMatches) = i
415     endif
416     enddo
417 gezelter 2204
418    
419 gezelter 1490 if (nMatches .ne. 0) then
420     allocate(MatchList(nMatches), stat=error)
421     if (error.ne.0) write(*, *) 'Could not allocate MatchList!'
422     do i = 1, nMatches
423     MatchList(i) = MatchListTemp(i)
424     enddo
425     endif
426 gezelter 2204
427 gezelter 1490 deallocate(MatchListTemp)
428    
429 gezelter 2204
430 gezelter 1490 end subroutine getAllMatches1i
431    
432     subroutine getAllMatches2i(this, MatchID1, MatchValue1, &
433     MatchID2, MatchValue2, nMatches, MatchList)
434     type(Vector), pointer :: this
435     integer, intent(in) :: MatchID1, MatchID2
436     integer, intent(in) :: MatchValue1, MatchValue2
437     integer, pointer :: MatchList(:)
438     integer, allocatable :: MatchListTemp(:)
439     integer, intent(out) :: nMatches
440     integer :: error, i
441 gezelter 2204
442 gezelter 1490 if(associated(MatchList)) deallocate(MatchList)
443     MatchList => null()
444    
445     allocate(MatchListTemp(this%elementCount), stat=error)
446     if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!'
447 gezelter 2204
448 gezelter 1490 nMatches = 0
449 gezelter 2204
450 gezelter 1490 do i = 1, this%elementCount
451     if ((this%integerElementProperties(i, MatchID1) == MatchValue1) .and. &
452     (this%integerElementProperties(i, MatchID2) == MatchValue2)) then
453     nMatches = nMatches + 1
454     MatchListTemp(nMatches) = i
455     endif
456     enddo
457    
458     if (nMatches .ne. 0) then
459     allocate(MatchList(nMatches), stat=error)
460     if (error.ne.0) write(*, *) 'Could not allocate MatchList!'
461     do i = 1, nMatches
462     MatchList(i) = MatchListTemp(i)
463     enddo
464     endif
465 gezelter 2204
466 gezelter 1490 deallocate(MatchListTemp)
467    
468     end subroutine getAllMatches2i
469    
470     subroutine getAllMatches1l(this, MatchID, MatchValue, nMatches, MatchList)
471     type(Vector), pointer :: this
472     integer, intent(in) :: MatchID
473     logical, intent(in) :: MatchValue
474     integer, pointer :: MatchList(:)
475     integer, allocatable :: MatchListTemp(:)
476     integer, intent(out) :: nMatches
477     integer :: error, i
478 gezelter 2204
479 gezelter 1490 if(associated(MatchList)) deallocate(MatchList)
480     MatchList => null()
481    
482     allocate(MatchListTemp(this%elementCount), stat=error)
483     if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!'
484 gezelter 2204
485 gezelter 1490 nMatches = 0
486 gezelter 2204
487 gezelter 1490 do i = 1, this%elementCount
488     if (this%logicalElementProperties(i, MatchID).eqv.MatchValue) then
489     nMatches = nMatches + 1
490     MatchListTemp(nMatches) = i
491     endif
492     enddo
493    
494     if (nMatches .ne. 0) then
495     allocate(MatchList(nMatches), stat=error)
496     if (error.ne.0) write(*, *) 'Could not allocate MatchList!'
497     do i = 1, nMatches
498     MatchList(i) = MatchListTemp(i)
499     enddo
500     endif
501 gezelter 2204
502 gezelter 1490 deallocate(MatchListTemp)
503    
504     end subroutine getAllMatches1l
505    
506     subroutine getAllMatches2l(this, MatchID1, MatchValue1, &
507     MatchID2, MatchValue2, nMatches, MatchList)
508     type(Vector), pointer :: this
509     integer, intent(in) :: MatchID1, MatchID2
510     logical, intent(in) :: MatchValue1, MatchValue2
511     integer, pointer :: MatchList(:)
512     integer, allocatable :: MatchListTemp(:)
513     integer, intent(out) :: nMatches
514     integer :: error, i
515 gezelter 2204
516 gezelter 1490 if(associated(MatchList)) deallocate(MatchList)
517     MatchList => null()
518    
519     allocate(MatchListTemp(this%elementCount), stat=error)
520     if(error .ne. 0) write(*,*) 'Could not allocate MatchListTemp!'
521 gezelter 2204
522 gezelter 1490 nMatches = 0
523 gezelter 2204
524 gezelter 1490 do i = 1, this%elementCount
525     if ((this%logicalElementProperties(i, MatchID1).eqv.MatchValue1) .and. &
526     (this%logicalElementProperties(i, MatchID2).eqv.MatchValue2)) then
527     nMatches = nMatches + 1
528     MatchListTemp(nMatches) = i
529     endif
530     enddo
531    
532     if (nMatches .ne. 0) then
533     allocate(MatchList(nMatches), stat=error)
534     if (error.ne.0) write(*, *) 'Could not allocate MatchList!'
535     do i = 1, nMatches
536     MatchList(i) = MatchListTemp(i)
537     enddo
538     endif
539 gezelter 2204
540 gezelter 1490 deallocate(MatchListTemp)
541    
542     end subroutine getAllMatches2l
543 gezelter 2204
544    
545 gezelter 1490 subroutine getElementPropertyReal(this, id, PropName, pv)
546     type(Vector), pointer :: this
547     integer :: id, whichprop
548     character(len=*) :: PropName
549     real( kind = 8 ) :: pv
550 gezelter 2204
551 gezelter 1490 whichprop = getPropertyIndex(this, PropName)
552     if (whichprop .eq. 0 ) then
553     write(*,*) 'unknown property: ', PropName
554     pv = 0.0
555     else
556     if (this%PropertyDataType(whichprop) .ne. real_data_type) then
557     write(*,*) 'Property: ', PropName, " is not real data type."
558     pv = 0.0
559     else
560     pv = this%realElementProperties(id, whichprop)
561     endif
562     endif
563     end subroutine getElementPropertyReal
564    
565     subroutine getElementPropertyInt(this, id, PropName, pv)
566     type(Vector), pointer :: this
567     integer :: id, whichprop
568     character(len=*) :: PropName
569     integer :: pv
570 gezelter 2204
571 gezelter 1490 whichprop = getPropertyIndex(this, PropName)
572     if (whichprop .eq. 0 ) then
573     write(*,*) 'unknown property! ', PropName
574     pv = 0
575     else
576     if (this%PropertyDataType(whichprop) .ne. integer_data_type) then
577     write(*,*) 'Property! ', PropName, " is not integer data type."
578     pv = 0
579     else
580     pv = this%integerElementProperties(id, whichprop)
581     endif
582     endif
583     end subroutine getElementPropertyInt
584    
585     subroutine getElementPropertyLogical(this, id, PropName, pv)
586     type(Vector), pointer :: this
587     integer :: id, whichprop
588     character(len=*) :: PropName
589     logical :: pv
590 gezelter 2204
591 gezelter 1490 whichprop = getPropertyIndex(this, PropName)
592     if (whichprop .eq. 0 ) then
593     write(*,*) 'unknown property! ', PropName
594     pv = .false.
595     else
596     if (this%PropertyDataType(whichprop) .ne. logical_data_type) then
597     write(*,*) 'Property! ', PropName, " is not logical data type."
598     pv = .false.
599     else
600     pv = this%logicalElementProperties(id, whichprop)
601     endif
602     endif
603     end subroutine getElementPropertyLogical
604    
605     function getPropertyIndex(this, PropName) result (id)
606     type(Vector), pointer :: this
607     integer :: id, i
608     character(len=*) :: PropName
609    
610     do i = 1, this%propertyCount
611     if (this%PropertyDescriptions(i) == PropName) then
612     id = i
613     return
614     endif
615 gezelter 2204 enddo
616 gezelter 1490 id = 0
617     end function getPropertyIndex
618    
619     subroutine ensureCapacityHelper(this, minCapacity, minPropCap)
620     type(Vector), pointer :: this, that
621     integer, intent(in) :: minCapacity, minPropCap
622     integer :: oldCapacity, oldPropCap
623     integer :: newCapacity, newPropCap
624     logical :: resizeFlag
625    
626     resizeFlag = .false.
627    
628 gezelter 2204 ! first time: allocate a new vector with default size
629 gezelter 1490
630     if (.not. associated(this)) then
631     this => initialize()
632     endif
633    
634     oldCapacity = size(this%ElementData)
635     oldPropCap = size(this%PropertyDescriptions)
636 gezelter 2204
637 gezelter 1490 if (minCapacity > oldCapacity) then
638     if (this%capacityIncrement .gt. 0) then
639     newCapacity = oldCapacity + this%capacityIncrement
640     else
641     newCapacity = oldCapacity * 2
642     endif
643     if (newCapacity .lt. minCapacity) then
644     newCapacity = minCapacity
645     endif
646     resizeFlag = .true.
647     else
648     newCapacity = oldCapacity
649     endif
650 gezelter 2204
651 gezelter 1490 !!! newCapacity is not set.....
652     if (minPropCap > oldPropCap) then
653     if (this%PropertyIncrement .gt. 0) then
654     newPropCap = oldPropCap + this%PropertyIncrement
655     else
656     newPropCap = oldPropCap * 2
657     endif
658     if (newPropCap .lt. minPropCap) then
659     newPropCap = minPropCap
660     endif
661     resizeFlag = .true.
662     else
663     newPropCap = oldPropCap
664     endif
665 gezelter 2204
666 gezelter 1490 if (resizeFlag) then
667     that => initialize(newCapacity, newPropCap, &
668     this%capacityIncrement, this%PropertyIncrement)
669     call copyAllData(this, that)
670 gezelter 2180 this => destroy(this)
671 gezelter 1490 this => that
672     endif
673     end subroutine ensureCapacityHelper
674 gezelter 2204
675 gezelter 1490 subroutine copyAllData(v1, v2)
676     type(Vector), pointer :: v1
677     type(Vector), pointer :: v2
678     integer :: i, j
679 gezelter 2204
680 gezelter 1490 do i = 1, v1%elementCount
681     v2%elementData(i) = v1%elementData(i)
682     do j = 1, v1%propertyCount
683    
684     if (v1%PropertyDataType(j) .eq. integer_data_type) &
685     v2%integerElementProperties(i,j) = &
686     v1%integerElementProperties(i,j)
687    
688     if (v1%PropertyDataType(j) .eq. real_data_type) &
689     v2%realElementProperties(i,j) = v1%realElementProperties(i,j)
690    
691     if (v1%PropertyDataType(j) .eq. logical_data_type) &
692     v2%logicalElementProperties(i,j) = &
693     v1%logicalElementProperties(i,j)
694     enddo
695     enddo
696 gezelter 2204
697 gezelter 1490 do j = 1, v1%propertyCount
698     v2%PropertyDescriptions(j) = v1%PropertyDescriptions(j)
699     v2%PropertyDataType(j) = v1%PropertyDataType(j)
700     enddo
701 gezelter 2204
702 gezelter 1490 v2%elementCount = v1%elementCount
703     v2%propertyCount = v1%propertyCount
704 gezelter 2204
705 gezelter 1490 return
706     end subroutine copyAllData
707    
708     function addElement(this) result (id)
709     type(Vector), pointer :: this
710     integer :: id
711     integer :: error
712 gezelter 2204
713 gezelter 1490 if (.not. associated(this)) then
714     call ensureCapacityHelper(this,1,0)
715     else
716     call ensureCapacityHelper(this, this%elementCount + 1, this%PropertyCount)
717     end if
718 gezelter 2204
719 gezelter 1490 this%elementCount = this%elementCount + 1
720 gezelter 2204
721 gezelter 1490 !! We never use this and we set the entire array to the same value
722     this%elementData = this%elementCount
723     id = this%elementCount
724     end function addElement
725    
726     recursive subroutine setElementPropertyReal(this, id, PropName, PropValue)
727     type(Vector), pointer :: this
728     integer :: id, i
729     character(len=*), intent(in) :: PropName
730     real( kind = 8 ), intent(in) :: PropValue
731     logical :: foundit
732 gezelter 2204
733 gezelter 1490 foundit = .false.
734    
735     ! first make sure that the PropName isn't in the list of known properties:
736    
737     do i = 1, this%propertyCount
738     if (PropName == this%PropertyDescriptions(i)) then
739     foundit = .true.
740     this%realElementProperties(id,i) = PropValue
741     endif
742     enddo
743    
744     if (.not.foundit) then
745 gezelter 2204 call addPropertyToVector(this, PropName, real_data_type)
746     call setElementPropertyReal(this, id, PropName, PropValue)
747 gezelter 1490 endif
748     end subroutine setElementPropertyReal
749    
750     recursive subroutine setElementPropertyInt(this, id, PropName, PropValue)
751     type(Vector), pointer :: this
752     integer :: id, i
753     character(len=*), intent(in) :: PropName
754     integer, intent(in) :: PropValue
755     logical :: foundit
756    
757     foundit = .false.
758     ! first make sure that the PropName isn't in the list of known properties:
759     do i = 1, this%propertyCount
760     if (PropName == this%PropertyDescriptions(i)) then
761     foundit = .true.
762     this%integerElementProperties(id,i) = PropValue
763     endif
764     enddo
765 gezelter 2204
766 gezelter 1490 if (.not.foundit) then
767     call addPropertyToVector(this, PropName, integer_data_type)
768     call setElementPropertyInt(this, id, PropName, PropValue)
769     endif
770     end subroutine setElementPropertyInt
771    
772     recursive subroutine setElementPropertyLogical(this, id, PropName, PropValue)
773     type(Vector), pointer :: this
774     integer :: id, i
775     character(len=*), intent(in) :: PropName
776     logical, intent(in) :: PropValue
777     logical :: foundit
778    
779     foundit = .false.
780     ! first make sure that the PropName isn't in the list of known properties:
781     do i = 1, this%propertyCount
782     if (PropName == this%PropertyDescriptions(i)) then
783     foundit = .true.
784     this%logicalElementProperties(id,i) = PropValue
785     endif
786     enddo
787 gezelter 2204
788 gezelter 1490 if (.not.foundit) then
789     call addPropertyToVector(this, PropName, logical_data_type)
790     call setElementPropertyLogical(this, id, PropName, PropValue)
791     endif
792     end subroutine setElementPropertyLogical
793    
794     subroutine addPropertyToVector(this, PropName, data_type)
795     type(Vector), pointer :: this
796     character(len=*), intent(in) :: PropName
797     integer data_type
798 gezelter 2204
799     call ensureCapacityHelper(this, this%elementCount, this%propertyCount + 1)
800     this%propertyCount = this%propertyCount + 1
801     this%PropertyDescriptions(this%propertyCount) = PropName
802     this%PropertyDataType(this%propertyCount) = data_type
803     end subroutine addPropertyToVector
804    
805 gezelter 1490 function initialize_0i() result(this)
806     type(Vector), pointer :: this
807     this => initialize_2i(10, 5)
808     end function initialize_0i
809    
810     function initialize_1i(nprop) result(this)
811     integer, intent(in) :: nprop
812     type(Vector), pointer :: this
813     this => initialize_2i(10, nprop)
814     end function initialize_1i
815    
816     function initialize_2i(cap, nprop) result(this)
817     integer, intent(in) :: cap, nprop
818     type(Vector), pointer :: this
819     this => initialize_4i(cap, nprop, 0, 0)
820     end function initialize_2i
821    
822     function initialize_3i(cap, nprop, capinc) result(this)
823     integer, intent(in) :: cap, nprop, capinc
824     type(Vector), pointer :: this
825     this => initialize_4i(cap, nprop, capinc, 0)
826     end function initialize_3i
827    
828     function initialize_4i(cap, nprop, capinc, propinc) result(this)
829 gezelter 2204 integer, intent(in) :: cap, nprop, capinc, propinc
830 gezelter 1490 integer :: error
831     type(Vector), pointer :: this
832    
833     nullify(this)
834    
835 gezelter 2204 if (cap < 0) then
836 gezelter 1490 write(*,*) 'Bogus Capacity:', cap
837     return
838     endif
839     if (nprop < 0) then
840     write(*,*) 'Bogus Number of Properties:', nprop
841     return
842     endif
843 gezelter 2204
844 gezelter 1490 allocate(this,stat=error)
845     if ( error /= 0 ) then
846     write(*,*) 'Could not allocate Vector!'
847     return
848     end if
849    
850     this%initialCapacity = cap
851     this%initialProperties = nprop
852     this%capacityIncrement = capinc
853     this%propertyIncrement = propinc
854 gezelter 2204
855 gezelter 1490 allocate(this%elementData(this%initialCapacity), stat=error)
856     if(error /= 0) write(*,*) 'Could not allocate elementData!'
857    
858 gezelter 2204
859 gezelter 1490 allocate(this%PropertyDescriptions(this%initialProperties), &
860     stat=error)
861     if(error /= 0) write(*,*) 'Could not allocate PropertyDescriptions!'
862    
863     allocate(this%PropertyDataType(this%initialProperties), &
864     stat=error)
865     if(error /= 0) write(*,*) 'Could not allocate PropertyDataType!'
866 gezelter 2204
867 gezelter 1490 allocate(this%integerElementProperties(this%initialCapacity, &
868     this%initialProperties), stat=error)
869     if(error /= 0) write(*,*) 'Could not allocate integerElementProperties!'
870    
871     allocate(this%realElementProperties(this%initialCapacity, &
872     this%initialProperties), stat=error)
873     if(error /= 0) write(*,*) 'Could not allocate realElementProperties!'
874    
875     allocate(this%logicalElementProperties(this%initialCapacity, &
876     this%initialProperties), stat=error)
877     if(error .ne. 0) write(*,*) 'Could not allocate logicalElementProperties!'
878    
879     end function initialize_4i
880 chuckv 2166
881 gezelter 2204 !! This function destroys the vector components....
882 chuckv 2166 function destroy(this) result(null_this)
883     logical :: done
884     type(Vector), pointer :: this
885     type(Vector), pointer :: null_this
886    
887 chuckv 2171 if (.not. associated(this)) then
888     null_this => null()
889     return
890     end if
891 gezelter 2204
892     !! Walk down the list and deallocate each of the vector component
893     if(associated(this%logicalElementProperties)) then
894     deallocate(this%logicalElementProperties)
895     this%logicalElementProperties=>null()
896     endif
897     if(associated(this%realElementProperties)) then
898     deallocate(this%realElementProperties)
899     this%realElementProperties=>null()
900     endif
901     if(associated(this%integerElementProperties)) then
902     deallocate(this%integerElementProperties)
903     this%integerElementProperties=>null()
904     endif
905     if(associated(this%PropertyDataType)) then
906     deallocate(this%PropertyDataType)
907     this%PropertyDataType=>null()
908     endif
909     if(associated(this%PropertyDescriptions)) then
910     deallocate(this%PropertyDescriptions)
911     this%PropertyDescriptions=>null()
912     endif
913     if(associated(this%elementData)) then
914     deallocate(this%elementData)
915     this%elementData=>null()
916     endif
917     deallocate(this)
918     this => null()
919     null_this => null()
920 chuckv 2166 end function destroy
921 gezelter 2204
922 gezelter 1490 end module Vector_class