Neko 1.99.3
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 => init_register_integer_scalar
70 procedure, pass(this) :: init_host_array => init_register_host_array
71 procedure, pass(this) :: init_device_array => init_register_device_array
72 procedure, pass(this) :: init_vector => init_register_vector
73 procedure, pass(this) :: init_matrix => init_register_matrix
74 procedure, pass(this) :: init_field => init_register_field
76 procedure, pass(this) :: free => free_register
77
79 procedure, pass(this) :: get_name
80 procedure, pass(this) :: get_type
81 procedure, pass(this) :: get_real_scalar
82 procedure, pass(this) :: get_integer_scalar
83 procedure, pass(this) :: get_host_array
84 procedure, pass(this) :: get_device_array
85 procedure, pass(this) :: get_vector
86 procedure, pass(this) :: get_matrix
87 procedure, pass(this) :: get_field
88 procedure, pass(this) :: is_allocated
89
90 procedure, pass(this) :: move_from => move_from_registry_entry
91 end type registry_entry_t
92
93contains
94
96 subroutine init_register_host_array(this, n, name)
97 class(registry_entry_t), intent(inout) :: this
98 integer, intent(in) :: n
99 character(len=*), optional, intent(in) :: name
100
101 if (this%allocated) then
102 call neko_error("init_register_host_array: " // &
103 "Register entry is already allocated.")
104 end if
105
106 call this%free()
107
108 allocate(this%host_array_ptr)
109 call this%host_array_ptr%init(n)
110
111 if (present(name)) this%name = trim(name)
112 this%type = 'host_array'
113 this%allocated = .true.
114
115 end subroutine init_register_host_array
116
118 subroutine init_register_device_array(this, n, name)
119 class(registry_entry_t), intent(inout) :: this
120 integer, intent(in) :: n
121 character(len=*), optional, intent(in) :: name
122
123 if (this%allocated) then
124 call neko_error("init_register_device_array: " // &
125 "Register entry is already allocated.")
126 end if
127
128 call this%free()
129
130 allocate(this%device_array_ptr)
131 call this%device_array_ptr%init(n)
132
133 if (present(name)) this%name = trim(name)
134 this%type = 'device_array'
135 this%allocated = .true.
136
137 end subroutine init_register_device_array
138
140 subroutine init_register_vector(this, n, name)
141 class(registry_entry_t), intent(inout) :: this
142 integer, intent(in) :: n
143 character(len=*), optional, intent(in) :: name
144
145 if (this%allocated) then
146 call neko_error("init_register_vector: " &
147 // "Register entry is already allocated.")
148 end if
149
150 call this%free()
151
152 allocate(this%vector_ptr)
153 call this%vector_ptr%init(n)
154
155 if (present(name)) this%name = trim(name)
156 this%type = 'vector'
157 this%allocated = .true.
158
159 end subroutine init_register_vector
160
162 subroutine init_register_matrix(this, nrows, ncols, name)
163 class(registry_entry_t), intent(inout) :: this
164 integer, intent(in) :: nrows, ncols
165 character(len=*), optional, intent(in) :: name
166
167 if (this%allocated) then
168 call neko_error("init_register_matrix: " &
169 // "Register entry is already allocated.")
170 end if
171
172 call this%free()
173
174 allocate(this%matrix_ptr)
175 call this%matrix_ptr%init(nrows, ncols)
176
177 if (present(name)) this%name = trim(name)
178 this%type = 'matrix'
179 this%allocated = .true.
180
181 end subroutine init_register_matrix
182
184 subroutine init_register_field(this, dof, name)
185 class(registry_entry_t), intent(inout) :: this
186 type(dofmap_t), target, intent(in) :: dof
187 character(len=*), intent(in) :: name
188
189 if (this%allocated) then
190 call neko_error("init_register_field: " &
191 // "Register entry is already allocated.")
192 end if
193
194 call this%free()
195
196 allocate(this%field_ptr)
197 call this%field_ptr%init(dof, trim(name))
198
199 this%name = trim(name)
200 this%type = 'field'
201 this%allocated = .true.
202
203 end subroutine init_register_field
204
206 subroutine init_register_real_scalar(this, val, name)
207 class(registry_entry_t), intent(inout) :: this
208 real(kind=rp), intent(in) :: val
209 character(len=*), optional, intent(in) :: name
210
211 if (this%allocated) then
212 call neko_error("init_register_real_scalar: " &
213 // "Register entry is already allocated.")
214 end if
215
216 call this%free()
217
218 this%real_scalar = val
219
220 if (present(name)) this%name = trim(name)
221 this%type = 'real_scalar'
222 this%allocated = .true.
223
224 end subroutine init_register_real_scalar
225
227 subroutine init_register_integer_scalar(this, val, name)
228 class(registry_entry_t), intent(inout) :: this
229 integer, intent(in) :: val
230 character(len=*), optional, intent(in) :: name
231
232 if (this%allocated) then
233 call neko_error("init_register_integer_scalar: " &
234 // "Register entry is already allocated.")
235 end if
236
237 call this%free()
238
239 this%integer_scalar = val
240
241 if (present(name)) this%name = trim(name)
242 this%type = 'integer_scalar'
243 this%allocated = .true.
244
245 end subroutine init_register_integer_scalar
246
248 subroutine free_register(this)
249 class(registry_entry_t), intent(inout) :: this
250
251 if (associated(this%host_array_ptr)) then
252 call this%host_array_ptr%free()
253 deallocate(this%host_array_ptr)
254 end if
255
256 if (associated(this%device_array_ptr)) then
257 call this%device_array_ptr%free()
258 deallocate(this%device_array_ptr)
259 end if
260
261 if (associated(this%vector_ptr)) then
262 call this%vector_ptr%free()
263 deallocate(this%vector_ptr)
264 end if
265
266 if (associated(this%matrix_ptr)) then
267 call this%matrix_ptr%free()
268 deallocate(this%matrix_ptr)
269 end if
270
271 if (associated(this%field_ptr)) then
272 call this%field_ptr%free()
273 deallocate(this%field_ptr)
274 end if
275
276 this%real_scalar = 0.0_rp
277 this%integer_scalar = 0
278
279 this%name = ""
280 this%type = ""
281 this%allocated = .false.
282
283 end subroutine free_register
284
286 pure function get_name(this) result(name)
287 class(registry_entry_t), intent(in) :: this
288 character(len=:), allocatable :: name
289 name = trim(this%name)
290 end function get_name
291
293 pure function get_type(this) result(type)
294 class(registry_entry_t), intent(in) :: this
295 character(len=:), allocatable :: type
296 type = trim(this%type)
297 end function get_type
298
300 pure function is_allocated(this) result(allocated)
301 class(registry_entry_t), intent(in) :: this
302 logical :: allocated
303 allocated = this%allocated
304 end function is_allocated
305
306
308 function get_host_array(this) result(host_array_ptr)
309 class(registry_entry_t), target, intent(in) :: this
310 type(host_array_t), pointer :: host_array_ptr
311 if (this%get_type() .ne. 'host_array') then
312 call neko_error("registry_entry::get_host_array: " &
313 // "Registry entry is not of type 'host_array'.")
314 end if
315 host_array_ptr => this%host_array_ptr
316 end function get_host_array
317
319 function get_device_array(this) result(device_array_ptr)
320 class(registry_entry_t), target, intent(in) :: this
321 type(device_array_t), pointer :: device_array_ptr
322 if (this%get_type() .ne. 'device_array') then
323 call neko_error("registry_entry::get_device_array: " &
324 // "Registry entry is not of type 'device_array'.")
325 end if
326 device_array_ptr => this%device_array_ptr
327 end function get_device_array
328
330 function get_vector(this) result(vector_ptr)
331 class(registry_entry_t), target, intent(in) :: this
332 type(vector_t), pointer :: vector_ptr
333 if (this%get_type() .ne. 'vector') then
334 call neko_error("registry_entry::get_vector: " &
335 // "Registry entry is not of type 'vector'.")
336 end if
337 vector_ptr => this%vector_ptr
338 end function get_vector
339
341 function get_matrix(this) result(matrix_ptr)
342 class(registry_entry_t), target, intent(in) :: this
343 type(matrix_t), pointer :: matrix_ptr
344 if (this%get_type() .ne. 'matrix') then
345 call neko_error("registry_entry::get_field: " &
346 // "Registry entry is not of type 'matrix'.")
347 end if
348 matrix_ptr => this%matrix_ptr
349 end function get_matrix
350
352 function get_field(this) result(field_ptr)
353 class(registry_entry_t), target, intent(in) :: this
354 type(field_t), pointer :: field_ptr
355 if (this%get_type() .ne. 'field') then
356 call neko_error("registry_entry::get_field: " &
357 // "Registry entry is not of type 'field'.")
358 end if
359 field_ptr => this%field_ptr
360 end function get_field
361
363 function get_real_scalar(this) result(scalar_ptr)
364 class(registry_entry_t), target, intent(in) :: this
365 real(kind=rp), pointer :: scalar_ptr
366 if (this%get_type() .ne. 'real_scalar') then
367 call neko_error("registry_entry::get_real_scalar: " &
368 // "Registry entry is not of type 'real_scalar'.")
369 end if
370 scalar_ptr => this%real_scalar
371 end function get_real_scalar
372
374 function get_integer_scalar(this) result(scalar_ptr)
375 class(registry_entry_t), target, intent(in) :: this
376 integer, pointer :: scalar_ptr
377 if (this%get_type() .ne. 'integer_scalar') then
378 call neko_error("registry_entry::get_integer_scalar: " &
379 // "Registry entry is not of type 'integer_scalar'.")
380 end if
381 scalar_ptr => this%integer_scalar
382 end function get_integer_scalar
383
385 subroutine move_from_registry_entry(this, source)
386 class(registry_entry_t), intent(inout) :: this
387 class(registry_entry_t), intent(inout) :: source
388
389 if (.not. source%is_allocated()) return
390 call this%free()
391
392 this%name = source%name
393 this%type = source%type
394 this%allocated = source%allocated
395
396 select case (trim(this%type))
397 case ('real_scalar')
398 this%real_scalar = source%real_scalar
399 case ('integer_scalar')
400 this%integer_scalar = source%integer_scalar
401 case ('host_array')
402 this%host_array_ptr => source%host_array_ptr
403 nullify(source%host_array_ptr)
404 case ('device_array')
405 this%device_array_ptr => source%device_array_ptr
406 nullify(source%device_array_ptr)
407 case ('vector')
408 this%vector_ptr => source%vector_ptr
409 nullify(source%vector_ptr)
410 case ('matrix')
411 this%matrix_ptr => source%matrix_ptr
412 nullify(source%matrix_ptr)
413 case ('field')
414 this%field_ptr => source%field_ptr
415 nullify(source%field_ptr)
416 case default
417 call neko_error("move_from_registry_entry: " // &
418 "Unsupported registry entry type: " // trim(this%type))
419 end select
420
421 ! Free the source entry after moving
422 call source%free()
423
424 end subroutine move_from_registry_entry
425end 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.