(git:e7e05ae)
submatrix_types.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
9 
10  USE kinds, ONLY: dp
11  USE message_passing, ONLY: mp_request_null,&
12  mp_request_type
13  USE util, ONLY: sort
14 
15  IMPLICIT NONE
16  PRIVATE
17 
18  INTEGER, PARAMETER :: extvec_alloc_factor = 2, extvec_initial_alloc = 32
19  INTEGER, PARAMETER :: set_modulus = 257 ! determines the number of buckets, should be a prime
20 
21  TYPE :: extvec_type
22  INTEGER, DIMENSION(:), ALLOCATABLE :: darr
23  INTEGER :: elements = 0, allocated = 0
24  CONTAINS
25  PROCEDURE :: insert => extvec_insert
26  PROCEDURE :: reset => extvec_reset
27  END TYPE extvec_type
28 
29  TYPE, PUBLIC :: set_type
30  TYPE(extvec_type), DIMENSION(0:set_modulus - 1) :: data
31  INTEGER, DIMENSION(:), ALLOCATABLE :: sorted
32  INTEGER :: elements = 0
33  LOGICAL :: sorted_up_to_date = .false.
34  CONTAINS
35  PROCEDURE :: insert => set_insert
36  PROCEDURE :: reset => set_reset
37  PROCEDURE :: find => set_find
38  PROCEDURE :: get => set_get
39  PROCEDURE :: getall => set_getall
40  PROCEDURE :: update_sorted => set_update_sorted
41  END TYPE set_type
42 
43  TYPE, PUBLIC :: intbuffer_type
44  INTEGER, DIMENSION(:), POINTER :: data
45  INTEGER :: size = 0
46  LOGICAL :: allocated = .false.
47  TYPE(mp_request_type) :: mpi_request = mp_request_null
48  CONTAINS
49  PROCEDURE :: alloc => intbuffer_alloc
50  PROCEDURE :: dealloc => intbuffer_dealloc
51  END TYPE intbuffer_type
52 
53  ! TODO: Make data type generic
54  TYPE, PUBLIC :: buffer_type
55  REAL(kind=dp), DIMENSION(:), POINTER :: data
56  INTEGER :: size = 0
57  LOGICAL :: allocated = .false.
58  TYPE(mp_request_type) :: mpi_request = mp_request_null
59  CONTAINS
60  PROCEDURE :: alloc => buffer_alloc
61  PROCEDURE :: dealloc => buffer_dealloc
62  END TYPE buffer_type
63 
64  TYPE, PUBLIC :: bufptr_type
65  REAL(kind=dp), DIMENSION(:), POINTER :: target => null()
66  END TYPE bufptr_type
67 
68  TYPE, PUBLIC :: setarray_type
69  TYPE(set_type), DIMENSION(:), ALLOCATABLE :: sets
70  END TYPE setarray_type
71 
72 CONTAINS
73 
74 ! **************************************************************************************************
75 !> \brief insert element into extendable vector
76 !> \param this - instance of extvec_type
77 !> \param elem - element to insert
78 ! **************************************************************************************************
79  PURE SUBROUTINE extvec_insert(this, elem)
80  CLASS(extvec_type), INTENT(INOUT) :: this
81  INTEGER, INTENT(IN) :: elem
82  INTEGER, DIMENSION(:), ALLOCATABLE :: tmp
83 
84  IF (this%allocated .EQ. 0) THEN
85  this%allocated = extvec_initial_alloc
86  ALLOCATE (this%darr(this%allocated))
87  ELSE
88  IF (this%elements .EQ. this%allocated) THEN
89  ALLOCATE (tmp(this%allocated))
90  tmp(:) = this%darr
91  DEALLOCATE (this%darr)
92  ALLOCATE (this%darr(this%allocated*extvec_alloc_factor))
93  this%darr(1:this%allocated) = tmp
94  DEALLOCATE (tmp)
95  this%allocated = this%allocated*extvec_alloc_factor
96  END IF
97  END IF
98 
99  this%elements = this%elements + 1
100  this%darr(this%elements) = elem
101  END SUBROUTINE extvec_insert
102 
103 ! **************************************************************************************************
104 !> \brief purge extendable vector and free allocated memory
105 !> \param this - instance of extvec_type
106 ! **************************************************************************************************
107  PURE SUBROUTINE extvec_reset(this)
108  CLASS(extvec_type), INTENT(INOUT) :: this
109 
110  IF (ALLOCATED(this%darr)) DEALLOCATE (this%darr)
111  this%allocated = 0
112  this%elements = 0
113  END SUBROUTINE extvec_reset
114 
115 ! **************************************************************************************************
116 !> \brief insert element into set
117 !> \param this - instance of set_type
118 !> \param elem - element to insert
119 ! **************************************************************************************************
120  PURE SUBROUTINE set_insert(this, elem)
121  CLASS(set_type), INTENT(INOUT) :: this
122  INTEGER, INTENT(IN) :: elem
123 
124  IF (.NOT. this%find(elem)) THEN
125  CALL this%data(modulo(elem, set_modulus))%insert(elem)
126  this%sorted_up_to_date = .false.
127  this%elements = this%elements + 1
128  END IF
129 
130  END SUBROUTINE set_insert
131 
132 ! **************************************************************************************************
133 !> \brief purse set and free allocated memory
134 !> \param this - instance of set_type
135 ! **************************************************************************************************
136  PURE SUBROUTINE set_reset(this)
137  CLASS(set_type), INTENT(INOUT) :: this
138  INTEGER :: i
139 
140  DO i = 0, set_modulus - 1
141  CALL this%data(i)%reset
142  END DO
143  IF (ALLOCATED(this%sorted)) DEALLOCATE (this%sorted)
144  this%elements = 0
145  this%sorted_up_to_date = .false.
146  END SUBROUTINE set_reset
147 
148 ! **************************************************************************************************
149 !> \brief find element in set
150 !> \param this - instance of set_type
151 !> \param elem - element to look for
152 !> \return .TRUE. if element is contained in set, .FALSE. otherwise
153 ! **************************************************************************************************
154  PURE FUNCTION set_find(this, elem) RESULT(found)
155  CLASS(set_type), INTENT(IN) :: this
156  INTEGER, INTENT(IN) :: elem
157  LOGICAL :: found
158  INTEGER :: i, idx
159 
160  found = .false.
161  idx = modulo(elem, set_modulus)
162 
163  DO i = 1, this%data(idx)%elements
164  IF (this%data(idx)%darr(i) .EQ. elem) THEN
165  found = .true.
166  EXIT
167  END IF
168  END DO
169 
170  END FUNCTION set_find
171 
172 ! **************************************************************************************************
173 !> \brief get element from specific position in set
174 !> \param this - instance of set_type
175 !> \param idx - position in set
176 !> \return element at position idx
177 ! **************************************************************************************************
178  FUNCTION set_get(this, idx) RESULT(elem)
179  CLASS(set_type), INTENT(INOUT) :: this
180  INTEGER, INTENT(IN) :: idx
181  INTEGER :: elem
182 
183  IF (.NOT. this%sorted_up_to_date) CALL this%update_sorted
184 
185  elem = this%sorted(idx)
186  END FUNCTION set_get
187 
188 ! **************************************************************************************************
189 !> \brief get all elements in set as sorted list
190 !> \param this - instance of set_type
191 !> \return sorted array containing set elements
192 ! **************************************************************************************************
193  FUNCTION set_getall(this) RESULT(darr)
194  CLASS(set_type), INTENT(INOUT) :: this
195  INTEGER, DIMENSION(this%elements) :: darr
196 
197  IF (.NOT. this%sorted_up_to_date) CALL this%update_sorted
198 
199  darr = this%sorted
200  END FUNCTION set_getall
201 
202 ! **************************************************************************************************
203 !> \brief update internal list of set elements
204 !> \param this - instance of extendable vector
205 ! **************************************************************************************************
206  SUBROUTINE set_update_sorted(this)
207  CLASS(set_type), INTENT(INOUT) :: this
208  INTEGER :: i, idx
209  INTEGER, DIMENSION(:), ALLOCATABLE :: tmp
210 
211  IF (ALLOCATED(this%sorted)) DEALLOCATE (this%sorted)
212  ALLOCATE (this%sorted(this%elements))
213 
214  idx = 1
215  DO i = 0, set_modulus - 1
216  IF (this%data(i)%elements .GT. 0) THEN
217  this%sorted(idx:idx + this%data(i)%elements - 1) = this%data(i)%darr(1:this%data(i)%elements)
218  idx = idx + this%data(i)%elements
219  END IF
220  END DO
221 
222  ALLOCATE (tmp(this%elements))
223  CALL sort(this%sorted, this%elements, tmp)
224  DEALLOCATE (tmp)
225 
226  this%sorted_up_to_date = .true.
227  END SUBROUTINE set_update_sorted
228 
229 ! **************************************************************************************************
230 !> \brief allocate buffer
231 !> \param this - instance of buffer_type
232 !> \param elements - number of elements contained in buffer
233 ! **************************************************************************************************
234  PURE SUBROUTINE buffer_alloc(this, elements)
235  CLASS(buffer_type), INTENT(INOUT) :: this
236  INTEGER, INTENT(IN) :: elements
237 
238  ALLOCATE (this%data(elements))
239  this%allocated = .true.
240  this%size = elements
241  END SUBROUTINE buffer_alloc
242 
243 ! **************************************************************************************************
244 !> \brief deallocate buffer
245 !> \param this - instance of buffer_type
246 ! **************************************************************************************************
247  PURE SUBROUTINE buffer_dealloc(this)
248  CLASS(buffer_type), INTENT(INOUT) :: this
249 
250  IF (this%allocated) DEALLOCATE (this%data)
251  this%allocated = .false.
252  this%size = 0
253  END SUBROUTINE buffer_dealloc
254 
255 ! **************************************************************************************************
256 !> \brief allocate integer buffer
257 !> \param this - instance of intBuffer_type
258 !> \param elements - number of elements contained in buffer
259 ! **************************************************************************************************
260  PURE SUBROUTINE intbuffer_alloc(this, elements)
261  CLASS(intbuffer_type), INTENT(INOUT) :: this
262  INTEGER, INTENT(IN) :: elements
263 
264  ALLOCATE (this%data(elements))
265  this%allocated = .true.
266  this%size = elements
267  END SUBROUTINE intbuffer_alloc
268 
269 ! **************************************************************************************************
270 !> \brief deallocate integer buffer
271 !> \param this - instance of intBuffer_type
272 ! **************************************************************************************************
273  PURE SUBROUTINE intbuffer_dealloc(this)
274  CLASS(intbuffer_type), INTENT(INOUT) :: this
275 
276  IF (this%allocated) DEALLOCATE (this%data)
277  this%allocated = .false.
278  this%size = 0
279  END SUBROUTINE intbuffer_dealloc
280 
281 END MODULE submatrix_types
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Definition: grid_common.h:117
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
Definition: grid_common.h:153
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Interface to the message passing library MPI.
type(mp_request_type), parameter, public mp_request_null
pure subroutine extvec_insert(this, elem)
insert element into extendable vector
All kind of helpful little routines.
Definition: util.F:14