Neko 1.99.3
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
298 subroutine request_host_array(this, v, index, n, clear)
299 class(scratch_registry_t), target, intent(inout) :: this
300 type(host_array_t), pointer, intent(inout) :: v
301 integer, intent(inout) :: index
302 integer, intent(in) :: n
303 logical, intent(in) :: clear
304
305 associate(entries => this%entries, n_entries => this%n_entries, &
306 n_inuse => this%n_inuse)
307
308 do index = 1, this%get_size()
309 if (.not. this%inuse(index)) then
310
311 if (.not. entries(index)%is_allocated()) then
312 call entries(index)%init_host_array(n)
313 n_entries = n_entries + 1
314 else if (trim(entries(index)%get_type()) .ne. 'host_array') then
315 cycle
316 end if
317
318 v => entries(index)%get_host_array()
319 if (v%size() .ne. n) then
320 nullify(v)
321 cycle
322 end if
323
324 if (clear) call rzero(v%x, v%size())
325 this%inuse(index) = .true.
326 this%n_inuse = this%n_inuse + 1
327 return
328 end if
329 end do
330
331 ! all existing host_arrays in use, we need to expand to add a new one
332 index = n_entries + 1
333 call this%expand()
334 n_entries = n_entries + 1
335 n_inuse = n_inuse + 1
336 this%inuse(n_entries) = .true.
337 call this%entries(n_entries)%init_host_array(n)
338 v => this%entries(n_entries)%get_host_array()
339
340 end associate
341 end subroutine request_host_array
342
348 subroutine request_device_array(this, v, index, n, clear)
349 class(scratch_registry_t), target, intent(inout) :: this
350 type(device_array_t), pointer, intent(inout) :: v
351 integer, intent(inout) :: index
352 integer, intent(in) :: n
353 logical, intent(in) :: clear
354
355 associate(entries => this%entries, n_entries => this%n_entries, &
356 n_inuse => this%n_inuse)
357
358 do index = 1, this%get_size()
359 if (.not. this%inuse(index)) then
360
361 if (.not. entries(index)%is_allocated()) then
362 call entries(index)%init_device_array(n)
363 n_entries = n_entries + 1
364 else if (trim(entries(index)%get_type()) .ne. 'device_array') then
365 cycle
366 end if
367
368 v => entries(index)%get_device_array()
369 if (v%size() .ne. n) then
370 nullify(v)
371 cycle
372 end if
373
374 if (clear) call device_rzero(v%x_d, v%size())
375 this%inuse(index) = .true.
376 this%n_inuse = this%n_inuse + 1
377 return
378 end if
379 end do
380
381 ! all existing device_arrays in use, we need to expand to add a new one
382 index = n_entries + 1
383 call this%expand()
384 n_entries = n_entries + 1
385 n_inuse = n_inuse + 1
386 this%inuse(n_entries) = .true.
387 call this%entries(n_entries)%init_device_array(n)
388 v => this%entries(n_entries)%get_device_array()
389
390 end associate
391 end subroutine request_device_array
392
398 subroutine request_vector(this, v, index, n, clear)
399 class(scratch_registry_t), target, intent(inout) :: this
400 type(vector_t), pointer, intent(inout) :: v
401 integer, intent(inout) :: index
402 integer, intent(in) :: n
403 logical, intent(in) :: clear
404
405 associate(entries => this%entries, n_entries => this%n_entries, &
406 n_inuse => this%n_inuse)
407
408 do index = 1, this%get_size()
409 if (.not. this%inuse(index)) then
410
411 if (.not. entries(index)%is_allocated()) then
412 call entries(index)%init_vector(n)
413 n_entries = n_entries + 1
414 else if (trim(entries(index)%get_type()) .ne. 'vector') then
415 cycle
416 end if
417
418 v => entries(index)%get_vector()
419 if (v%size() .ne. n) then
420 nullify(v)
421 cycle
422 end if
423
424 if (clear) call vector_rzero(v)
425 this%inuse(index) = .true.
426 this%n_inuse = this%n_inuse + 1
427 return
428 end if
429 end do
430
431 ! all existing vectors in use, we need to expand to add a new one
432 index = n_entries + 1
433 call this%expand()
434 n_entries = n_entries + 1
435 n_inuse = n_inuse + 1
436 this%inuse(n_entries) = .true.
437 call this%entries(n_entries)%init_vector(n)
438 v => this%entries(n_entries)%get_vector()
439
440 end associate
441 end subroutine request_vector
442
449 subroutine request_matrix(this, m, index, nrows, ncols, clear)
450 class(scratch_registry_t), target, intent(inout) :: this
451 type(matrix_t), pointer, intent(inout) :: m
452 integer, intent(inout) :: index
453 integer, intent(in) :: nrows, ncols
454 logical, intent(in) :: clear
455
456 associate(entries => this%entries, n_entries => this%n_entries, &
457 n_inuse => this%n_inuse)
458
459 do index = 1, this%get_size()
460 if (.not. this%inuse(index)) then
461
462 if (.not. entries(index)%is_allocated()) then
463 call entries(index)%init_matrix(nrows, ncols)
464 n_entries = n_entries + 1
465 else if (trim(entries(index)%get_type()) .ne. 'matrix') then
466 cycle
467 end if
468
469 m => entries(index)%get_matrix()
470 if (m%get_nrows() .ne. nrows .or. &
471 m%get_ncols() .ne. ncols) then
472 nullify(m)
473 cycle
474 end if
475
476 if (clear) call matrix_rzero(m)
477 this%inuse(index) = .true.
478 this%n_inuse = this%n_inuse + 1
479 return
480 end if
481 end do
482
483 ! all existing matrices in use, we need to expand to add a new one
484 index = n_entries + 1
485 call this%expand()
486 n_entries = n_entries + 1
487 n_inuse = n_inuse + 1
488 this%inuse(n_entries) = .true.
489 call this%entries(n_entries)%init_matrix(nrows, ncols)
490 m => this%entries(n_entries)%get_matrix()
491
492 end associate
493 end subroutine request_matrix
494
495
500 subroutine request_field(this, f, index, clear)
501 class(scratch_registry_t), target, intent(inout) :: this
502 type(field_t), pointer, intent(inout) :: f
503 integer, intent(inout) :: index
504 logical, intent(in) :: clear
505 character(len=10) :: name
506
507 if (.not. associated(this%dof)) then
508 call neko_error("scratch_registry::request_field: "&
509 // "No dofmap assigned to scratch registry.")
510 end if
511
512 associate(entries => this%entries, n_entries => this%n_entries, &
513 n_inuse => this%n_inuse)
514
515 do index = 1, this%get_size()
516 if (.not. this%inuse(index)) then
517
518 if (.not. entries(index)%is_allocated()) then
519 write(name, "(A3,I0.3)") "wrk", index
520 call entries(index)%init_field(this%dof, trim(name))
521 n_entries = n_entries + 1
522 else if (entries(index)%get_type() .ne. 'field') then
523 cycle
524 end if
525
526 f => entries(index)%get_field()
527 if (clear) call field_rzero(f)
528 this%inuse(index) = .true.
529 this%n_inuse = this%n_inuse + 1
530 return
531 end if
532 end do
533
534 ! all existing fields in use, we need to expand to add a new one
535 index = n_entries + 1
536 call this%expand()
537 n_entries = n_entries + 1
538 n_inuse = n_inuse + 1
539 this%inuse(n_entries) = .true.
540 write (name, "(A3,I0.3)") "wrk", index
541 call this%entries(n_entries)%init_field(this%dof, trim(name))
542 f => this%entries(n_entries)%get_field()
543
544 end associate
545 end subroutine request_field
546
549 subroutine relinquish_host_array_single(this, index)
550 class(scratch_registry_t), target, intent(inout) :: this
551 integer, intent(inout) :: index
552
553 if (trim(this%entries(index)%get_type()) .ne. 'host_array') then
554 call neko_error("scratch_registry::relinquish_host_array_single: " &
555 // "Register entry is not a host_array.")
556 end if
557
558 this%inuse(index) = .false.
559 this%n_inuse = this%n_inuse - 1
560 end subroutine relinquish_host_array_single
561
564 subroutine relinquish_host_array_multiple(this, indices)
565 class(scratch_registry_t), target, intent(inout) :: this
566 integer, intent(inout) :: indices(:)
567 integer :: i
568
569 do i = 1, size(indices)
570 if (trim(this%entries(indices(i))%get_type()) .ne. 'host_array') then
571 call neko_error("scratch_registry::relinquish_host_array_single: " &
572 // "Register entry is not a host_array.")
573 end if
574
575 this%inuse(indices(i)) = .false.
576 end do
577 this%n_inuse = this%n_inuse - size(indices)
578 end subroutine relinquish_host_array_multiple
579
582 subroutine relinquish_device_array_single(this, index)
583 class(scratch_registry_t), target, intent(inout) :: this
584 integer, intent(inout) :: index
585
586 if (trim(this%entries(index)%get_type()) .ne. 'device_array') then
587 call neko_error("scratch_registry::relinquish_device_array_single: " &
588 // "Register entry is not a device_array.")
589 end if
590
591 this%inuse(index) = .false.
592 this%n_inuse = this%n_inuse - 1
593 end subroutine relinquish_device_array_single
594
597 subroutine relinquish_device_array_multiple(this, indices)
598 class(scratch_registry_t), target, intent(inout) :: this
599 integer, intent(inout) :: indices(:)
600 integer :: i
601
602 do i = 1, size(indices)
603 if (trim(this%entries(indices(i))%get_type()) .ne. 'device_array') then
604 call neko_error("scratch_registry::relinquish_device_array_single: " &
605 // "Register entry is not a device_array.")
606 end if
607
608 this%inuse(indices(i)) = .false.
609 end do
610 this%n_inuse = this%n_inuse - size(indices)
612
615 subroutine relinquish_vector_single(this, index)
616 class(scratch_registry_t), target, intent(inout) :: this
617 integer, intent(inout) :: index
618
619 if (trim(this%entries(index)%get_type()) .ne. 'vector') then
620 call neko_error("scratch_registry::relinquish_vector_single: " &
621 // "Register entry is not a vector.")
622 end if
623
624 this%inuse(index) = .false.
625 this%n_inuse = this%n_inuse - 1
626 end subroutine relinquish_vector_single
627
630 subroutine relinquish_vector_multiple(this, indices)
631 class(scratch_registry_t), target, intent(inout) :: this
632 integer, intent(inout) :: indices(:)
633 integer :: i
634
635 do i = 1, size(indices)
636 if (trim(this%entries(indices(i))%get_type()) .ne. 'vector') then
637 call neko_error("scratch_registry::relinquish_vector_single: " &
638 // "Register entry is not a vector.")
639 end if
640
641 this%inuse(indices(i)) = .false.
642 end do
643 this%n_inuse = this%n_inuse - size(indices)
644 end subroutine relinquish_vector_multiple
645
648 subroutine relinquish_matrix_single(this, index)
649 class(scratch_registry_t), target, intent(inout) :: this
650 integer, intent(inout) :: index
651
652 if (trim(this%entries(index)%get_type()) .ne. 'matrix') then
653 call neko_error("scratch_registry::relinquish_matrix_single: " &
654 // "Register entry is not a matrix.")
655 end if
656
657 this%inuse(index) = .false.
658 this%n_inuse = this%n_inuse - 1
659 end subroutine relinquish_matrix_single
660
663 subroutine relinquish_matrix_multiple(this, indices)
664 class(scratch_registry_t), target, intent(inout) :: this
665 integer, intent(inout) :: indices(:)
666 integer :: i
667
668 do i = 1, size(indices)
669 if (trim(this%entries(indices(i))%get_type()) .ne. 'matrix') then
670 call neko_error("scratch_registry::relinquish_matrix_single: " &
671 // "Register entry is not a matrix.")
672 end if
673
674 this%inuse(indices(i)) = .false.
675 end do
676 this%n_inuse = this%n_inuse - size(indices)
677 end subroutine relinquish_matrix_multiple
678
681 subroutine relinquish_field_single(this, index)
682 class(scratch_registry_t), target, intent(inout) :: this
683 integer, intent(inout) :: index
684
685 if (trim(this%entries(index)%get_type()) .ne. 'field') then
686 call neko_error("scratch_registry::relinquish_field_single: " &
687 // "Register entry is not a field.")
688 end if
689
690 this%inuse(index) = .false.
691 this%n_inuse = this%n_inuse - 1
692 end subroutine relinquish_field_single
693
696 subroutine relinquish_field_multiple(this, indices)
697 class(scratch_registry_t), target, intent(inout) :: this
698 integer, intent(inout) :: indices(:)
699 integer :: i
700
701 do i = 1, size(indices)
702 if (trim(this%entries(indices(i))%get_type()) .ne. 'field') then
703 call neko_error("scratch_registry::relinquish_field_single: " &
704 // "Register entry is not a field.")
705 end if
706
707 this%inuse(indices(i)) = .false.
708 end do
709 this%n_inuse = this%n_inuse - size(indices)
710 end subroutine relinquish_field_multiple
711
714 subroutine relinquish_single(this, index)
715 class(scratch_registry_t), target, intent(inout) :: this
716 integer, intent(inout) :: index
717
718 this%inuse(index) = .false.
719 this%n_inuse = this%n_inuse - 1
720 end subroutine relinquish_single
721
724 subroutine relinquish_multiple(this, indices)
725 class(scratch_registry_t), target, intent(inout) :: this
726 integer, intent(inout) :: indices(:)
727 integer :: i
728
729 do i = 1, size(indices)
730 this%inuse(indices(i)) = .false.
731 end do
732 this%n_inuse = this%n_inuse - size(indices)
733 end subroutine relinquish_multiple
734
735end 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:233
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.