Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SourceIMP/utilities/RocfracPrep/GENII_LinkedList.f90
Go to the documentation of this file.
1 !*********************************************************************
2 !* Illinois Open Source License *
3 !* *
4 !* University of Illinois/NCSA *
5 !* Open Source License *
6 !* *
7 !* Copyright@2008, University of Illinois. All rights reserved. *
8 !* *
9 !* Developed by: *
10 !* *
11 !* Center for Simulation of Advanced Rockets *
12 !* *
13 !* University of Illinois *
14 !* *
15 !* www.csar.uiuc.edu *
16 !* *
17 !* Permission is hereby granted, free of charge, to any person *
18 !* obtaining a copy of this software and associated documentation *
19 !* files (the "Software"), to deal with the Software without *
20 !* restriction, including without limitation the rights to use, *
21 !* copy, modify, merge, publish, distribute, sublicense, and/or *
22 !* sell copies of the Software, and to permit persons to whom the *
23 !* Software is furnished to do so, subject to the following *
24 !* conditions: *
25 !* *
26 !* *
27 !* @ Redistributions of source code must retain the above copyright *
28 !* notice, this list of conditions and the following disclaimers. *
29 !* *
30 !* @ Redistributions in binary form must reproduce the above *
31 !* copyright notice, this list of conditions and the following *
32 !* disclaimers in the documentation and/or other materials *
33 !* provided with the distribution. *
34 !* *
35 !* @ Neither the names of the Center for Simulation of Advanced *
36 !* Rockets, the University of Illinois, nor the names of its *
37 !* contributors may be used to endorse or promote products derived *
38 !* from this Software without specific prior written permission. *
39 !* *
40 !* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
41 !* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
42 !* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
43 !* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
44 !* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
45 !* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
46 !* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
47 !* USE OR OTHER DEALINGS WITH THE SOFTWARE. *
48 !*********************************************************************
49 !* Please acknowledge The University of Illinois Center for *
50 !* Simulation of Advanced Rockets in works and publications *
51 !* resulting from this software or its derivatives. *
52 !*********************************************************************
53 ! The problem is how to treat generic lists in Fortran 90.
54 ! Lists can be (1) homogeneous (elements all of the same type) or
55 ! (2) heterogeneous.
56 !
57 ! (1) Often there is a need to work with many (homogeneous) lists which
58 ! may be of different types. Patrice Lignelet has shown how generic list
59 ! properties may be logically treated in Fortran 90. However it still
60 ! appears that the list operations (initialization, addition/removal of
61 ! elements etc) must be separately defined for each list type, which
62 ! leads to considerable duplication of code.
63 !
64 ! (2) Jean Vezina has shown how to handle a heterogeneous list by employing the
65 ! F90 TRANSFER() function.
66 !
67 ! Peter McGavin at Industrial Research Limited (p.mcgavin@irl.cri.nz)
68 ! has constructed a species of generic list for Fortran 90. The method
69 ! is based on 2 ideas: the properties of the TRANSFER() function, and
70 ! the fact that a pointer to a derived data type also points to the
71 ! *first field* within the data type (and conversely).
72 !
73 ! Since the TRANSFER() function does not accept pointer arguments the
74 ! method requires the introduction of 2 auxilliary data types which
75 ! contain the pointers, one in the generic list module and one for each
76 ! list type in the calling program (the same construction is adopted
77 ! when defining "arrays of pointers"). In spite of this complication the
78 ! method represents a big saving, both conceptually and practically, when
79 ! many lists of different types are involved.
80 !
81 ! To make clear the method we present a simple generic list module
82 ! together with a calling program. The list module defines a
83 ! uni-directional linked list with a few sample operations, but
84 ! obviously more complicated generic lists could be substituted in its
85 ! place (eg include back pointers).
86 !
87 ! Roger Young
88 ! Peter McGavin
89 !
90 ! .........................................................................
91 
93 ! Defines a generic uni-directional linked list with a few sample operations
94 
95 IMPLICIT NONE
96 
97 PRIVATE
98 
99 PUBLIC :: &
100  link_type, &! Put a Link_Type field first in your structure
101  link_ptr_type, &! Mold this to and from your type ptr with TRANSFER
102  list_type ! You should declare a List_Type variable
103 
104 PUBLIC :: &
105  li_init_list, &! Initialise the List_Type variable before use
106  li_get_head, &! Returns the first Link in the list
107  li_get_next, &! Return the next Link after a given one
108  li_add_to_head, &! Add a Link to the head of the list
109  li_remove_head, &! Remove the first Link and return it
110  li_get_len, &! Compute list length
111  li_associated, &! Check if list member is associated
112  li_check_list ! Aborts program if list is invalid or corrupt
113 
115  PRIVATE
116  TYPE(link_type), POINTER :: Next
117 END TYPE link_type
118 
119 ! Auxilliary data type required for the transfer function
120 TYPE link_ptr_type ! Use TRANSFER() function to mold Link_Ptr_Type
121  PRIVATE ! to your pointer type and vice versa
122  TYPE(link_type), POINTER :: P
123 END TYPE link_ptr_type
124 
126  PRIVATE
127  TYPE(link_type) :: Head ! Dummy Link always at head of list
128 END TYPE list_type
129 
130 CONTAINS
131 
132 !-----------------------------------------------------------------------
133 SUBROUTINE abort(Message)
134 IMPLICIT NONE
135 CHARACTER *(*) message
136 
137 WRITE(6,*) message
138 WRITE(6,*) 'Program aborted'
139 stop
140 
141 END SUBROUTINE abort
142 
143 !-----------------------------------------------------------------------
144 SUBROUTINE li_check_list(List,Message)
145 IMPLICIT NONE
146 TYPE(list_type) list
147 CHARACTER *(*) message
148 
149 IF(.NOT.ASSOCIATED(list%Head%Next))THEN
150  WRITE(6,*) message
151  CALL abort('List is not initialised in call to LI_Check_List()')
152 ENDIF
153 
154 END SUBROUTINE li_check_list
155 
156 !-----------------------------------------------------------------------
157 SUBROUTINE li_init_list(List)
158  IMPLICIT NONE
159  integer :: numprocs
160  TYPE(list_type),INTENT(INOUT),TARGET :: list
161 
162  nullify(list%Head%Next)
163 
164  RETURN
165 END SUBROUTINE li_init_list
166 
167 !-----------------------------------------------------------------------
168 SUBROUTINE li_add_to_head(Link,List)
169  IMPLICIT NONE
170  TYPE(list_type),INTENT(INOUT) :: list
171  TYPE(link_ptr_type),INTENT(INOUT) :: link
172 
173  link%P%Next => list%Head%Next
174  list%Head%Next => link%P
175 
176  RETURN
177 END SUBROUTINE li_add_to_head
178 
179 !-----------------------------------------------------------------------
180 INTEGER FUNCTION li_get_len(List)
181  IMPLICIT NONE
182  TYPE(list_type), INTENT(IN),TARGET :: list
183  TYPE(link_ptr_type) :: link
184  INTEGER n
185 
186  link%P => list%Head
187  n = 0
188  DO WHILE(ASSOCIATED(link%P%Next))
189  link%P => link%P%Next
190  n = n+1
191  ENDDO
192  li_get_len = n
193 
194  RETURN
195 END FUNCTION li_get_len
196 
197 !-----------------------------------------------------------------------
198 FUNCTION li_associated(Link)
199  IMPLICIT NONE
200  LOGICAL :: li_associated
201  TYPE(link_ptr_type),INTENT(IN) :: link
202 
203  li_associated = .false.
204  IF(ASSOCIATED(link%P))li_associated=.true.
205 
206  RETURN
207 END FUNCTION li_associated
208 
209 !-----------------------------------------------------------------------
210 FUNCTION li_get_next(Link)
211  IMPLICIT NONE
212  Type(link_ptr_type) :: li_get_next
213  TYPE(link_ptr_type),INTENT(IN) :: link
214 
215  IF(.NOT.ASSOCIATED(link%P%Next))THEN
216  nullify(li_get_next%P)
217  ELSE
218  li_get_next%P => link%P%Next
219  ENDIF
220 
221  RETURN
222 END FUNCTION li_get_next
223 
224 !-----------------------------------------------------------------------
225 FUNCTION li_get_head(List)
226  IMPLICIT NONE
227  TYPE(link_ptr_type) :: li_get_head
228  TYPE(list_type),INTENT(IN),TARGET :: list
229 
230  li_get_head%P => list%Head%Next
231 
232  RETURN
233 END FUNCTION li_get_head
234 
235 !-----------------------------------------------------------------------
236 FUNCTION li_remove_head(List)
237  IMPLICIT NONE
239  TYPE(list_type),INTENT(INOUT),TARGET :: list
240  TYPE(link_ptr_type) :: link
241 
242  link%P => list%Head%Next
243  IF(ASSOCIATED(link%P))THEN
244  list%Head%Next => link%P%Next
245  nullify(link%P%Next)
246  ENDIF
247  li_remove_head%P => link%P
248 
249  RETURN
250 END FUNCTION li_remove_head
251 
252 !-----------------------------------------------------------------------
253 END MODULE generic_list
254 
255 
static void abort(int ierr)
Definition: Roccom_base.C:205
subroutine, public li_add_to_head(Link, List)
type(link_ptr_type) function, public li_get_head(List)
subroutine, public li_check_list(List, Message)
logical function, public li_associated(Link)
const NT & n
type(link_ptr_type) function, public li_get_next(Link)
type(link_ptr_type) function, public li_remove_head(List)