Neko 1.99.9
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 tensor3, only : tensor3_t
43 use tensor4, only : tensor4_t
44 use field, only : field_t
45
46 use dofmap, only : dofmap_t
47 use utils, only : neko_error
48 implicit none
49 private
50
51 type, public :: registry_entry_t
53 character(len=80), private :: name = ""
55 character(len=80), private :: type = ""
57 logical, private :: allocated = .false.
58
59 ! Storage. Only one of these will be allocated at a time.
60 real(kind=rp), private :: real_scalar = 0.0_rp
61 integer, private :: integer_scalar = 0
62
63 ! Array objects
64 type(host_array_t), private, pointer :: host_array_ptr => null()
65 type(device_array_t), private, pointer :: device_array_ptr => null()
66
67 ! Mathematical objects
68 type(vector_t), private, pointer :: vector_ptr => null()
69 type(matrix_t), private, pointer :: matrix_ptr => null()
70 type(tensor3_t), private, pointer :: tensor3_ptr => null()
71 type(tensor4_t), private, pointer :: tensor4_ptr => null()
72
73 ! Complex objects
74 type(field_t), private, pointer :: field_ptr => null()
75
76 contains
77 ! Constructors
78 procedure, pass(this) :: init_real_scalar => init_register_real_scalar
79 procedure, pass(this) :: init_integer_scalar => &
81 procedure, pass(this) :: init_host_array => init_register_host_array
82 procedure, pass(this) :: init_device_array => init_register_device_array
83 procedure, pass(this) :: init_vector => init_register_vector
84 procedure, pass(this) :: init_matrix => init_register_matrix
85 procedure, pass(this) :: init_tensor3 => init_register_tensor3
86 procedure, pass(this) :: init_tensor4 => init_register_tensor4
87 procedure, pass(this) :: init_field => init_register_field
88
90 procedure, pass(this) :: free => free_register
91
93 procedure, pass(this) :: get_name
94 procedure, pass(this) :: get_type
95 procedure, pass(this) :: get_real_scalar
96 procedure, pass(this) :: get_integer_scalar
97 procedure, pass(this) :: get_host_array
98 procedure, pass(this) :: get_device_array
99 procedure, pass(this) :: get_vector
100 procedure, pass(this) :: get_matrix
101 procedure, pass(this) :: get_tensor3
102 procedure, pass(this) :: get_tensor4
103 procedure, pass(this) :: get_field
104
105 procedure, pass(this) :: is_allocated
106 procedure, pass(this) :: move_from => move_from_registry_entry
107 end type registry_entry_t
108
109contains
110
112 subroutine init_register_host_array(this, n, name)
113 class(registry_entry_t), intent(inout) :: this
114 integer, intent(in) :: n
115 character(len=*), optional, intent(in) :: name
116
117 if (this%allocated) then
118 call neko_error("init_register_host_array: " // &
119 "Register entry is already allocated.")
120 end if
121
122 call this%free()
123
124 allocate(this%host_array_ptr)
125 call this%host_array_ptr%init(n)
126
127 if (present(name)) this%name = trim(name)
128 this%type = 'host_array'
129 this%allocated = .true.
130
131 end subroutine init_register_host_array
132
134 subroutine init_register_device_array(this, n, name)
135 class(registry_entry_t), intent(inout) :: this
136 integer, intent(in) :: n
137 character(len=*), optional, intent(in) :: name
138
139 if (this%allocated) then
140 call neko_error("init_register_device_array: " // &
141 "Register entry is already allocated.")
142 end if
143
144 call this%free()
145
146 allocate(this%device_array_ptr)
147 call this%device_array_ptr%init(n)
148
149 if (present(name)) this%name = trim(name)
150 this%type = 'device_array'
151 this%allocated = .true.
152
153 end subroutine init_register_device_array
154
156 subroutine init_register_vector(this, n, name)
157 class(registry_entry_t), intent(inout) :: this
158 integer, intent(in) :: n
159 character(len=*), optional, intent(in) :: name
160
161 if (this%allocated) then
162 call neko_error("init_register_vector: " &
163 // "Register entry is already allocated.")
164 end if
165
166 call this%free()
167
168 allocate(this%vector_ptr)
169 call this%vector_ptr%init(n)
170
171 if (present(name)) this%name = trim(name)
172 this%type = 'vector'
173 this%allocated = .true.
174
175 end subroutine init_register_vector
176
178 subroutine init_register_matrix(this, nrows, ncols, name)
179 class(registry_entry_t), intent(inout) :: this
180 integer, intent(in) :: nrows, ncols
181 character(len=*), optional, intent(in) :: name
182
183 if (this%allocated) then
184 call neko_error("init_register_matrix: " &
185 // "Register entry is already allocated.")
186 end if
187
188 call this%free()
189
190 allocate(this%matrix_ptr)
191 call this%matrix_ptr%init(nrows, ncols)
192
193 if (present(name)) this%name = trim(name)
194 this%type = 'matrix'
195 this%allocated = .true.
196
197 end subroutine init_register_matrix
198
200 subroutine init_register_tensor3(this, n, m, l, name)
201 class(registry_entry_t), intent(inout) :: this
202 integer, intent(in) :: n, m, l
203 character(len=*), optional, intent(in) :: name
204
205 if (this%allocated) then
206 call neko_error("init_register_tensor3: " &
207 // "Register entry is already allocated.")
208 end if
209
210 call this%free()
211
212 allocate(this%tensor3_ptr)
213 call this%tensor3_ptr%init(n, m, l)
214
215 if (present(name)) this%name = trim(name)
216 this%type = 'tensor3'
217 this%allocated = .true.
218
219 end subroutine init_register_tensor3
220
222 subroutine init_register_tensor4(this, n, m, l, k, name)
223 class(registry_entry_t), intent(inout) :: this
224 integer, intent(in) :: n, m, l, k
225 character(len=*), optional, intent(in) :: name
226
227 if (this%allocated) then
228 call neko_error("init_register_tensor4: " &
229 // "Register entry is already allocated.")
230 end if
231
232 call this%free()
233
234 allocate(this%tensor4_ptr)
235 call this%tensor4_ptr%init(n, m, l, k)
236
237 if (present(name)) this%name = trim(name)
238 this%type = 'tensor4'
239 this%allocated = .true.
240
241 end subroutine init_register_tensor4
242
244 subroutine init_register_field(this, dof, name)
245 class(registry_entry_t), intent(inout) :: this
246 type(dofmap_t), target, intent(in) :: dof
247 character(len=*), intent(in) :: name
248
249 if (this%allocated) then
250 call neko_error("init_register_field: " &
251 // "Register entry is already allocated.")
252 end if
253
254 call this%free()
255
256 allocate(this%field_ptr)
257 call this%field_ptr%init(dof, trim(name))
258
259 this%name = trim(name)
260 this%type = 'field'
261 this%allocated = .true.
262
263 end subroutine init_register_field
264
266 subroutine init_register_real_scalar(this, val, name)
267 class(registry_entry_t), intent(inout) :: this
268 real(kind=rp), intent(in) :: val
269 character(len=*), optional, intent(in) :: name
270
271 if (this%allocated) then
272 call neko_error("init_register_real_scalar: " &
273 // "Register entry is already allocated.")
274 end if
275
276 call this%free()
277
278 this%real_scalar = val
279
280 if (present(name)) this%name = trim(name)
281 this%type = 'real_scalar'
282 this%allocated = .true.
283
284 end subroutine init_register_real_scalar
285
287 subroutine init_register_integer_scalar(this, val, name)
288 class(registry_entry_t), intent(inout) :: this
289 integer, intent(in) :: val
290 character(len=*), optional, intent(in) :: name
291
292 if (this%allocated) then
293 call neko_error("init_register_integer_scalar: " &
294 // "Register entry is already allocated.")
295 end if
296
297 call this%free()
298
299 this%integer_scalar = val
300
301 if (present(name)) this%name = trim(name)
302 this%type = 'integer_scalar'
303 this%allocated = .true.
304
305 end subroutine init_register_integer_scalar
306
308 subroutine free_register(this)
309 class(registry_entry_t), intent(inout) :: this
310
311 if (associated(this%host_array_ptr)) then
312 call this%host_array_ptr%free()
313 deallocate(this%host_array_ptr)
314 end if
315
316 if (associated(this%device_array_ptr)) then
317 call this%device_array_ptr%free()
318 deallocate(this%device_array_ptr)
319 end if
320
321 if (associated(this%vector_ptr)) then
322 call this%vector_ptr%free()
323 deallocate(this%vector_ptr)
324 end if
325
326 if (associated(this%matrix_ptr)) then
327 call this%matrix_ptr%free()
328 deallocate(this%matrix_ptr)
329 end if
330
331 if (associated(this%tensor3_ptr)) then
332 call this%tensor3_ptr%free()
333 deallocate(this%tensor3_ptr)
334 end if
335
336 if (associated(this%tensor4_ptr)) then
337 call this%tensor4_ptr%free()
338 deallocate(this%tensor4_ptr)
339 end if
340
341 if (associated(this%field_ptr)) then
342 call this%field_ptr%free()
343 deallocate(this%field_ptr)
344 end if
345
346 this%real_scalar = 0.0_rp
347 this%integer_scalar = 0
348
349 this%name = ""
350 this%type = ""
351 this%allocated = .false.
352
353 end subroutine free_register
354
356 pure function get_name(this) result(name)
357 class(registry_entry_t), intent(in) :: this
358 character(len=:), allocatable :: name
359 name = trim(this%name)
360 end function get_name
361
363 pure function get_type(this) result(type)
364 class(registry_entry_t), intent(in) :: this
365 character(len=:), allocatable :: type
366 type = trim(this%type)
367 end function get_type
368
370 pure function is_allocated(this) result(allocated)
371 class(registry_entry_t), intent(in) :: this
372 logical :: allocated
373 allocated = this%allocated
374 end function is_allocated
375
377 function get_host_array(this) result(host_array_ptr)
378 class(registry_entry_t), target, intent(in) :: this
379 type(host_array_t), pointer :: host_array_ptr
380 if (this%get_type() .ne. 'host_array') then
381 call neko_error("registry_entry::get_host_array: " &
382 // "Registry entry is not of type 'host_array'.")
383 end if
384 host_array_ptr => this%host_array_ptr
385 end function get_host_array
386
388 function get_device_array(this) result(device_array_ptr)
389 class(registry_entry_t), target, intent(in) :: this
390 type(device_array_t), pointer :: device_array_ptr
391 if (this%get_type() .ne. 'device_array') then
392 call neko_error("registry_entry::get_device_array: " &
393 // "Registry entry is not of type 'device_array'.")
394 end if
395 device_array_ptr => this%device_array_ptr
396 end function get_device_array
397
399 function get_vector(this) result(vector_ptr)
400 class(registry_entry_t), target, intent(in) :: this
401 type(vector_t), pointer :: vector_ptr
402 if (this%get_type() .ne. 'vector') then
403 call neko_error("registry_entry::get_vector: " &
404 // "Registry entry is not of type 'vector'.")
405 end if
406 vector_ptr => this%vector_ptr
407 end function get_vector
408
410 function get_matrix(this) result(matrix_ptr)
411 class(registry_entry_t), target, intent(in) :: this
412 type(matrix_t), pointer :: matrix_ptr
413 if (this%get_type() .ne. 'matrix') then
414 call neko_error("registry_entry::get_field: " &
415 // "Registry entry is not of type 'matrix'.")
416 end if
417 matrix_ptr => this%matrix_ptr
418 end function get_matrix
419
421 function get_tensor3(this) result(tensor3_ptr)
422 class(registry_entry_t), target, intent(in) :: this
423 type(tensor3_t), pointer :: tensor3_ptr
424 if (this%get_type() .ne. 'tensor3') then
425 call neko_error("registry_entry::get_field: " &
426 // "Registry entry is not of type 'tensor3'.")
427 end if
428 tensor3_ptr => this%tensor3_ptr
429 end function get_tensor3
430
432 function get_tensor4(this) result(tensor4_ptr)
433 class(registry_entry_t), target, intent(in) :: this
434 type(tensor4_t), pointer :: tensor4_ptr
435 if (this%get_type() .ne. 'tensor4') then
436 call neko_error("registry_entry::get_field: " &
437 // "Registry entry is not of type 'tensor4'.")
438 end if
439 tensor4_ptr => this%tensor4_ptr
440 end function get_tensor4
441
443 function get_field(this) result(field_ptr)
444 class(registry_entry_t), target, intent(in) :: this
445 type(field_t), pointer :: field_ptr
446 if (this%get_type() .ne. 'field') then
447 call neko_error("registry_entry::get_field: " &
448 // "Registry entry is not of type 'field'.")
449 end if
450 field_ptr => this%field_ptr
451 end function get_field
452
454 function get_real_scalar(this) result(scalar_ptr)
455 class(registry_entry_t), target, intent(in) :: this
456 real(kind=rp), pointer :: scalar_ptr
457 if (this%get_type() .ne. 'real_scalar') then
458 call neko_error("registry_entry::get_real_scalar: " &
459 // "Registry entry is not of type 'real_scalar'.")
460 end if
461 scalar_ptr => this%real_scalar
462 end function get_real_scalar
463
465 function get_integer_scalar(this) result(scalar_ptr)
466 class(registry_entry_t), target, intent(in) :: this
467 integer, pointer :: scalar_ptr
468 if (this%get_type() .ne. 'integer_scalar') then
469 call neko_error("registry_entry::get_integer_scalar: " &
470 // "Registry entry is not of type 'integer_scalar'.")
471 end if
472 scalar_ptr => this%integer_scalar
473 end function get_integer_scalar
474
476 subroutine move_from_registry_entry(this, source)
477 class(registry_entry_t), intent(inout) :: this
478 class(registry_entry_t), intent(inout) :: source
479
480 if (.not. source%is_allocated()) return
481 call this%free()
482
483 this%name = source%name
484 this%type = source%type
485 this%allocated = source%allocated
486
487 select case (trim(this%type))
488 case ('real_scalar')
489 this%real_scalar = source%real_scalar
490 case ('integer_scalar')
491 this%integer_scalar = source%integer_scalar
492 case ('host_array')
493 this%host_array_ptr => source%host_array_ptr
494 nullify(source%host_array_ptr)
495 case ('device_array')
496 this%device_array_ptr => source%device_array_ptr
497 nullify(source%device_array_ptr)
498 case ('vector')
499 this%vector_ptr => source%vector_ptr
500 nullify(source%vector_ptr)
501 case ('matrix')
502 this%matrix_ptr => source%matrix_ptr
503 nullify(source%matrix_ptr)
504 case ('tensor3')
505 this%tensor3_ptr => source%tensor3_ptr
506 nullify(source%tensor3_ptr)
507 case ('tensor4')
508 this%tensor4_ptr => source%tensor4_ptr
509 nullify(source%tensor4_ptr)
510 case ('field')
511 this%field_ptr => source%field_ptr
512 nullify(source%field_ptr)
513 case default
514 call neko_error("move_from_registry_entry: " // &
515 "Unsupported registry entry type: " // trim(this%type))
516 end select
517
518 ! Free the source entry after moving
519 call source%free()
520
521 end subroutine move_from_registry_entry
522end 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:14
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.
type(tensor3_t) function, pointer get_tensor3(this)
Get the tensor3 pointer of the registry 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_tensor4(this, n, m, l, k, name)
Initialize a register entry.
subroutine init_register_device_array(this, n, name)
Initialize by a device array.
type(tensor4_t) function, pointer get_tensor4(this)
Get the tensor4 pointer of the registry entry.
subroutine init_register_tensor3(this, n, m, l, name)
Initialize a register entry.
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.
Defines a rank-3 tensor.
Definition tensor3.f90:34
Defines a rank-4 tensor.
Definition tensor4.f90:34
Utilities.
Definition utils.f90:35
Defines a vector.
Definition vector.f90:34
Device-only temporary array.
Host-only temporary array.