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

# Content
1 !!
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 ! 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 !! @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
65 module Vector_class
66
67 implicit NONE
68 PRIVATE
69
70 public :: initialize
71 public :: destroy
72 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
83 integer, parameter :: logical_data_type = 1
84 integer, parameter :: integer_data_type = 2
85 integer, parameter :: real_data_type = 3
86
87 !!
88 type, public :: Vector
89 PRIVATE
90 integer :: initialCapacity = 10
91 integer :: capacityIncrement = 0
92 integer :: elementCount = 0
93
94 integer :: initialProperties = 5
95 integer :: PropertyIncrement = 0
96 integer :: propertyCount = 0
97
98 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 !! Initialize vector
107 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
175 id = 0
176
177 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
226 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
236 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
287 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
321 ! first figure out which properties we are using to do the match:
322
323 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
333 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
373 ! first figure out which properties we are using to do the match:
374
375 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
385 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
394 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
403 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
409 nMatches = 0
410
411 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
418
419 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
427 deallocate(MatchListTemp)
428
429
430 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
442 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
448 nMatches = 0
449
450 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
466 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
479 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
485 nMatches = 0
486
487 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
502 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
516 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
522 nMatches = 0
523
524 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
540 deallocate(MatchListTemp)
541
542 end subroutine getAllMatches2l
543
544
545 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
551 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
571 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
591 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 enddo
616 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 ! first time: allocate a new vector with default size
629
630 if (.not. associated(this)) then
631 this => initialize()
632 endif
633
634 oldCapacity = size(this%ElementData)
635 oldPropCap = size(this%PropertyDescriptions)
636
637 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
651 !!! 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
666 if (resizeFlag) then
667 that => initialize(newCapacity, newPropCap, &
668 this%capacityIncrement, this%PropertyIncrement)
669 call copyAllData(this, that)
670 this => destroy(this)
671 this => that
672 endif
673 end subroutine ensureCapacityHelper
674
675 subroutine copyAllData(v1, v2)
676 type(Vector), pointer :: v1
677 type(Vector), pointer :: v2
678 integer :: i, j
679
680 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
697 do j = 1, v1%propertyCount
698 v2%PropertyDescriptions(j) = v1%PropertyDescriptions(j)
699 v2%PropertyDataType(j) = v1%PropertyDataType(j)
700 enddo
701
702 v2%elementCount = v1%elementCount
703 v2%propertyCount = v1%propertyCount
704
705 return
706 end subroutine copyAllData
707
708 function addElement(this) result (id)
709 type(Vector), pointer :: this
710 integer :: id
711 integer :: error
712
713 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
719 this%elementCount = this%elementCount + 1
720
721 !! 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
733 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 call addPropertyToVector(this, PropName, real_data_type)
746 call setElementPropertyReal(this, id, PropName, PropValue)
747 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
766 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
788 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
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 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 integer, intent(in) :: cap, nprop, capinc, propinc
830 integer :: error
831 type(Vector), pointer :: this
832
833 nullify(this)
834
835 if (cap < 0) then
836 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
844 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
855 allocate(this%elementData(this%initialCapacity), stat=error)
856 if(error /= 0) write(*,*) 'Could not allocate elementData!'
857
858
859 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
867 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
881 !! This function destroys the vector components....
882 function destroy(this) result(null_this)
883 logical :: done
884 type(Vector), pointer :: this
885 type(Vector), pointer :: null_this
886
887 if (.not. associated(this)) then
888 null_this => null()
889 return
890 end if
891
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 end function destroy
921
922 end module Vector_class