Neko 1.99.5
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scratch_registry.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!
39 use host_array, only : host_array_t
41 use field, only : field_t
42 use vector, only : vector_t
43 use matrix, only : matrix_t
44
45 use math, only : rzero
46 use device_math, only : device_rzero
47 use field_math, only : field_rzero
48 use vector_math, only : vector_rzero
49 use matrix_math, only : matrix_rzero
50
51 use dofmap, only : dofmap_t
52 use utils, only : neko_error
53 implicit none
54 private
55
56 type, public :: scratch_registry_t
58 type(registry_entry_t), private, allocatable :: entries(:)
60 logical, private, allocatable :: inuse(:)
62 integer, private :: n_entries = 0
64 integer, private :: n_inuse = 0
66 integer, private :: expansion_size = 10
68 type(dofmap_t), pointer :: dof => null()
69 contains
70 procedure, private, pass(this) :: expand
72 procedure, pass(this) :: init => scratch_registry_init
74 procedure, pass(this) :: free => scratch_registry_free
76 procedure, pass(this) :: set_dofmap => scratch_registry_set_dofmap
78 procedure, pass(this) :: get_n_entries
80 procedure, pass(this) :: get_n_inuse
82 procedure, pass(this) :: get_expansion_size
84 procedure, pass(this) :: get_size
86 procedure, pass(this) :: get_inuse
87
89 procedure, pass(this) :: request_host_array
90 procedure, pass(this) :: relinquish_host_array_single
91 procedure, pass(this) :: relinquish_host_array_multiple
93 generic :: relinquish_host_array => relinquish_host_array_single, &
95
97 procedure, pass(this) :: request_device_array
98 procedure, pass(this) :: relinquish_device_array_single
99 procedure, pass(this) :: relinquish_device_array_multiple
101 generic :: relinquish_device_array => relinquish_device_array_single, &
103
105 procedure, pass(this) :: request_vector
106 procedure, pass(this) :: relinquish_vector_single
107 procedure, pass(this) :: relinquish_vector_multiple
109 generic :: relinquish_vector => relinquish_vector_single, &
111
113 procedure, pass(this) :: request_matrix
114 procedure, pass(this) :: relinquish_matrix_single
115 procedure, pass(this) :: relinquish_matrix_multiple
117 generic :: relinquish_matrix => relinquish_matrix_single, &
119
121 procedure, pass(this) :: request_field
122 procedure, pass(this) :: relinquish_field_single
123 procedure, pass(this) :: relinquish_field_multiple
125 generic :: relinquish_field => relinquish_field_single, &
127
129 generic :: request => request_host_array, request_device_array, &
131 procedure, pass(this) :: relinquish_single
132 procedure, pass(this) :: relinquish_multiple
134 generic :: relinquish => relinquish_single, relinquish_multiple
135 end type scratch_registry_t
136
139
140contains
141
150 subroutine scratch_registry_init(this, size, expansion_size, dof)
151 class(scratch_registry_t), intent(inout) :: this
152 integer, optional, intent(in) :: size
153 integer, optional, intent(in) :: expansion_size
154 type(dofmap_t), target, intent(in), optional :: dof
155 integer :: s
156
157 call this%free()
158
159 s = 10
160 if (present(size)) s = size
161 if (present(dof)) this%dof => dof
162
163 allocate(this%entries(s))
164 allocate(this%inuse(s))
165 this%inuse(:) = .false.
166
167 this%expansion_size = 10
168 if (present(expansion_size)) this%expansion_size = expansion_size
169
170 end subroutine scratch_registry_init
171
173 subroutine scratch_registry_free(this)
174 class(scratch_registry_t), intent(inout):: this
175 integer :: i
176
177 if (allocated(this%inuse)) then
178 if(any(this%inuse)) then
179 call neko_error("scratch_registry::free: " // &
180 "Cannot free scratch registry with in-use entries.")
181 end if
182 deallocate(this%inuse)
183 end if
184
185 if (allocated(this%entries)) then
186 do i = 1, this%n_entries
187 call this%entries(i)%free()
188 end do
189
190 deallocate(this%entries)
191 end if
192
193 if (associated(this%dof)) nullify(this%dof)
194
195 ! Reset to default values
196 this%n_entries = 0
197 this%n_inuse = 0
198 this%expansion_size = 10
199
200 end subroutine scratch_registry_free
201
206 subroutine scratch_registry_set_dofmap(this, dof)
207 class(scratch_registry_t), intent(inout) :: this
208 type(dofmap_t), target, intent(in) :: dof
209
210 if (associated(this%dof, dof)) then
211 return
212 else if (associated(this%dof)) then
213 call neko_error("scratch_registry::set_dofmap: "&
214 // "Dofmap is already assigned to scratch registry.")
215 end if
216
217 this%dof => dof
218 end subroutine scratch_registry_set_dofmap
219
221 pure function get_n_entries(this) result(n)
222 class(scratch_registry_t), intent(in) :: this
223 integer :: n
224
225 n = this%n_entries
226 end function get_n_entries
227
229 pure function get_n_inuse(this) result(n)
230 class(scratch_registry_t), intent(in) :: this
231 integer :: n, i
232
233 n = count(this%inuse)
234 end function get_n_inuse
235
237 pure function get_size(this) result(n)
238 class(scratch_registry_t), intent(in) :: this
239 integer :: n
240
241 if (allocated(this%entries)) then
242 n = size(this%entries)
243 else
244 n = 0
245 end if
246 end function get_size
247
249 pure function get_expansion_size(this) result(n)
250 class(scratch_registry_t), intent(in) :: this
251 integer :: n
252
253 n = this%expansion_size
254 end function get_expansion_size
255
257 pure logical function get_inuse(this, index)
258 class(scratch_registry_t), target, intent(in) :: this
259 integer, intent(in) :: index
260
261 get_inuse = this%inuse(index)
262 end function get_inuse
263
264 subroutine expand(this)
265 class(scratch_registry_t), intent(inout) :: this
266 type(registry_entry_t), allocatable :: temp(:)
267 logical, allocatable :: temp2(:)
268 integer :: i, n
269
270 n = this%get_size()
271
272 if (n .gt. 0) then
273 call move_alloc(this%entries, temp)
274 call move_alloc(this%inuse, temp2)
275 end if
276
277 allocate(this%entries(n + this%expansion_size))
278 allocate(this%inuse(n + this%expansion_size), source = .false.)
279
280 if (n .gt. 0) then
281 do i = 1, n
282 call this%entries(i)%move_from(temp(i))
283 this%inuse(i) = temp2(i)
284 call temp(i)%free()
285 end do
286 end if
287
288 if (allocated(temp)) deallocate(temp)
289 if (allocated(temp2)) deallocate(temp2)
290
291 end subroutine expand
292
299 subroutine request_host_array(this, v, index, n, clear)
300 class(scratch_registry_t), target, intent(inout) :: this
301 type(host_array_t), pointer, intent(inout) :: v
302 integer, intent(inout) :: index
303 integer, intent(in) :: n
304 logical, intent(in) :: clear
305
306 associate(entries => this%entries, n_entries => this%n_entries, &
307 n_inuse => this%n_inuse)
308
309 do index = 1, this%get_size()
310 if (.not. this%inuse(index)) then
311
312 if (.not. entries(index)%is_allocated()) then
313 call entries(index)%init_host_array(n)
314 n_entries = n_entries + 1
315 else if (trim(entries(index)%get_type()) .ne. 'host_array') then
316 cycle
317 end if
318
319 v => entries(index)%get_host_array()
320 if (v%size() .ne. n) then
321 nullify(v)
322 cycle
323 end if
324
325 if (clear) call rzero(v%x, v%size())
326 this%inuse(index) = .true.
327 this%n_inuse = this%n_inuse + 1
328 return
329 end if
330 end do
331
332 ! all existing host_arrays in use, we need to expand to add a new one
333 index = n_entries + 1
334 call this%expand()
335 n_entries = n_entries + 1
336 n_inuse = n_inuse + 1
337 this%inuse(n_entries) = .true.
338 call this%entries(n_entries)%init_host_array(n)
339 v => this%entries(n_entries)%get_host_array()
340
341 end associate
342 end subroutine request_host_array
343
350 subroutine request_device_array(this, v, index, n, clear)
351 class(scratch_registry_t), target, intent(inout) :: this
352 type(device_array_t), pointer, intent(inout) :: v
353 integer, intent(inout) :: index
354 integer, intent(in) :: n
355 logical, intent(in) :: clear
356
357 associate(entries => this%entries, n_entries => this%n_entries, &
358 n_inuse => this%n_inuse)
359
360 do index = 1, this%get_size()
361 if (.not. this%inuse(index)) then
362
363 if (.not. entries(index)%is_allocated()) then
364 call entries(index)%init_device_array(n)
365 n_entries = n_entries + 1
366 else if (trim(entries(index)%get_type()) .ne. 'device_array') then
367 cycle
368 end if
369
370 v => entries(index)%get_device_array()
371 if (v%size() .ne. n) then
372 nullify(v)
373 cycle
374 end if
375
376 if (clear) call device_rzero(v%x_d, v%size())
377 this%inuse(index) = .true.
378 this%n_inuse = this%n_inuse + 1
379 return
380 end if
381 end do
382
383 ! all existing device_arrays in use, we need to expand to add a new one
384 index = n_entries + 1
385 call this%expand()
386 n_entries = n_entries + 1
387 n_inuse = n_inuse + 1
388 this%inuse(n_entries) = .true.
389 call this%entries(n_entries)%init_device_array(n)
390 v => this%entries(n_entries)%get_device_array()
391
392 end associate
393 end subroutine request_device_array
394
400 subroutine request_vector(this, v, index, n, clear)
401 class(scratch_registry_t), target, intent(inout) :: this
402 type(vector_t), pointer, intent(inout) :: v
403 integer, intent(inout) :: index
404 integer, intent(in) :: n
405 logical, intent(in) :: clear
406
407 associate(entries => this%entries, n_entries => this%n_entries, &
408 n_inuse => this%n_inuse)
409
410 do index = 1, this%get_size()
411 if (.not. this%inuse(index)) then
412
413 if (.not. entries(index)%is_allocated()) then
414 call entries(index)%init_vector(n)
415 n_entries = n_entries + 1
416 else if (trim(entries(index)%get_type()) .ne. 'vector') then
417 cycle
418 end if
419
420 v => entries(index)%get_vector()
421 if (v%size() .ne. n) then
422 nullify(v)
423 cycle
424 end if
425
426 if (clear) call vector_rzero(v)
427 this%inuse(index) = .true.
428 this%n_inuse = this%n_inuse + 1
429 return
430 end if
431 end do
432
433 ! all existing vectors in use, we need to expand to add a new one
434 index = n_entries + 1
435 call this%expand()
436 n_entries = n_entries + 1
437 n_inuse = n_inuse + 1
438 this%inuse(n_entries) = .true.
439 call this%entries(n_entries)%init_vector(n)
440 v => this%entries(n_entries)%get_vector()
441
442 end associate
443 end subroutine request_vector
444
451 subroutine request_matrix(this, m, index, nrows, ncols, clear)
452 class(scratch_registry_t), target, intent(inout) :: this
453 type(matrix_t), pointer, intent(inout) :: m
454 integer, intent(inout) :: index
455 integer, intent(in) :: nrows, ncols
456 logical, intent(in) :: clear
457
458 associate(entries => this%entries, n_entries => this%n_entries, &
459 n_inuse => this%n_inuse)
460
461 do index = 1, this%get_size()
462 if (.not. this%inuse(index)) then
463
464 if (.not. entries(index)%is_allocated()) then
465 call entries(index)%init_matrix(nrows, ncols)
466 n_entries = n_entries + 1
467 else if (trim(entries(index)%get_type()) .ne. 'matrix') then
468 cycle
469 end if
470
471 m => entries(index)%get_matrix()
472 if (m%get_nrows() .ne. nrows .or. &
473 m%get_ncols() .ne. ncols) then
474 nullify(m)
475 cycle
476 end if
477
478 if (clear) call matrix_rzero(m)
479 this%inuse(index) = .true.
480 this%n_inuse = this%n_inuse + 1
481 return
482 end if
483 end do
484
485 ! all existing matrices in use, we need to expand to add a new one
486 index = n_entries + 1
487 call this%expand()
488 n_entries = n_entries + 1
489 n_inuse = n_inuse + 1
490 this%inuse(n_entries) = .true.
491 call this%entries(n_entries)%init_matrix(nrows, ncols)
492 m => this%entries(n_entries)%get_matrix()
493
494 end associate
495 end subroutine request_matrix
496
497
502 subroutine request_field(this, f, index, clear)
503 class(scratch_registry_t), target, intent(inout) :: this
504 type(field_t), pointer, intent(inout) :: f
505 integer, intent(inout) :: index
506 logical, intent(in) :: clear
507 character(len=10) :: name
508
509 if (.not. associated(this%dof)) then
510 call neko_error("scratch_registry::request_field: "&
511 // "No dofmap assigned to scratch registry.")
512 end if
513
514 associate(entries => this%entries, n_entries => this%n_entries, &
515 n_inuse => this%n_inuse)
516
517 do index = 1, this%get_size()
518 if (.not. this%inuse(index)) then
519
520 if (.not. entries(index)%is_allocated()) then
521 write(name, "(A3,I0.3)") "wrk", index
522 call entries(index)%init_field(this%dof, trim(name))
523 n_entries = n_entries + 1
524 else if (entries(index)%get_type() .ne. 'field') then
525 cycle
526 end if
527
528 f => entries(index)%get_field()
529 if (clear) call field_rzero(f)
530 this%inuse(index) = .true.
531 this%n_inuse = this%n_inuse + 1
532 return
533 end if
534 end do
535
536 ! all existing fields in use, we need to expand to add a new one
537 index = n_entries + 1
538 call this%expand()
539 n_entries = n_entries + 1
540 n_inuse = n_inuse + 1
541 this%inuse(n_entries) = .true.
542 write (name, "(A3,I0.3)") "wrk", index
543 call this%entries(n_entries)%init_field(this%dof, trim(name))
544 f => this%entries(n_entries)%get_field()
545
546 end associate
547 end subroutine request_field
548
551 subroutine relinquish_host_array_single(this, index)
552 class(scratch_registry_t), target, intent(inout) :: this
553 integer, intent(inout) :: index
554
555 if (trim(this%entries(index)%get_type()) .ne. 'host_array') then
556 call neko_error("scratch_registry::relinquish_host_array_single: " &
557 // "Register entry is not a host_array.")
558 end if
559
560 this%inuse(index) = .false.
561 this%n_inuse = this%n_inuse - 1
562 end subroutine relinquish_host_array_single
563
566 subroutine relinquish_host_array_multiple(this, indices)
567 class(scratch_registry_t), target, intent(inout) :: this
568 integer, intent(inout) :: indices(:)
569 integer :: i
570
571 do i = 1, size(indices)
572 if (trim(this%entries(indices(i))%get_type()) .ne. 'host_array') then
573 call neko_error("scratch_registry::relinquish_host_array_single: " &
574 // "Register entry is not a host_array.")
575 end if
576
577 this%inuse(indices(i)) = .false.
578 end do
579 this%n_inuse = this%n_inuse - size(indices)
580 end subroutine relinquish_host_array_multiple
581
584 subroutine relinquish_device_array_single(this, index)
585 class(scratch_registry_t), target, intent(inout) :: this
586 integer, intent(inout) :: index
587
588 if (trim(this%entries(index)%get_type()) .ne. 'device_array') then
589 call neko_error("scratch_registry::relinquish_device_array_single: " &
590 // "Register entry is not a device_array.")
591 end if
592
593 this%inuse(index) = .false.
594 this%n_inuse = this%n_inuse - 1
595 end subroutine relinquish_device_array_single
596
599 subroutine relinquish_device_array_multiple(this, indices)
600 class(scratch_registry_t), target, intent(inout) :: this
601 integer, intent(inout) :: indices(:)
602 integer :: i
603
604 do i = 1, size(indices)
605 if (trim(this%entries(indices(i))%get_type()) .ne. 'device_array') then
606 call neko_error("scratch_registry::relinquish_device_array_single: " &
607 // "Register entry is not a device_array.")
608 end if
609
610 this%inuse(indices(i)) = .false.
611 end do
612 this%n_inuse = this%n_inuse - size(indices)
614
617 subroutine relinquish_vector_single(this, index)
618 class(scratch_registry_t), target, intent(inout) :: this
619 integer, intent(inout) :: index
620
621 if (trim(this%entries(index)%get_type()) .ne. 'vector') then
622 call neko_error("scratch_registry::relinquish_vector_single: " &
623 // "Register entry is not a vector.")
624 end if
625
626 this%inuse(index) = .false.
627 this%n_inuse = this%n_inuse - 1
628 end subroutine relinquish_vector_single
629
632 subroutine relinquish_vector_multiple(this, indices)
633 class(scratch_registry_t), target, intent(inout) :: this
634 integer, intent(inout) :: indices(:)
635 integer :: i
636
637 do i = 1, size(indices)
638 if (trim(this%entries(indices(i))%get_type()) .ne. 'vector') then
639 call neko_error("scratch_registry::relinquish_vector_single: " &
640 // "Register entry is not a vector.")
641 end if
642
643 this%inuse(indices(i)) = .false.
644 end do
645 this%n_inuse = this%n_inuse - size(indices)
646 end subroutine relinquish_vector_multiple
647
650 subroutine relinquish_matrix_single(this, index)
651 class(scratch_registry_t), target, intent(inout) :: this
652 integer, intent(inout) :: index
653
654 if (trim(this%entries(index)%get_type()) .ne. 'matrix') then
655 call neko_error("scratch_registry::relinquish_matrix_single: " &
656 // "Register entry is not a matrix.")
657 end if
658
659 this%inuse(index) = .false.
660 this%n_inuse = this%n_inuse - 1
661 end subroutine relinquish_matrix_single
662
665 subroutine relinquish_matrix_multiple(this, indices)
666 class(scratch_registry_t), target, intent(inout) :: this
667 integer, intent(inout) :: indices(:)
668 integer :: i
669
670 do i = 1, size(indices)
671 if (trim(this%entries(indices(i))%get_type()) .ne. 'matrix') then
672 call neko_error("scratch_registry::relinquish_matrix_single: " &
673 // "Register entry is not a matrix.")
674 end if
675
676 this%inuse(indices(i)) = .false.
677 end do
678 this%n_inuse = this%n_inuse - size(indices)
679 end subroutine relinquish_matrix_multiple
680
683 subroutine relinquish_field_single(this, index)
684 class(scratch_registry_t), target, intent(inout) :: this
685 integer, intent(inout) :: index
686
687 if (trim(this%entries(index)%get_type()) .ne. 'field') then
688 call neko_error("scratch_registry::relinquish_field_single: " &
689 // "Register entry is not a field.")
690 end if
691
692 this%inuse(index) = .false.
693 this%n_inuse = this%n_inuse - 1
694 end subroutine relinquish_field_single
695
698 subroutine relinquish_field_multiple(this, indices)
699 class(scratch_registry_t), target, intent(inout) :: this
700 integer, intent(inout) :: indices(:)
701 integer :: i
702
703 do i = 1, size(indices)
704 if (trim(this%entries(indices(i))%get_type()) .ne. 'field') then
705 call neko_error("scratch_registry::relinquish_field_single: " &
706 // "Register entry is not a field.")
707 end if
708
709 this%inuse(indices(i)) = .false.
710 end do
711 this%n_inuse = this%n_inuse - size(indices)
712 end subroutine relinquish_field_multiple
713
716 subroutine relinquish_single(this, index)
717 class(scratch_registry_t), target, intent(inout) :: this
718 integer, intent(inout) :: index
719
720 this%inuse(index) = .false.
721 this%n_inuse = this%n_inuse - 1
722 end subroutine relinquish_single
723
726 subroutine relinquish_multiple(this, indices)
727 class(scratch_registry_t), target, intent(inout) :: this
728 integer, intent(inout) :: indices(:)
729 integer :: i
730
731 do i = 1, size(indices)
732 this%inuse(indices(i)) = .false.
733 end do
734 this%n_inuse = this%n_inuse - size(indices)
735 end subroutine relinquish_multiple
736
737end module scratch_registry
Module containing device only array type.
subroutine, public device_rzero(a_d, n, strm)
Zero a real vector.
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
subroutine, public field_rzero(a, n)
Zero a real vector.
Defines a field.
Definition field.f90:34
Module containing host-only array type.
Definition math.f90:60
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:235
subroutine, public matrix_rzero(a, n)
Zero a real matrix .
Defines a matrix.
Definition matrix.f90:34
Defines a registry entry for storing and requesting temporary objects This is used in the registries ...
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
subroutine relinquish_matrix_single(this, index)
Relinquish the use of a matrix in the registry.
pure logical function get_inuse(this, index)
Get the inuse status for a given index.
pure integer function get_n_inuse(this)
Get the number of objects currently in use.
subroutine scratch_registry_free(this)
Destructor.
subroutine request_field(this, f, index, clear)
Get a field from the registry by assigning it to a pointer.
subroutine relinquish_matrix_multiple(this, indices)
Relinquish the use of multiple matrices in the registry.
subroutine relinquish_host_array_single(this, index)
Relinquish the use of a host_array in the registry.
pure integer function get_n_entries(this)
Get the number of objects stored in the registry.
subroutine relinquish_device_array_multiple(this, indices)
Relinquish the use of multiple device_arrays in the registry.
subroutine request_host_array(this, v, index, n, clear)
Get a host_array from the registry by assigning it to a pointer.
subroutine relinquish_field_single(this, index)
Relinquish the use of a field in the registry.
subroutine relinquish_host_array_multiple(this, indices)
Relinquish the use of multiple host_arrays in the registry.
pure integer function get_size(this)
Get the size of the objects array.
subroutine scratch_registry_set_dofmap(this, dof)
Assign a dofmap to the scratch registry.
subroutine relinquish_field_multiple(this, indices)
Relinquish the use of multiple fields in the registry.
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
subroutine relinquish_vector_multiple(this, indices)
Relinquish the use of multiple vectors in the registry.
subroutine expand(this)
subroutine relinquish_device_array_single(this, index)
Relinquish the use of a device_array in the registry.
subroutine relinquish_vector_single(this, index)
Relinquish the use of a vector in the registry.
subroutine request_matrix(this, m, index, nrows, ncols, clear)
Get a matrix from the registry by assigning it to a pointer.
subroutine request_vector(this, v, index, n, clear)
Get a vector from the registry by assigning it to a pointer.
subroutine request_device_array(this, v, index, n, clear)
Get a device_array from the registry by assigning it to a pointer.
subroutine scratch_registry_init(this, size, expansion_size, dof)
Constructor, optionally taking initial registry and expansion size as argument.
subroutine relinquish_multiple(this, indices)
Relinquish the use of multiple objects in the registry.
subroutine relinquish_single(this, index)
Relinquish the use of an object in the registry.
pure integer function get_expansion_size(this)
Get the expansion size.
Utilities.
Definition utils.f90:35
subroutine, public vector_rzero(a, n)
Zero a real vector.
Defines a vector.
Definition vector.f90:34
Device-only temporary array.
Host-only temporary array.