Neko 1.99.5
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
registry_entry.f90
Go to the documentation of this file.
1! Copyright (c) 2025-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
37 use num_types, only : rp
38 use host_array, only : host_array_t
40 use vector, only : vector_t
41 use matrix, only : matrix_t
42 use field, only : field_t
43
44 use dofmap, only : dofmap_t
45 use utils, only : neko_error
46 implicit none
47 private
48
49 type, public :: registry_entry_t
51 character(len=80), private :: name = ""
53 character(len=80), private :: type = ""
55 logical, private :: allocated = .false.
56
57 ! Storage. Only one of these will be allocated at a time.
58 real(kind=rp), private :: real_scalar = 0.0_rp
59 integer, private :: integer_scalar = 0
60 type(host_array_t), private, pointer :: host_array_ptr => null()
61 type(device_array_t), private, pointer :: device_array_ptr => null()
62 type(vector_t), private, pointer :: vector_ptr => null()
63 type(matrix_t), private, pointer :: matrix_ptr => null()
64 type(field_t), private, pointer :: field_ptr => null()
65
66 contains
67 ! Constructors
68 procedure, pass(this) :: init_real_scalar => init_register_real_scalar
69 procedure, pass(this) :: init_integer_scalar => &
71 procedure, pass(this) :: init_host_array => init_register_host_array
72 procedure, pass(this) :: init_device_array => init_register_device_array
73 procedure, pass(this) :: init_vector => init_register_vector
74 procedure, pass(this) :: init_matrix => init_register_matrix
75 procedure, pass(this) :: init_field => init_register_field
77 procedure, pass(this) :: free => free_register
78
80 procedure, pass(this) :: get_name
81 procedure, pass(this) :: get_type
82 procedure, pass(this) :: get_real_scalar
83 procedure, pass(this) :: get_integer_scalar
84 procedure, pass(this) :: get_host_array
85 procedure, pass(this) :: get_device_array
86 procedure, pass(this) :: get_vector
87 procedure, pass(this) :: get_matrix
88 procedure, pass(this) :: get_field
89 procedure, pass(this) :: is_allocated
90
91 procedure, pass(this) :: move_from => move_from_registry_entry
92 end type registry_entry_t
93
94contains
95
97 subroutine init_register_host_array(this, n, name)
98 class(registry_entry_t), intent(inout) :: this
99 integer, intent(in) :: n
100 character(len=*), optional, intent(in) :: name
101
102 if (this%allocated) then
103 call neko_error("init_register_host_array: " // &
104 "Register entry is already allocated.")
105 end if
106
107 call this%free()
108
109 allocate(this%host_array_ptr)
110 call this%host_array_ptr%init(n)
111
112 if (present(name)) this%name = trim(name)
113 this%type = 'host_array'
114 this%allocated = .true.
115
116 end subroutine init_register_host_array
117
119 subroutine init_register_device_array(this, n, name)
120 class(registry_entry_t), intent(inout) :: this
121 integer, intent(in) :: n
122 character(len=*), optional, intent(in) :: name
123
124 if (this%allocated) then
125 call neko_error("init_register_device_array: " // &
126 "Register entry is already allocated.")
127 end if
128
129 call this%free()
130
131 allocate(this%device_array_ptr)
132 call this%device_array_ptr%init(n)
133
134 if (present(name)) this%name = trim(name)
135 this%type = 'device_array'
136 this%allocated = .true.
137
138 end subroutine init_register_device_array
139
141 subroutine init_register_vector(this, n, name)
142 class(registry_entry_t), intent(inout) :: this
143 integer, intent(in) :: n
144 character(len=*), optional, intent(in) :: name
145
146 if (this%allocated) then
147 call neko_error("init_register_vector: " &
148 // "Register entry is already allocated.")
149 end if
150
151 call this%free()
152
153 allocate(this%vector_ptr)
154 call this%vector_ptr%init(n)
155
156 if (present(name)) this%name = trim(name)
157 this%type = 'vector'
158 this%allocated = .true.
159
160 end subroutine init_register_vector
161
163 subroutine init_register_matrix(this, nrows, ncols, name)
164 class(registry_entry_t), intent(inout) :: this
165 integer, intent(in) :: nrows, ncols
166 character(len=*), optional, intent(in) :: name
167
168 if (this%allocated) then
169 call neko_error("init_register_matrix: " &
170 // "Register entry is already allocated.")
171 end if
172
173 call this%free()
174
175 allocate(this%matrix_ptr)
176 call this%matrix_ptr%init(nrows, ncols)
177
178 if (present(name)) this%name = trim(name)
179 this%type = 'matrix'
180 this%allocated = .true.
181
182 end subroutine init_register_matrix
183
185 subroutine init_register_field(this, dof, name)
186 class(registry_entry_t), intent(inout) :: this
187 type(dofmap_t), target, intent(in) :: dof
188 character(len=*), intent(in) :: name
189
190 if (this%allocated) then
191 call neko_error("init_register_field: " &
192 // "Register entry is already allocated.")
193 end if
194
195 call this%free()
196
197 allocate(this%field_ptr)
198 call this%field_ptr%init(dof, trim(name))
199
200 this%name = trim(name)
201 this%type = 'field'
202 this%allocated = .true.
203
204 end subroutine init_register_field
205
207 subroutine init_register_real_scalar(this, val, name)
208 class(registry_entry_t), intent(inout) :: this
209 real(kind=rp), intent(in) :: val
210 character(len=*), optional, intent(in) :: name
211
212 if (this%allocated) then
213 call neko_error("init_register_real_scalar: " &
214 // "Register entry is already allocated.")
215 end if
216
217 call this%free()
218
219 this%real_scalar = val
220
221 if (present(name)) this%name = trim(name)
222 this%type = 'real_scalar'
223 this%allocated = .true.
224
225 end subroutine init_register_real_scalar
226
228 subroutine init_register_integer_scalar(this, val, name)
229 class(registry_entry_t), intent(inout) :: this
230 integer, intent(in) :: val
231 character(len=*), optional, intent(in) :: name
232
233 if (this%allocated) then
234 call neko_error("init_register_integer_scalar: " &
235 // "Register entry is already allocated.")
236 end if
237
238 call this%free()
239
240 this%integer_scalar = val
241
242 if (present(name)) this%name = trim(name)
243 this%type = 'integer_scalar'
244 this%allocated = .true.
245
246 end subroutine init_register_integer_scalar
247
249 subroutine free_register(this)
250 class(registry_entry_t), intent(inout) :: this
251
252 if (associated(this%host_array_ptr)) then
253 call this%host_array_ptr%free()
254 deallocate(this%host_array_ptr)
255 end if
256
257 if (associated(this%device_array_ptr)) then
258 call this%device_array_ptr%free()
259 deallocate(this%device_array_ptr)
260 end if
261
262 if (associated(this%vector_ptr)) then
263 call this%vector_ptr%free()
264 deallocate(this%vector_ptr)
265 end if
266
267 if (associated(this%matrix_ptr)) then
268 call this%matrix_ptr%free()
269 deallocate(this%matrix_ptr)
270 end if
271
272 if (associated(this%field_ptr)) then
273 call this%field_ptr%free()
274 deallocate(this%field_ptr)
275 end if
276
277 this%real_scalar = 0.0_rp
278 this%integer_scalar = 0
279
280 this%name = ""
281 this%type = ""
282 this%allocated = .false.
283
284 end subroutine free_register
285
287 pure function get_name(this) result(name)
288 class(registry_entry_t), intent(in) :: this
289 character(len=:), allocatable :: name
290 name = trim(this%name)
291 end function get_name
292
294 pure function get_type(this) result(type)
295 class(registry_entry_t), intent(in) :: this
296 character(len=:), allocatable :: type
297 type = trim(this%type)
298 end function get_type
299
301 pure function is_allocated(this) result(allocated)
302 class(registry_entry_t), intent(in) :: this
303 logical :: allocated
304 allocated = this%allocated
305 end function is_allocated
306
307
309 function get_host_array(this) result(host_array_ptr)
310 class(registry_entry_t), target, intent(in) :: this
311 type(host_array_t), pointer :: host_array_ptr
312 if (this%get_type() .ne. 'host_array') then
313 call neko_error("registry_entry::get_host_array: " &
314 // "Registry entry is not of type 'host_array'.")
315 end if
316 host_array_ptr => this%host_array_ptr
317 end function get_host_array
318
320 function get_device_array(this) result(device_array_ptr)
321 class(registry_entry_t), target, intent(in) :: this
322 type(device_array_t), pointer :: device_array_ptr
323 if (this%get_type() .ne. 'device_array') then
324 call neko_error("registry_entry::get_device_array: " &
325 // "Registry entry is not of type 'device_array'.")
326 end if
327 device_array_ptr => this%device_array_ptr
328 end function get_device_array
329
331 function get_vector(this) result(vector_ptr)
332 class(registry_entry_t), target, intent(in) :: this
333 type(vector_t), pointer :: vector_ptr
334 if (this%get_type() .ne. 'vector') then
335 call neko_error("registry_entry::get_vector: " &
336 // "Registry entry is not of type 'vector'.")
337 end if
338 vector_ptr => this%vector_ptr
339 end function get_vector
340
342 function get_matrix(this) result(matrix_ptr)
343 class(registry_entry_t), target, intent(in) :: this
344 type(matrix_t), pointer :: matrix_ptr
345 if (this%get_type() .ne. 'matrix') then
346 call neko_error("registry_entry::get_field: " &
347 // "Registry entry is not of type 'matrix'.")
348 end if
349 matrix_ptr => this%matrix_ptr
350 end function get_matrix
351
353 function get_field(this) result(field_ptr)
354 class(registry_entry_t), target, intent(in) :: this
355 type(field_t), pointer :: field_ptr
356 if (this%get_type() .ne. 'field') then
357 call neko_error("registry_entry::get_field: " &
358 // "Registry entry is not of type 'field'.")
359 end if
360 field_ptr => this%field_ptr
361 end function get_field
362
364 function get_real_scalar(this) result(scalar_ptr)
365 class(registry_entry_t), target, intent(in) :: this
366 real(kind=rp), pointer :: scalar_ptr
367 if (this%get_type() .ne. 'real_scalar') then
368 call neko_error("registry_entry::get_real_scalar: " &
369 // "Registry entry is not of type 'real_scalar'.")
370 end if
371 scalar_ptr => this%real_scalar
372 end function get_real_scalar
373
375 function get_integer_scalar(this) result(scalar_ptr)
376 class(registry_entry_t), target, intent(in) :: this
377 integer, pointer :: scalar_ptr
378 if (this%get_type() .ne. 'integer_scalar') then
379 call neko_error("registry_entry::get_integer_scalar: " &
380 // "Registry entry is not of type 'integer_scalar'.")
381 end if
382 scalar_ptr => this%integer_scalar
383 end function get_integer_scalar
384
386 subroutine move_from_registry_entry(this, source)
387 class(registry_entry_t), intent(inout) :: this
388 class(registry_entry_t), intent(inout) :: source
389
390 if (.not. source%is_allocated()) return
391 call this%free()
392
393 this%name = source%name
394 this%type = source%type
395 this%allocated = source%allocated
396
397 select case (trim(this%type))
398 case ('real_scalar')
399 this%real_scalar = source%real_scalar
400 case ('integer_scalar')
401 this%integer_scalar = source%integer_scalar
402 case ('host_array')
403 this%host_array_ptr => source%host_array_ptr
404 nullify(source%host_array_ptr)
405 case ('device_array')
406 this%device_array_ptr => source%device_array_ptr
407 nullify(source%device_array_ptr)
408 case ('vector')
409 this%vector_ptr => source%vector_ptr
410 nullify(source%vector_ptr)
411 case ('matrix')
412 this%matrix_ptr => source%matrix_ptr
413 nullify(source%matrix_ptr)
414 case ('field')
415 this%field_ptr => source%field_ptr
416 nullify(source%field_ptr)
417 case default
418 call neko_error("move_from_registry_entry: " // &
419 "Unsupported registry entry type: " // trim(this%type))
420 end select
421
422 ! Free the source entry after moving
423 call source%free()
424
425 end subroutine move_from_registry_entry
426end module registry_entry
Module containing device only array type.
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Defines a field.
Definition field.f90:34
Module containing host-only array type.
Defines a matrix.
Definition matrix.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Defines a registry entry for storing and requesting temporary objects This is used in the registries ...
real(kind=rp) function, pointer get_real_scalar(this)
Get the real scalar pointer of the registry entry.
subroutine init_register_field(this, dof, name)
Initialize a register entry.
subroutine init_register_host_array(this, n, name)
Initialize by a host array.
pure character(len=:) function, allocatable get_name(this)
Get the name of the registry entry.
subroutine init_register_device_array(this, n, name)
Initialize by a device array.
subroutine init_register_real_scalar(this, val, name)
Initialize a scalar register entry.
subroutine init_register_matrix(this, nrows, ncols, name)
Initialize a register entry.
type(device_array_t) function, pointer get_device_array(this)
Get the device_array pointer of the registry entry.
subroutine init_register_vector(this, n, name)
Initialize a register entry.
subroutine init_register_integer_scalar(this, val, name)
Initialize an integer scalar register entry.
subroutine move_from_registry_entry(this, source)
Move a registry entry from another entry.
type(field_t) function, pointer get_field(this)
Get the field pointer of the registry entry.
subroutine free_register(this)
Free a register entry.
type(host_array_t) function, pointer get_host_array(this)
Get the host array pointer of the registry entry.
pure logical function is_allocated(this)
Check if the registry entry is allocated.
type(vector_t) function, pointer get_vector(this)
Get the vector pointer of the registry entry.
type(matrix_t) function, pointer get_matrix(this)
Get the matrix pointer of the registry entry.
pure character(len=:) function, allocatable get_type(this)
Get the type of the registry entry.
integer function, pointer get_integer_scalar(this)
Get the integer scalar pointer of the registry entry.
Utilities.
Definition utils.f90:35
Defines a vector.
Definition vector.f90:34
Device-only temporary array.
Host-only temporary array.