Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
checkpoint_payload.f90
Go to the documentation of this file.
1! Copyright (c) 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 disclaimer
13! in the documentation and/or other materials provided with the
14! distribution.
15!
16! * Neither the name of Neko nor the names of its contributors may be used
17! to endorse or promote products derived from this software without
18! specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30! POSSIBILITY OF SUCH DAMAGE.
31!
34 use num_types, only : rp, dp, i8
35 use field, only : field_t, field_ptr_t
37 use mesh, only : mesh_t
38 use space, only : space_t
39 use utils, only : neko_error
40 use, intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr, c_loc, c_f_pointer
41 implicit none
42 private
43
45 type, public :: checkpoint_array_t
47 character(len=:), allocatable :: name
50 real(kind=rp), pointer :: x(:) => null()
54 real(kind=dp), pointer :: x_dp(:) => null()
56 type(c_ptr) :: x_d = c_null_ptr
58 integer(kind=i8) :: global_count = 0_i8
60 integer(kind=i8) :: offset = 0_i8
62 logical :: replicated = .false.
63 end type checkpoint_array_t
64
66 type, public :: checkpoint_array_ptr_t
68 type(checkpoint_array_t), pointer :: ptr => null()
70
74 character(len=:), allocatable :: name
76 real(kind=rp), pointer :: x(:) => null()
78 type(c_ptr) :: x_d = c_null_ptr
80 type(mesh_t), pointer :: msh => null()
82 type(space_t), pointer :: xh => null()
84
88 type(checkpoint_mesh_array_t), pointer :: ptr => null()
90
92 type, public :: checkpoint_payload_t
94 character(len=:), allocatable :: name
96 type(field_ptr_t), allocatable :: fields(:)
98 type(field_series_ptr_t), allocatable :: series(:)
100 type(checkpoint_array_ptr_t), allocatable :: arrays(:)
102 type(checkpoint_mesh_array_ptr_t), allocatable :: mesh_arrays(:)
103 contains
105 procedure, pass(this) :: init => checkpoint_payload_init
107 procedure, pass(this) :: free => checkpoint_payload_free
109 procedure, pass(this) :: add_field => checkpoint_payload_add_field
111 procedure, pass(this) :: add_series => checkpoint_payload_add_series
113 procedure, pass(this), private :: add_array_1d
115 procedure, pass(this), private :: add_array_2d
117 procedure, pass(this), private :: add_array_3d
119 procedure, pass(this), private :: add_array_4d
121 generic :: add_array => add_array_1d, add_array_2d, add_array_3d, &
126 procedure, pass(this) :: add_array_dp => checkpoint_payload_add_array_dp
128 procedure, pass(this) :: add_mesh_array => add_mesh_array_4d
130 procedure, pass(this) :: field_count => checkpoint_payload_field_count
132 procedure, pass(this) :: series_count => checkpoint_payload_series_count
134 procedure, pass(this) :: array_count => checkpoint_payload_array_count
136 procedure, pass(this) :: mesh_array_count => &
139 procedure, pass(this) :: find_field => checkpoint_payload_find_field
141 procedure, pass(this) :: find_series => checkpoint_payload_find_series
143 procedure, pass(this) :: find_array => checkpoint_payload_find_array
145 procedure, pass(this) :: find_mesh_array => &
147 end type checkpoint_payload_t
148
152 type(checkpoint_payload_t), pointer :: ptr => null()
154
155contains
156
159 subroutine checkpoint_payload_init(this, name)
160 class(checkpoint_payload_t), intent(inout) :: this
161 character(len=*), intent(in) :: name
162
163 call this%free()
164
165 if (len_trim(name) .eq. 0) then
166 call neko_error("Checkpoint payload name cannot be empty")
167 end if
168 if (name(1:1) .eq. "/" .or. &
169 name(len_trim(name):len_trim(name)) .eq. "/") then
170 call neko_error("Checkpoint payload names cannot start or end with '/'")
171 end if
172 if (index(trim(name), "//") .gt. 0) then
173 call neko_error("Checkpoint payload names cannot contain empty groups")
174 end if
175
176 this%name = trim(name)
177
178 end subroutine checkpoint_payload_init
179
181 subroutine checkpoint_payload_free(this)
182 class(checkpoint_payload_t), intent(inout) :: this
183 integer :: i
184
185 if (allocated(this%fields)) then
186 do i = 1, size(this%fields)
187 if (associated(this%fields(i)%ptr)) nullify(this%fields(i)%ptr)
188 end do
189 deallocate(this%fields)
190 end if
191
192 if (allocated(this%series)) then
193 do i = 1, size(this%series)
194 if (associated(this%series(i)%ptr)) nullify(this%series(i)%ptr)
195 end do
196 deallocate(this%series)
197 end if
198
199 if (allocated(this%arrays)) then
200 do i = 1, size(this%arrays)
201 if (associated(this%arrays(i)%ptr)) then
202 if (associated(this%arrays(i)%ptr%x)) then
203 nullify(this%arrays(i)%ptr%x)
204 end if
205 if (associated(this%arrays(i)%ptr%x_dp)) then
206 nullify(this%arrays(i)%ptr%x_dp)
207 end if
208 this%arrays(i)%ptr%x_d = c_null_ptr
209 deallocate(this%arrays(i)%ptr)
210 end if
211 end do
212 deallocate(this%arrays)
213 end if
214
215 if (allocated(this%mesh_arrays)) then
216 do i = 1, size(this%mesh_arrays)
217 if (associated(this%mesh_arrays(i)%ptr)) then
218 if (associated(this%mesh_arrays(i)%ptr%x)) then
219 nullify(this%mesh_arrays(i)%ptr%x)
220 end if
221 this%mesh_arrays(i)%ptr%x_d = c_null_ptr
222 nullify(this%mesh_arrays(i)%ptr%msh)
223 nullify(this%mesh_arrays(i)%ptr%Xh)
224 deallocate(this%mesh_arrays(i)%ptr)
225 end if
226 end do
227 deallocate(this%mesh_arrays)
228 end if
229
230 if (allocated(this%name)) deallocate(this%name)
231
232 end subroutine checkpoint_payload_free
233
236 subroutine checkpoint_payload_add_field(this, fld)
237 class(checkpoint_payload_t), intent(inout) :: this
238 type(field_t), target, intent(in) :: fld
239 type(field_ptr_t), allocatable :: tmp(:)
240 integer :: i, n
241
242 call checkpoint_payload_validate_name(this, fld%name)
243
244 n = this%field_count()
245 do i = 1, n
246 if (associated(this%fields(i)%ptr, fld)) then
247 call neko_error( &
248 "Field already registered in checkpoint payload '" // &
249 trim(this%name) // "'")
250 end if
251 end do
252
253 allocate(tmp(n + 1))
254 if (n .gt. 0) tmp(1:n) = this%fields
255 tmp(n + 1)%ptr => fld
256 call move_alloc(tmp, this%fields)
257
258 end subroutine checkpoint_payload_add_field
259
262 subroutine checkpoint_payload_add_series(this, fld_series)
263 class(checkpoint_payload_t), intent(inout) :: this
264 type(field_series_t), target, intent(in) :: fld_series
265 type(field_series_ptr_t), allocatable :: tmp(:)
266 integer :: i, j, n
267
268 do j = 1, fld_series%size()
269 call checkpoint_payload_validate_name(this, fld_series%lf(j)%name)
270 do i = 1, j - 1
271 if (trim(fld_series%lf(i)%name) .eq. &
272 trim(fld_series%lf(j)%name)) then
273 call neko_error("Duplicate field name in checkpoint series")
274 end if
275 end do
276 end do
277
278 n = this%series_count()
279 do i = 1, n
280 if (associated(this%series(i)%ptr, fld_series)) then
281 call neko_error("Field series already registered in checkpoint " // &
282 "payload '" // trim(this%name) // "'")
283 end if
284 end do
285
286 allocate(tmp(n + 1))
287 if (n .gt. 0) tmp(1:n) = this%series
288 tmp(n + 1)%ptr => fld_series
289 call move_alloc(tmp, this%series)
290
291 end subroutine checkpoint_payload_add_series
292
293 ! The dummies below are `target` but deliberately not `contiguous`. The
294 ! payload keeps the address of the array for the lifetime of the run, so
295 ! the dummy has to alias the actual argument. gfortran 12 passes a pointer
296 ! array to a `contiguous` dummy through a temporary copy, and the stored
297 ! address then points at memory that is freed on return; the rigid-body
298 ! arrays and the lagged mass matrices in ale_manager are pointer arrays.
299 ! A plain `target` dummy is never copied, so `c_loc` of its first element
300 ! is the actual's address. Every registered array is whole and contiguous,
301 ! which is_contiguous checks.
302
310 subroutine add_array_1d(this, name, x, global_count, offset, &
311 device_ptr, replicated)
312 class(checkpoint_payload_t), intent(inout) :: this
313 character(len=*), intent(in) :: name
314 real(kind=rp), target, intent(inout) :: x(:)
315 integer(kind=i8), intent(in), optional :: global_count, offset
316 type(c_ptr), intent(in), optional :: device_ptr
317 logical, intent(in), optional :: replicated
318 real(kind=rp), pointer :: flat(:)
319
320 if (.not. is_contiguous(x)) then
321 call neko_error("Checkpoint array '" // trim(name) // "' must be " // &
322 "contiguous")
323 end if
324 call c_f_pointer(c_loc(x(1)), flat, [size(x)])
325 call checkpoint_payload_add_array(this, name, flat, global_count, &
326 offset, device_ptr, replicated)
327
328 end subroutine add_array_1d
329
337 subroutine add_array_2d(this, name, x, global_count, offset, &
338 device_ptr, replicated)
339 class(checkpoint_payload_t), intent(inout) :: this
340 character(len=*), intent(in) :: name
341 real(kind=rp), target, intent(inout) :: x(:,:)
342 integer(kind=i8), intent(in), optional :: global_count, offset
343 type(c_ptr), intent(in), optional :: device_ptr
344 logical, intent(in), optional :: replicated
345 real(kind=rp), pointer :: flat(:)
346
347 if (.not. is_contiguous(x)) then
348 call neko_error("Checkpoint array '" // trim(name) // "' must be " // &
349 "contiguous")
350 end if
351 call c_f_pointer(c_loc(x(1,1)), flat, [size(x)])
352 call checkpoint_payload_add_array(this, name, flat, global_count, &
353 offset, device_ptr, replicated)
354
355 end subroutine add_array_2d
356
364 subroutine add_array_3d(this, name, x, global_count, offset, &
365 device_ptr, replicated)
366 class(checkpoint_payload_t), intent(inout) :: this
367 character(len=*), intent(in) :: name
368 real(kind=rp), target, intent(inout) :: x(:,:,:)
369 integer(kind=i8), intent(in), optional :: global_count, offset
370 type(c_ptr), intent(in), optional :: device_ptr
371 logical, intent(in), optional :: replicated
372 real(kind=rp), pointer :: flat(:)
373
374 if (.not. is_contiguous(x)) then
375 call neko_error("Checkpoint array '" // trim(name) // "' must be " // &
376 "contiguous")
377 end if
378 call c_f_pointer(c_loc(x(1,1,1)), flat, [size(x)])
379 call checkpoint_payload_add_array(this, name, flat, global_count, &
380 offset, device_ptr, replicated)
381
382 end subroutine add_array_3d
383
391 subroutine add_array_4d(this, name, x, global_count, offset, &
392 device_ptr, replicated)
393 class(checkpoint_payload_t), intent(inout) :: this
394 character(len=*), intent(in) :: name
395 real(kind=rp), target, intent(inout) :: x(:,:,:,:)
396 integer(kind=i8), intent(in), optional :: global_count, offset
397 type(c_ptr), intent(in), optional :: device_ptr
398 logical, intent(in), optional :: replicated
399 real(kind=rp), pointer :: flat(:)
400
401 if (.not. is_contiguous(x)) then
402 call neko_error("Checkpoint array '" // trim(name) // "' must be " // &
403 "contiguous")
404 end if
405 call c_f_pointer(c_loc(x(1,1,1,1)), flat, [size(x)])
406 call checkpoint_payload_add_array(this, name, flat, global_count, &
407 offset, device_ptr, replicated)
408
409 end subroutine add_array_4d
410
417 subroutine add_mesh_array_4d(this, name, x, msh, Xh, device_ptr)
418 class(checkpoint_payload_t), intent(inout) :: this
419 character(len=*), intent(in) :: name
420 real(kind=rp), target, intent(inout) :: x(:,:,:,:)
421 type(mesh_t), target, intent(in) :: msh
422 type(space_t), target, intent(in) :: Xh
423 type(c_ptr), intent(in), optional :: device_ptr
424 real(kind=rp), pointer :: flat(:)
425
426 if (any(shape(x) .ne. [xh%lx, xh%ly, xh%lz, msh%nelv])) then
427 call neko_error("Checkpoint mesh array must have shape " // &
428 "(lx, ly, lz, nelv)")
429 end if
430 if (.not. is_contiguous(x)) then
431 call neko_error("Checkpoint array '" // trim(name) // "' must be " // &
432 "contiguous")
433 end if
434 call c_f_pointer(c_loc(x(1,1,1,1)), flat, [size(x)])
435 call checkpoint_payload_add_mesh_array(this, name, flat, msh, xh, &
436 device_ptr)
437
438 end subroutine add_mesh_array_4d
439
447 subroutine checkpoint_payload_add_array(this, name, x, global_count, &
448 offset, device_ptr, replicated)
449 class(checkpoint_payload_t), intent(inout) :: this
450 character(len=*), intent(in) :: name
451 real(kind=rp), pointer, intent(inout) :: x(:)
452 integer(kind=i8), intent(in), optional :: global_count, offset
453 type(c_ptr), intent(in), optional :: device_ptr
454 logical, intent(in), optional :: replicated
455 type(checkpoint_array_ptr_t), allocatable :: tmp(:)
456 logical :: is_replicated
457 integer :: n
458
459 call checkpoint_payload_validate_name(this, name)
460
461 is_replicated = .false.
462 if (present(replicated)) is_replicated = replicated
463
464 if (is_replicated) then
465 if (present(global_count) .or. present(offset)) then
466 call neko_error("Replicated checkpoint arrays do not take a " // &
467 "global count or offset")
468 end if
469 else if (.not. present(global_count) .or. .not. present(offset)) then
470 call neko_error("Distributed checkpoint arrays require a global " // &
471 "count and offset")
472 end if
473
474 n = this%array_count()
475 allocate(tmp(n + 1))
476 if (n .gt. 0) tmp(1:n) = this%arrays
477 allocate(tmp(n + 1)%ptr)
478 tmp(n + 1)%ptr%name = trim(name)
479 tmp(n + 1)%ptr%x => x
480 tmp(n + 1)%ptr%replicated = is_replicated
481 if (is_replicated) then
482 tmp(n + 1)%ptr%global_count = int(size(x), i8)
483 tmp(n + 1)%ptr%offset = 0_i8
484 else
485 tmp(n + 1)%ptr%global_count = global_count
486 tmp(n + 1)%ptr%offset = offset
487 if (tmp(n + 1)%ptr%offset .lt. 0_i8 .or. &
488 tmp(n + 1)%ptr%global_count .lt. int(size(x), i8) .or. &
489 tmp(n + 1)%ptr%offset + int(size(x), i8) .gt. &
490 tmp(n + 1)%ptr%global_count) then
491 call neko_error("Invalid checkpoint array selection")
492 end if
493 end if
494 if (present(device_ptr)) tmp(n + 1)%ptr%x_d = device_ptr
495 call move_alloc(tmp, this%arrays)
496
497 end subroutine checkpoint_payload_add_array
498
505 subroutine checkpoint_payload_add_array_dp(this, name, x, global_count, &
506 offset, replicated)
507 class(checkpoint_payload_t), intent(inout) :: this
508 character(len=*), intent(in) :: name
509 real(kind=dp), contiguous, target, intent(inout) :: x(:)
510 integer(kind=i8), intent(in), optional :: global_count, offset
511 logical, intent(in), optional :: replicated
512 type(checkpoint_array_ptr_t), allocatable :: tmp(:)
513 logical :: is_replicated
514 integer :: n
515
516 call checkpoint_payload_validate_name(this, name)
517
518 is_replicated = .false.
519 if (present(replicated)) is_replicated = replicated
520
521 if (is_replicated) then
522 if (present(global_count) .or. present(offset)) then
523 call neko_error("Replicated checkpoint arrays do not take a " // &
524 "global count or offset")
525 end if
526 else if (.not. present(global_count) .or. .not. present(offset)) then
527 call neko_error("Distributed checkpoint arrays require a global " // &
528 "count and offset")
529 end if
530
531 n = this%array_count()
532 allocate(tmp(n + 1))
533 if (n .gt. 0) tmp(1:n) = this%arrays
534 allocate(tmp(n + 1)%ptr)
535 tmp(n + 1)%ptr%name = trim(name)
536 tmp(n + 1)%ptr%x_dp => x
537 tmp(n + 1)%ptr%replicated = is_replicated
538 if (is_replicated) then
539 tmp(n + 1)%ptr%global_count = int(size(x), i8)
540 tmp(n + 1)%ptr%offset = 0_i8
541 else
542 tmp(n + 1)%ptr%global_count = global_count
543 tmp(n + 1)%ptr%offset = offset
544 if (tmp(n + 1)%ptr%offset .lt. 0_i8 .or. &
545 tmp(n + 1)%ptr%global_count .lt. int(size(x), i8) .or. &
546 tmp(n + 1)%ptr%offset + int(size(x), i8) .gt. &
547 tmp(n + 1)%ptr%global_count) then
548 call neko_error("Invalid checkpoint array selection")
549 end if
550 end if
551 call move_alloc(tmp, this%arrays)
552
554
561 subroutine checkpoint_payload_add_mesh_array(this, name, x, msh, Xh, &
562 device_ptr)
563 class(checkpoint_payload_t), intent(inout) :: this
564 character(len=*), intent(in) :: name
565 real(kind=rp), pointer, intent(inout) :: x(:)
566 type(mesh_t), target, intent(in) :: msh
567 type(space_t), target, intent(in) :: Xh
568 type(c_ptr), intent(in), optional :: device_ptr
569 type(checkpoint_mesh_array_ptr_t), allocatable :: tmp(:)
570 integer :: n
571
572 call checkpoint_payload_validate_name(this, name)
573
574 if (size(x) .ne. msh%nelv * xh%lxyz) then
575 call neko_error( &
576 "Checkpoint mesh array size does not match its mesh " // &
577 "and function space")
578 end if
579
580 n = this%mesh_array_count()
581 allocate(tmp(n + 1))
582 if (n .gt. 0) tmp(1:n) = this%mesh_arrays
583 allocate(tmp(n + 1)%ptr)
584 tmp(n + 1)%ptr%name = trim(name)
585 tmp(n + 1)%ptr%x => x
586 tmp(n + 1)%ptr%msh => msh
587 tmp(n + 1)%ptr%Xh => xh
588 if (present(device_ptr)) tmp(n + 1)%ptr%x_d = device_ptr
589 call move_alloc(tmp, this%mesh_arrays)
590
592
595 subroutine checkpoint_payload_validate_name(this, name)
596 class(checkpoint_payload_t), intent(in) :: this
597 character(len=*), intent(in) :: name
598 integer :: i, j
599
600 if (len_trim(name) .eq. 0) then
601 call neko_error("Checkpoint field name cannot be empty")
602 end if
603 if (index(trim(name), "/") .gt. 0) then
604 call neko_error("Checkpoint field names cannot contain '/'")
605 end if
606
607 do i = 1, this%field_count()
608 if (trim(this%fields(i)%ptr%name) .eq. trim(name)) then
609 call neko_error("Duplicate field name '" // trim(name) // &
610 "' in checkpoint payload '" // trim(this%name) // "'")
611 end if
612 end do
613
614 do i = 1, this%series_count()
615 do j = 1, this%series(i)%ptr%size()
616 if (trim(this%series(i)%ptr%lf(j)%name) .eq. trim(name)) then
617 call neko_error("Duplicate field name '" // trim(name) // &
618 "' in checkpoint payload '" // trim(this%name) // "'")
619 end if
620 end do
621 end do
622
623 do i = 1, this%array_count()
624 if (trim(this%arrays(i)%ptr%name) .eq. trim(name)) then
625 call neko_error("Duplicate field or array name '" // trim(name) // &
626 "' in checkpoint payload '" // trim(this%name) // "'")
627 end if
628 end do
629
630 do i = 1, this%mesh_array_count()
631 if (trim(this%mesh_arrays(i)%ptr%name) .eq. trim(name)) then
632 call neko_error("Duplicate field or array name '" // trim(name) // &
633 "' in checkpoint payload '" // trim(this%name) // "'")
634 end if
635 end do
636
638
641 pure function checkpoint_payload_field_count(this) result(n)
642 class(checkpoint_payload_t), intent(in) :: this
643 integer :: n
644
645 if (allocated(this%fields)) then
646 n = size(this%fields)
647 else
648 n = 0
649 end if
650
652
655 pure function checkpoint_payload_series_count(this) result(n)
656 class(checkpoint_payload_t), intent(in) :: this
657 integer :: n
658
659 if (allocated(this%series)) then
660 n = size(this%series)
661 else
662 n = 0
663 end if
664
666
669 pure function checkpoint_payload_array_count(this) result(n)
670 class(checkpoint_payload_t), intent(in) :: this
671 integer :: n
672
673 if (allocated(this%arrays)) then
674 n = size(this%arrays)
675 else
676 n = 0
677 end if
678
680
683 pure function checkpoint_payload_mesh_array_count(this) result(n)
684 class(checkpoint_payload_t), intent(in) :: this
685 integer :: n
686
687 if (allocated(this%mesh_arrays)) then
688 n = size(this%mesh_arrays)
689 else
690 n = 0
691 end if
692
694
698 function checkpoint_payload_find_field(this, name) result(fld)
699 class(checkpoint_payload_t), intent(in) :: this
700 character(len=*), intent(in) :: name
701 type(field_t), pointer :: fld
702 integer :: i
703
704 nullify(fld)
705 do i = 1, this%field_count()
706 if (trim(this%fields(i)%ptr%name) .eq. trim(name)) then
707 fld => this%fields(i)%ptr
708 return
709 end if
710 end do
711
713
717 function checkpoint_payload_find_series(this, name) result(series)
718 class(checkpoint_payload_t), intent(in) :: this
719 character(len=*), intent(in) :: name
720 type(field_series_t), pointer :: series
721 integer :: i
722
723 nullify(series)
724 do i = 1, this%series_count()
725 if (trim(this%series(i)%ptr%f%name) .eq. trim(name)) then
726 series => this%series(i)%ptr
727 return
728 end if
729 end do
730
732
736 function checkpoint_payload_find_array(this, name) result(array)
737 class(checkpoint_payload_t), intent(in) :: this
738 character(len=*), intent(in) :: name
739 type(checkpoint_array_t), pointer :: array
740 integer :: i
741
742 nullify(array)
743 do i = 1, this%array_count()
744 if (trim(this%arrays(i)%ptr%name) .eq. trim(name)) then
745 array => this%arrays(i)%ptr
746 return
747 end if
748 end do
749
751
755 function checkpoint_payload_find_mesh_array(this, name) result(array)
756 class(checkpoint_payload_t), intent(in) :: this
757 character(len=*), intent(in) :: name
758 type(checkpoint_mesh_array_t), pointer :: array
759 integer :: i
760
761 nullify(array)
762 do i = 1, this%mesh_array_count()
763 if (trim(this%mesh_arrays(i)%ptr%name) .eq. trim(name)) then
764 array => this%mesh_arrays(i)%ptr
765 return
766 end if
767 end do
768
770
771end module checkpoint_payload
Format-independent checkpoint payloads.
subroutine checkpoint_payload_validate_name(this, name)
Validate that a dataset name is non-empty and unique in a payload.
subroutine checkpoint_payload_add_series(this, fld_series)
Add a field series using the native names of its lag fields.
subroutine checkpoint_payload_add_field(this, fld)
Add a field using its native name as the dataset name.
pure integer function checkpoint_payload_series_count(this)
Return the number of field series in a payload.
subroutine add_array_4d(this, name, x, global_count, offset, device_ptr, replicated)
Add a rank-four contiguous real array.
subroutine checkpoint_payload_init(this, name)
Initialize a payload.
type(field_series_t) function, pointer checkpoint_payload_find_series(this, name)
Find a field series by the native name of its base field.
subroutine checkpoint_payload_add_array(this, name, x, global_count, offset, device_ptr, replicated)
Store a flattened real array in a payload.
pure integer function checkpoint_payload_field_count(this)
Return the number of fields in a payload.
subroutine checkpoint_payload_free(this)
Release all pointers held by a payload.
type(field_t) function, pointer checkpoint_payload_find_field(this, name)
Find a field by its native name.
subroutine add_array_1d(this, name, x, global_count, offset, device_ptr, replicated)
Add a rank-one real array.
subroutine add_mesh_array_4d(this, name, x, msh, xh, device_ptr)
Add a four-dimensional nodal mesh array.
type(checkpoint_array_t) function, pointer checkpoint_payload_find_array(this, name)
Find an array descriptor by dataset name.
subroutine add_array_2d(this, name, x, global_count, offset, device_ptr, replicated)
Add a rank-two contiguous real array.
subroutine checkpoint_payload_add_array_dp(this, name, x, global_count, offset, replicated)
Store a rank-one double-precision array in a payload.
subroutine checkpoint_payload_add_mesh_array(this, name, x, msh, xh, device_ptr)
Store a flattened nodal mesh array in a payload.
pure integer function checkpoint_payload_array_count(this)
Return the number of arrays in a payload.
type(checkpoint_mesh_array_t) function, pointer checkpoint_payload_find_mesh_array(this, name)
Find a mesh-array descriptor by dataset name.
pure integer function checkpoint_payload_mesh_array_count(this)
Return the number of mesh arrays in a payload.
subroutine add_array_3d(this, name, x, global_count, offset, device_ptr, replicated)
Add a rank-three contiguous real array.
Contains the field_serties_t type.
Defines a field.
Definition field.f90:34
Defines a mesh.
Definition mesh.f90:34
integer, parameter, public i8
Definition num_types.f90:7
integer, parameter, public dp
Definition num_types.f90:10
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Defines a function space.
Definition space.f90:34
Utilities.
Definition utils.f90:35
Pointer wrapper around checkpoint_array_t.
A named real array and its selection in a global checkpoint dataset.
Pointer wrapper around checkpoint_mesh_array_t.
A named nodal real array distributed over mesh elements.
Pointer wrapper used to keep payload addresses stable as the list grows.
A named collection of live fields to checkpoint together.
field_ptr_t, To easily obtain a pointer to a field
Definition field.f90:83
A wrapper for a pointer to a field_series_t.
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
The function space for the SEM solution fields.
Definition space.f90:64