ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/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

# 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.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
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