ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/utils/vector_class.F90
Revision: 1930
Committed: Wed Jan 12 22:41:40 2005 UTC (19 years, 5 months ago) by gezelter
File size: 28441 byte(s)
Log Message:
merging new_design branch into OOPSE-2.0

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 1930 !! @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 1490
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